using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.IO.Ports;
using System.Threading;
namespace ReadCardWince
{
class ICCard
{
public delegate void DataReadEvent();
public event DataReadEvent HaveReadData;
public delegate void DataWriteEvent();
public event DataWriteEvent HaveWriteData;
private ManualResetEvent threadOvered = new ManualResetEvent(true);
private ManualResetEvent portDataGet = new ManualResetEvent(true);
SerialPort sp = new SerialPort();
private int iMutex;
private byte[] dtResvice;
private bool bDataSuc;
private int ipos;
private byte[] dtReadCard = new byte[4];
private byte[] dtWriteCard = new byte[4];
public byte[] dtData = new byte[16];
public byte[] iddtData = new byte[3];
public byte[] pwddtData = new byte[3];
public bool DataSuc
{
get { return bDataSuc; }
}
public string sData
{
get
{
string ret = String.Empty;
for (int i = 0; i < dtData.Length; i++)
{
ret += String.Format("{0:X2} ", dtData[i]);
}
return ret;
}
}
public string idsData
{
get
{
string idret = string.Empty;
for (int i = 0; i < iddtData.Length; i++)
{
idret += String.Format("{0:X2} ", iddtData[i]);
}
return idret;
}
}
public string pwdsData
{
get
{
string pwdret = String.Empty;
for (int i = 0; i < pwddtData.Length; i++)
{
pwdret += String.Format("{0:X2}", pwddtData[i]);
//pwdret += pwddtData[i];
}
return pwdret;
}
}
public ICCard(string sIOPort, int br)
{
sp.PortName = sIOPort;
sp.BaudRate = br;
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
sp.WriteTimeout = 1000;
sp.ReadTimeout = 1000;
bDataSuc = false;
iMutex = 0;
dtResvice = new byte[50];
}
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//throw new Exception("The method or operation is not implemented.");
DataGet();
sp.DiscardInBuffer();
}
private void DataGet()
{
byte verify;
byte[] inputData = new byte[20];
while (sp.BytesToRead > 0)
{
inputData[0] = (byte)sp.ReadByte();//.Read(inputData, 0,serialPort1.ReadBufferSize+1);
//for (int i = 0; i < serialPort1.ReadBufferSize; i++)
//{
dtResvice[ipos++] = inputData[0];
//}
}
if (ipos > 0)
{
if (dtResvice[ipos - 1] == 0x0d)
{
verify = dtResvice[0];
for (int i = 1; i < ipos - 2; i++)
{
verify = (byte)(verify ^ dtResvice[i]);
}
if (verify == dtResvice[ipos - 2])
{
portDataGet.Set();
}
}
}
}
public bool IsOpen
{
get { return sp.IsOpen; }
}
public void Open()
{
if (sp.IsOpen) return;
try
{ sp.Open(); }
catch
{ throw new Exception("Port Not Open"); }
}
public void Close()
{
int i = Environment.TickCount;
//while (Environment.TickCount - i < 2000 && sp.IsOpen)
Application.DoEvents();
sp.Close();//现在没有死锁了,关闭串口
}
public void ReadData()
{
if (sp.IsOpen == false) throw new Exception("Port Not Open");
if (iMutex > 0) return;
iMutex++;
threadOvered.Reset();
WaitCallback waitCallback = new WaitCallback(PortReadThread);
ThreadPool.QueueUserWorkItem(waitCallback);
}
public void WriteData()
{
if (sp.IsOpen == false) throw new Exception("Port Not Open");
if (iMutex > 0) return;
iMutex++;
threadOvered.Reset();
WaitCallback waitCallback = new WaitCallback(PortWriteThread);
ThreadPool.QueueUserWorkItem(waitCallback);
}
//读卡线程
private void PortReadThread(object state)
{
byte[] bSend = null;
byte verify;
Array.Clear(dtResvice, 0, dtResvice.Length);
//关卡
bSend = new byte[8] { 0x3c, 0x04, 0x01, 0x68, 0x00, 0x00, 0x51, 0x0d };
verify = bSend[0];
for (int i = 1; i < bSend.Length - 2; i++)
{
verify = (byte)(verify ^ bSend[i]);
}
bSend[bSend.Length - 2] = verify;
ipos = 0;
portDataGet.Reset();
sp.Write(bSend, 0, bSend.Length);
portDataGet.WaitOne();
Thread.Sleep(50);
Close();
Open();
//寻卡
Array.Clear(dtResvice, 0, dtResvice.Length);
bSend = new byte[8] { 0x3c, 0x04, 0x01, 0x70, 0x01, 0x00, 0x00, 0x0d };
verify = bSend[0];
for (int i = 1; i < bSend.Length - 2; i++)
{
verify = (byte)(verify ^ bSend[i]);
}
bSend[bSend.Length - 2] = verify;
ipos = 0;
portDataGet.Reset();
sp.Write(bSend, 0, bSend.Length);
portDataGet.WaitOne();
Thread.Sleep(100);
verify = dtResvice[0];
for (int i = 1; i < ipos - 2; i++)
{
verify = (byte)(verify ^ dtResvice[i]);
}
if (verify == dtResvice[ipos - 2] && dtResvice[ipos - 1] == 0x0d)
{
if (dtResvice[0] == 0x3c)
if (dtResvice[1] == 0x05)
{
dtReadCard[0] = dtResvice[2];
dtReadCard[1] = dtResvice[3];
dtReadCard[2] = dtResvice[4];
dtReadCard[3] = dtResvice[5];
}
else
{
iMutex--;
threadOvered.Set();
return;
}
}
else
{
iMutex--;
threadOvered.Set();
return;
}
Thread.Sleep(50);
Close();
Open();
Array.Clear(dtResvice, 0, dtResvice.Length);
//密码验证 3C 08 01 6A 00 01 四字节卡号 BCC 0D 密码认证
bSend = new byte[12] { 0x3c, 0x08, 0x01, 0x6a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d };
bSend[6] = dtReadCard[0];
bSend[7] = dtReadCard[1];
bSend[8] = dtReadCard[2];
bSend[9] = dtReadCard[3];
verify = bSend[0];
for (int i = 1; i < bSend.Length - 2; i++)
{
verify = (byte)(verify ^ bSend[i]);
}
bSend[bSend.Length - 2] = verify;
ipos = 0;
portDataGet.Reset();
sp.Write(bSend, 0, bSend.Length);
portDataGet.WaitOne();
verify = dtResvice[0];
for (int i = 1; i < ipos - 2; i++)
{
verify = (byte)(verify ^ dtResvice[i]);
}
if (verify == dtResvice[ipos - 2] && dtResvice[ipos - 1] == 0x0d)
{
if (dtResvice[0] == 0x3c)
if (dtResvice[1] != 0x02)
{
iMutex--;
threadOvered.Set();
return;
}
}
else
{
iMutex--;
threadOvered.Set();
return;
}
Thread.Sleep(50);
Close();
Open();
Array.Clear(dtResvice, 0, dtResvice.Length);
//读取数据 3C 04 01 66 01 00 BCC 0D读卡(返回前三个字节为个人密码)
bSend = new byte[8] { 0x3c, 0x04, 0x01, 0x66, 0x04, 0x00, 0x00, 0x0d };
verify = bSend[0];
for (int i = 1; i < bSend.Length - 2; i++)
{
verify = (byte)(verify ^ bSend[i]);
}
bSend[bSend.Length - 2] = verify;
ipos = 0;
portDataGet.Reset();
sp.Write(bSend, 0, bSend.Length);
portDataGet.WaitOne();
verify = dtResvice[0];
for (int i = 1; i < ipos - 2; i++)
{
verify = (byte)(verify ^ dtResvice[i]);
}
if (verify == dtResvice[ipos - 2] && dtResvice[ipos - 1] == 0x0d)
{
if (dtResvice[0] == 0x3c)
if (dtResvice[1] == 0x12)
{
Buffer.BlockCopy(dtResvice, 3, dtData, 0, 16);
Buffer.BlockCopy(dtResvice, 3, pwddtData, 0, 3);
Buffer.BlockCopy(dtResvice, 6, iddtData, 0, 3);
bDataSuc = true;
}
else
{
iMutex--;
threadOvered.Set();
return;
}
}
Thread.Sleep(50);
Close();
Open();
Array.Clear(dtResvice, 0, dtResvice.Length);
//关卡
bSend = new byte[8] { 0x3c, 0x04, 0x01, 0x68, 0x00, 0x00, 0x51, 0x0d };
verify = bSend[0];
for (int i = 1; i < bSend.Length - 2; i++)
{
verify = (byte)(verify ^ bSend[i]);
}
bSend[bSend.Length - 2] = verify;
ipos = 0;
portDataGet.Reset();
sp.Write(bSend, 0, bSend.Length);
portDataGet.WaitOne();
Thread.Sleep(50);
Close();
Open();
Array.Clear(dtResvice, 0, dtResvice.Length);
//发光管亮一次:3C 03 01 6D 55(TIME) BCC 0D
bSend = new byte[7] { 0x3c, 0x03, 0x01, 0x6d, 0x0a, 0x00, 0x0d };
verify = bSend[0];
for (int i = 1; i < bSend.Length - 2; i++)
{
verify = (byte)(verify ^ bSend[i]);
}
bSend[bSend.Length - 2] = verify;
ipos = 0;
portDataGet.Reset();
sp.Write(bSend, 0, bSend.Length);
portDataGet.WaitOne();
Thread.Sleep(50);
Close();
Open();
//鸣笛
Array.Clear(dtResvice, 0, dtResvice.Length);
bSend = new byte[7] { 0x3c, 0x03, 0x01, 0x6b, 0x0a, 0x00, 0x0d };
verify = bSend[0];
for (int i = 1; i < bSend.Length - 2; i++)
{
verify = (byte)(verify ^ bSend[i]);
}
bSend[bSend.Length - 2] = verify;
ipos = 0;
portDataGet.Reset();
sp.Write(bSend, 0, bSend.Length);
portDataGet.WaitOne();
Thread.Sleep(50);
iMutex--;
threadOvered.Set();
if (HaveReadData != null)
{
HaveReadData();
}
Close();
}