module BSSAP_LE_Types {

/* BSSAP_LE_Types, defining abstract TTCN-3 data types for the 3GPP BSSMAP-LE protocol.
 *
 * BSSMAP-LE is a 3GPP standard protocol used by SMLC and its peers in a GSM network.
 * This file covers 3GPP TS 49.031 version 15.0.0 Release 15
 *
 * (C) 2020 by Harald Welte <laforge@gnumonks.org>
 * 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
 */

import from General_Types all;
import from Osmocom_Types all;
import from BSSAP_Types all;
import from BSSLAP_Types all;
import from MobileL3_CommonIE_Types all;

/* TS 49.031 Section 10.1 */
type enumerated BSSMAP_LE_MsgType {
	BSSMAP_LE_PERFORM_LOC_REQ	('00101011'B),
	BSSMAP_LE_PERFORM_LOC_RESP	('00101101'B),
	BSSMAP_LE_PERFORM_LOC_ABORT	('00101110'B),
	BSSMAP_LE_PERFORM_LOC_INFO	('00101111'B),
	BSSMAP_LE_ASSIST_INFO_REQ	('00100000'B),
	BSSMAP_LE_ASSIST_INFO_RESP	('00100001'B),

	BSSMAP_LE_CONN_ORIENTED_INFO	('00101010'B),
	BSSMAP_LE_CONN_LESS_INFO	('00111010'B),

	BSSMAP_LE_RESET			('00110000'B),
	BSSMAP_LE_RESET_ACK		('00110001'B)
} with { variant "FIELDLENGTH(8)" };

/* TS 49.031 Section 10.2 */
type enumerated BSSMAP_LE_IEI {
	BSSMAP_LE_IEI_LCS_QoS		('00111110'B),
	BSSMAP_LE_IEI_LCS_PRIORITY	('01000011'B),
	BSSMAP_LE_IEI_LOCATION_TYPE	('01000100'B),
	BSSMAP_LE_IEI_GANSS_LOCATION_TYPE ('10000010'B),
	BSSMAP_LE_IEI_GEO_LOCATION	('01000101'B),
	BSSMAP_LE_IEI_POSITIONING_DATA	('01000110'B),
	BSSMAP_LE_IEI_GANSS_POS_DATA	('10000011'B),
	BSSMAP_LE_IEI_VELOCITY_DATA	('01010101'B),
	BSSMAP_LE_IEI_LCS_CAUSE		('01000111'B),
	BSSMAP_LE_IEI_LCS_CLIENT_TYPE	('01001000'B),
	BSSMAP_LE_IEI_APDU		('01001001'B),
	BSSMAP_LE_IEI_NET_ELEM_ID	('01001010'B),
	BSSMAP_LE_IEI_REQ_GPS_ASS_D	('01001011'B),
	BSSMAP_LE_IEI_REQ_GANSS_ASS_D	('01000001'B),
	BSSMAP_LE_IEI_DECIPH_KEYS	('01001100'B),
	BSSMAP_LE_IEI_RET_ERR_REQ	('01001101'B),
	BSSMAP_LE_IEI_RET_ERR_CAUSE	('01001110'B),
	BSSMAP_LE_IEI_SEGMENTATION	('01001111'B),
	BSSMAP_LE_IEI_CLASSMARK3_INFO	('00010011'B),
	BSSMAP_LE_IEI_CAUSE		('00000100'B),
	BSSMAP_LE_IEI_CELL_ID		('00000101'B),
	BSSMAP_LE_IEI_CHOSEN_CHAN	('00100001'B),
	BSSMAP_LE_IEI_IMSI		('00000000'B),
	BSSMAP_LE_IEI_LCS_CAPABILITY	('01010000'B),
	BSSMAP_LE_IEI_PKT_MEAS_REP	('01010001'B),
	BSSMAP_LE_IEI_CELL_ID_LIST	('01010010'B),
	BSSMAP_LE_IEI_IMEI		('10000000'B),
	BSSMAP_LE_IEI_BSS_MLAT_CAP	('10000100'B),
	BSSMAP_LE_IEI_CELL_INFO_LIST	('10000101'B),
	BSSMAP_LE_IEI_BTS_RX_ACC_LVL	('10000110'B),
	BSSMAP_LE_IEI_MLAT_METHOD	('10000111'B),
	BSSMAP_LE_IEI_MLAT_TA		('10001000'B),
	BSSMAP_LE_IEI_MS_SYNC_ACC	('10001001'B),
	BSSMAP_LE_IEI_SHORT_ID_SET	('10001010'B),
	BSSMAP_LE_IEI_RANDOM_ID_SET	('10001011'B),
	BSSMAP_LE_IEI_SHORT_BSS_ID	('10001100'B),
	BSSMAP_LE_IEI_RANDOM_ID		('10001101'B),
	BSSMAP_LE_IEI_SHORT_ID		('10001110'B),
	BSSMAP_LE_IEI_COVERAGE_CLASS	('10001111'B),
	BSSMAP_LE_IEI_MTA_ACC_SEC_RQD	('10010000'B)
} with { variant "FIELDLENGTH(8)" };

/* Section 9.1 */
type record BSSMAP_LE_PerfLocReq {
	BSSMAP_LE_MsgType 			msg_type,
	BSSMAP_LE_IE_LocationType		location_type,
	BSSMAP_IE_CellIdentifier		cell_id,
	BSSMAP_IE_ClassmarkInformationType3	cm3 optional,
	BSSMAP_LE_IE_LcsClientType		lcs_client_type optional,
	BSSMAP_IE_ChosenChannel			chosen_channel optional,
	BSSMAP_LE_IE_LcsPriority		lcs_priority optional,
	BSSMAP_LE_IE_LcsQoS			lcs_qos optional,
	BSSMAP_LE_IE_ReqGpsAssD			req_gps_ass_d optional,
	BSSMAP_LE_IE_APDU			bsslap_apdu optional,
	BSSMAP_LE_IE_LcsCapability		lcs_capability optional,
	BSSMAP_LE_IE_PacketMeasRep		packet_meas_rep optional,
	BSSMAP_LE_IE_CellIdList			meas_cell_id_list optional,
	BSSMAP_LE_IE_IMSI			imsi optional,
	BSSMAP_LE_IE_IMEI			imei optional
	// TODO: more optional IEs
};

/* Section 9.2 */
type record BSSMAP_LE_PerfLocResp {
	BSSMAP_LE_MsgType			msg_type,
	BSSMAP_LE_IE_GeographicLoc		geographic_loc optional,
	BSSMAP_LE_IE_PositioningData		pos_data optional,
	BSSMAP_LE_IE_DecipheringKeys		deciph_keys optional,
	BSSMAP_LE_IE_LcsCause			lcs_cause optional,
	BSSMAP_LE_IE_VelocityData		velocity_data optional,
	BSSMAP_LE_IE_GanssPosData		ganss_pos_data optional
};

/* Section 9.4 */
type record BSSMAP_LE_PerfLocAbort {
	BSSMAP_LE_MsgType			msg_type,
	BSSMAP_LE_IE_LcsCause			lcs_cause
};

/* Section 9.8 */
type record BSSMAP_LE_ConnOrientedInfo {
	BSSMAP_LE_MsgType			msg_type,
	BSSMAP_LE_IE_APDU			bsslap_apdu,
	BSSMAP_LE_IE_Segmentation		segmentation optional
	// TODO: MLA related optional IEs
};

/* Section 9.9 */
type record BSSMAP_LE_ConnLessInfo {
	BSSMAP_LE_MsgType			msg_type,
	BSSMAP_LE_IE_NetElementId		source_id,
	BSSMAP_LE_IE_NetElementId		dest_id,
	BSSMAP_LE_IE_APDU			bsslap_apdu optional,
	BSSMAP_LE_IE_Segmentation		segmentation optional,
	BSSMAP_LE_IE_RetErrReq			ret_err_req optional,
	BSSMAP_LE_IE_RetErrCause		ret_err_cause optional
};

/* Section 9.10 */
type record BSSMAP_LE_Reset {
	BSSMAP_LE_MsgType 		msg_type,
	BSSMAP_IE_Cause			cause
};

/* Section 9.11 */
type record BSSMAP_LE_ResetAck {
	BSSMAP_LE_MsgType 		msg_type
};

/* Section 9.12 */
type record BSSMAP_LE_PerformLocInfo {
	BSSMAP_LE_MsgType 		msg_type,
	BSSMAP_IE_CellIdentifier	cell_id,
	BSSMAP_LE_IE_APDU		bsslap_apdu optional
};

type union BSSMAP_LE_PDU {
	BSSMAP_LE_PerfLocReq		perf_loc_req,
	BSSMAP_LE_PerfLocResp		perf_loc_resp,
	BSSMAP_LE_PerfLocAbort		perf_loc_abort,
	BSSMAP_LE_ConnOrientedInfo	co_info,
	BSSMAP_LE_ConnLessInfo		cl_info,
	BSSMAP_LE_Reset			reset,
	BSSMAP_LE_ResetAck		reset_ack,
	BSSMAP_LE_PerformLocInfo	perf_loc_info,
	/* The following BSSMAP messages defined in 3GPP TS 48.008 are applicable to the Lb interface to
	 * support signaling to a Type A LMU using an SDCCH */
	PDU_BSSMAP_CipherModeCommand	cipherModeCommand,
	PDU_BSSMAP_CipherModeComplete	cipherModeComplete,
	PDU_BSSMAP_CipherModeReject	cipherModeReject,
	PDU_BSSMAP_ClassmarkUpdate	classmarkUpdate,
	PDU_BSSMAP_ClearCommand		clearCommand,
	PDU_BSSMAP_ClearComplete	clearComplete,
	PDU_BSSMAP_ClearRequest		clearRequest,
	PDU_BSSMAP_CompleteLayer3Information	completeLayer3Information,
	PDU_BSSMAP_Confusion		confusion,
	PDU_BSSMAP_HandoverRequired	handoverRequired,
	PDU_BSSMAP_HandoverRequiredReject handoverRequiredReject,
	PDU_BSSMAP_HandoverPerformed	handoverPerformed,
	PDU_BSSMAP_Paging		paging
} with {
	variant "TAG(
			perf_loc_req,	msg_type = BSSMAP_LE_PERFORM_LOC_REQ;
			perf_loc_resp,	msg_type = BSSMAP_LE_PERFORM_LOC_RESP;
			perf_loc_abort,	msg_type = BSSMAP_LE_PERFORM_LOC_ABORT;
			co_info,	msg_type = BSSMAP_LE_CONN_ORIENTED_INFO;
			cl_info,	msg_type = BSSMAP_LE_CONN_LESS_INFO;
			reset,		msg_type = BSSMAP_LE_RESET;
			reset_ack,	msg_type = BSSMAP_LE_RESET_ACK;
			perf_loc_info,	msg_type = BSSMAP_LE_PERFORM_LOC_INFO;
		)"
};

/* Section 10.3 */
type record BSSMAP_LE_IE_APDU {
	BSSMAP_LE_IEI		iei,
	uint16_t		len,
	BSSMAP_LE_ProtocolId	protocol_id,
	BIT1			spare,
	octetstring		data
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_APDU)"
	variant (len) "LENGTHTO(protocol_id,spare,data)"
};
type enumerated BSSMAP_LE_ProtocolId {
	BSSMAP_LE_PROT_RESERVED		('0000000'B),
	BSSMAP_LE_PROT_BSSLAP		('0000001'B),
	BSSMAP_LE_PROT_LLP		('0000010'B),
	BSSMAP_LE_PROT_SMLCPP		('0000011'B)
} with { variant "FIELDLENGTH(7)" };

/* Section 10.8 */
type record BSSMAP_LE_IE_DecipheringKeys {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BIT7			spare,
	boolean			ciph_key_flag,
	OCT7			cur_deciph_key,
	OCT7			next_deciph_key
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_DECIPH_KEYS)"
	variant (len) "LENGTHTO(spare,ciph_key_flag,cur_deciph_key,next_deciph_key)"
}

/* Section 10.9 */
type record BSSMAP_LE_IE_GeographicLoc {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	octetstring		location
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_GEO_LOCATION)"
	variant (len) "LENGTHTO(location)"
}

/* Section 10.10 */
type record BSSMAP_LE_IE_ReqGpsAssD {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BIT16			flags,
	octetstring		sat_data
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_REQ_GPS_ASS_D)"
	variant (len) "LENGTHTO(flags,sat_data)"
}

/* Section 10.11 */
type record BSSMAP_LE_IE_IMSI {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	MobileIdentityV		imsi
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_IMSI)"
	variant (len) "LENGTHTO(imsi)"
}

/* Section 10.13 */
type record BSSMAP_LE_IE_LcsCause {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BSSMAP_LE_LcsCause	cause,
	OCT1			diag_val optional
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_LCS_CAUSE)"
	variant (len) "LENGTHTO(cause,diag_val)"
}
type enumerated BSSMAP_LE_LcsCause {
	BSSMAP_LE_LCS_CAUSE_UNSPECIFIED		('00000000'B),
	BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE	('00000001'B),
	BSSMAP_LE_LCS_CAUSE_PROTOCOL_ERROR	('00000010'B),
	BSSMAP_LE_LCS_CAUSE_DATA_MISSING_IN_REQ	('00000011'B),
	BSSMAP_LE_LCS_CAUSE_UNEXP_DATA_IN_REQ	('00000100'B),
	BSSMAP_LE_LCS_CAUSE_POS_METH_FAILURE	('00000101'B),
	BSSMAP_LE_LCS_CAUSE_TGT_MS_UNREACHABLE	('00000110'B),
	BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED	('00000111'B),
	BSSMAP_LE_LCS_CAUSE_FACILITY_NOTSUPP	('00001000'B),
	BSSMAP_LE_LCS_CAUSE_INTER_BSC_HO	('00001001'B),
	BSSMAP_LE_LCS_CAUSE_INTRA_BSC_HO	('00001010'B),
	BSSMAP_LE_LCS_CAUSE_CONGESTION		('00001011'B),
	BSSMAP_LE_LCS_CAUSE_INTER_NSE_CHG	('00001100'B),
	BSSMAP_LE_LCS_CAUSE_RA_UPDAT		('00001101'B),
	BSSMAP_LE_LCS_CAUSE_PTMSI_REALLOC	('00001110'B),
	BSSMAP_LE_LCS_CAUSE_GPRS_SUSPENSION	('00001111'B)
} with { variant "FIELDLENGTH(8)" };

