Skip to content

Commit

Permalink
Implement the ALTERNATE_TIME_OFFSET_ENABLE management message.
Browse files Browse the repository at this point in the history
If the local PTP management client enables a time zone, append the
matching TLV to outgoing Announce messages.

Signed-off-by: Richard Cochran <[email protected]>
  • Loading branch information
richardcochran committed Feb 25, 2023
1 parent d1b65c7 commit f70a3d6
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 3 deletions.
80 changes: 78 additions & 2 deletions clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,43 @@ static int clock_resize_pollfd(struct clock *c, int new_nports);
static void clock_remove_port(struct clock *c, struct port *p);
static void clock_stats_display(struct clock_stats *s);

static int clock_alttime_offset_append(struct clock *c, int key, struct ptp_message *m)
{
struct alternate_time_offset_indicator_tlv *atoi;
struct tlv_extra *extra;
int tlv_len;

tlv_len = sizeof(*atoi) + c->tz[key].display_name.length;
if (tlv_len % 2) {
tlv_len++;
}
extra = msg_tlv_append(m, tlv_len);
if (!extra) {
return -1;
}
atoi = (struct alternate_time_offset_indicator_tlv *) extra->tlv;
atoi->type = TLV_ALTERNATE_TIME_OFFSET_INDICATOR;
atoi->length = tlv_len - sizeof(atoi->type) - sizeof(atoi->length);
atoi->keyField = key;

/* Message alignment broken by design. */
memcpy(&atoi->currentOffset, &c->tz[key].current_offset,
sizeof(atoi->currentOffset));

memcpy(&atoi->jumpSeconds, &c->tz[key].jump_seconds,
sizeof(atoi->jumpSeconds));

memcpy(&atoi->timeOfNextJump.seconds_lsb, &c->tz[key].next_jump_lsb,
sizeof(atoi->timeOfNextJump.seconds_lsb));

memcpy(&atoi->timeOfNextJump.seconds_msb, &c->tz[key].next_jump_msb,
sizeof(atoi->timeOfNextJump.seconds_msb));

ptp_text_copy(&atoi->displayName, &c->tz[key].display_name);

return 0;
}

