Browse Source

VorgeaUR0401ServerHandler

rainbow954 7 years ago
parent
commit
decbd1524b
22 changed files with 4212 additions and 3 deletions
  1. 190 0
      src/main/java/com/tidecloud/dataacceptance/common/Converter.java
  2. 284 0
      src/main/java/com/tidecloud/dataacceptance/common/StringTool.java
  3. 1081 0
      src/main/java/com/tidecloud/dataacceptance/rfid/RFIDReaderHelper.java
  4. 89 0
      src/main/java/com/tidecloud/dataacceptance/rfid/ReaderConnector.java
  5. 63 0
      src/main/java/com/tidecloud/dataacceptance/rfid/ReaderDataPackageParser.java
  6. 19 0
      src/main/java/com/tidecloud/dataacceptance/rfid/ReaderDataPackageProcess.java
  7. 170 0
      src/main/java/com/tidecloud/dataacceptance/rfid/bean/MessageTran.java
  8. 203 0
      src/main/java/com/tidecloud/dataacceptance/rfid/config/CMD.java
  9. 187 0
      src/main/java/com/tidecloud/dataacceptance/rfid/config/ERROR.java
  10. 6 0
      src/main/java/com/tidecloud/dataacceptance/rfid/config/HEAD.java
  11. 19 0
      src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/DataPackageParser.java
  12. 20 0
      src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/DataPackageProcess.java
  13. 38 0
      src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/ModuleConnector.java
  14. 30 0
      src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/RXTXListener.java
  15. 368 0
      src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/ReaderHelper.java
  16. 1051 0
      src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/RXObserver.java
  17. 171 0
      src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/ReaderSetting.java
  18. 26 0
      src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/bean/RXInventory6BTag.java
  19. 81 0
      src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/bean/RXInventoryTag.java
  20. 37 0
      src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/bean/RXOperationTag.java
  21. 67 0
      src/main/java/com/tidecloud/dataacceptance/service/impl/VorgeaUR0401ServerHandler.java
  22. 12 3
      src/main/resources/application.yml

+ 190 - 0
src/main/java/com/tidecloud/dataacceptance/common/Converter.java

@@ -0,0 +1,190 @@
+package com.tidecloud.dataacceptance.common;
+
+public class Converter {
+	/**
+	 * Data storage mode little endian.
+	 */
+	public static final int LITTLE_ENDIAN = 0;
+	/**
+	 * Data storage mode big endian.
+	 */
+	public static final int BIG_ENDIAN = 1;
+	
+	/**
+	 * converter int into byte array 
+	 * @param number  the number to be converted
+	 * @param order   according to the storage way of int, converter to byte array  
+	 * @return        bytes array after converted  
+	 */
+	public static byte[] getBytes(int number, int order) {
+		int temp = number;
+		byte[] b = new byte[4];
+		
+		if (order == LITTLE_ENDIAN) {
+			for (int i = b.length - 1; i >= 0; i--) {
+				b[i] = new Long(temp & 0xff).byteValue();
+				temp = temp >> 8;
+			}
+		} else {
+			for (int i = 0; i < b.length; i++) {
+				b[i] = new Long(temp & 0xff).byteValue();
+				temp = temp >> 8;
+			}
+		}
+
+		return b;
+
+	}
+	
+	/**
+	 * converter long into bytes array   
+	 * @param number   number to be converted
+	 * @param order    according to the storage way of long, converter to byte array
+	 * @return         bytes array after converted 
+	 */
+	public static byte[] getBytes(long number, int order) {
+		long temp = number;
+		byte[] b = new byte[8];
+		
+		if (order == LITTLE_ENDIAN) {
+			for (int i = b.length - 1; i >= 0; i--) {
+				b[i] = new Long(temp & 0xff).byteValue();
+				temp = temp >> 8;
+			}
+		} else {
+			for (int i = 0; i < b.length; i++) {
+				b[i] = new Long(temp & 0xff).byteValue();
+				temp = temp >> 8;
+			}
+		}
+
+		return b;
+
+	}
+	
+	/**
+	 * converter short into bytes array 
+	 * @param number   number to be converted
+	 * @param order    according to the storage way of short, converter to byte array
+	 * @return         bytes array after converted  
+	 */
+	public static byte[] getBytes(short number, int order) {
+		int temp = number;
+		byte[] b = new byte[8];
+		
+		if (order == LITTLE_ENDIAN) {
+			for (int i = b.length - 1; i >= 0; i--) {
+				b[i] = new Long(temp & 0xff).byteValue();
+				temp = temp >> 8;
+			}
+		} else {
+			for (int i = 0; i < b.length; i++) {
+				b[i] = new Long(temp & 0xff).byteValue();
+				temp = temp >> 8;
+			}
+		}
+
+		return b;
+
+	}
+
+	/**
+	 * converter byte array into long  
+	 * @param b       byte array to be converted
+	 * @param order   according to the format, converter to long 
+	 * @return        long after converted
+	 */
+	public static long byteToLong(byte[] b, int order) {
+		long s = 0;
+		long s0 = b[0] & 0xff;
+		long s1 = b[1] & 0xff;
+		long s2 = b[2] & 0xff;
+		long s3 = b[3] & 0xff;
+		long s4 = b[4] & 0xff;
+		long s5 = b[5] & 0xff;
+		long s6 = b[6] & 0xff;
+		long s7 = b[7] & 0xff;
+
+		if (order == LITTLE_ENDIAN) {
+			s1 <<= 8 * 1;
+			s2 <<= 8 * 2;
+			s3 <<= 8 * 3;
+			s4 <<= 8 * 4;
+			s5 <<= 8 * 5;
+			s6 <<= 8 * 6;
+			s7 <<= 8 * 7;
+		} else {
+			s0 <<= 8 * 7;
+			s1 <<= 8 * 6;
+			s2 <<= 8 * 5;
+			s3 <<= 8 * 4;
+			s4 <<= 8 * 3;
+			s5 <<= 8 * 2;
+			s6 <<= 8 * 1;
+		}
+		s = s0 | s1 | s2 | s3 | s4 | s5 | s6 | s7;
+
+		return s;
+	}
+
+	/**
+	 * converter byte array into int  
+	 * @param b       byte array to be converted 
+	 * @param order   according to the format, converter to int  
+	 * @return        int after converted  
+	 */
+	public static int byteToInt(byte[] b, int order) {
+		int s = 0;
+		int s0 = b[0] & 0xff;
+		int s1 = b[1] & 0xff;
+		int s2 = b[2] & 0xff;
+		int s3 = b[3] & 0xff;
+		
+		if (order == LITTLE_ENDIAN) {
+			s2 <<= 8;
+			s1 <<= 16;
+			s0 <<= 24;
+		} else {
+			s3 <<= 24;
+			s2 <<= 16;
+			s1 <<= 8;
+		}
+		
+		s = s0 | s1 | s2 | s3;
+
+		return s;
+	}
+
+	/**
+	 * converter byte array into short  
+	 * @param b       byte array number to be converted
+	 * @param order   according to the format, converter to short  
+	 * @return        short after converted  
+	 */
+	public static short byteToShort(byte[] b, int order) {
+		short s = 0;
+		short s0 = (short) (b[0] & 0xff);
+		short s1 = (short) (b[1] & 0xff);
+		
+		if (order == LITTLE_ENDIAN) {
+			s0 <<= 8;
+			s = (short) (s0 | s1);
+		} else {
+			s1 <<= 8;
+			s = (short) (s0 | s1);
+		}
+		
+		return s;
+	}
+	
+	/**
+	 * byte convert to char
+	 * @param i need converted byte
+	 * @return char converted
+	 */
+	public static char byteToHex(int i) {
+		if (i >= 0 && i < 16)
+			return "0123456789ABCDEF".charAt(i);
+		return 'G';
+	}
+}

+ 284 - 0
src/main/java/com/tidecloud/dataacceptance/common/StringTool.java

