Browse Source

新卡无法清除记录,没有旧代码,重新开发软件。该版本已实现清除新卡旧卡记录功能

DFS_Shuo_Chen 7 months ago
commit
f3a3ecb07e
59 changed files with 3139 additions and 0 deletions
  1. BIN
      Bin/RIDBMTReader.exe
  2. BIN
      Bin/RIDBMTReader.rar
  3. BIN
      Bin/RIDBMTReader/RIDBMTReader.exe
  4. 2 0
      Bin/RIDBMTReader/conn.ini
  5. 2 0
      Bin/conn.ini
  6. 22 0
      RIDBMTReader.sln
  7. BIN
      RIDBMTReader.v12.suo
  8. 519 0
      RIDBMTReader/ComHandle.cpp
  9. 56 0
      RIDBMTReader/ComHandle.h
  10. 23 0
      RIDBMTReader/Debug/RIDBMTReader.Build.CppClean.log
  11. 7 0
      RIDBMTReader/Debug/RIDBMTReader.log
  12. BIN
      RIDBMTReader/Debug/RIDBMTReader.tlog/CL.read.1.tlog
  13. BIN
      RIDBMTReader/Debug/RIDBMTReader.tlog/CL.write.1.tlog
  14. 2 0
      RIDBMTReader/Debug/RIDBMTReader.tlog/RIDBMTReader.lastbuildstate
  15. BIN
      RIDBMTReader/Debug/RIDBMTReader.tlog/cl.command.1.tlog
  16. BIN
      RIDBMTReader/Debug/RIDBMTReader.tlog/link.command.1.tlog
  17. BIN
      RIDBMTReader/Debug/RIDBMTReader.tlog/link.read.1.tlog
  18. BIN
      RIDBMTReader/Debug/RIDBMTReader.tlog/link.write.1.tlog
  19. BIN
      RIDBMTReader/Debug/RIDBMTReader.tlog/rc.command.1.tlog
  20. BIN
      RIDBMTReader/Debug/RIDBMTReader.tlog/rc.read.1.tlog
  21. BIN
      RIDBMTReader/Debug/RIDBMTReader.tlog/rc.write.1.tlog
  22. 588 0
      RIDBMTReader/MySeries.cpp
  23. 80 0
      RIDBMTReader/MySeries.h
  24. 104 0
      RIDBMTReader/RIDBMTReader.cpp
  25. 32 0
      RIDBMTReader/RIDBMTReader.h
  26. BIN
      RIDBMTReader/RIDBMTReader.rc
  27. 143 0
      RIDBMTReader/RIDBMTReader.vcxproj
  28. 87 0
      RIDBMTReader/RIDBMTReader.vcxproj.filters
  29. 372 0
      RIDBMTReader/RIDBMTReaderDlg.cpp
  30. 47 0
      RIDBMTReader/RIDBMTReaderDlg.h
  31. 92 0
      RIDBMTReader/ReadMe.txt
  32. 9 0
      RIDBMTReader/Release/RIDBMTReader.log
  33. BIN
      RIDBMTReader/Release/RIDBMTReader.tlog/CL.read.1.tlog
  34. BIN
      RIDBMTReader/Release/RIDBMTReader.tlog/CL.write.1.tlog
  35. 2 0
      RIDBMTReader/Release/RIDBMTReader.tlog/RIDBMTReader.lastbuildstate
  36. BIN
      RIDBMTReader/Release/RIDBMTReader.tlog/cl.command.1.tlog
  37. BIN
      RIDBMTReader/Release/RIDBMTReader.tlog/link.command.1.tlog
  38. BIN
      RIDBMTReader/Release/RIDBMTReader.tlog/link.read.1.tlog
  39. BIN
      RIDBMTReader/Release/RIDBMTReader.tlog/link.write.1.tlog
  40. BIN
      RIDBMTReader/Release/RIDBMTReader.tlog/rc.command.1.tlog
  41. BIN
      RIDBMTReader/Release/RIDBMTReader.tlog/rc.read.1.tlog
  42. BIN
      RIDBMTReader/Release/RIDBMTReader.tlog/rc.write.1.tlog
  43. 2 0
      RIDBMTReader/conn.ini
  44. 133 0
      RIDBMTReader/global.cpp
  45. 62 0
      RIDBMTReader/global.h
  46. BIN
      RIDBMTReader/res/RIDBMTReader.ico
  47. BIN
      RIDBMTReader/res/RIDBMTReader.rc2
  48. BIN
      RIDBMTReader/resource.h
  49. 8 0
      RIDBMTReader/stdafx.cpp
  50. 53 0
      RIDBMTReader/stdafx.h
  51. 8 0
      RIDBMTReader/targetver.h
  52. 306 0
      RIDBMTReader/tools.cpp
  53. 26 0
      RIDBMTReader/tools.h
  54. 6 0
      clear.bat
  55. 0 0
      文档/MT318-118、119-V1.4通讯协议.doc
  56. 22 0
      文档/指令参考.txt
  57. 58 0
      文档/新文件 4.txt
  58. 73 0
      文档/调试问题.txt
  59. 193 0
      文档/铭特加油测试记录清除工具.docx

BIN
Bin/RIDBMTReader.exe


BIN
Bin/RIDBMTReader.rar


BIN
Bin/RIDBMTReader/RIDBMTReader.exe


+ 2 - 0
Bin/RIDBMTReader/conn.ini

@@ -0,0 +1,2 @@
+[Config]
+PORT=

+ 2 - 0
Bin/conn.ini

@@ -0,0 +1,2 @@
+[Config]
+PORT=

+ 22 - 0
RIDBMTReader.sln

@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RIDBMTReader", "RIDBMTReader\RIDBMTReader.vcxproj", "{91A1546B-87FC-4C7B-B961-E57B2DC66A39}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{91A1546B-87FC-4C7B-B961-E57B2DC66A39}.Debug|Win32.ActiveCfg = Debug|Win32
+		{91A1546B-87FC-4C7B-B961-E57B2DC66A39}.Debug|Win32.Build.0 = Debug|Win32
+		{91A1546B-87FC-4C7B-B961-E57B2DC66A39}.Release|Win32.ActiveCfg = Release|Win32
+		{91A1546B-87FC-4C7B-B961-E57B2DC66A39}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

BIN
RIDBMTReader.v12.suo


+ 519 - 0
RIDBMTReader/ComHandle.cpp

@@ -0,0 +1,519 @@
+#include "stdafx.h"
+#include "ComHandle.h"
+#include "global.h"
+#include "RIDBMTReaderDlg.h"
+#include <string>
+using namespace std;
+
+
+ComHandle::ComHandle()
+{
+	m_open = FALSE;
+
+	memset(CommBuf, 0, 1024);
+	CommBufLen = 0;
+}
+
+
+int ComHandle::opencom(int portno)
+{
+	closecom();
+
+	if (portno > 0)
+	{
+		//新建串口通讯对象
+		m_pSerial = new CMyCESeries();
+		m_pSerial->m_OnSeriesRead = OnComRead;
+		//m_nPortNo = portNo;
+
+
+		int rtn = m_pSerial->OpenPort(this, portno);
+
+		//打开串口
+		if (rtn)
+		{
+			addText("打开串口" + std::to_string(portno) + "成功");
+			m_open = TRUE;
+		}
+		else
+		{
+			addText("打开串口" + std::to_string(portno) + "失败");
+			m_open = FALSE;
+
+			if (m_pSerial)
+			{
+				delete m_pSerial;
+				m_pSerial = NULL;
+			}
+		}
+
+		return rtn;
+	}
+	else
+		return false;
+
+}
+
+
+int ComHandle::closecom()
+{
+	if (m_open && m_pSerial != NULL)
+	{
+		m_pSerial->ClosePort();
+
+		delete m_pSerial;
+		m_pSerial = NULL;
+
+		m_open = FALSE;
+
+		return true;
+	}
+	return false;
+}
+
+int ComHandle::senddata()
+{
+
+
+
+	//int nRc = m_pSerial->WriteSyncPort(buff, len);
+	//return nRc;
+
+	return false;
+}
+
+void ComHandle::addText(string str)
+{
+	if (m_pRichEdit)
+	{
+		m_pRichEdit->SetSel(-1, -1);
+
+		m_pRichEdit->ReplaceSel((str+ string("\r\n")).c_str());
+
+		m_pRichEdit->PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
+
+
+		if (m_pRichEdit->GetLineCount() > 500)
+		{
+			m_pRichEdit->SetSel(0, -1);
+			m_pRichEdit->Clear();
+		}
+	}
+}
+
+
+bool ComHandle::ProcessComData(BYTE* buf, DWORD bufLen)
+{
+
+
+	string s = "";
+	char ch[4];
+	for (auto i = 0; i < bufLen; ++i)
+	{
+		sprintf_s(ch, "%.2x ", buf[i]);
+		s += ch;
+	}
+
+	char chlog[1000];
+	sprintf_s(chlog, "收到数据:%s", s.data());
+	//addText(chlog);
+
+
+	int ack = 0;
+	int recv = 0;
+	if (g_enq == 0)
+	{
+		ack = buf[0];
+	}
+	else
+	{
+		recv = 1;
+
+
+		memcpy(CommBuf + CommBufLen, buf, bufLen);
+		CommBufLen += bufLen;
+
+		if (CommBufLen == bufLen)
+		{
+			if (CommBuf[0] != 0x02)
+			{
+				addText("数据起始位不对");
+				memset(CommBuf, 0, 1024);
+				CommBufLen = 0;
+				return 0;
+			}
+
+
+		}
+
+		if (CommBufLen < 5)
+		{
+			return 0;
+		}
+
+		int len = CommBuf[1] * 256 + CommBuf[2];
+
+		if (len + 5 > CommBufLen)
+		{
+			return 0;
+		}
+		else if (len + 5 < CommBufLen)
+		{
+			addText("收到数据总长度超出");
+			memset(CommBuf, 0, 1024);
+			CommBufLen = 0;
+			return 0;
+		}
+		
+
+		unsigned char xor = XORChecksum(CommBuf, CommBufLen - 1);
+		if (xor != CommBuf[CommBufLen - 1])
+		{
+			addText("收到数据校验不对");
+			g_stage = 0;
+			memset(CommBuf, 0, 1024);
+			CommBufLen = 0;
+			return 0;
+		}
+
+
+
+
+		BYTE tbu[128] = { 0 };
+		unsigned tle = 0;
+		memcpy(tbu, CommBuf, CommBufLen);
+		tle = CommBufLen;
+		s = "";
+		for (auto i = 0; i < tle; ++i)
+		{
+			sprintf_s(ch, "%.2x ", tbu[i]);
+			s += ch;
+		}
+
+		sprintf_s(chlog, "收到数据 合并:%s", s.data());
+		//addText(chlog);
+	}
+
+
+
+
+
+
+
+	int bsuccess = TRUE;
+
+	if (g_stage == 1)
+	{
+
+		if (g_enq == 0)
+		{
+			if (ack == 0x06)
+			{
+				unsigned char b[2] = { 0x05 };
+				senddata(b, 1);
+				g_enq = 1;
+			}
+			else
+			{
+				addText("应答不成功,code:"+to_string(ack));
+				bsuccess = FALSE;
+			}
+
+		}
+		else
+		{
+			addText("收到查询卡状态回复");
+
+
+			if (CommBuf[5] == 0x31)
+			{
+				addText("卡座无卡");
+				bsuccess = FALSE;
+			}
+
+			if (CommBuf[6] == 0x30)
+			{
+				addText("卡座无卡");
+				bsuccess = FALSE;
+			}
+			else if (CommBuf[6] == 0x3f)
+			{
+				addText("无法识别");
+				bsuccess = FALSE;
+			}
+			else if (CommBuf[6] != 0x31)
+			{
+				addText("非触点cpu卡,可能会引起失败");
+			}
+
+		}
+
+
+		
+	}
+	else if (g_stage == 2)
+	{
+		if (g_enq == 0)
+		{
+			if (ack == 0x06)
+			{
+				unsigned char b[2] = { 0x05 };
+				senddata(b, 1);
+				g_enq = 1;
+			}
+			else
+			{
+				addText("应答不成功,code:" + to_string(ack));
+				bsuccess = FALSE;
+			}
+
+		}
+		else
+		{
+
+			addText("收到CPU卡冷复位回复");
+
+
+			int result = CommBuf[5];
+			if (result == 0x59 || result == 0x5A)
+			{
+				addText("复位成功");
+			}
+			else if (result == 0x4E)
+			{
+				addText("复位不成功");
+				bsuccess = FALSE;
+			}
+			else if (result == 0x45)
+			{
+				addText("卡机无卡");
+				bsuccess = FALSE;
+			}
+			else if (result == 0x57)
+			{
+				addText("卡不在允许操作的位置上");
+				bsuccess = FALSE;
+			}
+			else
+			{
+				addText("无定义");
+			}
+		}
+
+	}
+	else if (g_stage >=3 && g_stage <=10)
+	{ 
+		if (g_enq == 0)
+		{
+			if (ack == 0x06)
+			{
+				unsigned char b[2] = { 0x05 };
+				senddata(b, 1);
+				g_enq = 1;
+			}
+			else
+			{
+				addText("应答不成功,code:" + to_string(ack));
+				bsuccess = FALSE;
+			}
+
+		}
+		else
+		{
+
+			if (g_stage == 3)
+			{
+				addText("收到select adf回复");
+
+			}
+			else if (g_stage == 4)
+			{
+				addText("收到ET1回复");
+
+			}
+			else if (g_stage == 5)
+			{
+				addText("收到读21号文件回复");
+
+			}
+			else if (g_stage == 6)
+			{
+				addText("收到读26号文件回复");
+
+			}
+			else if (g_stage == 7)
+			{
+				addText("收到verify回复");
+
+			}
+			else if (g_stage == 8)
+			{
+				int count = CommBuf[8] * 256 + CommBuf[9];
+
+
+				addText("收到查询记录个数上限值回复,"+to_string(count));
+
+
+
+			}
+			else if (g_stage == 9)
+			{
+				int count = CommBuf[8] * 256 + CommBuf[9];
+				addText("收到查询未导出记录个数回复," + to_string(count));
+
+			}
+			else if (g_stage == 10)
+			{
+				addText("收到清除记录计数器回复");
+
+			}
+
+
+			int result = CommBuf[5];
+			if (result == 0x59)
+			{
+				addText("操作成功");
+
+				if (g_stage == 8)
+				{
+					AfxMessageBox("清除记录成功");
+				}
+			}
+			else if (result == 0x4E)
+			{
+				addText("操作不成功");
+				bsuccess = FALSE;
+			}
+			else if (result == 0x45)
+			{
+				addText("卡机无卡");
+				bsuccess = FALSE;
+			}
+			else if (result == 0x57)
+			{
+				addText("卡不在允许操作的位置上");
+				bsuccess = FALSE;
+			}
+			else
+			{
+				addText("无定义");
+			}
+		}
+
+	}
+	else if (g_stage == 11)
+	{
+		//弹卡		
+		if (g_enq == 0)
+		{
+			if (ack == 0x06)
+			{
+				unsigned char b[2] = { 0x05 };
+				senddata(b, 1);
+				g_enq = 1;
+			}
+
+		}
+		else
+		{
+		}
+
+	}
+
+
+	if (g_stage == 0)
+	{
+		//弹卡		
+		if (g_enq == 0)
+		{
+			if (ack == 0x06)
+			{
+				unsigned char b[2] = { 0x05 };
+				senddata(b, 1);
+				g_enq = 1;
+			}
+
+		}
+		else
+		{
+		}
+	}
+
+
+	if (!bsuccess)
+	{
+		addText("操作失败");
+		AfxMessageBox("操作失败");
+		g_stage = 0;
+		memset(CommBuf, 0, 1024);
+		CommBufLen = 0;
+		return 0;
+	}
+
+
+	if (g_enq == 1 && recv ==1 && g_stage > 0 && g_stage < 11)
+	{
+		g_stage++;
+
+
+		((CRIDBMTReaderDlg*)pParentDlg)->sendStageData();
+	}
+
+
+
+	memset(CommBuf, 0, 1024);
+	CommBufLen = 0;
+
+
+
+
+
+	return true;
+}
+
+
+void ComHandle::linkRichEdit(CRichEditCtrl* pRichEdit)
+{
+	m_pRichEdit = pRichEdit;
+}
+
+
+int ComHandle::senddata(const BYTE*buf, DWORD bufLen)
+{
+	if (!m_open || !m_pSerial)
+	{
+		addText("串口未成功打开");
+		return false;
+	}
+
+
+	int nRc = m_pSerial->WriteSyncPort(buf, bufLen);
+
+	if (nRc)
+	{
+		CString strS = "";
+		for (int i = 0; i < bufLen; ++i)
+		{
+			CString strW;
+			CStringA str;
+			strW.Format(_T("%.2x"), buf[i]);
+			strS += strW + " ";
+		}
+
+		//addText(string(" 发送:") + strS.GetString());
+	}
+	else
+	{
+		addText("发送数据失败");
+	}
+
+
+
+	return nRc;
+}
+
+
+void ComHandle::setparentdlg(CRIDBMTReaderDlg *pdlg)
+{
+	pParentDlg = (CDialogEx*)pdlg;
+}

