static bool WaitForStateChange(int index)
        {
            bool result = false;
            LanXIRESTBoundary module          = modules[index];
            int lastUpdate                    = 0;
            Dictionary <string, dynamic> prev = module.RequestWithPath("/rest/rec/onchange?last=0", "GET", null, false);

            for (; ;)
            {
                // Get the module state
                Dictionary <string, dynamic> dict = module.RequestWithPath("/rest/rec/onchange?last=" + lastUpdate.ToString(), "GET", null, false);
                TimeSpan elapsed = runTime.Elapsed;      // Get elapsed time
                if (stopThreads == true)
                {
                    break;
                }
                lastUpdate = dict["lastUpdateTag"];
                dict.Remove("lastUpdateTag");
                dict.Remove("lastSdCardUpdateTag");
                dict.Remove("lastTransducerUpdateTag");
                if (dict.ContainsKey("recordingStatus"))
                {
                    (dict["recordingStatus"] as Dictionary <string, dynamic>).Remove("channelStatus");
                }

                Recurse(dict, prev, elapsed, modules_ip[index]);

                prev = dict;
            }
            return(result);
        }
        static readonly int IN_A_FRAME  = 1;           //

        static void Main(string[] args)
        {
            // Use program arguments if specified, otherwise use constants
            // Arguments are in the sequence [[[<lanxi_ip>] <output_time>] <output_time2>]
            string lanxi_ip     = LANXI_IP;
            int    output_time1 = OUTPUT_TIME;
            int    output_time2 = OUTPUT_TIME;

            if (args.Length >= 1)
            {
                lanxi_ip = args[0];
            }
            if (args.Length >= 2)
            {
                output_time1 = Convert.ToInt32(args[1]);
                output_time2 = output_time1;
            }
            if (args.Length >= 3)
            {
                output_time2 = Convert.ToInt32(args[2]);
            }

            LanXIRESTBoundary rest = new LanXIRESTBoundary(lanxi_ip);

            // Open recorder application
            rest.PutRequestWithPath("/rest/rec/open", null);

            // Prepare generator
            string outputChannelStart = File.ReadAllText(@"OutputGenerator_OutputChannelStart.json");

            rest.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart);

            // Configure generator channels
            string outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetup.json");

            rest.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);

            // Start output
            rest.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart);
            if (IN_A_FRAME != 0)
            {
                rest.PutRequestWithPath("/rest/rec/apply", null);
            }

            Thread.Sleep(output_time1);

            // Change generator configuration (frequencies and amplitude)
            outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetup2.json");
            rest.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);

            Thread.Sleep(output_time2);

            // Stop output
            rest.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart);

            // Close recorder application
            rest.PutRequestWithPath("/rest/rec/close", null);
        }
        static void Main(string[] args)
        {
            if (numOfModules == 0)
            {
                Console.WriteLine("ERROR: Missing module IP(s).");
                goto DONE;
            }

            runTime = Stopwatch.StartNew();
            runTime.Start();

            for (int i = 0; i < numOfModules; i++)
            {
                try
                {
                    IPAddress ip;
                    bool      success = IPAddress.TryParse(modules_ip[i], out ip);
                    if (success)
                    {
                        ip = IPAddress.Parse(modules_ip[i]);
                        byte[] pIp = ip.GetAddressBytes();
                        if (pIp[0] == 0 || (pIp[0] + pIp[1] + pIp[2] + pIp[3]) == 0)
                        {
                            success = false;
                        }
                    }
                    if (!success)
                    {
                        Console.WriteLine("ERROR: '{0}' is not a valid IP address", modules_ip[i]);
                        goto DONE;
                    }

                    modules[i] = new LanXIRESTBoundary(modules_ip[i]);
                }
                catch (FormatException e)
                {
                    Console.WriteLine("Exception: {0}  ('{1}')", e.Message, modules_ip[i]);
                    goto DONE;
                }
            }
            StartThreads();
DONE:
            Console.WriteLine("\r\nPress ENTER to terminate");
            Console.ReadLine();

            stopThreads = true;
            Console.WriteLine("Stopping");
        }
        static readonly string LANXI_IP = "10.100.35.192"; // IP address (or hostname) of the LAN-XI module

        static void Main(string[] args)
        {
            // Use program arguments if specified, otherwise use constants.
            // Arguments are in the sequence [[[<lanxi_ip>] <output_file>] <samples_to_receive>]
            string lanxi_ip = LANXI_IP;

            if (args.Length >= 1)
            {
                lanxi_ip = args[0];
            }

            // Initialize boundary objects
            LanXIRESTBoundary rest = new LanXIRESTBoundary(lanxi_ip);

            //reboot the LAN-XI module
            rest.PutRequestWithPath("/rest/rec/reboot", null);
        }
        /// <summary>
        /// Sets up socket communication
        /// </summary>
        public static int SetModuleToIdle(LanXIRESTBoundary rest)
        {
            Dictionary <string, dynamic> dict;

            // Bring recorder back from any state to Idle state
            dict = rest.GetRequestWithPath("/rest/rec/onchange");
            if (dict == null)
            {
                return(-1);
            }
            if (dict["moduleState"] == "RecorderRecording")
            {
                rest.PutRequestWithPath("/rest/rec/measurements/stop", null);
                rest.WaitForRecorderState("RecorderStreaming");
                rest.PutRequestWithPath("/rest/rec/finish", null);
                rest.WaitForRecorderState("RecorderOpened");
                rest.PutRequestWithPath("/rest/rec/close", null);
                rest.WaitForRecorderState("Idle");
            }
            else if (dict["moduleState"] == "RecorderStreaming")
            {
                rest.PutRequestWithPath("/rest/rec/finish", null);
                rest.WaitForRecorderState("RecorderOpened");
                rest.PutRequestWithPath("/rest/rec/close", null);
                rest.WaitForRecorderState("Idle");
            }
            else if (dict["moduleState"] == "RecorderConfiguring")
            {
                rest.PutRequestWithPath("/rest/rec/cancel", null);
                rest.WaitForRecorderState("RecorderOpened");
                rest.PutRequestWithPath("/rest/rec/close", null);
                rest.WaitForRecorderState("Idle");
            }
            else if (dict["moduleState"] == "RecorderOpened")
            {
                rest.PutRequestWithPath("/rest/rec/close", null);
                rest.WaitForRecorderState("Idle");
            }
            return(0);
        }
        /// <summary>
        /// Changes module's state to 'RecorderRecording' and starts measurement.
        /// </summary>
        /// <param name="index">Module index</param>
        static void StartSDcarMeasuremnet(int index)
        {
            try
            {
                LanXIRESTBoundary module      = modules[index];
                int    numberOfActiveChannels = channelInfo[index].numOfactiveChannels;
                string columnLable            = channelInfo[index].lable;
                string module_ip = modules_ip[index];

                // Start measuring.
                module.PostRequestWithPath("/rest/rec/measurements", null);

                // Wait for module to enter RecorderRecording state
                string recorderRecording = "RecorderRecording";
                module.WaitForRecorderState(recorderRecording);

                Thread.Sleep(MEASURE_TIME * 1000);
            }
            catch (Exception ex)
            {
                Console.WriteLine("StartMeasuremnet(exception): {0}", ex.Message);
            }
        }
        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);

            // Set sync mode to stand-alone
            master.PutRequestWithPath("/rest/rec/syncmode", "{\"synchronization\": {\"mode\": \"stand-alone\",\"usegps\": false}}");
            slave.PutRequestWithPath("/rest/rec/syncmode", "{\"synchronization\": {\"mode\": \"stand-alone\"}}");

            // Start measurement
            // During this process commands are generally performed on SLAVEs first, finished with MASTER

            // 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(@"Frame_3050_3160_OpenParameters.json");

            slave.PutRequestWithPath("/rest/rec/open", openParameters);
            master.PutRequestWithPath("/rest/rec/open", openParameters);


            // Prepare generator
            string outputChannelStart = File.ReadAllText(@"Frame_3050_3160_OutputChannelStart.json");

            slave.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart);

            // Configure generator channels
            string outputChannelConfiguration = File.ReadAllText(@"Frame_3050_3160_OutputChannelSetup.json");

            slave.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);

            // Start output
            slave.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart);
            master.PutRequestWithPath("/rest/rec/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");

            // Get TEDS information
            S_Arr = slave.RequestWithPathTeds("/rest/rec/channels/input/all/transducers", "GET", null, false);
            M_Arr = master.RequestWithPathTeds("/rest/rec/channels/input/all/transducers", "GET", null, false);
            for (i = 0; i < S_Arr.Count; i++)
            {
                if (S_Arr[i] != null)
                {
                    Console.WriteLine("Slave Tranducer serialNumber {0}\r\n  type.number {1} ", S_Arr[0].serialNumber, S_Arr[0].type.number);
                }
            }
            for (i = 0; i < M_Arr.Count; i++)
            {
                if (M_Arr[i] != null)
                {
                    Console.WriteLine("Master Tranducer serialNumber {0}\r\n  type.number {1} ", M_Arr[0].serialNumber, M_Arr[0].type.number);
                }
            }

            // 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 MasterInputChannelConfiguration = File.ReadAllText(@"Frame_3050_3160_MasterInputChannelSetup.json");
            string SlaveInputChannelConfiguration  = File.ReadAllText(@"Frame_3050_3160_SlaveInputChannelSetup.json");

            slave.PutRequestWithPath("/rest/rec/channels/input", SlaveInputChannelConfiguration);
            master.PutRequestWithPath("/rest/rec/channels/input", MasterInputChannelConfiguration);

            // 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}\t{8}\t{9}",
                               outputSamples[0, 0][j], outputSamples[0, 1][j], outputSamples[0, 2][j], outputSamples[0, 3][j], outputSamples[0, 4][j], outputSamples[0, 5][j],
                               outputSamples[1, 0][j], outputSamples[1, 1][j], outputSamples[1, 2][j], outputSamples[1, 3][j]);
            }
            file.Close();
        }
