/* 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(NSVCConfiguration config, NSConfiguration nsconfig, charstring id) runs on NS_Provider_IPL4_CT {

	/* connect socket */
	map(self:IPL4, system:IPL4);
	var Result res := f_IPL4_connect(IPL4, config.provider.ip.remote_ip,
					 config.provider.ip.remote_udp_port,
					 config.provider.ip.local_ip,
					 config.provider.ip.local_udp_port, 0, { udp := {}});
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect NS UDP socket ", config.provider.ip);
		mtc.stop;
	}
	g_conn_id := res.connId;
	NSE.send(NS_Provider_Evt:{link_status := NS_PROV_LINK_STATUS_UP});

	/* 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 */
