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

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


		}
	}
}

}
