org.ka2ddo.aprs
Class Message

java.lang.Object
  extended by org.ka2ddo.ax25.AX25Message
      extended by org.ka2ddo.aprs.Message
All Implemented Interfaces:
java.io.Serializable, java.lang.Cloneable, java.lang.Comparable<AX25Message>, CommentedMessage
Direct Known Subclasses:
DefaultMessage, MessageMessage, PositionlessWeatherReport, PositionMessage, Query, StationCapabilities, StatusMessage, TelemetryMessage, UltimeterRawMessage

public abstract class Message
extends AX25Message
implements CommentedMessage

This abstract class defines the common parts of one APRS message. Subclasses handle the details of specific message types.

See Also:
Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from class org.ka2ddo.ax25.AX25Message
AX25Message.Precedence
 
Field Summary
protected  java.lang.String comment
          Free-text comment in this message.
protected  java.util.Map<java.lang.Enum,java.lang.Object> extensions
          Optional map of extracted data fields in this APRS message.
protected  byte msgType
          APRS message type code (prefix character in the message text).
static java.lang.String S_PERMANENT
          Reserved APRS timestamp string for permanent Objects.
static java.lang.String S_PERMANENT_UC
          Reserved APRS timestamp string for permanent Objects, with uppercase timezone letter.
protected  char symbolCode
          The APRS symbol code within the specified table for the station originating this message.
protected  char symTableId
          The APRS symbol table ID (or overlay character) for the station originating this message.
static java.nio.charset.Charset USASCII
          Character set for 7-bit ASCII.
 
Fields inherited from class org.ka2ddo.ax25.AX25Message
ax25Frame, invalid, ISO_8859_1, originatingCallsign, PERMANENT, rcptTime, thirdParty, timestamp, UTC, UTF8
 
Constructor Summary
protected Message()
          Create an uninitialized message.
protected Message(byte msgType, java.lang.String thirdParty, long rcptTime)
          Set up this superclass's infrastructure for a particular message type at a particular receive time with the specified third-party routing.
 
Method Summary
 boolean bodyEquals(AX25Message o)
          Compare the contents of the body of the message, reporting if they match.
 int compareTo(AX25Message o)
          Compares this object with the specified object for order.
protected  int decodeDatestamp(byte[] body, int pos)
          Extract an APRS-standard 8-digit date/timestamp from a byte array presumably containing a timestamped APRS message and store it in the timestamp field of this Message object.
protected  int decodeHurricaneParams(byte[] body, int offset)
          Extract APRS-standard hurricane/tropical storm information from a message body.
protected  int decodeTimestamp(byte[] body, int pos, long rcvTimestamp)
          Extract an APRS-standard 6-digit timestamp from a byte array presumably containing a timestamped APRS message and store it in the timestamp field of this Message object.
protected  int decodeWeatherParams(byte[] body, int offset)
          Extract APRS-standard weather information from a message body.
protected  int decodeWeatherParams(java.lang.String body, int offset)
          Extract APRS-standard weather information from a message body.
 AX25Message dup()
          Creates and returns a deep copy of this Message.
protected static java.lang.String encodeTimestamp(java.util.Date date, long now)
          Produce a APRS-standard 6-digit timestamp string for the specified date/time, using the most precise format possible relative to the current time.
protected  void extractComment(byte[] body, int offset)
          Extract the remaining text in the byte buffer as the free-text comment of this message.
protected  void extractComment(byte[] body, int startPos, int endPos)
          Extract the remaining text in the byte buffer as the free-text comment of this message.
static java.lang.String extractSymbol(java.lang.String dest)
          Decode a symbol from the destination tocall (handling the case of old hardware and/or software whose limited message set does not include messages with symbol codes in the message body).
static java.lang.String formatBody(byte[] body, int offset)
          Convert a byte array into a UTF8 printable string.
 java.lang.String getComment()
          Get the free-text comment of this message,
 java.lang.Object getExtension(java.lang.Enum key)
          Get a particular extension value from this message.
 java.lang.String getExtensionString()
          Build a formatted string of the weather data known to this message,
 int getMsgType()
          Get the APRS message type code for this message.
 java.util.Map<java.lang.Enum,java.lang.Object> getReadOnlyExtensionMap()
          Get a reference to the extension map that should not be modified.
 char getSymbolCode()
          Get the APRS symbol code for this Message.
 char getSymTableId()
          Get the APRS symbol table ID or overlay character for this Message.
 boolean hasWeather()
          Report if this Message contains weather information.
