jmri.jmrix.loconet
Class SlotManager

java.lang.Object
  extended by jmri.jmrix.AbstractProgrammer
      extended by jmri.jmrix.loconet.SlotManager
All Implemented Interfaces:
EventListener, CommandStation, LocoNetListener, Programmer

public class SlotManager
extends AbstractProgrammer
implements LocoNetListener, CommandStation

Controls a collection of slots, acting as the counter-part of a LocoNet command station.

A SlotListener can register to hear changes. By registering here, the SlotListener is saying that it wants to be notified of a change in any slot. Alternately, the SlotListener can register with some specific slot, done via the LocoNetSlot object itself.

Strictly speaking, functions 9 through 28 are not in the actual slot, but it's convenient to imagine there's an "extended slot" and keep track of them here. This is a partial implementation, though, because setting is still done directly in LocoNetThrottle. In particular, if this slot has not been read from the command station, the first message directly setting F9 through F28 will not have a place to store information. Instead, it will trigger a slot read, so the following messages will be properly handled.

Some of the message formats used in this class are Copyright Digitrax, Inc. and used with permission as part of the JMRI project. That permission does not extend to uses in other software products. If you wish to use this code, algorithm or these message formats outside of JMRI, please contact Digitrax Inc for separate permission.

This Programmer implementation is single-user only. It's not clear whether the command stations can have multiple programming requests outstanding (e.g. service mode and ops mode, or two ops mode) at the same time, but this code definitely can't.

Author:
Bob Jacobsen Copyright (C) 2001, 2003

Field Summary
protected  int _mode
          Records the current mode of the Programmer implementation.
protected  String commandStationType
           
protected  int nextReadSlot
           
 
Fields inherited from class jmri.jmrix.AbstractProgrammer
LONG_TIMEOUT, propListeners, SHORT_TIMEOUT
 
Fields inherited from interface jmri.Programmer
ADDRESSMODE, CBUSNODEVARMODE, DIRECTBITMODE, DIRECTBYTEMODE, NONE, OPSACCBITMODE, OPSACCBYTEMODE, OPSACCEXTBITMODE, OPSACCEXTBYTEMODE, OPSBITMODE, OPSBYTEMODE, PAGEMODE, REGISTERMODE
 
Constructor Summary
SlotManager(LnTrafficController tc)
           
 
Method Summary
 void addSlotListener(SlotListener l)
           
 void confirmCV(int CV, int val, ProgListener p)
          Confirm the value of a CV using the specified programming mode.
 void confirmCVOpsMode(int CV, int val, ProgListener p, int addr, boolean longAddr)
           
 void doConfirm(int CV, int val, ProgListener p, int pcmd)
           
protected  void doPowerOn()
          Internal routine to handle a timeout & turn power off
 void doWrite(int CV, int val, ProgListener p, int pcmd)
           
 int findSlotFromMessage(LocoNetMessage m)
          FInd the slot number that a message references
 void forwardMessageToSlot(LocoNetMessage m, int i)
           
 boolean getCanRead()
          Determine whether this Programmer implementation is capable of reading decoder contents.
 String getCommandStationType()
          Get the command station type
 int getInUseCount()
          Provide a snapshot of the slots in use
 int getMode()
          Get the current mode of the Programmer implementation.
 boolean getProgPowersOff()
          Determine whether this Programmer implementation powers off the main track after a service track programming operation.
 boolean hasMode(int mode)
          Determine is a mode is available for this Programmer implementation
 void message(LocoNetMessage m)
          Listen to the LocoNet.
protected  void notify(LocoNetSlot s)
          Trigger the notification of all SlotListeners.
protected  void notifyProgListenerEnd(int value, int status)
          internal method to notify of the final result
protected  void notifyProgListenerLack(int status)
          Internal method to notify of the LACK result.
protected  void notifyPropertyChange(String name, int oldval, int newval)
          Trigger notification of PropertyChangeListeners.