+ 56 - 0
RIDBMTReader/ComHandle.h

@@ -0,0 +1,56 @@
+#pragma once
+
+#include "MySeries.h"
+
+#include <string>
+using std::string;
+
+
+class CRIDBMTReaderDlg;
+
+class ComHandle
+{
+public:
+	ComHandle();
+
+	int opencom(int portno);
+
+	int closecom();
+
+	int senddata();
+
+	void addText(string str);
+
+	bool ProcessComData(BYTE* buf, DWORD bufLen);
+
+	static void CALLBACK OnComRead(void * pOwner, BYTE* buf, DWORD bufLen)
+	{
+		if (bufLen <= 1024)
+		{
+			ComHandle* pThis = (ComHandle*)pOwner;
+
+			pThis->ProcessComData(buf, bufLen);
+		}
+	}
+
+
+	void linkRichEdit(CRichEditCtrl* pRichEdit);
+	void setparentdlg(CRIDBMTReaderDlg *pdlg);
+
+	int senddata(const BYTE*buf, DWORD bufLen);
+
+	int m_open;
+
+public:
+	CDialogEx* pParentDlg;
+
+protected:
+	CMyCESeries* m_pSerial;
+	CRichEditCtrl* m_pRichEdit;
+
+	BYTE CommBuf[1024];
+	unsigned CommBufLen = 0;
+	
+};
+
+

+ 23 - 0
RIDBMTReader/Debug/RIDBMTReader.Build.CppClean.log

@@ -0,0 +1,23 @@
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.pch
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\vc120.pdb
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\vc120.idb
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\stdafx.obj
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\comhandle.obj
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\global.obj
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\myseries.obj
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.obj
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreaderdlg.obj
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\tools.obj
+c:\bitbucket\ridbmtreader\bin\ridbmtreader.ilk
+c:\bitbucket\ridbmtreader\bin\ridbmtreader.exe
+c:\bitbucket\ridbmtreader\bin\ridbmtreader.pdb
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.res
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.tlog\cl.command.1.tlog
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.tlog\cl.read.1.tlog
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.tlog\cl.write.1.tlog
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.tlog\link.command.1.tlog
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.tlog\link.read.1.tlog
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.tlog\link.write.1.tlog
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.tlog\rc.command.1.tlog
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.tlog\rc.read.1.tlog
+c:\bitbucket\ridbmtreader\ridbmtreader\debug\ridbmtreader.tlog\rc.write.1.tlog

+ 7 - 0
RIDBMTReader/Debug/RIDBMTReader.log

@@ -0,0 +1,7 @@
+  ComHandle.cpp
+c:\bitbucket\ridbmtreader\ridbmtreader\comhandle.cpp(111): warning C4018: '<' : signed/unsigned mismatch
+c:\bitbucket\ridbmtreader\ridbmtreader\comhandle.cpp(156): warning C4018: '>' : signed/unsigned mismatch
+c:\bitbucket\ridbmtreader\ridbmtreader\comhandle.cpp(160): warning C4018: '<' : signed/unsigned mismatch
+c:\bitbucket\ridbmtreader\ridbmtreader\comhandle.cpp(187): warning C4018: '<' : signed/unsigned mismatch
+c:\bitbucket\ridbmtreader\ridbmtreader\comhandle.cpp(495): warning C4018: '<' : signed/unsigned mismatch
+  RIDBMTReader.vcxproj -> C:\Bitbucket\RIDBMTReader\Bin\RIDBMTReader.exe

BIN
RIDBMTReader/Debug/RIDBMTReader.tlog/CL.read.1.tlog


BIN
RIDBMTReader/Debug/RIDBMTReader.tlog/CL.write.1.tlog


+ 2 - 0
RIDBMTReader/Debug/RIDBMTReader.tlog/RIDBMTReader.lastbuildstate

@@ -0,0 +1,2 @@
+#TargetFrameworkVersion=v4.0:PlatformToolSet=v120_xp:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit
+Debug|Win32|C:\Bitbucket\RIDBMTReader\|

BIN
RIDBMTReader/Debug/RIDBMTReader.tlog/cl.command.1.tlog


BIN
RIDBMTReader/Debug/RIDBMTReader.tlog/link.command.1.tlog


BIN
RIDBMTReader/Debug/RIDBMTReader.tlog/link.read.1.tlog


BIN
RIDBMTReader/Debug/RIDBMTReader.tlog/link.write.1.tlog


BIN
RIDBMTReader/Debug/RIDBMTReader.tlog/rc.command.1.tlog


BIN
RIDBMTReader/Debug/RIDBMTReader.tlog/rc.read.1.tlog


BIN
RIDBMTReader/Debug/RIDBMTReader.tlog/rc.write.1.tlog


+ 588 - 0
RIDBMTReader/MySeries.cpp

