module AbisOML_Types {

/* AbisOML_Types, defining abstract TTCN-3 data types for the A-bis OML protocol.
 *
 * A-bis OML is a 3GP standard protocol used between BTS and BSC in a GSM network;
 * it is specified in 3GPP TS 12.21.
 *
 * (C) 2019 by Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of the GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;

type enumerated OML_MessageDiscriminator {
	ABIS_OM_MDISC_FOM	('80'H),
	ABIS_OM_MDISC_MMI	('40'H),
	ABIS_OM_MDISC_TRAU	('20'H),
	ABIS_OM_MDISC_MANUF	('10'H)
} with { variant "FIELDLENGTH(8)" };

type enumerated OML_Placement {
	ABIS_OM_PLACEMENT_ONLY		('80'H),
	ABIS_OM_PLACEMENT_FIRST		('40'H),
	ABIS_OM_PLACEMENT_MIDDLE	('20'H),
	ABIS_OM_PLACEMENT_LAST		('10'H)
} with { variant "FIELDLENGTH(8)" };

type union OML_Union {
	OML_FOM		fom,
	OML_MANUF	manuf,
	octetstring	other
};

type record OML_PDU {
	OML_MessageDiscriminator	mdisc,
	OML_Placement			placement,
	uint8_t				sequence,
	OML_Union			u
} with {
	 variant (u) "CROSSTAG(
			fom, mdisc = ABIS_OM_MDISC_FOM;
			manuf, mdisc = ABIS_OM_MDISC_MANUF;
			other, OTHERWISE;
		)" };


type record OML_FOM_ObjectInstance {
	uint8_t		bts_nr,
	uint8_t		trx_nr,
	uint8_t		ts_nr
};


type record OML_FOM_Header {
	OML_FOM_MessageType		msg_type,
	OML_FOM_ObjectClass		obj_class,
	OML_FOM_ObjectInstance		obj_inst
};

/* Section 9.1 */
type enumerated OML_FOM_MessageType {
	/* SW Download Management Messages */
	NM_MT_LOAD_INIT			('01'H),
	NM_MT_LOAD_INIT_ACK		('02'H),
	NM_MT_LOAD_INIT_NACK		('03'H),
	NM_MT_LOAD_SEG			('04'H),
	NM_MT_LOAD_SEG_ACK		('05'H),
	NM_MT_LOAD_ABORT		('06'H),
	NM_MT_LOAD_END			('07'H),
	NM_MT_LOAD_END_ACK		('08'H),
	NM_MT_LOAD_END_NACK		('09'H),
	NM_MT_SW_ACT_REQ		('0a'H),
	NM_MT_SW_ACT_REQ_ACK		('0b'H),
	NM_MT_SW_ACT_REQ_NACK		('0c'H),
	NM_MT_ACTIVATE_SW		('0d'H),
	NM_MT_ACTIVATE_SW_ACK		('0e'H),
	NM_MT_ACTIVATE_SW_NACK		('0f'H),
	NM_MT_SW_ACTIVATED_REP		('10'H),

	/* A-bis Interface Management Messages */
	NM_MT_ESTABLISH_TEI		('21'H),
	NM_MT_ESTABLISH_TEI_ACK		('22'H),
	NM_MT_ESTABLISH_TEI_NACK	('23'H),
	NM_MT_CONN_TERR_SIGN		('24'H),
	NM_MT_CONN_TERR_SIGN_ACK	('25'H),
	NM_MT_CONN_TERR_SIGN_NACK	('26'H),
	NM_MT_DISC_TERR_SIGN		('27'H),
	NM_MT_DISC_TERR_SIGN_ACK	('28'H),
	NM_MT_DISC_TERR_SIGN_NACK	('29'H),
	NM_MT_CONN_TERR_TRAF		('2a'H),
	NM_MT_CONN_TERR_TRAF_ACK	('2b'H),
	NM_MT_CONN_TERR_TRAF_NACK	('2c'H),
	NM_MT_DISC_TERR_TRAF		('2d'H),
	NM_MT_DISC_TERR_TRAF_ACK	('2e'H),
	NM_MT_DISC_TERR_TRAF_NACK	('2f'H),
	/* Transmission Management Messages */
	NM_MT_CONN_MDROP_LINK		('31'H),
	NM_MT_CONN_MDROP_LINK_ACK	('32'H),
	NM_MT_CONN_MDROP_LINK_NACK	('33'H),
	NM_MT_DISC_MDROP_LINK		('34'H),
	NM_MT_DISC_MDROP_LINK_ACK	('35'H),
	NM_MT_DISC_MDROP_LINK_NACK	('36'H),
	/* Air Interface Management Messages */
	NM_MT_SET_BTS_ATTR		('41'H),
	NM_MT_SET_BTS_ATTR_ACK		('42'H),
	NM_MT_SET_BTS_ATTR_NACK		('43'H),
	NM_MT_SET_RADIO_ATTR		('44'H),
	NM_MT_SET_RADIO_ATTR_ACK	('45'H),
	NM_MT_SET_RADIO_ATTR_NACK	('46'H),
	NM_MT_SET_CHAN_ATTR		('47'H),
	NM_MT_SET_CHAN_ATTR_ACK		('48'H),
	NM_MT_SET_CHAN_ATTR_NACK	('49'H),
	/* Test Management Messages */
	NM_MT_PERF_TEST			('51'H),
	NM_MT_PERF_TEST_ACK		('52'H),
	NM_MT_PERF_TEST_NACK		('53'H),
	NM_MT_TEST_REP			('54'H),
	NM_MT_SEND_TEST_REP		('55'H),
	NM_MT_SEND_TEST_REP_ACK		('56'H),
	NM_MT_SEND_TEST_REP_NACK	('57'H),
	NM_MT_STOP_TEST			('58'H),
	NM_MT_STOP_TEST_ACK		('59'H),
	NM_MT_STOP_TEST_NACK		('5a'H),
	/* State Management and Event Report Messages */
	NM_MT_STATECHG_EVENT_REP	('61'H),
	NM_MT_FAILURE_EVENT_REP		('62'H),
	NM_MT_STOP_EVENT_REP		('63'H),
	NM_MT_STOP_EVENT_REP_ACK	('64'H),
	NM_MT_STOP_EVENT_REP_NACK	('65'H),
	NM_MT_REST_EVENT_REP		('66'H),
	NM_MT_REST_EVENT_REP_ACK	('67'H),
	NM_MT_REST_EVENT_REP_NACK	('68'H),
	NM_MT_CHG_ADM_STATE		('69'H),
	NM_MT_CHG_ADM_STATE_ACK		('6a'H),
	NM_MT_CHG_ADM_STATE_NACK	('6b'H),
	NM_MT_CHG_ADM_STATE_REQ		('6c'H),
	NM_MT_CHG_ADM_STATE_REQ_ACK	('6d'H),
	NM_MT_CHG_ADM_STATE_REQ_NACK	('6e'H),

	NM_MT_REP_OUTST_ALARMS		('93'H),
	NM_MT_REP_OUTST_ALARMS_ACK	('94'H),
	NM_MT_REP_OUTST_ALARMS_NACK	('95'H),

	/* Equipment Management Messages */
	NM_MT_CHANGEOVER		('71'H),
	NM_MT_CHANGEOVER_ACK		('72'H),
	NM_MT_CHANGEOVER_NACK		('73'H),
	NM_MT_OPSTART			('74'H),
	NM_MT_OPSTART_ACK		('75'H),
	NM_MT_OPSTART_NACK		('76'H),
	NM_MT_REINIT			('77'H),
	NM_MT_REINIT_ACK		('78'H),
	NM_MT_REINIT_NACK		('79'H),
	NM_MT_SET_SITE_OUT		('7a'H),
	NM_MT_SET_SITE_OUT_ACK		('7b'H),
	NM_MT_SET_SITE_OUT_NACK		('7c'H),

	NM_MT_CHG_HW_CONF		('90'H),
	NM_MT_CHG_HW_CONF_ACK		('91'H),
	NM_MT_CHG_HW_CONF_NACK		('92'H),

	/* Measurement Management Messages */
	NM_MT_MEAS_RES_REQ		('8a'H),
	NM_MT_MEAS_RES_RESP		('8b'H),
	NM_MT_STOP_MEAS			('8c'H),
	NM_MT_START_MEAS		('8d'H),

	/* Other Messages */
	NM_MT_GET_ATTR			('81'H),
	NM_MT_GET_ATTR_RESP		('82'H),
	NM_MT_GET_ATTR_NACK		('83'H),
	NM_MT_SET_ALARM_THRES		('84'H),
	NM_MT_SET_ALARM_THRES_ACK	('85'H),
	NM_MT_SET_ALARM_THRES_NACK	('86'H),

	/* IPA specific messages */
	NM_MT_IPACC_RESTART		('87'H),
	NM_MT_IPACC_RESTART_ACK		('88'H),
	NM_MT_IPACC_RESTART_NACK	('89'H),

	NM_MT_IPACC_RSL_CONNECT		('e0'H),
	NM_MT_IPACC_RSL_CONNECT_ACK	('e1'H),
	NM_MT_IPACC_RSL_CONNECT_NACK	('e2'H),
	NM_MT_IPACC_RSL_DISCONNECT	('e3'H),
	NM_MT_IPACC_RSL_DISCONNECT_ACK	('e4'H),
	NM_MT_IPACC_RSL_DISCONNECT_NACK	('e5'H),
	NM_MT_IPACC_CONN_TRAF		('e6'H),
	NM_MT_IPACC_CONN_TRAF_ACK	('e7'H),
	NM_MT_IPACC_CONN_TRAF_NACK	('e8'H),
	NM_MT_IPACC_DEF_BOOT_SW		('ec'H),
	NM_MT_IPACC_DEF_BOOT_SW_ACK	('ed'H),
	MN_MT_IPACC_DEF_BOOT_SW_NACK	('ee'H),
	NM_MT_IPACC_SET_NVATTR		('ef'H),
	NM_MT_IPACC_SET_NVATTR_ACK	('f0'H),
	NM_MT_IPACC_SET_NVATTR_NACK	('f1'H),
	NM_MT_IPACC_GET_NVATTR		('f2'H),
	NM_MT_IPACC_GET_NVATTR_ACK	('f3'H),
	NM_MT_IPACC_GET_NVATTR_NACK	('f4'H),
	NM_MT_IPACC_SET_ATTR		('f5'H),
	NM_MT_IPACC_SET_ATTR_ACK	('f6'H),
	NM_MT_IPACC_SET_ATTR_NACK	('f7'H)

} with { variant "FIELDLENGTH(8)" };

/* Section 9.2 */
type enumerated OML_FOM_ObjectClass {
	NM_OC_SITE_MANAGER		('00'H),
	NM_OC_BTS			('01'H),
	NM_OC_RADIO_CARRIER		('02'H),
	NM_OC_CHANNEL			('03'H),
	NM_OC_BASEB_TRANSC		('04'H),

	NM_OC_IPAC_E1_TRUNK		('0e'H),
	NM_OC_IPAC_E1_PORT		('0f'H),
	NM_OC_IPAC_E1_CHAN		('10'H),
	NM_OC_IPAC_CLK_MODULE		('22'H),

	NM_OC_GPRS_NSE			('f0'H),
	NM_OC_GPRS_CELL			('f1'H),
	NM_OC_GPRS_NSVC			('f2'H),

	NM_OC_NULL			('ff'H)
} with { variant "FIELDLENGTH(8)" };

/* Section 9.4 */
type enumerated OML_FOM_IE_Type {
	NM_ATT_ABIS_CHANNEL		('01'H),
	NM_ATT_ADD_INFO			('02'H),
	NM_ATT_ADD_TEXT			('03'H),
	NM_ATT_ADM_STATE		('04'H),
	NM_ATT_ARFCN_LIST		('05'H),
	NM_ATT_AUTON_REPORT		('06'H),
	NM_ATT_AVAIL_STATUS		('07'H),
	NM_ATT_BCCH_ARFCN		('08'H),
	NM_ATT_BSIC			('09'H),
	NM_ATT_BTS_AIR_TIMER		('0a'H),
	NM_ATT_CCCH_L_I_P		('0b'H),
	NM_ATT_CCCH_L_T			('0c'H),
	NM_ATT_CHAN_COMB		('0d'H),
	NM_ATT_CONN_FAIL_CRIT		('0e'H),
	NM_ATT_DEST			('0f'H),
	/* res */
	NM_ATT_EVENT_TYPE		('11'H),
	NM_ATT_FILE_ID			('12'H),
	NM_ATT_FILE_VERSION		('13'H),
	NM_ATT_GSM_TIME			('14'H),
	NM_ATT_HSN			('15'H),
	NM_ATT_HW_CONFIG		('16'H),
	NM_ATT_HW_DESC			('17'H),
	NM_ATT_INTAVE_PARAM		('18'H),
	NM_ATT_INTERF_BOUND		('19'H),
	NM_ATT_LIST_REQ_ATTR		('1a'H),
	NM_ATT_MAIO			('1b'H),
	NM_ATT_MANUF_STATE		('1c'H),
	NM_ATT_MANUF_THRESH		('1d'H),
	NM_ATT_MANUF_ID			('1e'H),
	NM_ATT_MAX_TA			('1f'H),
	NM_ATT_MDROP_LINK		('20'H),
	NM_ATT_MDROP_NEXT		('21'H),
	NM_ATT_NACK_CAUSES		('22'H),
	NM_ATT_NY1			('23'H),
	NM_ATT_OPER_STATE		('24'H),
	NM_ATT_OVERL_PERIOD		('25'H),
	NM_ATT_PHYS_CONF		('26'H),
	NM_ATT_POWER_CLASS		('27'H),
	NM_ATT_POWER_THRESH		('28'H),
	NM_ATT_PROB_CAUSE		('29'H),
	NM_ATT_RACH_B_THRESH		('2a'H),
	NM_ATT_LDAVG_SLOTS		('2b'H),
	NM_ATT_RAD_SUBC			('2c'H),
	NM_ATT_RF_MAXPOWR_R		('2d'H),
	NM_ATT_SITE_INPUTS		('2e'H),
	NM_ATT_SITE_OUTPUTS		('2f'H),
	NM_ATT_SOURCE			('30'H),
	NM_ATT_SPEC_PROB		('31'H),
	NM_ATT_START_TIME		('32'H),
	NM_ATT_T200			('33'H),
	NM_ATT_TEI			('34'H),
	NM_ATT_TEST_DUR			('35'H),
	NM_ATT_TEST_NO			('36'H),
	NM_ATT_TEST_REPORT		('37'H),
	NM_ATT_VSWR_THRESH		('38'H),
	NM_ATT_WINDOW_SIZE		('39'H),
	/* res */
	NM_ATT_BS11_RSSI_OFFS		('3d'H),
	NM_ATT_BS11_TXPWR		('3e'H),
	NM_ATT_BS11_DIVERSITY		('3f'H),
	/* res */
	NM_ATT_TSC			('40'H),
	NM_ATT_SW_CONFIG		('41'H),
	NM_ATT_SW_DESCR			('42'H),
	NM_ATT_SEVERITY			('43'H),
	NM_ATT_GET_ARI			('44'H),
	NM_ATT_HW_CONF_CHG		('45'H),
	NM_ATT_OUTST_ALARM		('46'H),
	NM_ATT_FILE_DATA		('47'H),
	NM_ATT_MEAS_RES			('48'H),
	NM_ATT_MEAS_TYPE		('49'H),
	/* res */
	NM_ATT_BS11_ESN_FW_CODE_NO	('4c'H),
	NM_ATT_BS11_ESN_HW_CODE_NO	('4f'H),
	/* res */
	NM_ATT_BS11_ESN_PCB_SERIAL	('55'H),
	NM_ATT_BS11_EXCESSIVE_DISTANCE	('58'H),
	NM_ATT_BS11_ALL_TEST_CATG	('60'H),
	NM_ATT_BS11_BTSLS_HOPPING	('61'H),
	NM_ATT_BS11_CELL_ALLOC_NR	('62'H),
	NM_ATT_BS11_CELL_GLOBAL_ID	('63'H),

	NM_ATT_BS11_ENA_INTERF_CLASS	('66'H),
	NM_ATT_BS11_ENA_INT_INTEC_HANDO	('67'H),
	NM_ATT_BS11_ENA_INT_INTRC_HANDO	('68'H),
	NM_ATT_BS11_ENA_MS_PWR_CTRL	('69'H),
	NM_ATT_BS11_ENA_PWR_BDGT_HO	('6a'H),
	NM_ATT_BS11_ENA_PWR_CTRL_RLFW	('6b'H),
	NM_ATT_BS11_ENA_RXLEV_HO	('6c'H),
	NM_ATT_BS11_ENA_RXQUAL_HO	('6d'H),
	NM_ATT_BS11_FACCH_QUAL		('6e'H),

	NM_ATT_IPACC_DST_IP		('80'H),
	NM_ATT_IPACC_DST_IP_PORT	('81'H),
	NM_ATT_IPACC_SSRC		('82'H),
	NM_ATT_IPACC_RTP_PAYLD_TYPE	('83'H),
	NM_ATT_IPACC_BASEB_ID		('84'H),
	NM_ATT_IPACC_STREAM_ID		('85'H),
	NM_ATT_IPACC_NV_FLAGS		('86'H),
	NM_ATT_IPACC_FREQ_CTRL		('87'H),
	NM_ATT_IPACC_PRIM_OML_CFG	('88'H),
	NM_ATT_IPACC_SEC_OML_CFG	('89'H),
	NM_ATT_IPACC_IP_IF_CFG		('8a'H),
	NM_ATT_IPACC_IP_GW_CFG		('8b'H),
	NM_ATT_IPACC_IN_SERV_TIME	('8c'H),
	NM_ATT_IPACC_TRX_BTS_ASS	('8d'H),
	NM_ATT_IPACC_LOCATION		('8e'H),	/* string describing location */
	NM_ATT_IPACC_PAGING_CFG		('8f'H),
	NM_ATT_IPACC_FILE_DATA		('90'H),
	NM_ATT_IPACC_UNIT_ID		('91'H),	/* Site/BTS/TRX */
	NM_ATT_IPACC_PARENT_UNIT_ID	('92'H),
	NM_ATT_IPACC_UNIT_NAME		('93'H),	/* default: nbts-<mac-as-string> */
	NM_ATT_IPACC_SNMP_CFG		('94'H),
	NM_ATT_IPACC_PRIM_OML_CFG_LIST	('95'H),
	NM_ATT_IPACC_PRIM_OML_FB_TOUT	('96'H),
	NM_ATT_IPACC_CUR_SW_CFG		('97'H),
	NM_ATT_IPACC_TIMING_BUS		('98'H),
	NM_ATT_IPACC_CGI		('99'H),
	NM_ATT_IPACC_RAC		('9a'H),
	NM_ATT_IPACC_OBJ_VERSION	('9b'H),
	NM_ATT_IPACC_GPRS_PAGING_CFG	('9c'H),
	NM_ATT_IPACC_NSEI		('9d'H),
	NM_ATT_IPACC_BVCI		('9e'H),
	NM_ATT_IPACC_NSVCI		('9f'H),
	NM_ATT_IPACC_NS_CFG		('a0'H),
	NM_ATT_IPACC_BSSGP_CFG		('a1'H),
	NM_ATT_IPACC_NS_LINK_CFG	('a2'H),
	NM_ATT_IPACC_RLC_CFG		('a3'H),
	NM_ATT_IPACC_ALM_THRESH_LIST	('a4'H),
	NM_ATT_IPACC_MONIT_VAL_LIST	('a5'H),
	NM_ATT_IPACC_TIB_CONTROL	('a6'H),
	NM_ATT_IPACC_SUPP_FEATURES	('a7'H),
	NM_ATT_IPACC_CODING_SCHEMES	('a8'H),
	NM_ATT_IPACC_RLC_CFG_2		('a9'H),
	NM_ATT_IPACC_HEARTB_TOUT	('aa'H),
	NM_ATT_IPACC_UPTIME		('ab'H),
	NM_ATT_IPACC_RLC_CFG_3		('ac'H),
	NM_ATT_IPACC_SSL_CFG		('ad'H),
	NM_ATT_IPACC_SEC_POSSIBLE	('ae'H),
	NM_ATT_IPACC_IML_SSL_STATE	('af'H),
	NM_ATT_IPACC_REVOC_DATE		('b0'H),


/*
	NM_ATT_BS11_RF_RES_IND_PER	('8f'H),

	NM_ATT_BS11_RX_LEV_MIN_CELL	('90'H),
	NM_ATT_BS11_ABIS_EXT_TIME	('91'H),
	NM_ATT_BS11_TIMER_HO_REQUEST	('92'H),
	NM_ATT_BS11_TIMER_NCELL		('93'H),
	NM_ATT_BS11_TSYNC		('94'H),
	NM_ATT_BS11_TTRAU		('95'H),
	NM_ATT_BS11_EMRG_CFG_MEMBER	('9b'H),
	NM_ATT_BS11_TRX_AREA		('9f'H),

	NM_ATT_BS11_BCCH_RECONF		('d7'H),
	NM_ATT_BS11_BIT_ERR_THESH	('a0'H),
	NM_ATT_BS11_BOOT_SW_VERS	('a1'H),
	NM_ATT_BS11_CCLK_ACCURACY	('a3'H),
	NM_ATT_BS11_CCLK_TYPE		('a4'H),
	NM_ATT_BS11_INP_IMPEDANCE	('aa'H),
	NM_ATT_BS11_L1_PROT_TYPE	('ab'H),
	NM_ATT_BS11_LINE_CFG		('ac'H),
	NM_ATT_BS11_LI_PORT_1		('ad'H),
	NM_ATT_BS11_LI_PORT_2		('ae'H),

	NM_ATT_BS11_L1_REM_ALM_TYPE	('b0'H),
	NM_ATT_BS11_SW_LOAD_INTENDED	('bb'H),
	NM_ATT_BS11_SW_LOAD_SAFETY	('bc'H),
	NM_ATT_BS11_SW_LOAD_STORED	('bd'H),

	NM_ATT_BS11_VENDOR_NAME		('c1'H),
	NM_ATT_BS11_HOPPING_MODE	('c5'H),
	NM_ATT_BS11_LMT_LOGON_SESSION	('c6'H),
	NM_ATT_BS11_LMT_LOGIN_TIME	('c7'H),
	NM_ATT_BS11_LMT_USER_ACC_LEV	('c8'H),
	NM_ATT_BS11_LMT_USER_NAME	('c9'H),

	NM_ATT_BS11_L1_CONTROL_TS	('d8'H),
	NM_ATT_BS11_RADIO_MEAS_GRAN	('dc'H),
	NM_ATT_BS11_RADIO_MEAS_REP	('dd'H),

	NM_ATT_BS11_SH_LAPD_INT_TIMER	('e8'H),

	NM_ATT_BS11_BTS_STATE		('f0'H),
	NM_ATT_BS11_E1_STATE		('f1'H),
	NM_ATT_BS11_PLL			('f2'H),
	NM_ATT_BS11_RX_OFFSET		('f3'H),
	NM_ATT_BS11_ANT_TYPE		('f4'H),
	NM_ATT_BS11_PLL_MODE		('fc'H),
	NM_ATT_BS11_PASSWORD		('fd'H),
*/

	/* osmocom (osmo-bts) specific attributes, used in combination
	 * with the "org.osmocom" manufacturer identification */
	NM_ATT_OSMO_REDUCEPOWER		('fe'H)	/* TLV_TYPE_TV */

} with { variant "FIELDLENGTH(8)" };

/* Section 9.4.4 */
type enumerated OML_FOM_AdministrativeState {
	NM_STATE_LOCKED			('01'H),
	NM_STATE_UNLOCKED		('02'H),
	NM_STATE_SHUTDOWN		('03'H),
	NM_STATE_NULL			('ff'H)
} with { variant "FIELDLENGTH(8)" };

/* Section 9.4.7 */
type enumerated OML_FOM_AvailabilityStatus {
	NM_AVSTATE_IN_TEST		(1),
	NM_AVSTATE_POWER_OFF		(2),
	NM_AVSTATE_OFF_LINE		(3),
	NM_AVSTATE_DEPENDENCY		(5),
	NM_AVSTATE_DEGRADED		(6),
	NM_AVSTATE_NOT_INSTALLED	(7),
	NM_AVSTATE_OK			(255)
} with { variant "FIELDLENGTH(8)" };

type enumerated OML_FOM_OperationalState {
	NM_OPSTATE_DISABLED		(1),
	NM_OPSTATE_ENABLED		(2),
	NM_OPSTATE_NULL			(255)
} with { variant "FIELDLENGTH(8)" };

/* Section 9.4.13 */
type enumerated OML_ChannelCombination {
	NM_CHANC_TCHFull		('00'H), /* TCH/F + TCH/H + SACCH/TF */
	NM_CHANC_TCHHalf		('01'H), /* TCH/H(0,1) + FACCH/H(0,1) + SACCH/TH(0,1) */
	NM_CHANC_TCHHalf2		('02'H), /* TCH/H(0) + FACCH/H(0) + SACCH/TH(0) + TCH/H(1) */
	NM_CHANC_SDCCH			('03'H), /* SDCCH/8 + SACCH/8 */
	NM_CHANC_mainBCCH		('04'H), /* FCCH + SCH + BCCH + CCCH */
	NM_CHANC_BCCHComb		('05'H), /* FCCH + SCH + BCCH + CCCH + SDCCH/4 + SACCH/C4 */
	NM_CHANC_BCCH			('06'H), /* BCCH + CCCH */
	NM_CHANC_BCCH_CBCH		('07'H), /* CHANC_BCCHComb + CBCH */
	NM_CHANC_SDCCH_CBCH		('08'H), /* CHANC_SDCCH8 + CBCH */
	/* ip.access + Osmocom */
	NM_CHANC_IPAC_bPDCH		('0b'H), /* PBCCH + PCCCH + PDTCH/F + PACCH/F + PTCCH/F */
	NM_CHANC_IPAC_cPDCH		('0c'H), /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */
	NM_CHANC_IPAC_PDCH		('0d'H), /* PDTCH/F + PACCH/F + PTCCH/F */
	NM_CHANC_IPAC_TCHFull_PDCH	('80'H),
	NM_CHANC_IPAC_TCHFull_TCHHalf	('81'H),
	/* Osmocom */
	NM_CHANC_OSMO_TCHFull_TCHHalf_PDCH ('90'H)
} with { variant "FIELDLENGTH(8)" };

/* Section 9.4.16 */
type enumerated OML_FOM_EventType {
	NM_EVT_COMM_FAIL		(1),
	NM_EVT_QOS_FAIL			(2),
	NM_EVT_PROC_FAIL		(3),
	NM_EVT_EQUIP_FAIL		(4),
	NM_EVT_ENV_FAIL			(5)
} with { variant "FIELDLENGTH(8)" };

/* Section 9.4.63 */
type enumerated OML_FOM_Severity {
	NM_SEVER_CEASED			(0),
	NM_SEVER_CRITICAL		(1),
	NM_SEVER_MAJOR			(2),
	NM_SEVER_MINOR			(3),
	NM_SEVER_WARNING		(4),
	NM_SEVER_INDETERMINATE		(5)
} with { variant "FIELDLENGTH(8)" };

/* Section 9.4.36 */
type enumerated OML_FOM_NackCause {
	/* General Nack Causes */
	NM_NACK_INCORR_STRUCT		('01'H),
	NM_NACK_MSGTYPE_INVAL		('02'H),
	NM_NACK_OBJCLASS_INVAL		('05'H),
	NM_NACK_OBJCLASS_NOTSUPP	('06'H),
	NM_NACK_BTSNR_UNKN		('07'H),
	NM_NACK_TRXNR_UNKN		('08'H),
	NM_NACK_OBJINST_UNKN		('09'H),
	NM_NACK_ATTRID_INVAL		('0c'H),
	NM_NACK_ATTRID_NOTSUPP		('0d'H),
	NM_NACK_PARAM_RANGE		('0e'H),
	NM_NACK_ATTRLIST_INCONSISTENT	('0f'H),
	NM_NACK_SPEC_IMPL_NOTSUPP	('10'H),
	NM_NACK_CANT_PERFORM		('11'H),
	/* Specific Nack Causes */
	NM_NACK_RES_NOTIMPL		('19'H),
	NM_NACK_RES_NOTAVAIL		('1a'H),
	NM_NACK_FREQ_NOTAVAIL		('1b'H),
	NM_NACK_TEST_NOTSUPP		('1c'H),
	NM_NACK_CAPACITY_RESTR		('1d'H),
	NM_NACK_PHYSCFG_NOTPERFORM	('1e'H),
	NM_NACK_TEST_NOTINIT		('1f'H),
	NM_NACK_PHYSCFG_NOTRESTORE	('20'H),
	NM_NACK_TEST_NOSUCH		('21'H),
	NM_NACK_TEST_NOSTOP		('22'H),
	NM_NACK_MSGINCONSIST_PHYSCFG	('23'H),
	NM_NACK_FILE_INCOMPLETE		('25'H),
	NM_NACK_FILE_NOTAVAIL		('26'H),
	NM_NACK_FILE_NOTACTIVATE	('27'H),
	NM_NACK_REQ_NOT_GRANT		('28'H),
	NM_NACK_WAIT			('29'H),
	NM_NACK_NOTH_REPORT_EXIST	('2a'H),
	NM_NACK_MEAS_NOTSUPP		('2b'H),
	NM_NACK_MEAS_NOTSTART		('2c'H)
} with { variant "FIELDLENGTH(8)" };



type record OML_FOM {
	uint8_t				len,
	OML_FOM_Header			hdr,
	OML_FOM_IE_List			ies optional
} with { variant (len) "LENGTHTO(hdr,ies)" };

type record OML_IE_LV {
	uint8_t		len,
	octetstring	payload
} with { variant (len) "LENGTHTO(payload)" };

type record OML_IE_L16V {
	uint16_t	len,
	octetstring	payload
} with { variant (len) "LENGTHTO(payload)" };

template (value) OML_IE_L16V ts_OML_IE_L16V(template (value) uint16_t len, template (value) octetstring payload) := {
	len := len,
	payload := payload
}
template OML_IE_L16V tr_OML_IE_L16V(template uint16_t len, template octetstring payload) := {
	len := len,
	payload := payload
}


type record OML_IE_AvailStatus {
	uint16_t			len,
	OML_FOM_AvailabilityStatus	avail_status
} with { variant (len) "LENGTHTO(avail_status)" };

/* Section 9.4.1 */
type record OML_FOM_AbisChannel {
	uint8_t		bts_port_nr,
	uint8_t		timeslot_nr,
	OML_FOM_Subslot	subslot_nr
};
type enumerated OML_FOM_Subslot {
	NM_SUBSLOT_A		(0),
	NM_SUBSLOT_B		(1),
	NM_SUBSLOT_C		(2),
	NM_SUBSLOT_D		(3),
	NM_SUBSLOT_64k		(255)
} with { variant "FIELDLENGTH(8)" };

/* Section 9.4.5 */
type record of uint16_t OML_ArfcnList;
type record OML_IE_ArfcnList {
	uint16_t 	len,
	OML_ArfcnList	arfcn_list
};

/* Section 9.4.25 */
type record length(6) of uint8_t OML_FOM_InterfLevBoundaries;

/* Section 9.4.42 */
type record length(3) of uint8_t OML_FOM_PowerOuthputThresholds;

/* Section 9.4.43 */
type enumerated OML_FOM_ProbableCauseType {
	NM_PCAUSE_T_X721	(1),
	NM_PCAUSE_T_GSM		(2),
	NM_PCAUSE_T_MANUF	(3)
} with { variant "FIELDLENGTH(8)" };
type record OML_FOM_ProbableCause {
	OML_FOM_ProbableCauseType	cause_type,
	OCT2				cause_value
};

/* Section 9.4.53 */
type record OML_FOM_T200 {
	uint8_t		sdcch_5ms,
	uint8_t		facch_f_5ms,
	uint8_t		facch_h_5ms,
	uint8_t		sacch_tch_sapi0_10ms,
	uint8_t		sacch_sdcch_10ms,
	uint8_t		sdcch_sapi3_5ms,
	uint8_t		sacch_rch_sapi3_10ms
};

/* Section 9.4.64 */
type record OML_FOM_ARI {
	uint16_t	len,
	uint8_t	non_reported_attr_len,
	set of uint8_t	non_reported_attr optional,
	OML_FOM_IE_List		ies optional
} with { variant (len) "LENGTHTO(non_reported_attr_len,non_reported_attr,ies)"
	variant (non_reported_attr_len) "LENGTHTO(non_reported_attr)" };

type union OML_FOM_IE_Body {
	OML_FOM_AbisChannel		abis_channel,
	OML_FOM_AdministrativeState	adm_state,
	OCT1				auton_report,
	uint16_t			bcch_arfcn,
	uint8_t				bsic,
	uint8_t				air_timer,
	uint8_t				load_ind_period,
	uint8_t				load_threshold,
	OML_ChannelCombination		chan_comb,
	OML_FOM_EventType		event_type,
	uint16_t			gsm_time,
	uint8_t				hsn,
	uint8_t				intave_param,
	OML_FOM_InterfLevBoundaries	interf_bound,
	uint8_t				maio,
	uint8_t				manuf_state,
	uint8_t				max_ta,
	OML_FOM_NackCause		nack_causes,
	uint8_t				ny1,
	OML_FOM_OperationalState	opstate,
	uint8_t				power_class,
	OML_FOM_PowerOuthputThresholds	power_thresh,
	OML_FOM_ProbableCause		prob_cause,
	uint8_t				rach_b_thresh,
	uint16_t			loadavg_slots,
	uint8_t				radio_subch,
	uint8_t				rf_maxpwr_r,
	uint8_t				spec_prob,
	uint16_t			start_time,
	OML_FOM_T200			t200,
	uint8_t				tei,
	uint8_t				test_no,
	OCT2				vswr_thresh,
	uint8_t				window_size,
	uint8_t				tsc,
	OML_FOM_Severity		severity,
	uint8_t				outst_alarm,
	uint8_t				meas_type,

	OML_IE_AvailStatus		avail_status,
	OML_IE_ArfcnList		arfcn_list,

	uint32_t		ip,
	uint16_t		portnr,
	uint8_t			stream_id,
	OCT6			sec_oml_cfg,
	OCT8			ip_if_cfg,
	OCT12			ip_gw_cfg,
	uint32_t		in_serv_time,
	uint16_t		paging_cfg,
	OCT2			freq_ctrl,

	OML_FOM_ARI		ari,

	OML_IE_L16V		other
};

type record OML_FOM_IE {
	OML_FOM_IE_Type		iei,
	OML_FOM_IE_Body		body
} with { variant (body) "CROSSTAG(
		abis_channel, iei = NM_ATT_ABIS_CHANNEL;
		adm_state, iei = NM_ATT_ADM_STATE;
		auton_report, iei = NM_ATT_AUTON_REPORT;
		bcch_arfcn, iei = NM_ATT_BCCH_ARFCN;
		bsic, iei = NM_ATT_BSIC;
		air_timer, iei = NM_ATT_BTS_AIR_TIMER;
		load_ind_period, iei = NM_ATT_CCCH_L_I_P;
		load_threshold, iei = NM_ATT_CCCH_L_T;
		chan_comb, iei = NM_ATT_CHAN_COMB;
		event_type, iei = NM_ATT_EVENT_TYPE;
		gsm_time, iei = NM_ATT_GSM_TIME;
		hsn, iei = NM_ATT_HSN;
		intave_param, iei = NM_ATT_INTAVE_PARAM;
		interf_bound, iei = NM_ATT_INTERF_BOUND;
		maio, iei = NM_ATT_MAIO;
		manuf_state, iei = NM_ATT_MANUF_STATE;
		max_ta, iei = NM_ATT_MAX_TA;
		nack_causes, iei = NM_ATT_NACK_CAUSES;
		ny1, iei = NM_ATT_NY1;
		opstate, iei = NM_ATT_OPER_STATE;
		power_class, iei = NM_ATT_POWER_CLASS;
		power_thresh, iei = NM_ATT_POWER_THRESH;
		prob_cause, iei = NM_ATT_PROB_CAUSE;
		rach_b_thresh, iei = NM_ATT_RACH_B_THRESH;
		loadavg_slots, iei = NM_ATT_LDAVG_SLOTS;
		radio_subch, iei = NM_ATT_RAD_SUBC;
		rf_maxpwr_r, iei = NM_ATT_RF_MAXPOWR_R;
		spec_prob, iei = NM_ATT_SPEC_PROB;
		start_time, iei = NM_ATT_START_TIME;
		t200, iei = NM_ATT_T200;
		tei, iei = NM_ATT_TEI;
		test_no, iei = NM_ATT_TEST_NO;
		vswr_thresh, iei = NM_ATT_VSWR_THRESH;
		window_size, iei = NM_ATT_WINDOW_SIZE;
		tsc, iei = NM_ATT_TSC;
		severity, iei = NM_ATT_SEVERITY;
		outst_alarm, iei = NM_ATT_OUTST_ALARM;
		meas_type, iei = NM_ATT_MEAS_TYPE;

		avail_status, iei = NM_ATT_AVAIL_STATUS;
		arfcn_list, iei = NM_ATT_ARFCN_LIST;

		ip, iei = NM_ATT_IPACC_DST_IP;
		portnr, iei = NM_ATT_IPACC_DST_IP_PORT;
		stream_id, iei = NM_ATT_IPACC_STREAM_ID;
		sec_oml_cfg, iei = NM_ATT_IPACC_SEC_OML_CFG;
		ip_if_cfg, iei = NM_ATT_IPACC_IP_IF_CFG;
		ip_gw_cfg, iei = NM_ATT_IPACC_IP_GW_CFG;
		in_serv_time, iei = NM_ATT_IPACC_IN_SERV_TIME;
		paging_cfg, iei = NM_ATT_IPACC_PAGING_CFG;
		freq_ctrl, iei = NM_ATT_IPACC_FREQ_CTRL;

		ari, iei = NM_ATT_GET_ARI;

		other, OTHERWISE;
	)" };

type record of OML_FOM_IE OML_FOM_IE_List;

type record OML_MANUF_IPA {
	uint8_t			len,
	uint8_t			str_len,
	charstring		manuf_str,
	OML_FOM_Header		hdr,
	OML_FOM_IE_List		ies optional
} with { variant (len) "LENGTHTO(hdr,ies)"
         variant (str_len) "LENGTHTO(manuf_str)" };

type union OML_MANUF {
	OML_MANUF_IPA			ipa
};


external function enc_OML_PDU(in OML_PDU msg) return octetstring
	with { extension "prototype(convert) encode(RAW)" };
external function dec_OML_PDU(in octetstring stream) return OML_PDU
	with { extension "prototype(convert) decode(RAW)" };



template (value) OML_FOM_IE ts_OML_IE(OML_FOM_IE_Type iei, template (value) OML_FOM_IE_Body body) := {
	iei := iei,
	body := body
}
template OML_FOM_IE tr_OML_IE(OML_FOM_IE_Type iei, template OML_FOM_IE_Body body) := {
	iei := ?,
	body := body
}

template OML_PDU tr_OML_FOM_only := {
	mdisc := ABIS_OM_MDISC_FOM,
	placement := ABIS_OM_PLACEMENT_ONLY,
	sequence := 0,
	u := ?
}

template OML_PDU tr_OML_MsgType(template OML_FOM_MessageType msg_type,
				template OML_FOM_ObjectClass obj_class := ?,
				template OML_FOM_ObjectInstance obj_inst := ?,
				template OML_FOM_IE_List ies := *)
modifies tr_OML_FOM_only := {
	u := {
		fom := {
			hdr := {
				msg_type := msg_type,
				obj_class := obj_class,
				obj_inst := obj_inst
			},
			ies := ies
		}
	}
}
template (value) OML_PDU ts_OML_MsgType(template (value) OML_FOM_MessageType msg_type,
					template (value) OML_FOM_ObjectClass obj_class,
					template (value) OML_FOM_ObjectInstance obj_inst,
					template (omit) OML_FOM_IE_List ies := omit) := {
	mdisc := ABIS_OM_MDISC_FOM,
	placement := ABIS_OM_PLACEMENT_ONLY,
	sequence := 0,
	u := {
		fom := {
			len := 0, /* overwritten */
			hdr := ts_OML_FomHeader(msg_type, obj_class, obj_inst),
			ies := ies
		}
	}
}


template (value) OML_FOM_Header ts_OML_FomHeader(template (value) OML_FOM_MessageType msg_type,
						 template (value) OML_FOM_ObjectClass obj_class,
						 template (value) OML_FOM_ObjectInstance obj_inst) := {
	msg_type := msg_type,
	obj_class := obj_class,
	obj_inst := obj_inst
}
template OML_FOM_Header tr_OML_FomHeader(template OML_FOM_MessageType msg_type,
					 template OML_FOM_ObjectClass obj_class,
					 template OML_FOM_ObjectInstance obj_inst) := {
	msg_type := msg_type,
	obj_class := obj_class,
	obj_inst := obj_inst
}


template (value) OML_FOM_ObjectInstance ts_OML_ObjectInstance(uint8_t bts, uint8_t trx, uint8_t ts) := {
	bts_nr := bts,
	trx_nr := trx,
	ts_nr := ts
}
template OML_FOM_ObjectInstance tr_OML_ObjectInstance(template uint8_t bts, template uint8_t trx,
						      template uint8_t ts) := {
	bts_nr := bts,
	trx_nr := trx,
	ts_nr := ts
}



template (value) OML_PDU ts_OML_IPA_MsgType(template (value) OML_FOM_MessageType msg_type,
					    template (value) OML_FOM_ObjectClass obj_class,
					    template (value) OML_FOM_ObjectInstance obj_inst,
					    template (omit) OML_FOM_IE_List ies := omit) := {
	mdisc := ABIS_OM_MDISC_MANUF,
	placement := ABIS_OM_PLACEMENT_ONLY,
	sequence := 0,
	u := {
		manuf := {
			ipa := {
				len := 0, /* overwritten */
				str_len := 13,
				manuf_str := "com.ipaccess" & char(0,0,0,0),
				hdr := ts_OML_FomHeader(msg_type, obj_class, obj_inst),
				ies := ies
			}
		}
	}
}
template OML_PDU tr_OML_IPA_MsgType(template OML_FOM_MessageType msg_type := ?,
				    template OML_FOM_ObjectClass obj_class := ?,
				    template OML_FOM_ObjectInstance obj_inst := ?,
				    template OML_FOM_IE_List ies := *) := {
	mdisc := ABIS_OM_MDISC_MANUF,
	placement := ABIS_OM_PLACEMENT_ONLY,
	sequence := 0,
	u := {
		manuf := {
			ipa := {
				len := ?,
				str_len := 13,
				manuf_str := "com.ipaccess" & char(0,0,0,0),
				hdr := tr_OML_FomHeader(msg_type, obj_class, obj_inst),
				ies := ies
			}
		}
	}
}

/* 8.8.1 State Changed Event Report */
template (value) OML_PDU ts_OML_StateChgEvtRep(template (value) OML_FOM_ObjectClass obj_class,
					       template (value) OML_FOM_ObjectInstance obj_inst,
					       template (value) OML_FOM_OperationalState opstate,
					       template (value) OML_FOM_AvailabilityStatus avstate) :=
	ts_OML_MsgType(NM_MT_STATECHG_EVENT_REP, obj_class, obj_inst, {
			ts_OML_IE(NM_ATT_OPER_STATE, OML_FOM_IE_Body:{opstate := opstate}),
			ts_OML_IE(NM_ATT_AVAIL_STATUS, OML_FOM_IE_Body:{avail_status := {len:= 1, avail_status := avstate}})
			});
template OML_PDU tr_OML_StateChgEvtRep(template OML_FOM_ObjectClass obj_class,
				       template OML_FOM_ObjectInstance obj_inst,
				       template OML_FOM_OperationalState opstate := ?,
				       template OML_FOM_AvailabilityStatus avstate := ?,
				       template OML_FOM_AdministrativeState admstate := ?) :=
	tr_OML_MsgType(NM_MT_STATECHG_EVENT_REP, obj_class, obj_inst, {
			tr_OML_IE(NM_ATT_OPER_STATE, OML_FOM_IE_Body:{opstate := opstate}),
			tr_OML_IE(NM_ATT_AVAIL_STATUS, OML_FOM_IE_Body:{avail_status := {len := 1, avail_status := avstate}}),
			tr_OML_IE(NM_ATT_ADM_STATE, OML_FOM_IE_Body:{adm_state := admstate})
			});

/* 8.8.2 Failure Event Report */
template (value) OML_PDU ts_OML_FailureEvtRep(template (value) OML_FOM_ObjectClass obj_class,
					      template (value) OML_FOM_ObjectInstance obj_inst,
					      template (value) OML_FOM_EventType evt_type,
					      template (value) OML_FOM_Severity severity,
					      template (value) OML_FOM_ProbableCause cause) :=
	ts_OML_MsgType(NM_MT_FAILURE_EVENT_REP, obj_class, obj_inst, {
			ts_OML_IE(NM_ATT_EVENT_TYPE, OML_FOM_IE_Body:{event_type := evt_type}),
			ts_OML_IE(NM_ATT_SEVERITY, OML_FOM_IE_Body:{severity := severity}),
			ts_OML_IE(NM_ATT_PROB_CAUSE, OML_FOM_IE_Body:{prob_cause := cause})
			});
template OML_PDU tr_OML_FailureEvtRep(template OML_FOM_ObjectClass obj_class,
				      template OML_FOM_ObjectInstance obj_inst,
				      template OML_FOM_EventType evt_type,
				      template OML_FOM_Severity severity,
				      template OML_FOM_ProbableCause cause) :=
	tr_OML_MsgType(NM_MT_FAILURE_EVENT_REP, obj_class, obj_inst, {
			tr_OML_IE(NM_ATT_EVENT_TYPE, OML_FOM_IE_Body:{event_type := evt_type}),
			tr_OML_IE(NM_ATT_SEVERITY, OML_FOM_IE_Body:{severity := severity}),
			tr_OML_IE(NM_ATT_PROB_CAUSE, OML_FOM_IE_Body:{prob_cause := cause}),
			*
			});

/* 8.8.5 Change Administrative State */
template (value) OML_PDU ts_OML_ChangeAdmState(template (value) OML_FOM_ObjectClass obj_class,
						template (value) OML_FOM_ObjectInstance obj_inst,
						template (value) OML_FOM_AdministrativeState adm_st) :=
	ts_OML_MsgType(NM_MT_CHG_ADM_STATE, obj_class, obj_inst, {
			ts_OML_IE(NM_ATT_ADM_STATE, OML_FOM_IE_Body:{adm_state := adm_st})
			});
template OML_PDU tr_OML_ChangeAdmState(template OML_FOM_ObjectClass obj_class,
					template OML_FOM_ObjectInstance obj_inst,
					template OML_FOM_AdministrativeState adm_st) :=
	tr_OML_MsgType(NM_MT_CHG_ADM_STATE, obj_class, obj_inst, {
			tr_OML_IE(NM_ATT_ADM_STATE, OML_FOM_IE_Body:{adm_state := adm_st})
			});

template (value) OML_PDU ts_OML_ChangeAdmStateACK(template (value) OML_FOM_ObjectClass obj_class,
						template (value) OML_FOM_ObjectInstance obj_inst,
						template (value) OML_FOM_AdministrativeState adm_st) :=
	ts_OML_MsgType(NM_MT_CHG_ADM_STATE_ACK, obj_class, obj_inst, {
			ts_OML_IE(NM_ATT_ADM_STATE, OML_FOM_IE_Body:{adm_state := adm_st})
			});
template OML_PDU tr_OML_ChangeAdmStateACK(template OML_FOM_ObjectClass obj_class,
					template OML_FOM_ObjectInstance obj_inst,
					template OML_FOM_AdministrativeState adm_st) :=
	tr_OML_MsgType(NM_MT_CHG_ADM_STATE_ACK, obj_class, obj_inst, {
			tr_OML_IE(NM_ATT_ADM_STATE, OML_FOM_IE_Body:{adm_state := adm_st})
			});
template (value) OML_PDU ts_OML_ChangeAdmStateNACK(template (value) OML_FOM_ObjectClass obj_class,
						template (value) OML_FOM_ObjectInstance obj_inst,
						template (value) OML_FOM_NackCause cause) :=
	ts_OML_MsgType(NM_MT_CHG_ADM_STATE_NACK, obj_class, obj_inst, {
			ts_OML_IE(NM_ATT_NACK_CAUSES, OML_FOM_IE_Body:{nack_causes := cause})
			});
template OML_PDU tr_OML_ChangeAdmStateNACK(template OML_FOM_ObjectClass obj_class,
					   template OML_FOM_ObjectInstance obj_inst,
					   template OML_FOM_NackCause cause := ?) :=
	tr_OML_MsgType(NM_MT_CHG_ADM_STATE_NACK, obj_class, obj_inst, {
			*,
			tr_OML_IE(NM_ATT_NACK_CAUSES, OML_FOM_IE_Body:{nack_causes := cause})
			});





/* 8.9.2 Opstart */
template (value) OML_PDU ts_OML_Opstart(template (value) OML_FOM_ObjectClass obj_class,
					template (value) OML_FOM_ObjectInstance obj_inst) :=
	ts_OML_MsgType(NM_MT_OPSTART, obj_class, obj_inst);
template OML_PDU tr_OML_Opstart(template OML_FOM_ObjectClass obj_class,
				template OML_FOM_ObjectInstance obj_inst) :=
	tr_OML_MsgType(NM_MT_OPSTART, obj_class, obj_inst);

template (value) OML_PDU ts_OML_OpstartACK(template (value) OML_FOM_ObjectClass obj_class,
					   template (value) OML_FOM_ObjectInstance obj_inst) :=
	ts_OML_MsgType(NM_MT_OPSTART_ACK, obj_class, obj_inst);
template OML_PDU tr_OML_OpstartACK(template OML_FOM_ObjectClass obj_class,
				   template OML_FOM_ObjectInstance obj_inst) :=
	tr_OML_MsgType(NM_MT_OPSTART_ACK, obj_class, obj_inst);

template (value) OML_PDU ts_OML_OpstartNACK(template (value) OML_FOM_ObjectClass obj_class,
					    template (value) OML_FOM_ObjectInstance obj_inst,
					    template (value) OML_FOM_NackCause cause) :=
	ts_OML_MsgType(NM_MT_OPSTART_NACK, obj_class, obj_inst, {
		ts_OML_IE(NM_ATT_NACK_CAUSES, OML_FOM_IE_Body:{nack_causes := cause})
		});
template OML_PDU tr_OML_OpstartNACK(template OML_FOM_ObjectClass obj_class,
				   template OML_FOM_ObjectInstance obj_inst,
				   template OML_FOM_NackCause cause := ?) :=
	tr_OML_MsgType(NM_MT_OPSTART_NACK, obj_class, obj_inst, {
		tr_OML_IE(NM_ATT_NACK_CAUSES, OML_FOM_IE_Body:{nack_causes := cause})
		});

/* 8.3.5 SW Activate Request */
template (value) OML_PDU ts_OML_SwActReq(template (value) OML_FOM_ObjectClass obj_class,
					 template (value) OML_FOM_ObjectInstance obj_inst,
					 template (value) octetstring hw_config,
					 template (value) octetstring sw_config) :=
	ts_OML_MsgType(NM_MT_SW_ACT_REQ, obj_class, obj_inst, {
		ts_OML_IE(NM_ATT_HW_CONFIG, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, hw_config)}),
		ts_OML_IE(NM_ATT_SW_CONFIG, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, sw_config)})
		});
