TMC32_QJB/App/billmode.c
2026-04-30 16:23:12 +08:00

559 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
******************************************************************************
* @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<36><34><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 <20><><EFBFBD><EFBFBD>˰<EFBFBD><CBB0><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>
* @param[in] pCode <20><><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 <20><><EFBFBD>ŷ<EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>Ҫȥ<D2AA><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ֱ<EFBFBD>Ӵ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD>
* @param[in] pCode <20><><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 ֧<><D6A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>
* @param[in] pCode <20><><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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>
* @param[in] pCode <20><><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 ȫ<><C8AB>E<EFBFBD><45>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>
* @param[in] pCode <20><><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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC>Ʊģʽ<C4A3><CABD><EFBFBD><EFBFBD>
* @param[in] pCode <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>0<EFBFBD><30><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;
}