Exemplo n.º 8
0
        static void Main(string[] args)
        {
            // Use program arguments if specified, otherwise use constants.
            // Arguments are in the sequence [[[<lanxi_ip>] <output_file>] <samples_to_receive>]
            string lanxi_ip    = LANXI_IP;
            string output_file = OUTPUT_FILE;

            if (args.Length >= 1)
            {
                lanxi_ip = args[0];
            }
            if (args.Length >= 2)
            {
                output_file = args[1];
            }
            if (args.Length >= 3)
            {
                samples_to_receive = Convert.ToInt32(args[2]);
            }

            Dictionary <string, dynamic> dict;

            // Initialize boundary objects
            LanXIRESTBoundary rest = new LanXIRESTBoundary(lanxi_ip);
            //Set module system time to PC time
            TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));

            rest.PutRequestWithPath("/rest/rec/module/time", Convert.ToInt64(t.TotalMilliseconds).ToString()); //The module will ignore this if time is already set with year >= 2009

            //Set systemtime and measurment time
            string SetPtpTime = "{\r\n\"synchronization\": {\r\n\"settime\": " + Convert.ToInt64(t.TotalMilliseconds).ToString() + "\r\n}\r\n}";

            rest.PutRequestWithPath("/rest/rec/syncmode", SetPtpTime);

            // Start measurement

            // Open the Recorder application on the LAN-XI module
            rest.PutRequestWithPath("/rest/rec/open", null);
            rest.WaitForRecorderState("RecorderOpened");

            // Create Recorder configuration
            rest.PutRequestWithPath("/rest/rec/create", null);
            rest.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
            // In this example a JSON file has been prepared with the desired configuration.
            string inputChannelConfiguration = File.ReadAllText(@"InputStreaming_InputChannelSetup.json");

            rest.PutRequestWithPath("/rest/rec/channels/input", inputChannelConfiguration);
            rest.WaitForRecorderState("RecorderStreaming");

            // Get the TCP port provided by the LAN-XI module for streaming samples
            dict = rest.GetRequestWithPath("/rest/rec/channels/input");
            dict = rest.GetRequestWithPath("/rest/rec/destination/socket");

            UInt16 port = (UInt16)dict["tcpPort"];

            Console.WriteLine("Streaming TCP port: {0}", port);

            // Start measuring
            rest.PostRequestWithPath("/rest/rec/measurements", null);
            rest.WaitForRecorderState("RecorderRecording");

            // Streaming should now be running

            // Let connectSocketAndStream() method handle socket connection
            // The socket connection may be established while the Recorder was in the "RecorderStreaming" state
            ConnectSocketAndStream(lanxi_ip, port);

            // Stop measuring and close socket
            rest.PutRequestWithPath("/rest/rec/measurements/stop", null);
            rest.WaitForRecorderState("RecorderStreaming");
            sock.Shutdown(SocketShutdown.Both);
            sock.Close();

            rest.PutRequestWithPath("/rest/rec/finish", null);
            rest.WaitForRecorderState("RecorderOpened");

            // Close Recorder application
            rest.PutRequestWithPath("/rest/rec/close", null);
            rest.WaitForRecorderState("Idle");

            StreamWriter file = new StreamWriter(output_file);

            for (int i = 0; i < outputSamples[0].Count; i++)
            {
                double value1 = (Convert.ToDouble(outputSamples[0][i]) * ScaleFactor[0]) / POWER2_23;
                double value2 = (Convert.ToDouble(outputSamples[1][i]) * ScaleFactor[1]) / POWER2_23;
                double value3 = (Convert.ToDouble(outputSamples[2][i]) * ScaleFactor[2]) / POWER2_23;
                double value4 = (Convert.ToDouble(outputSamples[3][i]) * ScaleFactor[3]) / POWER2_23;
                file.WriteLine("{0}\t{1}\t{2}\t{3}", value1.ToString("F6"), value2.ToString("F6"), value3.ToString("F6"), value4.ToString("F6"));
            }
            file.Close();
        }
        static readonly int IN_A_FRAME         = 1;           //

        static void Main(string[] args)
        {
            // Use program arguments if specified, otherwise use constants.
            // Arguments are in the sequence [[[<lanxi_ip>] <samples_to_receive>] <samples_to_prime>]
            string lanxi_ip           = LANXI_IP;
            int    samples_to_receive = SAMPLES_TO_RECEIVE;
            int    samples_to_prime   = SAMPLES_TO_PRIME;

            if (args.Length >= 1)
            {
                lanxi_ip = args[0];
            }
            if (args.Length >= 2)
            {
                samples_to_receive = Convert.ToInt32(args[1]);
            }
            if (args.Length >= 3)
            {
                samples_to_prime = Convert.ToInt32(args[2]);
            }

            // Initialize boundary object
            LanXIRESTBoundary rest = new LanXIRESTBoundary(lanxi_ip);

            // Start measurement

            // Open the Recorder application on the LAN-XI module
            rest.PutRequestWithPath("/rest/rec/open", null);
            rest.WaitForRecorderState("RecorderOpened");

            // Prepare generator
            string outputChannelStart = File.ReadAllText(@"InOutStreaming_OutputChannelStartStreaming.json");

            rest.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart);

            // Configure generator channels
            string outputChannelConfiguration = File.ReadAllText(@"InOutStreaming_OutputChannelSetupStreaming.json");

            rest.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);

            // Get port numbers to send samples to
            Dictionary <string, dynamic> dict = rest.GetRequestWithPath("/rest/rec/generator/output");

            UInt16[] outputPorts = new UInt16[2];
            outputPorts[0] = (UInt16)dict["outputs"][0]["inputs"][0]["port"];
            outputPorts[1] = (UInt16)dict["outputs"][1]["inputs"][0]["port"];

            Console.WriteLine("Output streaming TCP ports: {0} - {1}", outputPorts[0], outputPorts[1]);

            // Create Recorder configuration
            rest.PutRequestWithPath("/rest/rec/create", null);
            rest.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
            // In this example a JSON file has been prepared with the desired config.
            string inputChannelConfiguration = File.ReadAllText(@"InOutStreaming_InputChannelSetup.json");

            rest.PutRequestWithPath("/rest/rec/channels/input", inputChannelConfiguration);
            rest.WaitForRecorderState("RecorderStreaming");

            // Get the TCP port provided by the LAN-XI module for streaming samples
            dict = rest.GetRequestWithPath("/rest/rec/destination/socket");
            UInt16 inputPort = (UInt16)dict["tcpPort"];

            Console.WriteLine("Input streaming TCP port: {0}", inputPort);

            // Start measuring
            rest.PostRequestWithPath("/rest/rec/measurements", null);
            rest.WaitForRecorderState("RecorderRecording");

            // Streaming should now be running

            // Let connectSocketAndStream() method handle socket connection
            // The socket connection may be established while the Recorder was in the "RecorderStreaming" state
            SocketCommunication comm = new SocketCommunication(lanxi_ip, inputPort, outputPorts, samples_to_receive);
            Thread commThread        = new Thread(new ThreadStart(comm.ConnectSocketAndStream));

            commThread.Start();

            while (SocketCommunication.samplesReceived[0] < samples_to_prime || SocketCommunication.samplesReceived[1] < samples_to_prime)
            {
                Thread.Sleep(100);
            }

            // Start output
            rest.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart);
            if (IN_A_FRAME != 0)
            {
                rest.PutRequestWithPath("/rest/rec/apply", null);
            }

            while (commThread.IsAlive)
            {
                Thread.Sleep(10);
            }

            // Stop output
            rest.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart);

            // Stop measuring and close sockets
            rest.PutRequestWithPath("/rest/rec/measurements/stop", null);
            rest.WaitForRecorderState("RecorderStreaming");
            comm.inputSocket.Close();
            for (int i = 0; i < 2; i++)
            {
                comm.outputSockets[i].Close();
            }

            // Finish recording
            rest.PutRequestWithPath("/rest/rec/finish", null);
            rest.WaitForRecorderState("RecorderOpened");

            // Close Recorder application
            rest.PutRequestWithPath("/rest/rec/close", null);
            rest.WaitForRecorderState("Idle");

            // Module should now be back in the Idle state without the Recorder application running
        }
Exemplo n.º 10
0
        static void Main(string[] args)
        {
            // Use program arguments if specified, otherwise use constants.
            // Arguments are in the sequence [[[<lanxi_ip>] <freq1>] <freq2>]
            string lanxi_ip = LANXI_IP;
            int    freq1    = FREQ1;
            int    freq2    = FREQ2;

            if (args.Length >= 1)
            {
                lanxi_ip = args[0];
            }
            if (args.Length >= 3)
            {
                freq1 = Convert.ToInt32(args[1]);
                freq2 = Convert.ToInt32(args[2]);
            }
            Dictionary <string, dynamic> dict;

            LanXIRESTBoundary rest = new LanXIRESTBoundary(lanxi_ip);

            string syncParametersMaster = "{\"synchronization\": {\r\n\"mode\": \"stand-alone\" } } }";

            dict = rest.PutRequestWithPath("/rest/rec/syncmode", syncParametersMaster);
            if (dict == null)
            {
                Console.WriteLine("\r\nPress ENTER to terminate");
                Console.ReadLine();
                return;
            }

            // Open recorder application
            rest.PutRequestWithPath("/rest/rec/open", null);

            // Prepare generator
            string outputChannelStart = File.ReadAllText(@"OutputStreaming_OutputChannelStartStreaming.json");

            rest.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart);

            // Configure generator channels
            string outputChannelConfiguration = File.ReadAllText(@"OutputStreaming_OutputChannelSetupStreaming.json");

            rest.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);

            // Get port numbers to send samples to
            dict = rest.GetRequestWithPath("/rest/rec/generator/output");
            UInt16 port1 = (UInt16)dict["outputs"][0]["inputs"][0]["port"];
            UInt16 port2 = (UInt16)dict["outputs"][1]["inputs"][0]["port"];

            Console.WriteLine("Streaming TCP ports: {0} - {1}", port1, port2);

            // Let OutputHelper connect to the sockets and stream data
            OutputHelper output1Helper = new OutputHelper(lanxi_ip, port1, freq1);
            OutputHelper output2Helper = new OutputHelper(lanxi_ip, port2, freq2);
            Thread       output1Thread = new Thread(new ThreadStart(output1Helper.StreamToChannel));
            Thread       output2Thread = new Thread(new ThreadStart(output2Helper.StreamToChannel));

            output1Thread.Start();
            output2Thread.Start();

            // Wait until channels are primed
            while (!output1Helper.primed || !output2Helper.primed)
            {
                Thread.Sleep(100);
            }
            Console.WriteLine("Channels primed");

            // Start output
            rest.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart);
            if (IN_A_FRAME != 0)
            {
                rest.PutRequestWithPath("/rest/rec/apply", null);
            }

            // Wait for output sampling to finish
            while (output1Thread.IsAlive || output2Thread.IsAlive)
            {
                Thread.Sleep(10);
            }

            // Stop output
            rest.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart);

            // Close recorder application
            rest.PutRequestWithPath("/rest/rec/close", null);
        }
    //
    // This program demonstrates how to stream sample data from a LAN-XI module in
    // multi-socket mode, i.e. using one TCP stream per input channel on the module.
    //
    // It works with any LAN-XI module, and will stream data from all input channels
    // using the highest supported bandwidth. About two seconds of streamed data
    // will be saved to a text file in a format suitable for import into e.g. Matlab
    // or Excel.
    //
    // Users may specify the IP address of the LAN-XI module and the name of the
    // output file on the command line.
    //
    static void Main(string[] args)
    {
        // LAN-XI module IP address
        var ipAddr = (args.Length >= 1) ? args[0] : "192.168.1.101";

        // Name of output file to store samples from the module
        var fileName = (args.Length >= 2) ? args[1] : "LANXI.out";

        Console.WriteLine("LAN-XI module at {0}, saving streamed data to {1}", ipAddr, fileName);

        var rest = new LanXIRESTBoundary(ipAddr);

        // Open the recorder application in the module
        rest.PutRequestWithPath("/rest/rec/open", null);
        rest.WaitForRecorderState("RecorderOpened");

        // Prepare the module for a new recording
        rest.PutRequestWithPath("/rest/rec/create", null);
        rest.WaitForRecorderState("RecorderConfiguring");

        // Get the default recording setup from the module
        var setup            = rest.GetRequestWithPath("/rest/rec/channels/input/default");
        var numberOfChannels = ((ArrayList)setup["channels"]).Count;

        // Modify the setup to use multi-socket streaming on all channels
        for (var i = 0; i < numberOfChannels; i++)
        {
            setup["channels"][i]["destinations"] = new string [] { "multiSocket" };
        }

        // Convert modified setup back to JSON string
        var serializer = new JavaScriptSerializer();
        var setupJson  = serializer.Serialize(setup);

        // Apply the setup
        rest.PutRequestWithPath("/rest/rec/channels/input", setupJson);
        rest.WaitForRecorderState("RecorderStreaming");

        // Request a list of TCP ports to connect to, one port for each enabled input channel
        var portsResponse = rest.GetRequestWithPath("/rest/rec/destination/sockets");
        var ports         = (int [])((ArrayList)portsResponse["tcpPorts"]).ToArray(typeof(int));

        Console.WriteLine("Will stream samples from TCP ports {0}",
                          string.Join(", ", Array.ConvertAll(ports, port => port.ToString())));

        var samples = new ArrayList[numberOfChannels];
        var threads = new Thread[numberOfChannels];
        var sockets = new Socket[numberOfChannels];

        // Connect sockets to each TCP port and spin up threads to read from the sockets
        for (var i = 0; i < numberOfChannels; i++)
        {
            var endPoint = new IPEndPoint(IPAddress.Parse(ipAddr), ports[i]);
            sockets[i] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            sockets[i].Connect(endPoint);

            Console.WriteLine("Connected to {0}", endPoint);

            samples[i] = new ArrayList();

            var sock = sockets[i];
            var samp = samples[i];

            threads[i] = new Thread(() =>
            {
                try
                {
                    for (;;)
                    {
                        var header = ReadHeader(sock);
                        ReadMessage(sock, samp, (int)header.dataLength, header.messageType);
                    }
                }
                catch (Exception ex) when(ex is ObjectDisposedException || ex is SocketException)
                {
                    // Thrown when we close the socket
                }
            });

            threads[i].Start();
        }

        // Start streaming
        rest.PostRequestWithPath("/rest/rec/measurements", null);
        rest.WaitForRecorderState("RecorderRecording");

        // Collect some samples
        Console.WriteLine("Streaming data for 2 seconds...");
        Thread.Sleep(2000);

        // Stop streaming
        rest.PutRequestWithPath("/rest/rec/measurements/stop", null);
        rest.WaitForRecorderState("RecorderStreaming");

        // Close sockets, wait for threads to exit
        for (var i = 0; i < numberOfChannels; i++)
        {
            sockets[i].Shutdown(SocketShutdown.Both);
            sockets[i].Close();

            threads[i].Join();
        }

        // Close streaming session
        rest.PutRequestWithPath("/rest/rec/finish", null);
        rest.WaitForRecorderState("RecorderOpened");

        // Close recorder application
        rest.PutRequestWithPath("/rest/rec/close", null);
        rest.WaitForRecorderState("Idle");

        // Samples are streamed in blocks starting from the first channel to
        // the last channel. Unless we got lucky and streaming was stopped
        // exactly after receiving a block from the last channel, we will
        // have ended up with more samples from the first channel(s) than
        // the last channel. Prevent out-of-bounds reads from the buffers
        // by only reading up to the number of samples stored in the buffer
        // from the last channel.
        var lastChannel     = numberOfChannels - 1;
        var numberOfSamples = samples[lastChannel].Count;

        Console.WriteLine("Got {0} samples from each channel", numberOfSamples);

        Console.WriteLine("Writing output file");

        // Write samples to text file, each line containing
        // one sample from each channel, separated by tab
        using (var file = new StreamWriter(fileName))
        {
            for (var sample = 0; sample < numberOfSamples; sample++)
            {
                var line      = "";
                var separator = "";

                for (var channel = 0; channel < numberOfChannels; channel++)
                {
                    line     += separator + samples[channel][sample];
                    separator = "\t";
                }

                file.WriteLine(line);
            }
        }

        Console.WriteLine("Done");
    }
        static void Main(string[] args)
        {
            // Use program arguments if specified, otherwise use constants.
            // Arguments are in the sequence [[[<lanxi_ip>] <output_file>] <samples_to_receive>]
            string lanxi_ip    = LANXI_IP;
            string output_file = OUTPUT_FILE;
            Dictionary <string, dynamic> dict;

            if (args.Length == 0)
            {
                string fileName = @"CanStreaming_testInfo.json";
                if (File.Exists(fileName))
                {
                    string[] testInfo = File.ReadAllLines(fileName);
                    foreach (string line in testInfo)
                    {
                        string[] col = line.Split(',');
                        if (string.Compare(col[0], "ModuleIP") == 0)
                        {
                            lanxi_ip = col[1].Trim();
                        }

                        if (string.Compare(col[0], "TestTime") == 0)
                        {
                            testTime = Convert.ToInt32(col[1]);
                        }

                        if (string.Compare(col[0], "NumberOfLoops") == 0)
                        {
                            numberOfTests = Convert.ToInt32(col[1]);
                        }

                        if (string.Compare(col[0], "StopOnError") == 0)
                        {
                            stopOnError = Convert.ToBoolean(col[1]);
                        }

                        if (string.Compare(col[0], "VerifyData") == 0)
                        {
                            VerifyData = Convert.ToBoolean(col[1]);
                        }

                        if (string.Compare(col[0], "EnableObd2") == 0)
                        {
                            obd2Enabled = Convert.ToBoolean(col[1]);
                        }


                        if (string.Compare(col[0], "TestData") == 0)
                        {
                            for (int i = 0; i < 8; i++)
                            {
                                dataToTest[i] = Convert.ToByte(col[i + 1]);
                            }
                        }
                    }
                }
            }
            else
            {
                if (args.Length >= 1)
                {
                    lanxi_ip = args[0];
                }
                if (args.Length >= 2)
                {
                    output_file = args[1];
                }
                if (args.Length >= 3)
                {
                    samples_to_receive = Convert.ToInt32(args[2]);
                }
            }

            testTime *= 1000;                   // Conver it to millisconds.

            // Initialize boundary objects
            LanXIRESTBoundary rest = new LanXIRESTBoundary(lanxi_ip);



            // Start measurement
            if (SetModuleToIdle(rest) < 0)
            {
                return;
            }

            // Connect to CAN-IB module. Use the IPs from the Json file
//            string canibIPs = File.ReadAllText(@"CanStreaming_CanIbIPs.json");
//            if (rest.PutRequestWithPath("/rest/rec/can/connect", canibIPs) == null)
//                goto EXIT_STREAMING;


            // Open the Recorder application on the LAN-XI module
            if (rest.PutRequestWithPath("/rest/rec/open", null) == null)
            {
                goto EXIT_STREAMING;
            }
            rest.WaitForRecorderState("RecorderOpened");


            for (int loop = 0; loop < numberOfTests; loop++)
            {
                idCounter = 0;

                Console.WriteLine("\r\n\r\n************************** Test No: {0} **************************", loop + 1);



                //************************* Auto baud rate detection *************************
                // Note: Baud rate detection requires that CAN channel is connected to a CAN-bus
                //       with CAN activity.
                if (testBaudRateDetectCommand)
                {
                    string detectBaudrate = File.ReadAllText(@"CanStreaming_detectBaudRate.json");
                    dict = rest.PutRequestWithPath("/rest/rec/can/detectBaudRate", detectBaudrate);
                    if (dict == null)
                    {
                        goto EXIT_STREAMING;
                    }

                    var channels = dict["channels"] as ArrayList;
                    foreach (Dictionary <string, object> channel in channels)
                    {
                        var channelId = channel["channel"];
                        var baudRate  = channel["baudRate"];
                        Console.WriteLine("channel={0} baudRate={1}", channelId, baudRate);
                    }
                    //goto EXIT_STREAMING;
                }
                //****************************************************************************


                // Create Recorder configuration
                if (rest.PutRequestWithPath("/rest/rec/create", null) == null)
                {
                    goto EXIT_STREAMING;
                }
                rest.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
                // In this example a JSON file has been prepared with the desired configuration.
                string inputChannelConfiguration = File.ReadAllText(@"CanStreaming_ChannelSetup.json");
                if (inputChannelConfiguration.Length > 0)
                {
                    int j = 0;
                    for (int i = 0; i < 2; i++)
                    {
                        JavaScriptSerializer js = new JavaScriptSerializer();
                        dynamic d       = js.Deserialize <dynamic>(inputChannelConfiguration);
                        bool    enabled = Convert.ToBoolean(d["canChannels"][i]["enabled"]);
                        if (enabled == true)
                        {
                            enabledCanChannels[j++] = i + 1;
                        }
                    }
                    //Console.WriteLine("Number enabled CAN channels = {0}.", enabledCanChannels);
                }


/*
 *              var serializer = new JavaScriptSerializer();
 *              Dictionary<string, dynamic> json = serializer.Deserialize<Dictionary<string, object>>(inputChannelConfiguration);
 *
 */

                if (rest.PutRequestWithPath("/rest/rec/channels/input", inputChannelConfiguration) == null)
                {
                    goto EXIT_STREAMING;
                }
                rest.WaitForRecorderState("RecorderStreaming");



                //******************************** OBD-II ***********************************
                // First delete all messages
                string delMsg = File.ReadAllText(@"CanStreaming_DeleteAllObd2.json");
                if (rest.DeleteRequestWithPath("/rest/rec/can/obd2", delMsg) == null)
                {
                    goto EXIT_STREAMING;
                }


                // We assume that CAN channel 1 is looped back to channel 2
                if (obd2Enabled)
                {
                    string obd2Msg          = File.ReadAllText(@"CanStreaming_AddCanObd2.json");
                    JavaScriptSerializer js = new JavaScriptSerializer();
                    dynamic d       = js.Deserialize <dynamic>(obd2Msg);
                    dynamic dataArr = d["Obd2Messages"][0]["data"];
                    var     len     = dataArr.Length;
                    UInt16  chan    = Convert.ToUInt16(d["Obd2Messages"][0]["channel"]);
                    if (chan == 1)
                    {
                        obdChannel = 102;                   // Channel 1 sending OBD2 message and channel 2 receiving data
                    }
                    else if (chan == 2)
                    {
                        obdChannel = 101;                   // Channel 2 sending OBD2 message and channel 1 receiving data
                    }
                    else
                    {
                        Console.WriteLine("**************** ERROR **********************");
                        Console.WriteLine("ERROR: Invalid OBD channel number in the OBD-steup (channel={0}). Discarding OBD-setup.", chan);
                        obd2Enabled = false;
                    }

                    // Overwrite test data with data from first OBD2-message in the CanStreaming_AddCanObd2.json file
                    if (VerifyData)
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            if (i < len)
                            {
                                dataToTest[i] = Convert.ToByte(dataArr[i]);
                            }
                            else
                            {
                                dataToTest[i] = 0;
                            }
                        }
                    }

                    if (rest.PutRequestWithPath("/rest/rec/can/obd2", obd2Msg) == null)
                    {
                        goto EXIT_STREAMING;
                    }
                }
                //string delMsg = File.ReadAllText(@"CanStreaming_DeleteAllObd2.json");
                //if (rest.DeleteRequestWithPath("/rest/rec/can/obd2", delMsg)==null)
                //  goto EXIT_STREAMING;
                //****************************************************************************


                // Get the TCP port provided by the LAN-XI module for streaming samples
                dict = rest.GetRequestWithPath("/rest/rec/destination/socket");
                if (dict == null)
                {
                    goto EXIT_STREAMING;
                }

                UInt16 port = (UInt16)dict["tcpPort"];
                Console.WriteLine("Streaming TCP port: {0}", port);

                // Start measuring
                if (rest.PostRequestWithPath("/rest/rec/measurements", null) == null)
                {
                    goto EXIT_STREAMING;
                }
                rest.WaitForRecorderState("RecorderRecording");


                //***************************** Send Message ********************************
                if (sendMessage > 0)
                {
                    string sendMessageCommand = File.ReadAllText(@"CanStreaming_SendMessages.json");
                    for (int i = 0; i < sendMessage; i++)
                    {
                        if (rest.PutRequestWithPath("/rest/rec/can/sendMessages", sendMessageCommand) == null)
                        {
                            goto EXIT_STREAMING;
                        }
                        Thread.Sleep(10);
                    }
                }
                //****************************************************************************



                // Streaming should now be running

                // Let connectSocketAndStream() method handle socket connection
                // The socket connection may be established while the Recorder was in the "RecorderStreaming" state
                ConnectSocketAndStream(lanxi_ip, port);