@@ -0,0 +1,588 @@
+/*-----------------------------------------
+* Copyright (c) 2008 Eric Wong
+* 本版紧供读者参考,不得用于任何商业行为
+*
+* 文件名称: CESeries.cpp
+* 文件标识: 
+* 摘要:用于封装WINCE 串口通讯
+*
+* 当前版本: 1.0
+* 作者: 汪兵 Eric Wong
+* 完成日期: 2008年1月17日
+*
+* 取代版本:
+* 原作者: 
+* 完成日期: 
+----------------------------------------*/
+#include "StdAfx.h"
+#include "MySeries.h"
+
+//构造函数
+CMyCESeries::CMyCESeries(UINT portNo, UINT baud, UINT parity, UINT databits, UINT stopbits)
+:m_portNo(portNo)
+,m_baud(baud)
+,m_parity(parity)
+,m_databits(databits)
+,m_stopbits(stopbits)
+,m_hReadThread(NULL)
+,m_hReadCloseEvent(NULL)
+{
+	//m_portNo		= portNo;		//串口号使用串口1 CAN模块和GPS共用
+	//m_baud			= baud;		//波特率
+	//m_parity		= parity;		//奇偶校验,0-None,1-Odd,2-Even
+	//m_databits		= databits;		//数据位
+	//m_stopbits		= stopbits;		//停止位 0-停止位1,1-停止位1.5,2-停止位2
+
+	//初始化内部变量
+	m_hComm = INVALID_HANDLE_VALUE;
+	m_OnSeriesRead = NULL;
+	m_hReadCloseEvent = NULL;
+	m_bOpened = false;
+
+	bCanComRead		= true;
+	m_bSyncOrAsync	= true;//使用同步方式或者异步方式(重叠方式),默认值为true:异步方式
+
+	memset(&m_olWrite,0,sizeof(OVERLAPPED));
+}
+
+//析构函数
+CMyCESeries::~CMyCESeries()
+{
+	if (m_bOpened)
+		ClosePort();
+}
+
+//串口读线程函数
+DWORD CMyCESeries::ReadThreadFunc(LPVOID lparam)
+{
+	CMyCESeries *ceSeries = (CMyCESeries*)lparam;
+	
+	
+	BYTE * readBuf = NULL;//读取的字节
+	DWORD actualReadLen=0;//实际读取的字节数
+	DWORD willReadLen;
+	
+	DWORD dwReadErrors;
+	COMSTAT	cmState;
+	//异步方式下将使用这些变量
+	//LPOVERLAPPED 
+	OVERLAPPED olWait;
+	//memset(&olWaite,0,sizeof(olWaite));  
+	memset(&olWait,0,sizeof(OVERLAPPED)); 
+    olWait.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); 
+	
+	//同步方式,将使用该变量
+	DWORD	 evtMask;
+	
+
+
+	// 清空缓冲,并检查串口是否打开。
+	ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE); 
+	
+	
+	//清空串口
+	PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );
+	
+	SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );//设置3个串口事件
+	
+	//可以查看串口设置了哪些事件
+	//DWORD dwMask1;
+	//GetCommMask(ceSeries->m_hComm,&dwMask1);
+
+	OVERLAPPED olRead;
+	memset(&olRead,0,sizeof(OVERLAPPED)); 
+	olRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
+
+
+	while(TRUE)
+	{
+		if(ceSeries->m_bSyncOrAsync)//异步方式下
+		{
+			DWORD dwCommStatus = 0;
+			BOOL bWait1=0;
+			bWait1= WaitCommEvent(ceSeries->m_hComm,&dwCommStatus,&olWait);//如果以上设置的3个事件中任何一个发生了,这里主要是监测接收缓冲区中有数据时
+			//while(!bWait1);//等待WaitCommEvent返回为TRUE,再往下执行,这种方式行不通,重叠方式(异步方式)时,该函数一直返回为false,
+			DWORD dwByte; //norains:It is only suitable for the GetOverlappedResult(),not undefined here.
+			if(GetOverlappedResult(ceSeries->m_hComm,&olWait,&dwByte,TRUE) == FALSE)//正常清空下,会一直在该函数阻塞,直到olWaite中的hEvent事件发生了
+			//则该函数不阻塞了,并且返回值为True
+			{
+				 if(GetLastError() != ERROR_IO_PENDING)
+				 {
+					 return 0x30;
+				 }
+				 //Clear the error flag
+				 DWORD dwErrors;
+				 COMSTAT comStat;
+				 memset(&comStat,0,sizeof(comStat));
+				 ClearCommError(ceSeries->m_hComm,&dwErrors,&comStat);
+				 return 0x35;
+			}
+			
+				//表示串口收到字符		
+			if (dwCommStatus & EV_RXCHAR) 
+			{
+				ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
+				willReadLen = cmState.cbInQue ;
+				if (willReadLen <= 0)
+				{
+					continue;
+				}
+				
+				//异步方式
+				//分配内存
+				readBuf = new BYTE[willReadLen+1];
+				ZeroMemory(readBuf,willReadLen+1);
+				//读取串口数据
+
+				//异步方式
+				if(ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,&olRead)==FALSE)//异步操作,在读取完成以后返回TRUE
+				{
+					//释放内存
+					delete[] readBuf;
+					readBuf = NULL;
+
+					if(GetLastError() != ERROR_IO_PENDING)
+						return 0x40;
+
+					if(GetOverlappedResult(ceSeries->m_hComm,&olRead,&actualReadLen,TRUE) == FALSE)
+						return 0x45;
+
+					if(actualReadLen == 0)
+						return 0x50;
+				}
+				else//缓冲区中的数据读取完时
+				{
+					//如果读取的数据大于0,
+					if (actualReadLen>0)
+					{
+						//触发读取回调函数
+						if (ceSeries->m_OnSeriesRead)
+						{
+							ceSeries->m_OnSeriesRead(ceSeries->m_pOwner,readBuf,actualReadLen);
+						}
+					}
+					//释放内存
+					delete[] readBuf;
+					readBuf = NULL;
+				}
+			}
+			
+		}
+		else//同步方式下
+		{
+				if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
+				{	
+					SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
+					//表示串口收到字符
+					if (evtMask & EV_RXCHAR)
+					{
+						ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
+						willReadLen = cmState.cbInQue ;
+						if (willReadLen <= 0)
+						{
+							continue;
+						}
+						
+						//分配内存
+						readBuf = new BYTE[willReadLen];
+						ZeroMemory(readBuf,willReadLen);
+						//读取串口数据
+						ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0);
+						
+						//如果读取的数据大于0,
+						if (actualReadLen>0)
+						{
+							//触发读取回调函数
+							if (ceSeries->m_OnSeriesRead)
+							{
+								ceSeries->m_OnSeriesRead(ceSeries->m_pOwner,readBuf,actualReadLen);
+							}
+						}
+
+						//释放内存
+						delete[] readBuf;
+						readBuf = NULL;
+					}
+				}
+		}
+
+		
+		
+		//每次读线程执行到该处时,都会等待(或者叫阻塞)10milseconds,看是否关闭串口事件是否发生
+		//在ClosePort()函数体中调用了CloseHandle(m_hReadCloseEvent);来使得该事件有信号,我觉得可以用SetEvent(m_hReadCloseEvent)代替,该函数也是使得事件有信号
+		//当执行了ClosePotr()函数后,说明该事件已经发生了,则当在读线程函数中执行到此处时,
+		//将会跳出while(true),从而退出读线程,
+		if (WaitForSingleObject(ceSeries->m_hReadCloseEvent, 10) == WAIT_OBJECT_0)//
+		{
+			TRACE("线程ReadThreadFunc退出\n");
+			break;
+		}
+	}
+
+	//关闭事件
+	CloseHandle( olRead.hEvent );
+	CloseHandle( olWait.hEvent );
+
+	//释放内存
+	if(readBuf)
+	{
+		delete[] readBuf;
+		readBuf = NULL;
+	}
+
+	ExitThread(0);
+	return 0;
+}
+
+//关闭读线程
+void CMyCESeries::CloseReadThread()
+{
+	if( m_hComm != INVALID_HANDLE_VALUE )
+	{
+	//	SetEvent(m_hReadCloseEvent);
+	//	CloseHandle(m_hReadCloseEvent);
+
+		//WaitForSingleObject(m_hReadThread, 1000);
+
+	//	DWORD exitCode;
+	//	BOOL ret = GetExitCodeThread(m_hReadThread, &exitCode);
+		//if(ret && exitCode != 0)
+		{
+			TRACE("强行关闭ReadThreadFunc线程\n");
+			TerminateThread(m_hReadThread,0);
+		}
+	//	CloseHandle(m_hReadThread);
+
+		m_hReadThread = NULL;
+	}
+
+/*
+	if( m_hComm != INVALID_HANDLE_VALUE )
+	{
+		SetEvent(m_hReadCloseEvent);
+		//设置所有事件无效
+		SetCommMask(m_hComm, 0);
+		//清空所有将要读的数据
+		PurgeComm( m_hComm,  PURGE_RXCLEAR );
+		//等待4秒,如果读线程没有退出,则强制退出
+		if (WaitForSingleObject(m_hReadThread,4000) == WAIT_TIMEOUT)
+		{
+			TerminateThread(m_hReadThread,0);
+		}
+		m_hReadThread = NULL;
+	}
+//*/
+}
+
+
+//函数介绍:打开串口
+//入口参数:pPortOwner	:使用此串口类的窗体句柄
+//		   portNo		:串口号
+//		   baud			:波特率
+//		   parity		:奇偶校验
+//		   databits		:数据位
+//		   stopbits		:停止位
+//出口参数:(无)
+//返回值:TRUE:成功打开串口;FALSE:打开串口失败
+BOOL CMyCESeries::OpenPort(void * pOwner,
+						 UINT portNo	,			//串口号
+						 UINT baud		,			//波特率
+						 UINT parity	,			//奇偶校验
+						 UINT databits	,			//数据位
+						 UINT stopbits  ,				//停止位
+						 bool isASync
+						 )
+{
+	m_portNo		= portNo;		//串口号使用串口1 CAN模块和GPS共用
+	m_baud			= baud;		//波特率
+	m_parity		= parity;		//奇偶校验,0-None,1-Odd,2-Even
+	m_databits		= databits;		//数据位
+	m_stopbits		= stopbits;		//停止位 0-停止位1,1-停止位1.5,2-停止位2
+
+	m_bSyncOrAsync	= isASync;
+
+	DCB commParam;
+	TCHAR szPort[15];	
+
+	ASSERT(pOwner!=NULL);
+	m_pOwner = pOwner;
+	
+	// 已经打开的话,直接返回
+	if (m_hComm != INVALID_HANDLE_VALUE)
+	{
+		return TRUE;
+	}
+	
+	//设置串口名
+	//wsprintf(szPort, _T("\.\COM%d:"), portNo);
+	wsprintf(szPort, _T("\\\\.\\COM%d"), portNo);
+	//sprintf(szPort, "\\\\.\\COM%d", portNo);
+	//打开串口
+	
+	if(m_bSyncOrAsync)//m_bSyncOrAsync值为0,则用同步方式创建,否则以异步方式创建、
+	{
+			m_hComm = CreateFile(			//以异步方式创建
+			szPort,
+			GENERIC_READ | GENERIC_WRITE,	//允许读和写
+			0,								//独占方式(共享模式)
+			NULL,
+			OPEN_EXISTING,					//打开而不是创建(创建方式)
+			 FILE_FLAG_OVERLAPPED,
+			0
+			);
+	}
+	else
+	{
+		m_hComm = CreateFile(			//以同步方式创建
+		szPort,
+		GENERIC_READ | GENERIC_WRITE,	//允许读和写
+		0,								//独占方式(共享模式)
+		NULL,
+		OPEN_EXISTING,					//打开而不是创建(创建方式)
+		0,  
+		NULL
+		);
+	}
+
+
+	if (m_hComm == INVALID_HANDLE_VALUE)
+	{
+		// 无效句柄,返回。		
+		TRACE(_T("CreateFile 返回无效句柄\n"));
+		DWORD  ErrNo = GetLastError();
+		return FALSE;
+		
+	}
+	
+	// 得到打开串口的当前属性参数,修改后再重新设置串口。
+	if (!GetCommState(m_hComm,&commParam))
+	{		
+		//关闭串口
+		CloseHandle (m_hComm);
+		m_hComm = INVALID_HANDLE_VALUE;
+		return FALSE;
+	}
+
+	if(m_bSyncOrAsync)//如果是异步方式,每创建一个串口对象,并且成功打开一个串口对象时后,才创建一个相应的发送事件
+	{
+		 //异步写串口     
+		m_olWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,_T("WriteData"));
+//		DWORD dwError = GetLastError();
+//		if(dwError !=0)
+//		{
+//			TRACE("异步方式创建串口对象时,为该串口对象所创建的写串口事件对象失败");
+//			return FALSE;
+//		}
+	}
+	
+	//设置串口参数
+	commParam.BaudRate = baud;					// 设置波特率 
+	commParam.fBinary = TRUE;					// 设置二进制模式,此处必须设置TRUE
+	commParam.fParity = TRUE;					// 支持奇偶校验 
+	commParam.ByteSize = databits;				// 数据位,范围:4-8 
+	commParam.Parity = parity;					// 校验模式
+	commParam.StopBits = stopbits;				// 停止位 
+	
+	commParam.fOutxCtsFlow = FALSE;				// No CTS output flow control 
+	commParam.fOutxDsrFlow = FALSE;				// No DSR output flow control 
+	commParam.fDtrControl = DTR_CONTROL_ENABLE; 
+	// DTR flow control type 
+	commParam.fDsrSensitivity = FALSE;			// DSR sensitivity 
+	commParam.fTXContinueOnXoff = TRUE;			// XOFF continues Tx 
+	commParam.fOutX = FALSE;					// No XON/XOFF out flow control 
+	commParam.fInX = FALSE;						// No XON/XOFF in flow control 
+	commParam.fErrorChar = FALSE;				// Disable error replacement 
+	commParam.fNull = FALSE;					// Disable null stripping 
+	commParam.fRtsControl = RTS_CONTROL_ENABLE; 
+	// RTS flow control 
+	commParam.fAbortOnError = FALSE;			// 当串口发生错误,并不终止串口读写
+	
+	//设置串口参数
+	if (!SetCommState(m_hComm, &commParam))
+	{
+		TRACE(_T("SetCommState error\n"));	
+		DWORD dwError = GetLastError();
+
+		//关闭串口
+		CloseHandle (m_hComm);
+		m_hComm = INVALID_HANDLE_VALUE;		
+		return FALSE;
+	}
+	
+    //设置串口读写时间
+	COMMTIMEOUTS CommTimeOuts;
+	GetCommTimeouts (m_hComm, &CommTimeOuts);
+	CommTimeOuts.ReadIntervalTimeout = MAXDWORD;  
+	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;  
+	CommTimeOuts.ReadTotalTimeoutConstant = 0;    
+	CommTimeOuts.WriteTotalTimeoutMultiplier = 10;  
+	CommTimeOuts.WriteTotalTimeoutConstant = 1000;  
+	if(!SetCommTimeouts( m_hComm, &CommTimeOuts ))
+	{
+		TRACE( _T("SetCommTimeouts 返回错误\n") );
+		//关闭串口
+		CloseHandle (m_hComm);
+
+		m_hComm = INVALID_HANDLE_VALUE;
+		return FALSE;
+	}
+	
+	//指定端口监测的事件集
+	SetCommMask (m_hComm, EV_RXCHAR);
+	//分配串口设备缓冲区
+	SetupComm(m_hComm,1024,1024);
+	//SetupComm(m_hComm,512,512);
+	//初始化缓冲区中的信息
+	PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
+	
+	CString strEvent;
+	strEvent.Format(_T("Com_ReadCloseEvent%d"),portNo);
+	m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,strEvent);
+
+	//创建串口读数据监听线程
+	if( bCanComRead == true )
+	{
+		m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);//通过this指针将串口对象传递给读线程函数ReadThreadFunc的形参
+	}
+		
+	
+	TRACE(_T("串口%d打开成功\n"), portNo);
+	m_bOpened = true;
+	return TRUE;
+}
+
+
+
+//函数介绍:关闭串口
+//入口参数:(无)
+//出口参数:(无)
+//返回值:  (无)
+void CMyCESeries::ClosePort()
+{	
+	//表示串口还没有打开
+	if (m_hComm == INVALID_HANDLE_VALUE)
+		return ;
+
+	//关闭事件
+	//TRACE("关闭串口读事件\n");	
+	Sleep(100);
+	//关闭读线程
+	CloseReadThread();
+
+	//关闭串口
+	TRACE("CMyCESeries关闭串口%d句柄\n", m_portNo);	
+	CloseHandle (m_hComm);
+	
+
+	//关闭事件
+	CloseHandle(m_olWrite.hEvent);
+
+	m_hComm = INVALID_HANDLE_VALUE;
+	m_bOpened = false;
+}
+
+
+//函数介绍:往串口写入数据
+//入口参数:buf :待写入数据缓冲区
+//	       bufLen : 待写入缓冲区长度
+//出口参数:(无)
+//返回值:TRUE:设置成功;FALSE:设置失败
+BOOL CMyCESeries::WriteSyncPort(const BYTE*buf , DWORD bufLen)
+{
+	if( false == m_bSyncOrAsync )//同步方式
+	{
+		DWORD dwNumBytesWritten;
+		DWORD dwHaveNumWritten =0 ; //已经写入多少
+		
+		int iInc = 0; //如果3次写入不成功,返回FALSE
+		ASSERT(m_hComm != INVALID_HANDLE_VALUE);
+		do
+		{
+			if (WriteFile (m_hComm,					//串口句柄 
+				buf+dwHaveNumWritten,				//被写数据缓冲区 
+				bufLen - dwHaveNumWritten,          //被写数据缓冲区大小
+				&dwNumBytesWritten,					//函数执行成功后,返回实际向串口写的个数	
+				NULL))								//此处必须设置NULL
+			{
+				dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;
+				//写入完成
+				if (dwHaveNumWritten == bufLen)
+				{
+					break;
+				}
+				iInc++;
+				if (iInc >= 3)
+				{
+					TRACE("CMyCESeries::WriteSyncPort 同步写串口失败3次\n");
+					return FALSE;
+				}
+				Sleep(10);
+			}
+			else
+			{
+				TRACE("CMyCESeries::WriteSyncPort 同步写串口失败\n");
+				return FALSE;
+			}
+		}while (TRUE);
+		
+		return TRUE;	
+	}
+	else//异步方式
+	{
+		DWORD dwNumBytesWritten;
+		DWORD dwHaveNumWritten =0 ; //已经写入多少
+
+//		OVERLAPPED olWrite;
+//		memset(&olWrite,0,sizeof(OVERLAPPED));
+//		m_olWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,_T("WriteData"));
+		 
+		//异步写串口     
+		if (WriteFile (m_hComm,					//串口句柄 
+						buf+dwHaveNumWritten,				//被写数据缓冲区 
+						bufLen - dwHaveNumWritten,          //被写数据缓冲区大小
+						&dwNumBytesWritten,					//函数执行成功后,返回实际向串口写的个数	
+						&m_olWrite) == FALSE)//并不是表示写入失败,而是没有将所有数据写入到缓冲区中,而只是写入了部分而已
+		{
+			if(GetLastError() != ERROR_IO_PENDING)
+			{
+				TRACE("CMyCESeries::WriteSyncPort 异步写串口0x20\n");
+				return 0x20;
+			}
+			if(GetOverlappedResult(m_hComm,&m_olWrite,&dwNumBytesWritten,TRUE) == FALSE)//这里将一直阻塞,直到将所有数据写入到缓冲区为止
+			{
+				TRACE("CMyCESeries::WriteSyncPort 异步写串口0x25\n");
+				return 0x25;
+			 }	
+		}
+		//else//写入成功
+		{
+			dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;
+			//写入完成
+			if (dwHaveNumWritten == bufLen)
+				return TRUE;
+			else
+			{
+				TRACE("CMyCESeries::WriteSyncPort 异步写串口%d失败\n", m_portNo);
+				return FALSE;
+			}
+		}
+	}
+}
+
+
+//函数介绍:设置串口读取、写入超时
+//入口参数:CommTimeOuts : 指向COMMTIMEOUTS结构
+//出口参数:(无)
+//返回值:TRUE:设置成功;FALSE:设置失败
+BOOL CMyCESeries::SetSeriesTimeouts(COMMTIMEOUTS CommTimeOuts)
+{
+	ASSERT(m_hComm != INVALID_HANDLE_VALUE);
+	return SetCommTimeouts(m_hComm,&CommTimeOuts);
+}
+
+
+//得到串口是否打开
+BOOL CMyCESeries::GetComOpened()
+{
+	return m_bOpened;
+}

