Exemplo n.º 1
0
static VOID CheckParam(PNV_INFO pNvInfo)
{
extern BOOL_T CheckAuthCode(VOID);
extern  const UINT8    ZERO_MAC_ADDR[MAC_ADDR_LEN];
#define COPY_MAC_ADDR(Addr1, Addr2)             NST_MOVE_MEM((Addr1), (Addr2), MAC_ADDR_LEN)
#define MAC_ADDR_IS_GROUP(Addr)       (((Addr[0]) & 0x01))
#define TX_GAIN_MAP_TBL_SIZE     0x28//0x26

    UINT32  i = 0;

    // CHECK TX PWR
    for (i=0; i<MAX_TXPOWER_ARRAY_SIZE*MAX_CH_NUM; i++)
        if (*((PUINT8)&pNvInfo->MaxTxPwr[0] + i) > (TX_GAIN_MAP_TBL_SIZE-1))
        {
            *((PUINT8)&pNvInfo->MaxTxPwr[0] + i) = *((PUINT8)&DefaultTxPwrIdxTbl[0] + i);
        }
    if (i != MAX_TXPOWER_ARRAY_SIZE*MAX_CH_NUM)
    {
        DBGPRINT(DEBUG_INFO, "Power of NvInfo is invalid [%d] = 0x%0x \n", i, *((PUINT8)&pNvInfo->MaxTxPwr[0] + i));
        NST_MOVE_MEM(pNvInfo->MaxTxPwr, DefaultTxPwrIdxTbl, sizeof(pNvInfo->MaxTxPwr));
    }

    // CHECK MAC ADDR
    if ((!MAC_ADDR_IS_GROUP(pNvInfo->MacAddr)) && (!NST_EQUAL_MEM(pNvInfo->MacAddr, ZERO_MAC_ADDR, MAC_ADDR_LEN)))
        COPY_MAC_ADDR(PermanentAddress, pNvInfo->MacAddr);

#ifdef CHECK_AUTH_CODE
    if (CheckAuthCode() == NST_FALSE)
    {
        DBGPRINT(DEBUG_TRACE, "Check auth code failed, dead loop\n");
        while (1)
            ;
    }
#endif

}
Exemplo n.º 2
0
/*******************************************************************************
 * 函数功能:将固网支付规范报文(脚本POS报文)解析到公共数据结构。
 *           指令被多次使用,则从第2次起输出数据解析到szReserved自定义字段中,这些
 *           数据按TLV格式组织。需要用到这些数据的模块按TLV格式自行解析。TAG编码
 *           规则如下:
 *           a) Tag为三字节
 *           b) 第一位0xDF
 *           c) 第二位 bit8为1,表示TAG有后续位,bit7-bit1表示指令编号,例如9号
 *              指令,读取商务应用号为 0x89 
 *           d) 第三位 bit8为0,bit7-bit1表示指令出现次数,例如第二次执行,则为
 *              0x02
 *           e) 例如第二次执行商务应用号时,数据保存Tag为 \xDF\x89\x02
 * 输入参数:
 *           ptApp      -  公共数据结构指针
 *           szInData   -  接收到的数据
 *           iInLen     -  接收到的数据长度
 * 输出参数:
 *           ptApp      -  公共数据结构指针
 * 返 回 值: 
 *           FAIL       -  拆包失败
 *           SUCC       -  拆包成功
 *           INVALID_PACK - 非法报文
 * 作    者:Robin
 * 日    期:2012/12/11
 * 修订日志:
 *
 ******************************************************************************/
