Skip to content

Commit 5b84c67

Browse files
committed
Merge branch 'time-sync' into 'main'
esp_matter: add missing attributes and commands for time sync cluster See merge request app-frameworks/esp-matter!990
2 parents 911a0a5 + c31958a commit 5b84c67

8 files changed

+402
-0
lines changed

components/esp_matter/esp_matter_attribute.cpp

+89
Original file line numberDiff line numberDiff line change
@@ -5028,5 +5028,94 @@ attribute_t *create_location_directory(cluster_t *cluster, uint8_t *value, uint1
50285028
} /* attribute */
50295029
} /* ecosystem_information */
50305030

5031+
namespace time_synchronization {
5032+
namespace attribute {
5033+
attribute_t *create_utc_time(cluster_t *cluster, nullable<uint64_t> value)
5034+
{
5035+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::UTCTime::Id,
5036+
ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_MANAGED_INTERNALLY,
5037+
esp_matter_nullable_uint64(value));
5038+
}
5039+
5040+
attribute_t *create_granularity(cluster_t *cluster, uint8_t value)
5041+
{
5042+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::Granularity::Id,
5043+
ATTRIBUTE_FLAG_MANAGED_INTERNALLY, esp_matter_enum8(value));
5044+
}
5045+
5046+
attribute_t *create_time_source(cluster_t *cluster, uint8_t value)
5047+
{
5048+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TimeSource::Id,
5049+
ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value));
5050+
}
5051+
5052+
attribute_t *create_trusted_time_source(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count)
5053+
{
5054+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TrustedTimeSource::Id,
5055+
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE,
5056+
esp_matter_array(value, length, count));
5057+
}
5058+
5059+
attribute_t *create_default_ntp(cluster_t *cluster, char *value, uint16_t length)
5060+
{
5061+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::DefaultNTP::Id,
5062+
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE | ATTRIBUTE_FLAG_NONVOLATILE,
5063+
esp_matter_char_str(value, length));
5064+
}
5065+
5066+
attribute_t *create_time_zone(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count)
5067+
{
5068+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TimeZone::Id,
5069+
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NONVOLATILE,
5070+
esp_matter_array(value, length, count));
5071+
}
5072+
5073+
attribute_t *create_dst_offset(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count)
5074+
{
5075+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::DSTOffset::Id,
5076+
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NONVOLATILE,
5077+
esp_matter_array(value, length, count));
5078+
}
5079+
5080+
attribute_t *create_local_time(cluster_t *cluster, nullable<uint64_t> value)
5081+
{
5082+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::LocalTime::Id,
5083+
ATTRIBUTE_FLAG_MANAGED_INTERNALLY | ATTRIBUTE_FLAG_NULLABLE,
5084+
esp_matter_nullable_uint64(value));
5085+
}
5086+
5087+
attribute_t *create_time_zone_database(cluster_t *cluster, uint8_t value)
5088+
{
5089+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TimeZoneDatabase::Id,
5090+
ATTRIBUTE_FLAG_NONE, esp_matter_enum8(value));
5091+
}
5092+
5093+
attribute_t *create_ntp_server_available(cluster_t *cluster, bool value)
5094+
{
5095+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::NTPServerAvailable::Id,
5096+
ATTRIBUTE_FLAG_NONE, esp_matter_bool(value));
5097+
}
5098+
5099+
attribute_t *create_time_zone_list_max_size(cluster_t *cluster, uint8_t value)
5100+
{
5101+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::TimeZoneListMaxSize::Id,
5102+
ATTRIBUTE_FLAG_MANAGED_INTERNALLY, esp_matter_uint8(value));
5103+
}
5104+
5105+
attribute_t *create_dst_offset_list_max_size(cluster_t *cluster, uint8_t value)
5106+
{
5107+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::DSTOffsetListMaxSize::Id,
5108+
ATTRIBUTE_FLAG_MANAGED_INTERNALLY, esp_matter_uint8(value));
5109+
}
5110+
5111+
attribute_t *create_supports_dns_resolve(cluster_t *cluster, bool value)
5112+
{
5113+
return esp_matter::attribute::create(cluster, TimeSynchronization::Attributes::SupportsDNSResolve::Id,
5114+
ATTRIBUTE_FLAG_NONE, esp_matter_uint64(value));
5115+
}
5116+
5117+
} /* attribute */
5118+
} /* time_synchronization */
5119+
50315120
} /* cluster */
50325121
} /* esp_matter */

components/esp_matter/esp_matter_attribute.h

+18
Original file line numberDiff line numberDiff line change
@@ -1245,5 +1245,23 @@ attribute_t *create_location_directory(cluster_t *cluster, uint8_t *value, uint1
12451245
} /* attribute */
12461246
} /* ecosystem_information */
12471247