+ 80 - 0
RIDBMTReader/MySeries.h

@@ -0,0 +1,80 @@
+/*-----------------------------------------
+* Copyright (c) 2008 Eric Wong
+* 本版紧供读者参考,不得用于任何商业行为
+*
+* 文件名称: CESeries.h
+* 文件标识: 
+* 摘要:用于封装WINCE 串口通讯
+*
+* 当前版本: 1.0
+* 作者: 汪兵 Eric Wong
+* 完成日期: 2008年1月17日
+*
+* 取代版本:
+* 原作者: 
+* 完成日期: 
+----------------------------------------*/
+#pragma once
+
+//定义串口接收数据函数类型
+typedef void (CALLBACK* MY_ONSERIESREAD)(void * pOwner /*父对象指针*/
+									  ,BYTE* buf  /*接收到的缓冲区*/
+									  ,DWORD dwBufLen /*接收到的缓冲区长度*/);
+
+
+class CMyCESeries
+{
+public:
+	bool bCanComRead;
+	bool m_bSyncOrAsync;//使用同步方式或者异步方式(重叠方式),默认值为true:异步方式
+	CMyCESeries(UINT portNo = -1, UINT baud = 9600, UINT parity = NOPARITY, UINT databits = 8, UINT stopbits = 0);
+	~CMyCESeries(void);
+public:
+	UINT m_portNo;				//串口号
+	UINT m_baud;				//波特率
+	UINT m_parity;				//奇偶校验
+	UINT m_databits;			//数据位
+	UINT m_stopbits;			//停止位
+
+	//打开串口
+	BOOL OpenPort(void* pOwner,/*指向父指针*/
+				  UINT portNo	= 1,		/*串口号*/
+				  UINT baud		= 9600,	/*波特率*/
+				  UINT parity	= 0,	/*奇偶校验*/
+				  UINT databits	= 8,		/*数据位*/
+				  UINT stopbits	= 0,        /*停止位*/
+				  bool isASync	= true
+				  );
+
+	//关闭串口
+	void ClosePort();
+	//写入数据
+	BOOL WriteSyncPort(const BYTE*buf , DWORD bufLen);
+	//设置串口读取、写入超时
+	BOOL SetSeriesTimeouts(COMMTIMEOUTS CommTimeOuts);
+	//得到串口是否打开
+	BOOL GetComOpened();
+
+private:
+    //同步串口读线程函数
+	static  DWORD WINAPI ReadThreadFunc(LPVOID lparam);
+	//static  DWORD WINAPI ReadThreadFunc2(LPVOID lparam);
+private:
+	//关闭读线程
+	void CloseReadThread();
+private:
+    //已打开的串口句柄
+//	HANDLE	m_hComm;
+	//读线程句柄
+	HANDLE m_hReadThread;
+	//读线程ID标识
+	DWORD m_dwReadThreadID;
+	//读线程退出事件
+	HANDLE m_hReadCloseEvent;
+	bool m_bOpened; //串口是否打开
+	void * m_pOwner; //指定父对象指针
+public:
+	MY_ONSERIESREAD m_OnSeriesRead; //同步方式下,串口读取回调函数
+	HANDLE	m_hComm;
+	OVERLAPPED m_olWrite;//假如该串口使用异步方式时,将会用到该变量
+};

+ 104 - 0
RIDBMTReader/RIDBMTReader.cpp

@@ -0,0 +1,104 @@
+
+// RIDBMTReader.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "RIDBMTReader.h"
+#include "RIDBMTReaderDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CRIDBMTReaderApp
+
+BEGIN_MESSAGE_MAP(CRIDBMTReaderApp, CWinApp)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CRIDBMTReaderApp construction
+
+CRIDBMTReaderApp::CRIDBMTReaderApp()
+{
+	// support Restart Manager
+	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+	// TODO: add construction code here,
+	// Place all significant initialization in InitInstance
+}
+
+
+// The one and only CRIDBMTReaderApp object
+
+CRIDBMTReaderApp theApp;
+
+
+// CRIDBMTReaderApp initialization
+
+BOOL CRIDBMTReaderApp::InitInstance()
+{
+//TODO: call AfxInitRichEdit2() to initialize richedit2 library.
+	// InitCommonControlsEx() is required on Windows XP if an application
+	// manifest specifies use of ComCtl32.dll version 6 or later to enable
+	// visual styles.  Otherwise, any window creation will fail.
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// Set this to include all the common control classes you want to use
+	// in your application.
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	CWinApp::InitInstance();
+
+
+	// Create the shell manager, in case the dialog contains
+	// any shell tree view or shell list view controls.
+	CShellManager *pShellManager = new CShellManager;
+
+	// Activate "Windows Native" visual manager for enabling themes in MFC controls
+	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
+
+	// Standard initialization
+	// If you are not using these features and wish to reduce the size
+	// of your final executable, you should remove from the following
+	// the specific initialization routines you do not need
+	// Change the registry key under which our settings are stored
+	// TODO: You should modify this string to be something appropriate
+	// such as the name of your company or organization
+	SetRegistryKey(_T("Local AppWizard-Generated Applications"));
+
+
+	AfxInitRichEdit2();
+
+	CRIDBMTReaderDlg dlg;
+	m_pMainWnd = &dlg;
+	INT_PTR nResponse = dlg.DoModal();
+	if (nResponse == IDOK)
+	{
+		// TODO: Place code here to handle when the dialog is
+		//  dismissed with OK
+	}
+	else if (nResponse == IDCANCEL)
+	{
+		// TODO: Place code here to handle when the dialog is
+		//  dismissed with Cancel
+	}
+	else if (nResponse == -1)
+	{
+		TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n");
+		TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n");
+	}
+
+	// Delete the shell manager created above.
+	if (pShellManager != NULL)
+	{
+		delete pShellManager;
+	}
+
+	// Since the dialog has been closed, return FALSE so that we exit the
+	//  application, rather than start the application's message pump.
+	return FALSE;
+}
+

