📄 iso8583.c
字号:
/*****************************************************************************/
/* ISO-8583 Packet / Unpacket Function Library - Internal Data */
/* ------------------------------------------------------------------------- */
/* Author: Frank Ho <frank_ho@263.net>, March 20, 2002 */
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include "applib.h"
#include "iso8583.h"
/*===========================================================================*/
/* ISO8583 Version Definition */
/*---------------------------------------------------------------------------*/
#define CFGBUFSZ 128 // Line size of config file
#define CFGRMSYM '#' // Remark symbol of config file
#define MAXFIELD 128 // Maximum field number
#define SECFIELD 64 // Field count per section
#define SECCOUNT ( MAXFIELD / SECFIELD ) // Number of sections
#define BMPBYTES ( MAXFIELD >> 3 ) // Total bitmap bytes
#define BMPBPSEC ( SECFIELD >> 3 ) // Bitmap bytes per section
#define MAXFTCNT 16 // Maximum field type count
#define STDFTCNT 5 // Standard filed type count
/*===========================================================================*/
/* ISO8583 Macro Definition */
/*---------------------------------------------------------------------------*/
#define BMPINDICATOR(x) ( ( (x) / SECFIELD - 1 ) * SECFIELD )
/*===========================================================================*/
/* Other Constants Definition */
/*---------------------------------------------------------------------------*/
#define DATBUFSZ 1024
/*===========================================================================*/
/* Data Structure Definition */
/*---------------------------------------------------------------------------*/
typedef struct {
unsigned char Type; // Field Type
ISO8583Callback Pack; // Field Packer
ISO8583Callback Unpack; // Field Unpacker
ISO8583Callback MACPck; // Field MAC Packer
} ISO8583TYPE;
typedef struct {
unsigned char Fmt; // Field Format, use FF_*
unsigned char Type; // Field Type, use FT_*
unsigned short Len; // Length of Fixed or Max. Len. of Var. data
} ISO8583FLDDEF;
typedef struct {
unsigned char Type; // Data Type, use DT_*
unsigned short Size; // Data/Buffer Size of DT_CHAR or DT_STRING
void *Data; // Data Pointer
} ISO8583FLDDAT;
/*===========================================================================*/
/* Field Definition List */
/*---------------------------------------------------------------------------*/
static ISO8583FLDDEF FldStd[] = {
{ FF_FIX, FT_BIN, 8 }, // 1: sencondary bitmap
{ FF_LL, FT_NUM, 19 }, // 2: primary account number (PAN)
{ FF_FIX, FT_NUM, 6 }, // 3: processing code
{ FF_FIX, FT_AMT, 12 }, // 4: amount, transaction
{ FF_FIX, FT_AMT, 12 }, // 5: amount, settlement
{ FF_FIX, FT_AMT, 12 }, // 6: amount, cardholder billing
{ FF_FIX, FT_NUM, 10 }, // 7: transmission date and time (GMT)
{ FF_FIX, FT_AMT, 8 }, // 8: amount, cardholder billing fee
{ FF_FIX, FT_NUM, 8 }, // 9: conversion rate, settlement
{ FF_FIX, FT_NUM, 8 }, // 10: conversion rate, cardholder billing
{ FF_FIX, FT_NUM, 6 }, // 11: system trace audit number
{ FF_FIX, FT_NUM, 6 }, // 12: time, local transaction
{ FF_FIX, FT_NUM, 4 }, // 13: date, local transaction
{ FF_FIX, FT_NUM, 4 }, // 14: date, expiration
{ FF_FIX, FT_NUM, 4 }, // 15: date, settlement
{ FF_FIX, FT_NUM, 4 }, // 16: date, conversion
{ FF_FIX, FT_NUM, 4 }, // 17: date, capture
{ FF_FIX, FT_NUM, 4 }, // 18: merchant type
{ FF_FIX, FT_NUM, 3 }, // 19: country code, acquiring institution
{ FF_FIX, FT_NUM, 3 }, // 20: country code, PAN extended
{ FF_FIX, FT_NUM, 3 }, // 21: country code, forwarding institution
{ FF_FIX, FT_NUM, 3 }, // 22: point of service entry mode
{ FF_FIX, FT_NUM, 3 }, // 23: application PAN number
{ FF_FIX, FT_NUM, 3 }, // 24: network international identifier
{ FF_FIX, FT_NUM, 2 }, // 25: point of service condition code
{ FF_FIX, FT_NUM, 2 }, // 26: point of service PIN capture code
{ FF_FIX, FT_NUM, 1 }, // 27: authorizing Id response length
{ FF_FIX, FT_AMT, 8 }, // 28: amount, transaction fee
{ FF_FIX, FT_AMT, 8 }, // 29: amount, settlement fee
{ FF_FIX, FT_AMT, 8 }, // 30: amount, transaction processing fee
{ FF_FIX, FT_AMT, 8 }, // 31: amount, settlement processing fee
{ FF_LL, FT_NUM, 11 }, // 32: acquiring institution Id code
{ FF_LL, FT_NUM, 11 }, // 33: forwarding institution Id code
{ FF_LL, FT_NUM, 28 }, // 34: primary account number, extended
{ FF_LL, FT_ANS, 37 }, // 35: track 2 data
{ FF_LLL, FT_ANS, 104 }, // 36: track 3 data
{ FF_FIX, FT_ANS, 12 }, // 37: retrieval reference number
{ FF_FIX, FT_ANS, 6 }, // 38: authorization Id response
{ FF_FIX, FT_ANS, 2 }, // 39: response code
{ FF_FIX, FT_ANS, 3 }, // 40: service restriction code
{ FF_FIX, FT_ANS, 8 }, // 41: card acceptor terminal Id
{ FF_FIX, FT_ANS, 15 }, // 42: card acceptor Id code
{ FF_FIX, FT_ANS, 40 }, // 43: card acceptor name/location
{ FF_LL, FT_ANS, 25 }, // 44: additional response data
{ FF_LL, FT_ANS, 76 }, // 45: track 1 data
{ FF_LLL, FT_ANS, 999 }, // 46: additional data, ISO
{ FF_LLL, FT_ANS, 999 }, // 47: additional data, national
{ FF_LLL, FT_ANS, 999 }, // 48: additional data, private
{ FF_FIX, FT_ANS, 3 }, // 49: currency code, transaction
{ FF_FIX, FT_ANS, 3 }, // 50: currency code, settlement
{ FF_FIX, FT_ANS, 3 }, // 51: currency code, cardholder billing
{ FF_FIX, FT_BIN, 8 }, // 52: personal Id number (PIN) data
{ FF_FIX, FT_NUM, 18 }, // 53: security related control information
{ FF_LLL, FT_ANS, 120 }, // 54: additional amounts
{ FF_NONE, FT_NONE, 0 }, // 55: RESERVED, ISO
{ FF_NONE, FT_NONE, 0 }, // 56: RESERVED, ISO
{ FF_NONE, FT_NONE, 0 }, // 57: RESERVED, national
{ FF_NONE, FT_NONE, 0 }, // 58: RESERVED, national
{ FF_NONE, FT_NONE, 0 }, // 59: RESERVED, national
{ FF_LLL, FT_ANS, 999 }, // 60: RESERVED, private
{ FF_LLL, FT_WKM, 999 }, // 61: RESERVED, private
//{ FF_LLL, FT_ANS, 999 }, // 61: RESERVED, private
{ FF_LLL, FT_ANS, 999 }, // 62: RESERVED, private
{ FF_LLL, FT_ANS, 999 }, // 63: RESERVED, private
{ FF_FIX, FT_BIN, 8 }, // 64: message authentication code
{ FF_FIX, FT_BIN, 8 }, // 65: tertiary bitmap
{ FF_FIX, FT_NUM, 1 }, // 66: settlement code
{ FF_FIX, FT_NUM, 2 }, // 67: extended payment code
{ FF_FIX, FT_NUM, 3 }, // 68: country code, receiving institution
{ FF_FIX, FT_NUM, 3 }, // 69: country code, settlement institution
{ FF_FIX, FT_NUM, 3 }, // 70: network management information code
{ FF_FIX, FT_NUM, 4 }, // 71: message number
{ FF_FIX, FT_NUM, 4 }, // 72: message number, last
{ FF_FIX, FT_NUM, 6 }, // 73: date, action
{ FF_FIX, FT_NUM, 10 }, // 74: credits, number
{ FF_FIX, FT_NUM, 10 }, // 75: credits, reversal number
{ FF_FIX, FT_NUM, 10 }, // 76: debits, number
{ FF_FIX, FT_NUM, 10 }, // 77: debits, reversal number
{ FF_FIX, FT_NUM, 10 }, // 78: transfer, number
{ FF_FIX, FT_NUM, 10 }, // 79: transfer, reversal number
{ FF_FIX, FT_NUM, 10 }, // 80: inquiries, number
{ FF_FIX, FT_NUM, 10 }, // 81: authorizations, number
{ FF_FIX, FT_AMT, 12 }, // 82: credits, amount, processing fee
{ FF_FIX, FT_AMT, 12 }, // 83: credits, amount, transaction fee
{ FF_FIX, FT_AMT, 12 }, // 84: debits, amount, processing fee
{ FF_FIX, FT_AMT, 12 }, // 85: debits, amount, transaction fee
{ FF_FIX, FT_AMT, 15 }, // 86: credits, amount
{ FF_FIX, FT_AMT, 15 }, // 87: credits, reversal amount
{ FF_FIX, FT_AMT, 15 }, // 88: debits, amount
{ FF_FIX, FT_AMT, 15 }, // 89: debits, reversal amount
{ FF_FIX, FT_NUM, 42 }, // 90: original data elements
{ FF_FIX, FT_ANS, 1 }, // 91: file update code
{ FF_FIX, FT_NUM, 2 }, // 92: file security code
{ FF_FIX, FT_NUM, 5 }, // 93: response indicatior
{ FF_FIX, FT_ANS, 7 }, // 94: service indicator
{ FF_FIX, FT_ANS, 42 }, // 95: replacement amounts
{ FF_FIX, FT_ANS, 8 }, // 96: message security code
{ FF_FIX, FT_AMT, 16 }, // 97: amount, net settlement
{ FF_FIX, FT_ANS, 25 }, // 98: payee
{ FF_LL, FT_ANS, 11 }, // 99: settlement institution Id code
{ FF_LL, FT_NUM, 11 }, // 100: receiving institution Id code
{ FF_LL, FT_ANS, 17 }, // 101: file name
{ FF_LL, FT_ANS, 28 }, // 102: account Id 1 (from)
{ FF_LL, FT_ANS, 28 }, // 103: account Id 2 (to)
{ FF_LLL, FT_ANS, 999 }, // 104: transaction description
{ FF_NONE, FT_NONE, 0 }, // 105: RESERVED, ISO
{ FF_NONE, FT_NONE, 0 }, // 106: RESERVED, ISO
{ FF_NONE, FT_NONE, 0 }, // 107: RESERVED, ISO
{ FF_NONE, FT_NONE, 0 }, // 108: RESERVED, ISO
{ FF_NONE, FT_NONE, 0 }, // 109: RESERVED, ISO
{ FF_NONE, FT_NONE, 0 }, // 110: RESERVED, ISO
{ FF_NONE, FT_NONE, 0 }, // 111: RESERVED, ISO
{ FF_NONE, FT_NONE, 0 }, // 112: RESERVED, national
{ FF_NONE, FT_NONE, 0 }, // 113: RESERVED, national
{ FF_NONE, FT_NONE, 0 }, // 114: RESERVED, national
{ FF_NONE, FT_NONE, 0 }, // 115: RESERVED, national
{ FF_NONE, FT_NONE, 0 }, // 116: RESERVED, national
{ FF_NONE, FT_NONE, 0 }, // 117: RESERVED, national
{ FF_NONE, FT_NONE, 0 }, // 118: RESERVED, national
{ FF_NONE, FT_NONE, 0 }, // 119: RESERVED, national
{ FF_LLL, FT_ANS, 999 }, // 120: RESERVED, private
{ FF_LLL, FT_ANS, 999 }, // 121: RESERVED, private
{ FF_LLL, FT_ANS, 999 }, // 122: RESERVED, private
{ FF_LLL, FT_ANS, 999 }, // 123: RESERVED, private
{ FF_LLL, FT_ANS, 999 }, // 124: RESERVED, private
{ FF_LLL, FT_ANS, 999 }, // 125 RESERVED, private
{ FF_LLL, FT_ANS, 999 }, // 126: RESERVED, private
{ FF_LLL, FT_ANS, 999 }, // 127: RESERVED, private
{ FF_FIX, FT_BIN, 8 } // 128: message authentication code
};
/*===========================================================================*/
/* Local Function - Standard Field Packer */
/*---------------------------------------------------------------------------*/
static int StdFldPacker( unsigned char FldFmt, unsigned char FldType,
unsigned int FldLen,
const char *Data, unsigned int *DatSize,
char *Buffer, unsigned int *BufSize )
{
unsigned int s;
char t[8];
switch ( FldFmt ) {
case FF_FIX:
if ( *DatSize != FldLen )
return -1;
if ( *BufSize < FldLen )
return -1;
memcpy( Buffer, Data, FldLen );
*BufSize = FldLen;
return 0;
case FF_LL:
if ( *DatSize > FldLen )
return -1;
s = *DatSize + 2;
if ( *BufSize < s )
return -1;
sprintf( t, "%02u", *DatSize );
memcpy( Buffer, t, 2 );
memcpy( Buffer + 2, Data, *DatSize );
*BufSize = s;
return 0;
case FF_LLL:
if ( *DatSize > FldLen )
return -1;
s = *DatSize + 3;
if ( *BufSize < s )
return -1;
sprintf( t, "%03u", *DatSize );
memcpy( Buffer, t, 3 );
memcpy( Buffer + 3, Data, *DatSize );
*BufSize = s;
return 0;
}
return -1;
}
/*===========================================================================*/
/* Local Function - Standard Field Unpacker */
/*---------------------------------------------------------------------------*/
static int StdFldUnpacker( unsigned char FldFmt, unsigned char FldType,
unsigned int FldLen,
const char *Data, unsigned int *DatSize,
char *Buffer, unsigned int *BufSize )
{
unsigned int s, l;
char t[8];
switch ( FldFmt ) {
case FF_FIX:
if ( *DatSize < FldLen )
return -1;
if ( *BufSize < FldLen )
return -1;
memcpy( Buffer, Data, FldLen );
*DatSize = FldLen;
*BufSize = FldLen;
return 0;
case FF_LL:
if ( *DatSize < 2 )
return -1;
memcpy( t, Data, 2 );
t[2] = 0;
if ( sscanf( t, "%u", &l ) != 1 )
return -1;
s = l + 2;
if ( *DatSize < s )
return -1;
if ( *BufSize < l )
return -1;
memcpy( Buffer, Data + 2, l );
*DatSize = s;
*BufSize = l;
return 0;
case FF_LLL:
if ( *DatSize < 3 )
return -1;
memcpy( t, Data, 3 );
t[3] = 0;
if ( sscanf( t, "%u", &l ) != 1 )
return -1;
s = l + 3;
if ( *DatSize < s )
return -1;
if ( *BufSize < l )
return -1;
memcpy( Buffer, Data + 3, l );
*DatSize = s;
*BufSize = l;
return 0;
}
return -1;
}
/*===========================================================================*/
/* Field Type Definition List */
/*---------------------------------------------------------------------------*/
static ISO8583TYPE FldTypeLst[MAXFTCNT] = {
{ FT_NONE, NULL, NULL, NULL },
{ FT_BIN, StdFldPacker, StdFldUnpacker, StdFldPacker },
{ FT_ANS, StdFldPacker, StdFldUnpacker, StdFldPacker },
{ FT_NUM, StdFldPacker, StdFldUnpacker, StdFldPacker },
{ FT_AMT, StdFldPacker, StdFldUnpacker, StdFldPacker }
};
/*===========================================================================*/
/* Data Definition */
/*---------------------------------------------------------------------------*/
static int ConfigFlag = 0;
static int InitFlag = 0;
static int FldTypeCnt = STDFTCNT;
static int BufDatSize;
static char DataBuffer[DATBUFSZ];
static char BMP[BMPBYTES];
static ISO8583FLDDEF FldDef[MAXFIELD];
static ISO8583FLDDAT FldDat[MAXFIELD];
/*===========================================================================*/
/* Local Function - Check Field Type */
/*---------------------------------------------------------------------------*/
static int CheckFieldType( unsigned char FldType )
{
int i;
for ( i = 0; i < FldTypeCnt; i ++ )
if ( FldTypeLst[i].Type == FldType )
break;
return i;
}
/*===========================================================================*/
/* Local Function - Check Field Number */
/*---------------------------------------------------------------------------*/
static int CheckFieldNumber( unsigned char FieldNum )
{
if ( FieldNum < 1 || FieldNum > MAXFIELD )
return -1;
FieldNum = ( FieldNum - 1 ) % SECFIELD;
if ( FieldNum == 0 || FieldNum == SECFIELD - 1 )
return -1;
return 0;
}
/*===========================================================================*/
/* Local Function - Convert Data To Data Buffer */
/*---------------------------------------------------------------------------*/
static void CvtDatToDataBuffer( ISO8583FLDDAT *Dat, ISO8583FLDDEF *Fld )
{
switch ( Dat->Type ) {
case DT_CHAR:
if ( Dat->Size < Fld->Len )
BufDatSize = Dat->Size;
else
BufDatSize = Fld->Len;
memcpy( DataBuffer, Dat->Data, BufDatSize );
if ( Fld->Fmt == FF_FIX && BufDatSize < Fld->Len ) {
memset( DataBuffer + BufDatSize, 0,
Fld->Len - BufDatSize );
BufDatSize = Fld->Len;
}
break;
case DT_STRING:
BufDatSize = strlen( Dat->Data );
if ( BufDatSize > Fld->Len )
BufDatSize = Fld->Len;
memcpy( DataBuffer, Dat->Data, BufDatSize );
if ( Fld->Fmt == FF_FIX && BufDatSize < Fld->Len ) {
memset( DataBuffer + BufDatSize, ' ',
Fld->Len - BufDatSize );
BufDatSize = Fld->Len;
}
break;
case DT_BYTE:
sprintf( DataBuffer, "%0*d", Fld->Len, (int)
*((char *) Dat->Data) );
BufDatSize = Fld->Len;
break;
case DT_UBYTE:
sprintf( DataBuffer, "%0*u", Fld->Len, (unsigned int)
*((unsigned char *) Dat->Data) );
BufDatSize = Fld->Len;
break;
case DT_SHORT:
sprintf( DataBuffer, "%0*d", Fld->Len, (int)
*((short *) Dat->Data) );
BufDatSize = Fld->Len;
break;
case DT_USHORT:
sprintf( DataBuffer, "%0*u", Fld->Len, (unsigned int)
*((unsigned short *) Dat->Data) );
BufDatSize = Fld->Len;
break;
case DT_LONG:
sprintf( DataBuffer, "%0*ld", Fld->Len,
*((long *) Dat->Data) );
BufDatSize = Fld->Len;
break;
case DT_ULONG:
sprintf( DataBuffer, "%0*lu", Fld->Len,
*((unsigned long *) Dat->Data) );
BufDatSize = Fld->Len;
break;
case DT_FLOAT:
sprintf( DataBuffer, "%0*.0f", Fld->Len,
*((float *) Dat->Data) );
BufDatSize = Fld->Len;
break;
case DT_DOUBLE:
sprintf( DataBuffer, "%0*.0lf", Fld->Len,
*((double *) Dat->Data) );
BufDatSize = Fld->Len;
break;
default:
BufDatSize = 0;
}
if ( BufDatSize > 0 && Fld->Type == FT_AMT )
if ( DataBuffer[0] == '-' )
DataBuffer[0] = 'D';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -