Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ESP32] Add sntp support to get real time on esp32 #32092

Merged
merged 8 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config/esp32/components/chip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@ menu "CHIP Core"
Opens the commissioning window automatically at application boot time if
the node is not yet commissioned.

config ENABLE_SNTP_TIME_SYNC
bool "Enable SNTP time synchronization"
default n
help
Enable this option to enable SNTP time synchronization

endmenu # "System Options"

menu "Security Options"
Expand Down
1 change: 1 addition & 0 deletions examples/energy-management-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ set(SRC_DIRS_LIST
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/energy-management-app/energy-management-common/src"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/ota"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/time"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server"
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util"
Expand Down
15 changes: 13 additions & 2 deletions examples/energy-management-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include <common/CHIPDeviceManager.h>
#include <common/Esp32AppServer.h>
#include <common/Esp32ThreadInit.h>
#if CONFIG_ENABLE_SNTP_TIME_SYNC
#include <time/TimeSync.h>
#endif
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "spi_flash_mmap.h"
#else
Expand Down Expand Up @@ -126,7 +129,8 @@ static void InitServer(intptr_t context)
PrintOnboardingCodes(chip::RendezvousInformationFlags(CONFIG_RENDEZVOUS_MODE));

DeviceCallbacksDelegate::Instance().SetAppDelegate(&sAppDeviceCallbacksDelegate);
Esp32AppServer::Init(); // Init ZCL Data Model and CHIP App Server AND Initialize device attestation config
Esp32AppServer::Init(); // Init ZCL Data Model and CHIP App Server AND
// Initialize device attestation config
#if CONFIG_ENABLE_ESP_INSIGHTS_TRACE
esp_insights_config_t config = {
.log_type = ESP_DIAG_LOG_TYPE_ERROR | ESP_DIAG_LOG_TYPE_WARNING | ESP_DIAG_LOG_TYPE_EVENT,
Expand All @@ -144,8 +148,15 @@ static void InitServer(intptr_t context)
Tracing::Register(backend);
#endif

// Application code should always be initialised after the initialisation of server.
// Application code should always be initialised after the initialisation of
// server.
ApplicationInit();

#if CONFIG_ENABLE_SNTP_TIME_SYNC
const char kNtpServerUrl[] = "pool.ntp.org";
const uint16_t kSyncNtpTimeIntervalDay = 1;
chip::Esp32TimeSync::Init(kNtpServerUrl, kSyncNtpTimeIntervalDay);
#endif
}

extern "C" void app_main()
Expand Down
3 changes: 3 additions & 0 deletions examples/energy-management-app/esp32/sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,6 @@ CONFIG_DISABLE_READ_CLIENT=y

# Increase LwIP IPv6 address number
CONFIG_LWIP_IPV6_NUM_ADDRESSES=6

# Enable sntp time sync
CONFIG_ENABLE_SNTP_TIME_SYNC=y
102 changes: 102 additions & 0 deletions examples/platform/esp32/time/TimeSync.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "TimeSync.h"
#include <esp_sntp.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/logging/CHIPLogging.h>

static constexpr time_t kMinValidTimeStampEpoch = 1704067200; // 1 Jan 2019
static constexpr uint32_t kSecondsInADay = 24 * 60 * 60;

namespace {
const uint8_t kMaxNtpServerStringSize = 128;
char sSntpServerName[kMaxNtpServerStringSize + 1];

CHIP_ERROR GetLocalTimeString(char * buf, size_t buf_len)
{
VerifyOrReturnError(buf_len > 0, CHIP_ERROR_INVALID_ARGUMENT);
struct tm timeinfo;
char strftime_buf[64];
time_t now;
jadhavrohit924 marked this conversation as resolved.
Show resolved Hide resolved
time(&now);
localtime_r(&now, &timeinfo);
if (strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%dT%H:%M:%S%z", &timeinfo) == 0)
{
ChipLogError(DeviceLayer, "Buffer too small");
return CHIP_ERROR_BUFFER_TOO_SMALL;
}
size_t print_size = snprintf(buf, buf_len, "%s, DST: %s", strftime_buf, timeinfo.tm_isdst ? "Yes" : "No");
if (print_size >= (buf_len - 1))
{
ChipLogError(DeviceLayer, "Buffer size %d insufficient for localtime string. Required size: %d", static_cast<int>(buf_len),
static_cast<int>(print_size));
return CHIP_ERROR_BUFFER_TOO_SMALL;
}
return CHIP_NO_ERROR;
}

bool ValidateTime()
{
time_t now;
time(&now);
return (now > kMinValidTimeStampEpoch);
}

CHIP_ERROR PrintCurrentTime()
{
char local_time[64] = { 0 };
ReturnErrorOnFailure(GetLocalTimeString(local_time, sizeof(local_time)));
if (!ValidateTime())
{
ChipLogProgress(DeviceLayer, "Time not synchronised yet.");
jadhavrohit924 marked this conversation as resolved.
Show resolved Hide resolved
return CHIP_ERROR_INCORRECT_STATE;
}
ChipLogProgress(DeviceLayer, "The current time is: %s.", local_time);
return CHIP_NO_ERROR;
}

void TimeSyncCallback(struct timeval * tv)
{
ChipLogProgress(DeviceLayer, "SNTP Synchronised.");
if (PrintCurrentTime() != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "SNTP time is not synchronised.");
}
}

} // anonymous namespace

namespace chip {
namespace Esp32TimeSync {
void Init(const char * aSntpServerName, const uint16_t aSyncSntpIntervalDay)
{
chip::Platform::CopyString(sSntpServerName, aSntpServerName);
if (esp_sntp_enabled())
{
ChipLogProgress(DeviceLayer, "SNTP already initialized.");
jadhavrohit924 marked this conversation as resolved.
Show resolved Hide resolved
}
ChipLogProgress(DeviceLayer, "Initializing SNTP. Using the SNTP server: %s", sSntpServerName);
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
esp_sntp_setservername(0, sSntpServerName);
esp_sntp_set_sync_interval(kSecondsInADay * aSyncSntpIntervalDay);
esp_sntp_init();
jadhavrohit924 marked this conversation as resolved.
Show resolved Hide resolved
sntp_set_time_sync_notification_cb(TimeSyncCallback);
}
} // namespace Esp32TimeSync
} // namespace chip
28 changes: 28 additions & 0 deletions examples/platform/esp32/time/TimeSync.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once
#include <esp_sntp.h>
#include <lib/core/CHIPError.h>
#include <lib/support/Span.h>

namespace chip {
namespace Esp32TimeSync {
void Init(const char * aSntpServerName, uint16_t aSyncSntpIntervalDay);
} // namespace Esp32TimeSync
} // namespace chip
7 changes: 3 additions & 4 deletions src/platform/ESP32/SystemTimeSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void)

CHIP_ERROR ClockImpl::GetClock_RealTime(Microseconds64 & aCurTime)
{
// TODO(19081): This platform does not properly error out if wall clock has
// not been set. For now, short circuit this.
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
#if 0
#if CONFIG_ENABLE_SNTP_TIME_SYNC
struct timeval tv;
if (gettimeofday(&tv, nullptr) != 0)
{
Expand All @@ -70,6 +67,8 @@ CHIP_ERROR ClockImpl::GetClock_RealTime(Microseconds64 & aCurTime)
static_assert(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD >= 0, "We might be letting through negative tv_sec values!");
aCurTime = Microseconds64((static_cast<uint64_t>(tv.tv_sec) * UINT64_C(1000000)) + static_cast<uint64_t>(tv.tv_usec));
return CHIP_NO_ERROR;
#else
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
#endif
}

Expand Down
Loading