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

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 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;
	/* 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});

	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);
	}
	/* 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_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 octetstring payload;
	var ASP_RSL_Unitdata rsl;

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

		/* 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));
		}


		}
	}
}

}
