NTP client, minor clean-up and enhancements
This commit is contained in:
parent
693d73cc0d
commit
b2080e94f7
@ -67,6 +67,10 @@
|
|||||||
# define CONFIG_NETUTILS_NTPCLIENT_POLLDELAYSEC 60
|
# define CONFIG_NETUTILS_NTPCLIENT_POLLDELAYSEC 60
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_NETUTILS_NTPCLIENT_SIGWAKEUP
|
||||||
|
# define CONFIG_NETUTILS_NTPCLIENT_SIGWAKEUP 18
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -77,7 +81,8 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define EXTERN extern "C"
|
#define EXTERN extern "C"
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#else
|
#else
|
||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
@ -86,24 +91,34 @@ extern "C" {
|
|||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ntpclient_start
|
* Name: ntpc_start
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Start the NTP daemon
|
* Start the NTP daemon
|
||||||
*
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* On success, the non-negative task ID of the NTPC daemon is returned;
|
||||||
|
* On failure, a negated errno value is returned.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int ntpclient_start(void);
|
int ntpc_start(void);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ntpclient_stop
|
* Name: ntpc_stop
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Stop the NTP daemon
|
* Stop the NTP daemon
|
||||||
*
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure. The current
|
||||||
|
* implementation only returns success.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int ntpclient_stop(void);
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
|
int ntpc_stop(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -32,4 +32,9 @@ config NETUTILS_NTPCLIENT_POLLDELAYSEC
|
|||||||
int "NTP client poll interval (seconds)"
|
int "NTP client poll interval (seconds)"
|
||||||
default 60
|
default 60
|
||||||
|
|
||||||
|
config NETUTILS_NTPCLIENT_SIGWAKEUP
|
||||||
|
int "NTP client wakeup signal number"
|
||||||
|
default 18
|
||||||
|
depends on !DISABLE_SIGNALS
|
||||||
|
|
||||||
endif # NETUTILS_NTPCLIENT
|
endif # NETUTILS_NTPCLIENT
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
/* This enumeration describes the state of the NTP daemon */
|
/* This enumeration describes the state of the NTP daemon */
|
||||||
|
|
||||||
enum ntpclient_daemon_e
|
enum ntpc_daemon_e
|
||||||
{
|
{
|
||||||
NTP_NOT_RUNNING = 0,
|
NTP_NOT_RUNNING = 0,
|
||||||
NTP_STARTED,
|
NTP_STARTED,
|
||||||
@ -81,9 +81,9 @@ enum ntpclient_daemon_e
|
|||||||
* instance of the NTP daemon is permitted in this implementation.
|
* instance of the NTP daemon is permitted in this implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ntpclient_daemon_s
|
struct ntpc_daemon_s
|
||||||
{
|
{
|
||||||
volatile uint8_t state; /* See enum ntpclient_daemon_e */
|
volatile uint8_t state; /* See enum ntpc_daemon_e */
|
||||||
sem_t interlock; /* Used to synchronize start and stop events */
|
sem_t interlock; /* Used to synchronize start and stop events */
|
||||||
pid_t pid; /* Task ID of the NTP daemon */
|
pid_t pid; /* Task ID of the NTP daemon */
|
||||||
};
|
};
|
||||||
@ -97,20 +97,20 @@ struct ntpclient_daemon_s
|
|||||||
* limitation is due only to this global data structure.
|
* limitation is due only to this global data structure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct ntpclient_daemon_s g_ntpclient_daemon;
|
static struct ntpc_daemon_s g_ntpc_daemon;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ntpclient_getuint32
|
* Name: ntpc_getuint32
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Return the big-endian, 4-byte value in network (big-endian) order.
|
* Return the big-endian, 4-byte value in network (big-endian) order.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline uint32_t ntpclient_getuint32(FAR uint8_t *ptr)
|
static inline uint32_t ntpc_getuint32(FAR uint8_t *ptr)
|
||||||
{
|
{
|
||||||
/* Network order is big-endian; host order is irrelevant */
|
/* Network order is big-endian; host order is irrelevant */
|
||||||
|
|
||||||
@ -121,14 +121,14 @@ static inline uint32_t ntpclient_getuint32(FAR uint8_t *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ntpclient_settime
|
* Name: ntpc_settime
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Given the NTP time in seconds, set the system time
|
* Given the NTP time in seconds, set the system time
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void ntpclient_settime(FAR uint8_t *timestamp)
|
static void ntpc_settime(FAR uint8_t *timestamp)
|
||||||
{
|
{
|
||||||
struct timespec tp;
|
struct timespec tp;
|
||||||
time_t seconds;
|
time_t seconds;
|
||||||
@ -158,7 +158,7 @@ static void ntpclient_settime(FAR uint8_t *timestamp)
|
|||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
seconds = ntpclient_getuint32(timestamp);
|
seconds = ntpc_getuint32(timestamp);
|
||||||
|
|
||||||
/* Translate seconds to account for the difference in the origin time */
|
/* Translate seconds to account for the difference in the origin time */
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ static void ntpclient_settime(FAR uint8_t *timestamp)
|
|||||||
* = (f * 1,953,125) / 8,388,608
|
* = (f * 1,953,125) / 8,388,608
|
||||||
*/
|
*/
|
||||||
|
|
||||||
frac = ntpclient_getuint32(timestamp + 4);
|
frac = ntpc_getuint32(timestamp + 4);
|
||||||
#ifdef CONFIG_HAVE_LONG_LONG
|
#ifdef CONFIG_HAVE_LONG_LONG
|
||||||
/* if we have 64-bit long long values, then the computation is easy */
|
/* if we have 64-bit long long values, then the computation is easy */
|
||||||
|
|
||||||
@ -207,14 +207,14 @@ static void ntpclient_settime(FAR uint8_t *timestamp)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
t32 = 0x001d * a16;
|
t32 = 0x001d * a16;
|
||||||
t0 = 0xcd65 * b0
|
t0 = 0xcd65 * b0;
|
||||||
|
|
||||||
/* Get the first b16 term
|
/* Get the first b16 term
|
||||||
*
|
*
|
||||||
* (a << 16) * 0xcd65
|
* (a << 16) * 0xcd65
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t16 = 0xcd65 * a16
|
t16 = 0xcd65 * a16;
|
||||||
|
|
||||||
/* Add the upper 16-bits to the b32 accumulator */
|
/* Add the upper 16-bits to the b32 accumulator */
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ static void ntpclient_settime(FAR uint8_t *timestamp)
|
|||||||
* b * 0x1d << 16)
|
* b * 0x1d << 16)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t16 = 0x001d * b
|
t16 = 0x001d * b0;
|
||||||
|
|
||||||
/* Add the upper 16-bits to the b32 accumulator */
|
/* Add the upper 16-bits to the b32 accumulator */
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ static void ntpclient_settime(FAR uint8_t *timestamp)
|
|||||||
* accomplish the divide by by 2**23.
|
* accomplish the divide by by 2**23.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nsec = (t32 << (32 - 23)) + (t0 >> 23)
|
nsec = (t32 << (32 - 23)) + (t0 >> 23);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set the system time */
|
/* Set the system time */
|
||||||
@ -272,11 +272,11 @@ static void ntpclient_settime(FAR uint8_t *timestamp)
|
|||||||
tp.tv_nsec = nsec;
|
tp.tv_nsec = nsec;
|
||||||
clock_settime(CLOCK_REALTIME, &tp);
|
clock_settime(CLOCK_REALTIME, &tp);
|
||||||
|
|
||||||
svdbg("Set time to %ld seconds: %d\n", tp.tv_sec, ret);
|
svdbg("Set time to %lu seconds: %d\n", (unsigned long)tp.tv_sec, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ntpclient_daemon
|
* Name: ntpc_daemon
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This the the NTP client daemon. This is a *very* minimal
|
* This the the NTP client daemon. This is a *very* minimal
|
||||||
@ -285,7 +285,7 @@ static void ntpclient_settime(FAR uint8_t *timestamp)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int ntpclient_daemon(int argc, char **argv)
|
static int ntpc_daemon(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct sockaddr_in server;
|
struct sockaddr_in server;
|
||||||
struct ntp_datagram_s xmit;
|
struct ntp_datagram_s xmit;
|
||||||
@ -299,8 +299,8 @@ static int ntpclient_daemon(int argc, char **argv)
|
|||||||
|
|
||||||
/* Indicate that we have started */
|
/* Indicate that we have started */
|
||||||
|
|
||||||
g_ntpclient_daemon.state = NTP_RUNNING;
|
g_ntpc_daemon.state = NTP_RUNNING;
|
||||||
sem_post(&g_ntpclient_daemon.interlock);
|
sem_post(&g_ntpc_daemon.interlock);
|
||||||
|
|
||||||
/* Create a datagram socket */
|
/* Create a datagram socket */
|
||||||
|
|
||||||
@ -309,8 +309,8 @@ static int ntpclient_daemon(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
ndbg("ERROR: socket failed: %d\n", errno);
|
ndbg("ERROR: socket failed: %d\n", errno);
|
||||||
|
|
||||||
g_ntpclient_daemon.state = NTP_STOPPED;
|
g_ntpc_daemon.state = NTP_STOPPED;
|
||||||
sem_post(&g_ntpclient_daemon.interlock);
|
sem_post(&g_ntpc_daemon.interlock);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,8 +324,8 @@ static int ntpclient_daemon(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
ndbg("ERROR: setsockopt failed: %d\n", errno);
|
ndbg("ERROR: setsockopt failed: %d\n", errno);
|
||||||
|
|
||||||
g_ntpclient_daemon.state = NTP_STOPPED;
|
g_ntpc_daemon.state = NTP_STOPPED;
|
||||||
sem_post(&g_ntpclient_daemon.interlock);
|
sem_post(&g_ntpc_daemon.interlock);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ static int ntpclient_daemon(int argc, char **argv)
|
|||||||
* access.
|
* access.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (g_ntpclient_daemon.state == NTP_STOP_REQUESTED)
|
while (g_ntpc_daemon.state == NTP_STOP_REQUESTED)
|
||||||
{
|
{
|
||||||
memset(&xmit, 0, sizeof(xmit));
|
memset(&xmit, 0, sizeof(xmit));
|
||||||
xmit.lvm = MKLVM(0, 3, NTP_VERSION);
|
xmit.lvm = MKLVM(0, 3, NTP_VERSION);
|
||||||
@ -356,8 +356,11 @@ static int ntpclient_daemon(int argc, char **argv)
|
|||||||
sizeof(struct sockaddr_in));
|
sizeof(struct sockaddr_in));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
ndbg("ERROR: sendto() failed: %d\n", errno);
|
if (g_ntpc_daemon.state != NTP_STOP_REQUESTED)
|
||||||
exitcode = EXIT_FAILURE;
|
{
|
||||||
|
ndbg("ERROR: sendto() failed: %d\n", errno);
|
||||||
|
exitcode = EXIT_FAILURE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,21 +372,26 @@ static int ntpclient_daemon(int argc, char **argv)
|
|||||||
if (nbytes >= NTP_DATAGRAM_MINSIZE)
|
if (nbytes >= NTP_DATAGRAM_MINSIZE)
|
||||||
{
|
{
|
||||||
svdbg("Setting time\n");
|
svdbg("Setting time\n");
|
||||||
ntpclient_settime(recv.recvtimestamp);
|
ntpc_settime(recv.recvtimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A full implementation of an NTP client would requireq much more. I
|
/* A full implementation of an NTP client would require much more. I
|
||||||
* think we we can skip that here.
|
* think we can skip most of that here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
svdbg("Waiting for %d seconds\n", CONFIG_NETUTILS_NTPCLIENT_POLLDELAYSEC);
|
if (g_ntpc_daemon.state == NTP_RUNNING)
|
||||||
(void)sleep(CONFIG_NETUTILS_NTPCLIENT_POLLDELAYSEC);
|
{
|
||||||
|
svdbg("Waiting for %d seconds\n",
|
||||||
|
CONFIG_NETUTILS_NTPCLIENT_POLLDELAYSEC);
|
||||||
|
|
||||||
|
(void)sleep(CONFIG_NETUTILS_NTPCLIENT_POLLDELAYSEC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The NTP client is terminating */
|
/* The NTP client is terminating */
|
||||||
|
|
||||||
g_ntpclient_daemon.state = NTP_STOPPED;
|
g_ntpc_daemon.state = NTP_STOPPED;
|
||||||
sem_post(&g_ntpclient_daemon.interlock);
|
sem_post(&g_ntpc_daemon.interlock);
|
||||||
return exitcode;
|
return exitcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,46 +399,50 @@ static int ntpclient_daemon(int argc, char **argv)
|
|||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ntpclient_start
|
* Name: ntpc_start
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Start the NTP daemon
|
* Start the NTP daemon
|
||||||
*
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* On success, the non-negative task ID of the NTPC daemon is returned;
|
||||||
|
* On failure, a negated errno value is returned.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int ntpclient_start(void)
|
int ntpc_start(void)
|
||||||
{
|
{
|
||||||
/* Is the NTP in a non-running state? */
|
/* Is the NTP in a non-running state? */
|
||||||
|
|
||||||
sched_lock();
|
sched_lock();
|
||||||
if (g_ntpclient_daemon.state == NTP_NOT_RUNNING ||
|
if (g_ntpc_daemon.state == NTP_NOT_RUNNING ||
|
||||||
g_ntpclient_daemon.state == NTP_STOPPED)
|
g_ntpc_daemon.state == NTP_STOPPED)
|
||||||
{
|
{
|
||||||
/* Is this the first time that the NTP daemon has been started? */
|
/* Is this the first time that the NTP daemon has been started? */
|
||||||
|
|
||||||
if (g_ntpclient_daemon.state == NTP_NOT_RUNNING)
|
if (g_ntpc_daemon.state == NTP_NOT_RUNNING)
|
||||||
{
|
{
|
||||||
/* Yes... then we will need to initialize the state structure */
|
/* Yes... then we will need to initialize the state structure */
|
||||||
|
|
||||||
sem_init(&g_ntpclient_daemon.interlock, 0, 0);
|
sem_init(&g_ntpc_daemon.interlock, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the NTP daemon */
|
/* Start the NTP daemon */
|
||||||
|
|
||||||
g_ntpclient_daemon.state = NTP_STARTED;
|
g_ntpc_daemon.state = NTP_STARTED;
|
||||||
g_ntpclient_daemon.pid =
|
g_ntpc_daemon.pid =
|
||||||
TASK_CREATE("NTP daemon", CONFIG_NETUTILS_NTPCLIENT_SERVERPRIO,
|
TASK_CREATE("NTP daemon", CONFIG_NETUTILS_NTPCLIENT_SERVERPRIO,
|
||||||
CONFIG_NETUTILS_NTPCLIENT_STACKSIZE, ntpclient_daemon,
|
CONFIG_NETUTILS_NTPCLIENT_STACKSIZE, ntpc_daemon,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* Handle failures to start the NTP daemon */
|
/* Handle failures to start the NTP daemon */
|
||||||
|
|
||||||
if (g_ntpclient_daemon.pid < 0)
|
if (g_ntpc_daemon.pid < 0)
|
||||||
{
|
{
|
||||||
int errval = errno;
|
int errval = errno;
|
||||||
DEBUGASSERT(errval > 0);
|
DEBUGASSERT(errval > 0);
|
||||||
|
|
||||||
g_ntpclient_daemon.state = NTP_STOPPED;
|
g_ntpc_daemon.state = NTP_STOPPED;
|
||||||
ndbg("ERROR: Failed to start the NTP daemon\n", errval);
|
ndbg("ERROR: Failed to start the NTP daemon\n", errval);
|
||||||
return -errval;
|
return -errval;
|
||||||
}
|
}
|
||||||
@ -439,44 +451,66 @@ int ntpclient_start(void)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
(void)sem_wait(&g_ntpclient_daemon.interlock);
|
(void)sem_wait(&g_ntpc_daemon.interlock);
|
||||||
}
|
}
|
||||||
while (g_ntpclient_daemon.state == NTP_STARTED);
|
while (g_ntpc_daemon.state == NTP_STARTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return OK;
|
return g_ntpc_daemon.pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ntpclient_stop
|
* Name: ntpc_stop
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Stop the NTP daemon
|
* Stop the NTP daemon
|
||||||
*
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success; a negated errno value on failure. The current
|
||||||
|
* implementation only returns success.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int ntpclient_stop(void)
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
|
int ntpc_stop(void)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Is the NTP in a running state? */
|
/* Is the NTP in a running state? */
|
||||||
|
|
||||||
sched_lock();
|
sched_lock();
|
||||||
if (g_ntpclient_daemon.state == NTP_STARTED ||
|
if (g_ntpc_daemon.state == NTP_STARTED ||
|
||||||
g_ntpclient_daemon.state == NTP_RUNNING)
|
g_ntpc_daemon.state == NTP_RUNNING)
|
||||||
{
|
{
|
||||||
/* Yes.. request that the daemon stop. */
|
/* Yes.. request that the daemon stop. */
|
||||||
|
|
||||||
g_ntpclient_daemon.state = NTP_STOP_REQUESTED;
|
g_ntpc_daemon.state = NTP_STOP_REQUESTED;
|
||||||
|
|
||||||
/* Wait for any daemon state change */
|
/* Wait for any daemon state change */
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
(void)sem_wait(&g_ntpclient_daemon.interlock);
|
/* Signal the NTP client */
|
||||||
|
|
||||||
|
ret = kill(g_ntpc_daemon.pid,
|
||||||
|
CONFIG_NETUTILS_NTPCLIENT_SIGWAKEUP);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ndbg("ERROR: kill pid %d failed: %d\n",
|
||||||
|
g_ntpc_daemon.pid, errno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the NTP client to respond to the stop request */
|
||||||
|
|
||||||
|
(void)sem_wait(&g_ntpc_daemon.interlock);
|
||||||
}
|
}
|
||||||
while (g_ntpclient_daemon.state == NTP_STOP_REQUESTED);
|
while (g_ntpc_daemon.state == NTP_STOP_REQUESTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user