1248+
namespace time_synchronization {
1249+
namespace attribute {
1250+
attribute_t *create_utc_time(cluster_t *cluster, nullable<uint64_t> value);
1251+
attribute_t *create_granularity(cluster_t *cluster, uint8_t value);
1252+
attribute_t *create_time_source(cluster_t *cluster, uint8_t value);
1253+
attribute_t *create_trusted_time_source(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count);
1254+
attribute_t *create_default_ntp(cluster_t *cluster, char *value, uint16_t length);
1255+
attribute_t *create_time_zone(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count);
1256+
attribute_t *create_dst_offset(cluster_t *cluster, uint8_t *value, uint16_t length, uint16_t count);
1257+
attribute_t *create_local_time(cluster_t *cluster, nullable<uint64_t> value);
1258+
attribute_t *create_time_zone_database(cluster_t *cluster, uint8_t value);
1259+
attribute_t *create_ntp_server_available(cluster_t *cluster, bool value);
1260+
attribute_t *create_time_zone_list_max_size(cluster_t *cluster, uint8_t value);
1261+
attribute_t *create_dst_offset_list_max_size(cluster_t *cluster, uint8_t value);
1262+
attribute_t *create_supports_dns_resolve(cluster_t *cluster, bool value);
1263+
} /* attribute */
1264+
} /* time_synchronization */
1265+
12481266
} /* cluster */
12491267
} /* esp_matter */

components/esp_matter/esp_matter_cluster.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -679,9 +679,14 @@ cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags)
679679

680680
/* Attributes managed internally */
681681
global::attribute::create_feature_map(cluster, 0);
682+
attribute::create_utc_time(cluster, nullable<uint64_t>());
683+
attribute::create_granularity(cluster, 0);
682684

683685
/* Attributes not managed internally */
684686
global::attribute::create_cluster_revision(cluster, cluster_revision);
687+
688+
/* Commands */
689+
command::create_set_utc_time(cluster);
685690
}
686691

687692
event::create_time_failure(cluster);

components/esp_matter/esp_matter_command.cpp

+104
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,62 @@ static esp_err_t esp_matter_command_callback_close(const ConcreteCommandPath &co
15551555
return ESP_OK;
15561556
}
15571557

1558+
static esp_err_t esp_matter_command_callback_set_utc_time(const ConcreteCommandPath &command_path, TLVReader &tlv_data,
1559+
void *opaque_ptr)
1560+
{
1561+
chip::app::Clusters::TimeSynchronization::Commands::SetUTCTime::DecodableType command_data;
1562+
CHIP_ERROR error = Decode(tlv_data, command_data);
1563+
if (error == CHIP_NO_ERROR) {
1564+
emberAfTimeSynchronizationClusterSetUTCTimeCallback((CommandHandler *)opaque_ptr, command_path, command_data);
1565+
}
1566+
return ESP_OK;
1567+
}
1568+
1569+
static esp_err_t esp_matter_command_callback_set_trusted_time_source(const ConcreteCommandPath &command_path,
1570+
TLVReader &tlv_data, void *opaque_ptr)
1571+
{
1572+
chip::app::Clusters::TimeSynchronization::Commands::SetTrustedTimeSource::DecodableType command_data;
1573+
CHIP_ERROR error = Decode(tlv_data, command_data);
1574+
if (error == CHIP_NO_ERROR) {
1575+
emberAfTimeSynchronizationClusterSetTrustedTimeSourceCallback((CommandHandler *)opaque_ptr, command_path,
1576+
command_data);
1577+
}
1578+
return ESP_OK;
1579+
}
1580+
1581+
static esp_err_t esp_matter_command_callback_set_time_zone(const ConcreteCommandPath &command_path, TLVReader &tlv_data,
1582+
void *opaque_ptr)
1583+
{
1584+
chip::app::Clusters::TimeSynchronization::Commands::SetTimeZone::DecodableType command_data;
1585+
CHIP_ERROR error = Decode(tlv_data, command_data);
1586+
if (error == CHIP_NO_ERROR) {
1587+
emberAfTimeSynchronizationClusterSetTimeZoneCallback((CommandHandler *)opaque_ptr, command_path, command_data);
1588+
}
1589+
return ESP_OK;
1590+
}
1591+
1592+
static esp_err_t esp_matter_command_callback_set_dst_offset(const ConcreteCommandPath &command_path, TLVReader &tlv_data,
1593+
void *opaque_ptr)
1594+
{
1595+
chip::app::Clusters::TimeSynchronization::Commands::SetDSTOffset::DecodableType command_data;
1596+
CHIP_ERROR error = Decode(tlv_data, command_data);
1597+
if (error == CHIP_NO_ERROR) {
1598+
emberAfTimeSynchronizationClusterSetDSTOffsetCallback((CommandHandler *)opaque_ptr, command_path, command_data);
1599+
}
1600+
return ESP_OK;
1601+
}
1602+
1603+
static esp_err_t esp_matter_command_callback_set_default_ntp(const ConcreteCommandPath &command_path, TLVReader &tlv_data,
1604+
void *opaque_ptr)
1605+
{
1606+
chip::app::Clusters::TimeSynchronization::Commands::SetDefaultNTP::DecodableType command_data;
1607+
CHIP_ERROR error = Decode(tlv_data, command_data);
1608+
if (error == CHIP_NO_ERROR) {
1609+
emberAfTimeSynchronizationClusterSetDefaultNTPCallback((CommandHandler *)opaque_ptr, command_path, command_data);
1610+
}
1611+
return ESP_OK;
1612+
}
1613+
15581614
namespace esp_matter {
15591615
namespace cluster {
15601616

@@ -3451,6 +3507,53 @@ command_t *create_reverse_open_commissioning_window(cluster_t *cluster)
34513507
} /* command */
34523508
} /* commissioner_control */
34533509