+ 32 - 0
RIDBMTReader/RIDBMTReader.h

@@ -0,0 +1,32 @@
+
+// RIDBMTReader.h : main header file for the PROJECT_NAME application
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "include 'stdafx.h' before including this file for PCH"
+#endif
+
+#include "resource.h"		// main symbols
+
+
+// CRIDBMTReaderApp:
+// See RIDBMTReader.cpp for the implementation of this class
+//
+
+class CRIDBMTReaderApp : public CWinApp
+{
+public:
+	CRIDBMTReaderApp();
+
+// Overrides
+public:
+	virtual BOOL InitInstance();
+
+// Implementation
+
+	DECLARE_MESSAGE_MAP()
+};
+
+extern CRIDBMTReaderApp theApp;

BIN
RIDBMTReader/RIDBMTReader.rc


+ 143 - 0
RIDBMTReader/RIDBMTReader.vcxproj

@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{91A1546B-87FC-4C7B-B961-E57B2DC66A39}</ProjectGuid>
+    <RootNamespace>RIDBMTReader</RootNamespace>
+    <Keyword>MFCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120_xp</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120_xp</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)Bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)Bin\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0409</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="ComHandle.h" />
+    <ClInclude Include="global.h" />
+    <ClInclude Include="MySeries.h" />
+    <ClInclude Include="Resource.h" />
+    <ClInclude Include="RIDBMTReader.h" />
+    <ClInclude Include="RIDBMTReaderDlg.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+    <ClInclude Include="tools.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="ComHandle.cpp" />
+    <ClCompile Include="global.cpp" />
+    <ClCompile Include="MySeries.cpp" />
+    <ClCompile Include="RIDBMTReader.cpp" />
+    <ClCompile Include="RIDBMTReaderDlg.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="tools.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="RIDBMTReader.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\RIDBMTReader.rc2" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\RIDBMTReader.ico" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+  <ProjectExtensions>
+    <VisualStudio>
+      <UserProperties RESOURCE_FILE="RIDBMTReader.rc" />
+    </VisualStudio>
+  </ProjectExtensions>
+</Project>

+ 87 - 0
RIDBMTReader/RIDBMTReader.vcxproj.filters

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="RIDBMTReader.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="RIDBMTReaderDlg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="stdafx.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Resource.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="ComHandle.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="global.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="MySeries.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="tools.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="RIDBMTReader.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="RIDBMTReaderDlg.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="ComHandle.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="global.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="MySeries.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="tools.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="RIDBMTReader.rc">
+      <Filter>Resource Files</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\RIDBMTReader.rc2">
+      <Filter>Resource Files</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\RIDBMTReader.ico">
+      <Filter>Resource Files</Filter>
+    </Image>
+  </ItemGroup>
+</Project>

+ 372 - 0
RIDBMTReader/RIDBMTReaderDlg.cpp

@@ -0,0 +1,372 @@
+
+// RIDBMTReaderDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "RIDBMTReader.h"
+#include "RIDBMTReaderDlg.h"
+#include "afxdialogex.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CRIDBMTReaderDlg dialog
+
+
+
+CRIDBMTReaderDlg::CRIDBMTReaderDlg(CWnd* pParent /*=NULL*/)
+	: CDialogEx(CRIDBMTReaderDlg::IDD, pParent)
+{
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CRIDBMTReaderDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_COMBO1, CB_Port);
+	DDX_Control(pDX, IDC_RICHEDIT21, m_richedit);
+}
+
+BEGIN_MESSAGE_MAP(CRIDBMTReaderDlg, CDialogEx)
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	ON_BN_CLICKED(IDC_BUTTON_OpenPort, &CRIDBMTReaderDlg::OnBnClickedButtonOpenport)
+	ON_BN_CLICKED(IDC_BUTTON_ClearTrade, &CRIDBMTReaderDlg::OnBnClickedButtonCleartrade)
+	ON_BN_CLICKED(IDC_BUTTON_PopCard, &CRIDBMTReaderDlg::OnBnClickedButtonPopcard)
+END_MESSAGE_MAP()
+
+
+// CRIDBMTReaderDlg message handlers
+
+BOOL CRIDBMTReaderDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// Set the icon for this dialog.  The framework does this automatically
+	//  when the application's main window is not a dialog
+	SetIcon(m_hIcon, TRUE);			// Set big icon
+	SetIcon(m_hIcon, FALSE);		// Set small icon
+
+	// TODO: Add extra initialization here
+
+	std::string strport = getConfig("PORT");
+
+
+	CString strCom[255];
+	CString strTemp;
+	CString strPort;
+
+	HANDLE hCom;
+	int index = 0;
+	for (int i = 0; i<255; i++)
+	{
+		strTemp.Format("\\\\.\\COM%d", i + 1);
+		strPort.Format("%d", i + 1);
+		hCom = CreateFile(strTemp, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+			OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+		if (INVALID_HANDLE_VALUE == hCom)
+			continue;
+
+
+		strCom[i] = strTemp;
+		CB_Port.AddString(strPort);
+
+
+		if (string(strPort.GetString()) == strport)
+		{
+			CB_Port.SetCurSel(index);
+		}
+
+		index++;
+
+		CloseHandle(hCom);
+	}
+
+
+
+
+	com.linkRichEdit(&m_richedit);
+	com.setparentdlg(this);
+
+
+	if (strport != "" || strport != "0")
+	{
+		OnBnClickedButtonOpenport();
+	}
+
+	return TRUE;  // return TRUE  unless you set the focus to a control
+}
+
+// If you add a minimize button to your dialog, you will need the code below
+//  to draw the icon.  For MFC applications using the document/view model,
+//  this is automatically done for you by the framework.
+
+void CRIDBMTReaderDlg::OnPaint()
+{
+	if (IsIconic())
+	{
+		CPaintDC dc(this); // device context for painting
+
+		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+		// Center icon in client rectangle
+		int cxIcon = GetSystemMetrics(SM_CXICON);
+		int cyIcon = GetSystemMetrics(SM_CYICON);
+		CRect rect;
+		GetClientRect(&rect);
+		int x = (rect.Width() - cxIcon + 1) / 2;
+		int y = (rect.Height() - cyIcon + 1) / 2;
+
+		// Draw the icon
+		dc.DrawIcon(x, y, m_hIcon);
+	}
+	else
+	{
+		CDialogEx::OnPaint();
+	}
+}
+
+// The system calls this function to obtain the cursor to display while the user drags
+//  the minimized window.
+HCURSOR CRIDBMTReaderDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+
+
+void CRIDBMTReaderDlg::OnBnClickedButtonOpenport()
+{
+	int portno = 0;
+
+	CString strport;
+	GetDlgItem(IDC_COMBO1)->GetWindowText(strport);
+
+	portno = atoi(strport.GetString());
+
+	com.opencom(portno);
+
+	saveConfig("PORT", strport.GetString());
+}
+
+
+void CRIDBMTReaderDlg::addText(string str)
+{
+	m_richedit.SetSel(-1, -1);
+	m_richedit.ReplaceSel((str + string("\r\n")).c_str());
+	m_richedit.PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
+}
+
+
+void CRIDBMTReaderDlg::OnBnClickedButtonCleartrade()
+{
+
+
+	g_stage = 1;
+	sendStageData();
+}
+
+void CRIDBMTReaderDlg::sendStageData()
+{
+	CString szInfo;
+
+	if (g_stage == 0)
+	{
+		return;
+	}
+	else if (g_stage == 1)
+	{
+
+		addText("查询卡状态");
+		szInfo = "020002314103";
+
+	}
+	else if (g_stage == 2)
+	{
+		addText("CPU卡冷复位(上电)");
+		szInfo = "020002374003";
+	}
+	else if (g_stage == 3)
+	{
+		addText("select adf");
+		string apdu = "00A404000E315041592E5359532E444446303100";
+		int len = apdu.size() / 2;
+		char chlen1[3] = { 0 };
+		char chlen2[3] = { 0 };
+		sprintf_s(chlen1, "%.2x", len + 4);
+		sprintf_s(chlen2, "%.2x", len);
+
+		szInfo = "0200" + CString(chlen1) + "374300" + CString(chlen2) + apdu.c_str() + "03";
+		szInfo = szInfo;
+	}
+	else if (g_stage == 4)
+	{
+		addText("select ET1");
+		string apdu = "00a404000ca00000000353494e4f50454300";
+		int len = apdu.size() / 2;
+		char chlen1[3] = { 0 };
+		char chlen2[3] = { 0 };
+		sprintf_s(chlen1, "%.2x", len + 4);
+		sprintf_s(chlen2, "%.2x", len);
+
+		szInfo = "0200" + CString(chlen1) + "374300" + CString(chlen2) + apdu.c_str() + "03";
+		szInfo = szInfo;
+	}
+	else if (g_stage == 5)
+	{
+		addText("读21号文件");
+		string apdu = "00b095001e";
+		int len = apdu.size() / 2;
+		char chlen1[3] = { 0 };
+		char chlen2[3] = { 0 };
+		sprintf_s(chlen1, "%.2x", len + 4);
+		sprintf_s(chlen2, "%.2x", len);
+
+		szInfo = "0200" + CString(chlen1) + "374300" + CString(chlen2) + apdu.c_str() + "03";
+		szInfo = szInfo;
+	}
+	else if (g_stage == 6)
+	{
+		addText("读26号文件");
+		string apdu = "00b09a0029";
+		int len = apdu.size() / 2;
+		char chlen1[3] = { 0 };
+		char chlen2[3] = { 0 };
+		sprintf_s(chlen1, "%.2x", len + 4);
+		sprintf_s(chlen2, "%.2x", len);
+
+		szInfo = "0200" + CString(chlen1) + "374300" + CString(chlen2) + apdu.c_str() + "03";
+		szInfo = szInfo;
+	}
+	else if (g_stage == 7)
+	{
+		addText("verify");
+		string apdu = "0020000002999900";
+		int len = apdu.size() / 2;
+		char chlen1[3] = { 0 };
+		char chlen2[3] = { 0 };
+		sprintf_s(chlen1, "%.2x", len + 4);
+		sprintf_s(chlen2, "%.2x", len);
+
+		szInfo = "0200" + CString(chlen1) + "374300" + CString(chlen2) + apdu.c_str() + "03";
+		szInfo = szInfo;
+	}
+	else if (g_stage == 8)
+	{
+		addText("查询记录个数上限值");
+		string apdu = "80B8000002";
+		int len = apdu.size() / 2;
+		char chlen1[3] = { 0 };
+		char chlen2[3] = { 0 };
+		sprintf_s(chlen1, "%.2x", len + 4);
+		sprintf_s(chlen2, "%.2x", len);
+
+		szInfo = "0200" + CString(chlen1) + "374300" + CString(chlen2) + apdu.c_str() + "03";
+		szInfo = szInfo;
+	}
+	else if (g_stage == 9)
+	{
+		addText("查询未导出记录个数");
+		string apdu = "80B8010002";
+		int len = apdu.size() / 2;
+		char chlen1[3] = { 0 };
+		char chlen2[3] = { 0 };
+		sprintf_s(chlen1, "%.2x", len + 4);
+		sprintf_s(chlen2, "%.2x", len);
+
+		szInfo = "0200" + CString(chlen1) + "374300" + CString(chlen2) + apdu.c_str() + "03";
+		szInfo = szInfo;
+	}
+	else if (g_stage == 10)
+	{
+		addText("清除记录计数器");
+		string apdu = "80BA0100020000";
+		int len = apdu.size() / 2;
+		char chlen1[3] = { 0 };
+		char chlen2[3] = { 0 };
+		sprintf_s(chlen1, "%.2x", len + 4);
+		sprintf_s(chlen2, "%.2x", len);
+
+		szInfo = "0200" + CString(chlen1) + "374300" + CString(chlen2) + apdu.c_str() + "03";
+		szInfo = szInfo;
+	}
+	else if (g_stage == 11)
+	{
+		addText("弹卡");
+		szInfo = "020002324003";
+	}
+
+
+
+
+	g_enq = 0;
+
+
+	BYTE tmpbuf[512] = { 0 };
+	int szlen = szInfo.GetLength();
+	for (int i = 0; i <= szlen / 2; i++)
+	{
+		string str = szInfo.Mid(i * 2, 2);
+
+		tmpbuf[i] = strtol(str.c_str(), NULL, 16);
+	}
+
+	unsigned char xor = XORChecksum(tmpbuf, szlen / 2);
+	char chxor[3];
+	sprintf_s(chxor, "%02x", xor);
+	szInfo += chxor;
+
+
+	BYTE buff[1024];
+	memset(buff, 0, 1024);
+	int sendlen = szInfo.GetLength();
+	for (int i = 0; i < sendlen; ++i)
+	{
+		CString str = szInfo.Mid(i * 2, 2);
+		sscanf_s(str, "%02x", &buff[i]);
+	}
+	com.senddata(buff, sendlen / 2);
+}
+
+
+
+void CRIDBMTReaderDlg::OnBnClickedButtonPopcard()
+{
+
+
+	CString szInfo;
+
+
+	addText("弹卡");
+	szInfo = "020002324003";
+
+	g_enq = 0;
+
+
+	BYTE tmpbuf[512] = { 0 };
+	int szlen = szInfo.GetLength();
+	for (int i = 0; i <= szlen / 2; i++)
+	{
+		string str = szInfo.Mid(i * 2, 2);
+
+		tmpbuf[i] = strtol(str.c_str(), NULL, 16);
+	}
+
+	unsigned char xor = XORChecksum(tmpbuf, szlen / 2);
+	char chxor[3];
+	sprintf_s(chxor, "%02x", xor);
+	szInfo += chxor;
+
+
+	BYTE buff[1024];
+	memset(buff, 0, 1024);
+	int sendlen = szInfo.GetLength();
+	for (int i = 0; i < sendlen; ++i)
+	{
+		CString str = szInfo.Mid(i * 2, 2);
+		sscanf_s(str, "%02x", &buff[i]);
+	}
+	com.senddata(buff, sendlen / 2);
+}

