package com.socket;
|
|
import android.os.Handler;
|
import android.os.Looper;
|
import android.os.Message;
|
import android.util.Log;
|
|
import com.google.gson.Gson;
|
import com.mode.BattRTData;
|
import com.mode.BattTestParam;
|
import com.mode.BattTestRtData;
|
import com.mode.DeviceState;
|
import com.mode.ServiceModel;
|
import com.util.Com;
|
import com.util.ComFn;
|
import com.util.Ecb_Aes;
|
import com.util.FBS_Cmd;
|
import com.util.FBS_ComBase;
|
import com.util.FBS_ComBuf;
|
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.io.OutputStream;
|
import java.io.UnsupportedEncodingException;
|
import java.net.InetSocketAddress;
|
import java.net.Socket;
|
import java.net.SocketAddress;
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
import java.util.Date;
|
|
public class MySocketClientThread extends Thread{
|
public static final String TAG = "MySocketClientThread";
|
|
private String server_ip; //服务器ip地址
|
private int server_port = 6666; //设备屏监听端口
|
|
private BattRTData battData; //电池实时数据
|
private BattTestParam testParam; //电池测试参数
|
private BattTestRtData testRtData; //电池测试数据
|
|
private FBS_Cmd m_FBS_Cmd = new FBS_Cmd();
|
|
|
private ByteBuffer bytebuffer_for_socket_RX = ByteBuffer.allocate(1500);
|
public Handler mHandler = null;
|
public static Socket socket = null;
|
private Date lastConTime; //上一次通讯成功的时间
|
private boolean thread_run_flag = true;
|
public boolean isRuning = false;
|
|
ServiceModel returnmodel = new ServiceModel();
|
|
private static MySocketClientThread thread ;
|
|
private MySocketClientThread(String server_ip){
|
this.server_ip = server_ip;
|
battData = new BattRTData();
|
testParam = new BattTestParam();
|
testRtData = new BattTestRtData();
|
|
}
|
|
public static MySocketClientThread createThread(String server_ip){
|
if(thread == null){
|
thread = new MySocketClientThread(server_ip);
|
}
|
return thread;
|
}
|
|
/*********************************************************************************************/
|
public void run()
|
{
|
|
//初始化消息循环队列,需要在Handler创建之前
|
Looper.prepare();
|
isRuning = true;
|
mHandler = new Handler()
|
{
|
public void handleMessage(Message msg)
|
{
|
ServiceModel model = (ServiceModel)msg.obj;
|
|
try
|
{
|
if(null != model.handler)
|
{
|
ServiceModel remodel = new ServiceModel();
|
remodel.cmd = model.cmd;
|
if(true == SocketComm(createByteBuffer(model), remodel))
|
{
|
remodel.code = 1;
|
remodel.cmd = m_FBS_Cmd.CMD;
|
//--------------- 新建消息与句柄 -----------------
|
Handler handler = model.handler;
|
Message toMain = handler.obtainMessage();
|
toMain.obj = remodel;
|
handler.sendMessage(toMain);
|
//-----------------------------------------------
|
sleep(100);
|
}else{
|
remodel.code = 0;
|
//--------------- 新建消息与句柄 -----------------
|
Handler handler = model.handler;
|
Message toMain = handler.obtainMessage();
|
toMain.obj = remodel;
|
handler.sendMessage(toMain);
|
}
|
}
|
}
|
catch (InterruptedException e)
|
{
|
e.printStackTrace();
|
}
|
}
|
};
|
Log.e(TAG, "Loop start at "+ Com.getDateTimeFormat(new Date(),Com.DTF_YMDhms) );
|
//启动子线程消息循环队列
|
Looper.loop();
|
isRuning = false;
|
Log.e(TAG, "Loop stop at "+ Com.getDateTimeFormat(new Date(),Com.DTF_YMDhms) );
|
if(socket != null){
|
try {
|
socket.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
/**
|
* 向指定的socket通道发送数据,以及接收数据
|
* @return
|
*/
|
|
public boolean SocketComm(ByteBuffer byteBuffer,ServiceModel model)
|
{
|
boolean res_t = false;
|
InputStream in = null;
|
OutputStream out = null;
|
try
|
{
|
// socket = new Socket();
|
// SocketAddress socAddress = new InetSocketAddress(server_ip, server_port);
|
// socket.connect(socAddress, 2000);
|
if(socket == null || socket.isClosed()){
|
Log.e(TAG, "SocketComm:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " );
|
reConnectDevice();
|
}
|
if(this.socket != null)
|
{
|
in = this.socket.getInputStream();
|
out = this.socket.getOutputStream();
|
//----------------- clear rx buff for tcp resend packet ----------------//
|
byte[] rx_buf_t = new byte[1024];
|
|
//----------------------------------------------------------------------//
|
bytebuffer_for_socket_RX.order(ByteOrder.LITTLE_ENDIAN);
|
bytebuffer_for_socket_RX.clear();
|
//--------------------- socket write -----------------------------------//
|
//--------------------- socket write -----------------------------------//
|
boolean aes_en = false;
|
byte[] plain_tx_t = makeCommBuf(model.cmd, byteBuffer, aes_en);
|
byte[] cipher_tx_t = new byte[plain_tx_t.length];
|
Ecb_Aes my_aes = new Ecb_Aes();
|
my_aes.ecb_encrypt(plain_tx_t, cipher_tx_t, plain_tx_t.length);
|
Date d1 = new Date();
|
//=====================================================================//
|
/*
|
for(int n=0; n<3; n++) {
|
out.write(b);
|
out.flush();
|
//-----------------------------------------------------------------//
|
try {
|
while(true) {
|
int rx_len_t = in.read(rx_buf_t);
|
if(rx_len_t > 0) {
|
if((bytebuffer_for_socket_RX.position()+rx_len_t)
|
< (bytebuffer_for_socket_RX.capacity()-16)) {
|
|
bytebuffer_for_socket_RX.put(rx_buf_t, 0, rx_len_t);
|
}
|
}
|
if(bytebuffer_for_socket_RX.position() > 8) {
|
break;
|
}
|
}
|
} catch (SocketTimeoutException soe) {
|
//soe.printStackTrace();
|
}
|
//-----------------------------------------------------------------//
|
}
|
//=====================================================================//
|
*/
|
int rx_read_time_out = 0;
|
//int rx_len = 0;
|
System.out.println("数据长度" + plain_tx_t.length + "\t发送数据:" + ComFn.bytesToHexString(plain_tx_t, plain_tx_t.length));
|
out.write(plain_tx_t);
|
out.flush();
|
while(true) {
|
if(in.available() > 0) {
|
rx_read_time_out = 0;
|
int rx_len_t = in.read(rx_buf_t);
|
if((bytebuffer_for_socket_RX.position()+rx_len_t)
|
< (bytebuffer_for_socket_RX.capacity()-1)) {
|
bytebuffer_for_socket_RX.put(rx_buf_t, 0, rx_len_t);
|
}
|
//bytebuffer_for_socket_RX.put((byte)in.read());
|
} else {
|
rx_read_time_out++;
|
if((bytebuffer_for_socket_RX.position() >= 8) && (rx_read_time_out>10)){
|
// res = true;
|
break;
|
}
|
if(rx_read_time_out > 220) {
|
break;
|
}
|
}
|
Thread.sleep(10);
|
}
|
|
bytebuffer_for_socket_RX.flip();
|
|
Date d2 = new Date();
|
long comm_tms = (d2.getTime() - d1.getTime());
|
if(comm_tms < 200) {
|
Thread.sleep(200 - comm_tms);
|
}
|
/*
|
System.out.println(this.getName()
|
+ " dev_id: " + m_StatAndParam.dev_id
|
+ " d2-d1:" + (comm_tms)+"ms"
|
+ " rx_len:" + bytebuffer_for_socket_RX.limit()
|
+ " tx_count:" + m_FBS_VCData.m_SysState.CommCount
|
+ " rx_err_sum:" + m_FBS_VCData.m_SysState.ErrCommCount
|
+ " rx_err_count:" + rx_errcount_for_live_of_thread
|
+ Com.getNowTimeWithAt());
|
*/
|
byte[] cipher_buf = new byte[bytebuffer_for_socket_RX.limit()];
|
byte[] plain_buf = new byte[bytebuffer_for_socket_RX.limit()];
|
bytebuffer_for_socket_RX.get(cipher_buf);
|
my_aes.ecb_decrypt(cipher_buf, plain_buf, cipher_buf.length);
|
|
System.err.println("数据长度"+cipher_buf.length+"\t返回数据:"+ ComFn.bytesToHexString(cipher_buf, cipher_buf.length));
|
//Log.e(TAG, "SocketComm: "+ComFn.bytesToHexString(plain_buf, plain_buf.length));
|
if(true == getDataFromCommBuf(model,cipher_buf)) {
|
res_t = true;
|
model.code = 1;
|
} else {
|
res_t = false;
|
model.code = 0;
|
}
|
thread_run_flag = true;
|
} else {
|
//System.out.println(this.getName() + "-------socket 异常关闭-------" + Com.getNowTimeWithAt());
|
thread_run_flag = false;
|
}
|
} catch (IOException | InterruptedException e) {
|
thread_run_flag = false;
|
} finally {
|
if(!thread_run_flag){
|
reConnectDevice();
|
}
|
}
|
return res_t;
|
}
|
|
/**
|
* 根据指定的命令构造byteBuffer
|
* @return
|
*/
|
public ByteBuffer createByteBuffer(ServiceModel model){
|
ByteBuffer buffer = ByteBuffer.allocate(0);
|
if(FBS_ComBase.CMD_CREATENEWBATT == model.cmd
|
|| FBS_ComBase.CMD_CHANGEBATT == model.cmd
|
|| FBS_ComBase.CMD_DELETENOWBATT == model.cmd
|
){
|
//新建电池组/切换电池组/删除电池组
|
testParam.battName = model.msg;
|
buffer = testParam.getNewBattByteBuffer();
|
}else if(FBS_ComBase.CMD_SETDISCHARGEPARAM == model.cmd){
|
Gson gson = new Gson();
|
BattTestParam param = gson.fromJson(model.msg,BattTestParam.class);
|
buffer = param.getByteBuffer();
|
}else if(FBS_ComBase.CMD_RETURNMAIN == model.cmd){
|
buffer = ByteBuffer.allocate(1);
|
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
buffer.position(0);
|
buffer.put(FBS_ComBase.changeIntToByte(Integer.parseInt(model.msg)));
|
buffer.flip();
|
}
|
return buffer;
|
}
|
|
/*********************************************************************************************/
|
public byte[] makeCommBuf(final int cmd, ByteBuffer bf, boolean aes_en)
|
{
|
ByteBuffer bbf = FBS_ComBuf.makeFbs9100CommBuf(0xFF, cmd, bf, aes_en);
|
byte byte_rest[] = new byte[bbf.limit()];
|
bbf.get(byte_rest);
|
return byte_rest;
|
}
|
/*********************************************************************************************/
|
|
/**
|
* 重新连接设备
|
*/
|
public boolean reConnectDevice(){
|
boolean flag = false;
|
if(socket != null){
|
try {
|
socket.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
try {
|
socket = new Socket();
|
SocketAddress socAddress = new InetSocketAddress(server_ip, this.server_port);
|
socket.connect(socAddress, 2000);
|
|
ServiceModel temp = new ServiceModel();
|
temp.cmd = FBS_ComBase.CMD_ENTERMACHINECONTROL;
|
SocketComm(ByteBuffer.allocate(0),temp); //进入上位机控制
|
flag = true;
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
return flag;
|
}
|
|
/*********************************************************************************************/
|
public Boolean getDataFromCommBuf(ServiceModel model ,final byte[] bytes)
|
{
|
returnmodel = new ServiceModel();
|
boolean isSuccess = false;
|
ByteBuffer bf = ByteBuffer.allocate(bytes.length);
|
bf.order(ByteOrder.LITTLE_ENDIAN);
|
bf.put(bytes);
|
bf.flip();
|
|
String msg = "";
|
if(true == m_FBS_Cmd.putByteBuffer(bf))
|
{
|
|
model.errcode = m_FBS_Cmd.RecState;
|
lastConTime = new Date();
|
|
//--------------------- 心跳包测试 ----------------------------------
|
if(FBS_ComBase.CMD_HEARTBEAT == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
byte[] b = new byte[bf.limit()];
|
bf.get(b);
|
try {
|
DeviceState deviceState = new DeviceState(m_FBS_Cmd.WorkState,new String(b,"utf-8"));
|
|
model.setData(deviceState);
|
System.out.println("当前电池组是:"+new String(b,"utf-8"));
|
} catch (UnsupportedEncodingException e) {
|
e.printStackTrace();
|
}
|
isSuccess = true;
|
//System.out.println("获取心跳包成功");
|
}
|
}
|
//--------------------- 新建电池组 ----------------------------------
|
else if(FBS_ComBase.CMD_CREATENEWBATT == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
//System.out.println("新建电池组成功");
|
}
|
}
|
|
//--------------------- 切换电池组 ----------------------------------
|
else if(FBS_ComBase.CMD_CHANGEBATT == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
Log.e(TAG, "getDataFromCommBuf: 切换电池组成功");
|
|
}
|
}
|
|
|
//--------------------- 删除电池组 ----------------------------------
|
else if(FBS_ComBase.CMD_DELETENOWBATT == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
//System.out.println("删除电池组成功");
|
}
|
}
|
//--------------------- 获取单体数据 ----------------------------------------------
|
else if(FBS_ComBase.CMD_GETBATTDATA == m_FBS_Cmd.CMD) {
|
System.err.println("获取单体数据");
|
if(battData.putByteBuffer(bf, m_FBS_Cmd.ByteLen-m_FBS_Cmd.BYTE_LEN)) {
|
//System.out.println("获取单体数据成功");
|
isSuccess = true;
|
model.setData(battData);
|
}
|
}
|
//--------------------- 获取放电参数 ----------------------------------------------
|
else if(FBS_ComBase.CMD_GETDISCHARGEPARAM == m_FBS_Cmd.CMD) {
|
Log.e(TAG, "getDataFromCommBuf: 获取放电参数" );
|
if(testParam.putByteBuffer(bf)) {
|
System.out.println("获取放电参数成功");
|
//System.out.println(testParam);
|
isSuccess = true;
|
model.setData(testParam);
|
}
|
}
|
//---------------------- 设置放电参数 --------------------------------------------------
|
else if(FBS_ComBase.CMD_SETDISCHARGEPARAM == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
//System.out.println("设置参数成功");
|
}
|
}
|
//--------------------- 启动放电 ----------------------------------
|
else if(FBS_ComBase.CMD_STARTDISCHARGE == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
//System.out.println("启动放电成功");
|
}
|
}
|
//--------------------- 放电暂停 ----------------------------------
|
else if(FBS_ComBase.CMD_PAUSEDISCHARGE == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
//System.out.println("暂停放电成功");
|
}
|
}
|
//--------------------- 停止放电 ----------------------------------
|
else if(FBS_ComBase.CMD_STOPDISCHARGE == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
//System.out.println("停止放电成功");
|
}
|
}
|
//--------------------- 获取放电数据 ----------------------------------
|
else if(FBS_ComBase.CMD_GETDISCHARGEDATA == m_FBS_Cmd.CMD) {
|
if(testRtData.putByteBuffer(bf)) {
|
isSuccess = true;
|
model.setData(testRtData);
|
//System.out.println("获取放电数据成功"+testRtData);
|
}
|
|
}
|
|
//--------------------- 启动充电 ----------------------------------
|
else if(FBS_ComBase.CMD_STARTCHARGE== m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
//System.out.println("启动充电成功");
|
}
|
}
|
//--------------------- 暂停充电 ----------------------------------
|
else if(FBS_ComBase.CMD_PAUSECHARGE== m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
// System.out.println("暂停充电成功");
|
}
|
}
|
//--------------------- 停止充电 ----------------------------------
|
else if(FBS_ComBase.CMD_STOPCHARGE== m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
//System.out.println("停止充电成功");
|
}
|
}
|
|
//--------------------- 获取充电数据 ----------------------------------
|
else if(FBS_ComBase.CMD_GETCHARGEDATA == m_FBS_Cmd.CMD) {
|
if(testRtData.putByteBuffer(bf)) {
|
isSuccess = true;
|
model.setData(testRtData);
|
//System.out.println("获取充电数据成功"+testRtData);
|
}
|
|
}
|
//--------------------- 清除告警 ----------------------------------
|
else if(FBS_ComBase.CMD_CLEARALARM == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
System.out.println("清除告警成功");
|
}
|
}
|
//--------------------- 进入 Android控制 ----------------------------------
|
else if(FBS_ComBase.CMD_ENTERMACHINECONTROL == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
System.out.println("进入Android模式成功");
|
}
|
}
|
|
|
//--------------------- 进入界面同步切换 ----------------------------------
|
else if(FBS_ComBase.CMD_RETURNMAIN == m_FBS_Cmd.CMD) {
|
if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) {
|
isSuccess = true;
|
System.out.println("切换界面成功");
|
}
|
}
|
}
|
return isSuccess;
|
}
|
|
public boolean setUpDeviceIp(String server_ip){
|
boolean flag = false;
|
if(this.socket == null){
|
flag = reConnectDevice();
|
}else{
|
synchronized (socket){
|
if (this.server_ip != null && server_ip.length() > 0){
|
flag = reConnectDevice();
|
}
|
}
|
}
|
return false;
|
}
|
|
//测试当前ip是否可以连接
|
public boolean testSockConn(String server_ip){
|
boolean flag = false;
|
Socket socket1 = null;
|
try {
|
socket1 = new Socket();
|
Log.e(TAG, "testSockConn: "+server_ip );
|
SocketAddress socAddress = new InetSocketAddress(server_ip, this.server_port);
|
socket1.connect(socAddress, 3000);
|
flag = true;
|
} catch (IOException e) {
|
e.printStackTrace();
|
} finally{
|
if(socket1 != null){
|
try {
|
socket1.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return flag;
|
}
|
|
}
|