package com.qk.yodemlib;
import android.util.Log;
import com.project.tools.ChatUtils;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
/**
* This is core Modem class supporting XModem (and some extensions XModem-1K, XModem-CRC), and YModem.<br/>
* YModem support is limited (currently block 0 is ignored).<br/>
* <br/>
* Created by Anton Sirotinkin (aesirot@mail.ru), Moscow 2014 <br/>
* I hope you will find this program useful.<br/>
* You are free to use/modify the code for any purpose, but please leave a reference to me.<br/>
*/
class Modem {
/* Protocol characters used */
protected static final byte SOH = 0x01; /* Start Of Header */
protected static final byte STX = 0x02; /* Start Of Text (used like SOH but means 1024 block size) */
protected static final byte EOT = 0x04; /* End Of Transmission */
protected static final byte ACK = 0x06; /* ACKnowlege */
protected static final byte NAK = 0x15; /* Negative AcKnowlege */
protected static final byte CAN = 0x18; /* CANcel character */
protected static final byte CPMEOF = 0x1A;
protected static final byte ST_C = 'C';
protected static final int MAXERRORS = 10;
private InputStream inputStream;
private OutputStream outputStream;
private boolean isReading = true;
/**
* Constructor
*
* @param inputStream stream for reading received data from other side
* @param outputStream stream for writing data to other side
*/
protected Modem(InputStream inputStream, OutputStream outputStream) {
this.inputStream = inputStream;
this.outputStream = outputStream;
isReading = true;
}
protected void sendDataBlocks(DataInputStream dataStream, int blockNumber, CRC crc, byte[] block) throws IOException {
int dataLength;
while ((dataLength = dataStream.read(block)) != -1) {
sendBlock(blockNumber++, block, dataLength, crc);
}
}
public void sendFileZero() throws IOException {
int errorCount = 0;
int character;
while (errorCount < 6) {
byte seq = 0x00;
byte[] data = YModemUtils.getDataPackage(new byte[128], 128, seq, new CRC16());
outputStream.write(data);
outputStream.flush();
try {
character = readByte();
if (character == ACK) {
break;
} else if (character == CAN) {
throw new IOException("Transmission terminated");
}
} catch (Exception ignored) {
}
errorCount++;
}
}
protected void sendEOT() throws IOException {
int errorCount = 0;
int character;
while (errorCount < 10) {
sendByte(EOT);
try {
character = readByte();
if (character == ACK) {
return;
} else if (character == CAN) {
throw new IOException("Transmission terminated");
}
} catch (Exception ignored) {
}
errorCount++;
}
}
protected void sendFileInfo(int blockNumber, byte[] block, int dataLength, CRC crc) throws IOException {
int errorCount;
byte character;
if (dataLength < block.length) {
block[dataLength] = CPMEOF;
}
errorCount = 0;
while (errorCount < MAXERRORS)
{
byte head;
if (block.length == 1024) {
head = STX;
// outputStream.write(STX);
} else { //128
head = SOH;
// outputStream.write(SOH);
}
byte[] headByte = YModemUtils.getDataHeader(ChatUtils.intToBytes(blockNumber)[0], head);
// Log.i("TAG", " -- block -- " + ChatUtils.bytesToHexString(block)); // 112个00
// outputStream.write(block);
byte[] crcbyte = writeCRC(block, crc);
byte[] fileData = YModemUtils.concat(headByte, block, crcbyte);
outputStream.write(fileData);
outputStream.flush();
Log.i("TAG", " -- sendFileInfo -- " + blockNumber + " ; " + ChatUtils.bytesToHexString(fileData));
boolean receiveACK = false;
while (true) {
try {
character = readByte();
if (character == ACK) {
receiveACK = true;
Log.i("TAG"," -- readByte ACK ---");
// shortSleep();
// return;
} else if (character == NAK) {
errorCount++;
shortSleepTime(10);
Log.i("TAG"," -- readByte NAK ---");
break;
} else if (character == ST_C) {
Log.i("TAG"," -- readByte ST_C ---");
if(receiveACK) {
shortSleepTime(10);
return;
} else {
errorCount++;
shortSleepTime(10);
break;
}
} else if (character == CAN) {
throw new IOException("Transmission terminated");
}else {
throw new IOException("Transmission terminated");
}
} catch (Exception e) {
errorCount++;
break;
}
}
}
throw new IOException("Too many errors caught, abandoning transfer");
}
protected void sendBlock(int blockNumber, byte[] block, int dataLength, CRC crc) throws IOException {
int errorCount;
byte character;
if (dataLength < block.length) {
block[dataLength] = CPMEOF;
}
errorCount = 0;
while (errorCount < MAXERRORS)
{
byte head;
if (block.length == 1024) {
head = STX;
// outputStream.write(STX);
} else { //128
head = SOH;
// outputStream.write(SOH);
}
byte[] headByte = YModemUtils.getDataHeader(ChatUtils.intToBytes(blockNumber)[0], head);
// outputStream.write(blockNumber);
// outputStream.write(~blockNumber);
//
// Log.i("TAG", " -- block -- " + ChatUtils.bytesToHexString(block)); // 112个00
// outputStream.write(block);
byte[] crcbyte = writeCRC(block, crc);
byte[] fileData = YModemUtils.concat(headByte, block, crcbyte);
outputStream.write(fileData);
outputStream.flush();
Log.i("TAG", " -- fileData -- " + blockNumber + " ; " + ChatUtils.bytesToHexString(fileData));
while (true) {
try {
character = readByte();
if (character == ACK) {
Log.i("TAG"," -- readByte ACK ---");
shortSleepTime(10);
return;
} else if (character == NAK) {
errorCount++;
Log.i("TAG"," -- readByte NAK ---");
shortSleepTime(10);
break;
} else if (character == ST_C) {
errorCount++;
Log.i("TAG"," -- readByte ST_C ---");
shortSleepTime(10);
break;
} else if (character == CAN) {
throw new IOException("Transmission terminated");
}else {
throw new
评论0