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.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

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


}
