module BSSAP_CodecPort {

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

type record BSSAP_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,
   PDU_BSSAP                        userData           optional,
   SCCP_PAR_Connection_Id           connectionId       optional,
   SCCP_PAR_Importance              importance         optional
}

template BSSAP_N_CONNECT_req ts_BSSAP_CONNECT_req(SCCP_PAR_Address called,
						 SCCP_PAR_Address calling,
						 SCCP_PAR_Connection_Id conn_id,
						 template PDU_BSSAP bssap := omit) := {
	calledAddress := called,
	callingAddress := calling,
	expeditedDataSel := omit,
	qualityOfService := omit,
	userData := bssap,
	connectionId := conn_id,
	importance := omit
}

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

template BSSAP_N_CONNECT_ind tr_BSSAP_CONNECT_ind(template SCCP_PAR_Address called,
						 template SCCP_PAR_Address calling,
						 template PDU_BSSAP payload := *) := {
	calledAddress := called,
	callingAddress := calling,
	qualityOfService := *,
	userData := payload,
	connectionId := *,
	importance := *
}

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

template BSSAP_N_CONNECT_res ts_BSSAP_CONNECT_res(SCCP_PAR_Connection_Id conn_id,
						 template PDU_BSSAP bssap := omit) := {
	respondingAddress := omit,
	expeditedDataSel := omit,
	qualityOfService := omit,
	userData := bssap,
	connectionId := conn_id,
	importance := omit
}

type record BSSAP_N_CONNECT_cfm
{
  SCCP_PAR_Address              respondingAddress optional,
  SCCP_PAR_Quality_Of_Service   qualityOfService  optional,
  PDU_BSSAP                     userData           optional,
  SCCP_PAR_Connection_Id        connectionId      optional,
  SCCP_PAR_Importance           importance        optional
}

template BSSAP_N_CONNECT_cfm tr_BSSAP_CONNECT_cfm(template SCCP_PAR_Connection_Id conn_id,
						  template PDU_BSSAP bssap := *) := {
	respondingAddress := *,
	qualityOfService := *,
	userData := bssap,
	connectionId := conn_id,
	importance := *
}

type record BSSAP_N_DATA_req
{
  PDU_BSSAP               userData               ,
  SCCP_PAR_Connection_Id  connectionId  optional ,
  SCCP_PAR_Importance     importance    optional
}

template BSSAP_N_DATA_req ts_BSSAP_DATA_req(SCCP_PAR_Connection_Id conn_id,
					    template PDU_BSSAP bssap) := {
	userData := bssap,
	connectionId := conn_id,
	importance := omit
}


type record BSSAP_N_DATA_ind
{
  PDU_BSSAP               userData               ,
  SCCP_PAR_Connection_Id  connectionId optional  ,
  SCCP_PAR_Importance     importance   optional
}

template BSSAP_N_DATA_ind tr_BSSAP_DATA_ind(SCCP_PAR_Connection_Id conn_id,
					    template PDU_BSSAP bssap := *) := {
	userData := bssap,
	connectionId := conn_id,
	importance := *
}


type record BSSAP_N_DISCONNECT_req
{
  SCCP_PAR_Address         respondingAddress  optional,
  SCCP_PAR_Reason          reason                      ,
  PDU_BSSAP                userData           optional ,
  SCCP_PAR_Connection_Id   connectionId       optional ,
  SCCP_PAR_Importance      importance         optional
}

template BSSAP_N_DISCONNECT_req ts_BSSAP_DISC_req(SCCP_PAR_Connection_Id conn_id,
						  template SCCP_PAR_Reason reason,
						  template PDU_BSSAP bssap := omit) := {
	respondingAddress := omit,
	reason := reason,
	userData := bssap,
	connectionId := conn_id,
	importance := omit
}


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

template BSSAP_N_DISCONNECT_ind tr_BSSAP_DISC_ind(template SCCP_PAR_Connection_Id conn_id,
						  template SCCP_PAR_Originator originator,
						  template SCCP_PAR_Reason reason,
						  template PDU_BSSAP bssap := *) := {
	originator := originator,
	respondingAddress:= *,
	reason := reason,
	userData := bssap,
	connectionId := conn_id,
	importance := *
}

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

template BSSAP_N_UNITDATA_req ts_BSSAP_UNITDATA_req(SCCP_PAR_Address called, SCCP_PAR_Address calling, template PDU_BSSAP payload) := {
	calledAddress := called,
	callingAddress := calling,
	sequenceControl := omit,
	returnOption := omit,
	userData := payload,
	importance := omit
}

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

template BSSAP_N_UNITDATA_ind tr_BSSAP_UNITDATA_ind(template SCCP_PAR_Address called, template SCCP_PAR_Address calling, template PDU_BSSAP payload) := {
	calledAddress := called,
	callingAddress := calling,
	sequenceControl := *,
	returnOption := *,
	userData := payload,
	importance := *
}

type record BSSAP_N_NOTICE_ind
{
  SCCP_PAR_Address               calledAddress            ,
  SCCP_PAR_Address               callingAddress           ,
  SCCP_PAR_Reason_For_Return     reasonForReturn          ,
  PDU_BSSAP                      userData                 ,
  SCCP_PAR_Importance            importance       optional
}



private function f_dec_ConnectInd(in ASP_SCCP_N_CONNECT_ind pin, out BSSAP_N_CONNECT_ind pout) {
	pout.calledAddress := pin.calledAddress;
	pout.callingAddress := pin.callingAddress;
	pout.qualityOfService := pin.qualityOfService;
	if (ispresent(pin.userData)) {
		pout.userData := dec_PDU_BSSAP(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 BSSAP_N_CONNECT_cfm pout) {
	pout.respondingAddress := pin.respondingAddress;
	pout.qualityOfService := pin.qualityOfService;
	if (ispresent(pin.userData)) {
		pout.userData := dec_PDU_BSSAP(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 BSSAP_N_DATA_ind pout) {
	pout.userData := dec_PDU_BSSAP(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 BSSAP_N_DISCONNECT_ind pout) {
	pout.originator := pin.originator;
	pout.respondingAddress := pin.respondingAddress;
	pout.reason := pin.reason;
	if (ispresent(pin.userData)) {
		pout.userData := dec_PDU_BSSAP(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 BSSAP_N_UNITDATA_ind pout) {
	pout.calledAddress := pin.calledAddress;
	pout.callingAddress := pin.callingAddress;
	pout.sequenceControl := pin.sequenceControl;
	pout.returnOption := pin.returnOption;
	pout.userData := dec_PDU_BSSAP(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 BSSAP_N_NOTICE_ind pout) {
	pout.calledAddress := pin.calledAddress;
	pout.callingAddress := pin.callingAddress;
	pout.reasonForReturn := pin.reasonForReturn;
	pout.userData := dec_PDU_BSSAP(pin.userData);
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }



private function f_enc_ConnectReq(in BSSAP_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_PDU_BSSAP(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 BSSAP_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_PDU_BSSAP(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 BSSAP_N_DATA_req pin, out ASP_SCCP_N_DATA_req pout) {
	pout.userData := enc_PDU_BSSAP(pin.userData);
	pout.connectionId := pin.connectionId;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }

private function f_enc_DisconnectReq(in BSSAP_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_PDU_BSSAP(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 BSSAP_N_UNITDATA_req pin, out ASP_SCCP_N_UNITDATA_req pout) {
	pout.calledAddress := pin.calledAddress;
	pout.callingAddress := pin.callingAddress;
	pout.userData := enc_PDU_BSSAP(pin.userData);
	pout.sequenceControl := pin.sequenceControl;
	pout.returnOption := pin.returnOption;
	pout.importance := pin.importance;
	//port.setstate(0);
} with {extension "prototype(fast)" }


/* 
type port BSSAP_CODEC_PT message map to SCCPasp_PT {
	out	BSSAP_N_CONNECT_req to ASP_SCCP_N_CONNECT_req with f_enc_ConnectReq(),
		BSSAP_N_CONNECT_res to ASP_SCCP_N_CONNECT_res with f_enc_ConnectRes(),
		BSSAP_N_DATA_req to ASP_SCCP_N_DATA_req with f_enc_DataReq(),
		BSSAP_N_DISCONNECT_req to ASP_SCCP_N_DISCONNECT_req with f_enc_DisconnectReq(),
		BSSAP_N_UNITDATA_req to ASP_SCCP_N_UNITDATA_req with f_enc_UnitdataReq(),
		ASP_SCCP_N_RESET_req, ASP_SCCP_N_RESET_resp;

	in	BSSAP_N_CONNECT_ind from ASP_SCCP_N_CONNECT_ind with f_dec_ConnectInd(),
		BSSAP_N_CONNECT_cfm from ASP_SCCP_N_CONNECT_cfm with f_dec_ConnectCfm(),
		BSSAP_N_DATA_ind from ASP_SCCP_N_DATA_ind with f_dec_DataInd(),
		BSSAP_N_DISCONNECT_ind from ASP_SCCP_N_DISCONNECT_ind with f_dec_DisconnectInd(),
		BSSAP_N_UNITDATA_ind from ASP_SCCP_N_UNITDATA_ind with f_dec_UnitdataInd(),
		BSSAP_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 BSSAP_CODEC_PT message {
	out	BSSAP_N_CONNECT_req,
		BSSAP_N_CONNECT_res,
		BSSAP_N_DATA_req,
		BSSAP_N_DISCONNECT_req,
		BSSAP_N_UNITDATA_req,
		ASP_SCCP_N_RESET_req;
	in	BSSAP_N_CONNECT_ind,
		BSSAP_N_CONNECT_cfm,
		BSSAP_N_DATA_ind,
		BSSAP_N_DISCONNECT_ind,
		BSSAP_N_UNITDATA_ind,
		BSSAP_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(BSSAP_N_CONNECT_req -> ASP_SCCP_N_CONNECT_req: function(f_enc_ConnectReq);
	    BSSAP_N_CONNECT_res -> ASP_SCCP_N_CONNECT_res: function(f_enc_ConnectRes);
	    BSSAP_N_DATA_req -> ASP_SCCP_N_DATA_req: function(f_enc_DataReq);
	    BSSAP_N_DISCONNECT_req -> ASP_SCCP_N_DISCONNECT_req: function(f_enc_DisconnectReq);
	    BSSAP_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 -> BSSAP_N_CONNECT_ind: function(f_dec_ConnectInd);
	   ASP_SCCP_N_CONNECT_cfm -> BSSAP_N_CONNECT_cfm: function(f_dec_ConnectCfm);
	   ASP_SCCP_N_DATA_ind -> BSSAP_N_DATA_ind: function(f_dec_DataInd);
	   ASP_SCCP_N_DISCONNECT_ind -> BSSAP_N_DISCONNECT_ind: function(f_dec_DisconnectInd);
	   ASP_SCCP_N_UNITDATA_ind -> BSSAP_N_UNITDATA_ind: function(f_dec_UnitdataInd);
	   ASP_SCCP_N_NOTICE_ind -> BSSAP_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)"
}


}