template OML_PDU tr_OML_SwActReq(template OML_FOM_ObjectClass obj_class,
				 template OML_FOM_ObjectInstance obj_inst,
				 template octetstring hw_config,
				 template octetstring sw_config) :=
	tr_OML_MsgType(NM_MT_SW_ACT_REQ, obj_class, obj_inst, {
		tr_OML_IE(NM_ATT_HW_CONFIG, OML_FOM_IE_Body:{other := tr_OML_IE_L16V(?, hw_config)}),
		tr_OML_IE(NM_ATT_SW_CONFIG, OML_FOM_IE_Body:{other := tr_OML_IE_L16V(?, sw_config)})
		});

template (value) OML_PDU ts_OML_SwActReqACK(template (value) OML_FOM_ObjectClass obj_class,
					 template (value) OML_FOM_ObjectInstance obj_inst,
					 template (value) octetstring hw_config,
					 template (value) octetstring sw_config) :=
	ts_OML_MsgType(NM_MT_SW_ACT_REQ_ACK, obj_class, obj_inst, {
		ts_OML_IE(NM_ATT_HW_CONFIG, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, hw_config)}),
		ts_OML_IE(NM_ATT_SW_CONFIG, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, sw_config)})
		});
template OML_PDU tr_OML_SwActReqACK(template OML_FOM_ObjectClass obj_class,
				 template OML_FOM_ObjectInstance obj_inst,
				 template octetstring hw_config,
				 template octetstring sw_config) :=
	tr_OML_MsgType(NM_MT_SW_ACT_REQ_ACK, obj_class, obj_inst, {
		tr_OML_IE(NM_ATT_HW_CONFIG, OML_FOM_IE_Body:{other := tr_OML_IE_L16V(?, hw_config)}),
		tr_OML_IE(NM_ATT_SW_CONFIG, OML_FOM_IE_Body:{other := tr_OML_IE_L16V(?, sw_config)})
		});