protected  void inferSymbol(AX25Callsign src, AX25Callsign dst)
          Decode a symbol from the destination AX25Callsign (handling the case of old hardware and/or software whose limited message set does not include messages with symbol codes in the message body).
 boolean isSymbolInferred()
          Report whether the non-null APRS symbol reported by this message is explicit or inferred from destination or source callsign.
protected static boolean looksLikeLongFormatLatitude(byte[] body, int pos, int len)
          Test the byte array to see if it looks like it contains a APRS text-format (long) position indicator.
 java.lang.String paramString()
          Descriptive text about this message, to be included in the toString() method's response.
 void setComment(java.lang.String comment)
          Set the free-text comment for this Message.
 void setSymbolCode(char symbolCode)
          Set the APRS symbol code for this Message.
 void setSymTableId(char symTableId)
          Set the APRS symbol table ID or overlay character for this Message.
<K extends java.lang.Enum,V>
void
storeExtension(K key, V value)
          Store an extracted data element in the Message.
 java.lang.String toString()
          Returns a string representation of the object.
 
Methods inherited from class org.ka2ddo.ax25.AX25Message
equals, extractSource, getAx25Frame, getFirstDigipeat, getLastDigipeat, getOriginalDestination, getOriginalSource, getOriginatingCallsign, getPrecedence, getRcptTime, getTimestamp, hashCode, hasPosition, hasThisFirstDigi, indexOf, indexOf, isInvalid, onlyDigits, onlyDigits, onlyDigitsOrPeriod, onlyDigitsOrSpace, onlyDigitsPlus, onlyPeriods, setAx25Frame, setInvalid, setOriginatingCallsign, setRcptTime, setTimestamp, split
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

S_PERMANENT

public static final java.lang.String S_PERMANENT
Reserved APRS timestamp string for permanent Objects.

See Also:
Constant Field Values

S_PERMANENT_UC

public static final java.lang.String S_PERMANENT_UC
Reserved APRS timestamp string for permanent Objects, with uppercase timezone letter.

See Also:
Constant Field Values

USASCII

public static final java.nio.charset.Charset USASCII
Character set for 7-bit ASCII.


symTableId

protected char symTableId
The APRS symbol table ID (or overlay character) for the station originating this message. May be zero if no symbol defined by this message.

See Also:
symbolCode

symbolCode

protected char symbolCode
The APRS symbol code within the specified table for the station originating this message. May be zero if no symbol defined by this message.

See Also:
symTableId

comment

protected java.lang.String comment
Free-text comment in this message.


extensions

protected java.util.Map<java.lang.Enum,java.lang.Object> extensions
Optional map of extracted data fields in this APRS message. May be null if no extensions present in the message.


msgType

protected byte msgType
APRS message type code (prefix character in the message text).

Constructor Detail

Message

protected Message()
Create an uninitialized message.


Message

protected Message(byte msgType,
                  java.lang.String thirdParty,
                  long rcptTime)
Set up this superclass's infrastructure for a particular message type at a particular receive time with the specified third-party routing.

Parameters:
msgType - printable ASCII character identifying the APRS message type
thirdParty - String of third-party network routing data (may be null)
rcptTime - time in milliseconds since Jan 1 1970 UTC that message was received or created
Method Detail

bodyEquals

public boolean bodyEquals(AX25Message o)
Compare the contents of the body of the message, reporting if they match.

Specified by:
bodyEquals in class AX25Message
Parameters:
o - another AX25Message to compare against
Returns:
boolean true if the body values are equivalent

compareTo

public int compareTo(AX25Message o)
Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

Specified by:
compareTo in interface java.lang.Comparable<AX25Message>
Overrides:
compareTo in class AX25Message
Parameters:
o - the object to be compared.
Returns:
a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
Throws:
java.lang.ClassCastException - if the specified object's type prevents it from being compared to this object.

