/* 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; import dk.dma.enav.model.geometry.Position; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; /** * AIS message 4 * * Base station report as defined by ITU-R M.1371-4 * */ public abstract class UTCDateResponseMessage extends AisMessage implements IPositionMessage { /** serialVersionUID. */ private static final long serialVersionUID = 1L; private int utcYear; // 14 bits : UTC Year private int utcMonth; // 4 bits : UTC Month private int utcDay; // 5 bits : UTC Day private int utcHour; // 5 bits : UTC Hour private int utcMinute; // 6 bits : UTC Minute private int utcSecond; // 6 bits : UTC Second private int posAcc; // 1 bit : AisPosition Accuracy private AisPosition pos; // : Lat/Long 1/100000 minute private int posType; // 4 bits : Type of position fixing device private int transmissionControl; // 1 bit : Transmission control for // longrange broadcast message private int spare; // 9 bits : Spare private int raim; // 1 bit : RAIM flag private int syncState; // 2 bits : SOTDMA sync state private int slotTimeout; // 3 bits : SOTDMA Slot Timeout private int subMessage; // 14 bits : SOTDMA sub-message protected UTCDateResponseMessage(int msgId) { super(msgId); } public UTCDateResponseMessage(Vdm vdm) throws AisMessageException, SixbitException { super(vdm); parse(); } public void parse() throws AisMessageException, SixbitException { BinArray binArray = vdm.getBinArray(); if (binArray.getLength() != 168) { throw new AisMessageException("Message 4 wrong length " + binArray.getLength() + " (should be 168)"); } super.parse(binArray); this.utcYear = (int) binArray.getVal(14); this.utcMonth = (int) binArray.getVal(4); this.utcDay = (int) binArray.getVal(5); this.utcHour = (int) binArray.getVal(5); this.utcMinute = (int) binArray.getVal(6); this.utcSecond = (int) binArray.getVal(6); this.posAcc = (int) binArray.getVal(1); this.pos = new AisPosition(); this.pos.setRawLongitude(binArray.getVal(28)); this.pos.setRawLatitude(binArray.getVal(27)); this.posType = (int) binArray.getVal(4); this.transmissionControl = (int) binArray.getVal(1); this.spare = (int) binArray.getVal(9); this.raim = (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(utcYear, 14); encoder.addVal(utcMonth, 4); encoder.addVal(utcDay, 5); encoder.addVal(utcHour, 5); encoder.addVal(utcMinute, 6); encoder.addVal(utcSecond, 6); encoder.addVal(posAcc, 1); encoder.addVal(pos.getRawLongitude(), 28); encoder.addVal(pos.getRawLatitude(), 27); encoder.addVal(posType, 4); encoder.addVal(transmissionControl, 1); encoder.addVal(spare, 9); encoder.addVal(raim, 1); encoder.addVal(syncState, 2); encoder.addVal(slotTimeout, 3); encoder.addVal(subMessage, 14); return encoder; } public int getUtcYear() { return utcYear; } public void setUtcYear(int utcYear) { this.utcYear = utcYear; } public int getUtcMonth() { return utcMonth; } public void setUtcMonth(int utcMonth) { this.utcMonth = utcMonth; } public int getUtcDay() { return utcDay; } public void setUtcDay(int utcDay) { this.utcDay = utcDay; } public int getUtcHour() { return utcHour; } public void setUtcHour(int utcHour) { this.utcHour = utcHour; } public int getUtcMinute() { return utcMinute; } public void setUtcMinute(int utcMinute) { this.utcMinute = utcMinute; } public int getUtcSecond() { return utcSecond; } public void setUtcSecond(int utcSecond) { this.utcSecond = utcSecond; } public Date getDate() { Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, getUtcYear()); cal.set(Calendar.MONTH, getUtcMonth() - 1); cal.set(Calendar.DAY_OF_MONTH, getUtcDay()); cal.set(Calendar.HOUR_OF_DAY, getUtcHour()); cal.set(Calendar.MINUTE, getUtcMinute()); cal.set(Calendar.SECOND, getUtcSecond()); cal.setTimeZone(TimeZone.getTimeZone("UTC")); return cal.getTime(); } public int getPosAcc() { return posAcc; } public void setPosAcc(int posAcc) { this.posAcc = posAcc; } @Override public Position getValidPosition() { AisPosition pos = this.pos; return pos == null ? null : pos.getGeoLocation(); } public AisPosition getPos() { return pos; } public void setPos(AisPosition pos) { this.pos = pos; } public int getPosType() { return posType; } public void setPosType(int posType) { this.posType = posType; } /** * @return the transmissionControl */ public int getTransmissionControl() { return transmissionControl; } /** * @param transmissionControl * the transmissionControl to set */ public void setTransmissionControl(int transmissionControl) { this.transmissionControl = transmissionControl; } public int getSpare() { return spare; } public void setSpare(int spare) { this.spare = spare; } public int getRaim() { return raim; } public void setRaim(int raim) { this.raim = raim; } 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; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(super.toString()); builder.append(", pos="); builder.append(pos); builder.append(", posAcc="); builder.append(posAcc); builder.append(", posType="); builder.append(posType); builder.append(", raim="); builder.append(raim); builder.append(", slotTimeout="); builder.append(slotTimeout); builder.append(", spare="); builder.append(spare); builder.append(", subMessage="); builder.append(subMessage); builder.append(", syncState="); builder.append(syncState); builder.append(", utcDay="); builder.append(utcDay); builder.append(", utcHour="); builder.append(utcHour); builder.append(", utcMinute="); builder.append(utcMinute); builder.append(", utcMonth="); builder.append(utcMonth); builder.append(", utcSecond="); builder.append(utcSecond); builder.append(", utcYear="); builder.append(utcYear); builder.append(", date="); builder.append(getDate()); builder.append("]"); return builder.toString(); } }