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
ff6d7afa
Commit
ff6d7afa
authored
Sep 21, 2018
by
Adam Wujek
💬
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch absolute_calibration
parents
0cc9d341
8611fb6d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
54 changed files
with
2506 additions
and
786 deletions
+2506
-786
main-loop.c
arch-sim/main-loop.c
+2
-0
sim-startup.c
arch-sim/sim-startup.c
+3
-3
main-loop.c
arch-unix/main-loop.c
+2
-0
wrc_ptp_ppsi.c
arch-wrpc/wrc_ptp_ppsi.c
+27
-10
wrpc-spll.c
arch-wrpc/wrpc-spll.c
+7
-0
wrpc.h
arch-wrpc/wrpc.h
+1
-0
hal_exports.h
arch-wrs/include/hal_exports.h
+1
-0
hal_shmem.h
arch-wrs/include/libwr/hal_shmem.h
+1
-0
ppsi-wrs.h
arch-wrs/include/ppsi-wrs.h
+1
-0
main-loop.c
arch-wrs/main-loop.c
+9
-7
wrs-startup.c
arch-wrs/wrs-startup.c
+1
-0
fsm.c
fsm.c
+71
-46
constants.h
include/ppsi/constants.h
+38
-14
ieee1588_types.h
include/ppsi/ieee1588_types.h
+3
-3
pp-instance.h
include/ppsi/pp-instance.h
+18
-6
ppsi.h
include/ppsi/ppsi.h
+46
-13
main-loop.c
lib-bare/main-loop.c
+2
-0
msgtype.c
msgtype.c
+1
-1
common-fun.c
proto-ext-whiterabbit/common-fun.c
+1
-1
fsm-table.c
proto-ext-whiterabbit/fsm-table.c
+1
-1
hooks.c
proto-ext-whiterabbit/hooks.c
+93
-21
state-wr-calibrated.c
proto-ext-whiterabbit/state-wr-calibrated.c
+2
-2
state-wr-calibration.c
proto-ext-whiterabbit/state-wr-calibration.c
+1
-1
state-wr-link-on.c
proto-ext-whiterabbit/state-wr-link-on.c
+1
-1
state-wr-locked.c
proto-ext-whiterabbit/state-wr-locked.c
+2
-2
state-wr-m-lock.c
proto-ext-whiterabbit/state-wr-m-lock.c
+3
-3
state-wr-present.c
proto-ext-whiterabbit/state-wr-present.c
+4
-6
state-wr-resp-calib-req.c
proto-ext-whiterabbit/state-wr-resp-calib-req.c
+2
-2
state-wr-s-lock.c
proto-ext-whiterabbit/state-wr-s-lock.c
+2
-2
wr-api.h
proto-ext-whiterabbit/wr-api.h
+11
-12
wr-msg.c
proto-ext-whiterabbit/wr-msg.c
+2
-18
Makefile
proto-standard/Makefile
+0
-1
bmc.c
proto-standard/bmc.c
+1293
-175
common-fun.c
proto-standard/common-fun.c
+58
-132
common-fun.h
proto-standard/common-fun.h
+10
-20
fsm-lib.c
proto-standard/fsm-lib.c
+34
-51
fsm-table.c
proto-standard/fsm-table.c
+1
-1
msg.c
proto-standard/msg.c
+30
-19
open-close.c
proto-standard/open-close.c
+2
-2
servo.c
proto-standard/servo.c
+0
-2
state-disabled.c
proto-standard/state-disabled.c
+1
-1
state-faulty.c
proto-standard/state-faulty.c
+1
-1
state-initializing.c
proto-standard/state-initializing.c
+55
-23
state-listening.c
proto-standard/state-listening.c
+40
-36
state-master.c
proto-standard/state-master.c
+37
-14
state-passive.c
proto-standard/state-passive.c
+68
-38
state-slave.c
proto-standard/state-slave.c
+166
-28
state-uncalibrated.c
proto-standard/state-uncalibrated.c
+0
-44
bare-time.c
time-bare/bare-time.c
+52
-0
sim-time.c
time-sim/sim-time.c
+34
-0
unix-time.c
time-unix/unix-time.c
+164
-1
wrpc-time.c
time-wrpc/wrpc-time.c
+41
-0
wrs-time.c
time-wrs/wrs-time.c
+49
-20
timeout.c
timeout.c
+11
-2
No files found.
arch-sim/main-loop.c
View file @
ff6d7afa
...
...
@@ -51,6 +51,8 @@ void sim_main_loop(struct pp_globals *ppg)
for
(
j
=
0
;
j
<
ppg
->
nlinks
;
j
++
)
{
ppi
=
INST
(
ppg
,
j
);
ppi
->
is_new_state
=
1
;
/* just tell that the links are up */
ppi
->
link_up
=
TRUE
;
}
delay_ns
=
run_all_state_machines
(
ppg
)
*
1000LL
*
1000LL
;
...
...
arch-sim/sim-startup.c
View file @
ff6d7afa
...
...
@@ -12,9 +12,9 @@
static
struct
pp_runtime_opts
sim_master_rt_opts
=
{
.
clock_quality
=
{
.
clockClass
=
PP_
CLASS_WR
_GM_LOCKED
,
.
clockAccuracy
=
PP_
DEFAULT_CLOCK_ACCURACY
,
.
offsetScaledLogVariance
=
PP_
DEFAULT_CLOCK_VARIANCE
,
.
clockClass
=
PP_
PTP_CLASS
_GM_LOCKED
,
.
clockAccuracy
=
PP_
ACCURACY_DEFAULT
,
.
offsetScaledLogVariance
=
PP_
VARIANCE_DEFAULT
,
},
.
flags
=
PP_DEFAULT_FLAGS
,
.
ap
=
PP_DEFAULT_AP
,
...
...
arch-unix/main-loop.c
View file @
ff6d7afa
...
...
@@ -48,6 +48,8 @@ void unix_main_loop(struct pp_globals *ppg)
for
(
j
=
0
;
j
<
ppg
->
nlinks
;
j
++
)
{
ppi
=
INST
(
ppg
,
j
);
/* just tell that the links are up */
ppi
->
link_up
=
TRUE
;
/*
* The main loop here is based on select. While we are not
...
...
arch-wrpc/wrc_ptp_ppsi.c
View file @
ff6d7afa
...
...
@@ -32,6 +32,7 @@ static struct wr_operations wrpc_wr_operations = {
.
locking_enable
=
wrpc_spll_locking_enable
,
.
locking_poll
=
wrpc_spll_locking_poll
,
.
locking_disable
=
wrpc_spll_locking_disable
,
.
locking_reset
=
wrpc_spll_locking_reset
,
.
enable_ptracker
=
wrpc_spll_enable_ptracker
,
.
adjust_in_progress
=
wrpc_adjust_in_progress
,
...
...
@@ -118,12 +119,14 @@ int wrc_ptp_set_mode(int mode)
struct
pp_globals
*
ppg
=
ppi
->
glbs
;
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
typeof
(
ppg
->
rt_opts
->
clock_quality
.
clockClass
)
*
class_ptr
;
typeof
(
ppg
->
rt_opts
->
clock_quality
.
clockAccuracy
)
*
accuracy_ptr
;
int
error
=
0
;
/*
* We need to change the class in the default options.
* Unfortunately, ppg->rt_opts may be yet unassigned when this runs
*/
class_ptr
=
&
__pp_default_rt_opts
.
clock_quality
.
clockClass
;
accuracy_ptr
=
&
__pp_default_rt_opts
.
clock_quality
.
clockAccuracy
;
ptp_mode
=
0
;
...
...
@@ -134,31 +137,38 @@ int wrc_ptp_set_mode(int mode)
case
WRC_MODE_ABSCAL
:
/* absolute calibration, gm-lookalike */
wrp
->
wrConfig
=
WR_M_ONLY
;
ppi
->
role
=
PPSI_ROLE_MASTER
;
*
class_ptr
=
PP_CLASS_WR_GM_LOCKED
;
*
class_ptr
=
PP_PTP_CLASS_GM_LOCKED
;
*
accuracy_ptr
=
PP_PTP_ACCURACY_GM_LOCKED
;
spll_init
(
SPLL_MODE_GRAND_MASTER
,
0
,
1
);
shw_pps_gen_unmask_output
(
1
);
lock_timeout
=
LOCK_TIMEOUT_GM
;
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
=
PP_CLASS_WR_GM_LOCKED
;
m1
(
ppi
);
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
=
PP_PTP_CLASS_GM_LOCKED
;
DSDEF
(
ppi
)
->
clockQuality
.
clockAccuracy
=
PP_PTP_ACCURACY_GM_LOCKED
;
bmc_m1
(
ppi
);
break
;
case
WRC_MODE_MASTER
:
wrp
->
wrConfig
=
WR_M_ONLY
;
ppi
->
role
=
PPSI_ROLE_MASTER
;
*
class_ptr
=
PP_CLASS_DEFAULT
;
*
class_ptr
=
PP_PTP_CLASS_GM_UNLOCKED
;
*
accuracy_ptr
=
PP_PTP_ACCURACY_GM_UNLOCKED
;
spll_init
(
SPLL_MODE_FREE_RUNNING_MASTER
,
0
,
1
);
shw_pps_gen_unmask_output
(
1
);
lock_timeout
=
LOCK_TIMEOUT_FM
;
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
=
PP_CLASS_DEFAULT
;
m1
(
ppi
);
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
=
PP_PTP_CLASS_GM_UNLOCKED
;
DSDEF
(
ppi
)
->
clockQuality
.
clockAccuracy
=
PP_PTP_ACCURACY_GM_UNLOCKED
;
bmc_m1
(
ppi
);
break
;
case
WRC_MODE_SLAVE
:
wrp
->
wrConfig
=
WR_S_ONLY
;
ppi
->
role
=
PPSI_ROLE_SLAVE
;
*
class_ptr
=
PP_CLASS_SLAVE_ONLY
;
*
accuracy_ptr
=
PP_ACCURACY_DEFAULT
;
spll_init
(
SPLL_MODE_SLAVE
,
0
,
1
);
shw_pps_gen_unmask_output
(
0
);
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
=
PP_CLASS_SLAVE_ONLY
;
DSDEF
(
ppi
)
->
clockQuality
.
clockAccuracy
=
PP_ACCURACY_DEFAULT
;
break
;
}
...
...
@@ -180,8 +190,10 @@ int wrc_ptp_set_mode(int mode)
pp_printf
(
"
\n
"
);
/* If we can't lock to the atomic/gps, we say it in the class */
if
(
error
&&
mode
==
WRC_MODE_GM
)
*
class_ptr
=
PP_CLASS_WR_GM_UNLOCKED
;
if
(
error
&&
mode
==
WRC_MODE_GM
)
{
*
class_ptr
=
PP_PTP_CLASS_GM_UNLOCKED
;
*
accuracy_ptr
=
PP_PTP_ACCURACY_GM_UNLOCKED
;
}
ptp_mode
=
mode
;
return
error
;
...
...
@@ -225,9 +237,10 @@ int wrc_ptp_start()
delay_ms
=
pp_state_machine
(
ppi
,
NULL
,
0
);
start_tics
=
timer_get_tics
();
WR_DSPOR
(
ppi
)
->
linkUP
=
FALSE
;
/* just tell that the link is up, if not it will anyhow not receive anything */
ppi
->
link_up
=
TRUE
;
ppi
->
state
=
PPS_INITIALIZING
;
wr_servo_reset
(
ppi
);
ptp_enabled
=
1
;
return
0
;
}
...
...
@@ -244,7 +257,11 @@ int wrc_ptp_stop()
memset
(
ppi
->
frgn_master
,
0
,
sizeof
(
ppi
->
frgn_master
));
ppi
->
frgn_rec_num
=
0
;
/* no known master */
/* just tell that the link is down now */
ppi
->
link_up
=
FALSE
;
ptp_enabled
=
0
;
ppi
->
next_state
=
PPS_DISABLED
;
pp_leave_current_state
(
ppi
);
wr_servo_reset
(
ppi
);
pp_close_globals
(
&
ppg_static
);
...
...
arch-wrpc/wrpc-spll.c
View file @
ff6d7afa
...
...
@@ -47,6 +47,13 @@ int wrpc_spll_locking_poll(struct pp_instance *ppi, int grandmaster)
return
locked
?
WR_SPLL_READY
:
WR_SPLL_ERROR
;
}
int
wrpc_spll_locking_reset
(
struct
pp_instance
*
ppi
)
{
//TODO?
return
WR_SPLL_OK
;
}
int
wrpc_spll_locking_disable
(
struct
pp_instance
*
ppi
)
{
/* softpll_disable(); */
...
...
arch-wrpc/wrpc.h
View file @
ff6d7afa
...
...
@@ -46,6 +46,7 @@ struct wrpc_ethhdr {
int
wrpc_spll_locking_enable
(
struct
pp_instance
*
ppi
);
int
wrpc_spll_locking_poll
(
struct
pp_instance
*
ppi
,
int
grandmaster
);
int
wrpc_spll_locking_disable
(
struct
pp_instance
*
ppi
);
int
wrpc_spll_locking_reset
(
struct
pp_instance
*
ppi
);
int
wrpc_spll_enable_ptracker
(
struct
pp_instance
*
ppi
);
int
wrpc_adjust_in_progress
(
void
);
int
wrpc_adjust_counters
(
int64_t
adjust_sec
,
int32_t
adjust_nsec
);
...
...
arch-wrs/include/hal_exports.h
View file @
ff6d7afa
...
...
@@ -26,6 +26,7 @@
#define HEXP_LOCK_CMD_START 1
#define HEXP_LOCK_CMD_CHECK 2
#define HEXP_LOCK_CMD_ENABLE_TRACKING 3
#define HEXP_LOCK_CMD_RESET 4
#define HEXP_LOCK_STATUS_LOCKED 0
#define HEXP_LOCK_STATUS_BUSY 1
...
...
arch-wrs/include/libwr/hal_shmem.h
View file @
ff6d7afa
...
...
@@ -11,6 +11,7 @@
#define HAL_PORT_STATE_UP 2
#define HAL_PORT_STATE_CALIBRATION 3
#define HAL_PORT_STATE_LOCKING 4
#define HAL_PORT_STATE_RESET 5
/* Read temperature from SFPs */
#define READ_SFP_DIAG_ENABLE 1
...
...
arch-wrs/include/ppsi-wrs.h
View file @
ff6d7afa
...
...
@@ -76,6 +76,7 @@ int wrs_calibration_pattern_disable(struct pp_instance *ppi);
int
wrs_locking_enable
(
struct
pp_instance
*
ppi
);
int
wrs_locking_poll
(
struct
pp_instance
*
ppi
,
int
grandmaster
);
int
wrs_locking_disable
(
struct
pp_instance
*
ppi
);
int
wrs_locking_reset
(
struct
pp_instance
*
ppi
);
int
wrs_enable_ptracker
(
struct
pp_instance
*
ppi
);
int
wrs_adjust_in_progress
(
void
);
int
wrs_adjust_counters
(
int64_t
adjust_sec
,
int32_t
adjust_nsec
);
...
...
arch-wrs/main-loop.c
View file @
ff6d7afa
...
...
@@ -29,7 +29,7 @@ static int run_all_state_machines(struct pp_globals *ppg)
for
(
j
=
0
;
j
<
ppg
->
nlinks
;
j
++
)
{
struct
pp_instance
*
ppi
=
INST
(
ppg
,
j
);
int
old_lu
=
WR_DSPOR
(
ppi
)
->
linkUP
;
int
old_lu
=
ppi
->
link_up
;
struct
hal_port_state
*
p
;
/* FIXME: we should save this pointer in the ppi itself */
...
...
@@ -40,29 +40,31 @@ static int run_all_state_machines(struct pp_globals *ppg)
continue
;
}
WR_DSPOR
(
ppi
)
->
linkUP
=
ppi
->
link_up
=
(
p
->
state
!=
HAL_PORT_STATE_LINK_DOWN
&&
p
->
state
!=
HAL_PORT_STATE_DISABLED
);
if
(
old_lu
!=
WR_DSPOR
(
ppi
)
->
linkUP
)
{
if
(
old_lu
!=
ppi
->
link_up
)
{
pp_diag
(
ppi
,
fsm
,
1
,
"iface %s went %s
\n
"
,
ppi
->
iface_name
,
WR_DSPOR
(
ppi
)
->
linkUP
?
"up"
:
"down"
);
ppi
->
iface_name
,
ppi
->
link_up
?
"up"
:
"down"
);
if
(
WR_DSPOR
(
ppi
)
->
linkUP
)
{
if
(
ppi
->
link_up
)
{
ppi
->
state
=
PPS_INITIALIZING
;
}
else
{
ppi
->
next_state
=
PPS_DISABLED
;
pp_leave_current_state
(
ppi
);
ppi
->
n_ops
->
exit
(
ppi
);
ppi
->
frgn_rec_num
=
0
;
ppi
->
frgn_rec_best
=
-
1
;
ppi
->
frgn_rec_best
=
0
;
if
(
ppg
->
ebest_idx
==
ppi
->
port_idx
)
wr_servo_reset
(
ppi
);
}
}
/* Do not call state machine if link is down */
if
(
WR_DSPOR
(
ppi
)
->
linkUP
)
if
(
ppi
->
link_up
)
delay_ms_j
=
pp_state_machine
(
ppi
,
NULL
,
0
);
else
delay_ms_j
=
PP_DEFAULT_NEXT_DELAY_MS
;
...
...
arch-wrs/wrs-startup.c
View file @
ff6d7afa
...
...
@@ -36,6 +36,7 @@ static struct wr_operations wrs_wr_operations = {
.
locking_enable
=
wrs_locking_enable
,
.
locking_poll
=
wrs_locking_poll
,
.
locking_disable
=
wrs_locking_disable
,
.
locking_reset
=
wrs_locking_reset
,
.
enable_ptracker
=
wrs_enable_ptracker
,
.
adjust_in_progress
=
wrs_adjust_in_progress
,
...
...
fsm.c
View file @
ff6d7afa
...
...
@@ -44,12 +44,12 @@ enum {
};
static
void
pp_diag_fsm
(
struct
pp_instance
*
ppi
,
char
*
name
,
int
sequence
,
int
p
len
)
int
len
)
{
if
(
sequence
==
STATE_ENTER
)
{
/* enter with or without a packet len */
pp_fsm_printf
(
ppi
,
"ENTER %s, packet len %i
\n
"
,
name
,
p
len
);
name
,
len
);
return
;
}
if
(
sequence
==
STATE_LOOP
)
{
...
...
@@ -85,10 +85,17 @@ get_current_state_table_item(struct pp_instance *ppi)
/*
* Returns delay to next state, which is always zero.
*/
static
int
leave_current_state
(
struct
pp_instance
*
ppi
)
int
pp_
leave_current_state
(
struct
pp_instance
*
ppi
)
{
/* If something has to be done in an extension */
if
(
pp_hooks
.
state_change
)
pp_hooks
.
state_change
(
ppi
);
/* if the next or old state is non standard PTP reset all timeouts */
if
((
ppi
->
state
>
PPS_SLAVE
)
||
(
ppi
->
next_state
>
PPS_SLAVE
))
pp_timeout_setall
(
ppi
);
ppi
->
state
=
ppi
->
next_state
;
pp_timeout_setall
(
ppi
);
ppi
->
flags
&=
~
PPI_FLAGS_WAITING
;
pp_diag_fsm
(
ppi
,
ppi
->
current_state_item
->
name
,
STATE_LEAVE
,
0
);
/* next_delay unused: go to new state now */
...
...
@@ -138,22 +145,22 @@ static int pp_packet_prefilter(struct pp_instance *ppi)
}
/*
* 9.5.2.3
: if an announce message comes from another port of the same
*
clock, switch all the ports but the lowest numbered one to
*
PASSIVE. Since all involved ports will see each other's announce,
* we just switch __this__ instance's port's status to PASSIVE if we
* need to.
*/
if
(
hdr
->
messageType
==
PPM_ANNOUNCE
&&
!
memcmp
(
&
hdr
->
sourcePortIdentity
.
clockIdentity
,
&
DSPOR
(
ppi
)
->
portIdentity
.
clockIdentity
,
sizeof
(
ClockIdentity
))
)
{
if
(
hdr
->
sourcePortIdentity
.
portNumber
<
DSPOR
(
ppi
)
->
portIdentity
.
portNumber
)
ppi
->
next_state
=
PPS_PASSIVE
;
return
-
1
;
* 9.5.2.3
& 9.5.2.2: For BCs the BMC (an extention to it)
*
handles the Announce (go to Passive), other messages are dropped
*
/
if
(
!
memcmp
(
&
hdr
->
sourcePortIdentity
.
clockIdentity
,
&
DSPOR
(
ppi
)
->
portIdentity
.
clockIdentity
,
sizeof
(
ClockIdentity
)))
{
if
(
DSDEF
(
ppi
)
->
numberPorts
>
1
)
{
/* Announces are handled by the BMC, since otherwise the state
* also the PASSIVE states in this case is overwritten */
if
(
hdr
->
messageType
!=
PPM_ANNOUNCE
)
{
/* ignore messages, except announce coming from its own clock */
return
-
1
;
}
}
}
return
0
;
}
...
...
@@ -165,24 +172,24 @@ static int type_length[__PP_NR_MESSAGES_TYPES] = {
[
PPM_PDELAY_RESP
]
=
PP_PDELAY_RESP_LENGTH
,
[
PPM_FOLLOW_UP
]
=
PP_FOLLOW_UP_LENGTH
,
[
PPM_DELAY_RESP
]
=
PP_DELAY_RESP_LENGTH
,
[
PPM_PDELAY_R_FUP
]
=
PP_PDELAY_R
_F
UP_LENGTH
,
[
PPM_PDELAY_R_FUP
]
=
PP_PDELAY_R
ESP_FOLLOW_
UP_LENGTH
,
[
PPM_ANNOUNCE
]
=
PP_ANNOUNCE_LENGTH
,
[
PPM_SIGNALING
]
=
PP_HEADER_LENGTH
,
[
PPM_SIGNALING
]
=
PP_HEADER_LENGTH
,
[
PPM_MANAGEMENT
]
=
PP_MANAGEMENT_LENGTH
,
};
static
int
fsm_unpack_verify_frame
(
struct
pp_instance
*
ppi
,
uint8_t
*
packet
,
int
p
len
)
void
*
buf
,
int
len
)
{
int
msgtype
=
0
;
if
(
p
len
)
msgtype
=
packet
[
0
]
&
0xf
;
if
(
msgtype
>=
__PP_NR_MESSAGES_TYPES
||
p
len
<
type_length
[
msgtype
])
if
(
len
)
msgtype
=
((
*
(
UInteger8
*
)
(
buf
+
0
))
&
0x0F
)
;
if
(
msgtype
>=
__PP_NR_MESSAGES_TYPES
||
len
<
type_length
[
msgtype
])
return
1
;
/* too short */
if
((
packet
[
1
]
&
0xf
)
!=
2
)
if
((
(
*
(
UInteger8
*
)
(
buf
+
1
))
&
0x0F
)
!=
2
)
return
1
;
/* wrong ptp version */
return
msg_unpack_header
(
ppi
,
packet
,
p
len
);
return
msg_unpack_header
(
ppi
,
buf
,
len
);
}
/*
...
...
@@ -194,18 +201,18 @@ static int fsm_unpack_verify_frame(struct pp_instance *ppi,
* is that of the extension, otherwise the one in state-table-default.c
*/
int
pp_state_machine
(
struct
pp_instance
*
ppi
,
uint8_t
*
packet
,
int
p
len
)
int
pp_state_machine
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
struct
pp_state_table_item
*
ip
;
struct
pp_time
*
t
=
&
ppi
->
last_rcv_time
;
int
state
,
err
=
0
;
int
msgtype
;
if
(
p
len
>
0
)
{
msgtype
=
packet
[
0
]
&
0xf
;
if
(
len
>
0
)
{
msgtype
=
((
*
(
UInteger8
*
)
(
buf
+
0
))
&
0x0F
)
;
pp_diag
(
ppi
,
frames
,
1
,
"RECV %02d bytes at %9d.%09d.%03d (type %x, %s)
\n
"
,
p
len
,
(
int
)
t
->
secs
,
(
int
)(
t
->
scaled_nsecs
>>
16
),
len
,
(
int
)
t
->
secs
,
(
int
)(
t
->
scaled_nsecs
>>
16
),
((
int
)(
t
->
scaled_nsecs
&
0xffff
)
*
1000
)
>>
16
,
msgtype
,
pp_msgtype_info
[
msgtype
].
name
);
}
...
...
@@ -213,9 +220,9 @@ int pp_state_machine(struct pp_instance *ppi, uint8_t *packet, int plen)
/*
* Discard too short packets
*/
if
(
p
len
<
PP_HEADER_LENGTH
)
{
p
len
=
0
;
packet
=
NULL
;
if
(
len
<
PP_HEADER_LENGTH
)
{
len
=
0
;
buf
=
NULL
;
}
/*
...
...
@@ -224,10 +231,10 @@ int pp_state_machine(struct pp_instance *ppi, uint8_t *packet, int plen)
* In case of error continue without a frame, so the current
* ptp state can update ppi->next_delay and return a proper value
*/
err
=
fsm_unpack_verify_frame
(
ppi
,
packet
,
p
len
);
err
=
fsm_unpack_verify_frame
(
ppi
,
buf
,
len
);
if
(
err
)
{
p
len
=
0
;
packet
=
NULL
;
len
=
0
;
buf
=
NULL
;
}
state
=
ppi
->
state
;
...
...
@@ -242,31 +249,49 @@ int pp_state_machine(struct pp_instance *ppi, uint8_t *packet, int plen)
ppi
->
next_state
=
state
;
ppi
->
next_delay
=
0
;
if
(
ppi
->
is_new_state
)
pp_diag_fsm
(
ppi
,
ip
->
name
,
STATE_ENTER
,
plen
);
pp_diag_fsm
(
ppi
,
ip
->
name
,
STATE_ENTER
,
len
);
/*
* Possibly filter out
packet
and maybe update port state
* Possibly filter out
buf
and maybe update port state
*/
if
(
packet
)
{
if
(
buf
)
{
err
=
pp_packet_prefilter
(
ppi
);
if
(
err
<
0
)
{
packet
=
NULL
;
p
len
=
0
;
buf
=
NULL
;
len
=
0
;
}
}
if
(
ppi
->
state
!=
ppi
->
next_state
)
return
leave_current_state
(
ppi
);
return
pp_
leave_current_state
(
ppi
);
if
(
!
p
len
)
if
(
!
len
)
ppi
->
received_ptp_header
.
messageType
=
PPM_NO_MESSAGE
;
err
=
ip
->
f1
(
ppi
,
packet
,
plen
);
err
=
ip
->
f1
(
ppi
,
buf
,
len
);
if
(
err
)
pp_printf
(
"fsm for %s: Error %i in %s
\n
"
,
ppi
->
port_name
,
err
,
ip
->
name
);
/* done: if new state mark it, and enter it now (0 ms) */
if
(
ppi
->
state
!=
ppi
->
next_state
)
return
leave_current_state
(
ppi
);
return
pp_leave_current_state
(
ppi
);
/* run bmc independent of state, and since not message driven do this
* here 9.2.6.8 */
if
(
pp_timeout
(
ppi
,
PP_TO_BMC
))
{
ppi
->
next_state
=
bmc
(
ppi
);
/* done: if new state mark it, and enter it now (0 ms) */
if
(
ppi
->
state
!=
ppi
->
next_state
)
return
pp_leave_current_state
(
ppi
);
}
pp_diag_fsm
(
ppi
,
ip
->
name
,
STATE_LOOP
,
0
);
/* check if the BMC timeout is the next to run */
if
(
pp_next_delay_1
(
ppi
,
PP_TO_BMC
)
<
ppi
->
next_delay
)
ppi
->
next_delay
=
pp_next_delay_1
(
ppi
,
PP_TO_BMC
);
return
ppi
->
next_delay
;
}
include/ppsi/constants.h
View file @
ff6d7afa
...
...
@@ -23,32 +23,56 @@
#define PP_DEFAULT_AP 10
#define PP_DEFAULT_AI 1000
#define PP_DEFAULT_DELAY_S 6
#define PP_DEFAULT_ANNOUNCE_INTERVAL 1
/* 0 in 802.1AS */
#define PP_DEFAULT_ANNOUNCE_INTERVAL 1
/* 0 in 802.1AS */
#define PP_DEFAULT_DELAYREQ_INTERVAL 0
#define PP_DEFAULT_SYNC_INTERVAL 0
/* -7 in 802.1AS */
#define PP_DEFAULT_SYNC_INTERVAL 0
/* -7 in 802.1AS */
#define PP_DEFAULT_SYNC_RECEIPT_TIMEOUT 3
#define PP_DEFAULT_ANNOUNCE_RECEIPT_TIMEOUT 20
/* 3 by default */
#define PP_DEFAULT_ANNOUNCE_RECEIPT_TIMEOUT 3
/* 3 by default */
#define PP_DEFAULT_UTC_OFFSET 37
#define PP_DEFAULT_PRIORITY1 128
#define PP_DEFAULT_PRIORITY2 128
/* Clock classes (pag 55, PTP-2008). See ppsi-manual for an explanation */
#define PP_CLASS_SLAVE_ONLY 255
#define PP_CLASS_DEFAULT 187
#define PP_CLASS_WR_GM_LOCKED 6
#define PP_CLASS_WR_GM_UNLOCKED 52
#define PP_CLASS_DEFAULT 248
#define PP_PTP_CLASS_GM_LOCKED 6
#define PP_PTP_CLASS_GM_HOLDOVER 7
#define PP_PTP_CLASS_GM_UNLOCKED 52
#define PP_ARB_CLASS_GM_LOCKED 13
#define PP_ARB_CLASS_GM_HOLDOVER 14
#define PP_ARB_CLASS_GM_UNLOCKED 58
#define PP_ACCURACY_DEFAULT 0xFE
#define PP_PTP_ACCURACY_GM_LOCKED 0x21
#define PP_PTP_ACCURACY_GM_HOLDOVER 0x21
#define PP_PTP_ACCURACY_GM_UNLOCKED 0xFE
#define PP_ARB_ACCURACY_GM_LOCKED 0x21
#define PP_ARB_ACCURACY_GM_HOLDOVER 0x21
#define PP_ARB_ACCURACY_GM_UNLOCKED 0xFE
#define PP_VARIANCE_DEFAULT 0xC71D
#define PP_PTP_VARIANCE_GM_LOCKED 0xB900
#define PP_PTP_VARIANCE_GM_HOLDOVER 0xC71D
#define PP_PTP_VARIANCE_GM_UNLOCKED 0xC71D
#define PP_ARB_VARIANCE_GM_LOCKED 0xB900
#define PP_ARB_VARIANCE_GM_HOLDOVER 0xC71D
#define PP_ARB_VARIANCE_GM_UNLOCKED 0xC71D
#define PP_SERVO_UNKNOWN 0
#define PP_SERVO_LOCKED 1
#define PP_SERVO_HOLDOVER 2
#define PP_SERVO_UNLOCKED 3
#define PP_DEFAULT_CLOCK_ACCURACY 0xFE
#define PP_DEFAULT_PRIORITY1 128
#define PP_DEFAULT_PRIORITY2 128
#define PP_DEFAULT_CLOCK_VARIANCE -4000
/* To be determined in
* 802.1AS. We use the
* same value as in ptpdv1
*/
#define PP_NR_FOREIGN_RECORDS 5
#define PP_FOREIGN_MASTER_TIME_WINDOW 4
#define PP_FOREIGN_MASTER_THRESHOLD 2
#define PP_DEFAULT_TTL 1
/* We use an array of timeouts, with these indexes */
enum
pp_timeouts
{
PP_TO_REQUEST
=
0
,
PP_TO_SYNC_SEND
,
PP_TO_BMC
,
PP_TO_ANN_RECEIPT
,
PP_TO_ANN_SEND
,
PP_TO_FAULT
,
...
...
@@ -71,7 +95,7 @@ enum pp_timeouts {
#define PP_DELAY_REQ_LENGTH 44
#define PP_DELAY_RESP_LENGTH 54
#define PP_PDELAY_RESP_LENGTH 54
#define PP_PDELAY_R
_FUP_LENGTH
54
#define PP_PDELAY_R
ESP_FOLLOW_UP_LENGTH
54
#define PP_MANAGEMENT_LENGTH 48
#define PP_MINIMUM_LENGTH 44
...
...
include/ppsi/ieee1588_types.h
View file @
ff6d7afa
...
...
@@ -45,7 +45,7 @@ typedef struct Integer64 {
typedef
struct
UInteger64
{
uint32_t
lsb
;
uint32_t
msb
;
uint32_t
msb
;
}
UInteger64
;
struct
TimeInterval
{
/* page 12 (32) -- never used */
...
...
@@ -54,7 +54,7 @@ struct TimeInterval { /* page 12 (32) -- never used */
/* White Rabbit extension */
typedef
struct
FixedDelta
{
UInteger64
scaledPicoseconds
;
UInteger64
scaledPicoseconds
;
}
FixedDelta
;
typedef
struct
Timestamp
{
/* page 13 (33) -- no typedef expected */
...
...
@@ -217,7 +217,7 @@ typedef struct DSCurrent { /* page 67 */
typedef
struct
DSParent
{
/* page 68 */
/* Dynamic */
PortIdentity
parentPortIdentity
;
/* Boolean
parentStats; -- not used */
/* Boolean parentStats; -- not used */
UInteger16
observedParentOffsetScaledLogVariance
;
Integer32
observedParentClockPhaseChangeRate
;
ClockIdentity
grandmasterIdentity
;
...
...
include/ppsi/pp-instance.h
View file @
ff6d7afa
...
...
@@ -64,11 +64,23 @@ struct pp_channel {
* it is called foreignMasterDS, see 9.3.2.4
*/
struct
pp_frgn_master
{
PortIdentity
port_id
;
/* used to identify old/new masters */
/* We don't need all fields of the following ones */
MsgAnnounce
ann
;
MsgHeader
hdr
;
/* how many announce messages from this port where received in the
* interval */
UInteger16
foreignMasterAnnounceMessages
[
PP_FOREIGN_MASTER_TIME_WINDOW
];
/* on which port we received the frame */
PortIdentity
receivePortIdentity
;
/* BMC related information */
UInteger16
sequenceId
;
PortIdentity
sourcePortIdentity
;
Octet
flagField
[
2
];
Integer16
currentUtcOffset
;
UInteger8
grandmasterPriority1
;
ClockQuality
grandmasterClockQuality
;
UInteger8
grandmasterPriority2
;
ClockIdentity
grandmasterIdentity
;
UInteger16
stepsRemoved
;
Enumeration8
timeSource
;
unsigned
long
ext_specific
;
/* used by extension */
};
/*
...
...
@@ -168,6 +180,7 @@ struct pp_instance {
UInteger16
sent_seq
[
__PP_NR_MESSAGES_TYPES
];
/* last sent this type */
MsgHeader
received_ptp_header
;
Boolean
link_up
;
char
*
iface_name
;
/* for direct actions on hardware */
char
*
port_name
;
/* for diagnostics, mainly */
int
port_idx
;
...
...
@@ -180,7 +193,6 @@ struct pp_instance {
unsigned
long
ptp_rx_count
;
};
/* The following things used to be bit fields. Other flags are now enums */
#define PPI_FLAG_FROM_CURRENT_PARENT 0x01
#define PPI_FLAG_WAITING_FOR_F_UP 0x02
#define PPI_FLAG_WAITING_FOR_RF_UP 0x04
#define PPI_FLAGS_WAITING 0x06
/* both of the above */
...
...
include/ppsi/ppsi.h
View file @
ff6d7afa
...
...
@@ -70,8 +70,6 @@ extern struct pp_msgtype_info pp_msgtype_info[16];
extern
int
pp_lib_may_issue_sync
(
struct
pp_instance
*
ppi
);
extern
int
pp_lib_may_issue_announce
(
struct
pp_instance
*
ppi
);
extern
int
pp_lib_may_issue_request
(
struct
pp_instance
*
ppi
);
extern
int
pp_lib_handle_announce
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
len
);
/* We use data sets a lot, so have these helpers */
static
inline
struct
pp_globals
*
GLBS
(
struct
pp_instance
*
ppi
)
...
...
@@ -150,15 +148,15 @@ extern void pp_prepare_pointers(struct pp_instance *ppi);
* allow NULL pointers.
*/
struct
pp_ext_hooks
{
int
(
*
init
)(
struct
pp_instance
*
ppg
,
unsigned
char
*
pkt
,
int
p
len
);
int
(
*
init
)(
struct
pp_instance
*
ppg
,
void
*
buf
,
int
len
);
int
(
*
open
)(
struct
pp_globals
*
ppi
,
struct
pp_runtime_opts
*
rt_opts
);
int
(
*
close
)(
struct
pp_globals
*
ppg
);
int
(
*
listening
)(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
(
*
master_msg
)(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
,
int
msgtype
);
int
(
*
new_slave
)(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
(
*
listening
)(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
(
*
master_msg
)(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
,
int
msgtype
);
int
(
*
new_slave
)(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
(
*
handle_resp
)(
struct
pp_instance
*
ppi
);
void
(
*
s1
)(
struct
pp_instance
*
ppi
,
MsgHeader
*
hdr
,
MsgAnnounce
*
ann
);
void
(
*
s1
)(
struct
pp_instance
*
ppi
,
struct
pp_frgn_master
*
frgn_master
);
int
(
*
execute_slave
)(
struct
pp_instance
*
ppi
);
int
(
*
handle_announce
)(
struct
pp_instance
*
ppi
);
int
(
*
handle_followup
)(
struct
pp_instance
*
ppi
,
struct
pp_time
*
orig
);
...
...
@@ -166,6 +164,8 @@ struct pp_ext_hooks {
int
(
*
handle_presp
)
(
struct
pp_instance
*
ppi
);
int
(
*
pack_announce
)(
struct
pp_instance
*
ppi
);
void
(
*
unpack_announce
)(
void
*
buf
,
MsgAnnounce
*
ann
);
int
(
*
state_decision
)(
struct
pp_instance
*
ppi
,
int
next_state
);
void
(
*
state_change
)(
struct
pp_instance
*
ppi
);
};
extern
struct
pp_ext_hooks
pp_hooks
;
/* The one for the extension we build */
...
...
@@ -198,6 +198,9 @@ extern struct pp_network_operations unix_net_ops;
* If "set" receives a NULL time value, it should update the TAI offset.
*/
struct
pp_time_operations
{
int
(
*
get_utc_time
)(
struct
pp_instance
*
ppi
,
int
*
hours
,
int
*
minutes
,
int
*
seconds
);
int
(
*
get_utc_offset
)(
struct
pp_instance
*
ppi
,
int
*
offset
,
int
*
leap59
,
int
*
leap61
);
int
(
*
set_utc_offset
)(
struct
pp_instance
*
ppi
,
int
offset
,
int
leap59
,
int
leap61
);
int
(
*
get
)(
struct
pp_instance
*
ppi
,
struct
pp_time
*
t
);
int
(
*
set
)(
struct
pp_instance
*
ppi
,
const
struct
pp_time
*
t
);
/* freq_ppb is parts per billion */
...
...
@@ -205,6 +208,7 @@ struct pp_time_operations {
int
(
*
adjust_offset
)(
struct
pp_instance
*
ppi
,
long
offset_ns
);
int
(
*
adjust_freq
)(
struct
pp_instance
*
ppi
,
long
freq_ppb
);
int
(
*
init_servo
)(
struct
pp_instance
*
ppi
);
int
(
*
get_servo_state
)(
struct
pp_instance
*
ppi
,
int
*
state
);
unsigned
long
(
*
calc_timeout
)(
struct
pp_instance
*
ppi
,
int
millisec
);
};
...
...
@@ -231,6 +235,7 @@ extern struct pp_time_operations unix_time_ops;
*/
extern
void
pp_timeout_init
(
struct
pp_instance
*
ppi
);
extern
void
__pp_timeout_set
(
struct
pp_instance
*
ppi
,
int
index
,
int
millisec
);
extern
void
pp_timeout_clear
(
struct
pp_instance
*
ppi
,
int
index
);
extern
void
pp_timeout_set
(
struct
pp_instance
*
ppi
,
int
index
);
extern
void
pp_timeout_setall
(
struct
pp_instance
*
ppi
);
extern
int
pp_timeout
(
struct
pp_instance
*
ppi
,
int
index
)
...
...
@@ -358,13 +363,38 @@ extern void pp_servo_got_psync(struct pp_instance *ppi); /* got t1 and t2 */
extern
void
pp_servo_got_presp
(
struct
pp_instance
*
ppi
);
/* got all t3..t6 */
/* bmc.c */
extern
void
m1
(
struct
pp_instance
*
ppi
);
extern
void
bmc_m1
(
struct
pp_instance
*
ppi
);
extern
void
bmc_m2
(
struct
pp_instance
*
ppi
);
extern
void
bmc_m3
(
struct
pp_instance
*
ppi
);
extern
void
bmc_s1
(
struct
pp_instance
*
ppi
,
struct
pp_frgn_master
*
frgn_master
);
extern
void
bmc_p1
(
struct
pp_instance
*
ppi
);
extern
void
bmc_p2
(
struct
pp_instance
*
ppi
);
extern
void
bmc_setup_local_frgn_master
(
struct
pp_instance
*
ppi
,
struct
pp_frgn_master
*
frgn_master
);
extern
int
bmc_idcmp
(
struct
ClockIdentity
*
a
,
struct
ClockIdentity
*
b
);
extern
int
bmc_pidcmp
(
struct
PortIdentity
*
a
,
struct
PortIdentity
*
b
);
extern
int
bmc
(
struct
pp_instance
*
ppi
);
extern
int
bmc_gm_cmp
(
struct
pp_instance
*
ppi
,
struct
pp_frgn_master
*
a
,
struct
pp_frgn_master
*
b
);
extern
int
bmc_topology_cmp
(
struct
pp_instance
*
ppi
,
struct
pp_frgn_master
*
a
,
struct
pp_frgn_master
*
b
);
extern
int
bmc_dataset_cmp
(
struct
pp_instance
*
ppi
,
struct
pp_frgn_master
*
a
,
struct
pp_frgn_master
*
b
);
extern
void
bmc_store_frgn_master
(
struct
pp_instance
*
ppi
,
struct
pp_frgn_master
*
frgn_master
,
void
*
buf
,
int
len
);
extern
void
bmc_add_frgn_master
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
extern
int
bmc_check_frgn_master
(
struct
pp_instance
*
ppi
);
/* msg.c */
extern
void
msg_init_header
(
struct
pp_instance
*
ppi
,
void
*
buf
);
extern
int
msg_from_current_master
(
struct
pp_instance
*
ppi
);
extern
int
__attribute__
((
warn_unused_result
))
msg_unpack_header
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
p
len
);
msg_unpack_header
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
extern
void
msg_unpack_sync
(
void
*
buf
,
MsgSync
*
sync
);
extern
int
msg_pack_sync
(
struct
pp_instance
*
ppi
,
struct
pp_time
*
orig_tstamp
);
extern
void
msg_unpack_announce
(
void
*
buf
,
MsgAnnounce
*
ann
);
...
...
@@ -383,7 +413,7 @@ extern void msg_unpack_pdelay_req(void *buf, MsgPDelayReq * pdelay_req);
#define PP_SEND_ERROR -1
#define PP_SEND_NO_STAMP 1
#define PP_SEND_DROP -2
#define PP_RECV_DROP PP_SEND_DROP
#define PP_RECV_DROP
PP_SEND_DROP
extern
void
*
msg_copy_header
(
MsgHeader
*
dest
,
MsgHeader
*
src
);
/* REMOVE ME!! */
extern
int
msg_issue_announce
(
struct
pp_instance
*
ppi
);
...
...
@@ -406,7 +436,7 @@ extern void pp_time_div2(struct pp_time *t);
*/
/* Use a typedef, to avoid long prototypes */
typedef
int
pp_action
(
struct
pp_instance
*
ppi
,
uint8_t
*
packet
,
int
p
len
);
typedef
int
pp_action
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
struct
pp_state_table_item
{
int
state
;
...
...
@@ -421,8 +451,11 @@ extern pp_action pp_initializing, pp_faulty, pp_disabled, pp_listening,
pp_master
,
pp_passive
,
pp_uncalibrated
,
pp_slave
,
pp_pclock
;;
/* Enforce a state change */
extern
int
pp_leave_current_state
(
struct
pp_instance
*
ppi
);
/* The engine */
extern
int
pp_state_machine
(
struct
pp_instance
*
ppi
,
uint8_t
*
packet
,
int
p
len
);
extern
int
pp_state_machine
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
/* Frame-drop support -- rx before tx, alphabetically */
extern
void
ppsi_drop_init
(
struct
pp_globals
*
ppg
,
unsigned
long
seed
);
...
...
lib-bare/main-loop.c
View file @
ff6d7afa
...
...
@@ -24,6 +24,8 @@ void bare_main_loop(struct pp_instance *ppi)
{
int
delay_ms
;
/* just tell that the links are up */
ppi
->
link_up
=
TRUE
;
/*
* The main loop here is based on select. While we are not
* doing anything else but the protocol, this allows extra stuff
...
...
msgtype.c
View file @
ff6d7afa
...
...
@@ -27,7 +27,7 @@ struct pp_msgtype_info pp_msgtype_info[16] = {
"delay_resp"
,
PP_DELAY_RESP_LENGTH
,
PP_NP_GEN
,
PP_E2E_MECH
,
3
,
PP_LOG_REQUEST
},
[
PPM_PDELAY_R_FUP
]
=
{
"pdelay_resp_follow_up"
,
PP_PDELAY_R
_F
UP_LENGTH
,
"pdelay_resp_follow_up"
,
PP_PDELAY_R
ESP_FOLLOW_
UP_LENGTH
,
PP_NP_GEN
,
PP_P2P_MECH
,
5
,
0x7f
},
[
PPM_ANNOUNCE
]
=
{
"announce"
,
PP_ANNOUNCE_LENGTH
,
...
...
proto-ext-whiterabbit/common-fun.c
View file @
ff6d7afa
...
...
@@ -10,7 +10,7 @@
/* We are entering WR handshake, as either master or slave */
void
wr_handshake_init
(
struct
pp_instance
*
ppi
,
int
mode_or_retry
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
switch
(
mode_or_retry
)
{
...
...
proto-ext-whiterabbit/fsm-table.c
View file @
ff6d7afa
...
...
@@ -20,7 +20,7 @@ struct pp_state_table_item pp_state_table[] = {
{
PPS_PRE_MASTER
,
"pre-master"
,
pp_master
,},
{
PPS_MASTER
,
"master"
,
pp_master
,},
{
PPS_PASSIVE
,
"passive"
,
pp_passive
,},
{
PPS_UNCALIBRATED
,
"uncalibrated"
,
pp_
uncalibrated
,},
{
PPS_UNCALIBRATED
,
"uncalibrated"
,
pp_
slave
,},
{
PPS_SLAVE
,
"slave"
,
pp_slave
,},
{
WRS_PRESENT
,
"uncalibrated/wr-present"
,
wr_present
,},
{
WRS_M_LOCK
,
"master/wr-m-lock"
,
wr_m_lock
,},
...
...
proto-ext-whiterabbit/hooks.c
View file @
ff6d7afa
#include <ppsi/ppsi.h>
#include "wr-api.h"
#include "../proto-standard/common-fun.h"
/* ext-whiterabbit must offer its own hooks */
static
int
wr_init
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
static
int
wr_init
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
...
...
@@ -52,8 +51,7 @@ static int wr_open(struct pp_globals *ppg, struct pp_runtime_opts *rt_opts)
/* FIXME check if correct: assign to each instance the same
* wr_data. May I move it to pp_globals? */
INST
(
ppg
,
i
)
->
ext_data
=
ppg
->
global_ext_data
;
INST
(
ppg
,
i
)
->
ext_data
=
ppg
->
global_ext_data
;
if
(
ppi
->
cfg
.
ext
==
PPSI_EXT_WR
)
{
switch
(
ppi
->
role
)
{
case
PPSI_ROLE_MASTER
:
...
...
@@ -73,7 +71,7 @@ static int wr_open(struct pp_globals *ppg, struct pp_runtime_opts *rt_opts)
return
0
;
}
static
int
wr_listening
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
static
int
wr_listening
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
...
...
@@ -82,7 +80,7 @@ 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
p
len
,
static
int
wr_master_msg
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
,
int
msgtype
)
{
MsgSignaling
wrsig_msg
;
...
...
@@ -105,7 +103,7 @@ static int wr_master_msg(struct pp_instance *ppi, unsigned char *pkt, int plen,
/* This is missing in the standard protocol */
case
PPM_SIGNALING
:
msg_unpack_wrsig
(
ppi
,
pkt
,
&
wrsig_msg
,
msg_unpack_wrsig
(
ppi
,
buf
,
&
wrsig_msg
,
&
(
WR_DSPOR
(
ppi
)
->
msgTmpWrMessageID
));
if
((
WR_DSPOR
(
ppi
)
->
msgTmpWrMessageID
==
SLAVE_PRESENT
)
&&
(
WR_DSPOR
(
ppi
)
->
wrConfig
&
WR_M_ONLY
))
{
...
...
@@ -119,7 +117,7 @@ static int wr_master_msg(struct pp_instance *ppi, unsigned char *pkt, int plen,
return
msgtype
;
}
static
int
wr_new_slave
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
static
int
wr_new_slave
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
pp_diag
(
ppi
,
ext
,
2
,
"hook: %s
\n
"
,
__func__
);
wr_servo_init
(
ppi
);
...
...
@@ -161,27 +159,35 @@ static int wr_handle_resp(struct pp_instance *ppi)
return
0
;
}
static
void
wr_s1
(
struct
pp_instance
*
ppi
,
MsgHeader
*
hdr
,
MsgAnnounce
*
ann
)
static
void
wr_s1
(
struct
pp_instance
*
ppi
,
struct
pp_frgn_master
*
frgn_master
)
{
pp_diag
(
ppi
,
ext
,
2
,
"hook: %s
\n
"
,
__func__
);
WR_DSPOR
(
ppi
)
->
parentIsWRnode
=
((
ann
->
ext_specific
&
WR_NODE_MODE
)
!=
NON_WR
);
((
frgn_master
->
ext_specific
&
WR_NODE_MODE
)
!=
NON_WR
);
WR_DSPOR
(
ppi
)
->
parentWrModeOn
=
(
ann
->
ext_specific
&
WR_IS_WR_MODE
)
?
TRUE
:
FALSE
;
(
frgn_master
->
ext_specific
&
WR_IS_WR_MODE
)
?
TRUE
:
FALSE
;
WR_DSPOR
(
ppi
)
->
parentCalibrated
=
((
ann
->
ext_specific
&
WR_IS_CALIBRATED
)
?
1
:
0
);
WR_DSPOR
(
ppi
)
->
parentWrConfig
=
ann
->
ext_specific
&
WR_NODE_MODE
;
((
frgn_master
->
ext_specific
&
WR_IS_CALIBRATED
)
?
1
:
0
);
WR_DSPOR
(
ppi
)
->
parentWrConfig
=
frgn_master
->
ext_specific
&
WR_NODE_MODE
;
DSCUR
(
ppi
)
->
primarySlavePortNumber
=
DSPOR
(
ppi
)
->
portIdentity
.
portNumber
;
}
static
int
wr_execute_slave
(
struct
pp_instance
*
ppi
)
int
wr_execute_slave
(
struct
pp_instance
*
ppi
)
{
pp_diag
(
ppi
,
ext
,
2
,
"hook: %s
\n
"
,
__func__
);
if
(
pp_timeout
(
ppi
,
PP_TO_FAULT
))
wr_servo_reset
(
ppi
);
/* the caller handles ptp state machine */
if
((
ppi
->
state
==
PPS_SLAVE
)
&&
(
WR_DSPOR
(
ppi
)
->
wrConfig
&
WR_S_ONLY
)
&&
(
WR_DSPOR
(
ppi
)
->
parentWrConfig
&
WR_M_ONLY
)
&&
(
!
WR_DSPOR
(
ppi
)
->
wrModeOn
||
!
WR_DSPOR
(
ppi
)
->
parentWrModeOn
))
{
/* We must start the handshake as a WR slave */
wr_handshake_init
(
ppi
,
PPS_SLAVE
);
}
/* The doRestart thing is not used, it seems */
if
(
!
WR_DSPOR
(
ppi
)
->
doRestart
)
return
0
;
...
...
@@ -193,13 +199,19 @@ static int wr_execute_slave(struct pp_instance *ppi)
static
int
wr_handle_announce
(
struct
pp_instance
*
ppi
)
{
pp_diag
(
ppi
,
ext
,
2
,
"hook: %s
\n
"
,
__func__
);
if
((
WR_DSPOR
(
ppi
)
->
wrConfig
&
WR_S_ONLY
)
&&
(
1
/* FIXME: Recommended State, see page 33*/
)
&&
(
WR_DSPOR
(
ppi
)
->
parentWrConfig
&
WR_M_ONLY
)
&&
(
!
WR_DSPOR
(
ppi
)
->
wrModeOn
||
!
WR_DSPOR
(
ppi
)
->
parentWrModeOn
))
{
/* We must start the handshake as a WR slave */
wr_handshake_init
(
ppi
,
PPS_SLAVE
);
if
((
ppi
->
state
==
WRS_PRESENT
)
||
(
ppi
->
state
==
WRS_S_LOCK
)
||
(
ppi
->
state
==
WRS_LOCKED
)
||
(
ppi
->
state
==
WRS_CALIBRATION
)
||
(
ppi
->
state
==
WRS_CALIBRATED
)
||
(
ppi
->
state
==
WRS_RESP_CALIB_REQ
)
||
(
ppi
->
state
==
WRS_WR_LINK_ON
))
{
/* reset announce timeout when in the WR slave states */
pp_timeout_set
(
ppi
,
PP_TO_ANN_RECEIPT
);
}
/* handshake is started in slave mode */
return
0
;
}
...
...
@@ -268,10 +280,68 @@ static void wr_unpack_announce(void *buf, MsgAnnounce *ann)
int
msg_len
=
htons
(
*
(
UInteger16
*
)
(
buf
+
2
));
pp_diag
(
NULL
,
ext
,
2
,
"hook: %s
\n
"
,
__func__
);
if
(
msg_len
>
PP
_ANNOUNCE_LENGTH
)
if
(
msg_len
>
=
WR
_ANNOUNCE_LENGTH
)
msg_unpack_announce_wr_tlv
(
buf
,
ann
);
else
ann
->
ext_specific
=
0
;
}
/* State decision algorithm 9.3.3 Fig 26 with extension for wr */
static
int
wr_state_decision
(
struct
pp_instance
*
ppi
,
int
next_state
)
{
pp_diag
(
ppi
,
ext
,
2
,
"hook: %s
\n
"
,
__func__
);
/*
* if in one of the WR states stay in them,
* they will eventually go back to the normal states
*/
if
((
ppi
->
state
==
WRS_PRESENT
)
||
(
ppi
->
state
==
WRS_M_LOCK
)
||
(
ppi
->
state
==
WRS_S_LOCK
)
||
(
ppi
->
state
==
WRS_LOCKED
)
||
(
ppi
->
state
==
WRS_CALIBRATION
)
||
(
ppi
->
state
==
WRS_CALIBRATED
)
||
(
ppi
->
state
==
WRS_RESP_CALIB_REQ
)
||
(
ppi
->
state
==
WRS_WR_LINK_ON
))
return
ppi
->
state
;
/* else do the normal statemachine */
return
next_state
;
}
static
void
wr_state_change
(
struct
pp_instance
*
ppi
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
pp_diag
(
ppi
,
ext
,
2
,
"hook: %s
\n
"
,
__func__
);
if
((
ppi
->
next_state
==
WRS_PRESENT
)
||
(
ppi
->
next_state
==
WRS_M_LOCK
)
||
(
ppi
->
next_state
==
WRS_S_LOCK
)
||
(
ppi
->
next_state
==
WRS_LOCKED
)
||
(
ppi
->
next_state
==
WRS_CALIBRATION
)
||
(
ppi
->
next_state
==
WRS_CALIBRATED
)
||
(
ppi
->
next_state
==
WRS_RESP_CALIB_REQ
)
||
(
ppi
->
next_state
==
WRS_WR_LINK_ON
))
return
;
/* if we are leaving the WR locked states reset the WR process */
if
((
ppi
->
next_state
!=
ppi
->
state
)
&&
(
wrp
->
wrModeOn
==
TRUE
)
&&
((
ppi
->
state
==
PPS_SLAVE
)
||
(
ppi
->
state
==
PPS_MASTER
)))
{
wrp
->
wrStateTimeout
=
WR_DEFAULT_STATE_TIMEOUT_MS
;
wrp
->
calPeriod
=
WR_DEFAULT_CAL_PERIOD
;
wrp
->
wrModeOn
=
FALSE
;
wrp
->
parentWrConfig
=
NON_WR
;
wrp
->
parentWrModeOn
=
FALSE
;
wrp
->
calibrated
=
!
WR_DEFAULT_PHY_CALIBRATION_REQUIRED
;
if
(
ppi
->
state
==
PPS_SLAVE
)
wrp
->
ops
->
locking_reset
(
ppi
);
}
}
struct
pp_ext_hooks
pp_hooks
=
{
.
init
=
wr_init
,
...
...
@@ -289,4 +359,6 @@ struct pp_ext_hooks pp_hooks = {
#endif
.
pack_announce
=
wr_pack_announce
,
.
unpack_announce
=
wr_unpack_announce
,
.
state_decision
=
wr_state_decision
,
.
state_change
=
wr_state_change
,
};
proto-ext-whiterabbit/state-wr-calibrated.c
View file @
ff6d7afa
...
...
@@ -13,7 +13,7 @@
* We enter here from WRS_CALIBRATION. If master we wait for
* a CALIBRATE message, if slave we wait for LINK_ON.
*/
int
wr_calibrated
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
wr_calibrated
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
MsgSignaling
wrsig_msg
;
...
...
@@ -32,7 +32,7 @@ int wr_calibrated(struct pp_instance *ppi, unsigned char *pkt, int plen)
}
if
(
ppi
->
received_ptp_header
.
messageType
==
PPM_SIGNALING
)
{
msg_unpack_wrsig
(
ppi
,
pkt
,
&
wrsig_msg
,
msg_unpack_wrsig
(
ppi
,
buf
,
&
wrsig_msg
,
&
(
wrp
->
msgTmpWrMessageID
));
if
((
wrp
->
msgTmpWrMessageID
==
CALIBRATE
)
&&
...
...
proto-ext-whiterabbit/state-wr-calibration.c
View file @
ff6d7afa
...
...
@@ -13,7 +13,7 @@
* We enter this state from WRS_M_LOCK or WRS_RESP_CALIB_REQ.
* We send CALIBRATE and do the hardware steps; finally we send CALIBRATED.
*/
int
wr_calibration
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
wr_calibration
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
int
sendmsg
=
0
;
...
...
proto-ext-whiterabbit/state-wr-link-on.c
View file @
ff6d7afa
...
...
@@ -13,7 +13,7 @@
* This is the last WR state: ack the other party and go master or slave.
* There is no timeout nor a check for is_new_state: we just do things once
*/
int
wr_link_on
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
wr_link_on
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
int
e
=
0
;
...
...
proto-ext-whiterabbit/state-wr-locked.c
View file @
ff6d7afa
...
...
@@ -13,7 +13,7 @@
* WR slave: got here from WRS_S_LOCK: send LOCKED, wait for CALIBRATE.
* On timeout resend.
*/
int
wr_locked
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
wr_locked
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
e
=
0
,
sendmsg
=
0
;
MsgSignaling
wrsig_msg
;
...
...
@@ -36,7 +36,7 @@ int wr_locked(struct pp_instance *ppi, unsigned char *pkt, int plen)
if
(
ppi
->
received_ptp_header
.
messageType
==
PPM_SIGNALING
)
{
msg_unpack_wrsig
(
ppi
,
pkt
,
&
wrsig_msg
,
msg_unpack_wrsig
(
ppi
,
buf
,
&
wrsig_msg
,
&
(
wrp
->
msgTmpWrMessageID
));
if
(
wrp
->
msgTmpWrMessageID
==
CALIBRATE
)
...
...
proto-ext-whiterabbit/state-wr-m-lock.c
View file @
ff6d7afa
...
...
@@ -13,7 +13,7 @@
* This the entry point for a WR master: send "LOCK" and wait
* for "LOCKED". On timeout retry sending, for WR_STATE_RETRY times.
*/
int
wr_m_lock
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
wr_m_lock
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
e
=
0
,
sendmsg
=
0
;
MsgSignaling
wrsig_msg
;
...
...
@@ -35,14 +35,14 @@ int wr_m_lock(struct pp_instance *ppi, unsigned char *pkt, int plen)
}
if
(
ppi
->
received_ptp_header
.
messageType
==
PPM_SIGNALING
)
{
msg_unpack_wrsig
(
ppi
,
pkt
,
&
wrsig_msg
,
msg_unpack_wrsig
(
ppi
,
buf
,
&
wrsig_msg
,
&
(
wrp
->
msgTmpWrMessageID
));
if
(
wrp
->
msgTmpWrMessageID
==
LOCKED
)
ppi
->
next_state
=
WRS_CALIBRATION
;
}
ppi
->
next_delay
=
wrp
->
wrStateTimeout
;
return
e
;
...
...
proto-ext-whiterabbit/state-wr-present.c
View file @
ff6d7afa
...
...
@@ -8,7 +8,6 @@
#include <ppsi/ppsi.h>
#include "wr-api.h"
#include "../proto-standard/common-fun.h"
/*
* WRS_PRESENT is the entry point for a WR slave
...
...
@@ -16,13 +15,13 @@
* Here we send SLAVE_PRESENT and wait for LOCK. If timeout,
* resent SLAVE_PRESENT from WR_STATE_RETRY times
*/
int
wr_present
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
wr_present
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
e
=
0
,
sendmsg
=
0
;
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
MsgSignaling
wrsig_msg
;
if
(
ppi
->
is_new_state
)
{
wrp
->
wrStateRetry
=
WR_STATE_RETRY
;
sendmsg
=
1
;
...
...
@@ -39,8 +38,7 @@ int wr_present(struct pp_instance *ppi, unsigned char *pkt, int plen)
}
if
(
ppi
->
received_ptp_header
.
messageType
==
PPM_SIGNALING
)
{
msg_unpack_wrsig
(
ppi
,
pkt
,
&
wrsig_msg
,
msg_unpack_wrsig
(
ppi
,
buf
,
&
wrsig_msg
,
&
(
wrp
->
msgTmpWrMessageID
));
if
(
wrp
->
msgTmpWrMessageID
==
LOCK
)
...
...
@@ -48,7 +46,7 @@ int wr_present(struct pp_instance *ppi, unsigned char *pkt, int plen)
}
if
(
e
==
0
)
st_com
_execute_slave
(
ppi
);
wr
_execute_slave
(
ppi
);
else
{
/* nothing, just stay here again */
}
...
...
proto-ext-whiterabbit/state-wr-resp-calib-req.c
View file @
ff6d7afa
...
...
@@ -9,7 +9,7 @@
#include <ppsi/ppsi.h>
#include "wr-api.h"
int
wr_resp_calib_req
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
wr_resp_calib_req
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
MsgSignaling
wrsig_msg
;
...
...
@@ -37,7 +37,7 @@ int wr_resp_calib_req(struct pp_instance *ppi, unsigned char *pkt, int plen)
if
(
ppi
->
received_ptp_header
.
messageType
==
PPM_SIGNALING
)
{
msg_unpack_wrsig
(
ppi
,
pkt
,
&
wrsig_msg
,
msg_unpack_wrsig
(
ppi
,
buf
,
&
wrsig_msg
,
&
(
wrp
->
msgTmpWrMessageID
));
if
(
wrp
->
msgTmpWrMessageID
==
CALIBRATED
)
{
...
...
proto-ext-whiterabbit/state-wr-s-lock.c
View file @
ff6d7afa
...
...
@@ -9,14 +9,14 @@
#include <ppsi/ppsi.h>
#include "wr-api.h"
int
wr_s_lock
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
wr_s_lock
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
int
enable
=
0
;
int
poll_ret
;
if
(
ppi
->
is_new_state
)
{
wrp
->
wrStateRetry
=
WR_STATE_RETRY
;
wrp
->
wrStateRetry
=
WR_STATE_RETRY
;
enable
=
1
;
}
else
if
(
pp_timeout
(
ppi
,
PP_TO_EXT_0
))
{
wrp
->
ops
->
locking_disable
(
ppi
);
...
...
proto-ext-whiterabbit/wr-api.h
View file @
ff6d7afa
...
...
@@ -11,8 +11,7 @@
/* Please increment WRS_PPSI_SHMEM_VERSION if you change any exported data
* structure */
#define WRS_PPSI_SHMEM_VERSION 20
/* Replace cField, t4_cf and t6_cf with
syncCF */
#define WRS_PPSI_SHMEM_VERSION 30
/* added HAL_PORT_STATE_RESET to hal */
/* Don't include the Following when this file is included in assembler. */
#ifndef __ASSEMBLY__
...
...
@@ -52,7 +51,6 @@ struct wr_dsport {
FixedDelta
otherNodeDeltaTx
;
FixedDelta
otherNodeDeltaRx
;
Boolean
doRestart
;
Boolean
linkUP
;
};
/* This uppercase name matches "DSPOR(ppi)" used by standard protocol */
...
...
@@ -86,21 +84,21 @@ void msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
int
msg_issue_wrsig
(
struct
pp_instance
*
ppi
,
Enumeration16
wr_msg_id
);
/* White rabbit state functions */
int
wr_present
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
wr_m_lock
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
wr_s_lock
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
wr_locked
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
wr_calibration
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
wr_calibrated
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
wr_resp_calib_req
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
wr_link_on
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
int
wr_present
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
wr_m_lock
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
wr_s_lock
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
wr_locked
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
wr_calibration
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
wr_calibrated
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
wr_resp_calib_req
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
wr_link_on
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
wr_abscal
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
plen
);
/* Common functions, used by various states and hooks */
void
wr_handshake_init
(
struct
pp_instance
*
ppi
,
int
mode
);
void
wr_handshake_fail
(
struct
pp_instance
*
ppi
);
/* goto non-wr */
int
wr_handshake_retry
(
struct
pp_instance
*
ppi
);
/* 1 == retry; 0 == failed */
int
wr_execute_slave
(
struct
pp_instance
*
ppi
);
struct
wr_servo_state
;
/* White Rabbit hw-dependent functions (code in arch-wrpc and arch-wrs) */
...
...
@@ -108,6 +106,7 @@ struct wr_operations {
int
(
*
locking_enable
)(
struct
pp_instance
*
ppi
);
int
(
*
locking_poll
)(
struct
pp_instance
*
ppi
,
int
grandmaster
);
int
(
*
locking_disable
)(
struct
pp_instance
*
ppi
);
int
(
*
locking_reset
)(
struct
pp_instance
*
ppi
);
int
(
*
enable_ptracker
)(
struct
pp_instance
*
ppi
);
int
(
*
adjust_in_progress
)(
void
);
...
...
proto-ext-whiterabbit/wr-msg.c
View file @
ff6d7afa
...
...
@@ -57,26 +57,9 @@ void msg_pack_announce_wr_tlv(struct pp_instance *ppi)
{
void
*
buf
;
UInteger16
wr_flags
=
0
;
int
locked
,
class
=
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
;
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
buf
=
ppi
->
tx_ptp
;
/* GM: update clock Class, according to whether we are locked or not */
if
(
class
<
PP_CLASS_DEFAULT
)
{
locked
=
wrp
->
ops
->
locking_poll
(
ppi
,
1
);
if
(
locked
==
WR_SPLL_READY
)
class
=
PP_CLASS_WR_GM_LOCKED
;
else
class
=
PP_CLASS_WR_GM_UNLOCKED
;
m1
(
ppi
);
if
(
class
!=
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
)
{
pp_error
(
"New class %i
\n
"
,
class
);
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
=
class
;
*
(
UInteger8
*
)
(
buf
+
48
)
=
class
;
}
}
/* Change length */
*
(
UInteger16
*
)(
buf
+
2
)
=
htons
(
WR_ANNOUNCE_LENGTH
);
...
...
@@ -124,7 +107,8 @@ void msg_unpack_announce_wr_tlv(void *buf, MsgAnnounce *ann)
tlv_versionNumber
==
WR_TLV_WR_VERSION_NUMBER
&&
tlv_wrMessageID
==
ANN_SUFIX
)
{
ann
->
ext_specific
=
(
UInteger16
)
get_be16
(
buf
+
76
);
}
}
else
ann
->
ext_specific
=
0
;
}
/* White Rabbit: packing WR Signaling messages*/
...
...
proto-standard/Makefile
View file @
ff6d7afa
...
...
@@ -11,7 +11,6 @@ OBJ-y += $D/fsm-table.o \
$D
/state-listening.o
\
$D
/state-master.o
\
$D
/state-passive.o
\
$D
/state-uncalibrated.o
\
$D
/state-slave.o
\
$D
/common-fun.o
\
$D
/bmc.o
\
...
...
proto-standard/bmc.c
View file @
ff6d7afa
This diff is collapsed.
Click to expand it.
proto-standard/common-fun.c
View file @
ff6d7afa
...
...
@@ -71,70 +71,6 @@ void pp_prepare_pointers(struct pp_instance *ppi)
}
}
/* Called by listening, passive, slave, uncalibrated */
int
st_com_execute_slave
(
struct
pp_instance
*
ppi
)
{
int
ret
=
0
;
if
(
pp_hooks
.
execute_slave
)
ret
=
pp_hooks
.
execute_slave
(
ppi
);
if
(
ret
==
1
)
/* done: just return */
return
0
;
if
(
ret
<
0
)
return
ret
;
if
(
pp_timeout
(
ppi
,
PP_TO_ANN_RECEIPT
)
||
pp_timeout
(
ppi
,
PP_TO_FAULT
))
{
/*
* Note: TO_FAULTY == SYNCHRONIZATION_FAULT
* should move us to UNCALIBRATED (not implemented)
*/
ppi
->
frgn_rec_num
=
0
;
if
(
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
!=
PP_CLASS_SLAVE_ONLY
&&
(
ppi
->
role
!=
PPSI_ROLE_SLAVE
))
{
ppi
->
next_state
=
PPS_MASTER
;
}
else
{
ppi
->
next_state
=
PPS_LISTENING
;
pp_timeout_set
(
ppi
,
PP_TO_ANN_RECEIPT
);
}
}
return
0
;
}
/* Called by slave and uncalibrated */
int
st_com_slave_handle_sync
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
len
)
{
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
MsgSync
sync
;
if
(
!
(
ppi
->
flags
&
PPI_FLAG_FROM_CURRENT_PARENT
))
return
0
;
/* t2 may be overriden by follow-up, save it immediately */
ppi
->
t2
=
ppi
->
last_rcv_time
;
msg_unpack_sync
(
buf
,
&
sync
);
if
((
hdr
->
flagField
[
0
]
&
PP_TWO_STEP_FLAG
)
!=
0
)
{
ppi
->
flags
|=
PPI_FLAG_WAITING_FOR_F_UP
;
ppi
->
recv_sync_sequence_id
=
hdr
->
sequenceId
;
/* for two-step, the stamp comes later */
ppi
->
t1
=
hdr
->
cField
;
/* most likely 0 */
return
0
;
}
/* one-step folllows */
ppi
->
flags
&=
~
PPI_FLAG_WAITING_FOR_F_UP
;
ppi
->
t1
=
sync
.
originTimestamp
;
pp_time_add
(
&
ppi
->
t1
,
&
hdr
->
cField
);
ppi
->
syncCF
=
0
;
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
pp_servo_got_psync
(
ppi
);
else
pp_servo_got_sync
(
ppi
);
return
0
;
}
static
int
presp_call_servo
(
struct
pp_instance
*
ppi
)
{
int
ret
=
0
;
...
...
@@ -151,23 +87,59 @@ static int presp_call_servo(struct pp_instance *ppi)
return
ret
;
}
int
st_com_peer_handle_pres
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
st_com_check_announce_receive_timeout
(
struct
pp_instance
*
ppi
)
{
struct
pp_globals
*
ppg
=
GLBS
(
ppi
);
int
is_gm
=
1
;
int
i
;
if
(
pp_timeout
(
ppi
,
PP_TO_ANN_RECEIPT
))
{
/* 9.2.6.11 b) reset timeout when an announce timeout happended */
pp_timeout_set
(
ppi
,
PP_TO_ANN_RECEIPT
);
if
(
DSDEF
(
ppi
)
->
clockQuality
.
clockClass
!=
PP_CLASS_SLAVE_ONLY
&&
(
ppi
->
role
!=
PPSI_ROLE_SLAVE
))
{
if
(
DSDEF
(
ppi
)
->
numberPorts
>
1
)
{
for
(
i
=
0
;
i
<
ppg
->
defaultDS
->
numberPorts
;
i
++
)
{
if
((
INST
(
ppg
,
i
)
->
state
==
PPS_UNCALIBRATED
)
||
(
INST
(
ppg
,
i
)
->
state
==
PPS_SLAVE
))
is_gm
=
0
;
}
if
(
is_gm
)
bmc_m1
(
ppi
);
else
bmc_m3
(
ppi
);
}
else
bmc_m1
(
ppi
);
ppi
->
next_state
=
PPS_MASTER
;
}
else
{
ppi
->
next_state
=
PPS_LISTENING
;
}
}
return
0
;
}
int
st_com_peer_handle_pres
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
MsgPDelayResp
resp
;
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
int
e
=
0
;
/* if not in P2P mode, just return */
if
(
!
CONFIG_HAS_P2P
||
ppi
->
mech
!=
PP_P2P_MECH
)
return
0
;
msg_unpack_pdelay_resp
(
buf
,
&
resp
);
if
((
memcmp
(
&
DSPOR
(
ppi
)
->
portIdentity
.
clockIdentity
,
&
resp
.
requestingPortIdentity
.
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
)
==
0
)
&&
if
((
bmc_idcmp
(
&
DSPOR
(
ppi
)
->
portIdentity
.
clockIdentity
,
&
resp
.
requestingPortIdentity
.
clockIdentity
)
==
0
)
&&
((
ppi
->
sent_seq
[
PPM_PDELAY_REQ
])
==
hdr
->
sequenceId
)
&&
(
DSPOR
(
ppi
)
->
portIdentity
.
portNumber
==
resp
.
requestingPortIdentity
.
portNumber
)
&&
(
ppi
->
flags
&
PPI_FLAG_FROM_CURRENT_PARENT
))
{
(
msg_from_current_master
(
ppi
)
))
{
ppi
->
t4
=
resp
.
requestReceiptTimestamp
;
pp_time_add
(
&
ppi
->
t4
,
&
hdr
->
cField
);
...
...
@@ -193,24 +165,26 @@ int st_com_peer_handle_pres(struct pp_instance *ppi, unsigned char *buf,
return
e
;
}
int
st_com_peer_handle_pres_followup
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
p
len
)
void
*
buf
,
int
len
)
{
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
MsgPDelayRespFollowUp
respFllw
;
int
e
=
0
;
/* if not in P2P mode, just return */
if
(
!
CONFIG_HAS_P2P
||
ppi
->
mech
!=
PP_P2P_MECH
)
return
0
;
msg_unpack_pdelay_resp_follow_up
(
buf
,
&
respFllw
);
if
((
memcmp
(
&
DSPOR
(
ppi
)
->
portIdentity
.
clockIdentity
,
&
respFllw
.
requestingPortIdentity
.
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
)
==
0
)
&&
if
((
bmc_idcmp
(
&
DSPOR
(
ppi
)
->
portIdentity
.
clockIdentity
,
&
respFllw
.
requestingPortIdentity
.
clockIdentity
)
==
0
)
&&
((
ppi
->
sent_seq
[
PPM_PDELAY_REQ
])
==
hdr
->
sequenceId
)
&&
(
DSPOR
(
ppi
)
->
portIdentity
.
portNumber
==
respFllw
.
requestingPortIdentity
.
portNumber
)
&&
(
ppi
->
flags
&
PPI_FLAG_FROM_CURRENT_PARENT
))
{
(
msg_from_current_master
(
ppi
)
))
{
ppi
->
t5
=
respFllw
.
responseOriginTimestamp
;
pp_time_add
(
&
ppi
->
t5
,
&
hdr
->
cField
);
...
...
@@ -224,11 +198,15 @@ int st_com_peer_handle_pres_followup(struct pp_instance *ppi,
return
e
;
}
int
st_com_peer_handle_preq
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
st_com_peer_handle_preq
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
e
=
0
;
/* if not in P2P mode, just return */
if
(
!
CONFIG_HAS_P2P
||
ppi
->
mech
!=
PP_P2P_MECH
)
return
0
;
if
(
pp_hooks
.
handle_preq
)
e
=
pp_hooks
.
handle_preq
(
ppi
);
if
(
e
)
...
...
@@ -240,64 +218,12 @@ int st_com_peer_handle_preq(struct pp_instance *ppi, unsigned char *buf,
return
0
;
}
/* Called by slave and uncalibrated */
int
st_com_slave_handle_followup
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
len
)
int
st_com_handle_announce
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
MsgFollowUp
follow
;
int
ret
=
0
;
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
if
(
!
(
ppi
->
flags
&
PPI_FLAG_FROM_CURRENT_PARENT
))
{
pp_error
(
"%s: Follow up message is not from current parent
\n
"
,
__func__
);
return
0
;
}
bmc_add_frgn_master
(
ppi
,
buf
,
len
);
if
(
!
(
ppi
->
flags
&
PPI_FLAG_WAITING_FOR_F_UP
))
{
pp_error
(
"%s: Slave was not waiting a follow up message
\n
"
,
__func__
);
return
0
;
}
if
(
ppi
->
recv_sync_sequence_id
!=
hdr
->
sequenceId
)
{
pp_error
(
"%s: SequenceID %d doesn't match last Sync message %d
\n
"
,
__func__
,
hdr
->
sequenceId
,
ppi
->
recv_sync_sequence_id
);
return
0
;
}
msg_unpack_follow_up
(
buf
,
&
follow
);
ppi
->
flags
&=
~
PPI_FLAG_WAITING_FOR_F_UP
;
/* t1 for calculations is T1 + Csyn + Cful -- see README-cfield */
pp_time_add
(
&
ppi
->
t1
,
&
follow
.
preciseOriginTimestamp
);
pp_time_add
(
&
ppi
->
t1
,
&
hdr
->
cField
);
ppi
->
syncCF
=
hdr
->
cField
.
scaled_nsecs
;
/* for diag about TC */
/* Call the extension; it may do it all and ask to return */
if
(
pp_hooks
.
handle_followup
)
ret
=
pp_hooks
.
handle_followup
(
ppi
,
&
ppi
->
t1
);
if
(
ret
==
1
)
return
0
;
if
(
ret
<
0
)
return
ret
;
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
pp_servo_got_psync
(
ppi
);
else
pp_servo_got_sync
(
ppi
);
return
0
;
}
/*
* Called by master, listenting, passive.
* FIXME: this must be implemented to support one-step masters
*/
int
st_com_master_handle_sync
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
len
)
{
/* No more used: follow up is sent right after the corresponding sync */
if
(
pp_hooks
.
handle_announce
)
return
pp_hooks
.
handle_announce
(
ppi
);
return
0
;
}
...
...
proto-standard/common-fun.h
View file @
ff6d7afa
...
...
@@ -12,40 +12,30 @@
#include <ppsi/ppsi.h>
/* Contains all functions common to more than one state */
int
st_com_check_announce_receive_timeout
(
struct
pp_instance
*
ppi
);
/* returns -1 in case of error, see below */
int
st_com_execute_slave
(
struct
pp_instance
*
ppi
);
/* Each of the following "handle" functions" return 0 in case of correct
* message, -1 in case the message contained in buf is not proper (e.g. size
* is not the expected one
*/
int
st_com_slave_handle_sync
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
len
);
int
st_com_master_handle_sync
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
len
);
int
st_com_slave_handle_followup
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
len
);
int
st_com_peer_handle_preq
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
st_com_peer_handle_preq
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
st_com_peer_handle_pres
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
st_com_peer_handle_pres
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
st_com_peer_handle_pres_followup
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
len
);
void
*
buf
,
int
len
);
int
st_com_handle_announce
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
int
__send_and_log
(
struct
pp_instance
*
ppi
,
int
msglen
,
int
chtype
);
/* Count successfully received PTP packets */
static
inline
int
__recv_and_count
(
struct
pp_instance
*
ppi
,
void
*
pkt
,
int
len
,
static
inline
int
__recv_and_count
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
,
struct
pp_time
*
t
)
{
int
ret
;
ret
=
ppi
->
n_ops
->
recv
(
ppi
,
pkt
,
len
,
t
);
ret
=
ppi
->
n_ops
->
recv
(
ppi
,
buf
,
len
,
t
);
if
(
ret
>
0
)
ppi
->
ptp_rx_count
++
;
return
ret
;
...
...
proto-standard/fsm-lib.c
View file @
ff6d7afa
...
...
@@ -79,12 +79,44 @@ int pp_lib_may_issue_sync(struct pp_instance *ppi)
int
pp_lib_may_issue_announce
(
struct
pp_instance
*
ppi
)
{
struct
DSTimeProperties
*
prop
=
DSPRO
(
ppi
);
int
ret
=
0
;
int
offset
,
leap59
,
leap61
;
int
hours
,
minutes
,
seconds
;
int
e
;
if
(
!
pp_timeout
(
ppi
,
PP_TO_ANN_SEND
))
return
0
;
pp_timeout_set
(
ppi
,
PP_TO_ANN_SEND
);
/* this check has to be done here since the
* update of the properties might have not
* happened before sending
*/
if
(
prop
->
ptpTimescale
)
{
ret
=
ppi
->
t_ops
->
get_utc_time
(
ppi
,
&
hours
,
&
minutes
,
&
seconds
);
if
(
ret
)
{
pp_diag
(
ppi
,
frames
,
1
,
"Could not get UTC time from system, taking received flags
\n
"
);
}
else
{
/* for 2 announce intervals after midnight, get the offset from the system */
if
((
hours
==
00
)
&&
(
minutes
==
00
)
&&
(
seconds
<=
(
0
+
(
2
*
(
1
<<
ppi
->
portDS
->
logAnnounceInterval
)))))
{
pp_diag
(
ppi
,
frames
,
2
,
"short after midnight, taking local offset
\n
"
);
ret
=
ppi
->
t_ops
->
get_utc_offset
(
ppi
,
&
offset
,
&
leap59
,
&
leap61
);
if
(
ret
)
{
pp_diag
(
ppi
,
frames
,
1
,
"Could not get UTC offset from system
\n
"
);
}
else
{
prop
->
currentUtcOffset
=
offset
;
}
prop
->
leap59
=
FALSE
;
prop
->
leap61
=
FALSE
;
}
}
}
e
=
pp_vlan_issue_announce
(
ppi
);
if
(
e
)
pp_diag
(
ppi
,
frames
,
1
,
"could not send announce
\n
"
);
...
...
@@ -108,53 +140,4 @@ int pp_lib_may_issue_request(struct pp_instance *ppi)
return
0
;
}
/* Called by this file, basically when an announce is got, all states */
static
void
__lib_add_foreign
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
)
{
int
i
;
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
/* Check if foreign master is already known */
for
(
i
=
0
;
i
<
ppi
->
frgn_rec_num
;
i
++
)
{
if
(
!
memcmp
(
&
hdr
->
sourcePortIdentity
,
&
ppi
->
frgn_master
[
i
].
port_id
,
sizeof
(
hdr
->
sourcePortIdentity
)))
{
/* already in Foreign master data set, update info */
msg_copy_header
(
&
ppi
->
frgn_master
[
i
].
hdr
,
hdr
);
msg_unpack_announce
(
buf
,
&
ppi
->
frgn_master
[
i
].
ann
);
return
;
}
}
/* New foreign master */
if
(
ppi
->
frgn_rec_num
<
PP_NR_FOREIGN_RECORDS
)
ppi
->
frgn_rec_num
++
;
/* FIXME: replace the worst */
i
=
ppi
->
frgn_rec_num
-
1
;
/* Copy new foreign master data set from announce message */
memcpy
(
&
ppi
->
frgn_master
[
i
].
port_id
,
&
hdr
->
sourcePortIdentity
,
sizeof
(
hdr
->
sourcePortIdentity
));
/*
* header and announce field of each Foreign Master are
* useful to run Best Master Clock Algorithm
*/
msg_copy_header
(
&
ppi
->
frgn_master
[
i
].
hdr
,
hdr
);
msg_unpack_announce
(
buf
,
&
ppi
->
frgn_master
[
i
].
ann
);
pp_diag
(
ppi
,
bmc
,
1
,
"New foreign Master %i added
\n
"
,
i
);
}
int
pp_lib_handle_announce
(
struct
pp_instance
*
ppi
,
unsigned
char
*
buf
,
int
len
)
{
__lib_add_foreign
(
ppi
,
buf
);
ppi
->
next_state
=
bmc
(
ppi
);
/* got a new announce: run bmc */
pp_timeout_set
(
ppi
,
PP_TO_ANN_RECEIPT
);
if
(
pp_hooks
.
handle_announce
)
return
pp_hooks
.
handle_announce
(
ppi
);
return
0
;
}
proto-standard/fsm-table.c
View file @
ff6d7afa
...
...
@@ -21,7 +21,7 @@ struct pp_state_table_item pp_state_table[] __attribute__((weak)) = {
{
PPS_PRE_MASTER
,
"pre-master"
,
pp_master
,},
{
PPS_MASTER
,
"master"
,
pp_master
,},
{
PPS_PASSIVE
,
"passive"
,
pp_passive
,},
{
PPS_UNCALIBRATED
,
"uncalibrated"
,
pp_
uncalibrated
,},
{
PPS_UNCALIBRATED
,
"uncalibrated"
,
pp_
slave
,},
{
PPS_SLAVE
,
"slave"
,
pp_slave
,},
{
PPS_END_OF_TABLE
,}
};
proto-standard/msg.c
View file @
ff6d7afa
...
...
@@ -9,8 +9,20 @@
#include <ppsi/ppsi.h>
#include "common-fun.h"
/* return 1 if the frame is from the current master, else 0 */
int
msg_from_current_master
(
struct
pp_instance
*
ppi
)
{
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
if
(
!
bmc_pidcmp
(
&
DSPAR
(
ppi
)
->
parentPortIdentity
,
&
hdr
->
sourcePortIdentity
))
return
1
;
else
return
0
;
}
/* Unpack header from in buffer to receieved_ptp_header field */
int
msg_unpack_header
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
p
len
)
int
msg_unpack_header
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
uint32_t
lsb
,
msb
;
...
...
@@ -35,20 +47,6 @@ int msg_unpack_header(struct pp_instance *ppi, void *buf, int plen)
hdr
->
sequenceId
=
htons
(
*
(
UInteger16
*
)
(
buf
+
30
));
hdr
->
logMessageInterval
=
(
*
(
Integer8
*
)
(
buf
+
33
));
/*
* This FLAG_FROM_CURRENT_PARENT must be killed. Meanwhile, say it's
* from current parent if we have no current parent, so the rest works
*/
if
(
!
DSPAR
(
ppi
)
->
parentPortIdentity
.
portNumber
||
(
!
memcmp
(
&
DSPAR
(
ppi
)
->
parentPortIdentity
.
clockIdentity
,
&
hdr
->
sourcePortIdentity
.
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
)
&&
(
DSPAR
(
ppi
)
->
parentPortIdentity
.
portNumber
==
hdr
->
sourcePortIdentity
.
portNumber
)))
ppi
->
flags
|=
PPI_FLAG_FROM_CURRENT_PARENT
;
else
ppi
->
flags
&=
~
PPI_FLAG_FROM_CURRENT_PARENT
;
return
0
;
}
...
...
@@ -111,6 +109,7 @@ int msg_pack_sync(struct pp_instance *ppi, struct pp_time *orig_tstamp)
*
(
UInteger16
*
)
(
buf
+
30
)
=
htons
(
ppi
->
sent_seq
[
PPM_SYNC
]);
/* Sync message */
memset
((
buf
+
34
),
0
,
10
);
*
(
UInteger16
*
)(
buf
+
34
)
=
htons
(
orig_tstamp
->
secs
>>
32
);
*
(
UInteger32
*
)(
buf
+
36
)
=
htonl
(
orig_tstamp
->
secs
);
*
(
UInteger32
*
)(
buf
+
40
)
=
htonl
(
orig_tstamp
->
scaled_nsecs
>>
16
);
...
...
@@ -173,7 +172,7 @@ static int msg_pack_announce(struct pp_instance *ppi)
*
(
UInteger16
*
)
(
buf
+
30
)
=
htons
(
ppi
->
sent_seq
[
PPM_ANNOUNCE
]);
/* Announce message */
memset
((
buf
+
34
),
0
,
1
0
);
memset
((
buf
+
34
),
0
,
3
0
);
*
(
Integer16
*
)
(
buf
+
44
)
=
htons
(
DSPRO
(
ppi
)
->
currentUtcOffset
);
*
(
UInteger8
*
)
(
buf
+
47
)
=
DSPAR
(
ppi
)
->
grandmasterPriority1
;
*
(
UInteger8
*
)
(
buf
+
48
)
=
DSPAR
(
ppi
)
->
grandmasterClockQuality
.
clockClass
;
...
...
@@ -183,7 +182,9 @@ static int msg_pack_announce(struct pp_instance *ppi)
*
(
UInteger8
*
)
(
buf
+
52
)
=
DSPAR
(
ppi
)
->
grandmasterPriority2
;
memcpy
((
buf
+
53
),
&
DSPAR
(
ppi
)
->
grandmasterIdentity
,
PP_CLOCK_IDENTITY_LENGTH
);
*
(
UInteger16
*
)
(
buf
+
61
)
=
htons
(
DSCUR
(
ppi
)
->
stepsRemoved
);
/* WORKAROUND 16bit casting doesn't seem to work on unaligned addresses */
*
(
UInteger8
*
)
(
buf
+
61
)
=
(
UInteger8
)(
DSCUR
(
ppi
)
->
stepsRemoved
>>
8
);
*
(
UInteger8
*
)
(
buf
+
62
)
=
(
UInteger8
)
DSCUR
(
ppi
)
->
stepsRemoved
;
*
(
Enumeration8
*
)
(
buf
+
63
)
=
DSPRO
(
ppi
)
->
timeSource
;
if
(
pp_hooks
.
pack_announce
)
...
...
@@ -211,11 +212,16 @@ void msg_unpack_announce(void *buf, MsgAnnounce *ann)
ann
->
grandmasterPriority2
=
*
(
UInteger8
*
)
(
buf
+
52
);
memcpy
(
&
ann
->
grandmasterIdentity
,
(
buf
+
53
),
PP_CLOCK_IDENTITY_LENGTH
);
ann
->
stepsRemoved
=
htons
(
*
(
UInteger16
*
)
(
buf
+
61
));
/* WORKAROUND htons doesn't seem to work on unaligned addresses */
ann
->
stepsRemoved
=
*
(
UInteger8
*
)(
buf
+
61
);
ann
->
stepsRemoved
=
(
ann
->
stepsRemoved
<<
8
)
+
*
(
UInteger8
*
)(
buf
+
62
);
ann
->
timeSource
=
*
(
Enumeration8
*
)
(
buf
+
63
);
/* this can fill in extention specific flags otherwise just zero them*/
if
(
pp_hooks
.
unpack_announce
)
pp_hooks
.
unpack_announce
(
buf
,
ann
);
else
ann
->
ext_specific
=
0
;
}
/* Pack Follow Up message into out buffer of ppi*/
...
...
@@ -229,6 +235,7 @@ static int msg_pack_follow_up(struct pp_instance *ppi,
*
(
UInteger16
*
)
(
buf
+
30
)
=
htons
(
ppi
->
sent_seq
[
PPM_SYNC
]);
/* Follow Up message */
memset
((
buf
+
34
),
0
,
10
);
*
(
UInteger16
*
)(
buf
+
34
)
=
htons
(
prec_orig_tstamp
->
secs
>>
32
);
*
(
UInteger32
*
)(
buf
+
36
)
=
htonl
(
prec_orig_tstamp
->
secs
);
*
(
UInteger32
*
)(
buf
+
40
)
=
htonl
(
prec_orig_tstamp
->
scaled_nsecs
>>
16
);
...
...
@@ -258,6 +265,7 @@ static int msg_pack_pdelay_resp_follow_up(struct pp_instance *ppi,
*
(
UInteger16
*
)
(
buf
+
30
)
=
htons
(
hdr
->
sequenceId
);
/* requestReceiptTimestamp */
memset
((
buf
+
34
),
0
,
20
);
*
(
UInteger16
*
)(
buf
+
34
)
=
htons
(
prec_orig_tstamp
->
secs
>>
32
);
*
(
UInteger32
*
)(
buf
+
36
)
=
htonl
(
prec_orig_tstamp
->
secs
);
*
(
UInteger32
*
)(
buf
+
40
)
=
htonl
(
prec_orig_tstamp
->
scaled_nsecs
>>
16
);
...
...
@@ -318,6 +326,7 @@ static int msg_pack_delay_req(struct pp_instance *ppi,
*
(
UInteger16
*
)
(
buf
+
30
)
=
htons
(
ppi
->
sent_seq
[
PPM_DELAY_REQ
]);
/* Delay_req message - we may send zero instead */
memset
((
buf
+
34
),
0
,
10
);
*
(
UInteger16
*
)
(
buf
+
34
)
=
htons
(
now
->
secs
>>
32
);
*
(
UInteger32
*
)
(
buf
+
36
)
=
htonl
(
now
->
secs
);
*
(
UInteger32
*
)
(
buf
+
40
)
=
htonl
(
now
->
scaled_nsecs
>>
16
);
...
...
@@ -336,10 +345,10 @@ static int msg_pack_pdelay_req(struct pp_instance *ppi,
*
(
UInteger16
*
)
(
buf
+
30
)
=
htons
(
ppi
->
sent_seq
[
PPM_PDELAY_REQ
]);
/* PDelay_req message - we may send zero instead */
memset
((
buf
+
34
),
0
,
20
);
*
(
UInteger16
*
)
(
buf
+
34
)
=
htons
(
now
->
secs
>>
32
);
*
(
UInteger32
*
)
(
buf
+
36
)
=
htonl
(
now
->
secs
);
*
(
UInteger32
*
)
(
buf
+
40
)
=
htonl
(
now
->
scaled_nsecs
>>
16
);
memset
(
buf
+
44
,
0
,
10
);
/* reserved to match pdelay_resp length */
return
len
;
}
...
...
@@ -360,6 +369,7 @@ static int msg_pack_pdelay_resp(struct pp_instance *ppi,
=
htonl
(
rcv_tstamp
->
scaled_nsecs
&
0xffff
);
/* requestReceiptTimestamp */
memset
((
buf
+
34
),
0
,
20
);
*
(
UInteger16
*
)
(
buf
+
34
)
=
htons
(
rcv_tstamp
->
secs
>>
32
);
*
(
UInteger32
*
)
(
buf
+
36
)
=
htonl
(
rcv_tstamp
->
secs
);
*
(
UInteger32
*
)
(
buf
+
40
)
=
htonl
(
rcv_tstamp
->
scaled_nsecs
>>
16
);
...
...
@@ -388,6 +398,7 @@ static int msg_pack_delay_resp(struct pp_instance *ppi,
*
(
UInteger16
*
)
(
buf
+
30
)
=
htons
(
hdr
->
sequenceId
);
/* Delay_resp message */
memset
((
buf
+
34
),
0
,
20
);
*
(
UInteger16
*
)(
buf
+
34
)
=
htons
(
rcv_tstamp
->
secs
>>
32
);
*
(
UInteger32
*
)(
buf
+
36
)
=
htonl
(
rcv_tstamp
->
secs
);
*
(
UInteger32
*
)(
buf
+
40
)
=
htonl
(
rcv_tstamp
->
scaled_nsecs
>>
16
);
...
...
proto-standard/open-close.c
View file @
ff6d7afa
...
...
@@ -14,8 +14,8 @@
struct
pp_runtime_opts
__pp_default_rt_opts
=
{
.
clock_quality
=
{
.
clockClass
=
PP_CLASS_DEFAULT
,
.
clockAccuracy
=
PP_
DEFAULT_CLOCK_ACCURACY
,
.
offsetScaledLogVariance
=
PP_
DEFAULT_CLOCK_VARIANCE
,
.
clockAccuracy
=
PP_
ACCURACY_DEFAULT
,
.
offsetScaledLogVariance
=
PP_
VARIANCE_DEFAULT
,
},
.
flags
=
PP_DEFAULT_FLAGS
,
.
ap
=
PP_DEFAULT_AP
,
...
...
proto-standard/servo.c
View file @
ff6d7afa
...
...
@@ -20,8 +20,6 @@ void pp_servo_init(struct pp_instance *ppi)
int
d
;
SRV
(
ppi
)
->
mpd_fltr
.
s_exp
=
0
;
/* clears meanPathDelay filter */
ppi
->
frgn_rec_num
=
0
;
/* no known master */
DSPAR
(
ppi
)
->
parentPortIdentity
.
portNumber
=
0
;
/* invalid */
if
(
ppi
->
t_ops
->
init_servo
)
{
/* The system may pre-set us to keep current frequency */
...
...
proto-standard/state-disabled.c
View file @
ff6d7afa
...
...
@@ -8,7 +8,7 @@
#include <ppsi/ppsi.h>
int
pp_disabled
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
pp_disabled
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
/* nothing to do */
ppi
->
next_delay
=
PP_DEFAULT_NEXT_DELAY_MS
;
...
...
proto-standard/state-faulty.c
View file @
ff6d7afa
...
...
@@ -13,7 +13,7 @@
* PTP_INITIALIZING state after a grace period.
*/
int
pp_faulty
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
pp_faulty
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
if
(
pp_timeout
(
ppi
,
PP_TO_FAULT
))
{
ppi
->
next_state
=
PPS_INITIALIZING
;
...
...
proto-standard/state-initializing.c
View file @
ff6d7afa
...
...
@@ -12,11 +12,11 @@
* Initialize parentDS
*/
static
void
init_parent_ds
(
struct
pp_instance
*
ppi
)
{
{
/* 8.2.3.2 */
DSPAR
(
ppi
)
->
parentPortIdentity
.
clockIdentity
=
DSDEF
(
ppi
)
->
clockIdentity
;
/* FIXME: portNumber ? */
DSPAR
(
ppi
)
->
parentPortIdentity
.
portNumber
=
0
;
/* 8.2.3.3 skipped (parentStats is not used) */
/* 8.2.3.4 */
DSPAR
(
ppi
)
->
observedParentOffsetScaledLogVariance
=
0xffff
;
...
...
@@ -36,35 +36,66 @@ static void init_parent_ds(struct pp_instance *ppi)
* Initializes network and other stuff
*/
int
pp_initializing
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
int
pp_initializing
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
unsigned
char
*
id
,
*
mac
;
unsigned
char
*
mac
;
unsigned
char
mac_port1
[
6
];
struct
DSPort
*
port
=
DSPOR
(
ppi
);
struct
pp_runtime_opts
*
opt
=
OPTS
(
ppi
);
struct
pp_globals
*
ppg
=
GLBS
(
ppi
);
int
ret
=
0
;
int
i
;
unsigned
int
portidx
;
unsigned
int
remainder
;
int
initds
=
1
;
if
(
ppi
->
n_ops
->
init
(
ppi
)
<
0
)
/* it must handle being called twice */
goto
failure
;
init_parent_ds
(
ppi
);
/* Clock identity comes from mac address with 0xff:0xfe intermixed */
id
=
(
unsigned
char
*
)
&
DSDEF
(
ppi
)
->
clockIdentity
;
mac
=
ppi
->
ch
[
PP_NP_GEN
].
addr
;
id
[
0
]
=
mac
[
0
];
id
[
1
]
=
mac
[
1
];
id
[
2
]
=
mac
[
2
];
id
[
3
]
=
0xff
;
id
[
4
]
=
0xfe
;
id
[
5
]
=
mac
[
3
];
id
[
6
]
=
mac
[
4
];
id
[
7
]
=
mac
[
5
];
/* only fill in the data set when initializing */
if
(
DSDEF
(
ppi
)
->
numberPorts
>
1
)
{
for
(
i
=
0
;
i
<
ppg
->
defaultDS
->
numberPorts
;
i
++
)
{
if
((
INST
(
ppg
,
i
)
->
state
!=
PPS_INITIALIZING
)
&&
(
INST
(
ppg
,
i
)
->
link_up
==
TRUE
))
initds
=
0
;
}
}
/*
* Initialize parent data set
* Initialize
default and
parent data set
*/
init_parent_ds
(
ppi
);
if
(
initds
)
{
if
(
DSDEF
(
ppi
)
->
numberPorts
>
1
)
{
/* Clock identity comes from mac address with 0xff:0xfe intermixed */
mac
=
ppi
->
ch
[
PP_NP_GEN
].
addr
;
/* calculate MAC of Port 0 */
portidx
=
ppi
-
ppi
->
glbs
->
pp_instances
;
remainder
=
portidx
;
for
(
i
=
5
;
i
>=
0
;
i
--
)
{
mac_port1
[
i
]
=
mac
[
i
]
-
remainder
;
if
(
mac
[
i
]
>=
remainder
)
remainder
=
0
;
else
remainder
=
1
;
}
}
else
{
/* Clock identity comes from mac address with 0xff:0xfe intermixed */
for
(
i
=
5
;
i
>=
0
;
i
--
)
mac_port1
[
i
]
=
((
unsigned
char
*
)
ppi
->
ch
[
PP_NP_GEN
].
addr
)[
i
];
}
DSDEF
(
ppi
)
->
clockIdentity
.
id
[
0
]
=
mac_port1
[
0
];
DSDEF
(
ppi
)
->
clockIdentity
.
id
[
1
]
=
mac_port1
[
1
];
DSDEF
(
ppi
)
->
clockIdentity
.
id
[
2
]
=
mac_port1
[
2
];
DSDEF
(
ppi
)
->
clockIdentity
.
id
[
3
]
=
0xff
;
DSDEF
(
ppi
)
->
clockIdentity
.
id
[
4
]
=
0xfe
;
DSDEF
(
ppi
)
->
clockIdentity
.
id
[
5
]
=
mac_port1
[
3
];
DSDEF
(
ppi
)
->
clockIdentity
.
id
[
6
]
=
mac_port1
[
4
];
DSDEF
(
ppi
)
->
clockIdentity
.
id
[
7
]
=
mac_port1
[
5
];
init_parent_ds
(
ppi
);
}
/*
* Initialize port data set
*/
...
...
@@ -78,9 +109,10 @@ int pp_initializing(struct pp_instance *ppi, unsigned char *pkt, int plen)
port
->
logSyncInterval
=
opt
->
sync_intvl
;
port
->
versionNumber
=
PP_VERSION_PTP
;
pp_timeout_init
(
ppi
);
pp_timeout_setall
(
ppi
);
if
(
pp_hooks
.
init
)
ret
=
pp_hooks
.
init
(
ppi
,
pkt
,
p
len
);
ret
=
pp_hooks
.
init
(
ppi
,
buf
,
len
);
if
(
ret
)
{
pp_diag
(
ppi
,
ext
,
1
,
"%s: can't init extension
\n
"
,
__func__
);
goto
failure
;
...
...
@@ -92,7 +124,7 @@ int pp_initializing(struct pp_instance *ppi, unsigned char *pkt, int plen)
DSDEF
(
ppi
)
->
clockQuality
.
clockAccuracy
);
msg_init_header
(
ppi
,
ppi
->
tx_ptp
);
/* This is used for all tx */
if
(
ppi
->
role
!=
PPSI_ROLE_MASTER
)
ppi
->
next_state
=
PPS_LISTENING
;
else
...
...
proto-standard/state-listening.c
View file @
ff6d7afa
...
...
@@ -9,58 +9,62 @@
#include <ppsi/ppsi.h>
#include "common-fun.h"
int
pp_listening
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
plen
)
static
pp_action
*
actions
[]
=
{
[
PPM_SYNC
]
=
0
,
[
PPM_DELAY_REQ
]
=
0
,
#if CONFIG_HAS_P2P
[
PPM_PDELAY_REQ
]
=
st_com_peer_handle_preq
,
[
PPM_PDELAY_RESP
]
=
st_com_peer_handle_pres
,
[
PPM_PDELAY_R_FUP
]
=
st_com_peer_handle_pres_followup
,
#endif
[
PPM_FOLLOW_UP
]
=
0
,
[
PPM_DELAY_RESP
]
=
0
,
[
PPM_ANNOUNCE
]
=
st_com_handle_announce
,
/* skip signaling and management, for binary size */
};
int
pp_listening
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
e
=
0
;
/* error var, to check errors in msg handling */
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
pp_timeout_set
(
ppi
,
PP_TO_FAULT
);
/* no fault as long as we listen */
if
(
pp_hooks
.
listening
)
e
=
pp_hooks
.
listening
(
ppi
,
pkt
,
p
len
);
e
=
pp_hooks
.
listening
(
ppi
,
buf
,
len
);
if
(
e
)
goto
out
;
/* when the clock is using peer-delay, listening must send it too */
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
e
=
pp_lib_may_issue_request
(
ppi
);
/*
* The management of messages is now table-driven
*/
if
(
hdr
->
messageType
<
ARRAY_SIZE
(
actions
)
&&
actions
[
hdr
->
messageType
])
{
e
=
actions
[
hdr
->
messageType
](
ppi
,
buf
,
len
);
}
else
{
if
(
len
)
pp_diag
(
ppi
,
frames
,
1
,
"Ignored frame %i
\n
"
,
hdr
->
messageType
);
}
switch
(
ppi
->
received_ptp_header
.
messageType
)
{
case
PPM_ANNOUNCE
:
e
=
pp_lib_handle_announce
(
ppi
,
pkt
,
plen
);
break
;
case
PPM_SYNC
:
e
=
st_com_master_handle_sync
(
ppi
,
pkt
,
plen
);
break
;
case
PPM_PDELAY_REQ
:
if
(
CONFIG_HAS_P2P
)
st_com_peer_handle_preq
(
ppi
,
pkt
,
plen
);
break
;
case
PPM_PDELAY_RESP
:
if
(
CONFIG_HAS_P2P
)
e
=
st_com_peer_handle_pres
(
ppi
,
pkt
,
plen
);
break
;
case
PPM_PDELAY_R_FUP
:
if
(
CONFIG_HAS_P2P
)
e
=
st_com_peer_handle_pres_followup
(
ppi
,
pkt
,
plen
);
break
;
st_com_check_announce_receive_timeout
(
ppi
);
default:
/* disregard, nothing to do */
break
;
}
if
(
pp_timeout
(
ppi
,
PP_TO_FAULT
))
ppi
->
next_state
=
PPS_FAULTY
;
out:
if
(
e
==
0
)
e
=
st_com_execute_slave
(
ppi
);
if
(
e
!=
0
)
ppi
->
next_state
=
PPS_FAULTY
;
ppi
->
next_delay
=
pp_next_delay_1
(
ppi
,
PP_TO_ANN_RECEIPT
);
return
0
;
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
{
ppi
->
next_delay
=
pp_next_delay_2
(
ppi
,
PP_TO_ANN_RECEIPT
,
PP_TO_REQUEST
);
}
else
{
ppi
->
next_delay
=
pp_next_delay_1
(
ppi
,
PP_TO_ANN_RECEIPT
);
}
return
e
;
}
proto-standard/state-master.c
View file @
ff6d7afa
...
...
@@ -10,10 +10,10 @@
#include "common-fun.h"
static
int
master_handle_delay_request
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
);
void
*
buf
,
int
len
);
static
pp_action
*
actions
[]
=
{
[
PPM_SYNC
]
=
st_com_master_handle_sync
,
[
PPM_SYNC
]
=
0
,
[
PPM_DELAY_REQ
]
=
master_handle_delay_request
,
#if CONFIG_HAS_P2P
[
PPM_PDELAY_REQ
]
=
st_com_peer_handle_preq
,
...
...
@@ -22,12 +22,12 @@ static pp_action *actions[] = {
#endif
[
PPM_FOLLOW_UP
]
=
0
,
[
PPM_DELAY_RESP
]
=
0
,
[
PPM_ANNOUNCE
]
=
pp_lib
_handle_announce
,
[
PPM_ANNOUNCE
]
=
st_com
_handle_announce
,
/* skip signaling and management, for binary size */
};
static
int
master_handle_delay_request
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
void
*
buf
,
int
len
)
{
if
(
ppi
->
state
==
PPS_MASTER
)
/* not pre-master */
msg_issue_delay_resp
(
ppi
,
&
ppi
->
last_rcv_time
);
...
...
@@ -38,15 +38,22 @@ static int master_handle_delay_request(struct pp_instance *ppi,
* MASTER and PRE_MASTER have many things in common. This function implements
* both states. We set "pre" internally to 0 or 1.
*/
int
pp_master
(
struct
pp_instance
*
ppi
,
uint8_t
*
pkt
,
int
p
len
)
int
pp_master
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
msgtype
;
int
pre
=
(
ppi
->
state
==
PPS_PRE_MASTER
);
int
e
=
0
;
/* error var, to check errors in msg handling */
pp_timeout_set
(
ppi
,
PP_TO_FAULT
);
/* no fault as long as we are
* master */
/* upgrade from pre-master to master */
if
(
pre
&&
pp_timeout
(
ppi
,
PP_TO_QUALIFICATION
))
{
ppi
->
next_state
=
PPS_MASTER
;
/* start sending imediately and reenter */
pp_timeout_clear
(
ppi
,
PP_TO_SYNC_SEND
);
pp_timeout_clear
(
ppi
,
PP_TO_ANN_SEND
);
ppi
->
next_delay
=
0
;
return
0
;
}
...
...
@@ -62,8 +69,6 @@ int pp_master(struct pp_instance *ppi, uint8_t *pkt, int plen)
/* when the clock is using peer-delay, the master must send it too */
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
pp_lib_may_issue_request
(
ppi
);
else
/* please check commit '6d7bf7e3' about below, I'm not sure */
pp_timeout_set
(
ppi
,
PP_TO_REQUEST
);
/*
* An extension can do special treatment of this message type,
...
...
@@ -72,10 +77,10 @@ int pp_master(struct pp_instance *ppi, uint8_t *pkt, int plen)
*/
msgtype
=
ppi
->
received_ptp_header
.
messageType
;
if
(
pp_hooks
.
master_msg
)
msgtype
=
pp_hooks
.
master_msg
(
ppi
,
pkt
,
p
len
,
msgtype
);
msgtype
=
pp_hooks
.
master_msg
(
ppi
,
buf
,
len
,
msgtype
);
if
(
msgtype
<
0
)
{
e
=
msgtype
;
p
len
=
0
;
len
=
0
;
e
=
PP_SEND_ERROR
;
/* well, "error" in general */
goto
out
;
}
...
...
@@ -85,13 +90,16 @@ int pp_master(struct pp_instance *ppi, uint8_t *pkt, int plen)
*/
if
(
msgtype
<
ARRAY_SIZE
(
actions
)
&&
actions
[
msgtype
])
{
e
=
actions
[
msgtype
](
ppi
,
pkt
,
p
len
);
e
=
actions
[
msgtype
](
ppi
,
buf
,
len
);
}
else
{
if
(
p
len
&&
msgtype
!=
PPM_NO_MESSAGE
)
if
(
len
&&
msgtype
!=
PPM_NO_MESSAGE
)
pp_diag
(
ppi
,
frames
,
1
,
"Ignored frame %i
\n
"
,
msgtype
);
}
if
(
pp_timeout
(
ppi
,
PP_TO_FAULT
))
ppi
->
next_state
=
PPS_FAULTY
;
out:
switch
(
e
)
{
case
PP_SEND_OK
:
/* 0 */
...
...
@@ -108,9 +116,24 @@ out:
break
;
}
/* we also use TO_QUALIFICATION, but avoid counting it here */
ppi
->
next_delay
=
pp_next_delay_3
(
ppi
,
PP_TO_ANN_SEND
,
PP_TO_SYNC_SEND
,
PP_TO_REQUEST
);
if
(
pre
)
{
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
{
ppi
->
next_delay
=
pp_next_delay_2
(
ppi
,
PP_TO_QUALIFICATION
,
PP_TO_REQUEST
);
}
else
{
ppi
->
next_delay
=
pp_next_delay_1
(
ppi
,
PP_TO_QUALIFICATION
);
}
}
else
{
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
{
ppi
->
next_delay
=
pp_next_delay_3
(
ppi
,
PP_TO_ANN_SEND
,
PP_TO_SYNC_SEND
,
PP_TO_REQUEST
);
}
else
{
ppi
->
next_delay
=
pp_next_delay_2
(
ppi
,
PP_TO_ANN_SEND
,
PP_TO_SYNC_SEND
);
}
}
return
e
;
}
proto-standard/state-passive.c
View file @
ff6d7afa
...
...
@@ -9,53 +9,83 @@
#include <ppsi/ppsi.h>
#include "common-fun.h"
int
pp_passive
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
plen
)
{
int
e
=
0
;
/* error var, to check errors in msg handling */
/* when the clock is using peer-delay, listening must send it too */
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
e
=
pp_lib_may_issue_request
(
ppi
);
static
int
passive_handle_announce
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
switch
(
ppi
->
received_ptp_header
.
messageType
)
{
static
pp_action
*
actions
[]
=
{
[
PPM_SYNC
]
=
0
,
[
PPM_DELAY_REQ
]
=
0
,
#if CONFIG_HAS_P2P
[
PPM_PDELAY_REQ
]
=
st_com_peer_handle_preq
,
[
PPM_PDELAY_RESP
]
=
st_com_peer_handle_pres
,
[
PPM_PDELAY_R_FUP
]
=
st_com_peer_handle_pres_followup
,
#endif
[
PPM_FOLLOW_UP
]
=
0
,
[
PPM_DELAY_RESP
]
=
0
,
[
PPM_ANNOUNCE
]
=
passive_handle_announce
,
/* skip signaling and management, for binary size */
};
case
PPM_ANNOUNCE
:
e
=
pp_lib_handle_announce
(
ppi
,
pkt
,
plen
);
break
;
case
PPM_SYNC
:
e
=
st_com_master_handle_sync
(
ppi
,
pkt
,
plen
);
break
;
case
PPM_PDELAY_REQ
:
if
(
CONFIG_HAS_P2P
)
st_com_peer_handle_preq
(
ppi
,
pkt
,
plen
);
break
;
static
int
passive_handle_announce
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
ret
=
0
;
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
struct
pp_frgn_master
*
erbest
=
&
ppi
->
frgn_master
[
ppi
->
frgn_rec_best
];
ret
=
st_com_handle_announce
(
ppi
,
buf
,
len
);
if
(
ret
)
return
ret
;
if
(
!
bmc_pidcmp
(
&
hdr
->
sourcePortIdentity
,
&
erbest
->
sourcePortIdentity
))
{
/*
* 9.2.6.11 d) reset timeout when an announce
* is received from the clock putting it into passive (erbest)
*/
pp_timeout_set
(
ppi
,
PP_TO_ANN_RECEIPT
);
}
return
0
;
}
case
PPM_PDELAY_RESP
:
if
(
CONFIG_HAS_P2P
)
e
=
st_com_peer_handle_pres
(
ppi
,
pkt
,
plen
);
break
;
int
pp_passive
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
e
=
0
;
/* error var, to check errors in msg handling */
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
case
PPM_PDELAY_R_FUP
:
if
(
CONFIG_HAS_P2P
)
e
=
st_com_peer_handle_pres_followup
(
ppi
,
pkt
,
plen
);
break
;
pp_timeout_set
(
ppi
,
PP_TO_FAULT
);
/* no fault as long as we are
* passive */
default:
/* disreguard, nothing to do */
break
;
/* when the clock is using peer-delay, passive must send it too */
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
e
=
pp_lib_may_issue_request
(
ppi
)
;
/*
* The management of messages is now table-driven
*/
if
(
hdr
->
messageType
<
ARRAY_SIZE
(
actions
)
&&
actions
[
hdr
->
messageType
])
{
e
=
actions
[
hdr
->
messageType
](
ppi
,
buf
,
len
);
}
else
{
if
(
len
)
pp_diag
(
ppi
,
frames
,
1
,
"Ignored frame %i
\n
"
,
hdr
->
messageType
);
}
if
(
e
==
0
)
e
=
st_com_execute_slave
(
ppi
);
st_com_check_announce_receive_timeout
(
ppi
);
if
(
e
!=
0
)
{
/* ignore: a lost frame is not the end of the world */
}
if
(
pp_timeout
(
ppi
,
PP_TO_FAULT
))
ppi
->
next_state
=
PPS_FAULTY
;
ppi
->
next_delay
=
PP_DEFAULT_NEXT_DELAY_MS
;
if
(
e
!=
0
)
ppi
->
next_state
=
PPS_FAULTY
;
return
0
;
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
{
ppi
->
next_delay
=
pp_next_delay_2
(
ppi
,
PP_TO_ANN_RECEIPT
,
PP_TO_REQUEST
);
}
else
{
ppi
->
next_delay
=
pp_next_delay_1
(
ppi
,
PP_TO_ANN_RECEIPT
);
}
return
e
;
}
proto-standard/state-slave.c
View file @
ff6d7afa
...
...
@@ -11,40 +11,125 @@
#include <ppsi/ppsi.h>
#include "common-fun.h"
static
int
slave_handle_response
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
plen
);
static
int
slave_handle_sync
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
static
int
slave_handle_followup
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
static
int
slave_handle_response
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
static
int
slave_handle_announce
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
);
static
pp_action
*
actions
[]
=
{
[
PPM_SYNC
]
=
st_com_
slave_handle_sync
,
[
PPM_SYNC
]
=
slave_handle_sync
,
[
PPM_DELAY_REQ
]
=
0
,
#if CONFIG_HAS_P2P
[
PPM_PDELAY_REQ
]
=
st_com_peer_handle_preq
,
[
PPM_PDELAY_RESP
]
=
st_com_peer_handle_pres
,
[
PPM_PDELAY_R_FUP
]
=
st_com_peer_handle_pres_followup
,
#endif
[
PPM_FOLLOW_UP
]
=
s
t_com_s
lave_handle_followup
,
[
PPM_FOLLOW_UP
]
=
slave_handle_followup
,
[
PPM_DELAY_RESP
]
=
slave_handle_response
,
[
PPM_ANNOUNCE
]
=
pp_lib
_handle_announce
,
[
PPM_ANNOUNCE
]
=
slave
_handle_announce
,
/* skip signaling and management, for binary size */
};
static
int
slave_handle_
response
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
p
len
)
static
int
slave_handle_
sync
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
e
=
0
;
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
MsgDelayResp
resp
;
MsgSync
sync
;
if
(
!
msg_from_current_master
(
ppi
))
return
0
;
/* t2 may be overriden by follow-up, save it immediately */
ppi
->
t2
=
ppi
->
last_rcv_time
;
msg_unpack_sync
(
buf
,
&
sync
);
if
((
hdr
->
flagField
[
0
]
&
PP_TWO_STEP_FLAG
)
!=
0
)
{
ppi
->
flags
|=
PPI_FLAG_WAITING_FOR_F_UP
;
ppi
->
recv_sync_sequence_id
=
hdr
->
sequenceId
;
/* for two-step, the stamp comes later */
ppi
->
t1
=
hdr
->
cField
;
/* most likely 0 */
return
0
;
}
/* one-step folllows */
ppi
->
flags
&=
~
PPI_FLAG_WAITING_FOR_F_UP
;
ppi
->
t1
=
sync
.
originTimestamp
;
pp_time_add
(
&
ppi
->
t1
,
&
hdr
->
cField
);
ppi
->
syncCF
=
0
;
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
pp_servo_got_psync
(
ppi
);
else
pp_servo_got_sync
(
ppi
);
return
0
;
}
static
int
slave_handle_followup
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
MsgFollowUp
follow
;
int
ret
=
0
;
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
if
(
!
msg_from_current_master
(
ppi
))
{
pp_error
(
"%s: Follow up message is not from current parent
\n
"
,
__func__
);
return
0
;
}
if
(
!
(
ppi
->
flags
&
PPI_FLAG_WAITING_FOR_F_UP
))
{
pp_error
(
"%s: Slave was not waiting a follow up message
\n
"
,
__func__
);
return
0
;
}
if
(
ppi
->
recv_sync_sequence_id
!=
hdr
->
sequenceId
)
{
pp_error
(
"%s: SequenceID %d doesn't match last Sync message "
"%d
\n
"
,
__func__
,
hdr
->
sequenceId
,
ppi
->
recv_sync_sequence_id
);
return
0
;
}
msg_unpack_follow_up
(
buf
,
&
follow
);
ppi
->
flags
&=
~
PPI_FLAG_WAITING_FOR_F_UP
;
/* t1 for calculations is T1 + Csyn + Cful -- see README-cfield */
pp_time_add
(
&
ppi
->
t1
,
&
follow
.
preciseOriginTimestamp
);
pp_time_add
(
&
ppi
->
t1
,
&
hdr
->
cField
);
ppi
->
syncCF
=
hdr
->
cField
.
scaled_nsecs
;
/* for diag about TC */
/* Call the extension; it may do it all and ask to return */
if
(
pp_hooks
.
handle_followup
)
ret
=
pp_hooks
.
handle_followup
(
ppi
,
&
ppi
->
t1
);
if
(
ret
==
1
)
return
0
;
if
(
ret
<
0
)
return
ret
;
if
(
CONFIG_HAS_P2P
&&
ppi
->
mech
==
PP_P2P_MECH
)
pp_servo_got_psync
(
ppi
);
else
pp_servo_got_sync
(
ppi
);
msg_unpack_delay_resp
(
pkt
,
&
resp
);
return
0
;
}
if
((
memcmp
(
&
DSPOR
(
ppi
)
->
portIdentity
.
clockIdentity
,
&
resp
.
requestingPortIdentity
.
clockIdentity
,
PP_CLOCK_IDENTITY_LENGTH
)
!=
0
)
||
static
int
slave_handle_response
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
e
=
0
;
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
MsgDelayResp
resp
;
msg_unpack_delay_resp
(
buf
,
&
resp
);
if
((
bmc_idcmp
(
&
DSPOR
(
ppi
)
->
portIdentity
.
clockIdentity
,
&
resp
.
requestingPortIdentity
.
clockIdentity
)
!=
0
)
||
((
ppi
->
sent_seq
[
PPM_DELAY_REQ
])
!=
hdr
->
sequenceId
)
||
(
DSPOR
(
ppi
)
->
portIdentity
.
portNumber
!=
resp
.
requestingPortIdentity
.
portNumber
)
||
!
(
ppi
->
flags
&
PPI_FLAG_FROM_CURRENT_PARENT
))
{
(
!
msg_from_current_master
(
ppi
)
))
{
pp_diag
(
ppi
,
frames
,
1
,
"pp_slave : "
"Delay Resp doesn't match Delay Req (f %x)
\n
"
,
ppi
->
flags
);
...
...
@@ -73,40 +158,97 @@ static int slave_handle_response(struct pp_instance *ppi, unsigned char *pkt,
return
0
;
}
int
pp_slave
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
plen
)
static
int
slave_handle_announce
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
ret
=
0
;
struct
pp_frgn_master
frgn_master
;
ret
=
st_com_handle_announce
(
ppi
,
buf
,
len
);
if
(
ret
)
return
ret
;
if
(
!
msg_from_current_master
(
ppi
))
return
0
;
/* 9.2.6.11 a) reset timeout */
pp_timeout_set
(
ppi
,
PP_TO_ANN_RECEIPT
);
/* 9.5.3 Figure 29 update data set if announce from current master */
bmc_store_frgn_master
(
ppi
,
&
frgn_master
,
buf
,
len
);
bmc_s1
(
ppi
,
&
frgn_master
);
return
0
;
}
static
int
slave_execute
(
struct
pp_instance
*
ppi
)
{
int
ret
=
0
;
if
(
pp_hooks
.
execute_slave
)
ret
=
pp_hooks
.
execute_slave
(
ppi
);
if
(
ret
==
1
)
/* done: just return */
return
0
;
if
(
ret
<
0
)
return
ret
;
return
0
;
}
/*
* SLAVE and UNCALIBRATED have many things in common. This function implements
* both states. We set "uncalibrated" internally to 0 or 1.
*/
int
pp_slave
(
struct
pp_instance
*
ppi
,
void
*
buf
,
int
len
)
{
int
e
=
0
;
/* error var, to check errors in msg handling */
int
uncalibrated
=
(
ppi
->
state
==
PPS_UNCALIBRATED
);
MsgHeader
*
hdr
=
&
ppi
->
received_ptp_header
;
if
(
ppi
->
is_new_state
)
{
/* upgrade from uncalibrated to slave or back*/
if
(
uncalibrated
)
{
/* TODO add implementation specific MASTER_CLOCK_SELECTED event
for now just change directly to new state on next round */
ppi
->
next_state
=
PPS_SLAVE
;
}
else
{
/* TODO add implementation specific SYNCHRONIZATION FAULT
* event */
if
(
pp_timeout
(
ppi
,
PP_TO_FAULT
))
ppi
->
next_state
=
PPS_UNCALIBRATED
;
}
/* when entering uncalibrated init servo */
if
((
ppi
->
state
==
PPS_UNCALIBRATED
)
&&
(
ppi
->
is_new_state
))
{
memset
(
&
ppi
->
t1
,
0
,
sizeof
(
ppi
->
t1
));
pp_diag
(
ppi
,
bmc
,
2
,
"Entered to uncalibrated, reset servo
\n
"
);
pp_servo_init
(
ppi
);
if
(
pp_hooks
.
new_slave
)
e
=
pp_hooks
.
new_slave
(
ppi
,
pkt
,
p
len
);
e
=
pp_hooks
.
new_slave
(
ppi
,
buf
,
len
);
if
(
e
)
goto
out
;
}
/* do a delay mesurement either in p2p or e2e delay mode */
pp_lib_may_issue_request
(
ppi
);
/*
* The management of messages is now table-driven
*/
if
(
hdr
->
messageType
<
ARRAY_SIZE
(
actions
)
&&
actions
[
hdr
->
messageType
])
{
e
=
actions
[
hdr
->
messageType
](
ppi
,
pkt
,
p
len
);
e
=
actions
[
hdr
->
messageType
](
ppi
,
buf
,
len
);
}
else
{
if
(
p
len
)
if
(
len
)
pp_diag
(
ppi
,
frames
,
1
,
"Ignored frame %i
\n
"
,
hdr
->
messageType
);
}
/*
* This function, common to
passive,listening etc
,
* is the core of the slave:
timeout ann-receipt,
hook
* This function, common to
uncalibrated and slave
,
* is the core of the slave: hook
*/
e
=
st_com_execute_slave
(
ppi
);
e
=
slave_execute
(
ppi
);
st_com_check_announce_receive_timeout
(
ppi
);
out:
switch
(
e
)
{
...
...
@@ -121,12 +263,8 @@ out:
break
;
}
if
(
ppi
->
next_state
!=
ppi
->
state
)
{
pp_servo_init
(
ppi
);
return
e
;
}
ppi
->
next_delay
=
pp_next_delay_2
(
ppi
,
PP_TO_ANN_RECEIPT
,
PP_TO_REQUEST
);
PP_TO_ANN_RECEIPT
,
PP_TO_REQUEST
);
return
e
;
}
proto-standard/state-uncalibrated.c
deleted
100644 → 0
View file @
0cc9d341
/*
* Copyright (C) 2011 CERN (www.cern.ch)
* Author: Aurelio Colosimo
* Based on PTPd project v. 2.1.0 (see AUTHORS for details)
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*/
#include <ppsi/ppsi.h>
#include "common-fun.h"
int
pp_uncalibrated
(
struct
pp_instance
*
ppi
,
unsigned
char
*
pkt
,
int
plen
)
{
int
e
=
0
;
/* error var, to check errors in msg handling */
switch
(
ppi
->
received_ptp_header
.
messageType
)
{
case
PPM_ANNOUNCE
:
e
=
pp_lib_handle_announce
(
ppi
,
pkt
,
plen
);
break
;
case
PPM_SYNC
:
e
=
st_com_slave_handle_sync
(
ppi
,
pkt
,
plen
);
break
;
case
PPM_FOLLOW_UP
:
e
=
st_com_slave_handle_followup
(
ppi
,
pkt
,
plen
);
break
;
default:
/* disreguard, nothing to do */
break
;
}
if
(
e
==
0
)
e
=
st_com_execute_slave
(
ppi
);
if
(
e
!=
0
)
ppi
->
next_state
=
PPS_FAULTY
;
ppi
->
next_delay
=
PP_DEFAULT_NEXT_DELAY_MS
;
return
0
;
}
time-bare/bare-time.c
View file @
ff6d7afa
...
...
@@ -8,6 +8,54 @@
#include <ppsi/ppsi.h>
#include "bare-linux.h"
static
int
bare_time_get_utc_time
(
struct
pp_instance
*
ppi
,
int
*
hours
,
int
*
minutes
,
int
*
seconds
)
{
/* TODO */
return
-
1
;
}
static
int
bare_time_get_utc_offset
(
struct
pp_instance
*
ppi
,
int
*
offset
,
int
*
leap59
,
int
*
leap61
)
{
int
ret
;
struct
bare_timex
t
;
/*
* Get the UTC/TAI difference
*/
memset
(
&
t
,
0
,
sizeof
(
t
));
ret
=
adjtimex
(
&
t
);
if
(
ret
>=
0
)
{
if
(
ret
==
TIME_INS
)
{
*
leap59
=
0
;
*
leap61
=
1
;
}
else
if
(
ret
==
TIME_DEL
)
{
*
leap59
=
1
;
*
leap61
=
0
;
}
else
{
*
leap59
=
0
;
*
leap61
=
0
;
}
*
offset
=
(
int
)
t
.
tai
;
return
0
;
}
else
{
*
leap59
=
0
;
*
leap61
=
0
;
*
offset
=
0
;
return
-
1
;
}
}
static
int
bare_time_set_utc_offset
(
struct
pp_instance
*
ppi
,
int
offset
,
int
leap59
,
int
leap61
)
{
/* TODO */
return
-
1
;
}
static
int
bare_time_get_servo_state
(
struct
pp_instance
*
ppi
,
int
*
state
)
{
*
state
=
PP_SERVO_UNKNOWN
;
return
0
;
}
static
int
bare_time_get
(
struct
pp_instance
*
ppi
,
struct
pp_time
*
t
)
{
struct
bare_timeval
tv
;
...
...
@@ -100,6 +148,10 @@ static unsigned long bare_calc_timeout(struct pp_instance *ppi, int millisec)
}
struct
pp_time_operations
bare_time_ops
=
{
.
get_utc_time
=
bare_time_get_utc_time
,
.
get_utc_offset
=
bare_time_get_utc_offset
,
.
set_utc_offset
=
bare_time_set_utc_offset
,
.
get_servo_state
=
bare_time_get_servo_state
,
.
get
=
bare_time_get
,
.
set
=
bare_time_set
,
.
adjust
=
bare_time_adjust
,
...
...
time-sim/sim-time.c
View file @
ff6d7afa
...
...
@@ -46,6 +46,36 @@ int sim_fast_forward_ns(struct pp_globals *ppg, int64_t ff_ns)
return
0
;
}
static
int
sim_time_get_utc_time
(
struct
pp_instance
*
ppi
,
int
*
hours
,
int
*
minutes
,
int
*
seconds
)
{
/* no UTC time */
*
hours
=
0
;
*
minutes
=
0
;
*
seconds
=
0
;
return
-
1
;
}
static
int
sim_time_get_utc_offset
(
struct
pp_instance
*
ppi
,
int
*
offset
,
int
*
leap59
,
int
*
leap61
)
{
/* no UTC offset */
*
leap59
=
0
;
*
leap61
=
0
;
*
offset
=
0
;
return
-
1
;
}
static
int
sim_time_set_utc_offset
(
struct
pp_instance
*
ppi
,
int
offset
,
int
leap59
,
int
leap61
)
{
/* no UTC offset */
return
-
1
;
}
static
int
sim_time_get_servo_state
(
struct
pp_instance
*
ppi
,
int
*
state
)
{
*
state
=
PP_SERVO_UNKNOWN
;
return
0
;
}
static
int
sim_time_get
(
struct
pp_instance
*
ppi
,
struct
pp_time
*
t
)
{
t
->
scaled_nsecs
=
(
SIM_PPI_ARCH
(
ppi
)
->
time
.
current_ns
%
...
...
@@ -113,6 +143,10 @@ static unsigned long sim_calc_timeout(struct pp_instance *ppi, int millisec)
}
struct
pp_time_operations
sim_time_ops
=
{
.
get_utc_time
=
sim_time_get_utc_time
,
.
get_utc_offset
=
sim_time_get_utc_offset
,
.
set_utc_offset
=
sim_time_set_utc_offset
,
.
get_servo_state
=
sim_time_get_servo_state
,
.
get
=
sim_time_get
,
.
set
=
sim_time_set
,
.
adjust
=
sim_time_adjust
,
...
...
time-unix/unix-time.c
View file @
ff6d7afa
...
...
@@ -23,6 +23,157 @@ static void clock_fatal_error(char *context)
exit
(
1
);
}
static
void
unix_time_clear_utc_flags
(
void
)
{
struct
timex
t
;
/*
* We have to call adjtime twice here, as kernels
* prior to 6b1859dba01c7 (included in 3.5 and
* -stable), had an issue with the state machine
* and wouldn't clear the STA_INS/DEL flag directly.
*/
t
.
modes
=
ADJ_STATUS
;
t
.
status
=
STA_PLL
;
adjtimex
(
&
t
);
/* Clear maxerror, as it can cause UNSYNC to be set */
t
.
modes
=
ADJ_MAXERROR
;
t
.
maxerror
=
0
;
adjtimex
(
&
t
);
/* Clear the status */
t
.
modes
=
ADJ_STATUS
;
t
.
status
=
0
;
adjtimex
(
&
t
);
}
static
int
unix_time_get_utc_time
(
struct
pp_instance
*
ppi
,
int
*
hours
,
int
*
minutes
,
int
*
seconds
)
{
int
ret
;
struct
timex
t
;
time_t
now
;
struct
tm
*
date
;
/* Get the UTC time */
memset
(
&
t
,
0
,
sizeof
(
t
));
ret
=
adjtimex
(
&
t
);
if
(
ret
>=
0
)
{
now
=
t
.
time
.
tv_sec
;
/* use gmtime for correct leap handling */
date
=
gmtime
(
&
now
);
*
hours
=
date
->
tm_hour
;
*
minutes
=
date
->
tm_min
;
*
seconds
=
date
->
tm_sec
;
return
0
;
}
else
{
*
hours
=
0
;
*
minutes
=
0
;
*
seconds
=
0
;
return
-
1
;
}
return
-
1
;
}
static
int
unix_time_get_utc_offset
(
struct
pp_instance
*
ppi
,
int
*
offset
,
int
*
leap59
,
int
*
leap61
)
{
int
ret
;
struct
timex
t
;
int
hours
,
minutes
,
seconds
;
unix_time_get_utc_time
(
ppi
,
&
hours
,
&
minutes
,
&
seconds
);
/*
* Get the UTC/TAI difference
*/
memset
(
&
t
,
0
,
sizeof
(
t
));
ret
=
adjtimex
(
&
t
);
if
(
ret
>=
0
)
{
if
(
hours
>=
12
)
{
if
((
t
.
status
&
STA_INS
)
==
STA_INS
)
{
*
leap59
=
0
;
*
leap61
=
1
;
}
else
if
((
t
.
status
&
STA_DEL
)
==
STA_DEL
)
{
*
leap59
=
1
;
*
leap61
=
0
;
}
else
{
*
leap59
=
0
;
*
leap61
=
0
;
}
}
else
{
unix_time_clear_utc_flags
();
*
leap59
=
0
;
*
leap61
=
0
;
}
/*
* Our WRS kernel has tai support, but our compiler does not.
* We are 32-bit only, and we know for sure that tai is
* exactly after stbcnt. It's a bad hack, but it works
*/
*
offset
=
*
((
int
*
)(
&
t
.
stbcnt
)
+
1
);
return
0
;
}
else
{
*
leap59
=
0
;
*
leap61
=
0
;
*
offset
=
0
;
return
-
1
;
}
}
static
int
unix_time_set_utc_offset
(
struct
pp_instance
*
ppi
,
int
offset
,
int
leap59
,
int
leap61
)
{
struct
timex
t
;
int
ret
;
unix_time_clear_utc_flags
();
/* get the current flags first */
memset
(
&
t
,
0
,
sizeof
(
t
));
ret
=
adjtimex
(
&
t
);
if
(
ret
>=
0
)
{
if
(
leap59
)
{
t
.
modes
=
MOD_STATUS
;
t
.
status
|=
STA_DEL
;
t
.
status
&=
~
STA_INS
;
}
else
if
(
leap61
)
{
t
.
modes
=
MOD_STATUS
;
t
.
status
|=
STA_INS
;
t
.
status
&=
~
STA_DEL
;
}
else
{
t
.
modes
=
MOD_STATUS
;
t
.
status
&=
~
STA_INS
;
t
.
status
&=
~
STA_DEL
;
}
if
(
adjtimex
(
&
t
)
<
0
)
{
pp_diag
(
ppi
,
time
,
1
,
"set UTC flags failed
\n
"
);
return
-
1
;
}
}
else
pp_diag
(
ppi
,
time
,
1
,
"get UTC flags failed
\n
"
);
t
.
modes
=
MOD_TAI
;
t
.
constant
=
offset
;
if
(
adjtimex
(
&
t
)
<
0
)
{
pp_diag
(
ppi
,
time
,
1
,
"set UTC offset failed
\n
"
);
return
-
1
;
}
else
pp_diag
(
ppi
,
time
,
1
,
"set UTC offset to: %i
\n
"
,
offset
);
return
0
;
}
static
int
unix_time_get_servo_state
(
struct
pp_instance
*
ppi
,
int
*
state
)
{
*
state
=
PP_SERVO_UNKNOWN
;
return
0
;
}
static
int
unix_time_get
(
struct
pp_instance
*
ppi
,
struct
pp_time
*
t
)
{
struct
timespec
tp
;
...
...
@@ -66,10 +217,17 @@ static int unix_time_set(struct pp_instance *ppi, const struct pp_time *t)
static
int
unix_time_init_servo
(
struct
pp_instance
*
ppi
)
{
struct
timex
t
;
int
ret
;
/* get the current flags first */
memset
(
&
t
,
0
,
sizeof
(
t
));
ret
=
adjtimex
(
&
t
);
if
(
ret
<
0
)
pp_diag
(
ppi
,
time
,
1
,
"get current UTC offset and flags failed"
);
/* We must set MOD_PLL and recover the current frequency value */
t
.
modes
=
MOD_STATUS
;
t
.
status
=
STA_PLL
;
t
.
status
|
=
STA_PLL
;
if
(
adjtimex
(
&
t
)
<
0
)
return
-
1
;
return
(
t
.
freq
>>
16
)
*
1000
;
/* positive or negative, not -1 */
...
...
@@ -124,6 +282,10 @@ static unsigned long unix_calc_timeout(struct pp_instance *ppi, int millisec)
}
struct
pp_time_operations
unix_time_ops
=
{
.
get_utc_time
=
unix_time_get_utc_time
,
.
get_utc_offset
=
unix_time_get_utc_offset
,
.
set_utc_offset
=
unix_time_set_utc_offset
,
.
get_servo_state
=
unix_time_get_servo_state
,
.
get
=
unix_time_get
,
.
set
=
unix_time_set
,
.
adjust
=
unix_time_adjust
,
...
...
@@ -132,3 +294,4 @@ struct pp_time_operations unix_time_ops = {
.
init_servo
=
unix_time_init_servo
,
.
calc_timeout
=
unix_calc_timeout
,
};
time-wrpc/wrpc-time.c
View file @
ff6d7afa
...
...
@@ -9,6 +9,43 @@
#include "pps_gen.h"
/* in wrpc-sw */
#include "syscon.h"
/* in wrpc-sw */
static
int
wrpc_time_get_utc_time
(
struct
pp_instance
*
ppi
,
int
*
hours
,
int
*
minutes
,
int
*
seconds
)
{
/* no UTC time */
*
hours
=
0
;
*
minutes
=
0
;
*
seconds
=
0
;
return
-
1
;
}
static
int
wrpc_time_get_utc_offset
(
struct
pp_instance
*
ppi
,
int
*
offset
,
int
*
leap59
,
int
*
leap61
)
{
/* no UTC offset */
*
leap59
=
0
;
*
leap61
=
0
;
*
offset
=
0
;
return
-
1
;
}
static
int
wrpc_time_set_utc_offset
(
struct
pp_instance
*
ppi
,
int
offset
,
int
leap59
,
int
leap61
)
{
/* no UTC offset */
return
-
1
;
}
static
int
wrpc_time_get_servo_state
(
struct
pp_instance
*
ppi
,
int
*
state
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
int
locked
;
locked
=
wrp
->
ops
->
locking_poll
(
ppi
,
1
);
if
(
locked
==
WR_SPLL_READY
)
*
state
=
PP_SERVO_LOCKED
;
else
*
state
=
PP_SERVO_UNLOCKED
;
return
0
;
}
static
int
wrpc_time_get
(
struct
pp_instance
*
ppi
,
struct
pp_time
*
t
)
{
uint64_t
sec
;
...
...
@@ -65,6 +102,10 @@ static unsigned long wrpc_calc_timeout(struct pp_instance *ppi, int millisec)
}
struct
pp_time_operations
wrpc_time_ops
=
{
.
get_utc_time
=
wrpc_time_get_utc_time
,
.
get_utc_offset
=
wrpc_time_get_utc_offset
,
.
set_utc_offset
=
wrpc_time_set_utc_offset
,
.
get_servo_state
=
wrpc_time_get_servo_state
,
.
get
=
wrpc_time_get
,
.
set
=
wrpc_time_set
,
.
adjust
=
wrpc_time_adjust
,
...
...
time-wrs/wrs-time.c
View file @
ff6d7afa
...
...
@@ -136,6 +136,21 @@ int wrs_locking_enable(struct pp_instance *ppi)
return
WR_SPLL_OK
;
}
int
wrs_locking_reset
(
struct
pp_instance
*
ppi
)
{
int
ret
,
rval
;
pp_diag
(
ppi
,
time
,
1
,
"Reset locking
\n
"
);
ret
=
minipc_call
(
hal_ch
,
DEFAULT_TO
,
&
__rpcdef_lock_cmd
,
&
rval
,
ppi
->
iface_name
,
HEXP_LOCK_CMD_RESET
,
0
);
if
((
ret
<
0
)
||
(
rval
<
0
))
return
WR_SPLL_ERROR
;
return
WR_SPLL_OK
;
}
int
wrs_locking_poll
(
struct
pp_instance
*
ppi
,
int
grandmaster
)
{
int
ret
,
rval
;
...
...
@@ -187,6 +202,34 @@ static int wrdate_get(struct pp_time *t)
return
0
;
}
static
int
wrs_time_get_utc_time
(
struct
pp_instance
*
ppi
,
int
*
hours
,
int
*
minutes
,
int
*
seconds
)
{
return
unix_time_ops
.
get_utc_time
(
ppi
,
hours
,
minutes
,
seconds
);
}
static
int
wrs_time_get_utc_offset
(
struct
pp_instance
*
ppi
,
int
*
offset
,
int
*
leap59
,
int
*
leap61
)
{
return
unix_time_ops
.
get_utc_offset
(
ppi
,
offset
,
leap59
,
leap61
);
}
static
int
wrs_time_set_utc_offset
(
struct
pp_instance
*
ppi
,
int
offset
,
int
leap59
,
int
leap61
)
{
return
unix_time_ops
.
set_utc_offset
(
ppi
,
offset
,
leap59
,
leap61
);
}
static
int
wrs_time_get_servo_state
(
struct
pp_instance
*
ppi
,
int
*
state
)
{
struct
wr_dsport
*
wrp
=
WR_DSPOR
(
ppi
);
int
locked
;
locked
=
wrp
->
ops
->
locking_poll
(
ppi
,
1
);
if
(
locked
==
WR_SPLL_READY
)
*
state
=
PP_SERVO_LOCKED
;
else
*
state
=
PP_SERVO_UNLOCKED
;
return
0
;
}
/* This is only used when the wrs is slave to a non-WR master */
static
int
wrs_time_get
(
struct
pp_instance
*
ppi
,
struct
pp_time
*
t
)
{
...
...
@@ -222,7 +265,6 @@ static int wrs_time_set(struct pp_instance *ppi, const struct pp_time *t)
{
struct
pp_time
diff
,
now
;
struct
timex
tx
;
int
tai_offset
=
0
;
int
msec
;
/*
...
...
@@ -279,25 +321,8 @@ static int wrs_time_set(struct pp_instance *ppi, const struct pp_time *t)
if
(
t
->
secs
<
1420730822
/* "now" as I write this */
)
return
0
;
/*
* Finally, set unix time too, but count the UTC/TAI difference
* assuming somebody has set up up for us
*/
memset
(
&
tx
,
0
,
sizeof
(
tx
));
if
(
adjtimex
(
&
tx
)
>=
0
)
{
/*
* Our WRS kernel has tai support, but our compiler does not.
* We are 32-bit only, and we know for sure that tai is
* exactly after stbcnt. It's a bad hack, but it works
*/
tai_offset
=
*
((
int
*
)(
&
tx
.
stbcnt
)
+
1
);
}
{
struct
pp_time
utc
=
*
t
;
/* t is "const". uff.... */
utc
.
secs
-=
tai_offset
;
unix_time_ops
.
set
(
ppi
,
&
utc
);
}
/* Finally, set unix time too */
unix_time_ops
.
set
(
ppi
,
t
);
return
0
;
}
...
...
@@ -371,6 +396,10 @@ static unsigned long wrs_calc_timeout(struct pp_instance *ppi,
}
struct
pp_time_operations
wrs_time_ops
=
{
.
get_utc_time
=
wrs_time_get_utc_time
,
.
get_utc_offset
=
wrs_time_get_utc_offset
,
.
set_utc_offset
=
wrs_time_set_utc_offset
,
.
get_servo_state
=
wrs_time_get_servo_state
,
.
get
=
wrs_time_get
,
.
set
=
wrs_time_set
,
.
adjust
=
wrs_time_adjust
,
...
...
timeout.c
View file @
ff6d7afa
...
...
@@ -22,6 +22,7 @@ struct timeout_config {
static
struct
timeout_config
to_configs
[
__PP_TO_ARRAY_SIZE
]
=
{
[
PP_TO_REQUEST
]
=
{
"REQUEST"
,
RAND_0_200
,},
[
PP_TO_SYNC_SEND
]
=
{
"SYNC_SEND"
,
RAND_70_130
,},
[
PP_TO_BMC
]
=
{
"BMC"
,
RAND_NONE
,},
[
PP_TO_ANN_RECEIPT
]
=
{
"ANN_RECEIPT"
,
RAND_NONE
,},
[
PP_TO_ANN_SEND
]
=
{
"ANN_SEND"
,
RAND_70_130
,},
[
PP_TO_FAULT
]
=
{
"FAULT"
,
RAND_NONE
,
4000
},
...
...
@@ -40,6 +41,7 @@ void pp_timeout_init(struct pp_instance *ppi)
to_configs
[
PP_TO_FAULT
].
value
=
1
<<
(
port
->
logMinDelayReqInterval
+
12
);
/* 0 -> 4096ms */
to_configs
[
PP_TO_SYNC_SEND
].
value
=
port
->
logSyncInterval
;
to_configs
[
PP_TO_BMC
].
value
=
1000
*
(
1
<<
port
->
logAnnounceInterval
);
to_configs
[
PP_TO_ANN_RECEIPT
].
value
=
1000
*
(
port
->
announceReceiptTimeout
<<
port
->
logAnnounceInterval
);
to_configs
[
PP_TO_ANN_SEND
].
value
=
port
->
logAnnounceInterval
;
...
...
@@ -54,6 +56,10 @@ void __pp_timeout_set(struct pp_instance *ppi, int index, int millisec)
to_configs
[
index
].
name
,
millisec
);
}
void
pp_timeout_clear
(
struct
pp_instance
*
ppi
,
int
index
)
{
__pp_timeout_set
(
ppi
,
index
,
0
);
}
void
pp_timeout_set
(
struct
pp_instance
*
ppi
,
int
index
)
{
...
...
@@ -111,8 +117,11 @@ void pp_timeout_set(struct pp_instance *ppi, int index)
void
pp_timeout_setall
(
struct
pp_instance
*
ppi
)
{
int
i
;
for
(
i
=
0
;
i
<
__PP_TO_ARRAY_SIZE
;
i
++
)
pp_timeout_set
(
ppi
,
i
);
for
(
i
=
0
;
i
<
__PP_TO_ARRAY_SIZE
;
i
++
)
{
/* keep BMC timeout */
if
(
i
!=
PP_TO_BMC
)
pp_timeout_set
(
ppi
,
i
);
}
/* but announce_send must be send soon */
__pp_timeout_set
(
ppi
,
PP_TO_ANN_SEND
,
20
);
}
...
...
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