Signed-off-by: Richard Cochran <richardcoch...@gmail.com> --- config.c | 15 +++++++++++++- port.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ port_private.h | 3 +++ power_profile.h | 31 +++++++++++++++++++++++++++++ tlv.h | 8 ++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 power_profile.h
diff --git a/config.c b/config.c index f028b88..cb4421f 100644 --- a/config.c +++ b/config.c @@ -31,6 +31,7 @@ #include "config.h" #include "ether.h" #include "hash.h" +#include "power_profile.h" #include "print.h" #include "util.h" @@ -66,7 +67,7 @@ typedef union { char *s; } any_t; -#define CONFIG_LABEL_SIZE 32 +#define CONFIG_LABEL_SIZE 64 #define CFG_ITEM_STATIC (1 << 0) /* statically allocated, not to be freed */ #define CFG_ITEM_LOCKED (1 << 1) /* command line value, may not be changed */ @@ -190,6 +191,13 @@ static struct config_enum hwts_filter_enu[] = { { NULL, 0 }, }; +static struct config_enum ieee_c37_238_enu[] = { + { "none", IEEE_C37_238_VERSION_NONE }, + { "2011", IEEE_C37_238_VERSION_2011 }, + { "2017", IEEE_C37_238_VERSION_2017 }, + { NULL, 0 }, +}; + static struct config_enum nw_trans_enu[] = { { "L2", TRANS_IEEE_802_3 }, { "UDPv4", TRANS_UDP_IPV4 }, @@ -300,6 +308,11 @@ struct config_item config_tab[] = { GLOB_ITEM_DBL("pi_proportional_exponent", -0.3, -DBL_MAX, DBL_MAX), GLOB_ITEM_DBL("pi_proportional_norm_max", 0.7, DBL_MIN, 1.0), GLOB_ITEM_DBL("pi_proportional_scale", 0.0, 0.0, DBL_MAX), + PORT_ITEM_ENU("power_profile.version", IEEE_C37_238_VERSION_NONE, ieee_c37_238_enu), + PORT_ITEM_INT("power_profile.2011.grandmasterTimeInaccuracy", 0xFFFFFFFF, 0, INT_MAX), + PORT_ITEM_INT("power_profile.2011.networkTimeInaccuracy", 0, 0, INT_MAX), + PORT_ITEM_INT("power_profile.2017.totalTimeInaccuracy", 0xFFFFFFFF, 0, INT_MAX), + PORT_ITEM_INT("power_profile.grandmasterID", 0, 0, 0xFFFF), GLOB_ITEM_INT("priority1", 128, 0, UINT8_MAX), GLOB_ITEM_INT("priority2", 128, 0, UINT8_MAX), GLOB_ITEM_STR("productDescription", ";;"), diff --git a/port.c b/port.c index 92f3ee3..23697a5 100644 --- a/port.c +++ b/port.c @@ -453,6 +453,46 @@ static int follow_up_info_append(struct ptp_message *m) return 0; } +static int ieee_c37_238_append(struct port *p, struct ptp_message *m) +{ + struct ieee_c37_238_2017_tlv *p17; + struct ieee_c37_238_2011_tlv *p11; + struct tlv_extra *extra; + + switch (p->pwr.version) { + case IEEE_C37_238_VERSION_NONE: + return 0; + case IEEE_C37_238_VERSION_2011: + extra = msg_tlv_append(m, sizeof(*p11)); + if (!extra) { + return -1; + } + p11 = (struct ieee_c37_238_2011_tlv *) extra->tlv; + p11->type = TLV_ORGANIZATION_EXTENSION; + p11->length = sizeof(*p11) - sizeof(p11->type) - sizeof(p11->length); + memcpy(p11->id, ieeec37_238_id, sizeof(ieeec37_238_id)); + p11->subtype[2] = 1; + p11->grandmasterID = p->pwr.grandmasterID; + p11->grandmasterTimeInaccuracy = p->pwr.grandmasterTimeInaccuracy; + p11->networkTimeInaccuracy = p->pwr.networkTimeInaccuracy; + break; + case IEEE_C37_238_VERSION_2017: + extra = msg_tlv_append(m, sizeof(*p17)); + if (!extra) { + return -1; + } + p17 = (struct ieee_c37_238_2017_tlv *) extra->tlv; + p17->type = TLV_ORGANIZATION_EXTENSION; + p17->length = sizeof(*p17) - sizeof(p17->type) - sizeof(p17->length); + memcpy(p17->id, ieeec37_238_id, sizeof(ieeec37_238_id)); + p17->subtype[2] = 2; + p17->grandmasterID = p->pwr.grandmasterID; + p17->totalTimeInaccuracy = p->pwr.totalTimeInaccuracy; + break; + } + return 0; +} + static int net_sync_resp_append(struct port *p, struct ptp_message *m) { struct timePropertiesDS tp = clock_time_properties(p->clock); @@ -1622,6 +1662,9 @@ int port_tx_announce(struct port *p, struct address *dst, uint16_t sequence_id) if (p->path_trace_enabled && path_trace_append(p, msg, dad)) { pr_err("%s: append path trace failed", p->log_name); } + if (ieee_c37_238_append(p, msg)) { + pr_err("%s: append power profile failed", p->log_name); + } err = port_prepare_and_send(p, msg, TRANS_GENERAL); if (err) { @@ -3332,6 +3375,16 @@ struct port *port_open(const char *phc_device, p->state = PS_INITIALIZING; p->delayMechanism = config_get_int(cfg, p->name, "delay_mechanism"); p->versionNumber = PTP_MAJOR_VERSION; + p->pwr.version = + config_get_int(cfg, p->name, "power_profile.version"); + p->pwr.grandmasterID = + config_get_int(cfg, p->name, "power_profile.grandmasterID"); + p->pwr.grandmasterTimeInaccuracy = + config_get_int(cfg, p->name, "power_profile.2011.grandmasterTimeInaccuracy"); + p->pwr.networkTimeInaccuracy = + config_get_int(cfg, p->name, "power_profile.2011.networkTimeInaccuracy"); + p->pwr.totalTimeInaccuracy = + config_get_int(cfg, p->name, "power_profile.2017.totalTimeInaccuracy"); p->slave_event_monitor = clock_slave_monitor(clock); if (!port_is_uds(p) && unicast_client_initialize(p)) { diff --git a/port_private.h b/port_private.h index e5837b9..3b02d2f 100644 --- a/port_private.h +++ b/port_private.h @@ -26,6 +26,7 @@ #include "fsm.h" #include "monitor.h" #include "msg.h" +#include "power_profile.h" #include "tmv.h" #define NSEC2SEC 1000000000LL @@ -153,6 +154,8 @@ struct port { LIST_HEAD(fm, foreign_clock) foreign_masters; /* TC book keeping */ TAILQ_HEAD(tct, tc_txd) tc_transmitted; + /* power profile */ + struct ieee_c37_238_settings_np pwr; /* unicast client mode */ struct unicast_master_table *unicast_master_table; /* unicast service mode */ diff --git a/power_profile.h b/power_profile.h new file mode 100644 index 0000000..6a7c8a4 --- /dev/null +++ b/power_profile.h @@ -0,0 +1,31 @@ +/** + * @file power_profile.h + * @brief Implements power profile features. + * @note Copyright (C) 2021 Richard Cochran <richardcoch...@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef HAVE_POWER_PROFILE_H +#define HAVE_POWER_PROFILE_H + +#include "pdt.h" + +enum power_profile_version { + IEEE_C37_238_VERSION_NONE, + IEEE_C37_238_VERSION_2011, + IEEE_C37_238_VERSION_2017, +}; + +#endif diff --git a/tlv.h b/tlv.h index 3d838b7..b973295 100644 --- a/tlv.h +++ b/tlv.h @@ -324,6 +324,14 @@ struct ieee_c37_238_2017_tlv { Octet pad[2]; } PACKED; +struct ieee_c37_238_settings_np { + Enumeration16 version; + UInteger16 grandmasterID; + UInteger32 grandmasterTimeInaccuracy; + UInteger32 networkTimeInaccuracy; + UInteger32 totalTimeInaccuracy; +} PACKED; + struct msg_interval_req_tlv { Enumeration16 type; UInteger16 length; -- 2.30.2 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel