Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mvnw.cmd eol=crlf
gradlew.bat eol=crlf
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ ais-lib-communication/aisbus.xml
.idea
*.iml
.DS_Store

.gradle
build/
Binary file added .mvn/wrapper/maven-wrapper.jar
Binary file not shown.
1 change: 1 addition & 0 deletions .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
language: java
jdk:
- oraclejdk8
8 changes: 8 additions & 0 deletions ais-lib-cli/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

description = 'AisLib CLI'
dependencies {
compile project(':ais-lib-communication')
compile project(':ais-lib-utils')
compile group: 'dk.dma.commons', name: 'dma-commons-app', version:'0.5-SNAPSHOT'
compile group: 'commons-io', name: 'commons-io', version:'2.4'
}
3 changes: 2 additions & 1 deletion ais-lib-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
<parent>
<groupId>dk.dma.ais.lib</groupId>
<artifactId>ais-parent</artifactId>
<version>2.4-SNAPSHOT</version>
<version>2.4-CCG-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<packaging>jar</packaging>
Expand Down
15 changes: 15 additions & 0 deletions ais-lib-communication/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

description = 'AIS Communication'
dependencies {
compile project(':ais-lib-messages')
compile group: 'dk.dma.commons', name: 'dma-commons-util', version:'0.5-SNAPSHOT'
compile group: 'dk.dma.enav', name: 'enav-util', version:'0.5'
compile group: 'com.beust', name: 'jcommander', version:'1.30'
compile group: 'javax.xml.bind', name: 'jaxb-api', version:'2.2.7'
compile group: 'org.antlr', name: 'antlr4-runtime', version:'4.2'
compile group: 'de.micromata.jak', name: 'JavaAPIforKml', version:'2.2.0'
compile group: 'org.apache.commons', name: 'commons-csv', version:'1.1'
compile group: 'org.apache.commons', name: 'commons-collections4', version:'4.1'
testCompile group: 'net.maritimecloud', name: 'mc-util', version:'0.1'
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version:'1.3'
}
39 changes: 37 additions & 2 deletions ais-lib-communication/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>dk.dma.ais.lib</groupId>
<artifactId>ais-parent</artifactId>
<version>2.4-SNAPSHOT</version>
<version>2.4-CCG-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand All @@ -15,6 +15,30 @@
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.sun.tools.jxc.maven2</groupId>
<artifactId>maven-jaxb-schemagen-plugin</artifactId>
Expand Down Expand Up @@ -97,5 +121,16 @@
<artifactId>commons-csv</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@
*/
package dk.dma.ais.packet;

import static java.util.Objects.requireNonNull;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import net.jcip.annotations.NotThreadSafe;
import dk.dma.ais.binary.SixbitException;
import dk.dma.ais.message.AisMessage;
import dk.dma.ais.message.AisMessageException;
Expand All @@ -31,6 +22,15 @@
import dk.dma.ais.sentence.Vdm;
import dk.dma.enav.model.geometry.Position;
import dk.dma.enav.model.geometry.PositionTime;
import net.jcip.annotations.NotThreadSafe;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static java.util.Objects.requireNonNull;

/**
* Encapsulation of the VDM lines containing a single AIS message including leading proprietary tags and comment/tag
Expand All @@ -43,6 +43,7 @@ public class AisPacket implements Comparable<AisPacket> {

private final String rawMessage;
private transient Vdm vdm;
private transient Vsi vsi;
private transient AisPacketTags tags;
private AisMessage message;
private volatile long timestamp = Long.MIN_VALUE;
Expand All @@ -56,6 +57,12 @@ private AisPacket(String stringMessage) {
this.vdm = vdm;
}

public AisPacket(Vdm correlatedVdm, Vsi vsi, String stringMessage) {
this(stringMessage);
this.vdm = correlatedVdm;
this.vsi = vsi;
}

public static AisPacket fromByteBuffer(ByteBuffer buffer) {
int cap = buffer.remaining();
byte[] buf = new byte[cap];
Expand Down Expand Up @@ -156,7 +163,7 @@ public AisMessage getAisMessage() throws AisMessageException, SixbitException {
* @return
*/
public boolean isValidMessage() {
return tryGetAisMessage() != null;
return isVsi() || tryGetAisMessage() != null;
}

/**
Expand Down Expand Up @@ -189,8 +196,7 @@ public static AisPacket from(String stringMessage) {
* Construct AisPacket from raw packet string
*
* @param messageString
* @param optional
* factory
*
* @return
* @throws SentenceException
*/
Expand All @@ -213,4 +219,12 @@ public static AisPacket readFromString(String messageString) throws SentenceExce
public int compareTo(AisPacket p) {
return Long.compare(getBestTimestamp(), p.getBestTimestamp());
}

public boolean isVsi() {
return vsi != null;
}

public Vsi getVsi() {
return vsi;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@
import dk.dma.ais.sentence.SentenceLine;
import dk.dma.ais.sentence.Vdm;
import net.jcip.annotations.NotThreadSafe;
import org.apache.commons.collections4.map.PassiveExpiringMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
* Class to parse lines in a stream containing VDM sentences. The class will deliver packets containing complete VDM and
Expand All @@ -51,6 +56,8 @@ public class AisPacketParser {

/** A received VDO/VDM */
private Vdm vdm = new Vdm();

private Map<String, AisPacket> vdmMessagesInTheLast2Seconds = Collections.synchronizedMap(new PassiveExpiringMap<>(2, TimeUnit.SECONDS, new HashMap<>()));

/**
* Sentence line parser
Expand Down Expand Up @@ -91,7 +98,7 @@ private AisPacket readLine(String line, boolean retry) throws SentenceException
}
sentenceTrace.addLast(line);
}

sentenceLine.parse(line);

// Ignore everything else than sentences
Expand Down Expand Up @@ -119,7 +126,9 @@ private AisPacket readLine(String line, boolean retry) throws SentenceException
}

// Add line to raw packet
packetLines.add(line);
if (!sentenceLine.isFormatter("VSI")) {
packetLines.add(line);
}

// Check if proprietary line
if (sentenceLine.isProprietary()) {
Expand All @@ -133,42 +142,68 @@ private AisPacket readLine(String line, boolean retry) throws SentenceException
}

// Check if VDM. If not the possible current VDM is broken.
if (!sentenceLine.isFormatter("VDM", "VDO")) {
if (!sentenceLine.isFormatter("VDM", "VDO", "VSI")) {
newVdm();
return null;
}

// Parse VDM
int result;
try {
result = vdm.parse(sentenceLine);
} catch (SentenceException e) {
newVdm();
// Do a single retry with the current line. The faulty sentence may be the last, not this one.
if (!retry) {
LOG.debug("Discarding current sentence group. New start: " + e.getMessage());
return readLine(line, true);
AisPacket packet;
if (sentenceLine.isFormatter("VDM", "VDO")) {
int result;
try {
result = vdm.parse(sentenceLine);
} catch (SentenceException e) {
newVdm();
// Do a single retry with the current line. The faulty sentence may be the last, not this one.
if (!retry) {
LOG.debug("Discarding current sentence group. New start: " + e.getMessage());
return readLine(line, true);
}
throw new SentenceException(e, sentenceTrace);
}
throw new SentenceException(e, sentenceTrace);
}

// If not complete package wait for more
if (result != 0) {
return null;
}
// If not complete package wait for more
if (result != 0) {
return null;
}

// Complete package have been read
// Complete package have been read

// Put proprietary tags on vdm
if (tags.size() > 0) {
vdm.setTags(new LinkedList<>(tags));
}
// Put proprietary tags on vdm
if (tags.size() > 0) {
vdm.setTags(new LinkedList<>(tags));
}

packet = new AisPacket(vdm, StringUtils.join(packetLines, "\r\n"));

keepPacketForVsiCorrelation(packet);
} else { // VSI
Vsi vsi = new Vsi();
vsi.parse(sentenceLine);

// Make packet
AisPacket packet = new AisPacket(vdm, StringUtils.join(packetLines, "\r\n"));
String messageKey = sentenceLine.getFields().get(1) + sentenceLine.getFields().get(2);
AisPacket correlatedVdmPacket = vdmMessagesInTheLast2Seconds.remove(messageKey);

if (correlatedVdmPacket != null) {
Vdm vdm = correlatedVdmPacket.getVdm();

packet = new AisPacket(vdm, vsi, correlatedVdmPacket.getStringMessage());
} else {
packet = null;
}
}

newVdm();

return packet;
}

private void keepPacketForVsiCorrelation(AisPacket packet) {
if (packet.getVdm().getCommentBlock() != null) {
SentenceLine sentenceLine = new SentenceLine(packet.getVdm().getRawSentencesJoined());
String stationId = packet.getVdm().getCommentBlock().getString("s");
String messageSequenceNumber = sentenceLine.getFields().get(3);
vdmMessagesInTheLast2Seconds.put(stationId + messageSequenceNumber, AisPacket.from(packet.getStringMessage()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,15 @@ private AisPacket handleLine(String line) throws IOException {
if (throwExceptions) {
throw new IOException(se);
}
LOG.error("Sentence error: " + line + " (possible related proptag: " + se.getPossibleProprietaryTag() + ")");
LOG.debug("Sentence trace: " + se.getMessage());
LOG.error("Sentence error: " + line + " (possible related proptag: " + se.getPossibleProprietaryTag() + ")", se);
LOG.debug("Sentence trace: " + se.getMessage(), se);
return null;
} catch (Exception e) {
if (throwExceptions) {
throw new IOException(e);
}
LOG.error("Sentence line error: " + line);
LOG.debug("Sentence line error: " + e.getMessage());
LOG.error("Sentence line error: " + line, e);
LOG.debug("Sentence line error: " + e.getMessage(), e);
return null;
}
}
Expand Down
Loading