module IPA_Types {

/* Definitions of abstract data types for the IPA multiplex protocol.
 * Uses the TITAN "RAW" codec syntax to auto-generate encoder and decoder
 * functions.
 *
 * (C) 2017 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.
 */

import from Osmocom_Types all;

type enumerated IpaStreamId {
	IPAC_PROTO_RSL_TRX0	(0),
	IPAC_PROTO_RSL_TRX1	(1),
	IPAC_PROTO_RSL_TRX2	(2),
	IPAC_PROTO_RSL_TRX3	(3),
	IPAC_PROTO_OSMO		(238),
	IPAC_PROTO_MGCP_OLD	(252),
	IPAC_PROTO_SCCP		(253),
	IPAC_PROTO_CCM		(254),
	IPAC_PROTO_OML		(255)
} with { variant "FIELDLENGTH(8)" }

type enumerated IpaExtStreamId {
	IPAC_PROTO_EXT_CTRL	('00'H),
	IPAC_PROTO_EXT_MGCP	('01'H),
	IPAC_PROTO_EXT_LAC	('02'H),
	IPAC_PROTO_EXT_SMSC	('03'H),
	IPAC_PROTO_EXT_ORC	('04'H),
	IPAC_PROTO_EXT_GSUP	('05'H),
	IPAC_PROTO_EXT_OAP	('06'H)
} with { variant "FIELDLENGTH(8)" }

external function enc_PDU_IPA(in PDU_IPA pdu) return octetstring
with { extension "prototype(convert)"
       extension "encode(RAW)"
     }

external function dec_PDU_IPA(in octetstring stream) return PDU_IPA
with { extension "prototype(convert)"
       extension "decode(RAW)"
     }

type record PDU_IPA
{
	uint16_t	lengthInd,
	IpaStreamId	streamId,
	IpaExtStreamId	streamIdExt optional,
	octetstring	payloadData
} with {
	variant (lengthInd) "LENGTHTO(streamIdExt,payloadData)";
	variant (lengthInd) "FIELDLENGTH(16)";
	variant (lengthInd) "BYTEORDER(last)";
	variant (streamIdExt) "PRESENCE(streamId=IPAC_PROTO_OSMO)";
}

template PDU_IPA ts_PDU_IPA(IpaStreamId id, template octetstring payload) := {
	lengthInd := 0,
	streamId := id,
	streamIdExt := omit,
	payloadData := valueof(payload)
}


type enumerated IpaCcmMsgtype {
	IPAC_MSGT_PING		('00'H),
	IPAC_MSGT_PONG		('01'H),
	IPAC_MSGT_ID_GET	('04'H),
	IPAC_MSGT_ID_RESP	('05'H),
	IPAC_MSGT_ID_ACK	('06'H)
} with { variant "FIELDLENGTH(8)" }

type enumerated IpaCcmIdTag {
	IPAC_IDTAG_SERNR	('00'H),
	IPAC_IDTAG_UNITNAME	('01'H),
	IPAC_IDTAG_LOCATION1	('02'H),
	IPAC_IDTAG_LOCATION2	('03'H),
	IPAC_IDTAG_EQUIPVERS	('04'H),
	IPAC_IDTAG_SWVERSION	('05'H),
	IPAC_IDTAG_IPADDR	('06'H),
	IPAC_IDTAG_MACADDR	('07'H),
	IPAC_IDTAG_UNIT		('08'H),
	IPAC_IDTAG_OSMO_RAND	('23'H)
} with { variant "FIELDLENGTH(8)" }


type record IpaCcmGetPart {
	uint8_t		len,
	IpaCcmIdTag	tag
} with { variant (len) "LENGTHTO(tag)" }

type set of IpaCcmGetPart IpaCcmIdGet;

type record IpaCcmRespPart {
	uint16_t	len,
	IpaCcmIdTag	tag,
	charstring	data
} with { variant (len) "LENGTHTO(data,tag)" }
type set of IpaCcmRespPart IpaCcmIdResp;

type union IpaCcmUnion {
	IpaCcmIdGet	get,
	IpaCcmIdResp	resp,
	octetstring	other
}

type record PDU_IPA_CCM {
	IpaCcmMsgtype	msg_type,
	IpaCcmUnion	u optional
} with { variant (u) "CROSSTAG(
			get, msg_type = IPAC_MSGT_ID_GET;
			resp, msg_type = IPAC_MSGT_ID_RESP;
			other, OTHERWISE;
	)" };


external function enc_PDU_IPA_CCM(in PDU_IPA_CCM pdu) return octetstring
with { extension "prototype(convert)"
       extension "encode(RAW)"
     }

external function dec_PDU_IPA_CCM(in octetstring stream) return PDU_IPA_CCM
with { extension "prototype(convert)"
       extension "decode(RAW)"
     }


} with { encode "RAW" }