toString

public java.lang.String toString()
Returns a string representation of the object.

Overrides:
toString in class AX25Message
Returns:
a string representation of the object.

getMsgType

public int getMsgType()
Get the APRS message type code for this message.

Returns:
the ASCII character identifying the type of this APRS message

decodeTimestamp

protected int decodeTimestamp(byte[] body,
                              int pos,
                              long rcvTimestamp)
Extract an APRS-standard 6-digit timestamp from a byte array presumably containing a timestamped APRS message and store it in the timestamp field of this Message object.

Parameters:
body - byte array containing the message
pos - index into the array where the timestamp is supposed to start
rcvTimestamp - default time (in Java milliseconds since Jan 1 1970 UTC) to use if timestamp field is all period characters
Returns:
index into the byte array immediately following the decoded timestamp
See Also:
AX25Message.timestamp

decodeDatestamp

protected int decodeDatestamp(byte[] body,
                              int pos)
Extract an APRS-standard 8-digit date/timestamp from a byte array presumably containing a timestamped APRS message and store it in the timestamp field of this Message object.

Parameters:
body - byte array containing the message
pos - index into the array where the timestamp is supposed to start
Returns:
index into the byte array immediately following the decoded timestamp
See Also:
AX25Message.timestamp

encodeTimestamp

protected static java.lang.String encodeTimestamp(java.util.Date date,
                                                  long now)
Produce a APRS-standard 6-digit timestamp string for the specified date/time, using the most precise format possible relative to the current time.

Parameters:
date - Data object of the time to format
now - current time in Java milliseconds since 1970 UTC, to determine if 'date' is so far away from current time that a format with the day in it is necessary
Returns:
7 character String of APRS representation of timestamp

looksLikeLongFormatLatitude

protected static boolean looksLikeLongFormatLatitude(byte[] body,
                                                     int pos,
                                                     int len)
Test the byte array to see if it looks like it contains a APRS text-format (long) position indicator.

Parameters:
body - byte array containing the APRS message
pos - index into the byte array where lat/lon values are supposed to start
len - remaining length of valid message bytes in the array
Returns:
boolean true if a long-format text lat/lon appears to be in the buffer

extractComment

protected void extractComment(byte[] body,
                              int offset)
Extract the remaining text in the byte buffer as the free-text comment of this message.

Parameters:
body - byte array containing the APRS message
offset - index into the byte array where the free-text comment begins

extractComment

protected void extractComment(byte[] body,
                              int startPos,
                              int endPos)
Extract the remaining text in the byte buffer as the free-text comment of this message.

Parameters:
body - byte array containing the APRS message
startPos - index into the byte array where the free-text comment begins
endPos - index into the byte array after the free-text comment ends

paramString

public java.lang.String paramString()
Descriptive text about this message, to be included in the toString() method's response. This method may be overridden, and the override may concatenate the results of the superclass's paramString) method with additional text of its own. This default implementation returns the free-text comment of this APRS message.

Overrides:
paramString in class AX25Message
Returns:
String describing the contents of this message
See Also:
toString(), getComment()

storeExtension

public <K extends java.lang.Enum,V> void storeExtension(K key,
                                                        V value)
Store an extracted data element in the Message.

Type Parameters:
K - any enum subclass
V - any Java object class
Parameters:
key - Enum that identifies the particular data item
value - the data value
See Also:
DataExtensionEnum, WeatherEnum

getReadOnlyExtensionMap

public java.util.Map<java.lang.Enum,java.lang.Object> getReadOnlyExtensionMap()
Get a reference to the extension map that should not be modified.

Returns:
Map of extension data element (may be an empty Map)
See Also:
DataExtensionEnum, WeatherEnum

getExtension

public java.lang.Object getExtension(java.lang.Enum key)
Get a particular extension value from this message.

Parameters:
key - Enum instance identifying the desired extension
Returns:
value for that extension, or null if no value stored
See Also:
DataExtensionEnum, WeatherEnum

formatBody

