Package jmri

Class NmraPacket

java.lang.Object
jmri.NmraPacket

public class NmraPacket
extends Object
Utilities for coding/decoding NMRA S&RP DCC packets.

Packets are (now) represented by an array of bytes. Preamble/postamble not included. Note that this is a data representation, _not_ a representation of the waveform! But this is a class, which might eventually also form a representation object.

This is meant to be a general Java NMRA implementation, so does NOT use JMRI utilities. In particular, it returns null instead of throwing JmriException for invalid requests. Callers need to check upstream.

The function is provided by static member functions; objects of this class should not be created.

Note that these functions are structured by packet type, not by what want to do. E.g. there are functions to create specific packet formats instead of a general "loco speed packet" routine which figures out which type of packet to use. Those decisions are to be made somewhere else.

Range and value checking is intended to be aggressive; if we can check, we should. Problems are reported as warnings.

The basic function is to build a packet with proper addressing, etc:

  • oneBytePacket
  • twoBytePacket
  • threeBytePacket
  • fourBytePacket
On top of those are built various special-purpose packet formats.
This file is part of JMRI.

JMRI is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. See the "COPYING" file for a copy of this license.

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

  • Nested Class Summary

    Nested Classes 
    Modifier and Type Class Description
    static class  NmraPacket.DccAddressType  
  • Field Summary

    Fields 
    Modifier and Type Field Description
    static int accIdAltHighLimit  
    static int accIdHighLimit  
    static int accIdLowLimit  
  • Method Summary

    Modifier and Type Method Description
    static byte[] accDecoderPkt​(int number, boolean closed)
    Provide an accessory control packet via a simplified interface
    static byte[] accDecoderPkt​(int addr, int active, int outputChannel)  
    static byte[] accDecoderPktOpsMode​(int accAddr, int cvNum, int data)
    Provide a basic operations mode accessory CV programming packet via a simplified interface, given an accessory address.
    static byte[] accDecoderPktOpsMode​(int addr, int active, int outputChannel, int cvNum, int data)
    Provide a basic operations mode accessory CV programming packet.
    static byte[] accDecoderPktOpsModeLegacy​(int accAddr, int cvNum, int data)
    Provide a legacy operations mode accessory CV programming packet via a simplified interface, given an accessory address.
    static byte[] accDecPktOpsMode​(int decAddr, int cvNum, int data)
    Provide a basic operations mode accessory CV programming packet via a simplified interface, given a decoder address.
    static byte[] accDecPktOpsModeLegacy​(int decAddr, int cvNum, int data)
    Provide a legacy operations mode accessory CV programming packet via a simplified interface, given a decoder address.
    static byte[] accSignalDecoderPkt​(int outputAddr, int aspect)
    Create a signal accessory instruction packet.
    protected static byte[] accSignalDecoderPktCommon​(int lowAddr, int boardAddr, int aspect)  
    static byte[] accSignalDecoderPktOpsMode​(int addr, int cvNum, int data)
    Provide an extended operations mode accessory CV programming packet via a simplified interface, given a signal address.
    static boolean addressCheck​(int address, boolean longAddr)
    Check if an address is (possibly) valid, e.g. fits within the NMRA space definition
    static byte[] altAccSignalDecoderPkt​(int outputAddr, int aspect)
    An alternative interpretation of RP-9.2.1 due to an omission in the address definition of extended accessory packets.
    static byte[] altAccSignalDecoderPktOpsMode​(int addr, int cvNum, int data)
    Provide an extended operations mode accessory CV programming packet via a simplified interface, given a signal address, using the alternative interpretation of S-9.2.1, due to an omission in the address definition of extended accessory packets.
    static byte[] analogControl​(int address, boolean longAddr, int function, int value)
    Provide an NMRA analog control instruction.
    static byte[] consistControl​(int address, boolean longAddr, int consist, boolean directionNormal)
    Provide an NMRA consist control instruction
    static int extractAddressNumber​(byte[] packet)
    Extract the numerical address from an NMRA packet.
    static NmraPacket.DccAddressType extractAddressType​(byte[] packet)
    Extract the address type from an NMRA packet.
    static int extractInstruction​(byte[] packet)
    Extract the instruction from an NMRA packet.
    static String format​(byte[] p)
    Convert NMRA packet to a readable form as hexadecimal characters.
    static byte[] fourBytePacket​(int address, boolean longAddr, byte byte1, byte byte2, byte byte3, byte byte4)
    Create a packet containing a four-byte instruction.
    static byte[] function0Through4Packet​(int address, boolean longAddr, boolean f0, boolean f1, boolean f2, boolean f3, boolean f4)  
    static byte[] function13Through20Packet​(int address, boolean longAddr, boolean f13, boolean f14, boolean f15, boolean f16, boolean f17, boolean f18, boolean f19, boolean f20)  
    static byte[] function21Through28Packet​(int address, boolean longAddr, boolean f21, boolean f22, boolean f23, boolean f24, boolean f25, boolean f26, boolean f27, boolean f28)  
    static byte[] function29Through36Packet​(int address, boolean longAddr, boolean f29, boolean f30, boolean f31, boolean f32, boolean f33, boolean f34, boolean f35, boolean f36)  
    static byte[] function37Through44Packet​(int address, boolean longAddr, boolean f37, boolean f38, boolean f39, boolean f40, boolean f41, boolean f42, boolean f43, boolean f44)  
    static byte[] function45Through52Packet​(int address, boolean longAddr, boolean f45, boolean f46, boolean f47, boolean f48, boolean f49, boolean f50, boolean f51, boolean f52)  
    static byte[] function53Through60Packet​(int address, boolean longAddr, boolean f53, boolean f54, boolean f55, boolean f56, boolean f57, boolean f58, boolean f59, boolean f60)  
    static byte[] function5Through8Packet​(int address, boolean longAddr, boolean f5, boolean f6, boolean f7, boolean f8)  
    static byte[] function61Through68Packet​(int address, boolean longAddr, boolean f61, boolean f62, boolean f63, boolean f64, boolean f65, boolean f66, boolean f67, boolean f68)  
    static byte[] function9Through12Packet​(int address, boolean longAddr, boolean f9, boolean f10, boolean f11, boolean f12)  
    static int getAccDecoderPktAddress​(byte[] packet)
    Recover the 1-based output address from an Accessory Decoder Control Packet, typically considered a turnout control packet
    static int getAccDecoderPktOpsModeAddress​(byte[] packet)
    Recover the accessory address from a Basic Accessory Decoder Packet Ops Mode Packet.
    static int getAccDecoderPktOpsModeLegacyAddress​(byte[] packet)
    Recover the equivalent accessory address from a Legacy Accessory Decoder Packet Ops Mode Packet.
    static int getAccDecPktOpsModeAddress​(byte[] packet)
    Recover the equivalent decoder address from a Basic Accessory Decoder Packet Ops Mode Packet.
    static int getAccDecPktOpsModeLegacyAddress​(byte[] packet)
    Recover the decoder address from a Legacy Accessory Decoder Packet Ops Mode Packet.
    static int getAccSignalDecoderPktAddress​(byte[] packet)
    Recover the 1-based output address from an Extended Accessory Decoder Control Packet otherwise known as a Signal Decoder Packet.
    static byte[] idlePacket()
    Create a packet containing a decoder idle instruction.
    static boolean isAccDecoderPktOpsMode​(byte[] packet)
    Determine if a packet is a Basic Accessory Decoder Packet address for operations mode programming.
    static boolean isAccDecoderPktOpsModeLegacy​(byte[] packet)
    Determine if a packet is a Legacy Accessory Decoder Packet address for operations mode programming.
    static boolean isAccSignalDecoderPkt​(byte[] packet)
    Determine if a packet is an Extended Accessory Decoder Control Packet otherwise known as a Signal Decoder Packet.
    static byte[] oneBytePacket​(int address, boolean longAddr, byte byte1)
    Create a packet containing a one-byte instruction.
    static byte[] opsCvWriteByte​(int address, boolean longAddr, int cvNum, int data)  
    static byte[] speedStep128Packet​(int address, boolean longAddr, int speed, boolean fwd)  
    static byte[] speedStep14Packet​(int address, boolean longAddr, int speed, boolean fwd, boolean F0)  
    static byte[] speedStep28Packet​(boolean full, int address, boolean longAddr, int speed, boolean fwd)
    New version of speedStep28Packet to allow access to the whole range of 28 step speed packets.
    static byte[] speedStep28Packet​(int address, boolean longAddr, int speed, boolean fwd)
    From NMRA RP 9.2.1 [A Crosland 05/02/12] There is an issue with this method in that it cannot create a 28 step speed packet for maximum speed.
    static byte[] threeBytePacket​(int address, boolean longAddr, byte byte1, byte byte2, byte byte3)
    Create a packet containing a three-byte instruction.
    static String toString​(byte[] p)
    Convert NMRA packet to human-readable form
    static byte[] twoBytePacket​(int address, boolean longAddr, byte byte1, byte byte2)
    Create a packet containing a two-byte instruction.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Method Details

    • idlePacket

      @CheckForNull public static byte[] idlePacket()
      Create a packet containing a decoder idle instruction.
      Returns:
      the packet as a byte array or null if the address is not valid
    • oneBytePacket

      @CheckForNull public static byte[] oneBytePacket​(int address, boolean longAddr, byte byte1)
      Create a packet containing a one-byte instruction.
      Parameters:
      address - the address to send the instruction to
      longAddr - true if address is long, false otherwise
      byte1 - the byte to send as an instruction
      Returns:
      the packet as a byte array or null if the address is not valid
    • twoBytePacket

      @CheckForNull public static byte[] twoBytePacket​(int address, boolean longAddr, byte byte1, byte byte2)
      Create a packet containing a two-byte instruction.
      Parameters:
      address - the address to send the instruction to
      longAddr - true if address is long, false otherwise
      byte1 - first byte in the instruction
      byte2 - second byte in the instruction
      Returns:
      the packet as a byte array or null if the address is not valid
    • threeBytePacket

      @CheckForNull public static byte[] threeBytePacket​(int address, boolean longAddr, byte byte1, byte byte2, byte byte3)
      Create a packet containing a three-byte instruction.
      Parameters:
      address - the address to send the instruction to
      longAddr - true if address is long, false otherwise
      byte1 - first byte in the instruction
      byte2 - second byte in the instruction
      byte3 - third byte in the instruction
      Returns:
      the packet as a byte array or null if the address is not valid
    • fourBytePacket

      @CheckForNull public static byte[] fourBytePacket​(int address, boolean longAddr, byte byte1, byte byte2, byte byte3, byte byte4)
      Create a packet containing a four-byte instruction.
      Parameters:
      address - the address to send the instruction to
      longAddr - true if address is long, false otherwise
      byte1 - first byte in the instruction
      byte2 - second byte in the instruction
      byte3 - third byte in the instruction
      byte4 - forth byte in the instruction
      Returns:
      the packet as a byte array or null if the address is not valid
    • accDecoderPkt

      public static byte[] accDecoderPkt​(int addr, int active, int outputChannel)
    • accDecoderPktOpsMode

      public static byte[] accDecoderPktOpsMode​(int addr, int active, int outputChannel, int cvNum, int data)
      Provide a basic operations mode accessory CV programming packet.

      From the NMRA Standard: Basic Accessory Decoder Packet address for operations mode programming

      10AAAAAA 0 1AAACDDD

      Where DDD is used to indicate the output whose CVs are being modified and C=1.
      If CDDD= 0000 then the CVs refer to the entire decoder.

      The resulting packet would be

      {preamble} 10AAAAAA 0 1AAACDDD 0 (1110CCVV 0 VVVVVVVV 0 DDDDDDDD) 0 EEEEEEEE 1
      Parameters:
      addr - the decoder address
      active - 1 or 0
      outputChannel - the output on the accessory
      cvNum - the CV
      data - the data
      Returns:
      a packet
    • accDecPktOpsModeLegacy

      public static byte[] accDecPktOpsModeLegacy​(int decAddr, int cvNum, int data)
      Provide a legacy operations mode accessory CV programming packet via a simplified interface, given a decoder address.

      From the NMRA Standard: The format for Accessory Decoder Configuration Variable Access Instructions is: {preamble} 0 10AAAAAA 0 0AAA11VV 0 VVVVVVVV 0 DDDDDDDD 0 EEEEEEEE 1 Where: A = Decoder address bits V = Desired CV address - (CV 513 = 10 00000000) D = Data for CV

      This is the old "legacy" format, newer decoders use the "Basic Accessory Decoder Packet"
      Parameters:
      decAddr - Address of decoder, in the range 1 to 511
      cvNum - the CV
      data - the data
      Returns:
      a packet
    • accSignalDecoderPkt

      public static byte[] accSignalDecoderPkt​(int outputAddr, int aspect)
      Create a signal accessory instruction packet.

      From the RP: Extended Accessory Decoder Control Packet Format The Extended Accessory Decoder Control Packet is included for the purpose of transmitting aspect control to signal decoders or data bytes to more complex accessory decoders. Each signal head can display one aspect at a time.

      {preamble} 0 10AAAAAA 0 0AAA0AA1 0 000XXXXX 0 EEEEEEEE 1

      XXXXX is for a single head. A value of 00000 for XXXXX indicates the absolute stop aspect. All other aspects represented by the values for XXXXX are determined by the signaling system used and the prototype being modeled.

      Despite this being an NMRA standard, or perhaps because of it, the addressing is not clear. The other form of packet generated by altAccSignalDecoderPkt(int, int) seems to be the one thats generally supported by hardware.

      Parameters:
      outputAddr - Address of accessory output, starting with 1 and a maximum of 2044
      aspect - Aspect Number starting with 0 and a maximum of 31
      Returns:
      the instruction packet
    • accSignalDecoderPktOpsMode

      public static byte[] accSignalDecoderPktOpsMode​(int addr, int cvNum, int data)
      Provide an extended operations mode accessory CV programming packet via a simplified interface, given a signal address.

      From the NMRA Standard: Extended Decoder Packet address for operations mode programming

      10AAAAAA 0 0AAA0AA1


      The resulting packet would be

      {preamble} 10AAAAAA 0 0AAA0AA1 0 (1110CCVV 0 VVVVVVVV 0 DDDDDDDD) 0 EEEEEEEE 1
      Parameters:
      addr - the signal address
      cvNum - the CV
      data - the data
      Returns:
      a packet
    • isAccSignalDecoderPkt

      public static boolean isAccSignalDecoderPkt​(byte[] packet)
      Determine if a packet is an Extended Accessory Decoder Control Packet otherwise known as a Signal Decoder Packet.

      This inverts the computation done by the accSignalDecoderPkt(int, int) method.

      Parameters:
      packet - a DCC packet to inspect
      Returns:
      true if a Signal Decoder Packet; false otherwise
    • isAccDecoderPktOpsMode

      public static boolean isAccDecoderPktOpsMode​(byte[] packet)
      Determine if a packet is a Basic Accessory Decoder Packet address for operations mode programming.

      This inverts the computation done by the accDecPktOpsMode(int, int, int) method.

      Parameters:
      packet - the packet to test
      Returns:
      true if the packet is a basic accessory decoder packet address
    • isAccDecoderPktOpsModeLegacy

      public static boolean isAccDecoderPktOpsModeLegacy​(byte[] packet)
      Determine if a packet is a Legacy Accessory Decoder Packet address for operations mode programming.

      This inverts the computation done by the accDecoderPktOpsModeLegacy(int, int, int) method.

      Parameters:
      packet - the packet to extract the address from
      Returns:
      the address
    • getAccDecPktOpsModeLegacyAddress

      public static int getAccDecPktOpsModeLegacyAddress​(byte[] packet)
      Recover the decoder address from a Legacy Accessory Decoder Packet Ops Mode Packet.
      Parameters:
      packet - the packet to extract the address from
      Returns:
      the decoder address
    • getAccDecoderPktOpsModeLegacyAddress

      public static int getAccDecoderPktOpsModeLegacyAddress​(byte[] packet)
      Recover the equivalent accessory address from a Legacy Accessory Decoder Packet Ops Mode Packet.
      Parameters:
      packet - the packet to extract the address from
      Returns:
      the accessory address
    • getAccDecoderPktOpsModeAddress

      public static int getAccDecoderPktOpsModeAddress​(byte[] packet)
      Recover the accessory address from a Basic Accessory Decoder Packet Ops Mode Packet.
      Parameters:
      packet - the packet to extract the address from
      Returns:
      the accessory address
    • getAccDecPktOpsModeAddress

      public static int getAccDecPktOpsModeAddress​(byte[] packet)
      Recover the equivalent decoder address from a Basic Accessory Decoder Packet Ops Mode Packet.
      Parameters:
      packet - the packet to extract the address from
      Returns:
      the decoder address
    • getAccSignalDecoderPktAddress

      public static int getAccSignalDecoderPktAddress​(byte[] packet)
      Recover the 1-based output address from an Extended Accessory Decoder Control Packet otherwise known as a Signal Decoder Packet.
      Parameters:
      packet - the packet to extract the address from
      Returns:
      the address
    • altAccSignalDecoderPkt

      public static byte[] altAccSignalDecoderPkt​(int outputAddr, int aspect)
      An alternative interpretation of RP-9.2.1 due to an omission in the address definition of extended accessory packets. Since there is no such description for the address bits of the Extended Accessory Decoder Control Packet, this interpretation assumes that the least significant bits of the extended packet type are still in bits 1 and 2 of byte two, see Basic Accessory Packet.
      Parameters:
      outputAddr - Address of accessory output, starting with 1 and a maximum of 2044
      aspect - Aspect Number starting with 0 and a maximum of 31
      Returns:
      a packet
    • altAccSignalDecoderPktOpsMode

      public static byte[] altAccSignalDecoderPktOpsMode​(int addr, int cvNum, int data)
      Provide an extended operations mode accessory CV programming packet via a simplified interface, given a signal address, using the alternative interpretation of S-9.2.1, due to an omission in the address definition of extended accessory packets.
      Parameters:
      addr - the signal address
      cvNum - the CV
      data - the data
      Returns:
      a packet
    • accSignalDecoderPktCommon

      protected static byte[] accSignalDecoderPktCommon​(int lowAddr, int boardAddr, int aspect)
    • getAccDecoderPktAddress

      public static int getAccDecoderPktAddress​(byte[] packet)
      Recover the 1-based output address from an Accessory Decoder Control Packet, typically considered a turnout control packet
      Parameters:
      packet - the packet to get an address from
      Returns:
      the accessory decoder address
    • accDecoderPkt

      public static byte[] accDecoderPkt​(int number, boolean closed)
      Provide an accessory control packet via a simplified interface
      Parameters:
      number - Address of accessory output, starting with 1
      closed - true if the output is to be configured to the "closed", a.k.a. the "normal" or "unset" position
      Returns:
      a packet
    • accDecoderPktOpsMode

      public static byte[] accDecoderPktOpsMode​(int accAddr, int cvNum, int data)
      Provide a basic operations mode accessory CV programming packet via a simplified interface, given an accessory address.

      Parameters:
      accAddr - Address of accessory, in the range 1 to 2044
      cvNum - CV number to access
      data - Data to be written
      Returns:
      a packet
    • accDecPktOpsMode

      public static byte[] accDecPktOpsMode​(int decAddr, int cvNum, int data)
      Provide a basic operations mode accessory CV programming packet via a simplified interface, given a decoder address.

      From the NMRA Standard: Basic Accessory Decoder Packet address for operations mode programming

      10AAAAAA 0 1AAACDDD

      Where DDD is used to indicate the output whose CVs are being modified and C=1.
      If CDDD= 0000 then the CVs refer to the entire decoder.

      Hence this method uses CDDD= 0000.

      For programming individual outputs use accDecoderPktOpsMode(int accAddr, int cvNum, int data)

      Parameters:
      decAddr - Address of decoder, in the range 1 to 511
      cvNum - CV number to access
      data - Data to be written
      Returns:
      a packet
    • accDecoderPktOpsModeLegacy

      public static byte[] accDecoderPktOpsModeLegacy​(int accAddr, int cvNum, int data)
      Provide a legacy operations mode accessory CV programming packet via a simplified interface, given an accessory address.

      From the NMRA Standard: The format for Accessory Decoder Configuration Variable Access Instructions is: {preamble} 0 10AAAAAA 0 0AAA11VV 0 VVVVVVVV 0 DDDDDDDD 0 EEEEEEEE 1 Where: A = Decoder address bits V = Desired CV address - (CV 513 = 10 00000000) D = Data for CV

      This is the old "legacy" format, newer decoders use the "Basic Accessory Decoder Packet"
      Parameters:
      accAddr - Address of accessory, in the range 1 to 2044
      cvNum - CV number to access
      data - Data to be written
      Returns:
      a packet
    • opsCvWriteByte

      public static byte[] opsCvWriteByte​(int address, boolean longAddr, int cvNum, int data)
    • speedStep128Packet

      public static byte[] speedStep128Packet​(int address, boolean longAddr, int speed, boolean fwd)
    • speedStep28Packet

      public static byte[] speedStep28Packet​(int address, boolean longAddr, int speed, boolean fwd)
      From NMRA RP 9.2.1 [A Crosland 05/02/12] There is an issue with this method in that it cannot create a 28 step speed packet for maximum speed. Input speed value in the range 0 - 28 is converted to speed steps, 0, estop, 1, 2, ..., 27.

      This method should probably be deprecated. It is used only by NceThrottle.java and EasyDccThrottle.java which themselves have issues in the way floating point speed values are converted to integer speed steps.

      A speed and direction instruction is used send information to motors connected to Multi Function Digital Decoders. Instruction "010" indicates a Speed and Direction Instruction for reverse operation and instruction "011" indicates a Speed and Direction Instruction for forward operation. In these instructions the data is used to control speed with bits 0-3 being defined exactly as in S-9.2 Section B. If Bit 1 of CV#29 has a value of one (1), then bit 4 is used as an intermediate speed step, as defined in S-9.2, Section B. If Bit 1 of CV#29 has a value of zero (0), then bit 4 shall 230 be used to control FL4. In this mode, Speed U0000 is stop, speed U0001 is emergency stop, speed U0010 is the first speed step and speed U1111 is full speed. This provides 14 discrete speed steps in each direction.

      Parameters:
      address - the DCC locomotive address
      longAddr - true if the address is long; false if short
      speed - the speed from 0-28
      fwd - true for forward direction; false for reverse
      Returns:
      the instruction or null if address or speed is invalid
    • speedStep28Packet

      @CheckForNull public static byte[] speedStep28Packet​(boolean full, int address, boolean longAddr, int speed, boolean fwd)
      New version of speedStep28Packet to allow access to the whole range of 28 step speed packets.

      Simply constructs a packet using the 5 bit speed value. This is consistent with the 128 and 14 step methods which do no further processing of the speed value.

      Parameters:
      full - must be true
      address - DCC address
      longAddr - true if DCC address is long; false if short
      speed - speed step value 0 - 31 for insertion into DC packet
      fwd - true for forward direction; false for reverse
      Returns:
      the instruction or null if address or speed is invalid
    • speedStep14Packet

      public static byte[] speedStep14Packet​(int address, boolean longAddr, int speed, boolean fwd, boolean F0)
    • function0Through4Packet

      public static byte[] function0Through4Packet​(int address, boolean longAddr, boolean f0, boolean f1, boolean f2, boolean f3, boolean f4)
    • function5Through8Packet

      public static byte[] function5Through8Packet​(int address, boolean longAddr, boolean f5, boolean f6, boolean f7, boolean f8)
    • function9Through12Packet

      public static byte[] function9Through12Packet​(int address, boolean longAddr, boolean f9, boolean f10, boolean f11, boolean f12)
    • function13Through20Packet

      public static byte[] function13Through20Packet​(int address, boolean longAddr, boolean f13, boolean f14, boolean f15, boolean f16, boolean f17, boolean f18, boolean f19, boolean f20)
    • function21Through28Packet

      public static byte[] function21Through28Packet​(int address, boolean longAddr, boolean f21, boolean f22, boolean f23, boolean f24, boolean f25, boolean f26, boolean f27, boolean f28)
    • function29Through36Packet

      public static byte[] function29Through36Packet​(int address, boolean longAddr, boolean f29, boolean f30, boolean f31, boolean f32, boolean f33, boolean f34, boolean f35, boolean f36)
    • function37Through44Packet

      public static byte[] function37Through44Packet​(int address, boolean longAddr, boolean f37, boolean f38, boolean f39, boolean f40, boolean f41, boolean f42, boolean f43, boolean f44)
    • function45Through52Packet

      public static byte[] function45Through52Packet​(int address, boolean longAddr, boolean f45, boolean f46, boolean f47, boolean f48, boolean f49, boolean f50, boolean f51, boolean f52)
    • function53Through60Packet

      public static byte[] function53Through60Packet​(int address, boolean longAddr, boolean f53, boolean f54, boolean f55, boolean f56, boolean f57, boolean f58, boolean f59, boolean f60)
    • function61Through68Packet

      public static byte[] function61Through68Packet​(int address, boolean longAddr, boolean f61, boolean f62, boolean f63, boolean f64, boolean f65, boolean f66, boolean f67, boolean f68)
    • analogControl

      public static byte[] analogControl​(int address, boolean longAddr, int function, int value)
      Provide an NMRA analog control instruction.

      Note that the NMRA draft of Fall 2004 only defines the value of "1" for the "function parameter", calling that the value for "volume control". However, DCC systems in the wild have been observed to use 0x7F for the function byte for volume control.

      Parameters:
      address - DCC locomotive address
      longAddr - true if this is a long address, false if short address
      function - see note above
      value - value to be sent in analog control instruction
      Returns:
      the instruction or null if the address is not valid
    • consistControl

      public static byte[] consistControl​(int address, boolean longAddr, int consist, boolean directionNormal)
      Provide an NMRA consist control instruction
      Parameters:
      address - DCC locomotive address
      longAddr - true for a long address, false if short address
      consist - the consist address to set for this locomotive; Send 00 as consist address to remove from consist
      directionNormal - true if the normal direction of travel for this address is the normal direction of travel for the consist
      Returns:
      the instruction
    • addressCheck

      public static boolean addressCheck​(int address, boolean longAddr)
      Check if an address is (possibly) valid, e.g. fits within the NMRA space definition
      Parameters:
      address - the address
      longAddr - true if address is long; false otherwise
      Returns:
      true if address is valid; false otherwise
    • extractAddressType

      public static NmraPacket.DccAddressType extractAddressType​(byte[] packet)
      Extract the address type from an NMRA packet.

      This finds and returns the type of address within a specific packet, e.g. "the stationary decoder space".

      Parameters:
      packet - the packet
      Returns:
      the type or NmraPacket.DccAddressType.NO_ADDRESS
    • extractAddressNumber

      public static int extractAddressNumber​(byte[] packet)
      Extract the numerical address from an NMRA packet.

      This finds and returns the numerical address within a specific type, e.g. "first address within the stationary decoder space".

      As a special case, IDLE is returned as -1 instead of 255. Best to check the address type first....

      Note: The decoding is not complete for the ACCESSORY_ADDRESS type.

      Parameters:
      packet - the packet
      Returns:
      the address; -1 is returned if there is no address or the case isn't considered yet
    • extractInstruction

      public static int extractInstruction​(byte[] packet)
      Extract the instruction from an NMRA packet.

      This finds and returns the instruction byte within a specific type of packet/instruction.

      Parameters:
      packet - the packet
      Returns:
      the instruction or 0
    • format

      public static String format​(byte[] p)
      Convert NMRA packet to a readable form as hexadecimal characters.
      Parameters:
      p - the raw packet
      Returns:
      the readable packet
      See Also:
      StringUtil.hexStringFromBytes(byte[])
    • toString

      public static String toString​(byte[] p) throws IllegalArgumentException
      Convert NMRA packet to human-readable form

      Note: Only gives a summary now, should this completely decode?

      2nd Note: The name may be a bad choice, as this is not the .toString() method of an object, but rather a procedure that takes a byte-array representation of a packet. But the analogy seems not so bad, until we have a true class for NmraPackets.

      Parameters:
      p - the raw packet
      Returns:
      the human-readable form for that packet
      Throws:
      IllegalArgumentException - if packet array can't be decoded, e.g. is too short or null