608 lines
18 KiB
C
608 lines
18 KiB
C
|
/******************************************************************************
|
||
|
* (C) Copyright 2018 EIGENCOMM International Ltd.
|
||
|
* All Rights Reserved
|
||
|
*******************************************************************************
|
||
|
* Filename: sntp.c
|
||
|
*
|
||
|
* Description: sntp
|
||
|
*
|
||
|
* History:creat by xwang
|
||
|
*
|
||
|
* Notes:
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
#include "lwip/opt.h"
|
||
|
|
||
|
|
||
|
#include "lwip/def.h"
|
||
|
#include "lwip/inet.h"
|
||
|
#include "lwip/sockets.h"
|
||
|
#include "posix/netdb.h"
|
||
|
#include "lwip/api.h"
|
||
|
#include "lwip/priv/api_msg.h"
|
||
|
#include "lwip/udp.h"
|
||
|
#include "lwip/dns.h"
|
||
|
#include "lwip/ip_addr.h"
|
||
|
|
||
|
#include "appmgr.h"
|
||
|
#include "networkmgr.h"
|
||
|
|
||
|
#include DEBUG_LOG_HEADER_FILE
|
||
|
#if (defined CHIP_EC618) || (defined CHIP_EC718) || (defined CHIP_EC716)
|
||
|
#include "slpman.h"
|
||
|
#elif defined CHIP_EC617
|
||
|
#include "slpman_ec617.h"
|
||
|
#endif
|
||
|
#include "sntp.h"
|
||
|
|
||
|
|
||
|
|
||
|
#define SNTP_THREAD_STACKSIZE 2048
|
||
|
#define SNTP_THREAD_PRIO 16
|
||
|
|
||
|
#define SNTP_ERR_KOD 1
|
||
|
|
||
|
/* SNTP protocol defines */
|
||
|
#define SNTP_MSG_LEN 48
|
||
|
|
||
|
#define SNTP_OFFSET_LI_VN_MODE 0
|
||
|
#define SNTP_LI_MASK 0xC0
|
||
|
#define SNTP_LI_NO_WARNING 0x00
|
||
|
#define SNTP_LI_LAST_MINUTE_61_SEC 0x01
|
||
|
#define SNTP_LI_LAST_MINUTE_59_SEC 0x02
|
||
|
#define SNTP_LI_ALARM_CONDITION 0x03 /* (clock not synchronized) */
|
||
|
|
||
|
#define SNTP_VERSION_MASK 0x38
|
||
|
#define SNTP_VERSION (4/* NTP Version 4*/<<3)
|
||
|
|
||
|
/* SNTP operating modes: default is to poll using unicast.
|
||
|
The mode has to be set before calling sntp_init(). */
|
||
|
#define SNTP_OPMODE_POLL 0
|
||
|
#define SNTP_OPMODE_LISTENONLY 1
|
||
|
|
||
|
#define SNTP_MODE_MASK 0x07
|
||
|
#define SNTP_MODE_CLIENT 0x03
|
||
|
#define SNTP_MODE_SERVER 0x04
|
||
|
#define SNTP_MODE_BROADCAST 0x05
|
||
|
|
||
|
#define SNTP_OFFSET_STRATUM 1
|
||
|
#define SNTP_STRATUM_KOD 0x00
|
||
|
|
||
|
#define SNTP_OFFSET_ORIGINATE_TIME 24
|
||
|
#define SNTP_OFFSET_RECEIVE_TIME 32
|
||
|
#define SNTP_OFFSET_TRANSMIT_TIME 40
|
||
|
|
||
|
/* number of seconds between 1900 and 1970 (MSB=1)*/
|
||
|
#define DIFF_SEC_1900_1970 (2208988800UL)
|
||
|
/* number of seconds between 1970 and Feb 7, 2036 (6:28:16 UTC) (MSB=0) */
|
||
|
#define DIFF_SEC_1970_2036 (2085978496UL)
|
||
|
|
||
|
#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0)
|
||
|
|
||
|
|
||
|
/**
|
||
|
* SNTP packet format (without optional fields)
|
||
|
* Timestamps are coded as 64 bits:
|
||
|
* - 32 bits seconds since Jan 01, 1970, 00:00
|
||
|
* - 32 bits seconds fraction (0-padded)
|
||
|
* For future use, if the MSB in the seconds part is set, seconds are based
|
||
|
* on Feb 07, 2036, 06:28:16.
|
||
|
*/
|
||
|
|
||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||
|
#include "arch/bpstruct.h"
|
||
|
#endif
|
||
|
PACK_STRUCT_BEGIN
|
||
|
struct SntpMsg {
|
||
|
PACK_STRUCT_FLD_8(u8_t li_vn_mode);
|
||
|
PACK_STRUCT_FLD_8(u8_t stratum);
|
||
|
PACK_STRUCT_FLD_8(u8_t poll);
|
||
|
PACK_STRUCT_FLD_8(u8_t precision);
|
||
|
PACK_STRUCT_FIELD(u32_t root_delay);
|
||
|
PACK_STRUCT_FIELD(u32_t root_dispersion);
|
||
|
PACK_STRUCT_FIELD(u32_t reference_identifier);
|
||
|
PACK_STRUCT_FIELD(u32_t reference_timestamp[2]);
|
||
|
PACK_STRUCT_FIELD(u32_t originate_timestamp[2]);
|
||
|
PACK_STRUCT_FIELD(u32_t receive_timestamp[2]);
|
||
|
PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]);
|
||
|
} PACK_STRUCT_STRUCT;
|
||
|
PACK_STRUCT_END
|
||
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||
|
#include "arch/epstruct.h"
|
||
|
#endif
|
||
|
|
||
|
#if 0
|
||
|
struct SntpMsg {
|
||
|
UINT8 li_vn_mode;
|
||
|
UINT8 stratum;
|
||
|
UINT8 poll;
|
||
|
UINT8 precision;
|
||
|
UINT32 root_delay;
|
||
|
UINT32 root_dispersion;
|
||
|
UINT32 reference_identifier;
|
||
|
UINT32 reference_timestamp[2];
|
||
|
UINT32 originate_timestamp[2];
|
||
|
UINT32 receive_timestamp[2];
|
||
|
UINT32 transmit_timestamp[2];
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
|
||
|
typedef struct SntpConfig_Tag{
|
||
|
UINT16 serverPort;
|
||
|
UINT16 reqHandler;
|
||
|
UINT16 autoSync;
|
||
|
UINT8 cid;
|
||
|
UINT8 rsvd;
|
||
|
CHAR serverAddr[DNS_MAX_NAME_LENGTH];
|
||
|
}SntpConfig;
|
||
|
|
||
|
|
||
|
static NET_ZI_DEF BOOL sntpIsOngoing = FALSE;
|
||
|
static NET_ZI_DEF sys_thread_t sntpThread = NULL;
|
||
|
static NET_ZI_DEF BOOL sntpTerminalFlag = FALSE;
|
||
|
static NET_ZI_DEF SntpConfig gSntpConfig;
|
||
|
|
||
|
/** Saves the last timestamp sent (which is sent back by the server)
|
||
|
* to compare against in response */
|
||
|
static NET_ZI_DEF UINT32 sntpLastTimeStampSent[2];
|
||
|
|
||
|
|
||
|
void SntpCallResultCallback(UINT32 result, UINT32 seconds, UINT32 us)
|
||
|
{
|
||
|
NmAtiSntpResultInt resultInd;
|
||
|
|
||
|
memset(&resultInd, 0, sizeof(NmAtiSntpResultInt));
|
||
|
|
||
|
|
||
|
resultInd.result = result;
|
||
|
resultInd.autoSync = gSntpConfig.autoSync;
|
||
|
resultInd.time = seconds;
|
||
|
resultInd.us = us;
|
||
|
|
||
|
AppMgrSendSntpResultInd(&resultInd, gSntpConfig.reqHandler);
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpCallResultCallback_1, P_INFO, 1, "SntpCallResultCallback result %u", result);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL SntpRecvResponse(struct SntpMsg *response, UINT32 *seconds, UINT32 *useconds)
|
||
|
{
|
||
|
UINT8 mode;
|
||
|
UINT8 stratum;
|
||
|
UINT32 rxSecs;
|
||
|
int is1900Based;
|
||
|
|
||
|
if(response == NULL || seconds == NULL || useconds == NULL)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpRecvResponse_1, P_WARNING, 0, "SntpRecvResponse: invalid parameter");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//init seconds and useconds
|
||
|
*seconds = 0;
|
||
|
*useconds = 0;
|
||
|
|
||
|
//parse the sntp response message
|
||
|
mode = response->li_vn_mode;
|
||
|
mode &= SNTP_MODE_MASK;
|
||
|
|
||
|
/* if this is a SNTP response... */
|
||
|
if (mode == SNTP_MODE_SERVER || mode == SNTP_MODE_BROADCAST)
|
||
|
{
|
||
|
|
||
|
stratum = response->stratum;
|
||
|
|
||
|
if (stratum == SNTP_STRATUM_KOD)
|
||
|
{
|
||
|
/* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpRecvResponse_2, P_WARNING, 0, "SntpRecvResponse: Received Kiss-of-Death");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* check originate_timetamp against sntp_last_timestamp_sent */
|
||
|
if ((response->originate_timestamp[0] != sntpLastTimeStampSent[0]) ||
|
||
|
(response->originate_timestamp[1] != sntpLastTimeStampSent[1]))
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpRecvResponse_3, P_WARNING, 0,
|
||
|
"SntpRecvResponse: Invalid originate timestamp in response");
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* correct answer */
|
||
|
rxSecs = ntohl(response->receive_timestamp[0]);
|
||
|
is1900Based = ((rxSecs & 0x80000000) != 0);
|
||
|
*seconds = is1900Based ? (rxSecs - DIFF_SEC_1900_1970) : (rxSecs + DIFF_SEC_1970_2036);
|
||
|
*useconds = ntohl(response->receive_timestamp[1]) / 4295;
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpRecvResponse_4, P_INFO, 2,
|
||
|
"SntpRecvResponse: correct response seconds %u,useconds %u", *seconds, *useconds);
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, sntp_recv_3, P_WARNING, 1,
|
||
|
"sntp_recv: Invalid mode in response: %u", mode);
|
||
|
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL SntpSendRequest(INT32 sockFd, ip_addr_t *serverAddr, UINT16 ServerPort)
|
||
|
{
|
||
|
struct sockaddr_storage to;
|
||
|
INT32 ret;
|
||
|
struct SntpMsg sntpReq;
|
||
|
UINT32 sntpTimeSec;
|
||
|
UINT32 sntpTimeUs;
|
||
|
|
||
|
//check paramter
|
||
|
if(sockFd < 0 || serverAddr == NULL)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpSendRequest_1, P_ERROR, 0, "SntpSendRequest parameter invalid");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (IP_IS_V4(serverAddr))
|
||
|
{
|
||
|
struct sockaddr_in *to4 = (struct sockaddr_in*)&to;
|
||
|
to4->sin_len = sizeof(struct sockaddr_in);
|
||
|
to4->sin_family = AF_INET;
|
||
|
to4->sin_port = htons(ServerPort);
|
||
|
inet_addr_from_ip4addr(&to4->sin_addr, ip_2_ip4(serverAddr));
|
||
|
}
|
||
|
else if(IP_IS_V6(serverAddr))
|
||
|
{
|
||
|
struct sockaddr_in6 *to6 = (struct sockaddr_in6*)&to;
|
||
|
to6->sin6_len = sizeof(struct sockaddr_in6);
|
||
|
to6->sin6_family = AF_INET6;
|
||
|
to6->sin6_port = htons(ServerPort);
|
||
|
inet6_addr_from_ip6addr(&to6->sin6_addr, ip_2_ip6(serverAddr));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpSendRequest_2, P_ERROR, 0, "SntpSendRequest parameter invalid");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//prepare sntp request message
|
||
|
|
||
|
memset(&sntpReq, 0, SNTP_MSG_LEN);
|
||
|
sntpReq.li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
|
||
|
|
||
|
/* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */
|
||
|
SNTP_GET_SYSTEM_TIME(sntpTimeSec, sntpTimeUs);
|
||
|
sntpLastTimeStampSent[0] = htonl(sntpTimeSec + DIFF_SEC_1900_1970);
|
||
|
sntpReq.transmit_timestamp[0] = sntpLastTimeStampSent[0];
|
||
|
/* we send/save us instead of fraction to be faster... */
|
||
|
sntpLastTimeStampSent[1] = htonl(sntpTimeUs);
|
||
|
sntpReq.transmit_timestamp[1] = sntpLastTimeStampSent[1];
|
||
|
|
||
|
//send sntp client reqeust
|
||
|
ret = sendto(sockFd, &sntpReq, SNTP_MSG_LEN, 0, (struct sockaddr*)&to, sizeof(to));
|
||
|
if(ret == SNTP_MSG_LEN)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpSendRequest_4, P_INFO, 0, "SntpSendRequest send sntp request success");
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpSendRequest_5, P_ERROR, 0, "SntpSendRequest send sntp request fail");
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
static void SntpTask(void *arg)
|
||
|
{
|
||
|
INT32 ret;
|
||
|
UINT32 result = SNTP_RESULT_FAIL;
|
||
|
slpManRet_t pmuRet = RET_UNKNOW_FALSE;
|
||
|
UINT8 sntpPmuHdr = 0;
|
||
|
ip_addr_t sntpServerAddr;
|
||
|
INT32 sockFd = -1;
|
||
|
UINT8 retryTimes = 0;
|
||
|
UINT32 secondsResponse;
|
||
|
UINT32 usecondsResponse;
|
||
|
struct SntpMsg sntpResponse;
|
||
|
NmAtiNetifInfo netInfo;
|
||
|
|
||
|
struct addrinfo hints, *target_address = PNULL;
|
||
|
|
||
|
SntpConfig *sntpParam = PNULL;
|
||
|
|
||
|
sntpParam = (SntpConfig*)arg;
|
||
|
|
||
|
|
||
|
//check sntp parameter
|
||
|
if (!sntpParam)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_1, P_ERROR, 0, "SntpTask start error, as sntp parameter invalid");
|
||
|
sntpIsOngoing = FALSE;
|
||
|
sntpThread = NULL;
|
||
|
sntpTerminalFlag = FALSE;
|
||
|
SntpCallResultCallback(SNTP_RESULT_PARAMTER_INVALID, 0, 0);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
//check pdp context status
|
||
|
if(NetMgrGetNetInfo(sntpParam->cid, &netInfo) != NM_SUCCESS)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_ATCMD_SOCK, sntp_netinfo_check_1, P_INFO, 1, "sntp get cid %d net info fail", sntpParam->cid);
|
||
|
sntpIsOngoing = FALSE;
|
||
|
sntpThread = NULL;
|
||
|
sntpTerminalFlag = FALSE;
|
||
|
SntpCallResultCallback(SNTP_RESULT_PDP_CONTEXT_STATUS_INVALID, 0, 0);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(netInfo.netStatus <= NM_NO_NETIF_OR_DEACTIVATED)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_ATCMD_SOCK, sntp_netinfo_check_2, P_INFO, 2, "sntp get cid %d net status %d is invalid ", sntpParam->cid, netInfo.netStatus);
|
||
|
sntpIsOngoing = FALSE;
|
||
|
sntpThread = NULL;
|
||
|
sntpTerminalFlag = FALSE;
|
||
|
SntpCallResultCallback(SNTP_RESULT_PDP_CONTEXT_STATUS_INVALID, 0, 0);
|
||
|
osThreadExit();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* start sntp, sntp task don't allow to enter HIB/Sleep2 state before ping terminated
|
||
|
*/
|
||
|
pmuRet = slpManApplyPlatVoteHandle("sntp", &sntpPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManPlatVoteDisableSleep(sntpPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
//get ping target address if target is url type
|
||
|
if(ipaddr_aton((const char*)sntpParam->serverAddr, &sntpServerAddr) == 0)
|
||
|
{
|
||
|
memset(&hints, 0, sizeof(hints));
|
||
|
hints.ai_family = AF_UNSPEC;
|
||
|
// hints.ai_socktype = SOCK_DGRAM;
|
||
|
// hints.ai_protocol = IPPROTO_UDP;
|
||
|
if (getaddrinfowithcid(sntpParam->serverAddr, NULL, &hints, &target_address, sntpParam->cid) != 0)
|
||
|
{
|
||
|
// OsaPrintf(P_ERROR, "Ping thread start error, can not get ip from url");
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_2, P_ERROR, 0, "SntpTask start error, can not get ip from url");
|
||
|
|
||
|
result = SNTP_RESULT_URL_RESOLVE_FAIL;
|
||
|
|
||
|
goto failAction;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (target_address->ai_family == AF_INET)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_3, P_SIG, 0, "SntpTaskresolve url success, it is ipv4 type");
|
||
|
struct sockaddr_in *to = (struct sockaddr_in *)target_address->ai_addr;
|
||
|
IP_SET_TYPE(&sntpServerAddr, IPADDR_TYPE_V4);
|
||
|
inet_addr_to_ip4addr(ip_2_ip4(&sntpServerAddr), &to->sin_addr);
|
||
|
}
|
||
|
else if (target_address->ai_family == AF_INET6)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_4, P_SIG, 0, "SntpTask resolve url success, it is ipv6 type");
|
||
|
struct sockaddr_in6 *to = (struct sockaddr_in6 *)target_address->ai_addr;
|
||
|
IP_SET_TYPE(&sntpServerAddr, IPADDR_TYPE_V6);
|
||
|
inet6_addr_to_ip6addr(ip_2_ip6(&sntpServerAddr),&to->sin6_addr);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_5, P_ERROR, 0, "SntpTask start error, get ip from url is invalid");
|
||
|
|
||
|
freeaddrinfo(target_address);
|
||
|
|
||
|
result = SNTP_RESULT_URL_RESOLVE_FAIL;
|
||
|
|
||
|
goto failAction;
|
||
|
|
||
|
}
|
||
|
freeaddrinfo(target_address);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||
|
int timeout = SNTP_RCV_TIMEOUT;
|
||
|
#else
|
||
|
struct timeval timeout;
|
||
|
timeout.tv_sec = SNTP_RCV_TIMEOUT;
|
||
|
timeout.tv_usec = 0;
|
||
|
#endif
|
||
|
|
||
|
if (IP_IS_V4(&sntpServerAddr))
|
||
|
{
|
||
|
sockFd = lwip_socket(AF_INET, SOCK_DGRAM, IP_PROTO_UDP);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sockFd = lwip_socket(AF_INET6, SOCK_DGRAM, IP_PROTO_UDP);
|
||
|
}
|
||
|
|
||
|
if (sockFd < 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_6, P_ERROR, 0, "SntpTask socket create error");
|
||
|
|
||
|
result = SNTP_RESULT_CREATE_CLIENT_SOCK_FAIL;
|
||
|
|
||
|
goto failAction;
|
||
|
}
|
||
|
|
||
|
if(sntpParam->cid != LWIP_PS_INVALID_CID)
|
||
|
{
|
||
|
if(lwip_bind_cid(sockFd, sntpParam->cid) != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_bind_cid_1, P_ERROR, 0, "SntpTask socket create with cid fail");
|
||
|
|
||
|
result = SNTP_RESULT_CREATE_CLIENT_SOCK_FAIL;
|
||
|
|
||
|
goto failAction;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ret = lwip_setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||
|
|
||
|
if (ret != 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_7, P_ERROR, 0, "SntpTask setting receive timeout failed");
|
||
|
|
||
|
result = SNTP_RESULT_CREATE_CLIENT_SOCK_FAIL;
|
||
|
|
||
|
goto failAction;
|
||
|
}
|
||
|
|
||
|
LWIP_UNUSED_ARG(ret);
|
||
|
|
||
|
while ((retryTimes < SNTP_RETRY_TIMES) && (sntpTerminalFlag == FALSE))
|
||
|
{
|
||
|
|
||
|
if (SntpSendRequest(sockFd, &sntpServerAddr, sntpParam->serverPort) == TRUE)
|
||
|
{
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_8, P_SIG, 0, "SntpTask: send request success");
|
||
|
|
||
|
memset(&sntpResponse, 0, sizeof(struct SntpMsg));
|
||
|
ret = recv(sockFd, &sntpResponse, SNTP_MSG_LEN, 0);
|
||
|
if(ret == SNTP_MSG_LEN)
|
||
|
{
|
||
|
|
||
|
if(SntpRecvResponse(&sntpResponse, &secondsResponse, &usecondsResponse) == TRUE)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_9, P_INFO, 0, "SntpTask: rcv response success");
|
||
|
result = SNTP_RESULT_OK;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_10, P_WARNING, 0, "SntpTask: rcv response, but process fail");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_11, P_WARNING, 0, "SntpTask: rcv response fail");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else // send request fail, try again
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_12, P_WARNING, 0, "SntpTask: send fail, need rty again");
|
||
|
sys_msleep(SNTP_RESEND_REQUEST_DELAY);
|
||
|
|
||
|
}
|
||
|
|
||
|
retryTimes ++;
|
||
|
|
||
|
}
|
||
|
|
||
|
if(retryTimes >= SNTP_RETRY_TIMES)
|
||
|
{
|
||
|
result = SNTP_RESULT_RETRY_REACH_MAX_TIMES;
|
||
|
}
|
||
|
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpTask_13, P_SIG, 0, "sntp task terminal");
|
||
|
|
||
|
|
||
|
failAction:
|
||
|
|
||
|
sntpIsOngoing = FALSE;
|
||
|
sntpThread = NULL;
|
||
|
sntpTerminalFlag = FALSE;
|
||
|
if(sockFd >= 0)
|
||
|
{
|
||
|
lwip_close(sockFd);
|
||
|
}
|
||
|
|
||
|
if(result != SNTP_RESULT_OK)
|
||
|
{
|
||
|
SntpCallResultCallback(result, 0, 0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SntpCallResultCallback(SNTP_RESULT_OK, secondsResponse, usecondsResponse);
|
||
|
}
|
||
|
|
||
|
/* before ping task exit, should allow to enter HIB/Sleep2, and release hander */
|
||
|
pmuRet = slpManPlatVoteEnableSleep(sntpPmuHdr, SLP_SLP2_STATE);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
pmuRet = slpManGivebackPlatVoteHandle(sntpPmuHdr);
|
||
|
OsaCheck(pmuRet == RET_TRUE, pmuRet, 0, 0);
|
||
|
|
||
|
osThreadExit();
|
||
|
}
|
||
|
|
||
|
void SntpTerminat(void)
|
||
|
{
|
||
|
if(sntpThread)
|
||
|
{
|
||
|
sntpTerminalFlag = TRUE;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL SntpInit(CHAR* serverAddr, UINT16 serverPort, UINT16 reqHandler, BOOL autoSync, UINT8 cid)
|
||
|
{
|
||
|
/* check the input */
|
||
|
if(!serverAddr || strlen(serverAddr) > DNS_MAX_NAME_LENGTH || strlen(serverAddr) == 0)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpInit_1, P_ERROR, 0,
|
||
|
"ERROR, SntpInit PARAMETER invalid");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (sntpIsOngoing)
|
||
|
{
|
||
|
ECOMM_TRACE(UNILOG_TCPIP_APP, SntpInit_2, P_ERROR, 0,
|
||
|
"ERROR, SntpInit has run");
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/* if set it in "sntp" task, maybe modify gSntpConfig for mutiple sntp request */
|
||
|
sntpIsOngoing = TRUE;
|
||
|
|
||
|
gSntpConfig.serverPort = serverPort?serverPort:SNTP_DEFAULT_PORT;
|
||
|
gSntpConfig.reqHandler = reqHandler;
|
||
|
gSntpConfig.cid = cid;
|
||
|
gSntpConfig.autoSync = (UINT16)autoSync;
|
||
|
|
||
|
//ping target setting
|
||
|
strcpy((char *)gSntpConfig.serverAddr, serverAddr);
|
||
|
|
||
|
sntpThread = sys_thread_new("sntp_task", SntpTask, (void*)&gSntpConfig, SNTP_THREAD_STACKSIZE, SNTP_THREAD_PRIO);
|
||
|
|
||
|
if (sntpThread == NULL)
|
||
|
{
|
||
|
sntpIsOngoing = FALSE;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//check sntp whether running,TRUE->running, FALSE->not run
|
||
|
BOOL SntpChkStatus(CHAR *serverAddr, UINT16 *serverPort, UINT8 *cid)
|
||
|
{
|
||
|
if (sntpIsOngoing)
|
||
|
{
|
||
|
strcpy(serverAddr, gSntpConfig.serverAddr);
|
||
|
*serverPort = gSntpConfig.serverPort;
|
||
|
*cid = gSntpConfig.cid;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|