#ifndef _ISO8583_H
#define _ISO8583_H
#include "ToppayDef.h"
#define LEN_OF_MAX_BUFFER 2048 /*定义ISO_data结构中最长的缓冲区*/
#define LEN_OF_ISO8583 64 /*定义ISO_data的长度*/
#define UNUSED 0
#define L_BCD 1 /*左对齐BCD码*/
#define L_ASC 2 /*左对齐ASC码*/
#define R_BCD 3
#define R_ASC 4
#define D_BIN 5
#define OVER 6
#define FIX_LEN 1 /*(FIX_LEN是指由ISO_8583中的长度决定该域的长度)*/
#define LLVAR_LEN 2 /*(LLVAR_LEN 00~99)*/
#define LLLVAR_LEN 3 /*(LLLVAR_LEN 00~999)*/
#define LEN_FIELD0 4
#define LEN_FIELD1 8
#define LEN_FIELD2 32
#define LEN_FIELD3 6
#define LEN_FIELD4 12
#define LEN_FIELD11 6
#define LEN_FIELD12 6
#define LEN_FIELD13 4
#define LEN_FIELD14 4
#define LEN_FIELD15 4
#define LEN_FIELD22 3
#define LEN_FIELD23 3
#define LEN_FIELD25 2
#define LEN_FIELD26 2
#define LEN_FIELD32 99
#define LEN_FIELD35 48
#define LEN_FIELD36 112
#define LEN_FIELD37 12
#define LEN_FIELD38 6
#define LEN_FIELD39 2
#define LEN_FIELD41 8
#define LEN_FIELD42 15
#define LEN_FIELD44 25
#define LEN_FIELD46 999
#define LEN_FIELD47 999
#define LEN_FIELD48 322
#define LEN_FIELD49 3
#define LEN_FIELD52 8
#define LEN_FIELD53 16
#define LEN_FIELD54 20
#define LEN_FIELD55 255
#define LEN_FIELD58 100
#define LEN_FIELD59 999
#define LEN_FIELD60 999
#define LEN_FIELD61 999
#define LEN_FIELD62 512
#define LEN_FIELD63 163
#define LEN_FIELD64 8
typedef struct {
uint8 field0[LEN_FIELD0];
uint8 field1[LEN_FIELD1];
uint8 field2[LEN_FIELD2];
uint8 field3[LEN_FIELD3];
uint8 field4[LEN_FIELD4];
uint8 field11[LEN_FIELD11];
uint8 field12[LEN_FIELD12];
uint8 field13[LEN_FIELD13];
uint8 field14[LEN_FIELD14];
uint8 field15[LEN_FIELD15];
uint8 field22[LEN_FIELD22];
uint8 field23[LEN_FIELD23];
uint8 field25[LEN_FIELD25];
uint8 field26[LEN_FIELD26];
uint8 field32[LEN_FIELD32];
uint8 field35[LEN_FIELD35];
uint8 field36[LEN_FIELD36];
uint8 field37[LEN_FIELD37];
uint8 field38[LEN_FIELD38];
uint8 field39[LEN_FIELD39];
uint8 field41[LEN_FIELD41];
uint8 field42[LEN_FIELD42];
uint8 field44[LEN_FIELD44];
uint8 field46[LEN_FIELD46];
uint8 field47[LEN_FIELD47];
uint8 field48[LEN_FIELD48];
uint8 field49[LEN_FIELD49];
uint8 field52[LEN_FIELD52];
uint8 field53[LEN_FIELD53];
uint8 field54[LEN_FIELD54];
uint8 field55[LEN_FIELD55];
uint8 field58[LEN_FIELD58];
uint8 field59[LEN_FIELD59];
uint8 field60[LEN_FIELD60];
uint8 field61[LEN_FIELD61];
uint8 field62[LEN_FIELD62];
uint8 field63[LEN_FIELD63];
uint8 field64[LEN_FIELD64];
}FIELDS;
typedef struct {
uint16 len_max;
uint8 len_type;
uint8 field_type;
uint16 field_len;
puint8 field;
}ISO8583_ATTR;
uint16 IsoToStr(puint8 dest_send);
void StrToIso(puint8 src_rece, uint16 src_len);
uint16 LenOfIso8583();
void ClearIso8583();
#endif
#ifndef _ISO8583_C
#define _ISO8583_C
#include "ToppayDef.h"
#include "ToppayProt.h"
#include "ISO8583.h"
#include "PacketProc.h"
#define LEN_LEN 2
#define TPDU_LEN 5
#define TPDU_ID 1
#define TPDU_ADDR_DEST 2
#define TPDU_ADDR_SRC 2
#define PACKET_HEADER_LEN 6
#define PACKET_HEADER_APP_TYPE 1
#define PACKET_HEADER_STANDARD 1
#define PACKET_HEADER_TERM_STATUS_AND_PROC_TYPE 1
#define PACKET_HEADER_RESERVE 3
#define FRONT_HEADER_LEN 69
#define FRONT_HEADER_RECOGNITION 23
#define FRONT_HEADER_ORGANIZATION 15
#define FRONT_HEADER_BUSI_TYPE 8
#define FRONT_HEADER_SUPPLIER 15
#define FRONT_HEADER_ISO8583_LEN 8
uint8 m_tpdu[TPDU_LEN] = {0};
uint8 m_packet_header[PACKET_HEADER_LEN] = {0};
uint8 m_front_header[FRONT_HEADER_LEN] = {0};
FIELDS m_fields;
ISO8583_ATTR m_iso8583[LEN_OF_ISO8583+1] = {
{LEN_FIELD0, FIX_LEN, R_BCD, 0, m_fields.field0}, /* 0 -- 类型 */
{LEN_FIELD1, FIX_LEN, L_ASC, 0, m_fields.field1}, /* 1 -- 位图 */
{LEN_FIELD2, LLVAR_LEN, D_BIN, 0, m_fields.field2}, /* 2 -- 主帐号 */
{LEN_FIELD3, FIX_LEN, R_BCD, 0, m_fields.field3}, /* 3 -- 交易处理码 */
{LEN_FIELD4, FIX_LEN, R_BCD, 0, m_fields.field4}, /* 4 -- 交易金额 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 5 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 6 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 7 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 8 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 9 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 10 -- 未使用 */
{LEN_FIELD11, FIX_LEN, R_BCD, 0, m_fields.field11}, /* 11 -- 系统跟踪号 */
{LEN_FIELD12, FIX_LEN, R_BCD, 0, m_fields.field12}, /* 12 -- 本地交易时间 */
{LEN_FIELD13, FIX_LEN, R_BCD, 0, m_fields.field13}, /* 13 -- 本地交易日期 */
{LEN_FIELD14, FIX_LEN, R_BCD, 0, m_fields.field14}, /* 14 -- 卡有效期 */
{LEN_FIELD15, FIX_LEN, R_BCD, 0, m_fields.field15}, /* 15 -- 结算日期 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 16 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 17 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 18 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 19 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 20 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 21 -- 未使用 */
{LEN_FIELD22, FIX_LEN, L_BCD, 0, m_fields.field22}, /* 22 -- 服务点输入方式 */
{LEN_FIELD23, FIX_LEN, R_BCD, 0, m_fields.field23}, /* 23 -- 卡序列号 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 24 -- NII(未使用) */
{LEN_FIELD25, FIX_LEN, L_BCD, 0, m_fields.field25}, /* 25 -- 服务点条件代码 */
{LEN_FIELD26, FIX_LEN, R_BCD, 0, m_fields.field26}, /* 26 -- 服务点PIN获取码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 27 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 28 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 29 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 30 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 31 -- 未使用 */
{LEN_FIELD32, LLVAR_LEN, L_BCD, 0, m_fields.field32}, /* 32 -- 受理方标识码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 33 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 34 -- 未使用 */
{LEN_FIELD35, LLVAR_LEN, D_BIN, 0, m_fields.field35}, /* 35 -- 二磁道数据 */
{LEN_FIELD36, LLLVAR_LEN, D_BIN, 0, m_fields.field36}, /* 36 -- 三磁道数据 */
{LEN_FIELD37, FIX_LEN, L_ASC, 0, m_fields.field37}, /* 37 -- 检索参考号 */
{LEN_FIELD38, FIX_LEN, L_ASC, 0, m_fields.field38}, /* 38 -- 授权码 */
{LEN_FIELD39, FIX_LEN, L_ASC, 0, m_fields.field39}, /* 39 -- 应答码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 40 -- 终端序列号 */
{LEN_FIELD41, FIX_LEN, R_ASC, 0, m_fields.field41}, /* 41 -- 受卡方终端标识码 */
{LEN_FIELD42, FIX_LEN, R_ASC, 0, m_fields.field42}, /* 42 -- 受卡方标识码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 43 -- 未使用 */
{LEN_FIELD44, LLVAR_LEN, L_ASC, 0, m_fields.field44}, /* 44 -- 附加返回数据 */
{UNUSED, 0, UNUSED, 0, NULL}, /* 45 -- 未使用 */
{LEN_FIELD46, LLLVAR_LEN, R_ASC, 0, m_fields.field46}, /* 46 -- 未使用 */
{LEN_FIELD47, LLLVAR_LEN, D_BIN, 0, m_fields.field47}, /* 47 -- 未使用 */
{LEN_FIELD48, LLLVAR_LEN, R_BCD, 0, m_fields.field48}, /* 48 -- 附加数据-私用 */
{LEN_FIELD49, FIX_LEN, R_ASC, 0, m_fields.field49}, /* 49 -- 交易货币代码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 50 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 51 -- 未使用 */
{LEN_FIELD52, FIX_LEN, L_ASC, 0, m_fields.field52}, /* 52 -- 个人标识码数据(PIN) */
{LEN_FIELD53, FIX_LEN, L_BCD, 0, m_fields.field53}, /* 53 -- 密码相关控制信息 */
{LEN_FIELD54, LLLVAR_LEN, R_ASC, 0, m_fields.field54}, /* 54 -- 附加金额 */ // max 20
{LEN_FIELD55, LLLVAR_LEN, R_ASC, 0, m_fields.field55}, /* 55 -- IC卡数据域 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 56 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 57 -- 未使用 */
{LEN_FIELD58, LLLVAR_LEN, R_BCD, 0, m_fields.field58}, /* 58 -- PBOC电子钱包标准交易信息 */
{LEN_FIELD59, LLLVAR_LEN, R_BCD, 0, m_fields.field59}, /* 59 -- 未使用 */
{LEN_FIELD60, LLLVAR_LEN, L_BCD, 0, m_fields.field60}, /* 60 -- 自定义域 */ // max 13
{LEN_FIELD61, LLLVAR_LEN, L_BCD, 0, m_fields.field61}, /* 61 -- 自定义域 */ // max 29
{LEN_FIELD62, LLLVAR_LEN, L_ASC, 0, m_fields.field62}, /* 62 -- 自定义域 */
{LEN_FIELD63, LLLVAR_LEN, L_ASC, 0, m_fields.field63}, /* 63 -- 自定义域 */ // max 163
{LEN_FIELD64, FIX_LEN, L_ASC, 0, m_fields.field64} /* 64 -- 报文鉴别码(MAC) */
};
boolean SetField(uint8 n, puint8 src, uint16 src_len)
{
uint16 len_real = src_len;
uint16 len_valid;
LogUtil("SetField", "n = %d, src = %s, src_len = %d");
if (n < 0 || n > LEN_OF_ISO8583 || src_len > LEN_OF_MAX_BUFFER)
{
return FALSE;
}
if ((n == 0) & (src_len != LEN_FIELD0))
{
return FALSE;
}
if (src_len == 0)
{
return TRUE;
}
if (len_real > m_iso8583[n].len_max)
{
len_real = m_iso8583[n].len_max;
}
len_valid = len_real;
if (m_iso8583[n].len_type == FIX_LEN)
{
len_real = m_iso8583[n].len_max;
}
if ((len_real + LenOfIso8583()) > LEN_OF_MAX_BUFFER)
{
return FALSE;
}
memset(m_iso8583[n].field, 0, len_real);
if (m_iso8583[n].field_type == L_BCD || m_iso8583[n].field_type == L_ASC || m_iso8583[n].field_type == D_BIN)
{
memcpy(m_iso8583[n].field, src, len_valid);
}
else if (m_iso8583[n].field_type == R_BCD || m_iso8583[n].field_type == R_ASC)
{
memcpy(m_iso8583[n].field+(len_real-len_valid)*sizeof(uint8), src, len_valid);
}
m_iso8583[n].field_len = len_real;
return TRUE;
}
uint16 GetField(uint8 n, puint8 dest) {
uint16 field_len;
LogUtil("GetField", "n = %d");
if (n < 0 || n > LEN_OF_ISO8583)
{
return FALSE;
}
field_len = m_iso8583[n].field_len;
memcpy(dest, m_iso8583[n].field, field_len);
return field_len;
}
void SetTPDU(uint8 id, puint8 des_addr, puint8 src_addr)
{
m_tpdu[0] = id;
memcpy(m_tpdu+TPDU_ID, des_addr, TPDU_ADDR_DEST);
memcpy(m_tpdu+TPDU_ID+TPDU_ADDR_DEST, src_addr, TPDU_ADDR_SRC);
}
void SetPacketHeader(uint8 app_type, uint8 standard, uint8 term_status, uint8 proc_code, uint8 *reserve)
{
m_packet_header[0] = app_type;
m_packet_header[PACKET_HEADER_APP_TYPE] = standard;
m_packet_header[PACKET_HEADER_APP_TYPE+PACKET_HEADER_STANDARD] = term_status * 16 + proc_code;
memcpy(m_packet_header+PACKET_HEADER_APP_TYPE+PACKET_HEADER_STANDARD+PACKET_HEADER_TERM_STATUS_AND_PROC_TYPE, reserve, PACKET_HEADER_RESERVE);
}
void SetFrontHeader(puint8 mer_id, puint8 term_id, puint8 orga_id, puint8 busi_type, uint16 len_iso)
{
uint8 i=0, len_bytes[8] = {0};
uint16 temp = len_iso;
for (i=0; i<8; i++)
{
len_bytes[7-i] = (temp % 10) + '0';
temp /= 10;
}
memcpy(m_front_header, mer_id, 15);
memcpy(m_front_header+15, term_id, 8);
memcpy(m_front_header+FRONT_HEADER_RECOGNITION, orga_id, FRONT_HEADER_ORGANIZATION);
memcpy(m_front_header+FRONT_HEADER_RECOGNITION+FRONT_HEADER_ORGANIZATION, busi_type, FRONT_HEADER_BUSI_TYPE);
memcpy(m_front_header+FRONT_HEADER_RECOGNITION+FRONT_HEADER_ORGANIZATION+FRONT_HEADER_BUSI_TYPE, mer_id, FRONT_HEADER_SUPPLIER);
memcpy(m_front_header+FRONT_HEADER_RECOGNITION+FRONT_HEADER_ORGANIZATION+FRONT_HEADER_BUSI_TYPE+FRONT_HEADER_SUPPLIER, len_bytes, FRONT_HEADER_ISO8583_LEN);
}
void MakePacketHeader(puint8 src_send, uint16 src_len)
{
uint8 len_len[15] = {0};
uint8 j,k;
// temp start
uint8 id = 0x60, des_addr[] = {0x09, 0x51}, src_addr[] = {0x00, 0x00};
uint8 app_type = 0x80, standard = 0x20, term_status = 0x00, proc_code = 0x00, reserve[] = {0x00, 0x00, 0x00};
uint8 mer_id[15], term_id[8], accqu_id[15], trad_type[8];
SetTPDU(id, des_addr, src_addr);
SetPacketHeader(app_type, standard, term_status, proc_code, reserve);
SetFrontHeader(default_mer_id, default_term_id, default_accqu_id, default_trad_type, src_len - (5+6+69));
// temp end
len_len[0] = (src_len ) >> 8;
len_len[1] = (src_len ) & 0x00FF;
memcpy(src_send, len_len, LEN_LEN);
memcpy(src_send+LEN_LEN, m_tpdu, TPDU_LEN);
memcpy(src_send+LEN_LEN+TPDU_LEN, m_packet_header, PACKET_HEADER_LEN);
memcpy(src_send+LEN_LEN+TPDU_LEN+PACKET_HEADER_LEN, m_front_header, FRONT_HEADER_LEN);
}
uint16 IsoToStr(puint8 dest_send)
{
uint8 i;
uint8 bitmap[LEN_FIELD1] = {0};
uint8 bitmax = 0x80;
puint8 temp;
uint16 field_len = 0, iso8583_offset = LEN_LEN + TPDU_LEN + PACKET_HEADER_LEN + FRONT_HEADER_LEN;
uint8 TEMP = 0;
LogUtil("IsoToStr", "");
for(i = 0; i<=LEN_OF_ISO8583; i++)
{
if (m_iso8583[i].field_type == UNUSED) {
continue;
}
if (i == 1) {
iso8583_offset += LEN_FIELD1;
continue;
}
if (i == 63)
{
TEMP++;
}
field_len = m_iso8583[i].field_len;
if (field_len > 0)
{
if (m_iso8583[i].len_type == LLVAR_LEN)
{
dest_send[iso8583_offset++] = field_len / 10 * 16 + field_len % 10;
} else if (m_iso8583[i].len_type == LLLVAR_LEN)
{
dest_send[iso8583_offset++] = (field_len/100) / 10 * 16 + (field_len/100) % 10 ;
dest_send[iso8583_offset++] = (field_len%100) / 10 * 16 + (field_len%100) % 10;
}
if (m_iso8583[i].field_type == L_BCD)
{
temp = (puint8)mmi_malloc((field_len+1) / 2 * sizeof(uint8));
field_len = AsciiToBcd(m_iso8583[i].field, temp, field_len, TRUE);
memcpy(dest_send + iso8583_offset * sizeof(uint8), temp, field_len);
iso8583_offset += field_len;
mmi_mfree(temp);
}
else if (m_iso8583[i].field_type == R_BCD)
{
temp = (puint8)mmi_malloc((field_len+1) / 2 * sizeof(uint8));
field_len = AsciiToBcd(m_iso8583[i].field, temp, field_len, FALSE);
memcpy(dest_send + iso8583_offset * sizeof(uint8), temp, field_len);
iso8583_offset += field_len;
mmi_mfree(temp);
}
else if (m_iso8583[i].field_type == L_ASC || m_iso8583[i].field_type == R_ASC)
{
memcpy(dest_send + iso8583_offset * sizeof(uint8), m_iso8583[i].field, field_len);
iso8583_offset += field_len;
}
else if (m_iso8583[i].field_type == D_BIN)
{
memcpy(dest_send + iso8583_offset * sizeof(uint8), (m_iso8583[i].field), field_len);
iso8583_offset += field_len;
}
if (i > 1) {
bitmap[(i-1)/LEN_FIELD1] |= (bitmax >> ((i-1)%LEN_FIELD1));
}
}
}
memcpy(dest_send+2+5+6+69+2, bitmap, LEN_FIELD1);
MakePacketHeader(dest_send, iso8583_offset - 2);
LogUtil("IsoToStr", "dest_send = %s, m_len_send = %d");
return iso8583_offset;
}
void StrToIso(puint8 src_rece, uint16 src_len)
{
uint8 i;
uint8 bitmap[LEN_FIELD1] = {0};
uint8 bitmax = 0x80;
puint8 temp;
uint16 field_len = 0, buffer_offset = LEN_LEN + TPDU_LEN + PACKET_HEADER_LEN + FRONT_HEADER_LEN;
LogUtil("IsoToStr", "src_rece = %s, src_len = %d");
ClearIso8583();
buffer_offset += 2;
memcpy(bitmap, src_rece + buffer_offset * sizeof(uint8), LEN_FIELD1);
buffer_offset += LEN_FIELD1;
for(i = 0; i<=LEN_OF_ISO8583; i++) {
if ((bitmap[(i-1)/LEN_FIELD1]) & ((bitmax >> ((i-1)%LEN_FIELD1))))
{
if (m_iso8583[i].len_type == FIX_LEN) {
field_len = m_iso8583[i].len_max;
} else if (m_iso8583[i].len_type == LLVAR_LEN) {
field_len = src_rece[buffer_offset] / 16 * 10 + src_rece[buffer_offset] % 16;
buffer_offset += 1;
} else if (m_iso8583[i].len_type == LLLVAR_LEN) {
field_len = (src_rece[buffer_offset] / 16 * 10 + src_rece[buffer_offset] %16) * 100 + src_rece[buffer_offset+1] / 16 * 10 + src_rece[buffer_offset+1] % 16;
buffer_offset += 2;
}
m_iso8583[i].field_len = field_len;
if (m_iso8583[i].field_type == L_BCD || m_iso8583[i].field_type == R_BCD)
{
temp = (puint8)mmi_malloc((field_len * 2 + 1) * sizeof(uint8)+1);
memset(temp, 0, field_len * 2 + 1);
BcdToAscii(src_rece + buffer_offset, temp, field_len);
memcpy(m_iso8583[i].field + 2, temp, field_len);
buffer_offset += (field_len+1)/2;
mmi_mfree(temp);
}
else if (m_iso8583[i].field_type == L_ASC || m_iso8583[i].field_type == R_ASC)
{
memcpy(m_iso8583[i].field, src_rece + buffer_offset * sizeof(uint8), field_len);
buffer_offset += field_len;
}
else if (m_iso8583[i].field_type == D_BIN)
{
memcpy(m_iso8583[i].field, src_rece + buffer_offset * sizeof(uint8), field_len);
buffer_offset += field_len;
}
}
}
}
uint16 LenOfIso8583()
{
uint8 i;
uint16 len_iso8583 = 0;
for (i=0; i<LEN_OF_ISO8583; i++)
{
if (m_iso8583[i].len_max == UNUSED)
{
continue;
}
len_iso8583 += m_iso8583[i].field_len;
}
return len_iso8583;
}
void ClearIso8583()
{
uint8 i;
LogUtil("ClearIso8583", "");
memset(&m_fields, 0, sizeof(m_fields));
for (i=0; i<LEN_OF_ISO8583; i++)
{
if (m_iso8583[i].len_max == UNUSED)
{
continue;
}
m_iso8583[i].field_len = 0;
}
}
#endif
#define _ISO8583_H
#include "ToppayDef.h"
#define LEN_OF_MAX_BUFFER 2048 /*定义ISO_data结构中最长的缓冲区*/
#define LEN_OF_ISO8583 64 /*定义ISO_data的长度*/
#define UNUSED 0
#define L_BCD 1 /*左对齐BCD码*/
#define L_ASC 2 /*左对齐ASC码*/
#define R_BCD 3
#define R_ASC 4
#define D_BIN 5
#define OVER 6
#define FIX_LEN 1 /*(FIX_LEN是指由ISO_8583中的长度决定该域的长度)*/
#define LLVAR_LEN 2 /*(LLVAR_LEN 00~99)*/
#define LLLVAR_LEN 3 /*(LLLVAR_LEN 00~999)*/
#define LEN_FIELD0 4
#define LEN_FIELD1 8
#define LEN_FIELD2 32
#define LEN_FIELD3 6
#define LEN_FIELD4 12
#define LEN_FIELD11 6
#define LEN_FIELD12 6
#define LEN_FIELD13 4
#define LEN_FIELD14 4
#define LEN_FIELD15 4
#define LEN_FIELD22 3
#define LEN_FIELD23 3
#define LEN_FIELD25 2
#define LEN_FIELD26 2
#define LEN_FIELD32 99
#define LEN_FIELD35 48
#define LEN_FIELD36 112
#define LEN_FIELD37 12
#define LEN_FIELD38 6
#define LEN_FIELD39 2
#define LEN_FIELD41 8
#define LEN_FIELD42 15
#define LEN_FIELD44 25
#define LEN_FIELD46 999
#define LEN_FIELD47 999
#define LEN_FIELD48 322
#define LEN_FIELD49 3
#define LEN_FIELD52 8
#define LEN_FIELD53 16
#define LEN_FIELD54 20
#define LEN_FIELD55 255
#define LEN_FIELD58 100
#define LEN_FIELD59 999
#define LEN_FIELD60 999
#define LEN_FIELD61 999
#define LEN_FIELD62 512
#define LEN_FIELD63 163
#define LEN_FIELD64 8
typedef struct {
uint8 field0[LEN_FIELD0];
uint8 field1[LEN_FIELD1];
uint8 field2[LEN_FIELD2];
uint8 field3[LEN_FIELD3];
uint8 field4[LEN_FIELD4];
uint8 field11[LEN_FIELD11];
uint8 field12[LEN_FIELD12];
uint8 field13[LEN_FIELD13];
uint8 field14[LEN_FIELD14];
uint8 field15[LEN_FIELD15];
uint8 field22[LEN_FIELD22];
uint8 field23[LEN_FIELD23];
uint8 field25[LEN_FIELD25];
uint8 field26[LEN_FIELD26];
uint8 field32[LEN_FIELD32];
uint8 field35[LEN_FIELD35];
uint8 field36[LEN_FIELD36];
uint8 field37[LEN_FIELD37];
uint8 field38[LEN_FIELD38];
uint8 field39[LEN_FIELD39];
uint8 field41[LEN_FIELD41];
uint8 field42[LEN_FIELD42];
uint8 field44[LEN_FIELD44];
uint8 field46[LEN_FIELD46];
uint8 field47[LEN_FIELD47];
uint8 field48[LEN_FIELD48];
uint8 field49[LEN_FIELD49];
uint8 field52[LEN_FIELD52];
uint8 field53[LEN_FIELD53];
uint8 field54[LEN_FIELD54];
uint8 field55[LEN_FIELD55];
uint8 field58[LEN_FIELD58];
uint8 field59[LEN_FIELD59];
uint8 field60[LEN_FIELD60];
uint8 field61[LEN_FIELD61];
uint8 field62[LEN_FIELD62];
uint8 field63[LEN_FIELD63];
uint8 field64[LEN_FIELD64];
}FIELDS;
typedef struct {
uint16 len_max;
uint8 len_type;
uint8 field_type;
uint16 field_len;
puint8 field;
}ISO8583_ATTR;
uint16 IsoToStr(puint8 dest_send);
void StrToIso(puint8 src_rece, uint16 src_len);
uint16 LenOfIso8583();
void ClearIso8583();
#endif
#ifndef _ISO8583_C
#define _ISO8583_C
#include "ToppayDef.h"
#include "ToppayProt.h"
#include "ISO8583.h"
#include "PacketProc.h"
#define LEN_LEN 2
#define TPDU_LEN 5
#define TPDU_ID 1
#define TPDU_ADDR_DEST 2
#define TPDU_ADDR_SRC 2
#define PACKET_HEADER_LEN 6
#define PACKET_HEADER_APP_TYPE 1
#define PACKET_HEADER_STANDARD 1
#define PACKET_HEADER_TERM_STATUS_AND_PROC_TYPE 1
#define PACKET_HEADER_RESERVE 3
#define FRONT_HEADER_LEN 69
#define FRONT_HEADER_RECOGNITION 23
#define FRONT_HEADER_ORGANIZATION 15
#define FRONT_HEADER_BUSI_TYPE 8
#define FRONT_HEADER_SUPPLIER 15
#define FRONT_HEADER_ISO8583_LEN 8
uint8 m_tpdu[TPDU_LEN] = {0};
uint8 m_packet_header[PACKET_HEADER_LEN] = {0};
uint8 m_front_header[FRONT_HEADER_LEN] = {0};
FIELDS m_fields;
ISO8583_ATTR m_iso8583[LEN_OF_ISO8583+1] = {
{LEN_FIELD0, FIX_LEN, R_BCD, 0, m_fields.field0}, /* 0 -- 类型 */
{LEN_FIELD1, FIX_LEN, L_ASC, 0, m_fields.field1}, /* 1 -- 位图 */
{LEN_FIELD2, LLVAR_LEN, D_BIN, 0, m_fields.field2}, /* 2 -- 主帐号 */
{LEN_FIELD3, FIX_LEN, R_BCD, 0, m_fields.field3}, /* 3 -- 交易处理码 */
{LEN_FIELD4, FIX_LEN, R_BCD, 0, m_fields.field4}, /* 4 -- 交易金额 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 5 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 6 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 7 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 8 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 9 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 10 -- 未使用 */
{LEN_FIELD11, FIX_LEN, R_BCD, 0, m_fields.field11}, /* 11 -- 系统跟踪号 */
{LEN_FIELD12, FIX_LEN, R_BCD, 0, m_fields.field12}, /* 12 -- 本地交易时间 */
{LEN_FIELD13, FIX_LEN, R_BCD, 0, m_fields.field13}, /* 13 -- 本地交易日期 */
{LEN_FIELD14, FIX_LEN, R_BCD, 0, m_fields.field14}, /* 14 -- 卡有效期 */
{LEN_FIELD15, FIX_LEN, R_BCD, 0, m_fields.field15}, /* 15 -- 结算日期 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 16 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 17 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 18 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 19 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 20 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 21 -- 未使用 */
{LEN_FIELD22, FIX_LEN, L_BCD, 0, m_fields.field22}, /* 22 -- 服务点输入方式 */
{LEN_FIELD23, FIX_LEN, R_BCD, 0, m_fields.field23}, /* 23 -- 卡序列号 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 24 -- NII(未使用) */
{LEN_FIELD25, FIX_LEN, L_BCD, 0, m_fields.field25}, /* 25 -- 服务点条件代码 */
{LEN_FIELD26, FIX_LEN, R_BCD, 0, m_fields.field26}, /* 26 -- 服务点PIN获取码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 27 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 28 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 29 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 30 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 31 -- 未使用 */
{LEN_FIELD32, LLVAR_LEN, L_BCD, 0, m_fields.field32}, /* 32 -- 受理方标识码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 33 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 34 -- 未使用 */
{LEN_FIELD35, LLVAR_LEN, D_BIN, 0, m_fields.field35}, /* 35 -- 二磁道数据 */
{LEN_FIELD36, LLLVAR_LEN, D_BIN, 0, m_fields.field36}, /* 36 -- 三磁道数据 */
{LEN_FIELD37, FIX_LEN, L_ASC, 0, m_fields.field37}, /* 37 -- 检索参考号 */
{LEN_FIELD38, FIX_LEN, L_ASC, 0, m_fields.field38}, /* 38 -- 授权码 */
{LEN_FIELD39, FIX_LEN, L_ASC, 0, m_fields.field39}, /* 39 -- 应答码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 40 -- 终端序列号 */
{LEN_FIELD41, FIX_LEN, R_ASC, 0, m_fields.field41}, /* 41 -- 受卡方终端标识码 */
{LEN_FIELD42, FIX_LEN, R_ASC, 0, m_fields.field42}, /* 42 -- 受卡方标识码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 43 -- 未使用 */
{LEN_FIELD44, LLVAR_LEN, L_ASC, 0, m_fields.field44}, /* 44 -- 附加返回数据 */
{UNUSED, 0, UNUSED, 0, NULL}, /* 45 -- 未使用 */
{LEN_FIELD46, LLLVAR_LEN, R_ASC, 0, m_fields.field46}, /* 46 -- 未使用 */
{LEN_FIELD47, LLLVAR_LEN, D_BIN, 0, m_fields.field47}, /* 47 -- 未使用 */
{LEN_FIELD48, LLLVAR_LEN, R_BCD, 0, m_fields.field48}, /* 48 -- 附加数据-私用 */
{LEN_FIELD49, FIX_LEN, R_ASC, 0, m_fields.field49}, /* 49 -- 交易货币代码 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 50 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 51 -- 未使用 */
{LEN_FIELD52, FIX_LEN, L_ASC, 0, m_fields.field52}, /* 52 -- 个人标识码数据(PIN) */
{LEN_FIELD53, FIX_LEN, L_BCD, 0, m_fields.field53}, /* 53 -- 密码相关控制信息 */
{LEN_FIELD54, LLLVAR_LEN, R_ASC, 0, m_fields.field54}, /* 54 -- 附加金额 */ // max 20
{LEN_FIELD55, LLLVAR_LEN, R_ASC, 0, m_fields.field55}, /* 55 -- IC卡数据域 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 56 -- 未使用 */
{UNUSED, UNUSED, UNUSED, 0, NULL}, /* 57 -- 未使用 */
{LEN_FIELD58, LLLVAR_LEN, R_BCD, 0, m_fields.field58}, /* 58 -- PBOC电子钱包标准交易信息 */
{LEN_FIELD59, LLLVAR_LEN, R_BCD, 0, m_fields.field59}, /* 59 -- 未使用 */
{LEN_FIELD60, LLLVAR_LEN, L_BCD, 0, m_fields.field60}, /* 60 -- 自定义域 */ // max 13
{LEN_FIELD61, LLLVAR_LEN, L_BCD, 0, m_fields.field61}, /* 61 -- 自定义域 */ // max 29
{LEN_FIELD62, LLLVAR_LEN, L_ASC, 0, m_fields.field62}, /* 62 -- 自定义域 */
{LEN_FIELD63, LLLVAR_LEN, L_ASC, 0, m_fields.field63}, /* 63 -- 自定义域 */ // max 163
{LEN_FIELD64, FIX_LEN, L_ASC, 0, m_fields.field64} /* 64 -- 报文鉴别码(MAC) */
};
boolean SetField(uint8 n, puint8 src, uint16 src_len)
{
uint16 len_real = src_len;
uint16 len_valid;
LogUtil("SetField", "n = %d, src = %s, src_len = %d");
if (n < 0 || n > LEN_OF_ISO8583 || src_len > LEN_OF_MAX_BUFFER)
{
return FALSE;
}
if ((n == 0) & (src_len != LEN_FIELD0))
{
return FALSE;
}
if (src_len == 0)
{
return TRUE;
}
if (len_real > m_iso8583[n].len_max)
{
len_real = m_iso8583[n].len_max;
}
len_valid = len_real;
if (m_iso8583[n].len_type == FIX_LEN)
{
len_real = m_iso8583[n].len_max;
}
if ((len_real + LenOfIso8583()) > LEN_OF_MAX_BUFFER)
{
return FALSE;
}
memset(m_iso8583[n].field, 0, len_real);
if (m_iso8583[n].field_type == L_BCD || m_iso8583[n].field_type == L_ASC || m_iso8583[n].field_type == D_BIN)
{
memcpy(m_iso8583[n].field, src, len_valid);
}
else if (m_iso8583[n].field_type == R_BCD || m_iso8583[n].field_type == R_ASC)
{
memcpy(m_iso8583[n].field+(len_real-len_valid)*sizeof(uint8), src, len_valid);
}
m_iso8583[n].field_len = len_real;
return TRUE;
}
uint16 GetField(uint8 n, puint8 dest) {
uint16 field_len;
LogUtil("GetField", "n = %d");
if (n < 0 || n > LEN_OF_ISO8583)
{
return FALSE;
}
field_len = m_iso8583[n].field_len;
memcpy(dest, m_iso8583[n].field, field_len);
return field_len;
}
void SetTPDU(uint8 id, puint8 des_addr, puint8 src_addr)
{
m_tpdu[0] = id;
memcpy(m_tpdu+TPDU_ID, des_addr, TPDU_ADDR_DEST);
memcpy(m_tpdu+TPDU_ID+TPDU_ADDR_DEST, src_addr, TPDU_ADDR_SRC);
}
void SetPacketHeader(uint8 app_type, uint8 standard, uint8 term_status, uint8 proc_code, uint8 *reserve)
{
m_packet_header[0] = app_type;
m_packet_header[PACKET_HEADER_APP_TYPE] = standard;
m_packet_header[PACKET_HEADER_APP_TYPE+PACKET_HEADER_STANDARD] = term_status * 16 + proc_code;
memcpy(m_packet_header+PACKET_HEADER_APP_TYPE+PACKET_HEADER_STANDARD+PACKET_HEADER_TERM_STATUS_AND_PROC_TYPE, reserve, PACKET_HEADER_RESERVE);
}
void SetFrontHeader(puint8 mer_id, puint8 term_id, puint8 orga_id, puint8 busi_type, uint16 len_iso)
{
uint8 i=0, len_bytes[8] = {0};
uint16 temp = len_iso;
for (i=0; i<8; i++)
{
len_bytes[7-i] = (temp % 10) + '0';
temp /= 10;
}
memcpy(m_front_header, mer_id, 15);
memcpy(m_front_header+15, term_id, 8);
memcpy(m_front_header+FRONT_HEADER_RECOGNITION, orga_id, FRONT_HEADER_ORGANIZATION);
memcpy(m_front_header+FRONT_HEADER_RECOGNITION+FRONT_HEADER_ORGANIZATION, busi_type, FRONT_HEADER_BUSI_TYPE);
memcpy(m_front_header+FRONT_HEADER_RECOGNITION+FRONT_HEADER_ORGANIZATION+FRONT_HEADER_BUSI_TYPE, mer_id, FRONT_HEADER_SUPPLIER);
memcpy(m_front_header+FRONT_HEADER_RECOGNITION+FRONT_HEADER_ORGANIZATION+FRONT_HEADER_BUSI_TYPE+FRONT_HEADER_SUPPLIER, len_bytes, FRONT_HEADER_ISO8583_LEN);
}
void MakePacketHeader(puint8 src_send, uint16 src_len)
{
uint8 len_len[15] = {0};
uint8 j,k;
// temp start
uint8 id = 0x60, des_addr[] = {0x09, 0x51}, src_addr[] = {0x00, 0x00};
uint8 app_type = 0x80, standard = 0x20, term_status = 0x00, proc_code = 0x00, reserve[] = {0x00, 0x00, 0x00};
uint8 mer_id[15], term_id[8], accqu_id[15], trad_type[8];
SetTPDU(id, des_addr, src_addr);
SetPacketHeader(app_type, standard, term_status, proc_code, reserve);
SetFrontHeader(default_mer_id, default_term_id, default_accqu_id, default_trad_type, src_len - (5+6+69));
// temp end
len_len[0] = (src_len ) >> 8;
len_len[1] = (src_len ) & 0x00FF;
memcpy(src_send, len_len, LEN_LEN);
memcpy(src_send+LEN_LEN, m_tpdu, TPDU_LEN);
memcpy(src_send+LEN_LEN+TPDU_LEN, m_packet_header, PACKET_HEADER_LEN);
memcpy(src_send+LEN_LEN+TPDU_LEN+PACKET_HEADER_LEN, m_front_header, FRONT_HEADER_LEN);
}
uint16 IsoToStr(puint8 dest_send)
{
uint8 i;
uint8 bitmap[LEN_FIELD1] = {0};
uint8 bitmax = 0x80;
puint8 temp;
uint16 field_len = 0, iso8583_offset = LEN_LEN + TPDU_LEN + PACKET_HEADER_LEN + FRONT_HEADER_LEN;
uint8 TEMP = 0;
LogUtil("IsoToStr", "");
for(i = 0; i<=LEN_OF_ISO8583; i++)
{
if (m_iso8583[i].field_type == UNUSED) {
continue;
}
if (i == 1) {
iso8583_offset += LEN_FIELD1;
continue;
}
if (i == 63)
{
TEMP++;
}
field_len = m_iso8583[i].field_len;
if (field_len > 0)
{
if (m_iso8583[i].len_type == LLVAR_LEN)
{
dest_send[iso8583_offset++] = field_len / 10 * 16 + field_len % 10;
} else if (m_iso8583[i].len_type == LLLVAR_LEN)
{
dest_send[iso8583_offset++] = (field_len/100) / 10 * 16 + (field_len/100) % 10 ;
dest_send[iso8583_offset++] = (field_len%100) / 10 * 16 + (field_len%100) % 10;
}
if (m_iso8583[i].field_type == L_BCD)
{
temp = (puint8)mmi_malloc((field_len+1) / 2 * sizeof(uint8));
field_len = AsciiToBcd(m_iso8583[i].field, temp, field_len, TRUE);
memcpy(dest_send + iso8583_offset * sizeof(uint8), temp, field_len);
iso8583_offset += field_len;
mmi_mfree(temp);
}
else if (m_iso8583[i].field_type == R_BCD)
{
temp = (puint8)mmi_malloc((field_len+1) / 2 * sizeof(uint8));
field_len = AsciiToBcd(m_iso8583[i].field, temp, field_len, FALSE);
memcpy(dest_send + iso8583_offset * sizeof(uint8), temp, field_len);
iso8583_offset += field_len;
mmi_mfree(temp);
}
else if (m_iso8583[i].field_type == L_ASC || m_iso8583[i].field_type == R_ASC)
{
memcpy(dest_send + iso8583_offset * sizeof(uint8), m_iso8583[i].field, field_len);
iso8583_offset += field_len;
}
else if (m_iso8583[i].field_type == D_BIN)
{
memcpy(dest_send + iso8583_offset * sizeof(uint8), (m_iso8583[i].field), field_len);
iso8583_offset += field_len;
}
if (i > 1) {
bitmap[(i-1)/LEN_FIELD1] |= (bitmax >> ((i-1)%LEN_FIELD1));
}
}
}
memcpy(dest_send+2+5+6+69+2, bitmap, LEN_FIELD1);
MakePacketHeader(dest_send, iso8583_offset - 2);
LogUtil("IsoToStr", "dest_send = %s, m_len_send = %d");
return iso8583_offset;
}
void StrToIso(puint8 src_rece, uint16 src_len)
{
uint8 i;
uint8 bitmap[LEN_FIELD1] = {0};
uint8 bitmax = 0x80;
puint8 temp;
uint16 field_len = 0, buffer_offset = LEN_LEN + TPDU_LEN + PACKET_HEADER_LEN + FRONT_HEADER_LEN;
LogUtil("IsoToStr", "src_rece = %s, src_len = %d");
ClearIso8583();
buffer_offset += 2;
memcpy(bitmap, src_rece + buffer_offset * sizeof(uint8), LEN_FIELD1);
buffer_offset += LEN_FIELD1;
for(i = 0; i<=LEN_OF_ISO8583; i++) {
if ((bitmap[(i-1)/LEN_FIELD1]) & ((bitmax >> ((i-1)%LEN_FIELD1))))
{
if (m_iso8583[i].len_type == FIX_LEN) {
field_len = m_iso8583[i].len_max;
} else if (m_iso8583[i].len_type == LLVAR_LEN) {
field_len = src_rece[buffer_offset] / 16 * 10 + src_rece[buffer_offset] % 16;
buffer_offset += 1;
} else if (m_iso8583[i].len_type == LLLVAR_LEN) {
field_len = (src_rece[buffer_offset] / 16 * 10 + src_rece[buffer_offset] %16) * 100 + src_rece[buffer_offset+1] / 16 * 10 + src_rece[buffer_offset+1] % 16;
buffer_offset += 2;
}
m_iso8583[i].field_len = field_len;
if (m_iso8583[i].field_type == L_BCD || m_iso8583[i].field_type == R_BCD)
{
temp = (puint8)mmi_malloc((field_len * 2 + 1) * sizeof(uint8)+1);
memset(temp, 0, field_len * 2 + 1);
BcdToAscii(src_rece + buffer_offset, temp, field_len);
memcpy(m_iso8583[i].field + 2, temp, field_len);
buffer_offset += (field_len+1)/2;
mmi_mfree(temp);
}
else if (m_iso8583[i].field_type == L_ASC || m_iso8583[i].field_type == R_ASC)
{
memcpy(m_iso8583[i].field, src_rece + buffer_offset * sizeof(uint8), field_len);
buffer_offset += field_len;
}
else if (m_iso8583[i].field_type == D_BIN)
{
memcpy(m_iso8583[i].field, src_rece + buffer_offset * sizeof(uint8), field_len);
buffer_offset += field_len;
}
}
}
}
uint16 LenOfIso8583()
{
uint8 i;
uint16 len_iso8583 = 0;
for (i=0; i<LEN_OF_ISO8583; i++)
{
if (m_iso8583[i].len_max == UNUSED)
{
continue;
}
len_iso8583 += m_iso8583[i].field_len;
}
return len_iso8583;
}
void ClearIso8583()
{
uint8 i;
LogUtil("ClearIso8583", "");
memset(&m_fields, 0, sizeof(m_fields));
for (i=0; i<LEN_OF_ISO8583; i++)
{
if (m_iso8583[i].len_max == UNUSED)
{
continue;
}
m_iso8583[i].field_len = 0;
}
}
#endif