org.ka2ddo.ax25
Class AX25Message

java.lang.Object
  extended by org.ka2ddo.ax25.AX25Message
All Implemented Interfaces:
java.io.Serializable, java.lang.Cloneable, java.lang.Comparable<AX25Message>
Direct Known Subclasses:
Message, OpenTracMessage

public abstract class AX25Message
extends java.lang.Object
implements java.lang.Comparable<AX25Message>, java.io.Serializable, java.lang.Cloneable

This class defines the common infrastructure for one decoded AX.25 message. Subclasses implement the details for different layer 3 and above protocols.

See Also:
Serialized Form

Nested Class Summary
static class AX25Message.Precedence
          This enum defines the allowed traffic precedence levels for messages.
 
Field Summary
 AX25Frame ax25Frame
          The AX.25 frame object from which this Message was extracted.
protected  boolean invalid
          Indicates whether message was correctly formatted or otherwise parseable.
static java.nio.charset.Charset ISO_8859_1
          ISO-Latin-1 character set for converting byte arrays into Unicode Strings.
 java.lang.String originatingCallsign
          Callsign of the station originating this message.
static long PERMANENT
          Reserved constant for non-expiring objects' timestamp.
 long rcptTime
          The time the message was received by the system in Java standard milliseconds since 1970 UTC.
 java.lang.String thirdParty
          The entire third-party routing path for this AX25Message, or null if this AX25message is still on its original network.
 long timestamp
          Message timestamp in Java standard milliseconds since 1970 UTC.
static java.util.TimeZone UTC
          TimeZone object for Greenwich Mean Time (or Universal Coordinated Time), used for converting text string times and dates into binary.
static java.nio.charset.Charset UTF8
          UTF-8 character set for converting byte arrays into Unicode Strings.
 
Constructor Summary
protected AX25Message()
          Constructor for partially initialized AX25Message.
protected AX25Message(java.lang.String thirdParty, long rcptTime)
          Constructor for AX25Message specifying the third-party network routing and receive time of the message.
 
Method Summary
protected abstract  boolean bodyEquals(AX25Message other)
          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.
 AX25Message dup()
          Creates and returns a copy of this AX25Message.
 boolean equals(java.lang.Object o)
          Test if the Object o is a duplicate of this Message.
 void extractSource()
          Extract the originating station callsign for this AX25Message.
 AX25Frame getAx25Frame()
          Get the AX.25 frame from which this Message was extracted.
 java.lang.String getFirstDigipeat(AX25Callsign[] digipeaters)
          Return the callsign of the first digipeat station for this message.
 java.lang.String getLastDigipeat(AX25Callsign[] digipeaters)
          Return the callsign of the last digipeat station for this message.
static java.lang.String getOriginalDestination(AX25Callsign dest, java.lang.String thirdParty)
          Extract the callsign of the original destination of this message.
static java.lang.String getOriginalSource(AX25Callsign src, java.lang.String thirdParty)
          Extract the callsign of the original destination of this message.
 java.lang.String getOriginatingCallsign()
          Get the callsign of the station that originated this message (not of any Tx-Igate relay).
 AX25Message.Precedence getPrecedence()
          Report the traffic-handling precedence for this message instance.
 long getRcptTime()
          Get the timestamp this AX25Message was received in milliseconds since 1 Jan 1970 UTC.
 long getTimestamp()
          Get the timestamp associated with this Message in milliseconds since 1 Jan 1970 UTC.
 int hashCode()
          Returns a hash code for this Message.
 boolean hasPosition()
          Report if this AX25Message contains position data.
 boolean hasThisFirstDigi(AX25Callsign[] digipeaters, java.lang.String digiCallsign)
          Test if the specified callsign is the first digipeat station for this message.
abstract  boolean hasWeather()
          Report if this AX25Message contains weather information.
static int indexOf(byte[] buf, int bufLen, char matchCh, int startPos)
          Search a byte array (assumed to be an ASCII string) for a matching character.
static int indexOf(byte[] buf, int bufLen, java.lang.String matchStr, int startPos)
          Search a byte array (assumed to be an ASCII string) for a matching ASCII string.
 boolean isInvalid()
          Test if this message was flagged as invalid.
static boolean onlyDigits(byte[] body, int pos, int len)
          Test if the specified part of the message body is strictly only ASCII digits.
static boolean onlyDigits(java.lang.String body, int pos, int len)
          Test if the specified part of the message body is strictly only ASCII digits.
static boolean onlyDigitsOrPeriod(java.lang.String body, int pos, int len)
          Test if the specified part of the message body is strictly only ASCII digits.
protected static boolean onlyDigitsOrSpace(byte[] body, int pos, int len)
          Test if the specified part of the message body is strictly only ASCII digits or space characters.
protected static boolean onlyDigitsPlus(byte[] body, int pos, int len)
          Test if the specified part of the message body is only ASCII digits or characters just after the digits (to support base+offset message codes in APRS).
protected static boolean onlyPeriods(byte[] body, int pos, int len)
          Test if the specified part of the message body is strictly only period characters.
 java.lang.String paramString()
          Descriptive text about this message, to be included in the toString() method's response.
 void setAx25Frame(AX25Frame ax25Frame)
          Attach the AX.25 frame from which this Message was extracted.
 void setInvalid(boolean invalid)
          Mark if this message is invalid or not.
 void setOriginatingCallsign(java.lang.String originatingCallsign)
          Set the originating callsign for this AX25Message.
 void setRcptTime(long rcptTime)
          Change the receive time of this message.
 void setTimestamp(long timestamp)
          Change the timestamp of this message.
static java.lang.String[] split(java.lang.String line, char separator)
          This is a more optimized version of String.split() that doesn't require compiling and evaluating regular expression patterns to do it, thereby saving chunks of transient heap (and probably some CPU time as well).
 java.lang.String toString()
          Returns a string representation of the object.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

PERMANENT

public static final long PERMANENT
Reserved constant for non-expiring objects' timestamp.

See Also:
Constant Field Values

ax25Frame

public AX25Frame ax25Frame
The AX.25 frame object from which this Message was extracted.


originatingCallsign

public java.lang.String originatingCallsign
Callsign of the station originating this message. This may not match the sender callsign if the message was relayed through a third-party network (such as APRS-IS). In such cases, sender will be the callsign of the station transmitting the message onto RF, and originatingCallsign will be taken from the third-party routing information to indicate the station that originally injected this message into the network of networks.

See Also:
AX25Frame.sender

thirdParty

public java.lang.String thirdParty
The entire third-party routing path for this AX25Message, or null if this AX25message is still on its original network.


timestamp

public long timestamp
Message timestamp in Java standard milliseconds since 1970 UTC. May be different from rcptTime if the message body has a time value in it.


rcptTime

public long rcptTime
The time the message was received by the system in Java standard milliseconds since 1970 UTC.


invalid

protected boolean invalid
Indicates whether message was correctly formatted or otherwise parseable.


ISO_8859_1

public static final java.nio.charset.Charset ISO_8859_1
ISO-Latin-1 character set for converting byte arrays into Unicode Strings.


UTF8

public static final java.nio.charset.Charset UTF8
UTF-8 character set for converting byte arrays into Unicode Strings.


UTC

public static final java.util.TimeZone UTC
TimeZone object for Greenwich Mean Time (or Universal Coordinated Time), used for converting text string times and dates into binary.

Constructor Detail

AX25Message

protected AX25Message()
Constructor for partially initialized AX25Message.


AX25Message

protected AX25Message(java.lang.String thirdParty,
                      long rcptTime)
Constructor for AX25Message specifying the third-party network routing and receive time of the message.

Parameters:
thirdParty - The entire third-party routing path for this AX25Message, or null if this AX25message is still on its original network.
rcptTime - The time the message was received by the system in Java standard milliseconds since 1970 UTC.
Method Detail

equals

public boolean equals(java.lang.Object o)
Test if the Object o is a duplicate of this Message.

Overrides:
equals in class java.lang.Object
Parameters:
o - Object to compare against this message.
Returns:
true if o is a Message with the same contents as this Message

bodyEquals

protected abstract boolean bodyEquals(AX25Message other)
Compare the contents of the body of the message, reporting if they match. This method must be overridden by concrete subclasses, but will only be called when the Class of the other message equals the Class of this message.

