static void Main(string[] args) { Dictionary <string, dynamic> dict; int i; // Use program arguments if specified, otherwise use constants. // Arguments are in the sequence [[[<master_ip> <slave_ip>] <output_file>] <samples_to_receive] string master_ip = MASTER_IP; string slave_ip = SLAVE_IP; string output_file = OUTPUT_FILE; if (args.Length >= 2) { master_ip = args[0]; slave_ip = args[1]; } if (args.Length >= 3) { output_file = args[2]; } if (args.Length >= 4) { samples_to_receive = Convert.ToInt32(args[3]); } // Instantiate Socket array. sock = new Socket[NumberOfModules]; // Initialize boundary objects LanXIRESTBoundary master = new LanXIRESTBoundary(master_ip); LanXIRESTBoundary slave = new LanXIRESTBoundary(slave_ip); // Start measurement // During this process commands are generally performed on SLAVEs first, finished with MASTER // Set synchronization mode on the LAN-XI modules. The body tells which module is master and which is slave. Body for each module is prepared in SyncParametersMaster.json and SyncParametersSlave.json // For this command, the MASTER should be treated first, then the slave(s) string syncParametersMaster = File.ReadAllText(@"PTPInputStreamingOutputGenerator_SyncParametersMaster.json"); master.PutRequestWithPath("/rest/rec/syncmode", syncParametersMaster); string syncParametersSlave = File.ReadAllText(@"PTPInputStreamingOutputGenerator_SyncParametersSlave.json"); slave.PutRequestWithPath("/rest/rec/syncmode", syncParametersSlave); // Wait until PTP is locked on all modules slave.WaitForPtpState("Locked"); master.WaitForPtpState("Locked"); // Open the Recorder application on the modules. The same body is sent to both modules, and is prepared in OpenParameters.json string openParameters = File.ReadAllText(@"PTPInputStreamingOutputGenerator_OpenParameters.json"); slave.PutRequestWithPath("/rest/rec/open", openParameters); master.PutRequestWithPath("/rest/rec/open", openParameters); // Prepare generator string outputChannelStart = File.ReadAllText(@"PTPInputStreamingOutputGenerator_OutputChannelStart.json"); slave.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart); master.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart); // Configure generator channels string outputChannelConfiguration = File.ReadAllText(@"PTPInputStreamingOutputGenerator_OutputChannelSetup.json"); slave.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration); master.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration); // Start output slave.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart); master.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart); master.PutRequestWithPath("/rest/rec/generator/apply", null); // Wait for all modules to be ready; Input in Sampling state, and module in the RecorderOpened state. slave.WaitForInputState("Sampling"); master.WaitForInputState("Sampling"); slave.WaitForRecorderState("RecorderOpened"); master.WaitForRecorderState("RecorderOpened"); // Create Recorder configuration on all modules slave.PutRequestWithPath("/rest/rec/create", null); master.PutRequestWithPath("/rest/rec/create", null); // Wait for all modules to be in the RecorderConfiguring state. slave.WaitForRecorderState("RecorderConfiguring"); master.WaitForRecorderState("RecorderConfiguring"); // Set a configuration for the input channels. Default configuration can be obtained by sending a GET request to /rest/rec/channels/input/default. // The body has been prepared and stored in PTPInputStreamingOutputGenerator_InputChannelSetup.json. In this example the setup is identical for the two modules, but it may differ as needed. string inputChannelConfiguration = File.ReadAllText(@"PTPInputStreamingOutputGenerator_InputChannelSetup.json"); slave.PutRequestWithPath("/rest/rec/channels/input", inputChannelConfiguration); master.PutRequestWithPath("/rest/rec/channels/input", inputChannelConfiguration); // Wait until all modules enter the Settled input state slave.WaitForInputState("Settled"); master.WaitForInputState("Settled"); // Synchronize modules. slave.PutRequestWithPath("/rest/rec/synchronize", null); master.PutRequestWithPath("/rest/rec/synchronize", null); // Wait for all modules to enter the Synchronized input state slave.WaitForInputState("Synchronized"); master.WaitForInputState("Synchronized"); // Start streaming between internally in the LAN-XI modules. slave.PutRequestWithPath("/rest/rec/startstreaming", null); master.PutRequestWithPath("/rest/rec/startstreaming", null); // Wait for all modules to enter the RecorderStreaming state slave.WaitForRecorderState("RecorderStreaming"); master.WaitForRecorderState("RecorderStreaming"); // Get the TCP ports provided by each LAN-XI module for streaming samples dict = master.GetRequestWithPath("/rest/rec/destination/socket"); UInt16 slavePort = (UInt16)dict["tcpPort"]; dict = slave.GetRequestWithPath("/rest/rec/destination/socket"); UInt16 masterPort = (UInt16)dict["tcpPort"]; // Connect to sockets. Let ConnectStreams() handle this. ConnectStreams(new string[] { master_ip, slave_ip }, new UInt16[] { masterPort, slavePort }); // Start measuring. slave.PostRequestWithPath("/rest/rec/measurements", null); master.PostRequestWithPath("/rest/rec/measurements", null); // Wait for modules to enter RecorderRecording state slave.WaitForRecorderState("RecorderRecording"); master.WaitForRecorderState("RecorderRecording"); // Streaming should now be running. // Let Stream() method handle streaming Stream(); // Stop measuring and close sockets for all modules. // During this process commands are generaly performed on MASTER module first, then on SLAVEs // Stop measurement on modules master.PutRequestWithPath("/rest/rec/measurements/stop", null); slave.PutRequestWithPath("/rest/rec/measurements/stop", null); // Wait for all modules to enter RecorderStreaming state master.WaitForRecorderState("RecorderStreaming"); slave.WaitForRecorderState("RecorderStreaming"); // Close sockets for (i = 0; i < NumberOfModules; i++) { sock[i].Shutdown(SocketShutdown.Both); sock[i].Close(); } // Finish recording master.PutRequestWithPath("/rest/rec/finish", null); slave.PutRequestWithPath("/rest/rec/finish", null); // Stop output // master.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart); // slave.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart); // Wait for modules to enter the RecorderOpened state master.WaitForRecorderState("RecorderOpened"); slave.WaitForRecorderState("RecorderOpened"); // Close Recorder application on all modules master.PutRequestWithPath("/rest/rec/close", null); slave.PutRequestWithPath("/rest/rec/close", null); // Wait for modules to enter the Idle state master.WaitForRecorderState("Idle"); slave.WaitForRecorderState("Idle"); // Write collected samples to output file StreamWriter file = new StreamWriter(output_file); for (int j = 0; j < outputSamples[0, 0].Count; j++) { file.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}", outputSamples[0, 0][j], outputSamples[0, 1][j], outputSamples[0, 2][j], outputSamples[0, 3][j], outputSamples[1, 0][j], outputSamples[1, 1][j], outputSamples[1, 2][j], outputSamples[1, 3][j]); } file.Close(); }