/*****************************************************************************
Copyright: 2013-2018, ZhiWan Tech. Co., Ltd.
File name:ps_ap.c
Description: 网管协议栈AP层
Author: 周涛
Version: 0.0.01
Date: 2022-4-15
History:
*****************************************************************************/
#include "includes.h"

static uint8 gPs_abyTempData[UDP_FRAME_MAX_LEN];

// CRC16标准值
static uint16 s_crc_table[16] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef};

// 模块初始化
void ps_ap_init(void)
{
    SYS_MEMSET(&gPs_abyTempData, 0, UDP_FRAME_MAX_LEN);
    return;
}

// 对数据进行转义处理
// pbyData:  待转义数据
// wLen:  数据长度
uint8 ps_ap_transfer(uint8 *pbyData, uint16 *wLen)
{
    uint16 i = 0;
    uint16 wCounter = 0;

    // 转移处理
    SYS_MEMSET(gPs_abyTempData, 0, UDP_FRAME_MAX_LEN);
    for (i = 1; i < (*wLen - 1); i++)
    {
        if (0x5E == pbyData[i]) // 将0x5E转义成0x5E,0x5D
        {
            gPs_abyTempData[wCounter] = 0x5E;
            wCounter++;
            gPs_abyTempData[wCounter] = 0x5D;
            wCounter++;
        }
        else if (0x7E == pbyData[i]) // 将0x7E转义成0x5E,0x7D
        {
            gPs_abyTempData[wCounter] = 0x5E;
            wCounter++;
            gPs_abyTempData[wCounter] = 0x7D;
            wCounter++;
        }
        else // 其它字符直接拷贝，不做转义处理
        {
            gPs_abyTempData[wCounter] = pbyData[i];
            wCounter++;
        }

        // 长度超长
        if ((wCounter + 2) > UDP_FRAME_MAX_LEN)
        {
            return 1;
        }
    }

    // 将数据拷贝回pbyData中
    for (i = 0; i < wCounter; i++)
    {
        pbyData[i + 1] = gPs_abyTempData[i];
    }

    pbyData[wCounter + 1] = pbyData[0]; // 保存结尾字符
    *wLen = wCounter + 2;

    return 0;
}

// 对输入数据实施转义逆操作
// pbyData:   待逆转义数据, wLen:  数据长度
uint8 ps_ap_transfer_reverse(uint8 *pbyData, uint16 *wLen)
{
    uint16 i = 0;
    uint16 wCounter = 0;
    uint8 byFlag = 0;

    // 逆向转义处理
    SYS_MEMSET(gPs_abyTempData, 0, UDP_FRAME_MAX_LEN);
    for (i = 1; i < (*wLen - 1); i++)
    {
        if ((0x5E == pbyData[i]) && (0x5D == pbyData[i + 1])) /*处理0x5E和0x5D两个连续字符*/
        {
            gPs_abyTempData[wCounter] = 0x5E;
            i++;
            wCounter++;
        }
        else if ((0x5E == pbyData[i]) && (0x7D == pbyData[i + 1])) /*处理0x5E和0x7D两个连续字符*/
        {
            gPs_abyTempData[wCounter] = 0x7E;
            i++;
            wCounter++;
        }
        else /*处理其它字符*/
        {
            gPs_abyTempData[wCounter] = pbyData[i];
            wCounter++;
        }

        /*数据过长退出转移处理*/
        if ((wCounter + 2) > UDP_FRAME_MAX_LEN)
        {
            return 1;
        }
    }

    // 将保存在abyTmp中的临时数据拷贝回pbyData指针中
    for (i = 0; i < wCounter; i++)
    {
        pbyData[i + 1] = gPs_abyTempData[i];
    }

    pbyData[wCounter + 1] = pbyData[0]; // 保存结束标识符
    *wLen = wCounter + 2;

    return 0;
}

// 生成crc校验码
uint16 ps_crc16(uint8 *data, uint16 len, uint16 def_crc)
{
    uint16 crc = def_crc;
    uint8 crc_h4;
    uint8 *ptr = data;

    while (len--)
    {
        crc_h4 = (uint8)(crc >> 12);
        crc <<= 4;
        crc ^= s_crc_table[crc_h4 ^ (*ptr >> 4)];
        crc_h4 = (uint8)(crc >> 12);
        crc <<= 4;
        crc ^= s_crc_table[crc_h4 ^ (*ptr & 0x0f)];
        ptr++;
    }

    return crc;
}

// AP层上行处理单元。包括帧同步，字符转义逆操作和CRC校验。数据正确则上行至VP层
// pbyData:从接口适配层接收的数据
// bySource:数据来源
// wLen:数据长度,
uint8 ps_up_ap_in(uint8 *pbyData, uint8 bySource, uint16 wLen)
{
    uint8 byFlag = 0;
    PS_HEAD_T *pstHead = (PS_HEAD_T *)pbyData;
    uint16 wCrc = 0;
    PS_TAIL_T *pstTail = NULL;

    // 参数合法性检查
    if (NULL == pbyData || UDP_FRAME_MIN_LEN > wLen || UDP_FRAME_MAX_LEN < wLen)
    {
        return 1;
    }

    // 校验帧头
    if (PS_AP_HEAD_FLAG != pstHead->stApHead.byStartFlag)
    {
        return 1;
    }

    // 反向转义处理
    byFlag = ps_ap_transfer_reverse(pbyData, &wLen);
    if (byFlag)
    {
        return byFlag;
    }

    // 校验帧尾
    pstTail = (PS_TAIL_T *)(pbyData + (wLen - 3));
    if (PS_AP_TAIL_FLAG != pstTail->byStopFlag)
    {
        return 1;
    }

    // CRC校验检查
    wCrc = ps_crc16(pbyData + 1, wLen - 4, 0); // 生成crc码
    if (pstTail->wCrc != wCrc)
    {
        return 1;
    }

    // VP 层数据输入处理
    byFlag = ps_up_vp_in(pbyData, bySource, wLen);
    if (byFlag)
    {
        return 1;
    }

    return 0;
}

// AP层下行处理单元。包括字符转义处理、CRC校验和数据发送至协议栈匹配层。
// pbyData:从接口适配层接收的数据
// bySource:数据来源，0：网管中心，1：GUI网管，2：本地上报
// wLen:数据长度
uint8 ps_down_ap_out(uint8 *pbyData, uint8 bySource, uint16 wLen)
{
    uint8 byFlag = 0;
    uint16 wCrc = 0;
    PS_TAIL_T *pstTail = (PS_TAIL_T *)(pbyData + (wLen - 3));

    if (pbyData == NULL || wLen < UDP_FRAME_MIN_LEN || wLen > UDP_FRAME_MAX_LEN)
    {
        return 1; // 参数不合法
    }

    // 添加CRC校验值
    wCrc = ps_crc16(pbyData + 1, wLen - 4, 0);
    pstTail->wCrc = wCrc;

    // 转义处理
    byFlag = ps_ap_transfer(pbyData, &wLen);
    if (byFlag)
    {
        return byFlag;
    }

    // 把数据发送到协议栈接口适配层
    byFlag = ps_receive_data_from_insite(pbyData, bySource, wLen);
    if (byFlag)
    {
        return byFlag;
    }

    return 0;
}
