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),
	IPAC_PROTO_EXT_RSPRO	('07'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,
	octetstring	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" }
