#include #include #include #include #include #include #include #include static t_configBlock *config; static const uint64_t UNIX_NTP_EPOCH_DIFF = 2208988800; extern const uint8_t SNTP_SOCK; typedef struct { uint8_t sntpBuffer[MAX_SNTP_BUF_SIZE]; uint64_t seconds; enum { SNTP_STATE_IDLE, SNTP_STATE_SEND, SNTP_STATE_DONE, SNTP_STATE_ERROR } sntpState; } sntpEngineHandle_t; sntpEngineHandle_t sntpEngineHandle = { .seconds = 0, .sntpState = SNTP_STATE_IDLE }; void networkSntpEngine(void *handle) { sntpEngineHandle_t *localHandle = (sntpEngineHandle_t*) handle; if (isNetworkAvailable()) { switch (localHandle->sntpState) { case SNTP_STATE_SEND: coloredMsg(LOG_BLUE, "nes, about to call SNTP"); uint8_t ntpServer[4]; if (wizDnsQuery(config->ntpServer, ntpServer)) { SNTP_init(SNTP_SOCK, ntpServer, 0, localHandle->sntpBuffer); uint16_t cycles = 0; uint32_t startTime = HAL_GetTick(); while (1) { cycles += 1; datetime curTime; if (1 == SNTP_run(&curTime)) { localHandle->seconds = curTime.seconds - UNIX_NTP_EPOCH_DIFF; coloredMsg(LOG_BLUE, "nes, cycles: %u, curTime: %lu", cycles, localHandle->seconds); uint32_t stopTime = HAL_GetTick(); coloredMsg(LOG_BLUE, "nes, duration: %u ms", stopTime - startTime); localHandle->sntpState = SNTP_STATE_DONE; break; } } if (localHandle->seconds == 0) { coloredMsg(LOG_BLUE, "nes, time update failed"); localHandle->sntpState = SNTP_STATE_ERROR; } } else { coloredMsg(LOG_BLUE, "nes, error when querying ntp server name"); localHandle->sntpState = SNTP_STATE_ERROR; } default: coloredMsg(LOG_BLUE, "nes, unexpected state"); } } else { coloredMsg(LOG_BLUE, "nes, no network yet, try again"); schAdd(networkSntpEngine, (void*) localHandle, 100, 0); } } uint64_t networkSntpQuery() { uint64_t res = 0; if (sntpEngineHandle.sntpState == SNTP_STATE_IDLE) { coloredMsg(LOG_BLUE, "nsq, start sntp request"); sntpEngineHandle.sntpState = SNTP_STATE_SEND; schAdd(networkSntpEngine, (void*) &sntpEngineHandle, 1, 0); } else if (sntpEngineHandle.sntpState == SNTP_STATE_DONE) { coloredMsg(LOG_BLUE, "nsq, start sntp done"); res = sntpEngineHandle.seconds; sntpEngineHandle.sntpState = SNTP_STATE_IDLE; } else if (sntpEngineHandle.sntpState == SNTP_STATE_ERROR) { coloredMsg(LOG_BLUE, "nsq, start sntp failed"); sntpEngineHandle.sntpState = SNTP_STATE_IDLE; } return res; } extern uint8_t SINK_SOCK; int8_t networkUdpSend(char *hostname, uint16_t port, uint8_t *buf, uint16_t bufLen) { uint8_t sinkAddr[4]; if (! wizDnsQuery(hostname, sinkAddr)) { coloredMsg(LOG_BLUE, "nus, failed to resolve sink server name"); return -1; } else { coloredMsg(LOG_BLUE, "nus, sink server at %d.%d.%d.%d", sinkAddr[0], sinkAddr[1], sinkAddr[2], sinkAddr[3]); } socket(SINK_SOCK, Sn_MR_UDP, port, 0); uint8_t sockState = getSn_SR(SINK_SOCK); if (sockState == SOCK_UDP) { sendto(SINK_SOCK, buf, bufLen, sinkAddr, port); coloredMsg(LOG_BLUE, "nus, sent"); } else { coloredMsg(LOG_BLUE, "nus, socket in unexpected state: %d", sockState); return -2; } close(SINK_SOCK); return 1; } void networkImplInit() { config = getConfig(); wizInit(); }