/* Osmocom MNCC type definitions in TTCN-3
 * (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
 * contributions by sysmocom -s.f.m.c. GmbH
 * (C) 2018 Vadim Yanitskiy <axilirator@gmail.com>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

module MNCC_Types {

import from Osmocom_Types all;

/* for architectures where 'int' is 32bit like x86_64 */
type integer int with { variant "FIELDLENGTH(32)" };


/* GSM 04.08 Bearer Capability: Rate Adaption */
type enumerated GSM48_bcap_ra {
	GSM48_BCAP_RA_NONE	(0),
	GSM48_BCAP_RA_V110_X30	(1),
	GSM48_BCAP_RA_X31	(2),
	GSM48_BCAP_RA_OTHER	(3)
};

/* GSM 04.08 Bearer Capability: Signalling access protocol */
type enumerated GSM48_bcap_sig_access {
	GSM48_BCAP_SA_NONE		(0),
	GSM48_BCAP_SA_I440_I450 	(1),
	GSM48_BCAP_SA_X21		(2),
	GSM48_BCAP_SA_X28_DP_IN		(3),
	GSM48_BCAP_SA_X28_DP_UN		(4),
	GSM48_BCAP_SA_X28_NDP		(5),
	GSM48_BCAP_SA_X32		(6)
};

/* GSM 04.08 Bearer Capability: User Rate */
type enumerated GSM48_bcap_user_rate {
	GSM48_BCAP_UR_NONE		(0),
	GSM48_BCAP_UR_300		(1),
	GSM48_BCAP_UR_1200		(2),
	GSM48_BCAP_UR_2400		(3),
	GSM48_BCAP_UR_4800		(4),
	GSM48_BCAP_UR_9600		(5),
	GSM48_BCAP_UR_12000		(6),
	GSM48_BCAP_UR_1200_75		(7)
};

/* GSM 04.08 Bearer Capability: Parity */
type enumerated GSM48_bcap_parity {
	GSM48_BCAP_PAR_ODD		(0),
	GSM48_BCAP_PAR_EVEN		(2),
	GSM48_BCAP_PAR_NONE		(3),
	GSM48_BCAP_PAR_ZERO		(4),
	GSM48_BCAP_PAR_ONE		(5)
};

/* GSM 04.08 Bearer Capability: Intermediate Rate */
type enumerated GSM48_bcap_interm_rate {
	GSM48_BCAP_IR_NONE		(0),
	GSM48_BCAP_IR_8k		(2),
	GSM48_BCAP_IR_16k		(3)
};

/* GSM 04.08 Bearer Capability: Transparency */
type enumerated GSM48_bcap_transp {
	GSM48_BCAP_TR_TRANSP		(0),
	GSM48_BCAP_TR_RLP		(1),
	GSM48_BCAP_TR_TR_PREF		(2),
	GSM48_BCAP_TR_RLP_PREF		(3)
};

/* GSM 04.08 Bearer Capability: Modem Type */
type enumerated GSM48_bcap_modem_type {
	GSM48_BCAP_MT_NONE		(0),
	GSM48_BCAP_MT_V21		(1),
	GSM48_BCAP_MT_V22		(2),
	GSM48_BCAP_MT_V22bis		(3),
	GSM48_BCAP_MT_V23		(4),
	GSM48_BCAP_MT_V26ter		(5),
	GSM48_BCAP_MT_V32		(6),
	GSM48_BCAP_MT_UNDEF		(7),
	GSM48_BCAP_MT_AUTO_1		(8)
};

type enumerated MNCC_MsgType {
	MNCC_SETUP_REQ		('0101'O),
	MNCC_SETUP_IND		('0102'O),
	MNCC_SETUP_RSP		('0103'O),
	MNCC_SETUP_CNF		('0104'O),
	MNCC_SETUP_COMPL_REQ	('0105'O),
	MNCC_SETUP_COMPL_IND	('0106'O),
	MNCC_CALL_CONF_IND	('0107'O),
	MNCC_CALL_PROC_REQ	('0108'O),
	MNCC_PROGRESS_REQ	('0109'O),
	MNCC_ALERT_REQ		('010a'O),
	MNCC_ALERT_IND		('010b'O),
	MNCC_NOTIFY_REQ		('010c'O),
	MNCC_NOTIFY_IND		('010d'O),
	MNCC_DISC_REQ		('010e'O),
	MNCC_DISC_IND		('010f'O),
	MNCC_REL_REQ		('0110'O),
	MNCC_REL_IND		('0111'O),
	MNCC_REL_CNF		('0112'O),
	MNCC_FACILITY_REQ	('0113'O),
	MNCC_FACILITY_IND	('0114'O),
	MNCC_START_DTMF_IND	('0115'O),
	MNCC_START_DTMF_RSP	('0116'O),
	MNCC_START_DTMF_REJ	('0117'O),
	MNCC_STOP_DTMF_IND	('0118'O),
	MNCC_STOP_DTMF_RSP	('0119'O),
	MNCC_MODIFY_REQ		('011a'O),
	MNCC_MODIFY_IND		('011b'O),
	MNCC_MODIFY_RSP		('011c'O),
	MNCC_MODIFY_CNF		('011d'O),
	MNCC_MODIFY_REJ		('011e'O),
	MNCC_HOLD_IND		('011f'O),
	MNCC_HOLD_CNF		('0120'O),
	MNCC_HOLD_REJ		('0121'O),
	MNCC_RETRIEVE_IND	('0122'O),
	MNCC_RETRIEVE_CNF	('0123'O),
	MNCC_RETRIEVE_REJ	('0124'O),
	MNCC_USERINFO_REQ	('0125'O),
	MNCC_USERINFO_IND	('0126'O),
	MNCC_REJ_REQ		('0127'O),
	MNCC_REJ_IND		('0128'O),
	MNCC_PROGRESS_IND	('0129'O),
	MNCC_CALL_PROC_IND	('012a'O),
	MNCC_CALL_CONF_REQ	('012b'O),
	MNCC_START_DTMF_REQ	('012c'O),
	MNCC_STOP_DTMF_REQ	('012d'O),
	MNCC_HOLD_REQ		('012e'O),
	MNCC_RETRIEVE_REQ	('012f'O),

	MNCC_BRIDGE		('0200'O),
	MNCC_FRAME_RECV		('0201'O),
	MNCC_FRAME_DROP		('0202'O),
	MNCC_LCHAN_MODIFY	('0203'O),
	MNCC_RTP_CREATE		('0204'O),
	MNCC_RTP_CONNECT	('0205'O),
	MNCC_RTP_FREE		('0206'O),

	GSM_TCHF_FRAME		('0300'O),
	GSM_TCHF_FRAME_EFR	('0301'O),
	GSM_TCHH_FRAME		('0302'O),
	GSM_TCH_FRAME_AMR	('0303'O),
	GSM_BAD_FRAME		('03ff'O),

	MNCC_SOCKET_HELLO	('0400'O)
};

