Skip to content

Commit

Permalink
[ESP32] Add sntp support to get real time on esp32 (project-chip#32092)
Browse files Browse the repository at this point in the history
* [ESP32] Add sntp support to get real time on esp32

* Address review comments

* Did some restructoring to address review comments

* Addressed review comments

* Again addressed review comments

* Restyled by clang-format

* Some renaming and error check

* Update sntp array to accomodate null terminating charactor

---------

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
jadhavrohit924 and restyled-commits authored Mar 5, 2024
1 parent 2c522cb commit 3d47e35
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 6 deletions.
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;
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.");
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.");
}
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();
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

0 comments on commit 3d47e35

Please sign in to comment.