/* 8.3.6 Activate SW */
template (value) OML_PDU ts_OML_ActivateSw(template (value) OML_FOM_ObjectClass obj_class,
					 template (value) OML_FOM_ObjectInstance obj_inst,
					 template (value) octetstring file_id,
					 template (value) octetstring sw_desc) :=
	ts_OML_MsgType(NM_MT_ACTIVATE_SW, obj_class, obj_inst, {
		ts_OML_IE(NM_ATT_FILE_ID, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, file_id)}),
		ts_OML_IE(NM_ATT_SW_DESCR, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, sw_desc)})
		});
template OML_PDU tr_OML_ActivateSw(template OML_FOM_ObjectClass obj_class,
				 template OML_FOM_ObjectInstance obj_inst,
				 template octetstring file_id,
				 template octetstring sw_desc) :=
	tr_OML_MsgType(NM_MT_ACTIVATE_SW, obj_class, obj_inst, {
		tr_OML_IE(NM_ATT_FILE_ID, OML_FOM_IE_Body:{other := tr_OML_IE_L16V(?, file_id)}),
		tr_OML_IE(NM_ATT_SW_DESCR, OML_FOM_IE_Body:{other := tr_OML_IE_L16V(?, sw_desc)})
		});

template (value) OML_PDU ts_OML_ActivateSwACK(template (value) OML_FOM_ObjectClass obj_class,
					 template (value) OML_FOM_ObjectInstance obj_inst,
					 template (value) octetstring file_id,
					 template (value) octetstring sw_desc) :=
	ts_OML_MsgType(NM_MT_ACTIVATE_SW_ACK, obj_class, obj_inst, {
		ts_OML_IE(NM_ATT_FILE_ID, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, file_id)}),
		ts_OML_IE(NM_ATT_SW_DESCR, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, sw_desc)})
		});