const integer GSM_MAX_FACILITY := 128;
const integer GSM_MAX_SSVERSION := 128;
const integer GSM_MAX_USERUSER := 128;

type record MNCC_bearer_cap_data {
	GSM48_bcap_ra		rate_adaptation,
	GSM48_bcap_sig_access	sig_access,
	int			async,
	int			nr_stop_bits,
	int			nr_data_bits,
	GSM48_bcap_user_rate	user_rate,
	GSM48_bcap_parity	parity,
	GSM48_bcap_interm_rate	interm_rate,
	GSM48_bcap_transp	transp,
	GSM48_bcap_modem_type	modem_type
};

type record length(0..8) of int MNCC_speech_vers;

/* Expanded fields from GSM TS 04.08, Table 10.5.102 */
type record MNCC_bearer_cap {
	int			transfer,
	int			mode,
	int			coding,
	int			radio,
	int			speech_ctm,
	MNCC_speech_vers	speech_ver,
	MNCC_bearer_cap_data	data	optional
};

template MNCC_bearer_cap ts_MNCC_bcap_voice := {
	transfer	:= 0,	/* speech */
	mode		:= 0,	/* circuit */
	coding		:= 0,	/* GSM standard */
	radio		:= 3,	/* FR/HR, FR preferred */
	speech_ctm	:= 0,	/* not supported */
	speech_ver	:= { 0, 2, 4, 1, 5, -1 },
	data		:= omit
};

template MNCC_bearer_cap ts_MNCC_bcap_data := {
	transfer	:= 1,	/* unrestricted digital information */
	mode		:= 0,	/* circuit */
	coding		:= 0,	/* GSM standard */
	radio		:= 3,	/* FR/HR, FR preferred */
	speech_ctm	:= 0,	/* not supported */
	speech_ver	:= { -1 },
	data		:= {
		rate_adaptation := GSM48_BCAP_RA_V110_X30,
		sig_access := GSM48_BCAP_SA_NONE,
		async := 1,
		nr_stop_bits := 1,
		nr_data_bits := 1,
		user_rate := GSM48_BCAP_UR_4800,
		parity := GSM48_BCAP_PAR_ODD,
		interm_rate := GSM48_BCAP_IR_8k,
		transp := GSM48_BCAP_TR_TRANSP,
		modem_type := GSM48_BCAP_MT_V21
	}
};

type record MNCC_number {
	GSM48_type_of_number	number_type,
	GSM48_num_plan_ind	plan,
	GSM48_present_ind	presence,
	GSM48_screening_ind	screen,
	charstring		number
};

/* 24.008 10.5.118 */
type enumerated GSM48_num_plan_ind {
	GSM48_NUMPLAN_UNKNOWN		(0),
	GSM48_NUMPLAN_E164		(1),
	GSM48_NUMPLAN_X121		(3),
	GSM48_NUMPLAN_F69		(4),
	GSM48_NUMPLAN_NATIONAL		(8),
	GSM48_NUMPLAN_PRIVATE		(9),
	GSM48_NUMPLAN_CTS		(11),
	GSM48_NUMPLAN_RESERVED		(15)
};

/* 04.08 10.5.118 */
type enumerated GSM48_type_of_number {
	GSM48_TON_UNKNOWN		(0),
	GSM48_TON_INTERNATIONAL		(1),
	GSM48_TON_NATIONAL		(2),
	GSM48_TON_NETWORK_SPECIFIC	(3),
	GSM48_TON_SHORT_CODE		(4)
};

/* 04.08 10.5.120 */
type enumerated GSM48_present_ind {
	GSM48_PRES_IND_ALLOWED		(0),
	GSM48_PRES_IND_RESTRICTED	(1),
	GSM48_PRES_IND_NUM_NOT_AVAIL	(2),
	GSM48_PRES_IND_RESERVED		(3)
};

type enumerated GSM48_screening_ind {
	GSM48_SCR_IND_NOT_SCREENED	(0),
	GSM48_SCR_IND_VERIF_PASSED	(1),
	GSM48_SCR_IND_VERIF_FAILED	(2),
	GSM48_SCR_IND_NETW_PROVIDED	(3)
};

