Pico Led Controller 1.0.3
A project to control LEDs using Raspberry Pi Pico W
Loading...
Searching...
No Matches
ntp.c File Reference
#include "ntp.h"
#include <string.h>
#include <time.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/dns.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"

Go to the source code of this file.

Functions

static void ntp_result (NTP_T *state, int status, time_t *result)
 
static void ntp_request (NTP_T *state)
 
static int64_t ntp_failed_handler (alarm_id_t id, void *user_data)
 
static void ntp_dns_found (const char *hostname, const ip_addr_t *ipaddr, void *arg)
 
static void ntp_recv (void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
 
static NTP_Tntp_init (void)
 
void ntp_deinit (void)
 NTP deinit.
 
void ntp_update_time (void)
 NTP update time.
 

Variables

volatile struct tm * utc = NULL
 UTC time struct.
 
volatile struct tm * current_utc = NULL
 UTC time struct.
 

Function Documentation

◆ ntp_deinit()

void ntp_deinit ( void  )

NTP deinit.

Function de-initializes the NTP.

Definition at line 114 of file ntp.c.

115{
116 if (utc)
117 {
118 free((void*)utc);
119 utc = NULL;
120 }
121}
volatile struct tm * utc
UTC time struct.
Definition ntp.c:13

References utc.

Referenced by main().

◆ ntp_dns_found()

static void ntp_dns_found ( const char *  hostname,
const ip_addr_t *  ipaddr,
void *  arg 
)
static

Definition at line 56 of file ntp.c.

57{
58 NTP_T *state = (NTP_T*)arg;
59 if (ipaddr)
60 {
61 state->ntp_server_address = *ipaddr;
62 printf("NTP address %s\n", ipaddr_ntoa(ipaddr));
63 ntp_request(state);
64 }
65 else
66 {
67 printf("NTP DNS request failed\n");
68 ntp_result(state, -1, NULL);
69 }
70}
static void ntp_result(NTP_T *state, int status, time_t *result)
Definition ntp.c:16
static void ntp_request(NTP_T *state)
Definition ntp.c:36
NTP struct.
Definition ntp.h:35
ip_addr_t ntp_server_address
Definition ntp.h:36

References ntp_request(), ntp_result(), and NTP_T_::ntp_server_address.

Referenced by ntp_update_time().

◆ ntp_failed_handler()

static int64_t ntp_failed_handler ( alarm_id_t  id,
void *  user_data 
)
static

Definition at line 48 of file ntp.c.

49{
50 NTP_T* state = (NTP_T*)user_data;
51 printf("NTP request failed\n");
52 ntp_result(state, -1, NULL);
53 return 0;
54}

References ntp_result().

Referenced by ntp_update_time().

◆ ntp_init()

static NTP_T * ntp_init ( void  )
static

Definition at line 95 of file ntp.c.

96{
97 NTP_T *state = (NTP_T*)calloc(1, sizeof(NTP_T));
98 if (!state)
99 {
100 printf("Failed to allocate state\n");
101 return NULL;
102 }
103 state->ntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
104 if (!state->ntp_pcb)
105 {
106 printf("Failed to create PCB\n");
107 free(state);
108 return NULL;
109 }
110 udp_recv(state->ntp_pcb, ntp_recv, state);
111 return state;
112}
static void ntp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
Definition ntp.c:72
struct udp_pcb * ntp_pcb
Definition ntp.h:38

References NTP_T_::ntp_pcb, and ntp_recv().

Referenced by ntp_update_time().

◆ ntp_recv()

static void ntp_recv ( void *  arg,
struct udp_pcb *  pcb,
struct pbuf *  p,
const ip_addr_t *  addr,
u16_t  port 
)
static

Definition at line 72 of file ntp.c.

73{
74 NTP_T *state = (NTP_T*)arg;
75 uint8_t mode = pbuf_get_at(p, 0) & 0x7;
76 uint8_t stratum = pbuf_get_at(p, 1);
77
78 if (ip_addr_cmp(addr, &state->ntp_server_address) && port == NTP_PORT && p->tot_len == NTP_MSG_LEN &&mode == 0x4 && stratum != 0)
79 {
80 uint8_t seconds_buf[4] = {0};
81 pbuf_copy_partial(p, seconds_buf, sizeof(seconds_buf), 40);
82 uint32_t seconds_since_1900 = seconds_buf[0] << 24 | seconds_buf[1] << 16 | seconds_buf[2] << 8 | seconds_buf[3];
83 uint32_t seconds_since_1970 = seconds_since_1900 - NTP_DELTA;
84 time_t epoch = seconds_since_1970;
85 ntp_result(state, 0, &epoch);
86 }
87 else
88 {
89 printf("Invalid NTP response\n");
90 ntp_result(state, -1, NULL);
91 }
92 pbuf_free(p);
93}
#define NTP_PORT
Definition ntp.h:16
#define NTP_DELTA
Definition ntp.h:17
#define NTP_MSG_LEN
Definition ntp.h:15

References NTP_DELTA, NTP_MSG_LEN, NTP_PORT, ntp_result(), and NTP_T_::ntp_server_address.

Referenced by ntp_init().

◆ ntp_request()

static void ntp_request ( NTP_T state)
static

Definition at line 36 of file ntp.c.

37{
38 cyw43_arch_lwip_begin();
39 struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, NTP_MSG_LEN, PBUF_RAM);
40 uint8_t *req = (uint8_t *) p->payload;
41 memset(req, 0, NTP_MSG_LEN);
42 req[0] = 0x1b;
43 udp_sendto(state->ntp_pcb, p, &state->ntp_server_address, NTP_PORT);
44 pbuf_free(p);
45 cyw43_arch_lwip_end();
46}

References NTP_MSG_LEN, NTP_T_::ntp_pcb, NTP_PORT, and NTP_T_::ntp_server_address.

Referenced by ntp_dns_found(), and ntp_update_time().

◆ ntp_result()

static void ntp_result ( NTP_T state,
int  status,
time_t *  result 
)
static

Definition at line 16 of file ntp.c.

17{
18 if (status == 0 && result)
19 {
20 // *result += TIMEZONE_OFFSET;
21 if (!utc)
22 utc = gmtime(result);
23 current_utc = gmtime(result);
24 printf("Got NTP response: %02d/%02d/%04d %02d:%02d:%02d\n", current_utc->tm_mday, current_utc->tm_mon + 1, current_utc->tm_year + 1900, current_utc->tm_hour, current_utc->tm_min, current_utc->tm_sec);
25 }
26
27 if (state->ntp_resend_alarm > 0)
28 {
29 cancel_alarm(state->ntp_resend_alarm);
30 state->ntp_resend_alarm = 0;
31 }
32 state->ntp_test_time = make_timeout_time_ms(NTP_TEST_TIME);
33 state->dns_request_sent = false;
34}
volatile struct tm * current_utc
UTC time struct.
Definition ntp.c:14
#define NTP_TEST_TIME
Definition ntp.h:18
absolute_time_t ntp_test_time
Definition ntp.h:39
bool dns_request_sent
Definition ntp.h:37
alarm_id_t ntp_resend_alarm
Definition ntp.h:40

References current_utc, NTP_T_::dns_request_sent, NTP_T_::ntp_resend_alarm, NTP_TEST_TIME, NTP_T_::ntp_test_time, and utc.

Referenced by ntp_dns_found(), ntp_failed_handler(), ntp_recv(), and ntp_update_time().

◆ ntp_update_time()

void ntp_update_time ( void  )

NTP update time.

Function updates the NTP time.

Definition at line 123 of file ntp.c.

124{
125 NTP_T *state = ntp_init();
126 if (!state)
127 return;
128 if (absolute_time_diff_us(get_absolute_time(), state->ntp_test_time) < 0 && !state->dns_request_sent)
129 {
130 state->ntp_resend_alarm = add_alarm_in_ms(NTP_RESEND_TIME, ntp_failed_handler, state, true);
131 cyw43_arch_lwip_begin();
132 int err = dns_gethostbyname(NTP_SERVER, &state->ntp_server_address, ntp_dns_found, state);
133 cyw43_arch_lwip_end();
134
135 state->dns_request_sent = true;
136 if (err == ERR_OK)
137 ntp_request(state);
138 else if (err != ERR_INPROGRESS)
139 {
140 printf("DNS request failed\n");
141 ntp_result(state, -1, NULL);
142 }
143 }
144 free(state);
145}
static int64_t ntp_failed_handler(alarm_id_t id, void *user_data)
Definition ntp.c:48
static void ntp_dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg)
Definition ntp.c:56
static NTP_T * ntp_init(void)
Definition ntp.c:95
#define NTP_SERVER
Definition ntp.h:14
#define NTP_RESEND_TIME
Definition ntp.h:19

References NTP_T_::dns_request_sent, ntp_dns_found(), ntp_failed_handler(), ntp_init(), ntp_request(), NTP_T_::ntp_resend_alarm, NTP_RESEND_TIME, ntp_result(), NTP_SERVER, NTP_T_::ntp_server_address, and NTP_T_::ntp_test_time.

Referenced by init().

Variable Documentation

◆ current_utc

volatile struct tm* current_utc = NULL

UTC time struct.

Struct for the last checked UTC time.

Definition at line 14 of file ntp.c.

Referenced by ntp_result().

◆ utc

volatile struct tm* utc = NULL

UTC time struct.

Struct for the UTC time of program start.

Definition at line 13 of file ntp.c.

Referenced by ntp_deinit(), ntp_result(), and ssi_handler().