/* IPA Osmo Extension: TCAP_ROUTING, used to set up TCAP routes in osmo-stp.
 * (C) 2025 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * 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
 */

module IPA_EXT_TCAP_ROUTING {

import from General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;

type enumerated IPA_EXT_TCAP_ROUTING_MsgType {
	IPA_EXT_TCAP_ROUTING_MSG_TID_ADD_RANGE	('01'O),
	IPA_EXT_TCAP_ROUTING_MSG_TID_ACK	('02'O),
	IPA_EXT_TCAP_ROUTING_MSG_TID_NACK	('03'O)
} with { variant "FIELDLENGTH(8)" };

type record IPA_EXT_TCAP_ROUTING_Hdr {
	IPA_EXT_TCAP_ROUTING_MsgType msg_type,
	uint32_t		seq_nr
} with { variant "" };

const uint8_t IPA_EXT_TCAP_ROUTING_SSN_WILDCARD  := 0;
const uint32_t IPA_EXT_TCAP_ROUTING_PC_WILDCARD  := 4294967295;

type record IPA_EXT_TCAP_ROUTING_ADD_RANGE {
	uint32_t tid_start,
	uint32_t tid_end,
	uint32_t pc,
	uint8_t ssn
} with { variant "" };

type record IPA_EXT_TCAP_ROUTING_ACK {
} with { variant "" };

type record IPA_EXT_TCAP_ROUTING_NACK {
	uint8_t cause
} with { variant "" };

type union IPA_EXT_TCAP_ROUTING_MsgUnion {
	IPA_EXT_TCAP_ROUTING_ADD_RANGE		add_range,
	IPA_EXT_TCAP_ROUTING_ACK		ack,
	IPA_EXT_TCAP_ROUTING_NACK		nack
} with { variant "" };

type record IPA_EXT_TCAP_ROUTING_Message {
	IPA_EXT_TCAP_ROUTING_MsgType msg_type,
	uint32_t seq_nr,
	IPA_EXT_TCAP_ROUTING_MsgUnion	u
} with { variant (u) "CROSSTAG(add_range, 	msg_type = IPA_EXT_TCAP_ROUTING_MSG_TID_ADD_RANGE;
			       ack,		msg_type = IPA_EXT_TCAP_ROUTING_MSG_TID_ACK;
			       nack,		msg_type = IPA_EXT_TCAP_ROUTING_MSG_TID_NACK)"
};

external function enc_IPA_EXT_TCAP_ROUTING_Message(in IPA_EXT_TCAP_ROUTING_Message pdu) return octetstring
	with { extension "prototype(convert) encode(RAW)" };
external function dec_IPA_EXT_TCAP_ROUTING_Message(in octetstring stream) return IPA_EXT_TCAP_ROUTING_Message
	with { extension "prototype(convert) decode(RAW)" };

/* Generic template for matching messages by type */
template (present) IPA_EXT_TCAP_ROUTING_Message
tr_IPA_EXT_TCAP_ROUTING_Message(template (present) IPA_EXT_TCAP_ROUTING_MsgType msg_type := ?) := {
	msg_type := msg_type,
	seq_nr := ?,
	u := ?
}

template (present) IPA_EXT_TCAP_ROUTING_Message
tr_IPA_EXT_TCAP_ROUTING_ACK := tr_IPA_EXT_TCAP_ROUTING_Message(IPA_EXT_TCAP_ROUTING_MSG_TID_ACK);

template (present) IPA_EXT_TCAP_ROUTING_Message
tr_IPA_EXT_TCAP_ROUTING_NACK := tr_IPA_EXT_TCAP_ROUTING_Message(IPA_EXT_TCAP_ROUTING_MSG_TID_NACK);

template (value) IPA_EXT_TCAP_ROUTING_Message
ts_IPA_EXT_TCAP_ROUTING_ADD_RANGE(template (value) uint32_t seq_nr,
				  template (value) uint32_t tid_start,
				  template (value) uint32_t tid_end,
				  template (value) uint32_t pc,
				  template (value) uint8_t ssn) := {
	msg_type := IPA_EXT_TCAP_ROUTING_MSG_TID_ADD_RANGE,
	seq_nr := seq_nr,
	u := {
		add_range := {
			tid_start := tid_start,
			tid_end := tid_end,
			pc := pc,
			ssn := ssn
		}
	}
}


} with { encode "RAW" };