template OML_PDU tr_OML_ActivateSwACK(template OML_FOM_ObjectClass obj_class,
				 template OML_FOM_ObjectInstance obj_inst,
				 template octetstring file_id,
				 template octetstring sw_desc) :=
	tr_OML_MsgType(NM_MT_ACTIVATE_SW_ACK, obj_class, obj_inst, {
		tr_OML_IE(NM_ATT_FILE_ID, OML_FOM_IE_Body:{other := tr_OML_IE_L16V(?, file_id)}),
		tr_OML_IE(NM_ATT_SW_DESCR, OML_FOM_IE_Body:{other := tr_OML_IE_L16V(?, sw_desc)})
		});

/* 8.3.7 SW Activated Report */
template (value) OML_PDU ts_OML_SwActivatedRep(template (value) OML_FOM_ObjectClass obj_class,
					       template (value) OML_FOM_ObjectInstance obj_inst) :=
	ts_OML_MsgType(NM_MT_SW_ACTIVATED_REP, obj_class, obj_inst, {});
template OML_PDU tr_OML_SwActivatedRep(template OML_FOM_ObjectClass obj_class,
				       template OML_FOM_ObjectInstance obj_inst) :=
	tr_OML_MsgType(NM_MT_SW_ACTIVATED_REP, obj_class, obj_inst, *);


/* 8.6.1 Set BTS Attributes */
template (value) OML_PDU ts_OML_SetBtsAttr(template (value) OML_FOM_ObjectInstance obj_inst,
					   template (value) OML_FOM_IE_List ies) :=
	ts_OML_MsgType(NM_MT_SET_BTS_ATTR, NM_OC_BTS, obj_inst, ies);
template OML_PDU tr_OML_SetBtsAttr(template OML_FOM_ObjectInstance obj_inst,
				   template OML_FOM_IE_List ies) :=
	tr_OML_MsgType(NM_MT_SET_BTS_ATTR, NM_OC_BTS, obj_inst, ies);


/* 8.6.2 Set Radio Carrier Attributes */
template (value) OML_PDU ts_OML_SetRadioAttr(template (value) OML_FOM_ObjectInstance obj_inst,
					     template (value) uint8_t maxpwr_r,
					     template (value) OML_ArfcnList arfcn_list) :=
	ts_OML_MsgType(NM_MT_SET_RADIO_ATTR, NM_OC_RADIO_CARRIER, obj_inst, {
		ts_OML_IE(NM_ATT_RF_MAXPOWR_R, OML_FOM_IE_Body:{rf_maxpwr_r := maxpwr_r}),
		ts_OML_IE(NM_ATT_ARFCN_LIST, OML_FOM_IE_Body:{arfcn_list := {len:=0, arfcn_list:=arfcn_list}})
		});
template OML_PDU tr_OML_SetRadioAttr(template OML_FOM_ObjectInstance obj_inst,
				     template uint8_t maxpwr_r,
				     template OML_ArfcnList arfcn_list) :=
	tr_OML_MsgType(NM_MT_SET_RADIO_ATTR, NM_OC_RADIO_CARRIER, obj_inst, {
		tr_OML_IE(NM_ATT_RF_MAXPOWR_R, OML_FOM_IE_Body:{rf_maxpwr_r := maxpwr_r}),
		tr_OML_IE(NM_ATT_ARFCN_LIST, OML_FOM_IE_Body:{arfcn_list := {len:=0, arfcn_list:=arfcn_list}})
		});


/* 8.6.3 Set Channel Attributes */
template (value) OML_PDU ts_OML_SetChanAttr(template (value) OML_FOM_ObjectInstance obj_inst,
					    template (value) OML_ChannelCombination chan_comb,
					    template (value) uint8_t tsc) :=
	ts_OML_MsgType(NM_MT_SET_CHAN_ATTR, NM_OC_CHANNEL, obj_inst, {
		ts_OML_IE(NM_ATT_CHAN_COMB, OML_FOM_IE_Body:{chan_comb := chan_comb}),
		ts_OML_IE(NM_ATT_TSC, OML_FOM_IE_Body:{tsc := tsc})
		});