/* Section 10.14 */
type record BSSMAP_LE_IE_LcsClientType {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BSSMAP_LE_ClientType	cltype
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_LCS_CLIENT_TYPE)"
	variant (len) "LENGTHTO(cltype)"
}
type enumerated BSSMAP_LE_ClientType {
	BSSMAP_LE_LCS_CTYPE_VALUE_ADDED_UNSPECIFIED	('00000000'B),
	BSSMAP_LE_LCS_CTYPE_PLMN_OPER_UNSPECIFIED	('00100000'B),
	BSSMAP_LE_LCS_CTYPE_PLMN_OPER_BCAST_SERVICE	('00100001'B),
	BSSMAP_LE_LCS_CTYPE_PLMN_OPER_OAM		('00100010'B),
	BSSMAP_LE_LCS_CTYPE_PLMN_OPER_ANON_STATS	('00100011'B),
	BSSMAP_LE_LCS_CTYPE_PLMN_OPER_TGT_MS_SVC	('00100100'B),
	BSSMAP_LE_LCS_CTYPE_EMERG_SVC_UNSPECIFIED	('00110000'B),
	BSSMAP_LE_LCS_CTYPE_LI_UNSPECIFIED		('01000000'B)
} with { variant "FIELDLENGTH(8)" };

/* Section 10.15 */
type record BSSMAP_LE_IE_LcsPriority {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	OCT1			priority
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_LCS_PRIORITY)"
	variant (len) "LENGTHTO(priority)"
}

/* Section 10.16 */
type record BSSMAP_LE_IE_LcsQoS {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,

	BIT6			spare,
	boolean			vel,
	boolean			vert,

	boolean			ha,
	uint7_t			horiz_acc,

	boolean			va,
	uint7_t			vert_acc,

	BIT2			rt,
	BIT6			spare2
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_LCS_QoS)"
	variant (len) "LENGTHTO(spare,vel,vert,ha,horiz_acc,va,vert_acc,rt,spare2)"
}

/* Section 10.18 */
type record BSSMAP_LE_IE_LocationType {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BSSMAP_LE_LocInfo	loc_info,
	BSSMAP_LE_PosMethod	pos_method optional
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_LOCATION_TYPE)"
	variant (len) "LENGTHTO(loc_info,pos_method)"
	variant (pos_method) "PRESENCE(loc_info = BSSMAP_LE_LOC_INFO_ASS_INFO_FOR_TGT_MS,
				       loc_info = BSSMAP_LE_LOC_INFO_DECIPH_KEYS_FOR_BCAST)"
}
type enumerated BSSMAP_LE_LocInfo {
	BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC	('00000000'B),
	BSSMAP_LE_LOC_INFO_ASS_INFO_FOR_TGT_MS		('00000001'B),
	BSSMAP_LE_LOC_INFO_DECIPH_KEYS_FOR_BCAST	('00000010'B)
} with { variant "FIELDLENGTH(8)" };
type enumerated BSSMAP_LE_PosMethod {
	BSSMAP_LE_POS_METHOD_RESERVED		('00000000'B),
	BSSMAP_LE_POS_MOBILE_ASSISTED_EOTD	('00000001'B),
	BSSMAP_LE_POS_MOBILE_BASED_EOTD		('00000010'B),
	BSSMAP_LE_POS_ASSISTED_GPS		('00000011'B),
	BSSMAP_LE_POS_ASSISTED_GANSS		('00000100'B),
	BSSMAP_LE_POS_ASSISTED_GPS_AND_GANSS	('00000101'B)
} with { variant "FIELDLENGTH(8)" };

/* Section 10.19 */
type record BSSMAP_LE_IE_NetElementId {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BIT4			spare,
	BSSMAP_LE_IdDiscr	id_discr,
	BSSMAP_LE_IdU		u
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_NET_ELEM_ID)"
	variant (len) "LENGTHTO(spare,id_discr,u)"
	variant (u) "CROSSTAG(
				cgi,		id_discr = BSSMAP_LE_ID_DISC_CGI;
				lac_ci,		id_discr = BSSMAP_LE_ID_DISC_LAC_CI;
				lai,		id_discr = BSSMAP_LE_ID_DISC_LAI;
				lac,		id_discr = BSSMAP_LE_ID_DISC_LAC;
				lmu,		id_discr = BSSMAP_LE_ID_LMU;
			)"
};
type enumerated BSSMAP_LE_IdDiscr {
	BSSMAP_LE_ID_DISC_CGI		('0000'B),
	BSSMAP_LE_ID_DISC_LAC_CI	('0001'B),
	BSSMAP_LE_ID_DISC_LAI		('0100'B),
	BSSMAP_LE_ID_DISC_LAC		('0101'B),
	BSSMAP_LE_ID_LMU		('0110'B)
} with { variant "FIELDLENGTH(4)" };
type union BSSMAP_LE_IdU {
	BSSMAP_LE_Id_CGI	cgi,
	BSSMAP_LE_Id_LAC_CI	lac_ci,
	BSSMAP_LE_Id_LAI	lai,
	uint16_t		lac,
	octetstring		lmu
};
type record BSSMAP_LE_Id_CGI {
	HEX6n		mcc_mnc,
	uint16_t	lac,
	uint16_t	ci
};
type record BSSMAP_LE_Id_LAC_CI {
	uint16_t	lac,
	uint16_t	ci
};
type record BSSMAP_LE_Id_LAI {
	HEX6n		mcc_mnc,
	uint16_t	lac
};

