module RANAP_CodecPort {

/* Simple RANAP Codec Port, translating between raw SCCP primitives with
 * octetstring payload towards the SCCP provider, and RANAP-SCCP primitives
 * which carry the decoded RANAP data types as payload.
 *
 * (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.
 */

import from General_Types all;
import from Osmocom_Types all;

import from SCCPasp_Types all;
import from SCCP_Types all;

import from RANAP_PDU_Descriptions all;
import from RANAP_Types all;

type record RANAP_N_CONNECT_req
{
   SCCP_PAR_Address                 calledAddress,
   SCCP_PAR_Address                 callingAddress     optional,
   SCCP_PAR_Expedited_Data_Sel	    expeditedDataSel   optional,
   SCCP_PAR_Quality_Of_Service      qualityOfService   optional,
   RANAP_PDU                        userData           optional,
   SCCP_PAR_Connection_Id           connectionId       optional,
   SCCP_PAR_Importance              importance         optional
}

template RANAP_N_CONNECT_req ts_RANAP_CONNECT_req(SCCP_PAR_Address called,
						 SCCP_PAR_Address calling,
						 SCCP_PAR_Connection_Id conn_id,
						 template RANAP_PDU ranap := omit) := {
	calledAddress := called,
	callingAddress := calling,
	expeditedDataSel := omit,
	qualityOfService := omit,
	userData := ranap,
	connectionId := conn_id,
	importance := omit
}

type record RANAP_N_CONNECT_ind
{
   SCCP_PAR_Address                 calledAddress,
   SCCP_PAR_Address                 callingAddress     optional,
   SCCP_PAR_Quality_Of_Service      qualityOfService   optional,
   RANAP_PDU                        userData           optional,
   SCCP_PAR_Connection_Id           connectionId       optional,
   SCCP_PAR_Importance              importance         optional
}

template RANAP_N_CONNECT_ind tr_RANAP_CONNECT_ind(template SCCP_PAR_Address called,
						 template SCCP_PAR_Address calling,
						 template RANAP_PDU payload := *) := {
	calledAddress := called,
	callingAddress := calling,
	qualityOfService := *,
	userData := payload,
	connectionId := *,
	importance := *
}

type record RANAP_N_CONNECT_res
{
   SCCP_PAR_Address			respondingAddress optional,
   SCCP_PAR_Expedited_Data_Sel		expeditedDataSel  optional,
   SCCP_PAR_Quality_Of_Service		qualityOfService  optional,
   RANAP_PDU				userData          optional,
   SCCP_PAR_Connection_Id		connectionId      optional,
   SCCP_PAR_Importance 			importance        optional
}

template RANAP_N_CONNECT_res ts_RANAP_CONNECT_res(SCCP_PAR_Connection_Id conn_id,
						 template RANAP_PDU ranap := omit) := {
	respondingAddress := omit,
	expeditedDataSel := omit,
	qualityOfService := omit,
	userData := ranap,
	connectionId := conn_id,
	importance := omit
}

type record RANAP_N_CONNECT_cfm
{
  SCCP_PAR_Address              respondingAddress optional,
  SCCP_PAR_Quality_Of_Service   qualityOfService  optional,
  RANAP_PDU                     userData           optional,
  SCCP_PAR_Connection_Id        connectionId      optional,
  SCCP_PAR_Importance           importance        optional
}

template RANAP_N_CONNECT_cfm tr_RANAP_CONNECT_cfm(template SCCP_PAR_Connection_Id conn_id,
						  template RANAP_PDU ranap := *) := {
	respondingAddress := *,
	qualityOfService := *,
	userData := ranap,
	connectionId := conn_id,
	importance := *
}

type record RANAP_N_DATA_req
{
  RANAP_PDU               userData               ,
  SCCP_PAR_Connection_Id  connectionId  optional ,
  SCCP_PAR_Importance     importance    optional
}

template RANAP_N_DATA_req ts_RANAP_DATA_req(SCCP_PAR_Connection_Id conn_id,
					    template RANAP_PDU ranap) := {
	userData := ranap,
	connectionId := conn_id,
	importance := omit
}


type record RANAP_N_DATA_ind
{
  RANAP_PDU               userData               ,
  SCCP_PAR_Connection_Id  connectionId optional  ,
  SCCP_PAR_Importance     importance   optional
}

template RANAP_N_DATA_ind tr_RANAP_DATA_ind(SCCP_PAR_Connection_Id conn_id,
					    template RANAP_PDU ranap := *) := {
	userData := ranap,
	connectionId := conn_id,
	importance := *
}


type record RANAP_N_DISCONNECT_req
{
  SCCP_PAR_Address         respondingAddress  optional,
  SCCP_PAR_Reason          reason                      ,
  RANAP_PDU                userData           optional ,
  SCCP_PAR_Connection_Id   connectionId       optional ,
  SCCP_PAR_Importance      importance         optional
}

template RANAP_N_DISCONNECT_req ts_RANAP_DISC_req(SCCP_PAR_Connection_Id conn_id,
						  template SCCP_PAR_Reason reason,
						  template RANAP_PDU ranap := omit) := {
	respondingAddress := omit,
	reason := reason,
	userData := ranap,
	connectionId := conn_id,
	importance := omit
}


type record RANAP_N_DISCONNECT_ind
{
  SCCP_PAR_Originator     originator                  ,
  SCCP_PAR_Address        respondingAddress  optional ,
  SCCP_PAR_Reason         reason                      ,
  RANAP_PDU               userData           optional ,
  SCCP_PAR_Connection_Id  connectionId       optional ,
  SCCP_PAR_Importance     importance         optional
}

template RANAP_N_DISCONNECT_ind tr_RANAP_DISC_ind(template SCCP_PAR_Connection_Id conn_id,
						  template SCCP_PAR_Originator originator,
						  template SCCP_PAR_Reason reason,
						  template RANAP_PDU ranap := *) := {
	originator := originator,
	respondingAddress:= *,
	reason := reason,
	userData := ranap,
	connectionId := conn_id,
	importance := *
}

type record RANAP_N_UNITDATA_req
{
  SCCP_PAR_Address          calledAddress               ,
  SCCP_PAR_Address          callingAddress              ,
  SCCP_PAR_Sequence_Control sequenceControl    optional ,
  SCCP_PAR_Return_Option    returnOption       optional ,
  RANAP_PDU                 userData                    ,
  SCCP_PAR_Importance       importance         optional
 }

template RANAP_N_UNITDATA_req ts_RANAP_UNITDATA_req(SCCP_PAR_Address called, SCCP_PAR_Address calling, template RANAP_PDU payload) := {
	calledAddress := called,
	callingAddress := calling,
	sequenceControl := omit,
	returnOption := omit,
	userData := payload,
	importance := omit
}

type record RANAP_N_UNITDATA_ind
{
  SCCP_PAR_Address           calledAddress              ,
  SCCP_PAR_Address           callingAddress             ,
  SCCP_PAR_Sequence_Control  sequenceControl  optional  ,
  SCCP_PAR_Return_Option     returnOption     optional  ,
  RANAP_PDU                  userData                   ,
  SCCP_PAR_Importance        importance       optional
}

template RANAP_N_UNITDATA_ind tr_RANAP_UNITDATA_ind(template SCCP_PAR_Address called, template SCCP_PAR_Address calling, template RANAP_PDU payload) := {
	calledAddress := called,
	callingAddress := calling,
	sequenceControl := *,
	returnOption := *,
	userData := payload,
	importance := *
}

type record RANAP_N_NOTICE_ind
{
  SCCP_PAR_Address               calledAddress            ,
  SCCP_PAR_Address               callingAddress           ,
  SCCP_PAR_Reason_For_Return     reasonForReturn          ,
  RANAP_PDU                      userData                 ,
  SCCP_PAR_Importance            importance       optional
}



private function f_dec_ConnectInd(in ASP_SCCP_N_CONNECT_ind pin, out RANAP_N_CONNECT_ind pout) {
	pout.calledAddress := pin.calledAddress;
	pout.callingAddress := pin.callingAddress;
	pout.qualityOfService := pin.qualityOfService;
	if (ispresent(pin.userData)) {
		pout.userData := dec_RANAP_PDU(pin.userData);
	} else {
		pout.userData := omit;
	}
	pout.connectionId := pin.connectionId;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_dec_ConnectCfm(in ASP_SCCP_N_CONNECT_cfm pin, out RANAP_N_CONNECT_cfm pout) {
	pout.respondingAddress := pin.respondingAddress;
	pout.qualityOfService := pin.qualityOfService;
	if (ispresent(pin.userData)) {
		pout.userData := dec_RANAP_PDU(pin.userData);
	} else {
		pout.userData := omit;
	}
	pout.connectionId := pin.connectionId;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_dec_DataInd(in ASP_SCCP_N_DATA_ind pin, out RANAP_N_DATA_ind pout) {
	pout.userData := dec_RANAP_PDU(pin.userData);
	pout.connectionId := pin.connectionId;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_dec_DisconnectInd(in ASP_SCCP_N_DISCONNECT_ind pin, out RANAP_N_DISCONNECT_ind pout) {
	pout.originator := pin.originator;
	pout.respondingAddress := pin.respondingAddress;
	pout.reason := pin.reason;
	if (ispresent(pin.userData)) {
		pout.userData := dec_RANAP_PDU(pin.userData);
	} else {
		pout.userData := omit;
	}
	pout.connectionId := pin.connectionId;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_dec_UnitdataInd(in ASP_SCCP_N_UNITDATA_ind pin, out RANAP_N_UNITDATA_ind pout) {
	pout.calledAddress := pin.calledAddress;
	pout.callingAddress := pin.callingAddress;
	pout.sequenceControl := pin.sequenceControl;
	pout.returnOption := pin.returnOption;
	pout.userData := dec_RANAP_PDU(pin.userData);
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_dec_NoticeInd(in ASP_SCCP_N_NOTICE_ind pin, out RANAP_N_NOTICE_ind pout) {
	pout.calledAddress := pin.calledAddress;
	pout.callingAddress := pin.callingAddress;
	pout.reasonForReturn := pin.reasonForReturn;
	pout.userData := dec_RANAP_PDU(pin.userData);
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }



private function f_enc_ConnectReq(in RANAP_N_CONNECT_req pin, out ASP_SCCP_N_CONNECT_req pout) {
	pout.calledAddress := pin.calledAddress;
	pout.callingAddress := pin.callingAddress;
	pout.expeditedDataSel := pin.expeditedDataSel;
	pout.qualityOfService := pin.qualityOfService;
	if (ispresent(pin.userData)) {
		pout.userData := enc_RANAP_PDU(pin.userData);
	} else {
		pout.userData := omit;
	}
	pout.connectionId := pin.connectionId;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_enc_ConnectRes(in RANAP_N_CONNECT_res pin, out ASP_SCCP_N_CONNECT_res pout) {
	pout.respondingAddress := pin.respondingAddress;
	pout.expeditedDataSel := pin.expeditedDataSel;
	pout.qualityOfService := pin.qualityOfService;
	if (ispresent(pin.userData)) {
		pout.userData := enc_RANAP_PDU(pin.userData);
	} else {
		pout.userData := omit;
	}
	pout.connectionId := pin.connectionId;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_enc_DataReq(in RANAP_N_DATA_req pin, out ASP_SCCP_N_DATA_req pout) {
	pout.userData := enc_RANAP_PDU(pin.userData);
	pout.connectionId := pin.connectionId;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_enc_DisconnectReq(in RANAP_N_DISCONNECT_req pin, out ASP_SCCP_N_DISCONNECT_req pout) {
	pout.respondingAddress := pin.respondingAddress;
	pout.reason := pin.reason;
	if (ispresent(pin.userData)) {
		pout.userData := enc_RANAP_PDU(pin.userData);
	} else {
		pout.userData := omit;
	}
	pout.connectionId := pin.connectionId;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_enc_UnitdataReq(in RANAP_N_UNITDATA_req pin, out ASP_SCCP_N_UNITDATA_req pout) {
	pout.calledAddress := pin.calledAddress;
	pout.callingAddress := pin.callingAddress;
	pout.userData := enc_RANAP_PDU(pin.userData);
	pout.sequenceControl := pin.sequenceControl;
	pout.returnOption := pin.returnOption;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }


/*
type port RANAP_CODEC_PT message map to SCCPasp_PT {
	out	RANAP_N_CONNECT_req to ASP_SCCP_N_CONNECT_req with f_enc_ConnectReq(),
		RANAP_N_CONNECT_res to ASP_SCCP_N_CONNECT_res with f_enc_ConnectRes(),
		RANAP_N_DATA_req to ASP_SCCP_N_DATA_req with f_enc_DataReq(),
		RANAP_N_DISCONNECT_req to ASP_SCCP_N_DISCONNECT_req with f_enc_DisconnectReq(),
		RANAP_N_UNITDATA_req to ASP_SCCP_N_UNITDATA_req with f_enc_UnitdataReq(),
		ASP_SCCP_N_RESET_req, ASP_SCCP_N_RESET_resp;

	in	RANAP_N_CONNECT_ind from ASP_SCCP_N_CONNECT_ind with f_dec_ConnectInd(),
		RANAP_N_CONNECT_cfm from ASP_SCCP_N_CONNECT_cfm with f_dec_ConnectCfm(),
		RANAP_N_DATA_ind from ASP_SCCP_N_DATA_ind with f_dec_DataInd(),
		RANAP_N_DISCONNECT_ind from ASP_SCCP_N_DISCONNECT_ind with f_dec_DisconnectInd(),
		RANAP_N_UNITDATA_ind from ASP_SCCP_N_UNITDATA_ind with f_dec_UnitdataInd(),
		RANAP_N_NOTICE_ind from ASP_SCCP_N_NOTICE_ind with f_dec_NoticeInd(),
		ASP_SCCP_N_STATE_ind, ASP_SCCP_N_RESET_ind, ASP_SCCP_N_RESET_cfm;
} with {extension "internal"}
*/

type port RANAP_CODEC_PT message {
	out	RANAP_N_CONNECT_req,
		RANAP_N_CONNECT_res,
		RANAP_N_DATA_req,
		RANAP_N_DISCONNECT_req,
		RANAP_N_UNITDATA_req,
		ASP_SCCP_N_RESET_req;
	in	RANAP_N_CONNECT_ind,
		RANAP_N_CONNECT_cfm,
		RANAP_N_DATA_ind,
		RANAP_N_DISCONNECT_ind,
		RANAP_N_UNITDATA_ind,
		RANAP_N_NOTICE_ind,
		ASP_SCCP_N_RESET_ind,
		ASP_SCCP_N_RESET_cfm,
		ASP_SCCP_N_STATE_ind;
} with { extension "internal user SCCPasp_PT
	out(RANAP_N_CONNECT_req -> ASP_SCCP_N_CONNECT_req: function(f_enc_ConnectReq);
	    RANAP_N_CONNECT_res -> ASP_SCCP_N_CONNECT_res: function(f_enc_ConnectRes);
	    RANAP_N_DATA_req -> ASP_SCCP_N_DATA_req: function(f_enc_DataReq);
	    RANAP_N_DISCONNECT_req -> ASP_SCCP_N_DISCONNECT_req: function(f_enc_DisconnectReq);
	    RANAP_N_UNITDATA_req -> ASP_SCCP_N_UNITDATA_req: function(f_enc_UnitdataReq);
	    ASP_SCCP_N_RESET_req -> ASP_SCCP_N_RESET_req: simple)
	in(ASP_SCCP_N_CONNECT_ind -> RANAP_N_CONNECT_ind: function(f_dec_ConnectInd);
	   ASP_SCCP_N_CONNECT_cfm -> RANAP_N_CONNECT_cfm: function(f_dec_ConnectCfm);
	   ASP_SCCP_N_DATA_ind -> RANAP_N_DATA_ind: function(f_dec_DataInd);
	   ASP_SCCP_N_DISCONNECT_ind -> RANAP_N_DISCONNECT_ind: function(f_dec_DisconnectInd);
	   ASP_SCCP_N_UNITDATA_ind -> RANAP_N_UNITDATA_ind: function(f_dec_UnitdataInd);
	   ASP_SCCP_N_NOTICE_ind -> RANAP_N_NOTICE_ind: function(f_dec_NoticeInd);
	   ASP_SCCP_N_RESET_ind -> ASP_SCCP_N_RESET_ind: simple;
	   ASP_SCCP_N_RESET_cfm -> ASP_SCCP_N_RESET_cfm: simple;
	   ASP_SCCP_N_STATE_ind -> ASP_SCCP_N_STATE_ind: simple)"
}


}
