using System; using System.IO; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Linq; using System.Text; using System.Net; using System.Threading; using System.Timers; namespace EdgeTech.SonarComms.Demo { class MainProgram { const string SonarCLI_Version = "1.1.2"; const string _versionInfo = "$Header: MainProgram.cs Revision:1.39 Fri Aug 03 10:04:46 2012 mps $"; private static string versionInfo; public static bool done = false; public static bool sub_bottom_being_used = false; public static bool side_scan_low_being_used = false; public static bool side_scan_high_being_used = false; public static SonarMessage.SonarMessagePingType[] pulseList = new SonarMessage.SonarMessagePingType[SonarMessage.MAX_NUM_ENTRIES_IN_PULSE_LIST]; public static bool pulseListDefined = false; public static bool doPulseListOnly = false; public static bool getSystemTypeOnly = false; public static int numPulses = 0; public static int masterSubsystem = SIDE_SCAN_HIGH; // Default // @mps 7/6/2012 public static int slave1Subsystem = -1; public static int slave2Subsystem = -1; public static SonarMessage.Header aliveHeader = new SonarMessage.Header(); public const int DefaultTimerInterval = 1000; // Do housekeeping every 1000 milliseconds private static System.Timers.Timer HouseKeepingTimer; const string defaultIniFile = "sonar_cli.ini"; public static string iniFilename; static byte[] iniData; public static StringBuilder helpInfo = new StringBuilder(); //public static StringBuilder dataLog = new StringBuilder(0x100000); public static int sequenceNumber = 0; // For Keep-Alive message private static Object thisLock = new Object(); public const byte LF = 10; // ASCII value for LineFeed public const byte CR = 13; // ASCII value for CarriageReturn public static string NL = Environment.NewLine; // Compliant version of newline? public const int SUB_BOTTOM = 0; public const int SIDE_SCAN_LOW = 20; public const int SIDE_SCAN_HIGH = 21; public const int PING_ON = 1; public const int PING_OFF = 0; public const int TRIGGER_MODE_INTERNAL = 0; public const int TRIGGER_MODE_EXTERNAL = 1; public const int TRIGGER_MODE_COUPLED = 2; public const int COMMAND_BUFSIZE = 0x10000; // Tcp/IP buffer size for command channel (0x10000 = 65,536) public const int DATA_BUFSIZE = 0x100000; // Tcp/IP buffer size for data channel (0x100000 = 1,048,576) public const int NOT_FOUND = -999; public const int NOT_USED = -1; public const int CH_0 = 0; public const int CH_1 = 1; public struct structSonarParameters { public IPAddress ipaddr; public int cmdPort; public int dataPort; public double Range0; public double Range20; public double Range21; public SonarMessage.TriggerParametersType Master; public SonarMessage.TriggerParametersType Slave1; public SonarMessage.TriggerParametersType Slave2; public int Power0; public int Power20; public int Power21; public int TriggerMode0; public int TriggerMode20; public int TriggerMode21; public int ReturnActivePingData0; public int ReturnActivePingData20; public int ReturnActivePingData21; public int SetTimeMethod; public int masterPulseID; public int slave1PulseID; public int slave2PulseID; } public static structSonarParameters sonarParameters = new structSonarParameters(); public struct structPulseList { public SonarMessage.SonarMessagePingType[] pulseList; public int numPulses; public bool pulseListDefined; // Constructor public structPulseList(int size) { pulseList = new SonarMessage.SonarMessagePingType[size]; numPulses = 0; pulseListDefined = false; } } public static structPulseList subBottomPulseList = new structPulseList((int)SonarMessage.MAX_NUM_ENTRIES_IN_PULSE_LIST); public static structPulseList sideScanLowPulseList = new structPulseList((int)SonarMessage.MAX_NUM_ENTRIES_IN_PULSE_LIST); public static structPulseList sideScanHighPulseList = new structPulseList((int)SonarMessage.MAX_NUM_ENTRIES_IN_PULSE_LIST); public struct PingCouplingParametersType { /* Subsystem number to trigger this subsystem on; i.e. source trigger */ public Int32 subSystem; /* Trigger on every Nth event (minimum value of 1). */ public UInt32 triggerDivisor; /* Trigger delay in micro-seconds for external or coupled modes. */ /* Trigger inhibit time for gated mode. (minimum value of 0) */ public UInt32 triggerDelay; } public static PingCouplingParametersType pingCouplingParameters = new PingCouplingParametersType(); public static CPortIO cmdChannel = new CPortIO("CommandChannel", COMMAND_BUFSIZE); public static CPortIO dataChannel = new CPortIO("DataChannel", DATA_BUFSIZE); static void Main(string[] args) { // If initialization file not found or there are erroneous inputs then quit, otherwise initialize sonar parameters if (!initialize(args)) return; if (Utils.doThisPrint(1)) Console.WriteLine("The Main thread has started."); while (!done) { if (!cmdChannel.isConnected) // If not connected then try to reconnect { Thread.Sleep(1000); // Wait 1 second before attempting to reconnect cmdChannel.Connect(COMMAND_BUFSIZE); if (cmdChannel.isConnected) { if(Utils.doThisPrint(3)) Console.WriteLine("Command channel connected "); cmdChannel.connectCount++; MainProgram.bootSonar(); } else { if(Utils.doThisPrint(3)) Console.WriteLine("Command channel not connected "); } } if (!dataChannel.isConnected) // If not connected then try to reconnect { Thread.Sleep(1000); // Wait 1 second before attempting to reconnect dataChannel.Connect(DATA_BUFSIZE); if (dataChannel.isConnected) { if(Utils.doThisPrint(3)) Console.WriteLine("Data channel connected "); dataChannel.connectCount++; } else { if(Utils.doThisPrint(3)) Console.WriteLine("Data channel not connected "); } } if (pulseListDefined && doPulseListOnly) { done = true; Console.WriteLine("Pulse List(s) done."); } // Use Sleep() to prevent wasteful busy loop Thread.Sleep(200); } // Close-out sockets before exiting cmdChannel.closeSocket(); dataChannel.closeSocket(); if(Utils.doThisPrint(2)) Console.WriteLine(" "); if (Utils.doThisPrint(1)) Console.WriteLine("The Main thread has terminated."); if (Utils.doThisPrint(2)) Console.WriteLine("Largest data MessageSize = {0}", dataChannel.LargestMessageSize); if(Utils.doThisPrint(2)) Console.WriteLine("Data connect count = {0}", dataChannel.connectCount); if(Utils.doThisPrint(2)) Console.WriteLine("Data disconnect count = {0}", dataChannel.disConnectCount); if(Utils.doThisPrint(2)) Console.WriteLine("Largest command MessageSize = {0}", cmdChannel.LargestMessageSize); if(Utils.doThisPrint(2)) Console.WriteLine("Command connect count = {0}", dataChannel.connectCount); if(Utils.doThisPrint(2)) Console.WriteLine("Command disconnect count = {0}", dataChannel.disConnectCount); } // Main() public static void setSocketParameters(IPAddress ipaddr, int cmdPortNumber, int dataPortNumber) { cmdChannel.setIPAddress(ipaddr); dataChannel.setIPAddress(ipaddr); cmdChannel.setPortNumber(cmdPortNumber); dataChannel.setPortNumber(dataPortNumber); } static bool initialize(string[] args) { bool showingIniDataOnly = false; bool terminateEarly = false; bool displayHelpOnly = false; // Create housekeeping timer that will periodically send keep-alive message to sonar HouseKeepingTimer = new System.Timers.Timer(DefaultTimerInterval); // Hook up the Elapsed event for the timer. HouseKeepingTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); HouseKeepingTimer.Enabled = true; iniFilename = defaultIniFile; Int32 level; if (args.Length > 0) { int k = 0; while (k < args.Length) { if (args[k].Equals("version", StringComparison.OrdinalIgnoreCase) || args[k].Equals("v", StringComparison.OrdinalIgnoreCase)) { if (Utils.doThisPrint(3)) Console.WriteLine("Sonar Command-Line Interface (Sonar CLI) Version {0}", SonarCLI_Version); if (Utils.doThisPrint(3)) Console.WriteLine("Sub-assembly revision numbers:"); if (Utils.doThisPrint(3)) Console.WriteLine(" {0}", MainProgram.getVersionInfo()); if (Utils.doThisPrint(3)) Console.WriteLine(" {0}", cmdChannel.getVersionInfo()); CReadIniFile tmpRead = new CReadIniFile(); if (Utils.doThisPrint(3)) Console.WriteLine(" {0}", tmpRead.getVersionInfo()); SonarMessage tmpSonar = new SonarMessage(); if (Utils.doThisPrint(3)) Console.WriteLine(" {0}", tmpSonar.getVersionInfo()); Utils tmpUtils = new Utils(); if (Utils.doThisPrint(3)) Console.WriteLine(" {0}", tmpUtils.getVersionInfo()); if (showingIniDataOnly || doPulseListOnly) { terminateEarly = false; } else { terminateEarly = true; } } else if (args[k].Equals("ini", StringComparison.OrdinalIgnoreCase) || args[k].Equals("i", StringComparison.OrdinalIgnoreCase)) { showingIniDataOnly = true; terminateEarly = false; Utils.setPrintThrottle(5); } else if (args[k].Equals("pulselist", StringComparison.OrdinalIgnoreCase) || args[k].Equals("p", StringComparison.OrdinalIgnoreCase)) { doPulseListOnly = true; terminateEarly = false; } else if (args[k].Equals("system", StringComparison.OrdinalIgnoreCase) || args[k].Equals("s", StringComparison.OrdinalIgnoreCase)) { getSystemTypeOnly = true; Utils.setPrintThrottle(1); terminateEarly = false; } else if (args[k].Equals("help", StringComparison.OrdinalIgnoreCase) || args[k].Equals("h", StringComparison.OrdinalIgnoreCase) || args[k].Equals("?", StringComparison.OrdinalIgnoreCase)) { displayHelpOnly = true; terminateEarly = false; } else if (args[k].Equals("-f", StringComparison.OrdinalIgnoreCase)) { k++; iniFilename = args[k]; } else if (Int32.TryParse(args[k], out level)) { if ((0 <= level) && (level <= 5)) { Utils.setPrintThrottle(level); } } else { if (Utils.doThisPrint(1)) Console.WriteLine("Error: Invalid command-line argument: {0}", args[k]); return false; } k++; } if (terminateEarly) return false; } // Read entire contents of initialization file file into one large byte array, iniData iniData = CReadIniFile.ReadFile(iniFilename); if (iniData == null) { return false; } // Now parse iniData and store the sonar parameters in struct sonarParameters bool stat = parseIniData(); if (stat) { // Check for subsystem collisions if (slave1Subsystem == masterSubsystem) { if (masterSubsystem != NOT_USED) { if (Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Master subsystem = {0}, Slave 1 subsystem = {1}", masterSubsystem, slave1Subsystem); if (Utils.doThisPrint(1)) Console.WriteLine("They cannot be equal."); return false; } } if (slave2Subsystem == masterSubsystem) { if (masterSubsystem != NOT_USED) { if (Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Master subsystem = {0}, Slave 2 subsystem = {1}", masterSubsystem, slave2Subsystem); if (Utils.doThisPrint(1)) Console.WriteLine("They cannot be equal."); return false; } } // Here is where we set the socket parameters - IP address and port numbers setSocketParameters(sonarParameters.ipaddr, sonarParameters.cmdPort, sonarParameters.dataPort); } if (displayHelpOnly) { if (helpInfo.Length == 0) { Console.WriteLine("No help info available."); } else { Console.WriteLine(helpInfo); } return false; } if (showingIniDataOnly) { if (Utils.doThisPrint(5)) Console.WriteLine("---------------------------------------- "); if (masterSubsystem == SIDE_SCAN_LOW) { if (Utils.doThisPrint(5)) Console.WriteLine("Master SubSystem: Side Scan Low"); } else if (masterSubsystem == SIDE_SCAN_HIGH) { if (Utils.doThisPrint(5)) Console.WriteLine("Master SubSystem: Side Scan High"); } else if (masterSubsystem == SUB_BOTTOM) { if (Utils.doThisPrint(5)) Console.WriteLine("Master SubSystem: Sub-Bottom"); } if (slave1Subsystem == SIDE_SCAN_LOW) { if (Utils.doThisPrint(5)) Console.WriteLine("Slave 1 SubSystem: Side Scan Low"); } else if (slave1Subsystem == SIDE_SCAN_HIGH) { if (Utils.doThisPrint(5)) Console.WriteLine("Slave 1 SubSystem: Side Scan High"); } else if (slave1Subsystem == SUB_BOTTOM) { if (Utils.doThisPrint(5)) Console.WriteLine("Slave 1 SubSystem: Sub-Bottom"); } if (slave2Subsystem == SIDE_SCAN_LOW) { if (Utils.doThisPrint(5)) Console.WriteLine("Slave 2 SubSystem: Side Scan Low"); } else if (slave2Subsystem == SIDE_SCAN_HIGH) { if (Utils.doThisPrint(5)) Console.WriteLine("Slave 2 SubSystem: Side Scan High"); } else if (slave2Subsystem == SUB_BOTTOM) { if (Utils.doThisPrint(5)) Console.WriteLine("Slave 2 SubSystem: Sub-Bottom"); } return false; } return stat; } // initialize() // Parse byte array iniData which contains the parameters read from initialization file // and place into struct sonarParameters. Data validation is also done here. // Program terminates with an error message if invalid inputs are encountered. static bool parseIniData() { // Parse iniData int len = iniData.Length; const int MAX_LINE_LENGTH = 160; byte[] buf = new byte[MAX_LINE_LENGTH]; bool cmdPortIsDefined = false; bool dataPortIsDefined = false; int k = 0; // Loop over entire iniData while (k < len) { int j = 0; for (j = 0; j < MAX_LINE_LENGTH; j++) buf[j] = 0; j = 0; // Consume one LineFeed-terminated line in the following while loop // and store in byte array buf while ( (j < MAX_LINE_LENGTH) && (k < len) ) { buf[j] = iniData[k]; j++; k++; if (iniData[k] == LF) break; } k++; // Prepare index for next line // First check for non-relevant lines and skip them int bufLen = j; if (bufLen < 3) continue; // Empty line (just a CR-LF) j = skipWhiteSpace(0, buf); if (j == -1) continue; // Nothing but whitespace if (buf[j] == (byte)';') continue; // Skip comments // Now parse the line byte[] buf2 = new byte[bufLen]; for (j = 0; j < bufLen; j++) { if (buf[j] == (byte)';') break; // Ignore trailing comments buf2[j] = buf[j]; } string str = System.Text.Encoding.ASCII.GetString(buf2); if (Utils.doThisPrint(5)) { if (!str.StartsWith("Help Info>")) // Do not show Help Info here. Just ini data. { Console.WriteLine("{0}: {1}", iniFilename, str); } } const int MAX_NUM_WORDS = 5; const double MIN_RANGE_METERS = 1.0; const double MAX_RANGE_METERS = 1000.0; const double MIN_ENTERED_PING_RATE_HZ = -50.0; const double MAX_ENTERED_PING_RATE_HZ = -0.1; string[] word = new string[MAX_NUM_WORDS]; int m = 0; j = 0; double dblTmp; int intTmp; // Breakup line into token words here while (m < MAX_NUM_WORDS) { j = getNextWord(j, buf2, out word[m]); if (j == -1) break; //word[m].Trim(); m++; } if (word[0].Equals("IP", StringComparison.OrdinalIgnoreCase)) { IPAddress ipTmp; try { ipTmp = IPAddress.Parse(word[2]); } catch (System.FormatException) { if(Utils.doThisPrint(1)) Console.WriteLine("Invalid IP address in initialization file: {0}", word[2]); return false; } sonarParameters.ipaddr = ipTmp; } if (word[0].Equals("Command", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[3]); if (intTmp < 1024 || intTmp > 65535) { if(Utils.doThisPrint(1)) Console.WriteLine("Invalid command port number in initialization file: {0}", intTmp); return false; } sonarParameters.cmdPort = intTmp; cmdPortIsDefined = true; } if (word[0].Equals("Data", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[3]); if (intTmp < 1024 || intTmp > 65535) { if (Utils.doThisPrint(1)) Console.WriteLine("Invalid data port number in initialization file: {0}", intTmp); return false; } sonarParameters.dataPort = intTmp; dataPortIsDefined = true; } // Do port numbers check here if (cmdPortIsDefined && dataPortIsDefined && (sonarParameters.dataPort==sonarParameters.cmdPort) ) { if (Utils.doThisPrint(1)) Console.WriteLine("Problem with port numbers in initialization file: {0}, {1}", sonarParameters.cmdPort, sonarParameters.dataPort); if(Utils.doThisPrint(1)) Console.WriteLine("Port numbers cannot be the same."); return false; } if (word[0].Equals("Range0", StringComparison.OrdinalIgnoreCase)) { dblTmp = Convert.ToDouble(word[1]); if (dblTmp > 0.0) // SB range in meters { if (dblTmp >= MIN_RANGE_METERS && dblTmp <= MAX_RANGE_METERS) { sonarParameters.Range0 = dblTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Range0 = {0} meters.", dblTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should lie within 1 to 1000 meters."); return false; } } else { if (dblTmp >= MIN_ENTERED_PING_RATE_HZ && dblTmp <= MAX_ENTERED_PING_RATE_HZ) { sonarParameters.Range0 = dblTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Range0 = {0} Hz.", dblTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should lie within -50.0 to -0.1 Hz."); return false; } } } if( word[0].Equals("Range20", StringComparison.OrdinalIgnoreCase ) ) { dblTmp = Convert.ToDouble(word[1]); if (dblTmp > 0.0) // SSL range in meters { if (dblTmp >= MIN_RANGE_METERS && dblTmp <= MAX_RANGE_METERS) { sonarParameters.Range20 = dblTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Range20 = {0} meters.", dblTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should lie within 1 to 1000 meters."); return false; } } else { if (dblTmp >= MIN_ENTERED_PING_RATE_HZ && dblTmp <= MAX_ENTERED_PING_RATE_HZ) { sonarParameters.Range20 = dblTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Range20 = {0} Hz.", dblTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should lie within -50.0 to -0.1 Hz."); return false; } } } if( word[0].Equals("Range21", StringComparison.OrdinalIgnoreCase ) ) { dblTmp = Convert.ToDouble(word[1]); if (dblTmp > 0.0) // SSH range in meters { if (dblTmp >= MIN_RANGE_METERS && dblTmp <= MAX_RANGE_METERS) { sonarParameters.Range21 = dblTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Range21 = {0} meters.", dblTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should lie within 1 to 1000 meters."); return false; } } else { if (dblTmp >= MIN_ENTERED_PING_RATE_HZ && dblTmp <= MAX_ENTERED_PING_RATE_HZ) { sonarParameters.Range21 = dblTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Range21 = {0} Hz.", dblTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should lie within -50.0 to -0.1 Hz."); return false; } } } if( !storeTriggerParameters(word, "Master", ref sonarParameters.Master) ) return false; if( !storeTriggerParameters(word, "Slave_1", ref sonarParameters.Slave1) ) return false; if( !storeTriggerParameters(word, "Slave_2", ref sonarParameters.Slave2) ) return false; if( word[0].Equals("Power0", StringComparison.OrdinalIgnoreCase ) ) { intTmp = Convert.ToInt32(word[1]); if (intTmp == 0 || intTmp == 1) { sonarParameters.Power0 = intTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Power0 = {0}.", intTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should be either 0 or 1."); return false; } } if( word[0].Equals("Power20", StringComparison.OrdinalIgnoreCase ) ) { intTmp = Convert.ToInt32(word[1]); if (intTmp == 0 || intTmp == 1) { sonarParameters.Power20 = intTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Power20 = {0}.", intTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should be either 0 or 1."); return false; } } if( word[0].Equals("Power21", StringComparison.OrdinalIgnoreCase ) ) { intTmp = Convert.ToInt32(word[1]); if (intTmp == 0 || intTmp == 1) { sonarParameters.Power21 = intTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Power21 = {0}.", intTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should be either 0 or 1."); return false; } } if (word[0].Equals("ReturnActivePingData0", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[1]); if (intTmp == 0 || intTmp == 1) { sonarParameters.ReturnActivePingData0 = intTmp; } else { if (Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: ReturnActivePingData0 = {0}.", intTmp); if (Utils.doThisPrint(1)) Console.WriteLine(" It should be either 0 or 1."); return false; } } if (word[0].Equals("ReturnActivePingData20", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[1]); if (intTmp == 0 || intTmp == 1) { sonarParameters.ReturnActivePingData20 = intTmp; } else { if (Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: ReturnActivePingData20 = {0}.", intTmp); if (Utils.doThisPrint(1)) Console.WriteLine(" It should be either 0 or 1."); return false; } } if (word[0].Equals("ReturnActivePingData21", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[1]); if (intTmp == 0 || intTmp == 1) { sonarParameters.ReturnActivePingData21 = intTmp; } else { if (Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: ReturnActivePingData21 = {0}.", intTmp); if (Utils.doThisPrint(1)) Console.WriteLine(" It should be either 0 or 1."); return false; } } if( word[0].Equals("Set", StringComparison.OrdinalIgnoreCase ) ) { intTmp = Convert.ToInt32(word[3]); if (intTmp == 0 || intTmp == 1) { sonarParameters.SetTimeMethod = intTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Set Time Method = {0}.", intTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should be either 0 or 1."); return false; } } if (word[0].Equals("Pulse", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[2]); if (intTmp > 0) { sonarParameters.masterPulseID = intTmp; } else { if (Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Master Pulse ID = {0}.", intTmp); if (Utils.doThisPrint(1)) Console.WriteLine(" It should be greater than 0."); return false; } } if (word[0].Equals("Pulse_1", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[2]); if (intTmp > 0) { sonarParameters.slave1PulseID = intTmp; } else { if (Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Slave_1 Pulse_1 ID = {0}.", intTmp); if (Utils.doThisPrint(1)) Console.WriteLine(" It should be greater than 0."); return false; } } if (word[0].Equals("Pulse_2", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[2]); if (intTmp > 0) { sonarParameters.slave2PulseID = intTmp; } else { if (Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: Slave_2 Pulse_2 ID = {0}.", intTmp); if (Utils.doThisPrint(1)) Console.WriteLine(" It should be greater than 0."); return false; } } if (word[0].Equals("Help")) { helpInfo.Append(str.Substring(11)+NL); } } // End Loop over entire iniData if (Utils.doThisPrint(5)) Console.WriteLine(" "); return true; } private static bool storeTriggerParameters( string[] word, string subSystemName, ref SonarMessage.TriggerParametersType TriggerParameters ) { int intTmp; int otherMode; string triggerKeyword; if (subSystemName.Equals("Master")) { triggerKeyword = "Trigger"; otherMode = 1; } else if (subSystemName.Equals("Slave_1")) { triggerKeyword = "Trigger_1"; otherMode = 2; } else if (subSystemName.Equals("Slave_2")) { triggerKeyword = "Trigger_2"; otherMode = 2; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous subSystemName in storeTriggerParameters()."); return false; } // Identify the current subsystem with its role: Master, Slave_1, or Slave_2 if( word[0].Equals(subSystemName, StringComparison.OrdinalIgnoreCase ) ) { intTmp = Convert.ToInt32(word[2]); if (intTmp == SUB_BOTTOM || intTmp == SIDE_SCAN_LOW || intTmp == SIDE_SCAN_HIGH || intTmp == NOT_USED) { if (intTmp == SUB_BOTTOM) sub_bottom_being_used = true; if (intTmp == SIDE_SCAN_LOW) side_scan_low_being_used = true; if (intTmp == SIDE_SCAN_HIGH) side_scan_high_being_used = true; if (subSystemName.Equals("Master")) { masterSubsystem = intTmp; //sonarParameters.Master.subSystem = intTmp; } if (subSystemName.Equals("Slave_1")) { slave1Subsystem = intTmp; //sonarParameters.Slave1.subSystem = intTmp; } if (subSystemName.Equals("Slave_2")) { slave2Subsystem = intTmp; //sonarParameters.Slave2.subSystem = intTmp; } } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: {0} Subsystem = {1}.", subSystemName, intTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should be either 0, 20, 21, or -1 (for not used)."); return false; } } if( word[0].Equals(triggerKeyword, StringComparison.OrdinalIgnoreCase ) ) { if (word[1].Equals("Mode", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[2]); // Master must be 0 or 1, Slave must be 0 or 2 if (intTmp == 0 || intTmp == otherMode) { TriggerParameters.triggerMode = (UInt32) intTmp; if (subSystemName.Equals("Master")) { if (masterSubsystem == 0) sonarParameters.TriggerMode0 = intTmp; if (masterSubsystem == 20) sonarParameters.TriggerMode20 = intTmp; if (masterSubsystem == 21) sonarParameters.TriggerMode21 = intTmp; } if (subSystemName.Equals("Slave_1")) { if (slave1Subsystem == 0) sonarParameters.TriggerMode0 = intTmp; if (slave1Subsystem == 20) sonarParameters.TriggerMode20 = intTmp; if (slave1Subsystem == 21) sonarParameters.TriggerMode21 = intTmp; } if (subSystemName.Equals("Slave_2")) { if (slave2Subsystem == 0) sonarParameters.TriggerMode0 = intTmp; if (slave2Subsystem == 20) sonarParameters.TriggerMode20 = intTmp; if (slave2Subsystem == 21) sonarParameters.TriggerMode21 = intTmp; } } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: {0} Trigger Mode = {1}.", subSystemName, intTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should be either 0 or {0}.", otherMode); return false; } } // Identify the source trigger if (word[1].Equals("Source", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[2]); // intTmp must be one of the three subsystems if (intTmp == SUB_BOTTOM || intTmp == SIDE_SCAN_LOW || intTmp == SIDE_SCAN_HIGH) { TriggerParameters.subSystem = (Int32)intTmp; } else { if (Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: {0} Trigger Source = {1}.", subSystemName, intTmp); if (Utils.doThisPrint(1)) Console.WriteLine(" It should be one of 0, 20, or 21"); return false; } } if (word[1].Equals("Divisor", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[2]); if (intTmp > 0) { TriggerParameters.triggerDivisor = (UInt32) intTmp; } else { if(Utils.doThisPrint(1)) Console.WriteLine("Erroneous input in initialization file: {0} Trigger Divisor = {1}.", subSystemName, intTmp); if(Utils.doThisPrint(1)) Console.WriteLine(" It should be greater than zero."); return false; } } if (word[1].Equals("Delay", StringComparison.OrdinalIgnoreCase)) { intTmp = Convert.ToInt32(word[2]); TriggerParameters.triggerDelay = (UInt32) intTmp; } } return true; } public static structSonarParameters getSonarParameters() { return sonarParameters; } // Return index of next non-white character in buf. Return -1 if none found. static int skipWhiteSpace(int start, byte[] buf) { int len = buf.Length; if (len == 0) return -1; int j = start; while (j < len) { byte b = buf[j]; if ( isWhiteSpace(b) ) // b is whitespace { j++; } else { return j; } } if (j == len) return -1; return j; } public static bool isWhiteSpace( byte b ) { if ((b > 7 && b < 14) || b == 32) // b is whitespace { return true; } return false; } public static bool isPrintable(byte b) { if ( (b > 41 && b < 127) || b == 13 || b == 10 || b == 32 ) { return true; } return false; } public static int getNextWord( int start, byte[] buf, out string word ) { word = null; int j = skipWhiteSpace(start, buf); if (j == -1) return j; int len = buf.Length; byte[] buf2 = new byte[len]; int start2 = j; while (j < len) { if (isWhiteSpace(buf[j])) break; byte b = buf[j]; buf2[j - start2] = b; j++; } int wordLen = j - start2; if (wordLen > 0) // We have a word { // First trim the word byte[] buf3 = new byte[wordLen]; for (int k = 0; k < wordLen; k++) buf3[k] = buf2[k]; word = System.Text.Encoding.ASCII.GetString(buf3); } else { word = null; j = -1; } return j; } public static void bootSonar() { double value; int iValue; //char[] tmp; char[] fnameToSonar = new char[256]; UInt32 masterTriggerMode = sonarParameters.Master.triggerMode; if (Utils.doThisPrint(3)) Console.WriteLine("In bootSonar()..."); Thread.Sleep(100); // Give socket a little time to initialize // First reset sonar. Note: For now, leave the following Reset command disabled. It seems to // kill the generation of sonar data. //cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_SYSTEM_RESET, // SonarMessage.SonarCommandType.SONAR_COMMAND_SET, 255, CH_0, 1, sizeof(int)); // Get current sonar system type if (getSystemTypeOnly) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_SYSTEM_TYPE, SonarMessage.SonarCommandType.SONAR_COMMAND_GET, 0, CH_0, 0, 0); Thread.Sleep(40); // Allow some time for sonar to respond //exit(0); return; } if (doPulseListOnly) { Utils.setPrintThrottle(5); // Adjust print throttle so that pulse lists get displayed // Send a Get command. Request sonar pulse list. if (sub_bottom_being_used) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_LIST, SonarMessage.SonarCommandType.SONAR_COMMAND_GET, SUB_BOTTOM, CH_0, SonarMessage.MAX_NUM_ENTRIES_IN_PULSE_LIST, sizeof(int)); Thread.Sleep(10); // Allow some time for sonar to respond } if (side_scan_low_being_used) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_LIST, SonarMessage.SonarCommandType.SONAR_COMMAND_GET, SIDE_SCAN_LOW, CH_0, SonarMessage.MAX_NUM_ENTRIES_IN_PULSE_LIST, sizeof(int)); Thread.Sleep(10); // Allow some time for sonar to respond } if (side_scan_high_being_used) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_LIST, SonarMessage.SonarCommandType.SONAR_COMMAND_GET, SIDE_SCAN_HIGH, CH_0, SonarMessage.MAX_NUM_ENTRIES_IN_PULSE_LIST, sizeof(int)); } int k = 0; while (!pulseListDefined) { Thread.Sleep(10); // Allow some time for sonar to respond k++; if (k > 9) { Utils.flagFatalError("Error: Cannot seem to get pulse list from sonar."); done = true; return; } } return; } // Now do Set commands // Set range for sub-bottom if (sub_bottom_being_used) { value = sonarParameters.Range0; if (value < 0.0) // Do as Ping Rate { Utils.flagFatalError("Ping rate is not currently supported. Use range instead."); done = true; return; //int pingRate = (int)(((-value) * 1000) + 0.5); //cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_RATE, // SonarMessage.SonarCommandType.SONAR_COMMAND_SET, // SUB_BOTTOM, CH_0, pingRate, sizeof(int)); } else // Do as range { int rangeMillimeters = (int)(((value) * 1000) + 0.5); cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_RANGE, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SUB_BOTTOM, CH_0, rangeMillimeters, sizeof(int)); } // Tell sonar to enable/disable return of sub-bottom active ping data //Thread.Sleep(1000); // Allow some time for sonar to respond iValue = sonarParameters.ReturnActivePingData0; cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_DATA_ACTIVE, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SUB_BOTTOM, CH_0, iValue, sizeof(int)); // Repeat for Channel 1 cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_DATA_ACTIVE, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SUB_BOTTOM, CH_1, iValue, sizeof(int)); //Thread.Sleep(100); // Allow some time for sonar to respond // Note: (Per Qinxi) - Ping Select command is currently ignored //int index = getPulseListIndex(SUB_BOTTOM); //if (index == NOT_FOUND) //{ // Utils.flagFatalError("Initialization file error: Invalid pulse ID for Sub-Bottom"); // done = true; // return; //} //tmp = subBottomPulseList.pulseList[index].fileName.ToCharArray(); //for (k = 0; k < 256; k++) fnameToSonar[k] = (char)0; //for (k = 0; k < tmp.Length; k++) fnameToSonar[k] = tmp[k]; //object fname = fnameToSonar; //cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_SELECT, // SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SUB_BOTTOM, // CH_0, fname, 256); cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_TRIGGER, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SUB_BOTTOM, CH_0, sonarParameters.TriggerMode0, (uint)sizeof(UInt32)); // Note: The Master subsystem does not use ping coupling parameters // If not Master, package trigger coupling parameters and send to sonar // Important Note: pingCouplingParameters.subSystem refers to the trigger source subsystem if (masterSubsystem != SUB_BOTTOM) { if (slave1Subsystem == SUB_BOTTOM) { pingCouplingParameters.subSystem = sonarParameters.Slave1.subSystem; pingCouplingParameters.triggerDivisor = sonarParameters.Slave1.triggerDivisor; pingCouplingParameters.triggerDelay = sonarParameters.Slave1.triggerDelay; } else if (slave2Subsystem == SUB_BOTTOM) { pingCouplingParameters.subSystem = sonarParameters.Slave2.subSystem; pingCouplingParameters.triggerDivisor = sonarParameters.Slave2.triggerDivisor; pingCouplingParameters.triggerDelay = sonarParameters.Slave2.triggerDelay; } else { Utils.flagFatalError("Configuration error with trigger parameters for Sub-Bottom in bootSonar()."); done = true; return; } uint pcpLength = (uint)Marshal.SizeOf(pingCouplingParameters); cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_COUPLING_PARAMETERS, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SUB_BOTTOM, CH_0, pingCouplingParameters, pcpLength); } Thread.Sleep(10); // Allow some time for sonar to respond } // Set range or ping rate for side-scan low frequency if (side_scan_low_being_used) { value = sonarParameters.Range20; if (value < 0.0) // Do as Ping Rate { Utils.flagFatalError("Ping rate is not currently supported. Use range instead."); done = true; return; //int pingRate = (int)(((-value) * 1000) + 0.5); //cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_RATE, // SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_LOW, // CH_0, pingRate, sizeof(int)); } else // Do as range { int rangeMillimeters = (int)(((value) * 1000) + 0.5); cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_RANGE, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_LOW, CH_0, rangeMillimeters, sizeof(int)); } // Tell sonar to enable/disable return of side scan low active ping data iValue = sonarParameters.ReturnActivePingData20; cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_DATA_ACTIVE, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_LOW, CH_0, iValue, sizeof(int)); // Repeat for Channel 1 cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_DATA_ACTIVE, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_LOW, CH_1, iValue, sizeof(int)); // Note: (Per Qinxi) - Ping Select command is currently ignored //int index = getPulseListIndex(SIDE_SCAN_LOW); //if (index == NOT_FOUND) //{ // Utils.flagFatalError("Initialization file error: Invalid pulse ID for Side-Scan Low"); // done = true; // return; //} // C# Note: The following does not work in this situation because fname must be 256 bytes long. // Therefore must use 256-byte array padded with trailing zeroes. //object fname = pulseList[index].fileName; //uint fnameLen = (uint)pulseList[index].fileName.Length; //cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_SELECT, // SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_LOW, // CH_0, fname, fnameLen); //tmp = sideScanLowPulseList.pulseList[index].fileName.ToCharArray(); //for (k = 0; k < 256; k++) fnameToSonar[k] = (char)0; //for (k = 0; k < tmp.Length; k++) fnameToSonar[k] = tmp[k]; //object fname = fnameToSonar; ////uint fnameLen = (uint)pulseList[index].fileName.Length; //cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_SELECT, // SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_LOW, // CH_0, fname, 256); cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_TRIGGER, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_LOW, CH_0, sonarParameters.TriggerMode20, (uint)sizeof(UInt32)); // Note: The Master subsystem does not use ping coupling parameters // If not Master, package trigger coupling parameters and send to sonar // Important Note: pingCouplingParameters.subSystem refers to the trigger source subsystem if (masterSubsystem != SIDE_SCAN_LOW) { if (slave1Subsystem == SIDE_SCAN_LOW) { pingCouplingParameters.subSystem = sonarParameters.Slave1.subSystem; pingCouplingParameters.triggerDivisor = sonarParameters.Slave1.triggerDivisor; pingCouplingParameters.triggerDelay = sonarParameters.Slave1.triggerDelay; } else if (slave2Subsystem == SIDE_SCAN_LOW) { pingCouplingParameters.subSystem = sonarParameters.Slave2.subSystem; pingCouplingParameters.triggerDivisor = sonarParameters.Slave2.triggerDivisor; pingCouplingParameters.triggerDelay = sonarParameters.Slave2.triggerDelay; } else { Utils.flagFatalError("Configuration error with trigger parameters for Side Scan Low in bootSonar()."); done = true; return; } uint pcpLength = (uint)Marshal.SizeOf(pingCouplingParameters); cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_COUPLING_PARAMETERS, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_LOW, CH_0, pingCouplingParameters, pcpLength); } Thread.Sleep(10); // Allow some time for sonar to respond } // Set range or ping rate for side-scan high frequency if (side_scan_high_being_used) { value = sonarParameters.Range21; if (value < 0.0) // Do as Ping Rate { Utils.flagFatalError("Ping rate is not currently supported. Use range instead."); done = true; return; //int pingRate = (int)(((-value) * 1000) + 0.5); //cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_RATE, // SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_HIGH, // CH_0, pingRate, sizeof(int)); } else // Do as range { int rangeMillimeters = (int)(((value) * 1000) + 0.5); cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_RANGE, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_HIGH, CH_0, rangeMillimeters, sizeof(int)); } // Tell sonar to enable/disable return of side scan high active ping data // Note: For sonar.exe this option is ON by default, but if you are going through // Discover, it is OFF by default. Also you must specify which channel // to turn or off. iValue = sonarParameters.ReturnActivePingData21; cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_DATA_ACTIVE, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_HIGH, CH_0, iValue, sizeof(int)); // Repeat for Channel 1 cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_DATA_ACTIVE, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_HIGH, CH_1, iValue, sizeof(int)); //int index = getPulseListIndex(SIDE_SCAN_HIGH); //if (index == NOT_FOUND) //{ // Utils.flagFatalError("Initialization file error: Invalid pulse ID for Side-Scan High"); // done = true; // return; //} //tmp = sideScanHighPulseList.pulseList[index].fileName.ToCharArray(); //for (k = 0; k < 256; k++) fnameToSonar[k] = (char)0; //for (k = 0; k < tmp.Length; k++) fnameToSonar[k] = tmp[k]; //object fname = fnameToSonar; ////uint fnameLen = (uint)pulseList[index].fileName.Length; //cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_SELECT, // SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_HIGH, // CH_0, fname, 256); cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_TRIGGER, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_HIGH, CH_0, sonarParameters.TriggerMode21, (uint)sizeof(UInt32)); // Note: The Master subsystem does not use ping coupling parameters // If not Master, package trigger coupling parameters and send to sonar // Important Note: pingCouplingParameters.subSystem refers to the trigger source subsystem if (masterSubsystem != SIDE_SCAN_HIGH) { if (slave1Subsystem == SIDE_SCAN_HIGH) { pingCouplingParameters.subSystem = sonarParameters.Slave1.subSystem; pingCouplingParameters.triggerDivisor = sonarParameters.Slave1.triggerDivisor; pingCouplingParameters.triggerDelay = sonarParameters.Slave1.triggerDelay; } else if (slave2Subsystem == SIDE_SCAN_HIGH) { pingCouplingParameters.subSystem = sonarParameters.Slave2.subSystem; pingCouplingParameters.triggerDivisor = sonarParameters.Slave2.triggerDivisor; pingCouplingParameters.triggerDelay = sonarParameters.Slave2.triggerDelay; } else { Utils.flagFatalError("Configuration error with trigger parameters for Side Scan High in bootSonar()."); done = true; return; } uint pcpLength = (uint)Marshal.SizeOf(pingCouplingParameters); cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING_COUPLING_PARAMETERS, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, SIDE_SCAN_HIGH, CH_0, pingCouplingParameters, pcpLength); } if (Utils.doThisPrint(3)) Console.WriteLine("bootSonar() complete."); Thread.Sleep(10); // Allow some time for sonar to respond } } // bootSonar() // subSystemID: SUB_BOTTOM, SIDE_SCAN_LOW, SIDE_SCAN_HIGH // Return value: An index pointing into the pulseList array public static int getPulseListIndex(int subSystemID) { int k; int pulseID = getPulseListID(subSystemID); if (pulseID == NOT_FOUND) return NOT_FOUND; // Make sure the pulseList is defined if (subSystemID == MainProgram.SUB_BOTTOM) { if (!MainProgram.subBottomPulseList.pulseListDefined) return NOT_FOUND; } if (subSystemID == MainProgram.SIDE_SCAN_LOW) { if (!MainProgram.sideScanLowPulseList.pulseListDefined) return NOT_FOUND; } if (subSystemID == MainProgram.SIDE_SCAN_HIGH) { if (!MainProgram.sideScanHighPulseList.pulseListDefined) return NOT_FOUND; } // Now find the corresponding index if (subSystemID == MainProgram.SUB_BOTTOM) { for (k = 0; k < MainProgram.subBottomPulseList.numPulses; k++) { if (pulseID == MainProgram.subBottomPulseList.pulseList[k].pulseID) return k; } } if (subSystemID == MainProgram.SIDE_SCAN_LOW) { for (k = 0; k < MainProgram.sideScanLowPulseList.numPulses; k++) { if (pulseID == MainProgram.sideScanLowPulseList.pulseList[k].pulseID) return k; } } if (subSystemID == MainProgram.SIDE_SCAN_HIGH) { for ( k = 0; k < MainProgram.sideScanHighPulseList.numPulses; k++) { if (pulseID == MainProgram.sideScanHighPulseList.pulseList[k].pulseID) return k; } } // If we reach here, then no index was found return NOT_FOUND; } // subSystemID: SUB_BOTTOM, SIDE_SCAN_LOW, SIDE_SCAN_HIGH // Return value: The pulse list ID associated with the subSystem public static int getPulseListID(int subSystemID) { if (masterSubsystem == subSystemID) { return sonarParameters.masterPulseID; } else if (slave1Subsystem == subSystemID) { return sonarParameters.slave1PulseID; } else if (slave2Subsystem == subSystemID) { return sonarParameters.slave2PulseID; } else // error { return NOT_FOUND; } } // This HouseKeepingTimer event executes every "DefaultTimerInterval" milliseconds // Currently it is used to get the Keep-Alive message and to intercept single-letter keyboard commands private static void OnTimedEvent(object source, ElapsedEventArgs e) { //if(Utils.doThisPrint(5)) Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime); if (doPulseListOnly) Utils.setPrintThrottle(0); if (Utils.doThisPrint(5)) Console.WriteLine("Inside housekeeping timer OnTimedEvent()"); bool keyPressed = Console.KeyAvailable; if (keyPressed) { ConsoleKeyInfo cki = Console.ReadKey(true); if (cki.Key == ConsoleKey.P) { if (Utils.doThisPrint(5)) Console.WriteLine("You pressed the P key."); // Turn pinging on if (sub_bottom_being_used) { if (sonarParameters.Power0 == 1) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, (byte)SUB_BOTTOM, CH_0, PING_ON, sizeof(int)); } } if (side_scan_low_being_used) { if (sonarParameters.Power20 == 1) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, (byte)SIDE_SCAN_LOW, CH_0, PING_ON, sizeof(int)); } } if (side_scan_high_being_used) { if (sonarParameters.Power21 == 1) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, (byte)SIDE_SCAN_HIGH, CH_0, PING_ON, sizeof(int)); } } } if (cki.Key == ConsoleKey.S) { if (Utils.doThisPrint(5)) Console.WriteLine("You pressed the S key."); // Turn pinging off if (sub_bottom_being_used) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, (byte)SUB_BOTTOM, CH_0, PING_OFF, sizeof(int)); } if (side_scan_low_being_used) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, (byte)SIDE_SCAN_LOW, CH_0, PING_OFF, sizeof(int)); } if (side_scan_high_being_used) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_PING, SonarMessage.SonarCommandType.SONAR_COMMAND_SET, (byte)SIDE_SCAN_HIGH, CH_0, PING_OFF, sizeof(int)); } } if (cki.Key == ConsoleKey.Q) { if (Utils.doThisPrint(5)) Console.WriteLine("You pressed the Q key."); //if (dataLog != null) dumpDataLog(); done = true; } } // Query for the Keep-Alive message Object osn = sequenceNumber; // Box sequenceNumber as an object // Send Keep-Alive message every fifth time if (sequenceNumber % 5 == 0) { cmdChannel.sendCommand(SonarMessage.SonarMessageType.SONAR_MESSAGE_ALIVE, SonarMessage.SonarCommandType.SONAR_COMMAND_GET, 0, CH_0, osn, sizeof(int)); } sequenceNumber++; } //public static StringBuilder getDataLog() //{ // return dataLog; //} //public static void dumpDataLog() //{ // System.IO.StreamWriter file = new System.IO.StreamWriter("DataLog.txt"); // file.WriteLine(dataLog); // file.Close(); // int numBytes = dataLog.Length; // if (Utils.doThisPrint(1)) Console.WriteLine("{0} bytes written to DataLog.txt", numBytes); //} public static string getVersionInfo() { versionInfo = _versionInfo.Remove(0, 9); string endStr = " mps $"; char[] end = endStr.ToCharArray(); versionInfo = versionInfo.TrimEnd( end ); return versionInfo; } } // class MainProgram }