protected  void programmerOpMessage(LocoNetMessage m, int i)
           
protected  LocoNetMessage progTaskStart(int pcmd, int val, int cvnum, boolean write)
          Internal method to create the LocoNetMessage for programmer task start
 void readCV(int CV, ProgListener p)
          Perform a CV read in the system-specific manner, and using the specified programming mode.
 void readCVOpsMode(int CV, ProgListener p, int addr, boolean longAddr)
          Invoked by LnOpsModeProgrammer to start an ops-mode read operation.
protected  void readNextSlot()
           
 void removeSlotListener(SlotListener l)
           
protected  void respondToAddrRequest(LocoNetMessage m, int i)
           
protected  void restartPowerTimer()
          Internal routine to handle timer restart if needed to restore power.
 void sendPacket(byte[] packet, int repeats)
          Send a DCC packet to the rails.
protected  void sendProgrammingReply(ProgListener p, int value, int status)
          Internal routine to forward a programing reply.
 void sendReadSlot(int slot)
          Send a message requesting the data from a particular slot.
 void setCanRead(boolean pCanRead)
          Configure whether this Programmer implementation is capable of reading decoder contents.
 void setCommandStationType(String value)
          Set the command station type
 void setMode(int mode)
          Set the mode of the Programmer implementation.
 void setProgPowersOff(boolean pProgPowersOff)
          Configure whether this Programmer owers off the main track after a service track programming operation.
 LocoNetSlot slot(int i)
          Access the information in a specific slot.
 void slotFromLocoAddress(int i, SlotListener l)
          Obtain a slot for a particular loco address.
protected  void stopPowerTimer()
          Internal routine to stop power timer, as another programming operation has happened
protected  void timeout()
          Internal routine to handle a timeout
 void update()
          Start the process of checking each slot for contents.
protected  void useProgrammer(ProgListener p)
           
 void writeCV(int CV, int val, ProgListener p)
          Perform a CV write in the system-specific manner, and using the specified programming mode.
 void writeCVOpsMode(int CV, int val, ProgListener p, int addr, boolean longAddr)
           
 
Methods inherited from class jmri.jmrix.AbstractProgrammer
addPropertyChangeListener, decodeErrorCode, registerFromCV, removePropertyChangeListener, restartTimer, startLongTimer, startShortTimer, stopTimer
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_mode

protected int _mode
Records the current mode of the Programmer implementation.


commandStationType

protected String commandStationType

nextReadSlot

protected int nextReadSlot
Constructor Detail

SlotManager

public SlotManager(LnTrafficController tc)
Method Detail

sendPacket

public void sendPacket(byte[] packet,
                       int repeats)
Send a DCC packet to the rails. This implements the CommandStation interface.

Specified by:
sendPacket in interface CommandStation
Parameters:
packet -
repeats - Number of times to repeat the transmission.

slot

public LocoNetSlot slot(int i)
Access the information in a specific slot. Note that this is a mutable access, so that the information in the LocoNetSlot object can be changed.

Parameters:
i - Specific slot, counted starting from zero.
Returns:
The Slot object

slotFromLocoAddress

public void slotFromLocoAddress(int i,
                                SlotListener l)
Obtain a slot for a particular loco address.

This requires access to the command station, even if the locomotive address appears in the current contents of the slot array, to ensure that our local image is up-to-date.

This method sends an info request. When the echo of this is returned from the LocoNet, the next slot-read is recognized as the response.

The object that's looking for this information must provide a SlotListener to notify when the slot ID becomes available.

The SlotListener is not subscribed for slot notifications; it can do that later if it wants. We don't currently think that's a race condition.

Parameters:
i - Specific slot, counted starting from zero.
l - The SlotListener to notify of the answer.

addSlotListener

public void addSlotListener(SlotListener l)

removeSlotListener

public void removeSlotListener(SlotListener l)

notify

protected void notify(LocoNetSlot s)
Trigger the notification of all SlotListeners.

Parameters:
s - The changed slot to notify.

message

public void message(LocoNetMessage m)
Listen to the LocoNet. This is just a steering routine, which invokes others for the various processing steps.

Specified by:
message in interface LocoNetListener
Parameters:
m - incoming message

findSlotFromMessage

public int findSlotFromMessage(LocoNetMessage m)
FInd the slot number that a message references


forwardMessageToSlot

public void forwardMessageToSlot(LocoNetMessage m,
                                 int i)

respondToAddrRequest

protected void respondToAddrRequest(LocoNetMessage m,
                                    int i)

programmerOpMessage

protected void programmerOpMessage(LocoNetMessage m,
                                   int i)

setMode

public void setMode(int mode)
Set the mode of the Programmer implementation.

Specified by:
setMode in interface Programmer
Parameters:
mode - A mode constant from the Programmer interface

getMode

public int getMode()
Get the current mode of the Programmer implementation.

Specified by:
getMode in interface Programmer
Returns:
A mode constant from the Programmer interface

notifyPropertyChange

protected void notifyPropertyChange(String name,
                                    int oldval,
                                    int newval)
Trigger notification of PropertyChangeListeners. The only bound property is Mode from the Programmer interface. It is not clear why this is not in AbstractProgrammer...

Parameters:
name - Changed property
oldval -
newval -

getProgPowersOff

public boolean getProgPowersOff()
Determine whether this Programmer implementation powers off the main track after a service track programming operation. This is entirely determined by the attached command station, not the code here, so it refers to the mProgPowersOff member variable which is recording the known state of that.

Returns:
True if main track off after service operation

setProgPowersOff

public void setProgPowersOff(boolean pProgPowersOff)
Configure whether this Programmer owers off the main track after a service track programming operation.

This is not part of the Programmer interface, but is used as part of the startup sequence for the LocoNet objects.

Parameters:
pProgPowersOff - True if power is off afterward

getCanRead

public boolean getCanRead()
Determine whether this Programmer implementation is capable of reading decoder contents. This is entirely determined by the attached command station, not the code here, so it refers to the mCanRead member variable which is recording the known state of that.

Specified by:
getCanRead in interface Programmer
Returns:
True if reads are possible

setCanRead

public void setCanRead(boolean pCanRead)
Configure whether this Programmer implementation is capable of reading decoder contents.

This is not part of the Programmer interface, but is used as part of the startup sequence for the LocoNet objects.

Parameters:
pCanRead - True if reads are possible

setCommandStationType

public void setCommandStationType(String value)
Set the command station type


getCommandStationType

public String getCommandStationType()
Get the command station type


hasMode

public boolean hasMode(int mode)
Determine is a mode is available for this Programmer implementation

Specified by:
hasMode in interface Programmer
Parameters:
mode - A mode constant from the Programmer interface
Returns:
True if paged or register mode

timeout

protected void timeout()
Internal routine to handle a timeout

Specified by:
timeout in class AbstractProgrammer

writeCVOpsMode

public void writeCVOpsMode(int CV,
                           int val,
                           ProgListener p,
                           int addr,
                           boolean longAddr)
                    throws ProgrammerException
Throws:
ProgrammerException

writeCV

public void writeCV(int CV,
                    int val,
                    ProgListener p)
             throws ProgrammerException
Description copied from interface: Programmer
Perform a CV write in the system-specific manner, and using the specified programming mode. Note that this returns before the write is complete; you have to provide a ProgListener to hear about completion. The exceptions will only be thrown at the start, not during the actual programming sequence. A typical exception would be due to an invalid mode (though that should be prevented earlier)

Specified by:
writeCV in interface Programmer
Throws:
ProgrammerException

doWrite

public void doWrite(int CV,
                    int val,
                    ProgListener p,
                    int pcmd)
             throws ProgrammerException
Throws:
ProgrammerException

