//--------------------------------------------------------------------------- #pragma hdrstop //--------------------------------------------------------------------------- #pragma argsused #include "stdio.h" //#include "cstring.h" #include "stdlib.h" #include "conio.h" #include "windows.h" #define _verbose ACTIVA_EXPLICACION_PROCESOS HANDLE LM_handle; bool LM_opened = false; int AbrePuerto(LPTSTR lpszPortName) { DWORD dwError; DCB PortDCB; COMMTIMEOUTS CommTimeouts; 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 = 7; // Number of bits/bytes, 4-8 /* PortDCB.ByteSize = 8; // Number of bits/bytes, 4-8 */ PortDCB.Parity = EVENPARITY; // 0-4=no,odd,even,mark,space PortDCB.StopBits = 0; // 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. printf( "Unable to configure the serial port\n%s\n" ); dwError = GetLastError (); 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 = 1000; 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. printf( "Unable to set the time-out parameters" ); dwError = GetLastError (); 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; }; void CierraPuerto(void) { if ( LM_opened ) { CloseHandle( LM_handle ); } }; // ObtenerRespuesta // Lee del puerto los datos pendientes del buffer // (solo lee lo que expulse el LM) // // char *ObtenerRespuesta( char *rcv ) { bool waitingResp = true; DWORD CHK, chkF = 0; int i = 0; DWORD dwCommModemStatus; if ( LM_opened ) { /* // 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 ( waitingResp ) { if ( rcv[i] != 0x06) waitingResp = false; // ACK // printf( "Esperando a la tarjeta\n" ); } if ( rcv[i] == 13 ) break; else { if ( !waitingResp || i==0 ) i++; } } else if ( CHK == 0 ) { chkF++; if ( chkF == 20 ) { sprintf( rcv, "ERROR: Respuesta fuera de tiempo" ); return rcv; } } } rcv[i+1] = '\0'; } else { sprintf( rcv, "ERROR: LM no abierto" ); } #ifdef _verbose printf( "Recibido: %s\n", rcv ); #endif return rcv; }; // EnviarComando // Envia el comando CMD al lector ID, devolviendo la respuesta 'rcv' // // // char *EnviaCMD1( char *CMD, char *rcv, char mlen ) { DWORD CHK; if ( LM_opened ) { #ifdef _verbose printf( "Enviado: %s\n", CMD ); #endif WriteFile( LM_handle, CMD, strlen(CMD)+mlen, &CHK, NULL ); ObtenerRespuesta( rcv ); } else sprintf( rcv, "ERROR: LM no abierto" ); return rcv; } char *EnviaCMD( char *CMD, char *rcv ) { EnviaCMD1( CMD, rcv, 0 ); return rcv; } #define ZT_ClearCommand "/CL0/" // #define ZT_ReadCommand "/RD3/" #define ZT_ReadCommand "/RD1/" #define ZT_WriteCommand "/WR1/" #define ACK 0x06 #define STX 0x02 #define NAK 0x15 #define ETX 0x03 #define EOT 0x04 #define CR 0x0D char CalculaBCC( char *cadena ) { int i, dev=0; for ( i=0; cadena[i] != ETX; i++ ) { dev ^= cadena[i]; } dev ^= cadena[i]; return dev; } char *LeeTarjeta( char *rcv ) { // Leemos una tarjeta char buff[3]; EnviaCMD( ZT_ReadCommand, rcv ); if ( rcv[0] == ACK && rcv[1] == 0x0D ) { // Ahora si se ha recibido Leemos la tarjeta que pasemos ObtenerRespuesta( rcv ); // Vemos si es la tarjeta o un error if ( rcv[0] == STX && rcv[1] == '/' && rcv[2] == 'E' && rcv[3] == 'R' ) { //es un error #ifdef _verbose printf( "Error: %d", rcv[1] ); #endif } else { char len = 0; while( rcv[len]!=CR )len++; char BCC = CalculaBCC( &rcv[1] ), BCCr = rcv[ len-1 ]; if ( BCC != BCCr ) { printf( "Error: BCC recibido es incorrecto BCC(%x) != R(%x)\n", BCC, BCCr ); } } buff[0] = ACK; buff[1] = '\0'; EnviaCMD( buff, rcv ); } else { sprintf( rcv, "ERROR: Commando no aceptado\n"); } return rcv; } char *EscribeTarjeta( char *datos, char *rcv ) { // Leemos una tarjeta char env[140], buff[140], BCC; EnviaCMD( ZT_WriteCommand, rcv ); if ( rcv[0] == ACK && rcv[1] == CR ) { sprintf( env, "%s%c", datos, ETX ); BCC = CalculaBCC( env ); sprintf( buff, "%c%s%c", STX, env, BCC ); if ( BCC ) EnviaCMD( buff, rcv ); else EnviaCMD1( buff, rcv, 1 ); if ( rcv[0] == ACK && rcv[1] == CR ) { // Ahora si se ha recibido Leemos la tarjeta que pasemos ObtenerRespuesta( rcv ); // Vemos si es la tarjeta o un error if ( !(rcv[0] == EOT && rcv[1] == CR) ) { //es un error sprintf( rcv, "Error: %s\n", rcv ); #ifdef _verbose printf( "Error: %s\n", rcv ); #endif } buff[0] = ACK; buff[1] = CR; buff[2] = '\0'; EnviaCMD( buff, rcv ); } else { sprintf( rcv, "ERROR: No se recibio respuesta despues de los datos\n" ); } } else { sprintf( rcv, "ERROR: Commando no aceptado\n"); } return rcv; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { printf("Pruebas con LM2000 JD soft (c)\n"); printf("------------------\n"); AbrePuerto("COM1:"); char rcv[80]; // Inicializamos el ZT-2300 EnviaCMD( ZT_ClearCommand, rcv ); if ( rcv[0] == 'E' ) { printf( "\nError durante la comunicación" ); } else { /* do{ LeeTarjeta( rcv ); } while ( getch() != 13 ); */ LeeTarjeta( rcv ); printf("\n\n\n%s\n\n", rcv ); // EscribeTarjeta( "123456789123465789765132156484513216", rcv ); } printf( "\n\n FIN DEL PROGRAMA \n\n" ); getch(); CierraPuerto(); return 0; }