//                Console.WriteLine("");

                // Stop measuring and close socket
                if (rest.PutRequestWithPath("/rest/rec/measurements/stop", null) == null)
                {
                    goto EXIT_STREAMING;
                }
                rest.WaitForRecorderState("RecorderStreaming");
                sock.Shutdown(SocketShutdown.Both);
                sock.Close();


                // Free memory used for streaming
                //for (int i = 0; i < outputSamples.Count(); i++)
                //{
                //    outputSamples[i].Clear();
                //}


                if (obd2Enabled)
                {
                    string delAllObd2Msg = File.ReadAllText(@"CanStreaming_DeleteAllObd2.json");
                    if (rest.DeleteRequestWithPath("/rest/rec/can/obd2", delAllObd2Msg) == null)
                    {
                        goto EXIT_STREAMING;
                    }
                }


                if (rest.PutRequestWithPath("/rest/rec/finish", null) == null)
                {
                    goto EXIT_STREAMING;
                }
                rest.WaitForRecorderState("RecorderOpened");
//                Console.WriteLine("*** Number of: messages={0} errors={1} ***", idCounter, totalErrors);
                if (stopOnError && dataError)
                {
                    break;
                }
                idCounter = 0;
                totalReceivedCanPackages = 0;
                dataError = false;
            }

            // Close Recorder application
            rest.PutRequestWithPath("/rest/rec/close", null);
            rest.WaitForRecorderState("Idle");
            return;

