module IPA_Emulation {

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

import from MGCP_Types all;

/*
modulepar {
}
*/

type enumerated IpaMode {
	IPA_MODE_CLIENT,
	IPA_MODE_SERVER
}

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

type port IPA_SP_PT message {
	inout ASP_IPA_Unitdata;
} with { extension "internal" }

type port IPA_MGCP_PT message {
	inout MgcpCommand, MgcpResponse;
} 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 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;
}

function f_connect(charstring remote_host, PortNumber remote_port,
		   charstring local_host, PortNumber local_port) 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_is_bsc_mgw := true;
}

function f_bind(charstring local_host, PortNumber local_port) 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_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
}

/* build IPA CCM ID RESP response from IPA CCM GET */
private function f_ccm_make_id_resp(PDU_IPA_CCM get) 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_UNIT) {
				foo := "0/1/2";
			}
			case (IPAC_IDTAG_UNITNAME) {
				foo := "mahlzeit";
			}
			case else {
				foo := "foo";
			}
		}
		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;
}

function main_client(charstring remote_host, PortNumber remote_port,
		     charstring local_host, PortNumber local_port) runs on IPA_Emulation_CT {
	g_mode := IPA_MODE_CLIENT;
	f_connect(remote_host, remote_port, local_host, local_port);
	ScanEvents();
}

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

	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 (IPAC_PROTO_OSMO) {
				select (ipa_rx.streamIdExt) {
					case (IPAC_PROTO_EXT_MGCP) {
						f_mgcp_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;
			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;
			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 {
			ipa_ud := {
				streamId := IPAC_PROTO_OSMO,
				streamIdExt := IPAC_PROTO_EXT_MGCP,
				payload := char2oct(enc_MgcpCommand(mgcp_cmd))
			}
			IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
		}
		[] IPA_MGCP_PORT.receive(MgcpResponse:?) -> value mgcp_rsp {
			ipa_ud := {
				streamId := IPAC_PROTO_OSMO,
				streamIdExt := IPAC_PROTO_EXT_MGCP,
				payload := char2oct(enc_MgcpResponse(mgcp_rsp))
			}
			IPA_PORT.send(f_from_asp(g_ipa_conn_id, ipa_ud));
		}


		/* Received MISC (RSL/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));
		}


		}
	}
}

}