Parameters:
other - another AX25Message to compare against
Returns:
boolean true if the body values are equivalent

hashCode

public int hashCode()
Returns a hash code for this Message.

Overrides:
hashCode in class java.lang.Object
Returns:
a hash code value for this object.

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>
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.

onlyDigits

public static boolean onlyDigits(java.lang.String body,
                                 int pos,
                                 int len)
Test if the specified part of the message body is strictly only ASCII digits.

Parameters:
body - String containing the message body
pos - starting index in the array to test
len - number of bytes to test
Returns:
boolean true if all the bytes are ASCII digits

onlyDigitsOrPeriod

public static boolean onlyDigitsOrPeriod(java.lang.String body,
                                         int pos,
                                         int len)
Test if the specified part of the message body is strictly only ASCII digits.

Parameters:
body - String containing the message body
pos - starting index in the array to test
len - number of bytes to test
Returns:
boolean true if all the bytes are ASCII digits

onlyDigits

public static boolean onlyDigits(byte[] body,
                                 int pos,
                                 int len)
Test if the specified part of the message body is strictly only ASCII digits.

Parameters:
body - byte array containing the message body
pos - starting index in the array to test
len - number of bytes to test
Returns:
boolean true if all the bytes are ASCII digits

onlyDigitsPlus

protected static boolean onlyDigitsPlus(byte[] body,
                                        int pos,
                                        int len)
Test if the specified part of the message body is only ASCII digits or characters just after the digits (to support base+offset message codes in APRS).

Parameters:
body - byte array containing the message body
pos - starting index in the array to test
len - number of bytes to test
Returns:
boolean true if all the bytes are in the 16-byte block containing ASCII digits

onlyDigitsOrSpace

protected static boolean onlyDigitsOrSpace(byte[] body,
                                           int pos,
                                           int len)
Test if the specified part of the message body is strictly only ASCII digits or space characters.

Parameters:
body - byte array containing the message body
pos - starting index in the array to test
len - number of bytes to test
Returns:
boolean true if all the bytes are ASCII digits or spaces

onlyPeriods

protected static boolean onlyPeriods(byte[] body,
                                     int pos,
                                     int len)
Test if the specified part of the message body is strictly only period characters.

Parameters:
body - byte array containing the message body
pos - starting index in the array to test
len - number of bytes to test
Returns:
boolean true if all the bytes are periods

indexOf

public static int indexOf(byte[] buf,
                          int bufLen,
                          char matchCh,
                          int startPos)
Search a byte array (assumed to be an ASCII string) for a matching character.

Parameters:
buf - byte array to search
bufLen - index of end of used part of buffer
matchCh - character value to search for in a forward search
startPos - zero-based index to start searching at
Returns:
first index of character occurance after the start pos, or -1 if not found

indexOf

public static int indexOf(byte[] buf,
                          int bufLen,
                          java.lang.String matchStr,
                          int startPos)
Search a byte array (assumed to be an ASCII string) for a matching ASCII string.

Parameters:
buf - byte array to search
bufLen - index of end of used part of buffer
matchStr - String value to search for in a forward search
startPos - zero-based index to start searching at
Returns:
first index of string occurance after the start pos, or -1 if not found

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. Its default implementation returns an empty string.

Returns:
String describing the contents of this message
See Also:
toString()

toString

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

Overrides:
toString in class java.lang.Object
Returns:
a string representation of the object.

extractSource

public void extractSource()
Extract the originating station callsign for this AX25Message.


getAx25Frame

public final AX25Frame getAx25Frame()
Get the AX.25 frame from which this Message was extracted.

Returns:
transport-compatible AX25Frame for this Message

setAx25Frame

public final void setAx25Frame(AX25Frame ax25Frame)
Attach the AX.25 frame from which this Message was extracted.

Parameters:
ax25Frame - AX25Frame object containing the encoding of this Message

getOriginalSource

public static java.lang.String getOriginalSource(AX25Callsign src,
                                                 java.lang.String thirdParty)
Extract the callsign of the original destination of this message.

Parameters:
src - AX25Callsign of the source of the original AX25Frame
thirdParty - String of the third-party routing of this message, or null if not routed over another network
Returns:
source callsign String

getOriginalDestination

public static java.lang.String getOriginalDestination(AX25Callsign dest,
                                                      java.lang.String thirdParty)
Extract the callsign of the original destination of this message.

Parameters:
dest - AX25Callsign of the destination (tocall) of the original AX25Frame
thirdParty - String of the third-party routing of this message, or null if not routed over another network
Returns:
destination callsign String

getLastDigipeat

public java.lang.String getLastDigipeat(AX25Callsign[] digipeaters)
Return the callsign of the last digipeat station for this message.

Parameters:
digipeaters - array of AX25Callsign digipeater addresses in AX.25 frame
Returns:
String station ID of last digipeat station, or empty string if sent directly by originating station

getFirstDigipeat

public java.lang.String getFirstDigipeat(AX25Callsign[] digipeaters)
Return the callsign of the first digipeat station for this message.

Parameters:
digipeaters - array of AX25Callsign digipeater addresses in AX.25 frame
Returns:
String station ID of first digipeat station, or empty string if sent directly by originating station

hasThisFirstDigi

public boolean hasThisFirstDigi(AX25Callsign[] digipeaters,
                                java.lang.String digiCallsign)
Test if the specified callsign is the first digipeat station for this message.

Parameters:
digipeaters - array of AX25Callsign digipeater addresses in AX.25 frame
digiCallsign - String callsign/SSID of digipeater
Returns:
boolean true if the specified digipeater is the first digi for this message

getTimestamp

public long getTimestamp()
Get the timestamp associated with this Message in milliseconds since 1 Jan 1970 UTC.

Returns:
time message was received or the timestamp in the message, or -1 if this is a permanent (non-timing-out message)

hasWeather

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

Returns:
boolean true if weather information in this AX25Message

hasPosition

public boolean hasPosition()
Report if this AX25Message contains position data. The default implementation returns false; position-reporting subclasses are expected to override this.

Returns:
boolean true if message contains position information

setTimestamp

public void setTimestamp(long timestamp)
Change the timestamp of this message. Intended only for use by the Transmitter class when creating a time-stamped duplicate of a periodically-repeated APRS Message.

Parameters:
timestamp - new time in Java milliseconds since epoch

setOriginatingCallsign

public void setOriginatingCallsign(java.lang.String originatingCallsign)
Set the originating callsign for this AX25Message. This should only be called on SendableMessages to initialize them before transmission.

Parameters:
originatingCallsign - String of the originating station callsign of this message

getOriginatingCallsign

public java.lang.String getOriginatingCallsign()
Get the callsign of the station that originated this message (not of any Tx-Igate relay).

Returns:
String callsign

getRcptTime

public long getRcptTime()
Get the timestamp this AX25Message was received in milliseconds since 1 Jan 1970 UTC.

Returns:
time message was received

setRcptTime

public void setRcptTime(long rcptTime)
Change the receive time of this message. Intended only for use by the Transmitter class when creating a time-stamped duplicate of a periodically-repeated APRS Message.

Parameters:
rcptTime - new time in Java milliseconds since epoch

isInvalid

public boolean isInvalid()
Test if this message was flagged as invalid.

Returns:
boolean true if this message is marked as invalid

setInvalid

public void setInvalid(boolean invalid)
Mark if this message is invalid or not.

Parameters:
invalid - boolean true if message should be considered invalid or incorrect syntax

getPrecedence

public AX25Message.Precedence getPrecedence()
Report the traffic-handling precedence for this message instance. Expected to be overridden by subclasses that have precedence fields.

Returns:
Precedence level for this AX25Message

dup

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

Returns:
a clone of this instance.
See Also:
Cloneable

split

public static java.lang.String[] split(java.lang.String line,
                                       char separator)
This is a more optimized version of String.split() that doesn't require compiling and evaluating regular expression patterns to do it, thereby saving chunks of transient heap (and probably some CPU time as well).

Parameters:
line - the String to split at occurrences of the separator
separator - the String delimiting substrings of the line
Returns:
array of Strings split at the various points the separator appears