Discussion:
[Linuxptp-devel] [PATCH 1/3] adds StaticPTPText and functions for setting PTPText and StaticPTPText
Geoff Salmon
2013-01-30 14:33:46 UTC
Permalink
StaticPTPText is like a PTPText that includes space for the text which
makes it more convenient for ptp texts stored in the clock.
---
ddt.h | 16 ++++++++++++++++
util.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
util.h | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 112 insertions(+)

diff --git a/ddt.h b/ddt.h
index f142f8e..5b35f32 100644
--- a/ddt.h
+++ b/ddt.h
@@ -71,6 +71,22 @@ struct PTPText {
Octet *text;
};

+/* A StaticPTPText is like a PTPText but includes space to store the
+ * text inside the struct. The text array must always be
+ * null-terminated. Also tracks a maximum number of symbols. Note in
+ * UTF-8, # symbols != # bytes.
+ */
+#define MAX_PTP_OCTETS 255
+struct StaticPTPText {
+ /* null-terminated array of UTF-8 symbols */
+ Octet text[MAX_PTP_OCTETS + 1];
+ /* number of used bytes in text, not including trailing
+ * null */
+ int length;
+ /* max number of UTF-8 symbols that can be in text */
+ int max_symbols;
+};
+
struct FaultRecord {
UInteger16 faultRecordLength;
struct Timestamp faultTime;
diff --git a/util.c b/util.c
index 4f432a6..06fe71c 100644
--- a/util.c
+++ b/util.c
@@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
+#include <string.h>

#include "sk.h"
#include "util.h"
@@ -90,3 +91,60 @@ int generate_clock_identity(struct ClockIdentity *ci, char *name)
ci->id[7] = mac[5];
return 0;
}
+
+/* Naive count of utf8 symbols. Doesn't detect invalid UTF-8 and
+ * probably doesn't count combining characters correctly. */
+static size_t strlen_utf8(const Octet *s)
+{
+ size_t len = 0;
+ char c;
+ while ((c = *(s++))) {
+ if ((c & 0xC0) != 0x80)
+ len++;
+ }
+ return len;
+}
+
+int static_ptp_text_copy(struct StaticPTPText *dst, const struct PTPText *src)
+{
+ int len = src->length;
+ if (dst->max_symbols > 0 && strlen_utf8(src->text) > dst->max_symbols)
+ return -1;
+ dst->length = len;
+ memcpy(dst->text, src->text, len);
+ dst->text[len] = '\0';
+ return 0;
+}
+
+void ptp_text_copy(struct PTPText *dst, const struct StaticPTPText *src)
+{
+ dst->length = src->length;
+ dst->text = (Octet *)src->text;
+}
+
+int ptp_text_set(struct PTPText *dst, const char *src)
+{
+ size_t len;
+ if (src) {
+ len = strnlen(src, MAX_PTP_OCTETS + 1);
+ if (len > MAX_PTP_OCTETS)
+ return -1;
+ dst->length = len;
+ dst->text = (Octet *)src;
+ } else {
+ dst->length = 0;
+ dst->text = NULL;
+ }
+ return 0;
+}
+
+int static_ptp_text_set(struct StaticPTPText *dst, const char *src)
+{
+ struct PTPText t;
+ size_t len = strnlen(src, MAX_PTP_OCTETS + 1);
+ if (len > MAX_PTP_OCTETS)
+ return -1;
+ t.length = len;
+ t.text = (Octet *)src;
+ return static_ptp_text_copy(dst, &t);
+}
diff --git a/util.h b/util.h
index d538cce..1b6b65a 100644
--- a/util.h
+++ b/util.h
@@ -56,4 +56,42 @@ char *pid2str(struct PortIdentity *id);

int generate_clock_identity(struct ClockIdentity *ci, char *name);

+/**
+ * Copies a PTPText to a StaticPTPText. This copies the text into the
+ * StaticPTPText.o
+ * @param dst The StaticPTPText to copy to
+ * @param src The PTPText to copy from
+ * @return Zero on success, -1 if text in src is too long or not valid
+ * UTF8
+ */
+int static_ptp_text_copy(struct StaticPTPText *dst, const struct PTPText *src);
+
+/**
+ * Copies a StaticPTPText to a PTPText. This makes the PTPText point
+ * to the memory inside the StaticPTPText.
+ * @param dst The PTPText to copy to
+ * @param src The StaticPTPText to copy from
+ */
+void ptp_text_copy(struct PTPText *dst, const struct StaticPTPText *src);
+
+/**
+ * Sets a PTPText from a null-terminated char*. After returning, the
+ * PTPText field points to the same memory as str, so str should not
+ * be modified and should remain valid as long as the PTPText can be
+ * used.
+ * @param dst The PTPText to copy to
+ * @param src The text to copy from
+ * @return Zero on success, -1 if src is too long
+ */
+int ptp_text_set(struct PTPText *dst, const char *src);
+
+/**
+ * Sets a StaticPTPText from a null-terminated char*.
+ * @param dst The StaticPTPText to copy to
+ * @param src The text to copy from
+ * @return Zero on success, -1 if text in src is too long or not valid
+ * UTF8
+ */
+int static_ptp_text_set(struct StaticPTPText *dst, const char *src);
+
#endif
--
1.7.9.5
Geoff Salmon
2013-01-30 14:33:47 UTC
Permalink
Adds struct containing clock description info that will be needed for
USER_DESCRIPTION and CLOCK_DESCRIPTION management messages.
---
clock.c | 9 ++++++++-
clock.h | 9 ++++++++-
config.h | 2 ++
ds.h | 8 ++++++++
ptp4l.c | 9 ++++++++-
5 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/clock.c b/clock.c
index b0a4de6..042c826 100644
--- a/clock.c
+++ b/clock.c
@@ -80,6 +80,7 @@ struct clock {
tmv_t c2;
tmv_t t1;
tmv_t t2;
+ struct clock_description desc;
};

struct clock the_clock;
@@ -412,7 +413,7 @@ UInteger8 clock_class(struct clock *c)

