/* 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 dk.dma.ais.binary.BinArray; import dk.dma.ais.binary.SixbitEncoder; import dk.dma.ais.binary.SixbitException; import dk.dma.ais.sentence.Vdm; /** * This message should be used as a standard position report for aircraft involved * in SAR operations instead of Messages 1, 2 or 3. Stations other than * aircraft involved in SAR operations should not use transmit this message. The * default reporting interval for this message should be 10 seconds. */ public class AisMessage9 extends AisMessage implements IPositionMessage { /** serialVersionUID. */ private static final long serialVersionUID = 1L; /** * Altitude (derived from GNSS) expressed in metres (0 4 094 metres) * 4 095 = not available, 4 094 = 4 094 metres or higher. * * Altitude is in meters. The special value 4095 indicates altitude is * not available; 4094 indicates 4094 meters or higher. */ private int altitude; //12 bits /** * Speed over ground in knot steps (0-1022 knots) * 1023 = not available, 1022 = 1022 knots or higher. * * Speed over ground is in knots, NOT deciknots as in the common navigation * block; planes go faster. The special value 1023 indicates speed not * available, 1022 indicates 1022 knots or higher. */ private int sog; //10 bits /** * AisPosition Accuracy: The position accuracy (PA) flag should be * determined in accordance with Table 47 1 = high ( =< 10 m) 0 = low (>10 * m) 0 = default */ private int posAcc; // 1 bit /** * Stores the positions in a general manner */ private AisPosition pos; // : Lat/Long 1/10000 minute /** * Course over Ground Course over ground in 1/10 = (0-3599). 3600 (E10h) = * not available = default. 3601-4095 should not be used */ private int cog; // 12 bits /** * Time stamp: UTC second when the report was generated by the EPFS (0-59 or * 60 if time stamp is not available, which should also be the default value * or 61 if positioning system is in manual input mode or 62 if electronic * position fixing system operates in estimated (dead reckoning) mode or 63 * if the positioning system is inoperative) 61, 62, 63 are not used by CS * AIS */ private int utcSec; // 6 bits : UTC Seconds /** * Reserved for definition by a competent regional authority. Should be set * to zero, if not used for any regional application. Regional applications * should not use zero */ private int regionalReserved; // 8 bits /** * DTE: Data terminal equipment (DTE) ready 0 = available 1 = not available * = default see 3.3.1 */ private int dte; // 1 bit : DTE flag /** * Not used. Should be set to zero. Reserved for future use. * * NOTE: In ITU-R M1371-4 this field is 3 bits compared to 1 previously */ private int spare; // 3 bits /** * 0 = Station operating in autonomous and continuous mode =default * 1 = Station operating in assigned mode */ private int assigned; // 1 bit : Assigned Mode Flag /** * RAIM-flag: Receiver autonomous integrity monitoring (RAIM) flag of * electronic position fixing device; 0 = RAIM not in use = default; 1 = * RAIM in use. See Table 47 */ private int raim; // 1 bit : RAIM flag /** * Communication state selector flag: * 0 = SOTDMA communication state follows * 1 = ITDMA communication state follows */ private int commStateSelectorFlag; // 1 bit /** * SOTDMA/ITDMA sync state: sync state is part of the defined communication * state (19) bits. The sync state is the first 2 bits of the 19 bits in the * communication state of the message. * * 0 UTC direct (see 3.1.1.1) 1 UTC indirect (see 3.1.1.2) 2 Station is * synchronized to a base station (base direct) 3 Station is synchronized to * another station based on the highest number of received stations or to * another mobile station, which is directly synchronized to a base station */ private int syncState; // 2 bits /** * SOTDMA Slot Timeout Specifies frames remaining until a new slot is * selected 0 means that this was the last transmission in this slot 1-7 * means that 1 to 7 frames respectively are left until slot change */ private int slotTimeout; // 3 bits /** * SOTDMA sub-message This field has many purposes see class description for * help: */ private int subMessage; // 14 bits public AisMessage9() { super(9); } public AisMessage9(Vdm vdm) throws AisMessageException, SixbitException { super(vdm); parse(vdm.getBinArray()); } public void parse(BinArray binArray) throws AisMessageException, SixbitException { BinArray sixbit = vdm.getBinArray(); if (sixbit.getLength() < 168) { throw new AisMessageException("Message 9 wrong length " + sixbit.getLength()); } super.parse(binArray); this.altitude = (int) binArray.getVal(12); this.sog = (int) binArray.getVal(10); this.posAcc = (int) binArray.getVal(1); this.pos = new AisPosition(); this.pos.setRawLongitude(binArray.getVal(28)); this.pos.setRawLatitude(binArray.getVal(27)); this.cog = (int) binArray.getVal(12); this.utcSec = (int) binArray.getVal(6); this.regionalReserved = (int) binArray.getVal(8); this.dte = (int) binArray.getVal(1); this.spare = (int) binArray.getVal(3); this.assigned = (int) binArray.getVal(1); this.raim = (int) binArray.getVal(1); this.commStateSelectorFlag = (int) binArray.getVal(1); this.syncState = (int) binArray.getVal(2); this.slotTimeout = (int) binArray.getVal(3); this.subMessage = (int) binArray.getVal(14); } @Override public SixbitEncoder getEncoded() { SixbitEncoder encoder = super.encode(); encoder.addVal(this.altitude, 12); encoder.addVal(this.sog, 10); encoder.addVal(this.posAcc, 1); encoder.addVal(this.pos.getRawLongitude(), 28); encoder.addVal(this.pos.getRawLatitude(), 27); encoder.addVal(this.cog, 12); encoder.addVal(this.utcSec, 6); encoder.addVal(this.regionalReserved, 8); encoder.addVal(this.dte, 1); encoder.addVal(this.spare, 3); encoder.addVal(this.assigned, 1); encoder.addVal(this.raim, 1); encoder.addVal(this.commStateSelectorFlag, 1); encoder.addVal(this.syncState, 2); encoder.addVal(this.slotTimeout, 3); encoder.addVal(this.subMessage, 14); return encoder; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(super.toString()); builder.append(", altitude="); builder.append(altitude); builder.append(", sog="); builder.append(sog); builder.append(", posAcc="); builder.append(posAcc); builder.append(", pos="); builder.append(pos); builder.append(", cog="); builder.append(cog); builder.append(", utcSec="); builder.append(utcSec); builder.append(", regionalReserved="); builder.append(regionalReserved); builder.append(", dte="); builder.append(dte); builder.append(", spare="); builder.append(spare); builder.append(", assigned="); builder.append(assigned); builder.append(", raim="); builder.append(raim); builder.append(", commStateSelectorFlag="); builder.append(commStateSelectorFlag); builder.append(", syncState="); builder.append(syncState); builder.append(", slotTimeout="); builder.append(slotTimeout); builder.append(", subMessage="); builder.append(subMessage); builder.append("]"); return builder.toString(); } public int getAltitude() { return altitude; } public void setAltitude(int altitude) { this.altitude = altitude; } public int getSog() { return sog; } public void setSog(int sog) { this.sog = sog; } public int getPosAcc() { return posAcc; } public void setPosAcc(int posAcc) { this.posAcc = posAcc; } public AisPosition getPos() { return pos; } public void setPos(AisPosition pos) { this.pos = pos; } public int getCog() { return cog; } public void setCog(int cog) { this.cog = cog; } public int getUtcSec() { return utcSec; } public void setUtcSec(int utcSec) { this.utcSec = utcSec; } public int getRegionalReserved() { return regionalReserved; } public void setRegionalReserved(int regionalReserved) { this.regionalReserved = regionalReserved; } 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; } public int getAssigned() { return assigned; } public void setAssigned(int assigned) { this.assigned = assigned; } public int getRaim() { return raim; } public void setRaim(int raim) { this.raim = raim; } public int getCommStateSelectorFlag() { return commStateSelectorFlag; } public void setCommStateSelectorFlag(int commStateSelectorFlag) { this.commStateSelectorFlag = commStateSelectorFlag; } public int getSyncState() { return syncState; } public void setSyncState(int syncState) { this.syncState = syncState; } public int getSlotTimeout() { return slotTimeout; } public void setSlotTimeout(int slotTimeout) { this.slotTimeout = slotTimeout; } public int getSubMessage() { return subMessage; } public void setSubMessage(int subMessage) { this.subMessage = subMessage; } }