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