#include "lip_opcua_tstmp.h"




#if LIP_OPCUA_ENABLE

#if LIP_PTP_ENABLE

    void lip_opcua_tstmp_to_ptp(const t_lip_opcua_tstmp *opcua_tstmp, t_lip_ptp_tstmp *ptp_tstmp, const t_lip_ptp_time_info *time_info) {
        int64_t sec = opcua_tstmp->ns100 / LIP_OPCUA_TSTMP_TICK_SEC;
        uint32_t ns100 = opcua_tstmp->ns100 % LIP_OPCUA_TSTMP_TICK_SEC;

        if (sec < (LIP_OPCUA_TSTMP_SEC_TO_PTP_EPOCH - time_info->currentUtcOffset)) {
            sec = 0;
        } else {
            sec -= (LIP_OPCUA_TSTMP_SEC_TO_PTP_EPOCH - time_info->currentUtcOffset);
        }
        ptp_tstmp->sec = (uint32_t)sec;
        ptp_tstmp->hsec = (uint16_t)(sec >> 32);
        ptp_tstmp->ns = ns100 * 100;
        ptp_tstmp->fract_ns = 0;
    }

    void lip_opcua_tstmp_from_ptp(const t_lip_ptp_tstmp *ptp_tstmp, t_lip_opcua_tstmp *opcua_tstmp, const t_lip_ptp_time_info *time_info) {
        uint64_t sec = ptp_tstmp->sec + ((uint64_t)ptp_tstmp->hsec << 32);
        if (time_info->flags1 & LIP_PTP_MSGFLAG1_PTP_TIMESCALE) {
            sec += (LIP_OPCUA_TSTMP_SEC_TO_PTP_EPOCH - time_info->currentUtcOffset);
        }
        opcua_tstmp->ns100 = sec * LIP_OPCUA_TSTMP_TICK_SEC + ptp_tstmp->ns / 100;
    }

#if LIP_OPCUA_TSTMP_PICOSEC_EN
    void lip_opcua_pubsub_tstmp_to_ptp(const t_lip_opcua_tstmp *opcua_tstmp, t_lip_ptp_tstmp *ptp_tstmp, uint8_t leap_sec) {
        int64_t sec = opcua_tstmp->ns100 / LIP_OPCUA_TSTMP_TICK_SEC;
        uint32_t ns100 = opcua_tstmp->ns100 % LIP_OPCUA_TSTMP_TICK_SEC;

        if (sec < (LIP_OPCUA_TSTMP_SEC_TO_PTP_EPOCH - leap_sec)) {
            sec = 0;
        } else {
            sec -= (LIP_OPCUA_TSTMP_SEC_TO_PTP_EPOCH - leap_sec);
        }
        ptp_tstmp->sec = (uint32_t)sec;
        ptp_tstmp->hsec = (uint16_t)(sec >> 32);
        ptp_tstmp->ns = ns100 * 100;
        ptp_tstmp->ns += opcua_tstmp->ps / 1000;
        ptp_tstmp->fract_ns = (opcua_tstmp->ps % 1000) * 0x10000 / 1000;
    }

    void lip_opcua_pubsub_tstmp_from_ptp(const t_lip_ptp_tstmp *ptp_tstmp, t_lip_opcua_tstmp *opcua_tstmp, uint8_t leap_sec) {
        uint64_t sec = ptp_tstmp->sec + ((uint64_t)ptp_tstmp->hsec << 32);
        sec += (LIP_OPCUA_TSTMP_SEC_TO_PTP_EPOCH - leap_sec);
        opcua_tstmp->ns100 = sec * LIP_OPCUA_TSTMP_TICK_SEC + ptp_tstmp->ns / 100;
        opcua_tstmp->ps = ptp_tstmp->fract_ns * 1000 / 0x10000 + (ptp_tstmp->ns % 100) * 1000;
    }
#endif
#endif

#endif