/* Section 10.20 */
type record BSSMAP_LE_IE_PositioningData {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BIT4			spare,
	uint4_t			discr,
	BSSMAP_LE_PosMethList	pos_meth
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_POSITIONING_DATA)"
	variant (len) "LENGTHTO(spare,discr,pos_meth)"
};
type record of BSSMAP_LE_PosMethodN BSSMAP_LE_PosMethList;
type record BSSMAP_LE_PosMethodN {
	BSSMAP_LE_Method	method,
	BSSMAP_LE_Usage		usage
};
type enumerated BSSMAP_LE_Method {
	BSSMAP_LE_METHOD_TA				('00000'B),
	BSSMAP_LE_METHOD_RESERVED0			('00001'B),
	BSSMAP_LE_METHOD_RESERVED1			('00010'B),
	BSSMAP_LE_METHOD_MOBILE_ASS_EOTD		('00011'B),
	BSSMAP_LE_METHOD_MOBILE_BASED_EOTD		('00100'B),
	BSSMAP_LE_METHOD_MOBILE_ASS_GPS			('00101'B),
	BSSMAP_LE_METHOD_MOBILE_BASED_GPS		('00110'B),
	BSSMAP_LE_METHOD_CONVENTIONAL_GPS		('00111'B),
	BSSMAP_LE_METHOD_UTDOA				('01000'B),
	BSSMAP_LE_METHOD_CELL_ID			('01100'B)
} with { variant "FIELDLENGTH(5)" };
type enumerated BSSMAP_LE_Usage {
	BSSMAP_LE_USAGE_ATTEMPTED_UNSUCC			('000'B),
	BSSMAP_LE_USAGE_ATTEMPTED_SUCC_NOT_USED			('001'B),
	BSSMAP_LE_USAGE_ATTEMPTED_SUCC_USED_VRFY_NOT_GEN	('010'B),
	BSSMAP_LE_USAGE_ATTEMPTED_SUCC_USED_GEN			('011'B),
	BSSMAP_LE_USAGE_ATTEMPTED_SUCC_USAGE_UNDETERMINED	('100'B)
} with { variant "FIELDLENGTH(3)" };

/* Section 10.21 */
type record BSSMAP_LE_IE_RetErrReq {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	OCT1			ret_err_type
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_RET_ERR_REQ)"
	variant (len) "LENGTHTO(ret_err_type)"
}

/* Section 10.22 */
type record BSSMAP_LE_IE_RetErrCause {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BSSMAP_LE_RetErrCause	cause
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_RET_ERR_REQ)"
	variant (len) "LENGTHTO(cause)"
}
type enumerated BSSMAP_LE_RetErrCause {
	BSSMAP_LE_RE_CAUSE_UNSPECIFIED		('00000000'B),
	BSSMAP_LE_RE_CAUSE_SYSTEM_FAILURE	('00000001'B),
	BSSMAP_LE_RE_CAUSE_PROTOCOL_ERROR	('00000010'B),
	BSSMAP_LE_RE_CAUSE_DEST_UNKNOWN		('00000011'B),
	BSSMAP_LE_RE_CAUSE_DEST_UNREACHABLE	('00000100'B),
	BSSMAP_LE_RE_CAUSE_CONGESTION		('00000101'B)
} with { variant "FIELDLENGTH(8)" };

/* Section 10.24 */
type record BSSMAP_LE_IE_Segmentation {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BIT3			spare,
	boolean			s_non_final,
	uint4_t			seg_nr,
	OCT2			msg_id optional
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_SEGMENTATION)"
	variant (len) "LENGTHTO(spare,s_non_final,seg_nr,msg_id)"
}