/* 24.008 Table 10.5.122 */
type enumerated GSM48_cause_coding {
	GSM48_CAUSE_CS_Q931		('00'B),
	GSM48_CAUSE_CS_RSVD		('01'B),
	GSM48_CAUSE_CS_NATIONAL		('10'B),
	GSM48_CAUSE_CS_GSM		('11'B)
}

type enumerated GSM48_cause_loc {
	GSM48_CAUSE_LOC_USER				('0000'B),
	GSM48_CAUSE_LOC_PRN_S_LU			('0001'B),
	GSM48_CAUSE_LOC_PUN_S_LU			('0010'B),
	GSM48_CAUSE_LOC_TRANS_NET			('0011'B),
	GSM48_CAUSE_LOC_PUN_S_RU			('0100'B),
	GSM48_CAUSE_LOC_PRN_S_RU			('0101'B),
	GSM48_CAUSE_LOC_INN_NET				('0111'B),
	GSM48_CAUSE_LOC_NET_BEYOND			('1010'B)
}



template (value) MNCC_number ts_MNCC_number(charstring number,
				    GSM48_type_of_number ton := GSM48_TON_INTERNATIONAL,
				    GSM48_num_plan_ind npi := GSM48_NUMPLAN_E164,
				    GSM48_present_ind pres := GSM48_PRES_IND_ALLOWED,
				    GSM48_screening_ind screen := GSM48_SCR_IND_NOT_SCREENED) := {
	number_type := ton,
	plan := npi,
	presence := pres,
	screen := screen,
	number := number
}

template MNCC_number tr_MNCC_number(template charstring number,
				    template GSM48_type_of_number ton := ?,
				    template GSM48_num_plan_ind npi := ?,
				    template GSM48_present_ind pres := ?,
				    template GSM48_screening_ind screen := ?) := {
	number_type := ton,
	plan := npi,
	presence := pres,
	screen := screen,
	number := number
}

type record MNCC_cause {
	GSM48_cause_loc		location,
	GSM48_cause_coding	coding,
	int		rec,
	int		rec_val,
	int		val,
	octetstring	diag
} with {
	variant (location) "FIELDLENGTH(32)";
	variant (coding) "FIELDLENGTH(32)";
}

template (value) MNCC_cause ts_MNCC_cause(int val,
				  GSM48_cause_loc loc := GSM48_CAUSE_LOC_PUN_S_LU,
				  GSM48_cause_coding coding := GSM48_CAUSE_CS_GSM,
				  octetstring diag := ''O) := {
	location := loc,
	coding := coding,
	rec := 0,
	rec_val := 0,
	val := val,
	diag := diag
}

type record MNCC_useruser {
	int		proto,
	charstring	info
};

type record MNCC_progress {
	int		coding,
	int		location,
	int		descr
};

type record MNCC_cccap {
	int		dtmf,
	int		pcp
};

type int MNCC_notify (0..127);
type charstring MNCC_keypad length (1);

type enumerated MNCC_bcap {
	GSM_MNCC_BCAP_SPEECH	(0),
	GSM_MNCC_BCAP_UNR_DIG	(1),
	GSM_MNCC_BCAP_AUDIO	(2),
	GSM_MNCC_BCAP_FAX_G3	(3),
	GSM_MNCC_BCAP_OTHER_ITC	(4),
	GSM_MNCC_BCAP_RESERVED	(7)
};


type record MNCC_PDU_Signal {
	uint32_t	callref,

	MNCC_bearer_cap	bearer_cap optional,
	MNCC_number	called optional,
	MNCC_number	calling optional,
	MNCC_number	redirecting optional,
	MNCC_number	connected optional,
	MNCC_cause	cause optional,
	MNCC_progress	progress optional,
	MNCC_useruser	useruser optional,
	charstring	facility optional,
	MNCC_cccap	cccap optional,
	charstring	ssversion optional,

	int		clir_sup,
	int		clir_inv,
	int		signal optional,

	MNCC_keypad	keypad optional,
	int		more,
	MNCC_notify	notify,
	int		emergency optional,
	charstring	imsi,

	uint8_t		lchan_type,	/* empty in OSmoMSC */
	uint8_t		lchan_mode,	/* empty in OsmoMSC */

	octetstring	gcr optional,
	charstring	sdp optional
};


type record MNCC_PDU_Data {
	uint32_t	callref,
	octetstring	data
};

type record MNCC_PDU_Rtp {
	uint32_t	callref,
	boolean		is_ipv6,
	octetstring	ip,
	uint16_t	rtp_port,
	uint32_t	payload_type,
	uint32_t	payload_msg_type,

	charstring	sdp optional
};

type record MNCC_PDU_Hello {
	uint32_t	version,
	uint32_t	mncc_size,
	uint32_t	data_frame_size,
	uint32_t	called_offset,
	uint32_t	signal_offset,
	uint32_t	emergency_offset,
	uint32_t	lchan_type_offset
};


type union MNCC_MsgUnion {
	MNCC_PDU_Signal	signal,
	MNCC_PDU_Data	data,
	MNCC_PDU_Rtp	rtp,
	MNCC_PDU_Hello	hello
};


type record MNCC_PDU {
	MNCC_MsgType	msg_type,
	MNCC_MsgUnion	u
} with { variant (u) "CROSSTAG(
			hello, msg_type = MNCC_SOCKET_HELLO;
			rtp, {	msg_type = MNCC_RTP_CREATE,
				msg_type = MNCC_RTP_CONNECT,
				msg_type = MNCC_RTP_FREE };
			data, {	msg_type = GSM_TCHF_FRAME,
				msg_type = GSM_TCHF_FRAME_EFR,
				msg_type = GSM_TCHH_FRAME,
				msg_type = GSM_TCH_FRAME_AMR,
				msg_type = GSM_BAD_FRAME };
			signal, OTHERWISE
			)"
};

external function enc_MNCC_PDU(in MNCC_PDU pdu) return octetstring;

external function dec_MNCC_PDU(in octetstring stream) return MNCC_PDU;

external function set_MNCC_version(in integer version) return boolean;

template (value) MNCC_PDU ts_MNCC_HELLO(uint32_t version := 5) := {
	msg_type := MNCC_SOCKET_HELLO,
	u := {
		hello := {
			version := version,
			mncc_size := 836,
			data_frame_size := 8,
			called_offset := 104,
			signal_offset := 796,
			emergency_offset := 812,
			lchan_type_offset := 0
		}
	}
}

template MNCC_PDU ts_MNCC_Sign(MNCC_MsgType msg_type, MNCC_PDU_Signal sign) := {
	msg_type := msg_type,
	u := {
		signal := sign
	}
}

template MNCC_PDU ts_MNCC_SIMPLE(MNCC_MsgType msg_type, uint32_t call_id) := {
	msg_type := msg_type,
	u := {
		signal := {
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

template MNCC_PDU tr_MNCC_SIMPLE(template MNCC_MsgType msg_type, template uint32_t call_id) := {
	msg_type := msg_type,
	u := {
		signal := {
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}



/* MT: MSC <- MNCC: SETUP.req from ext. MNCC handler to MSC */
template MNCC_PDU ts_MNCC_SETUP_req(uint32_t call_id, charstring called, charstring calling, charstring imsi := "",
				    template MNCC_bearer_cap bcap := ts_MNCC_bcap_voice) := {
	msg_type := MNCC_SETUP_REQ,
	u := {
		signal := {	/* See 24.008 9.3.23.1 */
			callref := call_id,
			bearer_cap := valueof(bcap),			/* mandatory */
			called := valueof(ts_MNCC_number(called)),	/* optional */
			calling := valueof(ts_MNCC_number(calling)),	/* optional */
			redirecting := omit,				/* optional */
			connected := omit,
			cause := omit,
			progress := omit,				/* optional */
			useruser := omit,				/* optional */
			facility := omit,				/* optional */
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,					/* optional */
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := imsi,
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
};
template MNCC_PDU tr_MNCC_SETUP_req(template uint32_t call_id := ?,
				    template charstring called := ?,
				    template charstring calling := *,
				    template charstring imsi := ?) := {
	msg_type := MNCC_SETUP_REQ,
	u := {
		signal := {	/* See 24.008 9.3.23.1 */
			callref := call_id,
			bearer_cap := *,				/* mandatory in CC */
			called := tr_MNCC_number(called),		/* optional */
			calling := tr_MNCC_number(calling),		/* optional */
			redirecting := *,				/* optional */
			connected := omit,
			cause := omit,
			progress := *,					/* optional */
			useruser := *,					/* optional */
			facility := *,					/* optional */
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := *,					/* optional */
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := imsi,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
};


/* MO: MSC <- MNCC: Respons to SETUP.ind */
template MNCC_PDU ts_MNCC_SETUP_rsp(uint32_t call_id, charstring imsi := "",
				    template MNCC_number connected := omit) := {
	msg_type := MNCC_SETUP_RSP,
	u := {
		signal := {	/* See 24.008 9.3.5 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := connected,
			cause := omit,
			progress := omit,
			useruser := omit,				/* optional */
			facility := omit,				/* optional */
			cccap := omit,
			ssversion := omit,				/* optional */
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := imsi,
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
};
template MNCC_PDU tr_MNCC_SETUP_rsp(template uint32_t call_id,
				    template charstring imsi := ?,
				    template MNCC_number connected := *) := {
	msg_type := MNCC_SETUP_RSP,
	u := {
		signal := {	/* See 24.008 9.3.5 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := connected,
			cause := omit,
			progress := omit,
			useruser := *,					/* optional */
			facility := *,					/* optional */
			cccap := omit,
			ssversion := *,					/* optional */
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := imsi,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
};


/* MO: MSC -> MNCC: SETUP.ind from MSC to ext. MNCC handler */
template MNCC_PDU tr_MNCC_SETUP_ind(template uint32_t call_id := ?, template MNCC_number called := ?,
				    template MNCC_number calling := *, template charstring imsi :=?) := {
	msg_type := MNCC_SETUP_IND,
	u := {
		signal := {	/* See 24.008 9.3.23.2 */
			callref := call_id,
			bearer_cap := ?,				/* mandatory */
			called := called,				/* mandatory */
			calling := calling,				/* optional */
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := *,					/* optional */
			facility := *,					/* optional */
			cccap := *,					/* optional */
			ssversion := *,					/* optional */
			clir_sup := ?,					/* optional */
			clir_inv := ?,					/* optional */
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := imsi,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}
template (value) MNCC_PDU ts_MNCC_SETUP_ind(uint32_t call_id, MNCC_number called,
				    template (omit) MNCC_number calling := omit,
				    template (omit) charstring imsi := omit,
				    template (value) MNCC_bearer_cap bcap := ts_MNCC_bcap_voice) := {
	msg_type := MNCC_SETUP_IND,
	u := {
		signal := {	/* See 24.008 9.3.23.2 */
			callref := call_id,
			bearer_cap := valueof(bcap),			/* mandatory */
			called := called,				/* mandatory */
			calling := calling,				/* optional */
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,				/* optional */
			facility := omit,				/* optional */
			cccap := omit,					/* optional */
			ssversion := omit,				/* optional */
			clir_sup := 0,					/* optional */
			clir_inv := 0,					/* optional */
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := imsi,
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/* MO: MSC <- MNCC: SETUP.cnf; Response to SETUP.ind */
template MNCC_PDU ts_MNCC_SETUP_CNF(uint32_t call_id, template MNCC_number connected := omit) := {
	msg_type := MNCC_SETUP_CNF,
	u := {
		signal := {	/* See 24.008 9.3.5 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := connected,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/* MT: MSC -> MNCC: SETUP.cnf; Response to SETUP.req */
template MNCC_PDU tr_MNCC_SETUP_cnf(uint32_t call_id, template MNCC_number connected := *) := {
	msg_type := MNCC_SETUP_CNF,
	u := {
		signal := {	/* See 24.008 9.3.5 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := connected,
			cause := omit,
			progress := *,
			useruser := *,
			facility := *,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}

/* MT: MSC -> MNCC: SETUP_COMPL.req; request to send CONNECT ACK */
template MNCC_PDU tr_MNCC_SETUP_COMPL_req(template uint32_t call_id) :=
		tr_MNCC_SIMPLE(MNCC_SETUP_COMPL_REQ, call_id); /* See 24.008 9.3.6 */

/* MT: MSC -> MNCC: SETUP_COMPL.ind; receipt of CONNECT ACK */
template MNCC_PDU tr_MNCC_SETUP_COMPL_ind(template uint32_t call_id := ?) :=
		tr_MNCC_SIMPLE(MNCC_SETUP_COMPL_IND, call_id); /* See 24.008 9.3.6 */
template (value) MNCC_PDU ts_MNCC_SETUP_COMPL_ind(uint32_t call_id) :=
		ts_MNCC_SIMPLE(MNCC_SETUP_COMPL_IND, call_id); /* See 24.008 9.3.6 */

/* MT: MSC -> MNCC: REJ.req; reject MT call */
template MNCC_PDU tr_MNCC_REJ_req(template uint32_t call_id, template MNCC_cause cause := *) := {
	msg_type := MNCC_REJ_REQ,
	u := {
		signal := {	/* See 24.008 9.3.19 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := omit,
			useruser := *,
			facility := *,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}

/* MO: MSC <- MNCC: REJ.ind; reject MO call */
template MNCC_PDU ts_MNCC_REJ_ind(uint32_t call_id, template MNCC_cause cause := omit) := {
	msg_type := MNCC_REJ_IND,
	u := {
		signal := {	/* See 24.008 9.3.19 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/* MT: MSC -> MNCC: CALL_CONF.req; send CALL CONFIRMED to MS */
template MNCC_PDU tr_MNCC_CALL_CONF_ind(template uint32_t call_id, template MNCC_bearer_cap bcap := *,
					template MNCC_cause cause := *,
					template MNCC_cccap cccap := *) := {
	msg_type := MNCC_CALL_CONF_IND,
	u := {
		signal := {	/* See 24.008 9.3.2 */
			callref := call_id,
			bearer_cap := bcap,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := cccap,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}
template MNCC_PDU ts_MNCC_CALL_CONF_ind(uint32_t call_id,
					template (omit) MNCC_bearer_cap bcap := omit,
					template (omit) MNCC_cause cause := omit,
					template (omit) MNCC_cccap cccap := omit) := {
	msg_type := MNCC_CALL_CONF_IND,
	u := {
		signal := {	/* See 24.008 9.3.2 */
			callref := call_id,
			bearer_cap := bcap,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := cccap,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}


/* MO: MSC <- MNCC: CALL_PROC.req; call establishment initiated in network */
template MNCC_PDU ts_MNCC_CALL_PROC_req(uint32_t call_id, template MNCC_bearer_cap bcap := omit,
					template MNCC_progress prog := omit,
					template charstring fac := omit,
					template MNCC_cccap cccap := omit) := {
	msg_type := MNCC_CALL_PROC_REQ,
	u := {
		signal := {	/* See 24.008 9.3.2 */
			callref := call_id,
			bearer_cap := bcap,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := prog,
			useruser := omit,
			facility := fac,
			cccap := cccap,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}
template MNCC_PDU tr_MNCC_CALL_PROC_req(template uint32_t call_id,
					template MNCC_bearer_cap bcap := *,
					template MNCC_progress prog := *,
					template charstring fac := *,
					template MNCC_cccap cccap := *) := {
	msg_type := MNCC_CALL_PROC_REQ,
	u := {
		signal := {	/* See 24.008 9.3.2 */
			callref := call_id,
			bearer_cap := bcap,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := prog,
			useruser := omit,
			facility := fac,
			cccap := cccap,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}


/*     MSC <- MNCC: PROGRESS.req; PROGRESS message from ISDN */
template MNCC_PDU ts_MNCC_PROGRESS_req(uint32_t call_id, MNCC_progress prog,
					template MNCC_useruser uu := omit) := {
	msg_type := MNCC_PROGRESS_REQ,
	u := {
		signal := {	/* See 24.008 9.3.17 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := prog,
			useruser := uu,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/* MO: MSC <- MNCC: ALERT.req; indicate that user alerting has been initiated */
template MNCC_PDU ts_MNCC_ALERT_req(uint32_t call_id, template MNCC_progress prog := omit,
				    template charstring fac := omit,
				    template MNCC_useruser uu := omit) := {
	msg_type := MNCC_ALERT_REQ,
	u := {
		signal := {	/* See 24.008 9.3.1 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := prog,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}
template MNCC_PDU tr_MNCC_ALERT_req(template uint32_t call_id,
				    template MNCC_progress prog := *,
				    template charstring fac := *,
				    template MNCC_useruser uu := *) := {
	msg_type := MNCC_ALERT_REQ,
	u := {
		signal := {	/* See 24.008 9.3.1 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := prog,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}



/* MT: MSC -> MNCC: ALERRT.ind; indicates that mobile user alerting has been initiated */
template MNCC_PDU tr_MNCC_ALERT_ind(template uint32_t call_id, template MNCC_progress prog := omit,
				    template charstring fac := omit,
				    template MNCC_useruser uu := omit) := {
	msg_type := MNCC_ALERT_IND,
	u := {
		signal := {	/* See 24.008 9.3.1 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := prog,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}
template (value) MNCC_PDU ts_MNCC_ALERT_ind(uint32_t call_id,
				    template (omit) MNCC_progress prog := omit,
				    template (omit) charstring fac := omit,
				    template (omit) MNCC_useruser uu := omit) := {
	msg_type := MNCC_ALERT_IND,
	u := {
		signal := {	/* See 24.008 9.3.1 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := prog,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}


/*   : MSC <- MNCC: NOTIFY.req; request to send information pertaining to a call (such as user suspended) */
template MNCC_PDU ts_MNCC_NOTIFY_req(uint32_t call_id, MNCC_notify notify) := {
	msg_type := MNCC_NOTIFY_REQ,
	u := {
		signal := {	/* See 24.008 9.3.16 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := notify,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC -> MNCC: NOTIFY.ind; indication to the mobile user */
template MNCC_PDU tr_MNCC_NOTIFY_ind(template uint32_t call_id, template MNCC_notify notify) := {
	msg_type := MNCC_NOTIFY_IND,
	u := {
		signal := {	/* See 24.008 9.3.16 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := notify,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}

/*   : MSC -> MNCC: DISC.ind; mobile user requests disconnect */
template MNCC_PDU tr_MNCC_DISC_ind(template uint32_t call_id := ?, template MNCC_cause cause := ?,
				   template MNCC_progress prog := *,
				   template charstring fac := *,
				   template MNCC_useruser uu := *) := {
	msg_type := MNCC_DISC_IND,
	u := {
		signal := {	/* See 24.008 9.3.7 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := prog,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}
template (value) MNCC_PDU ts_MNCC_DISC_ind(uint32_t call_id, template (value) MNCC_cause cause,
				   template (omit) MNCC_progress prog := omit,
				   template (omit) charstring fac := omit,
				   template (omit) MNCC_useruser uu := omit) := {
	msg_type := MNCC_DISC_IND,
	u := {
		signal := {	/* See 24.008 9.3.7 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := prog,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC <- MNCC: DISC.req; indicate disconnect to mobile user */
template MNCC_PDU ts_MNCC_DISC_req(uint32_t call_id, MNCC_cause cause,
				   template MNCC_progress prog := omit,
				   template charstring fac := omit,
				   template MNCC_useruser uu := omit) := {
	msg_type := MNCC_DISC_REQ,
	u := {
		signal := {	/* See 24.008 9.3.7 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := prog,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}
template MNCC_PDU tr_MNCC_DISC_req(template uint32_t call_id,
				   template MNCC_cause cause := *,
				   template MNCC_progress prog := omit,
				   template charstring fac := omit,
				   template MNCC_useruser uu := omit) := {
	msg_type := MNCC_DISC_REQ,
	u := {
		signal := {	/* See 24.008 9.3.7 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := prog,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}


/*   : MSC -> MNCC: REL.ind; mobile user informs network that user wants to release call + MM */
template MNCC_PDU tr_MNCC_REL_ind(template uint32_t call_id := ?, template MNCC_cause cause := ?,
				  template charstring fac := *, template MNCC_useruser uu := *) := {
	msg_type := MNCC_REL_IND,
	u := {
		signal := {	/* See 24.008 9.3.18 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := omit,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}
template (value) MNCC_PDU ts_MNCC_REL_ind(uint32_t call_id,
				  template (value) MNCC_cause cause,
				  template (omit) charstring fac := omit,
				  template (omit) MNCC_useruser uu := omit) := {
	msg_type := MNCC_REL_IND,
	u := {
		signal := {	/* See 24.008 9.3.18 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := omit,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC <- MNCC: REL.req; indicate to mobile user tat network intents to release MM */
template MNCC_PDU ts_MNCC_REL_req(uint32_t call_id, MNCC_cause cause,
				  template charstring fac := omit, template MNCC_useruser uu := omit) := {
	msg_type := MNCC_REL_REQ,
	u := {
		signal := {	/* See 24.008 9.3.18 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := omit,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}
template MNCC_PDU tr_MNCC_REL_req(template uint32_t call_id, template MNCC_cause cause := *,
				  template charstring fac := *, template MNCC_useruser uu := *) := {
	msg_type := MNCC_REL_REQ,
	u := {
		signal := {	/* See 24.008 9.3.18 */
			callref := call_id,
			bearer_cap := omit,
			called := *,
			calling := *,
			redirecting := *,
			connected := *,
			cause := cause,
			progress := omit,
			useruser := uu,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := ?,
			lchan_type := 0,
			lchan_mode := 0,
			gcr := *,
			sdp := *
		}
	}
}


/*   : MSC -> MNCC: REL.cnf; confirm REL_req */
template MNCC_PDU tr_MNCC_REL_cnf(template uint32_t call_id := ?, template MNCC_cause cause := ?,
				  template charstring fac := *, template MNCC_useruser uu := *)
modifies tr_MNCC_REL_ind := {
	msg_type := MNCC_REL_CNF
};
template (value) MNCC_PDU ts_MNCC_REL_cnf(uint32_t call_id,
					  template (value) MNCC_cause cause,
					  template (omit) charstring fac := omit,
					  template (omit) MNCC_useruser uu := omit)
modifies ts_MNCC_REL_ind := {
	msg_type := MNCC_REL_CNF
};


/*   : MSC <- MNCC: FACILITY.req; request transmission of facility */
template MNCC_PDU ts_MNCC_FACILITY_req(uint32_t call_id, charstring fac) := {
	msg_type := MNCC_FACILITY_REQ,
	u := {
		signal := {	/* See 24.008 9.3.9 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC -> MNCC: FACILITY.req; indicate reception of facility */
template MNCC_PDU tr_MNCC_FACILITY_ind(template uint32_t call_id := ?, template charstring fac := ?) := {
	msg_type := MNCC_FACILITY_IND,
	u := {
		signal := {	/* See 24.008 9.3.9 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := fac,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}

/*   : MSC -> MNCC: START_DTMF.ind; MS has */
template MNCC_PDU tr_MNCC_START_DTMF_ind(template uint32_t call_id := ?, template MNCC_keypad keypad := ?) := {
	msg_type := MNCC_START_DTMF_IND,
	u := {
		signal := {	/* See 24.008 9.3.24 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := keypad,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}

/*   : MSC <- MNCC: START_DTMF.rsp; Acknowledge start of DTMF */
template MNCC_PDU ts_MNCC_START_DTMF_rsp(uint32_t call_id, MNCC_keypad keypad) := {
	msg_type := MNCC_START_DTMF_RSP,
	u := {
		signal := {	/* See 24.008 9.3.25 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := keypad,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC <- MNCC: START_DTMF.rsp; Acknowledge start of DTMF */
template MNCC_PDU ts_MNCC_START_DTMF_rej(uint32_t call_id, MNCC_cause cause) := {
	msg_type := MNCC_START_DTMF_REJ,
	u := {
		signal := {	/* See 24.008 9.3.26 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC -> MNCC: STOP_DTMF.ind */
template MNCC_PDU tr_MNCC_STOP_DTMF_ind(template uint32_t call_id := ?) :=
	tr_MNCC_SIMPLE(MNCC_STOP_DTMF_IND, call_id); /* See 24.008 9.3.29 */

/*   : MSC <- MNCC: STOP_DTMF.rsp; Acknowledge stop of DTMF */
template MNCC_PDU ts_MNCC_STOP_DTMF_rsp(uint32_t call_id) :=
	ts_MNCC_SIMPLE(MNCC_STOP_DTMF_RSP, call_id); /* See 24.008 9.3.30 */

/*   : MSC -> MNCC: MODIFY.ind; request to start MO in-call modification */
template MNCC_PDU tr_MNCC_MODIFY_ind(template uint32_t call_id := ?, template MNCC_bearer_cap bcap := ?) := {
	msg_type := MNCC_MODIFY_IND,
	u := {
		signal := {	/* See 24.008 9.3.14 */
			callref := call_id,
			bearer_cap := bcap,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}

/*   : MSC <- MNCC: MODIFY.rsp; tespond to MO in-call modification */
template MNCC_PDU ts_MNCC_MODIFY_rsp(uint32_t call_id, MNCC_bearer_cap bcap) := {
	msg_type := MNCC_MODIFY_RSP,
	u := {
		signal := {	/* See 24.008 9.3.14 */
			callref := call_id,
			bearer_cap := bcap,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC <- MNCC: MODIFY.req; request to start MT in-call modification */
template MNCC_PDU ts_MNCC_MODIFY_req(uint32_t call_id, MNCC_bearer_cap bcap) := {
	msg_type := MNCC_MODIFY_REQ,
	u := {
		signal := {	/* See 24.008 9.3.14 */
			callref := call_id,
			bearer_cap := bcap,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC -> MNCC: MODIFY.cnf; MS has responded to MT in-call modification */
template MNCC_PDU tr_MNCC_MODIFY_cnf(template uint32_t call_id := ?,
				     template MNCC_bearer_cap bcap := ?) := {
	msg_type := MNCC_MODIFY_CNF,
	u := {
		signal := {	/* See 24.008 9.3.14 */
			callref := call_id,
			bearer_cap := bcap,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := *,
			imsi := ?,
			lchan_type := ?,
			lchan_mode := ?,
			gcr := *,
			sdp := *
		}
	}
}

/*   : MSC <- MNCC: Request transmission of USERINFO to MS */
template MNCC_PDU ts_MNCC_USERINFO_req(uint32_t call_id, MNCC_useruser uu, integer more) := {
	msg_type := MNCC_USERINFO_REQ,
	u := {
		signal := {	/* See 24.008 9.3.31 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := uu,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := more,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC -> MNCC: Indicate reception of USERINFO from MS */
template MNCC_PDU tr_MNCC_USERINFO_ind(template uint32_t call_id := ?, template MNCC_useruser uu := ?,
					integer more) := {
	msg_type := MNCC_USERINFO_IND,
	u := {
		signal := {	/* See 24.008 9.3.31 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := omit,
			progress := omit,
			useruser := uu,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := more,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := *,
			sdp := *
		}
	}
}

/*   : MSC -> MNCC: HOLD.ind; MS requests hold of call */
template MNCC_PDU tr_MNCC_HOLD_ind(template uint32_t call_id := ?) :=
				tr_MNCC_SIMPLE(MNCC_HOLD_IND, call_id); /* See 24.008 9.3.10 */

/*   : MSC <- MNCC: HOLD.cnf; network confirms hold of call */
template MNCC_PDU ts_MNCC_HOLD_cnf(uint32_t call_id) :=
				ts_MNCC_SIMPLE(MNCC_HOLD_CNF, call_id); /* See 24.008 9.3.11 */

/*   : MSC <- MNCC: HOLD.rej; network rejects hold of call */
template MNCC_PDU ts_MNCC_HOLD_rej(uint32_t call_id, MNCC_cause cause) := {
	msg_type := MNCC_HOLD_REJ,
	u := {
		signal := {	/* See 24.008 9.3.12 */
			callref := call_id,
			bearer_cap := omit,
			called := omit,
			calling := omit,
			redirecting := omit,
			connected := omit,
			cause := cause,
			progress := omit,
			useruser := omit,
			facility := omit,
			cccap := omit,
			ssversion := omit,
			clir_sup := 0,
			clir_inv := 0,
			signal := omit,
			keypad := omit,
			more := 0,
			notify := 0,
			emergency := omit,
			imsi := "",
			lchan_type := 0,
			lchan_mode := 0,
			gcr := omit,
			sdp := omit
		}
	}
}

/*   : MSC -> MNCC: RETRIEVE.ind; MS requests retrieval of held call */
template MNCC_PDU tr_MNCC_RETRIEVE_ind(template uint32_t call_id := ?) :=
				tr_MNCC_SIMPLE(MNCC_RETRIEVE_IND, call_id); /* See 24.008 9.3.20 */

/*   : MSC <- MNCC: RETRIEVE.cnf; network confirms retrieve of call */
template MNCC_PDU ts_MNCC_RETRIEVE_cnf(uint32_t call_id) :=
				ts_MNCC_SIMPLE(MNCC_RETRIEVE_CNF, call_id); /* See 24.008 9.3.21 */

/*   : MSC <- MNCC: RETRIEVE.rej; network rejects retrieve of call */
template MNCC_PDU ts_MNCC_RETRIEVE_rej(uint32_t call_id, MNCC_cause cause)
modifies ts_MNCC_HOLD_rej := {		/* See 24.008 9.3.22 */
	msg_type := MNCC_RETRIEVE_REJ
}


template MNCC_PDU ts_MNCC_SIMPLE_RTP(MNCC_MsgType msg_type, uint32_t call_id) := {
	msg_type := msg_type,
	u := {
		rtp := {
			callref := call_id,
			is_ipv6 := false,
			ip := '00000000'O,
			rtp_port := 0,
			payload_type := 0,
			payload_msg_type := 0,
			sdp := omit
		}
	}
}

/* MSC <- MNCC: RTP_CREATE.req; request creation of RTP */
template MNCC_PDU ts_MNCC_RTP_CREATE(uint32_t call_id) := ts_MNCC_SIMPLE_RTP(MNCC_RTP_CREATE, call_id);

/* MSC -> MNCC: RTP_CREATE.rsp; acknowledge creation of RTP (stating MSC side IP/Port) */
template MNCC_PDU tr_MNCC_RTP_CREATE(template uint32_t call_id := ?,
				     template octetstring ip := ?,
				     template uint16_t rtp_port := ?,
				     template uint32_t payload_type := ?) := {
	msg_type := MNCC_RTP_CREATE,
	u := {
		rtp := {
			callref := call_id,
			is_ipv6 := ?,
			ip := ip,
			rtp_port := rtp_port,
			payload_type := payload_type,
			payload_msg_type := ?,
			sdp := *
		}
	}
}

/* MSC <- MNCC: RTP_CONNECT.req; request connect of RTP */
template MNCC_PDU ts_MNCC_RTP_CONNECT(uint32_t call_id, boolean is_ipv6, octetstring ip, uint16_t rtp_port, uint32_t pt) := {
	msg_type := MNCC_RTP_CONNECT,
	u := {
		rtp := {
			callref := call_id,
			is_ipv6 := is_ipv6,
			ip := ip,
			rtp_port := rtp_port,
			payload_type := pt,
			payload_msg_type := 0,
			sdp := omit
		}
	}
}
template MNCC_PDU tr_MNCC_RTP_CONNECT(template uint32_t call_id,
				      template octetstring ip := ?,
				      template uint16_t rtp_port := ?,
				      template uint32_t pt := ?) := {
	msg_type := MNCC_RTP_CONNECT,
	u := {
		rtp := {
			callref := call_id,
			is_ipv6 := ?,
			ip := ip,
			rtp_port := rtp_port,
			payload_type := pt,
			payload_msg_type := 0,
			sdp := *
		}
	}
}


/* MSC <- MNCC: RTP_FREE.req; request connect of RTP */
template MNCC_PDU ts_MNCC_RTP_FREE(uint32_t call_id) := ts_MNCC_SIMPLE_RTP(MNCC_RTP_FREE, call_id);

function f_mncc_get_call_id(MNCC_PDU pdu) return uint32_t {
	if (ischosen(pdu.u.rtp)) {
		return pdu.u.rtp.callref;
	} else if (ischosen(pdu.u.data)) {
		return pdu.u.data.callref;
	} else if (ischosen(pdu.u.signal)) {
		return pdu.u.signal.callref;
	} else  {
		setverdict(fail, "Unable to determine Callref for MNCC", pdu);
		mtc.stop
	}
}

} with { encode "RAW" ; variant "FIELDORDER(msb)" }