Add a MNCC Socket implementation for TTCN-3

Change-Id: I8c334d4c2e630b2b779e73404c44a8df3278c614
diff --git a/library/MNCC_Types.ttcn b/library/MNCC_Types.ttcn
new file mode 100644
index 0000000..956a1ae
--- /dev/null
+++ b/library/MNCC_Types.ttcn
@@ -0,0 +1,387 @@
+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_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_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_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_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 },
+	data		:= omit
+};
+
+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)
+};
+
+
+template 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
+}
+
+type record MNCC_cause {
+	int		location,
+	int		coding,
+	int		rec,
+	int		rec_val,
+	int		val,
+	octetstring	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 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,
+
+	int		keypad optional,
+	int		more,
+	int		notify (0..127),
+	int		emergency optional,
+	charstring	imsi,
+
+	uint8_t		lchan_type,	/* empty in OSmoMSC */
+	uint8_t		lchan_mode	/* empty in OsmoMSC */
+};
+
+
+type record MNCC_PDU_Data {
+	uint32_t	callref,
+	octetstring	data
+};
+
+type record MNCC_PDU_Rtp {
+	uint32_t	callref,
+	uint32_t	ip,
+	uint16_t	rtp_port,
+	uint32_t	payload_type,
+	uint32_t	payload_msg_type
+};
+
+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;
+
+
+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_SETUP(uint32_t call_id, charstring called, charstring calling) := {
+	msg_type := MNCC_SETUP_REQ,
+	u := {
+		signal := {
+			callref := call_id,
+			bearer_cap := ts_MNCC_bcap_voice,
+			called := valueof(ts_MNCC_number(called)),
+			calling := valueof(ts_MNCC_number(calling)),
+			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 := "1234",
+			lchan_type := 0,
+			lchan_mode := 0
+		}
+	}
+};
+
+
+} with { encode "RAW" ; variant "FIELDORDER(msb)" }