/* NS Provider for NS/FR/E1
 * (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_FR {

import from NS_Emulation all;
import from NS_Types all;

import from AF_PACKET_PortType all;
import from FrameRelay_Types all;
import from FrameRelay_Emulation all;


type component NS_Provider_FR_CT extends NS_Provider_CT, FR_Client_CT {
	/* component reference to Frame Relay emulation */
	var FR_Emulation_CT vc_FREMU;

	var boolean link_available := false;
	var boolean pvc_active := false;
};

function main(NSVCConfiguration config, NSConfiguration nsconfig, charstring id) runs on NS_Provider_FR_CT system af_packet {

	/* start Frame Relay Emulation */
	vc_FREMU := FR_Emulation_CT.create(id & "-FRemu") alive;
	var Q933em_Config q933_cfg := valueof(ts_Q933em_Config(ats_is_user := not nsconfig.role_sgsn, bidirectional := false));
	q933_cfg.T391 := 1.0;
	map(vc_FREMU:FR, system:AF_PACKET) param (config.provider.fr.netdev);
	vc_FREMU.start(FrameRelay_Emulation.main(q933_cfg));

	/* connect ourselves to frame relay emulation */
	connect(self:FR, vc_FREMU:CLIENT);
	connect(self:FR_PROC, vc_FREMU:PROC);

	/* register ourselves for the specified DLCI */
	f_fremu_register(config.provider.fr.dlci);

	/* transceive between user-facing port and FR socket */
	while (true) {
		var FrameRelayFrame rx_fr;
		var FRemu_Event rx_frevt;
		var PDU_NS rx_pdu;
		alt {

		[not link_available] FR.receive(FrameRelayFrame:?) -> value rx_fr {
			log("Dropping Rx Msg because FR link not yet available", rx_fr);
				/* this can happen if the remote side has not yet recognized the
				 * link is dead; don' fail here */
			}
		[link_available and pvc_active] FR.receive(tr_FR(config.provider.fr.dlci)) -> value rx_fr {
			var PDU_NS ns := dec_PDU_NS(rx_fr.payload);
			NSE.send(ns);
			}
		[not pvc_active] FR.receive(tr_FR(config.provider.fr.dlci)) -> value rx_fr {
			log("Dropping Rx Msg because FR DLC not yet available", rx_fr);
			}
		[] FR.receive(tr_FR(?)) -> value rx_fr {
			log("Dropping Rx Msg because DLCI unknown", rx_fr);
			setverdict(fail);
			}

		[] FR.receive(FRemu_Event:{link_status:=FR_LINK_STS_AVAILABLE}) -> value rx_frevt {
			if (link_available == false and pvc_active == true) {
				NSE.send(NS_Provider_Evt:{link_status := NS_PROV_LINK_STATUS_UP});
			}
			link_available := true;
			}
		[] FR.receive(FRemu_Event:{link_status:=FR_LINK_STS_UNAVAILABLE}) -> value rx_frevt {
			link_available := false;
			pvc_active := false;
			NSE.send(NS_Provider_Evt:{link_status := NS_PROV_LINK_STATUS_DOWN});
			}
		[] FR.receive(tr_FRemu_PvcStatusAct(config.provider.fr.dlci, true)) -> value rx_frevt {
			if (pvc_active == false and link_available == true) {
				NSE.send(NS_Provider_Evt:{link_status := NS_PROV_LINK_STATUS_UP});
			}
			pvc_active := true;
			}
		[] FR.receive(tr_FRemu_PvcStatusAct(config.provider.fr.dlci, false)) -> value rx_frevt {
			pvc_active := false;
			NSE.send(NS_Provider_Evt:{link_status := NS_PROV_LINK_STATUS_DOWN});
			}
		[] FR.receive(FRemu_Event:?) -> value rx_frevt {
			log("Unhandled FRemu_event: ", rx_frevt);
			}
		[] NSE.receive(PDU_NS:?) -> value rx_pdu {
			FR.send(ts_FR(config.provider.fr.dlci, enc_PDU_NS(rx_pdu), true));
			}

		}
	}

} /* main */



} /* module */
