mirror of
https://github.com/RfidResearchGroup/RFIDtools.git
synced 2026-05-12 11:19:59 -07:00
Project rebuild & clean up.
This commit is contained in:
@@ -1,46 +0,0 @@
|
||||
package cn.dxl.common.posixio;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
/*
|
||||
* author DXL
|
||||
* 通信接口,实现了必要的元素传递以及通信实现规定
|
||||
*/
|
||||
public interface Communication extends Serializable, Closeable {
|
||||
|
||||
/**
|
||||
* @param sendMsg data buffer, transfer data from here.
|
||||
* @param offset the data from buffer valid offset.
|
||||
* @param length the data length from buffer,buffer may be 1024bytes, but valid data length is 512bytes.
|
||||
* @param timeout if write need timeout, use me.
|
||||
* @return the length of write finished.
|
||||
* @throws IOException throw a IOException if have some problem.
|
||||
*/
|
||||
int write(byte[] sendMsg, int offset, int length, int timeout) throws IOException;
|
||||
|
||||
/**
|
||||
* @param recvMsg data buffer, read data to here.
|
||||
* @param offset read data to buffer from offset started.
|
||||
* @param length the length of data need read.
|
||||
* @param timeout if read need timeout at data length no enough, use me.
|
||||
* @return the length of read finished.
|
||||
* @throws IOException throw a IOException if have some problem.
|
||||
*/
|
||||
int read(byte[] recvMsg, int offset, int length, int timeout) throws IOException;
|
||||
|
||||
/**
|
||||
* flush outputstream.
|
||||
*
|
||||
* @throws IOException throw a IOException if have some problem.
|
||||
*/
|
||||
void flush() throws IOException;
|
||||
|
||||
/**
|
||||
* close io stream
|
||||
*
|
||||
* @throws IOException throw a IOException if have some problem.
|
||||
*/
|
||||
void close() throws IOException;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package cn.dxl.common.util;
|
||||
|
||||
public class Checksum {
|
||||
/**
|
||||
* Calculates the checksum of the passed byte buffer.
|
||||
*
|
||||
* @param buffer
|
||||
* @param byteCount
|
||||
* @return byte checksum value
|
||||
*/
|
||||
public static byte calcChecksum(byte[] buffer, int byteCount) {
|
||||
byte checksum = 0;
|
||||
int bufPos = 0;
|
||||
while (byteCount-- != 0) {
|
||||
checksum += buffer[bufPos++];
|
||||
}
|
||||
return checksum;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package cn.dxl.common.xmodem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import cn.dxl.common.posixio.Communication;
|
||||
|
||||
/**
|
||||
* @author DXL
|
||||
* 抽象XModem,定义协议的基本特性,通用动作!
|
||||
*/
|
||||
public abstract class AbstractXModem {
|
||||
|
||||
protected String LOG_TAG = this.getClass().getSimpleName();
|
||||
|
||||
// 结束
|
||||
protected byte mEOT = 0x04;
|
||||
// 应答
|
||||
protected byte mACK = 0x06;
|
||||
// 重传
|
||||
protected byte mNAK = 0x15;
|
||||
// 无条件结束
|
||||
protected byte mCAN = 0x18;
|
||||
|
||||
// 以128字节块的形式传输数据
|
||||
protected int mBlockSize = 128;
|
||||
// 最大错误(无应答)包数
|
||||
protected int mErrorMax = 10;
|
||||
|
||||
// 通信接口,用于读取串口数据
|
||||
private Communication mCom;
|
||||
|
||||
public AbstractXModem(Communication com) {
|
||||
this.mCom = com;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sources 字节来源,可以是InputStream的任何有效实现!
|
||||
* @return 传输结果!
|
||||
*/
|
||||
public abstract boolean send(InputStream sources) throws IOException;
|
||||
|
||||
/**
|
||||
* @param target 字节去向,可以是OutputStream的任何有效实现!
|
||||
* @return 传输结果!
|
||||
*/
|
||||
public abstract boolean recv(OutputStream target) throws IOException;
|
||||
|
||||
/**
|
||||
* 刷新数据,进行剩余字节发送!!
|
||||
*
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
protected void flush() throws IOException {
|
||||
mCom.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据,每次在超时值内读取一个字节!
|
||||
*
|
||||
* @return 数据
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
protected byte read(int timeout) throws IOException {
|
||||
byte[] b = new byte[1];
|
||||
mCom.read(b, 0, 1, timeout);
|
||||
return b[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送数据
|
||||
*
|
||||
* @param data 数据
|
||||
* @return 发送成功的字节长度!
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
protected int write(byte data, int timeout) throws IOException {
|
||||
byte[] b = {data};
|
||||
return mCom.write(b, 0, 1, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送数据
|
||||
*
|
||||
* @param dataByte 数据
|
||||
* @param checkSum 校验和
|
||||
* @return 发送成功的字节
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
protected int write(byte[] dataByte, byte[] checkSum, int timeout) throws IOException {
|
||||
//分配缓冲区!
|
||||
ByteBuffer bb = ByteBuffer
|
||||
.allocate(dataByte.length + checkSum.length)
|
||||
.order(ByteOrder.BIG_ENDIAN)
|
||||
.put(dataByte) //提交数据!
|
||||
.put(checkSum); //提交校验!
|
||||
byte[] array = bb.array();
|
||||
return mCom.write(array, 0, array.length, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消传输。使停止!
|
||||
*
|
||||
* @param timeout 超时值!
|
||||
*/
|
||||
public void cancel(int timeout) throws IOException {
|
||||
write(mCAN, timeout);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package cn.dxl.common.xmodem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import cn.dxl.common.posixio.Communication;
|
||||
|
||||
public class XModem1024 extends AbstractXModem {
|
||||
|
||||
//起始头!
|
||||
private byte STX = 0x02;
|
||||
|
||||
public XModem1024(Communication com) {
|
||||
super(com);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean send(InputStream sources) throws IOException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean recv(OutputStream target) throws IOException {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
package cn.dxl.common.xmodem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import cn.dxl.common.posixio.Communication;
|
||||
import cn.dxl.common.util.Checksum;
|
||||
|
||||
public class XModem128 extends AbstractXModem {
|
||||
|
||||
/**
|
||||
* 128字节单块传输的XModem协议实现!
|
||||
* ---------------------------------------------------------------------------
|
||||
* | Byte1 | Byte2 | Byte3 |Byte4~Byte131| Byte132 |
|
||||
* |-------------------------------------------------------------------------|
|
||||
* |Start Of Header|Packet Number|~(Packet Number)| Packet Data | Check Sum |
|
||||
* ---------------------------------------------------------------------------
|
||||
*
|
||||
* @ref https://blog.csdn.net/jumahe/article/details/40266637
|
||||
*/
|
||||
|
||||
// 开始
|
||||
private byte SOH = 0x01;
|
||||
// 超时
|
||||
private final int TIMEOUT = 1000;
|
||||
|
||||
public XModem128(Communication com) {
|
||||
super(com);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean send(InputStream sources) throws IOException {
|
||||
// 错误包数
|
||||
int errorCount;
|
||||
// 包序号
|
||||
byte blockNumber = 0x01;
|
||||
// 校验和
|
||||
byte checkSum;
|
||||
// 读取到缓冲区的字节数量
|
||||
int nbytes;
|
||||
// 初始化数据缓冲区
|
||||
byte[] sector = new byte[mBlockSize];
|
||||
// 读取文件初始化
|
||||
while ((nbytes = sources.read(sector)) > 0) {
|
||||
// 如果最后一包数据小于128个字节,以0xff补齐
|
||||
if (nbytes < mBlockSize) {
|
||||
for (int i = nbytes; i < mBlockSize; i++) {
|
||||
sector[i] = (byte) 0xff;
|
||||
}
|
||||
}
|
||||
// 同一包数据最多发送10次
|
||||
errorCount = 0;
|
||||
while (errorCount < mErrorMax) {
|
||||
// 控制字符 + 包序号 + 包序号的反码 + 数据 + 校验和
|
||||
write(SOH, TIMEOUT); //1、发送控制字符!
|
||||
write(blockNumber, TIMEOUT); //2、发送包序号!
|
||||
write((byte) (255 - blockNumber), TIMEOUT); //3、发送包序号的反码!
|
||||
checkSum = Checksum.calcChecksum(sector, mBlockSize); //4、计算数据的校验和
|
||||
write(sector, new byte[]{checkSum}, TIMEOUT); //5、进行数据+校验和的封包发送!
|
||||
flush(); //6、刷新缓冲区,发送数据!
|
||||
// 获取应答数据
|
||||
byte data = read(TIMEOUT);
|
||||
//Log.d(LOG_TAG, "应答数据为: " + HexUtil.toHexString(data));
|
||||
// 如果收到应答数据则跳出循环,发送下一包数据
|
||||
// 未收到应答,错误包数+1,继续重发
|
||||
if (data == mNAK) {
|
||||
//重传!
|
||||
++errorCount;
|
||||
} else if (data == mCAN) {
|
||||
//终止命令!
|
||||
return false;
|
||||
} else if (data == mACK) {
|
||||
//Log.d(LOG_TAG, "ACK已收到,可以进行下一轮发送!");
|
||||
break;
|
||||
} else {
|
||||
//重传!
|
||||
++errorCount;
|
||||
}
|
||||
}
|
||||
// 包序号自增
|
||||
blockNumber = (byte) ((++blockNumber) % 256);
|
||||
}
|
||||
// 所有数据发送完成后,发送结束标识
|
||||
boolean isAck = false;
|
||||
while (!isAck) {
|
||||
write(mEOT, TIMEOUT);
|
||||
isAck = read(TIMEOUT) == mACK;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean recv(OutputStream target) throws IOException {
|
||||
// 错误包数
|
||||
int errorCount = 0;
|
||||
// 包序号
|
||||
byte blocknumber = 0x01;
|
||||
// 数据
|
||||
byte data;
|
||||
// 校验和
|
||||
int checkSum;
|
||||
// 初始化数据缓冲区
|
||||
byte[] sector = new byte[mBlockSize];
|
||||
// 握手,发起传输!
|
||||
write(mNAK, TIMEOUT);
|
||||
while (true) {
|
||||
if (errorCount > mErrorMax) {
|
||||
//Log.d(LOG_TAG, "错误重试次数已达上限!");
|
||||
return false;
|
||||
}
|
||||
// 获取应答数据
|
||||
data = read(TIMEOUT);
|
||||
if (data != mEOT) {
|
||||
try {
|
||||
// 判断接收到的是否是开始标识
|
||||
if (data != SOH) {
|
||||
//Log.d(LOG_TAG, "非开始标志!");
|
||||
errorCount++;
|
||||
continue;
|
||||
}
|
||||
// 获取包序号
|
||||
data = read(TIMEOUT);
|
||||
//Log.d(LOG_TAG, "包序号: " + data);
|
||||
// 判断包序号是否正确
|
||||
if (data != blocknumber) {
|
||||
//Log.d(LOG_TAG, "包序号不正常!");
|
||||
errorCount++;
|
||||
continue;
|
||||
}
|
||||
// 获取包序号的反码
|
||||
byte _blocknumber = read(TIMEOUT);
|
||||
//Log.d(LOG_TAG, "包序号的反码: " + _blocknumber);
|
||||
// 判断包序号的反码是否正确
|
||||
if (data + _blocknumber != (byte) 255) {
|
||||
//Log.d(LOG_TAG, "包序号的反码不正常!");
|
||||
errorCount++;
|
||||
continue;
|
||||
}
|
||||
// 获取数据
|
||||
for (int i = 0; i < mBlockSize; i++) {
|
||||
sector[i] = read(TIMEOUT);
|
||||
}
|
||||
//Log.d(LOG_TAG, "获取到的数据: " + HexUtil.toHexString(sector));
|
||||
// 获取校验和
|
||||
checkSum = read(TIMEOUT);
|
||||
//Log.d(LOG_TAG, "接收到的校验和: " + checkSum);
|
||||
// 判断校验和是否正确
|
||||
int crc = Checksum.calcChecksum(sector, mBlockSize);
|
||||
//Log.d(LOG_TAG, "计算到的校验和: " + crc);
|
||||
if (crc != checkSum) {
|
||||
//Log.d(LOG_TAG, "包数据的校验不正常!");
|
||||
errorCount++;
|
||||
continue;
|
||||
}
|
||||
//Log.d(LOG_TAG, "接收一帧完成!");
|
||||
// 发送应答
|
||||
write(mACK, TIMEOUT);
|
||||
// 包序号自增
|
||||
blocknumber++;
|
||||
// 将数据写入本地
|
||||
target.write(sector);
|
||||
// 错误包数归零
|
||||
errorCount = 0;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
// 如果出错发送重传标识
|
||||
if (errorCount != 0) {
|
||||
//Log.d(LOG_TAG, "错误,将发送重传标志!");
|
||||
write(mNAK, TIMEOUT);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 发送应答
|
||||
write(mACK, TIMEOUT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user