uint8_t clock_alttime_offset_get_key(struct ptp_message *req)
{
struct management_tlv_datum *mtd;
Expand Down Expand Up @@ -462,6 +499,16 @@ static int clock_management_fill_response(struct clock *c, struct port *p,
mtd->val = c->tds.flags & PTP_TIMESCALE;
datalen = sizeof(*mtd);
break;
case MID_ALTERNATE_TIME_OFFSET_ENABLE:
key = clock_alttime_offset_get_key(req);
if (key >= MAX_TIME_ZONES) {
break;
}
mtd = (struct management_tlv_datum *) tlv->data;
mtd->val = key;
mtd->reserved = c->tz[key].enabled ? 1 : 0;
datalen = sizeof(*mtd);
break;
case MID_ALTERNATE_TIME_OFFSET_NAME:
key = clock_alttime_offset_get_key(req);
if (key >= MAX_TIME_ZONES) {
Expand Down Expand Up @@ -574,7 +621,7 @@ static int clock_management_set(struct clock *c, struct port *p,
struct management_tlv_datum *mtd;
struct subscribe_events_np *sen;
struct management_tlv *tlv;
int key, respond = 0;
int k, key, respond = 0;

tlv = (struct management_tlv *) req->management.suffix;

Expand All @@ -591,6 +638,20 @@ static int clock_management_set(struct clock *c, struct port *p,
*changed = 1;
respond = 1;
break;
case MID_ALTERNATE_TIME_OFFSET_ENABLE:
mtd = (struct management_tlv_datum *) tlv->data;
key = mtd->val;
if (key == 0xff) {
for (k = 0; k < MAX_TIME_ZONES; k++) {
c->tz[k].enabled = mtd->reserved & 1 ? true : false;
}
respond = 1;
}
if (key < MAX_TIME_ZONES) {
c->tz[key].enabled = mtd->reserved & 1 ? true : false;
respond = 1;
}
break;
case MID_ALTERNATE_TIME_OFFSET_NAME:
aton = (struct alternate_time_offset_name *) tlv->data;
key = aton->keyField;
Expand Down Expand Up @@ -896,6 +957,22 @@ static int forwarding(struct clock *c, struct port *p)

/* public methods */

int clock_append_timezones(struct clock *c, struct ptp_message *m)
{
int err = 0, i;

for (i = 0; i < MAX_TIME_ZONES; i++) {
if (!c->tz[i].enabled) {
continue;
}
err = clock_alttime_offset_append(c, i, m);
if (err) {
break;
}
}
return err;
}

UInteger8 clock_class(struct clock *c)
{
return c->dds.clockQuality.clockClass;
Expand Down Expand Up @@ -1613,7 +1690,6 @@ int clock_manage(struct clock *c, struct port *p, struct ptp_message *msg)
case MID_GRANDMASTER_CLUSTER_TABLE:
case MID_ACCEPTABLE_MASTER_TABLE:
case MID_ACCEPTABLE_MASTER_MAX_TABLE_SIZE:
case MID_ALTERNATE_TIME_OFFSET_ENABLE:
case MID_ALTERNATE_TIME_OFFSET_MAX_KEY:
case MID_TRANSPARENT_CLOCK_DEFAULT_DATA_SET:
case MID_PRIMARY_DOMAIN:
Expand Down
8 changes: 8 additions & 0 deletions clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ enum clock_type {
CLOCK_TYPE_MANAGEMENT = 0x0800,
};

/**
* Appends the active time zone TLVs to a given message.
* @param c The clock instance.
* @param m The message that will receive the TLVs.
* @return Zero on success, non-zero otherwise.
*/
int clock_append_timezones(struct clock *c, struct ptp_message *m);

/**
* Obtains a reference to the best foreign master of a clock.
* @param c The clock instance.
Expand Down
8 changes: 8 additions & 0 deletions pmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,14 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
fprintf(fp, "TIMESCALE_PROPERTIES "
IFMT "ptpTimescale %d", mtd->val & PTP_TIMESCALE ? 1 : 0);
break;
case MID_ALTERNATE_TIME_OFFSET_ENABLE:
mtd = (struct management_tlv_datum *) mgt->data;
fprintf(fp, "ALTERNATE_TIME_OFFSET_ENABLE "
IFMT "keyField %hhu"
IFMT "enable %d",
mtd->val,
mtd->reserved & 1 ? 1 : 0);
break;
case MID_ALTERNATE_TIME_OFFSET_NAME:
aton = (struct alternate_time_offset_name *) mgt->data;
fprintf(fp, "ALTERNATE_TIME_OFFSET_NAME "
Expand Down
17 changes: 16 additions & 1 deletion pmc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ struct management_id idtab[] = {
{ "GRANDMASTER_CLUSTER_TABLE", MID_GRANDMASTER_CLUSTER_TABLE, not_supported },
{ "ACCEPTABLE_MASTER_TABLE", MID_ACCEPTABLE_MASTER_TABLE, not_supported },
{ "ACCEPTABLE_MASTER_MAX_TABLE_SIZE", MID_ACCEPTABLE_MASTER_MAX_TABLE_SIZE, not_supported },
{ "ALTERNATE_TIME_OFFSET_ENABLE", MID_ALTERNATE_TIME_OFFSET_ENABLE, not_supported },
{ "ALTERNATE_TIME_OFFSET_ENABLE", MID_ALTERNATE_TIME_OFFSET_ENABLE, do_set_action },
{ "ALTERNATE_TIME_OFFSET_NAME", MID_ALTERNATE_TIME_OFFSET_NAME, do_set_action },
{ "ALTERNATE_TIME_OFFSET_MAX_KEY", MID_ALTERNATE_TIME_OFFSET_MAX_KEY, not_supported },
{ "ALTERNATE_TIME_OFFSET_PROPERTIES", MID_ALTERNATE_TIME_OFFSET_PROPERTIES, do_set_action },
Expand Down Expand Up @@ -182,6 +182,7 @@ static void do_set_action(struct pmc *pmc, int action, int index, char *str)
char display_name[11] = {0};
uint64_t jump;
uint8_t key;
int enable;

mtd.reserved = 0;

Expand Down Expand Up @@ -210,6 +211,17 @@ static void do_set_action(struct pmc *pmc, int action, int index, char *str)
}
pmc_send_set_action(pmc, code, &mtd, sizeof(mtd));
break;
case MID_ALTERNATE_TIME_OFFSET_ENABLE:
cnt = sscanf(str, " %*s %*s keyField %hhu enable %d",
&mtd.val, &enable);
if (cnt != 2) {
fprintf(stderr, "%s SET needs 2 values\n",
idtab[index].name);
break;
}
mtd.reserved = enable ? 1 : 0;
pmc_send_set_action(pmc, code, &mtd, sizeof(mtd));
break;
case MID_ALTERNATE_TIME_OFFSET_NAME:
cnt = sscanf(str, " %*s %*s "
"keyField %hhu "
Expand Down Expand Up @@ -613,6 +625,9 @@ static int pmc_tlv_datalen(struct pmc *pmc, int id)
case MID_TIME_STATUS_NP:
len += sizeof(struct time_status_np);
break;
case MID_ALTERNATE_TIME_OFFSET_ENABLE:
len += sizeof(struct management_tlv_datum);
break;
case MID_ALTERNATE_TIME_OFFSET_NAME:
len += sizeof(struct alternate_time_offset_name);
break;
Expand Down
3 changes: 3 additions & 0 deletions port.c
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,9 @@ int port_tx_announce(struct port *p, struct address *dst, uint16_t sequence_id)
if (ieee_c37_238_append(p, msg)) {
pr_err("%s: append power profile failed", p->log_name);
}
if (clock_append_timezones(p->clock, msg)) {
pr_err("%s: append time zones failed", p->log_name);
}

err = port_prepare_and_send(p, msg, TRANS_GENERAL);
if (err) {
Expand Down

0 comments on commit f70a3d6

Please sign in to comment.