📄 iso8583.cpp
字号:
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// IT24 Sistemas S.A.
// ISO-8583-Message Propietary Library
//
//
// Libreria Propietaria de Mensajes ISO-8583.
// Propietaria implica que, como es de esperar de un estandard, se
// respeta el formato, pero... se ajustan los mensajes a las necesidades
// de B24-HISO.
// Entonces, esta es la base que verifica los mensajes ISO-8583-B24
// hasta el Secondary BitMap inclusive, en forma parametrica, a traves de un profile
// o bien con valores por default. Esta tecnica utiliza una lista de strings de bitmaps
// para cada tipo de transaccion y verifica contra los bitmaps informados en el mensaje.
// El modulo se basa en B24-HISO Release 4, en cuanto a Type, Offset y Length
// de campos ISO8583, y la forma parametrica de cargar los bitmaps externamente (EMF).
// (*) Adaptados los BITMAPS especialmente por omision , para conexion con RED LINK S.A.
//
// Tarea Fecha Autor Observaciones
// (Inicial) 1997.09.23 mdc Base
// (Inicial) 1997.09.26 mdc Base
// (Inicial) 1997.09.29 mdc Extensiones Headers/TrxCode/Bitmap
// (Inicial) 1997.10.08 mdc Extensiones Headers/TrxCode/Bitmap
// (Inicial) 1997.10.15 mdc Recalculo de Offsets dinamicamente
// (Inicial) 1997.10.28 mdc Tipo de Campo (0=Fijo,1,2,3=Variable)
// (Inicial) 1997.10.30 mdc Extensiones Headers/TrxCode/Bitmap
// (Inicial) 1997.10.31 mdc Longitud de mensaje
// (Inicial) 1997.11.06 mdc Extensiones de Funcionalidad en Campos
// (Inicial) 1997.11.07 mdc Extensiones de Tipos de Mensaje
// (Inicial) 1997.11.18 mdc Establecer Codigo de Respuesta de Mensaje
// (Inicial) 1997.12.16 mdc Chequeos fuertes de rangos de copia en InsertField()
// (Inicial) 1998.04.01 mdc Aportes voluntarios AFJP=Bitmaps validos
// (Inicial) 1998.06.22 mdc Reemplazo de CHAR[] por BYTE[], e inclusion de typedefs.h
// (Inicial) 1998.06.23 mdc Ultimos Movimientos=Bitmaps validos
// (Inicial) 1998.06.24 mdc ISO-MsgTypes en defines
// (Alfa) 1998.06.25 mdc Bitmaps ULTMOV corregidos
// (Beta) 1998.07.02 mdc Bitmaps AFJP corregidos
// (Beta) 1998.07.31 mdc BitMapList para cada TranTyp ahora parametrizable (SOAT)
// (Beta) 1998.08.06 mdc Agrega BitMaps harcodeados del SOAT-NT
// (Beta) 1998.09.03 mdc Buffer expandido a 4096 kbytes y agregado Tipo de Campo 4
// (Beta) 1998.10.15 mdc Longitud campo #126 en 4 digitos
// (Beta) 1998.12.02 mdc Exceso de copia en campo #126
// (Beta) 1998.12.23 mdc Nulificacion de buffer antes de copiar datos externos
// (Beta) 1999.06.10 mdc GetBitmapDescription() retorno dependiente de parametros.
// (Beta) 1999.07.07 mdc Precondicion: Verificacion habilitada? : Parametrizable en .INI
// (Beta) 2000.02.15 mdc Parametrizacion en archivo independinte de plataforma (.TXT)
// (Release) 2001.02.14 mdc ::InitMessage() con "Product-Id"="02" = POS
// (Release) 2001.06.27 mdc Longitud campo #56 en 4 digitos
// (Release) 2005.08.24 mdc _SYSTEM_ATM_ = _SYSTEM_BASE_
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
/* Base24 4.0 ISO-8583 FIELD NUMBER DEFINITIONS */
/* position type offset and length */
///////////////////////////////////////////////////////////////////////
/* 1, 0, primary^field( secndry^bit^map ),
2, 2, primary^field( pan ),
3, 0, primary^field( proc^cde ),
4, 0, primary^field( tran^amt ),
5, 0, primary^field( setl^amt ),
6, 0, primary^field( bill^amt ),
7, 0, primary^field( xmit^dat^tim ),
8, 0, primary^field( bill^fee ),
9, 0, primary^field( setl^conv^rat ),
10, 0, primary^field( bill^conv^rat ),
11, 0, primary^field( trace^num ),
12, 0, primary^field( tran^tim ),
13, 0, primary^field( tran^dat ),
14, 0, primary^field( exp^dat ),
15, 0, primary^field( setl^dat ),
16, 0, primary^field( conv^dat ),
17, 0, primary^field( cap^dat ),
18, 0, primary^field( mrcht^typ^cde ),
19, 0, primary^field( acq^inst^cntry^cde ),
20, 0, primary^field( pan^ext^cntry^cde ),
21, 0, primary^field( frwd^inst^cntry^cde ),
22, 0, primary^field( entry^mde ),
23, 0, primary^field( mbr^num ),
24, 0, primary^field( netw^intl^id ),
25, 0, primary^field( pt^tran^spcl^cde ),
26, 0, primary^field( pos^pin^capture^cde ),
27, 0, primary^field( auth^id^resp^len ),
28, 0, primary^field( tran^fee ),
29, 0, primary^field( setl^fee ),
30, 0, primary^field( tran^proc^fee ),
31, 0, primary^field( setl^proc^fee ),
32, 2, primary^field( acq^inst^id ),
33, 2, primary^field( frwd^inst^id ),
34, 2, primary^field( pan^extnd ),
35, 2, primary^field( track2 ),
36, 3, primary^field( track3 ),
37, 0, primary^field( retrvl^ref^num ),
38, 0, primary^field( auth^id^resp ),
39, 0, primary^field( resp^cde ),
40, 0, primary^field( service^cde ),
41, 0, primary^field( term^id ),
42, 0, primary^field( crd^accpt^id^cde ),
43, 0, primary^field( crd^accpt^name^loc ),
44, 2, primary^field( resp^data ),
45, 2, primary^field( track1 ),
46, 3, primary^field( add^data^iso ),
47, 3, primary^field( add^data^natl ),
48, 3, primary^field( add^data^prvt ),
49, 0, primary^field( crncy^cde ),
50, 0, primary^field( setl^crncy ),
51, 0, primary^field( bill^crncy ),
52, 0, primary^field( pin ),
53, 0, primary^field( sec^cntrl^info ),
54, 3, primary^field( add^amts ),
55, 3, primary^field( pri^rsrvd1^iso ),
56, 3, primary^field( pri^rsrvd2^iso ),
57, 3, primary^field( pri^rsrvd1^natl ),
58, 3, primary^field( pri^rsrvd2^natl ),
59, 3, primary^field( pri^rsrvd3^natl ),
60, 3, primary^field( pri^rsrvd1^prvt ),
61, 3, primary^field( pri^rsrvd2^prvt ),
62, 3, primary^field( pri^rsrvd3^prvt ),
63, 3, primary^field( pri^rsrvd4^prvt ),
64, 0, primary^field( pri^mac^cde ),
65, -1, 0, 0, ! Not defined in the standard !
66, 0, secndry^field( setl^cde ),
67, 0, secndry^field( extd^pay^cde ),
68, 0, secndry^field( rcv^inst^cntry^cde ),
69, 0, secndry^field( setl^inst^cntry^cde ),
70, 0, secndry^field( netw^mgmt^cde ),
71, 0, secndry^field( msg^num ),
72, 0, secndry^field( lst^msg^num ),
73, 0, secndry^field( action^dat ),
74, 0, secndry^field( num^cr ),
75, 0, secndry^field( num^cr^rvsl ),
76, 0, secndry^field( num^db ),
77, 0, secndry^field( num^db^rvsl ),
78, 0, secndry^field( num^xfer ),
79, 0, secndry^field( num^xfer^rvsl ),
80, 0, secndry^field( num^inq ),
81, 0, secndry^field( num^auth ),
82, 0, secndry^field( amt^cr^proc^fees ),
83, 0, secndry^field( amt^cr^tran^fees ),
84, 0, secndry^field( amt^db^proc^fees ),
85, 0, secndry^field( amt^db^tran^fees ),
86, 0, secndry^field( amt^cr ),
87, 0, secndry^field( amt^cr^rvsl ),
88, 0, secndry^field( amt^db ),
89, 0, secndry^field( amt^db^rvsl ),
90, 0, secndry^field( orig^info ),
91, 0, secndry^field( file^updt^cde ),
92, 0, secndry^field( file^sec^cde ),
93, 0, secndry^field( resp^ind ),
94, 0, secndry^field( srv^ind ),
95, 0, secndry^field( replacement ),
96, 0, secndry^field( msg^sec^cde ),
97, 0, secndry^field( setl^amt^net ),
98, 0, secndry^field( payee ),
99, 2, secndry^field( setl^inst ),
100, 2, secndry^field( rcv^inst ),
101, 2, secndry^field( fname ),
102, 2, secndry^field( acct1 ),
103, 2, secndry^field( acct2 ),
104, 3, secndry^field( tran^descr ),
105, 3, secndry^field( secndry^rsrvd1^iso ),
106, 3, secndry^field( secndry^rsrvd2^iso ),
107, 3, secndry^field( secndry^rsrvd3^iso ),
108, 3, secndry^field( secndry^rsrvd4^iso ),
109, 3, secndry^field( secndry^rsrvd5^iso ),
110, 3, secndry^field( secndry^rsrvd6^iso ),
111, 3, secndry^field( secndry^rsrvd7^iso ),
112, 3, secndry^field( secndry^rsrvd1^natl ),
113, 3, secndry^field( secndry^rsrvd2^natl ),
114, 3, secndry^field( secndry^rsrvd3^natl ),
115, 3, secndry^field( secndry^rsrvd4^natl ),
116, 3, secndry^field( secndry^rsrvd5^natl ),
117, 3, secndry^field( secndry^rsrvd6^natl ),
118, 3, secndry^field( secndry^rsrvd7^natl ),
119, 3, secndry^field( secndry^rsrvd8^natl ),
120, 3, secndry^field( secndry^rsrvd1^prvt ),
121, 3, secndry^field( secndry^rsrvd2^prvt ),
122, 3, secndry^field( secndry^rsrvd3^prvt ),
123, 3, secndry^field( secndry^rsrvd4^prvt ),
124, 3, secndry^field( secndry^rsrvd5^prvt ),
125, 3, secndry^field( secndry^rsrvd6^prvt ),
126, 3, secndry^field( secndry^rsrvd7^prvt ),
127, 3, secndry^field( secndry^rsrvd8^prvt ),
128, 0, secndry^field( secndry^mac^cde ) ;
*/
///////////////////////////////////////////////////////////////////////
// Headers ANSI
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
// Headers propios
// Header Type Definitions
#include <qusrinc/typedefs.h>
// Aliases
#include <qusrinc/alias.h>
// ISO-8583
#include <qusrinc/iso8583.h>
// ISO8583 Customer definitions
#include <qusrinc/dpcsys.h>
// Longitud de bitmap segun ISO
#ifndef BITMAP_STR_LEN
#define BITMAP_STR_LEN 16
#endif
#ifndef min
#define min(x,y) (x<y) ? x : y
#define max(x,y) (x>y) ? x : y
#endif // min-max
// Clase ISO8583MSG
// Constructor
ISO8583MSG::ISO8583MSG(void)
{
// Inicializacion
memset((PBYTE)chMsg,0x00,sizeof chMsg); // Buffer Mensaje
cbMsgLen = 0; // Longitud Buffer
// Buffer auxiliar de copia
memset(chAuxMsg,0x00,sizeof chAuxMsg); // Buffer Mensaje
cbAuxMsgLen = 0; // Longitud Buffer
bCheckMessage = FALSE; // No checking by default
// Descripcion de Bitmaps y Campos por default
DefaultBitmapsDescriptions();
DefaultFieldsDescriptions();
}
// Constructor opcional
ISO8583MSG::ISO8583MSG(PBYTE lpbExtMsg ,
WORD cbExtLen ,
PSTR szFldDescFile)
{
// Inicializacion
memset((PBYTE)chMsg,0x00,sizeof chMsg); // Buffer Mensaje
cbMsgLen = 0; // Longitud Buffer
// Buffer auxiliar de copia
memset(chAuxMsg,0x00,sizeof chAuxMsg); // Buffer Mensaje
cbAuxMsgLen = 0; // Longitud Buffer
bCheckMessage = TRUE; // Checking by default
// Descripcion de Bitmaps y Campos por default
DefaultBitmapsDescriptions();
DefaultFieldsDescriptions();
// 緿escripcion de Bitmaps y Campos parametrica?
if(szFldDescFile)
{
GetAllBitmapsDescriptions(szFldDescFile);
GetFieldsDescription(szFldDescFile);
}//end-if-szFldDescFile
if((lpbExtMsg) && (cbExtLen))
// Copia de buffer plano externo
Import(lpbExtMsg, cbExtLen);
}
// Destructor
ISO8583MSG::~ISO8583MSG(void)
{
// ...nada especifico que desalojar dinamicamente...
}
// Importador
BOOL ISO8583MSG::Import(const PBYTE lpbExtMsg, WORD cbExtLen)
{
PBYTE lpbLocMsg = lpbExtMsg;
PBYTE lpbMsgETX = NULL;
// Copia de buffer plano, chequeando longitud
if( (lpbExtMsg) &&
(cbExtLen < sizeof(chMsg)) &&
(cbExtLen > 0) )
{
// Nulificacion
memset((PBYTE)chMsg,0,sizeof chMsg);
cbMsgLen = 0;
///////////////////////////////////////////////////////////////
memmove((PBYTE)chMsg, lpbLocMsg, cbExtLen);
chMsg[cbExtLen] = 0x00; // Fin de Mensaje es NULL
cbMsgLen = cbExtLen;
// Si hay caracteres ETX o longitudes invalidas
lpbMsgETX = (PBYTE)strchr((char *)lpbLocMsg, 0x03);
if(lpbMsgETX)
{
*lpbMsgETX = 0x00;
cbMsgLen = strlen((char *)lpbLocMsg);
}
// Si hay caracteres ETX o longitudes invalidas
lpbMsgETX = (PBYTE)strchr((char *)lpbLocMsg, 0x02);
if(lpbMsgETX)
{
*lpbMsgETX = 0x00;
cbMsgLen = strlen((char *)lpbLocMsg);
}
if(cbExtLen > CISOMESSAGESIZE-1)
cbExtLen = CISOMESSAGESIZE-1;
///////////////////////////////////////////////////////////////
// Postcondicion: Recalculo dinamico de offsets de Campos presentes Ok?
return RecalculateOffsets();
}
else
// Error
return (FALSE);
}
// Exportador
BOOL ISO8583MSG::Export(PBYTE lpbExtMsg, PWORD pcbExtMsgLen)
{
// Copia de buffer plano, chequeando longitud
if( (lpbExtMsg) &&
((*pcbExtMsgLen) >= cbMsgLen) &&
((*pcbExtMsgLen) > 0) &&
(cbMsgLen > 0))
{
// Copia
memmove(lpbExtMsg, (PBYTE)chMsg, cbMsgLen);
///////////////////////////////////////////////////////////////
#ifdef _USE_ETX_
lpbExtMsg[cbMsgLen ] = 0x03; // ETX
lpbExtMsg[cbMsgLen+1] = 0x00; // NULL
(*pcbExtMsgLen) = cbMsgLen +1 ;
#else
lpbExtMsg[cbMsgLen ] = 0x00; // NUL
(*pcbExtMsgLen) = cbMsgLen ;
#endif
///////////////////////////////////////////////////////////////
// Ok
return (TRUE);
}
else
// Error
return (FALSE);
}
// Valor de Campo
BOOL ISO8583MSG::GetField(WORD wField,PWORD pwFieldLen,
PBYTE szValue,WORD wValueLen)
{
// Precondicion: Mensaje existente
if(!cbMsgLen)
return (FALSE);
// Precondicion: campo valido
if(!IsValidField(wField))
return (FALSE);
// Precondicion: Destino no nulo
if((pwFieldLen == NULL) || (szValue == NULL) || (wValueLen == 0))
return (FALSE);
// Implicit Length
WORD wImpLength = 0;
// Propiedades del Campo especifico
WORD wType = FieldType(wField),
wOffset = FieldOffset(wField),
wLength = FieldLength(wField);
// Campo Fijo o Variable?
if (wType == 0)
// Campo fijo, longitud explicita
wImpLength = wLength;
else
// Campo variable, extraer longitud implicita
if(!GetImplicitLength(wField, &wImpLength))
return (FALSE);
// Chequeo de longitud de campo, y eventual correccion
if(wImpLength == 0)
return (FALSE);
else if((INT)wImpLength > ((INT)cbMsgLen - 32)) // ISO Header=32 bytes
{
// Correccion de longitud implicita al maximo posible
wImpLength = cbMsgLen - 32;
// Correccion de longitud en campo interno
fdFields[wField].Set(wType,wOffset,wLength);
} // end-if
// Chequeo de longitud implicita/explicita contra la maxima a copiar
if(wValueLen < wImpLength)
{
// Copia directa...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -