Commit ca2f8041 authored by Aurelio Colosimo's avatar Aurelio Colosimo

all states implemented, with many TODO still to be fixed

With this patch, the whole ptp protocol state machine has been analyzed
and mostly included in the ptp-wr project.
parent db50f075
......@@ -159,6 +159,7 @@ struct pp_instance {
*/
MsgHeader msg_tmp_header;
MsgHeader pdelay_req_hdr;
MsgHeader delay_req_hdr;
UInteger32
is_from_self:1,
is_from_cur_par:1,
......
......@@ -67,65 +67,68 @@ int st_com_check_record_update(struct pp_instance *ppi)
return 0;
}
void st_com_add_foreign(unsigned char *buf, MsgHeader *hdr,
struct pp_instance *ppi)
void st_com_add_foreign(unsigned char *buf, struct pp_instance *ppi)
{
/*TODO "translate" it into ptp-wr structs*/
#ifdef _FROM_PTPD_2_1_0_
int i,j;
int i, j;
Boolean found = FALSE;
MsgHeader *hdr = &ppi->msg_tmp_header;
j = ptpClock->foreign_record_best;
j = ppi->foreign_record_best;
/*Check if Foreign master is already known*/
for (i=0;i<ptpClock->number_foreign_records;i++) {
if (!memcmp(header->sourcePortIdentity.clockIdentity,
ptpClock->foreign[j].foreignMasterPortIdentity.clockIdentity,
CLOCK_IDENTITY_LENGTH) &&
(header->sourcePortIdentity.portNumber ==
ptpClock->foreign[j].foreignMasterPortIdentity.portNumber))
/* Check if foreign master is already known */
for (i = 0; i < ppi->number_foreign_records; i++) {
if (!pp_memcmp(hdr->sourcePortIdentity.clockIdentity,
ppi->frgn_master[j].port_identity.
clockIdentity,
PP_CLOCK_IDENTITY_LENGTH) &&
(hdr->sourcePortIdentity.portNumber ==
ppi->frgn_master[j].port_identity.portNumber))
{
/*Foreign Master is already in Foreignmaster data set*/
ptpClock->foreign[j].foreignMasterAnnounceMessages++;
/* Foreign Master is already in Foreign master data set
*/
ppi->frgn_master[j].ann_messages++;
found = TRUE;
/* FIXME diag
DBGV("addForeign : AnnounceMessage incremented \n");
msgUnpackHeader(buf,&ptpClock->foreign[j].header);
msgUnpackAnnounce(buf,&ptpClock->foreign[j].announce);
*/
msg_copy_header(&ppi->frgn_master[j].hdr, hdr);
msg_unpack_announce(buf, &ppi->frgn_master[j].ann);
break;
}
j = (j+1)%ptpClock->number_foreign_records;
j = (j + 1) % ppi->number_foreign_records;
}
/*New Foreign Master*/
/* New foreign master */
if (!found) {
if (ptpClock->number_foreign_records <
ptpClock->max_foreign_records) {
ptpClock->number_foreign_records++;
if (ppi->number_foreign_records <
ppi->max_foreign_records) {
ppi->number_foreign_records++;
}
j = ptpClock->foreign_record_i;
/*Copy new foreign master data set from Announce message*/
memcpy(ptpClock->foreign[j].foreignMasterPortIdentity.clockIdentity,
header->sourcePortIdentity.clockIdentity,
CLOCK_IDENTITY_LENGTH);
ptpClock->foreign[j].foreignMasterPortIdentity.portNumber =
header->sourcePortIdentity.portNumber;
ptpClock->foreign[j].foreignMasterAnnounceMessages = 0;
j = ppi->foreign_record_i;
/* Copy new foreign master data set from announce message */
pp_memcpy(ppi->frgn_master[j].port_identity.clockIdentity,
hdr->sourcePortIdentity.clockIdentity,
PP_CLOCK_IDENTITY_LENGTH);
ppi->frgn_master[j].port_identity.portNumber =
hdr->sourcePortIdentity.portNumber;
ppi->frgn_master[j].ann_messages = 0;
/*
* header and announce field of each Foreign Master are
* usefull to run Best Master Clock Algorithm
*/
msgUnpackHeader(buf,&ptpClock->foreign[j].header);
msgUnpackAnnounce(buf,&ptpClock->foreign[j].announce);
DBGV("New foreign Master added \n");
msg_copy_header(&ppi->frgn_master[j].hdr, hdr);
msg_unpack_announce(buf, &ppi->frgn_master[j].ann);
/* FIXME diag DBGV("New foreign Master added \n");*/
ptpClock->foreign_record_i =
(ptpClock->foreign_record_i+1) %
ptpClock->max_foreign_records;
ppi->foreign_record_i = (ppi->foreign_record_i+1) %
ppi->max_foreign_records;
}
#endif /* _FROM_PTPD_2_1_0_ */
}
......@@ -152,7 +155,7 @@ int st_com_slave_handle_announce(unsigned char *buf, int len,
}
else {
/* st_com_add_foreign takes care of announce unpacking */
st_com_add_foreign(buf, hdr, ppi);
st_com_add_foreign(buf, ppi);
}
/*Reset Timer handling Announce receipt timeout*/
......@@ -298,10 +301,48 @@ int st_com_handle_pdelay_req(unsigned char *buf, int len,
} else {
msg_copy_header(&ppi->pdelay_req_hdr,hdr);
/* TODO
issuePDelayResp(time, header, rtOpts,
/* TODO issuePDelayResp(time, header, rtOpts,
ptpClock);
*/
}
return 0;
}
int st_com_master_handle_announce(unsigned char *buf, int len,
struct pp_instance *ppi)
{
if (len < PP_ANNOUNCE_LENGTH)
return -1;
if (ppi->is_from_self) {
/* FIXME diag
DBGV("HandleAnnounce : Ignore message from self \n");
*/
return 0;
}
/* FIXME diag
* DBGV("Announce message from another foreign master");
*/
st_com_add_foreign(buf, ppi);
ppi->record_update = TRUE;
return 0;
}
int st_com_master_handle_sync(unsigned char *buf, int len, TimeInternal *time,
struct pp_instance *ppi)
{
if (len < PP_SYNC_LENGTH)
return -1;
if (!ppi->is_from_self)
return 0;
/* Add latency */
add_TimeInternal(time,time,&ppi->rt_opts->outbound_latency);
/* TODO issueFollowup(time,rtOpts,ptpClock);*/
return 0;
}
......@@ -12,15 +12,23 @@ void st_com_restart_annrec_timer(struct pp_instance *ppi);
int st_com_check_record_update(struct pp_instance *ppi);
/*
void st_com_add_foreign(unsigned char *buf, MsgHeader *header,
struct pp_instance *ppi);
*/
int st_com_slave_handle_announce(unsigned char *buf, int len,
struct pp_instance *ppi);
int st_com_master_handle_announce(unsigned char *buf, int len,
struct pp_instance *ppi);
int st_com_slave_handle_sync(unsigned char *buf, int len, TimeInternal *time,
struct pp_instance *ppi);
int st_com_master_handle_sync(unsigned char *buf, int len, TimeInternal *time,
struct pp_instance *ppi);
int st_com_slave_handle_followup(unsigned char *buf, int len,
struct pp_instance *ppi);
......
......@@ -6,9 +6,10 @@
int pp_listening(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
if (ppi->is_new_state) {
int e = 0;
if (ppi->is_new_state)
st_com_restart_annrec_timer(ppi);
}
if (st_com_check_record_update(ppi))
goto state_updated;
......@@ -16,26 +17,7 @@ int pp_listening(struct pp_instance *ppi, unsigned char *pkt, int plen)
switch (ppi->msg_tmp_header.messageType) {
case PPM_ANNOUNCE:
if (plen < PP_ANNOUNCE_LENGTH) {
ppi->next_state = PPS_FAULTY;
goto state_updated;
}
if (ppi->is_from_self) {
/* FIXME diag
DBGV("HandleAnnounce : Ignore message from self \n");
*/
goto state_done;
}
/* FIXME diag
* DBGV("Announce message from another foreign master");
*/
st_com_add_foreign(pkt, &ppi->msg_tmp_header, ppi);
ppi->record_update = TRUE;
e = st_com_master_handle_announce(pkt, plen, ppi);
break;
default:
......@@ -43,15 +25,16 @@ int pp_listening(struct pp_instance *ppi, unsigned char *pkt, int plen)
break;
}
if (e == 0)
st_com_execute_slave(ppi);
else
ppi->next_state = PPS_FAULTY;
state_updated:
/* Leaving this state */
if (ppi->next_state != ppi->state) {
if (ppi->next_state != ppi->state)
pp_timer_stop(ppi->timers[PP_TIMER_ANNOUNCE_RECEIPT]);
}
state_done:
ppi->next_delay = PP_DEFAULT_NEXT_DELAY_MS;
return 0;
......
......@@ -2,9 +2,205 @@
* FIXME: header
*/
#include <pproto/pproto.h>
#include <dep/dep.h>
#include "state-common-fun.h"
int pp_master(struct pp_instance *ppi, unsigned char *newpkt, int plen)
int pp_master(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
/* TODO */
TimeInternal time; /* TODO: handle it, see handle(...) in protocol.c */
TimeInternal req_rec_tstamp;
TimeInternal correction_field;
TimeInternal resp_orig_tstamp;
int e = 0;
MsgHeader *hdr = &ppi->msg_tmp_header;
if (ppi->is_new_state) {
pp_timer_start(1 << DSPOR(ppi)->logSyncInterval,
ppi->timers[PP_TIMER_SYNC_INTERVAL]);
pp_timer_start(1 << DSPOR(ppi)->logAnnounceInterval,
ppi->timers[PP_TIMER_ANNOUNCE_INTERVAL]);
pp_timer_start(1 << DSPOR(ppi)->logMinPdelayReqInterval,
ppi->timers[PP_TIMER_PDELAYREQ_INTERVAL]);
}
if (st_com_check_record_update(ppi))
goto state_updated;
if (pp_timer_expired(ppi->timers[PP_TIMER_SYNC_INTERVAL])) {
/* FIXME diag
* DBGV("event SYNC_INTERVAL_TIMEOUT_EXPIRES\n");
*/
/* TODO issueSync(rtOpts, ptpClock); */
}
if (pp_timer_expired(ppi->timers[PP_TIMER_ANNOUNCE_INTERVAL])) {
/* FIXME diag
* DBGV("event ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES\n");
*/
/* TODO issueAnnounce(rtOpts, ptpClock); */
}
if (!ppi->rt_opts->e2e_mode) {
if (pp_timer_expired(ppi->timers[PP_TIMER_PDELAYREQ_INTERVAL]))
{
/* FIXME diag
* DBGV("event PDELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n");
*/
/* TODO issuePDelayReq(rtOpts,ptpClock); */
}
}
switch (ppi->msg_tmp_header.messageType) {
case PPM_ANNOUNCE:
e = st_com_master_handle_announce(pkt, plen, ppi);
break;
case PPM_SYNC:
e = st_com_master_handle_sync(pkt, plen, &time, ppi);
break;
case PPM_DELAY_REQ:
msg_copy_header(&ppi->delay_req_hdr, hdr);
/*TODO issueDelayResp(time,&ptpClock->delayReqHeader,rtOpts,ptpClock);
*/
break;
case PPM_PDELAY_REQ:
e = st_com_handle_pdelay_req(pkt, plen, &time, ppi);
break;
case PPM_PDELAY_RESP:
/* Loopback Timestamp */
if (ppi->rt_opts->e2e_mode)
break;
if (ppi->is_from_self) {
/*Add latency*/
add_TimeInternal(&time, &time,
&ppi->rt_opts->outbound_latency);
/* TODO issuePDelayRespFollowUp(
time,
&ptpClock->PdelayReqHeader,
rtOpts, ptpClock);
*/
break;
}
msg_unpack_pdelay_resp(pkt, &ppi->msg_tmp.presp);
if (!((ppi->sent_seq_id[PPM_PDELAY_REQ] ==
hdr->sequenceId)
&& (!pp_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] & 0x02) ==
PP_TWO_STEP_FLAG) {
/* 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);
/* TODO servo
updatePeerDelay(&ptpClock->owd_filt,
rtOpts,ptpClock,
&correctionField,FALSE);
*/
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);
/* TODO servo
updatePeerDelay(&ptpClock->owd_filt,
rtOpts, ptpClock,
&correctionField,TRUE);
*/
break;
}
break;
default:
/* disreguard, nothing to do */
break;
}
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_INTERVAL]);
pp_timer_stop(ppi->timers[PP_TIMER_ANNOUNCE_INTERVAL]);
pp_timer_stop(ppi->timers[PP_TIMER_PDELAYREQ_INTERVAL]);
}
ppi->next_delay = PP_DEFAULT_NEXT_DELAY_MS;
return 0;
}
......@@ -20,6 +20,11 @@ int pp_passive(struct pp_instance *ppi, unsigned char *pkt, int plen)
goto state_updated;
switch (ppi->msg_tmp_header.messageType) {
case PPM_ANNOUNCE:
e = st_com_master_handle_announce(pkt, plen, ppi);
break;
case PPM_PDELAY_REQ:
e = st_com_handle_pdelay_req(pkt, plen, &time, ppi);
break;
......
......@@ -5,6 +5,9 @@
int pp_pre_master(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
/* TODO */
/*
* No need of PRE_MASTER state because of only ordinary clock
* implementation.
*/
return 0;
}
......@@ -140,8 +140,7 @@ int pp_slave(struct pp_instance *ppi, unsigned char *pkt, int plen)
if (ppi->is_from_self) {
add_TimeInternal(&time, &time,
&ppi->rt_opts->outbound_latency);
/* TODO
issuePDelayRespFollowUp(time,
/* TODO issuePDelayRespFollowUp(time,
&ptpClock->PdelayReqHeader,
rtOpts,ptpClock);
*/
......
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