342 lines
10 KiB
C++
342 lines
10 KiB
C++
//---------------------------------------------------------------------------
|
|
|
|
#include <vcl.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#pragma hdrstop
|
|
|
|
#include "Main.h"
|
|
#include "SerieCfg.h"
|
|
//---------------------------------------------------------------------------
|
|
#pragma package(smart_init)
|
|
#pragma resource "*.dfm"
|
|
TSmartCard_Reader *SmartCard_Reader;
|
|
//---------------------------------------------------------------------------
|
|
__fastcall TSmartCard_Reader::TSmartCard_Reader(TComponent* Owner)
|
|
: TForm(Owner)
|
|
{
|
|
TabSheet1->TabVisible=false;
|
|
|
|
hCom=INVALID_HANDLE_VALUE;
|
|
atr = true; inver = false;
|
|
sprintf( serconfig1, "COM2: baud=9600 parity=O data=8 stop=2" );
|
|
sprintf( serconfig2, "COM2: baud=9600 parity=O data=8 stop=2" );
|
|
mlog->Lines->Clear();
|
|
Logger( "Inicialización del programa" );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TSmartCard_Reader::Logger(AnsiString log)
|
|
{
|
|
mlog->Lines->Add( log );
|
|
StatusBar1->SimpleText = AnsiString( TDateTime::CurrentDateTime() ) + " :: " + log;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TSmartCard_Reader::Puertoserie1Click(TObject *Sender)
|
|
{
|
|
TSerieConf *conf;
|
|
conf = new TSerieConf(this);
|
|
conf->ShowModal();
|
|
if ( conf->ModalResult == mrOk )
|
|
{
|
|
/* Cambiamos las cadenas de configuracion*/
|
|
try {
|
|
sprintf(serconfig1,"%s: baud=%d parity=%c data=%1d stop=%1d",
|
|
conf->comPort->Items->Strings[conf->comPort->ItemIndex].c_str(),conf->baudiosA->Text.ToInt(),conf->pariA->Text.c_str()[0],conf->bitsA->Text.ToInt(),conf->stopA->Text.ToInt() );
|
|
sprintf(serconfig2,"%s: baud=%d parity=%c data=%1d stop=%1d",
|
|
conf->comPort->Items->Strings[conf->comPort->ItemIndex].c_str(),conf->baudiosD->Text.ToInt(),conf->pariD->Text.c_str()[0],conf->bitsD->Text.ToInt(),conf->stopD->Text.ToInt() );
|
|
atr = conf->ATR->Checked;
|
|
inver = conf->ConvenioInverso->Checked;
|
|
Logger( "Configuracion del puerto cambiada a: " + AnsiString( serconfig2 ) );
|
|
} catch(...) {
|
|
Logger( "Error interpretando nueva configuración" );
|
|
}
|
|
/* y desconectamos */
|
|
Desconectar1Click(0);
|
|
}
|
|
|
|
delete conf;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TSmartCard_Reader::Conectar1Click(TObject *Sender)
|
|
{
|
|
if ( ! Conectar1->Checked )
|
|
{
|
|
Desconectar1->Checked = false;
|
|
Conectar1->Checked = true;
|
|
OpenCOM();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TSmartCard_Reader::Desconectar1Click(TObject *Sender)
|
|
{
|
|
if ( ! Desconectar1->Checked )
|
|
{
|
|
Desconectar1->Checked = true;
|
|
Conectar1->Checked = false;
|
|
CloseCOM();
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TSmartCard_Reader::OpenCOM(void)
|
|
{
|
|
char buf[256];
|
|
bool err = false;
|
|
|
|
if ( hCom == INVALID_HANDLE_VALUE )
|
|
{
|
|
if ( atr )
|
|
{
|
|
Logger( "Inicializando el puerto para LEER ATR: "+AnsiString(serconfig1) );
|
|
if ( Open(serconfig1)<0 )
|
|
{
|
|
Logger( "Error en la apertura del puerto para ATR" ); err = true;
|
|
} else {
|
|
ATR1Click(0);
|
|
}
|
|
}
|
|
if ( !err )
|
|
{
|
|
Logger( "Inicializando el puerto: "+AnsiString(serconfig2) );
|
|
if ( SetConfig(serconfig2)<0 )
|
|
{
|
|
Logger( "No puedo cambiar la velocidad" ); err = true;
|
|
} else {
|
|
/*
|
|
in[0]=0x21;in[1]=0xC1;in[2]=0x01;in[3]=0x58;in[4]=0xB9;
|
|
Send(out,buf,in,5,5);
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TSmartCard_Reader::CloseCOM(void)
|
|
{
|
|
if ( hCom != INVALID_HANDLE_VALUE )
|
|
{
|
|
CloseHandle(hCom);
|
|
hCom=INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
/*
|
|
Funciones extraida integramente de VIAMOSC,(c) No te importa, versión 0.1
|
|
Brevementes comentadas por mi (JDsoft para no confundirme)
|
|
*/
|
|
int __fastcall TSmartCard_Reader::DoReset(void)
|
|
{
|
|
EscapeCommFunction(hCom,SETRTS);
|
|
Sleep(50);
|
|
EscapeCommFunction(hCom,CLRRTS);
|
|
Sleep(250);
|
|
return 0;
|
|
}
|
|
|
|
int __fastcall TSmartCard_Reader::SetConfig(const char *serconfig)
|
|
{
|
|
DCB dcb;
|
|
BOOL fSuccess;
|
|
DWORD dwError;
|
|
ComErr[0]=0;
|
|
if (hCom==INVALID_HANDLE_VALUE) { strcpy(ComErr,"Port not open");return -1; }
|
|
fSuccess = GetCommState(hCom, &dcb);
|
|
if (!fSuccess) { strcpy(ComErr,"GetCommState failed");CloseHandle(hCom);return -1; }
|
|
fSuccess = BuildCommDCB(serconfig,&dcb);
|
|
if (!fSuccess) { strcpy(ComErr,"BuildCommDCB failed");CloseHandle(hCom);return -1; }
|
|
dcb.fRtsControl=RTS_CONTROL_DISABLE;
|
|
fSuccess = SetCommState(hCom, &dcb);
|
|
if (!fSuccess) { dwError=GetLastError();strcpy(ComErr,"SetCommState failed");CloseHandle(hCom);return -1; }
|
|
return 0;
|
|
}
|
|
|
|
DWORD __fastcall TSmartCard_Reader::SRead(BYTE *buf,DWORD bytes_to_read,DWORD wait)
|
|
{
|
|
DWORD bytes_read,cnt,t;
|
|
BYTE *buf2;
|
|
cnt=0;
|
|
buf2=buf;
|
|
ReadFile(hCom,(void*)buf,bytes_to_read,&bytes_read,NULL);
|
|
cnt+=bytes_read;
|
|
buf2+=bytes_read;
|
|
t=clock();
|
|
while ((clock()<t+wait) && cnt<bytes_to_read)
|
|
{
|
|
ReadFile(hCom,(void*)buf2,bytes_to_read-cnt,&bytes_read,NULL);
|
|
cnt+=bytes_read;
|
|
buf2+=bytes_read;
|
|
}
|
|
if(inver)
|
|
for(int i=0;i<cnt;++i) buf[i]=inverso(buf[i]);
|
|
return cnt;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
DWORD __fastcall TSmartCard_Reader::SWrite(BYTE *buf,DWORD bytes_to_write)
|
|
{
|
|
DWORD n,i,j,k,l,tt;
|
|
BYTE buf2[256],ch;
|
|
for(i=n=l=0;i<bytes_to_write;++i)
|
|
{
|
|
// tt=rdtsc();
|
|
if(inver) ch=inverso(buf[i]);
|
|
else ch=buf[i];
|
|
WriteFile(hCom,(void*)&ch,1,&j,NULL);
|
|
n+=j;
|
|
ReadFile(hCom,&buf2[l],n-l,&k,NULL);
|
|
l+=k;
|
|
// while(rdtsc()-tt<delay);
|
|
}
|
|
if(l<n) SRead(&buf2[l],n-l,20);
|
|
return n;
|
|
}
|
|
|
|
unsigned char __fastcall TSmartCard_Reader::inverso(unsigned char ch)
|
|
{
|
|
unsigned char r;
|
|
int i;
|
|
for(r=i=0;i<8;++i) { r<<=1;r|=(ch&1);ch>>=1; }
|
|
return ~r;
|
|
}
|
|
|
|
int __fastcall TSmartCard_Reader::Send(unsigned char *out,char *buf,unsigned char *in,int m,int RL)
|
|
{
|
|
int n,k;
|
|
SWrite(in,m);
|
|
k=SRead(out,RL,2500);
|
|
setarr(buf,out,k);
|
|
return k;
|
|
}
|
|
|
|
#define min(x,y) ((x<y)?(x):(y))
|
|
|
|
// Dado un caracter (con notacion hexadecimal)
|
|
// devuelve su valor en decimal
|
|
// Ej. '0' == 0 y 'B' == 11
|
|
int __fastcall TSmartCard_Reader::getnyb(char c)
|
|
{
|
|
if((c<='9')&&(c>='0')) return c-'0';
|
|
else if((c<='F')&&(c>='A')) return c-'A'+10;
|
|
else return -1;
|
|
}
|
|
|
|
// Dado un puntero a un par de caracteres, (con notacion hex)
|
|
// devuelve el número que representa
|
|
// Ej. '3B' == 3<<4 + 11
|
|
int __fastcall TSmartCard_Reader::getbyte(char *buf)
|
|
{
|
|
int v,w;
|
|
v=getnyb(toupper(*buf++));
|
|
w=getnyb(toupper(*buf++));
|
|
if((v<0)||(w<0)) return -1;
|
|
return (v<<4)+w;
|
|
}
|
|
|
|
// Dada una cadena del tipo "AF 32 2D E6"
|
|
// devuelve en la cadena a los valores en decimal:
|
|
// n == num_elementos a procesar de la cadena buf...
|
|
// Ejemplo: para la cadena anterior a[0]=0xAF; a[1]=0x32; a[2]=0x2D; a[3]=0xE6
|
|
int __fastcall TSmartCard_Reader::getarr(unsigned char *a,char *buf,int n)
|
|
{
|
|
int i;
|
|
for(i=0;i<n;++i,buf+=2)
|
|
{
|
|
int v;
|
|
while(*buf==' ') ++buf;
|
|
v=getbyte(buf);
|
|
if(v<0) return -1;
|
|
a[i]=v;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
// Igual que antes, pero para toda la cadena 'buf'
|
|
int __fastcall TSmartCard_Reader::getvar(unsigned char *a,char *buf)
|
|
{
|
|
int n;
|
|
n=0;
|
|
while(*buf!=0)
|
|
{
|
|
int v;
|
|
while(*buf==' ') ++buf;
|
|
if(*buf==0) return n;
|
|
v=getbyte(buf);buf+=2;
|
|
if(v<0) return -1;
|
|
a[n++]=v;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
|
|
// Dado un array de valores, los convierte a hexadecimal
|
|
// a[0]=0x1D y a[1]=0x24 ==> buf = "1D 24 ";
|
|
int __fastcall TSmartCard_Reader::setarr(char *buf,unsigned char *a,int n)
|
|
{
|
|
int i;
|
|
for(i=0;i<n;++i) sprintf(&buf[3*i],"%02x ",a[i]);
|
|
return n;
|
|
}
|
|
void __fastcall TSmartCard_Reader::Salir1Click(TObject *Sender)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
int __fastcall TSmartCard_Reader::Open(const char *serconfig)
|
|
{
|
|
COMMTIMEOUTS timeouts;
|
|
char string[16];
|
|
BOOL fSuccess;
|
|
ComErr[0]=0;
|
|
memcpy(string,serconfig,4);
|
|
string[4]=0x00;
|
|
hCom = CreateFile(string,GENERIC_READ | GENERIC_WRITE,0, NULL,OPEN_EXISTING, 0,NULL);
|
|
if (hCom == INVALID_HANDLE_VALUE) { strcpy(ComErr,"Could not create handle");return -1; }
|
|
fSuccess = SetupComm(hCom,1024,1024);
|
|
if (!fSuccess) { strcpy(ComErr,"SetupComm failed");CloseHandle(hCom);return -1; }
|
|
fSuccess = GetCommTimeouts(hCom,&timeouts);
|
|
if (!fSuccess) { strcpy(ComErr,"GetCommTimeouts failed");CloseHandle(hCom);return -1; }
|
|
timeouts.ReadIntervalTimeout=MAXDWORD;
|
|
fSuccess = SetCommTimeouts(hCom,&timeouts);
|
|
if (!fSuccess) { strcpy(ComErr,"SetCommTimeouts failed");CloseHandle(hCom);return -1; }
|
|
return 0;
|
|
}
|
|
|
|
/* MIS FUNCIONES AUXILIARES
|
|
*/
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TSmartCard_Reader::ATR1Click(TObject *Sender)
|
|
{
|
|
char buf[255];
|
|
DoReset();
|
|
lenATR=SRead(ATR,27,30);
|
|
setarr(buf,ATR,lenATR);
|
|
Logger( "ATR == " + AnsiString( buf ) );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
void __fastcall TSmartCard_Reader::Edit3KeyPress(TObject *Sender,
|
|
char &Key)
|
|
{
|
|
if ( Key==VK_RETURN )
|
|
SendCommand( Edit3->Text );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TSmartCard_Reader::BitBtn1Click(TObject *Sender)
|
|
{
|
|
SendCommand( Edit3->Text );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void __fastcall TSmartCard_Reader::SendCommand( AnsiString cmd )
|
|
{
|
|
char values[255],out[255];
|
|
getvar( values, cmd.c_str() );
|
|
Send( out, values, values, cmd.Length(), 254 );
|
|
Memo1->Lines->Insert(0, "-----------------------------------------" );
|
|
Memo1->Lines->Insert(0, "Respuesta: "+AnsiString(values) );
|
|
Memo1->Lines->Insert(0, "Enviado comando: "+cmd );
|
|
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|