/// <summary> /// Creates a TCP timeserver that listens for incoming connections and then responds with the current levels /// </summary> /// <returns> /// void /// </returns> public static void TcpUnitServer() { bool done = false; // Listen for connections on our defined port var listener = new TcpListener(IPAddress.Any, portNum); // Echo we're beginning the listener Console.WriteLine("Unit server now listening for TCP requests on port " + portNum); listener.Start(); while (!done) { TcpClient client = listener.AcceptTcpClient(); // accept the connection NetworkStream ns = client.GetStream(); // establish a network stream byte[] byte_levels = Encoding.ASCII.GetBytes(RetrieveData.ReadLevels()); // Retrieve and convert // try to send our data try { ns.Write(byte_levels, 0, byte_levels.Length); ns.Close(); client.Close(); // Show how many bytes we sent on each connection Console.WriteLine("Connection Established... Sent " + byte_levels.Length.ToString() + " Bytes"); } catch (Exception e) { Console.WriteLine(e.ToString()); } } }
public static void TcpTownClient() { // Placeholders String received = ""; // Fetch ips in a list Console.WriteLine("Fetching IPs"); SQLHelper getips = new SQLHelper("SELECT ip FROM units"); getips.Run_Cmd(); getips.SetIPs(); // Make a new list for the ips and ids List <string> iplist = getips.Get_List(); //List<string> idlist = getids.Get_List(); // Make a string for errors String errors = ""; Console.WriteLine("Beginning Requests..."); // Now go through down each ip and id in the lists and request the data foreach (var ipaddress in iplist) { // Grab the associated unit address from the database SQLHelper getid = new SQLHelper("SELECT unit_id FROM units WHERE ip='" + ipaddress + "' LIMIT 1"); //getid.Run_Reader(); string unit_id = getid.RunAndReturnOne(); // if the id is not our city identifier, proceed with asking for levels if (!unit_id.ToString().Contains(cityID)) { // Check if we're the unit before we try opening a network string string checkipcmd = "hostname -I"; var result = checkipcmd.ExecBash(); result = result.TrimEnd('\r', '\n'); result = result.TrimEnd(); // if we aren't the unit, proceed if (ipaddress.ToString() != result) { // Create a new TCP Client with the address and default port number var client = new TcpClient(ipaddress, portNum); // Establish a network Stream NetworkStream ns = client.GetStream(); // Setup a byte array byte[] bytes = new byte[1024]; // Read the bytes from the network stream into the array int bytesRead = ns.Read(bytes, 0, bytes.Length); // Format to string received = Encoding.ASCII.GetString(bytes, 0, bytesRead); } // if we ARE the unit, read the files locally else { received = RetrieveData.ReadLevels(); } // Turn the input levels to an array string[] levels = received.Split(','); // Turn each level into a double double wat = Convert.ToDouble(levels[0]); double sew = Convert.ToDouble(levels[1]); double pow = Convert.ToDouble(levels[2]); // Generate a timestamp Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; // Insert values with associated unit id into Database SQLHelper insertcmd = new SQLHelper("INSERT INTO status VALUES(" + unixTimestamp + "," + "'" + unit_id + "'," + wat + "," + sew + "," + pow + ")"); insertcmd.Run_Cmd(); // Check for errors errors = RetrieveData.EvaluateLevels(unixTimestamp, unit_id, wat, sew, pow); // If we have errors, pause briefly and then send them! if (!String.IsNullOrEmpty(errors)) { Console.WriteLine("Errors detected, sending to city control..."); System.Threading.Thread.Sleep(5000); try { SendError(errors); } catch (Exception e) { Console.WriteLine("Error reporting failed! Please ensure city control is powered on and running"); } } // Report levels to the console output Console.WriteLine("Unit " + unit_id + " reports " + wat + " water, " + sew + " sewage, " + pow + " power"); } // if we are dealing with a city, we need to send the acknowledgement message - sp spin up a server else { // echo we're ignoring Console.WriteLine("Skipping " + unit_id); } } }
static void Main(string[] args) { #region Command Arguments // Check for user input for (int i = 0; i < args.Length; i++) { if (args[i] == "--set-unit") { ContextSwitch.SetAsUnit(); } if (args[i] == "--set-town") { ContextSwitch.SetAsTown(); } if (args[i] == "--set-city") { ContextSwitch.SetAsCity(); } if (args[i] == "--get-mode") { Console.WriteLine(ContextSwitch.GetMode()); } if (args[i] == "--tcpscan") { NetworkRW.TCPScan(); } if (args[i] == "--gendb") { SQLHelper.CreateDB(); } if (args[i] == "--refresh-city") { NetworkRW.FindCity(); } } #endregion #region DeviceDefaults // If mode is not already set, then set it by default to unit mode if (!File.Exists("mode")) { ContextSwitch.SetAsDefault(); } // Create our dummy files if (!File.Exists("water") || !File.Exists("sewage") || !File.Exists("power")) { RetrieveData.CreateFiles(); } // Create a setupstat file if (!File.Exists("setupstat")) { ContextSwitch.CreateSetup(); } #endregion #region ModeDependants if (ContextSwitch.GetMode() == 0) // if unit { // We await a connection from the Town Control // by using the TCP Unit Server in Network Read/Write Console.WriteLine("Unit Mode Detected!"); ContextSwitch.FinishSetup(); // Setup can be set to finished NetworkRW.TcpUnitServer(); } if (ContextSwitch.GetMode() == 1) // if town { Console.WriteLine("Town Mode Detected!"); string stat = ContextSwitch.GetSetup(); // if the database doesn't exist, generate it and populate it if (stat == "pending") { Console.WriteLine("Generating Database..."); SQLHelper.CreateDB(); // create the database Console.WriteLine("Scanning Network..."); NetworkRW.TCPScan(); // populate the database Console.WriteLine("Detecting City..."); NetworkRW.FindCity(); // find the city ContextSwitch.FinishSetup(); // finish the setup } // Check setup again stat = ContextSwitch.GetSetup(); if (stat == "done") { // Initiate the TCP town client Console.WriteLine("Starting town client..."); NetworkRW.TcpTownClient(); // When finished, echo the errors to city Console.WriteLine("Sending any errors to city control..."); Console.WriteLine("Successfully sent errors"); } } if (ContextSwitch.GetMode() == 2) // if city { Console.WriteLine("City Mode Detected!"); string stat = ContextSwitch.GetSetup(); // if the error database doesn't exist yet generate it, but do not populate it. if (stat == "pending") { Console.WriteLine("Initializating setup:"); Console.WriteLine("Generating Database..."); SQLHelper.CreateErrorDB(); // create the error database NetworkRW.CitySetup(); // run the city setup } //check setup again stat = ContextSwitch.GetSetup(); if (stat == "done") { // just run the city server NetworkRW.CityServer(); } } if (ContextSwitch.GetMode() == 3) // DEBUG MODE { Console.WriteLine("DEBUG MODE Detected!"); SQLHelper.CreateErrorDB(); } #endregion }