Aktuellen Stand von SMSPLASH01 wieder hergeholt (separate LS100PortProxy Version für BSMD-AIS, da hier manuell <CR>'s in den Datenstrom eingebaut werden müssen)

This commit is contained in:
Daniel Schick 2018-04-06 18:26:24 +00:00
parent 09f8a9953f
commit e672bb8dee
33 changed files with 814 additions and 195 deletions

Binary file not shown.

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1B23254E-62EA-4AAF-803C-AAA0622B4570}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LS100PortProxy</RootNamespace>
<AssemblyName>LS100PortProxy</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RunCodeAnalysis>true</RunCodeAnalysis>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<OutputPath>bin\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<OutputPath>bin\Release\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MultiplexManager.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Binary file not shown.

View File

@ -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

View File

@ -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<ConnectionInfo> _connections = new List<ConnectionInfo>();
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<Chunk> chunks = new Queue<Chunk>();
}
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();
}
}
}

View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
namespace LS100PortProxy
{
/// <summary>
/// http://msdn.microsoft.com/en-GB/library/bbx2eya8.aspx
/// Async server socket msdn
/// http://msdn.microsoft.com/en-us/library/5w7b7x5f.aspx
/// </summary>
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: <progname> <interface #> <remoteaddress> <clientport> <serverport>");
Console.WriteLine("<progname> -> 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");
}
}
}

View File

@ -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")]

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<root>
<level value="INFO"/>
<appender-ref ref="LogFileAppender"/>
<appender-ref ref="TraceAppender"/>
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="LS100PortProxy.log"/>
<param name="AppendToFile" value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="10MB"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date [%thread] %-5level [%logger] - %message%newline"/>
</layout>
</appender>
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c %m%n"/>
</layout>
</appender>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
</configuration>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.8" targetFramework="net461" />
</packages>

View File

@ -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,14 +45,10 @@ 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
{
get { return this.cog / 10.0f; }
@ -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;
}

View File

@ -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;
}

View File

@ -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
@ -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;
}

View File

@ -1,7 +1,7 @@
using System;
using System.Collections;
using System.Diagnostics;
using System.Text;
using log4net;
namespace bsmd.AISService.AIS
{
@ -23,6 +23,8 @@ namespace bsmd.AISService.AIS
private int raim;
private int commstate;
private static ILog _log = LogManager.GetLogger(typeof(AIS_PosReport));
#region Properties
public Guid Id { get { if (!this.id.HasValue) this.id = Guid.NewGuid(); return this.id.Value; } }
@ -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;
}

View File

@ -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<SerialDataHandler> serialHandlerList = new List<SerialDataHandler>();
private List<TelnetDataHandler> telnetHandlerList = new List<TelnetDataHandler>();
private List<AIS_Target> dbUpdateQueue = new List<AIS_Target>();
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.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)
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)

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using log4net;
namespace bsmd.AISService.AIS
{
@ -10,6 +11,8 @@ namespace bsmd.AISService.AIS
protected string data;
protected string[] elements = null;
protected static ILog _log = LogManager.GetLogger(typeof(NMEA));
public enum Status
{
OK,
@ -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;
}
}

View File

@ -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");
}
}
}

View File

@ -48,7 +48,7 @@ namespace bsmd.AISService.AIS
}
catch (FormatException)
{
Trace.WriteLine("NMEA [PNMLS] input format error");
_log.Warn("NMEA [PNMLS] input format error");
}
}

View File

@ -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");
}
}

View File

@ -96,7 +96,6 @@ namespace bsmd.AISService.AIS
{
string line = this.port.ReadLine();
this.OnInputLineRead(line);
//System.Diagnostics.Trace.WriteLine(line);
}
catch (Exception) { }
}

View File

@ -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);
}

View File

@ -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));
}
*/
}
}

View File

@ -4,7 +4,31 @@
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="bsmd.AISService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<root>
<level value="ALL"/>
<appender-ref ref="LogFileAppender"/>
<appender-ref ref="TraceAppender"/>
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="C:\work\Logs\AISService.log"/>
<param name="AppendToFile" value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="10MB"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date [%thread] %-5level [%logger] - %message%newline"/>
</layout>
</appender>
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c %m%n"/>
</layout>
</appender>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>

View File

@ -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
{
/// <summary>
/// Saves a (class A or B) position report
/// </summary>
@ -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;
}

View File

@ -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
/// </summary>
/// <param name="target">target to save</param>
/// <returns>id of insert operation (to update hotposition table)</returns>
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,7 +209,7 @@ namespace bsmd.AISService.DB
if (result != null) // update
{
id = Convert.ToInt32(result);
id = (Guid) result;
}
#region Class A
@ -216,87 +218,58 @@ namespace bsmd.AISService.DB
{
AIS_StaticData staticData = target.LastStaticData as AIS_StaticData;
if (id >= 0)
if (id != Guid.Empty)
{
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);
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)
{
id = Guid.NewGuid();
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);
}
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()"));
}
}
@ -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;
}

View File

@ -5,6 +5,7 @@ using System.Data;
using System.Globalization;
using bsmd.AISService.AIS;
using log4net;
namespace bsmd.AISService.DB
{
@ -13,7 +14,6 @@ namespace bsmd.AISService.DB
{
#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<int, double> targets = new Dictionary<int, double>();
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);
}
}
}

View File

@ -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<AISWatchkeeper> watchkeeperShips = null;
private List<AISStaticData> dbShips = null;
private Dictionary<string, AISStation> 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<string, AISStation>();
Trace.WriteLine("loading stations..");
_log.Info("loading stations..");
List<AISStation> 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;

View File

@ -22,6 +22,9 @@ namespace bsmd.AISService
/// </summary>
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

View File

@ -33,6 +33,7 @@
//
// serviceProcessInstallerAIS
//
this.serviceProcessInstallerAIS.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstallerAIS.Password = null;
this.serviceProcessInstallerAIS.Username = null;
//

View File

@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="serviceProcessInstallerAIS.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
<value>17, 54</value>
</metadata>
<metadata name="serviceInstallerAIS.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>196, 17</value>

View File

@ -102,7 +102,9 @@
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="App.config">
<SubType>Designer</SubType>
</None>
<None Include="bsmd.AISService.licenseheader" />
<None Include="bsmdKey.snk" />
<None Include="packages.config" />

Binary file not shown.