TMC32_QJB/App/billmode.c

559 lines
10 KiB
C
Raw Normal View History

2026-04-30 08:23:12 +00:00
/**
******************************************************************************
* @file billmode.c
* @author TMC Scan Team
* @version V1.0.0
* @date 09/06/2019
* @brief This file provides the different modes of scanning.
******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, TMC SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2016 TMC</center></h2>
******************************************************************************
**/
#include "global.h"
static const unsigned char base64_suffix_map[256] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255,
255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255
};
const uint8_t TAXHead[3][2] = {{0x30, 0x31}, {0x31, 0x30}, {0x30, 0x34}};
const uint8_t BaiWangHead[7] = {0x5C, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36};
const uint8_t HangXinHead[5] = {0x6C, 0x78, 0x6B, 0x70, 0x3A};
const uint8_t QuanMinETail[9] = "CHINAUMS_";
/**
* @function base64_decode
* @brief base64<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param[in] *indata input data
* @param[in] inlen input data length
* @param[out] *outdata output data buf
* @param[out] *outlen output data length
* @return
*/
int base64_decode(const uint8_t *indata, uint16_t inlen, uint8_t *outdata, uint16_t *outlen)
{
int ret = 0;
if(indata == NULL || inlen <= 0 || outdata == NULL || outlen == NULL)
{
return ret = -1;
}
ret = inlen % 4;
if(ret != 0)
{
// <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD>4<EFBFBD>ֽڱ<D6BD><DAB1><EFBFBD>
return ret = -2;
}
int t = 0, x = 0, y = 0, i = 0;
unsigned char c = 0;
int g = 3;
while((indata[x] != 0) && (x < inlen))
{
// <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>Ӧ<EFBFBD><D3A6>ASCIIֵ<49><D6B5>Ӧbase64_suffix_map<61><70>ֵ
c = base64_suffix_map[indata[x++]];
if(c == 255) { return -1; } // <20><>Ӧ<EFBFBD><D3A6>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(c == 253) { continue; } // <20><>Ӧ<EFBFBD><D3A6>ֵ<EFBFBD>ǻ<EFBFBD><C7BB>л<EFBFBD><D0BB>߻س<DFBB>
if(c == 254) { c = 0; g--; } // <20><>Ӧ<EFBFBD><D3A6>ֵ<EFBFBD><D6B5>'='
t = (t << 6) | c; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>η<EFBFBD><CEB7><EFBFBD>һ<EFBFBD><D2BB>int<6E><74><EFBFBD><EFBFBD>ռ3<D5BC>ֽ<EFBFBD>
if(++y == 4)
{
outdata[i++] = (unsigned char)((t >> 16) & 0xff);
if(g > 1) { outdata[i++] = (unsigned char)((t >> 8) & 0xff); }
if(g > 2) { outdata[i++] = (unsigned char)(t & 0xff); }
y = t = 0;
}
}
*outlen = (i - 4); //<2F><>λУ<CEBB><D0A3>λ
return ret;
}
/**
* @function TaxBillMode
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param[in] pCode <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return
*/
int TaxBillMode(BarData *pCode)
{
int ret, i = 0, j = 0;
uint8_t *pData = NULL;
pData = (uint8_t *) PREOUTBUF;
uint16_t dataLen = 0;
uint8_t *pOut = NULL;
pOut = (uint8_t *) POSOUTBUF;
// <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>4<EFBFBD>ֽڱ<D6BD><DAB1><EFBFBD>
ret = (pCode->datalen - 4) % 4;
i = 0;
if(ret > 0)
{
while((4 - ret) != 0)
{
pCode->bardata[pCode->datalen - 1 + i] = '=';
ret++;
i++;
}
}
ret = base64_decode(pCode->bardata + 3, pCode->datalen - 4 + i, pData, &dataLen);
if(ret == 0)
{
i = 0;
while(i < dataLen)
{
if(pData[i] == 0x3C)
{
if((pData[i + 1] == 0x2F) && ((pData[i + 2] == 0x3E)))
{
pOut[j] = 0x20;
j++;
pOut[j] = 0x09;
j++;
i += 3;
}
else
{
pOut[j] = pData[i];
j++;
i++;
}
}
else
{
pOut[j] = pData[i];
j++;
i++;
}
}
Memcpy(pCode->bardata, pOut, j);
pCode->datalen = j;
return j;
}
else
{
return 0;
}
}
/**
* @function HangXinBillMode
* @brief <EFBFBD><EFBFBD><EFBFBD>ŷ<EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD>ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ֱ<EFBFBD>Ӵ<EFBFBD>ӡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param[in] pCode <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return
*/
int HangXinBillMode(BarData *pCode)
{
int ret, i = 0, j = 0;
int base64codelen = pCode->datalen - 6;
uint8_t *pData = NULL;
pData = (uint8_t *) PREOUTBUF;
uint16_t dataLen = 0;
uint8_t *pOut = NULL;
pOut = (uint8_t *) POSOUTBUF;
// <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>4<EFBFBD>ֽڱ<D6BD><DAB1><EFBFBD>
ret = base64codelen % 4;
i = 0;
if(ret > 0)
{
while((4 - ret) != 0)
{
pCode->bardata[pCode->datalen - 1 + i] = '=';
ret++;
i++;
}
}
ret = base64_decode(pCode->bardata + 5, pCode->datalen - 6 + i, pData, &dataLen);
if(ret == 0)
{
i = 0;
if((pData[0] >= 0x30) && (pData[0] <= 0x39))
{
i = 1;
dataLen = dataLen - 2;
}
while(i < dataLen)
{
if(pData[i] == 0x3C)
{
if((pData[i + 1] == 0x2F) && ((pData[i + 2] == 0x3E)))
{
pOut[j] = 0x20;
j++;
pOut[j] = 0x09;
j++;
i += 3;
}
else
{
pOut[j] = pData[i];
j++;
i++;
}
}
else
{
pOut[j] = pData[i];
j++;
i++;
}
}
Memcpy(pCode->bardata, pOut, j);
pCode->datalen = j;
return j;
}
else
{
return 0;
}
}
/**
* @function AliBillMode
* @brief ֧<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param[in] pCode <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return
*/
int AliBillMode(BarData *pCode)
{
int i = 0, j = 0;
uint8_t *pOut = NULL;
pOut = (uint8_t *) POSOUTBUF;
i = 2;
j = 0;
while(i < pCode->datalen)
{
if(pCode->bardata[i] == 0xE2)
{
if((pCode->bardata[i + 1] == 0x86) && (pCode->bardata[i + 2] == 0x92))
{
pOut[j] = 0x20;
j++;
pOut[j] = 0x09;
j++;
i += 4;
}
else
{
pOut[j] = pCode->bardata[i];
i++;
j++;
}
}
else if((pCode->bardata[i] == 0x41) && (pCode->bardata[i + 1] == 0x4C))
{
if((pCode->bardata[i + 2] == 0x49) && (pCode->bardata[i + 3] == 0x50))
{
break;
}
else
{
pOut[j] = pCode->bardata[i];
i++;
j++;
}
}
else
{
pOut[j] = pCode->bardata[i];
i++;
j++;
}
}
if(j > 0)
{
Memcpy(pCode->bardata, pOut, j);
pCode->datalen = j;
}
else
{
return 0;
}
return j;
}
/**
* @function BaiWangBillMode
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param[in] pCode <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return
*/
int BaiWangBillMode(BarData *pCode)
{
int i = 0, j = 0;
uint8_t *pOut = NULL;
pOut = (uint8_t *) POSOUTBUF;
i = 9;
j = 0;
while(i < pCode->datalen)
{
if(pCode->bardata[i] == 0xE2)
{
if((pCode->bardata[i + 1] == 0x86) && (pCode->bardata[i + 2] == 0x92))
{
pOut[j] = 0x20;
j++;
pOut[j] = 0x09;
j++;
i += 4;
}
else
{
pOut[j] = pCode->bardata[i];
i++;
j++;
}
}
else
{
pOut[j] = pCode->bardata[i];
i++;
j++;
}
}
if(j > 0)
{
Memcpy(pCode->bardata, pOut, j);
pCode->datalen = j;
}
else
{
return 0;
}
return j;
}
/**
* @function QuanMinEBillMode
* @brief ȫ<EFBFBD><EFBFBD>E<EFBFBD><EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param[in] pCode <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return
*/
int QuanMinEBillMode(BarData *pCode)
{
int i = 0, j = 0;
uint8_t *pOut = NULL;
pOut = (uint8_t *) POSOUTBUF;
i = 1;
j = 0;
while(i < (pCode->datalen - 9))
{
if(pCode->bardata[i] == 0xE2)
{
if((pCode->bardata[i + 1] == 0x86) && (pCode->bardata[i + 2] == 0x92))
{
pOut[j] = 0x20;
j++;
pOut[j] = 0x09;
j++;
i += 4;
}
else
{
pOut[j] = pCode->bardata[i];
i++;
j++;
}
}
else
{
pOut[j] = pCode->bardata[i];
i++;
j++;
}
}
if(j > 0)
{
Memcpy(pCode->bardata, pOut, j);
pCode->datalen = j;
}
else
{
return 0;
}
return j;
}
//<2F><>ֵ˰<D6B5><CBB0>Ʊ
int VATBillMode(BarData *pCode)
{
int i = 5, j = 0;
uint8_t *pOut = NULL;
pOut = (uint8_t *) POSOUTBUF;
for(i = 0; i < 3; i++)
{
if(Memcmp(&pCode->bardata[3], (uint8_t *)&TAXHead[i][0], 2) == TRUE)
{
break;
}
}
if(i >= 3)
{
return 0;
}
if(pCode->bardata[5] == ',')
{
for(i = 6; i < (pCode->datalen - 6); i++)
{
if(pCode->bardata[i] == ',')
{
pOut[j] = 0x09;
}
else
{
pOut[j] = pCode->bardata[i];
}
j++;
}
}
if(j > 0)
{
memcpy(pCode->bardata, pOut, j);
pCode->datalen = j;
}
else
{
return 0;
}
return j;
}
/**
* @function BillMode
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD>Ʊģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param[in] pCode <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ʊ<EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򷵻<EFBFBD>0
*/
int BillMode(BarData *pCode)
{
int tmp;
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD>Ʊģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD>Ʊģʽ<C4A3><CABD><EFBFBD><EFBFBD>*/
/*˰<><CBB0><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>*/
if((pCode->bardata[0] == '$') && (pCode->bardata[pCode->datalen - 1] == '$'))
{
if((pCode->bardata[1] == '0') && (pCode->bardata[2] == '1'))
{
tmp = TaxBillMode(pCode);
return tmp;
}
}
/*֧<><D6A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>*/
if((pCode->bardata[0] == '1') && (pCode->bardata[pCode->datalen - 1] == 0x92))
{
if((pCode->bardata[pCode->datalen - 2] == 0x86) && (pCode->bardata[pCode->datalen - 3] == 0xE2))
{
tmp = AliBillMode(pCode);
return tmp;
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>
if((Memcmp(pCode->bardata, (uint8_t *) BaiWangHead, sizeof(BaiWangHead))) && (pCode->bardata[pCode->datalen - 1] == 0x92))
{
if((pCode->bardata[pCode->datalen - 2] == 0x86) && (pCode->bardata[pCode->datalen - 3] == 0xE2))
{
tmp = BaiWangBillMode(pCode);
return tmp;
}
}
//<2F><><EFBFBD>ŷ<EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>
if((Memcmp(pCode->bardata, (uint8_t *) HangXinHead, sizeof(HangXinHead))) && (pCode->bardata[pCode->datalen - 1] == '$'))
{
tmp = HangXinBillMode(pCode);
return tmp;
}
//ȫ<><C8AB>E<EFBFBD><45>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>
if(pCode->bardata[0] == '1')
{
if(Memcmp(&pCode->bardata[pCode->datalen - 9], (uint8_t *) QuanMinETail, sizeof(QuanMinETail)))
{
tmp = QuanMinEBillMode(pCode);
return tmp;
}
}
//<2F><>ֵ˰<D6B5><CBB0>Ʊ
if((pCode->bartype == QR_Id) && (pCode->bardata[0] == '0'))
{
if((pCode->bardata[1] == '1') && (pCode->bardata[2] == ','))
{
tmp = VATBillMode(pCode);
return tmp;
}
}
return 0;
}