int UnpackScriptPos(T_App *ptApp, char *szInData, int iInLen)
{
    int     i;
    int     iIndex;                     /* 报文拆解索引值 */
    char    szTmpBuf[1024+1];           /* 临时变量 */
    int     iMsgLen;                    /* 消息内容长度 */
    int     iMsgIndex;                  /* 消息内容开始索引值 */
    int     iCmdNum;                    /* 流程代码个数 */
    int     iCmdLen;                    /* 流程代码长度 */
    char    szCmdData[512+1];           /* 流程代码内容 */
    int     iDataLen;                   /* 有效数据长度 */
    int     iDataIndex;                 /* 有效数据开始索引值 */
    char    szAuthCode[4];              /* 网关认证码 */

    /* 报文拆解 */
    iIndex = 0;

    /* TPDU */
    /* 跳过60 */
    iIndex += 1;

    /* 目的地址 */
    memcpy(ptApp->szTargetTpdu, szInData+iIndex, 2);
    iIndex += 2;
#ifdef DEBUG
    WriteLog(TRACE, "TPDU 目的地址:[%02x %02x]",
             ptApp->szTargetTpdu[0], ptApp->szTargetTpdu[1]);
#endif

    /* 源地址 */
    memcpy(ptApp->szSourceTpdu, szInData+iIndex, 2);
    iIndex += 2;
#ifdef DEBUG
    WriteLog(TRACE, "TPDU 源地址:[%02x %02x]",
             ptApp->szSourceTpdu[0], ptApp->szSourceTpdu[1]);
#endif

    /* 上送电话号码 */
    if(memcmp(szInData+iIndex, "\x4C\x52\x49\x00\x1C", 5) == 0)
    {
        /* 电话号码标识头 */
        iIndex += 5;

        /* 主叫号码 */
        memset(szTmpBuf, 0, sizeof(szTmpBuf));
        BcdToAsc(szInData+iIndex, 16, LEFT_ALIGN, (uchar*)szTmpBuf);

        for(i=0;i<16;i++)
        {
            if(szTmpBuf[i] != '0')
            {
                break;
            }
        }
        memcpy(ptApp->szCallingTel, szTmpBuf+i, 16-i);
        iIndex += 8;
#ifdef DEBUG
        WriteLog(TRACE, "主叫号码:[%s]", ptApp->szCallingTel);
#endif

        /* 被叫号码 */        
        memset(szTmpBuf, 0, sizeof(szTmpBuf));
        BcdToAsc(szInData+iIndex, 16, LEFT_ALIGN, (uchar*)szTmpBuf);

        for(i=0;i<16;i++)
        {
            if(szTmpBuf[i] != '0')
            {
                break;
            }
        }
        memcpy(ptApp->szCalledTelByNac, szTmpBuf+i, 16-i);
        iIndex += 8;
#ifdef DEBUG
        WriteLog(TRACE, "被叫号码:[%s]", ptApp->szCalledTelByNac);
#endif

        /* 电话号码标识尾 */
        iIndex += 12;
    }

    /* 报文同步序号 */
    iIndex += 1;

    /* 交易数据索引号 */
    iIndex += 2;

    /* 呼叫类型 */
    iIndex += 1;

    /* 接入网关编号 */
    ptApp->iFskId = (uchar)szInData[iIndex];
    iIndex ++;
#ifdef DEBUG
    WriteLog(TRACE, "接入网关编号:[%d]", ptApp->iFskId);
#endif

    /* 接入网关模块号 */
    ptApp->iModuleId = (uchar)szInData[iIndex];
    iIndex ++;
#ifdef DEBUG
    WriteLog(TRACE, "接入网关模块号:[%d]", ptApp->iModuleId);
#endif

    /* 接入网关通道号 */
    ptApp->iChannelId = (uchar)szInData[iIndex];
    iIndex ++;
#ifdef DEBUG
    WriteLog(TRACE, "接入网关通道号:[%d]", ptApp->iChannelId);
#endif

    /******************************消息内容数据拆包******************************/
    /* 消息内容长度 */
    iMsgLen = ((uchar)szInData[iIndex])*256 + (uchar)szInData[iIndex+1];
    iIndex += 2;

    /* 扣除MAC长度 */
    iMsgLen = iMsgLen - 8;
#ifdef DEBUG
    WriteLog(TRACE, "消息内容长度:[%d]", iMsgLen);
#endif

    /* 判断消息内容长度是否超出 */
    if(iMsgLen <= 0 || iMsgLen > 1024 || iMsgLen > (iInLen-iIndex-8))
	{
		WriteLog(ERROR, "消息内容长度[%d]非法!实际消息内容长度[%d]",
		         iMsgLen, iInLen-iIndex-8);

		return INVALID_PACK;
	}

    /* 消息内容 */
    /* 记录消息内容开始索引值,用于MAC计算 */
    iMsgIndex = iIndex;

    /* 报文类型 */
#ifdef DEBUG
    WriteLog(TRACE, "报文类型:[%02x]", szInData[iIndex]);
#endif
    iIndex += 1;

    /* 结束标志 */
#ifdef DEBUG
    WriteLog(TRACE, "结束标志:[%02x]", szInData[iIndex]);
#endif
    iIndex += 1; 

    /* 报文版本 */
    memcpy(ptApp->szMsgVer, szInData+iIndex, 2);    
    iIndex += 2;
#ifdef DEBUG
    WriteLog(TRACE, "报文版本:[%02x%02x]", ptApp->szMsgVer[0], ptApp->szMsgVer[1]);
#endif

    /* 应用脚本版本 */
    memcpy(ptApp->szAppVer, szInData+iIndex, 4);    
    iIndex += 4;
#ifdef DEBUG
    WriteLog(TRACE, "应用脚本版本:[%02x%02x%02x%02x]",
             ptApp->szAppVer[0], ptApp->szAppVer[1],
             ptApp->szAppVer[2], ptApp->szAppVer[3]);
#endif

    /* 终端程序版本 */
    BcdToAsc(szInData+iIndex, 8, LEFT_ALIGN, ptApp->szPosCodeVer);
    iIndex += 4;
#ifdef DEBUG
    WriteLog(TRACE, "终端程序版本:[%s]", ptApp->szPosCodeVer);
#endif

    /* 终端类型 */
    memcpy(ptApp->szPosType, szInData+iIndex, 10);
    iIndex += 10;
#ifdef DEBUG
    WriteLog(TRACE, "终端类型:[%s]", ptApp->szPosType);
#endif

    /* 网关认证码 */
    memcpy(szAuthCode, szInData+iIndex, 4);
    iIndex += 4;
#ifdef DEBUG
    WriteLog(TRACE, "网关认证码:[%02x%02x%02x%02x]",
             szAuthCode[0] & 0xFF, szAuthCode[1] & 0xFF,
             szAuthCode[2] & 0xFF, szAuthCode[3] & 0xFF);
#endif

    /* POS上送被叫号码 */
    memcpy(ptApp->szCalledTelByTerm, szInData+iIndex, 15);
    iIndex += 15;
    DelTailSpace(ptApp->szCalledTelByTerm);
#ifdef DEBUG
    WriteLog(TRACE, "POS上送被叫号码:[%s]", ptApp->szCalledTelByTerm);
#endif

    /* 来电显示标志 */
#ifdef DEBUG
    WriteLog(TRACE, "来电显示标志:[%c]", szInData[iIndex]);
#endif
    iIndex += 1;    

    /* 安全模块号 */
    memcpy(ptApp->szPsamNo, szInData+iIndex, 16);
    iIndex += 16;
#ifdef DEBUG
    WriteLog(TRACE, "安全模块号:[%s]", ptApp->szPsamNo);
#endif

    /* POS流水号 */
    memset(szTmpBuf, 0, sizeof(szTmpBuf));
    BcdToAsc(szInData+iIndex, 6, LEFT_ALIGN, (uchar*)szTmpBuf);
    ptApp->lPosTrace = atol(szTmpBuf);
    iIndex += 3;
#ifdef DEBUG
    WriteLog(TRACE, "POS流水号:[%ld]", ptApp->lPosTrace);
#endif

    /* 交易代码 */
    BcdToAsc(szInData+iIndex, 8, LEFT_ALIGN, ptApp->szTransCode);
    iIndex += 4;
#ifdef DEBUG
    WriteLog(TRACE, "交易代码:[%s]", ptApp->szTransCode);
#endif

    /* 根据szTransCode获取交易信息 */
    if(GetTranInfo(ptApp) != SUCC)
    {
        WriteLog(ERROR, "获取交易码[%s]对应交易定义失败!", ptApp->szTransCode);

        return FAIL;
    }

    /* trans_def交易定义表中trans_code标识终端交易,trans_type标识平台交易。并约定trans_type低4位相同,
       对平台而言,这些交易对应平台同一个交易,可以采用完全相同的交易流程。即在此trans_type做模10000处
       理,这样对于平台的所有模块都只需要按一个交易处理。*/
    ptApp->iTransType = ptApp->iTransType % 10000;

    /* 交易重发报文 */
    if(szInData[iMsgIndex] == 0x03)
    {
        ptApp->iOldTransType = ptApp->iTransType;

        ptApp->iTransType = RESEND;
    }

    /* 获取终端信息,检查终端是否需要更新 */
    if(ChkTermInfo(ptApp) != SUCC)
    {
        return FAIL;
    }

    /******************************流程代码数据拆包******************************/
    /* 流程代码个数 */
    iCmdNum = (uchar)szInData[iIndex];    
    iIndex ++;
#ifdef DEBUG
    WriteLog(TRACE, "流程代码个数:[%d]", iCmdNum);
#endif

    /* 计算流程代码长度 */
    iCmdLen = 0;

    for(i=0;i<iCmdNum;i++)
    {
        iCmdLen += CalcCmdBytes((uchar)szInData[iIndex+iCmdLen]);
    }
#ifdef DEBUG
    WriteLog(TRACE, "流程代码长度:[%d]", iCmdLen);
#endif

    /* 流程代码 */
    memset(szCmdData, 0, sizeof(szCmdData));
    memcpy(szCmdData, szInData+iIndex, iCmdLen);    
    iIndex += iCmdLen;

    /* 有效数据长度 */
    iDataLen = ((uchar)szInData[iIndex])*256 + (uchar)szInData[iIndex+1];
    iIndex += 2;

    /* 判断有效数据长度是否超出 */
	if(iDataLen > 1024 || iDataLen > (iInLen-iIndex))
	{
        WriteLog(ERROR, "有效数据长度[%d]非法!实际消息内容长度[%d]",
                 iDataLen, iInLen-iIndex);

		return INVALID_PACK;
	}

    /******************************指令数据解析******************************/
    /* 记录有效数据开始索引值 */
    iDataIndex = iIndex;
    
    if(PosOutput(ptApp, iCmdNum, szCmdData, iCmdLen, szInData+iDataIndex, iDataLen) != SUCC)
    {
		return INVALID_PACK;
    }

    /* 除了签到、回响测试、柜员签到交易以外,都需要进行MAC校验 */
    if((ptApp->iTransType != LOGIN &&
        ptApp->iTransType != ECHO_TEST &&
        ptApp->iTransType != DOWN_ALL_FUNCTION &&
        ptApp->iTransType != DOWN_ALL_MENU &&
        ptApp->iTransType != DOWN_ALL_PRINT &&
        ptApp->iTransType != DOWN_ALL_TERM &&
        ptApp->iTransType != DOWN_ALL_PSAM &&
        ptApp->iTransType != DOWN_ALL_ERROR &&
        ptApp->iTransType != TEST_DISP_OPER_INFO &&
        ptApp->iTransType != TEST_PRINT &&
        ptApp->iTransType != DOWN_ALL_OPERATION &&
        ptApp->iTransType != CENDOWN_ALL_OPERATION &&
        ptApp->iTransType != REGISTER &&
        ptApp->iTransType != TERM_REGISTER &&
        ptApp->iTransType != AUTO_VOID &&
        ptApp->iTransType != OPER_LOGIN) && giMacChk == 1)
    {
        memset(szTmpBuf, 0, sizeof(szTmpBuf));
        if(HsmCalcMac(ptApp, XOR_CALC_MAC, ptApp->szMacKey, 
                      szInData+iMsgIndex, iMsgLen, szTmpBuf) != SUCC)
        {
            WriteLog(ERROR, "计算报文MAC错误!");

            strcpy(ptApp->szRetCode, ERR_SYSTEM_ERROR);

            return FAIL;
        }

        if(memcmp(ptApp->szMac, szTmpBuf, 8) != 0) 
        {
            WriteLog(ERROR, "报文MAC错误!");

            strcpy(ptApp->szRetCode, ERR_MAC);
#ifdef DEBUG
            WriteLog(TRACE, "报文上送MAC:[%02x%02x%02x%02x] 计算MAC:[%02x%02x%02x%02x]",
            ptApp->szMac[0] & 0xFF, ptApp->szMac[1] & 0xFF,
            ptApp->szMac[2] & 0xFF, ptApp->szMac[3] & 0xFF,
            szTmpBuf[0] & 0xFF, szTmpBuf[1] & 0xFF,
            szTmpBuf[2] & 0xFF, szTmpBuf[3] & 0xFF);
#endif
            return FAIL;
        }
    }

    WriteAppStru(ptApp, "Read from ePos");

    /* 校验网关认证码 */
    if(CheckAuthCode(szAuthCode, ptApp->szPsamNo) != SUCC)
    {     
        WriteLog(ERROR, "验证网关认证码失败!");

        strcpy(ptApp->szRetCode, ERR_AUTHCODE);

        return FAIL; 
    }

    return SUCC;
}