/* (C) 2018 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 SCCP_Templates {

import from General_Types all;

import from SCCP_Types all;
import from SCCPasp_Types all;
import from SCCP_Emulation all;

/* construct a SCCP_PAR_Address with just PC + SSN and no GT */
template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn, octetstring sio,
							charstring sccp_srv_type) := {
	addressIndicator := {
		pointCodeIndic := '1'B,
		ssnIndicator := '1'B,
		globalTitleIndic := '0000'B,
		routingIndicator := '1'B
	},
	signPointCode := SCCP_SPC_int2bit(pc, sccp_srv_type, sio),
	subsystemNumber := ssn,
	globalTitle := omit
}

/* construct a SCCP_PAR_Address with only GT */
template (value) SCCP_PAR_Address ts_SccpAddr_GT(hexstring global_address) := {
	addressIndicator := {
		pointCodeIndic := '0'B,
		ssnIndicator := '0'B,
		globalTitleIndic := '0001'B, // NAI only
		routingIndicator := cg_route_on_GT // route on GT
	},
	signPointCode := omit,
	subsystemNumber := omit,
	globalTitle := {
		gti0001 := {
			natureOfAddress := '0000011'B,
			oddeven := '0'B,
			globalTitleAddress := global_address
		}
	}
}

/* construct a SCCP_PAR_Address with PC + SSN and GT */
template (value) SCCP_PAR_Address ts_SccpAddr_PC_GT(integer pc, octetstring sio,
						    charstring sccp_srv_type, hexstring gt_addr) := {
	addressIndicator := {
		pointCodeIndic := '1'B,
		ssnIndicator := '0'B,
		globalTitleIndic := '0001'B, // NAI only
		routingIndicator := cg_route_on_GT // route on GT
	},
	signPointCode := SCCP_SPC_int2bit(pc, sccp_srv_type, sio),
	subsystemNumber := omit,
	globalTitle := {
		gti0001 := {
			natureOfAddress := '0000011'B,
			oddeven := '0'B,
			globalTitleAddress := gt_addr
		}
	}
}

/* connection oriented SCCP */
const SCCP_param_ProtocolClass c_class2 := { class:='0010'B, messageHandling:='0000'B };//class 2

function ts_SCCP_CR(OCT3 source_lref, SCCP_PAR_Address calling, SCCP_PAR_Address called)
return template (value) PDU_SCCP {
	var SCCP_param_CPartyAddressEnc calling_enc := ConvertASPAddressToEncodedAddress_itu(calling);

	var template (value) PDU_SCCP ret := {
		connrequest := {
			messageType := cr,
			sourceLocRef := source_lref,
			protClass := c_class2,
			pointer1 := 2,
			pointer2 := 0, /* overwritten */
			calledPAddress := ConvertASPAddressToEncodedAddress_itu(called),
			optionalPart := {
				credit := omit,
				callingPAddress := {
					paramName := con_SCCP_cgPA,
					paramLength := calling_enc.paramLength, /* overwritten */
					addr := calling_enc.addr
				},
				data := omit,
				hopCounter := omit,
				importance := omit
			},
			eop := { paramName:= con_SCCP_eop }
		}
	}
	return ret;
}

template (present) PDU_SCCP tr_SCCP_CC(template (present) OCT3 source_lref,
				       template (present) OCT3 dest_lref) := {
	connconfirm := {
		messageType := cc,
		destLocRef := dest_lref,
		sourceLocRef := source_lref,
		protClass := c_class2,
		pointer1 := ?,
		optionalPart := *,
		eop := *
	}
}

template (value) PDU_SCCP ts_SCCP_UDT(SCCP_PAR_Address calling, SCCP_PAR_Address called,
				      template (value) octetstring data,
				      template (value) BIT4 msg_hdl := '0000'B) := {
	unitdata := {
		messageType := udt,
		protClass := {'0000'B, msg_hdl},
		pointer1 := 0,  /* overwritten */
		pointer2 := 0,  /* overwritten */
		pointer3 := 0,  /* overwritten */
		calledPAddress := ConvertASPAddressToEncodedAddress_itu(called),
		callingPAddress := ConvertASPAddressToEncodedAddress_itu(calling),
		data := {
			paramLength := 0,
			data := data
		}
	}
}

template PDU_SCCP tr_SCCP_UDT(SCCP_PAR_Address calling, SCCP_PAR_Address called,
			      template octetstring data := ?,
			      template BIT4 msg_hdl := '0000'B) := {
	unitdata := {
		messageType := udt,
		protClass := {'0000'B, msg_hdl},
		pointer1 := ?,
		pointer2 := ?,
		pointer3 := ?,
		calledPAddress := ConvertASPAddressToEncodedAddress_itu(called),
		callingPAddress := ConvertASPAddressToEncodedAddress_itu(calling),
		data := {
			paramLength := lengthof(data),
			data := data
		}
	}
}

template PDU_SCCP tr_SCCP_IT(template (present) OCT3 source_lref := ?,
			     template (present) OCT3 dest_lref := ?) := {
	inacttest := {
		messageType := it,
		destLocRef := dest_lref,
		sourceLocRef := source_lref,
		protClass := c_class2,
		sequencingSegmenting := {
			reserved := ?,
			p_s := ?,
			more := ?,
			pr := ?
		},
		credit := ?
	}
}

template PDU_SCCP ts_SCCP_IT(template (present) OCT3 source_lref,
			     template (present) OCT3 dest_lref) := {
	inacttest := {
		messageType := it,
		destLocRef := dest_lref,
		sourceLocRef := source_lref,
		protClass := c_class2,
		/* rfc3868 3.3.11: sequencing and credit are ignored with class2 */
		sequencingSegmenting := {
			reserved := '0'B,
			p_s := '0000000'B,
			more := '0'B,
			pr := '0000000'B
		},
		credit := '00'O
	}
}

template PDU_SCCP tr_SCCP_RLSD(template (present) OCT3 source_lref := ?,
			       template (present) OCT3 dest_lref := ?,
			       template (present) SCCP_param_ReleaseCause relcause := ?) := {
	released := {
		messageType := rlsd,
		destLocRef := dest_lref,
		sourceLocRef := source_lref,
		releaseCause := relcause,
		pointer1 := ?,
		optionalPart := *,
		eop := *
	}
}

template PDU_SCCP ts_SCCP_RLC(OCT3 source_lref, OCT3 dest_lref) := {
	relcomp := {
		messageType := rlc,
		destLocRef := dest_lref,
		sourceLocRef := source_lref
	}
}

template PDU_SCCP tr_SCCP_RLC(template (present) OCT3 source_lref := ?,
			      template (present) OCT3 dest_lref := ?) := {
	relcomp := {
		messageType := rlc,
		destLocRef := dest_lref,
		sourceLocRef := source_lref
	}
}


}
