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-2018 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 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" }
