doc: renamed project

This commit is contained in:
SylvanArnold
2025-04-29 13:52:54 +02:00
committed by Sylvan Arnold
parent 244e516bd8
commit 32618389d1
985 changed files with 1 additions and 1 deletions

View File

@@ -0,0 +1,242 @@
/*
* Copyright (c) 2023, Erich Styger
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "platform.h"
#if PL_CONFIG_USE_NTP_CLIENT
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
#include "lwip/dns.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "McuLog.h"
#include "McuRTOS.h"
#include "McuTimeDate.h"
#include "dns_resolver.h"
#include "ntp_client.h"
#if PL_CONFIG_USE_MINI
#include "minIni/McuMinINI.h"
#include "MinIniKeys.h"
#endif
static TaskHandle_t taskHandle; /* task handle of ntp task */
typedef struct ntp_desc_t {
DnsResolver_info_t addr; /* DNS resolved address information of DNS server */
struct udp_pcb *ntp_pcb; /* UDP protocol block */
alarm_id_t ntp_timeout_alarm; /* timeout alarm id, zero if no timeout is running */
} ntp_desc_t;
#define NTP_SERVER "pool.ntp.org" /* ntp server name */
#define NTP_MSG_LEN 48
#define NTP_PORT 123 /* ntp udp port number */
#define NTP_DELTA 2208988800 /* seconds between 1 Jan 1900 and 1 Jan 1970 */
#define NTP_PERIOD_TIME_MS (30*60*1000) /* period in ms between ntp requests */
#define NTP_TIMEOUT_TIME_MS (10*1000) /* timeout time in ms if there is no ntp response */
static unsigned int AddDaylightSavingHourOffset(uint8_t day, uint8_t month) {
return 2; /* \todo */
}
/* Called with results of operation */
static void ntp_result(ntp_desc_t *state, int status, time_t *result) {
if (status == 0 && result!=NULL) {
struct tm *utc = gmtime(result);
McuLog_info("got ntp response: %02d/%02d/%04d %02d:%02d:%02d",
utc->tm_mday, utc->tm_mon + 1, utc->tm_year + 1900,
utc->tm_hour, utc->tm_min, utc->tm_sec);
McuTimeDate_SetDate(utc->tm_year+1900, utc->tm_mon+1, utc->tm_mday);
McuTimeDate_SetTime(utc->tm_hour+AddDaylightSavingHourOffset(utc->tm_mday, utc->tm_mday), utc->tm_min, utc->tm_sec, 0);
}
if (state->ntp_timeout_alarm > 0) { /* cancel timeout pending alarm, as we have received a response */
cancel_alarm(state->ntp_timeout_alarm);
state->ntp_timeout_alarm = 0;
}
}
/* send an UDP NTP request message */
static void ntp_request(ntp_desc_t *state) {
// cyw43_arch_lwip_begin/end should be used around calls into lwIP to ensure correct locking.
// You can omit them if you are in a callback from lwIP. Note that when using pico_cyw_arch_poll
// these calls are a no-op and can be omitted, but it is a good practice to use them in
// case you switch the cyw43_arch type later.
cyw43_arch_lwip_begin();
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, NTP_MSG_LEN, PBUF_RAM);
uint8_t *req = (uint8_t *)p->payload;
memset(req, 0, NTP_MSG_LEN);
req[0] = 0x1b;
udp_sendto(state->ntp_pcb, p, &state->addr.resolved_addr, NTP_PORT);
pbuf_free(p);
cyw43_arch_lwip_end();
}
/* alarm callback handler */
static int64_t ntp_timeout_handler(alarm_id_t id, void *user_data) {
ntp_desc_t *state = (ntp_desc_t*)user_data;
McuLog_error("ntp request timeout");
ntp_result(state, -1, NULL); /* abort */
return 0;
}
/* lwIP callback for NTP data received */
static void ntp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) {
ntp_desc_t *state = (ntp_desc_t*)arg;
uint8_t mode = pbuf_get_at(p, 0) & 0x7;
uint8_t stratum = pbuf_get_at(p, 1);
/* Check the result */
if (ip_addr_cmp(addr, &state->addr.resolved_addr) && port == NTP_PORT && p->tot_len == NTP_MSG_LEN && mode == 0x4 && stratum != 0) {
uint8_t seconds_buf[4] = {0};
pbuf_copy_partial(p, seconds_buf, sizeof(seconds_buf), 40);
uint32_t seconds_since_1900 = seconds_buf[0] << 24 | seconds_buf[1] << 16 | seconds_buf[2] << 8 | seconds_buf[3];
uint32_t seconds_since_1970 = seconds_since_1900 - NTP_DELTA;
time_t epoch = seconds_since_1970;
ntp_result(state, 0, &epoch);
} else {
McuLog_error("invalid ntp response");
ntp_result(state, -1, NULL); /* abort */
}
pbuf_free(p);
}
static int ntp_init(ntp_desc_t *ntp_state) {
memset(ntp_state, 0, sizeof(ntp_desc_t));
ntp_state->ntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); /* setup udp protocol block */
if (!ntp_state->ntp_pcb) {
McuLog_error("failed to create udp pcb");
return -1; /* failed */
}
udp_recv(ntp_state->ntp_pcb, ntp_recv, ntp_state); /* set receive callback */
return 0; /* ok */
}
struct ntp {
bool start; /* if task remains suspended after startup, stored in minINI */
bool taskIsSuspended; /* if task is suspended or not */
} ntp;
bool NtpClient_GetDefaultStart(void) {
return ntp.start;
}
static uint8_t SetDefaultStart(bool start) {
#if PL_CONFIG_USE_MINI
if (McuMinINI_ini_putl(NVMC_MININI_SECTION_NTP, NVMC_MININI_KEY_NTP_START, start, NVMC_MININI_FILE_NAME)!=1) { /* 1: success */
return ERR_FAILED;
}
#endif
ntp.start = start;
return ERR_OK;
}
static void ntpTask(void *pv) {
ntp_desc_t ntp_state;
#define NTP_DEFAULT_START true
#if PL_CONFIG_USE_MINI
ntp.start = McuMinINI_ini_getbool(NVMC_MININI_SECTION_NTP, NVMC_MININI_KEY_NTP_START, NTP_DEFAULT_START, NVMC_MININI_FILE_NAME);
#else
ntp.start = NTP_DEFAULT_START;
#endif
ntp.taskIsSuspended = true;
vTaskSuspend(NULL); /* will be resumed by WiFi task */
if (ntp_init(&ntp_state)!=0) {
McuLog_fatal("failed initializing ntp");
for(;;) {
vTaskSuspend(NULL);
}
}
/* resolve NTP server name */
while (DnsResolver_ResolveName(NTP_SERVER, &ntp_state.addr, 5*1000)!=0) {
McuLog_error("dns request for '%s' failed", NTP_SERVER);
vTaskDelay(pdMS_TO_TICKS(30*1000));
} /* retry until success */
for(;;) {
do {
/* Set timeout alarm in case udp requests are lost */
ntp_state.ntp_timeout_alarm = add_alarm_in_ms(NTP_TIMEOUT_TIME_MS, ntp_timeout_handler, &ntp_state, true);
ntp_request(&ntp_state);
do {
vTaskDelay(pdMS_TO_TICKS(100)); /* wait for response or timeout */
} while (ntp_state.ntp_timeout_alarm>0); /* request still going on, timeout not expired? */
} while (ntp_state.ntp_timeout_alarm>0); /* retry */
vTaskDelay(pdMS_TO_TICKS(NTP_PERIOD_TIME_MS)); /* delay until next ntp request */
}
}
void NtpClient_TaskResume(void) {
if (taskHandle!=NULL) {
vTaskResume(taskHandle);
ntp.taskIsSuspended = false;
}
}
void NtpClient_TaskSuspend(void) {
if (taskHandle!=NULL) {
vTaskSuspend(taskHandle);
ntp.taskIsSuspended = true;
}
}
static uint8_t PrintStatus(const McuShell_StdIOType *io) {
McuShell_SendStatusStr((unsigned char*)"ntpclient", (unsigned char*)"NTP client status\r\n", io->stdOut);
McuShell_SendStatusStr((unsigned char*)" start", ntp.start?(unsigned char*)"true\r\n":(unsigned char*)"false\r\n", io->stdOut);
McuShell_SendStatusStr((unsigned char*)" suspended", ntp.taskIsSuspended?(unsigned char*)"true\r\n":(unsigned char*)"false\r\n", io->stdOut);
return ERR_OK;
}
static uint8_t PrintHelp(const McuShell_StdIOType *io) {
McuShell_SendHelpStr((unsigned char*)"ntpclient", (unsigned char*)"Group of ntpclient commands\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Print help or status information\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" start yes|no", (unsigned char*)"If ntplient task shall start be default\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" suspend|resume", (unsigned char*)"Suspend or resume ntp client task\r\n", io->stdOut);
return ERR_OK;
}
uint8_t NtpClient_ParseCommand(const unsigned char *cmd, bool *handled, const McuShell_StdIOType *io) {
const unsigned char *p;
uint16_t val16u;
if (McuUtility_strcmp((char*)cmd, McuShell_CMD_HELP)==0 || McuUtility_strcmp((char*)cmd, "ntpclient help")==0) {
*handled = true;
return PrintHelp(io);
} else if ((McuUtility_strcmp((char*)cmd, McuShell_CMD_STATUS)==0) || (McuUtility_strcmp((char*)cmd, "ntpclient status")==0)) {
*handled = true;
return PrintStatus(io);
} else if (McuUtility_strcmp((char*)cmd, "ntpclient resume")==0) {
*handled = true;
NtpClient_TaskResume();
} else if (McuUtility_strcmp((char*)cmd, "ntpclient suspend")==0) {
*handled = true;
NtpClient_TaskSuspend();
} else if (McuUtility_strcmp((char*)cmd, "ntpclient start yes")==0) {
*handled = true;
return SetDefaultStart(true);
} else if (McuUtility_strcmp((char*)cmd, "ntpclient start no")==0) {
*handled = true;
return SetDefaultStart(false);
}
return ERR_OK;
}
void NtpClient_Init(void) {
if (xTaskCreate(
ntpTask, /* pointer to the task */
"ntp", /* task name for kernel awareness debugging */
4096/sizeof(StackType_t), /* task stack size */
(void*)NULL, /* optional task startup argument */
tskIDLE_PRIORITY+1, /* initial priority */
&taskHandle /* optional task handle to create */
) != pdPASS)
{
McuLog_fatal("failed creating task");
for(;;){} /* error! probably out of memory */
}
}
#endif /* PL_CONFIG_USE_NTP_CLIENT */