Package org.ka2ddo.ax25
Class AX25Message
java.lang.Object
org.ka2ddo.ax25.AX25Message
- All Implemented Interfaces:
Serializable
,Cloneable
,Comparable<AX25Message>
- Direct Known Subclasses:
Message
,OpenTracMessage
public abstract class AX25Message
extends Object
implements Comparable<AX25Message>, Serializable, Cloneable
This class defines the common infrastructure for one decoded AX.25 message. Subclasses implement
the details for different layer 3 and above protocols.
- Author:
- Andrew Pavlin, KA2DDO
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enum
This enum defines the allowed traffic precedence levels for messages. -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected static final Set<ProtocolFamily>
A read-only protocol set that includes both APRS and OpenTRAC.The AX.25 frame object from which this Message was extracted.Optional map of extracted data fields in this APRS message.protected boolean
Indicates whether message was correctly formatted or otherwise parseable.Callsign of the station originating this message.Destination "callsign" from the station originating this message.static final long
Reserved constant for non-expiring objects' timestamp.long
The time the message was received by the system in Java standard milliseconds since 1970 UTC.The entire third-party routing path for this AX25Message, or null if this AX25message is still on its original network.long
Message timestamp in Java standard milliseconds since 1970 UTC.static final TimeZone
TimeZone object for Greenwich Mean Time (or Universal Coordinated Time), used for converting text string times and dates into binary. -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotected
Constructor for partially initialized AX25Message.protected
AX25Message
(String thirdParty, long rcptTime) Constructor for AX25Message specifying the third-party network routing and receive time of the message. -
Method Summary
Modifier and TypeMethodDescriptionprotected abstract boolean
bodyEquals
(AX25Message other) Compare the contents of the body of the message, reporting if they match.int
Compares this object with the specified object for order.dup()
Creates and returns a copy of this AX25Message.boolean
Test if the Object o is a duplicate of this Message.void
Extract the originating station callsign for this AX25Message.final AX25Frame
Get the AX.25 frame from which this Message was extracted.getExtension
(Enum key) Get a particular extension value from this message.getFirstDigipeat
(AX25Callsign[] digipeaters) Return the callsign of the first digipeat station for this message.getLastDigipeat
(AX25Callsign[] digipeaters) Return the callsign of the last digipeat station for this message.getNthDigipeat
(AX25Callsign[] digipeaters, int index) Return the callsign of the Nth digipeat station for this message.static String
getOriginalDestination
(AX25Callsign dest, String thirdParty) Extract the callsign of the original destination of this message.static String
getOriginalSource
(AX25Callsign src, String thirdParty) Extract the callsign of the original destination of this message.Get the callsign of the station that originated this message (not of any Tx-Igate relay).Get the destination address oeiginally specified bv the station that originated this message.Report the traffic-handling precedence for this message instance.Get the protocol family or families that this message corresponds to, so ports that don't support all protocols will not forward inappropriate packets.long
Get the timestamp this AX25Message was received in milliseconds since 1 Jan 1970 UTC.Get a reference to the extension map that should not be modified.long
Get the timestamp associated with this Message in milliseconds since 1 Jan 1970 UTC.int
hashCode()
Returns a hash code for this Message.boolean
Report if this AX25Message contains position data.boolean
hasThisFirstDigi
(AX25Callsign[] digipeaters, String digiCallsign) Test if the specified callsign is the first digipeat station for this message.abstract boolean
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
Search a byte array (assumed to be an ASCII string) for a matching ASCII string.boolean
isDirect()
Test if this message was sent directly (without any relay station).boolean
Test if this message was flagged as invalid.isRf
(int maxDigis) Test if this AX25Message came from an RF connection.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
(String body, int pos, int len) Test if the specified part of the message body is strictly only ASCII digits.static boolean
onlyDigitsOrPeriod
(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.Descriptive text about this message, to be included in the toString() method's response.final 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
(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 String[]
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).<K extends Enum,
V>
voidstoreExtension
(K key, V value) Store an extracted data element in the Message.toString()
Returns a string representation of the object.
-
Field Details
-
PERMANENT
public static final long PERMANENTReserved constant for non-expiring objects' timestamp.- See Also:
-
ax25Frame
The AX.25 frame object from which this Message was extracted. -
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:
-
originatingDest
Destination "callsign" from the station originating this message. This may not match the destination callsign if the message was relayed through a third-party network (such as APRS-IS). In such cases, destination will be the "tocall" (assuming APRS) of the station transmitting the message onto RF, and originatingDest will be taken from the third-party routing information to indicate the destination that originally injected this message into the network of networks.- See Also:
-
thirdParty
The entire third-party routing path for this AX25Message, or null if this AX25message is still on its original network. -
timestamp
public long timestampMessage 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 rcptTimeThe time the message was received by the system in Java standard milliseconds since 1970 UTC. -
invalid
protected boolean invalidIndicates whether message was correctly formatted or otherwise parseable. -
extensions
Optional map of extracted data fields in this APRS message. May be null if no extensions present in the message. -
UTC
TimeZone object for Greenwich Mean Time (or Universal Coordinated Time), used for converting text string times and dates into binary. -
APRS_AND_OPENTRAC
A read-only protocol set that includes both APRS and OpenTRAC.- See Also:
-
-
Constructor Details
-
AX25Message
protected AX25Message()Constructor for partially initialized AX25Message. -
AX25Message
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 Details
-
equals
Test if the Object o is a duplicate of this Message. -
bodyEquals
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. -
compareTo
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 interfaceComparable<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:
ClassCastException
- if the specified object's type prevents it from being compared to this object.
-
onlyDigits
Test if the specified part of the message body is strictly only ASCII digits.- Parameters:
body
- String containing the message bodypos
- starting index in the array to testlen
- number of bytes to test- Returns:
- boolean true if all the bytes are ASCII digits
-
onlyDigitsOrPeriod
Test if the specified part of the message body is strictly only ASCII digits.- Parameters:
body
- String containing the message bodypos
- starting index in the array to testlen
- 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 bodypos
- starting index in the array to testlen
- 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 bodypos
- starting index in the array to testlen
- 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 bodypos
- starting index in the array to testlen
- 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 bodypos
- starting index in the array to testlen
- 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 searchbufLen
- index of end of used part of buffermatchCh
- character value to search for in a forward searchstartPos
- zero-based index to start searching at- Returns:
- first index of character occurrence after the start pos, or -1 if not found
-
indexOf
Search a byte array (assumed to be an ASCII string) for a matching ASCII string.- Parameters:
buf
- byte array to searchbufLen
- index of end of used part of buffermatchStr
- String value to search for in a forward searchstartPos
- zero-based index to start searching at- Returns:
- first index of string occurrence after the start pos, or -1 if not found
-
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
Returns a string representation of the object. -
extractSource
Extract the originating station callsign for this AX25Message.- Throws:
IllegalArgumentException
- if thirdParty string is provided but doesn't have a sender>dest delimiter
-
getAx25Frame
Get the AX.25 frame from which this Message was extracted.- Returns:
- transport-compatible AX25Frame for this Message
-
setAx25Frame
Attach the AX.25 frame from which this Message was extracted.- Parameters:
ax25Frame
- AX25Frame object containing the encoding of this Message
-
getOriginalSource
Extract the callsign of the original destination of this message.- Parameters:
src
- AX25Callsign of the source of the original AX25FramethirdParty
- String of the third-party routing of this message, or null if not routed over another network- Returns:
- source callsign String
-
getOriginalDestination
Extract the callsign of the original destination of this message.- Parameters:
dest
- AX25Callsign of the destination (tocall) of the original AX25FramethirdParty
- String of the third-party routing of this message, or null if not routed over another network- Returns:
- destination callsign String
-
getLastDigipeat
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 received directly from originating station
-
getFirstDigipeat
Return the callsign of the first digipeat station for this message. Note this code considers a direct receive by an I-gate as the I-gate being the first "digipeater".- Parameters:
digipeaters
- array of AX25Callsign digipeater addresses in AX.25 frame- Returns:
- String station ID of first digipeat station, or empty string if received directly from originating station
-
getNthDigipeat
Return the callsign of the Nth digipeat station for this message. Note this code considers a direct receive by an I-gate as the I-gate being the first "digipeater". If the index is past all the third-party digipeaters and I-gate and this is an RF packet, the RF digipeaters used by the transmitting I-gate will then be iterated through. Note that RF digipeater aliases that are not marked has-been-repeated will not be counted, nor will "q" codes in a third-party prefix.- Parameters:
digipeaters
- array of AX25Callsign digipeater addresses in AX.25 frameindex
- zero-based index into the list of digipeat aliases- Returns:
- String station ID of Nth digipeat station, or null if past end of used digipeat list
-
hasThisFirstDigi
Test if the specified callsign is the first digipeat station for this message.- Parameters:
digipeaters
- array of AX25Callsign digipeater addresses in AX.25 framedigiCallsign
- 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
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
Get the callsign of the station that originated this message (not of any Tx-Igate relay).- Returns:
- String callsign
-
getOriginatingDest
Get the destination address oeiginally specified bv the station that originated this message.- 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
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
Creates and returns a copy of this AX25Message.- Returns:
- a clone of this instance.
- See Also:
-
storeExtension
Store an extracted data element in the Message.- Type Parameters:
K
- any enum subclassV
- any Java object class- Parameters:
key
- Enum that identifies the particular data itemvalue
- the data value- See Also:
-
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:
-
getExtension
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:
-
getProtocols
Get the protocol family or families that this message corresponds to, so ports that don't support all protocols will not forward inappropriate packets.- Returns:
- array of supported ProtocolFamily enums
-
isRf
Test if this AX25Message came from an RF connection.- Parameters:
maxDigis
- int maximum number of digipeat hops before we're not going to count it- Returns:
- Boolean.TRUE if a local Rf transmission, Boolean.FALSE if not RF-only, null if we can't tell
-
isDirect
public boolean isDirect()Test if this message was sent directly (without any relay station).- Returns:
- boolean true if direct, false if not
-
split
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 separatorseparator
- the String delimiting substrings of the line- Returns:
- array of Strings split at the various points the separator appears
-