@@ -0,0 +1,284 @@
+package com.tidecloud.dataacceptance.common;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
+/**
+ * The tool class about byte array and String convert.
+ *
+ */
+
+public class StringTool {
+
+	/**
+	 * Convert the hex string to byte array;
+	 * @param strHexValue the hex string value.
+	 * @return byte[] the resolved value.
+	 */
+	public static byte[] stringToByteArray(String strHexValue) {
+		String[] strAryHex = strHexValue.split(" ");
+        byte[] btAryHex = new byte[strAryHex.length];
+
+        try {
+			int nIndex = 0;
+			for (String strTemp : strAryHex) {
+			    btAryHex[nIndex] = (byte) Integer.parseInt(strTemp, 16);
+			    nIndex++;
+			}
+        } catch (NumberFormatException e) {
+
+        }
+
+        return btAryHex;
+    }
+
+	/**
+	 * Convert the Hex string array to byte array 
+	 * @param strAryHex the hex string value.
+	 * @param nLen the needed parse length.
+	 * @return byte[] the resolved value.
+	 */
+    public static byte[] stringArrayToByteArray(String[] strAryHex, int nLen) {
+    	if (strAryHex == null) return null;
+
+    	if (strAryHex.length < nLen) {
+    		nLen = strAryHex.length;
+    	}
+
+    	byte[] btAryHex = new byte[nLen];
+
+    	try {
+    		for (int i = 0; i < nLen; i++) {
+    			btAryHex[i] = (byte) Integer.parseInt(strAryHex[i], 16);
+    		}
+    	} catch (NumberFormatException e) {
+	
+        }
+
+    	return btAryHex;
+    }
+
+	/**
+	 * Convert the Hex string array to byte array
+	 * @param btAryHex the hex string value.
+	 * @param nIndex the starting parse position.
+	 * @param nLen the needed parse length.
+	 * @return byte[] the resolved value.
+	 */
+    public static String byteArrayToString(byte[] btAryHex, int nIndex, int nLen) {
+    	if (nIndex + nLen > btAryHex.length) {
+    		nLen = btAryHex.length - nIndex;
+    	}
+
+    	String strResult = String.format("%02X", btAryHex[nIndex]);
+    	for (int nloop = nIndex + 1; nloop < nIndex + nLen; nloop++ ) {
+    		String strTemp = String.format("%02X", btAryHex[nloop]);
+
+    		strResult += strTemp;
+    	}
+
+    	return strResult;
+    }
+
+	/**
+	 * Convert the String to StringArray
+	 * @param strValue the src string
+	 * @param nLen needed convert length
+	 * @return String[] the parsed value.
+	 */
+    public static String[] stringToStringArray(String strValue, int nLen) {
+        String[] strAryResult = null;
+
+        if (strValue != null && !strValue.equals("")) {
+            ArrayList<String> strListResult = new ArrayList<String>();
+            String strTemp = "";
+            int nTemp = 0;
+
+            for (int nloop = 0; nloop < strValue.length(); nloop++) {
+                if (strValue.charAt(nloop) == ' ') {
+                    continue;
+                } else {
+                    nTemp++;
+                    
+                    if (!Pattern.compile("^(([A-F])*([a-f])*(\\d)*)$")
+                    		.matcher(strValue.substring(nloop, nloop + 1))
+                    		.matches()) {
+                        return strAryResult;
+                    }
+
+                    strTemp += strValue.substring(nloop, nloop + 1);
+
+                    if ((nTemp == nLen) || (nloop == strValue.length() - 1 
+                    		&& (strTemp != null && !strTemp.equals("")))) {
+                        strListResult.add(strTemp);
+                        nTemp = 0;
+                        strTemp = "";
+                    }
+                }
+            }
+
+            if (strListResult.size() > 0) {
+            	strAryResult = new String[strListResult.size()];
+                for (int i = 0; i < strAryResult.length; i++) {
+                	strAryResult[i] = strListResult.get(i);
+                }
+            }
+        }
+
+        return strAryResult;
+    }
+
+	/**
+	 * Convert the byte array to special encode char array.
+	 * @param bytes the needed byte array.
+	 * @param encoding the encoding format.
+     * @return char[] the converted char array.
+     */
+	@Deprecated
+	public static char[] getChars (byte[] bytes,String encoding) {
+		Charset cs = Charset.forName (encoding);
+		ByteBuffer bb = ByteBuffer.allocate (bytes.length);
+		bb.put (bytes);
+		bb.flip ();
+		CharBuffer cb = cs.decode (bb);
+		return cb.array();
+	}
+
+	/**
+	 * resolve the bytes String data to ASCII.String like this "2f3Eab"
+	 * @param hexString the needed parse data.
+	 * @return String the return value.
+     */
+	@Deprecated
+	public static String toASCIIString(String hexString){
+		StringBuilder stringBuilder = new StringBuilder();
+		int i = 0;
+		while (i < hexString.length()){
+			stringBuilder.append((char)Integer.parseInt(hexString.substring(i,i + 2),16));
+			i = i +2;
+		}
+		return stringBuilder.toString();
+	}
+
+	/**
+	 * Resolve the bytes String data to ASCII.String like this "2f3Eab"
+	 * @param hexString the needed parse data.
+	 * @return String the return value.
+	 */
+	public static String hexStringToASCIIString(String hexString) {
+		StringBuilder stringBuilder = new StringBuilder();
+		if (hexString == null || hexString.equals("")) {
+			return null;
+		}
+		for (int i = 0; i < hexString.length(); i = i + 2){
+			char high = hexString.charAt(i);
+			char low = hexString.charAt(i+1);
+
+			char no = (char)(charToInt(high)* 16 + charToInt(low));
+			stringBuilder.append(no);
+		}
+		return stringBuilder.toString();
+	}
+	
+	/**
+	 * Convert the char 1-f to int value; 
+	 * @param c the needed converter character.
+	 * @return int the converted value.
+	 */
+
+	private static int charToInt(char c){
+		int num = -1;
+		num = "0123456789ABCDEF".indexOf(String.valueOf(c));
+		if (num < 0)
+			num = "0123456789abcdef".indexOf(String.valueOf(c));
+		return num;
+	}
+
+	/**
+	 * Get the sub bytes of the parent bytes;
+	 * @param bytes parent bytes;
+	 * @param start start position;
+	 * @param end end position;
+     * @return the child bytes;
+     */
+	public static byte[] subBytes(byte[] bytes, int start, int end){
+        byte[] subBytes = new byte[end - start];
+		System.arraycopy(bytes,start,subBytes,0,end - start);
+		return subBytes;
+	}
+
+	/**
+	 * Get the child position in their parents string 
+	 * @param parentBytes parent bytes;
+	 * @param childBytes child bytes;
+	 * @param startPosition start scan position;
+     * @return if -1 child not in parent string,or the child first position found in parent;
+     */
+	public static int subBytesContains(byte[] parentBytes, byte[] childBytes, int startPosition){
+		if (parentBytes.length < childBytes.length)
+			return -1;
+		for (int i = startPosition; i < parentBytes.length; i++){
+			for (int j = 0; j < childBytes.length; j++){
+				 if (parentBytes[i + j] == childBytes[j]){
+					 if (j == childBytes.length - 1)
+						 return i;
+					 continue;
+				 } else {
+					 break;
+				 }
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * Convert hexString to byte array.
+	 * @param hexString to bytes
+	 * @return The converted byte array.
+	 */
+	public static byte[] hexStringToBytes(String hexString){
+		byte[] bytes = new byte[hexString.length()/2];
+		if (hexString == null || hexString.equals("")) {
+			return null;
+		}
+		for (int i = 0; i < hexString.length(); i = i + 2){
+			char high = hexString.charAt(i);
+			char low = hexString.charAt(i+1);
+
+			bytes[i/2] = (byte) (charToInt(high)* 16 + charToInt(low));
+		}
+		return bytes;
+	}
+	
+	/**
+	 * Compare the both byte array
+	 * @param first the first byte array
+	 * @param second the second byte array 
+	 * @return if true first equals second ,otherwise unequal 
+	 */
+	public static boolean compareBytes(byte[] first,byte[] second){
+		if (first.length != second.length)
+			return false;
+		for (int i = 0; i < first.length; i++){
+			if (first[i] != second[i])
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Convert Ascii string to byte array.
+	 * @param string the needed converter data.
+	 * @return byte[] the converted value.
+     */
+	public static byte[] asciiStringToBytes(String string){
+		byte[] result = new byte[string.length()];
+		for (int i = 0; i < string.length(); i++) {
+			result[i] = (byte) string.charAt(i);
+		}
+		return result;
+	}
+}

+ 1081 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/RFIDReaderHelper.java

@@ -0,0 +1,1081 @@
+package com.tidecloud.dataacceptance.rfid;
+
+import com.tidecloud.dataacceptance.common.Converter;
+import com.tidecloud.dataacceptance.rfid.bean.MessageTran;
+import com.tidecloud.dataacceptance.rfid.config.CMD;
+import com.tidecloud.dataacceptance.rfid.module.interaction.ReaderHelper;
+
+/**
+ * The core class to operate RFID reader.You can send command to RFID reader via the methods.
+ * And you can receive the return data via register {@link #Observer} or if you want show the
+ * return data in UI ,you can register {@link #HandlerObserver}.
+ */
+public class RFIDReaderHelper extends ReaderHelper {
+	
+	RFIDReaderHelper() {
+		super();
+	}
+    private int sendMessage(byte btReadId, byte btCmd) {
+        MessageTran msgTran = new MessageTran(btReadId, btCmd);
+        return sendCommand(msgTran.getAryTranData());
+    }
+
+    private int sendMessage(byte btReadId, byte btCmd, byte[] btAryData) {
+        MessageTran msgTran = new MessageTran(btReadId, btCmd, btAryData);
+        return sendCommand(msgTran.getAryTranData());
+    }
+
+    /**
+     * Reset the specified address reader.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int reset(byte btReadId) {
+
+        byte btCmd = CMD.RESET;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Set the Serial Communication Baudrate.
+     * @param btReadId			Reader Address(0xFF Public Address)
+     * @param nIndexBaudrate	Baudrate(0x03: 38400bps, 0x04:115200 bps)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setUartBaudrate(byte btReadId, byte nIndexBaudrate) {
+        byte btCmd = CMD.SET_UART_BAUDRATE;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = nIndexBaudrate;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Get Reader Firmware Version.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getFirmwareVersion(byte btReadId) {
+        byte btCmd = CMD.GET_FIRMWARE_VERSION;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Set Reader Address.
+     * @param btReadId		Original Reader Address(0xFF Public Address)
+     * @param btNewReadId	New Reader Address,value range0-254(0x00-0xFE)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setReaderAddress(byte btReadId, byte btNewReadId) {
+        byte btCmd = CMD.SET_READER_ADDRESS;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btNewReadId;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Set work antenna.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btWorkAntenna	Ant ID(0x00:Ant 1, 0x01:Ant 2, 0x02:Ant 3, 0x03:Ant 4,0x04:Ant 5, 0x05:Ant 6, 0x06:Ant 7, 0x07:Ant 8)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setWorkAntenna(byte btReadId, byte btWorkAntenna) {
+        byte btCmd = CMD.SET_WORK_ANTENNA;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btWorkAntenna;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Query working antenna.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getWorkAntenna(byte btReadId) {
+        byte btCmd = CMD.GET_WORK_ANTENNA;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Set output power(Set the same output power of all antennas).
+     * <br> This command consumes more than 100mS.
+     * <br> If you want you change the output power frequently, please use Cmd_set_temporary_output_power command, which doesn't reduce the life of the internal flash memory.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btOutputPower	RF output power, range from 0 to 33(0x00 - 0x21), the unit is dBm.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setOutputPower(byte btReadId, byte btOutputPower) {
+        byte btCmd = CMD.SET_OUTPUT_POWER;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btOutputPower;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Set output power(Set the different output power for 4 antennas). <br>
+     * This command consumes more than 100mS. <br>
+     * If you want you change the output power frequently, please use
+     * Cmd_set_temporary_output_power command, which doesn't reduce the life of
+     * the internal flash memory.
+     *
+     * @param btReadId
+     *            Reader Address(0xFF Public Address)
+     * @param btPower1
+     *            Output power of antenna 1, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower2
+     *            Output power of antenna 2, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower3
+     *            Output power of antenna 3, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower4
+     *            Output power of antenna 4, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @return Succeeded :0, Failed:-1
+     */
+    public final int setOutputPower(byte btReadId, byte btPower1, byte btPower2, byte btPower3, byte btPower4) {
+        byte btCmd = CMD.SET_OUTPUT_POWER;
+        byte[] btAryData = new byte[4];
+
+        btAryData[0] = btPower1;
+        btAryData[1] = btPower2;
+        btAryData[2] = btPower3;
+        btAryData[3] = btPower4;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+    
+    /**
+     * Set output power(Set the different output power for 8 antennas). <br>
+     * This command consumes more than 100mS. <br>
+     * If you want you change the output power frequently, please use
+     * Cmd_set_temporary_output_power command, which doesn't reduce the life of
+     * the internal flash memory.
+     *
+     * @param btReadId
+     *            Reader Address(0xFF Public Address)
+     * @param btPower1
+     *            Output power of antenna 1, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower2
+     *            Output power of antenna 2, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower3
+     *            Output power of antenna 3, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower4
+     *            Output power of antenna 4, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower5
+     *            Output power of antenna 5, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower6
+     *            Output power of antenna 6, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower7
+     *            Output power of antenna 7, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @param btPower8
+     *            Output power of antenna 8, range from 0 to 33(0x00 - 0x21),
+     *            the unit is dBm.
+     * @return Succeeded :0, Failed:-1
+     */
+    public final int setOutputPower(byte btReadId, byte btPower1, byte btPower2, byte btPower3, byte btPower4,
+    		                                       byte btPower5, byte btPower6, byte btPower7, byte btPower8) {
+        byte btCmd = CMD.SET_OUTPUT_POWER;
+        byte[] btAryData = new byte[8];
+
+        btAryData[0] = btPower1;
+        btAryData[1] = btPower2;
+        btAryData[2] = btPower3;
+        btAryData[3] = btPower4;
+        btAryData[4] = btPower5;
+        btAryData[5] = btPower6;
+        btAryData[6] = btPower7;
+        btAryData[7] = btPower8;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Query output power.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getOutputPower(byte btReadId) {
+        byte btCmd = CMD.GET_OUTPUT_POWER;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+    
+    /**
+     * Query output power(8 antennas).
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getOutputPowerEight(byte btReadId) {
+        byte btCmd = CMD.GET_OUTPUT_POWER_EIGHT;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Set frequency region(system default frequencies).
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btRegion		Spectrum regulation(0x01:FCC, 0x02:ETSI, 0x03:CHN)
+     * @param btStartRegion	Start frequency of the spectrum,
+     * @param btEndRegion	End frequency of the spectrum,Setup the range of the RF output spectrum. The rules are: 1,Start frequency and end frequency should be in the range of the specified regulation. 2,Start frequency should be equal or lower than end frequency. 3, End frequency equals start frequency means use single frequency point.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setFrequencyRegion(byte btReadId, byte btRegion,
+                                        byte btStartRegion, byte btEndRegion) {
+        byte btCmd = CMD.SET_FREQUENCY_REGION;
+        byte[] btAryData = new byte[3];
+
+        btAryData[0] = btRegion;
+        btAryData[1] = btStartRegion;
+        btAryData[2] = btEndRegion;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Set frequency region(user defined frequencies).
+     * @param btReadId			Reader Address(0xFF Public Address)
+     * @param btFreqInterval	Frequency space, frequency space = FreqSpace x 10KHz.
+     * @param btChannelQuantity	Frequency Quantity, this quantity includes the start frequency, if set this byte to 1, it means use start frequency as the single carrier frequency . This byte should be larger than 0.
+     * @param nStartFreq		Start Frequency, the unit is KHz. Set the start frequency with hex format, for example, 915000KHz = 0D F6 38 KHz.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setUserDefineFrequency(byte btReadId, byte btFreqInterval,
+                                            byte btChannelQuantity, int nStartFreq) {
+        byte btCmd = CMD.SET_FREQUENCY_REGION;
+        byte[] btAryFreq = new byte[3];
+        byte[] btAryData = new byte[6];
+
+        btAryFreq = Converter.getBytes(nStartFreq, Converter.BIG_ENDIAN);
+
+        btAryData[0] = 4;
+        btAryData[1] = btFreqInterval;
+        btAryData[2] = btChannelQuantity;
+        btAryData[3] = btAryFreq[2];
+        btAryData[4] = btAryFreq[1];
+        btAryData[5] = btAryFreq[0];
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Query frequency region.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getFrequencyRegion(byte btReadId) {
+        byte btCmd = CMD.GET_FREQUENCY_REGION;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Set Buzzer behavior.
+     * <br>Buzzer behavior 0x02(Beep after every tag has identified) occupies CPU process time that affects anti-collision algorithm significantly. It is recommended that this option should be used for tag test.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btMode	Buzzer behavior(0x00:Quiet, 0x01:Beep after every inventory round if tag(s) identified, 0x02:Beep after every tag has identified.)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setBeeperMode(byte btReadId, byte btMode) {
+        byte btCmd = CMD.SET_BEEPER_MODE;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btMode;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Query internal temperature.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getReaderTemperature(byte btReadId) {
+        byte btCmd = CMD.GET_READER_TEMPERATURE;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Read GPIO Level.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int readGpioValue(byte btReadId) {
+        byte btCmd = CMD.READ_GPIO_VALUE;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Write GPIO Level.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btChooseGpio	ChooseGpio(0x03:Set GPIO3, 0x04:Set GPIO4)
+     * @param btGpioValue	GpioValue(0x00:Set to low level, 0x01:Set to high level)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int writeGpioValue(byte btReadId, byte btChooseGpio, byte btGpioValue) {
+        byte btCmd = CMD.WRITE_GPIO_VALUE;
+        byte[] btAryData = new byte[2];
+
+        btAryData[0] = btChooseGpio;
+        btAryData[1] = btGpioValue;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Set antenna connection detector status.
+     * @param btReadId			Reader Address(0xFF Public Address)
+     * @param btDetectorStatus	status(0x00:close detector of antenna connection, other values:sensitivity of antenna connection detector(return loss of port),unit dB. The higher the value, the greater the impedance matching requirements for port
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setAntConnectionDetector(byte btReadId, byte btDetectorStatus) {
+        byte btCmd = CMD.SET_ANT_CONNECTION_DETECTOR;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btDetectorStatus;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Get antenna connection detector status.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getAntConnectionDetector(byte btReadId) {
+        byte btCmd = CMD.GET_ANT_CONNECTION_DETECTOR;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Set temporary output power.
+     * <br>The output power value will Not be saved to the internal flash memory so that the output power will be restored from the internal flash memory after restart or power off.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btRfPower	RF output power, range from 20-33(0x14 - 0x21), the unit is dBm.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setTemporaryOutputPower(byte btReadId, byte btRfPower) {
+        byte btCmd = CMD.SET_TEMPORARY_OUTPUT_POWER;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btRfPower;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Set Reader Identifier.
+     * <br>The identifier is stored in internal flash.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btAryIdentifier	Reader's identifier (12 bytes).
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setReaderIdentifier(byte btReadId, byte[] btAryIdentifier) {
+        byte btCmd = CMD.SET_READER_IDENTIFIER;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryIdentifier);
+
+        return nResult;
+    }
+
+    /**
+     * Get Reader Identifier.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getReaderIdentifier(byte btReadId) {
+        byte btCmd = CMD.GET_READER_IDENTIFIER;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * RF Link Setup.
+     * <br>If this command succeeded, reader will be reset, and the profile configuration is stored in the internal flash.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btProfile	Communication rate(0xD0:Tari 25uS,FM0 40KHz, 0xD1:Tari 25uS,Miller 4 250KHz, 0xD2:Tari 25uS,Miller 4 300KHz, 0xD3:Tari 6.25uS,FM0 400KHz)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setRfLinkProfile(byte btReadId, byte btProfile) {
+        byte btCmd = CMD.SET_RF_LINK_PROFILE;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btProfile;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Read RF Link.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getRfLinkProfile(byte btReadId) {
+        byte btCmd = CMD.GET_RF_LINK_PROFILE;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Measure RF Port Return Loss.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btFrequency	FreqParameter, system will measure the return loss of current antenna port at the desired frequency.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getRfPortReturnLoss(byte btReadId, byte btFrequency) {
+        byte btCmd = CMD.GET_RF_PORT_RETURN_LOSS;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btFrequency;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Inventory Tag.
+     * <br>When reader gets this command, the inventory for EPC GEN2 tags starts, tag data will be stored in the internal buffer.
+     * <br>Attention:
+     * <br>When sets Repeat parameter to 255(0xFF), the anti-collision algorithm is optimized for applications with small tag quantity, which provide better efficiency and less response time.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btRepeat	Repeat time of inventory round. When Repeat = 255, The inventory duration is minimized. For example, if the RF field only has one or two tags, the inventory duration could be only 30-50 mS, this function provides a possibility for fast antenna switch applications on multi-ant devices.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int inventory(byte btReadId, byte btRepeat) {
+        byte btCmd = CMD.INVENTORY;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btRepeat;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Read Tag.
+     * <br>Attention:
+     * <br>If two tags have the same EPC, but different read data, then these two tags are considered different tags.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btMemBank	Tag memory bank(0x00:RESERVED, 0x01:EPC, 0x02:TID, 0x03:USER)
+     * @param btWordAdd	Read start address,please see the tag's spec for more information.
+     * @param btWordCnt	Read data length,Data length in WORD(16bits) unit. Please see the tag's spec for more information.
+     * @param btAryPassWord	Access password,4 bytes.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int readTag(byte btReadId, byte btMemBank, byte btWordAdd,
+                             byte btWordCnt, byte[] btAryPassWord) {
+        byte btCmd = CMD.READ_TAG;
+        byte[] btAryData = null;
+        if (btAryPassWord == null || btAryPassWord.length < 4) {
+            btAryPassWord = null;
+            btAryData = new byte[3];
+        } else {
+            btAryData = new byte[3 + 4];
+        }
+
+        btAryData[0] = btMemBank;
+        btAryData[1] = btWordAdd;
+        btAryData[2] = btWordCnt;
+
+        if (btAryPassWord != null) {
+            System.arraycopy(btAryPassWord, 0, btAryData, 3, btAryPassWord.length);
+        }
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Write Tag.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btAryPassWord	Access password, 4 bytes.
+     * @param btMemBank		Tag memory bank(0x00:RESERVED, 0x01:EPC, 0x02:TID, 0x03:USER)
+     * @param btWordAdd		Write start address,WORD(16 bits). When write EPC area, notice that EPC starts from address 02, the first two 2 words are for PC+CRC.
+     * @param btWordCnt		WORD(16 bits), please see the tag's spec for more information.
+     * @param btAryData		Write data, btWordCnt*2 bytes.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int writeTag(byte btReadId, byte[] btAryPassWord, byte btMemBank,
+                              byte btWordAdd, byte btWordCnt, byte[] btAryData) {
+        byte btCmd = CMD.WRITE_TAG;
+        byte[] btAryBuffer = new byte[btAryData.length + 7];
+
+        System.arraycopy(btAryPassWord, 0, btAryBuffer, 0, btAryPassWord.length);
+        // btAryPassWord.CopyTo(btAryBuffer, 0);
+        btAryBuffer[4] = btMemBank;
+        btAryBuffer[5] = btWordAdd;
+        btAryBuffer[6] = btWordCnt;
+        System.arraycopy(btAryData, 0, btAryBuffer, 7, btAryData.length);
+        // btAryData.CopyTo(btAryBuffer, 7);
+
+        int nResult = sendMessage(btReadId, btCmd, btAryBuffer);
+
+        return nResult;
+    }
+
+    /**
+     * Lock Tag.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btAryPassWord	Access password, 4 bytes.
+     * @param btMemBank		Tag memory bank(0x01:User Memory, 0x02:TID Memory, 0x03:EPC Memory, 0x04:Access Password, 0x05:Kill Password)
+     * @param btLockType	Lock operation type(0x00:Open, 0x01:Lock, 0x02:Permanent open, 0x03:Permanent lock)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int lockTag(byte btReadId, byte[] btAryPassWord, byte btMemBank,
+                             byte btLockType) {
+        byte btCmd = CMD.LOCK_TAG;
+        byte[] btAryData = new byte[6];
+
+        System.arraycopy(btAryPassWord, 0, btAryData, 0, btAryPassWord.length);
+        // btAryPassWord.CopyTo(btAryData, 0);
+        btAryData[4] = btMemBank;
+        btAryData[5] = btLockType;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Kill Tag.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btAryPassWord	Kill password,4 bytes
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int killTag(byte btReadId, byte[] btAryPassWord) {
+        byte btCmd = CMD.KILL_TAG;
+        byte[] btAryData = new byte[4];
+
+        System.arraycopy(btAryPassWord, 0, btAryData, 0, btAryPassWord.length);
+        // btAryPassWord.CopyTo(btAryData, 0);
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Set Access EPC match(EPC match is effective,until next refresh).
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btEpcLen	Length of EPC.
+     * @param btAryEpc	EPC, Length equals EpcLen.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setAccessEpcMatch(byte btReadId, byte btEpcLen,
+                                       byte[] btAryEpc) {
+        byte btCmd = CMD.SET_ACCESS_EPC_MATCH;
+        int nLen = (btEpcLen & 0xFF) + 2;
+        byte[] btAryData = new byte[nLen];
+
+        btAryData[0] = 0x00;
+        btAryData[1] = btEpcLen;
+        System.arraycopy(btAryEpc, 0, btAryData, 2, btAryEpc.length);
+        // btAryEpc.CopyTo(btAryData, 2);
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Clear EPC match.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int cancelAccessEpcMatch(byte btReadId) {
+        byte btCmd = CMD.SET_ACCESS_EPC_MATCH;
+        byte[] btAryData = new byte[1];
+        btAryData[0] = 0x01;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Query match EPC status.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getAccessEpcMatch(byte btReadId) {
+        byte btCmd = CMD.GET_ACCESS_EPC_MATCH;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Inventory Tag(Read Time Mode).
+     * <br>Attention:
+     * <br> The hardware has a dual CPU architecture, main CPU is responsible for tag inventory, and assistant CPU is responsible for data management. Inventory and data transfer are parallel and simultaneous. So the data transfer via serial port doesn't affect the efficiency of reader.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btRepeat	Repeat time of inventory round. When Repeat = 255, The inventory duration is minimized. For example, if the RF field only has one or two tags, the inventory duration could be only 30-50 mS, this function provides a possibility for fast antenna switch applications on multi-ant devices.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int realTimeInventory(byte btReadId, byte btRepeat) {
+        byte btCmd = CMD.REAL_TIME_INVENTORY;
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = btRepeat;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Fast Switch Antenna Mode.
+     * <br>Attention:
+     * <br> The hardware has a dual CPU architecture, main CPU is responsible for tag inventory, and assistant CPU is responsible for data management. Inventory and data transfer are parallel and simultaneous. So the data transfer via serial port doesn't affect the efficiency of reader.
+     * <br>In massive tag applications, please use cmd_real_time_inventory command which is more effective for large tag quantity applications.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btA			First working ant (00 - 03). If set this byte above 03 means ignore it.
+     * @param btStayA		Inventory round for an antenna.
+     * @param btB			Second working ant (00 - 03). If set this byte above 03 means ignore it.
+     * @param btStayB		Inventory round for an antenna.
+     * @param btC			Third working ant (00 - 03). If set this byte above 03 means ignore it.
+     * @param btStayC		Inventory round for an antenna.
+     * @param btD			Fourth working ant (00 - 03). If set this byte above 03 means ignore it.
+     * @param btStayD		Inventory round for an antenna.
+     * @param btInterval	Rest time between switching antennas. During the cause of rest, RF output will be cancelled, thus power consumption and heat generation are both reduced.
+     * @param btRepeat		Repeat the inventory with above ant switch sequence.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int fastSwitchAntInventory(byte btReadId,
+                                            byte btA, byte btStayA, byte btB, byte btStayB,
+                                            byte btC, byte btStayC, byte btD, byte btStayD,
+                                            byte btInterval, byte btRepeat) {
+
+        byte btCmd = CMD.FAST_SWITCH_ANT_INVENTORY;
+        byte[] btAryData = new byte[10];
+
+        btAryData[0] = btA;
+        btAryData[1] = btStayA;
+        btAryData[2] = btB;
+        btAryData[3] = btStayB;
+        btAryData[4] = btC;
+        btAryData[5] = btStayC;
+        btAryData[6] = btD;
+        btAryData[7] = btStayD;
+        btAryData[8] = btInterval;
+        btAryData[9] = btRepeat;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+    
+    /**
+     * Fast Switch Antenna Mode(8 Antennas).
+     * <br>Attention:
+     * <br> The hardware has a dual CPU architecture, main CPU is responsible for tag inventory, and assistant CPU is responsible for data management. Inventory and data transfer are parallel and simultaneous. So the data transfer via serial port doesn't affect the efficiency of reader.
+     * <br>In massive tag applications, please use cmd_real_time_inventory command which is more effective for large tag quantity applications.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btA			First working ant (00 - 07). If set this byte above 07 means ignore it.
+     * @param btStayA		Inventory round for an antenna.
+     * @param btB			Second working ant (00 - 07). If set this byte above 07 means ignore it.
+     * @param btStayB		Inventory round for an antenna.
+     * @param btC			Third working ant (00 - 07). If set this byte above 07 means ignore it.
+     * @param btStayC		Inventory round for an antenna.
+     * @param btD			Fourth working ant (00 - 07). If set this byte above 07 means ignore it.
+     * @param btStayD		Inventory round for an antenna.
+     * @param btE			First working ant (00 - 07). If set this byte above 07 means ignore it.
+     * @param btStayE		Inventory round for an antenna.
+     * @param btB			Second working ant (00 - 07). If set this byte above 07 means ignore it.
+     * @param btStayB		Inventory round for an antenna.
+     * @param btC			Third working ant (00 - 07). If set this byte above 07 means ignore it.
+     * @param btStayC		Inventory round for an antenna.
+     * @param btD			Fourth working ant (00 - 07). If set this byte above 07 means ignore it.
+     * @param btStayD		Inventory round for an antenna.
+     * @param btInterval	Rest time between switching antennas. During the cause of rest, RF output will be cancelled, thus power consumption and heat generation are both reduced.
+     * @param btRepeat		Repeat the inventory with above ant switch sequence.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int fastSwitchAntInventory(byte btReadId,
+                                            byte btA, byte btStayA, byte btB, byte btStayB,
+                                            byte btC, byte btStayC, byte btD, byte btStayD,
+                                            byte btE, byte btStayE, byte btF, byte btStayF,
+                                            byte btG, byte btStayG, byte btH, byte btStayH,
+                                            byte btInterval, byte btRepeat) {
+
+        byte btCmd = CMD.FAST_SWITCH_ANT_INVENTORY;
+        byte[] btAryData = new byte[18];
+
+        btAryData[0] = btA;
+        btAryData[1] = btStayA;
+        btAryData[2] = btB;
+        btAryData[3] = btStayB;
+        btAryData[4] = btC;
+        btAryData[5] = btStayC;
+        btAryData[6] = btD;
+        btAryData[7] = btStayD;
+        btAryData[8] = btE;
+        btAryData[9] = btStayE;
+        btAryData[10] = btF;
+        btAryData[11] = btStayF;
+        btAryData[12] = btG;
+        btAryData[13] = btStayG;
+        btAryData[14] = btH;
+        btAryData[15] = btStayH;
+        btAryData[16] = btInterval;
+        btAryData[17] = btRepeat;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * User define session and target inventory.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btSession	Desired session ID
+     * @param btTarget	Desired Inventoried Flag(0x00:A, 0x01:B)
+     * @param btRepeat	Number of times of repeating this inventory.
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int customizedSessionTargetInventory(byte btReadId,
+                                                      byte btSession, byte btTarget, byte btRepeat) {
+
+        byte btCmd = CMD.CUSTOMIZED_SESSION_TARGET_INVENTORY;
+        byte[] btAryData = new byte[3];
+
+        btAryData[0] = btSession;
+        btAryData[1] = btTarget;
+        btAryData[2] = btRepeat;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Set Impinj Monza FastTID.
+     * <br>Attention:
+     * <br>This function is only affective for some of Impinj Monza tag types.
+     * <br>This function improves the performance of identifying tag's TID.
+     * <br>When this function takes effect, tag's TID will be included to tag's EPC, therefore, tag's EPC will be altered; the original data (PC + EPC) will be changed to altered PC + EPC + EPC's CRC + TID.
+     * <br>If error occurred during identifying TID, only the original data (PC + EPC) will be sent.
+     * <br>If you don't need this function, please turn it off, otherwise there will be unnecessary time consumption.
+     * <br>This command doesn't store the status to internal flash. After reset or power on, the value stored in flash will be restored.
+     * @param btReadId	Reader Address(0xFF public address)
+     * @param blnOpen	Whether to open FastTID
+     * @param blnSave	Whether to store in FLASH
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int setImpinjFastTid(byte btReadId, boolean blnOpen, boolean blnSave) {
+
+        byte btCmd = (blnSave ? CMD.SET_AND_SAVE_IMPINJ_FAST_TID : CMD.SET_IMPINJ_FAST_TID);
+        byte[] btAryData = new byte[1];
+
+        btAryData[0] = (byte) (blnOpen ? 0x8D : 0x00);
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Query current set of FastTID.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getImpinjFastTid(byte btReadId) {
+        byte btCmd = CMD.GET_IMPINJ_FAST_TID;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Inventory 18000-6B Tag.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int iso180006BInventory(byte btReadId) {
+        byte btCmd = CMD.ISO18000_6B_INVENTORY;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Read 18000-6B Tag.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btAryUID	Operated Tag's UID, 8 bytes
+     * @param btWordAdd	Read data first address
+     * @param btWordCnt	Read data length
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int iso180006BReadTag(byte btReadId, byte[] btAryUID, byte btWordAdd, byte btWordCnt) {
+        byte btCmd = CMD.ISO18000_6B_READ_TAG;
+        int nLen = btAryUID.length + 2;
+        byte[] btAryData = new byte[nLen];
+
+        System.arraycopy(btAryUID, 0, btAryData, 0, btAryUID.length);
+        // btAryUID.CopyTo(btAryData, 0);
+        btAryData[nLen - 2] = btWordAdd;
+        btAryData[nLen - 1] = btWordCnt;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Write 18000-6B Tag.
+     * @param btReadId		Reader Address(0xFF Public Address)
+     * @param btAryUID		Operated Tag's UID, 8 bytes
+     * @param btWordAdd		Write data first address
+     * @param btWordCnt		Write data length
+     * @param btAryBuffer	Write data
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int iso180006BWriteTag(byte btReadId, byte[] btAryUID, byte btWordAdd,
+                                        byte btWordCnt, byte[] btAryBuffer) {
+        byte btCmd = CMD.ISO18000_6B_WRITE_TAG;
+        int nLen = btAryUID.length + 2 + btAryBuffer.length;
+        byte[] btAryData = new byte[nLen];
+
+        System.arraycopy(btAryUID, 0, btAryData, 0, btAryUID.length);
+        // btAryUID.CopyTo(btAryData, 0);
+        btAryData[btAryUID.length] = btWordAdd;
+        btAryData[btAryUID.length + 1] = btWordCnt;
+        System.arraycopy(btAryBuffer, 0, btAryData, btAryUID.length + 2,
+                btAryBuffer.length);
+        // btAryBuffer.CopyTo(btAryData, btAryUID.length + 2);
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Lock 18000-6B Tag.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btAryUID	Operated Tag's UID, 8 bytes
+     * @param btWordAdd	Locked address
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int iso180006BLockTag(byte btReadId, byte[] btAryUID, byte btWordAdd) {
+        byte btCmd = CMD.ISO18000_6B_LOCK_TAG;
+        int nLen = btAryUID.length + 1;
+        byte[] btAryData = new byte[nLen];
+
+        System.arraycopy(btAryUID, 0, btAryData, 0, btAryUID.length);
+        // btAryUID.CopyTo(btAryData, 0);
+        btAryData[nLen - 1] = btWordAdd;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Query 18000-6B Tag.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @param btAryUID	Operated Tag's UID, 8 bytes
+     * @param btWordAdd	To query address
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int iso180006BQueryLockTag(byte btReadId, byte[] btAryUID, byte btWordAdd) {
+        byte btCmd = CMD.ISO18000_6B_QUERY_LOCK_TAG;
+        int nLen = btAryUID.length + 1;
+        byte[] btAryData = new byte[nLen];
+
+        System.arraycopy(btAryUID, 0, btAryData, 0, btAryUID.length);
+        // btAryUID.CopyTo(btAryData, 0);
+        btAryData[nLen - 1] = btWordAdd;
+
+        int nResult = sendMessage(btReadId, btCmd, btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Get tag data and keep buffer.
+     * <br>Attention:
+     * <br>The data in the buffer won't be lost after execution of this command.
+     * <br>If the cmd_inventory is executed again, the tag data escalate in the buffer.
+     * <br>Other 18000-6C commands can clear the buffer.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getInventoryBuffer(byte btReadId) {
+        byte btCmd = CMD.GET_INVENTORY_BUFFER;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Get tag data and clear buffer.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getAndResetInventoryBuffer(byte btReadId) {
+        byte btCmd = CMD.GET_AND_RESET_INVENTORY_BUFFER;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Query tag quantity in buffer.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int getInventoryBufferTagCount(byte btReadId) {
+        byte btCmd = CMD.GET_INVENTORY_BUFFER_TAG_COUNT;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Clear buffer of tag data.
+     * @param btReadId	Reader Address(0xFF Public Address)
+     * @return	Succeeded :0, Failed:-1
+     */
+    public final int resetInventoryBuffer(byte btReadId) {
+        byte btCmd = CMD.RESET_INVENTORY_BUFFER;
+
+        int nResult = sendMessage(btReadId, btCmd);
+
+        return nResult;
+    }
+
+    /**
+     * Set the mask filter the Tag.
+     * @param btReadId The reader address.
+     * @param btMaskNo The mask No include(0x00,0x01,0x02,0x03,0x04),you set different mask via the mask No.
+     * @param btTarget Set the inventory way(s0,s1,s2 or s3),you must use you set target to inventory the tag.
+     * @param btAction The match tag or not Action,you can see the detail of this command.
+     * @param btMembank The select mask region,EPC,TID or USER.
+     * @param btStartAdd The mask start address(according to bit).
+     * @param btMaskLen The mask length (according to bit).
+     * @param maskValue The mask value.
+     * @return Succeeded :0, Failed:-1
+     */
+    public final int setTagMask(byte btReadId,byte btMaskNo,byte btTarget,byte btAction,byte btMembank,byte btStartAdd,byte btMaskLen,byte[] maskValue)
+    {
+        byte[] btAryData = new byte[7 + maskValue.length];
+        btAryData[0] = btMaskNo;
+        btAryData[1] = btTarget;
+        btAryData[2] = btAction;
+        btAryData[3] = btMembank;
+        btAryData[4] = btStartAdd;
+        btAryData[5] = btMaskLen;
+        System.arraycopy(maskValue, 0, btAryData, 6, maskValue.length);
+        btAryData[btAryData.length - 1] = (byte)0x00;
+
+        int nResult = sendMessage(btReadId,(byte)0x98,btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Get the mask setting.
+     * @param btReadId the reader address.
+     * @return Succeeded :0, Failed:-1
+     */
+    public final int getTagMask(byte btReadId)
+    {
+        byte[] btAryData = { (byte)0x20 };
+
+        int nResult = sendMessage(btReadId,(byte)0x98,btAryData);
+
+        return nResult;
+    }
+
+    /**
+     * Clear the masking.
+     * @param btReadId the reader address.
+     * @param btMaskNo The mask No include(0x00,0x01,0x02,0x03,0x04),you clear any mask via the mask No.
+     * @return Succeeded :0, Failed:-1
+     */
+    public final int clearTagMask(byte btReadId,byte btMaskNo)
+    {
+        byte[] btAryData = { btMaskNo };
+
+        int nResult = sendMessage(btReadId,(byte)0x98,btAryData);
+
+        return nResult;
+    }
+}

+ 89 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/ReaderConnector.java

@@ -0,0 +1,89 @@
+package com.tidecloud.dataacceptance.rfid;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+import com.tidecloud.dataacceptance.rfid.module.interaction.ModuleConnector;
+import com.tidecloud.dataacceptance.rfid.module.interaction.ReaderHelper;
+
+/**
+ * The implementation class of ModuleConnector.
+ *
+ */
+public class ReaderConnector implements ModuleConnector{
+	private  final String HOSTNAME_REGEXP = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
+			+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
+			+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
+			+ "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
+	
+	private RFIDReaderHelper mRFIDReaderHelper;
+	private Socket mSocket;
+	private InetSocketAddress mRemoteAddr;
+	
+	private final String USER = "USER";
+	
+	
+
+	@Override
+	public ReaderHelper connectNet(final String host, final int port) {
+
+		if (host.matches(HOSTNAME_REGEXP))
+			;
+		else {
+			return null;
+		}
+		
+		try {
+			mRemoteAddr = new InetSocketAddress(host, port);
+			mSocket = new Socket();
+		} catch (Exception e1) {
+			return null;
+		}
+
+		try {
+			mSocket.connect(mRemoteAddr, 4000);
+			return connect(mSocket.getInputStream(),mSocket.getOutputStream());
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+	
+	@Override
+	public ReaderHelper connect(InputStream in,OutputStream out) {
+		mRFIDReaderHelper = new RFIDReaderHelper();
+		try {
+			mRFIDReaderHelper.setReader(in,out,new ReaderDataPackageParser(),new ReaderDataPackageProcess());
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}		
+		return mRFIDReaderHelper;
+	}
+
+	@Override
+	public boolean isConnected() {
+		return (mRFIDReaderHelper != null ? mRFIDReaderHelper.isAlive() : false);
+	}
+
+	@Override
+	public void disConnect() {
+		if (mRFIDReaderHelper != null) {
+			mRFIDReaderHelper.signOut();
+			mRFIDReaderHelper = null;
+		}
+		try {
+			if (mSocket != null) {
+				mSocket.close();
+				mSocket = null;
+			}
+			
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		mRemoteAddr = null;
+	}
+
+}

+ 63 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/ReaderDataPackageParser.java

@@ -0,0 +1,63 @@
+package com.tidecloud.dataacceptance.rfid;
+
+import com.tidecloud.dataacceptance.rfid.config.HEAD;
+import com.tidecloud.dataacceptance.rfid.module.interaction.DataPackageParser;
+import com.tidecloud.dataacceptance.rfid.module.interaction.DataPackageProcess;
+
+import java.util.Arrays;
+
+/**
+ * The implementation class of DataPackageParser.
+ */
+
+public class ReaderDataPackageParser implements DataPackageParser {
+    private byte[] m_btAryBuffer = new byte[4096];
+    private int m_nLength = 0;
+    @Override
+    public void runReceiveDataCallback(byte[] btAryReceiveData, DataPackageProcess dataPackageProcess) {
+        try {
+            int nCount = btAryReceiveData.length;
+            byte[] btAryBuffer = new byte[nCount + m_nLength];
+
+            System.arraycopy(m_btAryBuffer, 0, btAryBuffer, 0, m_nLength);
+            System.arraycopy(btAryReceiveData, 0, btAryBuffer, m_nLength,
+                    btAryReceiveData.length);
+            int nIndex = 0;
+            int nMarkIndex = 0;
+            for (int nLoop = 0; nLoop < btAryBuffer.length; nLoop++) {
+                if (btAryBuffer.length > nLoop + 1) {
+                    if (btAryBuffer[nLoop] == HEAD.HEAD) {
+                        int nLen = btAryBuffer[nLoop + 1] & 0xFF;
+                        if (nLoop + 1 + nLen < btAryBuffer.length) {
+                            byte[] btAryAnaly = new byte[nLen + 2];
+                            System.arraycopy(btAryBuffer, nLoop, btAryAnaly, 0,
+                                    nLen + 2);
+                            dataPackageProcess.analyData(btAryAnaly);
+                            nLoop += 1 + nLen;
+                            nIndex = nLoop + 1;
+                        } else {
+                            nLoop += 1 + nLen;
+                        }
+                    } else {
+                        nMarkIndex = nLoop;
+                    }
+                }
+            }
+
+            if (nIndex < nMarkIndex) {
+                nIndex = nMarkIndex + 1;
+            }
+
+            if (nIndex < btAryBuffer.length) {
+                m_nLength = btAryBuffer.length - nIndex;
+                Arrays.fill(m_btAryBuffer, 0, 4096, (byte) 0);
+                System.arraycopy(btAryBuffer, nIndex, m_btAryBuffer, 0,
+                        btAryBuffer.length - nIndex);
+            } else {
+                m_nLength = 0;
+            }
+        } catch (Exception e) {
+        	e.printStackTrace();
+        }
+    }
+}

+ 19 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/ReaderDataPackageProcess.java

@@ -0,0 +1,19 @@
+package com.tidecloud.dataacceptance.rfid;
+
+import com.tidecloud.dataacceptance.rfid.bean.MessageTran;
+import com.tidecloud.dataacceptance.rfid.module.interaction.DataPackageProcess;
+
+/**
+ * The implementation class of DataPackageProcess.
+ */
+
+public class ReaderDataPackageProcess extends DataPackageProcess {
+    @Override
+    public void analyData(byte[] btPackage) {
+        MessageTran msgTran = new MessageTran(btPackage);
+        if (msgTran != null) {
+            setChanged();
+            notifyObservers(msgTran);
+        }
+    }
+}

+ 170 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/bean/MessageTran.java

@@ -0,0 +1,170 @@
+package com.tidecloud.dataacceptance.rfid.bean;
+
+import com.tidecloud.dataacceptance.rfid.config.HEAD;
+
+/**
+ * Object of describing data package;
+ * @author Administrator
+ *
+ */
+public class MessageTran {
+	private byte btPacketType;     //head of data, defauld value is 0xA0 
+    private byte btDataLen;        //Length of data package, which means the byte quantity after the "length", not including the "length" 
+    private byte btReadId;         //Address of reader 
+    private byte btCmd;            //The commend code of data package 
+    private byte[] btAryData;      //The commend specification of data package, some commends without specification  
+    private byte btCheck;          //Checksum 
+    private byte[] btAryTranData;  //Complete data package 
+    
+    /**
+     * MessageTran default constructor
+     */
+    public MessageTran() {
+	}
+
+    /**
+     * MessageTran Constructor 
+     * @param btReadId    address of reader  
+     * @param btCmd       command code of data package  
+     * @param btAryData   command parameters of data package, some commands without parameters  
+     */
+    public MessageTran(byte btReadId, byte btCmd, byte[] btAryData) {
+        int nLen = btAryData.length;
+
+        this.btPacketType = HEAD.HEAD;
+        this.btDataLen = (byte)(nLen + 3);
+        this.btReadId = btReadId;
+        this.btCmd = btCmd;
+
+        this.btAryData = new byte[nLen];
+        System.arraycopy(btAryData, 0, this.btAryData, 0, btAryData.length);
+        //btAryData.CopyTo(this.btAryData, 0);
+
+        this.btAryTranData = new byte[nLen + 5];
+        this.btAryTranData[0] = this.btPacketType;
+        this.btAryTranData[1] = this.btDataLen;
+        this.btAryTranData[2] = this.btReadId;
+        this.btAryTranData[3] = this.btCmd;
+        System.arraycopy(this.btAryData, 0, this.btAryTranData, 4, this.btAryData.length);
+        //this.btAryData.CopyTo(this.btAryTranData, 4);
+
+        this.btCheck = checkSum(this.btAryTranData, 0, nLen + 4);
+        this.btAryTranData[nLen + 4] = this.btCheck;
+    }
+
+    /**
+     * MessageTran Constructor
+      * @param btReadId   address of reader 
+     * @param btCmd       read command  
+     */
+    public MessageTran(byte btReadId, byte btCmd) {
+        this.btPacketType = HEAD.HEAD;
+        this.btDataLen = 0x03;
+        this.btReadId = btReadId;
+        this.btCmd = btCmd;
+
+        this.btAryTranData = new byte[5];
+        this.btAryTranData[0] = this.btPacketType;
+        this.btAryTranData[1] = this.btDataLen;
+        this.btAryTranData[2] = this.btReadId;
+        this.btAryTranData[3] = this.btCmd;
+
+        this.btCheck = checkSum(this.btAryTranData, 0, 4);
+        this.btAryTranData[4] = this.btCheck;
+    }
+
+    /**
+     * MessageTran constructor 
+     * @param btAryTranData   complete data package  
+     */
+    public MessageTran(byte[] btAryTranData) {
+        int nLen = btAryTranData.length;
+
+        this.btAryTranData = new byte[nLen];
+        System.arraycopy(btAryTranData, 0, this.btAryTranData, 0, btAryTranData.length);
+        //btAryTranData.CopyTo(this.btAryTranData, 0);
+
+
+        byte btCK = checkSum(this.btAryTranData, 0, this.btAryTranData.length - 1);
+        if (btCK != btAryTranData[nLen - 1]) {
+            return;
+        }
+
+        this.btPacketType = btAryTranData[0];
+        this.btDataLen = btAryTranData[1];
+        this.btReadId = btAryTranData[2];
+        this.btCmd = btAryTranData[3];
+        this.btCheck = btAryTranData[nLen - 1];
+
+        if (nLen > 5) {
+            this.btAryData = new byte[nLen - 5];
+            for (int nloop = 0; nloop < nLen - 5; nloop++ ) {
+                this.btAryData[nloop] = btAryTranData[4 + nloop];
+            }
+        }
+    }
+    
+    /**
+     * Obtain complete data package
+     * @return	 Data package 
+     */
+    public byte[] getAryTranData() {
+            return this.btAryTranData;
+    }
+
+    /**
+     * Obtain command parameters of data package, some command without parameters 
+     * @return	 commends parameters 
+     */
+    public byte[] getAryData() {
+            return this.btAryData;
+    }
+
+    /**
+     * Obtain address of reader  
+     * @return	Address of reader   
+     */
+    public byte getReadId() {
+            return this.btReadId;
+    }
+
+    /**
+     * Obtain command of data package  
+     * @return	 command  
+     */
+    public byte getCmd() {
+            return this.btCmd;
+    }
+
+    /**
+     * Obain head of data, default 0xA0  
+     * @return	head of data   
+     */
+    public byte getPacketType() {
+            return this.btPacketType;
+    }
+    
+    /**
+     * Check head of data 
+     * @return	 Result of checking 
+     */
+    public boolean checkPacketType() {
+        return this.btPacketType == HEAD.HEAD;
+    }
+
+    /**
+     * Calculate checksum  
+     * @param btAryBuffer   data	
+     * @param nStartPos	    start position	
+     * @param nLen	        Checking length		
+     * @return	            Checksum  
+     */
+    public byte checkSum(byte[] btAryBuffer, int nStartPos, int nLen) {
+        byte btSum = 0x00;
+
+        for (int nloop = nStartPos; nloop < nStartPos + nLen; nloop++ ) {
+            btSum += btAryBuffer[nloop];
+        }
+        return (byte)(((~btSum) + 1) & 0xFF);
+    }
+}

+ 203 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/config/CMD.java

@@ -0,0 +1,203 @@
+package com.tidecloud.dataacceptance.rfid.config;
+
+/**
+ * Regarding UHF return code and description, please refer to Serial_Protocol_User's_Guide_V2.38_en  
+ *
+ */
+public class CMD {
+	public final static byte RESET = 0x70;
+	public final static byte SET_UART_BAUDRATE = 0x71;
+	public final static byte GET_FIRMWARE_VERSION = 0x72;
+	public final static byte SET_READER_ADDRESS = 0x73;
+	public final static byte SET_WORK_ANTENNA = 0x74;
+	public final static byte GET_WORK_ANTENNA = 0x75;
+	public final static byte SET_OUTPUT_POWER = 0x76;
+	public final static byte GET_OUTPUT_POWER = 0x77;
+	public final static byte SET_FREQUENCY_REGION = 0x78;
+	public final static byte GET_FREQUENCY_REGION = 0x79;
+	public final static byte SET_BEEPER_MODE = 0x7A;
+	public final static byte GET_READER_TEMPERATURE = 0x7B;
+	public final static byte READ_GPIO_VALUE = 0x60;
+	public final static byte WRITE_GPIO_VALUE = 0x61;
+	public final static byte SET_ANT_CONNECTION_DETECTOR = 0x62;
+	public final static byte GET_ANT_CONNECTION_DETECTOR = 0x63;
+	public final static byte SET_TEMPORARY_OUTPUT_POWER = 0x66;
+	public final static byte SET_READER_IDENTIFIER = 0x67;
+	public final static byte GET_READER_IDENTIFIER = 0x68;
+	public final static byte SET_RF_LINK_PROFILE = 0x69;
+	public final static byte GET_RF_LINK_PROFILE = 0x6A;
+	public final static byte GET_RF_PORT_RETURN_LOSS = 0x7E;
+	public final static byte INVENTORY = (byte) 0x80;
+	public final static byte READ_TAG = (byte) 0x81;
+	public final static byte WRITE_TAG = (byte) 0x82;
+	public final static byte LOCK_TAG = (byte) 0x83;
+	public final static byte KILL_TAG = (byte) 0x84;
+	public final static byte SET_ACCESS_EPC_MATCH = (byte) 0x85;
+	public final static byte GET_ACCESS_EPC_MATCH = (byte) 0x86;
+	public final static byte REAL_TIME_INVENTORY = (byte) 0x89;
+	public final static byte FAST_SWITCH_ANT_INVENTORY = (byte) 0x8A;
+	public final static byte CUSTOMIZED_SESSION_TARGET_INVENTORY = (byte) 0x8B;
+	public final static byte SET_IMPINJ_FAST_TID = (byte) 0x8C;
+	public final static byte SET_AND_SAVE_IMPINJ_FAST_TID = (byte) 0x8D;
+	public final static byte GET_IMPINJ_FAST_TID = (byte) 0x8E;
+	public final static byte ISO18000_6B_INVENTORY = (byte) 0xB0;
+	public final static byte ISO18000_6B_READ_TAG = (byte) 0xB1;
+	public final static byte ISO18000_6B_WRITE_TAG = (byte) 0xB2;
+	public final static byte ISO18000_6B_LOCK_TAG = (byte) 0xB3;
+	public final static byte ISO18000_6B_QUERY_LOCK_TAG = (byte) 0xB4;
+	public final static byte GET_INVENTORY_BUFFER = (byte) 0x90;
+	public final static byte GET_AND_RESET_INVENTORY_BUFFER = (byte) 0x91;
+	public final static byte GET_INVENTORY_BUFFER_TAG_COUNT = (byte) 0x92;
+	public final static byte RESET_INVENTORY_BUFFER = (byte) 0x93;
+    public final static byte OPERATE_TAG_MASK = (byte) 0x98;
+    public final static byte GET_OUTPUT_POWER_EIGHT = (byte) 0x97;
+
+    /**
+     * The description of command.
+     * @param btCmd the command code.
+     * @return String the description of command.
+     */
+    public static String format(byte btCmd)
+    {
+        String strCmd = "";
+        switch (btCmd)
+        {
+            case RESET:
+                strCmd = "Reset reader.";
+                break;
+            case SET_UART_BAUDRATE:
+                strCmd = "Set baud rate of serial port.";
+                break;
+            case GET_FIRMWARE_VERSION:
+                strCmd = "Get firmware version.";
+                break;
+            case SET_READER_ADDRESS:
+                strCmd = "Set reader’s address.";
+                break;
+            case SET_WORK_ANTENNA:
+                strCmd = "Set working antenna.";
+                break;
+            case GET_WORK_ANTENNA:
+                strCmd = "Query current working antenna.";
+                break;
+            case SET_OUTPUT_POWER:
+                strCmd = "Set RF output power.";
+                break;
+            case GET_OUTPUT_POWER:
+                strCmd = "Query current RF output power.";
+                break;
+            case SET_FREQUENCY_REGION:
+                strCmd = "Set RF frequency spectrum.";
+                break;
+            case GET_FREQUENCY_REGION:
+                strCmd = "Query RF frequency spectrum.";
+                break;
+            case SET_BEEPER_MODE:
+                strCmd = "Set reader’s buzzer hehavior.";
+                break;
+            case GET_READER_TEMPERATURE:
+                strCmd = "Check reader’s internal temperature.";
+                break;
+            case READ_GPIO_VALUE:
+                strCmd = "Get GPIO1, GPIO2 status.";
+                break;
+            case WRITE_GPIO_VALUE:
+                strCmd = "Set GPIO3, GPIO4 status.";
+                break;
+            case SET_ANT_CONNECTION_DETECTOR:
+                strCmd = "Set antenna detector status.";
+                break;
+            case GET_ANT_CONNECTION_DETECTOR:
+                strCmd = "Get antenna detector status.";
+                break;
+            case SET_TEMPORARY_OUTPUT_POWER:
+                strCmd = "Set RF power without saving to flash.";
+                break;
+            case SET_READER_IDENTIFIER:
+                strCmd = "Set reader’s identification bytes.";
+                break;
+            case GET_READER_IDENTIFIER:
+                strCmd = "Get reader’s identification bytes.";
+                break;
+            case SET_RF_LINK_PROFILE:
+                strCmd = "Set RF link profile.";
+                break;
+            case GET_RF_LINK_PROFILE:
+                strCmd = "Get RF link profile.";
+                break;
+            case GET_RF_PORT_RETURN_LOSS:
+                strCmd = "Get current antenna port’s return loss.";
+                break;
+            case INVENTORY:
+                strCmd = "Inventory EPC C1G2 tags to buffer.";
+                break;
+            case READ_TAG:
+                strCmd = "Read EPC C1G2 tag(s).";
+                break;
+            case WRITE_TAG:
+                strCmd = "Write EPC C1G2 tag(s).";
+                break;
+            case LOCK_TAG:
+                strCmd = "Lock EPC C1G2 tag(s).";
+                break;
+            case KILL_TAG:
+                strCmd = "Kill EPC C1G2 tag(s).";
+                break;
+            case SET_ACCESS_EPC_MATCH:
+                strCmd = "Set tag access filter by EPC.";
+                break;
+            case GET_ACCESS_EPC_MATCH:
+                strCmd = "Query access filter by EPC.";
+                break;
+            case REAL_TIME_INVENTORY:
+                strCmd = "Inventory tags in real time mode.";
+                break;
+            case FAST_SWITCH_ANT_INVENTORY:
+                strCmd = "Real time inventory with fast ant switch.";
+                break;
+            case CUSTOMIZED_SESSION_TARGET_INVENTORY:
+                strCmd = "Inventory with desired session and inventoried flag.";
+                break;
+            case SET_IMPINJ_FAST_TID:
+                strCmd = "Set impinj FastTID function(Without saving to FLASH).";
+                break;
+            case SET_AND_SAVE_IMPINJ_FAST_TID:
+                strCmd = "Set impinj FastTID function(Save to FLASH).";
+                break;
+            case GET_IMPINJ_FAST_TID:
+                strCmd = "Get current FastTID setting.";
+                break;
+            case ISO18000_6B_INVENTORY:
+                strCmd = "Inventory 18000-6B tag(s).";
+                break;
+            case ISO18000_6B_READ_TAG:
+                strCmd = "Read 18000-6B tag.";
+                break;
+            case ISO18000_6B_WRITE_TAG:
+                strCmd = "Write 18000-6B tag.";
+                break;
+            case ISO18000_6B_LOCK_TAG:
+                strCmd = "Lock 18000-6B tag data byte.";
+                break;
+            case ISO18000_6B_QUERY_LOCK_TAG:
+                strCmd = "Query lock 18000-6B tag data byte.";
+                break;
+            case GET_INVENTORY_BUFFER:
+                strCmd = "Get buffered data without clearing.";
+                break;
+            case GET_AND_RESET_INVENTORY_BUFFER:
+                strCmd = "Get and clear buffered data.";
+                break;
+            case GET_INVENTORY_BUFFER_TAG_COUNT:
+                strCmd = "Query how many tags are buffered.";
+                break;
+            case RESET_INVENTORY_BUFFER:
+                strCmd = "Clear buffer.";
+                break;
+            default:
+                strCmd = "Unknown error.";
+                break;
+        }
+        return strCmd;
+    }
+}

+ 187 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/config/ERROR.java

@@ -0,0 +1,187 @@
+package com.tidecloud.dataacceptance.rfid.config;
+
+/**
+ * Regarding UHF error code and description, please refer to Serial_Protocol_User's_Guide_V2.38_en  
+ * 
+ *
+ */
+public class ERROR {
+	public final static byte SUCCESS = 0x10;
+	public final static byte FAIL = 0x11;
+	public final static byte MCU_RESET_ERROR = 0x20;
+	public final static byte CW_ON_ERROR = 0x21;
+	public final static byte ANTENNA_MISSING_ERROR = 0x22;
+	public final static byte WRITE_FLASH_ERROR = 0x23;
+	public final static byte READ_FLASH_ERROR = 0x24;
+	public final static byte SET_OUTPUT_POWER_ERROR = 0x25;
+	public final static byte TAG_INVENTORY_ERROR = 0x31;
+	public final static byte TAG_READ_ERROR = 0x32;
+	public final static byte TAG_WRITE_ERROR = 0x33;
+	public final static byte TAG_LOCK_ERROR = 0x34;
+	public final static byte TAG_KILL_ERROR = 0x35;
+	public final static byte NO_TAG_ERROR = 0x36;
+	public final static byte INVENTORY_OK_BUT_ACCESS_FAIL = 0x37;
+	public final static byte BUFFER_IS_EMPTY_ERROR = 0x38;
+	public final static byte ACCESS_OR_PASSWORD_ERROR = 0x40;
+	public final static byte PARAMETER_INVALID = 0x41;
+	public final static byte PARAMETER_INVALID_WORDCNT_TOO_LONG = 0x42;
+	public final static byte PARAMETER_INVALID_MEMBANK_OUT_OF_RANGE = 0x43;
+	public final static byte PARAMETER_INVALID_LOCK_REGION_OUT_OF_RANGE = 0x44;
+	public final static byte PARAMETER_INVALID_LOCK_ACTION_OUT_OF_RANGE = 0x45;
+	public final static byte PARAMETER_READER_ADDRESS_INVALID = 0x46;
+	public final static byte PARAMETER_INVALID_ANTENNA_ID_OUT_OF_RANGE = 0x47;
+	public final static byte PARAMETER_INVALID_OUTPUT_POWER_OUT_OF_RANGE = 0x48;
+	public final static byte PARAMETER_INVALID_FREQUENCY_REGION_OUT_OF_RANGE = 0x49;
+	public final static byte PARAMETER_INVALID_BAUDRATE_OUT_OF_RANGE = 0x4A;
+	public final static byte PARAMETER_BEEPER_MODE_OUT_OF_RANGE = 0x4B;
+	public final static byte PARAMETER_EPC_MATCH_LEN_TOO_LONG = 0x4C;
+	public final static byte PARAMETER_EPC_MATCH_LEN_ERROR = 0x4D;
+	public final static byte PARAMETER_INVALID_EPC_MATCH_MODE = 0x4E;
+	public final static byte PARAMETER_INVALID_FREQUENCY_RANGE = 0x4F;
+	public final static byte FAIL_TO_GET_RN16_FROM_TAG = 0x50;
+	public final static byte PARAMETER_INVALID_DRM_MODE = 0x51;
+	public final static byte PLL_LOCK_FAIL = 0x52;
+	public final static byte RF_CHIP_FAIL_TO_RESPONSE = 0x53;
+	public final static byte FAIL_TO_ACHIEVE_DESIRED_OUTPUT_POWER = 0x54;
+	public final static byte COPYRIGHT_AUTHENTICATION_FAIL = 0x55;
+	public final static byte SPECTRUM_REGULATION_ERROR = 0x56;
+	public final static byte OUTPUT_POWER_TOO_LOW = 0x57;
+	public final static byte UNKONW_ERROR = 0x58;
+
+	/**
+	 * The description of error code.
+	 * @param btErrorCode the error code.
+	 * @return String the description of error code.
+	 */
+	public static String format(byte btErrorCode)
+	{
+		String strErrorCode = "";
+		switch (btErrorCode)
+		{
+			case SUCCESS:
+				strErrorCode = "Command succeeded.";
+				break;
+			case FAIL:
+				strErrorCode = "Command failed.";
+				break;
+			case MCU_RESET_ERROR:
+				strErrorCode = "CPU reset error.";
+				break;
+			case CW_ON_ERROR:
+				strErrorCode = "Turn on CW error.";
+				break;
+			case ANTENNA_MISSING_ERROR:
+				strErrorCode = "Antenna is missing.";
+				break;
+			case WRITE_FLASH_ERROR:
+				strErrorCode = "Write flash error.";
+				break;
+			case READ_FLASH_ERROR:
+				strErrorCode = "Read flash error.";
+				break;
+			case SET_OUTPUT_POWER_ERROR:
+				strErrorCode = "Set output power error.";
+				break;
+			case TAG_INVENTORY_ERROR:
+				strErrorCode = "Error occurred when inventory.";
+				break;
+			case TAG_READ_ERROR:
+				strErrorCode = "Error occurred when read.";
+				break;
+			case TAG_WRITE_ERROR:
+				strErrorCode = "Error occurred when write.";
+				break;
+			case TAG_LOCK_ERROR:
+				strErrorCode = "Error occurred when lock.";
+				break;
+			case TAG_KILL_ERROR:
+				strErrorCode = "Error occurred when kill.";
+				break;
+			case NO_TAG_ERROR:
+				strErrorCode = "There is no tag to be operated.";
+				break;
+			case INVENTORY_OK_BUT_ACCESS_FAIL:
+				strErrorCode = "Tag Inventoried but access failed.";
+				break;
+			case BUFFER_IS_EMPTY_ERROR:
+				strErrorCode = "Buffer is empty.";
+				break;
+			case ACCESS_OR_PASSWORD_ERROR:
+				strErrorCode = "Access failed or wrong password.";
+				break;
+			case PARAMETER_INVALID:
+				strErrorCode = "Invalid parameter.";
+				break;
+			case PARAMETER_INVALID_WORDCNT_TOO_LONG:
+				strErrorCode = "WordCnt is too long.";
+				break;
+			case PARAMETER_INVALID_MEMBANK_OUT_OF_RANGE:
+				strErrorCode = "MemBank out of range.";
+				break;
+			case PARAMETER_INVALID_LOCK_REGION_OUT_OF_RANGE:
+				strErrorCode = "Lock region out of range.";
+				break;
+			case PARAMETER_INVALID_LOCK_ACTION_OUT_OF_RANGE:
+				strErrorCode = "LockType out of range.";
+				break;
+			case PARAMETER_READER_ADDRESS_INVALID:
+				strErrorCode = "Invalid reader address.";
+				break;
+			case PARAMETER_INVALID_ANTENNA_ID_OUT_OF_RANGE:
+				strErrorCode = "AntennaID out of range.";
+				break;
+			case PARAMETER_INVALID_OUTPUT_POWER_OUT_OF_RANGE:
+				strErrorCode = "Output power out of range.";
+				break;
+			case PARAMETER_INVALID_FREQUENCY_REGION_OUT_OF_RANGE:
+				strErrorCode = "Frequency region out of range.";
+				break;
+			case PARAMETER_INVALID_BAUDRATE_OUT_OF_RANGE:
+				strErrorCode = "Baud rate out of range.";
+				break;
+			case PARAMETER_BEEPER_MODE_OUT_OF_RANGE:
+				strErrorCode = "Buzzer behavior out of range.";
+				break;
+			case PARAMETER_EPC_MATCH_LEN_TOO_LONG:
+				strErrorCode = "EPC match is too long.";
+				break;
+			case PARAMETER_EPC_MATCH_LEN_ERROR:
+				strErrorCode = "EPC match length wrong.";
+				break;
+			case PARAMETER_INVALID_EPC_MATCH_MODE:
+				strErrorCode = "Invalid EPC match mode.";
+				break;
+			case PARAMETER_INVALID_FREQUENCY_RANGE:
+				strErrorCode = "Invalid frequency range.";
+				break;
+			case FAIL_TO_GET_RN16_FROM_TAG:
+				strErrorCode = "Failed to receive RN16 from tag.";
+				break;
+			case PARAMETER_INVALID_DRM_MODE:
+				strErrorCode = "Invalid DRM mode.";
+				break;
+			case PLL_LOCK_FAIL:
+				strErrorCode = "PLL can not lock.";
+				break;
+			case RF_CHIP_FAIL_TO_RESPONSE:
+				strErrorCode = "No response from RF chip.";
+				break;
+			case FAIL_TO_ACHIEVE_DESIRED_OUTPUT_POWER:
+				strErrorCode = "Can’t achieve desired output power level.";
+				break;
+			case COPYRIGHT_AUTHENTICATION_FAIL:
+				strErrorCode = "Can’t authenticate firmware copyright.";
+				break;
+			case SPECTRUM_REGULATION_ERROR:
+				strErrorCode = "Spectrum regulation wrong.";
+				break;
+			case OUTPUT_POWER_TOO_LOW:
+				strErrorCode = "Output power too low.";
+				break;
+			default:
+				strErrorCode = "Unknown Error";
+				break;
+		}
+		return strErrorCode;
+	}
+}

+ 6 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/config/HEAD.java

@@ -0,0 +1,6 @@
+package com.tidecloud.dataacceptance.rfid.config;
+
+public class HEAD {
+	/**UHF mark to indicate the head of data package */
+	public final static byte HEAD = (byte) 0xA0;
+}

+ 19 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/DataPackageParser.java

@@ -0,0 +1,19 @@
+package com.tidecloud.dataacceptance.rfid.module.interaction;
+
+/**
+ * You can receive the raw data returned by module.In order to get the data information you must
+ * resolve it according to the protocol of module.Then you can invoke method {@link #analyData(byte[])}
+ * in {@link #DataPackageProcess} put the data package to it.The default implementation of {
+ * @link #DataPackageParser} is {@link #ReaderDataPackageParser(RFID Reader) #TDScannerDataPackageParser
+ * (2D Scanner)}
+ */
+
+public interface DataPackageParser {
+    /**
+     * The method can receive the raw data returned by module.In order to get the data information you must
+     * resolve it according to the protocol of module.
+     * @param btAryReceiveData The returned data by module.
+     * @param dataPackageProcess The class process different data package return information.
+     */
+    void runReceiveDataCallback(byte[] btAryReceiveData, DataPackageProcess dataPackageProcess);
+}

+ 20 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/DataPackageProcess.java

@@ -0,0 +1,20 @@
+package com.tidecloud.dataacceptance.rfid.module.interaction;
+
+import java.util.Observable;
+
+/**
+ * The return data process class.This class resolve the return data package to
+ * find the information you want to get.The method {@link #analyData(byte[])}
+ * receive the complete data package returned by module. Then you can process
+ * the data package by yourself.The default implement is {@link #ReaderDataPackageProcess
+ * (RFID Reader) #TDScannerDataPackageProcess(2D Scanner)}
+ */
+
+public abstract class DataPackageProcess extends Observable{
+    /**
+     * The data return method,you can receive the return data
+     * if you implements this method.
+     * @param btPackage the module return data package.
+     */
+    public abstract void analyData(byte[] btPackage);
+}

+ 38 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/ModuleConnector.java

@@ -0,0 +1,38 @@
+package com.tidecloud.dataacceptance.rfid.module.interaction;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * The interface manage the connector of module.
+ */
+
+public interface ModuleConnector {
+    
+
+    /**
+     * Connection the reader through the network;
+     * @param host The ip address;
+     * @param port The prot;
+     * @return if true connecting success,or failed.
+     */
+    ReaderHelper connectNet(final String host, final int port);
+
+    /**
+     * Different data transmission form can import via I/O stream. 
+     * @param in read steam.
+     * @param out write steam.
+     * @return {@link #ReaderHelper} return the core class to operate Reader.
+     */
+    ReaderHelper connect(final InputStream in,final OutputStream out);
+    /**
+     * Verify the the connection is available or not.
+     * @return if true connection available,or unavailable;
+     */
+    boolean isConnected();
+
+    /**
+     * Interrupt the connection;
+     */
+    void disConnect();
+}

+ 30 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/RXTXListener.java

@@ -0,0 +1,30 @@
+package com.tidecloud.dataacceptance.rfid.module.interaction;
+
+/**
+ * Implement this interface who want to listen sending data to reader,receiving data from reader,and the connection missing with reader.
+ */
+public interface RXTXListener {
+	/**
+     * This method will callback when the reader receive the data returned by reader.
+     * You can monitor the raw data return from reader via override it.
+     * And this method running in child thread.
+     *
+     * @param btAryReceiveData return data.
+     */
+    void reciveData(byte[] btAryReceiveData);
+
+    /**
+     * This method will callback when the reader send the data returned by reader.
+     * You can monitor the raw data send to reader via override it.
+     *
+     * @param btArySendData the send data to reader.
+     */
+    void sendData(byte[] btArySendData);
+
+    /**
+     * This method will callback when the monitor thread of data returned by reader is quit.
+     * You can monitor it to do something when the monitor thread of data returned by reader quit.
+     * And this method running in child thread.
+     */
+    void onLostConnect();
+}

+ 368 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/module/interaction/ReaderHelper.java

@@ -0,0 +1,368 @@
+package com.tidecloud.dataacceptance.rfid.module.interaction;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Observer;
+
+/**
+ * Base class to operate all the modules.This class include the read and write functions to module.
+ * You can receive the data via implementation {@link #DataPackageParser}.Via method
+ * {@link #sendCommand(byte[])} send data to module.Reference {@link #setReader(InputStream, OutputStream, DataPackageParser, DataPackageProcess)}
+ */
+
+public abstract class ReaderHelper {
+
+    protected ReaderBase mReader;
+    protected RXTXListener mListener;
+    /**
+     * Constructor
+     */
+    public ReaderHelper() {
+        super();
+    }
+
+    /**
+     * Set the InputStream(read module data) , OutputStream(write data to module),DataPackageParser(
+     * Parser raw data returned by module to data package according to the module protocol.
+     * Then transmit the data package to DataPackageProcess) and DataPackageProcess(Process the
+     * data package to get different information).
+     * @param in  Input stream of module.
+     * @param out Output stream of module.
+     * @param parser parse the data returned by module.
+     * @param process process the data package parsed by parser
+     * @throws Exception Throw an error when in or out is empty
+     */
+    public void setReader(InputStream in, OutputStream out, DataPackageParser parser, DataPackageProcess process) throws Exception {
+
+        if (in == null || out == null) throw new NullPointerException("in Or out is NULL!");
+
+        if (mReader == null) {
+
+            mReader = new ReaderBase(in, out, parser, process) {
+
+                @Override
+                public void onLostConnect() {
+                    ReaderHelper.this.onLostConnect();
+                }
+
+                @Override
+                public void reciveData(byte[] btAryReceiveData) {
+                    ReaderHelper.this.reciveData(btAryReceiveData);
+                }
+
+                @Override
+                public void sendData(byte[] btArySendData) {
+                    ReaderHelper.this.sendData(btArySendData);
+                }
+            };
+        }
+    }
+
+    /**
+     * Update the data when have new data return.You can listener the notification
+     * if new data return by reader via register Observer. 
+     * @param observer Register it to observable to listener the return data.
+     */
+    public void registerObserver(Observer observer) {
+        if (mReader != null) {
+            mReader.registerObserver(observer);
+        } else {
+            throw new NullPointerException("The observable is null!");
+        }
+    }
+
+    /**
+     * UnRegister the Observer.
+     * @param observer Unregister it to observable to stop listener the return data.
+     */
+    public void unRegisterObserver(Observer observer) {
+        if (mReader != null) {
+            mReader.unRegisterObserver(observer);
+        } else {
+            throw new NullPointerException("The observable is null!");
+        }
+    }
+
+    /**
+     * UnRegister all the Observers;
+     */
+    public void unRegisterObservers() {
+        if (mReader != null) {
+            mReader.unRegisterObservers();
+        } else {
+            throw new NullPointerException("The observable is null!");
+        }
+    }
+
+    /**
+     * Judge the listener Thread is alive or not.
+     * @return if true the thread is run,or the thread exit.
+     */
+    public boolean isAlive() {
+        if (mReader == null) {
+            return false;
+        } else {
+            return mReader.IsAlive();
+        }
+    }
+
+    /**
+     * You can invoke this method restart the connection if the connection missing.
+     */
+    public void startWith() {
+        if (mReader == null) {
+            throw new NullPointerException("Reader is null!");
+        } else {
+        	if (!mReader.IsAlive()) {
+        		mReader.StartWait();
+        	}
+        }
+    }
+    /**
+     * Exit the listener thread ,release the resource.
+     */
+    public void signOut() {
+    	 if (mReader != null) {
+             mReader.signOut();
+             mReader = null;
+         }
+    	 mListener = null;
+    }
+    
+    /**
+     * Set RXTX listener to listen sending data to reader,receiving data from reader and the connection missing.
+     * @param listener the interface {@link RXTXListener}} implementation class will invoke according event method. 
+     */
+    public void setRXTXListener(RXTXListener listener) {
+    	this.mListener = listener;
+    }
+
+    /**
+     * This method will callback when the reader receive the data returned by reader.
+     * You can monitor the raw data return from reader via override it.
+     * And this method running in child thread.
+     *
+     * @param btAryReceiveData return data.
+     */
+    private void reciveData(byte[] btAryReceiveData) {
+    	if (mListener != null) {
+			mListener.reciveData(btAryReceiveData);
+		}
+    }
+
+    /**
+     * This method will callback when the reader send the data returned by reader.
+     * You can monitor the raw data send to reader via override it.
+     *
+     * @param btArySendData the send data to reader.
+     */
+    private void sendData(byte[] btArySendData) {
+    	if (mListener != null) {
+			mListener.sendData(btArySendData);
+		}
+    }
+
+    /**
+     * This method will callback when the monitor thread of data returned by reader is quit.
+     * You can monitor it to do something when the monitor thread of data returned by reader quit.
+     * And this method running in child thread.
+     */
+    private void onLostConnect() {
+    	if (mListener != null) {
+			mListener.onLostConnect();
+		}
+    }
+
+    /**
+     * Send data to the reader.
+     *
+     * @param btCMDPackage the data package send to reader.
+     * @return Succeeded :0, Failed:-1
+     */
+    public int sendCommand(byte[] btCMDPackage) {
+        return mReader.sendBuffer(btCMDPackage);
+    }
+
+
+    abstract class ReaderBase {
+        private WaitThread mWaitThread = null;
+        private InputStream mInStream = null;
+        private OutputStream mOutStream = null;
+
+        private DataPackageParser mPackageParser;
+        private DataPackageProcess mPackageProcess;
+
+        /**
+         * Connection Lost. This function is invoked when the listen thread exist;
+         */
+        public abstract void onLostConnect();
+
+        /**
+         * With reference constructor. Construct a Reader with input and output streams.
+         *
+         * @param in  Input Stream
+         * @param out Output Stream
+         */
+        public ReaderBase(InputStream in, OutputStream out, DataPackageParser parser, DataPackageProcess process) throws Exception {
+            this.mInStream = in;
+            this.mOutStream = out;
+            if (parser == null || process == null)
+                throw new Exception("DataPackageParser && DataPackageProcess are null exception!");
+            mPackageParser = parser;
+            mPackageProcess = process;
+            StartWait();
+        }
+
+        public boolean IsAlive() {
+            return mWaitThread != null && mWaitThread.isAlive();
+        }
+
+        public void StartWait() {
+            mWaitThread = new WaitThread();
+            mWaitThread.start();
+        }
+
+        /**
+         * Loop receiving data thread.
+         *
+         * @author Jie
+         */
+        private class WaitThread extends Thread {
+            private boolean mShouldRunning = true;
+
+            public WaitThread() {
+                mShouldRunning = true;
+            }
+
+            @Override
+            public void run() {
+                byte[] btAryBuffer = new byte[4096];
+                while (mShouldRunning) {
+                    try {
+                        int nLenRead = mInStream.read(btAryBuffer);
+                        if (nLenRead > 0) {
+                            byte[] btAryReceiveData = new byte[nLenRead];
+                            System.arraycopy(btAryBuffer, 0, btAryReceiveData, 0,
+                                    nLenRead);
+                            reciveData(btAryReceiveData);
+                            mPackageParser.runReceiveDataCallback(btAryReceiveData, mPackageProcess);
+                        }
+                    } catch (IOException e) {
+                        onLostConnect();
+                        return;
+                    } catch (Exception e) {
+                        onLostConnect();
+                        return;
+                    }
+                }
+            }
+
+            public void signOut() {
+                mShouldRunning = false;
+                interrupt();
+            }
+        }
+
+        /**
+         * Exit receive thread
+         */
+        public final void signOut() {
+        	if (mWaitThread != null) {
+        		mWaitThread.signOut();
+        		mWaitThread = null;
+        	}
+            try {
+            	if (mInStream != null) {
+            		 mInStream.close();
+            		 mInStream = null;
+            	}
+            	
+            	if (mOutStream != null) {
+            		mOutStream.close();
+            		mOutStream = null;
+            	}
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+                mInStream = null;
+                mOutStream = null;
+            }
+            unRegisterObservers();
+            mPackageParser = null;
+            mPackageProcess = null;
+        }
+
+        /**
+         * Register Observer in order to get update.
+         *
+         * @param observer
+         */
+        public void registerObserver(Observer observer) {
+            mPackageProcess.addObserver(observer);
+        }
+
+        /**
+         * UnRegister Observer.
+         * @param observer
+         */
+        public void unRegisterObserver(Observer observer) {
+            mPackageProcess.deleteObserver(observer);
+        }
+
+        /**
+         * UnRegister all Observers;
+         */
+        public void unRegisterObservers() {
+            mPackageProcess.deleteObservers();
+        }
+
+        /**
+         * Read function' This function will be called after read data.
+         *
+         * @param btAryReceiveData
+         */
+        public void reciveData(byte[] btAryReceiveData) {
+        }
+
+        /**
+         * Rewritable function,This function will be called after sending data.
+         *
+         * @param btArySendData Transmitted Data
+         */
+        public void sendData(byte[] btArySendData) {
+        }
+
+        /**
+         * Send data,Use synchronized() to prevent concurrent operation.
+         *
+         * @param btArySenderData To send data
+         * @return Succeeded :0, Failed:-1
+         */
+        private int sendMessage(byte[] btArySenderData) {
+
+            try {
+                synchronized (mOutStream) {        //Prevent Concurrent
+                    mOutStream.write(btArySenderData);
+                }
+            } catch (IOException e) {
+                onLostConnect();
+                return -1;
+            } catch (Exception e) {
+                return -1;
+            }
+            sendData(btArySenderData);
+            return 0;
+        }
+
+        /**
+         * Send the command to module.
+         * @param completeCMD the command
+         * @return Succeeded :0, Failed:-1
+         */
+        public final int sendBuffer(byte[] completeCMD) {
+            int nResult = sendMessage(completeCMD);
+            return nResult;
+        }
+    }
+}

+ 1051 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/RXObserver.java

@@ -0,0 +1,1051 @@
+package com.tidecloud.dataacceptance.rfid.rxobserver;
+
+import java.util.Arrays;
+import java.util.Observable;
+import java.util.Observer;
+
+import com.tidecloud.dataacceptance.common.StringTool;
+import com.tidecloud.dataacceptance.rfid.bean.MessageTran;
+import com.tidecloud.dataacceptance.rfid.config.CMD;
+import com.tidecloud.dataacceptance.rfid.config.ERROR;
+import com.tidecloud.dataacceptance.rfid.config.HEAD;
+import com.tidecloud.dataacceptance.rfid.rxobserver.bean.RXInventoryTag;
+import com.tidecloud.dataacceptance.rfid.rxobserver.bean.RXOperationTag;
+
+/**
+ * Created by Administrator on 8/24/2017.
+ */
+
+public class RXObserver implements Observer{
+    private ReaderSetting m_curReaderSetting = ReaderSetting.newInstance();
+    private String strEPC;
+    private String deviceId;
+
+   
+    @Override
+    public final void update(Observable o, Object arg) {
+        if (arg instanceof MessageTran) {
+            analyData((MessageTran) arg);
+            byte readId = ((MessageTran) arg).getReadId();
+            String strResult = String.format("%02X", readId);
+            this.deviceId = strResult;
+        }
+    }
+    
+   
+
+    private void analyData(MessageTran msgTran) {
+        if (msgTran.getPacketType() != HEAD.HEAD) {
+            return;
+        }
+
+        switch (msgTran.getCmd()) {
+            case CMD.RESET:
+                processReset(msgTran);
+                break;
+            case CMD.SET_UART_BAUDRATE:
+                processSetUartBaudrate(msgTran);
+                break;
+            case CMD.GET_FIRMWARE_VERSION:
+                processGetFirmwareVersion(msgTran);
+                break;
+            case CMD.SET_READER_ADDRESS:
+                processSetReaderAddress(msgTran);
+                break;
+            case CMD.SET_WORK_ANTENNA:
+                processSetWorkAntenna(msgTran);
+                break;
+            case CMD.GET_WORK_ANTENNA:
+                processGetWorkAntenna(msgTran);
+                break;
+            case CMD.SET_OUTPUT_POWER:
+                processSetOutputPower(msgTran);
+                break;
+            case CMD.GET_OUTPUT_POWER:
+            case CMD.GET_OUTPUT_POWER_EIGHT:
+                processGetOutputPower(msgTran);
+                break;
+            case CMD.SET_FREQUENCY_REGION:
+                processSetFrequencyRegion(msgTran);
+                break;
+            case CMD.GET_FREQUENCY_REGION:
+                processGetFrequencyRegion(msgTran);
+                break;
+            case CMD.SET_BEEPER_MODE:
+                processSetBeeperMode(msgTran);
+                break;
+            case CMD.GET_READER_TEMPERATURE:
+                processGetReaderTemperature(msgTran);
+                break;
+            case CMD.READ_GPIO_VALUE:
+                processReadGpioValue(msgTran);
+                break;
+            case CMD.WRITE_GPIO_VALUE:
+                processWriteGpioValue(msgTran);
+                break;
+            case CMD.SET_ANT_CONNECTION_DETECTOR:
+                processSetAntConnectionDetector(msgTran);
+                break;
+            case CMD.GET_ANT_CONNECTION_DETECTOR:
+                processGetAntConnectionDetector(msgTran);
+                break;
+            case CMD.SET_TEMPORARY_OUTPUT_POWER:
+                processSetTemporaryOutputPower(msgTran);
+                break;
+            case CMD.SET_READER_IDENTIFIER:
+                processSetReaderIdentifier(msgTran);
+                break;
+            case CMD.GET_READER_IDENTIFIER:
+                processGetReaderIdentifier(msgTran);
+                break;
+            case CMD.SET_RF_LINK_PROFILE:
+                processSetRfLinkProfile(msgTran);
+                break;
+            case CMD.GET_RF_LINK_PROFILE:
+                processGetRfLinkProfile(msgTran);
+                break;
+            case CMD.GET_RF_PORT_RETURN_LOSS:
+                processGetRfPortReturnLoss(msgTran);
+                break;
+            case CMD.INVENTORY:
+                processInventory(msgTran);
+                break;
+            case CMD.READ_TAG:
+                processReadTag(msgTran);
+                break;
+            case CMD.WRITE_TAG:
+                processWriteTag(msgTran);
+                break;
+            case CMD.LOCK_TAG:
+                processLockTag(msgTran);
+                break;
+            case CMD.KILL_TAG:
+                processKillTag(msgTran);
+                break;
+            case CMD.SET_ACCESS_EPC_MATCH:
+                processSetAccessEpcMatch(msgTran);
+                break;
+            case CMD.GET_ACCESS_EPC_MATCH:
+                processGetAccessEpcMatch(msgTran);
+                break;
+            case CMD.REAL_TIME_INVENTORY:
+                processRealTimeInventory(msgTran);
+                break;
+            case CMD.FAST_SWITCH_ANT_INVENTORY:
+                processFastSwitchInventory(msgTran);
+                break;
+            case CMD.CUSTOMIZED_SESSION_TARGET_INVENTORY:
+                processCustomizedSessionTargetInventory(msgTran);
+                break;
+            case CMD.SET_IMPINJ_FAST_TID:
+                processSetImpinjFastTid(msgTran);
+                break;
+            case CMD.SET_AND_SAVE_IMPINJ_FAST_TID:
+                processSetAndSaveImpinjFastTid(msgTran);
+                break;
+            case CMD.GET_IMPINJ_FAST_TID:
+                processGetImpinjFastTid(msgTran);
+                break;
+            case CMD.ISO18000_6B_INVENTORY:
+                processISO180006BInventory(msgTran);
+                break;
+            case CMD.ISO18000_6B_READ_TAG:
+                processISO180006BReadTag(msgTran);
+                break;
+            case CMD.ISO18000_6B_WRITE_TAG:
+                processISO180006BWriteTag(msgTran);
+                break;
+            case CMD.ISO18000_6B_LOCK_TAG:
+                processISO180006BLockTag(msgTran);
+                break;
+            case CMD.ISO18000_6B_QUERY_LOCK_TAG:
+                processISO180006BQueryLockTag(msgTran);
+                break;
+            case CMD.GET_INVENTORY_BUFFER:
+                processGetInventoryBuffer(msgTran);
+                break;
+            case CMD.GET_AND_RESET_INVENTORY_BUFFER:
+                processGetAndResetInventoryBuffer(msgTran);
+                break;
+            case CMD.GET_INVENTORY_BUFFER_TAG_COUNT:
+                processGetInventoryBufferTagCount(msgTran);
+                break;
+            case CMD.RESET_INVENTORY_BUFFER:
+                processResetInventoryBuffer(msgTran);
+                break;
+            case CMD.OPERATE_TAG_MASK:
+                processTagMask(msgTran);
+                break;
+            default:
+                break;
+        }
+    }
+
+	/**
+     * Parse all feedback of set command.
+     *
+     * @param msgTran
+     */
+    private void processSet(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            if (btAryData[0] == ERROR.SUCCESS) {
+                m_curReaderSetting.btReadId = msgTran.getReadId();
+                refreshSetting(m_curReaderSetting);
+                onExeCMDStatus(btCmd,ERROR.SUCCESS);
+                return;
+            } else {
+                onExeCMDStatus(btCmd,btAryData[0]);
+            }
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processReset(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processSetUartBaudrate(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processGetFirmwareVersion(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+        if (btAryData.length == 0x02) {
+            m_curReaderSetting.btReadId = msgTran.getReadId();
+            m_curReaderSetting.btMajor = btAryData[0];
+            m_curReaderSetting.btMinor = btAryData[1];
+            refreshSetting(m_curReaderSetting);
+            onExeCMDStatus(btCmd,ERROR.SUCCESS);
+            return;
+        } else if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processSetReaderAddress(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processSetWorkAntenna(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            if (btAryData[0] == ERROR.SUCCESS) {
+                m_curReaderSetting.btReadId = msgTran.getReadId();
+                refreshSetting(m_curReaderSetting);
+                onExeCMDStatus(btCmd,ERROR.SUCCESS);
+                return;
+            } else {
+                onExeCMDStatus(btCmd,btAryData[0]);
+            }
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processGetWorkAntenna(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            if (btAryData[0] == 0x00 || btAryData[0] == 0x01
+                    || btAryData[0] == 0x02 || btAryData[0] == 0x03) {
+                m_curReaderSetting.btReadId = msgTran.getReadId();
+                m_curReaderSetting.btWorkAntenna = btAryData[0];
+                refreshSetting(m_curReaderSetting);
+                onExeCMDStatus(btCmd,ERROR.SUCCESS);
+                return;
+            } else {
+                onExeCMDStatus(btCmd,btAryData[0]);
+            }
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processSetOutputPower(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processGetOutputPower(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x04 || btAryData.length == 0x01 || btAryData.length == 0x08) {
+            m_curReaderSetting.btReadId = msgTran.getReadId();
+            m_curReaderSetting.btAryOutputPower = btAryData.clone();
+            refreshSetting(m_curReaderSetting);
+            onExeCMDStatus(btCmd,ERROR.SUCCESS);
+            return;
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processSetFrequencyRegion(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processGetFrequencyRegion(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x03) {
+            m_curReaderSetting.btReadId = msgTran.getReadId();
+            m_curReaderSetting.btRegion = btAryData[0];
+            m_curReaderSetting.btFrequencyStart = btAryData[1];
+            m_curReaderSetting.btFrequencyEnd = btAryData[2];
+            refreshSetting(m_curReaderSetting);
+            onExeCMDStatus(btCmd,ERROR.SUCCESS);
+            return;
+        } else if (btAryData.length == 0x06) {
+            m_curReaderSetting.btReadId = msgTran.getReadId();
+            m_curReaderSetting.btRegion = btAryData[0];
+            m_curReaderSetting.btUserDefineFrequencyInterval = btAryData[1];
+            m_curReaderSetting.btUserDefineChannelQuantity = btAryData[2];
+            m_curReaderSetting.nUserDefineStartFrequency = (btAryData[3] & 0xFF)
+                    * 256
+                    * 256
+                    + (btAryData[4] & 0xFF)
+                    * 256
+                    + (btAryData[5] & 0xFF);
+            refreshSetting(m_curReaderSetting);
+            onExeCMDStatus(btCmd,ERROR.SUCCESS);
+            return;
+        } else if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processSetBeeperMode(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processGetReaderTemperature(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x02) {
+            m_curReaderSetting.btReadId = msgTran.getReadId();
+            m_curReaderSetting.btPlusMinus = btAryData[0];
+            m_curReaderSetting.btTemperature = btAryData[1];
+            refreshSetting(m_curReaderSetting);
+            onExeCMDStatus(btCmd,ERROR.SUCCESS);
+            return;
+        } else if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processReadGpioValue(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x02) {
+            m_curReaderSetting.btReadId = msgTran.getReadId();
+            m_curReaderSetting.btGpio1Value = btAryData[0];
+            m_curReaderSetting.btGpio2Value = btAryData[1];
+            refreshSetting(m_curReaderSetting);
+            onExeCMDStatus(btCmd,ERROR.SUCCESS);
+            return;
+        } else if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processWriteGpioValue(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processSetAntConnectionDetector(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processGetAntConnectionDetector(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            m_curReaderSetting.btReadId = msgTran.getReadId();
+            m_curReaderSetting.btAntDetector = btAryData[0];
+            refreshSetting(m_curReaderSetting);
+            onExeCMDStatus(btCmd,ERROR.SUCCESS);
+            return;
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processSetTemporaryOutputPower(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processSetReaderIdentifier(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processGetReaderIdentifier(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x0C) {
+            m_curReaderSetting.btReadId = msgTran.getReadId();
+
+            Arrays.fill(m_curReaderSetting.btAryReaderIdentifier, (byte) 0x00);
+            System.arraycopy(btAryData, 0,
+                    m_curReaderSetting.btAryReaderIdentifier, 0,
+                    btAryData.length);
+            refreshSetting(m_curReaderSetting);
+            onExeCMDStatus(btCmd,ERROR.SUCCESS);
+            return;
+        } else if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processSetRfLinkProfile(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processGetRfLinkProfile(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            if ((btAryData[0] & 0xFF) >= 0xD0 && (btAryData[0] & 0xFF) <= 0xD3) {
+                m_curReaderSetting.btReadId = msgTran.getReadId();
+                m_curReaderSetting.btRfLinkProfile = btAryData[0];
+                refreshSetting(m_curReaderSetting);
+                onExeCMDStatus(btCmd,ERROR.SUCCESS);
+                return;
+            } else {
+                onExeCMDStatus(btCmd,btAryData[0]);
+            }
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processGetRfPortReturnLoss(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            m_curReaderSetting.btReadId = msgTran.getReadId();
+            m_curReaderSetting.btReturnLoss = btAryData[0];
+            refreshSetting(m_curReaderSetting);
+            onExeCMDStatus(btCmd,ERROR.SUCCESS);
+            return;
+        } else if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processInventory(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+        if (btAryData.length == 0x09) {
+            RXInventoryTag.RXInventoryTagEnd end = new RXInventoryTag.RXInventoryTagEnd();
+            end.mCurrentAnt = btAryData[0];
+            end.mTagCount = (btAryData[1] & 0xFF) * 256
+                    + (btAryData[2] & 0xFF);
+            end.mReadRate = (btAryData[3] & 0xFF) * 256
+                    + (btAryData[4] & 0xFF);
+            end.mTotalRead = (btAryData[5] & 0xFF) * 256 * 256 * 256
+                    + (btAryData[6] & 0xFF) * 256 * 256 + (btAryData[7] & 0xFF)
+                    * 256 + (btAryData[8] & 0xFF);
+            end.cmd = btCmd;
+            onInventoryTagEnd(end);
+            return;
+        } else if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd, btAryData[0]);
+        } else {
+            onExeCMDStatus(btCmd, ERROR.UNKONW_ERROR);
+        }
+    }
+    private int mOperationTagCount = 0;
+    private void processReadTag(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            mOperationTagCount++;
+            int nLen = btAryData.length;
+            int nDataLen = (btAryData[nLen - 3] & 0xFF);
+            int nEpcLen = (btAryData[2] & 0xFF) - nDataLen - 4;
+
+            String strPC = StringTool.byteArrayToString(btAryData, 3, 2);
+            String strEPC = StringTool.byteArrayToString(btAryData, 5, nEpcLen);
+            String strCRC = StringTool.byteArrayToString(btAryData,
+                    5 + nEpcLen, 2);
+            String strData = StringTool.byteArrayToString(btAryData,
+                    7 + nEpcLen, nDataLen);
+
+            byte btTemp = btAryData[nLen - 2];
+            byte btAntId = (byte) ((btTemp & 0x03) + 1 + ((btAryData[nLen - 1] & 0xFF) >> 7) * 4);
+            int nReadCount = btAryData[nLen - 1] & 0x7F;
+
+            RXOperationTag tag = new RXOperationTag();
+            tag.strPC = strPC;
+            tag.strCRC = strCRC;
+            tag.strEPC = strEPC;
+            tag.strData = strData;
+            tag.nDataLen = nDataLen;
+            tag.btAntId = btAntId;
+            tag.nOperateCount = nReadCount;
+            tag.cmd = msgTran.getCmd();
+            onOperationTag(tag);
+
+            if (mOperationTagCount == ((btAryData[0] & 0xFF) * 256 + (btAryData[1] & 0xFF))) {
+                mOperationTagCount = 0;
+                onOperationTagEnd((btAryData[0] & 0xFF) * 256 + (btAryData[1] & 0xFF));
+            }
+        }
+    }
+
+    private void processWriteTag(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+        if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd, btAryData[0]);
+        } else {
+            int nLen = btAryData.length;
+            int nEpcLen = (btAryData[2] & 0xFF) - 4;
+
+            if (btAryData[nLen - 3] != ERROR.SUCCESS) {
+                onExeCMDStatus(btCmd, btAryData[nLen - 3]);
+                return;
+            }
+            mOperationTagCount++;
+            String strPC = StringTool.byteArrayToString(btAryData, 3, 2);
+            String strEPC = StringTool.byteArrayToString(btAryData, 5, nEpcLen);
+            String strCRC = StringTool.byteArrayToString(btAryData,
+                    5 + nEpcLen, 2);
+            // add by lei.li 2016/11/10 I do not know why i fix it.
+            //String strData = "";
+            String strData = StringTool.byteArrayToString(btAryData, 0,
+            		btAryData.length);
+            //add by lei.li 2016/1/17 I do not know why i fix it;
+            byte btTemp = btAryData[nLen - 2];
+            byte btAntId = (byte) ((btTemp & 0x03) + 1 + ((btAryData[nLen - 1] & 0xFF) >> 7) * 4);
+            int nReadCount = btAryData[nLen - 1] & 0x7F;
+
+            RXOperationTag tag = new RXOperationTag();
+            tag.strPC = strPC;
+            tag.strCRC = strCRC;
+            tag.strEPC = strEPC;
+            tag.strData = strData;
+            tag.nDataLen = btAryData.length;
+            tag.btAntId = btAntId;
+            tag.nOperateCount = nReadCount;
+            tag.cmd = msgTran.getCmd();
+            onOperationTag(tag);
+            if (mOperationTagCount == ((btAryData[0] & 0xFF) * 256 + (btAryData[1] & 0xFF))) {
+                mOperationTagCount = 0;
+                onOperationTagEnd((btAryData[0] & 0xFF) * 256 + (btAryData[1] & 0xFF));
+            }
+        }
+    }
+
+    private void processLockTag(MessageTran msgTran) {
+        processWriteTag(msgTran);
+    }
+
+    private void processKillTag(MessageTran msgTran) {
+        processWriteTag(msgTran);
+    }
+
+    private void processSetAccessEpcMatch(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processGetAccessEpcMatch(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+        if (btAryData.length == 0x01) {
+            if (btAryData[0] == 0x01) {
+                onExeCMDStatus(btCmd,ERROR.FAIL);
+                return;
+            } else {
+                onExeCMDStatus(btCmd,btAryData[0]);
+            }
+        } else {
+            if (btAryData[0] == 0x00) {
+                m_curReaderSetting.mMatchEpcValue = StringTool
+                        .byteArrayToString(btAryData, 2, btAryData[1] & 0xFF);
+                refreshSetting(m_curReaderSetting);
+                onExeCMDStatus(btCmd,ERROR.SUCCESS);
+                return;
+            } else {
+                onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+            }
+        }
+    }
+
+    private void processRealTimeInventory(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else if (btAryData.length == 0x07) {
+            RXInventoryTag.RXInventoryTagEnd end = new RXInventoryTag.RXInventoryTagEnd();
+            end.mCurrentAnt = btAryData[0];
+            end.mReadRate = (btAryData[1] & 0xFF) * 256
+                    + (btAryData[2] & 0xFF);
+            end.mTotalRead = (btAryData[3] & 0xFF) * 256 * 256
+                    * 256 + (btAryData[4] & 0xFF) * 256 * 256
+                    + (btAryData[5] & 0xFF) * 256 + (btAryData[6] & 0xFF);
+            end.cmd = btCmd;
+            onInventoryTagEnd(end);
+        } else {
+            int nLength = btAryData.length;
+            int nEpcLength = nLength - 4;
+
+            //add by lei.li 2017/1/11
+            String strEPC = "";
+            if (nEpcLength != 0) {
+                strEPC = StringTool.byteArrayToString(btAryData, 3, nEpcLength);
+            }
+            //add by lei.li 2017/1/11
+            String strPC = StringTool.byteArrayToString(btAryData, 1, 2);
+            String strRSSI = String.valueOf(btAryData[nLength - 1] & 0x7F);
+            byte btTemp = btAryData[0];
+            byte btAntId = (byte) ((btTemp & 0x03) + 1 + ((btAryData[nLength - 1] & 0xFF) >> 7) * 4);
+
+            byte btFreq = (byte) ((btTemp & 0xFF) >> 2);
+            String strFreq = getFreqString(btFreq);
+
+            RXInventoryTag tag = new RXInventoryTag();
+                tag.strPC = strPC;
+                tag.strEPC = strEPC;
+                tag.strRSSI = strRSSI;
+                tag.strFreq = strFreq;
+                tag.btAntId = btAntId;
+                tag.cmd = btCmd;
+            onInventoryTag(tag);
+        }
+    }
+
+    private void processFastSwitchInventory(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+        if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else if (btAryData.length == 0x02) {
+            onExeCMDStatus(btCmd,btAryData[1]);
+        } else if (btAryData.length == 0x07) {
+            // m_nSwitchTotal, m_nSwitchTime
+            int nSwitchTotal = (btAryData[0] & 0xFF) * 255 * 255
+                    + (btAryData[1] & 0xFF) * 255 + (btAryData[2] & 0xFF);
+            int nSwitchTime = (btAryData[3] & 0xFF) * 255 * 255 * 255
+                    + (btAryData[4] & 0xFF) * 255 * 255 + (btAryData[5] & 0xFF)
+                    * 255 + (btAryData[6] & 0xFF);
+            RXInventoryTag.RXFastSwitchAntInventoryTagEnd tagEnd = new RXInventoryTag.RXFastSwitchAntInventoryTagEnd();
+            tagEnd.mTotalRead = nSwitchTotal;
+            tagEnd.mCommandDuration = nSwitchTime;
+            onFastSwitchAntInventoryTagEnd(tagEnd);
+        } else {
+            int nLength = btAryData.length;
+            int nEpcLength = nLength - 4;
+
+            String strEPC = StringTool.byteArrayToString(btAryData, 3,
+                    nEpcLength);
+            String strPC = StringTool.byteArrayToString(btAryData, 1, 2);
+            String strRSSI = String.valueOf(btAryData[nLength - 1] & 0x7F);
+            byte btTemp = btAryData[0];
+            byte btAntId = (byte) ((btTemp & 0x03) + 1 + ((btAryData[nLength - 1] & 0xFF) >> 7) * 4);
+            // String strAntId = String.valueOf(btAntId & 0xFF);
+
+            byte btFreq = (byte) ((btTemp & 0xFF) >> 2);
+            String strFreq = getFreqString(btFreq);
+            RXInventoryTag tag = new RXInventoryTag();
+                tag.strPC = strPC;
+                tag.strEPC = strEPC;
+                tag.strRSSI = strRSSI;
+                tag.strFreq = strFreq;
+                tag.btAntId = btAntId;
+                tag.cmd = btCmd;
+            onInventoryTag(tag);
+        }
+    }
+
+    /**
+     * processCustomizedSessionTargetInventory and processRealTimeInventory return consistent.
+     *
+     * @param msgTran Packet contents
+     */
+    private void processCustomizedSessionTargetInventory(MessageTran msgTran) {
+        processRealTimeInventory(msgTran);
+    }
+
+    private void processSetImpinjFastTid(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processSetAndSaveImpinjFastTid(MessageTran msgTran) {
+        processSet(msgTran);
+    }
+
+    private void processGetImpinjFastTid(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+        if (btAryData.length == 0x01) {
+            if (btAryData[0] == 0x00 || (btAryData[0] & 0xFF) == 0x8D) {
+                m_curReaderSetting.btReadId = msgTran.getReadId();
+                m_curReaderSetting.btMonzaStatus = btAryData[0];
+                refreshSetting(m_curReaderSetting);
+                onExeCMDStatus(btCmd,ERROR.SUCCESS);
+                return;
+            } else {
+                onExeCMDStatus(btCmd,btAryData[0]);
+            }
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processISO180006BInventory(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            if ((btAryData[0] & 0xFF) != 0xFF) {
+                onExeCMDStatus(btCmd,btAryData[0]);
+            }
+        } else if (btAryData.length == 0x09) {
+            String strUID = StringTool.byteArrayToString(btAryData, 1, 8);
+            onInventory6BTag(btAryData[0],strUID);
+        } else if (btAryData.length == 0x02) {
+            onInventory6BTagEnd(btAryData[1] & 0xFF);
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processISO180006BReadTag(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+        if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            String strData = StringTool.byteArrayToString(btAryData, 1,
+                    btAryData.length - 1);
+            onRead6BTag(btAryData[0],strData);
+        }
+    }
+
+    private void processISO180006BWriteTag(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            onWrite6BTag(btAryData[0],btAryData[1]);
+        }
+    }
+
+    private void processISO180006BLockTag(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,ERROR.FAIL);
+        } else {
+            onLock6BTag(btAryData[0],btAryData[1]);
+        }
+    }
+
+    private void processISO180006BQueryLockTag(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            onLockQuery6BTag(btAryData[0],btAryData[1]);
+        }
+    }
+
+    private void processGetInventoryBuffer(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd,btAryData[0]);
+        } else {
+            int nDataLen = btAryData.length;
+            int nEpcLen = (btAryData[2] & 0xFF) - 4;
+
+            String strPC = StringTool.byteArrayToString(btAryData, 3, 2);
+            String strEPC = StringTool.byteArrayToString(btAryData, 5, nEpcLen);
+            String strCRC = StringTool.byteArrayToString(btAryData,
+                    5 + nEpcLen, 2);
+            String strRSSI = String.valueOf(btAryData[nDataLen - 3] & 0x7F);
+            byte btTemp = btAryData[nDataLen - 2];
+            byte btAntId = (byte) ((btTemp & 0x03) + 1 + ((btAryData[nDataLen - 3] & 0xFF) >> 7) * 4);
+            int nReadCount = btAryData[nDataLen - 1] & 0xFF;
+
+            RXInventoryTag tag = new RXInventoryTag();
+            tag.strPC = strPC;
+            tag.strCRC = strCRC;
+            tag.strEPC = strEPC;
+            tag.btAntId = btAntId;
+            tag.strRSSI = strRSSI;
+            tag.mReadCount = nReadCount;
+            tag.cmd = btCmd;
+            onInventoryTag(tag);
+        }
+    }
+
+    /**
+     * processGetAndResetInventoryBuffer and processGetInventoryBuffer return consistent.
+     *
+     * @param msgTran Packet contents
+     */
+    private void processGetAndResetInventoryBuffer(MessageTran msgTran) {
+        processGetInventoryBuffer(msgTran);
+    }
+
+    private void processGetInventoryBufferTagCount(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x02) {
+            onGetInventoryBufferTagCount((btAryData[0] & 0xFF) * 256 + (btAryData[1] & 0xFF));
+        } else if (btAryData.length == 0x01) {
+            onExeCMDStatus(btCmd, btAryData[0]);
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    private void processResetInventoryBuffer(MessageTran msgTran) {
+        byte btCmd = msgTran.getCmd();
+        byte[] btAryData = msgTran.getAryData();
+
+        if (btAryData.length == 0x01) {
+            if (btAryData[0] == ERROR.SUCCESS) {
+                onExeCMDStatus(btCmd,ERROR.SUCCESS);
+                return;
+            } else {
+                onExeCMDStatus(btCmd,btAryData[0]);
+            }
+        } else {
+            onExeCMDStatus(btCmd,ERROR.UNKONW_ERROR);
+        }
+    }
+
+    //Some question the reader will return all the mask setting.
+    //private int mMaskQuantity = 0;
+
+	private void processTagMask(MessageTran msgTran) {
+		/*
+        byte[] btAryData = msgTran.getAryData();
+        if (btAryData.length == 1) {
+            if (btAryData[0] == (byte) 0x10) {
+                onExeCMDStatus(msgTran.getCmd(),ERROR.SUCCESS);
+                return;
+            } else if (btAryData[0] == (byte) 0x41) {
+                onExeCMDStatus(msgTran.getCmd(),btAryData[0]);
+            } else {
+                onExeCMDStatus(msgTran.getCmd(),ERROR.UNKONW_ERROR);
+            }
+        } else {
+            if (btAryData.length > 7) {
+            	MaskMap map = new MaskMap(msgTran.getAryData());
+            	if (!m_curReaderSetting.mMaskValue.contains(map)) {
+            		m_curReaderSetting.mMaskValue.add(map);
+            		mMaskQuantity++;
+            		//System.out.format("Maskquantity %d", mMaskQuantity);
+            	}
+                if (mMaskQuantity == map.mMaskQuantity) {
+                	mMaskQuantity = 0;
+                	refreshSetting(m_curReaderSetting);
+                }
+            }
+        }*/
+		if (msgTran != null) {
+    		this.onConfigTagMask(msgTran);
+    	}
+    }
+
+    private String getFreqString(byte btFreq) {
+        if (m_curReaderSetting.btRegion == 4) {
+            float nExtraFrequency = (float) (btFreq & 0xFF)
+                    * (m_curReaderSetting.btUserDefineFrequencyInterval & 0xFF)
+                    * 10;
+            float nstartFrequency = (float) ((float) (m_curReaderSetting.nUserDefineStartFrequency & 0xFF)) / 1000;
+            float nStart = (float) (nstartFrequency + nExtraFrequency / 1000);
+            String strTemp = String.format("%.3f", nStart);
+            return strTemp;
+        } else {
+            if ((btFreq & 0xFF) < 0x07) {
+                float nStart = (float) (865.00f + (float) (btFreq & 0xFF) * 0.5f);
+                String strTemp = String.format("%.2f", nStart);
+
+                return strTemp;
+            } else {
+                float nStart = (float) (902.00f + ((float) (btFreq & 0xFF) - 7) * 0.5f);
+                String strTemp = String.format("%.2f", nStart);
+                return strTemp;
+            }
+        }
+    }
+
+    /**
+     * This method will callback when you send command to inquire the settings of reader.
+     * @param readerSetting return the ReaderSetting instance it include the inquire parameters.
+     */
+    protected void refreshSetting(ReaderSetting readerSetting) {
+    }
+
+    /**
+     * This method will callback when you send command to reader.Return the status of command.
+     * @param cmd The execution command reference {@link #CMD}
+     * @param status The execution status of command,0x10 is success,0x11 is failed.
+     */
+    protected void onExeCMDStatus(byte cmd,byte status) {
+    }
+
+    /**
+     * This method will callback when you send inventory command.Return inventoried tag it will
+     * be wrapped {@link RXInventoryTag} object.
+     * @param tag The {@link RXInventoryTag} object contain tag information.
+     */
+    protected void onInventoryTag(RXInventoryTag tag) {
+    	this.strEPC = tag.strEPC;
+    }
+
+    /**
+     * This method will callback when inventory end.Return {@link RXInventoryTag.RXInventoryTagEnd}
+     * contain end information.
+     * @param tagEnd {@link RXInventoryTag.RXInventoryTagEnd} object.
+     */
+    protected void onInventoryTagEnd(RXInventoryTag.RXInventoryTagEnd tagEnd) {
+
+    }
+
+    /**
+     * This method will callback when fast switch antenna inventory end.Return {@link RXInventoryTag.com.rfid.rxobserver.bean.RXInventoryTag.RXFastSwitchAntInventoryTagEnd}
+     * contain end information.
+     * @param tagEnd {@link RXInventoryTag.com.rfid.rxobserver.bean.RXInventoryTag.RXFastSwitchAntInventoryTagEnd} object.
+     */
+    protected void onFastSwitchAntInventoryTagEnd(RXInventoryTag.RXFastSwitchAntInventoryTagEnd tagEnd) {
+
+    }
+
+    /**
+     * This method will callback when inventory 6B tag.
+     * @param nAntID current antenna id.
+     * @param strUID the inventory uid.
+     */
+    protected void onInventory6BTag(byte nAntID, String strUID) {
+    }
+
+    /**
+     * This method will callback when inventory 6B tag end.
+     * @param nTagCount the inventory 6B tag count.
+     */
+    protected void onInventory6BTagEnd(int nTagCount) {
+    }
+
+    /**
+     * This method will callback when read 6B tag.
+     * @param antID current antenna id.
+     * @param strData read 6B tag data.
+     */
+    protected void onRead6BTag(byte antID, String strData) {
+    }
+
+    /**
+     * This method will callback when write 6B tag.
+     * @param nAntID current antenna id.
+     * @param nWriteLen Write data length.
+     */
+    protected void onWrite6BTag(byte nAntID, byte nWriteLen) {
+    }
+
+    /**
+     * This method will callback when lock 6B tag.
+     * @param nAntID  current antenna id.
+     * @param nStatus Lock 6B return status (0x00:The byte is successfully locked. 0xFE:The byte is already locked. 0xFF:The byte can’t be locked)
+     */
+    protected void onLock6BTag(byte nAntID, byte nStatus) {
+    }
+
+    /**
+     * This method will callback when lock query 6B tag.
+     * @param nAntID current antenna id.
+     * @param nStatus Lock 6B return status (0x00:The byte is not locked.. 0xFE:The byte is locked.)
+     */
+    protected void onLockQuery6BTag(byte nAntID, byte nStatus) {
+    }
+
+    /**
+     *  This method will callback when get the reader inventory buffer tag count.
+     * @param nTagCount the tag count in reader inventory buffer.
+     */
+    protected void onGetInventoryBufferTagCount(int nTagCount) {
+    }
+
+    /**
+     * This method will callback when you send read,write,lock or kill command.Return information it will be wrapped
+     * {@link RXOperationTag} object.It contain the information you want to get.
+     */
+    protected void onOperationTag(RXOperationTag tag) {
+    }
+
+    /**
+     * This method will callback when operation tag command execute finish.
+     * @param operationTagCount operation tag count.
+     */
+    protected void onOperationTagEnd(int operationTagCount) {
+    }
+    
+    /**
+     * The method will callback when execute the commands about tag mask include {@link com.tidecloud.dataacceptance.rfid.RFIDReaderHelper#setTagMask(byte, byte, byte, byte, byte, byte, byte, byte[])}}
+     * {@link com.tidecloud.dataacceptance.rfid.RFIDReaderHelper#getTagMask(byte)},{@link com.tidecloud.dataacceptance.rfid.RFIDReaderHelper#clearTagMask(byte, byte)}
+     * 
+     */
+    protected void onConfigTagMask(MessageTran msgTran) {
+    }
+
+	public String getDeviceId() {
+		return deviceId;
+	}
+
+	public void setDeviceId(String deviceId) {
+		this.deviceId = deviceId;
+	}
+	
+	public String getStrEPC() {
+   		return strEPC;
+   	}
+
+   	public void setStrEPC(String strEPC) {
+   		this.strEPC = strEPC;
+   	}
+   	
+}

+ 171 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/ReaderSetting.java

@@ -0,0 +1,171 @@
+package com.tidecloud.dataacceptance.rfid.rxobserver;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Reader setting describe object
+ * @author Administrator
+ *
+ */
+public class ReaderSetting {
+
+	private static final ReaderSetting mReaderSetting = new ReaderSetting();
+
+	/** Reader ID*/
+	public byte btReadId;
+	/** Reader major version NO*/
+	public byte btMajor;
+	/** Reader Minor version NO*/
+	public byte btMinor;
+	@Deprecated
+	public byte btIndexBaudrate;
+	/**Reader temperature symbol*/
+	public byte btPlusMinus;
+	/**Reader temperature value */
+	public byte btTemperature;
+	/**Output power 1,4 or 8 bytes*/
+	public byte []btAryOutputPower;
+	/** Work Antenna*/
+	public byte btWorkAntenna;
+	@Deprecated
+	public byte btDrmMode;
+	/** Frequency Region*/
+	public byte btRegion;
+	/** Frequency Start value*/
+	public byte btFrequencyStart;
+	/** Frequency End value*/
+	public byte btFrequencyEnd;
+	/** Beeper Mode*/
+	public byte btBeeperMode;
+	/** Reader GPI01 */
+	public byte btGpio1Value;
+	/** Reader GPI02 */
+	public byte btGpio2Value;
+	/** Reader GPI03 */
+	public byte btGpio3Value;
+	/** Reader GPI04 */
+	public byte btGpio4Value;
+	
+	/**Antenna sensitivity*/
+	public byte btAntDetector;
+	/** Monza TID switch status*/
+	public byte btMonzaStatus;
+	/** Monza Whether save the status*/
+	public boolean blnMonzaStore;
+	/**Identifier fixed 12 bytes*/
+	public byte []btAryReaderIdentifier;
+	/** Return loss */
+	public byte btReturnLoss;
+	@Deprecated
+	public byte btImpedanceFrequency;
+	
+	/** Custom starting frequency*/
+	public int nUserDefineStartFrequency;
+	/** Custom channel spacing*/
+	public byte btUserDefineFrequencyInterval;
+	/**  custom number frequency point */
+	public byte btUserDefineChannelQuantity;
+	/** Rf communications link*/
+	public byte btRfLinkProfile;
+	/** match epc value*/
+	public String mMatchEpcValue;
+
+	/**
+     * Get the single ReaderSetting instance.
+	 * @return the single ReaderSetting instance.
+	 */
+	static ReaderSetting newInstance() {
+		return mReaderSetting;
+	}
+
+	private ReaderSetting() {
+		btReadId = (byte) 0xFF;
+		btMajor = 0x00;
+		btMinor = 0x00;
+		btIndexBaudrate = 0x00;
+		btPlusMinus = 0x00;
+		btTemperature = 0x00;
+		btAryOutputPower = null;
+		btWorkAntenna = 0x00;
+		btDrmMode = 0x00;
+		btRegion = 0x00;
+		btFrequencyStart = 0x00;
+		btFrequencyEnd = 0x00;
+		btBeeperMode = 0x00;
+		blnMonzaStore = false;
+		btGpio1Value = 0x00;
+		btGpio2Value = 0x00;
+		btGpio3Value = 0x00;
+		btGpio4Value = 0x00;
+		btAntDetector = 0x00;
+		btMonzaStatus = 0x00;
+		btAryReaderIdentifier = new byte[12];
+		btReturnLoss = 0x00;
+		btImpedanceFrequency = 0x00;
+		nUserDefineStartFrequency = 0x00;
+		btUserDefineFrequencyInterval = 0x00;
+		btUserDefineChannelQuantity = 0x00;
+		btRfLinkProfile = 0x00;
+		mMatchEpcValue = null;
+	}
+	
+	/**
+	 * Wrapper class of mask query information.
+	 */
+	public static class MaskMap {
+        /** you can set 1-5 mask, this is the mask id*/
+		public byte mMaskID;
+		/** The quantity of setting mask*/
+		public byte mMaskQuantity;
+		/** 0x00	Inventoried S0
+		    0x01	Inventoried S1
+		 	0x02	Inventoried S2
+		 	0x03	Inventoried S3
+		 	0x04	SL
+		 */
+		public byte mTarget;
+		/** 	  Tag Matches Mask 	           |     Tag Doesn’t Match Mask
+		 0x00	Assert SL or inventoried ->A   |	Deassert SL or inventoried ->B
+		 0x01	Assert SL or inventoried ->A   |	Do nothing
+		 0x02	Do nothing	                   |    Deassert SL or inventoried->B
+		 0x03	Negate SL or(A->B,B->A)	       |    Do nothing
+		 0x04	Deassert SL or inventoried ->B |	Assert SL or inventoried->A
+		 0x05	Deaaert SL or inventoried ->B  |	Do nothing
+		 0x06	Do nothing	                   |    Assert SL or inventoried ->A
+		 0x07	Do nothing	                   |    Negate SL or (A->B, B->A)
+		 */
+		public byte mAction;
+		/**0x00	Reserved for Future use
+		   0x01	EPC
+		   0x02	TID
+		   0x03	USER
+		 */
+		public byte mMembank;
+		/** Start mask address,unit is bit*/
+		public byte mStartMaskAdd;
+		/** Mask length, unit is bit*/
+		public byte mMaskBitLen;
+		/**You need not complete mask all the value,it according the {@link #mMaskValue}*/
+		public byte[] mMaskValue;
+		/** Reserved */
+		public byte mTruncate;
+		public MaskMap(byte[] data) {
+			this.mMaskID =data[0];
+			this.mMaskQuantity = data[1];
+			this.mTarget = data[2];
+			this.mAction = data[3];
+			this.mMembank = data[4];
+			this.mStartMaskAdd = data[5];
+			this.mMaskBitLen = data[6];
+			this.mMaskValue = new byte[data.length - 8];
+			System.arraycopy(data,7,this.mMaskValue,0,mMaskValue.length);
+			this.mTruncate = data[data.length - 1];
+		}
+		
+		@Override
+		public boolean equals(Object obj) {
+			return this.mMaskID == ((MaskMap)obj).mMaskID;
+		}
+	}
+}

+ 26 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/bean/RXInventory6BTag.java

@@ -0,0 +1,26 @@
+package com.tidecloud.dataacceptance.rfid.rxobserver.bean;
+
+/**
+ * Wrapper class of ISO180006B tag return data package.
+ */
+
+public class RXInventory6BTag {
+    /** Inventory antenna id*/
+    public byte mAntID;
+    /** 6B tag UID*/
+    public String mUID;
+    /** cmd distinguish which command return.*/
+    public byte cmd;
+    /** The reader address of return data*/
+    public byte btReaderId;
+
+    /**
+     * Default constructor
+     */
+    public RXInventory6BTag() {
+        this.mAntID = 0x00;
+        this.mUID = "";
+        this.cmd = 0x00;
+        this.btReaderId = 0x00;
+    }
+}

+ 81 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/bean/RXInventoryTag.java

@@ -0,0 +1,81 @@
+package com.tidecloud.dataacceptance.rfid.rxobserver.bean;
+
+/**
+ * Created by Administrator on 8/24/2017.
+ */
+
+public class RXInventoryTag {
+    /** PC value*/
+    public String strPC;
+    /** CRC value*/
+    public String strCRC;
+    /** EPC value*/
+    public String strEPC;
+    /** antenna ID*/
+    public byte btAntId;
+    /** RSSI value*/
+    public String strRSSI;
+    /**carrier frequency*/
+    public String strFreq;
+    /** Inventory count only used in Get_inventory_buffer command */
+    public int mReadCount;
+    /** Distinguish the return tag data from which command cmd_get_inventory_buffer
+     *  cmd_real_time_inventory or cmd_customized_session_target_inventory;
+     * */
+    public byte cmd;
+    /**
+     * Defaulted constructor
+     */
+    public RXInventoryTag() {
+        strPC = "";
+        strCRC = "";
+        strEPC = "";
+        btAntId = 0;
+        strRSSI = "";
+        strFreq = "";
+        cmd = 0;
+    }
+
+    /**
+     * Wrapper class of inventory end data package.
+     */
+    public static class RXInventoryTagEnd {
+        /**Current work antenna*/
+        public int mCurrentAnt;
+        /** Tag count distinguish used EPC only use by inventory command*/
+        public int mTagCount;
+        /**Read rate*/
+        public int mReadRate;
+        /** The total tag count*/
+        public int mTotalRead;
+        /** cmd distinguish which command return.*/
+        public byte cmd;
+        /** The reader address of return data*/
+        public byte btReaderId;
+
+        public RXInventoryTagEnd() {
+            this.mCurrentAnt = 0;
+            this.mTagCount = 0;
+            this.mReadRate = 0;
+            this.mTotalRead = 0;
+            this.cmd = 0;
+            this.btReaderId = 0;
+        }
+    }
+
+    /**
+     * Wrapper class of fast switch antenna end data package.
+     */
+    public static class RXFastSwitchAntInventoryTagEnd {
+    	/** */
+        public int mTotalRead;
+        public int mCommandDuration;
+        /** The reader address of return data*/
+        public byte btReaderId;
+        public RXFastSwitchAntInventoryTagEnd () {
+            this.mTotalRead = 0;
+            this.mCommandDuration = 0;
+        }
+    }
+
+}

+ 37 - 0
src/main/java/com/tidecloud/dataacceptance/rfid/rxobserver/bean/RXOperationTag.java

@@ -0,0 +1,37 @@
+package com.tidecloud.dataacceptance.rfid.rxobserver.bean;
+
+/**
+ * Wrapper class of operation tag return data package.
+ */
+
+public class RXOperationTag {
+    /** PC value*/
+    public String strPC;
+    /** CRC value*/
+    public String strCRC;
+    /** EPC value*/
+    public String strEPC;
+    /** Data in total */
+    public String strData;
+    /** Length of data */
+    public int nDataLen;
+    /** Antenna ID*/
+    public byte btAntId;
+    /** Operating times */
+    public int nOperateCount;
+    /** Operating command*/
+    public byte cmd;
+    /**
+     *Operations (including read,write,lock and kill)tag default constructor
+     */
+    public RXOperationTag() {
+        strPC = "";
+        strCRC = "";
+        strEPC = "";
+        strData = "";
+        nDataLen = 0;
+        btAntId = 0;
+        nOperateCount = 0;
+        cmd = 0;
+    }
+}

+ 67 - 0
src/main/java/com/tidecloud/dataacceptance/service/impl/VorgeaUR0401ServerHandler.java

@@ -0,0 +1,67 @@
+package com.tidecloud.dataacceptance.service.impl;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import com.tidecloud.dataacceptance.rfid.ReaderDataPackageParser;
+import com.tidecloud.dataacceptance.rfid.ReaderDataPackageProcess;
+import com.tidecloud.dataacceptance.rfid.module.interaction.DataPackageParser;
+import com.tidecloud.dataacceptance.rfid.module.interaction.DataPackageProcess;
+import com.tidecloud.dataacceptance.rfid.rxobserver.RXObserver;
+import com.tidecloud.dataacceptance.service.AcceptanceInboundHandlerAdapter;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+
+/**
+ * @author ryan
+ */
+@Component
+@ChannelHandler.Sharable
+public class VorgeaUR0401ServerHandler extends AcceptanceInboundHandlerAdapter {
+
+	private static final Logger logger = LoggerFactory.getLogger(VorgeaUR0401ServerHandler.class);
+	
+
+	DataPackageParser mPackageParser = new ReaderDataPackageParser();
+	DataPackageProcess mPackageProcess = new ReaderDataPackageProcess();
+	
+	private RXObserver mObserver = new RXObserver() ;
+	DateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
+
+	@Override
+	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+
+		ByteBuf byteBuf = (ByteBuf) msg;
+		int len = byteBuf.readableBytes();
+
+		byte[] btAryReceiveData = new byte[len];
+
+		byteBuf.getBytes(0, btAryReceiveData);
+
+		mPackageProcess.addObserver(mObserver);
+		
+		mPackageParser.runReceiveDataCallback(btAryReceiveData, mPackageProcess);
+		// String strEPC = mObserver.ge
+		
+		// manageChannel(ctx.channel(), phone);
+		String epc = mObserver.getStrEPC();
+		String deviceId = mObserver.getDeviceId();
+		String storageStr = deviceId+";"+epc+";"+fmt.format(new Date());
+		dataStorage(storageStr);
+
+	}
+
+
+	@Override
+	public void reply(ChannelHandlerContext ctx, String msg) throws Exception {
+		// TODO Auto-generated method stub
+		
+	}
+}

+ 12 - 3
src/main/resources/application.yml

@@ -61,12 +61,21 @@ acceptance:
     enable: true    
    -
     name: yuguang
-    topic: device-yitong-bingshui
+    topic: device-yuguang
     ip: 10.27.118.76
     port: 7510
     dataFileDir: /home/service/collector_7510/rawdata/
-    handlerClass: com.tidecloud.dataacceptance.service.impl.YiTongGpsServerHandler
-    enable: true        
+    handlerClass: com.tidecloud.dataacceptance.service.impl.YuGuangGpsServerHandler
+    enable: true       
+
+   -
+    name: vorgea
+    topic: device-vorgea
+    ip: 10.27.118.76
+    port: 7511
+    dataFileDir: /home/service/collector_vorgea/rawdata/
+    handlerClass: com.tidecloud.dataacceptance.service.impl.VorgeaUR0401ServerHandler
+    enable: true         
       
 logging:
   config: