📄 industrx.cpp
字号:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// IT24 Sistemas S.A.// Process ATM Transaction Method//// Metodo de Procesamiento de Transaccion ATM, con conexion y desconexion a base de// datos para cada transaccion entrante, con manejo local de parsing del mensaje ISO// y seteo del codigo de respuesta en el mensaje saliente.//// Tarea Fecha Autor Observaciones// (Inicial) 2003.07.22 mdc Base// (Alfa) 2003.09.01 mdc CBL LOGG en funcion de macro de DEBUG// (Beta) 2004.05.24 mdc Motivo EXTRACT de Reverso/Forzado// (Beta) 2004.05.27 MDC WORD TrxResINDUS::ProcessIndividualTransfer(WORD wCause,boolean_t bIsRvsl)// Transferencia CBU de individuo// (Beta) 2004.11.23 MDC "Error COBOL"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Headers ANSI C/C++#include <stdio.h>#include <stdlib.h>#include <time.h>#include <ctype.h>#include <string.h>#include <memory.h>#ifndef _SYSTEM_ATM_ #define _SYSTEM_ATM_DEFINED_ #define _SYSTEM_ATM_ #endif // _SYSTEM_ATM_DEFINED_// Header Transaction Resolution#include <qusrinc/trxres.h>// Libreria de utilidades estandards#include <qusrinc/stdiol.h>// Header ISO Msg Redefinition#include <qusrinc/isoredef.h>// Header ISO 8583#include <qusrinc/iso8583.h>// Header EXTRACT BASE24 RED LINK#include <qusrinc/extrctst.h>#ifdef _SYSTEM_ATM_DEFINED_#undef _SYSTEM_ATM_#endif // _SYSTEM_ATM_DEFINED_// Librerias propias de TCP/IP v4#include <qusrinc/tcp4u.h>/////////////////////////////////////////////////////////////////////////////////////////// Definiciones y Macros de expansion MUY utiles para simplificar el codigo/////////////////////////////////////////////////////////////////////////////////////////// Macro de asignacion de String, con NULL al final#define COPYSTRING(dst,src) strcpy(dst,src) // Macro de asignacion de String, con NULL al final#define ASSIGNSTRING(dst,src) \ { strncpy(dst,src,sizeof(src)); dst[sizeof(src)]=0x00; }// Macro de asignacion de bytes a campo de estructura#define ASSIGNFIELD(dst,src) \ { memset(dst,' ',sizeof(dst)); memcpy(dst,src,min(sizeof(src),sizeof(dst))); }// Macro de asignacion de ceros a campo de estructura#define SETFIELDZEROED(dst) memset(dst ,'0',sizeof(dst))#define SETFIELDBLANKED(dst) memset(dst ,' ',sizeof(dst))#define SETSTRUCTZEROED(dst) memset(&dst,'0',sizeof(dst))#define SETSTRUCTBLANKED(dst) memset(&dst,' ',sizeof(dst))#define SETSTRUCTNULL(dst) memset(&dst, 0x00,sizeof(dst))// Mascara de inicializacion de time-stamp#define _TIMESTAMP_MASK_YYYY_ "YYYYMMDDHHMMSS" #define _TIMESTAMP_MASK_YY_ "YYMMDDHHMMSS" #define _TIMESTAMP_MASK_ _TIMESTAMP_MASK_YY_#define _DEBUG_CBL_MSG_/////////////////////////////////////////////////////////////////////////////////////////// Prototipo de funcion utilitaria que retorna la cantidad de bytes numericos en string/////////////////////////////////////////////////////////////////////////////////////////short strnumlen( char *pszValue , const short nMax );/////////////////////////////////////////////////////////////////////////////////////////// Longitud maxima de tarjeta en TACK-2static const short _MAX_CARDNUM_LEN_ = 19;// Nombre de Archivo de Mensaje EXTRACT al CBLSERVERstatic const char _CBLFILENAME_[] = "CBLLOGG.txt";////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Constructor///////////////////////////////////////////////////////////////////////////////////TrxResINDUS::TrxResINDUS(){}/////////////////////////////////////////////////////////////////////////////////////// Constructor opcional con parametros para el back-end///////////////////////////////////////////////////////////////////////////////////TrxResINDUS::TrxResINDUS(char szIPBackEnd[], unsigned short usPortBackEnd){ // Configurar el Back End tcpConn.setHost( szIPBackEnd ); tcpConn.setUsPort( usPortBackEnd );}///////////////////////////////////////////////////////////////////////////////////// Destructor///////////////////////////////////////////////////////////////////////////////////TrxResINDUS::~TrxResINDUS(){ // Cierre de conexion back end tcpConn.disconnect();}///////////////////////////////////////////////////////////////////////// Procesamiento de Transacciones ATM INDUS genericas, no en particular.///////////////////////////////////////////////////////////////////////WORD TrxResINDUS::ProcessGeneric(void){ // Enviar al sistema autorizador INDUS/AS400 y esperar rta. WORD wRespCode = EnviarYRecibirMsg(); /////////////////////////////////////////////////////////////////// // Verificar si fue rechazada y era un SAF que debia impactarse if ( Verify_Rejected_SAF( wRespCode ) ) // Forzar el envio a SAF LOCAL cuando es SAF online que no // pudo impactarse debido a cualquier tipo de error en el HOST. wRespCode = CISO_SYSTEM_FAILURE_I; /////////////////////////////////////////////////////////////////// // Backup de resultado de ejecucion hacia la clase base wProcRespCde = wRespCode; // Retornar codigo de rta. return (wRespCode);}//end-ProcessGeneric//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Mapear codigo de respuesta INDUS hacia RED LINK // El codigo INDUS es de 7 digitos, tal que si todos son blancos es aprobada,// y sino es un error de codigo alfanumerico que se mapea segun indican esta tablas///////////////////////////////////////////////////////////////////////////////////short TrxResINDUS::Mapear_RespCde_INDUS_REDLINK(char *szINDUS, char *szLINK, short nLen){ // Precondicion if(NULL == szINDUS || NULL == szLINK || nLen <= 0) // Postcondicion : 0=OK, -1=ERROR return (-1); // Inicializar con error generico strcpy( szLINK, CISO_GENERIC_ERROR); // Si son todos CEROS, es APROBADA if( strncmp(szINDUS,"000",3)==0 ) strcpy( szLINK, CISO_APPROVED); // Sino por omision se convierte el nro. de error else if( strncmp(szINDUS,"00",2)>=0 && strncmp(szINDUS,"99",2)<=0) strncpy( szLINK, szINDUS, 2); // Por omision es error generico else strcpy( szLINK, CISO_GENERIC_ERROR); //////////////////////////////////////////////////////////////// // Postcondicion : 0=OK, -1=ERROR return (0);};///////////////////////////////////////////////////////////////////////////////////////////////// Conexion con INDUS AS-400// Retorna ERROR ISO por procesamiento aprobado o no,////////////////////////////////////////////////////////////////////////////////////////////////WORD TrxResINDUS::EnviarYRecibirMsg(char szIPBackEnd[], unsigned short usPortBackEnd) { //////////////////////////////////////////////////////// // Estructura de datos para parser CBLSERVER //////////////////////////////////////////////////////// typedef struct CBLServerMsg_tag { char chTipoLinea1; // Fijo "1" char chPipe1; // Pipe char chCodigoProceso[11]; // Fijo "UGLNK000101" char chPipe2; // Pipe char chCodigoSucursal[8]; // Fijo "00000000" char chPipe3; // Pipe char chIdUsuario[8]; // Fijo "LINK" char chPipe4; // Pipe char chDireccionIP[20]; // char chPipe5; // Pipe char chNumeroTransaccion[15]; // char chNewLine; // New Line - Line Feed /*char chTipoLinea2;*/ // Fijo "2" msgEXTRACT extractBuff; // Registro EXTRACT } CBLServerMsg_t; char szCBLServerMsg[sizeof(CBLServerMsg_t)+1] = { //....:....1....:....2....:....3....:....4....:....5....:....6....:....7....:....8 "1|UGLNK000101|00000000|LINK | | \n" //....:....1....:....2....:....3....:....4....:....5....:....6....:....7....:....8 }; char *pszCBLServerMsg = szCBLServerMsg; CBLServerMsg_t *pCBLServerMsg = (CBLServerMsg_t *)szCBLServerMsg; //////////////////////////////////////////////////////// // Estructura EXTRACT local msgEXTRACT extractBuff; // Registro EXTRACT char *pszExtractBuff = (char *)&extractBuff; // Saldo de respuesta en campo AMT_3, formato ISO de 12 digitos TRAN_AMT *psztTran_Amt = (TRAN_AMT *)extractBuff.cuerpo.AMT_3; // Variables de soporte int iLenBuff = 0, iRetval = 0; WORD wBuff = 0, wRespCode = CISO_EXTERNAL_DECLINE_I ; /* respuesta default */ char szMsgTypeID[4+1] = {0}, szRespCode[8] = { CISO_GENERIC_ERROR }; /* preasignado error="05" */ // Constantes de soporte const boolean_t cbCONNECT_BY_TRX = is_true; /* conectarse por cada trx ? */#ifdef _DEBUG_CBL_MSG_ /***********************************************************************/ // Logg interno contra el mainframe, a nivel DUMP, solo para DEBUG FILE *hCBLFile = fopen(_CBLFILENAME_,"a+"); /***********************************************************************/#endif // _DEBUG_CBL_MSG_ /***********************************************************************/ /* Precondicion = Descomponer mensaje ISO-8583 en campos estructurados */ wRespCode = ProcessInit(); /***********************************************************************/ /* default de procesamiento del autorizador back end */ shAuthRespCde = TCP4U_SUCCESS; /***********************************************************************/ /* Comienzo a procesar trx. */ glLogg.Put("############# PARSEO DE TRX INDUS-ATM-POS #############\n"); /* Configurar direccion del Back End de autorizacion */ if(szIPBackEnd != NULL) tcpConn.setHost( szIPBackEnd ); if(usPortBackEnd > 0) tcpConn.setUsPort( usPortBackEnd ); /* Conectar al Back End de autorizacion, si no esta conectado ya */ if ( tcpConn.getMyActiveSock() != 0 && cbCONNECT_BY_TRX ) { glLogg.Put("### Conexion-Desconexion transaccion a transaccion ###\n"); tcpConn.disconnect( ); }; /* Conectar al Back End de autorizacion, si no esta conectado ya */ if ( tcpConn.getMyActiveSock() == 0 ) { /* Conectar al Back End de autorizacion, si no esta conectado ya */ tcpConn.connect( ); if( tcpConn.getIrc() != TCP4U_SUCCESS ) { glLogg.Put("### No se pudo conectar, error=<%i>, IP=<%s:%i> ###\n", tcpConn.getIrc() , tcpConn.getHost(), tcpConn.getUsPort() ); ////////////////////////////////////////////////////////////////////////// // Formatear campo ISO #44, RESP_DATA, saldo y disponible FormatField44_RESP_DATA( NULL, NULL ); // Formatear campo ISO #122, SECNDRY_RSRVD3_PRVT FormatField122_SECNDRY_RSRVD3_PRVT(); // Formatear campo ISO #123, SECNDRY_RSRVD4_PRVT, "DEPOSIT AMMOUNT" FormatField123_SECNDRY_RSRVD4_PRVT(); // Borrar campos no validos en la rta. : 43,48,52,63 isoMsg.DeleteField ( 43 ); isoMsg.DeleteField ( 48 ); isoMsg.DeleteField ( 52 ); isoMsg.DeleteField ( 63 ); // Borrar campo 120, OPCIONALMENTE PODRIAN NO VENIR EN UN REQUERIMIENTO isoMsg.DeleteField ( 120 ); ////////////////////////////////////////////////////////////////////////// // Destino no esta disponible, codigo de error para ISO8583 wRespCode = ( isoMsg.IsFinancialAdvice() || isoMsg.IsValidReversal() ) ? CISO_SYSTEM_FAILURE_I : CISO_DESTINY_NOT_AVAILABLE_I ; // Resultado del BACK END interno (-37268..+32767) shAuthRespCde = TCP4U_ERROR; // Retornar resultado ISO return (wRespCode); } else glLogg.Put("### Conectado OK ###\n"); };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -