package com.dev.fbs9009;
|
|
import java.io.FileInputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.io.OutputStream;
|
import java.net.ServerSocket;
|
import java.net.Socket;
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
|
import com.base.Com;
|
import com.base.ComBase;
|
import com.base.Crc16;
|
import com.sql.MysqlConnPool;
|
|
public class MyModBusUpdateThread {
|
public final int UPDATE_ERROR_PARAM = 1; //²ÎÊý´íÎó
|
public final int UPDATE_ERROR_CRC = 2; //CRC´íÎó
|
public final int UPDATE_ERROR_MANAGE = 3; //²Ù×÷ʧ°Ü
|
public final int UPDATE_ERROR_WORKING = 4; //ÕýÔÚ¹¤×÷
|
public final int UPDATE_ERROR_JUNHENG = 5; //ÕýÔÚ¾ùºâ²âÊÔ
|
public final int UPDATE_ERROR_FLENGTH = 6; //Îļþ³¤¶È´íÎó
|
|
public final int UPDATE_ERROR_FNOTEEXISTS = 7; //Éý¼¶Îļþ²»´æÔÚ
|
public final int UPDATE_ERROR_FILEERROR = 8; //Éý¼¶Îļþ²»·ûºÏÒªÇó
|
public final int UPDATE_ERROR_DISTANCESTOP = 9; //Ô¶³ÌÍ£Ö¹
|
|
|
|
|
private final int BYTE_LEN = 512;
|
private final int REG_CONTROL_COUNT = 1;
|
|
private int EVERY_BYTE_COUNT = 128; //ÿ¸öÊý¾Ý°üµÄ´óС 64¸ö¼Ä´æÆ÷ ¼° 128¸ö×Ö½Ú
|
private final int TOTAL_RESEND_COUNT = 5; //×î´óÖØ·¢´ÎÊý
|
|
|
public MysqlConnPool mysql_pool = null;
|
public LD_updateState upState = null;
|
|
private ByteBuffer LD9RxBuffer = ByteBuffer.allocate(1500);
|
private Socket socket;
|
public List<byte[]> filearr;
|
|
|
|
public MyModBusUpdateThread(MysqlConnPool mysql_pool,LD_updateState upState,Socket socket){
|
this.upState = upState;
|
this.mysql_pool = mysql_pool;
|
this.socket = socket;
|
}
|
|
/**
|
* ¼à²âÉ豸ÄÜ·ñÉý¼¶
|
* @return
|
*/
|
public boolean checkDevIsCanUpdate(){
|
boolean flag = false;
|
if(!this.upState.getUpFile().exists()){
|
flag = false;
|
this.upState.setStopreason(UPDATE_ERROR_FNOTEEXISTS);
|
System.err.println("update file is not exist !!!!");
|
}else{
|
initFileData(); //¶ÁÈ¡Éý¼¶ÎļþÊý¾Ý Éý¼¶ÎļþµÄ×ܳ¤¶ÈÊÇ512¸ö×Ö½ÚµÄÕûÊý±¶
|
if((this.upState.getFileCount()%512 == 0) && (this.upState.getFileCount() > 512) && (this.upState.getFileCount() < (400*1024+512))){
|
flag = true;
|
}else{
|
this.upState.setStopreason(UPDATE_ERROR_FILEERROR);
|
System.err.println("Éý¼¶Îļþ³¤¶ÈÒì³£");
|
flag = false;
|
}
|
}
|
return flag;
|
}
|
|
|
|
/**
|
* ·¢ËÍÉý¼¶µÄÎļþÊý¾Ý°ü
|
* @return
|
*/
|
public void sendUpdateFile(byte[] datapackage,int cmd,Socket socket){
|
ByteBuffer bf = getWriteByteBuffer(datapackage); //»ñÈ¡·¢ËÍÊý¾ÝµÄbuffer
|
ByteBuffer bf_t = makeLD9Data(255, cmd,MyModBusCom.LD9_CMD_UPDATEFILE_ADDR, bf);
|
byte[] plain_tx_t = new byte[bf_t.limit()];
|
bf_t.get(plain_tx_t);
|
OutputStream out = null;
|
InputStream in = null;
|
try {
|
in = socket.getInputStream();
|
out = socket.getOutputStream();
|
|
byte[] rx_buf_t = new byte[1024];
|
int buf_clr_read_count = 0;
|
while(in.available() > 0) {
|
int len = in.read(rx_buf_t);
|
if(++buf_clr_read_count >= 10) {
|
System.err.println("error_count:"+len);
|
}
|
try {
|
Thread.sleep(50);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
//System.out.println("plain_tx_t.length:"+plain_tx_t.length);
|
//System.out.println("·¢ËÍÊý¾Ý:"+ComFn.bytesToHexString(plain_tx_t,plain_tx_t.length));
|
out.write(plain_tx_t);
|
out.flush();
|
//****************************************************//
|
this.LD9RxBuffer.order(ByteOrder.BIG_ENDIAN);
|
this.LD9RxBuffer.clear();
|
this.LD9RxBuffer.position(0);
|
byte[] rx_buf = new byte[1024];
|
int rx_read_time_out = 0;
|
while(true) {
|
//System.out.println("»º³åÇøµÄÊý¾Ý³¤¶È:"+in.available());
|
if(in.available()>0){
|
rx_read_time_out = 0;
|
int rx_len_t = in.read(rx_buf);
|
if((this.LD9RxBuffer.position()+rx_len_t)
|
< (this.LD9RxBuffer.capacity()-1)) {
|
this.LD9RxBuffer.put(rx_buf, 0, rx_len_t);
|
//System.err.println("¶ÁÈ¡×Ö½Ú³¤¶È:"+rx_len_t);
|
}
|
}
|
if(LD9RxBuffer.position() >= 8) {
|
//System.err.println("½ÓÊÕµ½Êý¾Ý"+ComFn.bytesToHexString(this.LD9RxBuffer.array(),this.LD9RxBuffer.limit()));
|
break;
|
}else{
|
rx_read_time_out += 1;
|
if(rx_read_time_out>100){
|
break;
|
}
|
}
|
Thread.sleep(100);
|
}
|
this.LD9RxBuffer.flip();
|
} catch (IOException | InterruptedException e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* ·¢ËÍ¿ØÖÆÃüÁî
|
* @return
|
*/
|
public boolean sendControlFile(int codevalue,int reg_addr,int reg_count,Socket socket){
|
boolean flag = false;
|
ByteBuffer bytebuffer = ByteBuffer.allocate(4+reg_count*2);
|
bytebuffer.order(ByteOrder.BIG_ENDIAN);
|
bytebuffer.putShort(ComBase.changeIntToShort(reg_count));
|
bytebuffer.put(ComBase.changeIntToByte(reg_count*2));
|
if(reg_count == 1){
|
bytebuffer.putShort(ComBase.changeIntToShort(codevalue));
|
}else if(reg_count == 2){
|
bytebuffer.putInt(codevalue);
|
}
|
|
bytebuffer.flip();
|
ByteBuffer bf_t = makeLD9Data(255, MyModBusCom.CMD_MULTI_WRITE_MODBUS,reg_addr, bytebuffer);
|
byte[] plain_tx_t = new byte[bf_t.limit()];
|
bf_t.get(plain_tx_t);
|
OutputStream out = null;
|
InputStream in = null;
|
try {
|
in = socket.getInputStream();
|
out = socket.getOutputStream();
|
out.write(plain_tx_t);
|
|
//System.err.println("·¢ËÍÊý¾Ý:"+ComFn.bytesToHexString(plain_tx_t,plain_tx_t.length));
|
out.flush();
|
//****************************************************//
|
LD9RxBuffer.order(ByteOrder.BIG_ENDIAN);
|
LD9RxBuffer.clear();
|
int rx_read_time_out = 0;
|
byte[] rx_buf = new byte[1024];
|
while(true) {
|
if(in.available()>0){
|
rx_read_time_out = 0;
|
int rx_len_t = in.read(rx_buf);
|
if((LD9RxBuffer.position()+rx_len_t)
|
< (LD9RxBuffer.capacity()-1)) {
|
LD9RxBuffer.put(rx_buf, 0, rx_len_t);
|
}
|
}
|
if(LD9RxBuffer.position() >= 8) {
|
//System.out.println("½ÓÊÕÊý¾Ý:WWW"+ComFn.bytesToHexString(LD9RxBuffer.array(),LD9RxBuffer.array().length));
|
break;
|
}else{
|
rx_read_time_out += 1;
|
if(rx_read_time_out>500){
|
break;
|
}
|
}
|
Thread.sleep(100);
|
}
|
LD9RxBuffer.flip();
|
|
|
} catch (IOException | InterruptedException e) {
|
e.printStackTrace();
|
}
|
return flag;
|
}
|
|
/**
|
* Ô¶³ÌÉý¼¶É豸
|
* @return
|
*/
|
public boolean UpdateLd9Device(){
|
boolean dev_update_ok = false;
|
sendControlFile(MyModBusCom.LD_CMD_STARTSTOP_VALUE,MyModBusCom.LD9_CMD_UPDATE_SYS_ADDR,1,socket);
|
|
this.LD9RxBuffer.position(0);
|
//System.out.println("this.LD9RxBuffer limit:"+this.LD9RxBuffer.limit());
|
//System.out.println(checkDfuWriteAckBuf(this.LD9RxBuffer,this.filearr.get(nowdataindex).length/2));
|
if(LD9RxBuffer.limit()>=8 && this.checkDfuWriteAckBuf(this.LD9RxBuffer,REG_CONTROL_COUNT)) {
|
dev_update_ok= true;
|
System.out.println("Éý¼¶É豸Íê³É");
|
} else {
|
System.out.println("Éý¼¶É豸ʧ°Ü");
|
}
|
|
return dev_update_ok;
|
}
|
|
/**
|
* ½âÎöÉý¼¶ÎļþµÄÊý¾Ý
|
* @return
|
*/
|
public boolean initFileData(){
|
filearr = new ArrayList<byte[]>();
|
boolean flag = false;
|
FileInputStream fis = null;
|
//System.out.println(upfile.length());
|
//this.fileCount = upfile.length();
|
try {
|
fis = new FileInputStream(this.upState.getUpFile());
|
byte[] arr = new byte[EVERY_BYTE_COUNT];
|
int len = 0;
|
this.upState.setFileCount(0);;
|
while((len = fis.read(arr)) != -1){
|
byte[] b = new byte[EVERY_BYTE_COUNT];
|
for(int i=0;i<b.length;i++){
|
b[i] = (byte)0xff;
|
}
|
System.arraycopy(arr, 0, b, 0, len);
|
//System.out.println(b.length+"\t"+ComFn.bytesToHexString(b, b.length));
|
filearr.add(b);
|
this.upState.setFileCount(this.upState.getFileCount()+EVERY_BYTE_COUNT); //ͳ¼ÆÊý¾Ý°üÖеÄ×ܵÄ×Ö½Ú¸öÊý
|
|
}
|
//System.out.println(this.fileCount);
|
for(int i=0;i<filearr.size();i++){
|
for(int j =0;j<filearr.get(i).length/2;j++){
|
byte a = filearr.get(i)[j*2];
|
filearr.get(i)[j*2] = filearr.get(i)[j*2+1];
|
filearr.get(i)[j*2+1] = a;
|
}
|
}
|
this.upState.setCountpackage(this.filearr.size());
|
flag = true;
|
} catch (IOException e) {
|
e.printStackTrace();
|
} finally{
|
try {
|
if(fis != null){
|
fis.close();
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
return flag;
|
}
|
|
|
/**
|
* Æô¶¯LD9É豸µÄ¸üгÌÐò
|
* @return
|
*/
|
public boolean runLD9Update(){
|
System.out.println(this.upState.getDev_id()+"¿ªÊ¼Ô¶³ÌÉý¼¶:..........................");
|
|
boolean send_file_ok = false; //·¢ËÍÎļþ³É¹¦
|
boolean clear_tmpfile_ok = false; //Çå³ý»º´æÎļþ³É¹¦
|
|
initFileData(); //³õʼ»¯·¢ËÍÊý¾Ý
|
this.upState.setNowpackagenum(0); //µ±Ç°µÄ·¢°üË÷Òý
|
upState.setStarttime(new Date());
|
boolean connect_error = false; //ÊÇ·ñͨѶ´íÎó
|
int reSendCount = 0; //ÖØ·¢´ÎÊý
|
if(this.filearr.size()<1){
|
return false;
|
}
|
|
try {
|
while(!this.upState.isSend_upfile_ok()){
|
|
MyModBusUpdateThread_SQL.queryLD9_Update_StateByDev_id(mysql_pool, upState);
|
if(!this.upState.isUpdate_en()){
|
this.upState.setStopreason(UPDATE_ERROR_DISTANCESTOP); //Ô¶³ÌÍ£Ö¹
|
break;
|
}
|
|
if(!clear_tmpfile_ok && upState.getNowpackagenum() == 0){
|
upState.setStarttime(new Date());
|
//ÖØÐ¿ªÊ¼·¢ËÍÎļþʱ,·¢ËÍÇå¿Õ»º´æÃüÁî
|
sendControlFile(MyModBusCom.LD_CMD_STARTSTOP_VALUE,MyModBusCom.LD9_CMD_DELETE_TEMPFILE_ADDR,1,socket);
|
|
this.LD9RxBuffer.position(0);
|
//System.out.println("this.LD9RxBuffer limit:"+this.LD9RxBuffer.limit());
|
//System.out.println(checkDfuWriteAckBuf(this.LD9RxBuffer,this.filearr.get(nowdataindex).length/2));
|
if(LD9RxBuffer.limit()>=8 && this.checkDfuWriteAckBuf(this.LD9RxBuffer,REG_CONTROL_COUNT)) {
|
System.out.println("Çå¿Õ»º´æÎļþ³É¹¦");
|
clear_tmpfile_ok = true;
|
connect_error = false;
|
} else {
|
System.out.println("Çå¿Õ»º´æÎļþʧ°Ü");
|
connect_error = true;
|
}
|
}
|
|
if(clear_tmpfile_ok && upState.getNowpackagenum() < this.filearr.size()){
|
sendUpdateFile(this.filearr.get(upState.getNowpackagenum()),MyModBusCom.CMD_MULTI_WRITE_MODBUS,this.socket);
|
|
this.LD9RxBuffer.position(0);
|
//System.out.println("this.LD9RxBuffer limit:"+this.LD9RxBuffer.limit());
|
//System.out.println(checkDfuWriteAckBuf(this.LD9RxBuffer,this.filearr.get(nowdataindex).length/2));
|
if(LD9RxBuffer.limit()>=8 && true==this.checkDfuWriteAckBuf(this.LD9RxBuffer,this.filearr.get(upState.getNowpackagenum()).length/2)) {
|
System.out.println("·¢ËÍÊý¾Ý°ü"+upState.getNowpackagenum()+"³É¹¦");
|
this.upState.setNowpackagenum();
|
connect_error = false;
|
if(upState.getNowpackagenum() == this.filearr.size()){
|
send_file_ok = true; //·¢ËÍÎļþÊý¾Ý°üÍê³É
|
}
|
} else {
|
System.out.println("·¢ËÍÊý¾Ý°ü"+upState.getNowpackagenum()+"ʧ°Ü");
|
connect_error = true;
|
|
}
|
}
|
|
if(send_file_ok && !upState.isSend_upfile_ok()){
|
//·¢ËÍÎļþÊý¾Ý°üµÄÊý¾Ý³¤¶È
|
sendControlFile((int)this.upState.getFileCount(),MyModBusCom.LD9_CMD_UPDATECOUNT_ADDR,2,socket);
|
this.LD9RxBuffer.position(0);
|
//System.out.println("this.LD9RxBuffer limit:"+this.LD9RxBuffer.limit());
|
if(LD9RxBuffer.limit() >= 8 && this.checkDfuWriteAckBuf(this.LD9RxBuffer,2)) {
|
System.out.println(this.upState.getDev_id()+"Ô¶³ÌÉý¼¶Íê³É;±¾´ÎÉý¼¶ºÄʱ(Ãë):"+((upState.getUpdatetime().getTime()-upState.getStarttime().getTime())/1000));
|
|
upState.setSend_upfile_ok(true);
|
connect_error = false;
|
} else {
|
System.out.println(this.upState.getDev_id()+"Ô¶³ÌÉý¼¶Ê§°Ü");
|
connect_error = true;
|
|
}
|
}
|
Thread.sleep(50);
|
if(connect_error){
|
Thread.sleep(5000);
|
|
this.upState.setNowpackagenum(0);
|
clear_tmpfile_ok = false; //ÉèÖôÓÏÂ´ÎÆð¿ªÊ¼ÖØÐ·¢ËÍ
|
|
reSendCount++;
|
System.out.println("ÖØÐ·¢ËÍÎļþ´ÎÊý"+reSendCount);
|
if(reSendCount >3){
|
break; //ÖØ·¢³¬¹ý3´Î¾Í½áÊø±¾´Î·¢ËÍÊý¾Ý
|
}
|
}
|
|
MyModBusUpdateThread_SQL.updateLD9_Update_ProgressByDev_id(mysql_pool, this.upState);
|
}
|
} catch (InterruptedException e) {
|
e.printStackTrace();
|
} finally{
|
if(this.upState.isSend_upfile_ok()){
|
System.out.println(upState.getDev_id()+"·¢ËÍÉý¼¶Îļþ³É¹¦"+Com.getDateTimeFormat(new Date(), Com.DTF_YMDhms));
|
}else{
|
System.out.println(upState.getDev_id()+"·¢ËÍÉý¼¶Îļþʧ°Ü"+Com.getDateTimeFormat(new Date(), Com.DTF_YMDhms));
|
}
|
}
|
return this.upState.isSend_upfile_ok();
|
}
|
|
|
|
|
|
/**
|
* УÑé·¢ËÍ·µ»ØµÄÊý¾Ý
|
* @param lD9RxBuffer2 //¶ÁÈ¡µ½µÄ»º³åÁ÷Êý¾Ý (¸ù¾Ý·µ»ØµÄ¼Ä´æÆ÷¸öÊýÅжϲÙ×÷ÊÇ·ñ³É¹¦)
|
* @param regcount //¼Ä´æÆ÷¸öÊý
|
* @return
|
*/
|
private boolean checkDfuWriteAckBuf(ByteBuffer lD9RxBuffer, int regcount) {
|
//System.out.println("lD9RxBuffer.limit()"+lD9RxBuffer.limit());
|
boolean flag = false;
|
lD9RxBuffer.order(ByteOrder.BIG_ENDIAN);
|
lD9RxBuffer.position(0);
|
int dev_real_addr = ComBase.changeByteToInt(lD9RxBuffer.get()); //É豸µÄʵ¼ÊµØÖ·
|
int cmd = ComBase.changeByteToInt(lD9RxBuffer.get()); //ÃüÁî¶ÔÓ¦µÄ¶ÁдÃüÁî
|
//System.err.println(lD9RxBuffer.position());
|
int RES_Index = ComBase.changeShortToInt(lD9RxBuffer.getShort()); //»ñÈ¡¼Ä´æÆ÷µÄÆðʼλÖÃ
|
int code = ComBase.changeShortToInt(lD9RxBuffer.getShort());
|
int crc0 = lD9RxBuffer.getShort(lD9RxBuffer.limit() - 2);
|
int crc1 = Crc16.CalCRC16(lD9RxBuffer, lD9RxBuffer.limit()-2);
|
//System.out.println("crc0:"+crc0+"\t crc1:"+crc1);
|
if(crc0 != crc1){
|
this.upState.setStopreason(UPDATE_ERROR_CRC);
|
return false;
|
}
|
if(code == regcount){
|
//²Ù×÷½á¹ûµÈÓڼĴæÆ÷¸öÊýÊDzÙ×÷³É¹¦
|
flag = true;
|
}else if(code != regcount){
|
this.upState.setStopreason(getErrorCode(code)); //»ñÈ¡±¾´ÎͨÐÅʧ°ÜµÄÔÒò
|
System.err.println("¼ì²â¼Ä´æÆ÷¸öÊý²»¶ÔÓ¦");
|
}
|
return flag;
|
}
|
|
/**
|
* ½«·¢Ë͵ÄÎļþÊý¾Ý´ò°ü
|
* @param dat
|
* @return
|
*/
|
public ByteBuffer getWriteByteBuffer(byte[] dat)
|
{
|
ByteBuffer bytebuffer = ByteBuffer.allocate(BYTE_LEN);
|
bytebuffer.order(ByteOrder.BIG_ENDIAN);
|
bytebuffer.putShort(ComBase.changeIntToShort((int)Math.ceil((double)dat.length/2)));
|
bytebuffer.put(ComBase.changeIntToByte(dat.length));
|
//System.err.println(dat.length);
|
bytebuffer.put(dat);
|
//CRC = Crc16.CalCRC16(bytebuffer,bytebuffer.position());
|
//bytebuffer.putShort(ComBase.changeIntToShort(CRC));
|
|
bytebuffer.flip();
|
return bytebuffer;
|
}
|
|
/**
|
* ¹¹ÔìLD8·¢ËÍÊý¾ÝµÄ°ü
|
* @param dev_addr
|
* @param cmd
|
* @param bbf_tx
|
* @return
|
*/
|
public ByteBuffer makeLD9Data(int dev_addr,int cmd,int reg_addr,ByteBuffer bbf_tx){
|
ByteBuffer buffer = ByteBuffer.allocate(bbf_tx.limit() + 9);
|
buffer.order(ByteOrder.BIG_ENDIAN); //ÉèÖÃByteBufferµÄ×Ö½ÚÐò
|
|
buffer.put(ComBase.changeIntToByte(dev_addr)); //É豸µØÖ·
|
buffer.put(ComBase.changeIntToByte(cmd)); //ÃüÁî 03 or 05
|
buffer.putShort(ComBase.changeIntToShort(reg_addr)); //¼Ä´æÆ÷µÄÆðʼµØÖ·
|
buffer.put(bbf_tx);
|
//CRC = Crc16.CalCRC16(buffer, buffer.position());
|
int CRC = Crc16.CalCRC16(buffer, buffer.position()) & 0xFFFF;
|
buffer.putShort(ComBase.changeIntToShort(CRC));
|
buffer.flip();
|
return buffer;
|
}
|
|
|
public static void main(String[] args) {
|
//MyModBusUpdateThread thread1 = new MyModBusUpdateThread(null, 401900004, null);
|
//thread1.initFileData();
|
|
MysqlConnPool mysql_pool = new MysqlConnPool("127.0.0.1",3360,10);
|
LD_updateState upState = new LD_updateState(401900004);
|
|
ServerSocket server = null;
|
try {
|
server = new ServerSocket(9009);
|
while(true){
|
Socket socket = server.accept();
|
MyModBusUpdateThread thread = new MyModBusUpdateThread(mysql_pool, upState, socket);
|
System.out.println("Á¬½Ó³É¹¦");
|
boolean flag = thread.runLD9Update();
|
if(flag){
|
thread.UpdateLd9Device();
|
return;
|
}
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
} finally{
|
if(server != null){
|
try {
|
server.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}
|
|
/**
|
* ¸ù¾ÝÉ豸·µ»ØµÄ״̬Âë·µ»Ø¶ÔÓ¦Êý¾Ý¿âÖжÔÓ¦µÄʧ°ÜÔÒò
|
* @param code
|
* @return
|
*/
|
public int getErrorCode(int code){
|
switch(code){
|
case 0xF1:return UPDATE_ERROR_PARAM;
|
case 0xF2:return UPDATE_ERROR_CRC;
|
case 0xF3:return UPDATE_ERROR_MANAGE;
|
case 0xF4:return UPDATE_ERROR_WORKING;
|
case 0xF5:return UPDATE_ERROR_JUNHENG;
|
case 0xF6:return UPDATE_ERROR_FLENGTH;
|
}
|
return code;
|
}
|
}
|