📄 iso8583.cpp
字号:
{
// Length de campo especifico
return(wField >= 1 && wField <= CISOFIELDS)
? fdFields[wField-1].wLength
: 0;
}
// Tipo de Campo en el Mensaje
WORD ISO8583MSG::FieldType(WORD wField) // Type
{
// Type de campo especifico
return(wField >= 1 && wField <= CISOFIELDS)
? fdFields[wField-1].wType
: (WORD)(-1);
}
// Longitud de Mensaje
WORD ISO8583MSG::MessageLength(void)
{
return (cbMsgLen);
}
// Descripcion de Campos, tomada desde un archivo de parametrizacion
// externo opcional. Por omision se asume la tabla de inicializacion
// descripta en ISO8583MSG::DefaultFieldDescriptions()
BOOL ISO8583MSG::GetFieldsDescription(PSTR szFldDescFile)
{
// Campos temporales de conversion
int iFldType = 0,
iFldOffset = 0,
iFldLength = 0,
iIndex = 0,
iCount = 0,
iFldCount = 0;
FILE *pfStream = NULL;
// Rango ISO de posicion de campo, 1..128 en vez de 0..127
BOOL bIs_ISO_Range = FALSE;
// Campos de conversion ASCII-binario
char szIndex[128] = {0},
szFldType[128] = {0},
szFldOffset[128] = {0},
szFldLength[128] = {0},
szBuffer[128] = {0};
// Abrir flujo de entrada
pfStream = fopen(szFldDescFile, "rt");
if(NULL == pfStream)
return (FALSE);
// Reset de Descripcion de Campos
for(iIndex=0; iIndex < CISOFIELDS; iIndex++)
fdFields[iIndex].Reset();
// Mientras haya datos... leerlos y cargarlos (siempre habra 4 por linea)
while( fgets( szBuffer, sizeof szBuffer, pfStream ) )
{
// Escaneo de parametros (siempre habra 4 por linea)
iCount = sscanf( szBuffer, "%s %s %s %s", szIndex, szFldType, szFldOffset, szFldLength);
// Verificar parametros (siempre habra 4 por linea)
if(iCount == EOF || iCount != 4)
continue;
// Suma contador
iFldCount++;
// Convierte asignaciones
iIndex = atoi(szIndex);
iFldType = atoi(szFldType);
iFldOffset = atoi(szFldOffset);
iFldLength = atoi(szFldLength);
// De posicion indice 0..127, no ISO 1..128
if(iIndex == 0 && bIs_ISO_Range == FALSE && iFldCount == 1)
bIs_ISO_Range = FALSE; // Basado en campo 0..127, no en campo 1..128
else if(iIndex == 1 && bIs_ISO_Range == FALSE && iFldCount == 1)
{
bIs_ISO_Range = TRUE; // Basado en campo 1..128, no en campo 0..127
iIndex--; // Ajustar ISO 1..128 a formato interno de indice 0..127
}
// De posicion ISO 1..128 a indice 0..127
else if( iIndex >= 1 && iIndex <= CISOFIELDS && bIs_ISO_Range == TRUE )
iIndex--; // Ajustar ISO 1..128 a formato interno de indice 0..127
// Son valores validos?
if(
((iFldType == (WORD)(-1)) || // Reservado,
((iFldType >= FIELD_TYPE_FIX && // De Longitud Fija o
iFldType <= FIELD_TYPE_VAR_MAX)) // Variable?
)
&&
(iFldLength >= 0 && iFldLength <= CISOMESSAGESIZE) // Longitud?
&&
(iFldOffset >= 0 && iFldOffset <= CISOMESSAGESIZE) ) // Desplazamiento?
{
// Copia de valores (Type,Offset,Length)
fdFields[iIndex].wType = iFldType;
fdFields[iIndex].wOffset = iFldOffset;
fdFields[iIndex].wLength = iFldLength;
// Backup de Descriptor de Campo
fdFieldsBkp[iIndex] = fdFields[iIndex];
}
else
{
// Cierre del flujo
fclose(pfStream);
pfStream = NULL;
// Error
return (FALSE);
};//end-if
};//while
// Cierre del flujo
fclose(pfStream);
pfStream = NULL;
// Retorno Ok
return (TRUE);
}
// Recalculo de Offset segun BitMaps actuales
BOOL ISO8583MSG::RecalculateOffsets(void)
{
// Precondicion: Mensaje presente
if(!cbMsgLen)
return (FALSE);
// Precondicion: Header valido
if( !IsValidHeader() )
return (FALSE);
// Desplazamiento de campos desde el inicio del mensaje
int iOffset = 32; // ISO-Fix-Header-Size
// Longitud de Campo temporal
WORD wFldLen = 0;
// Segun la descripcion inicial de Campos evaluada,
// recalcular los Offsets de los campos variables,
// si los hubiere segun el BitMap... segun los descriptores
// originales...
for(WORD iIndex=0; iIndex < CISOFIELDS; iIndex++)
{
// Restore de Descriptor original
fdFields[iIndex] = fdFieldsBkp[iIndex];
// Esta activo el campo? (ISO 1-128)
if(IsValidField(iIndex+1))
{
// Es campo de Longitud Fija?
if((fdFields[iIndex].wType == FIELD_TYPE_FIX) &&
(fdFields[iIndex].wOffset != 0) &&
(fdFields[iIndex].wLength != 0))
{
// Se establece el Offset dinamico...
fdFields[iIndex].wOffset = iOffset;
// ...y se lo recalcula en base al Length
iOffset += fdFields[iIndex].wLength;
}
// Es campo de Longitud Variable?
else if((fdFields[iIndex].wType >= FIELD_TYPE_VAR_MIN) &&
(fdFields[iIndex].wType <= FIELD_TYPE_VAR_MAX) &&
(fdFields[iIndex].wLength != 0))
{
// Se establece el Offset dinamico...
fdFields[iIndex].wOffset = iOffset;
// ... y se lo recalcula segun la Longitud Implicita
// ... mas el Tipo de Campo Variable {1,2,3} (digitos implicitos)
// (Field ISO 1..128, Index 0..127)
if(!GetImplicitLength(iIndex+1, &wFldLen))
{
/////////////////////////////////////////
// Precondicion: Verificacion habilitada?
if(!bCheckMessage)
return (TRUE);
/////////////////////////////////////////
return (FALSE);
};
// Longitud implicita
fdFields[iIndex].wLength = wFldLen + fdFields[iIndex].wType;
// ...y se recalcula el Offset, Longitud mas los digitos implicitos:
iOffset += wFldLen + fdFields[iIndex].wType;
}
// (Type!={0,1,2,3})&&(Offset=Length=0) no considerados
}//if
}//for
// 2001-06-23-mdc. Postcondicion: Offset valido?
return (iOffset < CISOMESSAGESIZE)
? TRUE
: FALSE;
// Postcondicion: Offset valido?
return (iOffset < CISOMESSAGESIZE && iOffset < cbMsgLen)
? TRUE
: FALSE;
}
// Offsets & Lengths por default.
// Esta tabla de inicializacion de campos ISO-8583 de B24-HISO Release 4
// fue obtenida haciendo el siguiente comando en el BIND, en Tandem,
// "DUMP DATA BIT^MAP^TABLE^G 0,1001 DECIMAL FROM ATHISOO"
//
// TYPE especifica Longitud de Campo: {0=Fijo, 1,2,3,4=Variable} con 1,2,3,4 digitos
// implicitos: esto es, tomando los bytes y convertiendolos a entero.
// OFFSET especifica el desplazamiento desde el inicio del buffer.
// Se acumulan los desplazamientos anteriores y se suma la longitud.
// LENGTH especifica la longitud maxima admitida.
BOOL ISO8583MSG::DefaultFieldsDescriptions(void)
{
// Recordar que los equivalentes campos ISO-8583 son de 1 a 128
// Originales:
// Campo Numero ( Type, Offset, Length )
fdFieldsBkp[0].Set( 0, 32, 16 );
fdFieldsBkp[1].Set( 2, 48, 21 );
fdFieldsBkp[2].Set( 0, 69, 6 );
fdFieldsBkp[3].Set( 0, 75, 12 );
fdFieldsBkp[4].Set( 0, 87, 12 );
fdFieldsBkp[5].Set( 0, 99, 12 );
fdFieldsBkp[6].Set( 0, 111, 10 );
fdFieldsBkp[7].Set( 0, 121, 8 );
fdFieldsBkp[8].Set( 0, 129, 8 );
fdFieldsBkp[9].Set( 0, 137, 8 );
fdFieldsBkp[10].Set( 0, 145, 6 );
fdFieldsBkp[11].Set( 0, 151, 6 );
fdFieldsBkp[12].Set( 0, 157, 4 );
fdFieldsBkp[13].Set( 0, 161, 4 );
fdFieldsBkp[14].Set( 0, 165, 4 );
fdFieldsBkp[15].Set( 0, 169, 4 );
fdFieldsBkp[16].Set( 0, 173, 4 );
fdFieldsBkp[17].Set( 0, 177, 4 );
fdFieldsBkp[18].Set( 0, 181, 3 );
fdFieldsBkp[19].Set( 0, 184, 3 );
fdFieldsBkp[20].Set( 0, 187, 3 );
fdFieldsBkp[21].Set( 0, 190, 3 );
fdFieldsBkp[22].Set( 0, 193, 3 );
fdFieldsBkp[23].Set( 0, 196, 3 );
fdFieldsBkp[24].Set( 0, 199, 2 );
fdFieldsBkp[25].Set( 0, 201, 2 );
fdFieldsBkp[26].Set( 0, 203, 1 );
fdFieldsBkp[27].Set( 0, 204, 9 );
fdFieldsBkp[28].Set( 0, 213, 9 );
fdFieldsBkp[29].Set( 0, 222, 9 );
fdFieldsBkp[30].Set( 0, 231, 9 );
fdFieldsBkp[31].Set( 2, 240, 13 );
fdFieldsBkp[32].Set( 2, 253, 13 );
fdFieldsBkp[33].Set( 2, 266, 30 );
fdFieldsBkp[34].Set( 2, 296, 39 );
fdFieldsBkp[35].Set( 3, 335, 107 );
fdFieldsBkp[36].Set( 0, 442, 12 );
fdFieldsBkp[37].Set( 0, 454, 6 );
fdFieldsBkp[38].Set( 0, 460, 2 );
fdFieldsBkp[39].Set( 0, 462, 3 );
fdFieldsBkp[40].Set( 0, 465, 16 );
fdFieldsBkp[41].Set( 0, 481, 15 );
fdFieldsBkp[42].Set( 0, 496, 40 );
fdFieldsBkp[43].Set( 2, 536, 27 );
fdFieldsBkp[44].Set( 2, 563, 78 );
fdFieldsBkp[45].Set( 3, 641, 103 );
fdFieldsBkp[46].Set( 3, 744, 103 );
fdFieldsBkp[47].Set( 3, 847, 103 );
fdFieldsBkp[48].Set( 0, 950, 3 );
fdFieldsBkp[49].Set( 0, 953, 3 );
fdFieldsBkp[50].Set( 0, 956, 3 );
fdFieldsBkp[51].Set( 0, 959, 16 );
fdFieldsBkp[52].Set( 0, 975, 16 );
fdFieldsBkp[53].Set( 3, 991, 123 );
fdFieldsBkp[54].Set( 3, 1114, 363 );
#if defined( _SYSTEM_H24_ )
fdFieldsBkp[55].Set( 4, 1477, 103 ); // Campo especialmente ampliado para H24
#elif defined( _SYSTEM_SOAT_ ) || defined( _SYSTEM_BASE_ )
fdFieldsBkp[55].Set( 3, 1477, 103 );
#elif defined( _SYSTEM_ATM_ )
fdFieldsBkp[55].Set( 3, 1477, 103 );
#else
#error "Sin definir el Sistema bajo el cual se adapta la clase ISO8583"
#endif
fdFieldsBkp[56].Set( 3, 1580, 103 );
fdFieldsBkp[57].Set( 3, 1683, 103 );
fdFieldsBkp[58].Set( 3, 1786, 103 );
fdFieldsBkp[59].Set( 3, 1889, 103 );
fdFieldsBkp[60].Set( 3, 1992, 103 );
fdFieldsBkp[61].Set( 3, 2095, 103 );
fdFieldsBkp[62].Set( 3, 2198, 600 );
fdFieldsBkp[63].Set( 0, 2798, 16 );
fdFieldsBkp[64].Set( 65535, 0, 0 ); // Campo reservado en el estandard ISO
fdFieldsBkp[65].Set( 0, 2814, 1 );
fdFieldsBkp[66].Set( 0, 2815, 2 );
fdFieldsBkp[67].Set( 0, 2817, 3 );
fdFieldsBkp[68].Set( 0, 2820, 3 );
fdFieldsBkp[69].Set( 0, 2823, 3 );
fdFieldsBkp[70].Set( 0, 2826, 4 );
fdFieldsBkp[71].Set( 0, 2830, 4 );
fdFieldsBkp[72].Set( 0, 2834, 6 );
fdFieldsBkp[73].Set( 0, 2840, 10 );
fdFieldsBkp[74].Set( 0, 2850, 10 );
fdFieldsBkp[75].Set( 0, 2860, 10 );
fdFieldsBkp[76].Set( 0, 2870, 10 );
fdFieldsBkp[77].Set( 0, 2880, 10 );
fdFieldsBkp[78].Set( 0, 2890, 10 );
fdFieldsBkp[79].Set( 0, 2900, 10 );
fdFieldsBkp[80].Set( 0, 2910, 10 );
fdFieldsBkp[81].Set( 0, 2920, 12 );
fdFieldsBkp[82].Set( 0, 2932, 12 );
fdFieldsBkp[83].Set( 0, 2944, 12 );
fdFieldsBkp[84].Set( 0, 2956, 12 );
fdFieldsBkp[85].Set( 0, 2968, 16 );
fdFieldsBkp[86].Set( 0, 2984, 16 );
fdFieldsBkp[87].Set( 0, 3000, 16 );
fdFieldsBkp[88].Set( 0, 3016, 16 );
fdFieldsBkp[89].Set( 0, 3032, 42 );
fdFieldsBkp[90].Set( 0, 3074, 1 );
fdFieldsBkp[91].Set( 0, 3075, 2 );
fdFieldsBkp[92].Set( 0, 3077, 5 );
fdFieldsBkp[93].Set( 0, 3082, 7 );
fdFieldsBkp[94].Set( 0, 3089, 42 );
fdFieldsBkp[95].Set( 0, 3131, 16 );
fdFieldsBkp[96].Set( 0, 3147, 17 );
fdFieldsBkp[97].Set( 0, 3164, 25 );
fdFieldsBkp[98].Set( 2, 3189, 13 );
fdFieldsBkp[99].Set( 2, 3202, 13 );
fdFieldsBkp[100].Set( 2, 3215, 19 );
fdFieldsBkp[101].Set( 2, 3234, 30 );
fdFieldsBkp[102].Set( 2, 3264, 30 );
fdFieldsBkp[103].Set( 3, 3294, 103 );
fdFieldsBkp[104].Set( 3, 3397, 103 );
fdFieldsBkp[105].Set( 3, 3500, 103 );
fdFieldsBkp[106].Set( 3, 3603, 103 );
fdFieldsBkp[107].Set( 3, 3706, 103 );
fdFieldsBkp[108].Set( 3, 3809, 103 );
fdFieldsBkp[109].Set( 3, 3912, 103 );
fdFieldsBkp[110].Set( 3, 4015, 103 );
fdFieldsBkp[111].Set( 3, 4118, 203 );
fdFieldsBkp[112].Set( 3, 4321, 103 );
fdFieldsBkp[113].Set( 3, 4424, 103 );
fdFieldsBkp[114].Set( 3, 4527, 103 );
fdFieldsBkp[115].Set( 3, 4630, 103 );
fdFieldsBkp[116].Set( 3, 4733, 103 );
fdFieldsBkp[117].Set( 3, 4836, 103 );
fdFieldsBkp[118].Set( 3, 4939, 103 );
fdFieldsBkp[119].Set( 3, 5042, 153 );
fdFieldsBkp[120].Set( 3, 5195, 153 );
fdFieldsBkp[121].Set( 3, 5348, 153 );
fdFieldsBkp[122].Set( 3, 5501, 458 );
fdFieldsBkp[123].Set( 3, 5959, 687 );
fdFieldsBkp[124].Set( 3, 6646, 683 );
#if defined ( _SYSTEM_BASE_ ) || defined ( _SYSTEM_ATM_ )
fdFieldsBkp[125].Set( 3, 7329, 683 );
fdFieldsBkp[126].Set( 3, 8012, 203 );
fdFieldsBkp[127].Set( 0, 8215, 16 );
#elif defined( _SYSTEM_SOAT_ )
fdFieldsBkp[125].Set( 4, 7329,1500 ); // Campo especialmente ampliado para SOAT
fdFieldsBkp[126].Set( 3, 8829, 203 );
fdFieldsBkp[127].Set( 0, 9032, 16 );
#else
#error "Sin definir el Sistema bajo el cual se adapta la clase ISO8583"
#endif // _SOAT_SYSTEM_
// Siempre OK
return (TRUE);
}
// TypeId de Msg
BOOL ISO8583MSG::GetMsgTypeId(PBYTE lpszValue,WORD wValueLen)
{
// Precondicion: Mensaje presente
if(!cbMsgLen)
return (FALSE);
// Precondicion: ISO-Header OK
if(!IsValidHeader())
return (FALSE);
// Precondicion: Longitud suficiente: Son 4 de codigo mas 1 de NULL
if( wValueLen < 5 )
return (FALSE);
// Message-Type-Identifier [12..15=4]
memmove((PBYTE)lpszValue, (PBYTE)&chMsg[12], 4);
// Null-terminated array of bytes
memset((PBYTE)lpszValue+4,0,1);
// Ok
return (TRUE);
}
// Establecer TypeId de Msg
BOOL ISO8583MSG::SetMsgTypeId
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -