001package jmri.jmrix.rfid.protocol.olimex;
002
003import jmri.jmrix.AbstractMRReply;
004import jmri.jmrix.rfid.RfidProtocol;
005import org.slf4j.Logger;
006import org.slf4j.LoggerFactory;
007
008/**
009 * Common routines to extract the Tag information and validate checksum for
010 * implementations that use the Olimex protocol.
011 * <hr>
012 * This file is part of JMRI.
013 * <p>
014 * JMRI is free software; you can redistribute it and/or modify it under the
015 * terms of version 2 of the GNU General Public License as published by the Free
016 * Software Foundation. See the "COPYING" file for a copy of this license.
017 * <p>
018 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
019 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
020 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
021 *
022 * @author Matthew Harris Copyright (C) 2014
023 * @since 3.9.2
024 */
025public class OlimexRfidProtocol extends RfidProtocol {
026
027    public static final int SPECIFICMAXSIZE = 16;
028
029    public static final int getMaxSize() {
030        return SPECIFICMAXSIZE;
031    }
032
033    @Override
034    public String initString() {
035        // Continuous scanning, single report per seen tag
036        return "mc00"; // NOI18N
037    }
038
039    @Override
040    public String getTag(AbstractMRReply msg) {
041        StringBuilder sb = new StringBuilder(10);
042
043        for (int i = 3; i < 13; i++) {
044            sb.append((char) msg.getElement(i));
045        }
046
047        return sb.toString();
048    }
049
050    @Override
051    public String getCheckSum(AbstractMRReply msg) {
052        return "";
053    }
054
055    @Override
056    public boolean isValid(AbstractMRReply msg) {
057        return ((!isConcentrator && msg.getElement(2) == 0x2D)
058                || (isConcentrator
059                && msg.getElement(portPosition) >= concentratorFirst
060                && msg.getElement(portPosition) <= concentratorLast))
061                && msg.getElement(SPECIFICMAXSIZE - 1) == 0x3E;
062    }
063
064    @Override
065    public boolean endOfMessage(AbstractMRReply msg) {
066        if (msg.getNumDataElements() == SPECIFICMAXSIZE) {
067            if ((msg.getElement(SPECIFICMAXSIZE - 1) & 0xFF) == 0x3E
068                    && (msg.getElement(SPECIFICMAXSIZE - 2) & 0xFF) == 0x0A
069                    && (msg.getElement(SPECIFICMAXSIZE - 3) & 0xFF) == 0x0D) {
070                return true;
071            }
072            if (log.isDebugEnabled()) {
073                log.debug("Not a correctly formed message"); // NOI18N
074            }
075            return true;
076        }
077        return false;
078    }
079
080    @Override
081    public String toMonitorString(AbstractMRReply msg) {
082        // check for valid message
083        if (isValid(msg)) {
084            StringBuilder sb = new StringBuilder();
085            sb.append("Reply from Olimex reader.");
086            if (isConcentrator) {
087                sb.append(" Reply from port ");
088                sb.append(getReaderPort(msg));
089            }
090            sb.append(" Tag read ");
091            sb.append(getTag(msg));
092            return sb.toString();
093        } else {
094            return super.toMonitorString(msg);
095        }
096    }
097
098    private static final Logger log = LoggerFactory.getLogger(OlimexRfidProtocol.class);
099
100}