001package jmri.jmrix.loconet; 002 003import java.util.Locale; 004import javax.annotation.Nonnull; 005import jmri.Reporter; 006import org.slf4j.Logger; 007import org.slf4j.LoggerFactory; 008 009/** 010 * Manage the LocoNet-specific Reporter implementation. 011 * <p> 012 * System names are "LRnnn", where L is the user configurable system prefix, 013 * nnn is the Reporter number without padding. 014 * <p> 015 * Some of the message formats used in this class are Copyright Digitrax, Inc. 016 * and used with permission as part of the JMRI project. That permission does 017 * not extend to uses in other software products. If you wish to use this code, 018 * algorithm or these message formats outside of JMRI, please contact Digitrax 019 * Inc for separate permission. 020 * 021 * @author Bob Jacobsen Copyright (C) 2001 022 */ 023public class LnReporterManager extends jmri.managers.AbstractReporterManager implements LocoNetListener { 024 025 protected final LnTrafficController tc; 026 027 // ctor has to register for LocoNet events 028 public LnReporterManager(LocoNetSystemConnectionMemo memo) { 029 super(memo); 030 tc = memo.getLnTrafficController(); 031 if (tc != null) { 032 tc.addLocoNetListener(~0, this); 033 } else { 034 log.error("No layout connection, Reporter manager can't function"); 035 } 036 } 037 038 /** 039 * {@inheritDoc} 040 */ 041 @Override 042 @Nonnull 043 public LocoNetSystemConnectionMemo getMemo() { 044 return (LocoNetSystemConnectionMemo) memo; 045 } 046 047 @Override 048 public void dispose() { 049 if (tc != null) { 050 tc.removeLocoNetListener(~0, this); 051 } 052 super.dispose(); 053 } 054 055 @Override 056 @Nonnull 057 protected Reporter createNewReporter(@Nonnull String systemName, String userName) throws IllegalArgumentException { 058 Reporter t; 059 int addr = Integer.parseInt(systemName.substring(getSystemNamePrefix().length())); 060 t = new LnReporter(addr, tc, getSystemPrefix()); 061 t.setUserName(userName); 062 t.addPropertyChangeListener(this); 063 064 return t; 065 } 066 067 /** 068 * {@inheritDoc} 069 */ 070 @Override 071 public NameValidity validSystemNameFormat(@Nonnull String systemName) { 072 return (getBitFromSystemName(systemName) != 0) ? NameValidity.VALID : NameValidity.INVALID; 073 } 074 075 /** 076 * {@inheritDoc} 077 */ 078 @Override 079 @Nonnull 080 public String validateSystemNameFormat(@Nonnull String systemName, @Nonnull Locale locale) { 081 return validateIntegerSystemNameFormat(systemName, 1, 4096, locale); 082 } 083 084 /** 085 * Get the bit address from the system name. 086 * @param systemName a valid LocoNet-based Reporter System Name 087 * @return the turnout number extracted from the system name 088 */ 089 public int getBitFromSystemName(String systemName) { 090 try { 091 validateSystemNameFormat(systemName, Locale.getDefault()); 092 } catch (IllegalArgumentException ex) { 093 return 0; 094 } 095 return Integer.parseInt(systemName.substring(getSystemNamePrefix().length())); 096 } 097 098 /** 099 * {@inheritDoc} 100 */ 101 @Override 102 public String getEntryToolTip() { 103 return Bundle.getMessage("AddInputEntryToolTip"); 104 } 105 106 // listen for transponder messages, creating Reporters as needed 107 @Override 108 public void message(LocoNetMessage l) { 109 // check message type 110 int addr; 111 switch (l.getOpCode()) { 112 case LnConstants.OPC_MULTI_SENSE: 113 if ((l.getElement(1) & 0xC0) == 0) { 114 addr = (l.getElement(1) & 0x1F) * 128 + l.getElement(2) + 1; 115 break; 116 } 117 return; 118 case LnConstants.OPC_PEER_XFER: 119 if (l.getElement(1) == 0x09 && l.getElement(2) == 0x00) { 120 addr = (l.getElement(5) & 0x1F) * 128 + l.getElement(6) + 1; 121 break; 122 } 123 return; 124 case LnConstants.OPC_LISSY_UPDATE: 125 if (l.getElement(1) == 0x08) { 126 addr = (l.getElement(4) & 0x7F); 127 break; 128 } 129 return; 130 default: 131 return; 132 } 133 log.debug("Message for Reporter[{}]", addr); 134 LnReporter r = (LnReporter) provideReporter(getSystemNamePrefix() + addr); // NOI18N 135 r.messageFromManager(l); // make sure it got the message 136 } 137 138 private final static Logger log = LoggerFactory.getLogger(LnReporterManager.class); 139 140}