template OML_PDU tr_OML_SetChanAttr(template OML_FOM_ObjectInstance obj_inst,
				    template OML_ChannelCombination chan_comb,
				    template uint8_t tsc) :=
	tr_OML_MsgType(NM_MT_SET_CHAN_ATTR, NM_OC_CHANNEL, obj_inst, {
		tr_OML_IE(NM_ATT_CHAN_COMB, OML_FOM_IE_Body:{chan_comb := chan_comb}),
		*,
		tr_OML_IE(NM_ATT_TSC, OML_FOM_IE_Body:{tsc := tsc})
		});


/* 8.11.1 Get Attributes */
template (value) OML_PDU ts_OML_GetAttributes(template (value) OML_FOM_ObjectClass obj_class,
					      template (value) OML_FOM_ObjectInstance obj_inst,
					      template (value) octetstring req_attr) :=
	ts_OML_MsgType(NM_MT_GET_ATTR, obj_class, obj_inst, {
		ts_OML_IE(NM_ATT_LIST_REQ_ATTR, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, req_attr)})
			});
template OML_PDU tr_OML_GetAttributes(template OML_FOM_ObjectClass obj_class,
				      template OML_FOM_ObjectInstance obj_inst,
				      template octetstring req_attr) :=
	tr_OML_MsgType(NM_MT_GET_ATTR, obj_class, obj_inst, {
		tr_OML_IE(NM_ATT_LIST_REQ_ATTR, OML_FOM_IE_Body:{other := tr_OML_IE_L16V(?, req_attr)})
			});

