001package jmri.jmrix.rfid.serialdriver; 002 003import java.util.Arrays; 004import jmri.jmrix.rfid.RfidPortController; 005import jmri.jmrix.rfid.RfidProtocol; 006import jmri.jmrix.rfid.RfidSystemConnectionMemo; 007import jmri.jmrix.rfid.RfidTrafficController; 008import jmri.jmrix.rfid.generic.standalone.StandaloneReporterManager; 009import jmri.jmrix.rfid.generic.standalone.StandaloneSensorManager; 010import jmri.jmrix.rfid.generic.standalone.StandaloneTrafficController; 011import jmri.jmrix.rfid.merg.concentrator.ConcentratorReporterManager; 012import jmri.jmrix.rfid.merg.concentrator.ConcentratorSensorManager; 013import jmri.jmrix.rfid.merg.concentrator.ConcentratorTrafficController; 014import jmri.jmrix.rfid.protocol.coreid.CoreIdRfidProtocol; 015import jmri.jmrix.rfid.protocol.em18.Em18RfidProtocol; 016import jmri.jmrix.rfid.protocol.olimex.OlimexRfid1356mifareProtocol; 017import jmri.jmrix.rfid.protocol.olimex.OlimexRfidProtocol; 018import jmri.jmrix.rfid.protocol.parallax.ParallaxRfidProtocol; 019import jmri.jmrix.rfid.protocol.seeedstudio.SeeedStudioRfidProtocol; 020import org.slf4j.Logger; 021import org.slf4j.LoggerFactory; 022 023/** 024 * Provide access to RFID devices via a serial com port. 025 * Derived from the Oaktree code. 026 * 027 * @author Bob Jacobsen Copyright (C) 2006, 2007, 2008 028 * @author Matthew Harris Copyright (C) 2011 029 * @author Oscar A. Pruitt Copyright (C) 2015 030 * @author B. Milhaupt Copyright (C) 2017 031 * @since 2.11.4 032 */ 033public class SerialDriverAdapter extends RfidPortController { 034 035 public SerialDriverAdapter() { 036 super(new RfidSystemConnectionMemo()); 037 option1Name = "Adapter"; // NOI18N 038 option2Name = "Concentrator-Range"; // NOI18N 039 option3Name = "Protocol"; // NOI18N 040 option4Name = "Device"; // NOI18N 041 options.put(option1Name, new Option(Bundle.getMessage("ConnectionAdapter"), new String[]{"Generic Stand-alone", "MERG Concentrator"}, false)); // NOI18N 042 options.put(option2Name, new Option(Bundle.getMessage("ConnectionConcentratorRange"), new String[]{"A-H", "I-P"}, false)); // NOI18N 043 options.put(option3Name, new Option(Bundle.getMessage("ConnectionProtocol"), new String[]{"CORE-ID", "Olimex", "Parallax", "SeeedStudio", "EM-18"}, false)); // NOI18N 044 options.put(option4Name, new Option(Bundle.getMessage("ConnectionDeviceType"), new String[]{"MOD-RFID125", "MOD-RFID1356MIFARE"}, false)); // NOI18N 045 this.manufacturerName = jmri.jmrix.rfid.RfidConnectionTypeList.RFID; 046 } 047 048 @Override 049 public String openPort(String portName, String appName) { 050 // get and open the primary port 051 currentSerialPort = activatePort(portName, log); 052 if (currentSerialPort == null) { 053 log.error("failed to connect RFID to {}", portName); 054 return Bundle.getMessage("SerialPortNotFound", portName); 055 } 056 log.info("Connecting RFID to {} {}", portName, currentSerialPort); 057 058 // try to set it for communication via SerialDriver 059 // find the baud rate value, configure comm options 060 int baud = currentBaudNumber(mBaudRate); 061 062 // the Parallax reader uses 2400 baud, so set that here 063 if (getOptionState(option3Name).equals("Parallax")) { 064 log.debug("Set baud rate to 2400 for Parallax reader"); 065 baud = 2400; 066 } 067 setBaudRate(currentSerialPort, baud); 068 configureLeads(currentSerialPort, true, true); 069 // find and configure flow control 070 FlowControl flow = FlowControl.NONE; // default 071 if (getOptionState(option1Name).equals("MERG Concentrator")) { 072 // Set Hardware Flow Control for Concentrator 073 log.debug("Set hardware flow control for Concentrator"); 074 flow = FlowControl.RTSCTS; 075 } 076 setFlowControl(currentSerialPort, flow); 077 078 // report status 079 reportPortStatus(log, portName); 080 081 opened = true; 082 083 return null; // indicates OK return 084 } 085 086 /** 087 * Can the port accept additional characters? 088 * 089 * @return always true 090 */ 091 public boolean okToSend() { 092 return true; 093 } 094 095 /** 096 * Set up all of the other objects to operate connected to this port 097 */ 098 @Override 099 public void configure() { 100 RfidTrafficController control; 101 RfidProtocol protocol; 102 103 // set up the system connection first 104 String opt1 = getOptionState(option1Name); 105 switch (opt1) { 106 case "Generic Stand-alone": // NOI18N 107 // create a Generic Stand-alone port controller 108 log.debug("Create Generic Standalone SpecificTrafficController"); // NOI18N 109 control = new StandaloneTrafficController(this.getSystemConnectionMemo()); 110 this.getSystemConnectionMemo().setRfidTrafficController(control); 111 this.getSystemConnectionMemo().configureManagers( 112 new StandaloneSensorManager(this.getSystemConnectionMemo()), 113 new StandaloneReporterManager(this.getSystemConnectionMemo())); 114 break; 115 case "MERG Concentrator": // NOI18N 116 // create a MERG Concentrator port controller 117 log.debug("Create MERG Concentrator SpecificTrafficController"); // NOI18N 118 control = new ConcentratorTrafficController(this.getSystemConnectionMemo(), getOptionState(option2Name)); 119 this.getSystemConnectionMemo().setRfidTrafficController(control); 120 this.getSystemConnectionMemo().configureManagers( 121 new ConcentratorSensorManager(this.getSystemConnectionMemo()), 122 new ConcentratorReporterManager(this.getSystemConnectionMemo())); 123 break; 124 default: 125 // no connection at all - warn 126 log.warn("adapter option {} defaults to Generic Stand-alone", opt1); // NOI18N 127 // create a Generic Stand-alone port controller 128 control = new StandaloneTrafficController(this.getSystemConnectionMemo()); 129 this.getSystemConnectionMemo().setRfidTrafficController(control); 130 this.getSystemConnectionMemo().configureManagers( 131 new StandaloneSensorManager(this.getSystemConnectionMemo()), 132 new StandaloneReporterManager(this.getSystemConnectionMemo())); 133 break; 134 } 135 136 // Now do the protocol 137 String opt3 = getOptionState(option3Name); 138 String opt4 = getOptionState(option4Name); 139 if (opt1.equals("MERG Concentrator")) { // NOI18N 140 // MERG Concentrator only supports CORE-ID 141 log.info("set protocol to CORE-ID"); // NOI18N 142 String opt2 = getOptionState(option2Name); 143 switch (opt2) { 144 case "A-H": // NOI18N 145 log.info("set concentrator range to 'A-H' at position 1"); // NOI18N 146 protocol = new CoreIdRfidProtocol('A', 'H', 1); 147 break; 148 case "I-P": // NOI18N 149 log.info("set concentrator range to 'I-P' at position 1"); // NOI18N 150 protocol = new CoreIdRfidProtocol('I', 'P', 1); 151 break; 152 default: 153 // unrecognised concentrator range - warn 154 log.warn("concentrator range '{}' not supported - default to no concentrator", opt2); // NOI18N 155 protocol = new CoreIdRfidProtocol(); 156 break; 157 } 158 } else { 159 switch (opt3) { 160 case "CORE-ID": // NOI18N 161 log.info("set protocol to CORE-ID"); // NOI18N 162 protocol = new CoreIdRfidProtocol(); 163 break; 164 case "Olimex": // NOI18N 165 if (opt4.equals("MOD-RFID1356MIFARE")) { // NOI18N 166 log.info("set protocol for Olimex MOD-RFID1356MIFARE"); // NOI18N 167 protocol = new OlimexRfid1356mifareProtocol(); 168 } else { 169 log.info("set protocol for Olimex MOD-RFID125"); // NOI18N 170 protocol = new OlimexRfidProtocol(); 171 } 172 break; 173 case "Parallax": // NOI18N 174 log.info("set protocol to Parallax"); // NOI18N 175 protocol = new ParallaxRfidProtocol(); 176 break; 177 case "SeeedStudio": // NOI18N 178 log.info("set protocol to SeeedStudio"); // NOI18N 179 protocol = new SeeedStudioRfidProtocol(); 180 break; 181 case "EM-18": // NOI18N 182 log.info("set protocol to EM-18"); // NOI18N 183 protocol = new Em18RfidProtocol(); 184 break; 185 default: 186 // no protocol at all - warn 187 log.warn("protocol option {} defaults to CORE-ID", opt3); 188 // create a coreid protocol 189 protocol = new CoreIdRfidProtocol(); 190 break; 191 } 192 } 193 this.getSystemConnectionMemo().setProtocol(protocol); 194 195 // connect to the traffic controller 196 this.getSystemConnectionMemo().setRfidTrafficController(control); 197 control.setAdapterMemo(this.getSystemConnectionMemo()); 198 control.connectPort(this); 199 control.sendInitString(); 200 } 201 202 // base class methods for the RfidPortController interface 203 204 @Override 205 public boolean status() { 206 return opened; 207 } 208 209 /** 210 * {@inheritDoc} 211 */ 212 @Override 213 public String[] validBaudRates() { 214 return Arrays.copyOf(validSpeeds, validSpeeds.length); 215 } 216 217 /** 218 * {@inheritDoc} 219 */ 220 @Override 221 public int[] validBaudNumbers() { 222 return Arrays.copyOf(validSpeedValues, validSpeedValues.length); 223 } 224 225 protected String[] validSpeeds = new String[]{Bundle.getMessage("BaudAutomatic")}; 226 protected int[] validSpeedValues = new int[]{9600}; 227 228 @Override 229 public int defaultBaudIndex() { 230 return 0; 231 } 232 233 // private control members 234 235 private static final Logger log = LoggerFactory.getLogger(SerialDriverAdapter.class); 236 237}