CAP/LM2000_vcl/LM2000.cpp
2021-09-01 18:53:06 +02:00

1010 lines
30 KiB
C++

// #define PRUEBAS_SIN_VCL
//---------------------------------------------------------------------------
#include "stdlib.h"
#include "stdio.h"
#include "conio.h"
#include "windows.h"
#define _verbose ACTIVA_EXPLICACION_PROCESOS
#include "LM2000.h"
#ifndef PRUEBAS_SIN_VCL
#include <vcl.h>
#pragma hdrstop
//#include "stdafx.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TLm2000 *)
{
new TLm2000(NULL);
}
//---------------------------------------------------------------------------
__fastcall TLm2000::TLm2000(TComponent* Owner)
: TComponent(Owner)
#else
void __fastcall TLm2000::printfv( AnsiString msg )
{
printf( "%s\n", msg.c_str() );
}
__fastcall TLm2000::TLm2000(void)
#endif
{
LM_opened = false;
}
//-----------------------------------------------------------------------------
/**
Construtor de clase, que inicializa los parámetros de comunicación
*/
__fastcall TLm2000::~TLm2000(void)
{
// Si el puerto aun sigue abierto, lo cerramos...
if ( LM_opened )
CierraPuerto();
}
//---------------------------------------------------------------------------
#ifndef PRUEBAS_SIN_VCL
namespace Lm2000
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TLm2000)};
RegisterComponents("JD soft.", classes, 0);
}
}
#endif
//---------------------------------------------------------------------------
#define ENTER_CARD_MEMORY "A"
// B: solo se usa por compatibilidad -[ NO IMPLEMENTADO ]-
#define CARD_NOT_VALID "C"
#define RTF_MOTIVE_NOT_STANDARD 0
#define RTF_CARD_CODE_UNKNOWN 1
#define RTF_MAGNETIC_CARD_EXPIRED 2
#define RTF_PERIOD_NOT_VALID 3
#define RTF_ANTIPASSBACK_ERROR 4
#define RTF_CARD_VERSION_NOT_VALID 5
#define RTF_CREDIT_INSUFFICIENT 6
#define DELETE_CARD_MEMORY "D"
#define CONFIGURE_MEMORY "E"
#define FMC_LONG_CODES 1
#define FMC_PIN 2
#define FMC_EXPIRATION 4
#define FMC_PREFIX_FREE 8
#define FMC_MINI_MEMORY 16
#define FMC_CARD_REVISION 32
#define WRITE_CHARS_ON_BAND "F"
#define READ_CHARS_ON_BAND "F?"
// G: CONFIGURA PREFIJOS -[ NO IMPLEMENTADO ]-
#define PROGRAMMING_PERIODS "H"
#define SIMPLE_INTERROGATION "I"
#define PROGRAM_OPERATION_PARAMETERS "J"
#define RESET_CLOCK "K"
// L: Configura los tipos de usuarios -[ NO IMPLEMENTADO ]-
#define CARD_VALID "R"
// S: Sustituido por 'C' -[ NO IMPLEMENTADO ]-
#define DELETE_ALL_CARD_MEMORY "T"
#define PASSAGE_OPENING "P"
#define SHOW_NEXT_TRANSIT "U"
#define SET_TIME "V"
// Secuencia de lectura correcta de tarjetas
#define INITIALIZE_READING "O?"
#define READ_CARD_MEMORY "A?"
#define SHOW_NEXT_MESSAGE "N?"
// B?: Inicializa la lectura de mensajes personales
// -[ NO IMPLEMENTADO ]-
// Secuencia de lectura de mensajes personales
// -[ NO IMPLEMENTADO ]-
#define INITIALIZE_READING_CM "B?"
#define READ_PERSONAL_MESSAGE "Y?"
#define SHOW_NEXT_PMESSAGE "D?"
#define REINITILIZE_TRANSIS_M "C?"
#define READ_MEMORY_CFG "E?"
// F?: Lee cfg caracteres de la banda -[ NO IMPLEMENTADO ]-
#define READ_PREFIXES "G?"
// H?: Lee periodos
#define READ_OPERATION_CFG "J?"
#define READ_FIRMWARE "I?"
#define READ_TIMER(X) "b?,X"
#define READ_SYSTEM_MESSAGE "X?"
//-----------------------------------------------------------------------------
/**
Abre el puerto de comunicación "lpszrPortName"
Esta función debe ser llamada antes de cualquier otra comunicación;
*/
int __fastcall TLm2000::AbrePuerto(LPTSTR lpszPortName)
{
DWORD dwError;
DCB PortDCB;
COMMTIMEOUTS CommTimeouts;
// Antes de abrir, cerramos si asi procede
if ( LM_opened ) return true;
LM_opened = false;
// Open the serial port.
LM_handle = CreateFile (lpszPortName, // Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE,
// Access (read/write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING,// How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute
// to copy
// If it fails to open the port, return FALSE.
if ( LM_handle == INVALID_HANDLE_VALUE )
{
dwError = GetLastError ();
return false;
} else {
LM_opened = true;
}
PortDCB.DCBlength = sizeof (DCB);
// Get the default port setting information.
GetCommState (LM_handle, &PortDCB);
// Change the DCB structure settings.
PortDCB.BaudRate = 9600; // Current baud
PortDCB.fBinary = TRUE; // Binary mode; no EOF check
PortDCB.fParity = TRUE; // Enable parity checking.
PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
// DTR flow control type
PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity
PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx
PortDCB.fOutX = FALSE; // No XON/XOFF out flow control
PortDCB.fInX = FALSE; // No XON/XOFF in flow control
PortDCB.fErrorChar = FALSE; // Disable error replacement.
PortDCB.fNull = FALSE; // Disable null stripping.
PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
// RTS flow control
PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on
// error.
PortDCB.ByteSize = 8; // Number of bits/bytes, 4-8
PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
// Configure the port according to the specifications of the DCB
// structure.
if (!SetCommState (LM_handle, &PortDCB))
{
// Could not configure the serial port.
dwError = GetLastError ();
(printfv)( Format("Unable to configure the serial port\n%s\n", ARRAYOFCONST(("dwError")) ) );
return FALSE;
}
// Retrieve the time-out parameters for all read and write operations
// on the port.
GetCommTimeouts (LM_handle, &CommTimeouts);
// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
/// CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 5000;
CommTimeouts.ReadTotalTimeoutConstant = 1000;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
// Set the time-out parameters for all read and write operations
// on the port.
if (!SetCommTimeouts (LM_handle, &CommTimeouts))
{
// Could not set the time-out parameters.
dwError = GetLastError ();
(printfv)( Format( "Unable to set the time-out parameters: %s", ARRAYOFCONST(("dwError")) ) );
return FALSE;
}
// Direct the port to perform extended functions SETDTR and SETRTS.
// SETDTR: Sends the DTR (data-terminal-ready) signal.
// SETRTS: Sends the RTS (request-to-send) signal.
EscapeCommFunction (LM_handle, SETDTR);
EscapeCommFunction (LM_handle, SETRTS);
return LM_opened;
};
//-----------------------------------------------------------------------------
/**
Cierra el puerto, (siempre que este abierto) y libera los recursos pedidos
*/
void __fastcall TLm2000::CierraPuerto(void)
{
if ( LM_opened )
{
CloseHandle( LM_handle );
}
};
//-----------------------------------------------------------------------------
/**
Dada una cadena de entrada, genera el CheckSum de comprobación necesario,
devolviendo este al final.
*/
int __fastcall TLm2000::GeneraChecksum( char *cadena )
{
int CHK, i;
CHK = 0;
for ( i=0; cadena[i] != NULL; i++ )
{
CHK += cadena[i];
}
return ( CHK - ( (CHK / 10000)*10000 ) );
}
//-----------------------------------------------------------------------------
/**
NO SE PARA QUE ERA ESTO
*/
/*
int __fastcall:tieneRespuesta( char *CMD )
{
int dev = -1;
if ( strcmp( CMD, READ_FIRMWARE ) == 0 ) dev = 1;
return dev;
}
*/
//-----------------------------------------------------------------------------
/**
ObtenerRespuesta
Lee del puerto los datos pendientes del buffer
(solo lee lo que expulse el LM)
*/
char * __fastcall TLm2000::ObtenerRespuesta( char *rcv )
{
char buf[80], enviar[80];
DWORD CHK, chkF = 0;
int i = 0;
DWORD dwCommModemStatus;
if ( LM_opened )
{
/*
03-02-2002 ELIMINADO PARA EVITAR QUEDAR COLGADO A LA ESPERA DEL LEGO
Esperemos que los TIME-OUTS funcienen BIEN sin esto.
// Specify a set of events to be monitored for the port.
SetCommMask (LM_handle, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);
// Wait for an event to occur for the port.
WaitCommEvent (LM_handle, &dwCommModemStatus, 0);
// Re-specify the set of events to be monitored for the port.
SetCommMask (LM_handle, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);
*/
// Recogemos la respuesta del lector
while( i < 75 )
{
ReadFile( LM_handle, &(rcv[i]), 1, &CHK, NULL );
if ( CHK == 1 )
{
if ( rcv[i] == 13 ) break; else i++;
} else {
// if ( CHK == 0 )
if ( (++chkF) >= 10 )
{
sprintf( rcv, "ERROR: Respuesta fuera de tiempo" );
return rcv;
}
}
}
rcv[i+1] = '\0';
// Verificamos la respuesta del lector
if ( i > 10 && i < 75)
{
char *ptr;
// Generamos nuestro CHECKSUM de la respuesta
strcpy( buf, rcv ); buf[ i - 4 ] = '\0';
CHK = GeneraChecksum( buf );
// Aislamos el CHECKSUM de la respuesta
strcpy( buf, rcv ); ptr = buf + i - 4; buf[ i ] = '\0';
// Comparamos los CHECKSUM
sprintf( enviar, "%04d", CHK );
if ( strcmp( enviar, ptr ) != 0 )
{
strcpy( enviar, rcv );
sprintf( rcv, "ERROR CHECKSUM: (%04d) - %s", CHK, enviar );
}
} else
sprintf( rcv, "ERROR: Respuesta de longitud incorrecta" );
} else {
sprintf( rcv, "ERROR: LM no abierto" );
}
#ifdef _verbose
(printfv)( Format("Recibido: %s\n", ARRAYOFCONST((rcv)) ) );
#endif
return rcv;
};
//-----------------------------------------------------------------------------
/**
Envia el comando CMD al lector ID, devolviendo la respuesta 'rcv'
*/
char * __fastcall TLm2000::EnviarComando( char *CMD, int ID, char *rcv )
{
char buf[80], enviar[80];
DWORD CHK;
if ( LM_opened )
{
sprintf( buf, "L%03d:%s,", ID, CMD );
CHK = GeneraChecksum( buf );
sprintf( enviar, "%s%04d\r", buf, CHK );
#ifdef _verbose
(printfv)( Format("\nEnviado: %s\n", ARRAYOFCONST((enviar)) ) );
#endif
WriteFile( LM_handle, enviar, strlen(enviar), &CHK, NULL );
ObtenerRespuesta( rcv );
} else
sprintf( rcv, "ERROR: LM no abierto" );
return rcv;
}
//-----------------------------------------------------------------------------
/**
Procesa el transito devuelto tras una llamada a CMD=I
*/
void __fastcall TLm2000::ProcesaTransito( char *FGT, char *TPT, char *CDT, char *O, char *DTT, char *CTT, char *ETT )
{
#ifdef _verbose
(printfv)( Format("\nFGT %s\nTPT: %s\nCDT: %s\nO: %s\nDTT: %s\nCTT: %s\nETT: %s\n", ARRAYOFCONST((FGT, TPT, CDT, O, DTT, CTT, ETT)) ) );
#endif
#ifndef PRUEBAS_SIN_VCL
if ( FOnProcesaTransito ) (FOnProcesaTransito)( FGT, TPT, CDT, O, DTT, CTT, ETT );
#endif
}
//-----------------------------------------------------------------------------
/**
Dada una cadena de parámetros delimitados por coma ',', obtiene y de vuelve
en 'prm' el parametro 'narg'-esimo.
*/
char * __fastcall TLm2000::ObtenerParametro( char *cadena, int narg, char *prm )
{
int i;
char *inicio, *fin;
inicio = cadena;
fin = cadena;
// Delimitación del parámetro
for ( i=0; *fin != '\0' && i < narg; fin++ )
{
// Si es el comienzo de un nuevo parametro...
if ( *fin == ',' )
{
i++;
if ( i < narg )
inicio = (fin + 1);
}
}
// Longitud del parametro
i = fin - inicio - 1;
// Copia aislada del parámetro
strncpy( prm, inicio, i );
prm[ i ] = '\0';
return prm;
}
//-----------------------------------------------------------------------------
/**
Esta es la función que debe ser redefinida...
*/
// bool BuscaTarjeta( int FGA, int TPA, int CDA, int *TPR, int *PNR, char *message )
// {
// bool enc = false;
//
// #ifdef _verbose
// (printfv)( "Localizando tarjeta: (%d)-%d-%d", FGA, TPA, CDA );
// #endif
// // Localizamos la tarjeta
// if ( /* LOCALIZADA */ 1 )
// {
// *TPR = 0;
// *PNR = 0;
// sprintf( message, "ACCESO PERMITIDOwww.infdj.com" );
// enc = true;
// } else {
// sprintf( message, "ACCESO DENEGADOwww.infdj.com" );
// enc = false;
// }
//
// return enc;
// }
//
//-----------------------------------------------------------------------------
/**
Procesa una tarjeta despues de un SIMPLE_INTERROGATION
*/
bool __fastcall TLm2000::ProcesaTarjeta( int ID, char *msg )
{
char buff[80], rcv[80];
char message[80];
int FGA, TPA, CDA, TPR, PNR;
#ifdef _verbose
(printfv)( Format("ProcesaTarjeta: %s", ARRAYOFCONST((msg)) ) );
#endif
// Obtenemos los datos de la tarjeta
FGA = atoi( ObtenerParametro( msg, 2, buff ) );
TPA = atoi( ObtenerParametro( msg, 3, buff ) );
CDA = atoi( ObtenerParametro( msg, 4, buff ) );
// La cotejamos con nuestra base de datos ( CDA )
#ifdef PRUEBAS_SIN_VCL
if ( 1 )
#else
if ( (FOnBuscaTarjeta) && (FOnBuscaTarjeta)( ID, FGA, TPA, CDA, &TPR, &PNR, message ) )
#endif
{
// ¿Tiene permiso?
sprintf( buff, "%s, %d, %d,%s", CARD_VALID, TPR, PNR, message );
EnviarComando( buff, ID, rcv );
if ( rcv[5] == 'X' )
{
// Necesitamos esperar a que se libere la linea de comunicación
Sleep( 1000 );
PassageOpening( ID, (FGA & 0x0008) ? 1 : 2 );
}
} else {
// Si no esta...
sprintf( buff, "%s, %d,%s", CARD_NOT_VALID, RTF_MOTIVE_NOT_STANDARD, message );
EnviarComando( buff, ID, rcv );
}
return ( rcv[5] == 'X' );
}
//-----------------------------------------------------------------------------
/**
Realiza una InterrogaciónSimple
*/
char * __fastcall TLm2000::SimpleInterrogation( int ID, char *rcv )
{
char prm[7][20];
EnviarComando( SIMPLE_INTERROGATION, ID, rcv );
// Tratamos las posibles respuestas a una Interrogación Simple
switch( rcv[5] )
{
// Transit to download
case 'T':
#ifdef _verbose
(printfv)( "Transit to download\n" );
#endif
ProcesaTransito( ObtenerParametro( rcv, 2, prm[0] ),
ObtenerParametro( rcv, 3, prm[1] ),
ObtenerParametro( rcv, 4, prm[2] ),
ObtenerParametro( rcv, 5, prm[3] ),
ObtenerParametro( rcv, 6, prm[4] ),
ObtenerParametro( rcv, 7, prm[5] ),
ObtenerParametro( rcv, 8, prm[6] ) );
EnviarComando( SHOW_NEXT_TRANSIT, ID, rcv );
break;
// Information to Request
case 'H':
#ifdef _verbose
(printfv)( "Information to Request\n" );
#endif
ProcesaTarjeta( ID, rcv );
break;
// Alarm
case 'A':
#ifdef _verbose
(printfv)( "Alarm\n" );
#endif
break;
// No information to communicate
case 'R':
#ifdef _verbose
(printfv)( "No information to communicate\n" );
#endif
break;
// -- error --
default:
#ifdef _verbose
(printfv)( "ERROR: SimpleInterrogration ERROR de RESPUESTA\n" );
#endif
break;
}
return rcv;
}
//-----------------------------------------------------------------------------
/**
Lee una tarjeta de la memoria del lector
*/
bool __fastcall TLm2000::ReadCardMemory( int ID, TCard *CRD )
{
bool hay_mas_tarjetas = false;
char buff[80], rcv[80];
EnviarComando( READ_CARD_MEMORY, ID, rcv );
if ( rcv[0] != 'E' )
{
hay_mas_tarjetas = !( rcv[5] == 'X' && rcv[7] == '1' );
if ( hay_mas_tarjetas )
{
// Procesamos los parámetros
CRD->FLG = atol( ObtenerParametro( rcv, 2, buff ) ); // FLG
CRD->TYP = atol( ObtenerParametro( rcv, 3, buff ) ); // TYP
CRD->CDA = atol( ObtenerParametro( rcv, 4, buff ) ); // CDA
CRD->PIN = atol( ObtenerParametro( rcv, 5, buff ) ); // PIN
CRD->GIS = atol( ObtenerParametro( rcv, 6, buff ) ); // GIS
CRD->MES = atol( ObtenerParametro( rcv, 7, buff ) ); // MES
CRD->ANS = atol( ObtenerParametro( rcv, 8, buff ) ); // ANS
CRD->ORS = atol( ObtenerParametro( rcv, 9, buff ) ); // ORS
CRD->MIS = atol( ObtenerParametro( rcv, 10, buff ) ); // MIS
CRD->SES = atol( ObtenerParametro( rcv, 11, buff ) ); // SES
CRD->REV = atol( ObtenerParametro( rcv, 12, buff ) ); // REV
CRD->CRD = atol( ObtenerParametro( rcv, 13, buff ) ); // CRD
#ifdef _verbose
(printfv)( Format("FLG: %ld\nTYP: %ld\nCDA: %ld\nPIN: %ld\nGIS: %ld\nMES: %ld\nANS: %ld\nORS: %ld\nMIS: %ld\nSES: %ld\nREV: %ld\nCRD: %ld\n", ARRAYOFCONST((CRD->FLG, CRD->TYP, CRD->CDA, CRD->PIN, CRD->GIS, CRD->MES, CRD->ANS, CRD->ORS, CRD->MIS, CRD->SES, CRD->REV, CRD->CRD)) ) );
(printfv)( "CARD_FLAG\n--------\n" );
int nFLAG = CRD->FLG;
(printfv)( Format("EXTERNAL READER: %s\nINTERNAL READER: %s\nFROM LEFT TO RIGHT: %s\nFROM RIGHT TO LEFT %s\n",ARRAYOFCONST(( (nFLAG & 0x08) ? "SI":"NO",
(nFLAG & 0x04) ? "SI":"NO",
(nFLAG & 0x02) ? "SI":"NO",
(nFLAG & 0x01) ? "SI":"NO")) ) );
#endif
}
} else {
#ifdef _verbose
(printfv)( Format("ERROR READ_CARD_MEMORY: %s\n", ARRAYOFCONST((rcv)) ) );
#endif
}
return hay_mas_tarjetas;
}
//-----------------------------------------------------------------------------
/**
Debe devolver la lista de tarjetas de la memoria completa
(No implento el parametro de salida de momento)
*/
void __fastcall TLm2000::ReadEntireCardMemory( int ID )
{
char rcv[80];
TCard CRD;
EnviarComando( INITIALIZE_READING, ID, rcv );
if ( rcv[0] != 'E' )
{
while( ReadCardMemory( ID, &CRD ) )
{
// Procesar Tarjeta
///***///
EnviarComando( SHOW_NEXT_MESSAGE, ID, rcv );
};
} else {
#ifdef _verbose
(printfv)( Format("ERROR FIRST_CARD: %s\n", ARRAYOFCONST((rcv)) ) );
#endif
}
}
// #############################################################################
// #############################################################################
// #############################################################################
// #############################################################################
// #############################################################################
// #############################################################################
// #############################################################################
//-----------------------------------------------------------------------------
/**
Introducimos tarjetas en la Memoria
*/
int __fastcall TLm2000::EnterCardMemory( int ID, TCard *CRD )
{
int dev;
char enviar[80], rcv[80];
sprintf( enviar, "%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", ENTER_CARD_MEMORY,
CRD->FLG, CRD->TYP, CRD->CDA, CRD->PIN, CRD->GIS, CRD->MES,
CRD->ANS, CRD->ORS, CRD->MIS, CRD->SES, CRD->REV, CRD->CRD );
EnviarComando( enviar, ID, rcv );
if ( rcv[5] == 'X' )
{
dev = atol( ObtenerParametro( rcv, 2, enviar ) );
} else
if ( rcv[5] == 'E' )
{
switch( rcv[7] )
{
case '6':
dev = -6;
#ifdef _verbose
(printfv)( Format("ERROR EnterCardMemory Memory full: %s", ARRAYOFCONST((rcv)) ) );
#endif
break;
case '8':
dev = -8;
#ifdef _verbose
(printfv)( Format("ERROR EnterCardMemory Card code below acceptable minimum: %s", ARRAYOFCONST((rcv)) ) );
#endif
break;
default:
#ifdef _verbose
(printfv)( Format("ERROR EnterCardMemory (SIN IDENTIFICAR): %s", ARRAYOFCONST((rcv)) ) );
#endif
}
}
return dev;
}
//-----------------------------------------------------------------------------
/**
Elimina del LM'ID' la tarjeta TIP/COD
*/
int __fastcall TLm2000::DeleteCardMemory( int ID, int TIP, int COD )
{
int dev;
char enviar[80], rcv[80];
sprintf( enviar, "%s,0,%d,%d", DELETE_CARD_MEMORY, TIP, COD );
EnviarComando( enviar, ID, rcv );
if ( rcv[5] == 'X' )
dev = atoi( ObtenerParametro( rcv, 2, enviar ) );
else
dev = 0;
return dev;
}
//-----------------------------------------------------------------------------
/**
Elimina TODAS las tarjetas de la memoria
*/
int __fastcall TLm2000::DeleteAllCardMemory( int ID, int TIP )
{
return DeleteCardMemory( ID, TIP, TIP );
}
//-----------------------------------------------------------------------------
/**
Lee la configuración del Lector ID
*/
RMem * __fastcall TLm2000::ReadMemoryCFG( int ID, RMem *mem )
{
char rcv[80], prm[80];
EnviarComando( READ_MEMORY_CFG, ID, rcv );
mem->FMC = atoi( ObtenerParametro( rcv, 2, prm ) );
mem->MAC = atoi( ObtenerParametro( rcv, 3, prm ) );
mem->LFN = atoi( ObtenerParametro( rcv, 4, prm ) );
mem->NCR = atoi( ObtenerParametro( rcv, 5, prm ) );
mem->CMN = atoi( ObtenerParametro( rcv, 6, prm ) );
mem->CMX = atoi( ObtenerParametro( rcv, 7, prm ) );
mem->NBN = atoi( ObtenerParametro( rcv, 8, prm ) );
mem->NMP = atoi( ObtenerParametro( rcv, 9, prm ) );
mem->NFA = atoi( ObtenerParametro( rcv, 10, prm ) );
mem->RMS = atoi( ObtenerParametro( rcv, 11, prm ) );
mem->MCA = atoi( ObtenerParametro( rcv, 12, prm ) );
mem->MCR = atoi( ObtenerParametro( rcv, 13, prm ) );
#ifdef _verbose
(printfv)( Format("%s\n", ARRAYOFCONST((rcv)) ) );
(printfv)( Format("FMC: %d\nMAC: %d\nLFN: %d\nNCR: %d\nCMN: %d\nCMX: %d\nNBN: %d\nNMP: %d\nNFA: %d\nRMS: %d\nMCA: %d\nMCR: %d\n", ARRAYOFCONST((
mem->FMC, mem->MAC, mem->LFN, mem->NCR, mem->CMN, mem->CMX,
mem->NBN, mem->NMP, mem->NFA, mem->RMS, mem->MCA, mem->MCR)) ) );
#endif
return mem;
}
//-----------------------------------------------------------------------------
/**
Configura el Lector ID
*/
bool __fastcall TLm2000::ConfigureMemory( int ID, RMem *mem )
{
bool dev;
char enviar[80], rcv[80];
// Verificamos que todos los parámetros sean correctos
if ( ((mem->FMC) & ( FMC_LONG_CODES + FMC_MINI_MEMORY )) )
{
#ifdef _verbose
(printfv)( "Error ConfigureMemory: FMC_LONG_CODES y FMC_MINI_MEMORY son incompatibles" );
#endif
dev = false;
} else {
// Configuramos la memoria
sprintf( enviar, "%s,%s,,%s,,%s,%s,%s,%s,%s,%s,%s,%s", CONFIGURE_MEMORY,
mem->FMC, mem->LFN, /*mem->NCR, */ mem->CMN, mem->CMX, mem->NBN,
mem->NMP, mem->NFA, mem->RMS, mem->MCA, mem->MCR );
EnviarComando( enviar, ID, rcv );
if ( rcv[5] == 'E' )
{
#ifdef _verbose
(printfv)( "ERROR ConfigureMemory: MEMORY IS FULL ó PAMARETERS ARE INCORRECT" );
#endif
dev = false;
}
if ( rcv[5] == 'X' )
{
int resp = atoi( ObtenerParametro( rcv, 2, enviar ) );
#ifdef _verbose
(printfv)( "ConfigureMemory: " );
switch( resp )
{
case 0: (printfv)( "Memory not affected" ); break;
case 1: (printfv)( "Transit memory" ); break;
case 2: (printfv)( "Transit memory + personal messages memory" ); break;
case 3: (printfv)( "Transit memory + personal messages memory + periods" ); break;
default:
(printfv)( Format("Card Memory [ %d ]", ARRAYOFCONST((resp)) ) ); break;
}
dev = true;
#endif
}
}
return dev;
}
//-----------------------------------------------------------------------------
/**
Programación de los Periodos
*/
bool __fastcall TLm2000::ProgrammingPeriods( int ID, int NFS, int PBN, char *StarTime, char *EndTime, int GIF )
{
char enviar[80], rcv[80];
sprintf( enviar, "%s,%d,%d,%s,%s,%d", PROGRAMMING_PERIODS, NFS, PBN, StarTime, EndTime, GIF );
EnviarComando( enviar, ID, rcv );
#ifdef _verbose
if ( rcv[5] == 'E' )
(printfv)( Format("ERROR ProgrammingPeriods Arguments incorrect: %s", ARRAYOFCONST((rcv)) ) );
#endif
return ( rcv[5] == 'X' );
}
//-----------------------------------------------------------------------------
/**
Configura el número de caracteres en la banda
*/
bool __fastcall TLm2000::SetCharsOnBand( int ID, CAB *cab )
{
char enviar[80], rcv[80];
sprintf( enviar, "%s,%d,%d,%d,%d,%d,%d,%d,%d", WRITE_CHARS_ON_BAND, cab->GAP, cab->LEP, cab->GAC, cab->LEC, cab->GAR, cab->LER, cab->GDI, cab->GDF );
EnviarComando( enviar, ID, rcv );
#ifdef _verbose
if ( rcv[5] == 'E' )
(printfv)( Format("ERROR SetCharsOnBand: %s", ARRAYOFCONST((rcv)) ) );
#endif
return ( rcv[5] == 'X' );
}
//-----------------------------------------------------------------------------
/**
Parametros de operacion del programa
*/
bool __fastcall TLm2000::ProgramOperationParameters( int ID, POP *pop )
{
char enviar[80], rcv[80];
sprintf( enviar, "%s,%d,%d,%d,%d,%d,%d,%d,%d", PROGRAM_OPERATION_PARAMETERS, pop->BKN, pop->BKP, pop->PRN, pop->MCL, pop->MCK, pop->ENF, pop->SNV, pop->ENI );
EnviarComando( enviar, ID, rcv );
return ( rcv[5] == 'X' );
}
//-----------------------------------------------------------------------------
/**
Activar los reles de salida
1 Internal Reader
2 External Reader
3 Output 1
4 Output 2
*/
bool __fastcall TLm2000::PassageOpening( int ID, int Passage )
{
char enviar[80], rcv[80];
sprintf( enviar, "%s,%d", PASSAGE_OPENING, Passage );
EnviarComando( enviar, ID, rcv );
return ( rcv[5] == 'X' );
}
//-----------------------------------------------------------------------------
/**
Reconfigura el reloj
*/
bool __fastcall TLm2000::ResetClock( int ID, RClock *clock )
{
int err;
char enviar[80], rcv[80];
sprintf( enviar, "%s,%d,%d,%d,%d,%d,%d", RESET_CLOCK, clock->GIA, clock->MEA, clock->ANA, clock->ORA, clock->MIA, clock->SEA );
EnviarComando( enviar, ID, rcv );
#ifdef _verbose
if ( rcv[5] == 'E' )
{
err = atoi( ObtenerParametro( rcv, 2, enviar ) );
(printfv)( Format( "ERROR ResetClock: %s", ARRAYOFCONST(( (err == 0) ? "Date incorrect" : "Time incorrect")) ) );
}
#endif
return ( rcv[5] == 'X' );
}
//-----------------------------------------------------------------------------
/**
Lee los caracteres en la banda
*/
bool __fastcall TLm2000::GetCharsOnBand( int ID, CAB *cab )
{
int dev;
char enviar[80], rcv[80];
sprintf( enviar, "%s", READ_CHARS_ON_BAND );
EnviarComando( enviar, ID, rcv );
if ( rcv[5] != 'E' )
{
dev = true;
cab->GAP = atoi( ObtenerParametro( rcv, 2, enviar ) );
cab->LEP = atoi( ObtenerParametro( rcv, 3, enviar ) );
cab->GAC = atoi( ObtenerParametro( rcv, 4, enviar ) );
cab->LEC = atoi( ObtenerParametro( rcv, 5, enviar ) );
cab->GAR = atoi( ObtenerParametro( rcv, 6, enviar ) );
cab->LER = atoi( ObtenerParametro( rcv, 7, enviar ) );
cab->GDI = atoi( ObtenerParametro( rcv, 8, enviar ) );
cab->GDF = atoi( ObtenerParametro( rcv, 9, enviar ) );
#ifdef _verbose
(printfv)( Format("ReadCharsOnBand: %d", ARRAYOFCONST((dev)) ) );
#endif
} else {
dev = false;
#ifdef _verbose
(printfv)( Format("ERROR ReadCharsOnBand: %s", ARRAYOFCONST((rcv)) ) );
#endif
}
return dev;
}
//-----------------------------------------------------------------------------
/**
Lee los prefijos activos
*/
int __fastcall TLm2000::ReadingPrefixes( int ID, int NPR )
{
int dev;
char enviar[80], rcv[80];
sprintf( enviar, "%s,%d", READ_PREFIXES, NPR );
EnviarComando( enviar, ID, rcv );
if ( rcv[5] != 'E' )
{
dev = atoi( ObtenerParametro( rcv, 2, enviar ) );
#ifdef _verbose
(printfv)( Format("ReadingPrefixes: %d", ARRAYOFCONST((dev)) ) );
#endif
} else {
dev = -1;
#ifdef _verbose
(printfv)( Format("ERROR ReadingPrefixes: NPR argument", ARRAYOFCONST((dev)) ) );
#endif
}
return dev;
}
//-----------------------------------------------------------------------------
/**
Lee los mensajes personales
*/
bool __fastcall TLm2000::ReadPersonalMessage( int ID )
{
char rcv[80], prm[80];
int TPM, CDM, MSU;
EnviarComando( READ_PERSONAL_MESSAGE, ID, rcv );
TPM = atoi( ObtenerParametro( rcv, 2, prm ) );
CDM = atoi( ObtenerParametro( rcv, 3, prm ) );
MSU = atoi( ObtenerParametro( rcv, 4, prm ) );
#ifdef _verbose
(printfv)( Format("TPM: %d\nCDM: %d\nMSU: %d\n-------\n", ARRAYOFCONST((TPM, CDM, MSU)) ) );
#endif
return ( rcv[5] != 'X' );
}
//-----------------------------------------------------------------------------
/**
Lee todos los mensajes personales
*/
void __fastcall TLm2000::ReadAllPersonalMessage( int ID )
{
char rcv[80];
EnviarComando( INITIALIZE_READING_CM, ID, rcv );
if ( rcv[5] == 'X' )
{
while( ReadPersonalMessage( ID ) )
{
EnviarComando( SHOW_NEXT_PMESSAGE, ID, rcv );
};
}
}
//-----------------------------------------------------------------------------
/**
N.P.I de lo que hace esto
*/
void __fastcall TLm2000::SetTime( int ID, TSD *tsd )
{
char enviar[80], rcv[80];
sprintf( enviar, "%s,%d,%d,%d,%d,%d,%d,%d,", SET_TIME, tsd->CHN, tsd->GSL, tsd->MMS, tsd->ASL, tsd->HSL, tsd->MSL, tsd->SSL );
EnviarComando( enviar, ID, rcv );
if ( rcv[5] == 'X' )
{
/*
while( ReadPersonalMessage( ID ) )
{
EnviarComando( SHOW_NEXT_PMESSAGE, ID, rcv );
};
*/
}
}
//-----------------------------------------------------------------------------
/**
Lee los mensajes del sistema
*/
char * __fastcall TLm2000::ReadSystemMessages( int ID, int IDmsg, char *rcv )
{
char enviar[80];
sprintf( enviar, "%s,%d,", READ_SYSTEM_MESSAGE, IDmsg );
EnviarComando( enviar, ID, rcv );
if ( rcv[5] == 'E' )
{
#ifdef _verbose
sprintf( rcv, "ERROR ReadSystemMessage: IDmsg fuera de RANGO" );
#endif
}
return rcv;
}