/* 8.11.3 Get Attributes Response */
template (value) OML_PDU ts_OML_GetAttributesResponse(template (value) OML_FOM_ObjectClass obj_class,
						      template (value) OML_FOM_ObjectInstance obj_inst,
						      template (value) octetstring req_attr) :=
	ts_OML_MsgType(NM_MT_GET_ATTR_RESP, obj_class, obj_inst, {
		ts_OML_IE(NM_ATT_GET_ARI, OML_FOM_IE_Body:{other := ts_OML_IE_L16V(0, req_attr)})
			});
template OML_PDU tr_OML_GetAttributesResponse(template OML_FOM_ObjectClass obj_class,
					      template OML_FOM_ObjectInstance obj_inst,
					      template OML_FOM_ARI ari := ?) :=
	tr_OML_MsgType(NM_MT_GET_ATTR_RESP, obj_class, obj_inst, {
		tr_OML_IE(NM_ATT_GET_ARI, OML_FOM_IE_Body:{ari := ari})
			});

/* convert a request into an ACK */
function f_OML_make_ack(OML_PDU orig) return OML_PDU {
	var OML_PDU resp := orig;
	if (ischosen(resp.u.fom)) {
		int2enum(enum2int(orig.u.fom.hdr.msg_type)+1, resp.u.fom.hdr.msg_type);
	} else if (ischosen(resp.u.manuf)) {
		int2enum(enum2int(orig.u.manuf.ipa.hdr.msg_type)+1, resp.u.manuf.ipa.hdr.msg_type);
	} else {
		testcase.stop("Unsupported OML in f_OML_make_ack(): ", orig);
	}
	return resp;
}
function f_OML_make_ack_exp(OML_PDU orig) return template OML_PDU {
	var template OML_PDU resp := orig;
	var OML_FOM_MessageType msg_t;
	if (ischosen(resp.u.fom)) {
		resp.u.fom.len := ?;
		int2enum(enum2int(orig.u.fom.hdr.msg_type)+1, msg_t);
		resp.u.fom.hdr.msg_type := msg_t;
	} else if (ischosen(resp.u.manuf)) {
		resp.u.manuf.ipa.len := ?;
		int2enum(enum2int(orig.u.manuf.ipa.hdr.msg_type)+1, msg_t);
		resp.u.manuf.ipa.hdr.msg_type := msg_t;
	} else {
		testcase.stop("Unsupported OML in f_OML_make_ack(): ", orig);
	}
	return resp;
}

/* convert a request into a NACK, appending the cause IE */
function f_OML_make_nack(OML_PDU orig, OML_FOM_NackCause cause) return OML_PDU {
	var OML_PDU resp := orig;
	if (ischosen(resp.u.fom)) {
		int2enum(enum2int(orig.u.fom.hdr.msg_type)+2, resp.u.fom.hdr.msg_type);
		resp.u.fom.ies := orig.u.fom.ies & {
			valueof(ts_OML_IE(NM_ATT_NACK_CAUSES, OML_FOM_IE_Body:{nack_causes := cause}))
			};
	} else if (ischosen(resp.u.manuf)) {
		int2enum(enum2int(orig.u.manuf.ipa.hdr.msg_type)+2, resp.u.manuf.ipa.hdr.msg_type);
		resp.u.manuf.ipa.ies := orig.u.manuf.ipa.ies & {
			valueof(ts_OML_IE(NM_ATT_NACK_CAUSES, OML_FOM_IE_Body:{nack_causes := cause}))
			};
	} else {
		testcase.stop("Unsupported OML in f_OML_make_nack(): ", orig);
	}
	return resp;
}
function f_OML_make_nack_exp(OML_PDU orig, template OML_FOM_NackCause cause) return template OML_PDU {
	var template OML_PDU resp := orig;
	var OML_FOM_MessageType msg_t;
	if (ischosen(resp.u.fom)) {
		resp.u.fom.len := ?;
		int2enum(enum2int(orig.u.fom.hdr.msg_type)+2, msg_t);
		resp.u.fom.hdr.msg_type := msg_t;
		resp.u.fom.ies := { *,
			tr_OML_IE(NM_ATT_NACK_CAUSES, OML_FOM_IE_Body:{nack_causes := cause})
			};
	} else if (ischosen(resp.u.manuf)) {
		resp.u.manuf.ipa.len := ?;
		int2enum(enum2int(orig.u.manuf.ipa.hdr.msg_type)+2, msg_t);
		resp.u.manuf.ipa.hdr.msg_type := msg_t;
		resp.u.manuf.ipa.ies := { *,
			tr_OML_IE(NM_ATT_NACK_CAUSES, OML_FOM_IE_Body:{nack_causes := cause})
			};
/*
		resp.u.manuf.ipa.ies := resp.u.manuf.ipa.ies & {
			tr_OML_IE(NM_ATT_NACK_CAUSES, OML_FOM_IE_Body:{nack_causes := cause})
			};
*/
	} else {
		testcase.stop("Unsupported OML in f_OML_make_nack_exp(): ", orig);
	}
	return resp;
}

function f_OML_FOM_IE_List_get_ie(OML_FOM_IE_List ie_list, OML_FOM_IE_Type iei) return OML_FOM_IE_Body
{
	for (var integer i := 0; i < lengthof(ie_list); i := i + 1) {
		if (ie_list[i].iei == iei) {
			return ie_list[i].body;
		}
	}
	var OML_FOM_IE_Body dummy;
	return dummy; /*TODO: setverdict(fail?) */
}

function f_OML_FOM_get_ie(OML_FOM fom, OML_FOM_IE_Type iei) return OML_FOM_IE_Body
{
	return f_OML_FOM_IE_List_get_ie(fom.ies, iei);
}


/***********************************************************************
 * IPA / Osmocom specifics
 ***********************************************************************/



template (value) OML_PDU ts_OML_IPA_RslConnect(template (value) OML_FOM_ObjectInstance obj_inst,
					       template (value) uint8_t stream_id,
					       template (value) uint16_t port_nr) :=
	ts_OML_IPA_MsgType(NM_MT_IPACC_RSL_CONNECT, NM_OC_BASEB_TRANSC, obj_inst, {
			   ts_OML_IE(NM_ATT_IPACC_STREAM_ID, OML_FOM_IE_Body:{stream_id := stream_id}),
			   ts_OML_IE(NM_ATT_IPACC_DST_IP_PORT, OML_FOM_IE_Body:{portnr := port_nr})
			   });
template OML_PDU tr_OML_IPA_RslConnect(template (present) OML_FOM_ObjectInstance obj_inst,
				       template (present) uint8_t stream_id,
				       template (present) uint16_t port_nr) :=
	tr_OML_IPA_MsgType(NM_MT_IPACC_RSL_CONNECT, NM_OC_BASEB_TRANSC, obj_inst, {
			   tr_OML_IE(NM_ATT_IPACC_STREAM_ID, OML_FOM_IE_Body:{stream_id := stream_id}),
			   tr_OML_IE(NM_ATT_IPACC_DST_IP_PORT, OML_FOM_IE_Body:{portnr := port_nr})
			   });





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