package com.socket;
|
|
import android.os.Handler;
|
import android.os.Looper;
|
import android.os.Message;
|
import android.util.Log;
|
|
import com.concentrator.Concentrator_Cmd;
|
import com.concentrator.Concentrator_ComBase;
|
import com.concentrator.Concentrator_ComBuf;
|
import com.concentrator.Concentrator_Param;
|
import com.concentrator.Concentrator_State;
|
import com.fgkj.action.ServiceModel;
|
import com.google.gson.Gson;
|
import com.serial.SerialPort;
|
import com.util.ComFn;
|
|
import java.io.File;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.io.OutputStream;
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
|
/**
|
* 底层和汇集器通讯线程
|
*/
|
public class CommSockClientThread extends Thread{
|
public static final String TAG = "CommSockClientThread";
|
private static final String portName = "/dev/ttyS4"; //串口名称
|
private static final int portrate = 9600; //波特率
|
private ByteBuffer bytebuffer_for_socket_RX = ByteBuffer.allocate(1500);
|
private Concentrator_State concentratorState; //汇集器状态
|
private Concentrator_Param concentratorParam; //汇集器参数
|
|
|
private int rx_errcount_for_live_of_thread = 0;
|
private static CommSockClientThread clientThread;
|
private SerialPort socket;
|
public Handler mHandler = null;
|
private boolean thread_run_flag = true;
|
private Gson gson = new Gson();
|
private ServiceModel remodel = new ServiceModel();
|
|
private CommSockClientThread(){
|
this.concentratorState = new Concentrator_State();
|
this.concentratorParam = new Concentrator_Param();
|
}
|
|
|
/**
|
* 构造当前类的单例对象
|
* @return
|
*/
|
public static CommSockClientThread createClientThread(){
|
if(clientThread == null){
|
clientThread = new CommSockClientThread();
|
clientThread.start();
|
}
|
return clientThread;
|
}
|
|
|
@Override
|
public void run() {
|
this.setName(TAG);
|
|
//初始化消息循环队列,需要在Handler创建之前
|
Looper.prepare();
|
|
initConnectDevice();
|
|
mHandler = new Handler()
|
{
|
@Override
|
public void handleMessage(Message msg)
|
{
|
ServiceModel model = (ServiceModel) (msg.obj);
|
// int what = msg.what;
|
// List<BattDataThread> battData = FBS9600S_DeviceService.allBattDatt;
|
// if(model.battindex>0 && model.battindex<FBS9600S_DeviceService.MAXCONCENTRATORCOUNT){
|
// if(!battData.get(model.battindex-1).isInstall){
|
// return;
|
// }
|
// }
|
try
|
{
|
if(null != model.mhandler)
|
{
|
//开始构造发送数据包
|
model.msg = null;
|
byte[] basedata = makeComData(model);
|
if(basedata.length > 0 && true == SocketComm(basedata,model))
|
{
|
if(Concentrator_ComBase.CMD_MODEBUS_DEVICESTATE_INDEX == remodel.cmd)
|
{
|
remodel.data = concentratorState;
|
}
|
else if(Concentrator_ComBase.CMD_MODEBUS_SYSTEMPARAM_INDEX == remodel.cmd &&
|
Concentrator_ComBase.CMD_MODEBUS_READCMD == remodel.cmd_type )
|
{
|
//
|
remodel.data = concentratorParam;
|
}
|
else if(remodel.cmd >= Concentrator_ComBase.CMD_MODEBUS_BATTMONVOL_INDEX && remodel.cmd <= 0x239E)
|
{
|
remodel.data = concentratorState;
|
}
|
//-----------------------------------------------
|
}
|
//Log.e(TAG, "battindex:"+remodel.battindex+"====handleMessage: cmd"+remodel.cmd+"\tcmd_type:"+remodel.cmd_type+"\t"+model.mhandler );
|
Handler handler = remodel.mhandler;
|
Message toMain = handler.obtainMessage();
|
toMain.obj = remodel;
|
handler.sendMessage(toMain);
|
sleep(5);
|
}
|
}
|
catch (InterruptedException e)
|
{
|
e.printStackTrace();
|
}
|
}
|
};
|
|
Log.i(TAG, "mhandler is bound to - " + mHandler.getLooper().getThread().getName());
|
//启动子线程消息循环队列
|
Looper.loop();
|
Log.i(TAG, "Stop thread's message queue, thread is exited");
|
}
|
|
/**
|
* 向指定的socket通道发送数据,以及接收数据
|
* @return
|
* @throws InterruptedException
|
*/
|
|
public boolean SocketComm(final byte[] datasource,ServiceModel model) throws InterruptedException
|
{
|
//Log.e(TAG, "SocketComm: "+model );
|
remodel = model.clone();
|
boolean res_t = false;
|
try
|
{
|
if(this.socket != null)
|
{
|
InputStream in = this.socket.getInputStream();
|
OutputStream out = this.socket.getOutputStream();
|
//----------------- clear rx buff for tcp resend packet ----------------//
|
byte[] rx_buf_t = new byte[1024];
|
|
//----------------------------------------------------------------------//
|
bytebuffer_for_socket_RX.order(ByteOrder.BIG_ENDIAN);
|
bytebuffer_for_socket_RX.clear();
|
//--------------------- socket write -----------------------------------//
|
//--------------------- socket write -----------------------------------//
|
boolean aes_en = true;
|
byte[] plain_tx_t = datasource;
|
byte[] cipher_tx_t = new byte[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();
|
}
|
//-----------------------------------------------------------------//
|
}
|
//=====================================================================//
|
*/
|
//Log.e(TAG, "发送数据:"+ComFn.bytesToHexString(plain_tx_t,plain_tx_t.length));
|
int rx_read_time_out = 0;
|
//int rx_len = 0;
|
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>20)){
|
// res = true;
|
break;
|
}
|
if(rx_read_time_out > 30) {
|
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()];
|
bytebuffer_for_socket_RX.get(cipher_buf);
|
|
|
//Log.e(TAG, "接收数据: "+ ComFn.bytesToHexString(cipher_buf, cipher_buf.length));
|
if(true == getDataFromCommBuf(cipher_buf,remodel)) {
|
rx_errcount_for_live_of_thread = 0;
|
res_t = true;
|
remodel.code = 1;
|
/*
|
System.err.println(ComFn.bytesToHexString(buffer, buffer.length));
|
System.err.println(this.getName() + " DevId: " + m_StatAndParam.dev_id
|
+ "---- cmd:" + cmd + " RxLen: " + buffer.length
|
+ " 通信失败" + Com.getNowTimeWithAt());
|
*/
|
} else {
|
remodel.code = 0;
|
rx_errcount_for_live_of_thread++;
|
res_t = false;
|
}
|
} else {
|
//System.out.println(this.getName() + "-------socket 异常关闭-------" + Com.getNowTimeWithAt());
|
remodel.code = 0;
|
thread_run_flag = false;
|
}
|
} catch (IOException e) {
|
remodel.code = 0;
|
remodel.msg = e.getMessage();
|
thread_run_flag = false;
|
} finally {
|
//若在通信的过程中出现4次通信异常关闭连接
|
if(rx_errcount_for_live_of_thread >= 5 || !thread_run_flag){
|
if(socket != null){
|
try {
|
socket.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
initConnectDevice();
|
rx_errcount_for_live_of_thread = 0;
|
thread_run_flag = true;
|
}
|
}
|
return res_t;
|
}
|
|
public boolean getDataFromCommBuf(byte[] recebyte,final ServiceModel model){
|
boolean isSuccess = false;
|
ByteBuffer bf = ByteBuffer.allocate(recebyte.length);
|
bf.order(ByteOrder.BIG_ENDIAN);
|
bf.put(recebyte);
|
bf.flip();
|
Concentrator_Cmd Ccmd = new Concentrator_Cmd();
|
if(true == Ccmd.putByteBuffer(bf)){
|
if(Concentrator_ComBase.CMD_MODEBUS_READCMD == Ccmd.CMD){
|
//读取数据
|
if(Ccmd.ByteCount == Concentrator_State.BYTE_LEN){
|
//读取系统状态
|
if(concentratorState.putByteBuffer(bf)){
|
//Log.e(TAG, "获取设备状态成功 " );
|
isSuccess = true; //读取系统状态成功
|
}
|
}
|
|
if(Ccmd.ByteCount == Concentrator_Param.REG_COUNT*2){
|
//读取系统参数
|
if(concentratorParam.putByteBuffer(bf)){
|
//Log.e(TAG, "获取设备参数成功 " );
|
isSuccess = true;
|
}
|
}
|
|
if(Ccmd.ByteCount == Concentrator_State.MON_REG_COUNT*2){
|
//读取单体电压/内阻/温度
|
if(concentratorState.putMonDataBuffer(bf,model.cmd)) {
|
isSuccess = true;
|
}
|
}
|
}else if(Concentrator_ComBase.CMD_MODEBUS_SINGLEWRITECMD == Ccmd.CMD ||
|
Concentrator_ComBase.CMD_MODEBUS_WRITECMD == Ccmd.CMD ){
|
if(Ccmd.CMD == model.cmd_type){
|
//写入数据成功
|
isSuccess = true;
|
}
|
}
|
|
}
|
return isSuccess;
|
}
|
|
/**
|
* 尝试连接BTS设备
|
*/
|
public void initConnectDevice(){
|
boolean flag = false;
|
try {
|
// SerialPortFinder finder = new SerialPortFinder();
|
// String[] devicesPath = finder.getAllDevicesPath();
|
// for (int i =0;i<devicesPath.length;i++){
|
// Log.d(TAG, "initConnectDevice: "+devicesPath[i]);
|
// }
|
this.socket = new SerialPort(new File(portName),portrate,0);
|
flag = true;
|
} catch (Exception e) {
|
flag = false;
|
e.printStackTrace();
|
}finally {
|
Log.d(TAG, "initConnectDevice: ERROR\t"+this.socket );
|
if(!flag){
|
if(this.socket != null){
|
this.socket.close();
|
this.socket = null;
|
}
|
}else{
|
Log.e(TAG, "initConnectDevice: 打开串口成功" );
|
}
|
}
|
}
|
|
|
public byte[] makeComData(ServiceModel model){
|
byte[] b = null;
|
if(Concentrator_ComBase.CMD_MODEBUS_READCMD == model.cmd_type ||
|
Concentrator_ComBase.CMD_MODEBUS_WRITECMD == model.cmd_type ||
|
Concentrator_ComBase.CMD_MODEBUS_SINGLEWRITECMD == model.cmd_type
|
){
|
Concentrator_Cmd Ccmd = new Concentrator_Cmd();
|
Ccmd.makeCmd(model.battindex,model.cmd_type,model.cmd);
|
ByteBuffer buffer = ByteBuffer.allocate(0);
|
if(Concentrator_ComBase.CMD_MODEBUS_SYSTEMPARAM_INDEX == model.cmd){
|
//读写汇集器参数
|
if(Concentrator_ComBase.CMD_MODEBUS_READCMD == model.cmd_type){
|
//读取汇集器参数
|
buffer = concentratorParam.getReadByteBuffer();
|
}else{
|
//写汇集器参数
|
Concentrator_Param param = gson.fromJson(model.msg,Concentrator_Param.class);
|
buffer = param.getWriteByteBuffer();
|
}
|
}
|
if(Concentrator_ComBase.CMD_MODEBUS_DEVICESTATE_INDEX == model.cmd){
|
//读取系统状态
|
buffer = Ccmd.getReadByteBuffer(Concentrator_State.SYS_REG_COUNT);
|
}
|
if(Concentrator_ComBase.CMD_MODEBUS_BATTMONVOL_INDEX <= model.cmd &&model.cmd < 0x0239E ){
|
//读取单体数据(电压/温度/内阻)
|
buffer = Ccmd.getReadByteBuffer(Concentrator_State.MON_REG_COUNT);
|
}
|
|
if(Concentrator_ComBase.CMD_STARTRESTEST_INDEX == model.cmd ||
|
Concentrator_ComBase.CMD_STOPRESTTEST_INDEX == model.cmd ||
|
Concentrator_ComBase.CMD_RESTART_INDEX == model.cmd
|
){
|
//控制时传值(内阻测试[启动停止]/重启系统)
|
buffer = Ccmd.getReadByteBuffer(Concentrator_ComBase.CMD_CONTROL_VALUE);
|
}
|
|
b = makeCommBuf(Ccmd,buffer);
|
//Log.e(TAG, "****makeComData: "+ComFn.bytesToHexString(b,b.length) );
|
}else{
|
//Log.e(TAG, "makeComData: &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
|
b = new byte[0];
|
}
|
return b;
|
}
|
|
/*
|
* 构造发送数据
|
*/
|
public byte[] makeCommBuf(Concentrator_Cmd m_CMD, ByteBuffer bf)
|
{
|
ByteBuffer bbf = Concentrator_ComBuf.makeTmpSensorCommBuf(m_CMD, bf);
|
byte byte_rest[] = new byte[bbf.limit()];
|
bbf.get(byte_rest);
|
return byte_rest;
|
}
|
}
|