blob: b664b5e53c1e64f3ef71d9f37753d058cda50c9a [file] [log] [blame]
Harald Welte867243a2020-09-13 18:32:32 +02001/* NS Provider for NS/FR/E1
2 * (C) 2020 Harald Welte <laforge@gnumonks.org>
3 * contributions by sysmocom - s.f.m.c. GmbH
4 * All rights reserved.
5 *
6 * Released under the terms of GNU General Public License, Version 2 or
7 * (at your option) any later version.
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12module NS_Provider_FR {
13
14import from NS_Emulation all;
15import from NS_Types all;
16
17import from AF_PACKET_PortType all;
18import from FrameRelay_Types all;
19import from FrameRelay_Emulation all;
20
21
22type component NS_Provider_FR_CT extends NS_Provider_CT, FR_Client_CT {
23 /* component reference to Frame Relay emulation */
24 var FR_Emulation_CT vc_FREMU;
Harald Weltebd612cd2020-09-14 09:42:28 +020025
26 var boolean link_available := false;
27 var boolean pvc_active := false;
Harald Welte867243a2020-09-13 18:32:32 +020028};
29
Harald Welte90f19742020-11-06 19:34:40 +010030function main(NSVCConfiguration config, NSConfiguration nsconfig, charstring id) runs on NS_Provider_FR_CT system af_packet {
Harald Welte867243a2020-09-13 18:32:32 +020031
32 /* start Frame Relay Emulation */
Daniel Willmann09ed9942023-12-05 15:04:50 +010033 vc_FREMU := FR_Emulation_CT.create(id & "-FRemu") alive;
Harald Welte90f19742020-11-06 19:34:40 +010034 var Q933em_Config q933_cfg := valueof(ts_Q933em_Config(ats_is_user := not nsconfig.role_sgsn, bidirectional := false));
Harald Welte847a77e2020-09-14 12:55:47 +020035 q933_cfg.T391 := 1.0;
Harald Welte867243a2020-09-13 18:32:32 +020036 map(vc_FREMU:FR, system:AF_PACKET) param (config.provider.fr.netdev);
37 vc_FREMU.start(FrameRelay_Emulation.main(q933_cfg));
38
39 /* connect ourselves to frame relay emulation */
40 connect(self:FR, vc_FREMU:CLIENT);
41 connect(self:FR_PROC, vc_FREMU:PROC);
42
43 /* register ourselves for the specified DLCI */
44 f_fremu_register(config.provider.fr.dlci);
45
46 /* transceive between user-facing port and FR socket */
47 while (true) {
48 var FrameRelayFrame rx_fr;
49 var FRemu_Event rx_frevt;
50 var PDU_NS rx_pdu;
51 alt {
52
Harald Welte49f3ea82021-02-05 21:01:09 +010053 [not link_available] FR.receive(FrameRelayFrame:?) -> value rx_fr {
Harald Welte37202772021-02-16 18:50:15 +010054 log("Dropping Rx Msg because FR link not yet available", rx_fr);
Harald Welte49f3ea82021-02-05 21:01:09 +010055 /* this can happen if the remote side has not yet recognized the
56 * link is dead; don' fail here */
57 }
58 [link_available and pvc_active] FR.receive(tr_FR(config.provider.fr.dlci)) -> value rx_fr {
59 var PDU_NS ns := dec_PDU_NS(rx_fr.payload);
60 NSE.send(ns);
61 }
62 [not pvc_active] FR.receive(tr_FR(config.provider.fr.dlci)) -> value rx_fr {
Harald Welte37202772021-02-16 18:50:15 +010063 log("Dropping Rx Msg because FR DLC not yet available", rx_fr);
Harald Welte49f3ea82021-02-05 21:01:09 +010064 }
65 [] FR.receive(tr_FR(?)) -> value rx_fr {
Harald Welte37202772021-02-16 18:50:15 +010066 log("Dropping Rx Msg because DLCI unknown", rx_fr);
Harald Welte49f3ea82021-02-05 21:01:09 +010067 setverdict(fail);
Harald Welte867243a2020-09-13 18:32:32 +020068 }
69
Harald Weltebd612cd2020-09-14 09:42:28 +020070 [] FR.receive(FRemu_Event:{link_status:=FR_LINK_STS_AVAILABLE}) -> value rx_frevt {
71 if (link_available == false and pvc_active == true) {
72 NSE.send(NS_Provider_Evt:{link_status := NS_PROV_LINK_STATUS_UP});
73 }
74 link_available := true;
75 }
76 [] FR.receive(FRemu_Event:{link_status:=FR_LINK_STS_UNAVAILABLE}) -> value rx_frevt {
77 link_available := false;
Harald Weltec0c67ff2021-02-03 19:26:30 +010078 pvc_active := false;
Harald Weltebd612cd2020-09-14 09:42:28 +020079 NSE.send(NS_Provider_Evt:{link_status := NS_PROV_LINK_STATUS_DOWN});
80 }
81 [] FR.receive(tr_FRemu_PvcStatusAct(config.provider.fr.dlci, true)) -> value rx_frevt {
82 if (pvc_active == false and link_available == true) {
83 NSE.send(NS_Provider_Evt:{link_status := NS_PROV_LINK_STATUS_UP});
84 }
85 pvc_active := true;
86 }
87 [] FR.receive(tr_FRemu_PvcStatusAct(config.provider.fr.dlci, false)) -> value rx_frevt {
88 pvc_active := false;
89 NSE.send(NS_Provider_Evt:{link_status := NS_PROV_LINK_STATUS_DOWN});
90 }
Harald Welte867243a2020-09-13 18:32:32 +020091 [] FR.receive(FRemu_Event:?) -> value rx_frevt {
Harald Weltebd612cd2020-09-14 09:42:28 +020092 log("Unhandled FRemu_event: ", rx_frevt);
Harald Welte867243a2020-09-13 18:32:32 +020093 }
94 [] NSE.receive(PDU_NS:?) -> value rx_pdu {
95 FR.send(ts_FR(config.provider.fr.dlci, enc_PDU_NS(rx_pdu), true));
96 }
97
98 }
99 }
100
101} /* main */
102
103
104
105} /* module */