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


}