3510+
namespace time_synchronization {
3511+
namespace command {
3512+
constexpr const command_entry_t accepted_command_list[] = {
3513+
{TimeSynchronization::Commands::SetUTCTime::Id, COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_set_utc_time},
3514+
};
3515+
3516+
constexpr const command_entry_t generated_command_list[] = {};
3517+
3518+
command_t *create_set_utc_time(cluster_t *cluster)
3519+
{
3520+
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetUTCTime::Id, COMMAND_FLAG_ACCEPTED,
3521+
esp_matter_command_callback_set_utc_time);
3522+
}
3523+
3524+
command_t *create_set_trusted_time_source(cluster_t *cluster)
3525+
{
3526+
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetTrustedTimeSource::Id,
3527+
COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_set_trusted_time_source);
3528+
}
3529+
3530+
command_t *create_set_time_zone(cluster_t *cluster)
3531+
{
3532+
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetTimeZone::Id, COMMAND_FLAG_ACCEPTED,
3533+
esp_matter_command_callback_set_time_zone);
3534+
}
3535+
3536+
command_t *create_set_time_zone_response(cluster_t *cluster)
3537+
{
3538+
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetTimeZoneResponse::Id,
3539+
COMMAND_FLAG_GENERATED, nullptr);
3540+
}
3541+
3542+
command_t *create_set_dst_offset(cluster_t *cluster)
3543+
{
3544+
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetDSTOffset::Id,
3545+
COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_set_dst_offset);
3546+
}
3547+
3548+
command_t *create_set_default_ntp(cluster_t *cluster)
3549+
{
3550+
return esp_matter::command::create(cluster, TimeSynchronization::Commands::SetDefaultNTP::Id,
3551+
COMMAND_FLAG_ACCEPTED, esp_matter_command_callback_set_default_ntp);
3552+
}
3553+
3554+
} /* command */
3555+
} /* time_synchronization */
3556+
34543557
} /* cluster */
34553558
} /* esp_matter */
34563559

@@ -3499,6 +3602,7 @@ constexpr const cluster_command_t cluster_command_table[] = {
34993602
{ThreadNetworkDirectory::Id, GET_COMMAND_COUNT_LIST(cluster::thread_network_directory)},
35003603
{WaterHeaterManagement::Id, GET_COMMAND_COUNT_LIST(cluster::water_heater_management)},
35013604
{CommissionerControl::Id, GET_COMMAND_COUNT_LIST(cluster::commissioner_control)},
3605+
{TimeSynchronization::Id, GET_COMMAND_COUNT_LIST(cluster::time_synchronization)},
35023606
};
35033607

35043608
#if defined(CONFIG_ESP_MATTER_ENABLE_MATTER_SERVER) && defined(CONFIG_ESP_MATTER_ENABLE_DATA_MODEL)

components/esp_matter/esp_matter_command.h

+11
Original file line numberDiff line numberDiff line change
@@ -503,5 +503,16 @@ command_t *create_reverse_open_commissioning_window(cluster_t *cluster);
503503
} /* command */
504504
} /* commissioner_control */
505505

506+
namespace time_synchronization {
507+
namespace command {
508+
command_t *create_set_utc_time(cluster_t *cluster);
509+
command_t *create_set_trusted_time_source(cluster_t *cluster);
510+
command_t *create_set_time_zone(cluster_t *cluster);
511+
command_t *create_set_time_zone_response(cluster_t *cluster);
512+
command_t *create_set_dst_offset(cluster_t *cluster);
513+
command_t *create_set_default_ntp(cluster_t *cluster);
514+
} /* command */
515+
} /* time_synchronization */
516+
506517
} /* cluster */
507518
} /* esp_matter */