/* Section 10.26 */
type record BSSMAP_LE_IE_LcsCapability {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	octetstring		lcs_cap
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_LCS_CAPABILITY)"
	variant (len) "LENGTHTO(lcs_cap)"
}

type record BSSMAP_LE_IE_PacketMeasRep {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	octetstring		pkt_meas_rep
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_PKT_MEAS_REP)"
	variant (len) "LENGTHTO(pkt_meas_rep)"
}

type record BSSMAP_LE_IE_CellIdList {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BSSLAP_CellIdList	cell_id_list
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_CELL_ID_LIST)"
	variant (len) "LENGTHTO(cell_id_list)"
}

/* Section 10.29 */
type record BSSMAP_LE_IE_IMEI {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	MobileIdentityV		imei
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_IMEI)"
	variant (len) "LENGTHTO(imei)"
}

/* Section 10.30 */
type record BSSMAP_LE_IE_VelocityData {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	octetstring		data
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_VELOCITY_DATA)"
	variant (len) "LENGTHTO(data)"
}

/* Section 10.32 */
type record BSSMAP_LE_IE_GanssPosData {
	BSSMAP_LE_IEI		iei,
	uint8_t			len,
	BSSMAP_LE_GanssList	list
} with {
	variant "PRESENCE(iei = BSSMAP_LE_IEI_VELOCITY_DATA)"
	variant (len) "LENGTHTO(list)"
}
type record of BSSMAP_LE_Ganss BSSMAP_LE_GanssList;
type record BSSMAP_LE_Ganss {
	BSSMAP_LE_GanssMethod	method,
	BSSMAP_LE_GanssId	id,
	BSSMAP_LE_Usage		usage
};
type enumerated BSSMAP_LE_GanssMethod {
	BSSMAP_LE_GANSS_METH_MS_BASED		('00'B),
	BSSMAP_LE_GANSS_METH_MS_ASSISTED	('01'B),
	BSSMAP_LE_GANSS_METH_MS_CONVENTIONAL	('10'B),
	BSSMAP_LE_GANSS_METH_MS_RESERVED	('11'B)
} with { variant "FIELDLENGTH(2)" };
type enumerated BSSMAP_LE_GanssId {
	BSSMAP_LE_GANSS_ID_GALILEO		('000'B),
	BSSMAP_LE_GANSS_ID_SBAS			('001'B),
	BSSMAP_LE_GANSS_ID_MODERNIZED_GPS	('010'B),
	BSSMAP_LE_GANSS_ID_QZSS			('011'B),
	BSSMAP_LE_GANSS_ID_GLONASS		('100'B),
	BSSMAP_LE_GANSS_ID_BDS			('101'B)
} with { variant "FIELDLENGTH(3)" };

/* FIXME: Further IEs */




type union BSSMAPLEorDTAP {
	BSSMAP_LE_PDU		bssmap,
	octetstring  		dtap
}

type record PDU_BSSAP_LE {
	BIT1		discriminator, 	// 0 = BSSMAP-LE; 1 = DTAP-LE
	BIT7		spare,		// always '0000000'B
	OCT1		dlci optional,
	LIN1		lengthIndicator,
	BSSMAPLEorDTAP	pdu
} with {
	variant (lengthIndicator) "LENGTHTO(pdu)"
	variant (pdu) "CROSSTAG(bssmap, discriminator='0'B;
				dtap, discriminator='1'B)"
	variant (dlci) "PRESENCE(discriminator='1'B)"
}


external function enc_PDU_BSSAP_LE(in PDU_BSSAP_LE pdu) return octetstring
with { extension "prototype(convert) encode(RAW)" }
external function dec_PDU_BSSAP_LE(in octetstring stream) return PDU_BSSAP_LE
with { extension "prototype(convert) decode(RAW)" }


} with { encode "RAW" ; }