public static java.lang.String formatBody(byte[] body,
                                          int offset)
Convert a byte array into a UTF8 printable string.

Parameters:
body - byte array
offset - start index into the array
Returns:
String decoded from the trailing part of the byte array

getSymbolCode

public final char getSymbolCode()
Get the APRS symbol code for this Message.

Returns:
char of the symbol code, or '\0' if this Message does not include a symbol

getSymTableId

public final char getSymTableId()
Get the APRS symbol table ID or overlay character for this Message.

Returns:
char of the symbol table ID or overlay, or '\0' if this Message does not include a symbol

setSymbolCode

public void setSymbolCode(char symbolCode)
Set the APRS symbol code for this Message. Generally only meaningful for SendableMessages.

Parameters:
symbolCode - char of the symbol code, or '\0' if this Message should not include a symbol

setSymTableId

public void setSymTableId(char symTableId)
Set the APRS symbol table ID or overlay character for this Message.

Parameters:
symTableId - char of the symbol table ID or overlay, or '\0' if this Message should not include a symbol

decodeWeatherParams

protected int decodeWeatherParams(byte[] body,
                                  int offset)
Extract APRS-standard weather information from a message body.

Parameters:
body - byte array of message body
offset - starting position for parsing weather data
Returns:
end position in message body after weather data

decodeHurricaneParams

protected int decodeHurricaneParams(byte[] body,
                                    int offset)
Extract APRS-standard hurricane/tropical storm information from a message body.

Parameters:
body - byte array of message body
offset - starting position for parsing weather data
Returns:
end position in message body after weather data

decodeWeatherParams

protected int decodeWeatherParams(java.lang.String body,
                                  int offset)
Extract APRS-standard weather information from a message body.

Parameters:
body - String of message body
offset - starting position for parsing weather data
Returns:
end position in message body after weather data

hasWeather

public boolean hasWeather()
Report if this Message contains weather information.

Specified by:
hasWeather in class AX25Message
Returns:
boolean true if weather information in this Message

getExtensionString

public java.lang.String getExtensionString()
Build a formatted string of the weather data known to this message,

Returns:
String in weather comment format

getComment

public java.lang.String getComment()
Get the free-text comment of this message,

Specified by:
getComment in interface CommentedMessage
Returns:
free-text comment String

setComment

public void setComment(java.lang.String comment)
Set the free-text comment for this Message. Note this is only meaningful for SendableMessages.

Specified by:
setComment in interface CommentedMessage
Parameters:
comment - String free-text comment to associate with this Message

isSymbolInferred

public boolean isSymbolInferred()
Report whether the non-null APRS symbol reported by this message is explicit or inferred from destination or source callsign. Intended to be overridden by message types which can infer a symbol but can't explicitly specify the symbol.

Returns:
boolean true if symbol is inferred

inferSymbol

protected void inferSymbol(AX25Callsign src,
                           AX25Callsign dst)
Decode a symbol from the destination AX25Callsign (handling the case of old hardware and/or software whose limited message set does not include messages with symbol codes in the message body). This handles the GPSxyz, GPSCnn, GPSEnn, SPCxyz, and SYMxyz tocalls, per chapter 20 of the APRS Protocol Reference, V1.0.1.

Parameters:
src - source AX25Callsign to parse (assuming this Message was not relayed through a third-party network), or null to not use source SSID as final fallback
dst - destination AX25Callsign to parse (assuming this Message was not relayed through a third-party network)

extractSymbol

public static java.lang.String extractSymbol(java.lang.String dest)
Decode a symbol from the destination tocall (handling the case of old hardware and/or software whose limited message set does not include messages with symbol codes in the message body). This handles the GPSxyz, GPSCnn, GPSEnn, SPCxyz, and SYMxyz tocalls, per chapter 20 of the APRS Protocol Reference, V1.0.1.

Parameters:
dest - destination String to parse
Returns:
APRS symbol table and code for the specified destination, or null if not determinable

dup

public AX25Message dup()
Creates and returns a deep copy of this Message.

Overrides:
dup in class AX25Message
Returns:
a clone of this instance.
See Also:
Cloneable