components/esp_matter/esp_matter_feature.cpp

+118
Original file line numberDiff line numberDiff line change
@@ -4941,5 +4941,123 @@ esp_err_t add(cluster_t *cluster)
49414941

49424942
} /* feature */
49434943
} /* pump_configuration_and_control */
4944+
4945+
namespace time_synchronization {
4946+
namespace feature {
4947+
4948+
namespace time_zone {
4949+
uint32_t get_id()
4950+
{
4951+
return static_cast<uint32_t>(TimeSynchronization::Feature::kTimeZone);
4952+
}
4953+
4954+
esp_err_t add(cluster_t *cluster, config_t *config)
4955+
{
4956+
if (!cluster || !config) {
4957+
ESP_LOGE(TAG, "Cluster or config cannot be NULL");
4958+
return ESP_ERR_INVALID_ARG;
4959+
}
4960+
update_feature_map(cluster, get_id());
4961+
4962+
// Attributes managed internally
4963+
attribute::create_time_zone(cluster, nullptr, 0, 0);
4964+
attribute::create_dst_offset(cluster, nullptr, 0, 0);
4965+
attribute::create_local_time(cluster, nullable<uint64_t>());
4966+
attribute::create_time_zone_list_max_size(cluster, 0);
4967+
attribute::create_dst_offset_list_max_size(cluster, 0);
4968+
4969+
// Attributes not managed internally
4970+
attribute::create_time_zone_database(cluster, config->time_zone_database);
4971+
4972+
// Commands
4973+
command::create_set_time_zone(cluster);
4974+
command::create_set_dst_offset(cluster);
4975+
command::create_set_time_zone_response(cluster);
4976+
4977+
// Events
4978+
event::create_dst_table_empty(cluster);
4979+
event::create_dst_status(cluster);
4980+
event::create_time_zone_status(cluster);
4981+
4982+
return ESP_OK;
4983+
}
4984+
} /* time_zone */
4985+
4986+
namespace ntp_client {
4987+
uint32_t get_id()
4988+
{
4989+
return static_cast<uint32_t>(TimeSynchronization::Feature::kNTPClient);
4990+
}
4991+
4992+
esp_err_t add(cluster_t *cluster, config_t *config)
4993+
{
4994+
if (!cluster || !config) {
4995+
ESP_LOGE(TAG, "Cluster or config cannot be NULL");
4996+
return ESP_ERR_INVALID_ARG;
4997+
}
4998+
update_feature_map(cluster, get_id());
4999+
5000+
// Attributes managed internally
5001+
attribute::create_default_ntp(cluster, nullptr, 0);
5002+
5003+
// Attributes not managed internally
5004+
attribute::create_supports_dns_resolve(cluster, config->supports_dns_resolve);
5005+
5006+
// Commands
5007+
command::create_set_default_ntp(cluster);
5008+
5009+
return ESP_OK;
5010+
}
5011+
} /* ntp_client */
5012+
5013+
namespace ntp_server {
5014+
5015+
uint32_t get_id()
5016+
{
5017+
return static_cast<uint32_t>(TimeSynchronization::Feature::kNTPServer);
5018+
}
5019+
5020+
esp_err_t add(cluster_t *cluster, config_t *config)
5021+
{
5022+
if (!cluster || !config) {
5023+
ESP_LOGE(TAG, "Cluster or config cannot be NULL");
5024+
return ESP_ERR_INVALID_ARG;
5025+
}
5026+
update_feature_map(cluster, get_id());
5027+
5028+
// Attributes not managed internally
5029+
attribute::create_ntp_server_available(cluster, config->ntp_server_available);
5030+
5031+
return ESP_OK;
5032+
}
5033+
} /* ntp_server */
5034+
5035+
namespace time_sync_client {
5036+
uint32_t get_id()
5037+
{
5038+
return static_cast<uint32_t>(TimeSynchronization::Feature::kTimeSyncClient);
5039+
}
5040+
5041+
esp_err_t add(cluster_t *cluster)
5042+
{
5043+
if (!cluster) {
5044+
ESP_LOGE(TAG, "Cluster cannot be NULL");
5045+
return ESP_ERR_INVALID_ARG;
5046+
}
5047+
update_feature_map(cluster, get_id());
5048+
5049+
// Attributes managed internally
5050+
attribute::create_trusted_time_source(cluster, nullptr, 0, 0);
5051+
5052+
// Commands
5053+
command::create_set_trusted_time_source(cluster);
5054+
5055+
return ESP_OK;
5056+
}
5057+
} /* time_sync_client */
5058+
5059+
} /* feature */
5060+
} /* time_synchronization */
5061+
49445062
} /* cluster */
49455063
} /* esp_matter */

0 commit comments

Comments
 (0)