+ 47 - 0
RIDBMTReader/RIDBMTReaderDlg.h

@@ -0,0 +1,47 @@
+
+// RIDBMTReaderDlg.h : header file
+//
+
+#pragma once
+#include "afxwin.h"
+#include "global.h"
+#include "ComHandle.h"
+#include "afxcmn.h"
+#include "resource.h"
+
+
+// CRIDBMTReaderDlg dialog
+class CRIDBMTReaderDlg : public CDialogEx
+{
+// Construction
+public:
+	CRIDBMTReaderDlg(CWnd* pParent = NULL);	// standard constructor
+
+// Dialog Data
+	enum { IDD = IDD_RIDBMTREADER_DIALOG };
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
+
+
+// Implementation
+protected:
+	HICON m_hIcon;
+
+	// Generated message map functions
+	virtual BOOL OnInitDialog();
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	DECLARE_MESSAGE_MAP()
+public:
+	CComboBox CB_Port;
+	afx_msg void OnBnClickedButtonOpenport();
+
+	void addText(string str);
+	void sendStageData();
+
+	ComHandle com;
+	afx_msg void OnBnClickedButtonCleartrade();
+	CRichEditCtrl m_richedit;
+	afx_msg void OnBnClickedButtonPopcard();
+};

+ 92 - 0
RIDBMTReader/ReadMe.txt

@@ -0,0 +1,92 @@
+================================================================================
+    MICROSOFT FOUNDATION CLASS LIBRARY : RIDBMTReader Project Overview
+===============================================================================
+
+The application wizard has created this RIDBMTReader application for
+you.  This application not only demonstrates the basics of using the Microsoft
+Foundation Classes but is also a starting point for writing your application.
+
+This file contains a summary of what you will find in each of the files that
+make up your RIDBMTReader application.
+
+RIDBMTReader.vcxproj
+    This is the main project file for VC++ projects generated using an application wizard.
+    It contains information about the version of Visual C++ that generated the file, and
+    information about the platforms, configurations, and project features selected with the
+    application wizard.
+
+RIDBMTReader.vcxproj.filters
+    This is the filters file for VC++ projects generated using an Application Wizard. 
+    It contains information about the association between the files in your project 
+    and the filters. This association is used in the IDE to show grouping of files with
+    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+    "Source Files" filter).
+
+RIDBMTReader.h
+    This is the main header file for the application.  It includes other
+    project specific headers (including Resource.h) and declares the
+    CRIDBMTReaderApp application class.
+
+RIDBMTReader.cpp
+    This is the main application source file that contains the application
+    class CRIDBMTReaderApp.
+
+RIDBMTReader.rc
+    This is a listing of all of the Microsoft Windows resources that the
+    program uses.  It includes the icons, bitmaps, and cursors that are stored
+    in the RES subdirectory.  This file can be directly edited in Microsoft
+    Visual C++. Your project resources are in 1033.
+
+res\RIDBMTReader.ico
+    This is an icon file, which is used as the application's icon.  This
+    icon is included by the main resource file RIDBMTReader.rc.
+
+res\RIDBMTReader.rc2
+    This file contains resources that are not edited by Microsoft
+    Visual C++. You should place all resources not editable by
+    the resource editor in this file.
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+The application wizard creates one dialog class:
+
+RIDBMTReaderDlg.h, RIDBMTReaderDlg.cpp - the dialog
+    These files contain your CRIDBMTReaderDlg class.  This class defines
+    the behavior of your application's main dialog.  The dialog's template is
+    in RIDBMTReader.rc, which can be edited in Microsoft Visual C++.
+
+/////////////////////////////////////////////////////////////////////////////
+
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+    These files are used to build a precompiled header (PCH) file
+    named RIDBMTReader.pch and a precompiled types file named StdAfx.obj.
+
+Resource.h
+    This is the standard header file, which defines new resource IDs.
+    Microsoft Visual C++ reads and updates this file.
+
+RIDBMTReader.manifest
+	Application manifest files are used by Windows XP to describe an applications
+	dependency on specific versions of Side-by-Side assemblies. The loader uses this
+	information to load the appropriate assembly from the assembly cache or private
+	from the application. The Application manifest  maybe included for redistribution
+	as an external .manifest file that is installed in the same folder as the application
+	executable or it may be included in the executable in the form of a resource.
+/////////////////////////////////////////////////////////////////////////////
+
+Other notes:
+
+The application wizard uses "TODO:" to indicate parts of the source code you
+should add to or customize.
+
+If your application uses MFC in a shared DLL, you will need
+to redistribute the MFC DLLs. If your application is in a language
+other than the operating system's locale, you will also have to
+redistribute the corresponding localized resources mfc110XXX.DLL.
+For more information on both of these topics, please see the section on
+redistributing Visual C++ applications in MSDN documentation.
+
+/////////////////////////////////////////////////////////////////////////////

+ 9 - 0
RIDBMTReader/Release/RIDBMTReader.log

@@ -0,0 +1,9 @@
+  ComHandle.cpp
+ComHandle.cpp(111): warning C4018: '<' : signed/unsigned mismatch
+ComHandle.cpp(156): warning C4018: '>' : signed/unsigned mismatch
+ComHandle.cpp(160): warning C4018: '<' : signed/unsigned mismatch
+ComHandle.cpp(187): warning C4018: '<' : signed/unsigned mismatch
+ComHandle.cpp(495): warning C4018: '<' : signed/unsigned mismatch
+  Generating code
+  Finished generating code
+  RIDBMTReader.vcxproj -> C:\Bitbucket\RIDBMTReader\Bin\RIDBMTReader.exe

BIN
RIDBMTReader/Release/RIDBMTReader.tlog/CL.read.1.tlog


BIN
RIDBMTReader/Release/RIDBMTReader.tlog/CL.write.1.tlog


+ 2 - 0
RIDBMTReader/Release/RIDBMTReader.tlog/RIDBMTReader.lastbuildstate

@@ -0,0 +1,2 @@
+#TargetFrameworkVersion=v4.0:PlatformToolSet=v120_xp:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit
+Release|Win32|C:\Bitbucket\RIDBMTReader\|

BIN
RIDBMTReader/Release/RIDBMTReader.tlog/cl.command.1.tlog


BIN
RIDBMTReader/Release/RIDBMTReader.tlog/link.command.1.tlog


BIN
RIDBMTReader/Release/RIDBMTReader.tlog/link.read.1.tlog


BIN
RIDBMTReader/Release/RIDBMTReader.tlog/link.write.1.tlog


BIN
RIDBMTReader/Release/RIDBMTReader.tlog/rc.command.1.tlog


BIN
RIDBMTReader/Release/RIDBMTReader.tlog/rc.read.1.tlog


BIN
RIDBMTReader/Release/RIDBMTReader.tlog/rc.write.1.tlog


+ 2 - 0
RIDBMTReader/conn.ini

@@ -0,0 +1,2 @@
+[Config]
+PORT=5

+ 133 - 0
RIDBMTReader/global.cpp