struct clock *clock_create(int phc_index, struct interface *iface, int count,
enum timestamp_type timestamping, struct default_ds *dds,
- enum servo_type servo)
+ enum servo_type servo, struct clock_description *desc)
{
int i, fadj = 0, max_adj = 0.0, sw_ts = timestamping == TS_SOFTWARE ? 1 : 0;
struct clock *c = &the_clock;
@@ -428,6 +429,7 @@ struct clock *clock_create(int phc_index, struct interface *iface, int count,
if (c->nports)
clock_destroy(c);

+ c->desc = *desc;
c->free_running = dds->free_running;
c->freq_est_interval = dds->freq_est_interval;

@@ -951,3 +953,8 @@ static void handle_state_decision_event(struct clock *c)
port_dispatch(c->port[i], event, fresh_best);
}
}
+
+struct clock_description *clock_description(struct clock *c)
+{
+ return &c->desc;
+}
diff --git a/clock.h b/clock.h
index e815a49..95b5440 100644
--- a/clock.h
+++ b/clock.h
@@ -71,7 +71,7 @@ UInteger8 clock_class(struct clock *c);
*/
struct clock *clock_create(int phc_index, struct interface *iface, int count,
enum timestamp_type timestamping, struct default_ds *dds,
- enum servo_type servo);
+ enum servo_type servo, struct clock_description *desc);

/**
* Obtains a clock's default data set.
@@ -215,4 +215,11 @@ void clock_sync_interval(struct clock *c, int n);
*/
struct timePropertiesDS *clock_time_properties(struct clock *c);

+/**
+ * Obtain a clock's description.
+ * @param c The clock instance.
+ * @return A pointer to the clock_description of the clock.
+ */
+struct clock_description *clock_description(struct clock *c);
+
#endif
diff --git a/config.h b/config.h
index 497d683..764c571 100644
--- a/config.h
+++ b/config.h
@@ -76,6 +76,8 @@ struct config {
int print_level;
int use_syslog;
int verbose;
+
+ struct clock_description clock_desc;
};

int config_read(char *name, struct config *cfg);
diff --git a/ds.h b/ds.h
index 514679b..53dd296 100644
--- a/ds.h
+++ b/ds.h
@@ -114,4 +114,12 @@ struct port_defaults {
int freq_est_interval; /*log seconds*/
};

+#define OUI_LEN 3
+struct clock_description {
+ struct StaticPTPText productDescription;
+ struct StaticPTPText revisionData;
+ struct StaticPTPText userDescription;
+ Octet manufacturer_id[OUI_LEN];
+};
+
#endif
diff --git a/ptp4l.c b/ptp4l.c
index 4fc0c88..6499262 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -88,6 +88,13 @@ static struct config cfg_settings = {
.verbose = 0,

.cfg_ignore = 0,
+
+ .clock_desc = {
+ .productDescription = { .max_symbols = 64 },
+ .revisionData = { .max_symbols = 32 },
+ .userDescription = { .max_symbols = 128 },
+ .manufacturer_id = { 0, 0, 0 }
+ }
};

static void handle_int_quit_term(int s)
@@ -337,7 +344,7 @@ int main(int argc, char *argv[])

clock = clock_create(phc_index, iface, cfg_settings.nports,
*timestamping, &cfg_settings.dds,
- cfg_settings.clock_servo);
+ cfg_settings.clock_servo, &cfg_settings.clock_desc);
if (!clock) {
fprintf(stderr, "failed to create a clock\n");
return -1;
--
1.7.9.5
Geoff Salmon
2013-01-30 14:33:48 UTC
Permalink
---
config.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)

diff --git a/config.c b/config.c
index a4a6261..d9a9bf8 100644
--- a/config.c
+++ b/config.c
@@ -22,6 +22,7 @@
#include "config.h"
#include "ether.h"
#include "print.h"
+#include "util.h"

