SNTP module enhancements (#1243)

* Provide an error code to SNTP error callback.

* Switch SNTP to use ephemeral port.

In case we're being hit by ISP-level thou-shall-not-run-NTP silliness.
This commit is contained in:
Johny Mattsson 2016-04-15 20:49:18 +10:00 committed by Marcel Stör
parent a33f586855
commit f428897810
2 changed files with 23 additions and 10 deletions

View File

@ -58,6 +58,14 @@
# define sntp_dbg(...)
#endif
typedef enum {
NTP_NO_ERR = 0,
NTP_DNS_ERR,
NTP_MEM_ERR,
NTP_SEND_ERR,
NTP_TIMEOUT_ERR
} ntp_err_t;
typedef struct
{
uint32_t sec;
@ -107,14 +115,15 @@ static void cleanup (lua_State *L)
}
static void handle_error (lua_State *L)
static void handle_error (lua_State *L, ntp_err_t err)
{
sntp_dbg("sntp: handle_error\n");
if (state->err_cb_ref != LUA_NOREF)
{
lua_rawgeti (L, LUA_REGISTRYINDEX, state->err_cb_ref);
lua_pushinteger (L, err);
cleanup (L);
lua_call (L, 0, 0);
lua_call (L, 1, 0);
}
else
cleanup (L);
@ -135,7 +144,7 @@ static void sntp_dosend (lua_State *L)
struct pbuf *p = pbuf_alloc (PBUF_TRANSPORT, sizeof (ntp_frame_t), PBUF_RAM);
if (!p)
handle_error (L);
handle_error (L, NTP_MEM_ERR);
ntp_frame_t req;
os_memset (&req, 0, sizeof (req));
@ -156,7 +165,7 @@ static void sntp_dosend (lua_State *L)
sntp_dbg("sntp: send: %d\n", ret);
pbuf_free (p);
if (ret != ERR_OK)
handle_error (L);
handle_error (L, NTP_SEND_ERR);
}
@ -167,8 +176,8 @@ static void sntp_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
lua_State *L = lua_getstate ();
if (ipaddr == NULL)
{
NODE_ERR("DNS Fail!\n");
handle_error(L);
sntp_dbg("DNS Fail!\n");
handle_error(L, NTP_DNS_ERR);
}
else
{
@ -184,7 +193,7 @@ static void on_timeout (void *arg)
sntp_dbg("sntp: timer\n");
lua_State *L = lua_getstate ();
if (state->attempts >= MAX_ATTEMPTS)
handle_error (L);
handle_error (L, NTP_TIMEOUT_ERR);
else
sntp_dosend (L);
}
@ -332,8 +341,8 @@ static int sntp_sync (lua_State *L)
if (!state->pcb)
sync_err ("out of memory");
if (udp_bind (state->pcb, IP_ADDR_ANY, NTP_PORT) != ERR_OK)
sync_err ("ntp port in use");
if (udp_bind (state->pcb, IP_ADDR_ANY, 0) != ERR_OK)
sync_err ("no port available");
udp_recv (state->pcb, on_recv, L);

View File

@ -18,7 +18,11 @@ Attempts to obtain time synchronization.
#### Parameters
- `server_ip` if non-`nil`, that server is used. If `nil`, then the last contacted server is used. This ties in with the NTP anycast mode, where the first responding server is remembered for future synchronization requests. The easiest way to use anycast is to always pass nil for the server argument.
- `callback` Iif provided it will be invoked on a successful synchronization, with three parameters: seconds, microseconds, and server. Note that when the [rtctime](rtctime.md) module is available, there is no need to explicitly call [`rtctime.set()`](rtctime.md#rtctimeset) - this module takes care of doing so internally automatically, for best accuracy.
- `errcallback` failure callback with no parameters. The module automatically performs a number of retries before giving up and reporting the error.
- `errcallback` failure callback with a single integer parameter describing the type of error. The module automatically performs a number of retries before giving up and reporting the error. Error codes:
- 1: DNS lookup failed
- 2: Memory allocation failure
- 3: UDP send failed
- 4: Timeout, no NTP response received
#### Returns
`nil`