aboutsummaryrefslogtreecommitdiffstats
path: root/library/NS_Provider_FR.ttcn
blob: afa27d9eafd22ac28d16f096818d8282d4c3f986 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* 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(NSConfiguration config) runs on NS_Provider_FR_CT system af_packet {

	/* start Frame Relay Emulation */
	vc_FREMU := FR_Emulation_CT.create();
	var Q933em_Config q933_cfg := valueof(ts_Q933em_Config(ats_is_user := not config.role_sgsn, bidirectional := false));
	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 {

		[] FR.receive(FrameRelayFrame:?) -> value rx_fr {
			NSE.send(dec_PDU_NS(rx_fr.payload));
			}

		[] 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;
			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 */