Commit 6d9c1b56 authored by Alessandro Rubini's avatar Alessandro Rubini

state-master: merge extension into std, using hooks

Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 571e1b1d
......@@ -295,6 +295,8 @@ enum pp_std_messages {
PPM_ANNOUNCE,
PPM_SIGNALING,
PPM_MANAGEMENT,
PPM_NOTHING_TO_DO = 0x100, /* for hooks.master_msg() */
};
extern const char const * pp_msg_names[];
......
......@@ -311,6 +311,8 @@ struct pp_ext_hooks {
int (*open)(struct pp_instance *ppi, struct pp_runtime_opts *rt_opts);
int (*close)(struct pp_instance *ppi);
int (*listening)(struct pp_instance *ppi, unsigned char *pkt, int plen);
int (*master_msg)(struct pp_instance *ppi, unsigned char *pkt,
int plen, int msgtype);
};
extern struct pp_ext_hooks pp_hooks; /* The one for the extension we build */
......
......@@ -7,7 +7,6 @@ LIBWRO := $D/libwr.o
LIBS += $(LIBWRO)
OBJ-libwr := $D/fsm-table.o \
$D/state-master.o \
$D/state-slave.o \
$D/common-fun.o \
$D/bmc.o \
......
......@@ -35,8 +35,43 @@ static int wr_listening(struct pp_instance *ppi, unsigned char *pkt, int plen)
return 0;
}
static int wr_master_msg(struct pp_instance *ppi, unsigned char *pkt, int plen,
int msgtype)
{
MsgHeader *hdr = &ppi->msg_tmp_header;
MsgSignaling wrsig_msg;
TimeInternal *time = &ppi->last_rcv_time;
;
switch(msgtype) {
/* This case is modified from the default one */
case PPM_DELAY_REQ:
msg_copy_header(&ppi->delay_req_hdr, hdr);
ppi->delay_req_hdr.correctionfield.msb = 0;
ppi->delay_req_hdr.correctionfield.lsb =
phase_to_cf_units(ppi->last_rcv_time.phase);
msg_issue_delay_resp(ppi, time);
msgtype = PPM_NOTHING_TO_DO;
break;
/* This is missing in the standard protocol */
case PPM_SIGNALING:
msg_unpack_wrsig(ppi, pkt, &wrsig_msg,
&(WR_DSPOR(ppi)->msgTmpWrMessageID));
if ((WR_DSPOR(ppi)->msgTmpWrMessageID == SLAVE_PRESENT) &&
(WR_DSPOR(ppi)->wrConfig & WR_M_ONLY))
ppi->next_state = WRS_M_LOCK;
msgtype = PPM_NOTHING_TO_DO;
break;
}
return msgtype;
}
struct pp_ext_hooks pp_hooks = {
.init = wr_init,
.open = wr_open,
.listening = wr_listening,
.master_msg = wr_master_msg,
};
/*
* Aurelio Colosimo for CERN, 2011 -- GNU LGPL v2.1 or later
* Based on PTPd project v. 2.1.0 (see AUTHORS for details)
*/
#include <ppsi/ppsi.h>
#include <ppsi/diag.h>
#include "common-fun.h"
#include "wr-constants.h"
#include "wr-api.h"
int pp_master(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
TimeInternal *time;
TimeInternal *time_snt;
TimeInternal req_rec_tstamp;
TimeInternal correction_field;
TimeInternal resp_orig_tstamp;
int e = 0; /* error var, to check errors in msg handling */
MsgHeader *hdr = &ppi->msg_tmp_header;
time = &ppi->last_rcv_time;
if (ppi->is_new_state) {
DSPOR(ppi)->portState = PPS_MASTER;
pp_timer_start((1 << DSPOR(ppi)->logSyncInterval) * 1000,
ppi->timers[PP_TIMER_SYNC]);
pp_timer_start((1 << DSPOR(ppi)->logAnnounceInterval) * 1000,
ppi->timers[PP_TIMER_ANN_INTERVAL]);
pp_timer_start(
(1 << DSPOR(ppi)->logMinPdelayReqInterval) * 1000,
ppi->timers[PP_TIMER_PDELAYREQ]);
/* Send an announce immediately, when becomes master */
if (msg_issue_announce(ppi) < 0)
goto failure;
}
if (st_com_check_record_update(ppi))
goto state_updated;
if (pp_timer_expired(ppi->timers[PP_TIMER_SYNC])) {
PP_VPRINTF("event SYNC_INTERVAL_TIMEOUT_EXPIRES\n");
if (msg_issue_sync(ppi) < 0)
goto failure;
time_snt = &ppi->last_snt_time;
add_TimeInternal(time_snt, time_snt, &OPTS(ppi)->outbound_latency);
if (msg_issue_followup(ppi, time_snt))
goto failure;
}
if (pp_timer_expired(ppi->timers[PP_TIMER_ANN_INTERVAL])) {
PP_VPRINTF("event ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES\n");
if (msg_issue_announce(ppi) < 0)
goto failure;
}
if (!OPTS(ppi)->e2e_mode) {
if (pp_timer_expired(ppi->timers[PP_TIMER_PDELAYREQ])) {
PP_VPRINTF("event PDELAYREQ_INTERVAL_TOUT_EXPIRES\n");
if (msg_issue_pdelay_req(ppi) < 0)
goto failure;
}
}
if (plen == 0)
goto no_incoming_msg;
switch (ppi->msg_tmp_header.messageType) {
case PPM_ANNOUNCE:
e = st_com_master_handle_announce(ppi, pkt, plen);
break;
case PPM_SYNC:
e = st_com_master_handle_sync(ppi, pkt, plen);
break;
case PPM_DELAY_REQ:
msg_copy_header(&ppi->delay_req_hdr, hdr);
ppi->delay_req_hdr.correctionfield.msb = 0;
ppi->delay_req_hdr.correctionfield.lsb =
phase_to_cf_units(ppi->last_rcv_time.phase);
msg_issue_delay_resp(ppi, time);
break;
case PPM_PDELAY_REQ:
e = st_com_handle_pdelay_req(ppi, pkt, plen);
break;
case PPM_PDELAY_RESP:
/* Loopback Timestamp */
if (OPTS(ppi)->e2e_mode)
break;
if (ppi->is_from_self) {
/*Add latency*/
add_TimeInternal(time, time,
&OPTS(ppi)->outbound_latency);
e = msg_issue_pdelay_resp_follow_up(ppi, time);
break;
}
msg_unpack_pdelay_resp(pkt, &ppi->msg_tmp.presp);
if (!((ppi->sent_seq_id[PPM_PDELAY_REQ] ==
hdr->sequenceId)
&& (!memcmp(DSPOR(ppi)->portIdentity.clockIdentity,
ppi->msg_tmp.presp.requestingPortIdentity.
clockIdentity,
PP_CLOCK_IDENTITY_LENGTH))
&& (DSPOR(ppi)->portIdentity.portNumber ==
ppi->msg_tmp.presp.requestingPortIdentity.portNumber))
) {
if ((hdr->flagField[0] & PP_TWO_STEP_FLAG) != 0) {
/* Two Step Clock */
/* Store t4 (Fig 35) */
ppi->pdelay_resp_receive_time.seconds =
time->seconds;
ppi->pdelay_resp_receive_time.nanoseconds =
time->nanoseconds;
/* Store t2 (Fig 35) */
to_TimeInternal(&req_rec_tstamp,
&ppi->msg_tmp.presp.
requestReceiptTimestamp);
ppi->pdelay_req_receive_time.seconds =
req_rec_tstamp.seconds;
ppi->pdelay_req_receive_time.nanoseconds =
req_rec_tstamp.nanoseconds;
int64_to_TimeInternal(
hdr->correctionfield,
&correction_field);
ppi->last_pdelay_resp_corr_field.seconds =
correction_field.seconds;
ppi->last_pdelay_resp_corr_field.nanoseconds =
correction_field.nanoseconds;
break;
} else {
/* One step Clock */
/* Store t4 (Fig 35)*/
ppi->pdelay_resp_receive_time.seconds =
time->seconds;
ppi->pdelay_resp_receive_time.nanoseconds =
time->nanoseconds;
int64_to_TimeInternal(
hdr->correctionfield,
&correction_field);
pp_update_peer_delay(ppi, &correction_field, 0);
break;
}
}
break; /* XXX added by gnn for safety */
case PPM_PDELAY_RESP_FOLLOW_UP:
if (hdr->sequenceId == ppi->sent_seq_id[PPM_PDELAY_REQ] - 1) {
msg_unpack_pdelay_resp_followup(pkt,
&ppi->msg_tmp.prespfollow);
to_TimeInternal(&resp_orig_tstamp,
&ppi->msg_tmp.prespfollow.
responseOriginTimestamp);
ppi->pdelay_resp_send_time.seconds =
resp_orig_tstamp.seconds;
ppi->pdelay_resp_send_time.nanoseconds =
resp_orig_tstamp.nanoseconds;
int64_to_TimeInternal(
ppi->msg_tmp_header.correctionfield,
&correction_field);
add_TimeInternal(&correction_field,
&correction_field,
&ppi->last_pdelay_resp_corr_field);
pp_update_peer_delay(ppi, &correction_field, 1);
break;
}
break;
case PPM_SIGNALING:
{
MsgSignaling wrsig_msg;
msg_unpack_wrsig(ppi, pkt, &wrsig_msg,
&(WR_DSPOR(ppi)->msgTmpWrMessageID));
if ((WR_DSPOR(ppi)->msgTmpWrMessageID == SLAVE_PRESENT) &&
(WR_DSPOR(ppi)->wrConfig & WR_M_ONLY))
ppi->next_state = WRS_M_LOCK;
break;
}
default:
/* disreguard, nothing to do */
break;
}
no_incoming_msg:
failure:
if (e == 0) {
if (DSDEF(ppi)->slaveOnly ||
DSDEF(ppi)->clockQuality.clockClass == 255)
ppi->next_state = PPS_LISTENING;
} else {
ppi->next_state = PPS_FAULTY;
}
state_updated:
/* Leaving this state */
if (ppi->next_state != ppi->state) {
pp_timer_stop(ppi->timers[PP_TIMER_SYNC]);
pp_timer_stop(ppi->timers[PP_TIMER_ANN_INTERVAL]);
pp_timer_stop(ppi->timers[PP_TIMER_PDELAYREQ]);
}
ppi->next_delay = PP_DEFAULT_NEXT_DELAY_MS;
return 0;
}
......@@ -14,7 +14,7 @@ int pp_master(struct pp_instance *ppi, unsigned char *pkt, int plen)
TimeInternal req_rec_tstamp;
TimeInternal correction_field;
TimeInternal resp_orig_tstamp;
int msgtype;
int e = 0; /* error var, to check errors in msg handling */
MsgHeader *hdr = &ppi->msg_tmp_header;
......@@ -67,7 +67,23 @@ int pp_master(struct pp_instance *ppi, unsigned char *pkt, int plen)
if (plen == 0)
goto no_incoming_msg;
switch (ppi->msg_tmp_header.messageType) {
/*
* An extension can do special treatment of this message type,
* possibly returning error or eating the message by returning
* PPM_NOTHING_TO_DO
*/
msgtype = ppi->msg_tmp_header.messageType;
if (pp_hooks.master_msg)
msgtype = pp_hooks.master_msg(ppi, pkt, plen, msgtype);
if (msgtype < 0) {
e = msgtype;
goto failure;
}
switch (msgtype) {
case PPM_NOTHING_TO_DO:
break;
case PPM_ANNOUNCE:
e = st_com_master_handle_announce(ppi, pkt, plen);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment