module IPA_Emulation {

/* This module implements the IPA multiplex protocol on top of TCP, using the IPL4asp
 * test-port as provider.  It implements both client and server roles, as well was the CCM
 * handshake for establishing the identity of the client to the server.  It already knows
 * certain well-known sub-protocols such as A-bis RSL, MGCP and SCCP and transcodes messages
 * so the user can work with abstract data types rather than binary messages.  It handles
 * multiple packets inside one TCP segment */

import from IPA_Types all;
import from IPA_CodecPort all;
import from IPA_CodecPort_CtrlFunct all;
import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from MTP3asp_Types all;
import from MTP3asp_PortType all;
import from RSL_Types all;

import from MGCP_Types all;
import from GSUP_Types all;

import from Osmocom_CTRL_Types all;

modulepar {
	/* Use Osmocom extended IPA mux header */
	boolean mp_ipa_mgcp_uses_osmo_ext := true;
}

type enumerated IpaMode {
	IPA_MODE_CLIENT,
	IPA_MODE_SERVER
}

type record ASP_IPA_Unitdata {
	IpaStreamId	streamId,
	IpaExtStreamId	streamIdExt optional,
	octetstring	payload
}

type enumerated ASP_IPA_EventUpDown {
	ASP_IPA_EVENT_DOWN,
	ASP_IPA_EVENT_UP,
	ASP_IPA_EVENT_ID_ACK
}

/* an event indicating us whether or not a connection is physically up or down,
 * and whether we have received an ID_ACK */
type union ASP_IPA_Event {
	ASP_IPA_EventUpDown	up_down
}

template ASP_IPA_Event t_ASP_IPA_EVT_UD(ASP_IPA_EventUpDown ud) := {
	up_down := ud
}

template ASP_IPA_Unitdata t_ASP_IPA_UD(IpaStreamId sid, octetstring pl,
					template IpaExtStreamId esid := omit) := {
	streamId := sid,
	streamIdExt := esid,
	payload := pl
}

/* like ASP_IPA_Unitdata, but with RSL_Message abstract type instead of octetstring */
type record ASP_RSL_Unitdata {
	IpaStreamId	streamId,
	RSL_Message	rsl
};

template ASP_RSL_Unitdata ts_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
	streamId := sid,
	rsl := valueof(rsl)
}

template ASP_RSL_Unitdata tr_ASP_RSL_UD(IpaStreamId sid, template RSL_Message rsl) := {
	streamId := sid,
	rsl := rsl
}


template IpaStreamId t_IpaSidRSL := ( IPAC_PROTO_RSL_TRX0, IPAC_PROTO_RSL_TRX1,
				      IPAC_PROTO_RSL_TRX2, IPAC_PROTO_RSL_TRX3 );

/* Client port for general IPA messages, not further decoded */
type port IPA_SP_PT message {
	inout ASP_IPA_Unitdata, ASP_IPA_Event;
} with { extension "internal" }

/* Client port for MGCP inside IPA */
type port IPA_MGCP_PT message {
	inout MgcpCommand, MgcpResponse;
} with { extension "internal" }

/* Client port for A-bis RSL inside IPA */
type port IPA_RSL_PT message {
	inout ASP_RSL_Unitdata, ASP_IPA_Event;
} with { extension "internal" }

/* Client port for CTRL inside IPA */
type port IPA_CTRL_PT message {
	inout CtrlMessage, ASP_IPA_Event;
} with { extension "internal" }

/* Client port for CTRL inside IPA */
type port IPA_GSUP_PT message {
	inout GSUP_PDU, ASP_IPA_Event;
} with { extension "internal" }


type component IPA_Emulation_CT {
	/* down-facing port to IPA codec port */
	port IPA_CODEC_PT IPA_PORT;
	/* up-facing port to SCCP */
	port MTP3asp_SP_PT MTP3_SP_PORT;
	/* up-facing port for MGCP */
	port IPA_MGCP_PT IPA_MGCP_PORT;
	/* up-facing port for RSL */
	port IPA_RSL_PT IPA_RSL_PORT;
	/* up-facing port for CTRL */
	port IPA_CTRL_PT IPA_CTRL_PORT;
	/* up-facing port for GSUP */
	port IPA_GSUP_PT IPA_GSUP_PORT;

	/* up-facing port for other streams */
	port IPA_SP_PT IPA_SP_PORT;

	var boolean g_initialized := false;
	var ConnectionId g_ipa_conn_id := -1;
	/* Are we a BSC/MGW (truel) or MSC (false) */
	var boolean g_is_bsc_mgw;

	var IpaMode g_mode;
	var IPA_CCM_Parameters	g_ccm_pars := c_IPA_default_ccm_pars;
}

type record IPA_CCM_Parameters {
	charstring	ser_nr optional,
	charstring	name optional,
	charstring	location1 optional,
	charstring	location2 optional,
	charstring	equip_version optional,
	charstring	sw_version optional,
	charstring	ip_addr optional,
	charstring	mac_addr optional,
	charstring	unit_id optional,
	charstring	osmo_rand optional
}

const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
	ser_nr := "",
	name := "mahlzeit",
	location1 := "",
	location2 := "",
	equip_version := "",
	sw_version := "",
	ip_addr := "",
	mac_addr := "",
	unit_id := "0/1/2",
	osmo_rand := ""
};

/* Function to use to connect as client to a remote IPA Server */
function f_connect(charstring remote_host, PortNumber remote_port,
		   charstring local_host, PortNumber local_port,
		   IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
	var Result res;
	res := IPA_CodecPort_CtrlFunct.f_IPL4_connect(IPA_PORT, remote_host, remote_port,
						local_host, local_port, 0, { tcp:={} });
	g_ipa_conn_id := res.connId;
	g_ccm_pars := ccm_pars;
	g_is_bsc_mgw := true;
}

/* Function to use to bind to a local port as IPA server, accepting remote clients */
function f_bind(charstring local_host, PortNumber local_port,
		IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
	var Result res;
	res := IPA_CodecPort_CtrlFunct.f_IPL4_listen(IPA_PORT, 
						local_host, local_port, { tcp:={} });
	g_ipa_conn_id := res.connId;
	g_ccm_pars := ccm_pars;
	g_is_bsc_mgw := false;
}

template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
	sio := { '10'B, '00'B, '0011'B },
	opc := opc,
	dpc := 0,
	sls := 0,
	data := data
}


private template IpaCcmRespPart t_IdRespPart(IpaCcmIdTag tag, charstring payload) := {
	len := 0,	/* overwritten by codec */
	tag := tag,
	data := payload
}

private function f_send_IPA_EVT(template ASP_IPA_Event evt) runs on IPA_Emulation_CT {
	if (IPA_RSL_PORT.checkstate("Connected")) {
		IPA_RSL_PORT.send(evt);
	}
	if (IPA_CTRL_PORT.checkstate("Connected")) {
		IPA_CTRL_PORT.send(evt);
	}
	if (IPA_GSUP_PORT.checkstate("Connected")) {
		IPA_GSUP_PORT.send(evt);
	}
	/* FIXME: to other ports */
}

/* build IPA CCM ID RESP response from IPA CCM GET */
private function f_ccm_make_id_resp(PDU_IPA_CCM get) runs on IPA_Emulation_CT return PDU_IPA_CCM {
	var integer i;
	var PDU_IPA_CCM resp := {
		msg_type := IPAC_MSGT_ID_RESP,
		u := {
			resp := {}
		}
	}

	for (i := 0; i < sizeof(get.u.get); i := i + 1) {
		var IpaCcmIdTag tag := get.u.get[i].tag;
		var charstring foo;
		select (tag) {
			case (IPAC_IDTAG_SERNR) {
				foo := g_ccm_pars.ser_nr;
			}
			case (IPAC_IDTAG_UNITNAME) {
				foo := g_ccm_pars.name;
			}
			case (IPAC_IDTAG_LOCATION1) {
				foo := g_ccm_pars.location1;
			}
			case (IPAC_IDTAG_LOCATION2) {
				foo := g_ccm_pars.location2;
			}
			case (IPAC_IDTAG_EQUIPVERS) {
				foo := g_ccm_pars.equip_version;
			}
			case (IPAC_IDTAG_SWVERSION) {
				foo := g_ccm_pars.sw_version;
			}
			case (IPAC_IDTAG_IPADDR) {
				foo := g_ccm_pars.ip_addr;
			}
			case (IPAC_IDTAG_MACADDR) {
				foo := g_ccm_pars.mac_addr;
			}
			case (IPAC_IDTAG_UNIT) {
				foo := g_ccm_pars.unit_id;
			}
			case (IPAC_IDTAG_OSMO_RAND) {
				foo := g_ccm_pars.osmo_rand;
			}
			case else {
				foo := "unknown";
			}
		}
		resp.u.resp[sizeof(resp.u.resp)] := valueof(t_IdRespPart(tag, foo));
	}

	return resp;
}

/* transmit IPA CCM message */
private function f_ccm_tx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
	var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_CCM, enc_PDU_IPA_CCM(ccm)));
	log("CCM Tx:", ccm);
	IPA_PORT.send(ipa_tx);
}

template PDU_IPA_CCM ts_IPA_PONG := {
	msg_type := IPAC_MSGT_PONG,
	u := omit
}

template PDU_IPA_CCM ts_IPA_ACK := {
	msg_type := IPAC_MSGT_ID_ACK,
	u := omit
}

template PDU_IPA_CCM ts_IPA_ID_GET := {
	msg_type := IPAC_MSGT_ID_GET,
	u := {
		get := {
			{ 1, IPAC_IDTAG_UNITNAME }
		}
	}
}

/* receive IPA CCM message */
private function f_ccm_rx(PDU_IPA_CCM ccm) runs on IPA_Emulation_CT {
	select (ccm.msg_type) {
		case (IPAC_MSGT_PING) {
			f_ccm_tx(valueof(ts_IPA_PONG));
		}
		case (IPAC_MSGT_ID_ACK) {
			f_ccm_tx(valueof(ts_IPA_ACK));
		}
		case (IPAC_MSGT_ID_GET) {
			f_ccm_tx(f_ccm_make_id_resp(ccm));
		}
		case else {
			log("Unknown/unsupported IPA CCM message type", ccm);
		}
	}
}

private function f_to_asp(IPA_RecvFrom ipa_rx) return ASP_IPA_Unitdata {
	var ASP_IPA_Unitdata ret := {
		streamId := ipa_rx.streamId,
		streamIdExt := ipa_rx.streamIdExt,
		payload := ipa_rx.msg
	}
	return ret;
}

private function f_from_asp(ConnectionId connId, ASP_IPA_Unitdata ipa_tx) return IPA_Send {
	var IPA_Send ret := valueof(t_IPA_Send(connId, ipa_tx.streamId, ipa_tx.payload,
						ipa_tx.streamIdExt));
	return ret;
}

private function f_from_rsl(ConnectionId connId, ASP_RSL_Unitdata rsl_tx) return IPA_Send {
	var octetstring payload := enc_RSL_Message(rsl_tx.rsl);
	var IPA_Send ret := valueof(t_IPA_Send(connId, rsl_tx.streamId, payload));
	return ret;
}

/* main function to use for a client-side IPA implementation */
function main_client(charstring remote_host, PortNumber remote_port,
		     charstring local_host, PortNumber local_port,
		     IPA_CCM_Parameters ccm_pars := c_IPA_default_ccm_pars) runs on IPA_Emulation_CT {
	g_mode := IPA_MODE_CLIENT;
	f_connect(remote_host, remote_port, local_host, local_port, ccm_pars);
	f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
	ScanEvents();
}

/* main function to use for a server-side IPA implementation */
function main_server(charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
	g_mode := IPA_MODE_SERVER;
	f_bind(local_host, local_port);
	ScanEvents();
}

private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
	var charstring msg_ch := oct2char(msg);
	if (g_is_bsc_mgw) {
		log("============");
		log(msg_ch);
		IPA_MGCP_PORT.send(dec_MgcpCommand(msg_ch));
	} else {
		IPA_MGCP_PORT.send(dec_MgcpResponse(msg_ch));
	}
}

private function f_ctrl_to_user(octetstring msg) runs on IPA_Emulation_CT {
	var charstring msg_ch := oct2char(msg);
	IPA_CTRL_PORT.send(dec_CtrlMessage(msg_ch));
}

private function f_gsup_to_user(octetstring msg) runs on IPA_Emulation_CT {
	IPA_GSUP_PORT.send(dec_GSUP_PDU(msg));
}

private function f_mgcp_to_ud(octetstring payload) runs on IPA_Emulation_CT return ASP_IPA_Unitdata {
	if (mp_ipa_mgcp_uses_osmo_ext) {
		return valueof(t_ASP_IPA_UD(IPAC_PROTO_MGCP_OLD, payload));
	} else {
		return valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_MGCP));
	}
}

/* main loop function for both client and server. 'thread' of the component */
private function ScanEvents() runs on IPA_Emulation_CT {
	var IPA_RecvFrom ipa_rx;
	var ASP_IPA_Unitdata ipa_ud;
	var ASP_MTP3_TRANSFERreq mtp_req;
	var ASP_Event asp_evt;
	var MgcpCommand mgcp_cmd;
	var MgcpResponse mgcp_rsp;
	var CtrlMessage ctrl_msg;
	var GSUP_PDU gsup_msg;
	var octetstring payload;
	var ASP_RSL_Unitdata rsl;

	/* Set function for dissecting the binary */
	var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
	IPA_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(IPA_PORT, g_ipa_conn_id, vl_f, {0, 2, 3, 1, 0});

	while (true) {
		alt {
		/* Received IPA -> up into SCCP stack */
		[] IPA_PORT.receive(IPA_RecvFrom: ?) -> value ipa_rx {
			select (ipa_rx.streamId) {
			case (IPAC_PROTO_CCM) {
				var PDU_IPA_CCM ccm := dec_PDU_IPA_CCM(ipa_rx.msg);
				log("CCM Rx:", ccm);
				f_ccm_rx(ccm);
			} case (IPAC_PROTO_SCCP) {
				var ASP_MTP3_TRANSFERind mtp;
				mtp := valueof(ts_MTP3_XFER_ind(0, ipa_rx.msg));
				MTP3_SP_PORT.send(mtp);
			} case (IPAC_PROTO_MGCP_OLD) {
				f_mgcp_to_user(ipa_rx.msg);
			} case (t_IpaSidRSL) {
				rsl := {
					streamId := ipa_rx.streamId,
					rsl := dec_RSL_Message(ipa_rx.msg)
				};
				IPA_RSL_PORT.send(rsl);
			} case (IPAC_PROTO_OSMO) {
				select (ipa_rx.streamIdExt) {
					case (IPAC_PROTO_EXT_MGCP) {
						f_mgcp_to_user(ipa_rx.msg);
					} case (IPAC_PROTO_EXT_CTRL) {
						f_ctrl_to_user(ipa_rx.msg);
					} case (IPAC_PROTO_EXT_GSUP) {
						f_gsup_to_user(ipa_rx.msg);
					} case else {
						IPA_SP_PORT.send(f_to_asp(ipa_rx));
					}
				}
			} case else {
				IPA_SP_PORT.send(f_to_asp(ipa_rx));
				}
			}
		}

		/* server only */
		[] IPA_PORT.receive(ASP_Event:{connOpened:=?}) -> value asp_evt {
			log("IPA: Connected");
			g_ipa_conn_id := asp_evt.connOpened.connId;
			f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP));
			if (g_mode == IPA_MODE_SERVER) {
				f_ccm_tx(valueof(ts_IPA_ID_GET));
			}
		}

		[] IPA_PORT.receive(ASP_Event:{connClosed:=?}) -> value asp_evt {
			log("IPA: Closed");
			g_ipa_conn_id := -1;
			f_send_IPA_EVT(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_DOWN));
			self.stop;
		}

		/* Received SCCP -> down into IPA */
		[] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq: ?) -> value mtp_req {
			var IPA_Send ipa_tx := valueof(t_IPA_Send(g_ipa_conn_id, IPAC_PROTO_SCCP,
							mtp_req.data));
			IPA_PORT.send(ipa_tx);
		}

		/* Received MGCP -> down into IPA */
		[] IPA_MGCP_PORT.receive(MgcpCommand:?) -> value mgcp_cmd {
			payload := char2oct(enc_MgcpCommand(mgcp_cmd));
			ipa_ud := f_mgcp_to_ud(payload);
			IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
		}
		[] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
			payload := char2oct(enc_MgcpResponse(mgcp_rsp));
			ipa_ud := f_mgcp_to_ud(payload);
			IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
		}

		[] IPA_CTRL_PORT.receive(CtrlMessage:?) -> value ctrl_msg {
			payload := char2oct(enc_CtrlMessage(ctrl_msg));
			ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_CTRL));
			IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
		}

		[] IPA_GSUP_PORT.receive(GSUP_PDU:?) -> value gsup_msg {
			payload := enc_GSUP_PDU(gsup_msg);
			ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_GSUP));
			IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
		}

		/* Received RSL -> down into IPA */
		[] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
			IPA_PORT.send(f_from_rsl(g_ipa_conn_id, rsl));
		}


		/* Received MISC (OML/CTRL) -> down into IPA */
		[] IPA_SP_PORT.receive(ASP_IPA_Unitdata: ?) -> value ipa_ud {
			IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
		}


		}
	}
}

}
