Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
P
PPSi
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
50
Issues
50
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
PPSi
Commits
98a570ed
Commit
98a570ed
authored
Feb 27, 2013
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bmc: merge extension into std, using hooks
Signed-off-by:
Alessandro Rubini
<
rubini@gnudd.com
>
parent
656b8f01
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
17 additions
and
333 deletions
+17
-333
ppsi.h
include/ppsi/ppsi.h
+1
-0
Makefile
proto-ext-whiterabbit/Makefile
+0
-1
bmc.c
proto-ext-whiterabbit/bmc.c
+0
-332
hooks.c
proto-ext-whiterabbit/hooks.c
+13
-0
bmc.c
proto-standard/bmc.c
+3
-0
No files found.
include/ppsi/ppsi.h
View file @
98a570ed
...
...
@@ -315,6 +315,7 @@ struct pp_ext_hooks {
int
plen
,
int
msgtype
);
int
(
*
new_slave
)(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
plen
);
int
(
*
update_delay
)(
struct
pp_instance
*
ppi
);
void
(
*
s1
)(
struct
pp_instance
*
ppi
,
MsgHeader
*
hdr
,
MsgAnnounce
*
ann
);
};
extern
struct
pp_ext_hooks
pp_hooks
;
/* The one for the extension we build */
...
...
proto-ext-whiterabbit/Makefile
View file @
98a570ed
...
...
@@ -8,7 +8,6 @@ LIBS += $(LIBWRO)
OBJ-libwr
:=
$D
/fsm-table.o
\
$D
/common-fun.o
\
$D
/bmc.o
\
$D
/msg.o
\
$D
/hooks.o
\
$D
/state-wr-present.o
\
...
...
proto-ext-whiterabbit/bmc.c
deleted
100644 → 0
View file @
656b8f01
/*
* 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 "wr-api.h"
/* Flag Field bits symbolic names (table 57, pag. 151) */
#define FFB_LI61 0x01
#define FFB_LI59 0x02
#define FFB_UTCV 0x04
#define FFB_PTP 0x08
#define FFB_TTRA 0x10
#define FFB_FTRA 0x20
/* Local clock is becoming Master. Table 13 (9.3.5) of the spec. */
void
m1
(
struct
pp_instance
*
ppi
)
{
/* Current data set update */
DSCUR
(
ppi
)
->
stepsRemoved
=
0
;
DSCUR
(
ppi
)
->
offsetFromMaster
.
nanoseconds
=
0
;
DSCUR
(
ppi
)
->
offsetFromMaster
.
seconds
=
0
;
DSCUR
(
ppi
)
->
meanPathDelay
.
nanoseconds
=
0
;
DSCUR
(
ppi
)
->
meanPathDelay
.
seconds
=
0
;
/* Parent data set */
memcpy
(
DSPAR
(
ppi
)
->
parentPortIdentity
.
clockIdentity
,
DSDEF
(
ppi
)
->
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
);
DSPAR
(
ppi
)
->
parentPortIdentity
.
portNumber
=
0
;
DSPAR
(
ppi
)
->
parentStats
=
PP_DEFAULT_PARENTS_STATS
;
DSPAR
(
ppi
)
->
observedParentClockPhaseChangeRate
=
0
;
DSPAR
(
ppi
)
->
observedParentOffsetScaledLogVariance
=
0
;
memcpy
(
DSPAR
(
ppi
)
->
grandmasterIdentity
,
DSDEF
(
ppi
)
->
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
);
DSPAR
(
ppi
)
->
grandmasterClockQuality
.
clockAccuracy
=
DSDEF
(
ppi
)
->
clockQuality
.
clockAccuracy
;
DSPAR
(
ppi
)
->
grandmasterClockQuality
.
clockClass
=
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
;
DSPAR
(
ppi
)
->
grandmasterClockQuality
.
offsetScaledLogVariance
=
DSDEF
(
ppi
)
->
clockQuality
.
offsetScaledLogVariance
;
DSPAR
(
ppi
)
->
grandmasterPriority1
=
DSDEF
(
ppi
)
->
priority1
;
DSPAR
(
ppi
)
->
grandmasterPriority2
=
DSDEF
(
ppi
)
->
priority2
;
/* Time Properties data set */
DSPRO
(
ppi
)
->
timeSource
=
INTERNAL_OSCILLATOR
;
}
/* Local clock is synchronized to Ebest Table 16 (9.3.5) of the spec. */
void
s1
(
struct
pp_instance
*
ppi
,
MsgHeader
*
hdr
,
MsgAnnounce
*
ann
)
{
/* Current DS */
DSCUR
(
ppi
)
->
stepsRemoved
=
ann
->
stepsRemoved
+
1
;
/* Parent DS */
memcpy
(
DSPAR
(
ppi
)
->
parentPortIdentity
.
clockIdentity
,
hdr
->
sourcePortIdentity
.
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
);
DSPAR
(
ppi
)
->
parentPortIdentity
.
portNumber
=
hdr
->
sourcePortIdentity
.
portNumber
;
memcpy
(
DSPAR
(
ppi
)
->
grandmasterIdentity
,
ann
->
grandmasterIdentity
,
PP_CLOCK_IDENTITY_LENGTH
);
DSPAR
(
ppi
)
->
grandmasterClockQuality
.
clockAccuracy
=
ann
->
grandmasterClockQuality
.
clockAccuracy
;
DSPAR
(
ppi
)
->
grandmasterClockQuality
.
clockClass
=
ann
->
grandmasterClockQuality
.
clockClass
;
DSPAR
(
ppi
)
->
grandmasterClockQuality
.
offsetScaledLogVariance
=
ann
->
grandmasterClockQuality
.
offsetScaledLogVariance
;
DSPAR
(
ppi
)
->
grandmasterPriority1
=
ann
->
grandmasterPriority1
;
DSPAR
(
ppi
)
->
grandmasterPriority2
=
ann
->
grandmasterPriority2
;
/* Timeproperties DS */
DSPRO
(
ppi
)
->
currentUtcOffset
=
ann
->
currentUtcOffset
;
/* "Valid" is bit 2 in second octet of flagfield */
DSPRO
(
ppi
)
->
currentUtcOffsetValid
=
((
hdr
->
flagField
[
1
]
&
FFB_UTCV
)
!=
0
);
DSPRO
(
ppi
)
->
leap59
=
((
hdr
->
flagField
[
1
]
&
FFB_LI59
)
!=
0
);
DSPRO
(
ppi
)
->
leap61
=
((
hdr
->
flagField
[
1
]
&
FFB_LI61
)
!=
0
);
DSPRO
(
ppi
)
->
timeTraceable
=
((
hdr
->
flagField
[
1
]
&
FFB_TTRA
)
!=
0
);
DSPRO
(
ppi
)
->
frequencyTraceable
=
((
hdr
->
flagField
[
1
]
&
FFB_FTRA
)
!=
0
);
DSPRO
(
ppi
)
->
ptpTimescale
=
((
hdr
->
flagField
[
1
]
&
FFB_PTP
)
!=
0
);
DSPRO
(
ppi
)
->
timeSource
=
ann
->
timeSource
;
/* White Rabbit */
WR_DSPOR
(
ppi
)
->
parentIsWRnode
=
((
ann
->
wrFlags
&
WR_NODE_MODE
)
!=
NON_WR
);
WR_DSPOR
(
ppi
)
->
parentWrModeOn
=
(
ann
->
wrFlags
&
WR_IS_WR_MODE
)
?
TRUE
:
FALSE
;
WR_DSPOR
(
ppi
)
->
parentCalibrated
=
((
ann
->
wrFlags
&
WR_IS_CALIBRATED
)
?
1
:
0
);
WR_DSPOR
(
ppi
)
->
parentWrConfig
=
ann
->
wrFlags
&
WR_NODE_MODE
;
DSCUR
(
ppi
)
->
primarySlavePortNumber
=
DSPOR
(
ppi
)
->
portIdentity
.
portNumber
;
}
/* Copy local data set into header and ann message. 9.3.4 table 12. */
void
copy_d0
(
struct
pp_instance
*
ppi
,
MsgHeader
*
hdr
,
MsgAnnounce
*
ann
)
{
ann
->
grandmasterPriority1
=
DSDEF
(
ppi
)
->
priority1
;
memcpy
(
ann
->
grandmasterIdentity
,
DSDEF
(
ppi
)
->
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
);
ann
->
grandmasterClockQuality
.
clockClass
=
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
;
ann
->
grandmasterClockQuality
.
clockAccuracy
=
DSDEF
(
ppi
)
->
clockQuality
.
clockAccuracy
;
ann
->
grandmasterClockQuality
.
offsetScaledLogVariance
=
DSDEF
(
ppi
)
->
clockQuality
.
offsetScaledLogVariance
;
ann
->
grandmasterPriority2
=
DSDEF
(
ppi
)
->
priority2
;
ann
->
stepsRemoved
=
0
;
memcpy
(
hdr
->
sourcePortIdentity
.
clockIdentity
,
DSDEF
(
ppi
)
->
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
);
}
/*
* Data set comparison bewteen two foreign masters (9.3.4 fig 27)
* return similar to memcmp()
*/
Integer8
bmc_dataset_cmp
(
struct
pp_instance
*
ppi
,
MsgHeader
*
hdr_a
,
MsgAnnounce
*
ann_a
,
MsgHeader
*
hdr_b
,
MsgAnnounce
*
ann_b
)
{
short
comp
=
0
;
Octet
*
ppci
;
PP_VPRINTF
(
"BMC: in bmc_dataset_cmp
\n
"
);
/* Identity comparison */
if
(
!
memcmp
(
ann_a
->
grandmasterIdentity
,
ann_b
->
grandmasterIdentity
,
PP_CLOCK_IDENTITY_LENGTH
))
{
/* Algorithm part2 Fig 28 */
if
(
ann_a
->
stepsRemoved
>
ann_b
->
stepsRemoved
+
1
)
return
1
;
else
if
(
ann_b
->
stepsRemoved
>
ann_a
->
stepsRemoved
+
1
)
return
-
1
;
else
{
/* A within 1 of B */
ppci
=
DSPAR
(
ppi
)
->
parentPortIdentity
.
clockIdentity
;
if
(
ann_a
->
stepsRemoved
>
ann_b
->
stepsRemoved
)
{
if
(
!
memcmp
(
hdr_a
->
sourcePortIdentity
.
clockIdentity
,
ppci
,
PP_CLOCK_IDENTITY_LENGTH
))
{
PP_PRINTF
(
"Sender=Receiver: Error -1"
);
return
0
;
}
else
return
1
;
}
else
if
(
ann_b
->
stepsRemoved
>
ann_a
->
stepsRemoved
)
{
if
(
!
memcmp
(
hdr_b
->
sourcePortIdentity
.
clockIdentity
,
ppci
,
PP_CLOCK_IDENTITY_LENGTH
))
{
PP_PRINTF
(
"Sender=Receiver: Error -3"
);
return
0
;
}
else
{
return
-
1
;
}
}
else
{
/* steps removed A == steps removed B */
if
(
!
memcmp
(
hdr_a
->
sourcePortIdentity
.
clockIdentity
,
hdr_b
->
sourcePortIdentity
.
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
))
{
PP_PRINTF
(
"Sender=Receiver: Error -2"
);
return
0
;
}
else
if
((
memcmp
(
hdr_a
->
sourcePortIdentity
.
clockIdentity
,
hdr_b
->
sourcePortIdentity
.
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
))
<
0
)
return
-
1
;
else
return
1
;
}
}
}
else
{
/* GrandMaster are not identical */
/* FIXME: rewrite in a more readable way */
if
(
ann_a
->
grandmasterPriority1
==
ann_b
->
grandmasterPriority1
)
{
if
(
ann_a
->
grandmasterClockQuality
.
clockClass
==
ann_b
->
grandmasterClockQuality
.
clockClass
)
{
if
(
ann_a
->
grandmasterClockQuality
.
clockAccuracy
==
ann_b
->
grandmasterClockQuality
.
clockAccuracy
)
{
if
(
ann_a
->
grandmasterClockQuality
.
offsetScaledLogVariance
==
ann_b
->
grandmasterClockQuality
.
offsetScaledLogVariance
)
{
if
(
ann_a
->
grandmasterPriority2
==
ann_b
->
grandmasterPriority2
)
{
comp
=
memcmp
(
ann_a
->
grandmasterIdentity
,
ann_b
->
grandmasterIdentity
,
PP_CLOCK_IDENTITY_LENGTH
);
if
(
comp
<
0
)
return
-
1
;
else
if
(
comp
>
0
)
return
1
;
else
return
0
;
}
else
{
/* Priority2 are not identical */
comp
=
memcmp
(
&
ann_a
->
grandmasterPriority2
,
&
ann_b
->
grandmasterPriority2
,
1
);
if
(
comp
<
0
)
return
-
1
;
else
if
(
comp
>
0
)
return
1
;
else
return
0
;
}
}
else
{
/* offsetScaledLogVariance are not identical */
comp
=
memcmp
(
&
ann_a
->
grandmasterClockQuality
.
clockClass
,
&
ann_b
->
grandmasterClockQuality
.
clockClass
,
1
);
if
(
comp
<
0
)
return
-
1
;
else
if
(
comp
>
0
)
return
1
;
else
return
0
;
}
}
else
{
/* Accuracy are not identitcal */
comp
=
memcmp
(
&
ann_a
->
grandmasterClockQuality
.
clockAccuracy
,
&
ann_b
->
grandmasterClockQuality
.
clockAccuracy
,
1
);
if
(
comp
<
0
)
return
-
1
;
else
if
(
comp
>
0
)
return
1
;
else
return
0
;
}
}
else
{
/* ClockClass are not identical */
comp
=
memcmp
(
&
ann_a
->
grandmasterClockQuality
.
clockClass
,
&
ann_b
->
grandmasterClockQuality
.
clockClass
,
1
);
if
(
comp
<
0
)
return
-
1
;
else
if
(
comp
>
0
)
return
1
;
else
return
0
;
}
}
else
{
/* Priority1 are not identical */
comp
=
memcmp
(
&
ann_a
->
grandmasterPriority1
,
&
ann_b
->
grandmasterPriority1
,
1
);
if
(
comp
<
0
)
return
-
1
;
else
if
(
comp
>
0
)
return
1
;
else
return
0
;
}
}
}
/* State decision algorithm 9.3.3 Fig 26 */
UInteger8
bmc_state_decision
(
struct
pp_instance
*
ppi
,
MsgHeader
*
hdr
,
MsgAnnounce
*
ann
)
{
int
cmpres
;
if
(
OPTS
(
ppi
)
->
master_only
)
{
m1
(
ppi
);
return
PPS_MASTER
;
}
if
(
OPTS
(
ppi
)
->
slave_only
)
{
s1
(
ppi
,
hdr
,
ann
);
return
PPS_SLAVE
;
}
if
((
!
ppi
->
number_foreign_records
)
&&
(
ppi
->
state
==
PPS_LISTENING
))
return
PPS_LISTENING
;
copy_d0
(
ppi
,
&
ppi
->
msg_tmp_header
,
&
ppi
->
msg_tmp
.
announce
);
cmpres
=
bmc_dataset_cmp
(
ppi
,
&
ppi
->
msg_tmp_header
,
&
ppi
->
msg_tmp
.
announce
,
hdr
,
ann
);
if
(
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
<
128
)
{
if
(
cmpres
<
0
)
{
m1
(
ppi
);
return
PPS_MASTER
;
}
else
if
(
cmpres
>
0
)
{
s1
(
ppi
,
hdr
,
ann
);
return
PPS_PASSIVE
;
}
}
else
{
if
(
cmpres
<
0
)
{
m1
(
ppi
);
return
PPS_MASTER
;
}
else
if
(
cmpres
>
0
)
{
s1
(
ppi
,
hdr
,
ann
);
return
PPS_SLAVE
;
}
}
if
(
cmpres
==
0
)
{
PP_PRINTF
(
"Error in bmc_state_decision, cmpres=0.
\n
"
);
}
/* MB: Is this the return code below correct? */
/* Anyway, it's a valid return code. */
return
PPS_FAULTY
;
}
UInteger8
bmc
(
struct
pp_instance
*
ppi
,
struct
pp_frgn_master
*
frgn_master
)
{
Integer16
i
,
best
;
if
(
!
ppi
->
number_foreign_records
)
if
(
ppi
->
state
==
PPS_MASTER
)
{
m1
(
ppi
);
return
ppi
->
state
;
}
for
(
i
=
1
,
best
=
0
;
i
<
ppi
->
number_foreign_records
;
i
++
)
if
(
bmc_dataset_cmp
(
ppi
,
&
frgn_master
[
i
].
hdr
,
&
frgn_master
[
i
].
ann
,
&
frgn_master
[
best
].
hdr
,
&
frgn_master
[
best
].
ann
)
<
0
)
best
=
i
;
PP_VPRINTF
(
"bmc, best record : %d
\n
"
,
best
);
ppi
->
foreign_record_best
=
best
;
return
bmc_state_decision
(
ppi
,
&
frgn_master
[
best
].
hdr
,
&
frgn_master
[
best
].
ann
);
}
proto-ext-whiterabbit/hooks.c
View file @
98a570ed
...
...
@@ -92,6 +92,18 @@ static int wr_update_delay(struct pp_instance *ppi)
return
0
;
}
static
void
wr_s1
(
struct
pp_instance
*
ppi
,
MsgHeader
*
hdr
,
MsgAnnounce
*
ann
)
{
WR_DSPOR
(
ppi
)
->
parentIsWRnode
=
((
ann
->
wrFlags
&
WR_NODE_MODE
)
!=
NON_WR
);
WR_DSPOR
(
ppi
)
->
parentWrModeOn
=
(
ann
->
wrFlags
&
WR_IS_WR_MODE
)
?
TRUE
:
FALSE
;
WR_DSPOR
(
ppi
)
->
parentCalibrated
=
((
ann
->
wrFlags
&
WR_IS_CALIBRATED
)
?
1
:
0
);
WR_DSPOR
(
ppi
)
->
parentWrConfig
=
ann
->
wrFlags
&
WR_NODE_MODE
;
DSCUR
(
ppi
)
->
primarySlavePortNumber
=
DSPOR
(
ppi
)
->
portIdentity
.
portNumber
;
}
struct
pp_ext_hooks
pp_hooks
=
{
.
init
=
wr_init
,
...
...
@@ -100,4 +112,5 @@ struct pp_ext_hooks pp_hooks = {
.
master_msg
=
wr_master_msg
,
.
new_slave
=
wr_new_slave
,
.
update_delay
=
wr_update_delay
,
.
s1
=
wr_s1
,
};
proto-standard/bmc.c
View file @
98a570ed
...
...
@@ -84,6 +84,9 @@ void s1(struct pp_instance *ppi, MsgHeader *hdr, MsgAnnounce *ann)
DSPRO
(
ppi
)
->
frequencyTraceable
=
((
hdr
->
flagField
[
1
]
&
FFB_FTRA
)
!=
0
);
DSPRO
(
ppi
)
->
ptpTimescale
=
((
hdr
->
flagField
[
1
]
&
FFB_PTP
)
!=
0
);
DSPRO
(
ppi
)
->
timeSource
=
ann
->
timeSource
;
if
(
pp_hooks
.
s1
)
pp_hooks
.
s1
(
ppi
,
hdr
,
ann
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment