/* Copyright (c) 2011 Danish Maritime Authority. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package dk.dma.ais.message; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import dk.dma.ais.binary.BinArray; import dk.dma.ais.binary.SixbitEncoder; import dk.dma.ais.binary.SixbitException; import dk.dma.ais.sentence.Vdm; /** * AIS message 4 * * Ship static and voyage related data as defined by ITU-R M.1371-4 * */ public class AisMessage5 extends AisStaticCommon { /** serialVersionUID. */ private static final long serialVersionUID = 1L; /** * AIS version indicator: 0 = station compliant with Recommendation ITU-R M.1371-1 1 = station compliant with * Recommendation ITU-R M.1371-3 2-3 = station compliant with future editions */ int version; // 2 bits /** * IMO number: 1-999999999; 0 = not available = default � Not applicable to SAR aircraft */ long imo; // 30 bits /** * Type of electronic position fixing device: 0 = undefined (default) 1 = GPS 2 = GLONASS 3 = combined GPS/GLONASS 4 * = Loran-C 5 = Chayka 6 = integrated navigation system 7 = surveyed 8 = Galileo, 9-14 = not used 15 = internal * GNSS */ int posType; // 4 bits /** * ETA: Estimated time of arrival; MMDDHHMM UTC Bits 19-16: month; 1-12; 0 = not available = default Bits 15-11: * day; 1-31; 0 = not available = default Bits 10-6: hour; 0-23; 24 = not available = default Bits 5-0: minute; * 0-59; 60 = not available = default For SAR aircraft, the use of this field may be decided by the responsible * administration */ long eta; // 20 bits /** * Maximum present static draught: In 1/10 m, 255 = draught 25.5 m or greater, 0 = not available = default in * accordance with IMO Resolution A.851 Not applicable to SAR aircraft, should be set to 0 */ int draught; // 8 bits /** * Ship Destination: Maximum 20 characters using 6-bit ASCII; * * @@@@@@@@@@@@@@@@@@@@ = not available For SAR aircraft, the use of this field may be decided by the responsible * administration */ String dest; // 6x20 (120) bits /** * DTE: Data terminal equipment (DTE) ready 0 = available 1 = not available = default see � 3.3.1 */ int dte; // 1 bit : DTE flag /** * Spare. Not used. Should be set to zero. Reserved for future use */ int spare; // 1 bit : spare public AisMessage5() { super(5); } public AisMessage5(Vdm vdm) throws AisMessageException, SixbitException { super(vdm); parse(); } public void parse() throws AisMessageException, SixbitException { BinArray binArray = vdm.getBinArray(); if (binArray.getLength() < 424) { throw new AisMessageException("Message 5 wrong length " + binArray.getLength()); } super.parse(binArray); this.version = (int) binArray.getVal(2); this.imo = binArray.getVal(30); this.callsign = binArray.getString(7); this.name = binArray.getString(20); this.shipType = (int) binArray.getVal(8); this.dimBow = (int) binArray.getVal(9); this.dimStern = (int) binArray.getVal(9); this.dimPort = (int) binArray.getVal(6); this.dimStarboard = (int) binArray.getVal(6); this.posType = (int) binArray.getVal(4); this.eta = binArray.getVal(20); this.draught = (int) binArray.getVal(8); this.dest = binArray.getString(20); this.dte = (int) binArray.getVal(1); this.spare = (int) binArray.getVal(1); } @Override public SixbitEncoder getEncoded() { SixbitEncoder encoder = super.encode(); encoder.addVal(version, 2); encoder.addVal(imo, 30); encoder.addString(callsign, 7); encoder.addString(name, 20); encoder.addVal(shipType, 8); encoder.addVal(dimBow, 9); encoder.addVal(dimStern, 9); encoder.addVal(dimPort, 6); encoder.addVal(dimStarboard, 6); encoder.addVal(posType, 4); encoder.addVal(eta, 20); encoder.addVal(draught, 8); encoder.addString(dest, 20); encoder.addVal(dte, 1); encoder.addVal(spare, 1); return encoder; } public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } public long getImo() { return imo; } public void setImo(long imo) { this.imo = imo; } public int getPosType() { return posType; } public void setPosType(int posType) { this.posType = posType; } public long getEta() { return eta; } /** * Get ETA as date object * * @return date */ public Date getEtaDate() { int min = (int) (eta & 0x3F); int hour = (int) (eta & 0x7C0) >> 6; int day = (int) (eta & 0xF800) >> 11; int mon = (int) (eta & 0xF0000) >> 16; if (min == 60 || hour == 24 || day == 0 || mon == 0) { return null; } Calendar cal = Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone("GMT+0000")); cal.set(Calendar.MILLISECOND, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, min); cal.set(Calendar.HOUR_OF_DAY, hour); cal.set(Calendar.DAY_OF_MONTH, day); cal.set(Calendar.MONTH, mon - 1); return cal.getTime(); } public void setEta(long eta) { this.eta = eta; } public int getDraught() { return draught; } public void setDraught(int draught) { this.draught = draught; } public String getDest() { return dest; } public void setDest(String dest) { this.dest = dest; } public int getDte() { return dte; } public void setDte(int dte) { this.dte = dte; } public int getSpare() { return spare; } public void setSpare(int spare) { this.spare = spare; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(super.toString()); builder.append(", callsign="); builder.append(callsign); builder.append(", dest="); builder.append(dest); builder.append(", dimBow="); builder.append(dimBow); builder.append(", dimPort="); builder.append(dimPort); builder.append(", dimStarboard="); builder.append(dimStarboard); builder.append(", dimStern="); builder.append(dimStern); builder.append(", draught="); builder.append(draught); builder.append(", dte="); builder.append(dte); builder.append(", eta="); builder.append(eta); builder.append(", imo="); builder.append(imo); builder.append(", name="); builder.append(name); builder.append(", posType="); builder.append(posType); builder.append(", shipType="); builder.append(shipType); builder.append(", spare="); builder.append(spare); builder.append(", version="); builder.append(version); builder.append("]"); return builder.toString(); } }