EXIT_STREAMING:
            SetModuleToIdle(rest);
            return;

            //StreamWriter file = new StreamWriter(output_file);
            //for (int i = 0; i < outputSamples[0].Count; i++)
            //{
            //    finle.WriteLine("{0}\t{1}\t{2}\t{3}", outputSamples[0][i], outputSamples[1][i], outputSamples[2][i], /*outputSamples[3][i]*/0);
            //}
            //file.Close();
        }
        static void Main(string[] args)
        {
            // Use program arguments if specified, otherwise use constants.
            // Arguments are in the sequence [[[<lanxi_ip>] <output_file>] <samples_to_receive>]
            string lanxi_ip    = LANXI_IP;
            string output_file = OUTPUT_FILE;

            if (args.Length >= 1)
            {
                lanxi_ip = args[0];
            }
            if (args.Length >= 2)
            {
                output_file = args[1];
            }
            if (args.Length >= 3)
            {
                samples_to_receive = Convert.ToInt32(args[2]);
            }

            Dictionary <string, dynamic> dict;

            // Initialize boundary objects
            LanXIRESTBoundary rest = new LanXIRESTBoundary(lanxi_ip);

            // Start measurement
            string syncParametersMaster = "{\"synchronization\": {\r\n\"mode\": \"ptp\",\r\n\"domain\": 11,\"preferredMaster\": true } } }";

            dict = rest.PutRequestWithPath("/rest/rec/syncmode", syncParametersMaster);
            if (dict == null)
            {
                Console.WriteLine("\r\nPress ENTER to terminate");
                Console.ReadLine();
                return;
            }
            // Open the Recorder application on the LAN-XI module
            rest.PutRequestWithPath("/rest/rec/open", null);

            // Wait for all modules to be ready; Input in Sampling state, and module in the RecorderOpened state.
            rest.WaitForInputState("Sampling");
            rest.WaitForRecorderState("RecorderOpened");

            // Create Recorder configuration
            rest.PutRequestWithPath("/rest/rec/create", null);
            rest.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
            // In this example a JSON file has been prepared with the desired configuration.
            string inputChannelConfiguration = File.ReadAllText(@"InputStreaming_InputChannelSetup.json");

            rest.PutRequestWithPath("/rest/rec/channels/input", inputChannelConfiguration);
            rest.WaitForRecorderState("RecorderStreaming");

            dict = rest.PutRequestWithPath("/rest/rec/channels/input/bridgeNulling",
                                           "{\"channels\" : [{\"nulling\" : \"Automatic\", \"channel\" : 1},{\"nulling\" : \"Automatic\", \"channel\" : 2},{\"nulling\" : \"Automatic\", \"channel\" : 3}]}");

            double val1 = (double)dict["channels"][0]["nullingVoltage"];
            double val2 = (double)dict["channels"][1]["nullingVoltage"];
            double val3 = (double)dict["channels"][2]["nullingVoltage"];

            Console.WriteLine("Nulling: {0}, {1}, {2}", val1, val2, val3);
            // Get the TCP port provided by the LAN-XI module for streaming samples
            dict = rest.GetRequestWithPath("/rest/rec/destination/socket");

            UInt16 port = (UInt16)dict["tcpPort"];

            Console.WriteLine("Streaming TCP port: {0}", port);

            // Start measuring
            rest.PostRequestWithPath("/rest/rec/measurements", null);
            rest.WaitForRecorderState("RecorderRecording");

            // Streaming should now be running

            // Let connectSocketAndStream() method handle socket connection
            // The socket connection may be established while the Recorder was in the "RecorderStreaming" state
            ConnectSocketAndStream(lanxi_ip, port);

            // Stop measuring and close socket
            rest.PutRequestWithPath("/rest/rec/measurements/stop", null);
            rest.WaitForRecorderState("RecorderStreaming");
            sock.Shutdown(SocketShutdown.Both);
            sock.Close();

            rest.PutRequestWithPath("/rest/rec/finish", null);
            rest.WaitForRecorderState("RecorderOpened");

            // Close Recorder application
            rest.PutRequestWithPath("/rest/rec/close", null);
            rest.WaitForRecorderState("Idle");

            StreamWriter file = new StreamWriter(output_file);

            for (int i = 0; i < outputSamples[0].Count; i++)
            {
                file.WriteLine("{0}\t{1}\t{2}\t{3}", outputSamples[0][i], outputSamples[1][i], outputSamples[2][i], /*outputSamples[3][i]*/ 0);
            }
            file.Close();
        }
        static void Main(string[] args)
        {
            if (numOfModules == 0)
            {
                Console.WriteLine("ERROR: Missing module IP(s).");
                goto DONE;
            }

            Stopwatch runTime = Stopwatch.StartNew();

            runTime.Start();
            Stopwatch taskTime = Stopwatch.StartNew();

            taskTime.Start();

            for (int i = 0; i < numOfModules; i++)
            {
                try
                {
                    IPAddress ip;
                    bool      success = IPAddress.TryParse(modules_ip[i], out ip);
                    if (success)
                    {
                        ip = IPAddress.Parse(modules_ip[i]);
                        byte[] pIp = ip.GetAddressBytes();
                        if (pIp[0] == 0 || (pIp[0] + pIp[1] + pIp[2] + pIp[3]) == 0)
                        {
                            success = false;
                        }
                    }
                    if (!success)
                    {
                        Console.WriteLine("ERROR: '{0}' is not a valid IP address", modules_ip[i]);
                        goto DONE;
                    }

                    modules[i] = new LanXIRESTBoundary(modules_ip[i]);
                }
                catch (FormatException e)
                {
                    Console.WriteLine("Exception: {0}  ('{1}')", e.Message, modules_ip[i]);
                    goto DONE;
                }
            }

            List <Task <int> > tasks = new List <Task <int> >();

            GoToStartState(tasks);                                  // Make sure that all modules are in Idle state
            TimeSpan startStateTime = GetElapsedTime(taskTime);

            SetSychronizationMode(tasks);
            TimeSpan ptpLockingTime = GetElapsedTime(taskTime);

            OpenRecorder();
            GoToConfigurationRecordingState(tasks);
            TimeSpan cfgStateTime = GetElapsedTime(taskTime);

            RecorderSetup(tasks);                                   // Send channel setup(s) and wait for modules to settle
            TimeSpan settlingTime = GetElapsedTime(taskTime);

            GotToInputSynchronizeState(tasks);                 // Wait for modules to enter the Synchronized input state
            GoToRecorderStreamingState(tasks);                 // Change state to 'RecorderStreaming' and waits for PTP locked state

            GoToRecorderRecordingState();                      // Enters 'RecorderRecording' state and starts measurement
            TimeSpan measuringTime = GetElapsedTime(taskTime);

            GoToStartState(tasks);                                  // Stops measurement and gets modules into 'Idle' state
            TimeSpan restoreTime = GetElapsedTime(taskTime);

            taskTime.Stop();
            runTime.Stop();
            TimeSpan totalRunTime = runTime.Elapsed;

            Console.WriteLine();
            Console.WriteLine("**************************************************");
            Console.WriteLine("Get to Idle state:      {0}", startStateTime);   // Time to get moule into Idle state (if it is left in any other state)
            Console.WriteLine("PTP locking time:       {0}", ptpLockingTime);   // Time used to enter 'RecorderStreaming' state and PTP locked sate
            Console.WriteLine("Configuration time:     {0}", cfgStateTime);     // Time used to get module from 'Idle' to 'RecorderConfiguring' state
            Console.WriteLine("Setup + settling time:  {0}", settlingTime);     // Channel setup and waiting for settling
            Console.WriteLine("Measuring time:         {0}", measuringTime);    // Time used to enter 'RecorderRecording' state and measuring
            Console.WriteLine("Restore (to idle) time: {0}", restoreTime);      // Stop recording and getting module back to Idle state
            Console.WriteLine("Total run time:         {0}", totalRunTime);
            Console.WriteLine("**************************************************");

DONE:
            Console.WriteLine("\r\nPress ENTER to terminate");
            Console.ReadLine();
        }
        static readonly int IN_A_FRAME  = 1;           //

        static void Main(string[] args)
        {
            // Use program arguments if specified, otherwise use constants
            // Arguments are in the sequence [[[<lanxi_ip>] <output_time>] <output_time2>]
            string lanxi_ip     = LANXI_IP;
            int    output_time1 = OUTPUT_TIME;
            int    i;

            if (args.Length >= 1)
            {
                lanxi_ip = args[0];
            }
            if (args.Length >= 2)
            {
                output_time1 = Convert.ToInt32(args[1]);
            }

            LanXIRESTBoundary rest  = new LanXIRESTBoundary(lanxi_ip);
            string            state = rest.GetRecorderState();

            if (state.Equals("Idle"))
            {
                // Open recorder application
                rest.PutRequestWithPath("/rest/rec/open", null);
                rest.WaitForRecorderState("RecorderOpened");

                // Prepare generator
                string outputChannelStart = File.ReadAllText(@"OutputGenerator_OutputChannelStart.json");
                string outputChannelConfiguration;
                for (i = 0; i < 8; i++)
                {
                    rest.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart); //prepare, when channging signal type

                    // Configure generator channel
                    switch (i)
                    {
                    case 0:    //rember to set input channel to DC
                        outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetupDC.json"); break;

                    case 1:
                        outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetupSine.json"); break;

                    case 2:    //direction UP-UP-UP
                        outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetupLinSweep.json"); break;

                    case 3:    //direction UP-DOWN-UP-DOWN
                        outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetupLogSweep.json"); break;

                    case 4:
                        outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetupRandom.json"); break;

                    case 5:
                        outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetupPseudoRandom.json"); break;

                    case 6:
                        outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetupSquare.json"); break;

                    case 7:
                        outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetupBurst.json"); break;

                    default:
                        outputChannelConfiguration = File.ReadAllText(@"OutputGenerator_OutputChannelSetupSine.json"); break;
                    }
                    rest.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);

                    // Start output
                    rest.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart);
                    if (IN_A_FRAME != 0)
                    {
                        rest.PutRequestWithPath("/rest/rec/apply", null);
                    }

                    Thread.Sleep(output_time1);
                }

                // Close recorder application
                rest.PutRequestWithPath("/rest/rec/close", null);
            }
            else
            {
                Console.WriteLine("Module is not Idle, stat is {0}", state);
                Thread.Sleep(1000);
            }
        }
        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);

            SetRecorderStateTo(master, "Idle");
            SetRecorderStateTo(slave, "Idle");

            // 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(@"CIC_SyncParametersMaster.json");

            master.PutRequestWithPath("/rest/rec/syncmode", syncParametersMaster);
            string syncParametersSlave = File.ReadAllText(@"CIC_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(@"CIC_OpenParameters.json");

            slave.PutRequestWithPath("/rest/rec/open", openParameters);
            master.PutRequestWithPath("/rest/rec/open", openParameters);

            /*
             * // Prepare generator
             * string outputChannelStart = File.ReadAllText(@"CIC_OutputChannelStart.json");
             * slave.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart);
             *
             * // Configure generator channels
             * string outputChannelConfiguration = File.ReadAllText(@"CIC_OutputChannelSetup.json");
             * slave.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);
             *
             * // Start output
             * slave.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart);
             * master.PutRequestWithPath("/rest/rec/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");

            string CicConfig = File.ReadAllText(@"Cic_Configuration.json");

            slave.PutRequestWithPath("/rest/rec/channels/cic", CicConfig);


            // The body has been prepared and stored in CIC_MasterInputChannelSetup.json.
            string MasterInputChannelConfiguration = File.ReadAllText(@"CIC_MasterInputChannelSetup.json");
            string SlaveInputChannelConfiguration  = File.ReadAllText(@"CIC_SlaveInputChannelSetup.json");

            slave.PutRequestWithPath("/rest/rec/channels/input", SlaveInputChannelConfiguration);
            master.PutRequestWithPath("/rest/rec/channels/input", MasterInputChannelConfiguration);

            // 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();
        }
        /// <summary>
        /// Changes the recorder state to desired one. It can be changed from any state, but in one direction as shown:
        ///     RecorderRecording-->RecorderStreaming-->RecorderConfiguring-->RecorderOpened-->Idle
        /// </summary>
        /// <param name="module">LANXI module</param>
        /// <param name="state">Desired recorder state to achieve</param>
        /// <returns>
        ///     0   Successful
        ///     1   Unable to change to desired state
        ///    -1   Any error
        /// </returns>
        static public int SetRecorderStateTo(LanXIRESTBoundary module, string state)
        {
            Dictionary <string, dynamic> dict;
            bool success = false;
            bool wait    = false;

            do
            {
                dict = module.GetRequestWithPath("/rest/rec/onchange");
                if (dict == null)
                {
                    return(-1);
                }

                if (dict["moduleState"] == state)
                {
                    return(0);
                }

                if (dict["moduleState"] == "RecorderRecording")
                {
                    module.PutRequestWithPath("/rest/rec/measurements/stop", null);
                    success = module.WaitForRecorderState("RecorderStreaming");
                    wait    = true;
                }
                else if (dict["moduleState"] == "RecorderStreaming")
                {   // Check for backward state change request
                    if (state == "RecorderRecording")
                    {
                        return(1);
                    }

                    module.PutRequestWithPath("/rest/rec/finish", null);
                    success = module.WaitForRecorderState("RecorderOpened");
                    wait    = true;
                }
                else if (dict["moduleState"] == "RecorderConfiguring")
                {   // Check for backward state change request
                    if (state == "RecorderRecording" || state == "RecorderStreaming")
                    {
                        return(1);
                    }

                    module.PutRequestWithPath("/rest/rec/cancel", null);
                    success = module.WaitForRecorderState("RecorderOpened");
                    wait    = true;
                }
                else if (dict["moduleState"] == "RecorderOpened")
                {   // Check for backward state change request
                    if (state == "RecorderRecording" || state == "RecorderStreaming" || state == "RecorderConfiguring")
                    {
                        return(1);
                    }

                    module.PutRequestWithPath("/rest/rec/close", null);
                    success = module.WaitForRecorderState("Idle");
                    wait    = true;
                }
                else if (dict["moduleState"] == "Idle")
                {   // Check for backward state change request
                    if (state == "RecorderRecording" || state == "RecorderStreaming" || state == "RecorderConfiguring" || state == "RecorderOpened")
                    {
                        return(1);
                    }

                    if (wait)
                    {
                        Thread.Sleep(1000);
                    }
                    return(0);
                }
                else
                {
                    Console.WriteLine("ERROR: Unknown module state {0}", dict["moduleState"]);
                    break;
                }
            } while (success);      // Loop until desired state is reached

            Console.WriteLine("ERROR: {0}, Cannot change module state from {1} to {2}", Thread.CurrentThread.Name, dict["moduleState"], state);
            return(-1);
        }
Exemplo n.º 18
0
        static void Main(string[] args)
        {
            string module_ip         = MODULE_IP;
            string output_file       = OUTPUT_FILE;
            int    samples_to_stream = SAMPLES_TO_STREAM;
            int    freq = FREQ;
            int    runs = RUNS;

            if (args.Length >= 2)
            {
                module_ip = args[0];
                module_ip = args[1];
            }
            if (args.Length >= 3)
            {
                output_file = args[2];
            }
            if (args.Length >= 5)
            {
                samples_to_stream = Convert.ToInt32(args[3]);
                samples_to_record = Convert.ToInt32(args[4]);
            }
            if (args.Length >= 6)
            {
                freq = Convert.ToInt32(args[5]);
            }
            if (args.Length >= 7)
            {
                output_samples_to_prime = Convert.ToInt32(args[6]);
            }
            if (args.Length >= 8)
            {
                fs = Convert.ToUInt32(args[7]);
            }
            if (args.Length >= 9)
            {
                runs = Convert.ToInt32(args[8]);
            }

            PowerControl.Actions.PowerCycle();

            LanXIRESTBoundary generator = new LanXIRESTBoundary(module_ip);
            LanXIRESTBoundary recorder  = new LanXIRESTBoundary(module_ip);

            generator.PutRequestWithPath("/rest/rec/open", null);
            //recorder.PutRequestWithPath("/rest/rec/open", null);

            recorder.PutRequestWithPath("/rest/rec/create", null);

            string inputChannelConfiguration = File.ReadAllText(@"StreamingFastCycles_InputChannelSetup.json");

            recorder.PutRequestWithPath("/rest/rec/channels/input", inputChannelConfiguration);

            Dictionary <string, dynamic> inputStreamingDestination = recorder.GetRequestWithPath("/rest/rec/destination/socket");
            UInt16 inputStreamingPort = (UInt16)inputStreamingDestination["tcpPort"];

            recorder_port = inputStreamingPort;

            string outputChannelStart = File.ReadAllText(@"StreamingFastCycles_OutputChannelStart.json");

            generator.PutRequestWithPath("/rest/rec/generator/prepare", outputChannelStart);

            string outputChannelConfiguration = File.ReadAllText(@"StreamingFastCycles_OutputChannelSetup.json");

            generator.PutRequestWithPath("/rest/rec/generator/output", outputChannelConfiguration);

            Dictionary <string, dynamic> streamingPorts = generator.GetRequestWithPath("/rest/rec/generator/output");
            UInt16 streamingPort1 = (UInt16)streamingPorts["outputs"][0]["inputs"][0]["port"];
            UInt16 streamingPort2 = (UInt16)streamingPorts["outputs"][1]["inputs"][0]["port"];

            OutputHelper streamingHelper1 = new OutputHelper(module_ip, streamingPort1, freq, fs);
            OutputHelper streamingHelper2 = new OutputHelper(module_ip, streamingPort2, freq, fs);
            Thread       streamingThread1 = new Thread(new ThreadStart(streamingHelper1.StreamToChannel));
            Thread       streamingThread2 = new Thread(new ThreadStart(streamingHelper2.StreamToChannel));

            streamingThread1.Start();
            streamingThread2.Start();

            generator.PutRequestWithPath("/rest/rec/generator/start", outputChannelStart);

            while (!streamingHelper1.primed || !streamingHelper2.primed)
            {
                Thread.Sleep(10);
            }

            for (int run = 0; run < runs; run++)
            {
                samplesReceived      = new int[] { 0, 0, 0, 0 };
                inputSamplesReceived = new ArrayList[] { new ArrayList(), new ArrayList(), new ArrayList(), new ArrayList() };
                inputSampleBuffer    = new ArrayList();

                Thread inputStreamingThread = new Thread(new ThreadStart(ConnectSocketAndStream));
                inputStreamingThread.Start();

                recorder.PostRequestWithPath("/rest/rec/measurements", null);

                while (inputStreamingThread.IsAlive)
                {
                    Thread.Sleep(10);
                }

                recorder.PutRequestWithPath("/rest/rec/measurements/stop", null);

                inputSocket.Shutdown(SocketShutdown.Both);
                inputSocket.Close();

                StreamWriter file = new StreamWriter(output_file + "_" + run + ".out");
                for (int i = 0; i < inputSamplesReceived[0].Count; i++)
                {
                    file.WriteLine("{0}", inputSamplesReceived[CHANNEL_TO_STORE - 1][i]);
                }
                file.Close();
            }

            output = false;

            while (streamingThread1.IsAlive || streamingThread2.IsAlive)
            {
                Thread.Sleep(10);
            }

            generator.PutRequestWithPath("/rest/rec/generator/stop", outputChannelStart);

            recorder.PutRequestWithPath("/rest/rec/finish", null);

            //generator.PutRequestWithPath("/rest/rec/close", null);
            recorder.PutRequestWithPath("/rest/rec/close", null);
        }
        /// Changes module's state to 'RecorderRecording', starts measurement, receives samples and saves into file.
        /// </summary>
        /// <param name="index">Module index</param>
        static void StartSocketMeasuremnet(int index)
        {
            try
            {
                LanXIRESTBoundary module      = modules[index];
                int    numberOfActiveChannels = channelInfo[index].numOfactiveChannels;
                string columnLable            = channelInfo[index].lable;
                string module_ip = modules_ip[index];


                if (index == 0)
                {
                    Thread.CurrentThread.Name = outputFilePath + "Master(" + module_ip + ")";
                }
                else
                {
                    Thread.CurrentThread.Name = outputFilePath + "Slave(" + module_ip + ")";
                }


                StreamWriter file = new StreamWriter(Thread.CurrentThread.Name + ".csv");
                file.WriteLine(columnLable);


                // Prepare buffer to receive samples from module
                int[]   samplesReceived = new int[numberOfActiveChannels];   // Contains the number of accumulated samples received- for demo purpose. Array of one array per LAN-XI module, containing one integer per input channel.
                int[][] outputSamples   = new int[numberOfActiveChannels][]; // Buffers for storing samples fetched from the LAN-XI module. Requires one array per active channel
                                                                             // Allocate buffer for samples
                for (int channel = 0; channel < numberOfActiveChannels; channel++)
                {
                    outputSamples[channel]   = new int[4096]; // Buffer size will dynamically adjusted if required
                    samplesReceived[channel] = 0;
                }

                // Get the TCP ports provided by each LAN-XI module for streaming samples
                Dictionary <string, dynamic> dict = module.GetRequestWithPath("/rest/rec/destination/socket");
                UInt16 modulePort = (UInt16)dict["tcpPort"];

                // Connect the streaming socket to the LAN - XI module defined by address/ port.
                IPEndPoint remoteEP = new IPEndPoint(Dns.GetHostAddresses(module_ip)[0], modulePort);
                // Socket used when fetching samples from the LAN-XI module
                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.Connect(remoteEP);

                if (index != 0)
                {
                    // Start measuring on slaves, wait for trigger.
                    module.PostRequestWithPath("/rest/rec/measurements", null);
                    // Wait for module to enter RecorderRecording state
                    string recorderRecording = "RecorderRecording";
                    module.WaitForRecorderState(recorderRecording);
                    barrier.SignalAndWait();
                }
                else
                {
                    // Start measuring on master and send trigger
                    barrier.SignalAndWait();
                    Thread.Sleep(200);
                    module.PostRequestWithPath("/rest/rec/measurements", null);
                    // Wait for module to enter RecorderRecording state
                    string recorderRecording = "RecorderRecording";
                    module.WaitForRecorderState(recorderRecording);
                }

                // Handle streaming
                StreamingHeader streamingHeader;
                int             channelSamples = 0;
                bool            waitingForSamples;
                do
                {
                    waitingForSamples = false;

                    for (int channel = 0; channel < numberOfActiveChannels; channel++)
                    {
                        if (samplesReceived[channel] < SAMPLES_TO_RECEIVE) // If received samples for current channel is incomplete
                        {
                            waitingForSamples         = true;
                            streamingHeader           = ReadHeader(sock);
                            channelSamples            = ReadMessage(sock, (int)streamingHeader.dataLength, streamingHeader.messageType, ref outputSamples);
                            samplesReceived[channel] += channelSamples;  // Accumulate number of samples gathered for current channel
                        }
                    }

                    if (waitingForSamples)
                    {
                        Console.WriteLine("{0} Samples received:  {1}", Thread.CurrentThread.Name, string.Join(", ", samplesReceived));

                        // Write samples to file. Each line contains one sample from each active channel
                        for (int i = 0; i < channelSamples; i++)
                        {
                            for (int channel = 0; channel < numberOfActiveChannels; channel++)
                            {
                                file.Write(string.Format("{0,15:d8},", outputSamples[channel][i])); // Add sample from current channel
                            }
                            file.WriteLine();                                                       // Change line
                        }
                    }
                } while (waitingForSamples);

                file.Close();
                // Stop streaming
                module.PutRequestWithPath("/rest/rec/measurements/stop", null);
                module.WaitForRecorderState("RecorderStreaming");

                // Close sockets
                sock.Shutdown(SocketShutdown.Both);
                sock.Close();
                // Close streaming session
                module.PutRequestWithPath("/rest/rec/finish", null);
                module.WaitForRecorderState("RecorderOpened");

                // Close recorder application
                module.PutRequestWithPath("/rest/rec/close", null);
                module.WaitForRecorderState("Idle");
            }
            catch (Exception ex)
            {
                Console.WriteLine("StartMeasuremnet(exception): {0}", ex.Message);
            }
        }