001package jmri.jmrix.rfid;
002
003import java.io.DataInputStream;
004import java.io.DataOutputStream;
005import jmri.jmrix.AbstractStreamPortController;
006import jmri.jmrix.rfid.generic.standalone.StandaloneReporterManager;
007import jmri.jmrix.rfid.generic.standalone.StandaloneSensorManager;
008import jmri.jmrix.rfid.generic.standalone.StandaloneTrafficController;
009import jmri.jmrix.rfid.merg.concentrator.ConcentratorReporterManager;
010import jmri.jmrix.rfid.merg.concentrator.ConcentratorSensorManager;
011import jmri.jmrix.rfid.merg.concentrator.ConcentratorTrafficController;
012import jmri.jmrix.rfid.protocol.coreid.CoreIdRfidProtocol;
013import jmri.jmrix.rfid.protocol.em18.Em18RfidProtocol;
014import jmri.jmrix.rfid.protocol.olimex.OlimexRfid1356mifareProtocol;
015import jmri.jmrix.rfid.protocol.olimex.OlimexRfidProtocol;
016import jmri.jmrix.rfid.protocol.parallax.ParallaxRfidProtocol;
017import jmri.jmrix.rfid.protocol.seeedstudio.SeeedStudioRfidProtocol;
018import org.slf4j.Logger;
019import org.slf4j.LoggerFactory;
020
021/**
022 * Abstract base for classes representing a RFID communications port
023 * <p>
024 * NOTE: This currently only supports the standalone RFID interfaces.
025 *
026 * @author Paul Bender Copyright (C) 2014
027 */
028public class RfidStreamPortController extends AbstractStreamPortController implements RfidInterface {
029
030    public RfidStreamPortController(DataInputStream in, DataOutputStream out, String pname) {
031        super(new RfidSystemConnectionMemo(),in,out,pname);
032        option1Name = "Adapter"; // NOI18N
033        option2Name = "Concentrator-Range"; // NOI18N
034        option3Name = "Protocol"; // NOI18N
035        option4Name = "Device"; // NOI18N
036        options.put(option1Name, new Option(Bundle.getMessage("ConnectionAdapter"), new String[]{"Generic Stand-alone", "MERG Concentrator"}, false)); // NOI18N
037        options.put(option2Name, new Option(Bundle.getMessage("ConnectionConcentratorRange"), new String[]{"A-H", "I-P"}, false)); // NOI18N
038        options.put(option3Name, new Option(Bundle.getMessage("ConnectionProtocol"), new String[]{"CORE-ID", "Olimex", "Parallax", "SeeedStudio", "EM-18"}, false)); // NOI18N
039        options.put(option4Name, new Option(Bundle.getMessage("ConnectionDeviceType"), new String[]{"MOD-RFID125", "MOD-RFID1356MIFARE"}, false)); // NOI18N
040        this.manufacturerName = jmri.jmrix.rfid.RfidConnectionTypeList.RFID;
041    }
042
043    public RfidStreamPortController() {
044        super(new RfidSystemConnectionMemo());
045        option1Name = "Adapter"; // NOI18N
046        option2Name = "Concentrator-Range"; // NOI18N
047        option3Name = "Protocol"; // NOI18N
048        option4Name = "Device"; // NOI18N
049        options.put(option1Name, new Option(Bundle.getMessage("ConnectionAdapter"), new String[]{"Generic Stand-alone", "MERG Concentrator"}, false)); // NOI18N
050        options.put(option2Name, new Option(Bundle.getMessage("ConnectionConcentratorRange"), new String[]{"A-H", "I-P"}, false)); // NOI18N
051        options.put(option3Name, new Option(Bundle.getMessage("ConnectionProtocol"), new String[]{"CORE-ID", "Olimex", "Parallax", "SeeedStudio", "EM-18"}, false)); // NOI18N
052        options.put(option4Name, new Option(Bundle.getMessage("ConnectionDeviceType"), new String[]{"MOD-RFID125", "MOD-RFID1356MIFARE"}, false)); // NOI18N
053        this.manufacturerName = jmri.jmrix.rfid.RfidConnectionTypeList.RFID;
054    }
055
056    @Override
057    public void configure() {
058        log.debug("configure() called.");
059        RfidTrafficController control;
060        RfidProtocol protocol;
061
062        // set up the system connection first
063        String opt1 = getOptionState(option1Name);
064        switch (opt1) {
065            case "Generic Stand-alone": // NOI18N
066                // create a Generic Stand-alone port controller
067                log.debug("Create Generic Standalone SpecificTrafficController"); // NOI18N
068                control = new StandaloneTrafficController(this.getSystemConnectionMemo());
069                this.getSystemConnectionMemo().setRfidTrafficController(control);
070                this.getSystemConnectionMemo().configureManagers(
071                        new StandaloneSensorManager(this.getSystemConnectionMemo()),
072                        new StandaloneReporterManager(this.getSystemConnectionMemo()));
073                break;
074            case "MERG Concentrator": // NOI18N
075                // create a MERG Concentrator port controller
076                log.debug("Create MERG Concentrator SpecificTrafficController"); // NOI18N
077                control = new ConcentratorTrafficController(this.getSystemConnectionMemo(), getOptionState(option2Name));
078                this.getSystemConnectionMemo().configureManagers(
079                        new ConcentratorSensorManager(this.getSystemConnectionMemo()),
080                        new ConcentratorReporterManager(this.getSystemConnectionMemo()));
081                break;
082            default:
083                // no connection at all - warn
084                log.warn("adapter option {} defaults to Generic Stand-alone", opt1); // NOI18N
085                // create a Generic Stand-alone port controller
086                control = new StandaloneTrafficController(this.getSystemConnectionMemo());
087                this.getSystemConnectionMemo().configureManagers(
088                        new StandaloneSensorManager(this.getSystemConnectionMemo()),
089                        new StandaloneReporterManager(this.getSystemConnectionMemo()));
090                break;
091        }
092
093        // Now do the protocol
094        String opt3 = getOptionState(option3Name);
095        String opt4 = getOptionState(option4Name);
096        if (opt1.equals("MERG Concentrator")) { // NOI18N
097            // MERG Concentrator only supports CORE-ID
098            log.info("set protocol to CORE-ID"); // NOI18N
099            String opt2 = getOptionState(option2Name);
100            switch (opt2) {
101                case "A-H": // NOI18N
102                    log.info("set concentrator range to 'A-H' at position 1"); // NOI18N
103                    protocol = new CoreIdRfidProtocol('A', 'H', 1);
104                    break;
105                case "I-P": // NOI18N
106                    log.info("set concentrator range to 'I-P' at position 1"); // NOI18N
107                    protocol = new CoreIdRfidProtocol('I', 'P', 1);
108                    break;
109                default:
110                    // unrecognised concentrator range - warn
111                    log.warn("concentrator range '{}' not supported - default to no concentrator", opt2); // NOI18N
112                    protocol = new CoreIdRfidProtocol();
113                    break;
114            }
115        } else {
116            switch (opt3) {
117                case "CORE-ID": // NOI18N
118                    log.info("set protocol to CORE-ID"); // NOI18N
119                    protocol = new CoreIdRfidProtocol();
120                    break;
121                case "Olimex": // NOI18N
122                    if (opt4.equals("MOD-RFID1356MIFARE")) { // NOI18N
123                        log.info("set protocol for Olimex MOD-RFID1356MIFARE"); // NOI18N
124                        protocol = new OlimexRfid1356mifareProtocol();
125                    } else {
126                        log.info("set protocol for Olimex MOD-RFID125"); // NOI18N
127                        protocol = new OlimexRfidProtocol();
128                    }
129                    break;
130                case "Parallax": // NOI18N
131                    log.info("set protocol to Parallax"); // NOI18N
132                    protocol = new ParallaxRfidProtocol();
133                    break;
134                case "SeeedStudio": // NOI18N
135                    log.info("set protocol to SeeedStudio"); // NOI18N
136                    protocol = new SeeedStudioRfidProtocol();
137                    break;
138                case "EM-18": // NOI18N
139                    log.info("set protocol to EM-18"); // NOI18N
140                    protocol = new Em18RfidProtocol();
141                    break;
142                default:
143                    // no protocol at all - warn
144                    log.warn("protocol option {} defaults to CORE-ID", opt3);
145                    // create a coreid protocol
146                    protocol = new CoreIdRfidProtocol();
147                    break;
148            }
149        }
150        this.getSystemConnectionMemo().setProtocol(protocol);
151
152        // connect to the traffic controller
153        this.getSystemConnectionMemo().setRfidTrafficController(control);
154        control.setAdapterMemo(this.getSystemConnectionMemo());
155        this.getSystemConnectionMemo().configureManagers(
156                new StandaloneSensorManager(this.getSystemConnectionMemo()),
157                new StandaloneReporterManager(this.getSystemConnectionMemo()));
158        control.connectPort(this);
159    }
160
161    /**
162     * Check that this object is ready to operate. This is a question of
163     * configuration, not transient hardware status.
164     *
165     * @return true
166     */
167    @Override
168    public boolean status() {
169        return true;
170    }
171
172    /**
173     * Can the port accept additional characters?
174     *
175     * @return true
176     */
177    public boolean okToSend() {
178        return (true);
179    }
180
181    // RFID Interface methods.
182    @Override
183    public void addRfidListener(RfidListener l) {
184        this.getSystemConnectionMemo().getTrafficController().addRfidListener(l);
185    }
186
187    @Override
188    public void removeRfidListener(RfidListener l) {
189        this.getSystemConnectionMemo().getTrafficController().removeRfidListener(l);
190    }
191
192    @Override
193    public void sendRfidMessage(RfidMessage m, RfidListener l) {
194        this.getSystemConnectionMemo().getTrafficController().sendRfidMessage(m, l);
195    }
196
197    @Override
198    public RfidSystemConnectionMemo getSystemConnectionMemo() {
199        return (RfidSystemConnectionMemo) super.getSystemConnectionMemo();
200    }
201
202    private final static Logger log = LoggerFactory.getLogger(RfidStreamPortController.class);
203
204}