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

490 lines
9.7 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 outprompts.c
* @author TMC Scan Team
* @version V1.0.0
* @date 09/07/2019
* @brief
******************************************************************************
*
* 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"
const uint8_t aliPayCodeType[6][2] = {{0x32, 0x35}, {0x32, 0x36}, {0x32, 0x37}, {0x032, 0x38}, {0x32, 0x39}, {0x33, 0x30}};
const uint8_t weiPayCodeType[6][2] = {{0x31, 0x30}, {0x31, 0x31}, {0x31, 0x32}, {0x31, 0x33}, {0x31, 0x34}, {0x31, 0x35}};
const uint8_t cloudPayCodeType[2] = {0x36, 0x32};
extern uint8_t gReceiveKey;
/**
* @function ScanCodeType
* @brief 区分支付码类型
* @param[in] pCode 扫码结果
* @return 支付码类型(微信、支付宝、云闪付、其它)
*/
uint8_t ScanCodeType(BarData *pCode)
{
uint8_t tmpBuf[2];
uint8_t i = 0;
memcpy(tmpBuf, pCode->bardata, 2);
if((Memcmp(tmpBuf, (uint8_t *)&cloudPayCodeType, 2) == TRUE) && (pCode->datalen == CLOUDPAY_LEN))
{
return CLOUDPAY;
}
for(i = 0; i < 6; i++)
{
if((Memcmp(tmpBuf, (uint8_t *)&weiPayCodeType[i][0], 2) == TRUE) && (pCode->datalen == WECHATPAY_LEN))
{
return WECHATPAY;
}
if(Memcmp(tmpBuf, (uint8_t *)&aliPayCodeType[i][0], 2) == TRUE)
{
if((pCode->datalen >= ALIPAY_LEN_MIN) && (pCode->datalen <= ALIPAY_LEN_MAX))
{
return ALIPAY;
}
}
}
return OTHERPAY;
}
/**
* @function InputCodeType
* @brief 判断输入数据的编码格式
* @param[in] pCode input data
* @return
*/
uint8_t InputCodeType(BarData *pCode)
{
uint8_t codeType = GBK;
uint8_t *ptr = pCode->bardata;
uint8_t gbkFlag = TRUE;
int utfByte, inputData = 0;;
char b2, b3, b4;
if(gConfgBuf.inputCodeType == UTF8)
{
codeType = UTF8;
}
else
{
if(gConfgBuf.inputCodeType == AUTO) // AUTO
{
//根据解码结果判断当前编码是gbk还是utf_8,如果都不是按照gbk处理
while(inputData < pCode->datalen)
{
if(*(ptr + inputData) < 0x80)
{
inputData ++;
}
else
{
gbkFlag = FALSE;
//先按照utf-8解析
utfByte = enc_get_utf8_size(*(ptr + inputData));
switch(utfByte)
{
case 1:
inputData ++;
break;
case 2:
b2 = *(ptr + inputData + 1);
if((b2 >> 6) != 0x02)
{
codeType = GBK;
return codeType;
}
else
{
inputData += 2;
}
break;
case 3:
b2 = *(ptr + inputData + 1);
b3 = *(ptr + inputData + 2);
if(((b2 >> 6) != 0x02) || ((b3 >> 6) != 0x02))
{
codeType = GBK;
return codeType;
}
else
{
inputData += 3;
}
break;
case 4:
b2 = *(ptr + inputData + 1);
b3 = *(ptr + inputData + 2);
b4 = *(ptr + inputData + 3);
if(((b2 >> 6) != 0x02) || ((b3 >> 6) != 0x02) || ((b4 >> 6) != 0x02))
{
codeType = GBK;
return codeType;
}
else
{
inputData += 4;
}
break;
case 0:
codeType = GBK;
return codeType;
default:
codeType = GBK;
return codeType;
}
}
}
if(gbkFlag == TRUE)
{
codeType = GBK;
}
else
{
codeType = UTF8;
}
}
else
{
codeType = GBK;
}
}
return codeType;
}
/**
* @function ECIModeCheck
* @brief 检测数据是否含有ECI模式如果有去掉ECI数据
* @param[in] pCode 扫码结果
* @return
*/
void ECIModeCheck(BarData *pCode)
{
uint8_t *pTmpData = (uint8_t *)MIDOUTBUF;
uint16_t codelen = pCode->datalen, i = 0, j, offset = 0;
if(!pCode->containECI)
{
return;
}
memcpy(pTmpData, pCode->bardata, codelen);
while(i < codelen)
{
if(i < (codelen - ECI_NUMBER_NUM))
{
if(pTmpData[i] == '\\')
{
for(j = 0; j < ECI_NUMBER_NUM;j++)
{
if((pTmpData[i + 1 + j] < '0') || (pTmpData[i + 1 + j] > '9'))
{
break;
}
}
if(j == ECI_NUMBER_NUM)
{
i += (ECI_NUMBER_NUM + 1);
continue;
}
}
}
if((pTmpData[i] == '\\') && (pTmpData[i + 1] == '\\'))
{
i++;
continue;
}
pCode->bardata[offset++] = pTmpData[i++];
}
pCode->datalen = offset;
}
/**
* @function DataEdit
* @brief 数据编辑,按照特定的格式输出,默认格式 [前缀]][data][后缀][结束符]
* @param[in] pCode 扫码结果
* @return 数据长度
*/
uint16_t DataEdit(BarData *pCode)
{
uint16_t dataLen = 0, tmpLen;
uint8_t *pData = (uint8_t *)PREOUTBUF;
uint8_t *pOut = (uint8_t *)POSOUTBUF;
uint8_t inputCodeType, outputCodeType;
int tmp = 0;
//判断输入数据的格式。
inputCodeType = InputCodeType(pCode);
outputCodeType = gConfgBuf.outputCodeType;
if(gConfgBuf.billModeStatus == ON)
{
//发票模式
tmp = BillMode(pCode);
if(tmp > 0)
{
inputCodeType = UTF8;
outputCodeType = gConfgBuf.outputCodeType;
}
}
//ECI模式
if(gConfgBuf.ECIMode)
{
ECIModeCheck(pCode);
}
//前缀
if(gConfgBuf.prefixLen)
{
Memcpy(&pData[dataLen], gConfgBuf.prefix, gConfgBuf.prefixLen);
dataLen += gConfgBuf.prefixLen;
}
Memcpy(&pData[dataLen], pCode->bardata, pCode->datalen);
dataLen += pCode->datalen;
//后缀
if(gConfgBuf.prefixLen)
{
Memcpy(&pData[dataLen], gConfgBuf.suffix, gConfgBuf.suffixLen);
dataLen += gConfgBuf.suffixLen;
}
/*根据输入和输出数据的格式进行转换*/
if(inputCodeType == GBK)
{
if(outputCodeType == UNICODE)
{
tmpLen = GbkToUnicode(pData, pOut, dataLen);
dataLen = tmpLen;
}
else if(outputCodeType == UTF8)
{
tmpLen = GbkToUnicode(pData, (uint8_t *) MIDOUTBUF, dataLen);
tmpLen = unicode_to_utf8((uint8_t *) MIDOUTBUF, pOut, tmpLen);
dataLen = tmpLen;
}
else
{
Memcpy(pOut, pData, dataLen);
}
}
if(inputCodeType == UTF8)
{
if(outputCodeType == UNICODE)
{
tmpLen = utf8_to_unicode(pData, pOut, dataLen);
dataLen = tmpLen;
}
else if(outputCodeType == GBK)
{
tmpLen = utf8_to_unicode(pData, (uint8_t *) MIDOUTBUF, dataLen);
tmpLen = UnicodeToGbk((uint8_t *) MIDOUTBUF, pOut, tmpLen);
dataLen = tmpLen;
}
else
{
Memcpy(pOut, pData, dataLen);
}
}
//结束符
switch(gConfgBuf.endCode){
case END_DOCE_CRLF://换行回车
pOut[dataLen++] = '\r';
pOut[dataLen++] = '\n';
break;
case END_DOCE_TAB://TAB键
pOut[dataLen++] = '\t';
break;
case END_DOCE_CR://回车
pOut[dataLen++] = '\r';
break;
case END_DOCE_LF://new line
pOut[dataLen++] = '\n';
break;
defalut:
pOut[dataLen++] = '\n';
break;
}
return dataLen;
}
/**
* @function PayCodeReport
* @brief 设置码以外的码输出提示
* @param[in] pCode 解码数据
* @return
*/
void PayCodeReport(BarData *pCode)
{
uint16_t dataLen;
uint8_t payCodeType;
//蜂鸣器声音
if(gConfgBuf.buzzerStatus)
{
BuzzerSelect(SCAN_CODE_SUCCESS);
}
//补光灯闪烁
if(gConfgBuf.ledStatus && gConfgBuf.ledFlash)
{
AppLEDControl(LED_WHITE_FLASH);
}
//输出数据编辑,【Prefix】【Data】【Suffix】【结束符】
dataLen = DataEdit(pCode);
payCodeType = ScanCodeType(pCode);
if(payCodeType == WECHATPAY||payCodeType == ALIPAY||payCodeType == CLOUDPAY)
{
if(!gConfgBuf.payCodeEnable)
{
SetPackType(PACK_TYPEA);
SetOutputData((uint8_t *)"PAYCODEDISABLE", 14);
ReportData(pCode->bartype);
} else {
if(!gReceiveKey)
{
SetPackType(PACK_TYPEA);
SetOutputData((uint8_t *)"NOKEY", 5);
ReportData(pCode->bartype);
} else {
SetOutputData((uint8_t *)"PAY", 3);
SetOutputData((uint8_t *)POSOUTBUF, dataLen);
ReportData(pCode->bartype);
}
}
} else {
//扫码数据输出
if(!gReceiveKey)
{
SetPackType(PACK_TYPEA);
SetOutputData((uint8_t *)"NOKEY", 5);
ReportData(pCode->bartype);
} else {
SetOutputData((uint8_t *)"SCAN", 4);
SetOutputData((uint8_t *)POSOUTBUF, dataLen);
ReportData(pCode->bartype);
}
}
#if(SUPPORT_VOICE)
//语音播放
if(gConfgBuf.voiceStatus == VOICE_PAY)
{
//按支付码类型,区分语音类型播放
payCodeType = ScanCodeType(pCode);
{
if(gConfgBuf.voiceScanFinish == VOICE_FINISH_PRINT)
{
}
else if(gConfgBuf.voiceScanFinish == VOICE_SCAN_SUCCESS)
{
addPlayList(VOICEDATA,(uint8_t *)scanSuccessFile, sizeof(scanSuccessFile));
}
else
{
//除支付宝、微信、云闪付外,播放叮咚
addPlayList(VOICEDATA,(uint8_t *)scanFinishFile, sizeof(scanFinishFile));
}
}
}
else if(gConfgBuf.voiceStatus == VOICE_NO_PAY)
{
if(gConfgBuf.voiceScanFinish == VOICE_FINISH_PRINT)
{
}
else if(gConfgBuf.voiceScanFinish == VOICE_SCAN_SUCCESS)
{
addPlayList(VOICEDATA,(uint8_t *)scanSuccessFile, sizeof(scanSuccessFile));
}
else
{
//除支付宝、微信、云闪付外,播放叮咚
addPlayList(VOICEDATA,(uint8_t *)scanFinishFile, sizeof(scanFinishFile));
}
}
#endif
}
/**
* @function PayCodeReport
* @brief 设置码输出提示
* @param[in] pCode 解码数据
* @return
*/
void SetCodeReport(uint8_t setstatus)
{
//声音
if(gConfgBuf.buzzerStatus)
{
if(setstatus == TMC_OK)
{
BuzzerSelect(SET_CODE_SUCEESS);
}
else
{
BuzzerSelect(SET_CODE_ERROR);
}
}
#if(SUPPORT_VOICE)
//语音播放
if(gConfgBuf.voiceStatus)
{
if(setstatus == TMC_OK)
{
AppVoiceSelect(SET_CODE_SUCEESS);
}
else
{
AppVoiceSelect(SET_CODE_ERROR);
}
}
#endif
}