smartCARD/Main.cpp
2021-09-12 20:55:27 +02:00

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 );
}
//---------------------------------------------------------------------------