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 MOD-RFID1356MIFARE 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 * @author B. Milhaupt Copyright (C) 2017 024 * @since 4.9.4 025 */ 026public class OlimexRfid1356mifareProtocol extends RfidProtocol { 027 028 public static final int SPECIFICMAXSIZE = 13; 029 public final String initialize = "mt100\r\ne0\r\n"; // NOI18N 030 031 public static final int getMaxSize() { 032 return SPECIFICMAXSIZE; 033 } 034 035 @Override 036 public String initString() { 037 // Continuous scanning, single report per seen tag 038 return initialize; 039 } 040 041 @Override 042 public String getTag(AbstractMRReply msg) { 043 StringBuilder sb = new StringBuilder(10); 044 045 for (int i = 3; i < SPECIFICMAXSIZE-2; i++) { 046 sb.append((char) msg.getElement(i)); 047 } 048 049 return sb.toString(); 050 } 051 052 @Override 053 public String getCheckSum(AbstractMRReply msg) { 054 return ""; 055 } 056 057 @Override 058 public boolean isValid(AbstractMRReply msg) { 059 /* Typical message of "tag receive": 060 \r\n-C4178b55\r\n 061 */ 062 return ((!isConcentrator && msg.getElement(2) == 0x2D) 063 || (isConcentrator 064 && msg.getElement(portPosition) >= concentratorFirst 065 && msg.getElement(portPosition) <= concentratorLast)) 066 && msg.getElement(SPECIFICMAXSIZE - 1) == 0x0A; 067 } 068 069 @Override 070 public boolean endOfMessage(AbstractMRReply msg) { 071 if (msg.getNumDataElements() == SPECIFICMAXSIZE) { 072 /* Check end of expected response to tag read message: 073 \r\n-C4178b55\r\n 074 */ 075 if (((msg.getElement(SPECIFICMAXSIZE - 1) & 0xFF) == 0x0A) 076 && ((msg.getElement(SPECIFICMAXSIZE - 2) & 0xFF) == 0x0D) 077 && ((msg.getElement(SPECIFICMAXSIZE - 3) & 0xFF) != 0x0D) 078 && ((msg.getElement(SPECIFICMAXSIZE - 3) & 0xFF) != 0x0A)) { 079 return true; 080 } 081 /* Check end of message of expected response to init message: 082 mt100 083 OK>e0 084 OK> 085 086 or, in hex: 087 6Dh 74h 31h 30h 30h 0Dh0Ah 088 4Fh 4Bh 0Ah 0Dh3Eh 07h 65h 30h 0Dh0Ah 089 4Fh 4Bh 0Ah 0Dh3Eh 07h 090 */ 091 092 int i; 093 for (i = 0; i < initialize.length(); ++ i) { 094 if (msg.getElement(i) != initialize.charAt(i)) { 095 return false; 096 } 097 } 098 if (msg.getElement(i) != 'O') return false; 099 if (msg.getElement(i+1) != 'K') return false; 100 if (msg.getElement(i+2) != '\n') return false; 101 if (msg.getElement(i+3) != '\r') return false; 102 if (msg.getElement(i+4) != '>') return false; 103 if (msg.getElement(i+5) != 0x07) return false; 104 if (msg.getElement(i+6) != 'e') return false; 105 if (msg.getElement(i+7) != '0') return false; 106 if (msg.getElement(i+8) != '\n') return false; 107 if (msg.getElement(i+9) != '\r') return false; 108 if (msg.getElement(i+10) != 'O') return false; 109 if (msg.getElement(i+11) != 'K') return false; 110 111 if (log.isDebugEnabled()) { 112 log.debug("Not a correctly formed message"); // NOI18N 113 } 114 return true; 115 } 116 return false; 117 } 118 119 @Override 120 public String toMonitorString(AbstractMRReply msg) { 121 // check for valid message 122 if (isValid(msg)) { 123 StringBuilder sb = new StringBuilder(); 124 sb.append("Reply from Olimex MOD-RFID1356MIFARE reader."); 125 if (isConcentrator) { 126 sb.append(" Reply from port "); 127 sb.append(getReaderPort(msg)); 128 } 129 sb.append(" Tag read "); 130 sb.append(getTag(msg)); 131 return sb.toString(); 132 } else { 133 return super.toMonitorString(msg); 134 } 135 } 136 137 private static final Logger log = LoggerFactory.getLogger(OlimexRfid1356mifareProtocol.class.getName()); 138 139}