@@ -0,0 +1,133 @@
+#include "stdafx.h"
+
+#include "global.h"
+
+
+
+
+int g_stage = 0;
+DWORD g_tick;
+int g_enq = 0;//0-等回应(ACK)1-请求应答(ENQ)
+
+
+
+#define CONAPPNAME "Config"
+#define CONPATH ".\\conn.ini"
+
+string getConfig(string key)
+{
+	char ch[100] = { 0 };
+	GetPrivateProfileString(CONAPPNAME, key.c_str(), "", ch, 100, CONPATH);
+	string val = ch;
+	return val;
+}
+int getConfig_INT(string key)
+{
+	char ch[100] = { 0 };
+	GetPrivateProfileString(CONAPPNAME, key.c_str(), "", ch, 100, CONPATH);
+	return atoi(ch);
+}
+
+void saveConfig(string key, string val)
+{
+	WritePrivateProfileString(CONAPPNAME, key.c_str(), val.c_str(), CONPATH);
+}
+void saveConfig(string key, int val)
+{
+	WritePrivateProfileString(CONAPPNAME, key.c_str(), std::to_string(val).c_str(), CONPATH);
+}
+
+void saveConfig(string key, double val)
+{
+	char ch[50] = { 0 };
+	sprintf_s(ch, "%.2f", val);
+	WritePrivateProfileString(CONAPPNAME, key.c_str(), ch, CONPATH);
+}
+
+/*
+WORD calccrc(BYTE crcbuf, WORD crc, WORD polynom)
+{
+	BYTE i;
+	crc = crc ^ crcbuf;
+	for (i = 0; i<8; i++) {
+		BYTE chk;
+		chk = crc & 1;
+		crc = crc >> 1;
+		crc = crc & 0x7fff;
+		if (chk == 1)
+			crc = crc^polynom;
+		crc = crc & 0xffff;
+	}
+	return crc;
+}
+
+
+//注意modbus算出来高低位要调转
+WORD chkcrc_modbus(BYTE *buf, WORD len, WORD polynom)
+{
+	WORD i;
+	WORD crc;
+	crc = 0xffff;
+	for (i = 0; i<len; i++) {
+		crc = calccrc(*buf, crc, polynom);
+		buf++;
+	}
+	return crc;
+}
+*/
+std::string getCurrentDate()
+{
+	CTime tm = CTime::GetCurrentTime();
+
+
+	char time[30] = { 0 };
+	sprintf_s(time, "%04d%02d%02d", tm.GetYear(), tm.GetMonth(), tm.GetDay());
+
+	std::string str = time;
+	return str;
+}
+
+std::string getCurrentTime()
+{
+	CTime tm = CTime::GetCurrentTime();
+
+
+	char time[30] = { 0 };
+	sprintf_s(time, "%04d%02d%02d%02d%02d%02d", tm.GetYear(), tm.GetMonth(), tm.GetDay(), tm.GetHour(), tm.GetMinute(), tm.GetSecond());
+
+	std::string str = time;
+	return str;
+}
+
+
+std::string getCurrentTime_Short()
+{
+	CTime tm = CTime::GetCurrentTime();
+
+
+	char time[30] = { 0 };
+	sprintf_s(time, "%02d:%02d:%02d",  tm.GetHour(), tm.GetMinute(), tm.GetSecond());
+
+	std::string str = time;
+	return str;
+}
+
+
+// 计算异或校验
+unsigned char XORChecksum(unsigned char bytes[], int len)
+{
+	unsigned char rtn = 0;
+	if (len < 2)
+	{
+		return rtn;
+	}
+
+	rtn = bytes[0];
+
+	for (int i = 1; i < len; i++)
+	{
+		rtn ^= bytes[i];
+	}
+
+	return rtn;
+}

+ 62 - 0
RIDBMTReader/global.h

@@ -0,0 +1,62 @@
+#pragma once
+
+
+
+#include <string>
+using std::string;
+
+extern int g_stage;
+extern DWORD g_tick;
+extern int g_enq;
+
+string getConfig(string key);
+int getConfig_INT(string key);
+
+void saveConfig(string key, string val);
+void saveConfig(string key, int val);
+void saveConfig(string key, double val);
+
+//WORD calccrc(BYTE crcbuf, WORD crc, WORD polynom);
+
+//WORD chkcrc_modbus(BYTE *buf, WORD len, WORD polynom);
+
+std::string getCurrentDate();
+std::string getCurrentTime();
+std::string getCurrentTime_Short();
+
+WORD calccrc(BYTE crcbuf, WORD crc);
+WORD chkcrc(BYTE *buf, WORD len);
+
+
+template <class T>
+void numberToBuffer(T  number, int len, unsigned char * buf, bool isReversed = false)
+{
+	if (isReversed)
+	{
+		for (int i = 0; i<len; i++)
+			*((unsigned char *)(buf + len - i - 1)) = (unsigned char)(number / (T)pow(256.0, len - i - 1)) % 256L;
+	}
+	else
+	{
+		for (int i = 0; i<len; i++)
+			*((unsigned char *)(buf + i)) = (unsigned char)(number / (T)pow(256.0, len - i - 1)) % 256L;
+	}
+}
+
+template <class T>
+void bufferToNumber(const unsigned char * buf, int len, T & number, bool isReversed = false)
+{
+	number = 0;
+	if (isReversed)
+	{
+		for (int i = 0; i<len; i++)
+			number += *((unsigned char *)(buf + i)) * (T)pow(256.0, i);
+	}
+	else
+	{
+		for (int i = 0; i<len; i++)
+			number += *((unsigned char *)(buf + i)) * (T)pow(256.0, len - i - 1);
+	}
+}
+
+unsigned char XORChecksum(unsigned char bytes[], int len);

BIN
RIDBMTReader/res/RIDBMTReader.ico


BIN
RIDBMTReader/res/RIDBMTReader.rc2


BIN
RIDBMTReader/resource.h


+ 8 - 0
RIDBMTReader/stdafx.cpp

@@ -0,0 +1,8 @@
+
+// stdafx.cpp : source file that includes just the standard includes
+// RIDBMTReader.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+

+ 53 - 0
RIDBMTReader/stdafx.h

@@ -0,0 +1,53 @@
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // Exclude rarely-used stuff from Windows headers
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h>         // MFC core and standard components
+#include <afxext.h>         // MFC extensions
+
+
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // MFC support for Internet Explorer 4 Common Controls
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>             // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxcontrolbars.h>     // MFC support for ribbons and control bars
+
+
+
+
+
+
+
+
+
+#ifdef _UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif
+
+

+ 8 - 0
RIDBMTReader/targetver.h

@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>

+ 306 - 0
RIDBMTReader/tools.cpp

@@ -0,0 +1,306 @@
+#include "stdafx.h"
+
+#include "tools.h"
+
+
+const unsigned short crc_16_tab[] = {
+
+	0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
+
+	0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
+
+	0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
+
+	0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
+
+	0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
+
+	0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
+
+	0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
+
+	0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
+
+	0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+
+	0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
+
+	0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
+
+	0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
+
+	0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
+
+	0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
+
+	0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
+
+	0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
+
+	0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
+
+	0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+
+	0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
+
+	0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
+
+	0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
+
+	0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
+
+	0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
+
+	0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
+
+	0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
+
+	0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
+
+	0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+
+	0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
+
+	0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
+
+	0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
+
+	0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
+
+	0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
+
+};
+
+/* Generate GetCRC */
+unsigned short GetCRC(unsigned char *p, unsigned short n)
+{
+	unsigned char        ch;
+	unsigned short        i;
+	unsigned short        crc = 0x0000;
+
+	crc = 1;
+
+	for (i = 0; i < n; i++) {
+		ch = *p++;
+		crc = (unsigned short)(crc_16_tab[(ch^crc) & 0xff] ^ (crc >> 8));
+		//  crc = calc_crc(crc,(unsigned short)ch); 
+	}
+
+	crc = crc & 0x7f7f;
+
+	return crc;
+}
+
+unsigned short GetCRC2(unsigned char *p, unsigned short n)
+{
+	unsigned char        ch;
+	unsigned short        i;
+	unsigned short        crc = 0x0000;
+
+	for (i = 0; i < n; i++) {
+		ch = *p++;
+		crc = (unsigned short)(crc_16_tab[(ch^crc) & 0xff] ^ (crc >> 8));
+		//  crc = calc_crc(crc,(unsigned short)ch); 
+	}
+
+	return crc;
+}
+
+WORD calccrc(BYTE crcbuf, WORD crc)
+{
+	BYTE i;
+	crc = crc ^ crcbuf;
+	for (i = 0; i<8; i++) {
+		BYTE chk;
+		chk = crc & 1;
+		crc = crc >> 1;
+		crc = crc & 0x7fff;
+		if (chk == 1)
+			crc = crc ^ 0xa001;/* CRC polynom=0xa001 */
+		crc = crc & 0xffff;
+	}
+	return crc;
+}
+WORD calccrc(BYTE crcbuf, WORD crc, WORD polynom)
+{
+	BYTE i;
+	crc = crc ^ crcbuf;
+	for (i = 0; i<8; i++) {
+		BYTE chk;
+		chk = crc & 1;
+		crc = crc >> 1;
+		crc = crc & 0x7fff;
+		if (chk == 1)
+			crc = crc^polynom;
+		crc = crc & 0xffff;
+	}
+	return crc;
+}
+WORD chkcrc(BYTE *buf, WORD len)
+{
+	//BYTE hi,lo;
+	WORD i;
+	WORD crc;
+	crc = 0x0000;/* Initial crc value=0x0000 */
+	for (i = 0; i<len; i++) {
+		crc = calccrc(*buf, crc);
+		buf++;
+	}
+	//hi=crc%256;
+	//lo=crc/256;
+	//crc=((hi+0x0000)<<8)|lo;
+	return crc;
+}
+WORD chkcrc(BYTE *buf, WORD len, WORD polynom)
+{
+	WORD i;
+	WORD crc;
+	crc = 0x0000;
+	for (i = 0; i<len; i++) {
+		crc = calccrc(*buf, crc, polynom);
+		buf++;
+	}
+	return crc;
+}
+void crc_calc_sinopec(BYTE *ptr_buffer, WORD length)
+{
+	WORD crc_result;
+
+	/* calculate CRC */
+	crc_result = chkcrc(ptr_buffer, length);
+	/* ... and store it */
+	ptr_buffer[length] = (BYTE)(crc_result >> 8);;
+	ptr_buffer[length + 1] = (BYTE)crc_result;
+
+}
+
+
+//中石化协议 检查发送数据包的有效数据和CRC中的转义字符ch,每一个替换为两个
+bool transEscapeCharacter(BYTE buf[DIT_BUFSIZE], int& len, BYTE ch)
+{
+	bool ischeck = FALSE;
+	BYTE tmpData[DIT_BUFSIZE];
+	memset(tmpData, 0, DIT_BUFSIZE);
+	tmpData[0] = buf[0];
+
+	for (int i = 0, j = 0; j< DIT_BUFSIZE - 1; i++, j++)
+	{
+		if (i > 0)
+		{
+			if (buf[i] == ch)
+			{
+				tmpData[j] = ch;
+				tmpData[j + 1] = ch;
+				j++;
+				len++;
+				ischeck = true;
+			}
+			else
+			{
+				tmpData[j] = buf[i];
+			}
+		}
+	}
+	memcpy(buf, tmpData, DIT_BUFSIZE);
+	return ischeck;
+}
+
+
+//例如base=2,times=3,结果返回2的3次方
+unsigned long power(int base, int times)
+{
+	int i;
+	unsigned long rslt = 1;
+
+	for (i = 0; i<times; i++)
+		rslt *= base;
+
+	return rslt;
+}
+
+//bcd--存放BCD码的缓冲(高位在前如0x12 0x34 表示十进制数值1234)
+//len--bcd的字节长度
+//radix--
+//返回转换后的十进制数值
+//如:bcd = 0x12 0x34,则返回值为 1234
+unsigned long BCDtoDec(unsigned char *bcd, int len)
+{
+	int i, tmp;
+	unsigned long dec = 0;
+
+	for (i = 0; i<len; i++)
+	{
+		tmp = ((bcd[i] >> 4) & 0x0f) * 10 + (bcd[i] & 0x0f);
+		dec += tmp * power(100, len - 1 - i);
+	}
+
+	return dec;
+}
+
+
+//Dec--十进制数值
+//bcd--存放BCD码的缓冲(高位在前如0x12 0x34 表示十进制数值1234),得到的BCD码右对齐左补0
+//len--bcd的字节长度
+//返回0--成功
+//缓冲长度必须足够大,否则数字高位将被丢失
+////如:Dec = 1234, 则运行结束后bcd的最后两个字节 = 0x12 0x34(可能为0x00 0x00 ... 0x12 0x34 )
+int DectoBCD(int Dec, unsigned char *bcd, int len)
+{
+	int i, tmp;
+	for (i = 0; i<len; i++)
+	{
+		tmp = Dec % 100;
+		bcd[len - i - 1] = ((tmp / 10) << 4) + ((tmp % 10) & 0x0f);
+		Dec /= 100;
+	}
+
+	return 0;
+}
+
+//中石化协议 检查收到数据包的有效数据和CRC中的转义字符ch,每两个替换为一个
+bool checkEscapeCharacter(BYTE buf[1024], int& len, BYTE ch)
+{
+	bool ischeck = FALSE;
+	BYTE tmpData[1024];
+	memset(tmpData, 0, 1024);
+
+	for (int i = 0, j = 0; i< 1024; i++, j++)
+	{
+		if (i < 1024 - 1 && buf[i] == ch && buf[i + 1] == ch)
+		{
+			tmpData[j] = ch;
+			i += 1;
+			len--;
+			ischeck = TRUE;
+		}
+		else
+		{
+			tmpData[j] = buf[i];
+		}
+	}
+	memcpy(buf, tmpData, 1024);
+	return ischeck;
+}
+
+extern bool calcEscapeLength(const BYTE buf[DIT_BUFSIZE], int& len, BYTE ch)
+{
+	bool ischeck = FALSE;
+	//BYTE tmpData[1024];
+	//memset(tmpData, 0, 1024);
+
+	for (int i = 0, j = 0; i< 1024; i++, j++)
+	{
+		if (i < 1024 - 1 && buf[i] == ch && buf[i + 1] == ch)
+		{
+			//tmpData[j] = ch;
+			i += 1;
+			len--;
+			ischeck = TRUE;
+		}
+		else
+		{
+			//tmpData[j] = buf[i];
+		}
+	}
+	return ischeck;
+}

+ 26 - 0
RIDBMTReader/tools.h

@@ -0,0 +1,26 @@
+#pragma once
+
+
+#define DIT_BUFSIZE 1024
+
+
+
+
+
+extern unsigned short GetCRC(unsigned char *p, unsigned short n);
+extern unsigned short GetCRC2(unsigned char *p, unsigned short n);
+extern WORD calccrc(BYTE crcbuf, WORD crc);
+extern WORD calccrc(BYTE crcbuf, WORD crc, WORD polynom);
+extern WORD chkcrc(BYTE *buf, WORD len);
+extern WORD chkcrc(BYTE *buf, WORD len, WORD polynom);
+extern void crc_calc_sinopec(BYTE *ptr_buffer, WORD length);
+
+
+extern unsigned long power(int base, int times);
+extern unsigned long BCDtoDec(unsigned char *bcd, int len);
+extern int DectoBCD(int Dec, unsigned char *bcd, int len);
+
+extern bool checkEscapeCharacter(BYTE buf[DIT_BUFSIZE], int& len, BYTE ch);
+extern bool transEscapeCharacter(BYTE buf[DIT_BUFSIZE], int& len, BYTE ch);
+
+extern bool calcEscapeLength(const BYTE buf[DIT_BUFSIZE], int& len, BYTE ch);

+ 6 - 0
clear.bat

@@ -0,0 +1,6 @@
+@echo off
+rem 正在搜索...
+rem 删除文件
+for /f "delims=" %%i in ('dir /b /a-d /s "*.sdf" "*.ipch" "*.obj" "*.pdb" "*.pch" "*.ilk" "*.idb" "*.ncb" "*.res" "*.bsc" "*.sbr" "*.aps"') do del %%i
+rem 删除完毕
+pause

+ 0 - 0
文档/MT318-118、119-V1.4通讯协议.doc


+ 22 - 0
文档/指令参考.txt

@@ -0,0 +1,22 @@
+功能指令参考
+//reset
+3B6D000086014844524944230101000611
+
+//Select ADF                  
+00A404000C A00000000353494E4F504543
+61XX【XX值不用管】
+
+//Verify                               
+0020000002 9999
+9000
+
+//查询记录个数上限值
+80B8000002
+
+//查询未导出记录个数
+80B8010002
+
+//清记录计数器
+//80 BA 01 00 02 00 00
+
+

+ 58 - 0
文档/新文件 4.txt

@@ -0,0 +1,58 @@
+旧软件通讯跟踪
+
+1、
+02 00 02 37 40 03 74
+06
+05
+新卡这一步回复4e失败。02 00 03 37 40 4e 03 3b 
+
+2、
+02 00 18 37 43 00 14 00 A4 04 00 0E 31 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00 03 B0
+
+如果是新卡则是这步提示应用选择出错。
+
+3
+02 00 09 37 43 00 05 00 B2 01 0C 00 03 C6
+
+
+4
+02 00 09 37 43 00 05 00 B2 02 0C 00 03 C5
+
+
+5
+02 00 09 37 43 00 05 00 B2 03 0C 00 03 C4
+
+6
+02 00 09 37 43 00 05 00 B2 04 0C 00 03 C3
+
+
+7
+02 00 16 37 43 00 12 00 A4 00 0C A0 00 00 00 03 53 49 4E 4F 50 45 43 00 03 33
+
+8
+02 00 09 37 43 00 05 00 B0 95 00 1E 03 42
+
+9
+02 00 09 37 43 00 05 00 B0 9A 00 29 03 7A
+
+10
+02 00 0C 37 43 00 08 00 20 00 00 02 99 99 00 03 53
+
+
+11
+02 00 09 37 43 00 05 80 B8 00 00 02 03 43
+
+
+12
+02 00 09 37 43 00 05 80 B8 01 00 02 03 42
+
+
+13
+02 00 02 32 40 03 71
+
+
+
+
+
+
+

+ 73 - 0
文档/调试问题.txt

@@ -0,0 +1,73 @@
+
+旧卡问题(新卡该指令同样的问题)
+一、查询卡机版本失败
+收到数据:02 00 10 31 40 4d 54 33 31 38 2d 31 31 38 20 56 34 2e 31 30 03 3b 
+收到数据总长度超出
+
+二、
+打开串口5成功
+CPU卡冷复位(上电)
+ 发送:02 00 02 37 40 03 74 
+收到数据:06 
+ 发送:05 
+收到数据:02 
+收到数据:00 16 37 40 59 00 11 3b 6d 00 
+收到数据:00 86 01 20 11 06 28 00 00 01 86 00 00 
+收到数据:01 03 60 
+收到数据 合并:02 00 16 37 40 59 00 11 3b 6d 00 00 86 01 20 11 06 28 00 00 01 86 00 00 01 03 60 
+收到CPU卡冷复位回复
+复位成功
+reset
+ 发送:02 00 15 37 43 00 11 3b 6d 00 00 86 01 48 44 52 49 44 23 01 01 00 06 11 03 c7 
+收到数据:06 
+ 发送:05 
+收到数据:02 00 03 37 43 4e 03 38 
+收到数据 合并:02 00 03 37 43 4e 03 38 
+收到reset回复
+操作不成功
+操作失败
+
+
+三、跳过reset
+select adf
+ 发送:02 00 17 37 43 00 13 00 a4 04 00 0c a0 00 00 00 03 53 49 4e 4f 50 45 43 61 00 03 52 
+收到数据:06 
+ 发送:05 
+收到数据:02 00 03 37 43 4e 03 38 
+收到数据 合并:02 00 03 37 43 4e 03 38 
+收到select adf回复
+操作不成功
+操作失败
+
+四
+verify
+ 发送:02 00 0d 37 43 00 09 00 20 00 00 02 99 99 90 00 03 c3 
+收到数据:06 
+ 发送:05 
+收到数据:02 00 03 37 43 4e 03 38 
+收到数据 合并:02 00 03 37 43 4e 03 38 
+收到verify回复
+操作不成功
+操作失败
+
+
+
+新卡问题
+打开串口5成功
+弹卡
+ 发送:02 00 02 32 40 03 71 
+收到数据:06 
+ 发送:05 
+收到数据:02 
+收到数据:00 03 32 40 30 03 40 
+收到数据 合并:02 00 03 32 40 30 03 40 
+CPU卡冷复位(上电)
+ 发送:02 00 02 37 40 03 74 
+收到数据:06 
+ 发送:05 
+收到数据:02 
+收到数据:00 03 37 40 4e 03 3b 
+收到数据 合并:02 00 03 37 40 4e 03 3b 
+收到CPU卡冷复位回复
+复位不成功
+操作失败

+ 193 - 0
文档/铭特加油测试记录清除工具.docx

@@ -0,0 +1,193 @@
+清记录流程:
+
+1、查询卡状态1
+Host发送: 
+0x02 
+0x00 
+0x02 
+0x31 
+0x41 
+0x03 
+BCC 
+Reader返回 
+0x02 
+0x00 
+0x06 
+0x31 
+0x41 
+状态字S1
+状态字S2
+状态字S3
+状态字S4
+0x03
+BCC 
+  S1卡座状态=0x30表示有卡,0x31表示无卡。 
+  S2:卡类型
+      S2=0x30 卡机内无卡
+      S2=0x3f 无法识别
+S2=0x31 触点cpu卡
+S2=0x32 RF-- TYPE B CPU卡
+S2=0x33 RF -- TYPE A CPU卡
+S2=0x34 RF -- M1卡
+S2=0x35 AT88SC1608卡
+S2=0x36 SLE4442卡
+  S3:卡状态
+      S3=0x30 下电状态
+      S3=0x31 休眠状态
+S3=0x32 激活状态
+S3=0x33 忙态(通信状态)
+  S4:供电状态
+      S4=0x30 供电正常
+      S4=0x31 掉电
+
+
+2、CPU卡冷复位 (上电)
+
+ HOST发送: 
+0x02 
+0x00 
+0x02 
+0x37 
+0X40 
+0x03 
+BCC 
+
+Reader操作成功返回: T=0 CPU卡复位成功返回操作状态字P=`Y'(0x59) 
+0x02 
+通讯包长度2 byte 
+0x37 
+0x40 
+操作状态字P
+复位数据包长度2 byte
+复位数据n byte 
+0x03
+BCC 
+
+通讯包长度=5+ 复位数据长度n 
+Reader操作成功返回: T=1 CPU卡复位成功返回操作状态字P=`Z'(0X5A) 
+0x02 
+通讯包长度2 byte 
+0x37 
+0x40 
+操作状态字P
+复位数据包长度2 byte
+复位数据n byte 
+0x03
+BCC 
+
+通讯包长度=5+ 复位数据长度n 
+Reader操作失败返回: 
+0x02 
+0x00 
+0x03 
+0x37 
+0x40 
+操作状态字P
+0x03
+BCC
+
+  操作状态字 P=`N'(0x4E) 复位不成功 
+     P=`E'(0x45) 卡机无卡 
+     P=`W'(0x57) 卡不在允许操作的位置上。 
+
+
+
+C-APDU命令操作(3-10)
+
+HOST发送: 
+0x02 
+通讯包长度2 byte 
+0x37 
+0x43 
+C-APDU包长度2 byte
+C-APDU包 n byte
+0x03 
+BCC 
+
+  通讯包长度=4+ C-APDU包长度n (n最大值为262byte) 
+Reader操作成功返回: 操作状态字P=`Y'(0x59) 
+0x02 
+通讯包长度2 byte 
+0x37 
+0x43 
+操作状态字P
+C-APDU操作返回包
+长度2 byte 
+C-APDU操作 
+返回包 n byte 
+0x03 
+BCC 
+
+通讯包长度=5+ C-APDU返回包长度n (n最大值257byte) 
+Reader操作失败返回: 
+0x02 
+0x00 
+0x03 
+0x37 
+0x43 
+操作状态字P
+0x03
+BCC
+
+  操作状态字 P=`N'(0x4E) 操作不成功 
+P=`E'(0x45) 卡机无卡 
+     P=`W'(0x57) 卡不在允许操作的位置上。 
+
+
+
+功能指令参考
+
+3、Select ADF                  
+00A404000E315041592E5359532E444446303100
+
+4 APDU 选择应用ET1
+00a404000ca00000000353494e4f50454300
+
+5 :读RID卡21号文件
+00b095001e
+
+6:读RID卡26号文件
+00b09a0029
+
+
+7、Verify                               
+0020000002999900
+
+
+
+8、查询记录个数上限值
+80B8000002
+
+
+9查询未导出记录个数
+80B8010002
+
+
+10清记录计数器
+//80 BA 01 00 02 00 00
+
+11、弹卡
+
+Host发送: 
+0x02 
+0x00 
+0x02 
+0x32 
+0x40 
+0x03 
+BCC 
+Reader返回 
+0x02 
+0x00 
+0x03 
+0x32 
+0x40 
+状态字S1
+0x03
+BCC 
+  执行弹卡动作,并返回状态。
+  S1卡座状态=0x30表示弹卡成功,0x31表示弹卡失败。 
+
+
+
+