diff --git a/core/src/main/java/org/lflang/federated/extensions/CExtension.java b/core/src/main/java/org/lflang/federated/extensions/CExtension.java index 9e91349c98..69c59ccfed 100644 --- a/core/src/main/java/org/lflang/federated/extensions/CExtension.java +++ b/core/src/main/java/org/lflang/federated/extensions/CExtension.java @@ -520,9 +520,9 @@ public String generatePreamble( extern "C" { #endif"""); includes.pr("#include \"core/federated/federate.h\""); - includes.pr("#include \"core/federated/network/net_common.h\""); - includes.pr("#include \"core/federated/network/net_util.h\""); - includes.pr("#include \"core/federated/network/socket_common.h\""); + includes.pr("#include \"network/api/net_driver.h\""); + includes.pr("#include \"network/api/net_common.h\""); + includes.pr("#include \"network/api/net_util.h\""); includes.pr("#include \"core/federated/clock-sync.h\""); includes.pr("#include \"core/threaded/reactor_threaded.h\""); includes.pr("#include \"core/utils/util.h\""); @@ -543,9 +543,9 @@ protected String makePreamble( var code = new CodeBuilder(); code.pr("#include \"core/federated/federate.h\""); - code.pr("#include \"core/federated/network/net_common.h\""); - code.pr("#include \"core/federated/network/net_util.h\""); - code.pr("#include \"core/federated/network/socket_common.h\""); + code.pr("#include \"network/api/net_driver.h\""); + code.pr("#include \"network/api/net_common.h\""); + code.pr("#include \"network/api/net_util.h\""); code.pr("#include \"core/federated/clock-sync.h\""); code.pr("#include \"core/threaded/reactor_threaded.h\""); code.pr("#include \"core/utils/util.h\""); @@ -686,8 +686,9 @@ private String generateCodeToInitializeFederate( String.join( "\n", "// Initialize the socket mutexes", - "lf_mutex_init(&lf_outbound_socket_mutex);", - "lf_mutex_init(&socket_mutex);", + "lf_mutex_init(&lf_outbound_netchan_mutex);", + "lf_mutex_init(&lf_inbound_netchan_mutex);", + "lf_mutex_init(&shutdown_mutex);", "lf_cond_init(&lf_port_status_changed, &env->mutex);")); // Find the STA (A.K.A. the global STP offset) for this federate. @@ -740,16 +741,16 @@ else if (globalSTP instanceof CodeExprImpl) code.pr( String.join( "\n", - "// Initialize the array of socket for incoming connections to -1.", + "// Initialize the array of network drivers for incoming connections to -1.", "for (int i = 0; i < NUMBER_OF_FEDERATES; i++) {", - " _fed.sockets_for_inbound_p2p_connections[i] = -1;", + " _fed.netchans_for_inbound_p2p_connections[i] = NULL;", "}")); code.pr( String.join( "\n", - "// Initialize the array of socket for outgoing connections to -1.", + "// Initialize the array of network drivers for outgoing connections to -1.", "for (int i = 0; i < NUMBER_OF_FEDERATES; i++) {", - " _fed.sockets_for_outbound_p2p_connections[i] = -1;", + " _fed.netchans_for_outbound_p2p_connections[i] = NULL;", "}")); var clockSyncOptions = federate.targetConfig.getOrDefault(ClockSyncOptionsProperty.INSTANCE); // If a test clock offset has been specified, insert code to set it here. @@ -765,7 +766,7 @@ else if (globalSTP instanceof CodeExprImpl) code.pr( String.join( "\n", - "// Connect to the RTI. This sets _fed.socket_TCP_RTI and _lf_rti_socket_UDP.", + "// Connect to the RTI. This sets _fed.netchan_to_RTI and _lf_rti_socket_UDP.", "lf_connect_to_rti(" + addDoubleQuotes(rtiConfig.getHost()) + ", " @@ -775,14 +776,14 @@ else if (globalSTP instanceof CodeExprImpl) // Disable clock synchronization for the federate if it resides on the same host as the RTI, // unless that is overridden with the clock-sync-options target property. if (CExtensionUtils.clockSyncIsOn(federate, rtiConfig)) { - code.pr("synchronize_initial_physical_clock_with_rti(&_fed.socket_TCP_RTI);"); + code.pr("synchronize_initial_physical_clock_with_rti(_fed.netchan_to_RTI);"); } if (numberOfInboundConnections > 0) { code.pr( String.join( "\n", - "// Create a socket server to listen to other federates.", + "// Create a server to listen to other federates.", "// If a port is specified by the user, that will be used", "// as the only possibility for the server. If not, the port", "// will be selected by the OS (by specifying port 0).", diff --git a/core/src/main/java/org/lflang/federated/extensions/CExtensionUtils.java b/core/src/main/java/org/lflang/federated/extensions/CExtensionUtils.java index ad982431a2..39b74febe2 100644 --- a/core/src/main/java/org/lflang/federated/extensions/CExtensionUtils.java +++ b/core/src/main/java/org/lflang/federated/extensions/CExtensionUtils.java @@ -28,6 +28,7 @@ import org.lflang.target.property.ClockSyncOptionsProperty; import org.lflang.target.property.ClockSyncOptionsProperty.ClockSyncOptions; import org.lflang.target.property.CmakeIncludeProperty; +import org.lflang.target.property.CommunicationModeProperty; import org.lflang.target.property.CompileDefinitionsProperty; import org.lflang.target.property.CoordinationOptionsProperty; import org.lflang.target.property.CoordinationProperty; @@ -201,6 +202,10 @@ public static void handleCompileDefinitions( if (federate.targetConfig.get(AuthProperty.INSTANCE)) { definitions.put("FEDERATED_AUTHENTICATED", ""); } + if (federate.targetConfig.isSet(CommunicationModeProperty.INSTANCE)) { + definitions.put( + "COMM_TYPE", federate.targetConfig.get(CommunicationModeProperty.INSTANCE).toString()); + } definitions.put("NUMBER_OF_FEDERATES", String.valueOf(federateNames.size())); definitions.put("EXECUTABLE_PREAMBLE", ""); definitions.put("FEDERATE_ID", String.valueOf(federate.id)); @@ -325,7 +330,7 @@ public static void generateCMakeInclude( /** * Generate code that sends the neighbor structure message to the RTI. See {@code - * MSG_TYPE_NEIGHBOR_STRUCTURE} in {@code federated/net_common.h}. + * MSG_TYPE_NEIGHBOR_STRUCTURE} in {@code network/api/net_common.h}. * * @param federate The federate that is sending its neighbor structure */ @@ -342,7 +347,7 @@ public static String generateFederateNeighborStructure(FederateInstance federate "* information is needed for the RTI to perform the centralized coordination.", "* @see MSG_TYPE_NEIGHBOR_STRUCTURE in net_common.h", "*/", - "void lf_send_neighbor_structure_to_RTI(int rti_socket) {")); + "void lf_send_neighbor_structure_to_RTI(netchan_t rti_netchan) {")); code.indent(); // Initialize the array of information about the federate's immediate upstream // and downstream relayed (through the RTI) logical connections, to send to the @@ -444,8 +449,8 @@ public static String generateFederateNeighborStructure(FederateInstance federate code.pr( String.join( "\n", - "write_to_socket_fail_on_error(", - " &rti_socket, ", + "write_to_netchan_fail_on_error(", + " rti_netchan, ", " buffer_size,", " buffer_to_send,", " NULL,", diff --git a/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java b/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java index 7044265574..281b9a203d 100644 --- a/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java +++ b/core/src/main/java/org/lflang/generator/c/CCmakeGenerator.java @@ -37,6 +37,7 @@ import org.lflang.target.property.AuthProperty; import org.lflang.target.property.BuildTypeProperty; import org.lflang.target.property.CmakeIncludeProperty; +import org.lflang.target.property.CommunicationModeProperty; import org.lflang.target.property.CompileDefinitionsProperty; import org.lflang.target.property.CompilerProperty; import org.lflang.target.property.PlatformProperty; @@ -426,6 +427,10 @@ CodeBuilder generateCMakeCode( cMakeCode.pr("target_link_libraries( ${LF_MAIN_TARGET} PRIVATE OpenSSL::SSL)"); cMakeCode.newLine(); } + if (targetConfig.isSet(CommunicationModeProperty.INSTANCE)) { + cMakeCode.pr("set(COMM_TYPE " + targetConfig.get(CommunicationModeProperty.INSTANCE) + ")"); + cMakeCode.newLine(); + } if (!targetConfig.get(SingleThreadedProperty.INSTANCE) && platformOptions.platform() != Platform.ZEPHYR diff --git a/core/src/main/java/org/lflang/generator/c/CGenerator.java b/core/src/main/java/org/lflang/generator/c/CGenerator.java index 2c21ae7b7f..46507a06ce 100644 --- a/core/src/main/java/org/lflang/generator/c/CGenerator.java +++ b/core/src/main/java/org/lflang/generator/c/CGenerator.java @@ -921,9 +921,13 @@ protected void copyTargetFiles() throws IOException { FileUtil.copyFromClassPath("/lib/c/reactor-c/" + directory, dest, true, false); } for (var directory : - List.of("logging", "platform", "low_level_platform", "trace", "version", "tag")) { + List.of( + "logging", "platform", "low_level_platform", "trace", "version", "tag", "network")) { var entry = "/lib/c/reactor-c/" + directory; if (arduino) { + if ("network".equals(directory)) { + continue; // Skip copying for the "network" directory + } if (FileConfig.class.getResource(entry + "/api") != null) { FileUtil.copyFromClassPath( entry + "/api", diff --git a/core/src/main/java/org/lflang/generator/c/CPreambleGenerator.java b/core/src/main/java/org/lflang/generator/c/CPreambleGenerator.java index 1b3a6d22d9..09a4681c79 100644 --- a/core/src/main/java/org/lflang/generator/c/CPreambleGenerator.java +++ b/core/src/main/java/org/lflang/generator/c/CPreambleGenerator.java @@ -65,7 +65,7 @@ public static String generateIncludeStatements(TargetConfig targetConfig, boolea code.pr("int lf_reactor_c_main(int argc, const char* argv[]);"); if (targetConfig.isSet(FedSetupProperty.INSTANCE)) { code.pr("#include \"include/core/federated/federate.h\""); - code.pr("#include \"include/core/federated/network/net_common.h\""); + code.pr("#include \"network/api/net_common.h\""); } if (cppMode || arduinoBased(targetConfig)) { code.pr("}"); diff --git a/core/src/main/java/org/lflang/target/Target.java b/core/src/main/java/org/lflang/target/Target.java index 1e2e67788f..f0dc63aef0 100644 --- a/core/src/main/java/org/lflang/target/Target.java +++ b/core/src/main/java/org/lflang/target/Target.java @@ -556,6 +556,7 @@ public void initialize(TargetConfig config) { ClockSyncModeProperty.INSTANCE, ClockSyncOptionsProperty.INSTANCE, CmakeIncludeProperty.INSTANCE, + CommunicationModeProperty.INSTANCE, CompileDefinitionsProperty.INSTANCE, CompilerProperty.INSTANCE, CoordinationOptionsProperty.INSTANCE, diff --git a/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java b/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java new file mode 100644 index 0000000000..f4aade96c3 --- /dev/null +++ b/core/src/main/java/org/lflang/target/property/CommunicationModeProperty.java @@ -0,0 +1,43 @@ +package org.lflang.target.property; + +import org.lflang.MessageReporter; +import org.lflang.ast.ASTUtils; +import org.lflang.lf.Element; +import org.lflang.target.property.type.CommunicationModeType; +import org.lflang.target.property.type.CommunicationModeType.CommunicationMode; + +public final class CommunicationModeProperty + extends TargetProperty { + + /** Singleton target property instance. */ + public static final CommunicationModeProperty INSTANCE = new CommunicationModeProperty(); + + private CommunicationModeProperty() { + super(new CommunicationModeType()); + } + + @Override + public Element toAstElement(CommunicationMode value) { + return ASTUtils.toElement(value.toString()); + } + + @Override + public CommunicationMode initialValue() { + return CommunicationMode.TCP; + } + + @Override + public CommunicationMode fromAst(Element node, MessageReporter reporter) { + return fromString(ASTUtils.elementToSingleString(node), reporter); + } + + @Override + protected CommunicationMode fromString(String string, MessageReporter reporter) { + return this.type.forName(string); + } + + @Override + public String name() { + return "comm-type"; + } +} diff --git a/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java new file mode 100644 index 0000000000..c2a30f612b --- /dev/null +++ b/core/src/main/java/org/lflang/target/property/type/CommunicationModeType.java @@ -0,0 +1,44 @@ +package org.lflang.target.property.type; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.lflang.target.property.type.CommunicationModeType.CommunicationMode; + +/** Enumeration of communication types */ +public class CommunicationModeType extends OptionsType { + + @Override + protected Class enumClass() { + return CommunicationMode.class; + } + + /** Enumeration of communication types. */ + public enum CommunicationMode { + TCP("TCP"); + + // More communication modes will be added. + + /** Alias used in toString method. */ + private final String alias; + + /** Private constructor for Cmake build types. */ + CommunicationMode(String alias) { + this.alias = alias; + } + + /** Return the alias. */ + @Override + public String toString() { + return this.alias; + } + + public static List optionsList() { + return Arrays.stream(CommunicationMode.values()).collect(Collectors.toList()); + } + + public static CommunicationMode getDefault() { + return CommunicationMode.TCP; + } + } +} diff --git a/core/src/main/resources/lib/c/reactor-c b/core/src/main/resources/lib/c/reactor-c index 8072355921..94cfbfdb2c 160000 --- a/core/src/main/resources/lib/c/reactor-c +++ b/core/src/main/resources/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit 80723559219363879ea01c5efd91c410d68a61a0 +Subproject commit 94cfbfdb2ca3d3b7283e59d0cba99db5b148e5ad diff --git a/core/src/main/resources/lib/cpp/reactor-cpp b/core/src/main/resources/lib/cpp/reactor-cpp index d009fdd85b..d255a3da57 160000 --- a/core/src/main/resources/lib/cpp/reactor-cpp +++ b/core/src/main/resources/lib/cpp/reactor-cpp @@ -1 +1 @@ -Subproject commit d009fdd85bf15beb992a3102a99ed91497f8a6fd +Subproject commit d255a3da57d38db2988bcab68024b0a77ccc8657