Project rebuild & clean up.

This commit is contained in:
dxl
2020-04-13 12:17:12 +08:00
parent 86e2e9c5cf
commit df501b9181
2326 changed files with 297 additions and 2980642 deletions
@@ -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;
}
}