package com.sunvote.xpadcomm; import android.annotation.SuppressLint; import android.os.Handler; import android.os.HandlerThread; import android.util.Log; import com.sunvote.udptransfer.UDPModule; import com.sunvote.udptransfer.stream.SunVoteInputStream; import com.sunvote.util.LogUtil; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; public class XPadApi implements XPadApiInterface { private static String TAG = "XPadApi"; private ComListener m_listener; private static XPadApi m_xpadApi = null; private OutputStream mOutputStream; private SunVoteInputStream mInputStream; private ReadThread mReadThread; private ArrayList sendQueen = new ArrayList(); private int serialNumber; private int allOkSerialNumber; private boolean isShowLog = true; private boolean isShowOnlineLog = false; private OnLineInfo onLineInfo; // private boolean hasGetBaseInfo = false; private UDPModule client ; private int writeFrimPageErrCnt = 0; private HandlerThread sendThread = new HandlerThread("send"); private Handler taskHandler = null; // public SerialPortFinder mSerialPortFinder = new SerialPortFinder(); public synchronized static XPadApi getInstance() { if (m_xpadApi == null) { m_xpadApi = new XPadApi(); m_xpadApi.init(); } return m_xpadApi; } public XPadApi() { sendThread.start(); taskHandler = new Handler(sendThread.getLooper()); } public void init() { try { allOkSerialNumber = -1; // mSerialPort = getSerialPort(); // mOutputStream = mSerialPort.getOutputStream(); // mInputStream = mSerialPort.getInputStream(); client = new UDPModule(); mOutputStream = client.getOutputStream(); mInputStream = client.getInputStream(); mInputStream.setOnBytesReceiver(new SunVoteInputStream.OnBytesReceiver() { @Override public void onBytesReceiver(byte[] datas, int length) { // int rxDataLen = datas[3] + 4;// len // checkComData(datas,length); LogUtil.i(TAG,"xpadapi rec:" ,datas); // dowith(datas,length); checkComData(datas,length); } }); Arrays.fill(broadcastData, (byte) 0x0);// 清空多包结果 /* Create a receiving thread */ // mReadThread = new ReadThread(); // mReadThread.start(); // InitThread initThread = new InitThread(); } catch (SecurityException e) { LogUtil.e(TAG,e); } catch (Exception e) { LogUtil.e(TAG,e); } } public UDPModule getClient() { return client; } public void closeCom() { if (mReadThread != null) mReadThread.interrupt(); if(client != null){ client.release(); } } public static void printDataBuf(byte[] buf, int len, String flag) { String tmpStr = new String(); for (int i = 0; i < len; i++) { tmpStr += String.format("%x ", buf[i]); } LogUtil.d(TAG, flag + ":" + tmpStr); } public static String getDataBufString(byte[] buf, int len, String flag) { String tmpStr = new String(); for (int i = 0; i < len; i++) { tmpStr += String.format("%x ", buf[i]); } return flag + ":" + tmpStr; } public static byte[] intToByteArray1(int i) { byte[] result = new byte[4]; result[0] = (byte) ((i >> 24) & 0xFF); result[1] = (byte) ((i >> 16) & 0xFF); result[2] = (byte) ((i >> 8) & 0xFF); result[3] = (byte) (i & 0xFF); return result; } @Override public void setComListener(ComListener cl) { m_listener = cl; } public VoteResultItem getVoteResultItem(){ return new VoteResultItem(); } private Runnable sendTask = new Runnable() { @Override public void run() { // 从队列中取出待发送数据 VoteResultItem voteResultItem = null; boolean send = false; synchronized (sendQueen) { if(sendQueen.size() > 0) { Iterator it = sendQueen.iterator(); while (it.hasNext()) { voteResultItem = it.next(); if ((!voteResultItem.sendOk && !send) || voteResultItem.ansType == AnsType_Select) { // 取出数据发送 if(send){ try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } voteResultItem.status = 1 ; writeToCom(voteResultItem.data); voteResultItem.sendTimes++; send = true; } } } } // 轮询下一次发送数据 taskHandler.removeCallbacks(this); taskHandler.postDelayed(this,1000); } }; public class VoteResultItem { public int serialNo; public int status;// 0:未发送 1:已发送 public int ansType; // public int ansCount;// 批次提交的选项数 public int allOK; //1 确认提交 public byte[] data; public boolean sendOk; public int sendTimes = 0; /** * 用于回调标志结果显示 */ public String retBack = "" ; } /* * function:addToSendQueen params: 发送内容 功能:添加到发送队列 */ private void addToSendQueen(VoteResultItem item) { boolean isComb = false;// 合并 synchronized (sendQueen) { if (item.ansType == AnsType_BatchSingle && item.allOK != 1) { for (int i = 0; i < sendQueen.size(); i++) { VoteResultItem it = (VoteResultItem) sendQueen.get(i); if (it.status != 1 && it.ansType == AnsType_BatchSingle && it.ansCount < 6) { it.data[9 + it.ansCount * 3] = item.data[9]; it.data[10 + it.ansCount * 3] = item.data[10]; it.data[11 + it.ansCount * 3] = item.data[11]; it.ansCount++; isComb = true; LogUtil.d(TAG, "addToSendQueen isComb=true 合并:" + it.ansCount); break; } } } } if (isComb == false) { sendQueen.add(item); } LogUtil.d(TAG, "addToSendQueen serialNo=" + item.serialNo + " size=" + sendQueen.size()); // 轮询下一次发送数据 taskHandler.removeCallbacks(sendTask); taskHandler.post(sendTask); } private void sendToModalSuccessResponse(int serialNo){ LogUtil.i(TAG,"send vote sendToModalSuccessResponse:" + serialNo); synchronized (sendQueen) { for (int i = 0; i < sendQueen.size(); i++) { VoteResultItem it = (VoteResultItem) sendQueen.get(i); if (serialNo == it.serialNo) { it.sendOk = true; break; } } } } /* * function:addToSendQueen params:流水号 功能:根据流水号删除队列已发送成功的项 */ private VoteResultItem removeSentItem(int serialNo) { LogUtil.d(TAG, "send success : " + serialNo); VoteResultItem ret = null; synchronized (sendQueen) { Iterator it = sendQueen.iterator(); while (it.hasNext()) { VoteResultItem voteResultItem = it.next(); if (voteResultItem.status == 1 && voteResultItem.serialNo == serialNo) { voteResultItem.sendOk = true; boolean remove = sendQueen.remove(voteResultItem); LogUtil.d(TAG, "remove success ? " + remove); ret = voteResultItem; break; } } } return ret; } private void clearSentItems() { synchronized (sendQueen){ sendQueen.clear(); } } @Override public void getWorkMode() { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x70; mBuffer[5] = 0x01; writeToCom(mBuffer); } @Override public void setWorkMode(int iMode) { byte[] mBuffer = new byte[0x1F + 4]; // Arrays.fill(mBuffer, (byte) 0x55); Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x70; mBuffer[5] = 0x02; mBuffer[6] = (byte) iMode; writeToCom(mBuffer); } @Override public void getBaseStatus() { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x70; mBuffer[5] = 0x03; writeToCom(mBuffer); } @Override public void getVoteStatus() { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x70; mBuffer[5] = 0x04; writeToCom(mBuffer); } @Override public void getKeypadParam() { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x70; mBuffer[5] = 0x05; writeToCom(mBuffer); } @Override public void setKeypadParam(int keyId, byte[] KEYSN) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x70; mBuffer[5] = 0x06; mBuffer[6] = (byte) ((keyId >> 8) & 0xFF);// keyId mBuffer[7] = (byte) (keyId & 0xFF); // mBuffer[8] =(byte) 0xFF; System.arraycopy(KEYSN, 0, mBuffer, 8, 6); byte[] parecode = new byte[4]; Arrays.fill(parecode, (byte) 0xFF); System.arraycopy(KEYSN, 0, mBuffer, 14, 4); writeToCom(mBuffer); } @Override public void checkOnLine(int volt, int keyinStatus) { if(isInComCommunicationTest){ return; } byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x70; mBuffer[5] = 0x07; mBuffer[6] = (byte) volt; mBuffer[7] = (byte) keyinStatus; writeToCom(mBuffer); } @Override public void execKeypadMatch(int iMode, int channal) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x70; mBuffer[5] = 0x08; mBuffer[6] = (byte) iMode; mBuffer[7] = (byte) channal; writeToCom(mBuffer); } private boolean isInComCommunicationTest = false; @Override public void comCommunicationTest(int sendn,int okn) { isInComCommunicationTest = (sendn != 200); byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x30; mBuffer[5] = 0x0; mBuffer[6] = 0x0; mBuffer[7] = 7; mBuffer[8] = (byte) sendn; mBuffer[9] = (byte) okn; mBuffer[10] = (byte)0xAA; for(int i=1;i<17;i++){ mBuffer[10+i] = (byte)i; } writeToCom(mBuffer); } @Override public synchronized void submitVote(int ansType, String info) {// byte[] ansData if (ansType == AnsType_Single) {// 单值 byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) serialNumber;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) ansType; int val = Integer.parseInt(info); mBuffer[8] = (byte) val; VoteResultItem it = new VoteResultItem(); it.status = 0; it.ansType = ansType; it.ansCount = 1; it.serialNo = (byte)(serialNumber); serialNumberInc(); it.data = mBuffer; addToSendQueen(it); } else if (ansType == AnsType_Select) { String[] ary = info.split(","); String val = ary[0]; int tm = Integer.parseInt(ary[1]); byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) serialNumber;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) ansType; ; mBuffer[8] = (byte) ((tm >> 8) & 0xff); mBuffer[9] = (byte) (tm & 0xff); mBuffer[10] = (byte) ((tm >> 8) & 0xff); mBuffer[11] = (byte) (tm & 0xff); VoteResultItem it = new VoteResultItem(); it.retBack = info; it.status = 0; it.ansType = ansType; it.ansCount = 1; it.serialNo = (byte)serialNumber; serialNumberInc(); it.data = mBuffer; addToSendQueen(it); } else if (ansType == AnsType_Number) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) serialNumber;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) ansType; byte[] val = util_encodeBCD(info.getBytes()); System.arraycopy(val,0,mBuffer,8,8); VoteResultItem it = new VoteResultItem(); it.status = 0; it.ansType = ansType; it.ansCount = 1; it.serialNo = serialNumber; serialNumberInc(); it.data = mBuffer; addToSendQueen(it); } else if (ansType == AnsType_LoginIn) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) serialNumber;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) ansType; mBuffer[8] = 3;//3 签到信息按BCD码格式 byte[] val = util_encodeBCD(info.getBytes()); System.arraycopy(val,0,mBuffer,9,9); VoteResultItem it = new VoteResultItem(); it.status = 0; it.ansType = ansType; it.ansCount = 1; it.serialNo = serialNumber; serialNumberInc(); it.data = mBuffer; addToSendQueen(it); } else if (ansType == AnsType_BatchSingle) { // String[] ary= info.split(","); byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) serialNumber;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) ansType; mBuffer[8] = 0;// ALLOK int pos = 9; String[] item = info.split(":"); if (item.length > 1) { int num = Integer.parseInt(item[0]); int val = Integer.parseInt(item[1]); mBuffer[pos++] = (byte) (num >> 8); mBuffer[pos++] = (byte) (num & 0xff); mBuffer[pos++] = (byte) val; } VoteResultItem it = new VoteResultItem(); it.status = 0; it.ansType = ansType; it.serialNo = serialNumber; serialNumberInc(); it.ansCount = 1; it.data = mBuffer; addToSendQueen(it); } else if (ansType == AnsType_BatchNumber) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) serialNumber;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) ansType; mBuffer[8] = 0;// ALLOK String[] item = info.split(":"); if (item.length > 1) { String[] itIndex = item[0].split("_"); if(itIndex.length==2){ //综合测评 int personId = Integer.parseInt(itIndex[0]); int projectId =Integer.parseInt(itIndex[1]); mBuffer[9] = (byte)personId; mBuffer[10] = (byte)projectId; }else { int num = Integer.parseInt(item[0]); mBuffer[9] = (byte) (num >> 8); mBuffer[10] = (byte) (num & 0xff); } String strNum = item[1]; byte[] val = util_encodeBCD(strNum.getBytes()); System.arraycopy(val, 0, mBuffer, 11, 4); } VoteResultItem it = new VoteResultItem(); it.status = 0; it.ansType = ansType; it.serialNo = serialNumber; serialNumberInc(); it.ansCount = 1; it.data = mBuffer; addToSendQueen(it); } else if (ansType == AnsType_SelectOther) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) serialNumber;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) ansType; mBuffer[8] = 0;// ALLOK int pos = 9; String[] item = info.split(":"); if (item.length > 1) { int num = Integer.parseInt(item[0]); String val = item[1]; mBuffer[pos++] = (byte) (num >> 8); mBuffer[pos++] = (byte) num; mBuffer[pos++] = 0;// slot try { byte[] name = val.getBytes("GB2312"); System.arraycopy(name, 0, mBuffer, pos, name.length > 16 ? 16 : name.length); } catch (UnsupportedEncodingException e) { LogUtil.e(TAG,e); } // 名字最多16 } VoteResultItem it = new VoteResultItem(); it.retBack = info; it.status = 0; it.ansType = ansType; it.serialNo = (byte)serialNumber; serialNumberInc(); it.ansCount = 1; it.data = mBuffer; addToSendQueen(it); }else if(ansType == AnsType_Service){ byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) serialNumber;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) ansType; mBuffer[8] = 4; int serv_type = Integer.parseInt(info); mBuffer[9] = (byte) serv_type; VoteResultItem it = new VoteResultItem(); it.status = 0; it.ansType = ansType; it.serialNo = serialNumber; serialNumberInc(); it.ansCount = 1; it.data = mBuffer; addToSendQueen(it); } } private int ChoiceValueToInt(String val) { int ret = 0; for (int i = 0; i < val.length(); i++) { char cc = val.charAt(i); if (cc < 'I') { ret |= 1 << (8 + (cc - 'A')); } else { ret |= 1 << (cc - 'I'); } } return ret; } public void submitVoteFource(int ansType, String info) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) serialNumber;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) ansType; mBuffer[8] = 0;// ALLOK int pos = 9; String[] item = info.split(":"); if (item.length > 1) { int num = Integer.parseInt(item[0]); String val = item[1]; mBuffer[pos++] = (byte) (num >> 8); mBuffer[pos++] = (byte) num; mBuffer[pos++] = 0;// slot try { byte[] name = val.getBytes("GB2312"); System.arraycopy(name, 0, mBuffer, pos, name.length > 16 ? 16 : name.length); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block LogUtil.e(TAG,e); } // 名字最多16 } VoteResultItem it = new VoteResultItem(); it.status = 0; it.ansType = ansType; it.serialNo = (byte)serialNumber; serialNumberInc(); it.ansCount = 1; it.data = mBuffer; addToSendQueen(it); } @Override public void submitVoteAllOK() { int allokSerialNum = 0xff; byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) allokSerialNum;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) AnsType_BatchSingle; mBuffer[8] = 1;// ALLOK VoteResultItem it = new VoteResultItem(); it.status = 0; it.ansType = AnsType_BatchSingle; it.serialNo = ((byte)allokSerialNum & 0xff); allOkSerialNumber = (byte)allokSerialNum; it.ansCount = 1; it.allOK = 1; it.data = mBuffer; addToSendQueen(it); } @Override public void cancelSubmitVoteAllOK() { int cancelAllokSerialNum = 0xfe; byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = (byte) cancelAllokSerialNum;// 流水号 mBuffer[6] = 1;// MSGTYPE 1:ID mode, 2:SN mBuffer[7] = (byte) AnsType_BatchSingle; mBuffer[8] = 0;// ALLOK VoteResultItem it = new VoteResultItem(); it.status = 0; it.ansType = AnsType_BatchSingle; it.serialNo = cancelAllokSerialNum; // allOkSerialNumber = serialNumber; it.ansCount = 1; it.allOK = 0; it.data = mBuffer; addToSendQueen(it); //serialNumber=0; } private void serialNumberInc(){ serialNumber++; if(serialNumber == 0xfe){ serialNumber = 0; } } @Override public void submitSelectOther(String info) { // TODO Auto-generated method stub } @Override public void submitVoteBySn(byte[] keySn, String info) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x73; mBuffer[5] = 0x08;// 流水号 mBuffer[6] = 2;// MSGTYPE mBuffer[7] = 1;// ANSTYPE System.arraycopy(keySn, 0, mBuffer, 8, 6);// keysn // System.arraycopy(ansData, 0, mBuffer, 8, // ansData.length<=16?ansData.length:16); // info??? writeToCom(mBuffer); } @Override public void sendCmdData(int cmdId, byte[] data) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = (byte) 0xB0;// 0x30 表决器下载单包类指令 mBuffer[5] = 0x0;// keyid 填 0 mBuffer[6] = 0x0;// keyid mBuffer[7] = (byte) cmdId;// KCMD System.arraycopy(data, 0, mBuffer, 8, data.length);// keysn writeToCom(mBuffer); } @Override public void configMode() { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 0x1F; mBuffer[4] = 0x70; mBuffer[5] = 0x09; writeToCom(mBuffer); } private byte[] firmFileBuffer; private int firmWritePage; private int firmWritePageMax; @Override public void startFirmUpdate(byte[] fileBuffer) { firmFileBuffer = fileBuffer; firmWritePage = 0; firmWritePageMax = firmFileBuffer.length / 32; if (firmWritePageMax % 32 > 0) { firmWritePageMax++; } byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 10; mBuffer[4] = 0x78; mBuffer[5] = 0x01; writeToCom(mBuffer); } private void keepFirmMode() { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 10; mBuffer[4] = 0x78; mBuffer[5] = 0x02; writeToCom(mBuffer); } private void eraseFlash() { int file_len = firmFileBuffer.length; byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 10; mBuffer[4] = 0x78; mBuffer[5] = 0x03; mBuffer[6] = 0; mBuffer[7] = (byte) (file_len / 1024); writeToCom(mBuffer); } private void writeFlash(int page) { byte[] mBuffer = new byte[38 + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 38; mBuffer[4] = 0x78; mBuffer[5] = 0x04; mBuffer[6] = (byte) (page / 256); mBuffer[7] = (byte) (page % 256); int pos = 0; for (int i = 0; i < 32; i++) { pos = page * 32 + i; if (pos == firmFileBuffer.length - 1) { break; } mBuffer[8 + i] = firmFileBuffer[pos]; } LogUtil.d(TAG,"write flash page:"+page); writeToCom(mBuffer); } /* * status 1: success 2 : fail */ private void exitFirmUpdate(int status) { byte[] mBuffer = new byte[0x1F + 4]; Arrays.fill(mBuffer, (byte) 0x0); mBuffer[0] = (byte) 0xF5; mBuffer[1] = (byte) 0xAA; mBuffer[2] = (byte) 0xAA; mBuffer[3] = (byte) 10; mBuffer[4] = 0x78; mBuffer[5] = 5; mBuffer[6] = (byte) status; writeToCom(mBuffer); } public void writeToCom(byte[] data) { if (mOutputStream != null) { try { int crcValue = Crc16.getUnsignedShort(Crc16.crc16(data, data.length - 4 - 2)); data[data.length - 2] = (byte) (crcValue >> 8); data[data.length - 1] = (byte) (crcValue); if (isShowLog) { if (data[4] == 0x70 && data[5] == 0x07) { // Log.d(TAG, "check online"); if (isShowOnlineLog) { printDataBuf(data, data.length, "send:"); } } else { printDataBuf(data, data.length, "send:"); } } mOutputStream.write(data); } catch (IOException e) { LogUtil.e(TAG,e); } m_listener.onSendData(data, data.length); } } private byte[] SerDataRx = new byte[100]; int iSerRxN = 0; private byte[] comBuffer = new byte[1024]; private class ReadThread extends Thread { @Override public void run() { super.run(); while (!isInterrupted()) { try { Arrays.fill(comBuffer, (byte) 0x0);// 清空结果 // byte[] buffer = new byte[512];// buffer 64字节 if (mInputStream == null) { return; } int size = mInputStream.read(comBuffer); dowith(comBuffer,size); } catch (IOException e) { LogUtil.e(TAG,e); return; } } } } private void dowith(byte[] comBuffer, int size) { if (size > 0 && m_listener != null) { int recvLen = size; int rxDataLen = 0; for (int i = 0; i < recvLen; i++) { if (iSerRxN >= 512) { iSerRxN = 0; break; } int dd = Crc16.getUnsignedByte(comBuffer[i]); SerDataRx[iSerRxN] = comBuffer[i];// 先保存数据 switch (iSerRxN) { case 0: if (dd == 0xF5) { iSerRxN++; } break; case 1: if (dd == 0xAA) iSerRxN++; else { if (dd == 0xF5) iSerRxN = 1; else iSerRxN = 0; } break; case 2: if (dd == 0xAA) iSerRxN++; else { if (dd == 0xF5) iSerRxN = 1; else iSerRxN = 0; } break; case 3:// len if (dd > 128) // C_SERMAXN iSerRxN = 0; else { iSerRxN++; } break; default: iSerRxN++; rxDataLen = SerDataRx[3] + 4;// len if (rxDataLen <= 3) break; if (iSerRxN == rxDataLen) { if (Crc16.checkPack(SerDataRx)) { int crcValue = Crc16 .getUnsignedShort(Crc16.crc16(SerDataRx, rxDataLen - 4 - 2)); int originCrcValue = 0; originCrcValue |= (SerDataRx[rxDataLen - 2] & 0xff) << 8; originCrcValue |= SerDataRx[rxDataLen - 1] & 0xff; if (crcValue != originCrcValue) { System.out.println("recv package crc error!\n"); } else { checkComData(SerDataRx, rxDataLen); } for (int j = 0; j < SerDataRx.length; j++) { SerDataRx[j] = 0; } iSerRxN = 0; } } break; }// switch } // for } } @SuppressLint("NewApi") private void checkComData(byte[] data, int size) { LogUtil.i(TAG,"checkComData",data); m_listener.onComData(data, size); int cmd = data[4] & 0xFF; switch (cmd) { case CMD_CHECK_BASE_STATUS_RESPONSE:// 查询状态类指令应答 int cmd1 = data[5] & 0xFF; if (cmd1 == 1) {// 返回当前工作模式和版本 ModelInfo info = new ModelInfo(); info.mode = data[6]; info.hModel = data[7] & 0xff; info.sVer = data[8] + "." + data[9] + "." + data[10]; m_listener.onModelEvent(info); } else if (cmd1 == 3) { // 查询基础信标 结果 onBaseInfo(data); } else if (cmd1 == 4) { // 查询投票信标 结果 onVoteInfo(data); } else if (cmd1 == 5 || cmd1 == 6) {// 返回当前键盘参数结果 KeypadInfo info = new KeypadInfo(); info.ok = data[6]; info.chan = data[7]; info.keyId = ((data[8] & 0xff) << 8) | (data[9] & 0xff); byte[] sn = Arrays.copyOfRange(data, 10, 16); info.keySn = getKeySn(sn); byte[] mc = Arrays.copyOfRange(data, 16, 19); info.matchCode = new String(mc); m_listener.onKeyPadEvent(info); // if(!hasGetBaseInfo){ //第一次启动时取 // hasGetBaseInfo = true; // getBaseStatus(); // } } else if (cmd1 == 7) {// 查询键盘在线状态结果 OnLineInfo info = new OnLineInfo(); info.onLine = data[6]; info.idMode = data[7]; info.chan = data[8] & 0xff; info.rssi = data[9] & 0xff; info.tx = data[10]; info.rx = data[11]; info.baseId = data[12] & 0xff; info.keyId = ((data[13] & 0xff) << 8) | (data[14] & 0xff); byte[] sn = Arrays.copyOfRange(data, 15, 21); info.keySn = getKeySn(sn); onLineInfo = info; m_listener.onOnLineEvent(info); } else if (cmd1 == 8 || cmd1 == 9) { KeypadInfo info = new KeypadInfo(); info.cmd1 = cmd1; info.ok = data[6]; info.chan = data[7]; info.keyId = ((data[8] & 0xff) << 8) | (data[9] & 0xff); byte[] sn = Arrays.copyOfRange(data, 10, 16); info.keySn = getKeySn(sn); byte[] mc = Arrays.copyOfRange(data, 16, 19); info.matchCode = new String(mc); m_listener.onKeyPadEvent(info); } break; case CMD_BASE_STATUS_CHANGE:// 基础信标变化(主动下发) responseBaseStatusChange(data, size); onBaseInfo(data); break; case CMD_VOTE_STATUS_CHANGE:// 投票信标变化 responseVoteStatusChange(data, size); clearSentItems(); onVoteInfo(data); break; case CMD_VOTE_RESULT_SEND_RESPONSE: // sendToModalSuccessResponse( data[5] & 0xff); break; case CMD_VOTE_SEND_SUCCESS_RESPONSE: sendToModalSuccessResponse( data[5] & 0xff); responseVoteSendSuccess(data, size); break; case CMD_KEY_MANAGE:// 表决器管理类指令,单包,透传 CmdDataInfo info = new CmdDataInfo(); info.cmd = data[7]; info.data = Arrays.copyOfRange(data, 8, 28); if(info.cmd == 25 ){ int keyId = (data[5] << 8) | data[6]; if(keyId != 0) { responseClearKeyboardData(data,size); } }else if(info.cmd == 20){ int keyId = (data[5] << 8) | data[6]; if(keyId == onLineInfo.keyId){ responseAuthrizeKeyboardData(data,size); }else{ break; } } m_listener.onCmdData(info); break; case CMD_MULTI_PCKAGE_DOWNLOAD: onMultiPackageInfo(data, size); break; case CMD_COM_COMMUNICATION_TEST_RESPONSE: int sendn = data[8] & 0xff; boolean isOk = true; for(int i=1;i<17;i++){ if(data[10+i] != i){ isOk = false; } } m_listener.onComCommunicationTest(sendn,isOk); break; case CMD_FIRM_UPDATE_RESPONSE: switch (data[5]) { case 2:// '模块询问是否进入DFU keepFirmMode(); eraseFlash(); break; case 3:// 擦除应答 if (data[8] != 1) { LogUtil.e(TAG, "eraseFlash fail"); m_listener.onFirmUpdateResult(false, "擦除固件失败!"); break; } LogUtil.e(TAG, "eraseFlash ok"); m_listener.onFirmUpdateInfo("擦除固件完成,开始写入..."); CheckFirmReceveThread checkFirmThread = new CheckFirmReceveThread(); checkFirmThread.start(); writeFrimPageErrCnt = 0; writeFlash(firmWritePage); break; case 4:// 写应答 if (data[8] == 1) { firmWritePage++; writeFrimPageErrCnt = 0; if (firmWritePage < firmWritePageMax ) { m_listener.onFirmUpdate(firmWritePage * 100 / firmWritePageMax); LogUtil.d(TAG, "write page ok! " + firmWritePage + "/" + firmWritePageMax + " ==" + firmWritePage * 100 / firmWritePageMax + "%"); writeFlash(firmWritePage); } else { m_listener.onFirmUpdateInfo("写入完成"); m_listener.onFirmUpdate(100); LogUtil.i(TAG, "write 100%"); sleep(2000); exitFirmUpdate(1); LogUtil.i(TAG, "exitFirmUpdate"); m_listener.onFirmUpdateResult(true, null); } } else { LogUtil.d(TAG,"应答写失败 write page error"); } break; case 5: // 退出升级 LogUtil.d(TAG, "exit update!"); m_listener.onFirmUpdateInfo("退出升级模式成功!"); sleep(3000); LogUtil.d(TAG, "sleep 3s getWorkMode!"); for(int i=0;i<5;i++) { getWorkMode(); sleep(1000); } getBaseStatus(); break; default: break; } default: break; } } private void sleep(int ms){ try { Thread.sleep(ms); } catch (Exception e) { } } //// 回应模块基础信标变化,模块停止重发,否则模块会不断发送 private void responseBaseStatusChange(byte[] data, int size) { byte[] retData = Arrays.copyOf(data, size); retData[4] = (byte) 0xF1; writeToCom(retData); } // 处理基础信标变化 private void onBaseInfo(byte[] data) { LogUtil.i(TAG,"onBaseInfo",data); BaseInfo info = new BaseInfo(); info.baseId = data[5] & 0xff;// baseID info.idMode = data[6] & 0xff; info.confId = ((data[7] & 0xff) << 8) | (data[8] & 0xff); info.billId = data[9] & 0xff; info.authCode = (data[10] & 0xff) << 8 | (data[11] & 0xff); info.login = data[12] & 0xff; info.report = data[13] & 0xff; info.offTime = data[14] & 0xff; info.attrib = data[15] & 0xff; info.pageNo = (data[16] & 0xff) << 8 | (data[17] & 0xff); byte[] bname = Arrays.copyOfRange(data, 16, 16 + 12); info.baseName = new String(bname); m_listener.onBaseEvent(info); } // 回应模块投票信标变化,模块停止重发,否则模块会不断发送 private void responseVoteStatusChange(byte[] data, int size) { byte[] retData = Arrays.copyOf(data, size); retData[4] = (byte) 0xF2; writeToCom(retData); } // 回应发送成功通知 private void responseVoteSendSuccess(byte[] data, int size) { // byte[] retData = Arrays.copyOf(data, size); // retData[4] = (byte) 0xF3; // writeToCom(retData); int serialNo = data[5] & 0xff; VoteResultItem item = removeSentItem(serialNo); if ((byte)serialNo == allOkSerialNumber) { m_listener.onVoteSubmitAllOkSuccess(); } else { if(item == null){ LogUtil.e(TAG,"serialNo " + " 丢失???"); } m_listener.onVoteSubmitSuccess(item); } } //回复清空键盘数据 private void responseClearKeyboardData(byte[] data,int len){ byte[] retData = Arrays.copyOf(data, len); retData[4] = (byte) 0xB0; retData[8] = 1; writeToCom(retData); } //回复键盘授权数据 private void responseAuthrizeKeyboardData(byte[] data,int len){ byte[] retData = Arrays.copyOf(data, len); retData[4] = (byte) 0xB0; retData[8] = 1; writeToCom(retData); } // 处理投票信标变化 private void onVoteInfo(byte[] data) { byte[] dt = Arrays.copyOfRange(data, 4, data.length);// 从len开始,和文档下标统一 VoteInfo info = new VoteInfo(); info.baseId = dt[1] & 0xff; info.nowT = dt[2] & 0xff << 8 | dt[3] & 0xff; info.dataPos = dt[4] & 0xff; info.mode = dt[5] & 0xff; info.mode1_msgType = dt[6] & 0xff; // if(info.mode != VoteType_Stop){ // serialNumber = 0; // } if (info.mode == VoteType_Stop) { // 停止 if (info.mode1_msgType == 2) { // 有结果 info.resultInfo.resultType = dt[7] & 0xff; info.resultInfo.bits = dt[8] & 0xff; info.resultInfo.num0 = (dt[9] & 0xff) << 8 | (dt[10] & 0xff); info.resultInfo.num1 = (dt[11] & 0xff) << 8 | (dt[12] & 0xff); info.resultInfo.num2 = (dt[13] & 0xff) << 8 | (dt[14] & 0xff); info.resultInfo.num3 = (dt[15] & 0xff) << 8 | (dt[16] & 0xff); info.resultInfo.num4 = (dt[17] & 0xff) << 8 | (dt[18] & 0xff); info.resultInfo.num5 = (dt[19] & 0xff) << 8 | (dt[20] & 0xff); if(dt.length > 22){ info.resultInfo.num6 = (dt[21] & 0xff) << 8 | (dt[22] & 0xff); } } } else if (info.mode == VoteType_BatchVote) { printDataBuf(data, data.length, "batchvote:"); if(dt.length > 23){ info.mode2_modify = dt[23] & 0xff; } info.mode3_secret = dt[12] & 0xff; info.less = dt[11] & 0xff; info.mode3_secret = dt[12] & 0xff; info.fixballot = dt[13] & 0xff ; if(info.fixballot > 0 ){ info.limitFavor = dt[14] & 0xff ; info.limitOppo = dt[15] & 0xff ; info.limitWaiver = dt[16] & 0xff ; }else{ info.limitFavor = 0 ; info.limitOppo = 0 ; info.limitWaiver = 0; } info.voteid = dt[21] & 0xff; } else if (info.mode == VoteType_Choice) { info.mode2_modify = dt[7] & 0xff; info.mode3_secret = dt[8] & 0xff; info.mode4 = dt[9] & 0xff; info.mode5 = dt[10] & 0xff; info.mode6 = dt[11] & 0xff; info.mode7 = dt[12] & 0xff; }else if(info.mode == VoteType_BatchElect) {//选举 info.electInfo.type = dt[6] & 0xff; info.electInfo.random = dt[7] & 0xff; info.electInfo.select = dt[8] & 0xff; info.electInfo.other = dt[9] & 0xff; info.electInfo.less = dt[10] & 0xff; info.electInfo.secrecy = dt[11] & 0xff; info.electInfo.modify = dt[12] & 0xff; info.electInfo.start = dt[13] & 0xff; info.electInfo.end = dt[14] & 0xff; info.electInfo.equityMode = dt[15] & 0xff; info.electInfo.minSelect = dt[16] & 0xff; info.electInfo.voteid = dt[21] & 0xff; }else if(info.mode == VoteType_SingleItemEvalue) {//单项评分 info.singleEvalueInfo.mode1 = dt[6] & 0xff; info.singleEvalueInfo.mode2 = dt[7] & 0xff; info.singleEvalueInfo.mode3 = dt[8] & 0xff; info.singleEvalueInfo.mode4 = dt[9] & 0xff; info.singleEvalueInfo.mode5 = dt[10] & 0xff; info.singleEvalueInfo.mode6 = dt[11] & 0xff; info.singleEvalueInfo.mode7 = dt[12] & 0xff; info.singleEvalueInfo.mode8 = dt[13] & 0xff; info.singleEvalueInfo.mode9 = dt[14] & 0xff; info.singleEvalueInfo.mode10 = dt[15] & 0xff; info.singleEvalueInfo.mode11 = dt[16] & 0xff; info.singleEvalueInfo.mode12 = dt[17] & 0xff; info.singleEvalueInfo.title = new byte[12]; System.arraycopy(dt, 12, info.singleEvalueInfo.title, 0, 12); if(dt.length > 24){ info.singleEvalueInfo.number = dt[24] & 0xff; } }else if(info.mode == VoteType_BatchEvalue) { info.batchEvalueInfo.mode1 = dt[6] & 0xff; info.batchEvalueInfo.startVal = (dt[7] & 0xff) << 8 | (dt[8] & 0xff); info.batchEvalueInfo.endVal = (dt[9] & 0xff) << 8 | (dt[10] & 0xff); info.batchEvalueInfo.autoMove = dt[11] & 0xff; info.batchEvalueInfo.width1 = dt[12] & 0xff; info.batchEvalueInfo.width2 = dt[13] & 0xff; info.batchEvalueInfo.less = dt[14] & 0xff; info.batchEvalueInfo.secrecy = dt[15] & 0xff; info.batchEvalueInfo.modify = dt[16] & 0xff; info.batchEvalueInfo.ruleStart = dt[17] & 0xff; info.batchEvalueInfo.ruleEnd = dt[18] & 0xff; info.batchEvalueInfo.sliderover = dt[19] & 0xff; }else if(info.mode == VoteType_BatchIDEvalue){ info.batchEvalueInfo.mode1 = dt[6] & 0xff; info.batchEvalueInfo.startVal = (dt[7] & 0xff) << 8 | (dt[8] & 0xff); info.batchEvalueInfo.endVal = (dt[9] & 0xff) << 8 | (dt[10] & 0xff); info.batchEvalueInfo.autoMove = dt[11] & 0xff; info.batchEvalueInfo.width1 = dt[12] & 0xff; info.batchEvalueInfo.width2 = dt[13] & 0xff; info.batchEvalueInfo.less = dt[14] & 0xff; info.batchEvalueInfo.secrecy = dt[15] & 0xff; info.batchEvalueInfo.modify = dt[16] & 0xff; info.batchEvalueInfo.ruleStart = dt[17] & 0xff; info.batchEvalueInfo.ruleEnd = dt[18] & 0xff; info.batchEvalueInfo.sliderover = dt[19] & 0xff; } else { info.mode2_modify = dt[7] & 0xff; info.mode3_secret = dt[8] & 0xff; info.mode4 = dt[9] & 0xff; info.voteid = dt[11] & 0xff; info.file = dt[12] & 0xff; info.init = dt[13] & 0xff; } m_listener.onVoteEvent(info); } private byte[] broadcastData = new byte[4096]; private byte[] fileData; private int fileLen; private int lastPackH = -1; private short needBits = 0; private int okBits = 0; private int currDownloadMsgId; private int broadMsgId = -1; private long lastOnMultiPackageDataTime; private int maxPackH; //用于计算收到长度 private int maxPachL; //用于计算收到长度 private int downType; private int downId; private void onMultiPackageInfo(byte[] data, int size) { byte[] dt = Arrays.copyOfRange(data, 3, data.length);// 从len开始,和文档下标统一 int downCmd = dt[4]; //1 进入或退出下载状态 downType = dt[5];// 10即时信息 或 11短信 downId = dt[6]; ////数据包标识码 int dcmd = dt[7];// 1:进入下载 0:退出下载 if (downCmd == 1) { // 1:进入/退出下载 resopnseMultiPackageMode(data, size); if (dcmd == 1) {//模式 1进入下载 Log.d(TAG, " 1:进入下载 。。。。。downType = " + downType + " downId:"+downId); // m_listener.onMultiPackageStartDownload(downType,downId); if (downType == 40 ) {//下载文件模式 lastPackH = -1; int packH = dt[8]; int packL = dt[9] + 1; fileLen = (packH * 16 + packL) * 16 ; LogUtil.d(TAG, "下载文件,长度:" + fileLen); fileData = new byte[fileLen]; Arrays.fill(fileData, (byte) 0x0); } else if (downType >=1 && downType <=3) { maxPackH = 0; maxPachL = 0; Arrays.fill(broadcastData, (byte) 0x0); } } else { //0退出下载 LogUtil.d(TAG, dcmd + ": 退出下载。。。。。。。。。"); if (downType == 40) { if (System.currentTimeMillis() - lastOnMultiPackageDataTime > 500) { lastOnMultiPackageDataTime = System.currentTimeMillis(); m_listener.onMultiPackageData(fileData, fileLen -4 ); } }else if(downType >=1 && downType <=3){ if (System.currentTimeMillis() - lastOnMultiPackageDataTime > 500) { lastOnMultiPackageDataTime = System.currentTimeMillis(); Log.d(TAG, "maxPackH:" + maxPackH + " maxPachL:" + maxPachL); broadcastData[0] = (byte) 0xF4 ; broadcastData[1] = (byte) 0xF5 ; broadcastData[2] = (byte) downType; broadcastData[3] = (byte) downId; m_listener.onMultiPackageData(broadcastData, (maxPackH+1) * 16 + (maxPachL+1) * 16 + 4); } } } } else if (downCmd == 2) { // 2:下载数据 int msgid = (byte) dt[6]; byte packH = dt[7];// 数据段 编号 当前最大15(16片) byte packL = dt[8];// 数据片编号 LogUtil.d(TAG, "下载。。。msgId:" + msgid + " packH:" + packH + " apckL:" + packL); if (downType == 40) {// 文件下载 if (lastPackH != packH) { //新的packH LogUtil.i(TAG, "new packH......."); okBits = 0; lastPackH = packH; } System.arraycopy(dt, 9, fileData, (packH * 16 + packL) * 16, 16); okBits |= (1 << packL); LogUtil.d(TAG, "packL:" + packL + " okBits:" + okBits); } else {// 广播 needBits = calcBits(packH); if (broadMsgId != msgid) { Arrays.fill(broadcastData, (byte) 0x0); broadMsgId = msgid; okBits = 0; } System.arraycopy(dt, 9, broadcastData, packL * 16, 16); okBits |= (1 << packL); LogUtil.d(TAG, "packL:" + packL + " okBits:" + okBits + " needBits:" + needBits); if (okBits == needBits) { if (broadMsgId != currDownloadMsgId) { m_listener.onMultiPackageData(broadcastData, (packH + 1) * 16); currDownloadMsgId = broadMsgId; } Arrays.fill(broadcastData, (byte) 0x0); broadMsgId = msgid; okBits = 0; } /*needBits = calcBits(packH); if (broadMsgId != msgid) { Arrays.fill(broadcastData, (byte) 0x0); broadMsgId = msgid; okBits = 0; } System.arraycopy(dt, 9, broadcastData, packL * 16, 16); if (lastPackH != packH) { Log.i(TAG, "new packH......."); needBits = calcBits((byte)16); okBits = 0; lastPackH = packH; maxPachL = 0; } if(packH> maxPackH){ maxPackH = packH; } if(packL > maxPachL){ maxPachL = packL; } if(downType >=1 && downType <=3){ System.arraycopy(dt, 9, broadcastData, (packH * 16 + packL) * 16 + 4, 16); }else { System.arraycopy(dt, 9, broadcastData, (packH * 16 + packL) * 16, 16); } okBits |= (1 << packL); Log.d(TAG, "packL:" + packL + " okBits:" + okBits + " needBits:" + (needBits & 0xffff) + " downType" + downType); if( downType > 3) { if (okBits == needBits) { if (broadMsgId != currDownloadMsgId) { m_listener.onMultiPackageData(broadcastData, (maxPackH * 16 + maxPachL) * 16 ); currDownloadMsgId = broadMsgId; } Arrays.fill(broadcastData, (byte) 0x0); broadMsgId = msgid; okBits = 0; } }*/ } } else if (downCmd == 3) { // 3:询问 resopnseMultiPackageQuery(data, size); Log.d(TAG, " 3:询问。。。。。。。。。"); } } private short calcBits(byte packh) { short bits = 0; for (int i = 0; i <= packh; i++) { bits |= (1 << i); } return bits; } private void resopnseMultiPackageMode(byte[] data, int size) { byte[] retData = Arrays.copyOf(data, size); retData[4] = (byte) 0xC0; writeToCom(retData); } private void resopnseMultiPackageQuery(byte[] data, int size) { byte[] retData = Arrays.copyOf(data, size); retData[4] = (byte) 0xC0; int tmpOk = ~okBits; retData[11] = (byte) tmpOk; retData[12] = (byte) (tmpOk >> 8); writeToCom(retData); } public static String getVoteType(int mode) { switch (mode) { case VoteType_Stop: return "VoteType_Stop"; case VoteType_Signin: return "VoteType_Signin"; case VoteType_Vote: return "VoteType_Vote"; case VoteType_BatchVote: return "VoteType_BatchVote"; case VoteType_BatchElect: return "VoteType_BatchElect"; default: break; } return "" + mode; } public static String getKeySn(byte[] data) { String sn = ""; String CS = "0123456789ABCDEF"; for (int i = 0; i < 6; i++) { sn += CS.charAt((data[i] >> 4) & 0xF); sn += CS.charAt((data[i] >> 0) & 0xF); } return sn; } private long writeOkPageNo; private int compareCount; private class CheckFirmReceveThread extends Thread{ public void run() { while (true) { try { Thread.sleep(1000); if(writeOkPageNo != firmWritePage ){ writeOkPageNo = firmWritePage; //sendMessage(keypadID + ":recv"+lastReceveLength+"\n"); //LogUtil.d(TAG,"CheckReceveThread:check ok!"); compareCount = 0; }else{ compareCount ++; if(compareCount <= 20){ LogUtil.d(TAG,"CheckWriteFirmhread:retry ==========="); m_listener.onFirmUpdateInfo("与入页:"+firmWritePage +"失败, 次数:" + compareCount); writeFlash(firmWritePage); }else{ compareCount = 0; LogUtil.d(TAG,"CheckWriteFirmhread:fail , exit!"); LogUtil.e(TAG, "写入扇区" + firmWritePage + "失败!"); m_listener.onFirmUpdateResult(false, "写入扇区" + firmWritePage + "失败!"); exitFirmUpdate(2); break; } } if (firmWritePage > 0 && firmWritePage == firmWritePageMax) { LogUtil.d(TAG,"CheckWriteFirmhread:ok : exit!"); break; } } catch (InterruptedException e) { e.printStackTrace(); } } } }; private static int encodeBCD(byte c) { if (c >= 'a' && c <= 'f') { return 10 + (c - 'a'); }else if (c >= '0' && c <= '9') { return c - '0'; }else if (c >= 'A' && c <= 'F') { return 10 + (c - 'A'); }else if(c == '.'){ return 0xE; } return -1; } /** *把字符串形式转换为字节形式 */ private byte[] util_encodeBCD(byte[] cs) { byte[] rs = new byte[17]; Arrays.fill(rs, (byte) 0xff);// int len = cs.length<16 ? cs.length : 16; int io = 0; for (int i = 0; i < len ; i+=2) { int n = encodeBCD(cs[i]); n <<= 4; if(i+1 == cs.length){ rs[io++] = (byte) (n|0xf); break; } n |= encodeBCD(cs[i+1]); if (n < 0) { break; } rs[io++] = (byte)n; } rs[++io] = 0; return rs; } public static String util_decodeBCD(byte[] cs , int len){ byte[] buf = new byte[8*2]; Arrays.fill(buf,(byte) 0); String bcdNum = "0123456789ABCD.F"; String bcdStr = bytesToHexString(cs); for(int i=0;i= '0' && item <= '9') { buf[i] = item; }else if(item == 'E' ){ buf[i] = '.'; }else if(item == 'F' ){ buf[i] = 0; break; } item = bcdStr.getBytes()[i+1]; if(item >= '0' && item <= '9') { buf[i+1] = item ; }else if(item == 'E' ){ buf[i+1] = '.'; }else if(item == 'F' ){ buf[i+1] = 0; break; } } return new String(buf).trim(); } public static String bytesToHexString(byte[] src){ StringBuilder stringBuilder = new StringBuilder(""); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString().toUpperCase(); } }