enum config_section {
GLOBAL_SECTION,
@@ -148,6 +149,17 @@ static enum parser_result parse_port_setting(const char *option,
return PARSED_OK;
}

+static int count_char(const char *str, char c)
+{
+ int num = 0;
+ char s;
+ while ((s = *(str++))) {
+ if (s == c)
+ num++;
+ }
+ return num;
+}
+
static enum parser_result parse_global_setting(const char *option,
const char *value,
struct config *cfg)
@@ -157,6 +169,7 @@ static enum parser_result parse_global_setting(const char *option,
UInteger16 u16;
UInteger8 u8;
unsigned char mac[MAC_LEN];
+ unsigned char oui[OUI_LEN];

struct defaultDS *dds = &cfg->dds.dds;
struct port_defaults *pod = &cfg->pod;
@@ -333,6 +346,29 @@ static enum parser_result parse_global_setting(const char *option,
else
return BAD_VALUE;

+ } else if (!strcmp(option, "product_description")) {
+ if (count_char(value, ';') != 2)
+ return BAD_VALUE;
+ if (static_ptp_text_set(&cfg->clock_desc.productDescription, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "revision_data")) {
+ if (count_char(value, ';') != 2)
+ return BAD_VALUE;
+ if (static_ptp_text_set(&cfg->clock_desc.revisionData, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "user_description")) {
+ if (static_ptp_text_set(&cfg->clock_desc.userDescription, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "manufacturer_id")) {
+ if (OUI_LEN != sscanf(value, "%hhx:%hhx:%hhx",
+ &oui[0], &oui[1], &oui[2]))
+ return BAD_VALUE;
+ for (i = 0; i < OUI_LEN; i++)
+ cfg->clock_desc.manufacturer_id[i] = oui[i];
+
} else
return NOT_PARSED;
--
1.7.9.5
Miroslav Lichvar
2013-01-30 14:53:23 UTC
Permalink
clock.c | 15 +++++++++------
config.c | 5 +++++
ds.h | 1 +
ptp4l.c | 1 +
4 files changed, 16 insertions(+), 6 deletions(-)
config.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
Delio, Geoff,

when adding new config options, please add also a description to the
ptp4l man page and also a setting to the default value to default.cfg,
so they are always complete.

Thanks,
--
Miroslav Lichvar
Delio Brignoli
2013-01-30 15:16:17 UTC
Permalink
Post by Miroslav Lichvar
clock.c | 15 +++++++++------
config.c | 5 +++++
ds.h | 1 +
ptp4l.c | 1 +
4 files changed, 16 insertions(+), 6 deletions(-)
config.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
Delio, Geoff,
when adding new config options, please add also a description to the
ptp4l man page and also a setting to the default value to default.cfg,
so they are always complete.
ack. Will send in V2

Thanks
--
Delio
Geoff Salmon
2013-01-30 16:07:00 UTC
Permalink
StaticPTPText is like a PTPText that includes space for the text which
makes it more convenient for ptp texts stored in the clock.
---
ddt.h | 16 ++++++++++++++++
util.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
util.h | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 112 insertions(+)

diff --git a/ddt.h b/ddt.h
index f142f8e..5b35f32 100644
--- a/ddt.h
+++ b/ddt.h
@@ -71,6 +71,22 @@ struct PTPText {
Octet *text;
};

+/* A StaticPTPText is like a PTPText but includes space to store the
+ * text inside the struct. The text array must always be
+ * null-terminated. Also tracks a maximum number of symbols. Note in
+ * UTF-8, # symbols != # bytes.
+ */
+#define MAX_PTP_OCTETS 255
+struct StaticPTPText {
+ /* null-terminated array of UTF-8 symbols */
+ Octet text[MAX_PTP_OCTETS + 1];
+ /* number of used bytes in text, not including trailing
+ * null */
+ int length;
+ /* max number of UTF-8 symbols that can be in text */
+ int max_symbols;
+};
+
struct FaultRecord {
UInteger16 faultRecordLength;
struct Timestamp faultTime;
diff --git a/util.c b/util.c
index 4f432a6..06fe71c 100644
--- a/util.c
+++ b/util.c
@@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
+#include <string.h>

#include "sk.h"
#include "util.h"
@@ -90,3 +91,60 @@ int generate_clock_identity(struct ClockIdentity *ci, char *name)
ci->id[7] = mac[5];
return 0;
}
+
+/* Naive count of utf8 symbols. Doesn't detect invalid UTF-8 and
+ * probably doesn't count combining characters correctly. */
+static size_t strlen_utf8(const Octet *s)
+{
+ size_t len = 0;
+ char c;
+ while ((c = *(s++))) {
+ if ((c & 0xC0) != 0x80)
+ len++;
+ }
+ return len;
+}
+
+int static_ptp_text_copy(struct StaticPTPText *dst, const struct PTPText *src)
+{
+ int len = src->length;
+ if (dst->max_symbols > 0 && strlen_utf8(src->text) > dst->max_symbols)
+ return -1;
+ dst->length = len;
+ memcpy(dst->text, src->text, len);
+ dst->text[len] = '\0';
+ return 0;
+}
+
+void ptp_text_copy(struct PTPText *dst, const struct StaticPTPText *src)
+{
+ dst->length = src->length;
+ dst->text = (Octet *)src->text;
+}
+
+int ptp_text_set(struct PTPText *dst, const char *src)
+{
+ size_t len;
+ if (src) {
+ len = strnlen(src, MAX_PTP_OCTETS + 1);
+ if (len > MAX_PTP_OCTETS)
+ return -1;
+ dst->length = len;
+ dst->text = (Octet *)src;
+ } else {
+ dst->length = 0;
+ dst->text = NULL;
+ }
+ return 0;
+}
+
+int static_ptp_text_set(struct StaticPTPText *dst, const char *src)
+{
+ struct PTPText t;
+ size_t len = strnlen(src, MAX_PTP_OCTETS + 1);
+ if (len > MAX_PTP_OCTETS)
+ return -1;
+ t.length = len;
+ t.text = (Octet *)src;
+ return static_ptp_text_copy(dst, &t);
+}
diff --git a/util.h b/util.h
index d538cce..1b6b65a 100644
--- a/util.h
+++ b/util.h
@@ -56,4 +56,42 @@ char *pid2str(struct PortIdentity *id);

int generate_clock_identity(struct ClockIdentity *ci, char *name);

+/**
+ * Copies a PTPText to a StaticPTPText. This copies the text into the
+ * StaticPTPText.o
+ * @param dst The StaticPTPText to copy to
+ * @param src The PTPText to copy from
+ * @return Zero on success, -1 if text in src is too long or not valid
+ * UTF8
+ */
+int static_ptp_text_copy(struct StaticPTPText *dst, const struct PTPText *src);
+
+/**
+ * Copies a StaticPTPText to a PTPText. This makes the PTPText point
+ * to the memory inside the StaticPTPText.
+ * @param dst The PTPText to copy to
+ * @param src The StaticPTPText to copy from
+ */
+void ptp_text_copy(struct PTPText *dst, const struct StaticPTPText *src);
+
+/**
+ * Sets a PTPText from a null-terminated char*. After returning, the
+ * PTPText field points to the same memory as str, so str should not
+ * be modified and should remain valid as long as the PTPText can be
+ * used.
+ * @param dst The PTPText to copy to
+ * @param src The text to copy from
+ * @return Zero on success, -1 if src is too long
+ */
+int ptp_text_set(struct PTPText *dst, const char *src);
+
+/**
+ * Sets a StaticPTPText from a null-terminated char*.
+ * @param dst The StaticPTPText to copy to
+ * @param src The text to copy from
+ * @return Zero on success, -1 if text in src is too long or not valid
+ * UTF8
+ */
+int static_ptp_text_set(struct StaticPTPText *dst, const char *src);
+
#endif
--
1.7.9.5
Richard Cochran
2013-02-03 18:19:43 UTC
Permalink
Post by Geoff Salmon
StaticPTPText is like a PTPText that includes space for the text which
makes it more convenient for ptp texts stored in the clock.
---
ddt.h | 16 ++++++++++++++++
util.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
util.h | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 112 insertions(+)
diff --git a/ddt.h b/ddt.h
index f142f8e..5b35f32 100644
--- a/ddt.h
+++ b/ddt.h
@@ -71,6 +71,22 @@ struct PTPText {
Octet *text;
};
+/* A StaticPTPText is like a PTPText but includes space to store the
+ * text inside the struct. The text array must always be
+ * null-terminated. Also tracks a maximum number of symbols. Note in
+ * UTF-8, # symbols != # bytes.
+ */
+#define MAX_PTP_OCTETS 255
+struct StaticPTPText {
+ /* null-terminated array of UTF-8 symbols */
+ Octet text[MAX_PTP_OCTETS + 1];
+ /* number of used bytes in text, not including trailing
+ * null */
+ int length;
+ /* max number of UTF-8 symbols that can be in text */
+ int max_symbols;
+};
+
struct FaultRecord {
UInteger16 faultRecordLength;
struct Timestamp faultTime;
diff --git a/util.c b/util.c
index 4f432a6..06fe71c 100644
--- a/util.c
+++ b/util.c
@@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
+#include <string.h>
#include "sk.h"
#include "util.h"
@@ -90,3 +91,60 @@ int generate_clock_identity(struct ClockIdentity *ci, char *name)
ci->id[7] = mac[5];
return 0;
}
+
+/* Naive count of utf8 symbols. Doesn't detect invalid UTF-8 and
+ * probably doesn't count combining characters correctly. */
+static size_t strlen_utf8(const Octet *s)
+{
+ size_t len = 0;
+ char c;
+ while ((c = *(s++))) {
+ if ((c & 0xC0) != 0x80)
+ len++;
+ }
+ return len;
+}
+
+int static_ptp_text_copy(struct StaticPTPText *dst, const struct PTPText *src)
+{
+ int len = src->length;
+ if (dst->max_symbols > 0 && strlen_utf8(src->text) > dst->max_symbols)
+ return -1;
+ dst->length = len;
+ memcpy(dst->text, src->text, len);
+ dst->text[len] = '\0';
+ return 0;
+}
+
+void ptp_text_copy(struct PTPText *dst, const struct StaticPTPText *src)
+{
+ dst->length = src->length;
+ dst->text = (Octet *)src->text;
+}
+
+int ptp_text_set(struct PTPText *dst, const char *src)
+{
+ size_t len;
+ if (src) {
+ len = strnlen(src, MAX_PTP_OCTETS + 1);
All of my no-x86 cross compilers give a warning here:

linuxptp/util.c: In function 'ptp_text_set':
linuxptp/util.c:129: warning: implicit declaration of function 'strnlen'

This function seems to be a GNU extension.

Thanks,
Richard
Richard Cochran
2013-02-03 18:47:47 UTC
Permalink
Post by Geoff Salmon
StaticPTPText is like a PTPText that includes space for the text which
makes it more convenient for ptp texts stored in the clock.
I have a couple of minor comments...
Post by Geoff Salmon
@@ -71,6 +71,22 @@ struct PTPText {
Octet *text;
};
+/* A StaticPTPText is like a PTPText but includes space to store the
+ * text inside the struct. The text array must always be
+ * null-terminated. Also tracks a maximum number of symbols. Note in
+ * UTF-8, # symbols != # bytes.
+ */
+#define MAX_PTP_OCTETS 255
+struct StaticPTPText {
Since this is our own invention, better to shun CamelCase and use
something like "static_ptp_text".
Post by Geoff Salmon
+ /* null-terminated array of UTF-8 symbols */
+ Octet text[MAX_PTP_OCTETS + 1];
+ /* number of used bytes in text, not including trailing
+ * null */
Comment should fit all on one line.
Post by Geoff Salmon
+ int length;
+ /* max number of UTF-8 symbols that can be in text */
+ int max_symbols;
+};
Thanks,
Richard
Geoff Salmon
2013-01-30 16:07:01 UTC
Permalink
Adds struct containing clock description info that will be needed for
USER_DESCRIPTION and CLOCK_DESCRIPTION management messages.
---
clock.c | 9 ++++++++-
clock.h | 9 ++++++++-
config.h | 2 ++
ds.h | 8 ++++++++
ptp4l.c | 9 ++++++++-
5 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/clock.c b/clock.c
index b0a4de6..042c826 100644
--- a/clock.c
+++ b/clock.c
@@ -80,6 +80,7 @@ struct clock {
tmv_t c2;
tmv_t t1;
tmv_t t2;
+ struct clock_description desc;
};

struct clock the_clock;
@@ -412,7 +413,7 @@ UInteger8 clock_class(struct clock *c)

struct clock *clock_create(int phc_index, struct interface *iface, int count,
enum timestamp_type timestamping, struct default_ds *dds,
- enum servo_type servo)
+ enum servo_type servo, struct clock_description *desc)
{
int i, fadj = 0, max_adj = 0.0, sw_ts = timestamping == TS_SOFTWARE ? 1 : 0;
struct clock *c = &the_clock;
@@ -428,6 +429,7 @@ struct clock *clock_create(int phc_index, struct interface *iface, int count,
if (c->nports)
clock_destroy(c);

+ c->desc = *desc;
c->free_running = dds->free_running;
c->freq_est_interval = dds->freq_est_interval;

@@ -951,3 +953,8 @@ static void handle_state_decision_event(struct clock *c)
port_dispatch(c->port[i], event, fresh_best);
}
}
+
+struct clock_description *clock_description(struct clock *c)
+{
+ return &c->desc;
+}
diff --git a/clock.h b/clock.h
index e815a49..95b5440 100644
--- a/clock.h
+++ b/clock.h
@@ -71,7 +71,7 @@ UInteger8 clock_class(struct clock *c);
*/
struct clock *clock_create(int phc_index, struct interface *iface, int count,
enum timestamp_type timestamping, struct default_ds *dds,
- enum servo_type servo);
+ enum servo_type servo, struct clock_description *desc);

/**
* Obtains a clock's default data set.
@@ -215,4 +215,11 @@ void clock_sync_interval(struct clock *c, int n);
*/
struct timePropertiesDS *clock_time_properties(struct clock *c);

+/**
+ * Obtain a clock's description.
+ * @param c The clock instance.
+ * @return A pointer to the clock_description of the clock.
+ */
+struct clock_description *clock_description(struct clock *c);
+
#endif
diff --git a/config.h b/config.h
index 497d683..764c571 100644
--- a/config.h
+++ b/config.h
@@ -76,6 +76,8 @@ struct config {
int print_level;
int use_syslog;
int verbose;
+
+ struct clock_description clock_desc;
};

int config_read(char *name, struct config *cfg);
diff --git a/ds.h b/ds.h
index 514679b..fb0a984 100644
--- a/ds.h
+++ b/ds.h
@@ -114,4 +114,12 @@ struct port_defaults {
int freq_est_interval; /*log seconds*/
};

+#define OUI_LEN 3
+struct clock_description {
+ struct StaticPTPText productDescription;
+ struct StaticPTPText revisionData;
+ struct StaticPTPText userDescription;
+ Octet manufacturerId[OUI_LEN];
+};
+
#endif
diff --git a/ptp4l.c b/ptp4l.c
index 4fc0c88..c4e8791 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -88,6 +88,13 @@ static struct config cfg_settings = {
.verbose = 0,

.cfg_ignore = 0,
+
+ .clock_desc = {
+ .productDescription = { .max_symbols = 64 },
+ .revisionData = { .max_symbols = 32 },
+ .userDescription = { .max_symbols = 128 },
+ .manufacturerId = { 0, 0, 0 }
+ }
};

static void handle_int_quit_term(int s)
@@ -337,7 +344,7 @@ int main(int argc, char *argv[])

clock = clock_create(phc_index, iface, cfg_settings.nports,
*timestamping, &cfg_settings.dds,
- cfg_settings.clock_servo);
+ cfg_settings.clock_servo, &cfg_settings.clock_desc);
if (!clock) {
fprintf(stderr, "failed to create a clock\n");
return -1;
--
1.7.9.5
Richard Cochran
2013-02-03 18:50:42 UTC
Permalink
Post by Geoff Salmon
Adds struct containing clock description info that will be needed for
USER_DESCRIPTION and CLOCK_DESCRIPTION management messages.
---
clock.c | 9 ++++++++-
clock.h | 9 ++++++++-
config.h | 2 ++
ds.h | 8 ++++++++
ptp4l.c | 9 ++++++++-
5 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/clock.c b/clock.c
index b0a4de6..042c826 100644
--- a/clock.c
+++ b/clock.c
@@ -80,6 +80,7 @@ struct clock {
tmv_t c2;
tmv_t t1;
tmv_t t2;
+ struct clock_description desc;
Add this into 'stuct default_ds', and then ...
Post by Geoff Salmon
};
struct clock the_clock;
@@ -412,7 +413,7 @@ UInteger8 clock_class(struct clock *c)
struct clock *clock_create(int phc_index, struct interface *iface, int count,
enum timestamp_type timestamping, struct default_ds *dds,
- enum servo_type servo)
+ enum servo_type servo, struct clock_description *desc)
{
... there will be no need to change this signature.

Thanks,
Richard
Geoff Salmon
2013-01-30 16:07:02 UTC
Permalink
---
config.c | 36 ++++++++++++++++++++++++++++++++++++
default.cfg | 6 ++++++
ptp4l.8 | 20 ++++++++++++++++++++
ptp4l.c | 5 +++--
4 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/config.c b/config.c
index a4a6261..1dc23ae 100644
--- a/config.c
+++ b/config.c
@@ -22,6 +22,7 @@
#include "config.h"
#include "ether.h"
#include "print.h"
+#include "util.h"

enum config_section {
GLOBAL_SECTION,
@@ -148,6 +149,17 @@ static enum parser_result parse_port_setting(const char *option,
return PARSED_OK;
}

+static int count_char(const char *str, char c)
+{
+ int num = 0;
+ char s;
+ while ((s = *(str++))) {
+ if (s == c)
+ num++;
+ }
+ return num;
+}
+
static enum parser_result parse_global_setting(const char *option,
const char *value,
struct config *cfg)
@@ -157,6 +169,7 @@ static enum parser_result parse_global_setting(const char *option,
UInteger16 u16;
UInteger8 u8;
unsigned char mac[MAC_LEN];
+ unsigned char oui[OUI_LEN];

struct defaultDS *dds = &cfg->dds.dds;
struct port_defaults *pod = &cfg->pod;
@@ -333,6 +346,29 @@ static enum parser_result parse_global_setting(const char *option,
else
return BAD_VALUE;

+ } else if (!strcmp(option, "product_description")) {
+ if (count_char(value, ';') != 2)
+ return BAD_VALUE;
+ if (static_ptp_text_set(&cfg->clock_desc.productDescription, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "revision_data")) {
+ if (count_char(value, ';') != 2)
+ return BAD_VALUE;
+ if (static_ptp_text_set(&cfg->clock_desc.revisionData, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "user_description")) {
+ if (static_ptp_text_set(&cfg->clock_desc.userDescription, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "manufacturer_id")) {
+ if (OUI_LEN != sscanf(value, "%hhx:%hhx:%hhx",
+ &oui[0], &oui[1], &oui[2]))
+ return BAD_VALUE;
+ for (i = 0; i < OUI_LEN; i++)
+ cfg->clock_desc.manufacturerId[i] = oui[i];
+
} else
return NOT_PARSED;

diff --git a/default.cfg b/default.cfg
index ee2700d..873f8fc 100644
--- a/default.cfg
+++ b/default.cfg
@@ -51,3 +51,9 @@ udp6_scope 0x0E
network_transport UDPv4
delay_mechanism E2E
time_stamping hardware
+#
+# Clock description
+#
+product_description ;;
+revision_data ;;
+manufacturer_id 00:00:00
diff --git a/ptp4l.8 b/ptp4l.8
index fadf854..662f462 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -303,6 +303,26 @@ The default is 1 (enabled).
.B time_stamping
The time stamping method. The allowed values are hardware, software and legacy.
The default is hardware.
+.TP
+.B product_description
+The product description string. Allowed values must be of the form
+manufacturerName;modelNumber;instanceIdentifier and contain at most 64
+utf8 symbols. The default is ";;".
+.TP
+.B revision_data
+The revision description string which contains the revisions for node
+hardware (HW), firmware (FW), and software (SW). Allowed values are of
+the form HW;FW;SW and contain at most 32 utf8 symbols. The default is
+an ";;".
+.TP
+.B user_description
+The user description string. Allowed values are of the form
+name;location and contain at most 128 utf8 symbols. The default is an
+empty string.
+.TP
+.B manufacturer_id
+The manufacturer id which should be an OUI owned by the manufacturer.
+The default is 00:00:00.

.SH SEE ALSO
.BR pmc (8),
diff --git a/ptp4l.c b/ptp4l.c
index c4e8791..9391d1f 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -90,8 +90,8 @@ static struct config cfg_settings = {
.cfg_ignore = 0,

.clock_desc = {
- .productDescription = { .max_symbols = 64 },
- .revisionData = { .max_symbols = 32 },
+ .productDescription = { .max_symbols = 64, .text = ";;" },
+ .revisionData = { .max_symbols = 32, .text = ";;" },
.userDescription = { .max_symbols = 128 },
.manufacturerId = { 0, 0, 0 }
}
@@ -248,6 +248,7 @@ int main(int argc, char *argv[])
if (config && (c = config_read(config, &cfg_settings))) {
return c;
}
+
if (ds->flags & DDS_SLAVE_ONLY) {
ds->clockQuality.clockClass = 255;
}
--
1.7.9.5
Richard Cochran
2013-02-03 18:58:29 UTC
Permalink
Post by Geoff Salmon
@@ -333,6 +346,29 @@ static enum parser_result parse_global_setting(const char *option,
else
return BAD_VALUE;
+ } else if (!strcmp(option, "product_description")) {
I think it better to retain the (admittedly distasteful) lowerCamelCase here,
like "productDescription", and so on.
Post by Geoff Salmon
+ if (count_char(value, ';') != 2)
+ return BAD_VALUE;
+ if (static_ptp_text_set(&cfg->clock_desc.productDescription, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "revision_data")) {
+ if (count_char(value, ';') != 2)
+ return BAD_VALUE;
+ if (static_ptp_text_set(&cfg->clock_desc.revisionData, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "user_description")) {
+ if (static_ptp_text_set(&cfg->clock_desc.userDescription, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "manufacturer_id")) {
Maybe use "manufacturerIdentity" here ...
Post by Geoff Salmon
+ if (OUI_LEN != sscanf(value, "%hhx:%hhx:%hhx",
+ &oui[0], &oui[1], &oui[2]))
+ return BAD_VALUE;
+ for (i = 0; i < OUI_LEN; i++)
+ cfg->clock_desc.manufacturerId[i] = oui[i];
+
} else
return NOT_PARSED;
diff --git a/ptp4l.c b/ptp4l.c
index c4e8791..9391d1f 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -90,8 +90,8 @@ static struct config cfg_settings = {
.cfg_ignore = 0,
.clock_desc = {
- .productDescription = { .max_symbols = 64 },
- .revisionData = { .max_symbols = 32 },
+ .productDescription = { .max_symbols = 64, .text = ";;" },
+ .revisionData = { .max_symbols = 32, .text = ";;" },
.userDescription = { .max_symbols = 128 },
.manufacturerId = { 0, 0, 0 }
... and here.

Thanks,
Richard
Geoff Salmon
2013-01-30 16:06:59 UTC
Permalink
v2 adds config options to default.cfg and ptp4l.8

This patch set adds a clock_description struct to the clock which
holds some of the data needed for the CLOCK_DESCRIPTION management
message. There's also a patch for configuring the description.

You'll see the first patch adds a StaticPTPText struct that includes
storage space for the string. This avoids any dynamic memory
allocation and simplifies setting the string value. There will only
ever be a handful of StaticPTPStructs, so the wasted memory won't
exceed a couple kilobytes.

StaticPTPText's can also enforce symbol length restrictions and I've
added strlen_utf8 in util.c to determine the symbol length of utf8
strings. However, it won't detect invalid utf8 or account for
combining characters. Dealing with how to count combining characters
is a rabbit hole we probably don't want to go down, but detecting
invalid utf8 data may be a good idea in the future, especially when
the user description can be set remotely using a management message.

Geoff Salmon (3):
adds StaticPTPText and functions for setting PTPText and
StaticPTPText
adds clock description
config clock description

clock.c | 9 ++++++++-
clock.h | 9 ++++++++-
config.c | 36 ++++++++++++++++++++++++++++++++++++
config.h | 2 ++
ddt.h | 16 ++++++++++++++++
default.cfg | 6 ++++++
ds.h | 8 ++++++++
ptp4l.8 | 20 ++++++++++++++++++++
ptp4l.c | 10 +++++++++-
util.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
util.h | 38 ++++++++++++++++++++++++++++++++++++++
11 files changed, 209 insertions(+), 3 deletions(-)
--
1.7.9.5
Richard Cochran
2013-02-03 18:14:44 UTC
Permalink
Post by Geoff Salmon
v2 adds config options to default.cfg and ptp4l.8
Just getting around to these patches, and I notice that your SOB is
missing on all three.

Thanks,
Richard
Geoff Salmon
2013-02-03 22:01:49 UTC
Permalink
This patch set adds a clock_description struct to the clock which
holds some of the data needed for the CLOCK_DESCRIPTION management
message. There's also a patch for configuring the description.

You'll see the first patch adds a static_ptp_text struct that includes
storage space for the string. This avoids any dynamic memory
allocation and simplifies setting the string value. There will only
ever be a handful of StaticPTPStructs, so the wasted memory won't
exceed a couple kilobytes.

static_ptp_text's can also enforce symbol length restrictions and I've
added strlen_utf8 in util.c to determine the symbol length of utf8
strings. However, it won't detect invalid utf8 or account for
combining characters. Dealing with how to count combining characters
is a rabbit hole we probably don't want to go down, but detecting
invalid utf8 data may be a good idea in the future, especially when
the user description can be set remotely using a management message.

Geoff Salmon (3):
adds static_ptp_text and functions for setting PTPText and
static_ptp_text
adds clock description
config clock description

clock.c | 7 +++++++
clock.h | 7 +++++++
config.c | 36 ++++++++++++++++++++++++++++++++++++
ddt.h | 15 +++++++++++++++
default.cfg | 6 ++++++
ds.h | 9 +++++++++
ptp4l.8 | 20 ++++++++++++++++++++
ptp4l.c | 12 ++++++++++++
util.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
util.h | 38 ++++++++++++++++++++++++++++++++++++++
10 files changed, 208 insertions(+)
--
1.8.1.2
Geoff Salmon
2013-02-03 22:01:50 UTC
Permalink
static_ptp_text is like a PTPText that includes space for the text
which makes it more convenient for ptp texts stored in the clock.

Signed-off-by: Geoff Salmon <***@se-instruments.com>
---
ddt.h | 15 +++++++++++++++
util.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
util.h | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 111 insertions(+)

diff --git a/ddt.h b/ddt.h
index f142f8e..760b443 100644
--- a/ddt.h
+++ b/ddt.h
@@ -71,6 +71,21 @@ struct PTPText {
Octet *text;
};

+/* A static_ptp_text is like a PTPText but includes space to store the
+ * text inside the struct. The text array must always be
+ * null-terminated. Also tracks a maximum number of symbols. Note in
+ * UTF-8, # symbols != # bytes.
+ */
+#define MAX_PTP_OCTETS 255
+struct static_ptp_text {
+ /* null-terminated array of UTF-8 symbols */
+ Octet text[MAX_PTP_OCTETS + 1];
+ /* number of used bytes in text, not including trailing null */
+ int length;
+ /* max number of UTF-8 symbols that can be in text */
+ int max_symbols;
+};
+
struct FaultRecord {
UInteger16 faultRecordLength;
struct Timestamp faultTime;
diff --git a/util.c b/util.c
index 4f432a6..cb8db61 100644
--- a/util.c
+++ b/util.c
@@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
+#include <string.h>

#include "sk.h"
#include "util.h"
@@ -90,3 +91,60 @@ int generate_clock_identity(struct ClockIdentity *ci, char *name)
ci->id[7] = mac[5];
return 0;
}
+
+/* Naive count of utf8 symbols. Doesn't detect invalid UTF-8 and
+ * probably doesn't count combining characters correctly. */
+static size_t strlen_utf8(const Octet *s)
+{
+ size_t len = 0;
+ char c;
+ while ((c = *(s++))) {
+ if ((c & 0xC0) != 0x80)
+ len++;
+ }
+ return len;
+}
+
+int static_ptp_text_copy(struct static_ptp_text *dst, const struct PTPText *src)
+{
+ int len = src->length;
+ if (dst->max_symbols > 0 && strlen_utf8(src->text) > dst->max_symbols)
+ return -1;
+ dst->length = len;
+ memcpy(dst->text, src->text, len);
+ dst->text[len] = '\0';
+ return 0;
+}
+
+void ptp_text_copy(struct PTPText *dst, const struct static_ptp_text *src)
+{
+ dst->length = src->length;
+ dst->text = (Octet *)src->text;
+}
+
+int ptp_text_set(struct PTPText *dst, const char *src)
+{
+ size_t len;
+ if (src) {
+ len = strlen(src);
+ if (len > MAX_PTP_OCTETS)
+ return -1;
+ dst->length = len;
+ dst->text = (Octet *)src;
+ } else {
+ dst->length = 0;
+ dst->text = NULL;
+ }
+ return 0;
+}
+
+int static_ptp_text_set(struct static_ptp_text *dst, const char *src)
+{
+ struct PTPText t;
+ size_t len = strlen(src);
+ if (len > MAX_PTP_OCTETS)
+ return -1;
+ t.length = len;
+ t.text = (Octet *)src;
+ return static_ptp_text_copy(dst, &t);
+}
diff --git a/util.h b/util.h
index d538cce..5fe9dda 100644
--- a/util.h
+++ b/util.h
@@ -56,4 +56,42 @@ char *pid2str(struct PortIdentity *id);

int generate_clock_identity(struct ClockIdentity *ci, char *name);

+/**
+ * Copies a PTPText to a static_ptp_text. This copies the text into
+ * the static_ptp_text.o
+ * @param dst The static_ptp_text to copy to
+ * @param src The PTPText to copy from
+ * @return Zero on success, -1 if text in src is too long or not valid
+ * UTF8
+ */
+int static_ptp_text_copy(struct static_ptp_text *dst, const struct PTPText *src);
+
+/**
+ * Copies a static_ptp_text to a PTPText. This makes the PTPText point
+ * to the memory inside the static_ptp_text.
+ * @param dst The PTPText to copy to
+ * @param src The static_ptp_text to copy from
+ */
+void ptp_text_copy(struct PTPText *dst, const struct static_ptp_text *src);
+
+/**
+ * Sets a PTPText from a null-terminated char*. After returning, the
+ * PTPText field points to the same memory as str, so str should not
+ * be modified and should remain valid as long as the PTPText can be
+ * used.
+ * @param dst The PTPText to copy to
+ * @param src The text to copy from
+ * @return Zero on success, -1 if src is too long
+ */
+int ptp_text_set(struct PTPText *dst, const char *src);
+
+/**
+ * Sets a static_ptp_text from a null-terminated char*.
+ * @param dst The static_ptp_text to copy to
+ * @param src The text to copy from
+ * @return Zero on success, -1 if text in src is too long or not valid
+ * UTF8
+ */
+int static_ptp_text_set(struct static_ptp_text *dst, const char *src);
+
#endif
--
1.8.1.2
Geoff Salmon
2013-02-03 22:01:51 UTC
Permalink
Adds struct containing clock description info that will be needed for
USER_DESCRIPTION and CLOCK_DESCRIPTION management messages.

Signed-off-by: Geoff Salmon <***@se-instruments.com>
---
clock.c | 7 +++++++
clock.h | 7 +++++++
ds.h | 9 +++++++++
ptp4l.c | 12 ++++++++++++
4 files changed, 35 insertions(+)

diff --git a/clock.c b/clock.c
index b0a4de6..f152b45 100644
--- a/clock.c
+++ b/clock.c
@@ -80,6 +80,7 @@ struct clock {
tmv_t c2;
tmv_t t1;
tmv_t t2;
+ struct clock_description desc;
};

struct clock the_clock;
@@ -430,6 +431,7 @@ struct clock *clock_create(int phc_index, struct interface *iface, int count,

c->free_running = dds->free_running;
c->freq_est_interval = dds->freq_est_interval;
+ c->desc = dds->clock_desc;

if (c->free_running) {
c->clkid = CLOCK_INVALID;
@@ -951,3 +953,8 @@ static void handle_state_decision_event(struct clock *c)
port_dispatch(c->port[i], event, fresh_best);
}
}
+
+struct clock_description *clock_description(struct clock *c)
+{
+ return &c->desc;
+}
diff --git a/clock.h b/clock.h
index e815a49..581fa14 100644
--- a/clock.h
+++ b/clock.h
@@ -215,4 +215,11 @@ void clock_sync_interval(struct clock *c, int n);
*/
struct timePropertiesDS *clock_time_properties(struct clock *c);

+/**
+ * Obtain a clock's description.
+ * @param c The clock instance.
+ * @return A pointer to the clock_description of the clock.
+ */
+struct clock_description *clock_description(struct clock *c);
+
#endif
diff --git a/ds.h b/ds.h
index 514679b..ff0e2ee 100644
--- a/ds.h
+++ b/ds.h
@@ -39,10 +39,19 @@ struct defaultDS {
UInteger8 reserved2;
} PACKED;

+#define OUI_LEN 3
+struct clock_description {
+ struct static_ptp_text productDescription;
+ struct static_ptp_text revisionData;
+ struct static_ptp_text userDescription;
+ Octet manufacturerIdentity[OUI_LEN];
+};
+
struct default_ds {
struct defaultDS dds;
int free_running;
int freq_est_interval; /*log seconds*/
+ struct clock_description clock_desc;
};

struct dataset {
diff --git a/ptp4l.c b/ptp4l.c
index 4fc0c88..3e64159 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -52,6 +52,18 @@ static struct config cfg_settings = {
},
.free_running = 0,
.freq_est_interval = 1,
+ .clock_desc = {
+ .productDescription = {
+ .max_symbols = 64,
+ .text = ";;"
+ },
+ .revisionData = {
+ .max_symbols = 32,
+ .text = ";;"
+ },
+ .userDescription = { .max_symbols = 128 },
+ .manufacturerIdentity = { 0, 0, 0 },
+ },
},

.pod = {
--
1.8.1.2
Geoff Salmon
2013-02-03 22:01:52 UTC
Permalink
Signed-off-by: Geoff Salmon <***@se-instruments.com>
---
config.c | 36 ++++++++++++++++++++++++++++++++++++
default.cfg | 6 ++++++
ptp4l.8 | 20 ++++++++++++++++++++
3 files changed, 62 insertions(+)

diff --git a/config.c b/config.c
index a4a6261..c05127a 100644
--- a/config.c
+++ b/config.c
@@ -22,6 +22,7 @@
#include "config.h"
#include "ether.h"
#include "print.h"
+#include "util.h"

enum config_section {
GLOBAL_SECTION,
@@ -148,6 +149,17 @@ static enum parser_result parse_port_setting(const char *option,
return PARSED_OK;
}

+static int count_char(const char *str, char c)
+{
+ int num = 0;
+ char s;
+ while ((s = *(str++))) {
+ if (s == c)
+ num++;
+ }
+ return num;
+}
+
static enum parser_result parse_global_setting(const char *option,
const char *value,
struct config *cfg)
@@ -157,6 +169,7 @@ static enum parser_result parse_global_setting(const char *option,
UInteger16 u16;
UInteger8 u8;
unsigned char mac[MAC_LEN];
+ unsigned char oui[OUI_LEN];

struct defaultDS *dds = &cfg->dds.dds;
struct port_defaults *pod = &cfg->pod;
@@ -333,6 +346,29 @@ static enum parser_result parse_global_setting(const char *option,
else
return BAD_VALUE;

+ } else if (!strcmp(option, "productDescription")) {
+ if (count_char(value, ';') != 2)
+ return BAD_VALUE;
+ if (static_ptp_text_set(&cfg->dds.clock_desc.productDescription, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "revisionData")) {
+ if (count_char(value, ';') != 2)
+ return BAD_VALUE;
+ if (static_ptp_text_set(&cfg->dds.clock_desc.revisionData, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "userDescription")) {
+ if (static_ptp_text_set(&cfg->dds.clock_desc.userDescription, value) != 0)
+ return BAD_VALUE;
+
+ } else if (!strcmp(option, "manufacturerIdentity")) {
+ if (OUI_LEN != sscanf(value, "%hhx:%hhx:%hhx",
+ &oui[0], &oui[1], &oui[2]))
+ return BAD_VALUE;
+ for (i = 0; i < OUI_LEN; i++)
+ cfg->dds.clock_desc.manufacturerIdentity[i] = oui[i];
+
} else
return NOT_PARSED;

diff --git a/default.cfg b/default.cfg
index ee2700d..876c1ab 100644
--- a/default.cfg
+++ b/default.cfg
@@ -51,3 +51,9 @@ udp6_scope 0x0E
network_transport UDPv4
delay_mechanism E2E
time_stamping hardware
+#
+# Clock description
+#
+productDescription ;;
+revisionData ;;
+manufacturerIdentity 00:00:00
diff --git a/ptp4l.8 b/ptp4l.8
index fadf854..aea0196 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -303,6 +303,26 @@ The default is 1 (enabled).
.B time_stamping
The time stamping method. The allowed values are hardware, software and legacy.
The default is hardware.
+.TP
+.B productDescription
+The product description string. Allowed values must be of the form
+manufacturerName;modelNumber;instanceIdentifier and contain at most 64
+utf8 symbols. The default is ";;".
+.TP
+.B revisionData
+The revision description string which contains the revisions for node
+hardware (HW), firmware (FW), and software (SW). Allowed values are of
+the form HW;FW;SW and contain at most 32 utf8 symbols. The default is
+an ";;".
+.TP
+.B userDescription
+The user description string. Allowed values are of the form
+name;location and contain at most 128 utf8 symbols. The default is an
+empty string.
+.TP
+.B manufacturerIdentity
+The manufacturer id which should be an OUI owned by the manufacturer.
+The default is 00:00:00.

.SH SEE ALSO
.BR pmc (8),
--
1.8.1.2
Richard Cochran
2013-02-04 11:19:34 UTC
Permalink
Post by Geoff Salmon
You'll see the first patch adds a static_ptp_text struct that includes
storage space for the string. This avoids any dynamic memory
allocation and simplifies setting the string value. There will only
ever be a handful of StaticPTPStructs, so the wasted memory won't
exceed a couple kilobytes.
Geoff,

I like what you have done here with the static memory scheme. I went
ahead and applied this series.

Thanks,
Richard

Loading...