/*
 * @Description: 工具模块-crc校验子模块
 * @Author: yangsw
 * @Date: 2021-05-24 16:12:07
 * @LastEditTime: 2023-01-09 21:45:30
 * @LastEditors: Lida
 * @Reference: 
 */
#include "util_crc.h"


static const unsigned short wCRCTalbeAbs[]={ 0x0000,0xCC01,0xD801,0x1400,0xF001,0x3C00,0x2800,0xE401,0xA001, 0x6C00,0x7800,
0xB401,0x5000,0x9C01,0x8801,0x4400 };

/**
 * @brief: CRC16-MODBUS
 * @return {short} CRC16结果
 * @note: 
 * @see: 
 * @param {unsigned char} *data 待计算数据
 * @param {unsigned short} len 待计算数据长度
 */
unsigned short Util_Crc16(unsigned char *data,unsigned short len){ 
    unsigned short wCRC=0xFFFF; 
    unsigned short i; 
    unsigned char chChar; 
    for(i = 0;i<len;i++){ 
        chChar = *data++; 
        wCRC= wCRCTalbeAbs[(chChar^wCRC)&15]^(wCRC>>4); 
        wCRC= wCRCTalbeAbs[((chChar>>4)^wCRC)&15]^(wCRC>>4); 
    }
    return wCRC; 
}

/**
 * @brief: CRC16-MODBUS-连续
 * @return {short} CRC16结果
 * @note: 数据太大时，用此函数分段计算CRC16
 * @see: 
 * @param {unsigned short} CRC 上一次CRC16结果
 * @param {unsigned char} *data 待计算数据
 * @param {unsigned short} len 待计算数据长度
 */
unsigned short Util_Crc16_Cut(unsigned short crc,unsigned char *data,unsigned short len){ 
    unsigned short wCRC=crc; 
    unsigned short i; 
    unsigned char chChar; 
    for(i = 0;i<len;i++){ 
        chChar = *data++; 
        wCRC= wCRCTalbeAbs[(chChar^wCRC)&15]^(wCRC>>4); 
        wCRC= wCRCTalbeAbs[((chChar>>4)^wCRC)&15]^(wCRC>>4); 
    }
    return wCRC; 
}

//在帧头 DDH 和帧尾 DCH 之间的数据出现的 DBH、DCH、DDH 分别与 40H 异或，变成（9BH、9CH、9DH）再在前加 DBH，如收到一个字节是 DDH，经过转义后变为 DBH，9DH.
gw_s16 Change_Original_Data(gw_u8 *in_data,gw_u16 in_len,gw_u8 *out_data){
    gw_u8* buff=Svc_Com_Get_Buf();
    if(buff==NULL){
        Svc_Log_Printf(LOG_ERROR,"%s->null buff!",__FUNCTION__);
        return -1;
    }
    buff[0]=in_data[0];
    gw_u16 j=1;
    gw_u16 i;
    for(i=1;i<in_len-1;i++){
        if(in_data[i]==0xDB||in_data[i]==0xDC||in_data[i]==0xDD){
            buff[j]=0xDB;
            j++;
            buff[j]=(in_data[i]^0x40);
        }else{
             buff[j]=in_data[i];
        }
        j++;
    }
    buff[j] = in_data[i];
    gw_u16 out_len=j+1;
    memcpy(out_data,buff,out_len);
    return out_len;
}

//在帧头 DDH 和帧尾 DCH 之间的数据出现的 DBH 9DH、DBH 9CH、DBH 9BH ,去掉DBH,（9BH、9CH、9DH）分别与 40H 异或，变成（DBH、DCH、DDH）,如收到数据是 DBH 9DH，经过反转义后变为 DDH.
gw_s16 Get_Original_Data(gw_u8 *in_data,gw_u16 in_len,gw_u8 *out_data){
    gw_u8* buff=Svc_Com_Get_Buf();
    if(buff==NULL){
        Svc_Log_Printf(LOG_ERROR,"%s->null buff!",__FUNCTION__);
        return -1;
    }
    int j=0;
    for(int i=1;i<in_len-1;i++){
        if((in_data[i]&0xFF)==0xDB){
            if(in_data[i+1]==0x9B||in_data[i+1]==0x9C||in_data[i+1]==0x9D){
                    buff[j]=in_data[i+1]^0x40;
                    i++;
            }
        }else{
            buff[j]=in_data[i];
        }
        j++;
    }
    gw_u16 out_len=j;
    memcpy(out_data,buff,out_len);
    return out_len;
}