confirmCVOpsMode

public void confirmCVOpsMode(int CV,
                             int val,
                             ProgListener p,
                             int addr,
                             boolean longAddr)
                      throws ProgrammerException
Throws:
ProgrammerException

confirmCV

public void confirmCV(int CV,
                      int val,
                      ProgListener p)
               throws ProgrammerException
Description copied from interface: Programmer
Confirm the value of a CV using the specified programming mode. On some systems, this is faster than a read. Note that this returns before the confirm is complete; you have to provide a ProgListener to hear about completion. The exceptions will only be thrown at the start, not during the actual programming sequence. A typical exception would be due to an invalid mode (though that should be prevented earlier)

Specified by:
confirmCV in interface Programmer
Throws:
ProgrammerException

doConfirm

public void doConfirm(int CV,
                      int val,
                      ProgListener p,
                      int pcmd)
               throws ProgrammerException
Throws:
ProgrammerException

readCVOpsMode

public void readCVOpsMode(int CV,
                          ProgListener p,
                          int addr,
                          boolean longAddr)
                   throws ProgrammerException
Invoked by LnOpsModeProgrammer to start an ops-mode read operation.

Parameters:
CV - Which CV to read
p - Who to notify on complete
addr - Address of the locomotive
longAddr - true if a long address, false if short address
Throws:
ProgrammerException

readCV

public void readCV(int CV,
                   ProgListener p)
            throws ProgrammerException
Description copied from interface: Programmer
Perform a CV read in the system-specific manner, and using the specified programming mode. Note that this returns before the read is complete; you have to provide a ProgListener to hear about completion. The exceptions will only be thrown at the start, not during the actual programming sequence. A typical exception would be due to an invalid mode (though that should be prevented earlier)

Specified by:
readCV in interface Programmer
Throws:
ProgrammerException

useProgrammer

protected void useProgrammer(ProgListener p)
                      throws ProgrammerException
Throws:
ProgrammerException

progTaskStart

protected LocoNetMessage progTaskStart(int pcmd,
                                       int val,
                                       int cvnum,
                                       boolean write)
Internal method to create the LocoNetMessage for programmer task start


notifyProgListenerEnd

protected void notifyProgListenerEnd(int value,
                                     int status)
internal method to notify of the final result

Parameters:
value - The cv value to be returned
status - The error code, if any

notifyProgListenerLack

protected void notifyProgListenerLack(int status)
Internal method to notify of the LACK result. This is a separate routine from nPLRead in case we need to handle something later

Parameters:
status - The error code, if any

sendProgrammingReply

protected void sendProgrammingReply(ProgListener p,
                                    int value,
                                    int status)
Internal routine to forward a programing reply. This is delayed to prevent overruns of the command station.

Parameters:
value - the value to return
status - The error code, if any

stopPowerTimer

protected void stopPowerTimer()
Internal routine to stop power timer, as another programming operation has happened


restartPowerTimer

protected void restartPowerTimer()
Internal routine to handle timer restart if needed to restore power. This is only needed in service mode.


doPowerOn

protected void doPowerOn()
Internal routine to handle a timeout & turn power off


update

public void update()
Start the process of checking each slot for contents.

This is not invoked by this class, but can be invoked from elsewhere to start the process of scanning all slots to update their contents.


sendReadSlot

public void sendReadSlot(int slot)
Send a message requesting the data from a particular slot.

Parameters:
slot - Slot number

readNextSlot

protected void readNextSlot()

getInUseCount

public int getInUseCount()
Provide a snapshot of the slots in use



Copyright © 1997 - 2011 JMRI Community.
JMRI, DecoderPro, PanelPro, SoundPro, DispatcherPro and associated logos are our trademarks.

Additional information on copyright, trademarks and licenses is linked here.
Site hosted by: Get JMRI Model Railroad Interface at SourceForge.net. Fast, secure and Free Open Source software downloads