Identifier Framework and Message/Event Processing Overhaul (#455)

* WIP on new P25 message framer.

* WIP on new P25 message framer.

* Adds new 1/2 and 3/4 rate trellis decoders.  Still trying to chase
down why there is a sync pattern mismatch in the NID buffer queue.

* WIP - new p25 message framer works correctly now.  PDU's are dectected
and decoded using the 1/2 and 3/4 rate trellis decoders.  Packet
Sequences are assembled.  Need to add a new packet sequence message
factory that can detect Motorola Auto Registration Service (ARS)
formatted UDP/ID packets and SNDCP command packets.

* WIP - removes nullify on channel results queue.

* WIP - updates message framer for TSBK 1/2/3 processing.

* WIP removing P25 sync pattern and nid bits from all message parsers.

* WIP - merges identifier framework branch changes into this branch.

* WIP on updating link control words to new format and identifier framework.

* WIP - implements rest of link control words for extended formats

* WIP - initial work on ISP/OSP TSBK message restructuring.

* WIP - adds more TSBK ISP and OSP messages

* WIP - finished updating most of the TSBK ISP and OSP messages.  Converted
all messages to no longer include the NID (nac + dataunitID) so that
each message can simply hold the parsed values.  Removed AliasList as
an argument to each message and updated all messges to use the new
IIdentifer and IAPCO25Channel interfaces.

Removed legacy TDU and LDU link control messages and replaced with a
single LinkControlWord class hierarchy.

P25 decoder state is not yet updated for the new message structure.

PDU message parsing is not fully implemented.

* WIP - adds some Multi-Block trunking control messages with Alternate
and Unconfirmed formats.

* WIP - Fully implements AMBTC and UMBTC PDU message parsers.

Some package restructuring.

* WIP - Resolves Link control parsing in LDU1 and 2 messages.

* WIP - finishes updating TSBK and Link Control messages.  Adds support
for moto link control messages for patch groups.

* WIP - finishes updating TSBK and Link Control messages.  Adds support
for moto link control messages for patch groups.  Adds support for moto
ARS service, IPV4 decoding, and UDP/IP packets.

* WIP - finishes SNDCP packet data with header parsing.  Compressed IP or
UDP headers are not yet supported, but are logged as such.

* WIP - converts all talkgroup identifiers to integers and updates
alias list to create a per-protocol map of talkgroup id's to alias.

Inserts a legacy talkgroup (ltr, p25, passport, mpt1327, mdc, etc.)
conversion utility to convert existing legacy (string) talkgroups to
new integer talkgroup format.

Creates an audio packet manager to insert metadata into audio packets
before streaming packets for playback, recording, and/or streaming.

Creates identifier collection to manage current identifiers in each of
the channel and decoder states.

Creates simplified channel metadata to maintain the now playing display.

Moves channel attributes (alias list, system, site, name) as configuration
identifiers in the channel state.

Many other refactoring and updates.

* WIP - numerous updates to push use of identifier collection throughout
the system.  Updates the channel metadata and audio packet processing
logic.  Implements a large portion of the P25 decode state processing.
Updates traffic channel management.  Adds user preferences for timestamp
and identifier formatting, however doesn't add a user interface yet.

* WIP - initial implementation of user preferences editor window.

* WIP - updates preferences editor window to close and dispose window but
retain javafx event thread running.

* WIP - fully updates p25 decoder state and traffic channel processing to
use the new identifier framework.

Cleans up channel event processing and removes channel model as the sole
broadcaster of channel events.  Channel processing manager now listens
for all start/stop events and requestors dispatch event directly to the
channel processing manager.

Resolves issue in airspy that was causing user interface to lock-up.  The
issue appears to occur when the dongle is plugged into a usb port that
can't fully support the data rate.  sdrtrunk now recognizes these errors
and warns the user that they should use another usb port.

* WIP - updates alias action manager and adds new talkgroup range alias identifier.

Updates playlist to incorporate a version number so that the playlist
updater only runs when needed, to update a playlist to the correct
version format.

Updates user preferences to use the google event bus to broadcast
preference update notifications to remove the need for listeners to
register directly on the user preferences instance.

* WIP - updates alias id editors to flag invalid values and moves legacy
alias ids to legacy package.

Updates event logging configuration to add traffic channel decode events
and decoded message logging.  Removes binary message logging since that
is now replaced with demodulated bitstream recording.

* Removes system properties from user preferences.  Preferences are stored
in the OS-dependent settings store (windows - registry)

* Updates MapService to use new PlottableDecodeEvent instead of monitoring
all of the decoded messages.

Updates Fleetsync decoder and related messages to identifier framework.

* Updates LTR-Net, Fleetsync and LJ1200 decoders to new identifier
framework and adds support for user preferences for formatting of
LTR-Net and fleetsync talkgroup identifiers.

Breaks LTR-Net messages into various message types and uses a new
message factory.

Removes alias list from message processing for ltr-net, fleetsync and
lj1200.

* Updates LTR-Standard messages to Identifier framework.

* Removes Plottable and IPlottable from codebase.

* wip

* WIP on MPT-1327 messages.

* Updates MPT1327 decoder to identifier framework and new traffic channel
manager.  This decoder still needs to be updated with a new message
parser factory and a sync detector like what is now used for P25.

* Updates MDC1200 decoder and message to identifier framework.

* Updates Tait1200 and Passport decoders to identifier framework.

* Merges changes from master branch.

* Removes legacy alias support classes.  Updates passport message processor
to only pass valid messages.  Adds support to playlist updater for
converting passport mobile ids to become passport talkgroup values.

* Updates P25 decoder state and channel state to better track allocated
traffic channels.  Resolves issue in timestamp manager for trackig
message timestamps. Resolves issue in airspy tuner that was causing
the tuner to stop sending samples to the application.

* Update P25 Decoder state to process SNDCP management messages and
PDU messages.

Updates P25 activity summary to display network and site details.

Resolves issue with overlay panel that prevented enabled channels from
rendering correctly when zoomed in.

* Creates a new FilePreferences as part of the user preferences to begin
the transition of SystemProperties over to user preferences and consolidate
file preferences in one location.

Updates playlist manager to use the new file preferences and to use
default.xml as the new default playlist name, following conversion of
a playlist_v2.xml format to the new format.

In the near future, the user will be able to edit file locations and to
create/use other playlists.

Resolved an issue with all decoder states where not all identifiers were
being included in decode events.
This commit is contained in:
Denny Sheirer
2018-12-24 09:08:34 -05:00
committed by GitHub
parent 735fca16d6
commit b67d4d92dc
869 changed files with 64776 additions and 45233 deletions

View File

@@ -1,212 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package io.github.dsheirer.module.decode.ltrnet;
import io.github.dsheirer.alias.Alias;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.module.decode.DecoderType;
import io.github.dsheirer.module.decode.event.CallEvent;
public class LTRCallEvent extends CallEvent
{
private String mChannel;
private long mFrequency;
public LTRCallEvent( DecoderType type,
CallEventType callEventType,
AliasList aliasList,
String fromID,
String toID,
String channel,
long frequency,
String details )
{
super( type, callEventType, aliasList, fromID, toID, details );
mChannel = channel;
mFrequency = frequency;
}
/**
* Checks if the message's talkgroup matches this call event. Counts the
* number of messages that match this call event to use in determining if
* a call event is valid or an isolated (errant) message.
*
* See: isValid()
*/
public boolean isMatchingTalkgroup( LTRNetMessage message )
{
String talkgroup = message.getTalkgroupID();
if( talkgroup != null && getToID() != null &&
talkgroup.contentEquals( getToID() ) )
{
return true;
}
return isMatchingTalkgroup( message.getTalkgroupID() );
}
public boolean isMatchingTalkgroup( String talkgroup )
{
return talkgroup != null && getToID() != null && talkgroup.contentEquals( getToID() );
}
private Alias getAlias(String talkgroup )
{
if( hasAliasList() )
{
return getAliasList().getTalkgroupAlias( talkgroup );
}
return null;
}
@Override
public Alias getFromIDAlias()
{
if( mCallEventType == CallEventType.CALL ||
mCallEventType == CallEventType.REGISTER ||
mCallEventType == CallEventType.ID_UNIQUE )
{
if( hasAliasList() )
{
try
{
int radioID = Integer.parseInt( getFromID() );
return mAliasList.getUniqueID( radioID );
}
catch( Exception e )
{
//Do nothing, we couldn't parse the int radio id value
}
}
}
else if( mCallEventType == CallEventType.REGISTER_ESN )
{
if( hasAliasList() )
{
return mAliasList.getESNAlias( getFromID() );
}
}
else
{
return getAlias( getFromID() );
}
return null;
}
@Override
public Alias getToIDAlias()
{
return getAlias( getToID() );
}
@Override
public String getChannel()
{
return mChannel;
}
@Override
public long getFrequency()
{
return mFrequency;
}
public static class Builder
{
/* Required parameters */
private DecoderType mDecoderType;
private CallEventType mCallEventType;
/* Optional parameters */
private AliasList mAliasList;
private String mFromID;
private String mToID;
private String mDetails;
private String mChannel;
private long mFrequency;
public Builder( DecoderType decoderType, CallEventType callEventType )
{
mDecoderType = decoderType;
mCallEventType = callEventType;
}
public Builder aliasList( AliasList aliasList )
{
mAliasList = aliasList;
return this;
}
public Builder from( String val )
{
mFromID = val;
return this;
}
public Builder channel( String channel )
{
mChannel = channel;
return this;
}
public Builder details( String details )
{
mDetails = details;
return this;
}
public Builder frequency( long frequency )
{
mFrequency = frequency;
return this;
}
public Builder to( String toID )
{
mToID = toID;
return this;
}
public LTRCallEvent build()
{
return new LTRCallEvent( this );
}
}
/**
* Private constructor for the builder
*/
private LTRCallEvent( Builder builder )
{
this( builder.mDecoderType,
builder.mCallEventType,
builder.mAliasList,
builder.mFromID,
builder.mToID,
builder.mChannel,
builder.mFrequency,
builder.mDetails );
}
}

View File

@@ -15,7 +15,6 @@
******************************************************************************/
package io.github.dsheirer.module.decode.ltrnet;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.bits.MessageFramer;
import io.github.dsheirer.bits.SyncPattern;
import io.github.dsheirer.dsp.fsk.LTRDecoder;
@@ -37,7 +36,7 @@ public class LTRNetDecoder extends Decoder implements IReusableBufferListener, L
* LTR-Net Decoder. Decodes unfiltered (e.g. demodulated but with no DC or
* audio filtering) samples and produces LTR-Net messages.
*/
public LTRNetDecoder(DecodeConfigLTRNet config, AliasList aliasList, LTRDecoder ltrDecoder)
public LTRNetDecoder(DecodeConfigLTRNet config, LTRDecoder ltrDecoder)
{
mLTRDecoder = ltrDecoder;
@@ -52,7 +51,7 @@ public class LTRNetDecoder extends Decoder implements IReusableBufferListener, L
mLTRDecoder.setMessageFramer(mLTRMessageFramer);
mLTRMessageFramer.setSyncDetectListener(mLTRDecoder);
mLTRMessageProcessor = new LTRNetMessageProcessor(config.getMessageDirection(), aliasList);
mLTRMessageProcessor = new LTRNetMessageProcessor(config.getMessageDirection());
mLTRMessageFramer.addMessageListener(mLTRMessageProcessor);
mLTRMessageProcessor.setMessageListener(getMessageListener());
}
@@ -61,9 +60,9 @@ public class LTRNetDecoder extends Decoder implements IReusableBufferListener, L
* LTR-Net Decoder. Decodes unfiltered (e.g. demodulated but with no DC or
* audio filtering) samples and produces LTR-Net messages.
*/
public LTRNetDecoder(DecodeConfigLTRNet config, AliasList aliasList)
public LTRNetDecoder(DecodeConfigLTRNet config)
{
this(config, aliasList, new LTRDecoder(LTR_NET_MESSAGE_LENGTH));
this(config, new LTRDecoder(LTR_NET_MESSAGE_LENGTH));
}
@Override

View File

@@ -15,7 +15,6 @@
******************************************************************************/
package io.github.dsheirer.module.decode.ltrnet;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.dsp.fsk.LTRDecoderInstrumented;
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
import javafx.beans.property.SimpleIntegerProperty;
@@ -24,9 +23,9 @@ public class LTRNetDecoderInstrumented extends LTRNetDecoder
{
public SimpleIntegerProperty bufferCount = new SimpleIntegerProperty();
public LTRNetDecoderInstrumented(DecodeConfigLTRNet config, AliasList aliasList)
public LTRNetDecoderInstrumented(DecodeConfigLTRNet config)
{
super(config, aliasList, new LTRDecoderInstrumented(LTR_NET_MESSAGE_LENGTH));
super(config, new LTRDecoderInstrumented(LTR_NET_MESSAGE_LENGTH));
}
public LTRDecoderInstrumented getLTRDecoder()

View File

@@ -1,345 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package io.github.dsheirer.module.decode.ltrnet;
import io.github.dsheirer.alias.Alias;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.bits.BinaryMessage;
import io.github.dsheirer.edac.CRC;
import io.github.dsheirer.edac.CRCLTR;
import io.github.dsheirer.map.Plottable;
import io.github.dsheirer.message.MessageDirection;
import io.github.dsheirer.message.MessageType;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class LTRNetISWMessage extends LTRNetMessage
{
private static final int sCHIU_UNIQUE_ID = 24;
private static final int sCHIU_ESN_LOW = 27;
private static final int sCHIU_ESN_HIGH = 29;
private static final int sFREE_CALL = 21;
private static final int sFREE_END_CALL = 23;
private static final int sFREE_REQUEST_ACCESS = 31;
private LTRNetISWMessage mAuxMessage;
public LTRNetISWMessage( BinaryMessage message, AliasList list )
{
super( message, MessageDirection.ISW, list );
/**
* If the CRC fails, test for a transmitted CRC of 127 and then check
* the Free field for special messages
*/
if( mCRC == CRC.FAILED_CRC && CRCLTR.getTransmittedChecksum( mMessage ) == 127 )
{
if( getFree() == sFREE_REQUEST_ACCESS ||
getFree() == sFREE_END_CALL )
{
mCRC = CRC.PASSED;
}
}
mMessageType = getMessageType();
}
public void setAuxiliaryMessage( LTRNetISWMessage message )
{
if( message != null )
{
mAuxMessage = message;
}
}
public String getESN()
{
if( mMessageType == MessageType.ID_ESNH )
{
if( mAuxMessage != null &&
mAuxMessage.getMessageType() == MessageType.ID_ESNL )
{
return getESNHigh() + mAuxMessage.getESNLow();
}
else
{
return getESNHigh() + "xxxx";
}
}
else
{
if( mAuxMessage != null &&
mAuxMessage.getMessageType() == MessageType.ID_ESNH )
{
return mAuxMessage.getESNHigh() + getESNLow();
}
else
{
return "xxxx" + getESNLow();
}
}
}
public Alias getESNAlias()
{
if( mAliasList != null )
{
return mAliasList.getESNAlias( getESN() );
}
return null;
}
public String getESNHigh()
{
int esnHigh = getInt( sSIXTEEN_BITS );
return String.format("%04X", esnHigh & 0xFFFF );
}
public String getESNLow()
{
int esnLow = getInt( sSIXTEEN_BITS );
return String.format("%04X", esnLow & 0xFFFF );
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( mDatestampFormatter.format( new Date( System.currentTimeMillis() ) ) );
sb.append( " LTRNet ISW [" );
sb.append( mCRC.getAbbreviation() );
sb.append( "] " );
sb.append( getMessage() );
pad( sb, 100 );
sb.append( mMessage.toString() );
return sb.toString();
}
@Override
public String getMessage()
{
StringBuilder sb = new StringBuilder();
switch( mMessageType )
{
case CA_STRT:
sb.append( "CALL LCN:" );
sb.append( format( getChannel(), 2 ) );
sb.append( " TG [ " );
sb.append( getTalkgroupID() );
sb.append( "/" );
sb.append( getTalkgroupIDAlias() );
sb.append( " ] FREE:" );
sb.append( format( getFree(), 2 ) );
break;
case CA_ENDD:
sb.append( "END* AREA:" );
sb.append( getArea() );
sb.append( " LCN:" );
sb.append( format( getChannel(), 2 ) );
sb.append( " TG [" );
sb.append( getTalkgroupID() );
sb.append( "/" );
sb.append( getTalkgroupIDAlias() );
sb.append( "] FREE:" );
sb.append( format( getFree(), 2 ) );
break;
case RQ_ACCE:
sb.append( "REQUEST ACCESS LCN:" );
sb.append( format( getChannel(), 2 ) );
sb.append( " TG [ " );
sb.append( getTalkgroupID() );
sb.append( "/" );
sb.append( getTalkgroupIDAlias() );
sb.append( " ] FREE:" );
sb.append( format( getFree(), 2 ) );
break;
case ID_ESNL:
sb.append( "ESN LOW " );
sb.append( getESN() );
sb.append( "/" );
sb.append( getESNAlias() );
break;
case ID_ESNH:
sb.append( "ESN HIGH " );
sb.append( getESN() );
sb.append( "/" );
sb.append( getESNAlias() );
break;
case ID_UNIQ:
sb.append( "RADIO UNIQUE ID " );
sb.append( getRadioUniqueID() );
if( getRadioUniqueIDAlias() != null )
{
sb.append( "/" );
sb.append( getRadioUniqueIDAlias().getName() );
}
break;
default:
sb.append( "UNKNOWN " );
sb.append( getArea() );
sb.append( " " );
sb.append( format( getChannel(), 2 ) );
sb.append( " " );
sb.append( format( getHomeRepeater(), 2 ) );
sb.append( " " );
sb.append( format( getGroup(), 3 ) );
sb.append( " " );
sb.append( format( getFree(), 2 ) );
sb.append( " CRC:" );
sb.append( CRCLTR.getTransmittedChecksum( mMessage ) );
sb.append( " CALC:" );
sb.append( CRCLTR.getCalculatedChecksum( mMessage ) );
}
return sb.toString();
}
public int getRadioUniqueID()
{
int retVal = INT_NULL_VALUE;
if( mMessageType == MessageType.ID_UNIQ )
{
retVal = getInt( sSIXTEEN_BITS );
}
return retVal;
}
public Alias getRadioUniqueIDAlias()
{
if( mAliasList != null )
{
return mAliasList.getUniqueID( getRadioUniqueID() );
}
return null;
}
public MessageType getMessageType()
{
MessageType retVal = MessageType.UN_KNWN;
int channel = getChannel();
if( channel == 31 )
{
retVal = MessageType.CA_ENDD;
}
else if( channel > 20 )
{
switch( channel )
{
case sCHIU_UNIQUE_ID:
retVal = MessageType.ID_UNIQ;
break;
case sCHIU_ESN_LOW:
retVal = MessageType.ID_ESNH;
break;
case sCHIU_ESN_HIGH:
retVal = MessageType.ID_ESNL;
break;
}
}
else if( channel > 0 )
{
int free = getFree();
switch( free )
{
case sFREE_CALL:
retVal = MessageType.CA_STRT;
break;
case sFREE_END_CALL:
retVal = MessageType.CA_ENDD;
break;
case sFREE_REQUEST_ACCESS:
retVal = MessageType.RQ_ACCE;
break;
}
}
return retVal;
}
@Override
public String getFromID()
{
return null;
}
@Override
public Alias getFromIDAlias()
{
return null;
}
@Override
public void setAuxiliaryMessage( LTRNetOSWMessage message )
{
// TODO Auto-generated method stub
}
@Override
public Plottable getPlottable()
{
// TODO Auto-generated method stub
return null;
}
/**
* Provides a listing of aliases contained in the message.
*/
public List<Alias> getAliases()
{
List<Alias> aliases = new ArrayList<Alias>();
Alias from = getFromIDAlias();
if( from != null )
{
aliases.add( from );
}
Alias to = getToIDAlias();
if( to != null )
{
aliases.add( to );
}
Alias esn = getESNAlias();
if( esn != null )
{
aliases.add( esn );
}
return aliases;
}
}

View File

@@ -1,243 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package io.github.dsheirer.module.decode.ltrnet;
import io.github.dsheirer.alias.Alias;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.bits.BinaryMessage;
import io.github.dsheirer.edac.CRC;
import io.github.dsheirer.edac.CRCLTR;
import io.github.dsheirer.message.Message;
import io.github.dsheirer.message.MessageDirection;
import io.github.dsheirer.message.MessageType;
import io.github.dsheirer.module.decode.DecoderType;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
public abstract class LTRNetMessage extends Message
{
protected static final String sUNKNOWN = "**UNKNOWN**";
protected static final int INT_NULL_VALUE = -1;
protected static final double sDOUBLE_NULL_VALUE = -1.0D;
protected SimpleDateFormat mDatestampFormatter =
new SimpleDateFormat( "yyyyMMdd HHmmss" );
protected DecimalFormat mDecimalFormatter = new DecimalFormat("0.00000");
protected static final int[] sSYNC = { 8,7,6,5,4,3,2,1,0 };
protected static final int[] sAREA = { 9 };
protected static final int[] sCHANNEL = { 14,13,12,11,10 };
protected static final int[] sHOME_REPEATER = { 19,18,17,16,15 };
protected static final int[] sGROUP = { 27,26,25,24,23,22,21,20 };
protected static final int[] sFREE = { 32,31,30,29,28 };
protected static final int[] sCRC = { 39,38,37,36,35,34,33 };
protected static final int[] sSIXTEEN_BITS = { 32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17 };
protected static final int[] sMANUFACTURER_ID = { 23,22,21,20,19,18,17 };
protected BinaryMessage mMessage;
protected MessageType mMessageType;
protected CRC mCRC;
protected AliasList mAliasList;
public LTRNetMessage( BinaryMessage message,
MessageDirection direction,
AliasList list )
{
mMessage = message;
mCRC = CRCLTR.check( message, direction );
mAliasList = list;
}
public MessageType getMessageType()
{
return mMessageType;
}
public abstract void setAuxiliaryMessage( LTRNetOSWMessage message );
public boolean isValid()
{
return mCRC != CRC.FAILED_CRC && mCRC != CRC.FAILED_PARITY;
}
/**
* Appends spaces to the end of the stringbuilder to make it length long
*/
protected void pad( StringBuilder sb, int length )
{
while( sb.length() < length )
{
sb.append( " " );
}
}
@Override
public String getBinaryMessage()
{
return mMessage.toString();
}
/**
* Returns a value formatted in hex notation.
*
* @param value - integer value
* @return - hex digits returned
*/
protected static String getHex( int value, int digits )
{
return String.format( "%0" + digits + "X", value );
}
protected int getInt( int[] bits )
{
int retVal = 0;
for( int x = 0; x < bits.length; x++ )
{
if( mMessage.get( bits[ x ] ) )
{
retVal += 1<<x;
}
}
return retVal;
}
/**
* Pads an integer value with additional zeroes to make it decimalPlaces long
*/
public String format( int number, int decimalPlaces )
{
StringBuilder sb = new StringBuilder();
int paddingRequired = decimalPlaces - ( String.valueOf( number ).length() );
for( int x = 0; x < paddingRequired; x++)
{
sb.append( "0" );
}
sb.append( number );
return sb.toString();
}
public String format( String val, int places )
{
StringBuilder sb = new StringBuilder();
sb.append( val );
while( sb.length() < places )
{
sb.append( " " );
}
return sb.toString();
}
public CRC getCRC()
{
return mCRC;
}
public int getArea()
{
return getInt( sAREA );
}
public int getChannel()
{
return getInt( sCHANNEL );
}
public int getHomeRepeater()
{
return getInt( sHOME_REPEATER );
}
public int getGroup()
{
return getInt( sGROUP );
}
public String getTalkgroupID()
{
StringBuilder sb = new StringBuilder();
sb.append( getArea() );
sb.append( "-" );
sb.append( format( getHomeRepeater(), 2 ) );
sb.append( "-" );
sb.append( format( getGroup(), 3 ) );
return sb.toString();
}
public Alias getTalkgroupIDAlias()
{
return mAliasList.getTalkgroupAlias( getTalkgroupID() );
}
public int getFree()
{
return getInt( sFREE );
}
public int getCRCChecksum()
{
return getInt( sCRC );
}
@Override
public String getProtocol()
{
return DecoderType.LTR_NET.getDisplayString();
}
@Override
public String getEventType()
{
if( mMessageType != null )
{
return mMessageType.getDisplayText();
}
else
{
return MessageType.UN_KNWN.getDisplayText();
}
}
@Override
public String getToID()
{
return null;
}
@Override
public Alias getToIDAlias()
{
return null;
}
@Override
public String getErrorStatus()
{
return mCRC.getDisplayText();
}
}

View File

@@ -2,79 +2,53 @@ package io.github.dsheirer.module.decode.ltrnet;
import io.github.dsheirer.filter.Filter;
import io.github.dsheirer.filter.FilterElement;
import io.github.dsheirer.message.Message;
import io.github.dsheirer.message.MessageType;
import io.github.dsheirer.message.IMessage;
import io.github.dsheirer.module.decode.ltrnet.message.LtrNetMessage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LTRNetMessageFilter extends Filter<Message>
public class LTRNetMessageFilter extends Filter<IMessage>
{
private HashMap<MessageType, FilterElement<MessageType>> mElements =
new HashMap<MessageType, FilterElement<MessageType>>();
public LTRNetMessageFilter()
{
super( "LTR-Net Message Filter" );
private Map<LtrNetMessageType, FilterElement<LtrNetMessageType>> mElements = new HashMap<>();
mElements.put( MessageType.CA_STRT,
new FilterElement<MessageType>( MessageType.CA_STRT ) );
mElements.put( MessageType.CA_ENDD,
new FilterElement<MessageType>( MessageType.CA_ENDD ) );
mElements.put( MessageType.SY_IDLE,
new FilterElement<MessageType>( MessageType.SY_IDLE ) );
mElements.put( MessageType.ID_UNIQ,
new FilterElement<MessageType>( MessageType.ID_UNIQ ) );
mElements.put( MessageType.ID_ESNH,
new FilterElement<MessageType>( MessageType.ID_ESNH ) );
mElements.put( MessageType.ID_ESNL,
new FilterElement<MessageType>( MessageType.ID_ESNL ) );
mElements.put( MessageType.RQ_ACCE,
new FilterElement<MessageType>( MessageType.RQ_ACCE ) );
mElements.put( MessageType.ID_SITE,
new FilterElement<MessageType>( MessageType.ID_SITE ) );
mElements.put( MessageType.FQ_RXHI,
new FilterElement<MessageType>( MessageType.FQ_RXHI ) );
mElements.put( MessageType.FQ_RXLO,
new FilterElement<MessageType>( MessageType.FQ_RXLO ) );
mElements.put( MessageType.FQ_TXHI,
new FilterElement<MessageType>( MessageType.FQ_TXHI ) );
mElements.put( MessageType.FQ_TXLO,
new FilterElement<MessageType>( MessageType.FQ_TXLO ) );
mElements.put( MessageType.ID_NBOR,
new FilterElement<MessageType>( MessageType.ID_NBOR ) );
mElements.put( MessageType.MA_CHNH,
new FilterElement<MessageType>( MessageType.MA_CHNH ) );
mElements.put( MessageType.MA_CHNL,
new FilterElement<MessageType>( MessageType.MA_CHNL ) );
}
@Override
public boolean passes( Message message )
public LTRNetMessageFilter()
{
if( mEnabled && canProcess( message ) )
{
LTRNetMessage ltr = (LTRNetMessage)message;
if( mElements.containsKey( ltr.getMessageType() ) )
{
return mElements.get( ltr.getMessageType() ).isEnabled();
}
}
return false;
super("LTR-Net Message Filter");
for(LtrNetMessageType type: LtrNetMessageType.values())
{
mElements.put(type, new FilterElement<>(type));
}
}
@Override
public boolean canProcess( Message message )
@Override
public boolean passes(IMessage message)
{
return message instanceof LTRNetMessage;
if(mEnabled && canProcess(message))
{
LtrNetMessage ltr = (LtrNetMessage) message;
if(mElements.containsKey(ltr.getLtrNetMessageType()))
{
return mElements.get(ltr.getLtrNetMessageType()).isEnabled();
}
}
return false;
}
@Override
@Override
public boolean canProcess(IMessage message)
{
return message instanceof LtrNetMessage;
}
@Override
public List<FilterElement<?>> getFilterElements()
{
return new ArrayList<FilterElement<?>>( mElements.values() );
return new ArrayList<FilterElement<?>>(mElements.values());
}
}

View File

@@ -1,164 +1,132 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014,2015 Dennis Sheirer
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package io.github.dsheirer.module.decode.ltrnet;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.bits.BinaryMessage;
import io.github.dsheirer.message.Message;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.message.IMessage;
import io.github.dsheirer.message.MessageDirection;
import io.github.dsheirer.message.MessageType;
import io.github.dsheirer.module.decode.ltrnet.message.LtrNetMessage;
import io.github.dsheirer.module.decode.ltrnet.message.LtrNetMessageFactory;
import io.github.dsheirer.module.decode.ltrnet.message.isw.RegistrationRequestEsnHigh;
import io.github.dsheirer.module.decode.ltrnet.message.isw.RegistrationRequestEsnLow;
import io.github.dsheirer.module.decode.ltrnet.message.osw.ReceiveFrequencyHigh;
import io.github.dsheirer.module.decode.ltrnet.message.osw.ReceiveFrequencyLow;
import io.github.dsheirer.module.decode.ltrnet.message.osw.TransmitFrequencyHigh;
import io.github.dsheirer.module.decode.ltrnet.message.osw.TransmitFrequencyLow;
import io.github.dsheirer.sample.Listener;
import java.util.HashMap;
import java.util.Map;
public class LTRNetMessageProcessor implements Listener<BinaryMessage>
public class LTRNetMessageProcessor implements Listener<CorrectedBinaryMessage>
{
private Listener<Message> mMessageListener;
private Listener<IMessage> mMessageListener;
private HashMap<Integer,LTRNetOSWMessage> mReceiveHighAuxMessages =
new HashMap<Integer,LTRNetOSWMessage>();
private HashMap<Integer,LTRNetOSWMessage> mReceiveLowAuxMessages =
new HashMap<Integer,LTRNetOSWMessage>();
private Map<Integer,ReceiveFrequencyHigh> mReceiveHighMessageMap = new HashMap<>();
private Map<Integer,ReceiveFrequencyLow> mReceiveLowMessageMap = new HashMap<>();
private Map<Integer,TransmitFrequencyHigh> mTransmitHighMessageMap = new HashMap<>();
private Map<Integer,TransmitFrequencyLow> mTransmitLowMessageMap = new HashMap<>();
private HashMap<Integer,LTRNetOSWMessage> mTransmitHighAuxMessages =
new HashMap<Integer,LTRNetOSWMessage>();
private HashMap<Integer,LTRNetOSWMessage> mTransmitLowAuxMessages =
new HashMap<Integer,LTRNetOSWMessage>();
private RegistrationRequestEsnHigh mRegistrationRequestEsnHighMessage;
private RegistrationRequestEsnLow mRegistrationRequestEsnLowMessage;
private LTRNetISWMessage mESNHighMessage;
private LTRNetISWMessage mESNLowMessage;
private MessageDirection mDirection;
private AliasList mAliasList;
public LTRNetMessageProcessor( MessageDirection direction, AliasList list )
{
mDirection = direction;
mAliasList = list;
}
@Override
public void receive( BinaryMessage buffer )
private MessageDirection mDirection;
public LTRNetMessageProcessor(MessageDirection direction)
{
if( mMessageListener != null )
{
LTRNetMessage message;
if( mDirection == MessageDirection.OSW )
{
message = new LTRNetOSWMessage( buffer, mAliasList );
if( message.isValid() )
{
if( message.getMessageType() == MessageType.FQ_TXHI )
{
mTransmitHighAuxMessages.put( message.getHomeRepeater(), (LTRNetOSWMessage)message );
message.setAuxiliaryMessage( mTransmitLowAuxMessages.get(message.getHomeRepeater() ) );
}
else if( message.getMessageType() == MessageType.FQ_TXLO )
{
mTransmitLowAuxMessages.put( message.getHomeRepeater(),
(LTRNetOSWMessage)message );
message.setAuxiliaryMessage( mTransmitHighAuxMessages.get(
message.getHomeRepeater() ) );
}
else if( message.getMessageType() == MessageType.FQ_RXHI )
{
mReceiveHighAuxMessages.put( message.getHomeRepeater(),
(LTRNetOSWMessage)message );
message.setAuxiliaryMessage( mReceiveLowAuxMessages.get(
message.getHomeRepeater() ) );
}
else if( message.getMessageType() == MessageType.FQ_RXLO )
{
mReceiveLowAuxMessages.put( message.getHomeRepeater(),
(LTRNetOSWMessage)message );
message.setAuxiliaryMessage( mReceiveHighAuxMessages.get(
message.getHomeRepeater() ) );
}
}
}
else
{
buffer.flip( 0, 40 );
message = new LTRNetISWMessage( buffer, mAliasList );
if( message.isValid() )
{
/**
* Catch ESN High messages to marry up with ESN Low messages. Purge
* the ESN high message after 2 messages, so that it doesn't get
* paired with the wrong esn low message
*/
if( message.getMessageType() == MessageType.ID_ESNH )
{
mESNHighMessage = (LTRNetISWMessage)message;
if( mESNLowMessage != null )
{
/* Check that the stored message is not older than
* 5 seconds */
if( System.currentTimeMillis() -
mESNLowMessage.getTimeReceived() < 5000 )
{
((LTRNetISWMessage)message).setAuxiliaryMessage( mESNLowMessage );
}
else
{
mESNLowMessage = null;
}
}
}
else if( message.getMessageType() == MessageType.ID_ESNL )
{
mESNLowMessage = (LTRNetISWMessage)message;
if( mESNHighMessage != null )
{
/* Check that the stored message is not older than 5 seconds */
if( System.currentTimeMillis() - mESNHighMessage.getTimeReceived() < 5000 )
{
((LTRNetISWMessage)message).setAuxiliaryMessage( mESNHighMessage );
}
else
{
mESNHighMessage = null;
}
}
}
}
}
mMessageListener.receive( message );
}
mDirection = direction;
}
public void setMessageListener( Listener<Message> listener )
@Override
public void receive(CorrectedBinaryMessage buffer)
{
mMessageListener = listener;
LtrNetMessage message = LtrNetMessageFactory.create(mDirection, buffer, System.currentTimeMillis());
if(message.isValid())
{
switch(message.getLtrNetMessageType())
{
case OSW_TRANSMIT_FREQUENCY_HIGH:
if(message instanceof TransmitFrequencyHigh)
{
TransmitFrequencyHigh transmitFrequencyHigh = (TransmitFrequencyHigh)message;
mTransmitHighMessageMap.put(transmitFrequencyHigh.getChannel(), transmitFrequencyHigh);
transmitFrequencyHigh.setFrequencyLow(mTransmitLowMessageMap.get(transmitFrequencyHigh.getChannel()));
}
break;
case OSW_TRANSMIT_FREQUENCY_LOW:
if(message instanceof TransmitFrequencyLow)
{
TransmitFrequencyLow transmitFrequencyLow = (TransmitFrequencyLow)message;
mTransmitLowMessageMap.put(transmitFrequencyLow.getChannel(), transmitFrequencyLow);
transmitFrequencyLow.setFrequencyHigh(mTransmitHighMessageMap.get(transmitFrequencyLow.getChannel()));
}
break;
case OSW_RECEIVE_FREQUENCY_HIGH:
if(message instanceof ReceiveFrequencyHigh)
{
ReceiveFrequencyHigh receiveFrequencyHigh = (ReceiveFrequencyHigh)message;
mReceiveHighMessageMap.put(receiveFrequencyHigh.getChannel(), receiveFrequencyHigh);
receiveFrequencyHigh.setFrequencyLow(mReceiveLowMessageMap.get(receiveFrequencyHigh.getChannel()));
}
break;
case OSW_RECEIVE_FREQUENCY_LOW:
if(message instanceof ReceiveFrequencyLow)
{
ReceiveFrequencyLow receiveFrequencyLow = (ReceiveFrequencyLow)message;
mReceiveLowMessageMap.put(receiveFrequencyLow.getChannel(), receiveFrequencyLow);
receiveFrequencyLow.setFrequencyHigh(mReceiveHighMessageMap.get(receiveFrequencyLow.getChannel()));
}
break;
case ISW_REGISTRATION_REQUEST_ESN_HIGH:
if(message instanceof RegistrationRequestEsnHigh)
{
((RegistrationRequestEsnHigh)message).setEsnLowMessage(mRegistrationRequestEsnLowMessage);
}
break;
case ISW_REGISTRATION_REQUEST_ESN_LOW:
if(message instanceof RegistrationRequestEsnLow)
{
((RegistrationRequestEsnLow)message).setESNHighMessage(mRegistrationRequestEsnHighMessage);
}
break;
case ISW_CALL_START:
case ISW_CALL_END:
//Reset the esn messages
mRegistrationRequestEsnHighMessage = null;
mRegistrationRequestEsnLowMessage = null;
break;
}
if(mMessageListener != null)
{
mMessageListener.receive(message);
}
}
}
public void setMessageListener(Listener<IMessage> listener)
{
mMessageListener = listener;
}
public void removeMessageListener()
{
mMessageListener = null;
mMessageListener = null;
}
}

View File

@@ -1,644 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package io.github.dsheirer.module.decode.ltrnet;
import io.github.dsheirer.alias.Alias;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.bits.BinaryMessage;
import io.github.dsheirer.map.Plottable;
import io.github.dsheirer.message.MessageDirection;
import io.github.dsheirer.message.MessageType;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class LTRNetOSWMessage extends LTRNetMessage
{
private static final int CHANNEL_FREQUENCY_MESSAGE_TYPE_BIT = 20;
private static final int CHANNEL_MAP_MESSAGE_TYPE_BIT = 17;
private static final int CHIU_UNIQUE_ID = 17;
private static final int CHIU_SITE_ID = 18;
private static final int CHIU_TRANSMIT_FREQUENCY = 24;
private static final int CHIU_RECEIVE_FREQUENCY = 25;
private static final int CHIU_NEIGHBOR = 26;
private static final int CHIU_MAP = 28;
private static final int CHIU_CALL_END = 31;
private static final int HOME_DIRECTED_GROUP_CALL = 29;
private static final int HOME_CHANNEL_IN_USE_MUTE_AUDIO = 30;
private static final int GROUP_DO_NOTHING = 253;
private static final int GROUP_CWID = 254;
private static final int GROUP_CHANNEL_IDLE = 255;
private static final int FREE_ALL_CHANNELS_BUSY = 0;
private static final int FREE_LTR_GROUP_CALL = 30;
private static final int FREE_LTRNET_GROUP_CALL = 31;
private LTRNetOSWMessage mAuxMessage;
public LTRNetOSWMessage( BinaryMessage message, AliasList list )
{
super( message, MessageDirection.OSW, list );
mMessageType = getType();
}
public void setAuxiliaryMessage( LTRNetOSWMessage message )
{
if( message != null )
{
mAuxMessage = message;
}
}
public String getRadioUniqueIDText()
{
StringBuilder sb = new StringBuilder();
int radioId = getRadioUniqueID();
if( radioId != INT_NULL_VALUE )
{
sb.append( " RADIO UNIQUE ID: " );
sb.append( radioId );
}
return sb.toString();
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( mDatestampFormatter.format(
new Date( System.currentTimeMillis() ) ) );
sb.append( " LTRNet OSW [" );
sb.append( mCRC.getAbbreviation() );
sb.append( "] " );
sb.append( getMessage() );
pad( sb, 100 );
sb.append( mMessage.toString() );
return sb.toString();
}
@Override
public String getMessage()
{
StringBuilder sb = new StringBuilder();
switch( mMessageType )
{
case SY_IDLE:
sb.append( "IDLE AREA:" );
sb.append( getArea() );
sb.append( " LCN:" );
sb.append( format( getChannel(), 2 ) );
sb.append( " HOME:" );
sb.append( format( getHomeRepeater(), 2 ) );
sb.append( " GRP:" );
sb.append( format( getGroup(), 3 ) );
sb.append( " FREE:" );
sb.append( format( getFree(), 2 ) );
break;
case CA_STRT:
sb.append( "CALL LCN:" );
sb.append( format( getChannel(), 2 ) );
sb.append( " TG [ " );
sb.append( getTalkgroupID() );
sb.append( "/" );
sb.append( getTalkgroupIDAlias() );
sb.append( " ] FREE:" );
sb.append( format( getFree(), 2 ) );
break;
case CA_ENDD:
sb.append( "END* AREA:" );
sb.append( getArea() );
sb.append( " LCN:" );
sb.append( format( getChannel(), 2 ) );
sb.append( " TG [" );
sb.append( getTalkgroupID() );
sb.append( "/" );
sb.append( getTalkgroupIDAlias() );
sb.append( "] FREE:" );
sb.append( format( getFree(), 2 ) );
break;
case MA_CHNL:
sb.append( "CHAN MAP LOW LCN [" );
sb.append( getChannelMapAsString( getChannelMapLow() ) );
sb.append( "]" );
break;
case MA_CHNH:
sb.append( "CHAN MAP HIGH LCN [" );
sb.append( getChannelMapAsString( getChannelMapHigh() ) );
sb.append( "]" );
break;
case FQ_RXLO:
sb.append( "CHAN RX LOW LCN:" );
sb.append( format( getHomeRepeater(), 2 ) );
sb.append( " = " );
long rxFreqLo = getFrequency();
if( rxFreqLo > 0 )
{
sb.append( mDecimalFormatter.format( (double)rxFreqLo / 1E6d ) );
}
else
{
sb.append( "000.00000" );
}
sb.append( " MHz" );
break;
case FQ_RXHI:
sb.append( "CHAN RX HIGH LCN:" );
sb.append( format( getHomeRepeater(), 2 ) );
sb.append( " = " );
long rxfreqhi = getFrequency();
if( rxfreqhi > 0 )
{
sb.append( mDecimalFormatter.format( (double)rxfreqhi / 1E6d ) );
}
else
{
sb.append( "000.00000" );
}
sb.append( " MHz" );
break;
case FQ_TXHI:
sb.append( "CHAN TX LOW LCN:" );
sb.append( format( getHomeRepeater(), 2 ) );
sb.append( " = " );
long txfreq = getFrequency();
if( txfreq > 0 )
{
sb.append( mDecimalFormatter.format( (double)txfreq / 1E6d ) );
}
else
{
sb.append( "000.00000" );
}
sb.append( " MHz" );
break;
case FQ_TXLO:
sb.append( "CHAN TX HIGH LCN:" );
sb.append( format( getHomeRepeater(), 2 ) );
sb.append( " = " );
long txFreqLo = getFrequency();
if( txFreqLo > 0 )
{
sb.append( mDecimalFormatter.format( (double)txFreqLo / 1E6d ) );
}
else
{
sb.append( "000.00000" );
}
sb.append( " MHz" );
break;
case ID_SITE:
String siteId = getSiteID();
if( siteId != null )
{
sb.append( "SITE ID: " );
sb.append( siteId );
sb.append( " " );
sb.append( getSiteIDAlias() );
}
break;
case ID_NBOR:
int neighborRank = getNeighborRank();
String neighborId = getNeighborID();
if( neighborRank != INT_NULL_VALUE &&
neighborId != null )
{
sb.append( "NEIGHBOR SITE " );
sb.append( neighborRank );
sb.append( ": " );
sb.append( neighborId );
sb.append( " " );
sb.append( getNeighborIDAlias() );
}
break;
case ID_UNIQ:
sb.append( "REGISTER RADIO UNIQUE ID:" );
sb.append( getRadioUniqueID() );
break;
default:
sb.append( "UNKNOWN " );
sb.append( getArea() );
sb.append( " " + format( getChannel(), 2 ) );
sb.append( " " + format( getHomeRepeater(), 2 ) );
sb.append( " " + format( getGroup(), 3 ) );
sb.append( " " + format( getFree(), 2 ) );
sb.append( " A:" );
sb.append( getArea() );
sb.append( " C:" );
sb.append( format( getChannel(), 2 ) );
sb.append( " H:" );
sb.append( format( getHomeRepeater(), 2 ) );
sb.append( " G:" );
sb.append( format( getGroup(), 3 ) );
sb.append( " F:" );
sb.append( format( getFree(), 2 ) );
}
return sb.toString();
}
public String getTalkgroupID()
{
StringBuilder sb = new StringBuilder();
sb.append( getArea() );
sb.append( "-" );
sb.append( format( getHomeRepeater(), 2 ) );
sb.append( "-" );
sb.append( format( getGroup(), 3 ) );
return sb.toString();
}
public Alias getTalkgroupIDAlias()
{
if( mAliasList != null )
{
return mAliasList.getTalkgroupAlias( getTalkgroupID() );
}
return null;
}
public ArrayList<Integer> getChannelMapLow()
{
ArrayList<Integer> retVal = new ArrayList<Integer>();
if( mMessageType == MessageType.MA_CHNL )
{
for( int x = 27; x >= 18; x-- )
{
if( mMessage.get( x ) )
{
retVal.add( 28 - x );
}
}
}
return retVal;
}
public ArrayList<Integer> getChannelMapHigh()
{
ArrayList<Integer> retVal = new ArrayList<Integer>();
if( mMessageType == MessageType.MA_CHNH )
{
for( int x = 27; x >= 18; x-- )
{
if( mMessage.get( x ) )
{
retVal.add( 38 - x );
}
}
}
return retVal;
}
public String getChannelMapAsString( ArrayList<Integer> channels )
{
StringBuilder sb = new StringBuilder();
for( Integer channel: channels )
{
sb.append( channel );
sb.append( " " );
}
return sb.toString();
}
public int getRadioUniqueID()
{
int retVal = INT_NULL_VALUE;
if( mMessageType == MessageType.ID_UNIQ )
{
retVal = mMessage.getInt( 17, 32 );
}
return retVal;
}
public Alias getRadioUniqueIDAlias()
{
if( mAliasList != null )
{
return mAliasList.getUniqueID( getRadioUniqueID() );
}
return null;
}
public String getSiteID()
{
if( mMessageType == MessageType.ID_SITE )
{
return String.valueOf( mMessage.getInt( 23, 32 ) );
}
return null;
}
public Alias getSiteIDAlias()
{
if( mAliasList != null )
{
return mAliasList.getSiteID( getSiteID() );
}
return null;
}
public String getNeighborID()
{
if( mMessageType == MessageType.ID_NBOR )
{
int id = mMessage.getInt( 23, 32 );
if( id > 0 )
{
return String.valueOf( id );
}
}
return null;
}
private Alias getNeighborIDAlias()
{
if( mAliasList != null )
{
return mAliasList.getSiteID( getNeighborID() );
}
return null;
}
public int getNeighborRank()
{
int retVal = INT_NULL_VALUE;
if( mMessageType == MessageType.ID_NBOR )
{
retVal = mMessage.getInt( 15, 18 ) + 1;
}
return retVal;
}
public long getFrequency()
{
long retVal = 0;
if( mAuxMessage != null )
{
int high;
int low;
MessageType type = getMessageType();
if( type == MessageType.FQ_RXHI || type == MessageType.FQ_TXHI )
{
high = getHighChannelUnits();
low = mAuxMessage.getLowChannelUnits();
}
else
{
high = mAuxMessage.getHighChannelUnits();
low = getLowChannelUnits();
}
if( high != INT_NULL_VALUE && low != INT_NULL_VALUE )
{
retVal = ( high + low ) * 1250 + 150000000;
}
}
return retVal;
}
/**
* Returns the value of the high order (15 - 12) frequency bits which are
* the lower 4 bits of the Free field, left shifted by 12, representing the
* frequency value in units of .00125 MHz
*/
public int getHighChannelUnits()
{
int retVal = INT_NULL_VALUE;
if( mAuxMessage != null &&
( mMessageType == MessageType.FQ_RXHI ||
mMessageType == MessageType.FQ_TXHI ) )
{
retVal = mMessage.getInt( 29, 32 );
retVal = Integer.rotateLeft( retVal, 12 );
}
return retVal;
}
/**
* Returns the value of the low order (11 - 0) frequency bits which are
* contained in the Group and Free fields representing the frequency value
* units of .00125 MHz
*/
public int getLowChannelUnits()
{
int retVal = INT_NULL_VALUE;
if( mMessageType == MessageType.FQ_RXLO ||
mMessageType == MessageType.FQ_TXLO )
{
retVal = mMessage.getInt( 21, 32 );
}
return retVal;
}
public MessageType getType()
{
MessageType retVal = MessageType.UN_KNWN;
int channel = getChannel();
int home = getHomeRepeater();
//LTR-Net messages
if( home != 31 && ( channel > 20 || home > 20 ) )
{
switch( channel )
{
case CHIU_UNIQUE_ID:
retVal = MessageType.ID_UNIQ;
break;
case CHIU_SITE_ID:
retVal = MessageType.ID_SITE;
break;
case CHIU_TRANSMIT_FREQUENCY:
if( getHomeRepeater() == 24 )
{
retVal = MessageType.ID_UNIQ;
}
else
{
if( mMessage.get( CHANNEL_FREQUENCY_MESSAGE_TYPE_BIT ) )
{
retVal = MessageType.FQ_TXHI;
}
else
{
retVal = MessageType.FQ_TXLO;
}
}
break;
case CHIU_RECEIVE_FREQUENCY:
if( mMessage.get( CHANNEL_FREQUENCY_MESSAGE_TYPE_BIT ) )
{
retVal = MessageType.FQ_RXHI;
}
else
{
retVal = MessageType.FQ_RXLO;
}
break;
case CHIU_NEIGHBOR:
retVal = MessageType.ID_NBOR;
break;
case CHIU_MAP:
if( mMessage.get( CHANNEL_MAP_MESSAGE_TYPE_BIT ) )
{
retVal = MessageType.MA_CHNH;
}
else
{
retVal = MessageType.MA_CHNL;
}
break;
case CHIU_CALL_END:
retVal = MessageType.CA_ENDD;
}
}
else
{
int group = getGroup();
if( group == GROUP_CHANNEL_IDLE )
{
retVal = MessageType.SY_IDLE;
}
else
{
retVal = MessageType.CA_STRT;
}
}
return retVal;
}
@Override
public String getFromID()
{
if( mMessageType == MessageType.CA_STRT ||
mMessageType == MessageType.CA_ENDD )
{
return getTalkgroupID();
}
else
{
return null;
}
}
@Override
public Alias getFromIDAlias()
{
if( mMessageType == MessageType.CA_STRT ||
mMessageType == MessageType.CA_ENDD )
{
return getTalkgroupIDAlias();
}
else
{
return null;
}
}
@Override
public Plottable getPlottable()
{
// TODO Auto-generated method stub
return null;
}
/**
* Provides a listing of aliases contained in the message.
*/
public List<Alias> getAliases()
{
List<Alias> aliases = new ArrayList<Alias>();
Alias from = getFromIDAlias();
if( from != null )
{
aliases.add( from );
}
Alias to = getToIDAlias();
if( to != null )
{
aliases.add( to );
}
Alias neighbor = getNeighborIDAlias();
if( neighbor != null )
{
aliases.add( neighbor );
}
Alias uid = getRadioUniqueIDAlias();
if( uid != null )
{
aliases.add( uid );
}
Alias site = getSiteIDAlias();
if( site != null )
{
aliases.add( site );
}
return aliases;
}
}

View File

@@ -0,0 +1,46 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet;
public enum LtrNetMessageType
{
ISW_CALL_END,
ISW_CALL_START,
ISW_REGISTRATION_REQUEST_ESN_HIGH,
ISW_REGISTRATION_REQUEST_ESN_LOW,
ISW_REQUEST_ACCESS,
ISW_UNIQUE_ID,
ISW_UNKNOWN,
OSW_CALL_END,
OSW_CALL_START,
OSW_CHANNEL_MAP_HIGH,
OSW_CHANNEL_MAP_LOW,
OSW_SYSTEM_IDLE,
OSW_NEIGHBOR_ID,
OSW_RECEIVE_FREQUENCY_HIGH,
OSW_RECEIVE_FREQUENCY_LOW,
OSW_REGISTRATION_ACCEPT,
OSW_SITE_ID,
OSW_TRANSMIT_FREQUENCY_HIGH,
OSW_TRANSMIT_FREQUENCY_LOW,
OSW_UNKNOWN
}

View File

@@ -0,0 +1,111 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.channel;
import io.github.dsheirer.channel.IChannelDescriptor;
import io.github.dsheirer.module.decode.p25.message.IFrequencyBand;
import io.github.dsheirer.protocol.Protocol;
public class LtrNetChannel implements IChannelDescriptor, Comparable<LtrNetChannel>
{
private long mDownlink;
private long mUplink;
private int mChannel;
public LtrNetChannel(int channel)
{
mChannel = channel;
}
public int getChannel()
{
return mChannel;
}
public void setDownlink(long downlink)
{
mDownlink = downlink;
}
public void setUplink(long uplink)
{
mUplink = uplink;
}
@Override
public long getDownlinkFrequency()
{
return mDownlink;
}
@Override
public long getUplinkFrequency()
{
return mUplink;
}
@Override
public int[] getFrequencyBandIdentifiers()
{
return new int[0];
}
@Override
public void setFrequencyBand(IFrequencyBand bandIdentifier)
{
//No-op
}
@Override
public boolean isTDMAChannel()
{
return false;
}
@Override
public int getTimeslotCount()
{
return 0;
}
@Override
public Protocol getProtocol()
{
return Protocol.LTR_NET;
}
@Override
public String toString()
{
return String.valueOf(getChannel());
}
public String description()
{
return "TRANSMIT: " + getDownlinkFrequency() + " RECEIVE:" + getUplinkFrequency();
}
@Override
public int compareTo(LtrNetChannel o)
{
return Integer.compare(getChannel(), o.getChannel());
}
}

View File

@@ -0,0 +1,46 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.identifier;
import io.github.dsheirer.identifier.Form;
import io.github.dsheirer.identifier.IdentifierClass;
import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.identifier.integer.IntegerIdentifier;
import io.github.dsheirer.protocol.Protocol;
public class NeighborIdentifier extends IntegerIdentifier
{
public NeighborIdentifier(int site)
{
super(site, IdentifierClass.NETWORK, Form.NEIGHBOR_SITE, Role.BROADCAST);
}
@Override
public Protocol getProtocol()
{
return Protocol.LTR_NET;
}
public static NeighborIdentifier create(int site)
{
return new NeighborIdentifier(site);
}
}

View File

@@ -0,0 +1,46 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.identifier;
import io.github.dsheirer.identifier.Form;
import io.github.dsheirer.identifier.IdentifierClass;
import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.identifier.integer.IntegerIdentifier;
import io.github.dsheirer.protocol.Protocol;
public class SiteIdentifier extends IntegerIdentifier
{
public SiteIdentifier(int site)
{
super(site, IdentifierClass.NETWORK, Form.SITE, Role.BROADCAST);
}
@Override
public Protocol getProtocol()
{
return Protocol.LTR_NET;
}
public static SiteIdentifier create(int site)
{
return new SiteIdentifier(site);
}
}

View File

@@ -0,0 +1,66 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.identifier;
import io.github.dsheirer.identifier.Form;
import io.github.dsheirer.identifier.IdentifierClass;
import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.identifier.integer.IntegerIdentifier;
import io.github.dsheirer.protocol.Protocol;
/**
* Unique ID or radio ID for LTR-Net radios is a 16-bit logical network radio identifier value.
*/
public class UniqueIdentifier extends IntegerIdentifier implements Comparable<UniqueIdentifier>
{
public UniqueIdentifier(int value, Role role)
{
super(value, IdentifierClass.USER, Form.UNIQUE_ID, role);
}
@Override
public Protocol getProtocol()
{
return Protocol.LTR_NET;
}
/**
* Creates a unique identifier for the FROM radio role
*/
public static UniqueIdentifier createFrom(int value)
{
return new UniqueIdentifier(value, Role.FROM);
}
/**
* Creates a unique identifier for the TO radio role
*/
public static UniqueIdentifier createTo(int value)
{
return new UniqueIdentifier(value, Role.TO);
}
@Override
public int compareTo(UniqueIdentifier o)
{
return getValue().compareTo(o.getValue());
}
}

View File

@@ -0,0 +1,116 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.edac.CRC;
import io.github.dsheirer.edac.CRCLTR;
import io.github.dsheirer.identifier.talkgroup.LTRTalkgroup;
import io.github.dsheirer.message.Message;
import io.github.dsheirer.message.MessageDirection;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.protocol.Protocol;
public abstract class LtrNetMessage extends Message
{
protected static final int[] SYNC = {0, 1, 2, 3, 4, 5, 6, 7, 8};
protected static final int[] AREA = {9};
protected static final int[] CHANNEL = {10, 11, 12, 13, 14};
protected static final int[] HOME_REPEATER = {15, 16, 17, 18, 19};
protected static final int[] GROUP = {20, 21, 22, 23, 24, 25, 26, 27};
protected static final int[] FREE = {28, 29, 30, 31, 32};
protected static final int[] CRC_FIELD = {33, 34, 35, 36, 37, 38, 39};
protected static final int[] SIXTEEN_BITS = {17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
protected CorrectedBinaryMessage mMessage;
protected CRC mCRC;
private LTRTalkgroup mTalkgroup;
public LtrNetMessage(CorrectedBinaryMessage message, MessageDirection direction, long timestamp)
{
super(timestamp);
mMessage = message;
mCRC = CRCLTR.check(message, direction);
}
/**
* Underlying binary message
*/
protected CorrectedBinaryMessage getMessage()
{
return mMessage;
}
public abstract LtrNetMessageType getLtrNetMessageType();
@Override
public Protocol getProtocol()
{
return Protocol.LTR_NET;
}
/**
* Talkgroup identifier
*/
public LTRTalkgroup getTalkgroup()
{
if(mTalkgroup == null)
{
mTalkgroup = LTRTalkgroup.create((getHomeRepeater(getMessage()) << 8) + getGroup(getMessage()));
}
return mTalkgroup;
}
public boolean isValid()
{
return mCRC.passes();
}
public CRC getCRC()
{
return mCRC;
}
public static int getArea(CorrectedBinaryMessage message)
{
return message.getInt(AREA);
}
public static int getChannel(CorrectedBinaryMessage message)
{
return message.getInt(CHANNEL);
}
public static int getHomeRepeater(CorrectedBinaryMessage message)
{
return message.getInt(HOME_REPEATER);
}
public static int getGroup(CorrectedBinaryMessage message)
{
return message.getInt(GROUP);
}
public static int getFree(CorrectedBinaryMessage message)
{
return message.getInt(FREE);
}
}

View File

@@ -0,0 +1,119 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.message.MessageDirection;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.module.decode.ltrnet.message.isw.IswCallEnd;
import io.github.dsheirer.module.decode.ltrnet.message.isw.IswCallStart;
import io.github.dsheirer.module.decode.ltrnet.message.isw.IswUniqueId;
import io.github.dsheirer.module.decode.ltrnet.message.isw.IswUnknown;
import io.github.dsheirer.module.decode.ltrnet.message.isw.LtrNetIswMessage;
import io.github.dsheirer.module.decode.ltrnet.message.isw.RegistrationRequestEsnHigh;
import io.github.dsheirer.module.decode.ltrnet.message.isw.RegistrationRequestEsnLow;
import io.github.dsheirer.module.decode.ltrnet.message.isw.RequestAccess;
import io.github.dsheirer.module.decode.ltrnet.message.osw.ChannelMapHigh;
import io.github.dsheirer.module.decode.ltrnet.message.osw.ChannelMapLow;
import io.github.dsheirer.module.decode.ltrnet.message.osw.LtrNetOswMessage;
import io.github.dsheirer.module.decode.ltrnet.message.osw.NeighborId;
import io.github.dsheirer.module.decode.ltrnet.message.osw.OswCallEnd;
import io.github.dsheirer.module.decode.ltrnet.message.osw.OswCallStart;
import io.github.dsheirer.module.decode.ltrnet.message.osw.OswUnknown;
import io.github.dsheirer.module.decode.ltrnet.message.osw.ReceiveFrequencyHigh;
import io.github.dsheirer.module.decode.ltrnet.message.osw.ReceiveFrequencyLow;
import io.github.dsheirer.module.decode.ltrnet.message.osw.RegistrationAccept;
import io.github.dsheirer.module.decode.ltrnet.message.osw.SiteId;
import io.github.dsheirer.module.decode.ltrnet.message.osw.SystemIdle;
import io.github.dsheirer.module.decode.ltrnet.message.osw.TransmitFrequencyHigh;
import io.github.dsheirer.module.decode.ltrnet.message.osw.TransmitFrequencyLow;
/**
* Message factory for creating LTR-Net messages
*/
public class LtrNetMessageFactory
{
public static LtrNetMessage create(MessageDirection messageDirection, CorrectedBinaryMessage message, long timestamp)
{
switch(messageDirection)
{
case ISW:
//Flip all of the message bits since ISW messages are inverted
message.flip(0, 40);
LtrNetMessageType iswType = LtrNetIswMessage.getMessageType(message);
switch(iswType)
{
case ISW_CALL_END:
return new IswCallEnd(message, timestamp);
case ISW_CALL_START:
return new IswCallStart(message, timestamp);
case ISW_REGISTRATION_REQUEST_ESN_HIGH:
return new RegistrationRequestEsnHigh(message, timestamp);
case ISW_REGISTRATION_REQUEST_ESN_LOW:
return new RegistrationRequestEsnLow(message, timestamp);
case ISW_REQUEST_ACCESS:
return new RequestAccess(message, timestamp);
case ISW_UNIQUE_ID:
return new IswUniqueId(message, timestamp);
case ISW_UNKNOWN:
default:
return new IswUnknown(message, timestamp);
}
case OSW:
LtrNetMessageType oswType = LtrNetOswMessage.getMessageType(message);
switch(oswType)
{
case OSW_CALL_END:
return new OswCallEnd(message, timestamp);
case OSW_CALL_START:
return new OswCallStart(message, timestamp);
case OSW_CHANNEL_MAP_HIGH:
return new ChannelMapHigh(message, timestamp);
case OSW_CHANNEL_MAP_LOW:
return new ChannelMapLow(message, timestamp);
case OSW_SYSTEM_IDLE:
return new SystemIdle(message, timestamp);
case OSW_NEIGHBOR_ID:
return new NeighborId(message, timestamp);
case OSW_RECEIVE_FREQUENCY_HIGH:
return new ReceiveFrequencyHigh(message, timestamp);
case OSW_RECEIVE_FREQUENCY_LOW:
return new ReceiveFrequencyLow(message, timestamp);
case OSW_REGISTRATION_ACCEPT:
return new RegistrationAccept(message, timestamp);
case OSW_SITE_ID:
return new SiteId(message, timestamp);
case OSW_TRANSMIT_FREQUENCY_HIGH:
return new TransmitFrequencyHigh(message, timestamp);
case OSW_TRANSMIT_FREQUENCY_LOW:
return new TransmitFrequencyLow(message, timestamp);
case OSW_UNKNOWN:
default:
return new OswUnknown(message, timestamp);
}
}
return null;
}
}

View File

@@ -0,0 +1,80 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.isw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.ArrayList;
import java.util.List;
/**
* Call End Message.
*/
public class IswCallEnd extends LtrNetIswMessage
{
private List<Identifier> mIdentifiers;
/**
* Constructs a message
*/
public IswCallEnd(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.ISW_CALL_END;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("CALL END TALKGROUP:").append(getTalkgroup().formatted());
sb.append(" AREA:").append(getArea(getMessage()));
sb.append(" LCN:").append(getChannel(getMessage()));
sb.append(" FREE:").append(getFree(getMessage()));
return sb.toString();
}
/**
* LCN for the call
*/
public int getChannel()
{
return getChannel(getMessage());
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getTalkgroup());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,80 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.isw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.ArrayList;
import java.util.List;
/**
* Call Start Message.
*/
public class IswCallStart extends LtrNetIswMessage
{
private List<Identifier> mIdentifiers;
/**
* Constructs a message
*/
public IswCallStart(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.ISW_CALL_START;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("CALL START TALKGROUP:").append(getTalkgroup().formatted());
sb.append(" AREA:").append(getArea(getMessage()));
sb.append(" LCN:").append(getChannel(getMessage()));
sb.append(" FREE:").append(getFree(getMessage()));
return sb.toString();
}
/**
* LCN for the call
*/
public int getChannel()
{
return getChannel(getMessage());
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getTalkgroup());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,83 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.isw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.module.decode.ltrnet.identifier.UniqueIdentifier;
import java.util.ArrayList;
import java.util.List;
/**
* ESN Low Message. ESN is transmitted over two messages with the ESNHigh message containing the high-order 16 bits
* and the ESNLow message containing the low-order 16 bits.
*/
public class IswUniqueId extends LtrNetIswMessage
{
private UniqueIdentifier mUniqueIdentifier;
private List<Identifier> mIdentifiers;
/**
* Constructs an ESN-High message
*/
public IswUniqueId(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.ISW_UNIQUE_ID;
}
public UniqueIdentifier getUniqueID()
{
if(mUniqueIdentifier == null)
{
mUniqueIdentifier = UniqueIdentifier.createFrom(getMessage().getInt(SIXTEEN_BITS));
}
return mUniqueIdentifier;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("RADIO UNIQUE ID: ").append(getUniqueID());
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getUniqueID());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,65 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.isw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.Collections;
import java.util.List;
/**
* ISW Unknown Message.
*/
public class IswUnknown extends LtrNetIswMessage
{
/**
* Constructs a message
*/
public IswUnknown(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.ISW_UNKNOWN;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("ISW UNKNOWN MESSAGE - AREA:").append(getArea(getMessage()));
sb.append(" LCN:").append(getChannel(getMessage()));
sb.append(" HOME:").append(getHomeRepeater(getMessage()));
sb.append(" GROUP").append(getGroup(getMessage()));
sb.append(" FREE:").append(getFree(getMessage()));
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
return Collections.EMPTY_LIST;
}
}

View File

@@ -0,0 +1,93 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.isw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.edac.CRC;
import io.github.dsheirer.edac.CRCLTR;
import io.github.dsheirer.message.MessageDirection;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.module.decode.ltrnet.message.LtrNetMessage;
public abstract class LtrNetIswMessage extends LtrNetMessage
{
/**
* LTR-Net Inbound (mobile - to tower) Message
*/
public LtrNetIswMessage(CorrectedBinaryMessage message, long timestamp)
{
super(message, MessageDirection.ISW, timestamp);
/**
* If the CRC fails, test for a transmitted CRC of 127 and then check
* the Free field for special messages
*/
if(mCRC == CRC.FAILED_CRC && CRCLTR.getTransmittedChecksum(mMessage) == 127)
{
int free = getFree(getMessage());
if(free == 31 || free == 23)
{
mCRC = CRC.PASSED;
}
}
}
/**
* Determines the ISW message type
*/
public static LtrNetMessageType getMessageType(CorrectedBinaryMessage message)
{
int channel = getChannel(message);
if(channel == 31)
{
return LtrNetMessageType.ISW_CALL_END;
}
else if(channel > 20)
{
switch(channel)
{
case 24:
return LtrNetMessageType.ISW_UNIQUE_ID;
case 27:
return LtrNetMessageType.ISW_REGISTRATION_REQUEST_ESN_LOW;
case 29:
return LtrNetMessageType.ISW_REGISTRATION_REQUEST_ESN_HIGH;
}
}
else if(channel > 0)
{
int free = getFree(message);
switch(free)
{
case 21:
return LtrNetMessageType.ISW_CALL_START;
case 23:
return LtrNetMessageType.ISW_CALL_END;
case 31:
return LtrNetMessageType.ISW_REQUEST_ACCESS;
}
}
return LtrNetMessageType.ISW_UNKNOWN;
}
}

View File

@@ -0,0 +1,113 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.isw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.identifier.esn.ESNIdentifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.protocol.Protocol;
import java.util.ArrayList;
import java.util.List;
/**
* ESN High Message. ESN is transmitted over two messages with the ESNHigh message containing the high-order 16 bits
* and the ESNLow message containing the low-order 16 bits.
*/
public class RegistrationRequestEsnHigh extends LtrNetIswMessage
{
private RegistrationRequestEsnLow mRegistrationRequestEsnLow;
private ESNIdentifier mESNIdentifier;
private List<Identifier> mIdentifiers;
/**
* Constructs an ESN-High message
*/
public RegistrationRequestEsnHigh(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.ISW_REGISTRATION_REQUEST_ESN_HIGH;
}
/**
* Sets the corresponding ESN low message that can be used to create the full ESN value
*/
public void setEsnLowMessage(RegistrationRequestEsnLow message)
{
if(message != null)
{
mRegistrationRequestEsnLow = message;
}
}
public boolean isCompleteEsn()
{
return mRegistrationRequestEsnLow != null;
}
/**
* ESN Identifier with at least the high-order 16-bits specified and optionally includes the low-order 16 bits.
*/
public ESNIdentifier getESN()
{
if(mESNIdentifier == null)
{
mESNIdentifier = ESNIdentifier.create(getESNHigh() +
(mRegistrationRequestEsnLow != null ? mRegistrationRequestEsnLow.getESNLow() : "xxxx"),
Protocol.LTR_NET, Role.FROM);
}
return mESNIdentifier;
}
public String getESNHigh()
{
int esnHigh = getMessage().getInt(SIXTEEN_BITS);
return String.format("%04X", esnHigh & 0xFFFF);
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("ESN HIGH: ").append(getESN());
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getESN());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,112 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.isw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.identifier.esn.ESNIdentifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.protocol.Protocol;
import java.util.ArrayList;
import java.util.List;
/**
* ESN Low Message. ESN is transmitted over two messages with the ESNHigh message containing the high-order 16 bits
* and the ESNLow message containing the low-order 16 bits.
*/
public class RegistrationRequestEsnLow extends LtrNetIswMessage
{
private RegistrationRequestEsnHigh mRegistrationRequestEsnHigh;
private ESNIdentifier mESNIdentifier;
private List<Identifier> mIdentifiers;
/**
* Constructs an ESN-High message
*/
public RegistrationRequestEsnLow(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.ISW_REGISTRATION_REQUEST_ESN_LOW;
}
/**
* Sets the corresponding ESN high message that can be used to create the full ESN value
*/
public void setESNHighMessage(RegistrationRequestEsnHigh message)
{
if(message != null)
{
mRegistrationRequestEsnHigh = message;
}
}
public boolean isCompleteEsn()
{
return mRegistrationRequestEsnHigh != null;
}
/**
* ESN Identifier with at least the high-order 16-bits specified and optionally includes the low-order 16 bits.
*/
public ESNIdentifier getESN()
{
if(mESNIdentifier == null)
{
mESNIdentifier = ESNIdentifier.create((mRegistrationRequestEsnHigh != null ? mRegistrationRequestEsnHigh.getESNHigh() : "xxxx") + getESNLow(),
Protocol.LTR_NET, Role.FROM);
}
return mESNIdentifier;
}
public String getESNLow()
{
int esnLow = getMessage().getInt(SIXTEEN_BITS);
return String.format("%04X", esnLow & 0xFFFF);
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("ESN LOW: ").append(getESN());
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getESN());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,72 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.isw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.ArrayList;
import java.util.List;
/**
* Request access Message.
*/
public class RequestAccess extends LtrNetIswMessage
{
private List<Identifier> mIdentifiers;
/**
* Constructs a message
*/
public RequestAccess(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.ISW_REQUEST_ACCESS;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("REQUEST ACCESS TALKGROUP:").append(getTalkgroup());
sb.append(" AREA:").append(getArea(getMessage()));
sb.append(" LCN:").append(getChannel(getMessage()));
sb.append(" FREE:").append(getFree(getMessage()));
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getTalkgroup());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,77 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Channel Map - High Channels (11 - 20).
*/
public class ChannelMapHigh extends LtrNetOswMessage
{
/**
* Constructs a message
*/
public ChannelMapHigh(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_CHANNEL_MAP_HIGH;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("CHANNEL MAP HIGH ").append(getChannels());
return sb.toString();
}
public List<Integer> getChannels()
{
List<Integer> retVal = new ArrayList<>();
for(int x = 27; x >= 18; x--)
{
if(getMessage().get(x))
{
retVal.add(38 - x);
}
}
return retVal;
}
@Override
public List<Identifier> getIdentifiers()
{
return Collections.EMPTY_LIST;
}
}

View File

@@ -0,0 +1,77 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Channel Map - Low Channels (1 - 10).
*/
public class ChannelMapLow extends LtrNetOswMessage
{
/**
* Constructs a message
*/
public ChannelMapLow(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_CHANNEL_MAP_LOW;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("CHANNEL MAP LOW ").append(getChannels());
return sb.toString();
}
public List<Integer> getChannels()
{
List<Integer> retVal = new ArrayList<>();
for(int x = 27; x >= 18; x--)
{
if(getMessage().get(x))
{
retVal.add(28 - x);
}
}
return retVal;
}
@Override
public List<Identifier> getIdentifiers()
{
return Collections.EMPTY_LIST;
}
}

View File

@@ -0,0 +1,63 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
/**
* Base frequency message
*/
public abstract class Frequency extends LtrNetOswMessage
{
/**
* Constructs a message
*/
public Frequency(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
protected abstract FrequencyHigh getFrequencyHigh();
protected abstract FrequencyLow getFrequencyLow();
protected abstract boolean hasFrequencyHigh();
protected abstract boolean hasFrequencyLow();
/**
* Channel number for the frequency
*/
public int getChannel()
{
return getHomeRepeater(getMessage());
}
/**
* Frequency for the channel when both the high and low frequency messages are available
*/
public long getFrequency()
{
if(hasFrequencyHigh() && hasFrequencyLow())
{
return 150000000 + ((getFrequencyHigh().getHighChannelUnits() + getFrequencyLow().getLowChannelUnits()) * 1250);
}
return 0;
}
}

View File

@@ -0,0 +1,80 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
/**
* Base frequency message
*/
public abstract class FrequencyHigh extends Frequency
{
private FrequencyLow mFrequencyLow;
/**
* Constructs a message
*/
public FrequencyHigh(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
/**
* Sets the corresponding low frequency message so that the correct frequency can be calculated
*/
public void setFrequencyLow(FrequencyLow frequencyLow)
{
mFrequencyLow = frequencyLow;
}
/**
* Returns the value of the high order (15 - 12) frequency bits which are
* the lower 4 bits of the Free field, left shifted by 12, representing the
* frequency value in units of .00125 MHz
*/
public int getHighChannelUnits()
{
return Integer.rotateLeft(getMessage().getInt(29, 32), 12);
}
@Override
protected FrequencyHigh getFrequencyHigh()
{
return this;
}
@Override
protected FrequencyLow getFrequencyLow()
{
return mFrequencyLow;
}
@Override
protected boolean hasFrequencyHigh()
{
return true;
}
@Override
protected boolean hasFrequencyLow()
{
return mFrequencyLow != null;
}
}

View File

@@ -0,0 +1,77 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
/**
* Base frequency message
*/
public abstract class FrequencyLow extends Frequency
{
private FrequencyHigh mFrequencyHigh;
/**
* Constructs a message
*/
public FrequencyLow(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
public void setFrequencyHigh(FrequencyHigh frequencyHigh)
{
mFrequencyHigh = frequencyHigh;
}
/**
* Returns the value of the low order (11 - 0) frequency bits which are
* contained in the Group and Free fields representing the frequency value
* units of .00125 MHz
*/
public int getLowChannelUnits()
{
return getMessage().getInt(21, 32);
}
@Override
protected FrequencyHigh getFrequencyHigh()
{
return mFrequencyHigh;
}
@Override
protected FrequencyLow getFrequencyLow()
{
return this;
}
@Override
protected boolean hasFrequencyHigh()
{
return mFrequencyHigh != null;
}
@Override
protected boolean hasFrequencyLow()
{
return true;
}
}

View File

@@ -0,0 +1,109 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.message.MessageDirection;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.module.decode.ltrnet.message.LtrNetMessage;
public abstract class LtrNetOswMessage extends LtrNetMessage
{
private static final int CHANNEL_FREQUENCY_MESSAGE_TYPE_BIT = 20;
private static final int CHANNEL_MAP_MESSAGE_TYPE_BIT = 17;
private static final int HOME_DIRECTED_GROUP_CALL = 29;
private static final int HOME_CHANNEL_IN_USE_MUTE_AUDIO = 30;
private static final int GROUP_DO_NOTHING = 253;
private static final int GROUP_CWID = 254;
private static final int GROUP_CHANNEL_IDLE = 255;
private static final int FREE_ALL_CHANNELS_BUSY = 0;
private static final int FREE_LTR_GROUP_CALL = 30;
private static final int FREE_LTRNET_GROUP_CALL = 31;
public LtrNetOswMessage(CorrectedBinaryMessage message, long timestamp)
{
super(message, MessageDirection.OSW, timestamp);
}
public static LtrNetMessageType getMessageType(CorrectedBinaryMessage message)
{
int channel = getChannel(message);
int home = getHomeRepeater(message);
//LTR-Net messages
if(home != 31 && (channel > 20 || home > 20))
{
switch(channel)
{
case 17:
return LtrNetMessageType.OSW_REGISTRATION_ACCEPT;
case 18:
return LtrNetMessageType.OSW_SITE_ID;
case 24:
if(message.get(CHANNEL_FREQUENCY_MESSAGE_TYPE_BIT))
{
return LtrNetMessageType.OSW_TRANSMIT_FREQUENCY_HIGH;
}
else
{
return LtrNetMessageType.OSW_TRANSMIT_FREQUENCY_LOW;
}
case 25:
if(message.get(CHANNEL_FREQUENCY_MESSAGE_TYPE_BIT))
{
return LtrNetMessageType.OSW_RECEIVE_FREQUENCY_HIGH;
}
else
{
return LtrNetMessageType.OSW_RECEIVE_FREQUENCY_LOW;
}
case 26:
return LtrNetMessageType.OSW_NEIGHBOR_ID;
case 28:
if(message.get(CHANNEL_MAP_MESSAGE_TYPE_BIT))
{
return LtrNetMessageType.OSW_CHANNEL_MAP_HIGH;
}
else
{
return LtrNetMessageType.OSW_CHANNEL_MAP_LOW;
}
case 31:
return LtrNetMessageType.OSW_CALL_END;
}
}
else
{
int group = getGroup(message);
if(group == GROUP_CHANNEL_IDLE)
{
return LtrNetMessageType.OSW_SYSTEM_IDLE;
}
else
{
return LtrNetMessageType.OSW_CALL_START;
}
}
return LtrNetMessageType.OSW_UNKNOWN;
}
}

View File

@@ -0,0 +1,87 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.module.decode.ltrnet.identifier.NeighborIdentifier;
import java.util.ArrayList;
import java.util.List;
/**
* Neighbor Identifier.
*/
public class NeighborId extends LtrNetOswMessage
{
private NeighborIdentifier mNeighborIdentifier;
private List<Identifier> mIdentifiers;
/**
* Constructs a message
*/
public NeighborId(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_NEIGHBOR_ID;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("NEIGHBOR:").append(getNeighborID());
sb.append(" RANK:").append(getNeighborRank());
return sb.toString();
}
public NeighborIdentifier getNeighborID()
{
if(mNeighborIdentifier == null)
{
mNeighborIdentifier = NeighborIdentifier.create(getMessage().getInt(23, 32));
}
return mNeighborIdentifier;
}
public int getNeighborRank()
{
return getMessage().getInt(15, 18) + 1;
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getNeighborID());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,80 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.ArrayList;
import java.util.List;
/**
* Call End Message.
*/
public class OswCallEnd extends LtrNetOswMessage
{
private List<Identifier> mIdentifiers;
/**
* Constructs a message
*/
public OswCallEnd(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_CALL_END;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("CALL END TALKGROUP:").append(getTalkgroup().formatted());
sb.append(" AREA:").append(getArea(getMessage()));
sb.append(" LCN:").append(getChannel(getMessage()));
sb.append(" FREE:").append(getFree(getMessage()));
return sb.toString();
}
/**
* LCN for the call
*/
public int getChannel()
{
return getChannel(getMessage());
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getTalkgroup());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,80 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.ArrayList;
import java.util.List;
/**
* Call Start Message.
*/
public class OswCallStart extends LtrNetOswMessage
{
private List<Identifier> mIdentifiers;
/**
* Constructs a message
*/
public OswCallStart(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_CALL_START;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("CALL START TALKGROUP:").append(getTalkgroup().formatted());
sb.append(" AREA:").append(getArea(getMessage()));
sb.append(" LCN:").append(getChannel(getMessage()));
sb.append(" FREE:").append(getFree(getMessage()));
return sb.toString();
}
/**
* LCN for the call
*/
public int getChannel()
{
return getChannel(getMessage());
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getTalkgroup());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,65 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.Collections;
import java.util.List;
/**
* OSW Unknown Message.
*/
public class OswUnknown extends LtrNetOswMessage
{
/**
* Constructs a message
*/
public OswUnknown(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_UNKNOWN;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("OSW UNKNOWN MESSAGE - AREA:").append(getArea(getMessage()));
sb.append(" LCN:").append(getChannel(getMessage()));
sb.append(" HOME:").append(getHomeRepeater(getMessage()));
sb.append(" GROUP").append(getGroup(getMessage()));
sb.append(" FREE:").append(getFree(getMessage()));
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
return Collections.EMPTY_LIST;
}
}

View File

@@ -0,0 +1,63 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.Collections;
import java.util.List;
public class ReceiveFrequencyHigh extends FrequencyHigh
{
/**
* Constructs a message
*
* @param message
* @param timestamp
*/
public ReceiveFrequencyHigh(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_RECEIVE_FREQUENCY_HIGH;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("LCN:").append(getChannel());
sb.append(" RECEIVE FREQUENCY:").append(getFrequency()).append(" - HIGH");
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
return Collections.EMPTY_LIST;
}
}

View File

@@ -0,0 +1,60 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.Collections;
import java.util.List;
public class ReceiveFrequencyLow extends FrequencyLow
{
/**
* Constructs a message
*/
public ReceiveFrequencyLow(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_RECEIVE_FREQUENCY_LOW;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("LCN:").append(getChannel());
sb.append(" RECEIVE FREQUENCY:").append(getFrequency()).append(" - LOW");
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
return Collections.emptyList();
}
}

View File

@@ -0,0 +1,82 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.module.decode.ltrnet.identifier.UniqueIdentifier;
import java.util.ArrayList;
import java.util.List;
/**
* Registration and assignment of Unique ID to a radio.
*/
public class RegistrationAccept extends LtrNetOswMessage
{
private UniqueIdentifier mUniqueIdentifier;
private List<Identifier> mIdentifiers;
/**
* Constructs an ESN-High message
*/
public RegistrationAccept(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_REGISTRATION_ACCEPT;
}
public UniqueIdentifier getUniqueID()
{
if(mUniqueIdentifier == null)
{
mUniqueIdentifier = UniqueIdentifier.createTo(getMessage().getInt(SIXTEEN_BITS));
}
return mUniqueIdentifier;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("REGISTRATION ACCEPT - RADIO UNIQUE ID: ").append(getUniqueID());
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getUniqueID());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,82 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import io.github.dsheirer.module.decode.ltrnet.identifier.SiteIdentifier;
import java.util.ArrayList;
import java.util.List;
/**
* Site Identifier.
*/
public class SiteId extends LtrNetOswMessage
{
private SiteIdentifier mSiteIdentifier;
private List<Identifier> mIdentifiers;
/**
* Constructs a message
*/
public SiteId(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_SITE_ID;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("SITE:").append(getSiteID());
return sb.toString();
}
public SiteIdentifier getSiteID()
{
if(mSiteIdentifier == null)
{
mSiteIdentifier = SiteIdentifier.create(getMessage().getInt(23, 32));
}
return mSiteIdentifier;
}
@Override
public List<Identifier> getIdentifiers()
{
if(mIdentifiers == null)
{
mIdentifiers = new ArrayList<>();
mIdentifiers.add(getSiteID());
}
return mIdentifiers;
}
}

View File

@@ -0,0 +1,65 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.Collections;
import java.util.List;
public class SystemIdle extends LtrNetOswMessage
{
public SystemIdle(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_SYSTEM_IDLE;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("IDLE - AREA:").append(getArea(getMessage()));
sb.append(" LCN:").append(getChannel(getMessage()));
sb.append(" HOME:").append(getHomeRepeater(getMessage()));
sb.append(" GROUP:").append(getGroup(getMessage()));
sb.append(" FREE:").append(getFree(getMessage()));
return sb.toString();
}
public int getChannel()
{
return getChannel(getMessage());
}
@Override
public List<Identifier> getIdentifiers()
{
return Collections.EMPTY_LIST;
}
}

View File

@@ -0,0 +1,60 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.Collections;
import java.util.List;
public class TransmitFrequencyHigh extends FrequencyHigh
{
/**
* Constructs a message
*/
public TransmitFrequencyHigh(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_TRANSMIT_FREQUENCY_HIGH;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("LCN:").append(getChannel());
sb.append(" TRANSMIT FREQUENCY:").append(getFrequency()).append(" - HIGH");
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
return Collections.EMPTY_LIST;
}
}

View File

@@ -0,0 +1,60 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.module.decode.ltrnet.message.osw;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.module.decode.ltrnet.LtrNetMessageType;
import java.util.Collections;
import java.util.List;
public class TransmitFrequencyLow extends FrequencyLow
{
/**
* Constructs a message
*/
public TransmitFrequencyLow(CorrectedBinaryMessage message, long timestamp)
{
super(message, timestamp);
}
@Override
public LtrNetMessageType getLtrNetMessageType()
{
return LtrNetMessageType.OSW_TRANSMIT_FREQUENCY_LOW;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("LCN:").append(getChannel());
sb.append(" TRANSMIT FREQUENCY:").append(getFrequency()).append(" - LOW");
return sb.toString();
}
@Override
public List<Identifier> getIdentifiers()
{
return Collections.EMPTY_LIST;
}
}