diff --git a/AIS/LS100PortProxy/Anleitung.docx b/AIS/LS100PortProxy/Anleitung.docx new file mode 100644 index 00000000..107d5566 Binary files /dev/null and b/AIS/LS100PortProxy/Anleitung.docx differ diff --git a/AIS/LS100PortProxy/LS100PortProxy.csproj b/AIS/LS100PortProxy/LS100PortProxy.csproj new file mode 100644 index 00000000..edff9a4a --- /dev/null +++ b/AIS/LS100PortProxy/LS100PortProxy.csproj @@ -0,0 +1,79 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {1B23254E-62EA-4AAF-803C-AAA0622B4570} + Exe + Properties + LS100PortProxy + LS100PortProxy + v4.6.1 + + + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + false + + + AnyCPU + bin\Debug\ + + + AnyCPU + bin\Release\ + + + + packages\log4net.2.0.8\lib\net45-full\log4net.dll + + + + + + + + + + + + + + + + + Designer + + + + + + \ No newline at end of file diff --git a/AIS/LS100PortProxy/LS100PortProxy.pdf b/AIS/LS100PortProxy/LS100PortProxy.pdf new file mode 100644 index 00000000..cf29f912 Binary files /dev/null and b/AIS/LS100PortProxy/LS100PortProxy.pdf differ diff --git a/AIS/LS100PortProxy/LS100PortProxy.sln b/AIS/LS100PortProxy/LS100PortProxy.sln new file mode 100644 index 00000000..a4cd7dc8 --- /dev/null +++ b/AIS/LS100PortProxy/LS100PortProxy.sln @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2015 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LS100PortProxy", "LS100PortProxy.csproj", "{1B23254E-62EA-4AAF-803C-AAA0622B4570}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1B23254E-62EA-4AAF-803C-AAA0622B4570}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1B23254E-62EA-4AAF-803C-AAA0622B4570}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B23254E-62EA-4AAF-803C-AAA0622B4570}.Debug|x86.ActiveCfg = Debug|x86 + {1B23254E-62EA-4AAF-803C-AAA0622B4570}.Debug|x86.Build.0 = Debug|x86 + {1B23254E-62EA-4AAF-803C-AAA0622B4570}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1B23254E-62EA-4AAF-803C-AAA0622B4570}.Release|Any CPU.Build.0 = Release|Any CPU + {1B23254E-62EA-4AAF-803C-AAA0622B4570}.Release|x86.ActiveCfg = Release|x86 + {1B23254E-62EA-4AAF-803C-AAA0622B4570}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5F49C6E1-0B93-4637-83E3-685F3DF259C5} + EndGlobalSection + GlobalSection(SubversionScc) = preSolution + Svn-Managed = True + Manager = AnkhSVN - Subversion Support for Visual Studio + EndGlobalSection +EndGlobal diff --git a/AIS/LS100PortProxy/MultiplexManager.cs b/AIS/LS100PortProxy/MultiplexManager.cs new file mode 100644 index 00000000..e7e61f0d --- /dev/null +++ b/AIS/LS100PortProxy/MultiplexManager.cs @@ -0,0 +1,305 @@ +// +// Class: MultiplexManager +// Current CLR: 4.0.30319.296 +// System: Microsoft Visual Studio 10.0 +// Author: dani +// Created: 4/8/2013 9:02:48 PM +// +// Copyright (c) 2013 Informatikbüro Daniel Schick. All rights reserved. + +using System; +using System.Text; +using System.Collections.Generic; +using System.Threading; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Diagnostics; +using log4net; + +namespace LS100PortProxy +{ + public class MultiplexManager + { + private int ifIdx; + private int clientPort; + private int serverPort; + private string remoteServerAddress; + private bool shouldStop = false; + private Thread _acceptThread; + private Socket _serverSocket; + private List _connections = new List(); + private TcpClient client; + private Thread _clientThread; + private NetworkStream clientStream; + private DateTime lastDataReceivedAt; + private ILog _log = LogManager.GetLogger(typeof(MultiplexManager)); + + private class Chunk + { + public int length; + public byte[] data; + public Chunk DeepClone() + { + Chunk newChunk = new Chunk(); + newChunk.length = this.length; + newChunk.data = new byte[this.length]; + Array.Copy(this.data, newChunk.data, this.length); + return newChunk; + } + } + + private class ConnectionInfo + { + public Socket Socket; + public Thread Thread; + public Queue chunks = new Queue(); + } + + public MultiplexManager(int ifIdx, string address, int cPort, int sPort) + { + this.ifIdx = ifIdx; + this.remoteServerAddress = address; + this.clientPort = cPort; + this.serverPort = sPort; + } + + public void StartServer() + { + this.SetupServerSocket(); + _acceptThread = new Thread(AcceptConnections); + _acceptThread.IsBackground = true; + _acceptThread.Start(); + } + + public void StopServer() + { + this.shouldStop = true; + _serverSocket.Close(); + _acceptThread.Join(); + } + + public static string ListIfs() + { + StringBuilder sb = new StringBuilder(); + IPHostEntry localMachineInfo = Dns.GetHostEntry(Dns.GetHostName()); + for(int i= 0;i< localMachineInfo.AddressList.Length; i++) + { + IPAddress address = localMachineInfo.AddressList[i]; + sb.AppendLine(string.Format("# {0}: {1}", i, address.ToString())); + } + return sb.ToString(); + } + + private void SetupServerSocket() + { + // Resolving local machine information + IPHostEntry localMachineInfo = Dns.GetHostEntry(Dns.GetHostName()); + IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Any, serverPort); + //IPEndPoint myEndpoint = new IPEndPoint(localMachineInfo.AddressList[this.ifIdx], serverPort); + + _log.InfoFormat("listening on {0}, port {1}", myEndpoint.Address, serverPort); + // Create the socket, bind it, and start listening + _serverSocket = new Socket(myEndpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + _serverSocket.Blocking = true; + _serverSocket.Bind(myEndpoint); + _serverSocket.Listen(32); + } + + private void AcceptConnections() + { + while (!shouldStop) + { // Accept a connection + try + { + Socket socket = _serverSocket.Accept(); + _log.InfoFormat("new connection from {0}", socket.RemoteEndPoint.ToString()); + ConnectionInfo connection = new ConnectionInfo(); + connection.Socket = socket; // Create the thread for the receives. + connection.Thread = new Thread(ProcessConnection); + connection.Thread.IsBackground = true; + connection.Thread.Start(connection); + // Store the socket + lock (_connections) + _connections.Add(connection); + } + catch (SocketException) { /* tu was */ } + Thread.Sleep(250); + } + this._serverSocket.Close(); + } + + private void ProcessConnection(object state) + { + ConnectionInfo connection = (ConnectionInfo)state; + try + { + while (!shouldStop) + { + // write all chunks in incoming chunk queue to this socket + + if (connection.Socket.Poll(1000, SelectMode.SelectWrite)) + { + while (connection.chunks.Count > 0) + { + Chunk aChunk = null; + lock (_connections) + { + aChunk = connection.chunks.Dequeue(); + } + int bytesToSend = aChunk.length; + byte[] buffer = aChunk.data; + while (bytesToSend > 0) + { + //string testOutput = Encoding.ASCII.GetString(aChunk.data); + //string[] lines = testOutput.Split('\r'); + //foreach(string line in lines) + // _log.Debug(line); + int actuallySentBytes = connection.Socket.Send(aChunk.data, aChunk.length, SocketFlags.None); + bytesToSend -= actuallySentBytes; + if (bytesToSend > 0) + { + byte[] newBuffer = new byte[bytesToSend]; + Array.Copy(buffer, aChunk.length - bytesToSend, newBuffer, 0, bytesToSend); + buffer = newBuffer; + } + } + aChunk = null; + } + } + else + { + // dump queue in this case, packets cannot be sent.. + lock (_connections) + { + connection.chunks.Clear(); + } + } + + Thread.Sleep(50); + } + } + catch (SocketException exc) + { + Console.WriteLine("Socket exception: " + exc.SocketErrorCode); + _log.WarnFormat("SocketException: {0}", exc.SocketErrorCode); + } + catch (Exception exc) + { Console.WriteLine("Exception: " + exc); } + finally + { + _log.InfoFormat("removing connection to {0}", connection.Socket.RemoteEndPoint); + connection.Socket.Close(); + lock (_connections) + _connections.Remove(connection); + GC.Collect(); + } + } + + + internal void StartClient() + { + this._clientThread = new Thread(new ThreadStart(this.ClientConnection)); + this._clientThread.Start(); + } + + private void ConnectClient() + { + try + { + if ((this.client != null) && (this.client.Connected)) return; + if (this.client != null) + { + this.client.Close(); + GC.Collect(); + } + this.client = new TcpClient(this.remoteServerAddress, this.clientPort); + this.clientStream = client.GetStream(); + _log.InfoFormat("TCP stream connected ({0}:{1})", this.remoteServerAddress, this.clientPort); + } + catch (Exception ex) + { + _log.ErrorFormat("ConnectClient(): {0}", ex.Message); + } + } + + private void ClientConnection() + { + while (!this.shouldStop) + { + try + { + if ((this.client == null) || !this.client.Connected) this.ConnectClient(); + if ((this.client != null) && this.client.Connected && this.clientStream.CanRead) + { + while (this.clientStream.CanRead && !this.shouldStop) + { + Chunk chunk = new Chunk(); + chunk.data = new byte[1024]; + chunk.length = this.clientStream.Read(chunk.data, 0, 1024); + + byte[] target = new byte[2048]; // einfach größer + int j = 0; + for (int i = 0; i < chunk.length; i++, j++) + { + target[j] = chunk.data[i]; + if (chunk.data[i] == 10) // LF + { + target[j] = 13; // CR + j++; + target[j] = 10; //LF + } + } + + if(j > chunk.length) // es wurden CR eingefügt + { + chunk.data = target; + chunk.length = j; + _log.DebugFormat("Chunk replaced, new length {0}", j); + } + + if (chunk.length > 0 && (this._connections.Count > 0)) + { + this.lastDataReceivedAt = DateTime.Now; // reset data timeout + + // clone chunk for each connected client + lock (this._connections) + { + foreach (ConnectionInfo connectionInfo in _connections) + { + connectionInfo.chunks.Enqueue(chunk.DeepClone()); + } + } + } + } + } + else + { + if ((DateTime.Now - lastDataReceivedAt) > TimeSpan.FromMinutes(10)) + { + // close client connection if no data is received for 10 minutes + _log.Info("Server inactive for 10 minutes, disconnecting"); + if(this.client != null) + this.client.Close(); + this.client = null; + } + Thread.Sleep(120000); // try connect again in 2 minutes + } + Thread.Sleep(50); + } + catch (Exception ex) + { + _log.ErrorFormat("client-side exception: {0}", ex.Message); + if (this.client != null) + { + this.client.Close(); + this.client = null; + } + Thread.Sleep(60000); // 60 Sekunden warten und neu verbinden + } + } + if(this.client != null) + this.client.Close(); + } + } +} diff --git a/AIS/LS100PortProxy/Program.cs b/AIS/LS100PortProxy/Program.cs new file mode 100644 index 00000000..9727658e --- /dev/null +++ b/AIS/LS100PortProxy/Program.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using log4net; + +namespace LS100PortProxy +{ + /// + /// http://msdn.microsoft.com/en-GB/library/bbx2eya8.aspx + /// Async server socket msdn + /// http://msdn.microsoft.com/en-us/library/5w7b7x5f.aspx + /// + class Program + { + static void Main(string[] args) + { + log4net.Config.XmlConfigurator.Configure(); + ILog _log = LogManager.GetLogger("Main"); + _log.Info("PortProxy started"); + if ((args.Length != 4) && (args.Length != 0)) + { + Console.WriteLine("Usage: "); + Console.WriteLine(" -> outputs interfaces"); + return; + } + + if (args.Length == 0) + { + Console.WriteLine(MultiplexManager.ListIfs()); + return; + } + + int ifIdx = Convert.ToInt32(args[0]); + string address = args[1]; + int clientPort = Convert.ToInt32(args[2]); + int serverPort = Convert.ToInt32(args[3]); + + MultiplexManager manager = new MultiplexManager(ifIdx, address, clientPort, serverPort); + manager.StartServer(); + + manager.StartClient(); + + Console.WriteLine("Port proxy läuft. Beliebige Taste drücken um zu beenden..."); + Console.ReadKey(); + Console.WriteLine("stopping.."); + manager.StopServer(); + Console.WriteLine("stopped."); + _log.Info("PortProxy stopped"); + } + } +} diff --git a/AIS/LS100PortProxy/Properties/AssemblyInfo.cs b/AIS/LS100PortProxy/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..8a811dd6 --- /dev/null +++ b/AIS/LS100PortProxy/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("LS100PortProxy")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("LS100PortProxy")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7ae7a332-a440-42d5-8d33-261e75424fe2")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AIS/LS100PortProxy/app.config b/AIS/LS100PortProxy/app.config new file mode 100644 index 00000000..ebdd9e2f --- /dev/null +++ b/AIS/LS100PortProxy/app.config @@ -0,0 +1,32 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AIS/LS100PortProxy/packages.config b/AIS/LS100PortProxy/packages.config new file mode 100644 index 00000000..09d3fdd6 --- /dev/null +++ b/AIS/LS100PortProxy/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/AIS/bsmd.AISService/AIS/AIS_ClassB.cs b/AIS/bsmd.AISService/AIS/AIS_ClassB.cs index d77d2077..63e7ddfd 100644 --- a/AIS/bsmd.AISService/AIS/AIS_ClassB.cs +++ b/AIS/bsmd.AISService/AIS/AIS_ClassB.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Text; using System.Diagnostics; +using log4net; namespace bsmd.AISService.AIS { @@ -27,6 +28,8 @@ namespace bsmd.AISService.AIS private int commStateSelectedFlag; private int commState; + private static ILog _log = LogManager.GetLogger(typeof(AIS_ClassB)); + #endregion #region Properties @@ -42,13 +45,9 @@ namespace bsmd.AISService.AIS { get { - return string.Format("{0}-{1}-{2} {3}:{4}:{5}", - this.timestamp.Year, this.timestamp.Month, this.timestamp.Day, - this.timestamp.Hour, this.timestamp.Minute, this.timestamp.Second); + return this.timestamp.ToString("yyyy-MM-ddTHH:mm:ss.000Z"); } - } - - + } public double Cog { @@ -141,7 +140,7 @@ namespace bsmd.AISService.AIS } catch (Exception e) { - Trace.WriteLine(string.Format("Error decoding AIS class B posreport: {0}", e.Message)); + _log.WarnFormat("Error decoding AIS class B posreport: {0}", e.Message); result = Status.PARSE_ERROR; } diff --git a/AIS/bsmd.AISService/AIS/AIS_ClassBExt.cs b/AIS/bsmd.AISService/AIS/AIS_ClassBExt.cs index a3956611..4e6473fb 100644 --- a/AIS/bsmd.AISService/AIS/AIS_ClassBExt.cs +++ b/AIS/bsmd.AISService/AIS/AIS_ClassBExt.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Text; using System.Diagnostics; +using log4net; namespace bsmd.AISService.AIS { @@ -35,6 +36,8 @@ namespace bsmd.AISService.AIS private int assignedMode; private int spare3; + private static ILog _log = LogManager.GetLogger(typeof(AIS_ClassBExt)); + #endregion #region Properties @@ -120,7 +123,7 @@ namespace bsmd.AISService.AIS catch (Exception e) { - Trace.WriteLine(string.Format("Error decoding AIS class B Ext posreport: {0}", e.Message)); + _log.WarnFormat("Error decoding AIS class B Ext posreport: {0}", e.Message); result = Status.PARSE_ERROR; } diff --git a/AIS/bsmd.AISService/AIS/AIS_ClassBStatic.cs b/AIS/bsmd.AISService/AIS/AIS_ClassBStatic.cs index 89c51757..465f3c2c 100644 --- a/AIS/bsmd.AISService/AIS/AIS_ClassBStatic.cs +++ b/AIS/bsmd.AISService/AIS/AIS_ClassBStatic.cs @@ -1,7 +1,7 @@ using System; using System.Collections; using System.Text; -using System.Diagnostics; +using log4net; namespace bsmd.AISService.AIS { @@ -17,6 +17,7 @@ namespace bsmd.AISService.AIS private string callsign; private int dimension; private int spare; + private static ILog _log = LogManager.GetLogger(typeof(AIS_ClassBStatic)); #endregion @@ -30,7 +31,7 @@ namespace bsmd.AISService.AIS public bool IsPartB { get { return this.partNumber == 1; } - } + } public string Name { @@ -40,7 +41,7 @@ namespace bsmd.AISService.AIS public string ShipType { get { return AIS_StaticData.GetShipType(this.shipType); } - } + } public string VendorId { @@ -57,6 +58,10 @@ namespace bsmd.AISService.AIS get { return this.shipType; } } + public int Dimension { get { return this.dimension; } } + + public int Spare { get { return this.spare; } } + // Todo: Dimensions.. #endregion @@ -120,7 +125,7 @@ namespace bsmd.AISService.AIS } catch (Exception e) { - Trace.WriteLine(string.Format("Error decoding AIS class B static data: {0}", e.Message)); + _log.WarnFormat("Error decoding AIS class B static data: {0}", e.Message); result = Status.PARSE_ERROR; } diff --git a/AIS/bsmd.AISService/AIS/AIS_PosReport.cs b/AIS/bsmd.AISService/AIS/AIS_PosReport.cs index 26a2b4fd..9d3e4c0c 100644 --- a/AIS/bsmd.AISService/AIS/AIS_PosReport.cs +++ b/AIS/bsmd.AISService/AIS/AIS_PosReport.cs @@ -1,7 +1,7 @@ using System; using System.Collections; using System.Diagnostics; -using System.Text; +using log4net; namespace bsmd.AISService.AIS { @@ -21,7 +21,9 @@ namespace bsmd.AISService.AIS private int reserved; private int spare; private int raim; - private int commstate; + private int commstate; + + private static ILog _log = LogManager.GetLogger(typeof(AIS_PosReport)); #region Properties @@ -38,9 +40,7 @@ namespace bsmd.AISService.AIS { get { - return string.Format("{0}-{1}-{2} {3}:{4}:{5}", - this.timestamp.Year, this.timestamp.Month, this.timestamp.Day, - this.timestamp.Hour, this.timestamp.Minute, this.timestamp.Second); + return this.timestamp.ToString("yyyy-MM-ddTHH:mm:ss.000Z"); } } @@ -181,7 +181,7 @@ namespace bsmd.AISService.AIS } catch (Exception e) { - Trace.WriteLine(string.Format("Error decoding AIS pos report: {0}", e.Message)); + _log.WarnFormat("Error decoding AIS pos report: {0}", e.Message); result = Status.PARSE_ERROR; } diff --git a/AIS/bsmd.AISService/AIS/AIS_QueueManager.cs b/AIS/bsmd.AISService/AIS/AIS_QueueManager.cs index faecdace..49d8f35d 100644 --- a/AIS/bsmd.AISService/AIS/AIS_QueueManager.cs +++ b/AIS/bsmd.AISService/AIS/AIS_QueueManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using System.Timers; using System.Diagnostics; +using System.Threading; namespace bsmd.AISService.AIS { @@ -25,8 +26,9 @@ public class AIS_QueueManager private List serialHandlerList = new List(); private List telnetHandlerList = new List(); private List dbUpdateQueue = new List(); - private Timer dbUpdateTimer = new Timer(); + private System.Timers.Timer dbUpdateTimer = new System.Timers.Timer(); private bool isStarted = false; + private Mutex dbSingleMutex = new Mutex(); #region Construction @@ -78,37 +80,41 @@ public class AIS_QueueManager void dbUpdateTimer_Elapsed(object sender, ElapsedEventArgs e) { - while (this.dbUpdateQueue.Count > 0) + + if (dbSingleMutex.WaitOne(0)) { - AIS_Target currentTarget = null; - lock (this.dbUpdateQueue) + while (this.dbUpdateQueue.Count > 0) { - // Trace.WriteLine(string.Format("Update queue size: {0}", this.dbUpdateQueue.Count)); - currentTarget = this.dbUpdateQueue[0]; - this.dbUpdateQueue.RemoveAt(0); - } - this.OnDBUpdateRequired(currentTarget); - } - - // remove stale targets - lock (this.activeTargetList) - { - - for(int i=0;i this.configuration.TargetStaleMins) + AIS_Target currentTarget = null; + lock (this.dbUpdateQueue) { - this.activeTargetList.RemoveAt(i); - i--; + // Trace.WriteLine(string.Format("Update queue size: {0}", this.dbUpdateQueue.Count)); + currentTarget = this.dbUpdateQueue[0]; + this.dbUpdateQueue.RemoveAt(0); + } + this.OnDBUpdateRequired(currentTarget); + } + + // remove stale targets + lock (this.activeTargetList) + { + + for (int i = 0; i < this.activeTargetList.Count; i++) + { + if (!this.activeTargetList[i].LastUpdate.HasValue) + continue; + + int diffmin = (int)(DateTime.Now - this.activeTargetList[i].LastUpdate.Value).TotalMinutes; + + if (diffmin > this.configuration.TargetStaleMins) + { + this.activeTargetList.RemoveAt(i); + i--; + } } } - } - + dbSingleMutex.ReleaseMutex(); + } } void decoder_AISMessageReceived(AIS message) diff --git a/AIS/bsmd.AISService/AIS/AIS_StaticData.cs b/AIS/bsmd.AISService/AIS/AIS_StaticData.cs index 6bff5030..36735efd 100644 --- a/AIS/bsmd.AISService/AIS/AIS_StaticData.cs +++ b/AIS/bsmd.AISService/AIS/AIS_StaticData.cs @@ -3,6 +3,8 @@ using System.Collections; using System.Diagnostics; using System.Text; +using log4net; + namespace bsmd.AISService.AIS { public class AIS_StaticData : AIS @@ -32,6 +34,8 @@ namespace bsmd.AISService.AIS private int dte; private int spare; + private static ILog _log = LogManager.GetLogger(typeof(AIS_StaticData)); + #endregion #region Properties @@ -120,22 +124,31 @@ namespace bsmd.AISService.AIS } } + public int DBShipType { get { return this.shiptype; } } + + public int DBDimension { get { return this.dimension; } } + + public int DBTypeOfDevice { get { return this.typeofdevice; } } + + public int DTE { get { return this.dte; } } + + public int Spare { get { return this.spare; } } + public string DBETA { get { if (this.eta.HasValue) { - return string.Format("{0}-{1}-{2} {3}:{4}:{5}", - this.eta.Value.Year, this.eta.Value.Month, this.eta.Value.Day, - this.eta.Value.Hour, this.eta.Value.Minute, this.eta.Value.Second); + return this.eta.Value.ToString("yyyy-MM-ddTHH:mm:ss.000Z"); } else + { return ""; + } } } - #endregion #region abstract method implementation @@ -197,8 +210,8 @@ namespace bsmd.AISService.AIS this.eta = new DateTime(DateTime.Now.Year, this.etamonth, this.etaday, this.etahour, this.etaminute, 0); } } - catch(Exception) { - Trace.WriteLine("ERROR creating ETA timestamp"); + catch(Exception e) { + _log.WarnFormat("ETA timestamp creation failed: {0}", e.Message); } this.maxpresetstaticdraught = AIS.GetInt(bits, 294, 301); @@ -219,7 +232,7 @@ namespace bsmd.AISService.AIS } catch (Exception e) { - Trace.WriteLine(string.Format("Error decoding AIS static data: {0}", e.Message)); + _log.WarnFormat("Error decoding AIS static data: {0}", e.Message); result = Status.PARSE_ERROR; } return result; diff --git a/AIS/bsmd.AISService/AIS/AIS_Telnet.cs b/AIS/bsmd.AISService/AIS/AIS_Telnet.cs index 5a8ae60b..753bb27d 100644 --- a/AIS/bsmd.AISService/AIS/AIS_Telnet.cs +++ b/AIS/bsmd.AISService/AIS/AIS_Telnet.cs @@ -13,6 +13,8 @@ using System.IO; using System.Text; using System.Net.Sockets; +using log4net; + namespace bsmd.AISService.AIS { public class AIS_Telnet @@ -29,6 +31,8 @@ namespace bsmd.AISService.AIS private int port; private DateTime? lastRead; + private static ILog _log = LogManager.GetLogger(typeof(AIS_Telnet)); + #endregion public AIS_Telnet(string theHostname, int thePort) @@ -99,7 +103,7 @@ namespace bsmd.AISService.AIS } catch (Exception ex) { - System.Diagnostics.Trace.WriteLine(string.Format("exception reading from tcp stream: {0}", ex.Message)); + _log.ErrorFormat("exception reading from tcp stream: {0}", ex.Message); result = ""; } } @@ -114,7 +118,7 @@ namespace bsmd.AISService.AIS { this.tcpSocket.Close(); this.tcpSocket = null; - System.Diagnostics.Trace.WriteLine("closing inactive TcpClient"); + _log.Info("closing inactive TcpClient"); this.lastRead = DateTime.Now; // reset timer } } @@ -138,12 +142,11 @@ namespace bsmd.AISService.AIS if ((this.tcpSocket != null) && (this.tcpSocket.Connected)) return; this.tcpSocket = new TcpClient(this.hostname, this.port); this.tcpStream = tcpSocket.GetStream(); - System.Diagnostics.Trace.WriteLine(string.Format("TCP stream connected ({0}:{1})", this.hostname, this.port)); + _log.InfoFormat("TCP stream connected ({0}:{1})", this.hostname, this.port); } catch (Exception ex) - { - System.Diagnostics.Trace.WriteLine( - string.Format("AIS_Telnet: cannot connect to ({0}:{1}) : {2}", this.hostname, this.port, ex.Message)); + { + _log.WarnFormat("AIS_Telnet: cannot connect to ({0}:{1}) : {2}", this.hostname, this.port, ex.Message); } } } diff --git a/AIS/bsmd.AISService/AIS/NMEA.cs b/AIS/bsmd.AISService/AIS/NMEA.cs index 71b74f2d..321ae6c6 100644 --- a/AIS/bsmd.AISService/AIS/NMEA.cs +++ b/AIS/bsmd.AISService/AIS/NMEA.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using log4net; namespace bsmd.AISService.AIS { @@ -8,7 +9,9 @@ namespace bsmd.AISService.AIS { protected string type = ""; protected string data; - protected string[] elements = null; + protected string[] elements = null; + + protected static ILog _log = LogManager.GetLogger(typeof(NMEA)); public enum Status { @@ -60,7 +63,7 @@ namespace bsmd.AISService.AIS } catch (Exception ex) { - System.Diagnostics.Trace.WriteLine(string.Format("Error decoding sentence: {0}, {1}", ex.Message, ex.StackTrace)); + _log.ErrorFormat("Error decoding sentence: {0}, {1}", ex.Message, ex.StackTrace); return null; } } diff --git a/AIS/bsmd.AISService/AIS/NMEA_AIS_Sentence.cs b/AIS/bsmd.AISService/AIS/NMEA_AIS_Sentence.cs index 9b916451..4da0066a 100644 --- a/AIS/bsmd.AISService/AIS/NMEA_AIS_Sentence.cs +++ b/AIS/bsmd.AISService/AIS/NMEA_AIS_Sentence.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using log4net; namespace bsmd.AISService.AIS { @@ -75,11 +76,11 @@ namespace bsmd.AISService.AIS { string fillbits_string = this.elements[6].Substring(0, this.elements[6].IndexOf('*')); if(!Int32.TryParse(fillbits_string, out this.fillbits)) - System.Diagnostics.Trace.WriteLine("AIS_Sentence.Decode(): fillbits are no integer"); + _log.Warn("AIS_Sentence.Decode(): fillbits are no integer"); } catch (ArgumentOutOfRangeException) { - System.Diagnostics.Trace.WriteLine("AIS_Sentence.Decode(): split() problem, trouble decoding fillbits"); + _log.Warn("AIS_Sentence.Decode(): split() problem, trouble decoding fillbits"); } } } diff --git a/AIS/bsmd.AISService/AIS/NMEA_PNMLS_Sentence.cs b/AIS/bsmd.AISService/AIS/NMEA_PNMLS_Sentence.cs index 65a61dea..1498395d 100644 --- a/AIS/bsmd.AISService/AIS/NMEA_PNMLS_Sentence.cs +++ b/AIS/bsmd.AISService/AIS/NMEA_PNMLS_Sentence.cs @@ -48,7 +48,7 @@ namespace bsmd.AISService.AIS } catch (FormatException) { - Trace.WriteLine("NMEA [PNMLS] input format error"); + _log.Warn("NMEA [PNMLS] input format error"); } } diff --git a/AIS/bsmd.AISService/AIS/SerialDataHandler.cs b/AIS/bsmd.AISService/AIS/SerialDataHandler.cs index 9e0395d8..7551313a 100644 --- a/AIS/bsmd.AISService/AIS/SerialDataHandler.cs +++ b/AIS/bsmd.AISService/AIS/SerialDataHandler.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using System.Diagnostics; +using log4net; namespace bsmd.AISService.AIS { @@ -10,6 +11,8 @@ namespace bsmd.AISService.AIS private Serial_IO serial_IO; private AIS_Decoder decoder; + private static ILog _log = LogManager.GetLogger(typeof(SerialDataHandler)); + public SerialDataHandler(Serial_IO io, AIS_Decoder decoder) { this.serial_IO = io; @@ -54,7 +57,7 @@ namespace bsmd.AISService.AIS } else { - Trace.WriteLine("Serial data handler: NMEA decoder returned null sentence"); + _log.Info("Serial data handler: NMEA decoder returned null sentence"); } } diff --git a/AIS/bsmd.AISService/AIS/Serial_IO.cs b/AIS/bsmd.AISService/AIS/Serial_IO.cs index 05817b3c..ab1c1ef7 100644 --- a/AIS/bsmd.AISService/AIS/Serial_IO.cs +++ b/AIS/bsmd.AISService/AIS/Serial_IO.cs @@ -95,8 +95,7 @@ namespace bsmd.AISService.AIS try { string line = this.port.ReadLine(); - this.OnInputLineRead(line); - //System.Diagnostics.Trace.WriteLine(line); + this.OnInputLineRead(line); } catch (Exception) { } } diff --git a/AIS/bsmd.AISService/AIS/TelnetDataHandler.cs b/AIS/bsmd.AISService/AIS/TelnetDataHandler.cs index 686c737d..047d4d82 100644 --- a/AIS/bsmd.AISService/AIS/TelnetDataHandler.cs +++ b/AIS/bsmd.AISService/AIS/TelnetDataHandler.cs @@ -12,6 +12,8 @@ using System.Collections.Generic; using System.Threading; using System.Diagnostics; +using log4net; + namespace bsmd.AISService.AIS { public class TelnetDataHandler @@ -21,6 +23,8 @@ namespace bsmd.AISService.AIS Thread readerThread; bool requestStop; + internal static ILog _log = LogManager.GetLogger(typeof(TelnetDataHandler)); + public TelnetDataHandler(AIS_Telnet telnetConnection, AIS_Decoder aisDecoder) { this.aisTelnet = telnetConnection; @@ -70,7 +74,7 @@ namespace bsmd.AISService.AIS private void ReaderThread() { NMEA.Status nmea_Status = NMEA.Status.OK; - System.Diagnostics.Trace.WriteLine("starting telnet reader thread"); + _log.Info("starting telnet reader thread"); while (!requestStop) { try @@ -92,7 +96,7 @@ namespace bsmd.AISService.AIS } else { - Trace.WriteLine("Serial data handler: NMEA decoder returned null/empty sentence"); + _log.Info("Serial data handler: NMEA decoder returned null/empty sentence"); } } } @@ -101,8 +105,7 @@ namespace bsmd.AISService.AIS var st = new StackTrace(ex, true); var frame = st.GetFrame(0); var line = frame.GetFileLineNumber(); - Trace.WriteLine(string.Format("Exception in telnet reader thread: {0}, top frame ln {1}", ex.Message, line)); - Trace.WriteLine(ex.StackTrace); + _log.WarnFormat("Exception in telnet reader thread: {0}, top frame ln {1}", ex.Message, line); } Thread.Sleep(100); } diff --git a/AIS/bsmd.AISService/AISService.cs b/AIS/bsmd.AISService/AISService.cs index b7115204..96bbdb75 100644 --- a/AIS/bsmd.AISService/AISService.cs +++ b/AIS/bsmd.AISService/AISService.cs @@ -66,6 +66,7 @@ namespace bsmd.AISService protected override void OnStop() { this.qManager.Stop(); + _log.Info("AIS Service stopped."); } protected void Init(string[] args) @@ -74,7 +75,7 @@ namespace bsmd.AISService if (configuration == null) { - Console.WriteLine(string.Format("cannot read configuration {0}", config_filename)); + _log.ErrorFormat("cannot read configuration {0}", config_filename); return; } @@ -82,7 +83,7 @@ namespace bsmd.AISService dbConnector.ConnectionString = configuration.DBConnectionString; if (!dbConnector.Open()) { - Console.WriteLine("Error connecting to database"); + _log.Error("Error connecting to database"); return; } @@ -90,14 +91,15 @@ namespace bsmd.AISService this.qManager = new AIS_QueueManager(configuration, AISStation.CreateSerial_IOs(stationList), AISStation.CreateAIS_Telnets(stationList)); qManager.DBUpdateRequired += new AIS_QueueManager.AISQueueChangedHandler(dbConnector.Update); - qManager.AISQueueChanged += new AIS_QueueManager.AISQueueChangedHandler(aisDecoder_AISMessageReceived); + // qManager.AISQueueChanged += new AIS_QueueManager.AISQueueChangedHandler(aisDecoder_AISMessageReceived); } + /* protected void aisDecoder_AISMessageReceived(AIS_Target target) { Console.WriteLine(string.Format("{0}: {1} Pos:{2} {3} at {4}", target.Station, target.Name, target.Latitude, target.Longitude, target.LastUpdate)); } - + */ } } diff --git a/AIS/bsmd.AISService/App.config b/AIS/bsmd.AISService/App.config index 0ab7508f..4a686434 100644 --- a/AIS/bsmd.AISService/App.config +++ b/AIS/bsmd.AISService/App.config @@ -4,7 +4,31 @@
+
+ + + + + + + + + + + + + + + + + + + + + + + diff --git a/AIS/bsmd.AISService/DB/AISPosReport.cs b/AIS/bsmd.AISService/DB/AISPosReport.cs index aee2b125..6d05d842 100644 --- a/AIS/bsmd.AISService/DB/AISPosReport.cs +++ b/AIS/bsmd.AISService/DB/AISPosReport.cs @@ -8,12 +8,14 @@ using System.Collections.Generic; using System.Text; using bsmd.AISService.AIS; +using log4net; namespace bsmd.AISService.DB { + internal class AISPosReport : AISBaseEntity { + + private static ILog _log = LogManager.GetLogger(typeof(AISPosReport)); - internal class AISPosReport : AISBaseEntity - { /// /// Saves a (class A or B) position report /// @@ -51,8 +53,8 @@ namespace bsmd.AISService.DB AIS_ClassB pr = target.LastPosReport as AIS_ClassB; aisStation.UpdateWithPositionReport(pr.MMSI, pr.Latitude, pr.Longitude, pr.Timestamp); - string query = string.Format("INSERT INTO aisposreport (Id, MMSI, NavStatus, ROT, COG, SOG, Accuracy, Longitude, Latitude, Heading, Timestamp, Reserved, Spare, Raim, CommState, Stationid) VALUES ('{0}', {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, '{10}', {11},{12},{13},{14},'{15}')", - pr.MMSI, 0, 0, pr.CogVal, pr.SogVal, 0, pr.LongitudeVal, pr.LatitudeVal, + string query = string.Format("INSERT INTO aisposreport (Id, MMSI, NavStatus, ROT, COG, SOG, Accuracy, Longitude, Latitude, Heading, Timestamp, Reserved, Spare, Raim, CommState, AISStationId) VALUES ('{0}', {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, '{10}', {11}, {12}, {13}, {14}, '{15}')", + pr.Id, pr.MMSI, 0, 0, pr.CogVal, pr.SogVal, 0, pr.LongitudeVal, pr.LatitudeVal, pr.TrueHeading ?? 511, pr.DBTimestamp, pr.Reserved, pr.Spare, pr.Raim, pr.CommState, (aisStation != null) ? aisStation.Id : Guid.Empty); con.ExecuteNonQuery(query); @@ -62,12 +64,12 @@ namespace bsmd.AISService.DB if (target.LastPosReport is AIS_ClassBExt) { - Trace.WriteLine("AIS class B ext not supported (yet)"); - // TODO: Import ClassB Extended report! + _log.Info("AIS class B ext not supported (yet)"); + } - Trace.WriteLine(string.Format("save pos report: we should not be here.. class type: {0}", target)); + _log.WarnFormat("save pos report: we should not be here.. class type: {0}", target); return null; } diff --git a/AIS/bsmd.AISService/DB/AISStaticData.cs b/AIS/bsmd.AISService/DB/AISStaticData.cs index 051dfcd8..5513e948 100644 --- a/AIS/bsmd.AISService/DB/AISStaticData.cs +++ b/AIS/bsmd.AISService/DB/AISStaticData.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.Diagnostics; using bsmd.AISService.AIS; +using log4net; namespace bsmd.AISService.DB { @@ -21,6 +22,7 @@ namespace bsmd.AISService.DB } private const string LoadDBShipsQuery = "SELECT aisposreport.MMSI, aisposreport.timestamp, aisposreport.latitude, aisposreport.longitude, aisposreport.stationid, aisposreport.cog, aisposreport.heading, aisposreport.navstatus, aisstaticdata.callsign, aisstaticdata.name, aisstaticdata.shiptype, aisstaticdata.classb, aisstaticdata.shipdescription FROM aisstaticdata JOIN hotposition ON aisstaticdata.mmsi = hotposition.mmsi JOIN aisposreport ON aisposreport.id = hotposition.pid ORDER BY aisstaticdata.name"; + private static ILog _log = LogManager.GetLogger(typeof(AISStaticData)); #region Fields @@ -188,12 +190,12 @@ namespace bsmd.AISService.DB /// /// target to save /// id of insert operation (to update hotposition table) - public static int? Save(AIS_Target target, DBConnector con, AISStation aisStation) + public static Guid? Save(AIS_Target target, DBConnector con, AISStation aisStation) { if(target.LastStaticData == null) return null; int mmsi = -1; - int id = -1; + Guid id = Guid.Empty; if(target.LastStaticData is AIS_StaticData) { mmsi = ((AIS_StaticData)target.LastStaticData).MMSI; @@ -207,96 +209,67 @@ namespace bsmd.AISService.DB if (result != null) // update { - id = Convert.ToInt32(result); + id = (Guid) result; } - + #region Class A if (target.LastStaticData is AIS_StaticData) { AIS_StaticData staticData = target.LastStaticData as AIS_StaticData; - - if (id >= 0) - { - if (staticData.ETA.HasValue) - { - query = string.Format("UPDATE aisstaticdata SET imonumber={0}, callsign='{1}', name='{2}', shiptype={3}, typeofdevice='{4}', shipdescription='{5}', eta='{6}', destination='{7}', breadth={8}, length={9}, draught='{10}', stationid={11}, classb=0 WHERE id={12}", - staticData.IMONumber, - staticData.Callsign.Replace("'","''"), - staticData.Name.Replace("'", "''"), - staticData.ShipTypeVal, - staticData.DeviceName, - staticData.ShipType, - staticData.DBETA, - staticData.Destination.Replace("'", "''"), - staticData.Breadth, - staticData.Length, - staticData.Draught, - aisStation.Id, - id); - } - else - { - query = string.Format("UPDATE aisstaticdata SET imonumber={0}, callsign='{1}', name='{2}', shiptype={3}, typeofdevice='{4}', shipdescription='{5}', destination='{6}', breadth={7}, length={8}, draught='{9}', stationid={10}, classb=0 WHERE id={11}", - staticData.IMONumber, - staticData.Callsign.Replace("'", "''"), - staticData.Name.Replace("'", "''"), - staticData.ShipTypeVal, - staticData.DeviceName, - staticData.ShipType, - staticData.Destination.Replace("'", "''"), - staticData.Breadth, - staticData.Length, - staticData.Draught, - aisStation.Id, - id); - } + if (id != Guid.Empty) + { + query = string.Format("UPDATE aisstaticdata SET imonumber={0}, callsign='{1}', name='{2}', shiptype={3}, dimension={4}, typeofdevice={5}, maxpresetstaticdraught={6}, " + + "destination='{7}', dte={8}, spare={9}, mmsi={10}, eta={11}, classb={12}, breadth={13}, length={14}, aisstation_id='{15}' " + + "WHERE Id='{16}'", + staticData.IMONumber, + (staticData.Callsign ?? "").Replace("'", "''"), + (staticData.Name ?? "").Replace("'", "''"), + staticData.ShipTypeVal, + staticData.DBDimension, + staticData.DBTypeOfDevice, + staticData.Draught, + (staticData.Destination ?? "").Replace("'", "''"), + staticData.DTE, + staticData.Spare, + staticData.MMSI, + staticData.ETA.HasValue ? string.Format("'{0}'", staticData.DBETA) : "NULL", + 0, + staticData.Breadth, + staticData.Length, + aisStation.Id, + id); + con.ExecuteNonQuery(query); } else { - if (staticData.ETA.HasValue) - { - - query = string.Format("INSERT INTO aisstaticdata SET imonumber={0}, callsign='{1}', name='{2}', shiptype={3}, typeofdevice='{4}', shipdescription='{5}', eta='{6}', destination='{7}', breadth={8}, length={9}, draught='{10}', stationid={11}, mmsi={12}, classb=0", - staticData.IMONumber, - staticData.Callsign.Replace("'", "''"), - staticData.Name.Replace("'", "''"), - staticData.ShipTypeVal, - staticData.DeviceName, - staticData.ShipType, - staticData.DBETA, - staticData.Destination.Replace("'", "''"), - staticData.Breadth, - staticData.Length, - staticData.Draught, - aisStation.Id, - staticData.MMSI); - } - else - { - query = string.Format("INSERT INTO aisstaticdata SET imonumber={0}, callsign='{1}', name='{2}', shiptype={3}, typeofdevice='{4}', shipdescription='{5}', destination='{6}', breadth={7}, length={8}, draught='{9}', stationid={10}, mmsi={11}, classb=0", - staticData.IMONumber, - staticData.Callsign.Replace("'", "''"), - staticData.Name.Replace("'", "''"), - staticData.ShipTypeVal, - staticData.DeviceName, - staticData.ShipType, - staticData.Destination.Replace("'", "''"), - staticData.Breadth, - staticData.Length, - staticData.Draught, - aisStation.Id, - staticData.MMSI); - } + id = Guid.NewGuid(); + + query = string.Format("INSERT INTO aisstaticdata (Id, aisversion, imoNumber, callsign, name, shiptype, dimension, typeofdevice, maxpresetstaticdraught, destination, " + + "dte, spare, mmsi, eta, classb, breadth, length, aisstation_id) VALUES ('{0}', {1}, {2}, '{3}', '{4}', {5}, {6}, {7}, {8}, '{9}', {10}, {11}, {12}, {13}, {14}, {15}, {16}, '{17}')", + id, + 0, + staticData.IMONumber, + (staticData.Callsign ?? "").Replace("'", "''"), + (staticData.Name ?? "").Replace("'", "''"), + staticData.ShipTypeVal, + staticData.DBDimension, + staticData.DBTypeOfDevice, + staticData.Draught, + (staticData.Destination ?? "").Replace("'", "''"), + staticData.DTE, + staticData.Spare, + staticData.MMSI, + staticData.ETA.HasValue ? string.Format("'{0}'", staticData.DBETA) : "NULL", + 0, + staticData.Breadth, + staticData.Length, + aisStation.Id.Value); con.ExecuteNonQuery(query); - - id = Convert.ToInt32(con.ExecuteScalar("SELECT LAST_INSERT_ID()")); - } - } #endregion @@ -307,31 +280,32 @@ namespace bsmd.AISService.DB { AIS_ClassBStatic staticData = target.LastStaticData as AIS_ClassBStatic; - if (id >= 0) // Update + if (id != Guid.Empty) // Update { - query = string.Format("UPDATE aisstaticdata SET stationid={0}, shiptype={1}, classb=1", aisStation.Id, staticData.ShipTypeVal); - if(staticData.Callsign != null) query += string.Format(", callsign='{0}'", staticData.Callsign); - if(staticData.Name != null) query += string.Format(", name='{0}'", staticData.Name); - if(staticData.VendorId != null) query += string.Format(", typeofdevice='{0}'", staticData.VendorId); - if(staticData.ShipType != null) query += string.Format(", shipdescription='{0}'", staticData.ShipType); - query += string.Format(" WHERE id={0}", id); + query = string.Format("UPDATE aisstaticdata SET aisstation_id = '{0}', shiptype={1}, classb=1, dimension = {2}, spare = {3}", + aisStation.Id, staticData.ShipTypeVal, staticData.Dimension, staticData.Spare); + if(staticData.Callsign != null) query += string.Format(", callsign='{0}'", staticData.Callsign.Replace("'", "''")); + if(staticData.Name != null) query += string.Format(", name='{0}'", staticData.Name.Replace("'","''")); + query += string.Format(" WHERE Id='{0}'", id); con.ExecuteNonQuery(query); } else // Insert { - query = string.Format("INSERT INTO aisstaticdata SET callsign='{0}', name='{1}', shiptype={2}, typeofdevice='{3}', shipdescription='{4}', stationid={5}, mmsi={6}, classb=1", - staticData.Callsign, - staticData.Name, + id = Guid.NewGuid(); + query = string.Format("INSERT INTO aisstaticdata (Id, callsign, name, shiptype, classb, dimension, spare, aisstation_id, mmsi) VALUES ('{0}', '{1}', '{2}', {3}, {4}, {5}, {6}, '{7}', {8})", + id, + (staticData.Callsign ?? "").Replace("'","''"), + (staticData.Name ?? "").Replace("'","''"), staticData.ShipTypeVal, - staticData.VendorId, - staticData.ShipType, + 1, + staticData.Dimension, + staticData.Spare, aisStation.Id, staticData.MMSI ); - con.ExecuteNonQuery(query); - id = Convert.ToInt32(con.ExecuteScalar("SELECT LAST_INSERT_ID()")); + con.ExecuteNonQuery(query); } } @@ -412,7 +386,7 @@ namespace bsmd.AISService.DB result.Add(ship); } reader.Close(); - Trace.WriteLine(string.Format("AISStaticData: {0} ships loaded from DB", result.Count)); + _log.InfoFormat("AISStaticData: {0} ships loaded from DB", result.Count); return result; } diff --git a/AIS/bsmd.AISService/DB/AISStation.cs b/AIS/bsmd.AISService/DB/AISStation.cs index 37cb1090..7a4061f4 100644 --- a/AIS/bsmd.AISService/DB/AISStation.cs +++ b/AIS/bsmd.AISService/DB/AISStation.cs @@ -5,6 +5,7 @@ using System.Data; using System.Globalization; using bsmd.AISService.AIS; +using log4net; namespace bsmd.AISService.DB { @@ -12,8 +13,7 @@ namespace bsmd.AISService.DB public class AISStation : AISBaseEntity { #region private members - - private Guid station_Id; + private string name; private bool active; private string comport; @@ -30,6 +30,7 @@ namespace bsmd.AISService.DB private DateTime? lastPosTimestamp; private bool isDirty = false; private Dictionary targets = new Dictionary(); + private static ILog _log = LogManager.GetLogger(typeof(AISStation)); #endregion @@ -101,7 +102,7 @@ namespace bsmd.AISService.DB this.comport, this.name, this.baudrate, - this.station_Id); + this.Id); if (con.ExecuteNonQuery(query) == 1) { @@ -177,7 +178,7 @@ namespace bsmd.AISService.DB while (reader.Read()) { AISStation station = new AISStation(); - station.station_Id = reader.GetGuid(0); + station.Id = reader.GetGuid(0); station.name = reader.GetString(1); station.active = reader.GetBoolean(2); station.latitude = (double) reader.GetInt32(3) / 600000; @@ -201,11 +202,11 @@ namespace bsmd.AISService.DB public static AISStation CreateStation(string name, DBConnector con) { AISStation newStation = new AISStation(); - newStation.station_Id = Guid.NewGuid(); + newStation.Id = Guid.NewGuid(); newStation.name = name; newStation.active = true; string query = string.Format("INSERT INTO aisstation SET Id='{0}', name='{1}',active=1", - newStation.station_Id, newStation.name); + newStation.Id, newStation.name); con.ExecuteNonQuery(query); return newStation; @@ -243,8 +244,7 @@ namespace bsmd.AISService.DB } catch (Exception ex) { - System.Diagnostics.Trace.WriteLine(string.Format("AIS_Telnet: cannot connect to host {0} port {1}: {2}", - station.TelnetHost ?? "", station.TelnetPort, ex.Message)); + _log.WarnFormat("AIS_Telnet: cannot connect to host {0} port {1}: {2}", station.TelnetHost ?? "", station.TelnetPort, ex.Message); } } } diff --git a/AIS/bsmd.AISService/DB/DBConnector.cs b/AIS/bsmd.AISService/DB/DBConnector.cs index 88252259..4a53cb7e 100644 --- a/AIS/bsmd.AISService/DB/DBConnector.cs +++ b/AIS/bsmd.AISService/DB/DBConnector.cs @@ -9,6 +9,7 @@ using System.Data; using System.Data.SqlClient; using bsmd.AISService.AIS; +using log4net; namespace bsmd.AISService.DB { @@ -20,6 +21,7 @@ namespace bsmd.AISService.DB private List watchkeeperShips = null; private List dbShips = null; private Dictionary updateStations = null; + private static ILog _log = LogManager.GetLogger(typeof(DBConnector)); public DBConnector() { } @@ -65,21 +67,48 @@ namespace bsmd.AISService.DB if (!this.CheckConnection()) return null; SqlCommand cmd = new SqlCommand(query, this.dbCon); - return cmd.ExecuteReader(); + SqlDataReader result = null; + try + { + result = cmd.ExecuteReader(); + } + catch(SqlException ex) + { + _log.ErrorFormat("ExecuteQuery: {0}", ex.Message); + } + return result; } public int ExecuteNonQuery(string query) { if (!this.CheckConnection()) return 0; SqlCommand cmd = new SqlCommand(query, this.dbCon); - return cmd.ExecuteNonQuery(); + int result = -1; + try + { + result = cmd.ExecuteNonQuery(); + } + catch(SqlException ex) + { + _log.ErrorFormat("ExecuteNonQuery: [{0}] {1} ", query, ex.Message); + } + return result; } public object ExecuteScalar(string query) { if (!this.CheckConnection()) return 0; SqlCommand cmd = new SqlCommand(query, this.dbCon); - return cmd.ExecuteScalar(); + object result = null; + try + { + result = cmd.ExecuteScalar(); + } + catch(SqlException ex) + { + _log.ErrorFormat("ExecuteScalar: [{0}] {1} ", query, ex.Message); + } + return result; } public bool Open() @@ -94,7 +123,7 @@ namespace bsmd.AISService.DB } catch (SqlException anException) { - Trace.WriteLine(string.Format("cannot open SQL DB connection: {0}", anException.Message)); + _log.ErrorFormat("cannot open SQL DB connection: {0}", anException.Message); } return false; } @@ -120,9 +149,9 @@ namespace bsmd.AISService.DB if (this.updateStations == null) { this.updateStations = new Dictionary(); - Trace.WriteLine("loading stations.."); + _log.Info("loading stations.."); List stations = AISStation.LoadStations(this); - Trace.WriteLine(string.Format("{0} stations loaded", stations.Count)); + _log.InfoFormat("{0} stations loaded", stations.Count); foreach (AISStation station in stations) if (!updateStations.ContainsKey(station.Name)) updateStations.Add(station.Name, station); @@ -140,7 +169,7 @@ namespace bsmd.AISService.DB } else { - Trace.WriteLine(string.Format("last pos report is null for target {0}", target.MMSI)); + _log.InfoFormat("last pos report is null for target {0}", target.MMSI); } if (target.LastStaticData != null) { @@ -153,8 +182,9 @@ namespace bsmd.AISService.DB } target.UpdateDB = false; // reset update flag - // Watchkeeper check + // Watchkeeper check + /* if (this.watchkeeperShips == null) this.watchkeeperShips = AISWatchkeeper.GetWatchkeeperShips(this); @@ -170,7 +200,7 @@ namespace bsmd.AISService.DB if (!target.IsWatchkeeperShip.HasValue) // didn't find it target.IsWatchkeeperShip = false; } - + */ } @@ -200,7 +230,7 @@ namespace bsmd.AISService.DB } catch (SqlException ex) { - System.Diagnostics.Trace.WriteLine(ex.ToString()); + _log.Error(ex.ToString()); } } return this.dbCon.State == System.Data.ConnectionState.Open; diff --git a/AIS/bsmd.AISService/Program.cs b/AIS/bsmd.AISService/Program.cs index 6e5351dc..916a639f 100644 --- a/AIS/bsmd.AISService/Program.cs +++ b/AIS/bsmd.AISService/Program.cs @@ -22,6 +22,9 @@ namespace bsmd.AISService /// public static int Main(string[] args) { + + log4net.Config.XmlConfigurator.Configure(); + if (Environment.UserInteractive) { if (args.Length > 0) @@ -85,7 +88,7 @@ namespace bsmd.AISService if (ex.InnerException != null && ex.InnerException.GetType() == typeof(Win32Exception)) { Win32Exception wex = (Win32Exception)ex.InnerException; - Console.WriteLine("Error(0x{0:X}): Service already installed!", wex.ErrorCode); + Console.WriteLine("Error {0}: {1}", wex.ErrorCode, wex.Message); return wex.ErrorCode; } else diff --git a/AIS/bsmd.AISService/ProjectInstaller.Designer.cs b/AIS/bsmd.AISService/ProjectInstaller.Designer.cs index 88477230..a254634e 100644 --- a/AIS/bsmd.AISService/ProjectInstaller.Designer.cs +++ b/AIS/bsmd.AISService/ProjectInstaller.Designer.cs @@ -33,6 +33,7 @@ // // serviceProcessInstallerAIS // + this.serviceProcessInstallerAIS.Account = System.ServiceProcess.ServiceAccount.LocalSystem; this.serviceProcessInstallerAIS.Password = null; this.serviceProcessInstallerAIS.Username = null; // diff --git a/AIS/bsmd.AISService/ProjectInstaller.resx b/AIS/bsmd.AISService/ProjectInstaller.resx index 7fb3a7a1..b267aed6 100644 --- a/AIS/bsmd.AISService/ProjectInstaller.resx +++ b/AIS/bsmd.AISService/ProjectInstaller.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 17, 17 + 17, 54 196, 17 diff --git a/AIS/bsmd.AISService/bsmd.AISService.csproj b/AIS/bsmd.AISService/bsmd.AISService.csproj index 60b6de37..fd63376c 100644 --- a/AIS/bsmd.AISService/bsmd.AISService.csproj +++ b/AIS/bsmd.AISService/bsmd.AISService.csproj @@ -102,7 +102,9 @@ - + + Designer + diff --git a/Stundensheet.xlsx b/Stundensheet.xlsx index 8bbed0bd..fbf505d9 100644 Binary files a/Stundensheet.xlsx and b/Stundensheet.xlsx differ