package cbcdownloader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Packet {
public static final int PACKET_KEY = 0xB07BA11;
private static final int CRC16_TABLE[] = { 0x0000, 0x1081, 0x2102, 0x3183,
0x4204, 0x5285, 0x6306, 0x7387, 0x8408, 0x9489, 0xa50a, 0xb58b,
0xc60c, 0xd68d, 0xe70e, 0xf78f };
private static final int SERIAL_MAX_RETRY = 5;
private static final int SERIAL_MESSAGE_OK = 1;
private static final int SERIAL_START = 0xCBC;
private static byte[] data = null;
public Packet(byte[] data) {
this.data = data;
}
private static boolean checkAck(InputStream in) throws IOException {
int ret = 0;
ret = in.read();
if (ret == SERIAL_MESSAGE_OK) {
return true;
}
return false;
}
private static void sendAck(OutputStream out) throws IOException {
out.write(SERIAL_MESSAGE_OK);
}
private static void sendErr(OutputStream out) throws IOException {
out.write(SERIAL_MESSAGE_OK + 1);
}
public boolean write(OutputStream out, InputStream in) throws IOException {
DataOutputStream dOut = new DataOutputStream(out);
byte[] dataNullTerm = nullTerminate(data);
for (int i = 0; i < SERIAL_MAX_RETRY; i++) {
dOut.writeInt(PACKET_KEY);
dOut.writeInt(dataNullTerm.length);
dOut.write(dataNullTerm);
if (checkAck(in))
return true;
}
return false;
}
private static int checksum(byte[] data) {
int crc = 0xffff;
byte c;
int i = 0;
int len = data.length;
while (len-- != 0) {
c = data[i++];
crc = ((crc >> 4) & 0x0fff) ^ CRC16_TABLE[((crc ^ c) & 15)];
c >>= 4;
crc = ((crc >> 4) & 0x0fff) ^ CRC16_TABLE[((crc ^ c) & 15)];
}
return ~crc & 0xffff;
}
public static byte[] nullTerminate(byte[] data) {
byte[] dataNullTerm = new byte[data.length + 1];
System.arraycopy(data, 0, dataNullTerm, 0, data.length);
dataNullTerm[data.length] = 0;
return dataNullTerm;
}
public static Packet readPacket(InputStream in, OutputStream out)
throws IOException {
DataInputStream dIn = new DataInputStream(in);
while (true) {
int key = dIn.readInt();
if (key != PACKET_KEY) {
continue;
}
int len = dIn.readInt();
byte[] data = new byte[len];
dIn.readFully(data);
sendAck(out);
return new Packet(data);
}
}
public byte[] getBytes() {
return data;
}
public String toString() {
return "Packet[len=" + getBytes().length + "]";
}
}