/* NS Provider for NS/UDP/IP
 * (C) 2020 Harald Welte <laforge@gnumonks.org>
 * contributions by sysmocom - s.f.m.c. GmbH
 * 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
 */

module NS_Provider_IPL4 {

import from NS_Emulation all;
import from NS_Types all;

import from IPL4asp_Types all;
import from IPL4asp_PortType all;

type component NS_Provider_IPL4_CT extends NS_Provider_CT {
	/* down-facing port towards IPL4asp to IUT */
	port IPL4asp_PT IPL4;
	var integer g_conn_id := -1;
};

function main(NSConfiguration config) runs on NS_Provider_IPL4_CT {

	/* connect socket */
	map(self:IPL4, system:IPL4);
	var Result res := f_IPL4_connect(IPL4, config.remote_ip, config.remote_udp_port, config.local_ip,
					 config.local_udp_port, 0, { udp := {}});
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect NS UDP socket from " &
			   config.local_ip & ":"  & int2str(config.local_udp_port) &
			   " to " & config.remote_ip & ":" & int2str(config.remote_udp_port));
		mtc.stop;
	}
	g_conn_id := res.connId;

	/* transceive beteween user-facing port and UDP socket */
	while (true) {
	var ASP_RecvFrom rx_rf;
	var PDU_NS rx_pdu;
	alt {

	[] IPL4.receive(ASP_RecvFrom:?) -> value rx_rf {
		NSE.send(dec_PDU_NS(rx_rf.msg));
		}

	[] IPL4.receive(ASP_ConnId_ReadyToRelease:?) {
		}

	[] IPL4.receive(ASP_Event:?) {
		}

	[] NSE.receive(PDU_NS:?) -> value rx_pdu {
		IPL4.send(ASP_Send:{connId := g_conn_id, proto := { udp := {} }, msg := enc_PDU_NS(rx_pdu)});
		}

	} /* alt */
	} /* while */

} /* main */



} /* module */
