You can subscribe to this list here.
| 2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(4) |
Aug
(12) |
Sep
(5) |
Oct
(28) |
Nov
(6) |
Dec
(1) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2011 |
Jan
(1) |
Feb
(18) |
Mar
|
Apr
|
May
|
Jun
(2) |
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(8) |
Nov
(3) |
Dec
(13) |
| 2012 |
Jan
(6) |
Feb
(9) |
Mar
(5) |
Apr
(2) |
May
(8) |
Jun
(37) |
Jul
(28) |
Aug
(16) |
Sep
(5) |
Oct
(2) |
Nov
(12) |
Dec
(4) |
| 2013 |
Jan
|
Feb
(11) |
Mar
(4) |
Apr
(3) |
May
(13) |
Jun
(3) |
Jul
(14) |
Aug
(21) |
Sep
(15) |
Oct
(38) |
Nov
(36) |
Dec
(12) |
| 2014 |
Jan
(12) |
Feb
(13) |
Mar
(22) |
Apr
(3) |
May
(2) |
Jun
(8) |
Jul
(11) |
Aug
(7) |
Sep
(5) |
Oct
(3) |
Nov
|
Dec
(1) |
| 2015 |
Jan
(1) |
Feb
|
Mar
|
Apr
(2) |
May
|
Jun
(36) |
Jul
(5) |
Aug
(1) |
Sep
(3) |
Oct
(13) |
Nov
(4) |
Dec
|
| 2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Sebastian P. <seb...@gm...> - 2021-05-31 04:40:54
|
I am using 2 Ubuntu VMs,one as slave and one as master. Slave sudo ptpd -i enp0s3 -s -C --ptpengine:transport=ethernet --ptpengine:disable_bmca=1 Master sudo ptpd -i enp0s3 -M -C --ptpengine:transport=ethernet --ptpengine:disable_bmca=1 This is the output I am getting on the slave side but the clock isnt updating. 2021-05-31 08:38:04.514524 ptpd2[63762].startup (info) (___) Configuration OK 2021-05-31 08:38:04.514801 ptpd2[63762].startup (info) (___) Successfully acquired lock on /var/run/ptpd2.lock 2021-05-31 08:38:04.514902 ptpd2[63762].startup (notice) (___) PTPDv2 started successfully on enp0s3 using "slaveonly" preset (PID 63762) 2021-05-31 08:38:04.514920 ptpd2[63762].startup (info) (___) TimingService.PTP0: PTP service init 2021-05-31 08:38:04.600221 ptpd2[63762].enp0s3 (info) (init) Observed_drift loaded from kernel: 500000 ppb 2021-05-31 08:38:04.600287 ptpd2[63762].enp0s3 (notice) (lstn_init) Now in state: PTP_LISTENING 2021-05-31 08:38:05.664053 ptpd2[63762].enp0s3 (info) (lstn_init) New best master selected: 080027fffe16a902(unknown)/1 2021-05-31 08:38:05.664095 ptpd2[63762].enp0s3 (notice) (slv) Now in state: PTP_SLAVE, Best master: 080027fffe16a902(unknown)/1 2021-05-31 08:38:05.664111 ptpd2[63762].enp0s3 (notice) (slv) Received first Sync from Master 2021-05-31 08:38:06.668126 ptpd2[63762].enp0s3 (notice) (slv) Servo: Going to slew the clock with the maximum frequency adjustment 2021-05-31 08:38:06.676018 ptpd2[63762].enp0s3 (notice) (slv) Received first Delay Response from Master 2021-05-31 08:38:14.515040 ptpd2[63762].enp0s3 (notice) (slv) TimingService.PTP0: elected best TimingService 2021-05-31 08:38:14.515088 ptpd2[63762].enp0s3 (info) (slv) TimingService.PTP0: acquired clock control How do I fix this?? |
|
From: <wow...@us...> - 2015-11-20 00:24:19
|
Revision: 604
http://sourceforge.net/p/ptpd/code/604
Author: wowczarek
Date: 2015-11-20 00:24:17 +0000 (Fri, 20 Nov 2015)
Log Message:
-----------
- minor ChangeLog update
Modified Paths:
--------------
trunk/ChangeLog
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2015-11-20 00:21:33 UTC (rev 603)
+++ trunk/ChangeLog 2015-11-20 00:24:17 UTC (rev 604)
@@ -1,6 +1,6 @@
2013-10-23 Wojciech Owczarek <woj...@ow...>
- * 2.3.2 releae
+ * 2.3.2 release
* Bug fixes / improvements since 2.3.1:
@@ -98,6 +98,7 @@
some missing values, PTPd now properly applies
configuration when receiving SET messages
- added simple SNMP poller script: snmptpq
+ - SNMP MIB now using PTPd's own Enterprise number
2013-06-10 Wojciech Owczarek <woj...@ow...>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-11-20 00:21:36
|
Revision: 603
http://sourceforge.net/p/ptpd/code/603
Author: wowczarek
Date: 2015-11-20 00:21:33 +0000 (Fri, 20 Nov 2015)
Log Message:
-----------
- management message handlers moved to management.c
- added support for configurable disabled state
[ todo: init network on disabled start]
- minor refactoring and typo fixes
- user-configurable clock user description
- correct profile ID reported based on configuration
- simplified enum option mapping in configuration
- added buffer guard function when unpacking
management TLVs to prevent from malformed
messages causing issues
- management TLVs no longer unpacked for GET
type requests - not needed
- support for nested / multiple embedded management
TLVs in a single message
- ptpd now responds to NULL management messages,
this is needed because some management
tools require this to detect live nodes
- SET management messages now apply configuration
properly via dictionary
- fixed multiple issues remaining after removing
config parse macros
- reworked config apply / reload code for more
clarity
- updated PTP SNMP MIB
- added counter table imlpementation for SNMP,
with writable counter clear hanfles
- added most code required for implementing
SNMP traps defined in the MIB
- added snmptpq, a simple but useful SNMP poller
script
Modified Paths:
--------------
trunk/ChangeLog
trunk/TODO
trunk/doc/PTPBASE-MIB.txt
trunk/src/arith.c
trunk/src/bmc.c
trunk/src/constants.h
trunk/src/datatypes.h
trunk/src/dep/configdefaults.c
trunk/src/dep/constants_dep.h
trunk/src/dep/daemonconfig.c
trunk/src/dep/daemonconfig.h
trunk/src/dep/iniparser/dictionary.c
trunk/src/dep/msg.c
trunk/src/dep/ptpd_dep.h
trunk/src/dep/servo.c
trunk/src/dep/snmp.c
trunk/src/dep/startup.c
trunk/src/dep/sys.c
trunk/src/display.c
trunk/src/management.c
trunk/src/protocol.c
trunk/src/ptpd.h
trunk/src/ptpd2.conf.5.in
trunk/src/ptpd2.conf.default-full
trunk/src/signaling.c
trunk/src/templates.conf
trunk/src/timingdomain.c
Added Paths:
-----------
trunk/src/def/managementTLV/unicastNegotiationEnable.def
trunk/tools/snmptpq
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2015-11-15 04:26:52 UTC (rev 602)
+++ trunk/ChangeLog 2015-11-20 00:21:33 UTC (rev 603)
@@ -55,10 +55,16 @@
significantly reduced memory footprint
- added dummy Makefile to src/dep to allow make commands
from that directory
+ - added buffer overflow protection for management
+ TLVs: protects against read past message length,
+ and against read past buffer space
* New features since 2.3.1:
- - support for user variables in configuration
+ - support for user variables in configuration:
+ - variables specified variables:name=val, and
+ used as @name@
+ - built-in variables: @pid@, @hostname@
- support for configuration templates:
- built-in
- template files
@@ -84,6 +90,14 @@
- fixed preserving incorrect master address when
best master lowers priority (GM change as a result
of announce from current master, not foreign)
+ - PTP MIB enhanced with string values, counter support,
+ clearing counters and more, added some missing items
+ from previously supported items
+ - SNMP trap support for common alarm conditions
+ - enhanced management message support: enable/disable port,
+ some missing values, PTPd now properly applies
+ configuration when receiving SET messages
+ - added simple SNMP poller script: snmptpq
2013-06-10 Wojciech Owczarek <woj...@ow...>
Modified: trunk/TODO
===================================================================
--- trunk/TODO 2015-11-15 04:26:52 UTC (rev 602)
+++ trunk/TODO 2015-11-20 00:21:33 UTC (rev 603)
@@ -13,10 +13,17 @@
- rework config option parsing x
- rework parseConfig to support an opcode, get rid of remaining macros x
- rework trigger and dependency macros: 2nd pass?
-- SET messages to refresh the config properly
+- SET messages to refresh the config properly x/-
- NVRAM write?
- pointer to best master x
- disqualification flag x
- remove masteraddr in favour of bestMaster->sourceAddr x
- use split token loop
- use pointer to best master x
+- management TLV buffer guard and don't unpack GET x
+- SNMP - implement statistics tables
+- SNMP - implement remaining traps
+- add alarm events -> trigger SNMP traps
+- add offset alarm threshold to config
+- remaining management message SET handling
+- clean up object order in the MIB
Modified: trunk/doc/PTPBASE-MIB.txt
===================================================================
--- trunk/doc/PTPBASE-MIB.txt 2015-11-15 04:26:52 UTC (rev 602)
+++ trunk/doc/PTPBASE-MIB.txt 2015-11-20 00:21:33 UTC (rev 603)
@@ -1,2928 +1,5741 @@
PTPBASE-MIB DEFINITIONS ::= BEGIN
IMPORTS
- MODULE-IDENTITY,
- OBJECT-TYPE,
- Integer32,
- Gauge32,
- Unsigned32,
- Counter32,
- Counter64,
- enterprises
- FROM SNMPv2-SMI
- OBJECT-GROUP,
- MODULE-COMPLIANCE
- FROM SNMPv2-CONF
- TEXTUAL-CONVENTION,
- TruthValue,
- DisplayString
- FROM SNMPv2-TC
- InterfaceIndexOrZero
- FROM IF-MIB
- InetAddressType,
- InetAddress
- FROM INET-ADDRESS-MIB;
+ enterprises,
+ MODULE-IDENTITY,
+ OBJECT-TYPE,
+ NOTIFICATION-TYPE,
+ Counter32,
+ Counter64,
+ Gauge32,
+ Integer32,
+ Unsigned32
+ FROM SNMPv2-SMI
+ TruthValue,
+ DisplayString,
+ TEXTUAL-CONVENTION
+ FROM SNMPv2-TC
+ InterfaceIndexOrZero
+ FROM IF-MIB
+ InetAddress,
+ InetAddressType
+ FROM INET-ADDRESS-MIB
+ OBJECT-GROUP,
+ NOTIFICATION-GROUP,
+ MODULE-COMPLIANCE
+ FROM SNMPv2-CONF;
-
ptpbaseMIB MODULE-IDENTITY
- LAST-UPDATED "201201230000Z"
- ORGANIZATION "TICTOC Working Group"
- CONTACT-INFO
- "WG Email: ti...@ie...
+ LAST-UPDATED "201510272300Z" -- Oct 27, 2015 11:00:00 PM
+ ORGANIZATION "TICTOC Working Group, PTPd project"
+ CONTACT-INFO
+ "WG Email: ti...@ie...
- Vinay Shankarkumar
- Cisco Systems,
- Email: vi...@ci...
+ Vinay Shankarkumar
+ Cisco Systems,
+ Email: vi...@ci...
- Laurent Montini,
- Cisco Systems,
- Email: lmo...@ci...
+ Laurent Montini,
+ Cisco Systems,
+ Email: lmo...@ci...
- Tim Frost,
- Symmetricom Inc.,
- Email: tf...@sy...
+ Tim Frost,
+ Symmetricom Inc.,
+ Email: tf...@sy...
- Greg Dowd,
- Symmetricom Inc.,
- Email: gd...@sy..."
+ Greg Dowd,
+ Symmetricom Inc.,
+ Email: gd...@sy...
+ Wojciech Owczarek
+ PTPd project,
+ Email: woj...@ow..."
+ DESCRIPTION
+ "The MIB module for PTP version 2 (IEEE Std. 1588(TM)-2008)
- DESCRIPTION
- "The MIB module for PTP version 2 (IEEE Std. 1588(TM)-2008)
+ Overview of PTP version 2 (IEEE Std. 1588(TM)-2008)
- Overview of PTP version 2 (IEEE Std. 1588(TM)-2008)
+ [IEEE 1588-2008] defines a protocol enabling precise
+ synchronization of clocks in measurement and control systems
+ implemented with packet-based networks, the Precision Time
+ Protocol Version 2 (PTPv2). This MIB does not address the
+ earlier version IEEE Std. 1588(TM)-2002 (PTPv1). The protocol
+ is applicable to network elements communicating using IP. The
+ protocol enables heterogeneous systems that include clocks of
+ various inherent precision, resolution, and stability to
+ synchronize to a grandmaster clock.
- [IEEE 1588-2008] defines a protocol enabling precise
- synchronization of clocks in measurement and control systems
- implemented with packet-based networks, the Precision Time
- Protocol Version 2 (PTPv2). This MIB does not address the
- earlier version IEEE Std. 1588(TM)-2002 (PTPv1). The protocol
- is applicable to network elements communicating using IP. The
- protocol enables heterogeneous systems that include clocks of
- various inherent precision, resolution, and stability to
- synchronize to a grandmaster clock.
+ The protocol supports system-wide synchronization accuracy in
+ the sub-microsecond range with minimal network and local clock
+ computing resources. [IEEE 1588-2008] uses UDP/IP or
+ Ethernet and can be adapted to other mappings. It includes
+ formal mechanisms for message extensions, higher sampling rates,
+ correction for asymmetry, a clock type to reduce error
+ accumulation in large topologies, and specifications on how to
+ incorporate the resulting additional data into the
+ synchronization protocol. The [IEEE 1588-2008] defines
+ conformance and management capability also.
- The protocol supports system-wide synchronization accuracy in
- the sub-microsecond range with minimal network and local clock
- computing resources. [IEEE 1588-2008] uses UDP/IP or
- Ethernet and can be adapted to other mappings. It includes
- formal mechanisms for message extensions, higher sampling rates,
- correction for asymmetry, a clock type to reduce error
- accumulation in large topologies, and specifications on how to
- incorporate the resulting additional data into the
- synchronization protocol. The [IEEE 1588-2008] defines
- conformance and management capability also.
+ MIB description
- MIB description
+ This MIB is to support the Precision Time Protocol version 2
+ (PTPv2, hereafter designated as PTP) features of network element
+ system devices, when using the default PTP profile described in
+ [IEEE 1588-2008], or the Telecom Profile described in
+ [G.8265.1], when running over the IP network layer.
- This MIB is to support the Precision Time Protocol version 2
- (PTPv2, hereafter designated as PTP) features of network element
- system devices, when using the default PTP profile described in
- [IEEE 1588-2008], or the Telecom Profile described in
- [G.8265.1], when running over the IP network layer.
+ This MIB is based on the TICTOC-PTPBASE-MIB from 2012, with
+ added enhancements such as GM address, Offset from Master as
+ string, Mean Path Delay as string, parent IP address, and a set
+ of PTP traps.
- It is envisioned this MIB will complement other managed objects
- to be defined to monitor, measure the performance of the PTP
- devices and telecom clocks.
+ It is envisioned this MIB will complement other managed objects
+ to be defined to monitor, measure the performance of the PTP
+ devices and telecom clocks.
- Some other PTP profiles have their own MIBs defined as part of
- the profile, and this MIB is not intended to replace those MIBs.
+ Some other PTP profiles have their own MIBs defined as part of
+ the profile, and this MIB is not intended to replace those MIBs.
- Acronyms:
- ARB Arbitrary Timescale
- E2E End-to-End
- EUI Extended Unique Identifier.
- GPS Global Positioning System
- IANA Internet Assigned Numbers Authority
- IP Internet Protocol
+ Acronyms:
+ ARB Arbitrary Timescale
+ E2E End-to-End
+ EUI Extended Unique Identifier.
+ GPS Global Positioning System
+ IANA Internet Assigned Numbers Authority
+ IP Internet Protocol
- MAC Media Access Control
- according to [IEEE 802.3-2008]
- NIST National Institute of Standards and Technology
- NTP Network Time Protocol (see IETF [RFC 5905])
- OUI Organizational Unique Identifier
- (allocated by the IEEE)
- P2P Peer-to-Peer
- PTP Precision Time Protocol
- TAI International Atomic Time
- TC Transparent Clock
- UDP User Datagram Protocol
- UTC Coordinated Universal Time
+ MAC Media Access Control
+ according to [IEEE 802.3-2008]
+ NIST National Institute of Standards and Technology
+ NTP Network Time Protocol (see IETF [RFC 5905])
+ OUI Organizational Unique Identifier
+ (allocated by the IEEE)
+ P2P Peer-to-Peer
+ PTP Precision Time Protocol
+ TAI International Atomic Time
+ TC Transparent Clock
+ UDP User Datagram Protocol
+ UTC Coordinated Universal Time
- References:
- [IEEE 1588-2008] IEEE Standard for A Precision Clock
- Synchronization Protocol for Networked Measurement and
- Control Systems, IEEE Std. 1588(TM)-2008, 24 July 2008.
+ References:
+ [IEEE 1588-2008] IEEE Standard for A Precision Clock
+ Synchronization Protocol for Networked Measurement and
+ Control Systems, IEEE Std. 1588(TM)-2008, 24 July 2008.
- [G.8265.1] Precision Time Protocol Telecom Profile for
- Frequency Synchronization, ITU-T Recommendation G.8265.1,
- October 2010.
+ [G.8265.1] Precision Time Protocol Telecom Profile for
+ Frequency Synchronization, ITU-T Recommendation G.8265.1,
+ October 2010.
- As defined in [IEEE 1588-2008]:
+ As defined in [IEEE 1588-2008]:
- Accuracy:
- The mean of the time or frequency error between the clock under
- test and a perfect reference clock, over an ensemble of
- measurements. Stability is a measure of how the mean varies
- with respect to variables such as time, temperature, and so on,
- while the precision is a measure of the deviation of the error
- from the mean.
+ Accuracy:
+ The mean of the time or frequency error between the clock under
+ test and a perfect reference clock, over an ensemble of
+ measurements. Stability is a measure of how the mean varies
+ with respect to variables such as time, temperature, and so on,
+ while the precision is a measure of the deviation of the error
+ from the mean.
- Atomic process:
- A process is atomic if the values of all inputs to the process
- are not permitted to change until all of the results of the
- process are instantiated, and the outputs of the process are
- not visible to other processes until the processing of each
- output is complete.
+ Atomic process:
+ A process is atomic if the values of all inputs to the process
+ are not permitted to change until all of the results of the
+ process are instantiated, and the outputs of the process are
+ not visible to other processes until the processing of each
+ output is complete.
- Boundary clock:
- A clock that has multiple Precision Time Protocol (PTP) ports in
- a domain and maintains the timescale used in the domain. It
- may serve as the source of time, i.e., be a master clock, and
- may synchronize to another clock, i.e., be a slave clock.
+ Boundary clock:
+ A clock that has multiple Precision Time Protocol (PTP) ports in
+ a domain and maintains the timescale used in the domain. It
+ may serve as the source of time, i.e., be a master clock, and
+ may synchronize to another clock, i.e., be a slave clock.
- Boundary node clock:
- A clock that has multiple Precision Time Protocol(PTP) ports in
- a domain and maintains the timescale used in the domain. It
+ Boundary node clock:
+ A clock that has multiple Precision Time Protocol(PTP) ports in
+ a domain and maintains the timescale used in the domain. It
- differs from a boundary clock in that the clock roles can
- change.
+ differs from a boundary clock in that the clock roles can
+ change.
- Clock:
- A node participating in the Precision Time Protocol (PTP) that
- is capable of providing a measurement of the passage of time
- since a defined epoch.
+ Clock:
+ A node participating in the Precision Time Protocol (PTP) that
+ is capable of providing a measurement of the passage of time
+ since a defined epoch.
- Domain:
- A logical grouping of clocks that synchronize to each other
- using the protocol, but that are not necessarily synchronized
- to clocks in another domain.
+ Domain:
+ A logical grouping of clocks that synchronize to each other
+ using the protocol, but that are not necessarily synchronized
+ to clocks in another domain.
- End-to-end transparent clock:
- A transparent clock that supports the use of the end-to-end
- delay measurement mechanism between slave clocks and the master
- clock. Each node must measure the residence time of PTP event
- messages and accumulate it in Correction Field.
+ End-to-end transparent clock:
+ A transparent clock that supports the use of the end-to-end
+ delay measurement mechanism between slave clocks and the master
+ clock. Each node must measure the residence time of PTP event
+ messages and accumulate it in Correction Field.
- Epoch:
- The origin of a timescale.
+ Epoch:
+ The origin of a timescale.
- Event:
- An abstraction of the mechanism by which signals or conditions
- are generated and represented.
+ Event:
+ An abstraction of the mechanism by which signals or conditions
+ are generated and represented.
- Foreign master:
- An ordinary or boundary clock sending Announce messages to
- another clock that is not the current master recognized by the
- other clock.
+ Foreign master:
+ An ordinary or boundary clock sending Announce messages to
+ another clock that is not the current master recognized by the
+ other clock.
- Grandmaster clock:
- Within a domain, a clock that is the ultimate source of time
- for clock synchronization using the protocol.
+ Grandmaster clock:
+ Within a domain, a clock that is the ultimate source of time
+ for clock synchronization using the protocol.
- Holdover:
- A clock previously synchronized/syntonized to another clock
- (normally a primary reference or a master clock) but now
- free-running based on its own internal oscillator, whose
- frequency is being adjusted using data acquired while it had
- been synchronized/syntonized to the other clock. It is said to
- be in holdover or in the holdover mode, as long as it is within
- its accuracy requirements.
+ Holdover:
+ A clock previously synchronized/syntonized to another clock
+ (normally a primary reference or a master clock) but now
+ free-running based on its own internal oscillator, whose
+ frequency is being adjusted using data acquired while it had
+ been synchronized/syntonized to the other clock. It is said to
+ be in holdover or in the holdover mode, as long as it is within
+ its accuracy requirements.
- Link:
- A network segment between two Precision Time Protocol ports
- supporting the peer delay mechanism of this standard. The peer
- delay mechanism is designed to measure the propagation time
- over such a link.
+ Link:
+ A network segment between two Precision Time Protocol ports
+ supporting the peer delay mechanism of this standard. The peer
+ delay mechanism is designed to measure the propagation time
+ over such a link.
- Management node:
- A device that configures and monitors clocks.
+ Management node:
+ A device that configures and monitors clocks.
- Master clock:
- In the context of a single Precision Time Protocol
- communication path, a clock that is the source of time to which
- all other clocks on that path synchronize.
+ Master clock:
+ In the context of a single Precision Time Protocol
+ communication path, a clock that is the source of time to which
+ all other clocks on that path synchronize.
- Message timestamp point:
- A point within a Precision Time Protocol event message serving
- as a reference point in the message. A timestamp is defined by
- the instant a message timestamp point passes the reference
- plane of a clock.
+ Message timestamp point:
+ A point within a Precision Time Protocol event message serving
+ as a reference point in the message. A timestamp is defined by
+ the instant a message timestamp point passes the reference
+ plane of a clock.
- Multicast communication:
- A communication model in which each Precision Time Protocol
- message sent from any PTP port is capable of being received and
- processed by all PTP ports on the same PTP communication path.
+ Multicast communication:
+ A communication model in which each Precision Time Protocol
+ message sent from any PTP port is capable of being received and
+ processed by all PTP ports on the same PTP communication path.
- Node:
- A device that can issue or receive Precision Time Protocol
- communications on a network.
+ Node:
+ A device that can issue or receive Precision Time Protocol
+ communications on a network.
- One-step clock:
- A clock that provides time information using a single event
- message.
+ One-step clock:
+ A clock that provides time information using a single event
+ message.
- On-pass support:
- Indicates that each node in the synchronization chain from
- master to slave can support IEEE-1588.
+ On-pass support:
+ Indicates that each node in the synchronization chain from
+ master to slave can support IEEE-1588.
- Ordinary clock:
- A clock that has a single Precision Time Protocol port in a
- domain and maintains the timescale used in the domain. It may
- serve as a source of time, i.e., be a master clock, or may
- synchronize to another clock, i.e., be a slave clock.
+ Ordinary clock:
+ A clock that has a single Precision Time Protocol port in a
+ domain and maintains the timescale used in the domain. It may
+ serve as a source of time, i.e., be a master clock, or may
+ synchronize to another clock, i.e., be a slave clock.
- Parent clock:
- The master clock to which a clock is synchronized.
+ Parent clock:
+ The master clock to which a clock is synchronized.
- Peer-to-peer transparent clock:
- A transparent clock that, in addition to providing Precision
- Time Protocol event transit time information, also provides
- corrections for the propagation delay of the link connected to
- the port receiving the PTP event message. In the presence of
- peer-to-peer transparent clocks, delay measurements between
- slave clocks and the master clock are performed using the
- peer-to-peer delay measurement mechanism.
+ Peer-to-peer transparent clock:
+ A transparent clock that, in addition to providing Precision
+ Time Protocol event transit time information, also provides
+ corrections for the propagation delay of the link connected to
+ the port receiving the PTP event message. In the presence of
+ peer-to-peer transparent clocks, delay measurements between
+ slave clocks and the master clock are performed using the
+ peer-to-peer delay measurement mechanism.
- Phase change rate:
- The observed rate of change in the measured time with respect
- to the reference time. The phase change rate is equal to the
- fractional frequency offset between the measured frequency and
- the reference frequency.
+ Phase change rate:
+ The observed rate of change in the measured time with respect
+ to the reference time. The phase change rate is equal to the
+ fractional frequency offset between the measured frequency and
+ the reference frequency.
- PortNumber:
- An index identifying a specific Precision Time Protocol port on
- a PTP node.
+ PortNumber:
+ An index identifying a specific Precision Time Protocol port on
+ a PTP node.
- Primary reference:
- A source of time and or frequency that is traceable to
- international standards.
+ Primary reference:
+ A source of time and or frequency that is traceable to
+ international standards.
- Profile:
- The set of allowed Precision Time Protocol features applicable
- to a device.
+ Profile:
+ The set of allowed Precision Time Protocol features applicable
+ to a device.
- Precision Time Protocol communication:
- Information used in the operation of the protocol, transmitted
- in a PTP message over a PTP communication path.
+ Precision Time Protocol communication:
+ Information used in the operation of the protocol, transmitted
+ in a PTP message over a PTP communication path.
- Precision Time Protocol communication path:
- The signaling path portion of a particular network enabling
- direct communication among ordinary and boundary clocks.
+ Precision Time Protocol communication path:
+ The signaling path portion of a particular network enabling
+ direct communication among ordinary and boundary clocks.
- Precision Time Protocol node:
- PTP ordinary, boundary, or transparent clock or a device that
- generates or parses PTP messages.
+ Precision Time Protocol node:
+ PTP ordinary, boundary, or transparent clock or a device that
+ generates or parses PTP messages.
- Precision Time Protocol port:
- A logical access point of a clock for PTP communications to the
- communications network.
+ Precision Time Protocol port:
+ A logical access point of a clock for PTP communications to the
+ communications network.
- Recognized standard time source:
- A recognized standard time source is a source external to
- Precision Time Protocol that provides time and/or frequency as
- appropriate that is traceable to the international standards
- laboratories maintaining clocks that form the basis for the
- International Atomic Time and Universal Coordinated Time
- timescales. Examples of these are GPS, NTP, and NIST
- timeservers.
+ Recognized standard time source:
+ A recognized standard time source is a source external to
+ Precision Time Protocol that provides time and/or frequency as
+ appropriate that is traceable to the international standards
+ laboratories maintaining clocks that form the basis for the
+ International Atomic Time and Universal Coordinated Time
+ timescales. Examples of these are GPS, NTP, and NIST
+ timeservers.
- Requestor:
- The port implementing the peer-to-peer delay mechanism that
- initiates the mechanism by sending a Pdelay_Req message.
+ Requestor:
+ The port implementing the peer-to-peer delay mechanism that
+ initiates the mechanism by sending a Pdelay_Req message.
- Responder:
+ Responder:
- The port responding to the receipt of a Pdelay_Req message as
- part of the operation of the peer-to-peer delay mechanism.
+ The port responding to the receipt of a Pdelay_Req message as
+ part of the operation of the peer-to-peer delay mechanism.
- Synchronized clocks:
- Two clocks are synchronized to a specified uncertainty if they
- have the same epoch and their measurements of the time of a
- single event at an arbitrary time differ by no more than that
- uncertainty.
+ Synchronized clocks:
+ Two clocks are synchronized to a specified uncertainty if they
+ have the same epoch and their measurements of the time of a
+ single event at an arbitrary time differ by no more than that
+ uncertainty.
- Syntonized clocks:
- Two clocks are syntonized if the duration of the second is the
- same on both, which means the time as measured by each advances
- at the same rate. They may or may not share the same epoch.
+ Syntonized clocks:
+ Two clocks are syntonized if the duration of the second is the
+ same on both, which means the time as measured by each advances
+ at the same rate. They may or may not share the same epoch.
- Timeout:
- A mechanism for terminating requested activity that, at least
- from the requester's perspective, does not complete within the
- specified time.
+ Timeout:
+ A mechanism for terminating requested activity that, at least
+ from the requester's perspective, does not complete within the
+ specified time.
- Timescale:
- A linear measure of time from an epoch.
+ Timescale:
+ A linear measure of time from an epoch.
- Traceability:
- A property of the result of a measurement or the value of a
- standard whereby it can be related to stated references,
- usually national or international standards, through an
- unbroken chain of comparisons all having stated uncertainties.
+ Traceability:
+ A property of the result of a measurement or the value of a
+ standard whereby it can be related to stated references,
+ usually national or international standards, through an
+ unbroken chain of comparisons all having stated uncertainties.
- Translation device:
- A boundary clock or, in some cases, a transparent clock that
- translates the protocol messages between regions implementing
- different transport and messaging protocols, between different
- versions of [IEEE 1588-2008], or different PTP profiles.
+ Translation device:
+ A boundary clock or, in some cases, a transparent clock that
+ translates the protocol messages between regions implementing
+ different transport and messaging protocols, between different
+ versions of [IEEE 1588-2008], or different PTP profiles.
- Transparent clock:
- A device that measures the time taken for a Precision Time
- Protocol event message to transit the device and provides this
- information to clocks receiving this PTP event message.
+ Transparent clock:
+ A device that measures the time taken for a Precision Time
+ Protocol event message to transit the device and provides this
+ information to clocks receiving this PTP event message.
- Two-step clock:
- A clock that provides time information using the combination of
- an event message and a subsequent general message.
+ Two-step clock:
+ A clock that provides time information using the combination of
+ an event message and a subsequent general message.
- The below table specifies the object formats of the various
- textual conventions used.
+ The below table specifies the object formats of the various
+ textual conventions used.
- Data type mapping Textual Convention SYNTAX
- ------------------- ------------------ ---------------------
- 5.3.2 TimeInterval ClockTimeInterval OCTET STRING(SIZE(1..255))
+ Data type mapping Textual Convention SYNTAX
+ ------------------- ------------------ ---------------------
+ 5.3.2 TimeInterval ClockTimeInterval OCTET STRING(SIZE(1..255))
- 5.3.3 Timestamp ClockTimestamp OCTET STRING(SIZE(6))
- 5.3.4 ClockIdentity ClockIdentity OCTET STRING(SIZE(1..255))
- 5.3.5 PortIdentity ClockPortNumber INTEGER(1..65535)
- 5.3.7 ClockQuality ClockQualityClassType
+ 5.3.3 Timestamp ClockTimestamp OCTET STRING(SIZE(6))
+ 5.3.4 ClockIdentity ClockIdentity OCTET STRING(SIZE(1..255))
+ 5.3.5 PortIdentity ClockPortNumber INTEGER(1..65535)
+ 5.3.7 ClockQuality ClockQualityClassType
- Simple master-slave hierarchy, section 6.6.2.4 [IEEE 1588-2008]:
+ Simple master-slave hierarchy, section 6.6.2.4 [IEEE 1588-2008]:
- +---------------+
- | Ordinary |
- | Clock -1 |
- | (GrandMaster) |
- +-------M-------+
- |
- 1
- |
- +---------------S-----------------+
- | Boundary |
- | Clock -1 |
- +-----M---------------------M-----+
- | |
- 2 3
- | |
- +-----S-----+ +------------S-------------+
- | Ordinary | | Boundary |
- | Clock -2 | | Clock -2 |
- +-----------+ +-----M--------------M-----+
- | |
- 4 5
- | |
- +-----S-----+ +-----S-----+
- | Ordinary | | Ordinary |
- | Clock -3 | | Clock -4 |
- +-----------+ +-----------+
+ +---------------+
+ | Ordinary |
+ | Clock -1 |
+ | (GrandMaster) |
+ +-------M-------+
+ |
+ 1
+ |
+ +---------------S-----------------+
+ | Boundary |
+ | Clock -1 |
+ +-----M---------------------M-----+
+ | |
+ 2 3
+ | |
+ +-----S-----+ +------------S-------------+
+ | Ordinary | | Boundary |
+ | Clock -2 | | Clock -2 |
+ +-----------+ +-----M--------------M-----+
+ | |
+ 4 5
+ | |
+ +-----S-----+ +-----S-----+
+ | Ordinary | | Ordinary |
+ | Clock -3 | | Clock -4 |
+ +-----------+ +-----------+
- Grandmaster
+ Grandmaster
- Boundary Clock(0-N) Ordinary Clocks(0-N)
- Ordinary Clocks(0-N)
+ Boundary Clock(0-N) Ordinary Clocks(0-N)
+ Ordinary Clocks(0-N)
- Relationship cardinality:
- PTP system 1 : N PTP Clocks
- PTP Clock 1 : 1 Domain
- PTP Clock 1 : N PTP Ports
- PTP Ports N : M Physical Ports (interface in IF-MIB)
+ Relationship cardinality:
+ PTP system 1 : N PTP Clocks
+ PTP Clock 1 : 1 Domain
+ PTP Clock 1 : N PTP Ports
+ PTP Ports N : M Physical Ports (interface in IF-MIB)
- Transparent clock diagram, section 6.7.1.3 of [IEEE 1588-2008]:
+ Transparent clock diagram, section 6.7.1.3 of [IEEE 1588-2008]:
- +-----------------------------+
- | Boundary clock - 1 |
- +-----------------------------+
- | |
- | |
- +-- A --+ B
- | |
- +----------------------+ |
- | Ordinary clock | |
- +----------------------+ |
- +----------------------+
- +----------------------+ | End-to-end |
- | Ordinary clock 1-1 |----------| transparent clock- |
- +----------------------+ | 1 - 1 |
- +----------------------+
- |
- C
- |
- +----------------------+
- +----------------------+ | End-to-end |
- | Ordinary clock 1-2 |----------| transparent clock- |
- +----------------------+ | 1 - 2 |
- +----------------------+
+ +-----------------------------+
+ | Boundary clock - 1 |
+ +-----------------------------+
+ | |
+ | |
+ +-- A --+ B
+ | |
+ +----------------------+ |
+ | Ordinary clock | |
+ +----------------------+ |
+ +----------------------+
+ +----------------------+ | End-to-end |
+ | Ordinary clock 1-1 |----------| transparent clock- |
+ +----------------------+ | 1 - 1 |
+ +----------------------+
+ |
+ C
+ |
+ +----------------------+
+ +----------------------+ | End-to-end |
+ | Ordinary clock 1-2 |----------| transparent clock- |
+ +----------------------+ | 1 - 2 |
+ +----------------------+
- The MIB refers to the sections of [IEEE 1588-2008]."
+ The MIB refers to the sections of [IEEE 1588-2008]."
+ -- revision log
+ -- ::= { mib-2 XXX }
+ -- 1.3.6.1.4.1.46649.1.1
+::= { enterprises 46649 1 1 }
- -- revision log
- -- ::= { mib-2 XXX }
- ::= { enterprises 39178 100 2 } -- Temporary assignment under IMSCO OID
+-- PTPd Private Enterprise Number (PEN)
-
-
ClockDomainType ::= TEXTUAL-CONVENTION
- DISPLAY-HINT "d"
- STATUS current
- DESCRIPTION
- "The Domain is identified by an integer, the domainNumber, in
- the range of 0 to 255. An integer value that is used to assign
- each PTP device to a particular domain. The following values
- define the valid domains.
+ DISPLAY-HINT "d"
+ STATUS current
+ DESCRIPTION
+ "The Domain is identified by an integer, the domainNumber, in
+ the range of 0 to 255. An integer value that is used to assign
+ each PTP device to a particular domain. The following values
+ define the valid domains.
- Value Definition
- --------- -------------------
- 0 Default domain
- 1 Alternate domain 1
- 2 Alternate domain 2
- 3 Alternate domain 3
- 4 - 127 User-defined domains
+ Value Definition
+ --------- -------------------
+ 0 Default domain
+ 1 Alternate domain 1
+ 2 Alternate domain 2
+ 3 Alternate domain 3
+ 4 - 127 User-defined domains
- 128 - 255 Reserved"
+ 128 - 255 Reserved"
+ REFERENCE
+ "Section 7.1 Domains, Table 2 of [IEEE 1588-2008]"
+ SYNTAX Unsigned32 (0..255)
- REFERENCE "Section 7.1 Domains, Table 2 of [IEEE 1588-2008]"
- SYNTAX Unsigned32 (0..255)
ClockIdentity ::= TEXTUAL-CONVENTION
- STATUS current
- DESCRIPTION
- "The clock Identity is an 8-octet array and will be presented in
- the form of a character array. The value of the
- ClockIdentity should be taken from the IEEE EUI-64 individual
- assigned numbers as indicated in Section 7.5.2.2.2 of
- [IEEE 1588-2008]. The EUI-64 address is divided into the
- following fields:
+ STATUS current
+ DESCRIPTION
+ "The clock Identity is an 8-octet array and will be presented in
+ the form of a character array. The value of the
+ ClockIdentity should be taken from the IEEE EUI-64 individual
+ assigned numbers as indicated in Section 7.5.2.2.2 of
+ [IEEE 1588-2008]. The EUI-64 address is divided into the
+ following fields:
- OUI bytes (0-2)
- Extension identifier bytes (3-7)
+ OUI bytes (0-2)
+ Extension identifier bytes (3-7)
- The clock identifier can be constructed from existing EUI-48
- assignments and here is an abbreviated example extracted from
- section 7.5.2.2.2 [IEEE 1588-2008].
+ The clock identifier can be constructed from existing EUI-48
+ assignments and here is an abbreviated example extracted from
+ section 7.5.2.2.2 [IEEE 1588-2008].
- Company EUI-48 = 0xACDE4823456716
- EUI-64 = ACDE48FFFE23456716
+ Company EUI-48 = 0xACDE4823456716
+ EUI-64 = ACDE48FFFE23456716
- It is important to note the IEEE Registration Authority has
- deprecated the use of MAC-48 in any new design."
+ It is important to note the IEEE Registration Authority has
+ deprecated the use of MAC-48 in any new design."
+ REFERENCE
+ "Section 7.5.2.2.1 of [IEEE 1588-2008]"
+ SYNTAX OCTET STRING (SIZE (1..255))
- REFERENCE "Section 7.5.2.2.1 of [IEEE 1588-2008]"
- SYNTAX OCTET STRING (SIZE (1..255))
ClockIntervalBase2 ::= TEXTUAL-CONVENTION
- DISPLAY-HINT "d"
- STATUS current
- DESCRIPTION
- "The interval included in message types Announce, Sync,
- Delay_Req, and Pdelay_Req as indicated in section 7.7.2.1 of
- [IEEE 1588-2008].
+ DISPLAY-HINT "d"
+ STATUS current
+ DESCRIPTION
+ "The interval included in message types Announce, Sync,
+ Delay_Req, and Pdelay_Req as indicated in section 7.7.2.1 of
+ [IEEE 1588-2008].
- The mean time interval between successive messages shall be
- represented as the logarithm to the base 2 of this time
- interval measured in seconds on the local clock of the device
- sending the message. The values of these logarithmic attributes
- shall be selected from integers in the range -128 to 127 subject
- to further limits established in an applicable PTP profile."
+ The mean time interval between successive messages shall be
+ represented as the logarithm to the base 2 of this time
+ interval measured in seconds on the local clock of the device
+ sending the message. The values of these logarithmic attributes
+ shall be selected from integers in the range -128 to 127 subject
+ to further limits established in an applicable PTP profile."
+ REFERENCE
+ "Section 7.7.2.1 General interval specification of
+ [IEEE 1588-2008]"
+ SYNTAX Integer32 (-128..127)
- REFERENCE "Section 7.7.2.1 General interval specification of
- [IEEE 1588-2008]"
- SYNTAX Integer32 (-128..127)
-
ClockMechanismType ::= TEXTUAL-CONVENTION
- STATUS current
- DESCRIPTION
- "The clock type based on whether End to End or peer to peer
- mechanisms are used. The mechanism used to calculate the Mean
- Path Delay as indicated in Table 9 of [IEEE 1588-2008].
+ STATUS current
+ DESCRIPTION
+ "The clock type based on whether End to End or peer to peer
+ mechanisms are used. The mechanism used to calculate the Mean
+ Path Delay as indicated in Table 9 of [IEEE 1588-2008].
- Delay mechanism Value(hex) Specification
- --------------- ---------- -------------
- E2E 01 The port is configured to use the
- delay request-response mechanism.
- P2P 02 The port is configured to use the
- peer delay mechanism.
- DISABLED FE The port does not implement the
- delay mechanism."
+ Delay mechanism Value(hex) Specification
+ --------------- ---------- -------------
+ E2E 01 The port is configured to use the
+ delay request-response mechanism.
+ P2P 02 The port is configured to use the
+ peer delay mechanism.
+ DISABLED FE The port does not implement the
+ delay mechanism."
+ REFERENCE
+ "Sections 8.2.5.4.4, 6.6.4, 7.4.2 of [IEEE 1588-2008]."
+ SYNTAX INTEGER {
+ e2e(1),
+ p2p(2),
+ disabled(254) }
- REFERENCE "Sections 8.2.5.4.4, 6.6.4, 7.4.2 of [IEEE 1588-2008]."
- SYNTAX INTEGER {
- e2e(1),
- p2p(2),
- disabled(254)
- }
ClockInstanceType ::= TEXTUAL-CONVENTION
- DISPLAY-HINT "d"
- STATUS current
- DESCRIPTION
- "The instance of the Clock of a given clock type in a given
- domain."
- SYNTAX Unsigned32 (0..255)
+ DISPLAY-HINT "d"
+ STATUS current
+ DESCRIPTION
+ "The instance of the Clock of a given clock type in a given
+ domain."
+ SYNTAX Unsigned32 (0..255)
+
ClockPortNumber ::= TEXTUAL-CONVENTION
- DISPLAY-HINT "d"
- STATUS current
- DESCRIPTION
- "An index identifying a specific Precision Time Protocol (PTP)
- port on a PTP node."
+ DISPLAY-HINT "d"
+ STATUS current
+ DESCRIPTION
+ "An index identifying a specific Precision Time Protocol (PTP)
+ port on a PTP node."
+ REFERENCE
+ "Sections 7.5.2.3 and 5.3.5 of [IEEE 1588-2008]"
+ SYNTAX Unsigned32 (0..65535)
- REFERENCE "Sections 7.5.2.3 and 5.3.5 of [IEEE 1588-2008]"
- SYNTAX Unsigned32 (0..65535)
ClockPortState ::= TEXTUAL-CONVENTION
- STATUS current
- DESCRIPTION
- "This is the value of the current state of the protocol engine
- associated with this port.
- Port state Value Description
- -----------------------------------------------------------
+ STATUS current
+ DESCRIPTION
+ "This is the value of the current state of the protocol engine
+ associated with this port.
+ Port state Value Description
+ -----------------------------------------------------------
- initializing 1 In this state a port initializes
- its data sets, hardware, and
- communication facilities.
- faulty 2 The fault state of the protocol.
- disabled 3 The port shall not place any
- messages on its communication path.
- listening 4 The port is waiting for the
- announceReceiptTimeout to expire or
- to receive an Announce message from
- a master.
- preMaster 5 The port shall behave in all respects
- as though it were in the MASTER state
- except that it shall not place any
- messages on its communication path
- except for Pdelay_Req, Pdelay_Resp,
- Pdelay_Resp_Follow_Up, signaling, or
- management messages.
- master 6 The port is behaving as a master port.
- passive 7 The port shall not place any messages
- on its communication path except for
- Pdelay_Req, Pdelay_Resp,
- Pdelay_Resp_Follow_Up, or signaling
- messages, or management messages that
- are a required response to another
- management message
- uncalibrated 8 The local port is preparing to
- synchronize to the master port.
- slave 9 The port is synchronizing to the
- selected master port."
+ initializing 1 In this state a port initializes
+ its data sets, hardware, and
+ communication facilities.
+ faulty 2 The fault state of the protocol.
+ disabled 3 The port shall not place any
+ messages on its communication path.
+ listening 4 The port is waiting for the
+ announceReceiptTimeout to expire or
+ to receive an Announce message from
+ a master.
+ preMaster 5 The port shall behave in all respects
+ as though it were in the MASTER state
+ except that it shall not place any
+ messages on its communication path
+ except for Pdelay_Req, Pdelay_Resp,
+ Pdelay_Resp_Follow_Up, signaling, or
+ management messages.
+ master 6 The port is behaving as a master port.
+ passive 7 The port shall not place any messages
+ on its communication path except for
+ Pdelay_Req, Pdelay_Resp,
+ Pdelay_Resp_Follow_Up, or signaling
+ messages, or management messages that
+ are a required response to another
+ management message
+ uncalibrated 8 The local port is preparing to
+ synchronize to the master port.
+ slave 9 The port is synchronizing to the
+ selected master port."
+ REFERENCE
+ "Section 8.2.5.3.1 portState and 9.2.5 of
+ [IEEE 1588-2008]"
+ SYNTAX INTEGER {
+ initializing(1),
+ faulty(2),
+ disabled(3),
+ listening(4),
+ preMaster(5),
+ master(6),
+ passive(7),
+ uncalibrated(8),
+ slave(9) }
- REFERENCE "Section 8.2.5.3.1 portState and 9.2.5 of
- [IEEE 1588-2008]"
- SYNTAX INTEGER {
- initializing(1),
- faulty(2),
- disabled(3),
- listening(4),
- preMaster(5),
- master(6),
- passive(7),
- uncalibrated(8),
- slave(9)
- }
ClockProfileType ::= TEXTUAL-CONVENTION
- STATUS current
- DESCRIPTION
- "Clock Profile used. A profile is the set of allowed Precision
- Time Protocol (PTP) features applicable to a device."
+ STATUS current
+ DESCRIPTION
+ "Clock Profile used. A profile is the set of allowed Precision
+ Time Protocol (PTP) features applicable to a device."
+ REFERENCE
+ "Section 3.1.30 and 19.3 PTP profiles of
+ [IEEE 1588-2008]"
+ SYNTAX INTEGER {
+ default(1),
+ telecom(2),
+ vendorspecific(3) }
- REFERENCE "Section 3.1.30 and 19.3 PTP profiles of
- [IEEE 1588-2008]"
- SYNTAX INTEGER {
- default(1),
- telecom(2),
- vendorspecific(3)
- }
-
ClockQualityAccuracyType ::= TEXTUAL-CONVENTION
- STATUS current
- DESCRIPTION
- "The ClockQuality as specified in section 5.3.7, 7.6.2.5 and
- Table 6 of [IEEE 1588-2008].
+ STATUS current
+ DESCRIPTION
+ "The ClockQuality as specified in section 5.3.7, 7.6.2.5 and
+ Table 6 of [IEEE 1588-2008].
- The following values are not represented in the enumerated
- values.
+ The following values are not represented in the enumerated
+ values.
- 0x01-0x1F Reserved
- 0x32-0x7F Reserved
+ 0x01-0x1F Reserved
+ 0x32-0x7F Reserved
- It is important to note that section 7.1.1 RFC2578 allows for
- gaps and enumerate values to start with zero when indicated by
- the protocol."
+ It is important to note that section 7.1.1 RFC2578 allows for
+ gaps and enumerate values to start with zero when indicated by
+ the protocol."
+ REFERENCE
+ "Section 5.3.7, 7.6.2.5 and Table 6 of
+ [IEEE 1588-2008]"
+ SYNTAX INTEGER {
+ reserved00(1), -- 0
+ nanoSecond25(32), -- 0x20
+ nanoSecond100(33), -- 0x21
+ nanoSecond250(34), -- 0x22
+ microSec1(35), -- 0x23
+ microSec2dot5(36), -- 0x24
+ microSec10(37), -- 0x25
+ microSec25(38), -- 0x26
+ microSec100(39), -- 0x27
+ microSec250(40), -- 0x28
+ milliSec1(41), -- 0x29
+ milliSec2dot5(42), -- 0x2A
+ milliSec10(43), -- 0x2B
+ milliSec25(44), -- 0x2C
+ milliSec100(45), -- 0x2D
+ milliSec250(46), -- 0x2E
+ second1(47), -- 0x2F
+ second10(48), -- 0x30
+ secondGreater10(49), -- 0x31
+ unknown(254), -- 0xFE
+ reserved255(255) -- 0xFF
+ }
- REFERENCE "Section 5.3.7, 7.6.2.5 and Table 6 of
- [IEEE 1588-2008]"
- SYNTAX INTEGER {
- reserved00(1), -- 0
- nanoSecond25(32), -- 0x20
- nanoSecond100(33), -- 0x21
- nanoSecond250(34), -- 0x22
- microSec1(35), -- 0x23
- microSec2dot5(36), -- 0x24
- microSec10(37), -- 0x25
- microSec25(38), -- 0x26
- microSec100(39), -- 0x27
- microSec250(40), -- 0x28
- milliSec1(41), -- 0x29
- milliSec2dot5(42), -- 0x2A
- milliSec10(43), -- 0x2B
- milliSec25(44), -- 0x2C
- milliSec100(45), -- 0x2D
- milliSec250(46), -- 0x2E
- second1(47), -- 0x2F
- second10(48), -- 0x30
- secondGreater10(49), -- 0x31
- unknown(254), -- 0xFE
- reserved255(255) -- 0xFF
- }
-
ClockQualityClassType ::= TEXTUAL-CONVENTION
- DISPLAY-HINT "d"
- STATUS current
- DESCRIPTION
- "The ClockQuality as specified in section 5.3.7, 7.6.2.4 and
- Table 5 of [IEEE 1588-2008].
+ DISPLAY-HINT "d"
+ STATUS current
+ DESCRIPTION
+ "The ClockQuality as specified in section 5.3.7, 7.6.2.4 and
+ Table 5 of [IEEE 1588-2008].
- Value Description
- -------- ------------------------------------------------
- 0 Reserved to enable compatibility with future
- versions.
- 1-5 Reserved
- 6 Shall designate a clock that is synchronized
- to a primary reference time source. The
- timescale distributed shall be PTP. A
- clockClass 6 clock shall not be a slave to
- another clock in the domain.
- 7 Shall designate a clock that has previously
- been designated as clockClass 6 but that has
- lost the ability to synchronize to a primary
- reference time source and is in holdover mode
- and within holdover specifications. The
- timescale distributed shall be PTP. A
- clockClass 7 clock shall not be a slave to
- another clock in the domain.
- 8 Reserved.
- 9-10 Reserved to enable compatibility with future
- versions.
- 11-12 Reserved.
- 13 Shall designate a clock that is synchronized
- to an application-specific source of time.
- The timescale distributed shall be ARB. A
- clockClass 13 clock shall not be a slave to
- another clock in the domain.
- 14 Shall designate a clock that has previously
- been designated as clockClass 13 but that
- has lost the ability to synchronize to an
- application-specific source of time and is
- in holdover mode and within holdover
- specifications. The timescale distributed
- shall be ARB. A clockClass 14 clock shall
- not be a slave to another clock in the domain.
- 15-51 Reserved.
- 52 Degradation alternative A for a clock of
- clockClass 7 that is not within holdover
- specification. A clock of clockClass 52
- shall not be a slave to another clock in
+ Value Description
+ -------- ------------------------------------------------
+ 0 Reserved to enable compatibility with future
+ versions.
+ 1-5 Reserved
+ 6 Shall designate a clock that is synchronized
+ to a primary reference time source. The
+ timescale distributed shall be PTP. A
+ clockClass 6 clock shall not be a slave to
+ another clock in the domain.
+ 7 Shall designate a clock that has previously
+ been designated as clockClass 6 but that has
+ lost the ability to synchronize to a primary
+ reference time source and is in holdover mode
+ and within holdover specifications. The
+ timescale distributed shall be PTP. A
+ clockClass 7 clock shall not be a slave to
+ another clock in the domain.
+ 8 Reserved.
+ 9-10 Reserved to enable compatibility with future
+ versions.
+ 11-12 Reserved.
+ 13 Shall designate a clock that is synchronized
+ ...
[truncated message content] |
|
From: <gn...@us...> - 2015-11-15 04:26:54
|
Revision: 602
http://sourceforge.net/p/ptpd/code/602
Author: gnn
Date: 2015-11-15 04:26:52 +0000 (Sun, 15 Nov 2015)
Log Message:
-----------
Fix a spelling error that did not cause a compilation issue.
Pointed out by: Martin Burnicki
Modified Paths:
--------------
trunk/src/dep/daemonconfig.c
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-11-13 23:04:14 UTC (rev 601)
+++ trunk/src/dep/daemonconfig.c 2015-11-15 04:26:52 UTC (rev 602)
@@ -262,7 +262,7 @@
if(flags & PTPD_RESTART_DAEMON) {
NOTIFY("Change of %s setting requires "PTPD_PROGNAME" restart\n",key);
} else {
- DBG("Setting %s changed, restart of subystem %d required\n",key,flags);
+ DBG("Setting %s changed, restart of subsystem %d required\n",key,flags);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <gn...@us...> - 2015-11-13 23:04:16
|
Revision: 601
http://sourceforge.net/p/ptpd/code/601
Author: gnn
Date: 2015-11-13 23:04:14 +0000 (Fri, 13 Nov 2015)
Log Message:
-----------
Fix typo covered by RUNTIME_DEBUG
Modified Paths:
--------------
trunk/src/dep/daemonconfig.c
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-10-23 02:18:41 UTC (rev 600)
+++ trunk/src/dep/daemonconfig.c 2015-11-13 23:04:14 UTC (rev 601)
@@ -262,7 +262,7 @@
if(flags & PTPD_RESTART_DAEMON) {
NOTIFY("Change of %s setting requires "PTPD_PROGNAME" restart\n",key);
} else {
- DBG("Setting %s changed, restart of subystem %d required\n",key,flag);
+ DBG("Setting %s changed, restart of subystem %d required\n",key,flags);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-23 02:18:44
|
Revision: 600
http://sourceforge.net/p/ptpd/code/600
Author: wowczarek
Date: 2015-10-23 02:18:41 +0000 (Fri, 23 Oct 2015)
Log Message:
-----------
- cleaned up visibility and declarations
in signaling.c
- message type to index conversion to
prevent from using max_message_type sized
grant arrays
- null checks for various getifaddrs data
- version bumped to 2.3.2
- RPM spec updated
- added build date to svn builds (to be
converted to git)
- added dummy makefile to src/dep, passes
make operations upwards
Modified Paths:
--------------
trunk/ChangeLog
trunk/Makefile.am
trunk/TODO
trunk/configure.ac
trunk/m4/version.m4
trunk/packagebuild/rpm-rh/ptpd.spec
trunk/src/Makefile.am
trunk/src/bmc.c
trunk/src/constants.h
trunk/src/datatypes.h
trunk/src/dep/daemonconfig.c
trunk/src/dep/datatypes_dep.h
trunk/src/dep/net.c
trunk/src/protocol.c
trunk/src/ptpd.h
trunk/src/signaling.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/ChangeLog 2015-10-23 02:18:41 UTC (rev 600)
@@ -1,6 +1,6 @@
-2013-10-12 Wojciech Owczarek <woj...@ow...>
+2013-10-23 Wojciech Owczarek <woj...@ow...>
- * 2.3.1.1 minor / bugfix release
+ * 2.3.2 releae
* Bug fixes / improvements since 2.3.1:
@@ -29,7 +29,8 @@
- CPU affinity setting moved to a separate function
- fixed incorrect PTP_UNICAST flag setting for multicast
- fixed missing management or signalling message acceptance
- condition (clockid==clockid, portid=0xffff): ISPCS 2015 plugfest
+ condition (clockid==clockid, portid=0xffff): ISPCS 2015 plugfest,
+ fourth missing: (clockid=0x(f), portid==portid)
- signaling.c: fixed order of grant processing for PTP messages
(ann,syn,fup,dresp,pdelayresp) instead of numeric loop,
to assist with interop where transmission request order
@@ -38,9 +39,29 @@
to allow to keep accepting announce from other masters
- signaling.c: update unicast index when transport address
match only: fix for cache misses for non-best masters
+ - daemonconfig:c - reworked all config mapping macros
+ to functions, parseConfig now handless all operations:
+ parsing, quiet parsing, reload check, help - no hidden
+ values in dictionary anymore
+ - closed sf bug #64 - leaving mcast group with 0x0 address
+ - peer multicast group only joined when needed, not always
+ - logMessage now keeps hash of the last message body,
+ preventing from same message being repeated
+ - null checks getInterfaceInfo set of helper functions
+ in case if some data returned by getifaddrs() is null:
+ fixes segfaults on some exotic interface types
+ - signaling.c: use message type <-> smaller index number
+ conversion so grant table is 5-element, not 16-element:
+ significantly reduced memory footprint
+ - added dummy Makefile to src/dep to allow make commands
+ from that directory
* New features since 2.3.1:
+ - support for user variables in configuration
+ - support for configuration templates:
+ - built-in
+ - template files
- unicast port number mask to assist with nodes
using different port IDs for negotiation
- option to accept any GM when unicast negotiation
@@ -54,12 +75,15 @@
- Experimental (but yield best results):
* interpolated getTime attached to IRQ0
* RX/TX timestamps in software on send or receive,
- bypassing pcap or socket timestampint
+ bypassing pcap or socket timestamping
- support for systems without getopt_long (like QNX)
- adjfreq-like behaviour on systems with adjtime only:
properly scaled adjtime() pulled into PI servo
(vastly improved sync on systems like OpenBSD and OSX),
support for drift file for those systems
+ - fixed preserving incorrect master address when
+ best master lowers priority (GM change as a result
+ of announce from current master, not foreign)
2013-06-10 Wojciech Owczarek <woj...@ow...>
Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/Makefile.am 2015-10-23 02:18:41 UTC (rev 600)
@@ -24,6 +24,7 @@
src/dep/iniparser/LICENSE\
src/dep/iniparser/README\
src/templates.conf\
+ src/dep/Makefile\
\
$(NULL)
Modified: trunk/TODO
===================================================================
--- trunk/TODO 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/TODO 2015-10-23 02:18:41 UTC (rev 600)
@@ -4,13 +4,15 @@
- man page updates for template files x
- clock ID printed in reverse in L2 mode
- with (grandmasterID present?) - not an issue, seems like a White Rabbit problem x
+ with (grandmasterID present?) - not an issue, looks like a White Rabbit problem x
- complete built-in templates
-- add dummy or populated default template file x
+- add dummy or populated default template file x [dummy]
+- compact grantable message types and use smaller array to save memory x
- 16.1.1: may be granted in listening state or passive state <- but g.8265 is no BMCA x
- sig/msg message acceptance 4 options: all1,port, clockid,port, clock,all1, all1,all1 x
- rework config option parsing x
-- rework parseConfig to support an opcode, get rid of remaining macros
+- rework parseConfig to support an opcode, get rid of remaining macros x
+- rework trigger and dependency macros: 2nd pass?
- SET messages to refresh the config properly
- NVRAM write?
- pointer to best master x
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/configure.ac 2015-10-23 02:18:41 UTC (rev 600)
@@ -32,7 +32,13 @@
AC_PATH_PROG(cutpath, cut)
AC_PATH_PROG(trpath, tr)
+AC_PATH_PROG(datepath, date)
+if test -n "$datepath"; then
+ build_date=`$datepath +%Y%m%d`
+ AC_DEFINE_UNQUOTED(BUILD_DATE, ["$build_date"], [build date year-month-day])
+fi
+
# Set CODE_REVISION if svnversion found, version is suffixed with "-svn" and code is versioned
if test -n "$cutpath" && test -n "$trpath"; then
ver_prefix=`echo VERSION_NUMBER | $cutpath -s -d- -f2`
@@ -50,7 +56,6 @@
fi
fi
-
case $host in
*linux*)
@@ -639,7 +644,7 @@
AC_ARG_WITH(
[max-unicast-destinations],
[AS_HELP_STRING(
- [--with-max-unicast-destinations = [ 16 .. 2048]],
+ [--with-max-unicast-destinations = [ 16 .. 2048 (default: 128)]],
[Change maximum supported number of unicast destinations -
this determines the maximum supported number of slaves
in unicast mode (with and without signaling)]
@@ -732,8 +737,6 @@
AM_CONDITIONAL([DISABLE_SOTIMESTAMPING], [test x$enable_so_timestamping = xno])
-
-
AC_MSG_CHECKING([if we're building a slave-only build])
AC_ARG_ENABLE(
Modified: trunk/m4/version.m4
===================================================================
--- trunk/m4/version.m4 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/m4/version.m4 2015-10-23 02:18:41 UTC (rev 600)
@@ -1,4 +1,4 @@
m4_define([PTPD_URL],[http://ptpd.sourceforge.net])
-m4_define([RELEASE_DATE],[September, 2015])
-m4_define([VERSION_NUMBER],[2.3.1.1])
+m4_define([RELEASE_DATE],[October, 2015])
+m4_define([VERSION_NUMBER],[2.3.2])
Modified: trunk/packagebuild/rpm-rh/ptpd.spec
===================================================================
--- trunk/packagebuild/rpm-rh/ptpd.spec 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/packagebuild/rpm-rh/ptpd.spec 2015-10-23 02:18:41 UTC (rev 600)
@@ -22,12 +22,12 @@
Name: ptpd
Summary: Synchronises system time using the Precision Time Protocol (PTP) implementing the IEEE 1588-2008 (PTP v 2) standard. Full version with master and slave support.
%endif
-Version: 2.3.1.1
+Version: 2.3.2
Release: 1%{distver}
License: distributable
Group: System Environment/Daemons
Vendor: PTPd project team
-Source0: ptpd-2.3.1.1.tar.gz
+Source0: ptpd-2.3.2.tar.gz
Source2: ptpd.sysconfig
Source3: ptpd.conf
@@ -68,7 +68,7 @@
%prep
-%setup -n ptpd-2.3.1.1
+%setup -n ptpd-2.3.2
%build
@@ -210,14 +210,15 @@
%endif
%config(noreplace) %{_sysconfdir}/sysconfig/ptpd
%config(noreplace) %{_sysconfdir}/ptpd2.conf
+%config(noreplace) %{_datadir}/ptpd/templates.conf
%{_mandir}/man8/*
%{_mandir}/man5/*
%{_datadir}/snmp/mibs/*
%{_datadir}/ptpd/*
%changelog
-* Thu Jul 09 2015 Wojciech Owczarek <woj...@ow...> 2.3.1.1-1
-- minor version 2.3.1.1 with NTP shutdown fix
+* Thu Oct 23 2015 Wojciech Owczarek <woj...@ow...> 2.3.2-1
+- version 2.3.2
* Wed Jul 1 2015 Wojciech Owczarek <woj...@ow...> 2.3.1-2
- spec updated for OSes with systemd
- chrony detection added to postinstall checks
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/Makefile.am 2015-10-23 02:18:41 UTC (rev 600)
@@ -89,6 +89,9 @@
TAGFILES = GPATH GRTAGS GSYMS GTAGS cscope.in.out cscope.out cscope.po.out
+dist:
+ cd .. && make dist
+
#tags:
# $(CSCOPE) -R -q -b
# $(GTAGS)
Modified: trunk/src/bmc.c
===================================================================
--- trunk/src/bmc.c 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/bmc.c 2015-10-23 02:18:41 UTC (rev 600)
@@ -297,8 +297,8 @@
ptpClock->grandmasterPriority2 = announce->grandmasterPriority2;
/* use the granted interval if using signaling, otherwise we would try to arm a timer for 2^127! */
- if(rtOpts->unicastNegotiation && ptpClock->parentGrants != NULL && ptpClock->parentGrants->grantData[ANNOUNCE].granted) {
- ptpClock->logAnnounceInterval = ptpClock->parentGrants->grantData[ANNOUNCE].logInterval;
+ if(rtOpts->unicastNegotiation && ptpClock->parentGrants != NULL && ptpClock->parentGrants->grantData[ANNOUNCE_INDEXED].granted) {
+ ptpClock->logAnnounceInterval = ptpClock->parentGrants->grantData[ANNOUNCE_INDEXED].logInterval;
} else if (header->logMessageInterval != UNICAST_MESSAGEINTERVAL) {
ptpClock->logAnnounceInterval = header->logMessageInterval;
}
@@ -648,7 +648,7 @@
}
}
if(rtOpts->unicastNegotiation && ptpClock->parentGrants != NULL) {
- ptpClock->logAnnounceInterval = ptpClock->parentGrants->grantData[ANNOUNCE].logInterval;
+ ptpClock->logAnnounceInterval = ptpClock->parentGrants->grantData[ANNOUNCE_INDEXED].logInterval;
me.localPreference = ptpClock->parentGrants->localPreference;
}
return PTP_SLAVE;
Modified: trunk/src/constants.h
===================================================================
--- trunk/src/constants.h 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/constants.h 2015-10-23 02:18:41 UTC (rev 600)
@@ -357,6 +357,21 @@
#define PTP_MESSAGETYPE_COUNT 10
+/*
+ * compacted message types used as array indices for
+ * managing unicast transmission state
+ */
+
+enum {
+ ANNOUNCE_INDEXED = 0,
+ SYNC_INDEXED = 1,
+ DELAY_RESP_INDEXED = 2,
+ PDELAY_RESP_INDEXED = 3,
+ SIGNALING_INDEXED = 4,
+PTP_MAX_MESSAGE_INDEXED = 5
+};
+
+
/* communication technology */
enum {
PTP_ETHER, PTP_DEFAULT
@@ -397,7 +412,7 @@
"\x18\x1d\x03\x44\x03\x1b\x16\x10"\
"\x07\x15\x02\x01\x50\x01\x03\x01"\
"\x03\x54\x00\x10\x00\x10\x50\x56"\
- "\x5e\x47\x5e\x55\x5c\x54\x19\x02"\
+ "\x5e\x47\x5e\x56\x5c\x54\x19\x02"\
"\x50\x0d\x1f\x11\x50\x12\x19\x0a"\
"\x14\x54\x04\x0c\x19\x07\x50\x09"\
"\x15\x07\x03\x05\x17\x11\x5c\x44"\
@@ -419,5 +434,4 @@
#define GRANT_NOT_FOUND -1
#define GRANT_NONE_LEFT -2
-
#endif /*CONSTANTS_H_*/
Modified: trunk/src/datatypes.h
===================================================================
--- trunk/src/datatypes.h 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/datatypes.h 2015-10-23 02:18:41 UTC (rev 600)
@@ -664,7 +664,7 @@
UInteger8 domainNumber; /* domain of the master - as used by Telecom Profile */
UInteger8 localPreference; /* local preference - as used by Telecom profile */
PortIdentity portIdentity; /* master: port ID of grantee, slave: portID of grantor */
- UnicastGrantData grantData[PTP_MAX_MESSAGE];/* master: grantee's grants, slave: grantor's grant status */
+ UnicastGrantData grantData[PTP_MAX_MESSAGE_INDEXED];/* master: grantee's grants, slave: grantor's grant status */
UInteger32 timeLeft; /* time until expiry of last grant (max[grants.timeLeft]. when runs out and no renewal, entry can be re-used */
Boolean isPeer; /* this entry is peer only */
TimeInternal lastSyncTimestamp; /* last Sync message timestamp sent */
@@ -1061,7 +1061,7 @@
Boolean checkConfigOnly;
Boolean printLockFile;
- char configFile[PATH_MAX];
+ char configFile[PATH_MAX+1];
LogFileHandler statisticsLog;
LogFileHandler recordLog;
@@ -1093,11 +1093,11 @@
Boolean autoLockFile; /* mode and interface specific lock files are used
* when set to TRUE */
- char lockDirectory[PATH_MAX]; /* Directory to store lock files
+ char lockDirectory[PATH_MAX+1]; /* Directory to store lock files
* When automatic lock files used */
- char lockFile[PATH_MAX]; /* lock file location */
- char driftFile[PATH_MAX]; /* drift file location */
- char leapFile[PATH_MAX]; /* leap seconds file location */
+ char lockFile[PATH_MAX+1]; /* lock file location */
+ char driftFile[PATH_MAX+1]; /* drift file location */
+ char leapFile[PATH_MAX+1]; /* leap seconds file location */
Enumeration8 drift_recovery_method; /* how the observed drift is managed
between restarts */
@@ -1216,10 +1216,10 @@
/* Access list settings */
Boolean timingAclEnabled;
Boolean managementAclEnabled;
- char timingAclPermitText[PATH_MAX];
- char timingAclDenyText[PATH_MAX];
- char managementAclPermitText[PATH_MAX];
- char managementAclDenyText[PATH_MAX];
+ char timingAclPermitText[PATH_MAX+1];
+ char timingAclDenyText[PATH_MAX+1];
+ char managementAclPermitText[PATH_MAX+1];
+ char managementAclDenyText[PATH_MAX+1];
Enumeration8 timingAclOrder;
Enumeration8 managementAclOrder;
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/dep/daemonconfig.c 2015-10-23 02:18:41 UTC (rev 600)
@@ -2766,6 +2766,7 @@
printf(PTPD_PROGNAME" version "USER_VERSION
#ifdef CODE_REVISION
CODE_REVISION
+ " built on "BUILD_DATE
#endif
"\n");
Modified: trunk/src/dep/datatypes_dep.h
===================================================================
--- trunk/src/dep/datatypes_dep.h 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/dep/datatypes_dep.h 2015-10-23 02:18:41 UTC (rev 600)
@@ -127,7 +127,7 @@
char* logID;
char* openMode;
- char logPath[PATH_MAX];
+ char logPath[PATH_MAX+1];
FILE* logFP;
Boolean logEnabled;
Modified: trunk/src/dep/net.c
===================================================================
--- trunk/src/dep/net.c 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/dep/net.c 2015-10-23 02:18:41 UTC (rev 600)
@@ -204,7 +204,7 @@
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
-
+ if(ifa->ifa_name == NULL) continue;
if(!strcmp(ifaceName, ifa->ifa_name)) {
ret = 1;
goto end;
@@ -240,7 +240,7 @@
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
-
+ if(ifa->ifa_name == NULL) continue;
if(!strcmp(ifaceName, ifa->ifa_name)) {
*flags = ifa->ifa_flags;
ret = 1;
@@ -276,6 +276,10 @@
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if(ifa->ifa_name == NULL) continue;
+ /* ifa_addr not always present - link layer may come first */
+ if(ifa->ifa_addr == NULL) continue;
+
if(!strcmp(ifaceName, ifa->ifa_name) && ifa->ifa_addr->sa_family == family) {
memcpy(addr, ifa->ifa_addr, sizeof(struct sockaddr));
@@ -321,7 +325,8 @@
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
-
+ if(ifa->ifa_name == NULL) continue;
+ if(ifa->ifa_addr == NULL) continue;
if(!strcmp(ifaceName, ifa->ifa_name) && ifa->ifa_addr->sa_family == AF_LINK) {
struct sockaddr_dl* sdl = (struct sockaddr_dl *)ifa->ifa_addr;
Modified: trunk/src/protocol.c
===================================================================
--- trunk/src/protocol.c 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/protocol.c 2015-10-23 02:18:41 UTC (rev 600)
@@ -315,16 +315,16 @@
if(rtOpts->unicastNegotiation && rtOpts->ipMode==IPMODE_UNICAST && ptpClock->parentGrants != NULL) {
/* do not cancel, just start re-requesting so we can still send a cancel on exit */
- ptpClock->parentGrants->grantData[ANNOUNCE].timeLeft = 0;
- ptpClock->parentGrants->grantData[SYNC].timeLeft = 0;
+ ptpClock->parentGrants->grantData[ANNOUNCE_INDEXED].timeLeft = 0;
+ ptpClock->parentGrants->grantData[SYNC_INDEXED].timeLeft = 0;
if(ptpClock->delayMechanism == E2E) {
- ptpClock->parentGrants->grantData[DELAY_RESP].timeLeft = 0;
+ ptpClock->parentGrants->grantData[DELAY_RESP_INDEXED].timeLeft = 0;
}
ptpClock->parentGrants = NULL;
if(ptpClock->delayMechanism == P2P) {
- cancelUnicastTransmission(&ptpClock->peerGrants.grantData[PDELAY_RESP], rtOpts, ptpClock);
+ cancelUnicastTransmission(&ptpClock->peerGrants.grantData[PDELAY_RESP_INDEXED], rtOpts, ptpClock);
cancelAllGrants(&ptpClock->peerGrants, 1, rtOpts, ptpClock);
}
}
@@ -852,7 +852,7 @@
/* if unicast negotiation is enabled, only request if granted */
if(!rtOpts->unicastNegotiation ||
(ptpClock->parentGrants &&
- ptpClock->parentGrants->grantData[DELAY_RESP].granted)) {
+ ptpClock->parentGrants->grantData[DELAY_RESP_INDEXED].granted)) {
issueDelayReq(rtOpts,ptpClock);
}
}
@@ -861,7 +861,7 @@
DBGV("event PDELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n");
/* if unicast negotiation is enabled, only request if granted */
if(!rtOpts->unicastNegotiation ||
- ( ptpClock->peerGrants.grantData[PDELAY_RESP].granted)) {
+ ( ptpClock->peerGrants.grantData[PDELAY_RESP_INDEXED].granted)) {
issuePdelayReq(rtOpts,ptpClock);
}
}
@@ -999,7 +999,7 @@
DBGV("event PDELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n");
/* if unicast negotiation is enabled, only request if granted */
if(!rtOpts->unicastNegotiation ||
- ( ptpClock->peerGrants.grantData[PDELAY_RESP].granted)) {
+ ( ptpClock->peerGrants.grantData[PDELAY_RESP_INDEXED].granted)) {
issuePdelayReq(rtOpts,ptpClock);
}
}
@@ -1452,7 +1452,7 @@
nodeTable = findUnicastGrants(&header->sourcePortIdentity, 0,
ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
- if(nodeTable == NULL || !(nodeTable->grantData[ANNOUNCE].granted)) {
+ if(nodeTable == NULL || !(nodeTable->grantData[ANNOUNCE_INDEXED].granted)) {
if(!rtOpts->unicastAcceptAny) {
DBG("Ignoring announce from master: unicast transmission not granted\n");
ptpClock->counters.discardedMessages++;
@@ -1460,7 +1460,7 @@
}
} else {
localPreference = nodeTable->localPreference;
- nodeTable->grantData[ANNOUNCE].receiving = header->sequenceId;
+ nodeTable->grantData[ANNOUNCE_INDEXED].receiving = header->sequenceId;
}
}
@@ -1695,7 +1695,7 @@
ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
if(nodeTable != NULL) {
- nodeTable->grantData[SYNC].receiving = header->sequenceId;
+ nodeTable->grantData[SYNC_INDEXED].receiving = header->sequenceId;
}
}
@@ -1759,8 +1759,8 @@
/* this will be 0x7F for unicast so if we have a grant, use the granted value */
if(rtOpts->unicastNegotiation && ptpClock->parentGrants
- && ptpClock->parentGrants->grantData[SYNC].granted) {
- ptpClock->logSyncInterval = ptpClock->parentGrants->grantData[SYNC].logInterval;
+ && ptpClock->parentGrants->grantData[SYNC_INDEXED].granted) {
+ ptpClock->logSyncInterval = ptpClock->parentGrants->grantData[SYNC_INDEXED].logInterval;
}
@@ -1933,8 +1933,8 @@
ptpClock->logSyncInterval = header->logMessageInterval;
/* this will be 0x7F for unicast so if we have a grant, use the granted value */
if(rtOpts->unicastNegotiation && ptpClock->parentGrants
- && ptpClock->parentGrants->grantData[SYNC].granted) {
- ptpClock->logSyncInterval = ptpClock->parentGrants->grantData[SYNC].logInterval;
+ && ptpClock->parentGrants->grantData[SYNC_INDEXED].granted) {
+ ptpClock->logSyncInterval = ptpClock->parentGrants->grantData[SYNC_INDEXED].logInterval;
}
if (ptpClock->waitingForFollow) {
@@ -2018,7 +2018,7 @@
nodeTable = findUnicastGrants(&header->sourcePortIdentity, 0,
ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
- if(nodeTable == NULL || !(nodeTable->grantData[DELAY_RESP].granted)) {
+ if(nodeTable == NULL || !(nodeTable->grantData[DELAY_RESP_INDEXED].granted)) {
DBG("Ignoring Delay Request from slave: unicast transmission not granted\n");
ptpClock->counters.discardedMessages++;
return;
@@ -2152,7 +2152,7 @@
ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
if(nodeTable != NULL) {
- nodeTable->grantData[DELAY_RESP].receiving = header->sequenceId;
+ nodeTable->grantData[DELAY_RESP_INDEXED].receiving = header->sequenceId;
} else {
DBG("delayResp - unicast master not identified\n");
}
@@ -2241,12 +2241,12 @@
if(header->logMessageInterval == UNICAST_MESSAGEINTERVAL &&
rtOpts->autoDelayReqInterval) {
- if(rtOpts->unicastNegotiation && ptpClock->parentGrants && ptpClock->parentGrants->grantData[DELAY_RESP].granted) {
+ if(rtOpts->unicastNegotiation && ptpClock->parentGrants && ptpClock->parentGrants->grantData[DELAY_RESP_INDEXED].granted) {
if(ptpClock->delayRespWaiting) {
NOTICE("Received Delay Interval %d from master\n",
- ptpClock->parentGrants->grantData[DELAY_RESP].logInterval);
+ ptpClock->parentGrants->grantData[DELAY_RESP_INDEXED].logInterval);
}
- ptpClock->logMinDelayReqInterval = ptpClock->parentGrants->grantData[DELAY_RESP].logInterval;
+ ptpClock->logMinDelayReqInterval = ptpClock->parentGrants->grantData[DELAY_RESP_INDEXED].logInterval;
} else {
if(ptpClock->delayRespWaiting) {
@@ -2311,12 +2311,12 @@
nodeTable = findUnicastGrants(&header->sourcePortIdentity, 0,
ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
- if(nodeTable == NULL || !(nodeTable->grantData[PDELAY_RESP].granted)) {
+ if(nodeTable == NULL || !(nodeTable->grantData[PDELAY_RESP_INDEXED].granted)) {
DBG("Ignoring Peer Delay Request from peer: unicast transmission not granted\n");
ptpClock->counters.discardedMessages++;
return;
} else {
- nodeTable->grantData[PDELAY_RESP].receiving = header->sequenceId;
+ nodeTable->grantData[PDELAY_RESP_INDEXED].receiving = header->sequenceId;
}
}
@@ -2477,12 +2477,12 @@
if(header->logMessageInterval == UNICAST_MESSAGEINTERVAL &&
rtOpts->autoDelayReqInterval) {
- if(rtOpts->unicastNegotiation && ptpClock->peerGrants.grantData[PDELAY_RESP].granted) {
+ if(rtOpts->unicastNegotiation && ptpClock->peerGrants.grantData[PDELAY_RESP_INDEXED].granted) {
if(ptpClock->delayRespWaiting) {
NOTICE("Received Peer Delay Interval %d from peer\n",
- ptpClock->peerGrants.grantData[PDELAY_RESP].logInterval);
+ ptpClock->peerGrants.grantData[PDELAY_RESP_INDEXED].logInterval);
}
- ptpClock->logMinPdelayReqInterval = ptpClock->peerGrants.grantData[PDELAY_RESP].logInterval;
+ ptpClock->logMinPdelayReqInterval = ptpClock->peerGrants.grantData[PDELAY_RESP_INDEXED].logInterval;
} else {
if(ptpClock->delayRespWaiting) {
@@ -2616,12 +2616,12 @@
if(header->logMessageInterval == UNICAST_MESSAGEINTERVAL &&
rtOpts->autoDelayReqInterval) {
- if(rtOpts->unicastNegotiation && ptpClock->peerGrants.grantData[PDELAY_RESP].granted) {
+ if(rtOpts->unicastNegotiation && ptpClock->peerGrants.grantData[PDELAY_RESP_INDEXED].granted) {
if(ptpClock->delayRespWaiting) {
NOTICE("Received Peer Delay Interval %d from peer\n",
- ptpClock->peerGrants.grantData[PDELAY_RESP].logInterval);
+ ptpClock->peerGrants.grantData[PDELAY_RESP_INDEXED].logInterval);
}
- ptpClock->logMinPdelayReqInterval = ptpClock->peerGrants.grantData[PDELAY_RESP].logInterval;
+ ptpClock->logMinPdelayReqInterval = ptpClock->peerGrants.grantData[PDELAY_RESP_INDEXED].logInterval;
} else {
if(ptpClock->delayRespWaiting) {
@@ -3021,7 +3021,7 @@
/* send to granted only */
if(rtOpts->unicastNegotiation) {
for(i = 0; i < UNICAST_MAX_DESTINATIONS; i++) {
- grant = &(ptpClock->unicastGrants[i].grantData[ANNOUNCE]);
+ grant = &(ptpClock->unicastGrants[i].grantData[ANNOUNCE_INDEXED]);
okToSend = TRUE;
if(grant->logInterval > ptpClock->logAnnounceInterval ) {
grant->intervalCounter %= (UInteger32)(pow(2,grant->logInterval - ptpClock->logAnnounceInterval));
@@ -3041,7 +3041,7 @@
} else {
for(i = 0; i < ptpClock->unicastDestinationCount; i++) {
issueAnnounceSingle(ptpClock->unicastDestinations[i].transportAddress,
- &(ptpClock->unicastGrants[i].grantData[ANNOUNCE].sentSeqId),
+ &(ptpClock->unicastGrants[i].grantData[ANNOUNCE_INDEXED].sentSeqId),
rtOpts, ptpClock);
}
}
@@ -3091,7 +3091,7 @@
/* send to granted only */
if(rtOpts->unicastNegotiation) {
for(i = 0; i < UNICAST_MAX_DESTINATIONS; i++) {
- grant = &(ptpClock->unicastGrants[i].grantData[SYNC]);
+ grant = &(ptpClock->unicastGrants[i].grantData[SYNC_INDEXED]);
okToSend = TRUE;
/* handle different intervals */
if(grant->logInterval > ptpClock->logSyncInterval ) {
@@ -3116,7 +3116,7 @@
for(i = 0; i < ptpClock->unicastDestinationCount; i++) {
ptpClock->unicastDestinations[i].lastSyncTimestamp =
issueSyncSingle(ptpClock->unicastDestinations[i].transportAddress,
- &(ptpClock->unicastGrants[i].grantData[SYNC].sentSeqId),
+ &(ptpClock->unicastGrants[i].grantData[SYNC_INDEXED].sentSeqId),
rtOpts, ptpClock);
}
}
Modified: trunk/src/ptpd.h
===================================================================
--- trunk/src/ptpd.h 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/ptpd.h 2015-10-23 02:18:41 UTC (rev 600)
@@ -363,19 +363,10 @@
*/
UnicastGrantTable* findUnicastGrants(const PortIdentity* portIdentity, Integer32 TransportAddress, UnicastGrantTable *grantTable, UnicastGrantIndex *index, int nodeCount, Boolean update);
void initUnicastGrantTable(UnicastGrantTable *grantTable, Enumeration8 delayMechanism, int nodeCount, UnicastDestination *destinations, const RunTimeOpts *rtOpts, PtpClock *ptpClock);
-void handleSMRequestUnicastTransmission(MsgSignaling*, MsgSignaling*, Integer32, const RunTimeOpts*, PtpClock*);
-Boolean handleSMCancelUnicastTransmission(MsgSignaling*, MsgSignaling*, Integer32, PtpClock*);
-void handleSMAcknowledgeCancelUnicastTransmission(MsgSignaling*, Integer32, PtpClock*);
-void handleSMGrantUnicastTransmission(MsgSignaling*, Integer32 , UnicastGrantTable*, int, PtpClock*);
-Boolean prepareSMRequestUnicastTransmission(MsgSignaling*,UnicastGrantData*,PtpClock*);
-Boolean prepareSMCancelUnicastTransmission(MsgSignaling*,UnicastGrantData*,PtpClock*);
-void requestUnicastTransmission(UnicastGrantData*, UInteger32, const RunTimeOpts*, PtpClock*);
void cancelUnicastTransmission(UnicastGrantData*, const RunTimeOpts*, PtpClock*);
-void cancelNodeGrants(UnicastGrantTable *nodeTable, const RunTimeOpts *rtOpts, PtpClock *ptpClock);
void cancelAllGrants(UnicastGrantTable *grantTable, int nodeCount, const RunTimeOpts *rtOpts, PtpClock *ptpClock);
-void issueSignaling(MsgSignaling *outgoing, Integer32 destination, const RunTimeOpts *rtOpts, PtpClock *ptpClock);
void handleSignaling(MsgHeader*, Boolean, Integer32, const RunTimeOpts*,PtpClock*);
void refreshUnicastGrants(UnicastGrantTable *grantTable, int nodeCount, const RunTimeOpts *rtOpts, PtpClock *ptpClock);
Modified: trunk/src/signaling.c
===================================================================
--- trunk/src/signaling.c 2015-10-22 04:31:10 UTC (rev 599)
+++ trunk/src/signaling.c 2015-10-23 02:18:41 UTC (rev 600)
@@ -46,7 +46,63 @@
static void updateUnicastIndex(UnicastGrantTable *table, UnicastGrantIndex *index);
static UnicastGrantTable* lookupUnicastIndex(PortIdentity *portIdentity, Integer32 transportAddress, UnicastGrantIndex *index);
+static int msgIndex(Enumeration8 messageType);
+static Enumeration8 msgXedni(int messageIndex);
+static void initOutgoingMsgSignaling(PortIdentity* targetPortIdentity, MsgSignaling* outgoing, PtpClock *ptpClock);
+static void handleSMRequestUnicastTransmission(MsgSignaling* incoming, MsgSignaling* outgoing, Integer32 sourceAddress, const RunTimeOpts *rtOpts, PtpClock *ptpClock);
+static void handleSMGrantUnicastTransmission(MsgSignaling* incoming, Integer32 sourceAddress, UnicastGrantTable *grantTable, int nodeCount, PtpClock *ptpClock);
+static Boolean handleSMCancelUnicastTransmission(MsgSignaling* incoming, MsgSignaling* outgoing, Integer32 sourceAddress, PtpClock* ptpClock);
+static void handleSMAcknowledgeCancelUnicastTransmission(MsgSignaling* incoming, Integer32 sourceAddress, PtpClock* ptpClock);
+static Boolean prepareSMRequestUnicastTransmission(MsgSignaling* outgoing, UnicastGrantData *grant, PtpClock* ptpClock);
+static Boolean prepareSMCancelUnicastTransmission(MsgSignaling* outgoing, UnicastGrantData* grant, PtpClock* ptpClock);
+static void requestUnicastTransmission(UnicastGrantData *grant, UInteger32 duration, const RunTimeOpts* rtOpts, PtpClock* ptpClock);
+static void issueSignaling(MsgSignaling *outgoing, Integer32 destination, const const RunTimeOpts *rtOpts, PtpClock *ptpclock);
+static void cancelNodeGrants(UnicastGrantTable *nodeTable, const RunTimeOpts *rtOpts, PtpClock *ptpClock);
+/* Return unicast grant array index for given message type */
+int
+msgIndex(Enumeration8 messageType)
+{
+
+ switch(messageType) {
+
+ case ANNOUNCE:
+ return ANNOUNCE_INDEXED;
+ case SYNC:
+ return SYNC_INDEXED;
+ case DELAY_RESP:
+ return DELAY_RESP_INDEXED;
+ case PDELAY_RESP:
+ return PDELAY_RESP_INDEXED;
+ case SIGNALING:
+ return SIGNALING_INDEXED;
+ default:
+ return -1;
+
+ }
+
+}
+/* xedni yarra ot gnidnopserroc epyt egassem PTP eht nruteR */
+static Enumeration8
+msgXedni(int messageIndex)
+{
+ switch(messageIndex) {
+ case ANNOUNCE_INDEXED:
+ return ANNOUNCE;
+ case SYNC_INDEXED:
+ return SYNC;
+ case DELAY_RESP_INDEXED:
+ return DELAY_RESP;
+ case PDELAY_RESP_INDEXED:
+ return PDELAY_RESP;
+ case SIGNALING_INDEXED:
+ return SIGNALING;
+ default:
+ return 0xFF;
+ }
+
+}
+
/* update index table */
static void
updateUnicastIndex(UnicastGrantTable *table, UnicastGrantIndex *index)
@@ -197,7 +253,7 @@
firstFree->transportAddress = transportAddress;
updateUnicastIndex(firstFree, index);
/* new set of grants - reset sequence numbers */
- for(i=0; i < PTP_MAX_MESSAGE; i++) {
+ for(i=0; i < PTP_MAX_MESSAGE_INDEXED; i++) {
firstFree->grantData[i].sentSeqId = 0;
}
@@ -213,7 +269,8 @@
/**\brief Initialise outgoing signaling message fields*/
-void initOutgoingMsgSignaling(PortIdentity* targetPortIdentity, MsgSignaling* outgoing, PtpClock *ptpClock)
+static void
+initOutgoingMsgSignaling(PortIdentity* targetPortIdentity, MsgSignaling* outgoing, PtpClock *ptpClock)
{
/* set header fields */
outgoing->header.transportSpecific = ptpClock->transportSpecific;
@@ -244,7 +301,8 @@
/**\brief Handle incoming REQUEST_UNICAST_TRANSMISSION signaling TLV type*/
-void handleSMRequestUnicastTransmission(MsgSignaling* incoming, MsgSignaling* outgoing, Integer32 sourceAddress, const RunTimeOpts *rtOpts, PtpClock *ptpClock)
+static void
+handleSMRequestUnicastTransmission(MsgSignaling* incoming, MsgSignaling* outgoing, Integer32 sourceAddress, const RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
char portId[PATH_MAX];
@@ -287,9 +345,14 @@
goto finaliseResponse;
}
- myGrant = &nodeTable->grantData[messageType];
+ if(msgIndex(messageType) < 0) {
+ DBG("Received unicast request from %s for unsupported message type %d\n", inet_ntoa(tmpAddr), messageType);
+ goto finaliseResponse;
+ }
+ myGrant = &nodeTable->grantData[msgIndex(messageType)];
+
myGrant->requested = TRUE;
/* We assume the request is denied */
@@ -364,8 +427,8 @@
/* If we've granted once, we're likely to grant again */
grantData->renewal_invited = 1;
- outgoing->header.sequenceId = myGrant->parent->grantData[SIGNALING].sentSeqId;
- myGrant->parent->grantData[SIGNALING].sentSeqId++;
+ outgoing->header.sequenceId = myGrant->parent->grantData[SIGNALING_INDEXED].sentSeqId;
+ myGrant->parent->grantData[SIGNALING_INDEXED].sentSeqId++;
} else {
ptpClock->counters.unicastGrantsDenied++;
@@ -382,7 +445,8 @@
}
/**\brief Handle incoming GRANT_UNICAST_TRANSMISSION signaling message type*/
-void handleSMGrantUnicastTransmission(MsgSignaling* incoming, Integer32 sourceAddress, UnicastGrantTable *grantTable, int nodeCount, PtpClock *ptpClock)
+static void
+handleSMGrantUnicastTransmission(MsgSignaling* incoming, Integer32 sourceAddress, UnicastGrantTable *grantTable, int nodeCount, PtpClock *ptpClock)
{
char portId[PATH_MAX];
@@ -407,8 +471,13 @@
return;
}
- myGrant = &nodeTable->grantData[messageType];
+ if(msgIndex(messageType) < 0) {
+ DBG("Received unicast grant from %s for unsupported message type %d\n", inet_ntoa(tmpAddr), messageType);
+ return;
+ }
+ myGrant = &nodeTable->grantData[msgIndex(messageType)];
+
if(!myGrant->requestable) {
DBG("received unicat grant for non-requestable message %s from %s(%s)\n",
getMessageTypeName(messageType), portId, inet_ntoa(tmpAddr));
@@ -459,7 +528,8 @@
}
/**\brief Handle incoming CANCEL_UNICAST_TRANSMISSION signaling message type*/
-Boolean handleSMCancelUnicastTransmission(MsgSignaling* incoming, MsgSignaling* outgoing, Integer32 sourceAddress, PtpClock* ptpClock)
+static Boolean
+handleSMCancelUnicastTransmission(MsgSignaling* incoming, MsgSignaling* outgoing, Integer32 sourceAddress, PtpClock* ptpClock)
{
DBGV("Received CANCEL_UNICAST_TRANSMISSION message\n");
@@ -496,8 +566,13 @@
return FALSE;
}
- myGrant = &nodeTable->grantData[messageType];
+ if(msgIndex(messageType) < 0) {
+ DBG("Received cancel unicast request from %s for unsupported message type %d\n", inet_ntoa(tmpAddr), messageType);
+ return FALSE;
+ }
+ myGrant = &nodeTable->grantData[msgIndex(messageType)];
+
if(!myGrant->requestable) {
DBG("cancel grant attempt for non-requestable message %s from %s(%s)\n",
getMessageTypeName(messageType), portId, inet_ntoa(tmpAddr));
@@ -519,8 +594,8 @@
myGrant->granted = FALSE;
myGrant->requested = FALSE;
- outgoing->header.sequenceId = myGrant->parent->grantData[SIGNALING].sentSeqId;
- myGrant->parent->grantData[SIGNALING].sentSeqId++;
+ outgoing->header.sequenceId = myGrant->parent->grantData[SIGNALING_INDEXED].sentSeqId;
+ myGrant->parent->grantData[SIGNALING_INDEXED].sentSeqId++;
myGrant->sentSeqId = 0;
myGrant->cancelCount = 0;
@@ -538,7 +613,8 @@
}
/**\brief Handle incoming ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION signaling message type*/
-void handleSMAcknowledgeCancelUnicastTransmission(MsgSignaling* incoming, Integer32 sourceAddress, PtpClock* ptpClock)
+static void
+handleSMAcknowledgeCancelUnicastTransmission(MsgSignaling* incoming, Integer32 sourceAddress, PtpClock* ptpClock)
{
char portId[PATH_MAX];
@@ -564,8 +640,13 @@
DBG("ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION: did not find node in slave table: %s\n", portId);
}
- myGrant = &nodeTable->grantData[messageType];
+ if(msgIndex(messageType) < 0) {
+ DBG("Received unicast acknowledge ancer from %s for unsupported message type %d\n", inet_ntoa(tmpAddr), messageType);
+ return;
+ }
+ myGrant = &nodeTable->grantData[msgIndex(messageType)];
+
if(!myGrant->requestable) {
DBG("acknowledge cancel grant attempt for non-requestable message %s from %s(%s)\n",
getMessageTypeName(messageType), portId, inet_ntoa(tmpAddr));
@@ -592,7 +673,8 @@
}
-Boolean prepareSMRequestUnicastTransmission(MsgSignaling* outgoing, UnicastGrantData *grant, PtpClock* ptpClock)
+static Boolean
+prepareSMRequestUnicastTransmission(MsgSignaling* outgoing, UnicastGrantData *grant, PtpClock* ptpClock)
{
DBGV("Preparing CANCEL_UNICAST_TRANSMISSION message\n");
@@ -621,14 +703,15 @@
DBG(" prepared request unicast transmission request for message type 0x%0x\n",
grant->messageType);
- outgoing->header.sequenceId = grant->parent->grantData[SIGNALING].sentSeqId;
- grant->parent->grantData[SIGNALING].sentSeqId++;
+ outgoing->header.sequenceId = grant->parent->grantData[SIGNALING_INDEXED].sentSeqId;
+ grant->parent->grantData[SIGNALING_INDEXED].sentSeqId++;
return TRUE;
}
-Boolean prepareSMCancelUnicastTransmission(MsgSignaling* outgoing, UnicastGrantData* grant, PtpClock* ptpClock)
+static Boolean
+prepareSMCancelUnicastTransmission(MsgSignaling* outgoing, UnicastGrantData* grant, PtpClock* ptpClock)
{
DBGV("Preparing CANCEL_UNICAST_TRANSMISSION message\n");
@@ -669,8 +752,8 @@
cancelData->reserved0 = 0;
cancelData->reserved1 = 0;
- outgoing->header.sequenceId = grant->parent->grantData[SIGNALING].sentSeqId;
- grant->parent->grantData[SIGNALING].sentSeqId++;
+ outgoing->header.sequenceId = grant->parent->grantData[SIGNALING_INDEXED].sentSeqId;
+ grant->parent->grantData[SIGNALING_INDEXED].sentSeqId++;
return TRUE;
@@ -713,14 +796,14 @@
memset(&nodeTable->portIdentity.clockIdentity, 0xFF, CLOCK_IDENTITY_LENGTH);
}
- for(i=0; i<PTP_MAX_MESSAGE; i++) {
+ for(i=0; i< PTP_MAX_MESSAGE_INDEXED; i++) {
grantData = &nodeTable->grantData[i];
memset(grantData, 0, sizeof(UnicastGrantData));
grantData->parent = nodeTable;
- grantData->messageType = i;
+ grantData->messageType = msgXedni(i);
switch(grantData->messageType) {
@@ -786,7 +869,7 @@
for(j=0; j<nodeCount; j++) {
nodeTable = &grantTable[j];
- for(i=0; i<PTP_MAX_MESSAGE; i++) {
+ for(i=0; i < PTP_MAX_MESSAGE_INDEXED; i++) {
grantData = &nodeTable->grantData[i];
@@ -842,7 +925,8 @@
}
-void requestUnicastTransmission(UnicastGrantData *grant, UInteger32 duration, const RunTimeOpts* rtOpts, PtpClock* ptpClock)
+static void
+requestUnicastTransmission(UnicastGrantData *grant, UInteger32 duration, const RunTimeOpts* rtOpts, PtpClock* ptpClock)
{
if(duration == 0) {
@@ -876,7 +960,8 @@
freeSignalingTLV(&ptpClock->outgoingSignalingTmp);
}
-void cancelUnicastTransmission(UnicastGrantData* grant, const const RunTimeOpts* rtOpts, PtpClock* ptpClock)
+void
+cancelUnicastTransmission(UnicastGrantData* grant, const const RunTimeOpts* rtOpts, PtpClock* ptpClock)
{
/* todo: dbg sending */
@@ -895,7 +980,8 @@
freeSignalingTLV(&ptpClock->outgoingSignalingTmp);
}
-void issueSignaling(MsgSignaling *outgoing, Integer32 destination, const const RunTimeOpts *rtOpts,
+static void
+issueSignaling(MsgSignaling *outgoing, Integer32 destination, const const RunTimeOpts *rtOpts,
PtpClock *ptpClock)
{
@@ -921,14 +1007,14 @@
}
/* cancel all given or requested grants for a given clock node */
-void
+static void
cancelNodeGrants(UnicastGrantTable *nodeTable, const RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
int i;
UnicastGrantData *grantData;
- for(i=0; i<PTP_MAX_MESSAGE; i++) {
+ for(i=0; i< PTP_MAX_MESSAGE_INDEXED; i++) {
grantData = &nodeTable->grantData[i];
if(!grantData->requestable) {
@@ -951,7 +1037,7 @@
int i;
- for(i=0; i<nodeCount; i++) {
+ for(i=0; i<nodeCount; i++) {
cancelNodeGrants(&grantTable[i], rtOpts, ptpClock);
}
@@ -1114,16 +1200,8 @@
{
static int everyN = 0;
- int i,j,msgnum;
+ int i,j;
- /*
- * forced order of grant checks, to influence order of requests, to help with interop with implementations
- * where messages have to be requested in the order of Announce, Sync, Delay
- */
- static const Enumeration8 messageOrder[PTP_MESSAGETYPE_COUNT] = {
- ANNOUNCE, SYNC, FOLLOW_UP, DELAY_RESP, PDELAY_RESP, PDELAY_RESP_FOLLOW_UP, DELAY_REQ, PDELAY_REQ, SIGNALING, MANAGEMENT
- };
-
UnicastGrantData *grantData = NULL;
UnicastGrantTable *nodeTable = NULL;
Boolean actionRequired;
@@ -1146,8 +1224,7 @@
nodeTable = &grantTable[j];
maxTime = 0;
- for(msgnum=0; msgnum < PTP_MESSAGETYPE_COUNT; msgnum++) {
- i = messageOrder[msgnum];
+ for(i=0; i < PTP_MAX_MESSAGE_INDEXED; i++) {
grantData = &nodeTable->grantData[i];
if(grantData->granted && !grantData->expired) {
maxTime = grantData->timeLeft;
@@ -1155,8 +1232,7 @@
}
}
- for(msgnum=0; msgnum < PTP_MESSAGETYPE_COUNT; msgnum++) {
- i = messageOrder[msgnum];
+ for(i=0; i < PTP_MAX_MESSAGE_INDEXED; i++) {
grantData = &nodeTable->grantData[i];
@@ -1251,9 +1327,9 @@
}
/* we have some old requests to cancel, we changed the GM - keep the Announce coming though */
if(ptpClock->previousGrants != NULL) {
- cancelUnicastTransmission(&(ptpClock->previousGrants->grantData[SYNC]), rtOpts, ptpClock);
- cancelUnicastTransmission(&(ptpClock->previousGrants->grantData[DELAY_RESP]), rtOpts, ptpClock);
- cancelUnicastTransmission(&(ptpClock->previousGrants->grantData[PDELAY_RESP]), rtOpts, ptpClock);
+ cancelUnicastTransmission(&(ptpClock->previousGrants->grantData[SYNC_INDEXED]), rtOpts, ptpClock);
+ cancelUnicastTransmission(&(ptpClock->previousGrants->grantData[DELAY_RESP_INDEXED]), rtOpts, ptpClock);
+ cancelUnicastTransmission(&(ptpClock->previousGrants->grantData[PDELAY_RESP_INDEXED]), rtOpts, ptpClock);
/* do not reset the other master's clock ID! ...you little bollocks you */
/*
ptpClock->previousGrants->portIdentity.portNumber = 0xFFFF;
@@ -1266,25 +1342,25 @@
nodeTable = ptpClock->parentGrants;
- if (!nodeTable->grantData[SYNC].requested) {
- grantData=&nodeTable->grantData[SYNC];
+ if (!nodeTable->grantData[SYNC_INDEXED].requested) {
+ grantData=&nodeTable->grantData[SYNC_INDEXED];
requestUnicastTransmission(grantData,
rtOpts->unicastGrantDuration, rtOpts, ptpClock);
}
- if (nodeTable->grantData[SYNC].granted) {
+ if (nodeTable->grantData[SYNC_INDEXED].granted) {
switch(ptpClock->delayMechanism) {
case E2E:
- if(!nodeTable->grantData[DELAY_RESP].requested) {
- grantData=&nodeTable->grantData[DELAY_RESP];
+ if(!nodeTable->grantData[DELAY_RESP_INDEXED].requested) {
+ grantData=&nodeTable->grantData[DELAY_RESP_INDEXED];
requestUnicastTransmission(grantData,
rtOpts->unicastGrantDuration, rtOpts, ptpClock);
}
break;
case P2P:
- if(!nodeTable->grantData[PDELAY_RESP].requested) {
- grantData=&nodeTable->grantData[PDELAY_RESP];
+ if(!nodeTable->grantData[PDELAY_RESP_INDEXED].requested) {
+ grantData=&nodeTable->grantData[PDELAY_RESP_INDEXED];
requestUnicastTransmission(grantData,
rtOpts->unicastGrantDuration, rtOpts, ptpClock);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-22 04:31:13
|
Revision: 599
http://sourceforge.net/p/ptpd/code/599
Author: wowczarek
Date: 2015-10-22 04:31:10 +0000 (Thu, 22 Oct 2015)
Log Message:
-----------
- added templates.conf missing from svn
- all config-related operations:
parse, help, print default, check restart,
now merged into parseConfig (opCode)
- removed more macros, help related
and restart check related
- added array size parameter
to configMapString for safe strncpy
(macros had access to array so could
run sizeof, now functions only have
a pointer)
- expanded ptpengine:interface man page
Modified Paths:
--------------
trunk/src/dep/daemonconfig.c
trunk/src/dep/daemonconfig.h
trunk/src/dep/startup.c
trunk/src/ptpd2.conf.5.in
Added Paths:
-----------
trunk/src/templates.conf
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-10-21 01:28:49 UTC (rev 598)
+++ trunk/src/dep/daemonconfig.c 2015-10-22 04:31:10 UTC (rev 599)
@@ -48,81 +48,59 @@
* within parseConfig - they assume the existence of the "dictionary*" dict variable.
*/
-/* Basic helper macros */
+static void printComment(const char* helptext);
-#define STRING_EMPTY(string)\
- (!strcmp(string,""))
+static int configSettingChanged(dictionary *oldConfig, dictionary *newConfig, const char *key);
-#define CONFIG_ISSET(key) \
- (strcmp(iniparser_getstring(dict, key, ""),"") != 0)
+static void warnRestart(const char *key, int flags);
-#define CONFIG_ISPRESENT(key) \
- (iniparser_find_entry(dict, key) != 0)
+static int configMapBoolean(int opCode, void *opArg, dictionary* dict,
+ dictionary *target, const char * key, int restartFlags, Boolean *var, Boolean def, const char* helptext);
-#define CONFIG_ISTRUE(key) \
- (iniparser_getboolean(dict,key,FALSE)==TRUE)
+static int configMapString(int opCode, void *opArg, dictionary *dict,
+ dictionary *target, const char *key, int restartFlags, char *var, int size, char *def, const char* helptext);
-#define DICT_ISTRUE(dict,key) \
- (iniparser_getboolean(dict,key,FALSE)==TRUE)
+static int checkRangeInt(dictionary *dict, const char *key, int rangeFlags, int minBound, int maxBound);
+static int configMapInt(int opCode, void *opArg, dictionary *dict,
+ dictionary *target, const char *key, int restartFlags, int intType, void *var, int def,
+ const char *helptext, int rangeFlags, int minBound, int maxBound);
-/*
- * Macros controlling the behaviour of parseConfig - using "hidden" keys.
- * Thanks to this, a single line in parseConfig can map settings and print help.
- * the SET_QUIET / END_QUIET macros suppress info and error output of parseConfig
- */
+static int checkRangeDouble(dictionary *dict, const char *key, int rangeFlags, double minBound, double maxBound);
-#define SET_QUIET() \
- dictionary_set(dict,"%quiet%:%quiet%","Y");
+static int configMapDouble(int opCode, void *opArg, dictionary *dict,
+ dictionary *target, const char *key, int restartFlags, double *var, double def,
+ const char *helptext, int rangeFlags, double minBound, double maxBound);
-#define END_QUIET() \
- dictionary_unset(dict,"%quiet%:%quiet%");
+static int configMapSelectValue(int opCode, void *opArg, dictionary *dict,
+ dictionary *target, const char* key, int restartFlags, uint8_t *var, int def, const char *helptext, ...);
-#define IS_QUIET()\
- ( CONFIG_ISTRUE("%quiet%:%quiet%") )
+static void parseUserVariables(dictionary *dict, dictionary *target);
-#define SET_SHOWDEFAULT() \
- SET_QUIET();\
- dictionary_set(dict,"%showdefault%:%showdefault%","Y");
+static void findUnknownSettings(int opCode, dictionary* source, dictionary* dict);
-#define END_SHOWDEFAULT() \
- END_QUIET();\
- dictionary_unset(dict,"%showdefault%:%showdefault%");
-#define IS_SHOWDEFAULT()\
- ( CONFIG_ISTRUE("%showdefault%:%showdefault%") )
+/* Basic helper macros */
-#define HELP_START() \
- SET_QUIET();\
- dictionary_set(dict,"%helponly%:%helponly%","T");
+#define STRING_EMPTY(string)\
+ (!strcmp(string,""))
-#define HELP_ITEM(key) \
- SET_QUIET();\
- dictionary_set(dict,"%helponly%:%helpitem%",key);
+#define CONFIG_ISSET(key) \
+ (strcmp(iniparser_getstring(dict, key, ""),"") != 0)
-#define HELP_ITEM_COMPLETE() \
- dictionary_set(dict,"%helponly%:%helpitem%","%complete%");
+#define CONFIG_ISPRESENT(key) \
+ (iniparser_find_entry(dict, key) != 0)
-#define HELP_ITEM_FOUND() \
- (strcmp(iniparser_getstring(dict, "%helponly%:%helpitem%" , ""),"%complete%") == 0)
+#define CONFIG_ISTRUE(key) \
+ (iniparser_getboolean(dict,key,FALSE)==TRUE)
-#define HELP_END() \
- dictionary_unset(dict,"%helponly%:%helponly%");\
- dictionary_unset(dict,"%helponly%:%helpitem%");\
- END_QUIET();
+#define DICT_ISTRUE(dict,key) \
+ (iniparser_getboolean(dict,key,FALSE)==TRUE)
-#define IS_HELP(key, helptext)\
- ( ( (strcmp(iniparser_getstring(dict, "%helponly%:%helpitem%", ""),key) == 0) ||\
- CONFIG_ISTRUE("%helponly%:%helponly%")) && (strcmp(helptext, "") != 0) )
-
-#define HELP_ON()\
- ( CONFIG_ISTRUE("%helponly%:%helponly%") || \
- CONFIG_ISSET("%helponly%:%helpitem%") )
-
/* Macros handling required settings, triggers, conflicts and dependencies */
#define CONFIG_KEY_REQUIRED(key) \
- if( !IS_QUIET() && !HELP_ON() && !CONFIG_ISSET(key) )\
+ if( !(opCode & CFGOP_PARSE_QUIET) && !(opCode & CFGOP_HELP_FULL) && !(opCode & CFGOP_HELP_SINGLE) && !CONFIG_ISSET(key) )\
{ \
ERROR("Configuration error: option \"%s\" is required\n", key); \
parseResult = FALSE;\
@@ -132,7 +110,7 @@
if( CONFIG_ISSET(key1) && \
!CONFIG_ISSET(key2)) \
{ \
- if(!IS_QUIET())\
+ if(!(opCode & CFGOP_PARSE_QUIET))\
ERROR("Configuration error: option \"%s\" requires option \"%s\"\n", key1, key2); \
parseResult = FALSE;\
}
@@ -141,7 +119,7 @@
if( CONFIG_ISSET(key1) && \
CONFIG_ISSET(key2)) \
{ \
- if(!IS_QUIET())\
+ if(!(opCode & CFGOP_PARSE_QUIET))\
ERROR("Configuration error: option \"%s\" cannot be used with option \"%s\"\n", key1, key2); \
parseResult = FALSE;\
}
@@ -150,7 +128,7 @@
if ( (condition) && \
!CONFIG_ISSET(dep) ) \
{ \
- if(!IS_QUIET())\
+ if(!(opCode & CFGOP_PARSE_QUIET))\
WARNING("Warning: %s\n", messageText); \
}
@@ -158,7 +136,7 @@
if ( (condition) && \
CONFIG_ISSET(dep) ) \
{ \
- if(!IS_QUIET())\
+ if(!(opCode & CFGOP_PARSE_QUIET))\
WARNING("Warning: %s\n", messageText); \
}
@@ -166,7 +144,7 @@
if ( (condition) && \
!CONFIG_ISSET(dep) ) \
{ \
- if(!IS_QUIET())\
+ if(!(opCode & CFGOP_PARSE_QUIET))\
ERROR("Configuration error: option \"%s=%s\" requires option \"%s\"\n", key, stringval, dep); \
parseResult = FALSE;\
}
@@ -175,7 +153,7 @@
if ( (condition) && \
CONFIG_ISSET(dep) ) \
{ \
- if(!IS_QUIET())\
+ if(!(opCode & CFGOP_PARSE_QUIET))\
ERROR("Configuration error: option \"%s=%s\" cannot be used with option \"%s\"\n", key, stringval, dep); \
parseResult = FALSE;\
}
@@ -184,7 +162,7 @@
if ( (condition) && \
CONFIG_ISSET(key) ) \
{ \
- if(!IS_QUIET())\
+ if(!(opCode & CFGOP_PARSE_QUIET))\
ERROR("Configuration error: option \"%s=%s\" cannot be used: \n%s", key, stringval, message); \
parseResult = FALSE;\
}
@@ -210,7 +188,7 @@
if ( (condition) && \
CONFIG_ISSET(key) ) \
{ \
- if(!IS_QUIET())\
+ if(!(opCode & CFGOP_PARSE_QUIET))\
ERROR("%s\n", warningtext); \
parseResult = FALSE;\
}
@@ -218,7 +196,7 @@
#define CONFIG_CONDITIONAL_ASSERTION(condition,warningtext) \
if ( (condition) ) \
{ \
- if(!IS_QUIET())\
+ if(!(opCode & CFGOP_PARSE_QUIET))\
ERROR("%s\n", warningtext); \
parseResult = FALSE;\
}
@@ -231,22 +209,6 @@
#define WARN_DEPRECATED(old,new,long,key)\
WARN_DEPRECATED_COMMENT( old,new,long,key,"")
-#define SETTING_CHANGED(key) \
- (strcmp(\
- dictionary_get(newConfig, key,""),\
- dictionary_get(oldConfig, key,"")\
- ) != 0 )
-/* Macro flagging component restart if the given option has changed */
-#define COMPONENT_RESTART_REQUIRED(key,flag)\
- if(SETTING_CHANGED(key)) {\
- if(flag == PTPD_RESTART_DAEMON) {\
- DBG("Setting %s changed, restart of ptpd process required\n",key,flag);\
- NOTIFY("Change of %s setting requires "PTPD_PROGNAME" restart\n",key);\
- } else\
- DBG("Setting %s changed, restart of subystem %d required\n",key,flag);\
- restartFlags |= flag;\
- }
-
#define CONFIG_KEY_ALIAS(src,dest) \
{ \
if(!STRING_EMPTY(dictionary_get(dict,src,""))) {\
@@ -256,8 +218,10 @@
}
/* Output a potentially multi-line string, prefixed with ;s */
-static void printComment(const char* helptext)
+static void
+printComment(const char* helptext)
{
+
int i, len;
len = strlen(helptext);
@@ -281,33 +245,75 @@
}
static int
-configMapBoolean(dictionary* dict, dictionary *target, const char * key, Boolean *var, Boolean def, const char* helptext)
+configSettingChanged(dictionary *oldConfig, dictionary *newConfig, const char *key)
{
- if(IS_HELP(key, helptext)) {
+
+ return(strcmp(
+ dictionary_get(newConfig, key,""),
+ dictionary_get(oldConfig, key,"")
+ ) != 0 );
+
+}
+
+/* warn about restart required if needed */
+static void
+warnRestart(const char *key, int flags)
+{
+ if(flags & PTPD_RESTART_DAEMON) {
+ NOTIFY("Change of %s setting requires "PTPD_PROGNAME" restart\n",key);
+ } else {
+ DBG("Setting %s changed, restart of subystem %d required\n",key,flag);
+ }
+}
+
+static int
+configMapBoolean(int opCode, void *opArg, dictionary* dict, dictionary *target,
+ const char * key, int restartFlags, Boolean *var, Boolean def, const char* helptext)
+{
+
+ if(opCode & CFGOP_RESTART_FLAGS) {
+ if(CONFIG_ISSET(key)) {
+ *(int*)opArg |= restartFlags;
+ if(opCode & CFGOP_RESTART_FLAGS && !(opCode & CFGOP_PARSE_QUIET)) {
+ warnRestart(key, restartFlags);
+ }
+ }
+ return 1;
+ } else if(opCode & CFGOP_HELP_FULL || opCode & CFGOP_HELP_SINGLE) {
+
+ char *helpKey = (char*)opArg;
+
+ if(opCode & CFGOP_HELP_SINGLE && strcmp(key, helpKey)) {
+ return 1;
+ }
+
+ helpKey[0] = '\0';
+
printf("setting: %s (--%s)\n", key, key);
printf(" type: BOOLEAN (value must start with t/T/y/Y/1/f/F/n/N/0)\n");
printf(" usage: %s\n", helptext);
printf("default: %s\n", def ? "Y" : "N");
printf("\n");
- HELP_ITEM_COMPLETE();
return 1;
} else {
if (!CONFIG_ISPRESENT(key)) {
*var = def;
dictionary_set(target,key,(*var)?"Y":"N");
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ if(!strcmp(helptext, "") && opCode & CFGOP_PRINT_DEFAULT) {
printComment(helptext);
printf("%s = %s\n", key,(*var)?"Y":"N");
}
return 1;
} else if(!CONFIG_ISSET(key) || iniparser_getboolean(dict,key,-1) == -1) {
- ERROR("Configuration error: option \"%s='%s'\" has unknown boolean value: must start with 0/1/t/T/f/F/y/Y/n/N\n",key,iniparser_getstring(dict,key,""));
+ if(!(opCode & CFGOP_PARSE_QUIET)) {
+ ERROR("Configuration error: option \"%s='%s'\" has unknown boolean value: must start with 0/1/t/T/f/F/y/Y/n/N\n",key,iniparser_getstring(dict,key,""));
+ }
dictionary_set(target,key,""); /* suppress the "unknown entry" warning for malformed boolean values */ \
return 0;
} else {
*var=iniparser_getboolean(dict,key,def);
dictionary_set(target,key,(*var)?"Y":"N");
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ if(strcmp(helptext, "") && opCode & CFGOP_PRINT_DEFAULT) {
printComment(helptext);\
printf("%s = %s\n", key,(*var)?"Y":"N");
}
@@ -317,23 +323,42 @@
}
static int
-configMapString(dictionary *dict, dictionary *target, const char *key, char *var, char *def, const char* helptext)
+configMapString(int opCode, void *opArg, dictionary *dict, dictionary *target,
+ const char *key, int restartFlags, char *var, int size, char *def, const char* helptext)
{
+ if(opCode & CFGOP_RESTART_FLAGS) {
+ if(CONFIG_ISSET(key)) {
+ *(int*)opArg |= restartFlags;
+ if(opCode & CFGOP_RESTART_FLAGS && !(opCode & CFGOP_PARSE_QUIET)) {
+ warnRestart(key, restartFlags);
+ }
+ }
+ return 1;
+ } else if(opCode & CFGOP_HELP_FULL || opCode & CFGOP_HELP_SINGLE) {
+ char *helpKey = (char*)opArg;
- if(IS_HELP(key, helptext)) {
+ if(opCode & CFGOP_HELP_SINGLE && strcmp(key, helpKey)) {
+ return 1;
+ }
+
+ helpKey[0] = '\0';
+
printf("setting: %s (--%s)\n", key, key);
printf(" type: STRING\n");
printf(" usage: %s\n", helptext);
printf("default: %s\n", (strcmp(def, "") == 0) ? "[none]" : def);
printf("\n");\
- HELP_ITEM_COMPLETE();
return 1;
} else {
char *tmpstring = iniparser_getstring(dict,key,def);
- if (strncmp(var, tmpstring, MAX_LINE_SIZE)) strncpy(var, tmpstring, sizeof(var) / sizeof(char));
+ /* do not overwrite the same pointer with the same pointer */
+ if (var!=tmpstring) {
+ strncpy(var, tmpstring, size);
+ var[size-1] = '\0';
+ }
dictionary_set(target, key, tmpstring);
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ if(strcmp(helptext,"") && opCode & CFGOP_PRINT_DEFAULT) {
printComment(helptext);
printf("%s = %s\n", key,tmpstring);
}
@@ -341,7 +366,8 @@
}
}
-static int checkRangeInt(dictionary *dict, const char *key, int rangeFlags, int minBound, int maxBound)
+static int
+checkRangeInt(dictionary *dict, const char *key, int rangeFlags, int minBound, int maxBound)
{
int tmpdouble = iniparser_getint(dict,key,minBound);
@@ -363,19 +389,35 @@
return 0;
}
- if(!ret && !IS_QUIET()) {
- ERROR("Configuration error: option \"%s=%d\" not within allowed range: %d..%d\n", key, tmpdouble, minBound, maxBound);
- }
-
return ret;
}
-static int configMapInt(dictionary *dict, dictionary *target, const char *key, int intType,
- void *var, int def, const char *helptext, int rangeFlags,
- int minBound, int maxBound)
+static int
+configMapInt(int opCode, void *opArg, dictionary *dict, dictionary *target, const char *key, int restartFlags, int intType,
+ void *var, int def, const char *helptext, int rangeFlags,
+ int minBound, int maxBound)
{
- if(IS_HELP(key, helptext)) {
+ int ret = 0;
+
+ if(opCode & CFGOP_RESTART_FLAGS) {
+ if(CONFIG_ISSET(key)) {
+ *(int*)opArg |= restartFlags;
+ if(opCode & CFGOP_RESTART_FLAGS && !(opCode & CFGOP_PARSE_QUIET)) {
+ warnRestart(key, restartFlags);
+ }
+ }
+ return 1;
+ } else if(opCode & CFGOP_HELP_FULL || opCode & CFGOP_HELP_SINGLE) {
+
+ char *helpKey = (char*)opArg;
+
+ if(opCode & CFGOP_HELP_SINGLE && strcmp(key, helpKey)) {
+ return 1;
+ }
+
+ helpKey[0] = '\0';
+
switch(rangeFlags) {
case RANGECHECK_NONE:
printf("setting: %s (--%s)\n", key, key);
@@ -383,7 +425,6 @@
printf(" usage: %s\n", helptext);
printf("default: %d\n", def);
printf("\n");
- HELP_ITEM_COMPLETE();
return 1;
case RANGECHECK_RANGE:
printf("setting: %s (--%s)\n", key, key);
@@ -396,7 +437,6 @@
printf(" usage: %s\n", helptext);
printf("default: %d\n", def);
printf("\n");
- HELP_ITEM_COMPLETE();
return 1;
case RANGECHECK_MIN:
printf("setting: %s (--%s)\n", key, key);
@@ -404,7 +444,6 @@
printf(" usage: %s\n", helptext);
printf("default: %d\n", def);
printf("\n");
- HELP_ITEM_COMPLETE();
return 1;
case RANGECHECK_MAX:
printf("setting: %s (--%s)\n", key, key);
@@ -412,7 +451,6 @@
printf(" usage: %s\n", helptext);
printf("default: %d\n", def);
printf("\n");
- HELP_ITEM_COMPLETE();
return 1;
default:
return 0;
@@ -447,19 +485,37 @@
break;
}
-
memset(buf, 0, 50);
snprintf(buf, 50, "%d", userVar);
dictionary_set(target,key,buf);
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ if(strcmp(helptext, "") && opCode & CFGOP_PRINT_DEFAULT) {
printComment(helptext);
printf("%s = %s\n", key,buf);
}
- return checkRangeInt(dict, key, rangeFlags, minBound, maxBound);
+ ret = checkRangeInt(dict, key, rangeFlags, minBound, maxBound);
+
+ if(!ret && !(opCode & CFGOP_PARSE_QUIET)) {
+ switch(rangeFlags) {
+ case RANGECHECK_RANGE:
+ ERROR("Configuration error: option \"%s=%s\" not within allowed range: %d..%d\n", key, buf, minBound, maxBound);
+ break;
+ case RANGECHECK_MIN:
+ ERROR("Configuration error: option \"%s=%s\" below allowed minimum: %d\n", key, buf, minBound);
+ break;
+ case RANGECHECK_MAX:
+ ERROR("Configuration error: option \"%s=%s\" above allowed maximum: %d\n", key, buf, maxBound);
+ break;
+ default:
+ return ret;
+ }
+ }
+
+ return ret;
}
}
-static int checkRangeDouble(dictionary *dict, const char *key, int rangeFlags, double minBound, double maxBound)
+static int
+checkRangeDouble(dictionary *dict, const char *key, int rangeFlags, double minBound, double maxBound)
{
double tmpdouble = iniparser_getdouble(dict,key,minBound);
@@ -481,18 +537,34 @@
return 0;
}
- if(!ret && !IS_QUIET()) {
- ERROR("Configuration error: option \"%s=%f\" not within allowed range: %f..%f\n", key, tmpdouble, minBound, maxBound);
- }
-
return ret;
}
-static int configMapDouble(dictionary *dict, dictionary *target, const char *key,
+static int
+configMapDouble(int opCode, void *opArg, dictionary *dict, dictionary *target, const char *key, int restartFlags,
double *var, double def, const char *helptext, int rangeFlags,
double minBound, double maxBound)
{
- if(IS_HELP(key, helptext)) {
+
+ int ret = 0;
+ if(opCode & CFGOP_RESTART_FLAGS) {
+ if(CONFIG_ISSET(key)) {
+ *(int*)opArg |= restartFlags;
+ if(opCode & CFGOP_RESTART_FLAGS && !(opCode & CFGOP_PARSE_QUIET)) {
+ warnRestart(key, restartFlags);
+ }
+ }
+ return 1;
+ } else if(opCode & CFGOP_HELP_FULL || opCode & CFGOP_HELP_SINGLE) {
+
+ char *helpKey = (char*)opArg;
+
+ if(opCode & CFGOP_HELP_SINGLE && strcmp(key, helpKey)) {
+ return 1;
+ }
+
+ helpKey[0] = '\0';
+
switch(rangeFlags) {
case RANGECHECK_NONE:
printf("setting: %s (--%s)\n", key, key);
@@ -500,7 +572,6 @@
printf(" usage: %s\n", helptext);
printf("default: %f\n", def);
printf("\n");
- HELP_ITEM_COMPLETE();
return 1;
case RANGECHECK_RANGE:
printf("setting: %s (--%s)\n", key, key);
@@ -513,7 +584,6 @@
printf(" usage: %s\n", helptext);
printf("default: %f\n", def);
printf("\n");
- HELP_ITEM_COMPLETE();
return 1;
case RANGECHECK_MIN:
printf("setting: %s (--%s)\n", key, key);
@@ -521,7 +591,6 @@
printf(" usage: %s\n", helptext);
printf("default: %f\n", def);
printf("\n");
- HELP_ITEM_COMPLETE();
return 1;
case RANGECHECK_MAX:
printf("setting: %s (--%s)\n", key, key);
@@ -529,7 +598,6 @@
printf(" usage: %s\n", helptext);
printf("default: %f\n", def);
printf("\n");
- HELP_ITEM_COMPLETE();
return 1;
default:
return 0;
@@ -540,16 +608,36 @@
memset(buf, 0, 50);
snprintf(buf, 50, "%f", *var);
dictionary_set(target,key,buf);
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ if(strcmp(helptext, "") && opCode & CFGOP_PRINT_DEFAULT) {
printComment(helptext);
printf("%s = %s\n", key,buf);
}
- return checkRangeDouble(dict, key, rangeFlags, minBound, maxBound);
+
+ ret = checkRangeDouble(dict, key, rangeFlags, minBound, maxBound);
+
+ if(!ret && !(opCode & CFGOP_PARSE_QUIET)) {
+ switch(rangeFlags) {
+ case RANGECHECK_RANGE:
+ ERROR("Configuration error: option \"%s=%f\" not within allowed range: %f..%f\n", key, *var, minBound, maxBound);
+ break;
+ case RANGECHECK_MIN:
+ ERROR("Configuration error: option \"%s=%f\" below allowed minimum: %f\n", key, *var, minBound);
+ break;
+ case RANGECHECK_MAX:
+ ERROR("Configuration error: option \"%s=%f\" above allowed maximum: %f\n", key, *var, maxBound);
+ break;
+ default:
+ return ret;
+ }
+ }
+
+ return ret;
}
}
static int
-configMapSelectValue(dictionary *dict, dictionary *target, const char* key, uint8_t *var, int def, const char *helptext, ...)
+configMapSelectValue(int opCode, void *opArg, dictionary *dict, dictionary *target,
+const char* key, int restartFlags, uint8_t *var, int def, const char *helptext, ...)
{
int ret;
@@ -597,25 +685,42 @@
}
va_end(ap);
+ if(opCode & CFGOP_RESTART_FLAGS) {
+ if(CONFIG_ISSET(key)) {
+ *(int*)opArg |= restartFlags;
+ if(opCode & CFGOP_RESTART_FLAGS && !(opCode & CFGOP_PARSE_QUIET)) {
+ warnRestart(key, restartFlags);
+ }
+ }
+ return 1;
+ } else if(opCode & CFGOP_HELP_FULL || opCode & CFGOP_HELP_SINGLE) {
- if(IS_HELP(key, helptext)) {
+ char *helpKey = (char*)opArg;
+
+ if(opCode & CFGOP_HELP_SINGLE && strcmp(key, helpKey)) {
+ return 1;
+ }
+
+ helpKey[0] = '\0';
+
printf("setting: %s (--%s)\n", key, key);
printf(" type: SELECT\n");
printf(" usage: %s\n", helptext);
printf("options: %s\n", sbuf);
printf("default: %s\n", defValue);
printf("\n");
- HELP_ITEM_COMPLETE();
ret = 1;
goto result;
} else {
dictionary_set(target, key, keyValue);
if(selectedValue < 0) {
- ERROR("Configuration error: option \"%s\" has unknown value: %s - allowed values: %s\n", key, keyValue, sbuf);
+ if(!(opCode & CFGOP_PARSE_QUIET)) {
+ ERROR("Configuration error: option \"%s\" has unknown value: %s - allowed values: %s\n", key, keyValue, sbuf);
+ }
ret = 0;
} else {
*var = (uint8_t)selectedValue;
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ if(strcmp(helptext, "") && opCode & CFGOP_PRINT_DEFAULT) {
printComment(helptext);
printf("; Options: %s\n", sbuf);
printf("%s = %s\n", key,keyValue);
@@ -654,7 +759,7 @@
search++;
replace = dictionary_get(dict, key, "");
snprintf(varname, sizeof(varname), "@%s@", search);
- DBG("replacing %s with %s in config\n", varname, replace);
+ DBGV("replacing %s with %s in config\n", varname, replace);
dictionary_replace(dict, varname, replace);
dictionary_set(target, key, replace);
}
@@ -669,7 +774,7 @@
* that are not present in the template - display only.
*/
static void
-findUnknownSettings(dictionary* source, dictionary* dict)
+findUnknownSettings(int opCode, dictionary* source, dictionary* dict)
{
int i = 0;
@@ -680,7 +785,7 @@
/* skip if the key is null or is a section */
if(source->key[i] == NULL || strstr(source->key[i],":") == NULL)
continue;
- if ( !iniparser_find_entry(dict, source->key[i]) && !IS_QUIET() )
+ if ( !iniparser_find_entry(dict, source->key[i]) && !(opCode & CFGOP_PARSE_QUIET) )
WARNING("Unknown configuration entry: %s - setting will be ignored\n", source->key[i]);
}
}
@@ -695,7 +800,7 @@
* ensure correct config reload behaviour.
*/
dictionary*
-parseConfig ( dictionary* dict, RunTimeOpts *rtOpts )
+parseConfig ( int opCode, void *opArg, dictionary* dict, RunTimeOpts *rtOpts )
{
/*-
@@ -705,6 +810,7 @@
*/
+
/*-
* WARNING: for ease of use, a limited number of keys is set
* via getopt in loadCommanLineOptions(). When renaming settings, make sure
@@ -729,7 +835,7 @@
PtpEnginePreset ptpPreset;
- if(!IS_QUIET()) {
+ if(!(opCode & CFGOP_PARSE_QUIET)) {
INFO("Checking configuration\n");
}
@@ -758,17 +864,20 @@
CONFIG_KEY_REQUIRED("ptpengine:interface");
- parseResult &= configMapString(dict, target, "ptpengine:interface",rtOpts->primaryIfaceName,rtOpts->primaryIfaceName,
+ parseResult &= configMapString(opCode, opArg, dict, target, "ptpengine:interface",
+ PTPD_RESTART_NETWORK, rtOpts->primaryIfaceName, sizeof(rtOpts->primaryIfaceName), rtOpts->primaryIfaceName,
"Network interface to use - eth0, igb0 etc. (required).");
- parseResult &= configMapString(dict, target, "ptpengine:backup_interface",rtOpts->backupIfaceName,rtOpts->backupIfaceName,
+ parseResult &= configMapString(opCode, opArg, dict, target, "ptpengine:backup_interface",
+ PTPD_RESTART_NETWORK, rtOpts->backupIfaceName, sizeof(rtOpts->backupIfaceName), rtOpts->backupIfaceName,
"Backup network interface to use - eth0, igb0 etc. When no GM available, \n"
" slave will keep alternating between primary and secondary until a GM is found.\n");
- CONFIG_KEY_TRIGGER("ptpengine:backup_interface",rtOpts->backupIfaceEnabled,TRUE,FALSE);
+ CONFIG_KEY_TRIGGER("ptpengine:backup_interface", rtOpts->backupIfaceEnabled,TRUE,FALSE);
/* Preset option names have to be mapped to defined presets - no free strings here */
- parseResult &= configMapSelectValue(dict, target, "ptpengine:preset", &rtOpts->selectedPreset,rtOpts->selectedPreset,
+ parseResult &= configMapSelectValue(opCode, opArg, dict, target, "ptpengine:preset",
+ PTPD_RESTART_PROTOCOL, &rtOpts->selectedPreset, rtOpts->selectedPreset,
"PTP engine preset:\n"
" none = Defaults, no clock class restrictions\n"
" masteronly = Master, passive when not best master (clock class 0..127)\n"
@@ -777,11 +886,11 @@
" (clock class 128..254)\n"
" slaveonly = Slave only (clock class 255 only)\n",
#ifndef PTPD_SLAVE_ONLY
- (getPtpPreset(PTP_PRESET_NONE,rtOpts)).presetName, PTP_PRESET_NONE,
- (getPtpPreset(PTP_PRESET_MASTERONLY,rtOpts)).presetName, PTP_PRESET_MASTERONLY,
- (getPtpPreset(PTP_PRESET_MASTERSLAVE,rtOpts)).presetName, PTP_PRESET_MASTERSLAVE,
+ (getPtpPreset(PTP_PRESET_NONE, rtOpts)).presetName, PTP_PRESET_NONE,
+ (getPtpPreset(PTP_PRESET_MASTERONLY, rtOpts)).presetName, PTP_PRESET_MASTERONLY,
+ (getPtpPreset(PTP_PRESET_MASTERSLAVE, rtOpts)).presetName, PTP_PRESET_MASTERSLAVE,
#endif /* PTPD_SLAVE_ONLY */
- (getPtpPreset(PTP_PRESET_SLAVEONLY,rtOpts)).presetName, PTP_PRESET_SLAVEONLY, NULL
+ (getPtpPreset(PTP_PRESET_SLAVEONLY, rtOpts)).presetName, PTP_PRESET_SLAVEONLY, NULL
);
CONFIG_KEY_CONDITIONAL_CONFLICT("ptpengine:preset",
@@ -792,7 +901,8 @@
ptpPreset = getPtpPreset(rtOpts->selectedPreset, rtOpts);
- parseResult &= configMapSelectValue(dict, target, "ptpengine:transport", &rtOpts->transport,rtOpts->transport,
+ parseResult &= configMapSelectValue(opCode, opArg, dict, target, "ptpengine:transport",
+ PTPD_RESTART_NETWORK, &rtOpts->transport, rtOpts->transport,
"Transport type for PTP packets. Ethernet transport requires libpcap support.",
"ipv4", UDP_IPV4,
#if 0
@@ -801,16 +911,17 @@
"ethernet", IEEE_802_3, NULL
);
- parseResult &= configMapBoolean(dict, target,"ptpengine:dot2as", &rtOpts->dot2AS,rtOpts->dot2AS,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:dot2as", PTPD_UPDATE_DATASETS, &rtOpts->dot2AS, rtOpts->dot2AS,
"Enable TransportSpecific field compatibility with 802.1AS / AVB (requires Ethernet transport)");
CONFIG_KEY_CONDITIONAL_WARNING_ISSET((rtOpts->transport != IEEE_802_3) && rtOpts->dot2AS,
"ptpengine:dot2as",
"802.1AS compatibility can only be used with the Ethernet transport\n");
- CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport != IEEE_802_3,rtOpts->dot2AS,FALSE,rtOpts->dot2AS);
+ CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport != IEEE_802_3, rtOpts->dot2AS,FALSE, rtOpts->dot2AS);
- parseResult &= configMapSelectValue(dict, target, "ptpengine:ip_mode", &rtOpts->ipMode, rtOpts->ipMode,
+ parseResult &= configMapSelectValue(opCode, opArg, dict, target, "ptpengine:ip_mode",
+ PTPD_RESTART_NETWORK, &rtOpts->ipMode, rtOpts->ipMode,
"IP transmission mode (requires IP transport) - hybrid mode uses\n"
" multicast for sync and announce, and unicast for delay request and\n"
" response; unicast mode uses unicast for all transmission.\n"
@@ -821,15 +932,18 @@
"hybrid", IPMODE_HYBRID, NULL
);
- parseResult &= configMapBoolean(dict, target,"ptpengine:unicast_negotiation", &rtOpts->unicastNegotiation,rtOpts->unicastNegotiation,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:unicast_negotiation",
+ PTPD_RESTART_PROTOCOL, &rtOpts->unicastNegotiation, rtOpts->unicastNegotiation,
"Enable unicast negotiation support using signaling messages\n");
- parseResult &= configMapBoolean(dict, target,"ptpengine:unicast_any_master", &rtOpts->unicastAcceptAny,rtOpts->unicastAcceptAny,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:unicast_any_master",
+ PTPD_RESTART_NONE, &rtOpts->unicastAcceptAny, rtOpts->unicastAcceptAny,
"When using unicast negotiation (slave), accept PTP messages from any master.\n"
" By default, only messages from acceptable masters (ptpengine:unicast_destinations)\n"
" are accepted, and only if transmission was granted by the master\n");
- parseResult &= configMapInt(dict, target, "ptpengine:unicast_port_mask", INTTYPE_U16, &rtOpts->unicastPortMask,rtOpts->unicastPortMask,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:unicast_port_mask",
+ PTPD_RESTART_PROTOCOL, INTTYPE_U16, &rtOpts->unicastPortMask, rtOpts->unicastPortMask,
"PTP port number wildcard mask applied onto port identities when running\n"
" unicast negotiation: allows multiple port identities to be accepted as one.\n"
" This option can be used as a workaround where a node sends signaling messages and\n"
@@ -844,15 +958,17 @@
"Unicast negotiation can only be used with unicast transmission\n");
/* disable unicast negotiation unless running unicast */
- CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport == IEEE_802_3,rtOpts->unicastNegotiation,FALSE,rtOpts->unicastNegotiation);
- CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->ipMode != IPMODE_UNICAST,rtOpts->unicastNegotiation,FALSE,rtOpts->unicastNegotiation);
+ CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport == IEEE_802_3, rtOpts->unicastNegotiation,FALSE, rtOpts->unicastNegotiation);
+ CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->ipMode != IPMODE_UNICAST, rtOpts->unicastNegotiation,FALSE, rtOpts->unicastNegotiation);
- parseResult &= configMapBoolean(dict, target,"ptpengine:disable_bmca", &rtOpts->disableBMCA,rtOpts->disableBMCA,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:disable_bmca",
+ PTPD_RESTART_PROTOCOL, &rtOpts->disableBMCA, rtOpts->disableBMCA,
"Disable Best Master Clock Algorithm for unicast masters:\n"
" Only effective for masteronly preset - all Announce messages\n"
" will be ignored and clock will transition directly into MASTER state.\n");
- parseResult &= configMapBoolean(dict, target,"ptpengine:unicast_negotiation_listening", &rtOpts->unicastNegotiationListening,rtOpts->unicastNegotiationListening,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:unicast_negotiation_listening",
+ PTPD_RESTART_NONE, &rtOpts->unicastNegotiationListening, rtOpts->unicastNegotiationListening,
"When unicast negotiation enabled on a master clock, \n"
" reply to transmission requests also in LISTENING state.");
@@ -861,7 +977,8 @@
INFO("Libpcap support is currently marked broken/experimental on Solaris platforms.\n"
"To test it, please build with --enable-experimental-options\n");
- parseResult &= configMapBoolean(dict, target,"ptpengine:use_libpcap", &rtOpts->pcap,FALSE,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:use_libpcap",
+ PTPD_RESTART_NETWORK, &rtOpts->pcap,FALSE,
"Use libpcap for sending and receiving traffic (automatically enabled\n"
" in Ethernet mode).");
@@ -872,19 +989,21 @@
"Libpcap support is currently marked broken/experimental on Solaris platforms.\n"
"To test it and use the Ethernet transport, please build with --enable-experimental-options\n");
#elif defined(PTPD_PCAP)
- parseResult &= configMapBoolean(dict, target,"ptpengine:use_libpcap", &rtOpts->pcap,rtOpts->pcap,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:use_libpcap",
+ PTPD_RESTART_NETWORK, &rtOpts->pcap, rtOpts->pcap,
"Use libpcap for sending and receiving traffic (automatically enabled\n"
" in Ethernet mode).");
/* in ethernet mode, activate pcap and overwrite previous setting */
- CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport==IEEE_802_3,rtOpts->pcap,TRUE,rtOpts->pcap);
+ CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport==IEEE_802_3, rtOpts->pcap,TRUE, rtOpts->pcap);
#else
if(CONFIG_ISTRUE("ptpengine:use_libpcap"))
INFO("Libpcap support disabled or not available. Please install libpcap,\n"
"build without --disable-pcap, or try building with ---with-pcap-config\n"
" to use ptpengine:use_libpcap.\n");
- parseResult &= configMapBoolean(dict, target,"ptpengine:use_libpcap", &rtOpts->pcap,FALSE,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:use_libpcap",
+ PTPD_RESTART_NETWORK, &rtOpts->pcap,FALSE,
"Use libpcap for sending and receiving traffic (automatically enabled\n"
" in Ethernet mode).");
@@ -898,12 +1017,14 @@
#endif /* PTPD_PCAP */
- parseResult &= configMapBoolean(dict, target,"ptpengine:disable_udp_checksums", &rtOpts->disableUdpChecksums,rtOpts->disableUdpChecksums,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:disable_udp_checksums",
+ PTPD_RESTART_NETWORK, &rtOpts->disableUdpChecksums, rtOpts->disableUdpChecksums,
"Disable UDP checksum validation on UDP sockets (Linux only).\n"
" Workaround for situations where a node (like Transparent Clock).\n"
" does not rewrite checksums\n");
- parseResult &= configMapSelectValue(dict, target, "ptpengine:delay_mechanism", &rtOpts->delayMechanism,rtOpts->delayMechanism,
+ parseResult &= configMapSelectValue(opCode, opArg, dict, target, "ptpengine:delay_mechanism",
+ PTPD_RESTART_PROTOCOL, &rtOpts->delayMechanism, rtOpts->delayMechanism,
"Delay detection mode used - use DELAY_DISABLED for syntonisation only\n"
" (no full synchronisation).",
"E2E", E2E,
@@ -911,62 +1032,72 @@
"DELAY_DISABLED", DELAY_DISABLED, NULL
);
- parseResult &= configMapInt(dict, target, "ptpengine:domain", INTTYPE_U8, &rtOpts->domainNumber,rtOpts->domainNumber,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:domain",
+ PTPD_RESTART_PROTOCOL, INTTYPE_U8, &rtOpts->domainNumber, rtOpts->domainNumber,
"PTP domain number.", RANGECHECK_RANGE, 0,127);
- parseResult &= configMapInt(dict, target, "ptpengine:port_number", INTTYPE_U16, &rtOpts->portNumber,rtOpts->portNumber,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:port_number", PTPD_UPDATE_DATASETS, INTTYPE_U16, &rtOpts->portNumber, rtOpts->portNumber,
"PTP port number (part of PTP Port Identity - not UDP port).\n"
" For ordinary clocks (single port), the default should be used, \n"
" but when running multiple instances to simulate a boundary clock, \n"
" The port number can be changed.",RANGECHECK_RANGE,1,65534);
- parseResult &= configMapBoolean(dict, target,"ptpengine:any_domain", &rtOpts->anyDomain, rtOpts->anyDomain,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:any_domain",
+ PTPD_RESTART_PROTOCOL, &rtOpts->anyDomain, rtOpts->anyDomain,
"Usability extension: if enabled, a slave-only clock will accept\n"
" masters from any domain, while preferring the configured domain,\n"
" and preferring lower domain number.\n"
" NOTE: this behaviour is not part of the standard.");
- parseResult &= configMapBoolean(dict, target,"ptpengine:slave_only", &rtOpts->slaveOnly, ptpPreset.slaveOnly,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:slave_only",
+ PTPD_RESTART_NONE, &rtOpts->slaveOnly, ptpPreset.slaveOnly,
"Slave only mode (sets clock class to 255, overriding value from preset).");
- parseResult &= configMapInt(dict, target, "ptpengine:inbound_latency", INTTYPE_I32, &rtOpts->inboundLatency.nanoseconds,rtOpts->inboundLatency.nanoseconds,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:inbound_latency",
+ PTPD_RESTART_NONE, INTTYPE_I32, &rtOpts->inboundLatency.nanoseconds, rtOpts->inboundLatency.nanoseconds,
"Specify latency correction (nanoseconds) for incoming packets.", RANGECHECK_NONE, 0,0);
- parseResult &= configMapInt(dict, target, "ptpengine:outbound_latency",INTTYPE_I32, &rtOpts->outboundLatency.nanoseconds,rtOpts->outboundLatency.nanoseconds,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:outbound_latency",
+ PTPD_RESTART_NONE, INTTYPE_I32, &rtOpts->outboundLatency.nanoseconds, rtOpts->outboundLatency.nanoseconds,
"Specify latency correction (nanoseconds) for outgoing packets.", RANGECHECK_NONE,0,0);
- parseResult &= configMapInt(dict, target, "ptpengine:offset_shift", INTTYPE_I32, &rtOpts->ofmShift.nanoseconds,rtOpts->ofmShift.nanoseconds,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:offset_shift",
+ PTPD_RESTART_NONE, INTTYPE_I32, &rtOpts->ofmShift.nanoseconds, rtOpts->ofmShift.nanoseconds,
"Apply an arbitrary shift (nanoseconds) to offset from master when\n"
" in slave state. Value can be positive or negative - useful for\n"
" correcting for antenna latencies, delay assymetry\n"
" and IP stack latencies. This will not be visible in the offset \n"
" from master value - only in the resulting clock correction.", RANGECHECK_NONE, 0,0);
- parseResult &= configMapBoolean(dict, target,"ptpengine:always_respect_utc_offset", &rtOpts->alwaysRespectUtcOffset, rtOpts->alwaysRespectUtcOffset,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:always_respect_utc_offset",
+ PTPD_RESTART_NONE, &rtOpts->alwaysRespectUtcOffset, rtOpts->alwaysRespectUtcOffset,
"Compatibility option: In slave state, always respect UTC offset\n"
" announced by best master, even if the the\n"
" currrentUtcOffsetValid flag is announced FALSE.\n"
" NOTE: this behaviour is not part of the standard.");
- parseResult &= configMapBoolean(dict, target,"ptpengine:prefer_utc_offset_valid", &rtOpts->preferUtcValid, rtOpts->preferUtcValid,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:prefer_utc_offset_valid",
+ PTPD_RESTART_NONE, &rtOpts->preferUtcValid, rtOpts->preferUtcValid,
"Compatibility extension to BMC algorithm: when enabled,\n"
" BMC for both master and save clocks will prefer masters\n"
" nannouncing currrentUtcOffsetValid as TRUE.\n"
" NOTE: this behaviour is not part of the standard.");
- parseResult &= configMapBoolean(dict, target,"ptpengine:require_utc_offset_valid", &rtOpts->requireUtcValid, rtOpts->requireUtcValid,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:require_utc_offset_valid",
+ PTPD_RESTART_NONE, &rtOpts->requireUtcValid, rtOpts->requireUtcValid,
"Compatibility option: when enabled, ptpd2 will ignore\n"
" Announce messages from masters announcing currentUtcOffsetValid\n"
" as FALSE.\n"
" NOTE: this behaviour is not part of the standard.");
/* from 30 seconds to 7 days */
- parseResult &= configMapInt(dict, target, "ptpengine:unicast_grant_duration", INTTYPE_U32, &rtOpts->unicastGrantDuration, rtOpts->unicastGrantDuration,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:unicast_grant_duration",
+ PTPD_RESTART_PROTOCOL, INTTYPE_U32, &rtOpts->unicastGrantDuration, rtOpts->unicastGrantDuration,
"Time (seconds) unicast messages are requested for by slaves\n"
" when using unicast negotiation, and maximum time unicast message\n"
" transmission is granted to slaves by masters\n", RANGECHECK_RANGE, 30, 604800);
- parseResult &= configMapInt(dict, target, "ptpengine:log_announce_interval", INTTYPE_I8, &rtOpts->logAnnounceInterval,rtOpts->logAnnounceInterval,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:log_announce_interval", PTPD_UPDATE_DATASETS, INTTYPE_I8, &rtOpts->logAnnounceInterval, rtOpts->logAnnounceInterval,
"PTP announce message interval in master state. When using unicast negotiation, for\n"
" slaves this is the minimum interval requested, and for masters\n"
" this is the only interval granted.\n"
@@ -976,7 +1107,7 @@
" "LOG2_HELP,RANGECHECK_RANGE,-4,7);
#endif
- parseResult &= configMapInt(dict, target, "ptpengine:log_announce_interval_max",INTTYPE_I8,&rtOpts->logMaxAnnounceInterval,rtOpts->logMaxAnnounceInterval,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:log_announce_interval_max", PTPD_UPDATE_DATASETS, INTTYPE_I8, &rtOpts->logMaxAnnounceInterval, rtOpts->logMaxAnnounceInterval,
"Maximum Announce message interval requested by slaves "
"when using unicast negotiation,\n"
#ifdef PTPD_EXPERIMENTAL
@@ -988,10 +1119,11 @@
CONFIG_CONDITIONAL_ASSERTION(rtOpts->logAnnounceInterval >= rtOpts->logMaxAnnounceInterval,
"ptpengine:log_announce_interval value must be lower than ptpengine:log_announce_interval_max\n");
- parseResult &= configMapInt(dict, target, "ptpengine:announce_receipt_timeout",INTTYPE_I8, &rtOpts->announceReceiptTimeout,rtOpts->announceReceiptTimeout,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:announce_receipt_timeout", PTPD_UPDATE_DATASETS, INTTYPE_I8, &rtOpts->announceReceiptTimeout, rtOpts->announceReceiptTimeout,
"PTP announce receipt timeout announced in master state.",RANGECHECK_RANGE,2,255);
- parseResult &= configMapInt(dict, target, "ptpengine:announce_receipt_grace_period",INTTYPE_INT,&rtOpts->announceTimeoutGracePeriod,rtOpts->announceTimeoutGracePeriod,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:announce_receipt_grace_period",
+ PTPD_RESTART_NONE, INTTYPE_INT, &rtOpts->announceTimeoutGracePeriod, rtOpts->announceTimeoutGracePeriod,
"PTP announce receipt timeout grace period in slave state:\n"
" when announce receipt timeout occurs, disqualify current best GM,\n"
" then wait n times announce receipt timeout before resetting.\n"
@@ -999,7 +1131,7 @@
" to react. When set to 0, this option is not used.", RANGECHECK_RANGE,
0,20);
- parseResult &= configMapInt(dict, target, "ptpengine:log_sync_interval",INTTYPE_I8,&rtOpts->logSyncInterval,rtOpts->logSyncInterval,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:log_sync_interval", PTPD_UPDATE_DATASETS, INTTYPE_I8, &rtOpts->logSyncInterval, rtOpts->logSyncInterval,
"PTP sync message interval in master state. When using unicast negotiation, for\n"
" slaves this is the minimum interval requested, and for masters\n"
" this is the only interval granted.\n"
@@ -1009,7 +1141,7 @@
" "LOG2_HELP,RANGECHECK_RANGE,-7,7);
#endif
- parseResult &= configMapInt(dict, target, "ptpengine:log_sync_interval_max",INTTYPE_I8,&rtOpts->logMaxSyncInterval,rtOpts->logMaxSyncInterval,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:log_sync_interval_max", PTPD_UPDATE_DATASETS, INTTYPE_I8, &rtOpts->logMaxSyncInterval, rtOpts->logMaxSyncInterval,
"Maximum Sync message interval requested by slaves "
"when using unicast negotiation,\n"
#ifdef PTPD_EXPERIMENTAL
@@ -1021,17 +1153,18 @@
CONFIG_CONDITIONAL_ASSERTION(rtOpts->logSyncInterval >= rtOpts->logMaxSyncInterval,
"ptpengine:log_sync_interval value must be lower than ptpengine:log_sync_interval_max\n");
- parseResult &= configMapBoolean(dict, target,"ptpengine:log_delayreq_override", &rtOpts->ignore_delayreq_interval_master,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:log_delayreq_override", PTPD_UPDATE_DATASETS, &rtOpts->ignore_delayreq_interval_master,
rtOpts->ignore_delayreq_interval_master,
"Override the Delay Request interval announced by best master.");
- parseResult &= configMapBoolean(dict, target,"ptpengine:log_delayreq_auto", &rtOpts->autoDelayReqInterval,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:log_delayreq_auto", PTPD_UPDATE_DATASETS, &rtOpts->autoDelayReqInterval,
rtOpts->autoDelayReqInterval,
"Automatically override the Delay Request interval\n"
" if the announced value is 127 (0X7F), such as in\n"
" unicast messages (unless using unicast negotiation)");
- parseResult &= configMapInt(dict, target, "ptpengine:log_delayreq_interval_initial",INTTYPE_I8,&rtOpts->initial_delayreq,rtOpts->initial_delayreq,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:log_delayreq_interval_initial",
+ PTPD_RESTART_NONE, INTTYPE_I8, &rtOpts->initial_delayreq, rtOpts->initial_delayreq,
"Delay request interval used before receiving first delay response\n"
#ifdef PTPD_EXPERIMENTAL
" "LOG2_HELP,RANGECHECK_RANGE,-30,30);
@@ -1040,7 +1173,7 @@
#endif
/* take the delayreq_interval from config, otherwise use the initial setting as default */
- parseResult &= configMapInt(dict, target, "ptpengine:log_delayreq_interval",INTTYPE_I8,&rtOpts->logMinDelayReqInterval,rtOpts->initial_delayreq,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:log_delayreq_interval", PTPD_UPDATE_DATASETS, INTTYPE_I8, &rtOpts->logMinDelayReqInterval, rtOpts->initial_delayreq,
"Minimum delay request interval announced when in master state,\n"
" in slave state overrides the master interval,\n"
" required in hybrid mode. When using unicast negotiation, for\n"
@@ -1052,7 +1185,7 @@
" "LOG2_HELP,RANGECHECK_RANGE,-7,7);
#endif
- parseResult &= configMapInt(dict, target, "ptpengine:log_delayreq_interval_max",INTTYPE_I8,&rtOpts->logMaxDelayReqInterval,rtOpts->logMaxDelayReqInterval,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:log_delayreq_interval_max", PTPD_UPDATE_DATASETS, INTTYPE_I8, &rtOpts->logMaxDelayReqInterval, rtOpts->logMaxDelayReqInterval,
"Maximum Delay Response interval requested by slaves "
"when using unicast negotiation,\n"
#ifdef PTPD_EXPERIMENTAL
@@ -1064,7 +1197,8 @@
CONFIG_CONDITIONAL_ASSERTION(rtOpts->logMinDelayReqInterval >= rtOpts->logMaxDelayReqInterval,
"ptpengine:log_delayreq_interval value must be lower than ptpengine:log_delayreq_interval_max\n");
- parseResult &= configMapInt(dict, target, "ptpengine:log_peer_delayreq_interval",INTTYPE_I8,&rtOpts->logMinPdelayReqInterval,rtOpts->logMinPdelayReqInterval,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:log_peer_delayreq_interval",
+ PTPD_RESTART_NONE, INTTYPE_I8, &rtOpts->logMinPdelayReqInterval, rtOpts->logMinPdelayReqInterval,
"Minimum peer delay request message interval in peer to peer delay mode.\n"
" When using unicast negotiation, this is the minimum interval requested, \n"
" and the only interval granted.\n"
@@ -1074,7 +1208,8 @@
" "LOG2_HELP,RANGECHECK_RANGE,-7,7);
#endif
- parseResult &= configMapInt(dict, target, "ptpengine:log_peer_delayreq_interval_max",INTTYPE_I8,&rtOpts->logMaxPdelayReqInterval,rtOpts->logMaxPdelayReqInterval,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:log_peer_delayreq_interval_max",
+ PTPD_RESTART_NONE, INTTYPE_I8, &rtOpts->logMaxPdelayReqInterval, rtOpts->logMaxPdelayReqInterval,
"Maximum Peer Delay Response interval requested by slaves "
"when using unicast negotiation,\n"
#ifdef PTPD_EXPERIMENTAL
@@ -1086,13 +1221,14 @@
CONFIG_CONDITIONAL_ASSERTION(rtOpts->logMinPdelayReqInterval >= rtOpts->logMaxPdelayReqInterval,
"ptpengine:log_peer_delayreq_interval value must be lower than ptpengine:log_peer_delayreq_interval_max\n");
- parseResult &= configMapInt(dict, target, "ptpengine:foreignrecord_capacity",INTTYPE_I16,&rtOpts->max_foreign_records,rtOpts->max_foreign_records,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:foreignrecord_capacity",
+ PTPD_RESTART_DAEMON, INTTYPE_I16, &rtOpts->max_foreign_records, rtOpts->max_foreign_records,
"Foreign master record size (Maximum number of foreign masters).",RANGECHECK_RANGE,5,10);
- parseResult &= configMapInt(dict, target, "ptpengine:ptp_allan_variance",INTTYPE_U16,&rtOpts->clockQuality.offsetScaledLogVariance,rtOpts->clockQuality.offsetScaledLogVariance,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:ptp_allan_variance", PTPD_UPDATE_DATASETS, INTTYPE_U16, &rtOpts->clockQuality.offsetScaledLogVariance, rtOpts->clockQuality.offsetScaledLogVariance,
"Specify Allan variance announced in master state.",RANGECHECK_RANGE,0,65535);
- parseResult &= configMapSelectValue(dict, target, "ptpengine:ptp_clock_accuracy", &rtOpts->clockQuality.clockAccuracy,rtOpts->clockQuality.clockAccuracy,
+ parseResult &= configMapSelectValue(opCode, opArg, dict, target, "ptpengine:ptp_clock_accuracy", PTPD_UPDATE_DATASETS, &rtOpts->clockQuality.clockAccuracy, rtOpts->clockQuality.clockAccuracy,
"Clock accuracy range announced in master state.",
"ACC_25NS", 0x20,
"ACC_100NS", 0x21,
@@ -1115,22 +1251,22 @@
"ACC_UNKNOWN", 0xFE, NULL
);
- parseResult &= configMapInt(dict, target, "ptpengine:utc_offset",INTTYPE_I16,&rtOpts->timeProperties.currentUtcOffset,rtOpts->timeProperties.currentUtcOffset,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:utc_offset", PTPD_UPDATE_DATASETS, INTTYPE_I16, &rtOpts->timeProperties.currentUtcOffset, rtOpts->timeProperties.currentUtcOffset,
"Underlying time source UTC offset announced in master state.", RANGECHECK_NONE,0,0);
- parseResult &= configMapBoolean(dict, target,"ptpengine:utc_offset_valid", &rtOpts->timeProperties.currentUtcOffsetValid,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:utc_offset_valid", PTPD_UPDATE_DATASETS, &rtOpts->timeProperties.currentUtcOffsetValid,
rtOpts->timeProperties.currentUtcOffsetValid,
"Underlying time source UTC offset validity announced in master state.");
- parseResult &= configMapBoolean(dict, target,"ptpengine:time_traceable", &rtOpts->timeProperties.timeTraceable,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:time_traceable", PTPD_UPDATE_DATASETS, &rtOpts->timeProperties.timeTraceable,
rtOpts->timeProperties.timeTraceable,
"Underlying time source time traceability announced in master state.");
- parseResult &= configMapBoolean(dict, target,"ptpengine:frequency_traceable", &rtOpts->timeProperties.frequencyTraceable,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:frequency_traceable", PTPD_UPDATE_DATASETS, &rtOpts->timeProperties.frequencyTraceable,
rtOpts->timeProperties.frequencyTraceable,
"Underlying time source frequency traceability announced in master state.");
- parseResult &= configMapSelectValue(dict, target, "ptpengine:ptp_timescale", (uint8_t*)&rtOpts->timeProperties.ptpTimescale,rtOpts->timeProperties.ptpTimescale,
+ parseResult &= configMapSelectValue(opCode, opArg, dict, target, "ptpengine:ptp_timescale", PTPD_UPDATE_DATASETS, (uint8_t*)&rtOpts->timeProperties.ptpTimescale, rtOpts->timeProperties.ptpTimescale,
"Time scale announced in master state (with ARB, UTC properties\n"
" are ignored by slaves). When clock class is set to 13 (application\n"
" specific), this value is ignored and ARB is used.",
@@ -1138,7 +1274,7 @@
"ARB", FALSE, NULL
);
- parseResult &= configMapSelectValue(dict, target, "ptpengine:ptp_timesource", &rtOpts->timeProperties.timeSource,rtOpts->timeProperties.timeSource,
+ parseResult &= configMapSelectValue(opCode, opArg, dict, target, "ptpengine:ptp_timesource", PTPD_UPDATE_DATASETS, &rtOpts->timeProperties.timeSource, rtOpts->timeProperties.timeSource,
"Time source announced in master state.",
"ATOMIC_CLOCK", ATOMIC_CLOCK,
"GPS", GPS,
@@ -1150,7 +1286,7 @@
"INTERNAL_OSCILLATOR", INTERNAL_OSCILLATOR, NULL
);
- parseResult &= configMapInt(dict, target, "ptpengine:clock_class",INTTYPE_U8,&rtOpts->clockQuality.clockClass,ptpPreset.clockClass.defaultValue,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:clock_class", PTPD_UPDATE_DATASETS, INTTYPE_U8, &rtOpts->clockQuality.clockClass,ptpPreset.clockClass.defaultValue,
"Clock class - announced in master state. Always 255 for slave-only.\n"
" Minimum, maximum and default values are controlled by presets.\n"
" If set to 13 (application specific time source), announced \n"
@@ -1162,34 +1298,35 @@
/* ClockClass = 13 triggers ARB */
CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->clockQuality.clockClass==DEFAULT_CLOCK_CLASS__APPLICATION_SPECIFIC_TIME_SOURCE,
- rtOpts->timeProperties.ptpTimescale,FALSE,rtOpts->timeProperties.ptpTimescale);
+ rtOpts->timeProperties.ptpTimescale,FALSE, rtOpts->timeProperties.ptpTimescale);
/* ClockClass = 14 triggers ARB */
CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->clockQuality.clockClass==14,
- rtOpts->timeProperties.ptpTimescale,FALSE,rtOpts->timeProperties.ptpTimescale);
+ rtOpts->timeProperties.ptpTimescale,FALSE, rtOpts->timeProperties.ptpTimescale);
/* ClockClass = 6 triggers PTP*/
CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->clockQuality.clockClass==6,
- rtOpts->timeProperties.ptpTimescale,TRUE,rtOpts->timeProperties.ptpTimescale);
+ rtOpts->timeProperties.ptpTimescale,TRUE, rtOpts->timeProperties.ptpTimescale);
/* ClockClass = 7 triggers PTP*/
CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->clockQuality.clockClass==7,
- rtOpts->timeProperties.ptpTimescale,TRUE,rtOpts->timeProperties.ptpTimescale);
+ rtOpts->timeProperties.ptpTimescale,TRUE, rtOpts->timeProperties.ptpTimescale);
/* ClockClass = 255 triggers slaveOnly */
- CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->clockQuality.clockClass==SLAVE_ONLY_CLOCK_CLASS,rtOpts->slaveOnly,TRUE,FALSE);
+ CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->clockQuality.clockClass==SLAVE_ONLY_CLOCK_CLASS, rtOpts->slaveOnly,TRUE,FALSE);
/* ...and vice versa */
- CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->slaveOnly==TRUE,rtOpts->clockQuality.clockClass,SLAVE_ONLY_CLOCK_CLASS,rtOpts->clockQuality.clockClass);
+ CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->slaveOnly==TRUE, rtOpts->clockQuality.clockClass,SLAVE_ONLY_CLOCK_CLASS, rtOpts->clockQuality.clockClass);
- parseResult &= configMapInt(dict, target, "ptpengine:priority1",INTTYPE_U8,&rtOpts->priority1,rtOpts->priority1,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:priority1", PTPD_UPDATE_DATASETS, INTTYPE_U8, &rtOpts->priority1, rtOpts->priority1,
"Priority 1 announced in master state,used for Best Master\n"
" Clock selection.",RANGECHECK_RANGE,0,248);
- parseResult &= configMapInt(dict, target, "ptpengine:priority2",INTTYPE_U8,&rtOpts->priority2,rtOpts->priority2,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:priority2", PTPD_UPDATE_DATASETS, INTTYPE_U8, &rtOpts->priority2, rtOpts->priority2,
"Priority 2 announced in master state, used for Best Master\n"
" Clock selection.",RANGECHECK_RANGE,0,248);
- parseResult &= configMapInt(dict, target, "ptpengine:max_listen",INTTYPE_INT,&rtOpts->maxListen,rtOpts->maxListen,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:max_listen",
+ PTPD_RESTART_NONE, INTTYPE_INT, &rtOpts->maxListen, rtOpts->maxListen,
"Number of consecutive resets to LISTENING before full network reset\n",RANGECHECK_MIN,1,0);
/*
@@ -1210,6 +1347,8 @@
"It is recommended to set the delay request interval (ptpengine:log_delayreq_interval) in unicast mode"
);
+
+
CONFIG_KEY_ALIAS("ptpengine:unicast_address","ptpengine:unicast_destinations");
/* unicast signaling slave -> must specify unicast destination(s) */
@@ -1228,22 +1367,25 @@
"unicast",
"ptpengine:unicast_destinations");
- CONFIG_KEY_TRIGGER("ptpengine:unicast_destinations",rtOpts->unicastDestinationsSet,TRUE,rtOpts->unicastDestinationsSet);
+ CONFIG_KEY_TRIGGER("ptpengine:unicast_destinations", rtOpts->unicastDestinationsSet,TRUE, rtOpts->unicastDestinationsSet);
- parseResult &= configMapString(dict, target, "ptpengine:unicast_destinations",rtOpts->unicastDestinations,rtOpts->unicastDestinations,
+ parseResult &= configMapString(opCode, opArg, dict, target, "ptpengine:unicast_destinations",
+ PTPD_RESTART_NETWORK, rtOpts->unicastDestinations, sizeof(rtOpts->unicastDestinations), rtOpts->unicastDestinations,
"Specify unicast slave addresses for unicast master operation, or unicast\n"
" master addresses for slave operation. Format is similar to an ACL: comma,\n"
" tab or space-separated IPv4 unicast addresses, one or more. For a slave,\n"
" when unicast negotiation is used, setting this is mandatory.");
- parseResult &= configMapString(dict, target, "ptpengine:unicast_domains",rtOpts->unicastDomains,rtOpts->unicastDomains,
+ parseResult &= configMapString(opCode, opArg, dict, target, "ptpengine:unicast_domains",
+ PTPD_RESTART_NETWORK, rtOpts->unicastDomains, sizeof(rtOpts->unicastDomains), rtOpts->unicastDomains,
"Specify PTP domain number for each configured unicast destination (ptpengine:unicast_destinations).\n"
" This is only used by slave-only clocks using unicast destinations to allow for each master\n"
" to be in a separate domain, such as with Telecom Profile. The number of entries should match the number\n"
" of unicast destinations, otherwise unconfigured domains or domains set to 0 are set to domain configured in\n"
" ptpengine:domain. The format is a comma, tab or space-separated list of 8-bit unsigned integers (0 .. 255)");
- parseResult &= configMapString(dict, target, "ptpengine:unicast_local_preference",rtOpts->unicastLocalPreference,rtOpts->unicastLocalPreference,
+ parseResult &= configMapString(opCode, opArg, dict, target, "ptpengine:unicast_local_preference",
+ PTPD_RESTART_NETWORK, rtOpts->unicastLocalPreference, sizeof(rtOpts->unicastLocalPreference), rtOpts->unicastLocalPreference,
"Specify a local preference for each configured unicast destination (ptpengine:unicast_destinations).\n"
" This is only used by slave-only clocks using unicast destinations to allow for each master's\n"
" BMC selection to be influenced by the slave, such as with Telecom Profile. The number of entries should match the number\n"
@@ -1257,41 +1399,50 @@
"P2P",
"ptpengine:unicast_peer_destination");
- CONFIG_KEY_TRIGGER("ptpengine:unicast_peer_destination",rtOpts->unicastPeerDestinationSet,TRUE,rtOpts->unicastPeerDestinationSet);
+ CONFIG_KEY_TRIGGER("ptpengine:unicast_peer_destination", rtOpts->unicastPeerDestinationSet,TRUE, rtOpts->unicastPeerDestinationSet);
- parseResult &= configMapString(dict, target, "ptpengine:unicast_peer_destination",rtOpts->unicastPeerDestination,rtOpts->unicastPeerDestination,
+ parseResult &= configMapString(opCode, opArg, dict, target, "ptpengine:unicast_peer_destination",
+ PTPD_RESTART_NETWORK, rtOpts->unicastPeerDestination, sizeof(rtOpts->unicastPeerDestination), rtOpts->unicastPeerDestination,
"Specify peer unicast adress for P2P unicast. Mandatory when\n"
" running unicast mode and P2P delay mode.");
- parseResult &= configMapBoolean(dict, target,"ptpengine:management_enable", &rtOpts->managementEnabled,rtOpts->managementEnabled,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:management_enable",
+ PTPD_RESTART_NONE, &rtOpts->managementEnabled, rtOpts->managementEnabled,
"Enable handling of PTP management messages.");
- parseResult &= configMapBoolean(dict, target,"ptpengine:management_set_enable", &rtOpts->managementSetEnable,rtOpts->managementSetEnable,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:management_set_enable",
+ PTPD_RESTART_NONE, &rtOpts->managementSetEnable, rtOpts->managementSetEnable,
"Accept SET and COMMAND management messages.");
- parseResult &= configMapBoolean(dict, target,"ptpengine:igmp_refresh", &rtOpts->do_IGMP_refresh,rtOpts->do_IGMP_refresh,
+ parseResult &= configMapBoolean(opCode, opArg, dict, target, "ptpengine:igmp_refresh",
+ PTPD_RESTART_NONE, &rtOpts->do_IGMP_refresh, rtOpts->do_IGMP_refresh,
"Send explicit IGMP joins between engine resets and periodically\n"
" in master state.");
- parseResult &= configMapInt(dict, target, "ptpengine:master_igmp_refresh_interval",INTTYPE_I8,&rtOpts->masterRefreshInterval,rtOpts->masterRefreshInterval,
+ parseResult &= configMapInt(opCode, opArg, dict, target, "ptpengine:master_igmp_refresh_interval",
+ PTPD_RESTART_PROTOCOL, INTTYPE_I8, &rtOpts->masterRefreshInterval, rtOpts->masterRefreshInterval,
"Periodic IGMP join interval (seconds) in master state when running\n"
" IPv4 multicast: when set below 10 or when ptpengine:igmp_refresh\n"
" is disabled, th...
[truncated message content] |
|
From: <wow...@us...> - 2015-10-21 01:28:51
|
Revision: 598
http://sourceforge.net/p/ptpd/code/598
Author: wowczarek
Date: 2015-10-21 01:28:49 +0000 (Wed, 21 Oct 2015)
Log Message:
-----------
- fixed missing assignment from configMapSelectValue()
Modified Paths:
--------------
trunk/src/dep/daemonconfig.c
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-10-21 00:59:21 UTC (rev 597)
+++ trunk/src/dep/daemonconfig.c 2015-10-21 01:28:49 UTC (rev 598)
@@ -549,7 +549,7 @@
}
static int
-configMapSelectValue(dictionary *dict, dictionary *target, const char* key, uint8_t *input, int def, const char *helptext, ...)
+configMapSelectValue(dictionary *dict, dictionary *target, const char* key, uint8_t *var, int def, const char *helptext, ...)
{
int ret;
@@ -614,7 +614,7 @@
ERROR("Configuration error: option \"%s\" has unknown value: %s - allowed values: %s\n", key, keyValue, sbuf);
ret = 0;
} else {
-
+ *var = (uint8_t)selectedValue;
if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
printComment(helptext);
printf("; Options: %s\n", sbuf);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-21 00:59:25
|
Revision: 597
http://sourceforge.net/p/ptpd/code/597
Author: wowczarek
Date: 2015-10-21 00:59:21 +0000 (Wed, 21 Oct 2015)
Log Message:
-----------
- removed masterAddr in favour of bestMaster->sourceAddr
- reworked all config option mapping macros to functions,
some macros still left
Modified Paths:
--------------
trunk/TODO
trunk/src/bmc.c
trunk/src/datatypes.h
trunk/src/dep/daemonconfig.c
trunk/src/dep/daemonconfig.h
trunk/src/dep/snmp.c
trunk/src/dep/statistics.c
trunk/src/dep/statistics.h
trunk/src/dep/sys.c
trunk/src/protocol.c
trunk/src/ptpd.h
Modified: trunk/TODO
===================================================================
--- trunk/TODO 2015-10-19 23:57:56 UTC (rev 596)
+++ trunk/TODO 2015-10-21 00:59:21 UTC (rev 597)
@@ -9,11 +9,12 @@
- add dummy or populated default template file x
- 16.1.1: may be granted in listening state or passive state <- but g.8265 is no BMCA x
- sig/msg message acceptance 4 options: all1,port, clockid,port, clock,all1, all1,all1 x
-- rework config option parsing
+- rework config option parsing x
+- rework parseConfig to support an opcode, get rid of remaining macros
- SET messages to refresh the config properly
- NVRAM write?
- pointer to best master x
- disqualification flag x
-- remove masteraddr in favour of bestMaster->sourceAddr
+- remove masteraddr in favour of bestMaster->sourceAddr x
- use split token loop
-- use pointer to best master
+- use pointer to best master x
Modified: trunk/src/bmc.c
===================================================================
--- trunk/src/bmc.c 2015-10-19 23:57:56 UTC (rev 596)
+++ trunk/src/bmc.c 2015-10-21 00:59:21 UTC (rev 597)
@@ -637,8 +637,6 @@
}
if (newBM) {
- ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
-
displayPortIdentity(&foreign->header.sourcePortIdentity,
"New best master selected:");
ptpClock->counters.masterChanges++;
@@ -673,7 +671,6 @@
} else if (comp > 0) {
s1(&foreign->header, &foreign->announce, ptpClock, rtOpts);
if (newBM) {
- ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
displayPortIdentity(&foreign->header.sourcePortIdentity,
"New best master selected:");
ptpClock->counters.masterChanges++;
@@ -695,7 +692,6 @@
"New best master selected:");
ptpClock->counters.masterChanges++;
if(ptpClock->portState == PTP_SLAVE)
- ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
displayStatus(ptpClock, "State: ");
if(rtOpts->calibrationDelay) {
ptpClock->isCalibrated = FALSE;
@@ -741,12 +737,3 @@
return (bmcStateDecision(ptpClock->bestMaster,
rtOpts,ptpClock));
}
-
-/* retrieve curent best master */
-ForeignMasterRecord
-*getBestMaster(PtpClock *ptpClock) {
-
- return(&(ptpClock->foreign[ptpClock->foreign_record_best]));
-
-}
-
Modified: trunk/src/datatypes.h
===================================================================
--- trunk/src/datatypes.h 2015-10-19 23:57:56 UTC (rev 596)
+++ trunk/src/datatypes.h 2015-10-21 00:59:21 UTC (rev 597)
@@ -903,7 +903,6 @@
/* user description is max size + 1 to leave space for a null terminator */
Octet user_description[USER_DESCRIPTION_MAX + 1];
- Integer32 masterAddr; // used for hybrid mode, when receiving announces
Integer32 LastSlaveAddr; // used for hybrid mode, when receiving delayreqs
Integer32 lastSyncDst; /* captures the destination address for last sync, so we know where to send the followUp */
Integer32 lastPdelayRespDst; /* captures the destination address of last pdelayResp so we know where to send the pdelayRespfollowUp */
@@ -1070,15 +1069,15 @@
LogFileHandler statusLog;
int leapSecondPausePeriod;
- int leapSecondHandling;
+ Enumeration8 leapSecondHandling;
Integer32 leapSecondSmearPeriod;
int leapSecondNoticePeriod;
Boolean periodicUpdates;
Boolean logStatistics;
- int statisticsTimestamp;
+ Enumeration8 statisticsTimestamp;
- int logLevel;
+ Enumeration8 logLevel;
int statisticsLogInterval;
int statusFileUpdateInterval;
@@ -1099,7 +1098,7 @@
char lockFile[PATH_MAX]; /* lock file location */
char driftFile[PATH_MAX]; /* drift file location */
char leapFile[PATH_MAX]; /* leap seconds file location */
- int drift_recovery_method; /* how the observed drift is managed
+ Enumeration8 drift_recovery_method; /* how the observed drift is managed
between restarts */
LeapSecondInfo leapInfo;
@@ -1109,8 +1108,8 @@
Boolean pcap; /* Receive and send packets using libpcap, bypassing the
network stack. */
- int transport; /* transport type */
- int ipMode; /* IP transmission mode */
+ Enumeration8 transport; /* transport type */
+ Enumeration8 ipMode; /* IP transmission mode */
Boolean dot2AS; /* 801.2AS support -> transportSpecific field */
Boolean disableUdpChecksums; /* disable UDP checksum validation where supported */
@@ -1152,12 +1151,12 @@
/* config dictionary containers - current, candidate and from CLI*/
dictionary *currentConfig, *candidateConfig, *cliConfig;
- int selectedPreset;
+ Enumeration8 selectedPreset;
int servoMaxPpb;
double servoKP;
double servoKI;
- int servoDtMethod;
+ Enumeration8 servoDtMethod;
double servoMaxdT;
/**
@@ -1221,8 +1220,8 @@
char timingAclDenyText[PATH_MAX];
char managementAclPermitText[PATH_MAX];
char managementAclDenyText[PATH_MAX];
- int timingAclOrder;
- int managementAclOrder;
+ Enumeration8 timingAclOrder;
+ Enumeration8 managementAclOrder;
} RunTimeOpts;
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-10-19 23:57:56 UTC (rev 596)
+++ trunk/src/dep/daemonconfig.c 2015-10-21 00:59:21 UTC (rev 597)
@@ -39,33 +39,6 @@
#include "../ptpd.h"
-/* -
- * Variadic macro argument count trick -> comp.std.c __VA_NARG__
- * Laurent Deniau et al, January 2006. Works from 1 argument up,
- * but in this code you will always have at least 2.
- */
-
-#define NUMARGS(...) \
- PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
-#define PP_NARG_(...) \
- PP_ARG_N(__VA_ARGS__)
-#define PP_ARG_N( \
- _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
- _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
- _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
- _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
- _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
- _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
- _61,_62,_63,N,...) N
-#define PP_RSEQ_N() \
- 63,62,61,60, \
- 59,58,57,56,55,54,53,52,51,50, \
- 49,48,47,46,45,44,43,42,41,40, \
- 39,38,37,36,35,34,33,32,31,30, \
- 29,28,27,26,25,24,23,22,21,20, \
- 19,18,17,16,15,14,13,12,11,10, \
- 9,8,7,6,5,4,3,2,1,0
-
/*-
* Helper macros - this is effectively the API for using the new config file interface.
* The macros below cover all operations required in parsing the configuration.
@@ -75,7 +48,6 @@
* within parseConfig - they assume the existence of the "dictionary*" dict variable.
*/
-
/* Basic helper macros */
#define STRING_EMPTY(string)\
@@ -251,363 +223,6 @@
parseResult = FALSE;\
}
-/* Range check macros */
-
-/* surrounded with {}s to limit the scope of the temporary variable */
-#define CONFIG_KEY_RANGECHECK_INT(key,min,max) \
- {\
- int tmpint = iniparser_getint(dict,key,min);\
- if (tmpint < min || tmpint > max) { \
- if(!IS_QUIET())\
- ERROR("Configuration error: option \"%s=%d\" not within allowed range: %d..%d\n", key, tmpint, min, max); \
- parseResult = FALSE;\
- }\
- }
-
-/* surrounded with {}s to limit the scope of the temporary variable */
-#define CONFIG_KEY_MIN_INT(key,min) \
- {\
- int tmpint = iniparser_getint(dict,key,min);\
- if (tmpint < min) { \
- if(!IS_QUIET())\
- ERROR("Configuration error: option \"%s=%d\" should be equal or greater than %d\n", key, tmpint, min); \
- parseResult = FALSE;\
- }\
- }
-
-/* surrounded with {}s to limit the scope of the temporary variable */
-#define CONFIG_KEY_MAX_INT(key,max) \
- {\
- int tmpint = iniparser_getint(dict,key,max);\
- if (tmpint > max) { \
- if(!IS_QUIET())\
- ERROR("Configuration error: option \"%s=%d\" should be equal or less than %d\n", key, tmpint, max); \
- parseResult = FALSE;\
- }\
- }
-
-/* surrounded with {}s to limit the scope of the temporary variable */
-#define CONFIG_KEY_RANGECHECK_DOUBLE(key,min,max) \
- {\
- double tmpdouble = iniparser_getdouble(dict,key,min);\
- if (tmpdouble < min || tmpdouble > max) { \
- if(!IS_QUIET())\
- ERROR("Configuration error: option \"%s=%f\" not within allowed range: %f..%f\n", key, tmpdouble, min, max); \
- parseResult = FALSE;\
- }\
- }
-
-/* surrounded with {}s to limit the scope of the temporary variable */
-#define CONFIG_KEY_MIN_DOUBLE(key,min) \
- {\
- double tmpdouble = iniparser_getdouble(dict,key,min);\
- if (tmpdouble < min) { \
- if(!IS_QUIET())\
- ERROR("Configuration error: option \"%s=%f\" should be equal or greater than %f\n", key, tmpdouble, min); \
- parseResult = FALSE;\
- }\
- }
-
-/* surrounded with {}s to limit the scope of the temporary variable */
-#define CONFIG_KEY_MAX_DOUBLE(key,max) \
- {\
- double tmpdouble = iniparser_getdouble(dict,key,max);\
- if (tmpdouble > max) { \
- if(!IS_QUIET())\
- ERROR("Configuration error: option \"%s=%f\" should be equal or less than %f\n", key, tmpdouble, max); \
- parseResult = FALSE;\
- }\
- }
-
-/*
- * Config mapping macros - effectively functions turned into macros. Because of
- * the use of varargs and argument counting, it made sense to make at least some
- * of them macros. To make parseConfig more consistent, all the mapping is done
- * via macros. Moving to functions would require handling the return values for
- * range checks, so again different calls for different mappings. With macros,
- * parseResult is set where needed. There may be a better way of doing this
- * (macros generate a huge amount of code), but this makes parseConfig very
- * simple
- */
-
-#define CONFIG_MAP_STRING(key,variable,default,helptext) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: STRING\n");\
- printf(" usage: %s\n", helptext);\
- printf("default: %s\n", (strcmp(default, "") == 0) ? "[none]" : default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {\
- variable = iniparser_getstring(dict,key,default);\
- dictionary_set(target, key, variable);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n\n", key,variable);\
- }\
- }
-
-/* double {}s to limit the scope of the temporary variable */
-#define CONFIG_MAP_CHARARRAY(key,variable,default,helptext) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: STRING\n");\
- printf(" usage: %s\n", helptext);\
- printf("default: %s\n", (strcmp(default, "") == 0) ? "[none]" : default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {{\
- char *tmpstring = iniparser_getstring(dict,key,default); \
- if (variable!=tmpstring) strncpy(variable,tmpstring,sizeof(variable) / sizeof(char));\
- dictionary_set(target, key, tmpstring);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,tmpstring);\
- }\
- }}
-
-#define CONFIG_MAP_BOOLEAN(key,variable,default,helptext) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: BOOLEAN (value must start with t/T/y/Y/1/f/F/n/N/0)\n");\
- printf(" usage: %s\n", helptext);\
- printf("default: %s\n", default ? "Y" : "N");\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {\
- if (!CONFIG_ISPRESENT(key)) {\
- variable = default;\
- dictionary_set(target,key,(variable)?"Y":"N");\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,(variable)?"Y":"N");\
- }\
- } else if(!CONFIG_ISSET(key) || iniparser_getboolean(dict,key,-1) == -1) {\
- ERROR("Configuration error: option \"%s='%s'\" has unknown boolean value: must start with 0/1/t/T/f/F/y/Y/n/N\n",key,iniparser_getstring(dict,key,""));\
- dictionary_set(target,key,""); /* suppress the "unknown entry" warning for malformed boolean values */ \
- parseResult = FALSE;\
- } else {\
- variable=iniparser_getboolean(dict,key,default);\
- dictionary_set(target,key,(variable)?"Y":"N");\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,(variable)?"Y":"N");\
- }\
- }\
- }
-
-#define CONFIG_MAP_INT(key,variable,default,helptext) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: INT\n");\
- printf(" usage: %s\n", helptext);\
- printf("default: %d\n", default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {{\
- variable = iniparser_getint(dict,key,default);\
- char buf[50];\
- memset(buf, 0, 50);\
- snprintf(buf, 50, "%d", variable);\
- dictionary_set(target,key,buf);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,buf);\
- }\
- }}
-
-#define CONFIG_MAP_INT_RANGE(key,variable,default,helptext,min,max) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: INT ");\
- if( min!=max )\
- printf("(min: %d, max: %d)\n", min, max);\
- else\
- printf("(only value of %d allowed)\n", min);\
- printf(" usage: %s\n", helptext);\
- printf("default: %d\n", default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {{\
- variable = iniparser_getint(dict,key,default);\
- CONFIG_KEY_RANGECHECK_INT(key,min,max);\
- char buf[50];\
- memset(buf, 0, 50);\
- snprintf(buf, 50, "%d", variable);\
- dictionary_set(target,key,buf);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,buf);\
- }\
- }}
-
-#define CONFIG_MAP_INT_MIN(key,variable,default,helptext,min) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: INT (min: %d)\n",min);\
- printf(" usage: %s\n", helptext);\
- printf("default: %d\n", default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {{\
- variable = iniparser_getint(dict,key,default);\
- CONFIG_KEY_MIN_INT(key,min);\
- char buf[50];\
- memset(buf, 0, 50);\
- snprintf(buf, 50, "%d", variable);\
- dictionary_set(target,key,buf);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,buf);\
- }\
- }}
-
-#define CONFIG_MAP_INT_MAX(key,variable,default,helptext,max) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: INT (max: %d)\n",max);\
- printf(" usage: %s\n", helptext);\
- printf("default: %d\n", default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {{\
- variable = iniparser_getint(dict,key,default);\
- CONFIG_KEY_MAX_INT(key,max);\
- char buf[50];\
- memset(buf, 0, 50);\
- snprintf(buf, 50, "%d", variable);\
- dictionary_set(target,key,buf);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,buf);\
- }\
- }}
-
-#define CONFIG_MAP_DOUBLE(key,variable,default,helptext) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: FLOAT\n");\
- printf(" usage: %s\n", helptext);\
- printf("default: %d\n", default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {{\
- variable = iniparser_getdouble(dict,key,default);\
- char buf[50];\
- memset(buf, 0, 50);\
- snprintf(buf, 50, "%f", variable);\
- dictionary_set(target,key,buf);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,buf);\
- }\
- }}
-
-#define CONFIG_MAP_DOUBLE_RANGE(key,variable,default,helptext,min,max) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: FLOAT ");\
- if( min!=max )\
- printf("(min: %f, max: %f)\n", min, max);\
- else\
- printf("(only value of %f allowed)", min);\
- printf("\n");\
- printf(" usage: %s\n", helptext);\
- printf("default: %f\n", default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {{\
- variable = iniparser_getdouble(dict,key,default);\
- CONFIG_KEY_RANGECHECK_DOUBLE(key,min,max);\
- char buf[50];\
- memset(buf, 0, 50);\
- snprintf(buf, 50, "%f", variable);\
- dictionary_set(target,key,buf);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,buf);\
- }\
- }}
-
-#define CONFIG_MAP_DOUBLE_MIN(key,variable,default,helptext,min) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: FLOAT(min: %f)\n", min);\
- printf(" usage: %s\n", helptext);\
- printf("default: %f\n", default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {{\
- variable = iniparser_getdouble(dict,key,default);\
- CONFIG_KEY_MIN_DOUBLE(key,min); \
- char buf[50];\
- memset(buf, 0, 50);\
- snprintf(buf, 50, "%f", variable);\
- dictionary_set(target,key,buf);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,buf);\
- }\
- }}
-
-#define CONFIG_MAP_DOUBLE_MAX(key,variable,default,helptext,max) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: FLOAT(max: %f)\n", max);\
- printf(" usage: %s\n", helptext);\
- printf("default: %f\n", default);\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {{\
- variable = iniparser_getdouble(dict,key,default);\
- CONFIG_KEY_MIN_DOUBLE(key,max);\
- char buf[50];\
- memset(buf, 0, 50);\
- snprintf(buf, 50, "%f", variable);\
- dictionary_set(target,key,buf);\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("%s = %s\n", key,buf);\
- }\
- }}
-
-#define CONFIG_MAP_SELECTVALUE(key,variable,default,helptext, ... ) \
- if(IS_HELP(key, helptext)) {\
- printf("setting: %s (--%s)\n", key, key);\
- printf(" type: SELECT\n");\
- printf(" usage: %s\n", helptext);\
- printf("options: ");\
- printKeyOptions (NUMARGS(__VA_ARGS__), __VA_ARGS__);\
- printf("\n");\
- printf("default: %s\n",\
- selectOptionName(default,NUMARGS(__VA_ARGS__),\
- __VA_ARGS__));\
- printf("\n");\
- HELP_ITEM_COMPLETE(); \
- } else {\
- int res;\
- if ( (res = selectKeyValue(\
- dict, key, default,NUMARGS(__VA_ARGS__),\
- __VA_ARGS__\
- )) == -1) {\
- variable = default;\
- parseResult = FALSE;\
- } else {\
- variable=res;\
- }\
- {\
- dictionary_set(target, key, selectOptionName(\
- variable,NUMARGS(__VA_ARGS__), __VA_ARGS__));\
- if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {\
- printComment(helptext);\
- printf("; Options: ");\
- printKeyOptions (NUMARGS(__VA_ARGS__), __VA_ARGS__);\
- printf("\n%s = %s\n", key,selectOptionName(\
- variable,NUMARGS(__VA_ARGS__), __VA_ARGS__));\
- }\
- }\
- }
-
/* Macro printing a warning for a deprecated command-line option */
#define WARN_DEPRECATED_COMMENT( old,new,long,key,comment )\
printf("Note: The use of '-%c' option is deprecated %s- consider using '-%c' (--%s) or the %s setting\n",\
@@ -640,164 +255,382 @@
}\
}
-/* concatenate every second vararg argument for string, int pairs and print it */
-static void
-printKeyOptions( int count, ... )
+/* Output a potentially multi-line string, prefixed with ;s */
+static void printComment(const char* helptext)
{
+ int i, len;
+ len = strlen(helptext);
+ if(len > 0)
+ printf("\n; ");
- char *optionvalue;
- va_list va;
- int i;
-
- /* if we got an incomplete argument list, cut it down to the last pair or nothing */
- if(count % 2 == 1) {
-
- count--;
-
+ for (i = 0; i < len; i++) {
+ printf("%c",helptext[i]);
+ if(helptext[i]=='\n') {
+ printf("; ");
+ while(i < len) {
+ if( helptext[++i]!=' ' && helptext[i]!='\t') {
+ i--;
+ break;
+ }
+ }
+ }
}
+ printf("\n");
- count/=2;
+}
- va_start(va, count);
-
- for(i = 0; i < count; i++) {
-
- optionvalue = (char *)va_arg(va, char *);
- (void)va_arg(va, int);
-
- printf("%s ", optionvalue);
-
- }
-
- va_end(va);
-
+static int
+configMapBoolean(dictionary* dict, dictionary *target, const char * key, Boolean *var, Boolean def, const char* helptext)
+{
+ if(IS_HELP(key, helptext)) {
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: BOOLEAN (value must start with t/T/y/Y/1/f/F/n/N/0)\n");
+ printf(" usage: %s\n", helptext);
+ printf("default: %s\n", def ? "Y" : "N");
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ return 1;
+ } else {
+ if (!CONFIG_ISPRESENT(key)) {
+ *var = def;
+ dictionary_set(target,key,(*var)?"Y":"N");
+ if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ printComment(helptext);
+ printf("%s = %s\n", key,(*var)?"Y":"N");
+ }
+ return 1;
+ } else if(!CONFIG_ISSET(key) || iniparser_getboolean(dict,key,-1) == -1) {
+ ERROR("Configuration error: option \"%s='%s'\" has unknown boolean value: must start with 0/1/t/T/f/F/y/Y/n/N\n",key,iniparser_getstring(dict,key,""));
+ dictionary_set(target,key,""); /* suppress the "unknown entry" warning for malformed boolean values */ \
+ return 0;
+ } else {
+ *var=iniparser_getboolean(dict,key,def);
+ dictionary_set(target,key,(*var)?"Y":"N");
+ if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ printComment(helptext);\
+ printf("%s = %s\n", key,(*var)?"Y":"N");
+ }
+ return 1;
+ }
+ }
}
-/* Return the number corresponding to a string from a number of string, int pairs */
static int
-selectKeyValue( dictionary* dict, const char* keyname, int default_option, int count, ... )
+configMapString(dictionary *dict, dictionary *target, const char *key, char *var, char *def, const char* helptext)
{
- char sbuf[SCREEN_BUFSZ];
- int len = 0;
- char *keyvalue, *optionvalue;
- va_list va;
- int ret, i, optionnumber;
+ if(IS_HELP(key, helptext)) {
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: STRING\n");
+ printf(" usage: %s\n", helptext);
+ printf("default: %s\n", (strcmp(def, "") == 0) ? "[none]" : def);
+ printf("\n");\
+ HELP_ITEM_COMPLETE();
+ return 1;
+ } else {
+ char *tmpstring = iniparser_getstring(dict,key,def);
+ if (strncmp(var, tmpstring, MAX_LINE_SIZE)) strncpy(var, tmpstring, sizeof(var) / sizeof(char));
+ dictionary_set(target, key, tmpstring);
+ if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ printComment(helptext);
+ printf("%s = %s\n", key,tmpstring);
+ }
+ return 1;
+ }
+}
- /* if we got an incomplete argument list, cut it down to the last pair or nothing */
- if(count % 2 == 1) {
+static int checkRangeInt(dictionary *dict, const char *key, int rangeFlags, int minBound, int maxBound)
+{
+ int tmpdouble = iniparser_getint(dict,key,minBound);
- count--;
+ int ret = 1;
- }
+ switch(rangeFlags) {
+ case RANGECHECK_NONE:
+ return ret;
+ case RANGECHECK_RANGE:
+ ret = !(tmpdouble < minBound || tmpdouble > maxBound);
+ break;
+ case RANGECHECK_MIN:
+ ret = !(tmpdouble < minBound);
+ break;
+ case RANGECHECK_MAX:
+ ret = !(tmpdouble > maxBound);
+ break;
+ default:
+ return 0;
+ }
- count/=2;
+ if(!ret && !IS_QUIET()) {
+ ERROR("Configuration error: option \"%s=%d\" not within allowed range: %d..%d\n", key, tmpdouble, minBound, maxBound);
+ }
- if ( !CONFIG_ISPRESENT(keyname) ) {
- ret = default_option;
- goto end;
- }
+ return ret;
+}
- memset(sbuf, 0, sizeof(sbuf));
- keyvalue = iniparser_getstring(dict, keyname, "");
+static int configMapInt(dictionary *dict, dictionary *target, const char *key, int intType,
+ void *var, int def, const char *helptext, int rangeFlags,
+ int minBound, int maxBound)
+{
+ if(IS_HELP(key, helptext)) {
+ switch(rangeFlags) {
+ case RANGECHECK_NONE:
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: INT\n");\
+ printf(" usage: %s\n", helptext);
+ printf("default: %d\n", def);
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ return 1;
+ case RANGECHECK_RANGE:
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: INT ");
+ if( minBound != maxBound )
+ printf("(min: %d, max: %d)\n", minBound, maxBound);
+ else
+ printf("(only value of %d allowed)", minBound);
+ printf("\n");
+ printf(" usage: %s\n", helptext);
+ printf("default: %d\n", def);
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ return 1;
+ case RANGECHECK_MIN:
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: INT (min: %d)\n", minBound);
+ printf(" usage: %s\n", helptext);
+ printf("default: %d\n", def);
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ return 1;
+ case RANGECHECK_MAX:
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: FLOAT (max: %d)\n", maxBound);
+ printf(" usage: %s\n", helptext);
+ printf("default: %d\n", def);
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ return 1;
+ default:
+ return 0;
+ }
+ } else {
+ char buf[50];
+ int userVar = iniparser_getint(dict,key,def);
- va_start(va, count);
+ switch(intType) {
+ case INTTYPE_INT:
+ *(int*)var = userVar;
+ break;
+ case INTTYPE_I8:
+ *(int8_t*)var = (int8_t)userVar;
+ break;
+ case INTTYPE_U8:
+ *(uint8_t*)var = (uint8_t)userVar;
+ break;
+ case INTTYPE_I16:
+ *(int16_t*)var = (int16_t)userVar;
+ break;
+ case INTTYPE_U16:
+ *(uint16_t*)var = (uint16_t)userVar;
+ break;
+ case INTTYPE_I32:
+ *(int32_t*)var = (int32_t)userVar;
+ break;
+ case INTTYPE_U32:
+ *(uint32_t*)var = (uint32_t)userVar;
+ break;
+ default:
+ break;
+ }
- for(i = 0; i < count; i++) {
- optionvalue = (char *)va_arg(va, char *);
- optionnumber = (int)va_arg(va, int);
+ memset(buf, 0, 50);
+ snprintf(buf, 50, "%d", userVar);
+ dictionary_set(target,key,buf);
+ if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ printComment(helptext);
+ printf("%s = %s\n", key,buf);
+ }
+ return checkRangeInt(dict, key, rangeFlags, minBound, maxBound);
+ }
+}
- len += snprintf(sbuf + len, sizeof(sbuf) - len, "%s ", optionvalue);
+static int checkRangeDouble(dictionary *dict, const char *key, int rangeFlags, double minBound, double maxBound)
+{
+ double tmpdouble = iniparser_getdouble(dict,key,minBound);
- if ( strcmp(keyvalue, optionvalue) == 0) {
+ int ret = 1;
- ret = optionnumber;
- goto end; /* must call va_end */
+ switch(rangeFlags) {
+ case RANGECHECK_NONE:
+ return ret;
+ case RANGECHECK_RANGE:
+ ret = !(tmpdouble < minBound || tmpdouble > maxBound);
+ break;
+ case RANGECHECK_MIN:
+ ret = !(tmpdouble < minBound);
+ break;
+ case RANGECHECK_MAX:
+ ret = !(tmpdouble > maxBound);
+ break;
+ default:
+ return 0;
+ }
+ if(!ret && !IS_QUIET()) {
+ ERROR("Configuration error: option \"%s=%f\" not within allowed range: %f..%f\n", key, tmpdouble, minBound, maxBound);
}
- }
+ return ret;
+}
- ERROR("Configuration error: option \"%s\" has unknown value: %s - allowed values: %s\n", keyname, keyvalue,sbuf);
-
- ret = -1;
-
-end:
-
- va_end(va);
- return ret;
-
+static int configMapDouble(dictionary *dict, dictionary *target, const char *key,
+ double *var, double def, const char *helptext, int rangeFlags,
+ double minBound, double maxBound)
+{
+ if(IS_HELP(key, helptext)) {
+ switch(rangeFlags) {
+ case RANGECHECK_NONE:
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: FLOAT\n");\
+ printf(" usage: %s\n", helptext);
+ printf("default: %f\n", def);
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ return 1;
+ case RANGECHECK_RANGE:
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: FLOAT ");
+ if( minBound != maxBound )
+ printf("(min: %f, max: %f)\n", minBound, maxBound);
+ else
+ printf("(only value of %f allowed)", minBound);
+ printf("\n");
+ printf(" usage: %s\n", helptext);
+ printf("default: %f\n", def);
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ return 1;
+ case RANGECHECK_MIN:
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: FLOAT(min: %f)\n", minBound);
+ printf(" usage: %s\n", helptext);
+ printf("default: %f\n", def);
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ return 1;
+ case RANGECHECK_MAX:
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: FLOAT(max: %f)\n", maxBound);
+ printf(" usage: %s\n", helptext);
+ printf("default: %f\n", def);
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ return 1;
+ default:
+ return 0;
+ }
+ } else {
+ char buf[50];
+ *var = iniparser_getdouble(dict,key,def);
+ memset(buf, 0, 50);
+ snprintf(buf, 50, "%f", *var);
+ dictionary_set(target,key,buf);
+ if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ printComment(helptext);
+ printf("%s = %s\n", key,buf);
+ }
+ return checkRangeDouble(dict, key, rangeFlags, minBound, maxBound);
+ }
}
-/* Return the string value for the given number value of string, int pairs */
-static char*
-selectOptionName( int value, int count, ... )
+static int
+configMapSelectValue(dictionary *dict, dictionary *target, const char* key, uint8_t *input, int def, const char *helptext, ...)
{
- char *ret, *optionvalue;
- int i, optionnumber;
- va_list va;
- /* if we got an incomplete argument list, cut it down to the last pair or nothing */
- if(count % 2 == 1) {
+ int ret;
+ int i;
+ /* fixed maximum to avoid while(1) */
+ int maxCount = 100;
+ char *name = NULL;
+ char *keyValue;
+ char *defValue = NULL;
+ int value;
+ va_list ap;
+ int selectedValue = -1;
- count--;
+ char sbuf[SCREEN_BUFSZ];
+ int len = 0;
- }
+ memset(sbuf, 0, sizeof(sbuf));
- ret = "[none]";
+ keyValue = iniparser_getstring(dict, key, "");
- count/=2;
+ va_start(ap, helptext);
- va_start(va, count);
+ for(i=0; i < maxCount; i++) {
- for(i = 0; i < count; i++) {
+ name = (char*)va_arg(ap, char*);
+ if(name == NULL) break;
- optionvalue = (char *)va_arg(va, char *);
- optionnumber = (int)va_arg(va, int);
+ value = (int)va_arg(ap, int);
- if ( optionnumber == value ) {
+ len += snprintf(sbuf + len, sizeof(sbuf) - len, "%s ", name);
- ret = optionvalue;
- goto end; /* must call va_end */
+ if(value == def) {
+ defValue = strdup(name);
+ }
+ if(!strcmp(name, keyValue)) {
+ selectedValue = value;
}
}
-end:
+ if(!strcmp(keyValue, "")) {
+ selectedValue = def;
+ keyValue = iniparser_getstring(dict, key, defValue);
+ }
- va_end(va);
- return ret;
+ va_end(ap);
-}
+ if(IS_HELP(key, helptext)) {
+ printf("setting: %s (--%s)\n", key, key);
+ printf(" type: SELECT\n");
+ printf(" usage: %s\n", helptext);
+ printf("options: %s\n", sbuf);
+ printf("default: %s\n", defValue);
+ printf("\n");
+ HELP_ITEM_COMPLETE();
+ ret = 1;
+ goto result;
+ } else {
+ dictionary_set(target, key, keyValue);
+ if(selectedValue < 0) {
+ ERROR("Configuration error: option \"%s\" has unknown value: %s - allowed values: %s\n", key, keyValue, sbuf);
+ ret = 0;
+ } else {
-/* Output a potentially multi-line string, prefixed with ;s */
-static void printComment(char* helptext)
-{
- int i, len;
- len = strlen(helptext);
-
- if(len > 0)
- printf("\n; ");
-
- for (i = 0; i < len; i++) {
- printf("%c",helptext[i]);
- if(helptext[i]=='\n') {
- printf("; ");
- while(i < len) {
- if( helptext[++i]!=' ' && helptext[i]!='\t') {
- i--;
- break;
+ if(!STRING_EMPTY(helptext) && IS_SHOWDEFAULT()) {
+ printComment(helptext);
+ printf("; Options: %s\n", sbuf);
+ printf("%s = %s\n", key,keyValue);
+ }
+ ret = 1;
}
- }
}
+result:
+
+ if(defValue != NULL) {
+ free(defValue);
}
- printf("\n");
+ return ret;
+
}
static void
@@ -925,17 +758,17 @@
CONFIG_KEY_REQUIRED("ptpengine:interface");
- CONFIG_MAP_CHARARRAY("ptpengine:interface",rtOpts->primaryIfaceName,rtOpts->primaryIfaceName,
+ parseResult &= configMapString(dict, target, "ptpengine:interface",rtOpts->primaryIfaceName,rtOpts->primaryIfaceName,
"Network interface to use - eth0, igb0 etc. (required).");
- CONFIG_MAP_CHARARRAY("ptpengine:backup_interface",rtOpts->backupIfaceName,rtOpts->backupIfaceName,
+ parseResult &= configMapString(dict, target, "ptpengine:backup_interface",rtOpts->backupIfaceName,rtOpts->backupIfaceName,
"Backup network interface to use - eth0, igb0 etc. When no GM available, \n"
" slave will keep alternating between primary and secondary until a GM is found.\n");
CONFIG_KEY_TRIGGER("ptpengine:backup_interface",rtOpts->backupIfaceEnabled,TRUE,FALSE);
/* Preset option names have to be mapped to defined presets - no free strings here */
- CONFIG_MAP_SELECTVALUE("ptpengine:preset",rtOpts->selectedPreset,rtOpts->selectedPreset,
+ parseResult &= configMapSelectValue(dict, target, "ptpengine:preset", &rtOpts->selectedPreset,rtOpts->selectedPreset,
"PTP engine preset:\n"
" none = Defaults, no clock class restrictions\n"
" masteronly = Master, passive when not best master (clock class 0..127)\n"
@@ -948,7 +781,7 @@
(getPtpPreset(PTP_PRESET_MASTERONLY,rtOpts)).presetName, PTP_PRESET_MASTERONLY,
(getPtpPreset(PTP_PRESET_MASTERSLAVE,rtOpts)).presetName, PTP_PRESET_MASTERSLAVE,
#endif /* PTPD_SLAVE_ONLY */
- (getPtpPreset(PTP_PRESET_SLAVEONLY,rtOpts)).presetName, PTP_PRESET_SLAVEONLY
+ (getPtpPreset(PTP_PRESET_SLAVEONLY,rtOpts)).presetName, PTP_PRESET_SLAVEONLY, NULL
);
CONFIG_KEY_CONDITIONAL_CONFLICT("ptpengine:preset",
@@ -959,16 +792,16 @@
ptpPreset = getPtpPreset(rtOpts->selectedPreset, rtOpts);
- CONFIG_MAP_SELECTVALUE("ptpengine:transport",rtOpts->transport,rtOpts->transport,
+ parseResult &= configMapSelectValue(dict, target, "ptpengine:transport", &rtOpts->transport,rtOpts->transport,
"Transport type for PTP packets. Ethernet transport requires libpcap support.",
"ipv4", UDP_IPV4,
#if 0
"ipv6", UDP_IPV6,
#endif
- "ethernet", IEEE_802_3
+ "ethernet", IEEE_802_3, NULL
);
- CONFIG_MAP_BOOLEAN("ptpengine:dot2as",rtOpts->dot2AS,rtOpts->dot2AS,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:dot2as", &rtOpts->dot2AS,rtOpts->dot2AS,
"Enable TransportSpecific field compatibility with 802.1AS / AVB (requires Ethernet transport)");
CONFIG_KEY_CONDITIONAL_WARNING_ISSET((rtOpts->transport != IEEE_802_3) && rtOpts->dot2AS,
@@ -977,7 +810,7 @@
CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport != IEEE_802_3,rtOpts->dot2AS,FALSE,rtOpts->dot2AS);
- CONFIG_MAP_SELECTVALUE("ptpengine:ip_mode", rtOpts->ipMode, rtOpts->ipMode,
+ parseResult &= configMapSelectValue(dict, target, "ptpengine:ip_mode", &rtOpts->ipMode, rtOpts->ipMode,
"IP transmission mode (requires IP transport) - hybrid mode uses\n"
" multicast for sync and announce, and unicast for delay request and\n"
" response; unicast mode uses unicast for all transmission.\n"
@@ -985,22 +818,22 @@
" (ptpengine:unicast_destinations).",
"multicast", IPMODE_MULTICAST,
"unicast", IPMODE_UNICAST,
- "hybrid", IPMODE_HYBRID
+ "hybrid", IPMODE_HYBRID, NULL
);
- CONFIG_MAP_BOOLEAN("ptpengine:unicast_negotiation",rtOpts->unicastNegotiation,rtOpts->unicastNegotiation,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:unicast_negotiation", &rtOpts->unicastNegotiation,rtOpts->unicastNegotiation,
"Enable unicast negotiation support using signaling messages\n");
- CONFIG_MAP_BOOLEAN("ptpengine:unicast_any_master",rtOpts->unicastAcceptAny,rtOpts->unicastAcceptAny,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:unicast_any_master", &rtOpts->unicastAcceptAny,rtOpts->unicastAcceptAny,
"When using unicast negotiation (slave), accept PTP messages from any master.\n"
" By default, only messages from acceptable masters (ptpengine:unicast_destinations)\n"
" are accepted, and only if transmission was granted by the master\n");
- CONFIG_MAP_INT_RANGE("ptpengine:unicast_port_mask",rtOpts->unicastPortMask,rtOpts->unicastPortMask,
+ parseResult &= configMapInt(dict, target, "ptpengine:unicast_port_mask", INTTYPE_U16, &rtOpts->unicastPortMask,rtOpts->unicastPortMask,
"PTP port number wildcard mask applied onto port identities when running\n"
" unicast negotiation: allows multiple port identities to be accepted as one.\n"
" This option can be used as a workaround where a node sends signaling messages and\n"
- " timing messages with different port identities",0,65535);
+ " timing messages with different port identities", RANGECHECK_RANGE, 0,65535);
CONFIG_KEY_CONDITIONAL_WARNING_ISSET((rtOpts->transport == IEEE_802_3) && rtOpts->unicastNegotiation,
"ptpengine:unicast_negotiation",
@@ -1014,12 +847,12 @@
CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport == IEEE_802_3,rtOpts->unicastNegotiation,FALSE,rtOpts->unicastNegotiation);
CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->ipMode != IPMODE_UNICAST,rtOpts->unicastNegotiation,FALSE,rtOpts->unicastNegotiation);
- CONFIG_MAP_BOOLEAN("ptpengine:disable_bmca",rtOpts->disableBMCA,rtOpts->disableBMCA,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:disable_bmca", &rtOpts->disableBMCA,rtOpts->disableBMCA,
"Disable Best Master Clock Algorithm for unicast masters:\n"
" Only effective for masteronly preset - all Announce messages\n"
" will be ignored and clock will transition directly into MASTER state.\n");
- CONFIG_MAP_BOOLEAN("ptpengine:unicast_negotiation_listening",rtOpts->unicastNegotiationListening,rtOpts->unicastNegotiationListening,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:unicast_negotiation_listening", &rtOpts->unicastNegotiationListening,rtOpts->unicastNegotiationListening,
"When unicast negotiation enabled on a master clock, \n"
" reply to transmission requests also in LISTENING state.");
@@ -1028,7 +861,7 @@
INFO("Libpcap support is currently marked broken/experimental on Solaris platforms.\n"
"To test it, please build with --enable-experimental-options\n");
- CONFIG_MAP_BOOLEAN("ptpengine:use_libpcap",rtOpts->pcap,FALSE,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:use_libpcap", &rtOpts->pcap,FALSE,
"Use libpcap for sending and receiving traffic (automatically enabled\n"
" in Ethernet mode).");
@@ -1039,7 +872,7 @@
"Libpcap support is currently marked broken/experimental on Solaris platforms.\n"
"To test it and use the Ethernet transport, please build with --enable-experimental-options\n");
#elif defined(PTPD_PCAP)
- CONFIG_MAP_BOOLEAN("ptpengine:use_libpcap",rtOpts->pcap,rtOpts->pcap,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:use_libpcap", &rtOpts->pcap,rtOpts->pcap,
"Use libpcap for sending and receiving traffic (automatically enabled\n"
" in Ethernet mode).");
@@ -1051,7 +884,7 @@
"build without --disable-pcap, or try building with ---with-pcap-config\n"
" to use ptpengine:use_libpcap.\n");
- CONFIG_MAP_BOOLEAN("ptpengine:use_libpcap",rtOpts->pcap,FALSE,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:use_libpcap", &rtOpts->pcap,FALSE,
"Use libpcap for sending and receiving traffic (automatically enabled\n"
" in Ethernet mode).");
@@ -1065,201 +898,201 @@
#endif /* PTPD_PCAP */
- CONFIG_MAP_BOOLEAN("ptpengine:disable_udp_checksums",rtOpts->disableUdpChecksums,rtOpts->disableUdpChecksums,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:disable_udp_checksums", &rtOpts->disableUdpChecksums,rtOpts->disableUdpChecksums,
"Disable UDP checksum validation on UDP sockets (Linux only).\n"
" Workaround for situations where a node (like Transparent Clock).\n"
" does not rewrite checksums\n");
- CONFIG_MAP_SELECTVALUE("ptpengine:delay_mechanism",rtOpts->delayMechanism,rtOpts->delayMechanism,
+ parseResult &= configMapSelectValue(dict, target, "ptpengine:delay_mechanism", &rtOpts->delayMechanism,rtOpts->delayMechanism,
"Delay detection mode used - use DELAY_DISABLED for syntonisation only\n"
" (no full synchronisation).",
"E2E", E2E,
"P2P", P2P,
- "DELAY_DISABLED", DELAY_DISABLED
+ "DELAY_DISABLED", DELAY_DISABLED, NULL
);
- CONFIG_MAP_INT_RANGE("ptpengine:domain",rtOpts->domainNumber,rtOpts->domainNumber,
- "PTP domain number.",0,127);
+ parseResult &= configMapInt(dict, target, "ptpengine:domain", INTTYPE_U8, &rtOpts->domainNumber,rtOpts->domainNumber,
+ "PTP domain number.", RANGECHECK_RANGE, 0,127);
- CONFIG_MAP_INT_RANGE("ptpengine:port_number",rtOpts->portNumber,rtOpts->portNumber,
+ parseResult &= configMapInt(dict, target, "ptpengine:port_number", INTTYPE_U16, &rtOpts->portNumber,rtOpts->portNumber,
"PTP port number (part of PTP Port Identity - not UDP port).\n"
" For ordinary clocks (single port), the default should be used, \n"
" but when running multiple instances to simulate a boundary clock, \n"
- " The port number can be changed.",1,65534);
+ " The port number can be changed.",RANGECHECK_RANGE,1,65534);
- CONFIG_MAP_BOOLEAN("ptpengine:any_domain",rtOpts->anyDomain, rtOpts->anyDomain,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:any_domain", &rtOpts->anyDomain, rtOpts->anyDomain,
"Usability extension: if enabled, a slave-only clock will accept\n"
" masters from any domain, while preferring the configured domain,\n"
" and preferring lower domain number.\n"
" NOTE: this behaviour is not part of the standard.");
- CONFIG_MAP_BOOLEAN("ptpengine:slave_only",rtOpts->slaveOnly, ptpPreset.slaveOnly,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:slave_only", &rtOpts->slaveOnly, ptpPreset.slaveOnly,
"Slave only mode (sets clock class to 255, overriding value from preset).");
- CONFIG_MAP_INT( "ptpengine:inbound_latency",rtOpts->inboundLatency.nanoseconds,rtOpts->inboundLatency.nanoseconds,
- "Specify latency correction (nanoseconds) for incoming packets.");
+ parseResult &= configMapInt(dict, target, "ptpengine:inbound_latency", INTTYPE_I32, &rtOpts->inboundLatency.nanoseconds,rtOpts->inboundLatency.nanoseconds,
+ "Specify latency correction (nanoseconds) for incoming packets.", RANGECHECK_NONE, 0,0);
- CONFIG_MAP_INT( "ptpengine:outbound_latency",rtOpts->outboundLatency.nanoseconds,rtOpts->outboundLatency.nanoseconds,
- "Specify latency correction (nanoseconds) for outgoing packets.");
+ parseResult &= configMapInt(dict, target, "ptpengine:outbound_latency",INTTYPE_I32, &rtOpts->outboundLatency.nanoseconds,rtOpts->outboundLatency.nanoseconds,
+ "Specify latency correction (nanoseconds) for outgoing packets.", RANGECHECK_NONE,0,0);
- CONFIG_MAP_INT( "ptpengine:offset_shift",rtOpts->ofmShift.nanoseconds,rtOpts->ofmShift.nanoseconds,
+ parseResult &= configMapInt(dict, target, "ptpengine:offset_shift", INTTYPE_I32, &rtOpts->ofmShift.nanoseconds,rtOpts->ofmShift.nanoseconds,
"Apply an arbitrary shift (nanoseconds) to offset from master when\n"
" in slave state. Value can be positive or negative - useful for\n"
" correcting for antenna latencies, delay assymetry\n"
" and IP stack latencies. This will not be visible in the offset \n"
- " from master value - only in the resulting clock correction.");
+ " from master value - only in the resulting clock correction.", RANGECHECK_NONE, 0,0);
- CONFIG_MAP_BOOLEAN("ptpengine:always_respect_utc_offset",rtOpts->alwaysRespectUtcOffset, rtOpts->alwaysRespectUtcOffset,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:always_respect_utc_offset", &rtOpts->alwaysRespectUtcOffset, rtOpts->alwaysRespectUtcOffset,
"Compatibility option: In slave state, always respect UTC offset\n"
" announced by best master, even if the the\n"
" currrentUtcOffsetValid flag is announced FALSE.\n"
" NOTE: this behaviour is not part of the standard.");
- CONFIG_MAP_BOOLEAN("ptpengine:prefer_utc_offset_valid",rtOpts->preferUtcValid, rtOpts->preferUtcValid,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:prefer_utc_offset_valid", &rtOpts->preferUtcValid, rtOpts->preferUtcValid,
"Compatibility extension to BMC algorithm: when enabled,\n"
" BMC for both master and save clocks will prefer masters\n"
" nannouncing currrentUtcOffsetValid as TRUE.\n"
" NOTE: this behaviour is not part of the standard.");
- CONFIG_MAP_BOOLEAN("ptpengine:require_utc_offset_valid",rtOpts->requireUtcValid, rtOpts->requireUtcValid,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:require_utc_offset_valid", &rtOpts->requireUtcValid, rtOpts->requireUtcValid,
"Compatibility option: when enabled, ptpd2 will ignore\n"
" Announce messages from masters announcing currentUtcOffsetValid\n"
" as FALSE.\n"
" NOTE: this behaviour is not part of the standard.");
/* from 30 seconds to 7 days */
- CONFIG_MAP_INT_RANGE("ptpengine:unicast_grant_duration", rtOpts->unicastGrantDuration, rtOpts->unicastGrantDuration,
+ parseResult &= configMapInt(dict, target, "ptpengine:unicast_grant_duration", INTTYPE_U32, &rtOpts->unicastGrantDuration, rtOpts->unicastGrantDuration,
"Time (seconds) unicast messages are requested for by slaves\n"
" when using unicast negotiation, and maximum time unicast message\n"
- " transmission is granted to slaves by masters\n", 30, 604800);
+ " transmission is granted to slaves by masters\n", RANGECHECK_RANGE, 30, 604800);
- CONFIG_MAP_INT_RANGE("ptpengine:log_announce_interval",rtOpts->logAnnounceInterval,rtOpts->logAnnounceInterval,
+ parseResult &= configMapInt(dict, target, "ptpengine:log_announce_interval", INTTYPE_I8, &rtOpts->logAnnounceInterval,rtOpts->logAnnounceInterval,
"PTP announce message interval in master state. When using unicast negotiation, for\n"
" slaves this is the minimum interval requested, and for masters\n"
" this is the only interval granted.\n"
#ifdef PTPD_EXPERIMENTAL
- " "LOG2_HELP,-30,30);
+ " "LOG2_HELP,RANGECHECK_RANGE,-30,30);
#else
- " "LOG2_HELP,-4,7);
+ " "LOG2_HELP,RANGECHECK_RANGE,-4,7);
#endif
- CONFIG_MAP_INT_RANGE("ptpengine:log_announce_interval_max",rtOpts->logMaxAnnounceInterval,rtOpts->logMaxAnnounceInterval,
+ parseResult &= configMapInt(dict, target, "ptpengine:log_announce_interval_max",INTTYPE_I8,&rtOpts->logMaxAnnounceInterval,rtOpts->logMaxAnnounceInterval,
"Maximum Announce message interval requested by slaves "
"when using unicast negotiation,\n"
#ifdef PTPD_EXPERIMENTAL
- " "LOG2_HELP,-30,30);
+ " "LOG2_HELP,RANGECHECK_RANGE,-30,30);
#else
- " "LOG2_HELP,-1,7);
+ " "LOG2_HELP,RANGECHECK_RANGE,-1,7);
#endif
CONFIG_CONDITIONAL_ASSERTION(rtOpts->logAnnounceInterval >= rtOpts->logMaxAnnounceInterval,
"ptpengine:log_announce_interval value must be lower than ptpengine:log_announce_interval_max\n");
- CONFIG_MAP_INT_RANGE("ptpengine:announce_receipt_timeout",rtOpts->announceReceiptTimeout,rtOpts->announceReceiptTimeout,
- "PTP announce receipt timeout announced in master state.",2,255);
+ parseResult &= configMapInt(dict, target, "ptpengine:announce_receipt_timeout",INTTYPE_I8, &rtOpts->announceReceiptTimeout,rtOpts->announceReceiptTimeout,
+ "PTP announce receipt timeout announced in master state.",RANGECHECK_RANGE,2,255);
- CONFIG_MAP_INT_RANGE("ptpengine:announce_receipt_grace_period",rtOpts->announceTimeoutGracePeriod,rtOpts->announceTimeoutGracePeriod,
+ parseResult &= configMapInt(dict, target, "ptpengine:announce_receipt_grace_period",INTTYPE_INT,&rtOpts->announceTimeoutGracePeriod,rtOpts->announceTimeoutGracePeriod,
"PTP announce receipt timeout grace period in slave state:\n"
" when announce receipt timeout occurs, disqualify current best GM,\n"
" then wait n times announce receipt timeout before resetting.\n"
" Allows for a seamless GM failover when standby GMs are slow\n"
- " to react. When set to 0, this option is not used.",
+ " to react. When set to 0, this option is not used.", RANGECHECK_RANGE,
0,20);
- CONFIG_MAP_INT_RANGE("ptpengine:log_sync_interval",rtOpts->logSyncInterval,rtOpts->logSyncInterval,
+ parseResult &= configMapInt(dict, target, "ptpengine:log_sync_interval",INTTYPE_I8,&rtOpts->logSyncInterval,rtOpts->logSyncInterval,
"PTP sync message interval in master state. When using unicast negotiation, for\n"
" slaves this is the minimum interval requested, and for masters\n"
" this is the only interval granted.\n"
#ifdef PTPD_EXPERIMENTAL
- " "LOG2_HELP,-30,30);
+ " "LOG2_HELP,RANGECHECK_RANGE,-30,30);
#else
- " "LOG2_HELP,-7,7);
+ " "LOG2_HELP,RANGECHECK_RANGE,-7,7);
#endif
- CONFIG_MAP_INT_RANGE("ptpengine:log_sync_interval_max",rtOpts->logMaxSyncInterval,rtOpts->logMaxSyncInterval,
+ parseResult &= configMapInt(dict, target, "ptpengine:log_sync_interval_max",INTTYPE_I8,&rtOpts->logMaxSyncInterval,rtOpts->logMaxSyncInterval,
"Maximum Sync message interval requested by slaves "
"when using unicast negotiation,\n"
#ifdef PTPD_EXPERIMENTAL
- " "LOG2_HELP,-30,30);
+ " "LOG2_HELP,RANGECHECK_RANGE,-30,30);
#else
- " "LOG2_HELP,-1,7);
+ " "LOG2_HELP,RANGECHECK_RANGE,-1,7);
#endif
CONFIG_CONDITIONAL_ASSERTION(rtOpts->logSyncInterval >= rtOpts->logMaxSyncInterval,
"ptpengine:log_sync_interval value must be lower than ptpengine:log_sync_interval_max\n");
- CONFIG_MAP_BOOLEAN("ptpengine:log_delayreq_override", rtOpts->ignore_delayreq_interval_master,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:log_delayreq_override", &rtOpts->ignore_delayreq_interval_master,
rtOpts->ignore_delayreq_interval_master,
"Override the Delay Request interval announced by best master.");
- CONFIG_MAP_BOOLEAN("ptpengine:log_delayreq_auto", rtOpts->autoDelayReqInterval,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:log_delayreq_auto", &rtOpts->autoDelayReqInterval,
rtOpts->autoDelayReqInterval,
"Automatically override the Delay Request interval\n"
" if the announced value is 127 (0X7F), such as in\n"
" unicast messages (unless using unicast negotiation)");
- CONFIG_MAP_INT_RANGE("ptpengine:log_delayreq_interval_initial",rtOpts->initial_delayreq,rtOpts->initial_delayreq,
+ parseResult &= configMapInt(dict, target, "ptpengine:log_delayreq_interval_initial",INTTYPE_I8,&rtOpts->initial_delayreq,rtOpts->initial_delayreq,
"Delay request interval used before receiving first delay response\n"
#ifdef PTPD_EXPERIMENTAL
- " "LOG2_HELP,-30,30);
+ " "LOG2_HELP,RANGECHECK_RANGE,-30,30);
#else
- " "LOG2_HELP,-7,7);
+ " "LOG2_HELP,RANGECHECK_RANGE,-7,7);
#endif
/* take the delayreq_interval from config, otherwise use the initial setting as default */
- CONFIG_MAP_INT_RANGE("ptpengine:log_delayreq_interval",rtOpts->logMinDelayReqInterval,rtOpts->initial_delayreq,
+ parseResult &= configMapInt(dict, target, "ptpengine:log_delayreq_interval",INTTYPE_I8,&rtOpts->logMinDelayReqInterval,rtOpts->initial_delayreq,
"Minimum delay request interval announced when in master state,\n"
" in slave state overrides the master interval,\n"
" required in hybrid mode. When using unicast negotiation, for\n"
" slaves this is the minimum interval requested, and for masters\n"
" this is the minimum interval granted.\n"
#ifdef PTPD_EXPERIMENTAL
- " "LOG2_HELP,-30,30);
+ " "LOG2_HELP,RANGECHECK_RANGE,-30,30);
#else
- " "LOG2_HELP,-7,7);
+ " "LOG2_HELP,RANGECHECK_RANGE,-7,7);
#endif
- CONFIG_MAP_INT_RANGE("ptpengine:log_delayreq_interval_max",rtOpts->logMaxDelayReqInterval,rtOpts->logMaxDelayReqInterval,
+ parseResult &= configMapInt(dict, target, "ptpengine:log_delayreq_interval_max",INTTYPE_I8,&rtOpts->logMaxDelayReqInterval,rtOpts->logMaxDelayReqInterval,
"Maximum Delay Response interval requested by slaves "
"when using unicast negotiation,\n"
#ifdef PTPD_EXPERIMENTAL
- " "LOG2_HELP,-30,30);
+ " "LOG2_HELP,RANGECHECK_RANGE,-30,30);
#else
- " "LOG2_HELP,-1,7);
+ " "LOG2_HELP,RANGECHECK_RANGE,-1,7);
#endif
CONFIG_CONDITIONAL_ASSERTION(rtOpts->logMinDelayReqInterval >= rtOpts->logMaxDelayReqInterval,
"ptpengine:log_delayreq_interval value must be lower than ptpengine:log_delayreq_interval_max\n");
- CONFIG_MAP_INT_RANGE("ptpengine:log_peer_delayreq_interval",rtOpts->logMinPdelayReqInterval,rtOpts->logMinPdelayReqInterval,
+ parseResult &= configMapInt(dict, target, "ptpengine:log_peer_delayreq_interval",INTTYPE_I8,&rtOpts->logMinPdelayReqInterval,rtOpts->logMinPdelayReqInterval,
"Minimum peer delay request message interval in peer to peer delay mode.\n"
" When using unicast negotiation, this is the minimum interval requested, \n"
" and the only interval granted.\n"
#ifdef PTPD_EXPERIMENTAL
- " "LOG2_HELP,-30,30);
+ " "LOG2_HELP,RANGECHECK_RANGE,-30,30);
#else
- " "LOG2_HELP,-7,7);
+ " "LOG2_HELP,RANGECHECK_RANGE,-7,7);
#endif
- CONFIG_MAP_INT_RANGE("ptpengine:log_peer_delayreq_interval_max",rtOpts->logMaxPdelayReqInterval,rtOpts->logMaxPdelayReqInterval,
+ parseResult &= configMapInt(dict, target, "ptpengine:log_peer_delayreq_interval_max",INTTYPE_I8,&rtOpts->logMaxPdelayReqInterval,rtOpts->logMaxPdelayReqInterval,
"Maximum Peer Delay Response interval requested by slaves "
"when using unicast negotiation,\n"
#ifdef PTPD_EXPERIMENTAL
- " "LOG2_HELP,-30,30);
+ " "LOG2_HELP,RANGECHECK_RANGE,-30,30);
#else
- " "LOG2_HELP,-1,7);
+ " "LOG2_HELP,RANGECHECK_RANGE,-1,7);
#endif
CONFIG_CONDITIONAL_ASSERTION(rtOpts->logMinPdelayReqInterval >= rtOpts->logMaxPdelayReqInterval,
"ptpengine:log_peer_delayreq_interval value must be lower than ptpengine:log_peer_delayreq_interval_max\n");
- CONFIG_MAP_INT_RANGE("ptpengine:foreignrecord_capacity",rtOpts->max_foreign_records,rtOpts->max_foreign_records,
- "Foreign master record size (Maximum number of foreign masters).",5,10);
+ parseResult &= configMapInt(dict, target, "ptpengine:foreignrecord_capacity",INTTYPE_I16,&rtOpts->max_foreign_records,rtOpts->max_foreign_records,
+ "Foreign master record size (Maximum number of foreign masters).",RANGECHECK_RANGE,5,10);
- CONFIG_MAP_INT_RANGE("ptpengine:ptp_allan_variance",rtOpts->clockQuality.offsetScaledLogVariance,rtOpts->clockQuality.offsetScaledLogVariance,
- "Specify Allan variance announced in master state.",0,65535);
+ parseResult &= configMapInt(dict, target, "ptpengine:ptp_allan_variance",INTTYPE_U16,&rtOpts->clockQuality.offsetScaledLogVariance,rtOpts->clockQuality.offsetScaledLogVariance,
+ "Specify Allan variance announced in master state.",RANGECHECK_RANGE,0,65535);
- CONFIG_MAP_SELECTVALUE("ptpengine:ptp_clock_accuracy",rtOpts->clockQuality.clockAccuracy,rtOpts->clockQuality.clockAccuracy,
+ parseResult &= configMapSelectValue(dict, target, "ptpengine:ptp_clock_accuracy", &rtOpts->clockQuality.clockAccuracy,rtOpts->clockQuality.clockAccuracy,
"Clock accuracy range announced in master state.",
"ACC_25NS", 0x20,
"ACC_100NS", 0x21,
@@ -1279,33 +1112,33 @@
"ACC_1S", 0x2F,
"ACC_10S", 0x30,
"ACC_10SPLUS", 0x31,
- "ACC_UNKNOWN", 0xFE
+ "ACC_UNKNOWN", 0xFE, NULL
);
- CONFIG_MAP_INT( "ptpengine:utc_offset",rtOpts->timeProperties.currentUtcOffset,rtOpts->timeProperties.currentUtcOffset,
- "Underlying time source UTC offset announced in master state.");
+ parseResult &= configMapInt(dict, target, "ptpengine:utc_offset",INTTYPE_I16,&rtOpts->timeProperties.currentUtcOffset,rtOpts->timeProperties.currentUtcOffset,
+ "Underlying time source UTC offset announced in master state.", RANGECHECK_NONE,0,0);
- CONFIG_MAP_BOOLEAN("ptpengine:utc_offset_valid",rtOpts->timeProperties.currentUtcOffsetValid,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:utc_offset_valid", &rtOpts->timeProperties.currentUtcOffsetValid,
rtOpts->timeProperties.currentUtcOffsetValid,
"Underlying time source UTC offset validity announced in master state.");
- CONFIG_MAP_BOOLEAN("ptpengine:time_traceable",rtOpts->timeProperties.timeTraceable,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:time_traceable", &rtOpts->timeProperties.timeTraceable,
rtOpts->timeProperties.timeTraceable,
"Underlying time source time traceability announced in master state.");
- CONFIG_MAP_BOOLEAN("ptpengine:frequency_traceable",rtOpts->timeProperties.frequencyTraceable,
+ parseResult &= configMapBoolean(dict, target,"ptpengine:frequency_traceable", &rtOpts->timeProperties.frequencyTraceable,
rtOpts->timeProperties.frequencyTraceable,
"Underlying time source frequency traceability announced in master state.");
- CONFIG_MAP_SELECTVALUE("ptpengine:ptp_timescale",rtOpts->timeProperties.ptpTimescale,rtOpts->timeProperties.ptpTimescale,
+ parseResult &= configMapSelectValue(dict, target, "ptpengine:ptp_timescale", (uint8_t*)&rtOpts->timeProperties.ptpTimescale,rtOpts->timeProperties.ptpTimescale,
"Time scale announced in master state (with ARB, UTC properties\n"
" are ignored by slaves). When clock class is set to 13 (application\n"
" specific), this value is ignored and ARB is used.",
"PTP", TRUE,
- "ARB", FALSE
+ "ARB", FALSE, NULL
);
- CONFIG_MAP_SELECTVALUE("ptpengine:ptp_timesource",rtOpts->timeProperties.timeSource,rtOpts->timeProperties.timeSource,
+ parseResult &= configMapSelectValue(dict, target, "ptpengine:ptp_timesource", &rtOpts->timeProperties.timeSource,rtOpts->timeProperties.timeSource,
"Time source announced in master state.",
"ATOMIC_CLOCK", ATOMIC_CLOCK,
"GPS", GPS,
@@ -1314,17 +1147,17 @@
"NTP", NTP,
"HAND_SET", HAND_SET,
"OTHER", OTHER,
- "INTERNAL_OSCILLATOR", INTERNAL_OSCILLATOR
+ "INTERNAL_OSCILLATOR", INTERNAL_OSCILLATOR, NULL
);
- CONFIG_MAP_INT_RANGE("ptpengine:clock_class",rtOpts->clockQuality.clockClass,ptpPreset.clockClass.defaultValue,
+ parseResult &= configMapInt(dict, target, "ptpengine:clock_class",INTTYPE_U8,&rtOpts->clockQuality.clockClass,ptpPreset.clockClass.defaultValue,
"Clock class - announced in master state. Always 255 for slave-only.\n"
" Minimum, maximum and default values are controlled by presets.\n"
" If set to 13 (application specific time source), announced \n"
" time scale is always set to ARB. This setting controls the\n"
" states a PTP port can be in. If below 128, port will only\n"
" be in MASTER or PASSIVE states (master only). If above 127,\n"
- " port will be in MASTER or SLAVE states.",
+ " port will be in MASTER or SLAVE states.", RANGECHECK_RANGE,
ptpPreset.clockClass.minValue,ptpPreset.clockClass.maxValue);
/* ClockClass = 13 triggers ARB */
@@ -1348,16 +1181,16 @@
/* ...and vice versa */
CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->slaveOnly==TRUE,rtOpts->clockQuality.clockClass,SLAVE_ONLY_CLOCK_CLASS,rtOpts->clockQuality.clockClass);
- CONFIG_MAP_INT_RANGE("ptpengine:priority1",rtOpts->priority1,rtOpts->priority1,
+ parseResult &= configMapInt(dict, target, "ptpengine:priority1",INTTYPE_U8,&rtOpts->priority1,rtOpts->priority1,
"Priority 1 announced in master state,used for Best Master\n"
- " Clock selection.",0,248);
+ " Clock selection.",RANGECHECK_RANGE,0,248);
- CONFIG_MAP_INT_RANGE("ptpengine:priority2",rtOpts->priority2,rtOpts->priority2,
+ parseResult &= configMapInt(dict, target, "ptpengine:priority2",INTTYPE_U8,&rtOpts->priority2,rtOpts->priority2,
"Priority 2 announced in master state, used for Best Master\n"
- " Clock selection.",0,248);
+ " Clock selection.",RANGECHECK_RANGE,0,248);
- CONFIG_MAP_INT_MIN( "ptpengine:max_listen",rtOpts->maxListen,rtOpts->maxListen,
- "Number of consecutive resets to LISTENING before full network reset\n",1);
+ parseResult &= configMapInt(dict, target, "ptpengine:max_listen",INTTYPE_INT,&rtOpts->maxListen,rtOpts->maxListen,
+ "Number of consecutive resets to LISTENING before full network reset\n",RANGECHECK_MIN,1,0);
/*
* TODO: in unicast and hybrid mode, automativally override master delayreq interval wi...
[truncated message content] |
|
From: <wow...@us...> - 2015-10-19 23:57:59
|
Revision: 596
http://sourceforge.net/p/ptpd/code/596
Author: wowczarek
Date: 2015-10-19 23:57:56 +0000 (Mon, 19 Oct 2015)
Log Message:
-----------
- reworked bmc functions to work on ForeignMasterRecord,
allowing for extra fields in the record when needed
- added pointer to best master (vs. array), to be
factored into source, NULL checks needed(?)
- added "disqualified" flag to FMR for grace period,
instead of setting prio/clockcl to 255
- added missing wildcard condition for sig/mgmt message
acceptance: clkid=all1, port match
- added default empty templates.conf to distribution
- updated man pages with template file information
- re-generated full default config file
- added macro for looping over split string tokens
(to be completed / factored into source)
Modified Paths:
--------------
trunk/Makefile.am
trunk/TODO
trunk/configure.ac
trunk/packagebuild/rpm-rh/ptpd.spec
trunk/src/bmc.c
trunk/src/constants.h
trunk/src/datatypes.h
trunk/src/dep/configdefaults.c
trunk/src/dep/net.c
trunk/src/dep/ptpd_dep.h
trunk/src/dep/sys.c
trunk/src/protocol.c
trunk/src/ptpd2.8.in
trunk/src/ptpd2.conf.5.in
trunk/src/ptpd2.conf.default-full
Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/Makefile.am 2015-10-19 23:57:56 UTC (rev 596)
@@ -23,6 +23,7 @@
src/dep/iniparser/AUTHORS\
src/dep/iniparser/LICENSE\
src/dep/iniparser/README\
+ src/templates.conf\
\
$(NULL)
@@ -40,6 +41,7 @@
ptpd2_DATA = src/leap-seconds.list \
src/ptpd2.conf.minimal \
src/ptpd2.conf.default-full \
+ src/templates.conf \
doc/PTPBASE-MIB.txt \
$(NULL)
Modified: trunk/TODO
===================================================================
--- trunk/TODO 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/TODO 2015-10-19 23:57:56 UTC (rev 596)
@@ -2,8 +2,18 @@
2.3.1.1 / 2.3.2:
-- man page updates for template files
+- man page updates for template files x
- clock ID printed in reverse in L2 mode
- with (grandmasterID present?)
+ with (grandmasterID present?) - not an issue, seems like a White Rabbit problem x
- complete built-in templates
-- add dummy or populated default template file
+- add dummy or populated default template file x
+- 16.1.1: may be granted in listening state or passive state <- but g.8265 is no BMCA x
+- sig/msg message acceptance 4 options: all1,port, clockid,port, clock,all1, all1,all1 x
+- rework config option parsing
+- SET messages to refresh the config properly
+- NVRAM write?
+- pointer to best master x
+- disqualification flag x
+- remove masteraddr in favour of bestMaster->sourceAddr
+- use split token loop
+- use pointer to best master
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/configure.ac 2015-10-19 23:57:56 UTC (rev 596)
@@ -458,6 +458,8 @@
esac
+
+
AC_SUBST(PTP_PCAP)
AM_CONDITIONAL([PCAP], [test x$ptpd_pcap_enabled = x1])
@@ -749,6 +751,7 @@
PTP_SLAVE_ONLY="-DPTPD_SLAVE_ONLY"
;;
esac
+
AC_SUBST(PTP_SLAVE_ONLY)
AM_CONDITIONAL([SLAVE_ONLY], [test x$enable_slave_only = xyes])
Modified: trunk/packagebuild/rpm-rh/ptpd.spec
===================================================================
--- trunk/packagebuild/rpm-rh/ptpd.spec 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/packagebuild/rpm-rh/ptpd.spec 2015-10-19 23:57:56 UTC (rev 596)
@@ -98,6 +98,7 @@
install -m 644 src/leap-seconds.list $RPM_BUILD_ROOT%{_datadir}/ptpd/leap-seconds.list
install -m 644 src/ptpd2.conf.minimal $RPM_BUILD_ROOT%{_datadir}/ptpd/ptpd2.conf.minimal
install -m 644 src/ptpd2.conf.default-full $RPM_BUILD_ROOT%{_datadir}/ptpd/ptpd2.conf.default-full
+install -m 644 src/templates.conf $RPM_BUILD_ROOT%{_datadir}/ptpd/templates.conf
{ cd $RPM_BUILD_ROOT
Modified: trunk/src/bmc.c
===================================================================
--- trunk/src/bmc.c 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/bmc.c 2015-10-19 23:57:56 UTC (rev 596)
@@ -85,6 +85,7 @@
memcpy(ptpClock->clockIdentity + 3, &pid, 2);
}
+ ptpClock->bestMaster = NULL;
ptpClock->numberPorts = NUMBER_PORTS;
ptpClock->clockQuality.clockAccuracy =
@@ -451,30 +452,40 @@
* return similar to memcmp() */
static Integer8
-bmcDataSetComparison(const MsgHeader *headerA, const MsgAnnounce *announceA, UInteger8 localPrefA,
- const MsgHeader *headerB, const MsgAnnounce *announceB, UInteger8 localPrefB,
- const PtpClock *ptpClock, const RunTimeOpts * rtOpts)
+bmcDataSetComparison(const ForeignMasterRecord *a, const ForeignMasterRecord *b, const PtpClock *ptpClock, const RunTimeOpts *rtOpts)
{
DBGV("Data set comparison \n");
short comp = 0;
+
+
+ /* disqualification comes above anything else */
+
+ if(a->disqualified > b->disqualified) {
+ return -1;
+ }
+
+ if(a->disqualified < b->disqualified) {
+ return 1;
+ }
+
/*Identity comparison*/
- comp = memcmp(announceA->grandmasterIdentity,announceB->grandmasterIdentity,CLOCK_IDENTITY_LENGTH);
+ comp = memcmp(a->announce.grandmasterIdentity,b->announce.grandmasterIdentity,CLOCK_IDENTITY_LENGTH);
if (comp!=0)
goto dataset_comp_part_1;
/* Algorithm part2 Fig 28 */
- if (announceA->stepsRemoved > announceB->stepsRemoved+1)
+ if (a->announce.stepsRemoved > b->announce.stepsRemoved+1)
return 1;
- if (announceA->stepsRemoved+1 < announceB->stepsRemoved)
+ if (a->announce.stepsRemoved+1 < b->announce.stepsRemoved)
return -1;
/* A within 1 of B */
- if (announceA->stepsRemoved > announceB->stepsRemoved) {
- comp = memcmp(headerA->sourcePortIdentity.clockIdentity,ptpClock->parentPortIdentity.clockIdentity,CLOCK_IDENTITY_LENGTH);
+ if (a->announce.stepsRemoved > b->announce.stepsRemoved) {
+ comp = memcmp(a->header.sourcePortIdentity.clockIdentity,ptpClock->parentPortIdentity.clockIdentity,CLOCK_IDENTITY_LENGTH);
if(comp < 0)
return -1;
if(comp > 0)
@@ -483,8 +494,8 @@
return 0;
}
- if (announceA->stepsRemoved < announceB->stepsRemoved) {
- comp = memcmp(headerB->sourcePortIdentity.clockIdentity,ptpClock->parentPortIdentity.clockIdentity,CLOCK_IDENTITY_LENGTH);
+ if (a->announce.stepsRemoved < b->announce.stepsRemoved) {
+ comp = memcmp(b->header.sourcePortIdentity.clockIdentity,ptpClock->parentPortIdentity.clockIdentity,CLOCK_IDENTITY_LENGTH);
if(comp < 0)
return -1;
@@ -494,7 +505,7 @@
return 0;
}
/* steps removed A = steps removed B */
- comp = memcmp(headerA->sourcePortIdentity.clockIdentity,headerB->sourcePortIdentity.clockIdentity,CLOCK_IDENTITY_LENGTH);
+ comp = memcmp(a->header.sourcePortIdentity.clockIdentity,b->header.sourcePortIdentity.clockIdentity,CLOCK_IDENTITY_LENGTH);
if (comp<0) {
return -1;
@@ -506,9 +517,9 @@
/* identity A = identity B */
- if (headerA->sourcePortIdentity.portNumber < headerB->sourcePortIdentity.portNumber)
+ if (a->header.sourcePortIdentity.portNumber < b->header.sourcePortIdentity.portNumber)
return -1;
- if (headerA->sourcePortIdentity.portNumber > headerB->sourcePortIdentity.portNumber)
+ if (a->header.sourcePortIdentity.portNumber > b->header.sourcePortIdentity.portNumber)
return 1;
DBG("Sender=Receiver : Error -2");
@@ -521,38 +532,38 @@
if(rtOpts->anyDomain) {
/* part 1: preferred domain wins */
- if(headerA->domainNumber == rtOpts->domainNumber && headerB->domainNumber != ptpClock->domainNumber)
+ if(a->header.domainNumber == rtOpts->domainNumber && b->header.domainNumber != ptpClock->domainNumber)
return -1;
- if(headerA->domainNumber != rtOpts->domainNumber && headerB->domainNumber == ptpClock->domainNumber)
+ if(a->header.domainNumber != rtOpts->domainNumber && b->header.domainNumber == ptpClock->domainNumber)
return 1;
/* part 2: lower domain wins */
- if(headerA->domainNumber < headerB->domainNumber)
+ if(a->header.domainNumber < b->header.domainNumber)
return -1;
- if(headerA->domainNumber > headerB->domainNumber)
+ if(a->header.domainNumber > b->header.domainNumber)
return 1;
}
/* Compare localPreference - only used by slaves when using unicast negotiation */
- DBGV("bmcDataSetComparison localPrefA: %d, localPrefB: %d\n", localPrefA, localPrefB);
- if(localPrefA < localPrefB) {
+ DBGV("bmcDataSetComparison a->localPreference: %d, b->localPreference: %d\n", a->localPreference, b->localPreference);
+ if(a->localPreference < b->localPreference) {
return -1;
}
- if(localPrefA > localPrefB) {
+ if(a->localPreference > b->localPreference) {
return 1;
}
/* Compare GM priority1 */
- if (announceA->grandmasterPriority1 < announceB->grandmasterPriority1)
+ if (a->announce.grandmasterPriority1 < b->announce.grandmasterPriority1)
return -1;
- if (announceA->grandmasterPriority1 > announceB->grandmasterPriority1)
+ if (a->announce.grandmasterPriority1 > b->announce.grandmasterPriority1)
return 1;
/* non-standard BMC extension to prioritise GMs with UTC valid */
if(rtOpts->preferUtcValid) {
- Boolean utcA = IS_SET(headerA->flagField1, UTCV);
- Boolean utcB = IS_SET(headerB->flagField1, UTCV);
+ Boolean utcA = IS_SET(a->header.flagField1, UTCV);
+ Boolean utcB = IS_SET(b->header.flagField1, UTCV);
if(utcA > utcB)
return -1;
if(utcA < utcB)
@@ -560,33 +571,33 @@
}
/* Compare GM class */
- if (announceA->grandmasterClockQuality.clockClass <
- announceB->grandmasterClockQuality.clockClass)
+ if (a->announce.grandmasterClockQuality.clockClass <
+ b->announce.grandmasterClockQuality.clockClass)
return -1;
- if (announceA->grandmasterClockQuality.clockClass >
- announceB->grandmasterClockQuality.clockClass)
+ if (a->announce.grandmasterClockQuality.clockClass >
+ b->announce.grandmasterClockQuality.clockClass)
return 1;
/* Compare GM accuracy */
- if (announceA->grandmasterClockQuality.clockAccuracy <
- announceB->grandmasterClockQuality.clockAccuracy)
+ if (a->announce.grandmasterClockQuality.clockAccuracy <
+ b->announce.grandmasterClockQuality.clockAccuracy)
return -1;
- if (announceA->grandmasterClockQuality.clockAccuracy >
- announceB->grandmasterClockQuality.clockAccuracy)
+ if (a->announce.grandmasterClockQuality.clockAccuracy >
+ b->announce.grandmasterClockQuality.clockAccuracy)
return 1;
/* Compare GM offsetScaledLogVariance */
- if (announceA->grandmasterClockQuality.offsetScaledLogVariance <
- announceB->grandmasterClockQuality.offsetScaledLogVariance)
+ if (a->announce.grandmasterClockQuality.offsetScaledLogVariance <
+ b->announce.grandmasterClockQuality.offsetScaledLogVariance)
return -1;
- if (announceA->grandmasterClockQuality.offsetScaledLogVariance >
- announceB->grandmasterClockQuality.offsetScaledLogVariance)
+ if (a->announce.grandmasterClockQuality.offsetScaledLogVariance >
+ b->announce.grandmasterClockQuality.offsetScaledLogVariance)
return 1;
/* Compare GM priority2 */
- if (announceA->grandmasterPriority2 < announceB->grandmasterPriority2)
+ if (a->announce.grandmasterPriority2 < b->announce.grandmasterPriority2)
return -1;
- if (announceA->grandmasterPriority2 > announceB->grandmasterPriority2)
+ if (a->announce.grandmasterPriority2 > b->announce.grandmasterPriority2)
return 1;
/* Compare GM identity */
@@ -598,16 +609,19 @@
}
/*State decision algorithm 9.3.3 Fig 26*/
-static UInteger8
-bmcStateDecision(MsgHeader *header, MsgAnnounce *announce, UInteger8 localPreference,
- const RunTimeOpts *rtOpts, PtpClock *ptpClock)
+static UInteger8
+bmcStateDecision(ForeignMasterRecord *foreign, const RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
Integer8 comp;
Boolean newBM;
- UInteger8 currentLocalPref = 0;
- newBM = ((memcmp(header->sourcePortIdentity.clockIdentity,
+ ForeignMasterRecord me;
+
+ memset(&me, 0, sizeof(me));
+ me.localPreference = LOWEST_LOCALPREFERENCE;
+
+ newBM = ((memcmp(foreign->header.sourcePortIdentity.clockIdentity,
ptpClock->parentPortIdentity.clockIdentity,CLOCK_IDENTITY_LENGTH)) ||
- (header->sourcePortIdentity.portNumber != ptpClock->parentPortIdentity.portNumber));
+ (foreign->header.sourcePortIdentity.portNumber != ptpClock->parentPortIdentity.portNumber));
if (ptpClock->slaveOnly) {
@@ -615,17 +629,17 @@
if(newBM && (ptpClock->parentGrants != NULL)) {
ptpClock->previousGrants = ptpClock->parentGrants;
}
- s1(header,announce,ptpClock, rtOpts);
+ s1(&foreign->header,&foreign->announce,ptpClock, rtOpts);
if(rtOpts->unicastNegotiation) {
ptpClock->parentGrants = findUnicastGrants(&ptpClock->parentPortIdentity, 0,
- ptpClock->unicastGrants, &ptpClock->grantIndex, ptpClock->unicastDestinationCount ,
+ ptpClock->unicastGrants, &ptpClock->grantIndex, ptpClock->unicastDestinationCount,
FALSE);
}
if (newBM) {
ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
- displayPortIdentity(&header->sourcePortIdentity,
+ displayPortIdentity(&foreign->header.sourcePortIdentity,
"New best master selected:");
ptpClock->counters.masterChanges++;
if (ptpClock->portState == PTP_SLAVE)
@@ -637,7 +651,7 @@
}
if(rtOpts->unicastNegotiation && ptpClock->parentGrants != NULL) {
ptpClock->logAnnounceInterval = ptpClock->parentGrants->grantData[ANNOUNCE].logInterval;
- currentLocalPref = ptpClock->parentGrants->localPreference;
+ me.localPreference = ptpClock->parentGrants->localPreference;
}
return PTP_SLAVE;
}
@@ -646,20 +660,21 @@
(ptpClock->portState == PTP_LISTENING))
return PTP_LISTENING;
- copyD0(&ptpClock->msgTmpHeader,&ptpClock->msgTmp.announce,ptpClock);
+// copyD0(&me.headerk->msgTmpHeader,&ptpClock->msgTmp.announce,ptpClock);
+ copyD0(&me.header, &me.announce, ptpClock);
DBGV("local clockQuality.clockClass: %d \n", ptpClock->clockQuality.clockClass);
- comp = bmcDataSetComparison(&ptpClock->msgTmpHeader, &ptpClock->msgTmp.announce, currentLocalPref, header, announce, localPreference, ptpClock, rtOpts);
+ comp = bmcDataSetComparison(&me, foreign, ptpClock, rtOpts);
if (ptpClock->clockQuality.clockClass < 128) {
if (comp < 0) {
m1(rtOpts, ptpClock);
return PTP_MASTER;
} else if (comp > 0) {
- s1(header,announce,ptpClock, rtOpts);
+ s1(&foreign->header, &foreign->announce, ptpClock, rtOpts);
if (newBM) {
ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
- displayPortIdentity(&header->sourcePortIdentity,
+ displayPortIdentity(&foreign->header.sourcePortIdentity,
"New best master selected:");
ptpClock->counters.masterChanges++;
if(ptpClock->portState == PTP_PASSIVE)
@@ -674,9 +689,9 @@
m1(rtOpts,ptpClock);
return PTP_MASTER;
} else if (comp > 0) {
- s1(header,announce,ptpClock, rtOpts);
+ s1(&foreign->header, &foreign->announce,ptpClock, rtOpts);
if (newBM) {
- displayPortIdentity(&header->sourcePortIdentity,
+ displayPortIdentity(&foreign->header.sourcePortIdentity,
"New best master selected:");
ptpClock->counters.masterChanges++;
if(ptpClock->portState == PTP_SLAVE)
@@ -716,20 +731,14 @@
}
for (i=1,best = 0; i<ptpClock->number_foreign_records;i++)
- if ((bmcDataSetComparison(&foreignMaster[i].header,
- &foreignMaster[i].announce,
- foreignMaster[i].localPreference,
- &foreignMaster[best].header,
- &foreignMaster[best].announce,
- foreignMaster[best].localPreference,
+ if ((bmcDataSetComparison(&foreignMaster[i], &foreignMaster[best],
ptpClock, rtOpts)) < 0)
best = i;
DBGV("Best record : %d \n",best);
ptpClock->foreign_record_best = best;
- return (bmcStateDecision(&foreignMaster[best].header,
- &foreignMaster[best].announce,
- foreignMaster[best].localPreference,
+ ptpClock->bestMaster = &foreignMaster[best];
+ return (bmcStateDecision(ptpClock->bestMaster,
rtOpts,ptpClock));
}
Modified: trunk/src/constants.h
===================================================================
--- trunk/src/constants.h 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/constants.h 2015-10-19 23:57:56 UTC (rev 596)
@@ -70,6 +70,8 @@
#define DEFAULT_FOREIGN_MASTER_TIME_WINDOW 4
#define DEFAULT_FOREIGN_MASTER_THRESHOLD 2
+/* g.8265.1 local preference, lowest value */
+#define LOWEST_LOCALPREFERENCE 255
/*
section 7.6.2.4, page 55:
Modified: trunk/src/datatypes.h
===================================================================
--- trunk/src/datatypes.h 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/datatypes.h 2015-10-19 23:57:56 UTC (rev 596)
@@ -495,7 +495,8 @@
MsgAnnounce announce; /* announce message -> all datasets */
MsgHeader header; /* header -> some datasets */
UInteger8 localPreference; /* local preference - only used by telecom profile */
- UInteger32 sourceAddr; /* source address */
+ UInteger32 sourceAddr; /* source address */
+ Boolean disqualified; /* if true, this one always loses */
} ForeignMasterRecord;
/**
@@ -761,6 +762,8 @@
/* Foreign master data set */
ForeignMasterRecord *foreign;
+ /* Current best master (unless it's us) */
+ ForeignMasterRecord *bestMaster;
/* Other things we need for the protocol */
UInteger16 number_foreign_records;
Modified: trunk/src/dep/configdefaults.c
===================================================================
--- trunk/src/dep/configdefaults.c 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/dep/configdefaults.c 2015-10-19 23:57:56 UTC (rev 596)
@@ -98,6 +98,10 @@
{"ptpengine:time_traceable","y"},
{"ptpengine:frequency_traceable","y"},
{"clock:leap_seconds_file", DATADIR"/"PACKAGE_NAME"/leap-seconds.list"},
+ /*
+ * UTC offset value and UTC offset valid flag
+ * will be announced if leap file is parsed and up to date
+ */
{NULL}}
},
@@ -114,7 +118,7 @@
{NULL}}
},
- { "full-logging-instance", "Logging for all facilities using 'instance' variable which user should provide", {
+ { "full-logging-instance", "Logging for all facilities using 'instance' variable which the user should provide", {
{"global:log_status", "y"},
{"global:status_file", "@rundir@/ptpd2.@instance@.status"},
{"global:statistics_log_interval", "1"},
@@ -579,7 +583,7 @@
fileDict = dictionary_new(0);
dict = dictionary_new(0);
-//INFO("tf: %s",DEFAULT_TEMPLATE_FILE);
+
loadFileList(fileDict, DEFAULT_TEMPLATE_FILE);
loadFileList(fileDict, files);
Modified: trunk/src/dep/net.c
===================================================================
--- trunk/src/dep/net.c 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/dep/net.c 2015-10-19 23:57:56 UTC (rev 596)
@@ -902,10 +902,10 @@
for(text__=text_;found < total; text__=NULL) {
token=strtok_r(text__,", ;\t",&stash);
- tmp = 255;
+ tmp = LOWEST_LOCALPREFERENCE;
if(token!=NULL) {
if (sscanf(token,"%d", &tmp) != 1) {
- tmp = 255;
+ tmp = LOWEST_LOCALPREFERENCE;
}
}
Modified: trunk/src/dep/ptpd_dep.h
===================================================================
--- trunk/src/dep/ptpd_dep.h 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/dep/ptpd_dep.h 2015-10-19 23:57:56 UTC (rev 596)
@@ -188,6 +188,29 @@
#define clearFlag(x,y) ( *(UInteger8*)((x)+((y)<8?1:0)) &= ~(1<<((y)<8?(y):(y)-8)) )
/** \}*/
+#define DEFAULT_TOKEN_DELIM ", ;\t"
+
+/*
+ * foreach loop across substrings from var, delimited by delim, placing
+ * each token in targetvar on iteration, using id variable name prefix
+ * to allow nesting (each loop uses an individual set of variables)
+ */
+#define foreach_token_begin(id, var, targetvar, delim) {\
+ char* id_stash; \
+ char* id_text_; \
+ char* id_text__; \
+ char* targetvar; \
+ id_text_=strdup(var); \
+ for(id_text__ = id_text_;; id_text__=NULL) { \
+ targetvar = strtok_r(id_text__, delim, &id_stash); \
+ if(targetvar==NULL) break;
+
+#define foreach_token_end(id) } \
+ if(id_text_ != NULL) { \
+ free(id_text_); \
+ }\
+}
+
/** \name msg.c
*-Pack and unpack PTP messages */
/**\{*/
Modified: trunk/src/dep/sys.c
===================================================================
--- trunk/src/dep/sys.c 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/dep/sys.c 2015-10-19 23:57:56 UTC (rev 596)
@@ -336,7 +336,7 @@
/* Write a formatted string to file pointer */
int writeMessage(FILE* destination, uint32_t *lastHash, int priority, const char * format, va_list ap) {
- char buf[PATH_MAX +1];
+
extern RunTimeOpts rtOpts;
extern Boolean startupInProgress;
@@ -344,6 +344,7 @@
char time_str[MAXTIMESTR];
struct timeval now;
#ifndef RUNTIME_DEBUG
+ char buf[PATH_MAX +1];
uint32_t hash;
va_list ap1;
#endif /* RUNTIME_DEBUG */
@@ -1065,7 +1066,7 @@
if(rtOpts->unicastNegotiation && ptpClock->parentGrants != NULL ) {
fprintf(out, ", localPref %d", ptpClock->parentGrants->localPreference);
}
- fprintf(out, "\n");
+ fprintf(out, "%s\n", (ptpClock->bestMaster != NULL && ptpClock->bestMaster->disqualified) ? " (timeout)" : "");
}
if(ptpClock->clockQuality.clockClass < 128 ||
Modified: trunk/src/protocol.c
===================================================================
--- trunk/src/protocol.c 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/protocol.c 2015-10-19 23:57:56 UTC (rev 596)
@@ -745,6 +745,7 @@
ptpClock->clockQuality.clockClass != SLAVE_ONLY_CLOCK_CLASS) {
ptpClock->number_foreign_records = 0;
ptpClock->foreign_record_i = 0;
+ ptpClock->bestMaster = NULL;
m1(rtOpts,ptpClock);
toState(PTP_MASTER, rtOpts, ptpClock);
@@ -761,15 +762,8 @@
* otherwise, timer will cycle and we will reset.
* Also don't clear the FMR just yet.
*/
- if (ptpClock->grandmasterClockQuality.clockClass != 255 &&
- ptpClock->grandmasterPriority1 != 255 &&
- ptpClock->grandmasterPriority2 != 255) {
- ptpClock->grandmasterClockQuality.clockClass = 255;
- ptpClock->grandmasterPriority1 = 255;
- ptpClock->grandmasterPriority2 = 255;
- ptpClock->foreign[ptpClock->foreign_record_best].announce.grandmasterPriority1=255;
- ptpClock->foreign[ptpClock->foreign_record_best].announce.grandmasterPriority2=255;
- ptpClock->foreign[ptpClock->foreign_record_best].announce.grandmasterClockQuality.clockClass=255;
+ if (!ptpClock->bestMaster->disqualified) {
+ ptpClock->bestMaster->disqualified = TRUE;
WARNING("GM announce timeout, disqualified current best GM\n");
ptpClock->counters.announceTimeouts++;
}
@@ -790,7 +784,7 @@
WARNING("No active masters present. Resetting port.\n");
ptpClock->number_foreign_records = 0;
ptpClock->foreign_record_i = 0;
-
+ ptpClock->bestMaster = NULL;
/* if flipping between primary and backup interface, a full nework re-init is required */
if(rtOpts->backupIfaceEnabled) {
ptpClock->runningBackupInterface = !ptpClock->runningBackupInterface;
@@ -1436,7 +1430,7 @@
{
UnicastGrantTable *nodeTable = NULL;
- UInteger8 localPreference = 0;
+ UInteger8 localPreference = LOWEST_LOCALPREFERENCE;
DBGV("HandleAnnounce : Announce message received : \n");
@@ -1563,7 +1557,7 @@
if (rtOpts->announceTimeoutGracePeriod &&
ptpClock->announceTimeouts > 0) {
- NOTICE("Received Announce message from master - cancelling timeout\n");
+ NOTICE("Received Announce message from current master - cancelling timeout\n");
ptpClock->announceTimeouts = 0;
/* we are available for clock control again */
ptpClock->clockControl.available = TRUE;
@@ -2689,7 +2683,8 @@
}
}
-/* Only accept the management / signaling message if it satisfies 15.3.1 Table 36 */
+/* Only accept the management / signaling message if it satisfies 15.3.1 Table 36 */
+/* Also 13.12.1 table 32 */
Boolean
acceptPortIdentity(PortIdentity thisPort, PortIdentity targetPort)
{
@@ -2703,12 +2698,18 @@
return TRUE;
}
- /* equal clockIDs and target port number is wildcard - this was missing up to 12oct15 */
+ /* equal clockIDs and target port number is wildcard */
if(!memcmp(targetPort.clockIdentity, thisPort.clockIdentity, CLOCK_IDENTITY_LENGTH) &&
(targetPort.portNumber == allOnesPortNumber)) {
return TRUE;
}
+ /* target clock ID is wildcard, port number matches */
+ if(!memcmp(targetPort.clockIdentity, allOnesClkIdentity, CLOCK_IDENTITY_LENGTH) &&
+ (targetPort.portNumber == thisPort.portNumber)) {
+ return TRUE;
+ }
+
/* target port and clock IDs are both wildcard */
if(!memcmp(targetPort.clockIdentity, allOnesClkIdentity, CLOCK_IDENTITY_LENGTH) &&
(targetPort.portNumber == allOnesPortNumber)) {
@@ -3586,6 +3587,7 @@
DBGV("addForeign : AnnounceMessage incremented \n");
msgUnpackHeader(buf,&ptpClock->foreign[j].header);
msgUnpackAnnounce(buf,&ptpClock->foreign[j].announce);
+ ptpClock->foreign[j].disqualified = FALSE;
ptpClock->foreign[j].localPreference = localPreference;
break;
}
@@ -3600,7 +3602,7 @@
ptpClock->number_foreign_records++;
}
- /* Preserve best master record from overwriting (sf FR #22) - use next slot*/
+ /* Preserve best master record from overwriting (sf FR #22) - use next slot */
if (ptpClock->foreign_record_i == ptpClock->foreign_record_best) {
ptpClock->foreign_record_i++;
ptpClock->foreign_record_i %= ptpClock->number_foreign_records;
@@ -3615,7 +3617,8 @@
header->sourcePortIdentity.portNumber;
ptpClock->foreign[j].foreignMasterAnnounceMessages = 0;
ptpClock->foreign[j].localPreference = localPreference;
- ptpClock->foreign[j].sourceAddr = sourceAddr;
+ ptpClock->foreign[j].sourceAddr = sourceAddr;
+ ptpClock->foreign[j].disqualified = FALSE;
/*
* header and announce field of each Foreign Master are
* usefull to run Best Master Clock Algorithm
Modified: trunk/src/ptpd2.8.in
===================================================================
--- trunk/src/ptpd2.8.in 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/ptpd2.8.in 2015-10-19 23:57:56 UTC (rev 596)
@@ -83,7 +83,8 @@
Display built-in configuration templates
.TP
\fB-t --templates \fI[name],[name],...\fR
-Apply one or more configuration templates in this order (\fIsee man(5) ptpd2.conf\fR)
+Apply one or more configuration templates in this order (\fIsee man(5) ptpd2.conf\fR),
+also see \fIptpengine:template_files\fR and the \
.TP
\fB-S --statistics-file \fIPATH\fR
Path to statistics file (also \fIglobal:statistics_file\fR)
Modified: trunk/src/ptpd2.conf.5.in
===================================================================
--- trunk/src/ptpd2.conf.5.in 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/ptpd2.conf.5.in 2015-10-19 23:57:56 UTC (rev 596)
@@ -59,16 +59,34 @@
\fBNote:\fR for the same effect, ptpd can be run from command line, such as \fI --config=/path/to/file --variables:instance=server15\fR
-.SH CONFIGURATION TEMPLATES
-As of version 2.3.1.1, ptpd enables the user to minimise the configuration effort for common scenarios, using built-in templates.
-A template is a named set of pre-defined settings whic are prepended before any other settings, so user can still overwrite
-settings provided by the template. To use this feature, set \fIglobal:config_templates=[name],[name],...\fR in the configuration file,
-or run ptpd with \fI--global:config_templates=[name],[name],...\fR. Multiple templates can be specified, separated by comma, space
-or tab; they are applied in the order they are provided, so template settings override any overlapping settings from previous
-templates specified.
+.SH CONFIGURATION TEMPLATES AND TEMPLATE FILES
+As of version 2.3.1.1, ptpd enables the user to minimise the configuration effort for common scenarios, using built-in templates
+and template files. A template is a named set of pre-defined settings whic are prepended before any other settings, so user can
+still overwrite settings provided by the template. To use this feature, set \fIglobal:config_templates=[name],[name],...\fR in the
+configuration file, or run ptpd with \fI--global:config_templates=[name],[name],...\fR. Multiple templates can be specified,
+separated by comma, space or tab; they are applied in the order they are provided, so template settings override any overlapping
+settings from previous templates specified. Templates can include \fIuser-defined variables\fR.
-To see the list of available templates, run ptpd with \fI-T\fR or \fI--templates\fR
+A number of \fItemplate files\fR can also be supplied with the \fIglobal:template_files\fR setting
+(comma, space or tab separated lis of file paths). The template files will be processed in the order they are provided in,
+so for overlapping settings, the last template applied overrides settings applied by any previous
+templates. PTPd will also try to load a default template file on startup: \fItemplates.conf\fR
+from the default data directory: \fI@prefix@/share/@PACKAGE_NAME@/templates.conf\fR
+The template file is formatted in .ini style - each template is a section defined as
+\fI[template-name]\fR, followed by a number of settings specified as \fIsection:setting\fR.
+
+\fBExample\fR:
+
+[my-template]
+
+global:verbose_foreground=Y
+
+ptpengine:preset=slaveonly
+
+
+To see the list of available built-in templates, run ptpd with \fI-T\fR or \fI--show-templates\fR
+
.SH CONFIGURATION VARIABLES
.RS 0
.TP 8
@@ -181,7 +199,8 @@
uses multicast for sync and announce, and unicast for delay request and response
.TP 12
\fIunicast\fR
-uses unicast for all transmission. When unicast mode is selected, destination IP(s) (\fIptpengine:unicast_destinations\fR) must be configured
+uses unicast for all transmission. When unicast mode is selected, destination IP(s) (\fIptpengine:unicast_
+destinations\fR) must be configured
depending on unicast negotiation setting (\fIptpengine:unicast_negotiation\fR) and master or slave role
(see: \fIptpengine:unicast_destinations\fR)
.RE
@@ -2383,6 +2402,42 @@
.RE
.RS 0
.TP 8
+\fBglobal:config_templates [\fISTRING\fB]\fR
+.RS 8
+.TP 8
+\fBusage\fR
+Comma, space or tab-separated list of template names to be applied to the configuration
+(see \fICONFIGURATION TEMPLATES AND TEMPLATE FILES\fR section). Templates are applied in the order
+they are specified, so any overlapping settings from one template are overridden with settings
+from the following template(s). PTPd provides some built-in templates - see the templates section
+above; to see the built-in templates, run ptpd with \fI-T\fR or \fI--show-templates\fR.
+.TP 8
+\fBdefault\fR
+\fI[none]\fR
+
+.RE
+.RE
+.RS 0
+.TP 8
+\fBglobal:template_files [\fISTRING\fB]\fR
+.RS 8
+.TP 8
+\fBusage\fR
+Comma, space or tab-separated list of template file paths to be loaded
+(see \fICONFIGURATION TEMPLATES AND TEMPLATE FILES\fR section). Template
+files are also loaded in the order they are provided, so templates in one file
+can be extended by templates in the next file(s); any overlapping settings are overridden
+by following files. PTPd will not exit when one or more template files cannot be opened.
+PTPd will always try to load \fI@prefix@/share/@PACKAGE_NAME@/templates.conf\fR on startup.
+.TP 8
+\fBdefault\fR
+\fI[none]\fR
+
+
+.RE
+.RE
+.RS 0
+.TP 8
\fBglobal:enable_snmp [\fIBOOLEAN\fB]\fR
.RS 8
.TP 8
Modified: trunk/src/ptpd2.conf.default-full
===================================================================
--- trunk/src/ptpd2.conf.default-full 2015-10-16 19:49:23 UTC (rev 595)
+++ trunk/src/ptpd2.conf.default-full 2015-10-19 23:57:56 UTC (rev 596)
@@ -46,6 +46,18 @@
;
ptpengine:unicast_negotiation = N
+; When using unicast negotiation (slave), accept PTP messages from any master.
+; By default, only messages from acceptable masters (ptpengine:unicast_destinations)
+; are accepted, and only if transmission was granted by the master
+;
+ptpengine:unicast_any_master = N
+
+; PTP port number wildcard mask applied onto port identities when running
+; unicast negotiation: allows multiple port identities to be accepted as one.
+; This option can be used as a workaround where a node sends signaling messages and
+; timing messages with different port identities
+ptpengine:unicast_port_mask = 0
+
; Disable Best Master Clock Algorithm for unicast masters:
; Only effective for masteronly preset - all Announce messages
; will be ignored and clock will transition directly into MASTER state.
@@ -60,6 +72,12 @@
; in Ethernet mode).
ptpengine:use_libpcap = N
+; Disable UDP checksum validation on UDP sockets (Linux only).
+; Workaround for situations where a node (like Transparent Clock).
+; does not rewrite checksums
+;
+ptpengine:disable_udp_checksums = Y
+
; Delay detection mode used - use DELAY_DISABLED for syntonisation only
; (no full synchronisation).
; Options: E2E P2P DELAY_DISABLED
@@ -100,7 +118,7 @@
; announced by best master, even if the the
; currrentUtcOffsetValid flag is announced FALSE.
; NOTE: this behaviour is not part of the standard.
-ptpengine:always_respect_utc_offset = N
+ptpengine:always_respect_utc_offset = Y
; Compatibility extension to BMC algorithm: when enabled,
; BMC for both master and save clocks will prefer masters
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-16 19:49:25
|
Revision: 595
http://sourceforge.net/p/ptpd/code/595
Author: wowczarek
Date: 2015-10-16 19:49:23 +0000 (Fri, 16 Oct 2015)
Log Message:
-----------
- added descriptions to built-in templates
- support for (multiple) template files
global:template_files + default file
$datadir/ptpd/templates.conf for user's templates
- fixed ptpd not printing startup messages until
config is fully parsed, broken since 2.3.0
(explicitly set nondaemon for -C and -V)
- TODO file added to keep track of what's left
until each release is complete
Modified Paths:
--------------
trunk/src/dep/configdefaults.c
trunk/src/dep/configdefaults.h
trunk/src/dep/daemonconfig.c
trunk/src/dep/iniparser/dictionary.c
trunk/src/dep/iniparser/dictionary.h
trunk/src/dep/iniparser/iniparser.c
trunk/src/dep/iniparser/iniparser.h
trunk/src/dep/startup.c
trunk/src/dep/sys.c
Added Paths:
-----------
trunk/TODO
Added: trunk/TODO
===================================================================
--- trunk/TODO (rev 0)
+++ trunk/TODO 2015-10-16 19:49:23 UTC (rev 595)
@@ -0,0 +1,9 @@
+# not part of distribution - TODO notes to implement before next release
+
+2.3.1.1 / 2.3.2:
+
+- man page updates for template files
+- clock ID printed in reverse in L2 mode
+ with (grandmasterID present?)
+- complete built-in templates
+- add dummy or populated default template file
Modified: trunk/src/dep/configdefaults.c
===================================================================
--- trunk/src/dep/configdefaults.c 2015-10-15 04:11:00 UTC (rev 594)
+++ trunk/src/dep/configdefaults.c 2015-10-16 19:49:23 UTC (rev 595)
@@ -1,5 +1,4 @@
-/*-
- * Copyright (c) 2013-2015 Wojciech Owczarek,
+/* Copyright (c) 2013-2015 Wojciech Owczarek,
*
* All Rights Reserved
*
@@ -38,6 +37,9 @@
#define CONFIG_ISTRUE(key) \
(iniparser_getboolean(dict,key,FALSE)==TRUE)
+#define CONFIG_ISSET(key) \
+ (strcmp(iniparser_getstring(dict, key, ""),"") != 0)
+
#define IS_QUIET()\
( CONFIG_ISTRUE("%quiet%:%quiet%") )
@@ -50,7 +52,7 @@
static const ConfigTemplate configTemplates[] = {
- { "g8265-e2e-master", {
+ { "g8265-e2e-master", "ITU-T G.8265.1 (Telecom profile) unicast master", {
{"ptpengine:preset", "masteronly"},
{"ptpengine:ip_mode", "unicast"},
{"ptpengine:unicast_negotiation", "y"},
@@ -65,7 +67,7 @@
{NULL}}
},
- { "g8265-e2e-slave", {
+ { "g8265-e2e-slave", "ITU-T G.8265.1 (Telecom profile) unicast slave", {
{"ptpengine:preset", "slaveonly"},
{"ptpengine:ip_mode", "unicast"},
{"ptpengine:unicast_negotiation", "y"},
@@ -75,7 +77,7 @@
{NULL}}
},
- { "layer2-p2p-master", {
+ { "layer2-p2p-master", "Layer 2 master using Peer to Peer", {
{"ptpengine:transport","ethernet"},
{"ptpengine:delay_mechanism","P2P"},
{"ptpengine:preset","masteronly"},
@@ -83,7 +85,7 @@
{NULL}}
},
- { "layer2-p2p-slave", {
+ { "layer2-p2p-slave", "Layer 2 slave running End to End", {
{"ptpengine:transport","ethernet"},
{"ptpengine:delay_mechanism","E2E"},
{"ptpengine:preset","slaveonly"},
@@ -91,7 +93,7 @@
{NULL}}
},
- { "valid-utc-properties", {
+ { "valid-utc-properties", "Basic property set to announce valid UTC, UTC offset and leap seconds", {
{"ptpengine:ptp_timescale","PTP"},
{"ptpengine:time_traceable","y"},
{"ptpengine:frequency_traceable","y"},
@@ -99,7 +101,7 @@
{NULL}}
},
- { "full-logging", {
+ { "full-logging", "Enable logging for all facilities (statistics, status, log file)", {
{"global:log_status", "y"},
{"global:status_file", "/var/run/ptpd2.status"},
{"global:statistics_log_interval", "1"},
@@ -112,7 +114,7 @@
{NULL}}
},
- { "full-logging-instance", {
+ { "full-logging-instance", "Logging for all facilities using 'instance' variable which user should provide", {
{"global:log_status", "y"},
{"global:status_file", "@rundir@/ptpd2.@instance@.status"},
{"global:statistics_log_interval", "1"},
@@ -133,13 +135,13 @@
/* template of a template looks like this... */
/*
- { "template-name", {
+ { "template-name", "template description", {
{"section:key","value"},
{"",""},
{NULL}}
},
- { "", {
+ { "", "", {
{"",""},
{"",""},
{NULL}}
@@ -488,53 +490,139 @@
return ret;
}
+/* Apply template search from dictionary src to dictionary dst */
+static int
+applyTemplateFromDictionary(dictionary *dict, dictionary *src, char *search, int overwrite) {
+ char *key, *value, *pos;
+ int i = 0;
+ int found;
+
+ /* -1 on not found, 0+ on actual applies */
+ found = -1;
+
+ for(i=0; i<src->n; i++) {
+ key = src->key[i];
+ value = src->val[i];
+ pos = strstr(key, ":");
+ if(value != NULL && pos != NULL) {
+ *pos = '\0';
+ pos++;
+ if(!strcmp(search, key) && (strstr(pos,":") != NULL)) {
+ if(found < 0) found = 0;
+ if( overwrite || !CONFIG_ISSET(pos)) {
+ DBG("template %s setting %s to %s\n", search, pos, value);
+ dictionary_set(dict, pos, value);
+ found++;
+ }
+ }
+ /* reverse the damage - no need for strdup() */
+ pos--;
+ *pos = ':';
+ }
+ }
+
+ return found;
+
+}
+
+static void loadFileList(dictionary *dict, char *list) {
+
+ char* stash;
+ char* text_;
+ char* text__;
+ char *filename;
+
+ if(dict == NULL) return;
+ if(!strlen(list)) return;
+
+ text_=strdup(list);
+
+ for(text__=text_;; text__=NULL) {
+ filename=strtok_r(text__,", ;\t",&stash);
+ if(filename==NULL) break;
+ if(!iniparser_merge_file(dict, filename,1)) {
+ ERROR("Could not load template file %s\n", filename);
+ } else {
+ INFO("Loaded template file %s\n",filename);
+ }
+ }
+
+ if(text_ != NULL) {
+ free(text_);
+ }
+
+}
+
/* split list to tokens, look for each template and apply it if found */
int
-applyConfigTemplates(char *templateNames, dictionary *dict) {
+applyConfigTemplates(dictionary *target, char *templateNames, char *files) {
ConfigTemplate *template = NULL;
TemplateOption *option = NULL;
char *templateName = NULL;
- Boolean found = 0;
+ int iFound = -1;
+ int fFound = -1;
+ dictionary *fileDict;
+ dictionary *dict;
+
char* stash;
char* text_;
char* text__;
- if(dict == NULL) {
+ if(target == NULL) {
return 0;
}
- if(strlen(templateNames)==0) return 0;
+ if(!strlen(templateNames)) return 0;
+ fileDict = dictionary_new(0);
+ dict = dictionary_new(0);
+//INFO("tf: %s",DEFAULT_TEMPLATE_FILE);
+ loadFileList(fileDict, DEFAULT_TEMPLATE_FILE);
+ loadFileList(fileDict, files);
+
text_=strdup(templateNames);
for(text__=text_;; text__=NULL) {
+ iFound = -1;
+ fFound = -1;
+
+ /* apply from built-in templates */
templateName=strtok_r(text__,", ;\t",&stash);
if(templateName==NULL) break;
- found = 0;
template = (ConfigTemplate*)configTemplates;
while(template->name != NULL) {
if(!strcmp(template->name, templateName)) {
- DBG("Loading config template %s\n", template->name);
+ if(iFound < 0) iFound = 0;
+ DBG("Loading built-in config template %s\n", template->name);
option = (TemplateOption*)template->options;
while(option->name != NULL) {
dictionary_set(dict, option->name, option->value);
DBG("----> %s = %s",option->name, option->value);
option++;
+ iFound++;
}
- found = 1;
- if (!IS_QUIET()) NOTICE("Applied configuration template \"%s\"\n", templateName);
break;
}
template++;
}
- if(!found) {
- if (!IS_QUIET()) WARNING("Configuration template \"%s\" not found\n", templateName);
+ /* apply from previously loaded files */
+ fFound = applyTemplateFromDictionary(dict, fileDict, templateName, 1);
+
+ if (!IS_QUIET()) {
+ if((iFound < 0) && (fFound < 0)) {
+ WARNING("Configuration template \"%s\" not found\n", templateName);
+ } else {
+ if(iFound < 0) iFound = 0;
+ if(fFound < 0) fFound = 0;
+ NOTICE("Applied configuration template \"%s\" (%d matches)\n", templateName,
+ iFound + fFound);
+ }
}
}
@@ -543,6 +631,10 @@
free(text_);
}
+ /* preserve existing settings */
+ dictionary_merge(dict, target, 0 , !IS_QUIET(), NULL);
+ dictionary_del(&fileDict);
+ dictionary_del(&dict);
return 0;
}
@@ -553,17 +645,18 @@
ConfigTemplate *template = NULL;
TemplateOption *option = NULL;
-
+ printf("\n");
template = (ConfigTemplate*)configTemplates;
while(template->name != NULL) {
- printf("Template: %s\n\n", template->name);
+ printf(" Template: %s\n", template->name);
+ printf("Description: %s\n\n", template->description);
option = (TemplateOption*)template->options;
while(option->name != NULL) {
printf("\t\t%s=\"%s\"\n", option->name, option->value);
option++;
}
template++;
- printf("\n");
+ printf("\n-\n\n");
}
}
Modified: trunk/src/dep/configdefaults.h
===================================================================
--- trunk/src/dep/configdefaults.h 2015-10-15 04:11:00 UTC (rev 594)
+++ trunk/src/dep/configdefaults.h 2015-10-16 19:49:23 UTC (rev 595)
@@ -12,6 +12,8 @@
#include <stddef.h>
#include "iniparser/iniparser.h"
+#define DEFAULT_TEMPLATE_FILE DATADIR"/"PACKAGE_NAME"/templates.conf"
+
typedef struct {
char * name;
char * value;
@@ -19,6 +21,7 @@
typedef struct {
char * name;
+ char * description;
TemplateOption options[100];
} ConfigTemplate;
@@ -42,7 +45,7 @@
};
void loadDefaultSettings( RunTimeOpts* rtOpts );
-int applyConfigTemplates(char *templateNames, dictionary *dict);
+int applyConfigTemplates(dictionary *dict, char *templateNames, char *files);
PtpEnginePreset getPtpPreset(int presetNumber, RunTimeOpts* rtOpts);
void dumpConfigTemplates();
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-10-15 04:11:00 UTC (rev 594)
+++ trunk/src/dep/daemonconfig.c 2015-10-16 19:49:23 UTC (rev 595)
@@ -830,6 +830,7 @@
}
+
/**
* Iterate through dictionary dict (template) and check for keys in source
* that are not present in the template - display only.
@@ -870,6 +871,7 @@
* Therefore loadDefaultSettings should normally be used before parseConfig
*/
+
/*-
* WARNING: for ease of use, a limited number of keys is set
* via getopt in loadCommanLineOptions(). When renaming settings, make sure
@@ -900,13 +902,19 @@
/*
* apply the configuration template(s) as statically defined in configdefaults.c
- * The list of templates is a comma, space or tab separated names. Any templates
- * are applied before anything else: so any settings after this can override
+ * and in template files. The list of templates and files is comma, space or tab separated.
+ * names. Any templates are applied before anything else: so any settings after this can override
*/
if (CONFIG_ISPRESENT("global:config_templates")) {
- applyConfigTemplates(dictionary_get(dict, "global:config_templates", ""), dict);
+ applyConfigTemplates(
+ dict,
+ dictionary_get(dict, "global:config_templates", ""),
+ dictionary_get(dict, "global:template_files", "")
+ );
+
/* also set the template names in the target dictionary */
dictionary_set(target, "global:config_templates", dictionary_get(dict, "global:config_templates", ""));
+ dictionary_set(target, "global:template_files", dictionary_get(dict, "global:template_files", ""));
}
parseUserVariables(dict, target);
@@ -2304,7 +2312,7 @@
/* make sure the %x% special keys are unset */
HELP_END();
- dictionary_merge( dict, *target, 0, NULL);
+ dictionary_merge( dict, *target, 0, 0, NULL);
dictionary_del(&dict);
return TRUE;
@@ -2663,10 +2671,12 @@
return FALSE;
/* run in foreground */
case 'C':
+ rtOpts->nonDaemon=1;
dictionary_set(dict,"global:foreground", "Y");
break;
/* verbose mode */
case 'V':
+ rtOpts->nonDaemon=1;
dictionary_set(dict,"global:foreground", "Y");
dictionary_set(dict,"global:verbose_foreground", "Y");
break;
Modified: trunk/src/dep/iniparser/dictionary.c
===================================================================
--- trunk/src/dep/iniparser/dictionary.c 2015-10-15 04:11:00 UTC (rev 594)
+++ trunk/src/dep/iniparser/dictionary.c 2015-10-16 19:49:23 UTC (rev 595)
@@ -435,13 +435,15 @@
return ;
}
-int dictionary_merge(dictionary* source, dictionary* dest, int warn, const char* warnStr)
+int dictionary_merge(dictionary* source, dictionary* dest, int overwrite, int warn, const char* warnStr)
{
int i = 0;
+ int clobber = 1;
if( source == NULL || dest == NULL) return -1;
+ if(warnStr == NULL) warnStr = "";
for(i = 0; i < source->n; i++) {
if(source->key[i] == NULL)
@@ -450,20 +452,28 @@
if((source->val[i] == NULL) || (strlen(source->val[i])==0))
continue;
/* no need to warn for settings whose value will not change */
- if(warn && (strcmp(dictionary_get(dest,source->key[i],""),"") != 0) &&
+ if((strcmp(dictionary_get(dest,source->key[i],""),"") != 0) &&
(strcmp(dictionary_get(dest,source->key[i],""),source->val[i]) != 0)) {
- WARNING("Warning: %s=\"%s\" : setting will be overwritten with value \"%s\" %s\n",
- source->key[i], dictionary_get(dest,source->key[i],""),
- source->val[i], warnStr);
+ if(!overwrite && warn) {
+ WARNING("Warning: %s=\"%s\" : value \"%s\" takes priority %s\n",
+ source->key[i], source->val[i],
+ dictionary_get(dest,source->key[i],""), warnStr);
+ }
+ clobber = 1;
+ if(!overwrite) {
+ clobber = 0;
+ }
}
- if ( dictionary_set( dest, source->key[i], source->val[i]) != 0)
- return -1;
+ if (clobber) {
+ if(dictionary_set( dest, source->key[i], source->val[i]) != 0) {
+ return -1;
+ }
+ }
}
return 0;
}
-
/* Test code */
#ifdef TESTDIC
#define NVALS 20000
Modified: trunk/src/dep/iniparser/dictionary.h
===================================================================
--- trunk/src/dep/iniparser/dictionary.h 2015-10-15 04:11:00 UTC (rev 594)
+++ trunk/src/dep/iniparser/dictionary.h 2015-10-16 19:49:23 UTC (rev 595)
@@ -184,6 +184,6 @@
/*--------------------------------------------------------------------------*/
void dictionary_dump(dictionary * d, FILE * out);
-int dictionary_merge(dictionary * source, dictionary * dest, int warn, const char* warnStr);
+int dictionary_merge(dictionary * source, dictionary * dest, int overwrite, int warn, const char* warnStr);
#endif
Modified: trunk/src/dep/iniparser/iniparser.c
===================================================================
--- trunk/src/dep/iniparser/iniparser.c 2015-10-15 04:11:00 UTC (rev 594)
+++ trunk/src/dep/iniparser/iniparser.c 2015-10-16 19:49:23 UTC (rev 595)
@@ -735,6 +735,23 @@
return dict ;
}
+
+int iniparser_merge_file(dictionary *dict, const char *filename, int overwrite) {
+
+ dictionary *src;
+
+ if ((src = iniparser_load(filename)) == NULL) {
+ return 0;
+ }
+
+ dictionary_merge(src, dict, overwrite, 0, NULL);
+
+ dictionary_del(&src);
+
+ return 1;
+
+}
+
/*-------------------------------------------------------------------------*/
/**
@brief Free all memory associated to an ini dictionary
Modified: trunk/src/dep/iniparser/iniparser.h
===================================================================
--- trunk/src/dep/iniparser/iniparser.h 2015-10-15 04:11:00 UTC (rev 594)
+++ trunk/src/dep/iniparser/iniparser.h 2015-10-16 19:49:23 UTC (rev 595)
@@ -291,6 +291,10 @@
/*--------------------------------------------------------------------------*/
dictionary * iniparser_load(const char * ininame);
+int iniparser_merge_file(dictionary *dict, const char * filename, int overwrite);
+
+dictionary * iniparser_load_list(const char* list);
+
/*-------------------------------------------------------------------------*/
/**
@brief Free all memory associated to an ini dictionary
Modified: trunk/src/dep/startup.c
===================================================================
--- trunk/src/dep/startup.c 2015-10-15 04:11:00 UTC (rev 594)
+++ trunk/src/dep/startup.c 2015-10-16 19:49:23 UTC (rev 595)
@@ -170,7 +170,7 @@
dictionary_del(&tmpConfig);
goto end;
}
- dictionary_merge(rtOpts->cliConfig, tmpConfig, 1, "from command line");
+ dictionary_merge(rtOpts->cliConfig, tmpConfig, 0, 1, "from command line");
/* Load default config to fill in the blanks in the config file */
RunTimeOpts tmpOpts;
loadDefaultSettings(&tmpOpts);
@@ -716,14 +716,14 @@
/* config file settings overwrite all others, except for empty strings */
INFO("Loading configuration file: %s\n",rtOpts->configFile);
if(loadConfigFile(&rtOpts->candidateConfig, rtOpts)) {
- dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 1, "from command line");
+ dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 0, 1, "from command line");
} else {
*ret = 1;
- dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 1, "from command line");
+ dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 0, 1, "from command line");
goto configcheck;
}
} else {
- dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 1, "from command line");
+ dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 0, 1, "from command line");
}
/**
* This is where the final checking of the candidate settings container happens.
Modified: trunk/src/dep/sys.c
===================================================================
--- trunk/src/dep/sys.c 2015-10-15 04:11:00 UTC (rev 594)
+++ trunk/src/dep/sys.c 2015-10-16 19:49:23 UTC (rev 595)
@@ -440,7 +440,10 @@
{
extern RunTimeOpts rtOpts;
extern Boolean startupInProgress;
- va_list ap;
+ va_list ap , ap1;
+
+ va_copy(ap1, ap);
+ va_start(ap1, format);
va_start(ap, format);
#ifdef RUNTIME_DEBUG
@@ -450,17 +453,19 @@
#endif
/* log level filter */
- if(priority > rtOpts.logLevel)
+ if(priority > rtOpts.logLevel) {
goto end;
-
+ }
/* If we're using a log file and the message has been written OK, we're done*/
if(rtOpts.eventLog.logEnabled && rtOpts.eventLog.logFP != NULL) {
if(writeMessage(rtOpts.eventLog.logFP, &rtOpts.eventLog.lastHash, priority, format, ap) > 0) {
maintainLogSize(&rtOpts.eventLog);
if(!startupInProgress)
goto end;
- else
+ else {
+ rtOpts.eventLog.lastHash = 0;
goto std_err;
+ }
}
}
@@ -487,17 +492,21 @@
syslogOpened = TRUE;
}
vsyslog(priority, format, ap);
- if (!startupInProgress)
+ if (!startupInProgress) {
goto end;
- else
+ }
+ else {
+ rtOpts.eventLog.lastHash = 0;
goto std_err;
+ }
}
std_err:
- va_start(ap, format);
+
/* Either all else failed or we're running in foreground - or we also log to stderr */
- writeMessage(stderr, &rtOpts.eventLog.lastHash, priority, format, ap);
+ writeMessage(stderr, &rtOpts.eventLog.lastHash, priority, format, ap1);
end:
+ va_end(ap1);
va_end(ap);
return;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-15 04:11:02
|
Revision: 594
http://sourceforge.net/p/ptpd/code/594
Author: wowczarek
Date: 2015-10-15 04:11:00 +0000 (Thu, 15 Oct 2015)
Log Message:
-----------
- prevent from leaving multicast group zero
- only join necessary multicast group,
tested when switching between e2e and p2p
while reloading ptpd
Modified Paths:
--------------
trunk/src/dep/datatypes_dep.h
trunk/src/dep/net.c
Modified: trunk/src/dep/datatypes_dep.h
===================================================================
--- trunk/src/dep/datatypes_dep.h 2015-10-14 19:46:42 UTC (rev 593)
+++ trunk/src/dep/datatypes_dep.h 2015-10-15 04:11:00 UTC (rev 594)
@@ -112,7 +112,8 @@
/* used for tracking the last TTL set */
int ttlGeneral;
int ttlEvent;
- Boolean joinedMulticast;
+ Boolean joinedPeer;
+ Boolean joinedGeneral;
struct ether_addr etherDest;
struct ether_addr peerEtherDest;
Boolean txTimestampFailure;
Modified: trunk/src/dep/net.c
===================================================================
--- trunk/src/dep/net.c 2015-10-14 19:46:42 UTC (rev 593)
+++ trunk/src/dep/net.c 2015-10-15 04:11:00 UTC (rev 594)
@@ -98,6 +98,10 @@
{
struct ip_mreq imr;
+ if(!multicastAddr || !netPath->interfaceAddr.s_addr) {
+ return TRUE;
+ }
+
/* Close General Multicast */
imr.imr_multiaddr.s_addr = multicastAddr;
imr.imr_interface.s_addr = netPath->interfaceAddr.s_addr;
@@ -106,7 +110,7 @@
&imr, sizeof(struct ip_mreq));
setsockopt(netPath->generalSock, IPPROTO_IP, IP_DROP_MEMBERSHIP,
&imr, sizeof(struct ip_mreq));
-
+
return TRUE;
}
@@ -133,7 +137,7 @@
/*
* For future use: Check if IPv4 address is multiast -
- * If last 4 bits of an address are 0xE (1110), it's multicast
+ * If first 4 bits of an address are 0xE (1110), it's multicast
*/
/*
static Boolean
@@ -560,7 +564,7 @@
}
/* this allows for leaving groups only if joined */
- netPath->joinedMulticast = TRUE;
+ netPath->joinedGeneral = TRUE;
netPath->multicastAddr = netAddr.s_addr;
if(!netInitMulticastIPv4(netPath, netPath->multicastAddr)) {
@@ -569,6 +573,9 @@
/* End of General multicast Ip address init */
+ if(rtOpts->delayMechanism != P2P) {
+ return TRUE;
+ }
/* Init Peer multicast IP address */
strncpy(addrStr, PEER_PTP_DOMAIN_ADDRESS, NET_ADDRESS_LENGTH);
@@ -576,6 +583,10 @@
ERROR("failed to encode multicast address: %s\n", addrStr);
return FALSE;
}
+
+ /* track if we have joined the p2p mcast group */
+ netPath->joinedPeer = TRUE;
+
netPath->peerMulticastAddr = netAddr.s_addr;
if(!netInitMulticastIPv4(netPath, netPath->peerMulticastAddr)) {
return FALSE;
@@ -2211,15 +2222,23 @@
netRefreshIGMP(NetPath * netPath, const RunTimeOpts * rtOpts, PtpClock * ptpClock)
{
DBG("netRefreshIGMP\n");
-
- if(netPath->joinedMulticast)
- netShutdownMulticast(netPath);
-
+
+ if(netPath->joinedGeneral) {
+ netShutdownMulticastIPv4(netPath, netPath->multicastAddr);
+ netPath->multicastAddr = 0;
+ }
+
+ if(netPath->joinedPeer) {
+ netShutdownMulticastIPv4(netPath, netPath->peerMulticastAddr);
+ netPath->peerMulticastAddr = 0;
+ }
+
/* suspend process 100 milliseconds, to make sure the kernel sends the IGMP_leave properly */
usleep(100*1000);
if (!netInitMulticast(netPath, rtOpts)) {
return FALSE;
}
+
return TRUE;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-14 19:46:44
|
Revision: 593
http://sourceforge.net/p/ptpd/code/593
Author: wowczarek
Date: 2015-10-14 19:46:42 +0000 (Wed, 14 Oct 2015)
Log Message:
-----------
- added getBestMaster() function
todo: maintain a pointer to best master
- master source addresses now maintained
in the FMR: fixes master IP display bug
where old master IP is displayed when
changing master as a result of current
master's announce
Modified Paths:
--------------
trunk/src/bmc.c
trunk/src/datatypes.h
trunk/src/dep/net.c
trunk/src/protocol.c
trunk/src/ptpd.h
Modified: trunk/src/bmc.c
===================================================================
--- trunk/src/bmc.c 2015-10-14 16:50:33 UTC (rev 592)
+++ trunk/src/bmc.c 2015-10-14 19:46:42 UTC (rev 593)
@@ -623,7 +623,7 @@
}
if (newBM) {
- ptpClock->masterAddr = ptpClock->netPath.lastSourceAddr;
+ ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
displayPortIdentity(&header->sourcePortIdentity,
"New best master selected:");
@@ -658,7 +658,7 @@
} else if (comp > 0) {
s1(header,announce,ptpClock, rtOpts);
if (newBM) {
- ptpClock->masterAddr = ptpClock->netPath.lastSourceAddr;
+ ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
displayPortIdentity(&header->sourcePortIdentity,
"New best master selected:");
ptpClock->counters.masterChanges++;
@@ -680,7 +680,7 @@
"New best master selected:");
ptpClock->counters.masterChanges++;
if(ptpClock->portState == PTP_SLAVE)
- ptpClock->masterAddr = ptpClock->netPath.lastSourceAddr;
+ ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
displayStatus(ptpClock, "State: ");
if(rtOpts->calibrationDelay) {
ptpClock->isCalibrated = FALSE;
@@ -733,25 +733,11 @@
rtOpts,ptpClock));
}
+/* retrieve curent best master */
+ForeignMasterRecord
+*getBestMaster(PtpClock *ptpClock) {
+ return(&(ptpClock->foreign[ptpClock->foreign_record_best]));
-/*
+}
-13.3.2.6, page 126
-
-PTPv2 valid flags per packet type:
-
-ALL:
- .... .0.. .... .... = PTP_UNICAST
-SYNC+Pdelay Resp:
- .... ..0. .... .... = PTP_TWO_STEP
-
-Announce only:
- .... .... ..0. .... = FREQUENCY_TRACEABLE
- .... .... ...0 .... = TIME_TRACEABLE
- .... .... .... 0... = PTP_TIMESCALE
- .... .... .... .0.. = PTP_UTC_REASONABLE
- .... .... .... ..0. = PTP_LI_59
- .... .... .... ...0 = PTP_LI_61
-
-*/
Modified: trunk/src/datatypes.h
===================================================================
--- trunk/src/datatypes.h 2015-10-14 16:50:33 UTC (rev 592)
+++ trunk/src/datatypes.h 2015-10-14 19:46:42 UTC (rev 593)
@@ -495,7 +495,7 @@
MsgAnnounce announce; /* announce message -> all datasets */
MsgHeader header; /* header -> some datasets */
UInteger8 localPreference; /* local preference - only used by telecom profile */
-
+ UInteger32 sourceAddr; /* source address */
} ForeignMasterRecord;
/**
Modified: trunk/src/dep/net.c
===================================================================
--- trunk/src/dep/net.c 2015-10-14 16:50:33 UTC (rev 592)
+++ trunk/src/dep/net.c 2015-10-14 19:46:42 UTC (rev 593)
@@ -1719,6 +1719,7 @@
#endif
ret=recvfrom(netPath->generalSock, buf, PACKET_SIZE, MSG_DONTWAIT, (struct sockaddr*)&from_addr, &from_addr_len);
netPath->lastSourceAddr = from_addr.sin_addr.s_addr;
+
/* do not report "from self" */
if(!netPath->lastSourceAddr || (netPath->lastSourceAddr != netPath->interfaceAddr.s_addr)) {
netPath->receivedPackets++;
Modified: trunk/src/protocol.c
===================================================================
--- trunk/src/protocol.c 2015-10-14 16:50:33 UTC (rev 592)
+++ trunk/src/protocol.c 2015-10-14 19:46:42 UTC (rev 593)
@@ -192,7 +192,7 @@
}
-void addForeign(Octet*,MsgHeader*,PtpClock*, UInteger8);
+void addForeign(Octet*,MsgHeader*,PtpClock*, UInteger8, UInteger32);
/* loop forever. doState() has a switch for the actions and events to be
checked for 'port_state'. the actions and events may or may not change
@@ -1570,7 +1570,7 @@
}
/* save the master address for display purposes or hybrid mode */
- ptpClock->masterAddr = ptpClock->netPath.lastSourceAddr;
+ ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
break;
@@ -1587,7 +1587,7 @@
* the slave will sit idle if current parent
* is not announcing, but another GM is
*/
- addForeign(ptpClock->msgIbuf,header,ptpClock,localPreference);
+ addForeign(ptpClock->msgIbuf,header,ptpClock,localPreference,ptpClock->netPath.lastSourceAddr);
break;
default:
@@ -1633,7 +1633,7 @@
/* update datasets (file bmc.c) */
s1(header,&ptpClock->msgTmp.announce,ptpClock, rtOpts);
- ptpClock->masterAddr = ptpClock->netPath.lastSourceAddr;
+ ptpClock->masterAddr = getBestMaster(ptpClock)->sourceAddr;
DBG("___ Announce: received Announce from current Master, so reset the Announce timer\n\n");
@@ -1650,7 +1650,7 @@
DBG("___ Announce: received Announce from another master, will add to the list, as it might be better\n\n");
DBGV("this is to be decided immediatly by bmc())\n\n");
- addForeign(ptpClock->msgIbuf,header,ptpClock,localPreference);
+ addForeign(ptpClock->msgIbuf,header,ptpClock,localPreference,ptpClock->netPath.lastSourceAddr);
}
break;
@@ -1668,7 +1668,7 @@
}
ptpClock->counters.announceMessagesReceived++;
DBGV("Announce message from another foreign master\n");
- addForeign(ptpClock->msgIbuf,header,ptpClock, localPreference);
+ addForeign(ptpClock->msgIbuf,header,ptpClock, localPreference,ptpClock->netPath.lastSourceAddr);
ptpClock->record_update = TRUE; /* run BMC() as soon as possible */
break;
@@ -1733,7 +1733,6 @@
if (ptpClock->syncWaiting) {
ptpClock->syncWaiting = FALSE;
-
NOTICE("Received first Sync from Master\n");
if (ptpClock->delayMechanism == E2E)
@@ -3564,7 +3563,7 @@
}
void
-addForeign(Octet *buf,MsgHeader *header,PtpClock *ptpClock, UInteger8 localPreference)
+addForeign(Octet *buf,MsgHeader *header,PtpClock *ptpClock, UInteger8 localPreference, UInteger32 sourceAddr)
{
int i,j;
Boolean found = FALSE;
@@ -3616,7 +3615,7 @@
header->sourcePortIdentity.portNumber;
ptpClock->foreign[j].foreignMasterAnnounceMessages = 0;
ptpClock->foreign[j].localPreference = localPreference;
-
+ ptpClock->foreign[j].sourceAddr = sourceAddr;
/*
* header and announce field of each Foreign Master are
* usefull to run Best Master Clock Algorithm
Modified: trunk/src/ptpd.h
===================================================================
--- trunk/src/ptpd.h 2015-10-14 16:50:33 UTC (rev 592)
+++ trunk/src/ptpd.h 2015-10-14 19:46:42 UTC (rev 593)
@@ -280,6 +280,8 @@
Boolean portIdentityEmpty(PortIdentity *portIdentity);
/* check if portIdentity is all ones */
Boolean portIdentityAllOnes(PortIdentity *portIdentity);
+/* retrieve best master */
+ForeignMasterRecord *getBestMaster(PtpClock *ptpClock);
/**
* \brief When recommended state is Master, copy local data into parent and grandmaster dataset
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-14 16:50:36
|
Revision: 592
http://sourceforge.net/p/ptpd/code/592
Author: wowczarek
Date: 2015-10-14 16:50:33 +0000 (Wed, 14 Oct 2015)
Log Message:
-----------
- renamed leap seconds file to non-date specific
- leap seconds file in default path added to
utc properties template
- changed dictionary_del to use double pointer,
and nullify the underlying pointer so we
can safely call dictionary_del multiple times
- small exit memory leak fixed as a result
of not deleting dictionaries on early
failure
- added log message body hash computation, same
message is not logged twice unless compiled
with debug enabled
- rand seed at startup
Modified Paths:
--------------
trunk/Makefile.am
trunk/packagebuild/rpm-rh/ptpd.spec
trunk/src/Makefile.am
trunk/src/arith.c
trunk/src/dep/configdefaults.c
trunk/src/dep/daemonconfig.c
trunk/src/dep/datatypes_dep.h
trunk/src/dep/iniparser/dictionary.c
trunk/src/dep/iniparser/dictionary.h
trunk/src/dep/iniparser/iniparser.c
trunk/src/dep/iniparser/iniparser.h
trunk/src/dep/startup.c
trunk/src/dep/sys.c
trunk/src/protocol.c
trunk/src/ptpd.h
Added Paths:
-----------
trunk/src/leap-seconds.list
Removed Paths:
-------------
trunk/src/leap-seconds.list.28dec2015
Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/Makefile.am 2015-10-14 16:50:33 UTC (rev 592)
@@ -19,7 +19,7 @@
src/ptpd2.conf.minimal\
src/ptpd2.8\
src/ptpd2.conf.5\
- src/leap-seconds.list.28dec2015\
+ src/leap-seconds.list\
src/dep/iniparser/AUTHORS\
src/dep/iniparser/LICENSE\
src/dep/iniparser/README\
@@ -37,7 +37,7 @@
$(NULL)
ptpd2dir = $(datadir)/$(PACKAGE)
-ptpd2_DATA = src/leap-seconds.list.28dec2015 \
+ptpd2_DATA = src/leap-seconds.list \
src/ptpd2.conf.minimal \
src/ptpd2.conf.default-full \
doc/PTPBASE-MIB.txt \
Modified: trunk/packagebuild/rpm-rh/ptpd.spec
===================================================================
--- trunk/packagebuild/rpm-rh/ptpd.spec 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/packagebuild/rpm-rh/ptpd.spec 2015-10-14 16:50:33 UTC (rev 592)
@@ -95,7 +95,7 @@
install -m 644 src/ptpd2.8 $RPM_BUILD_ROOT%{_mandir}/man8/ptpd2.8
install -m 644 src/ptpd2.conf.5 $RPM_BUILD_ROOT%{_mandir}/man5/ptpd2.conf.5
install -m 644 doc/PTPBASE-MIB.txt $RPM_BUILD_ROOT%{_datadir}/snmp/mibs/PTPBASE-MIB.txt
-install -m 644 src/leap-seconds.list.28dec2015 $RPM_BUILD_ROOT%{_datadir}/ptpd/leap-seconds.list.28dec2015
+install -m 644 src/leap-seconds.list $RPM_BUILD_ROOT%{_datadir}/ptpd/leap-seconds.list
install -m 644 src/ptpd2.conf.minimal $RPM_BUILD_ROOT%{_datadir}/ptpd/ptpd2.conf.minimal
install -m 644 src/ptpd2.conf.default-full $RPM_BUILD_ROOT%{_datadir}/ptpd/ptpd2.conf.default-full
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/Makefile.am 2015-10-14 16:50:33 UTC (rev 592)
@@ -12,9 +12,8 @@
if LINUX_KERNEL_HEADERS
AM_CFLAGS += $(LINUX_KERNEL_INCLUDES)
endif
+AM_CPPFLAGS += -DDATADIR='"$(datadir)"' $(PTP_DBL) $(PTP_DAEMON) $(PTP_EXP) $(PTP_SNMP) $(PTP_PCAP) $(PTP_STATISTICS) $(PTP_SLAVE_ONLY) $(PTP_PTIMERS) $(PTP_UNICAST_MAX) $(PTP_DISABLE_SOTIMESTAMPING)
-AM_CPPFLAGS += $(PTP_DBL) $(PTP_DAEMON) $(PTP_EXP) $(PTP_SNMP) $(PTP_PCAP) $(PTP_STATISTICS) $(PTP_SLAVE_ONLY) $(PTP_PTIMERS) $(PTP_UNICAST_MAX) $(PTP_DISABLE_SOTIMESTAMPING)
-
NULL=
#VERSION = 2.3.1
Modified: trunk/src/arith.c
===================================================================
--- trunk/src/arith.c 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/arith.c 2015-10-14 16:50:33 UTC (rev 592)
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2012-2015 Wojciech Owczarek,
* Copyright (c) 2011-2012 George V. Neville-Neil,
* Steven Kreuzer,
* Martin Burnicki,
Modified: trunk/src/dep/configdefaults.c
===================================================================
--- trunk/src/dep/configdefaults.c 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/dep/configdefaults.c 2015-10-14 16:50:33 UTC (rev 592)
@@ -95,7 +95,7 @@
{"ptpengine:ptp_timescale","PTP"},
{"ptpengine:time_traceable","y"},
{"ptpengine:frequency_traceable","y"},
- {"clock:leap_seconds_file",""},
+ {"clock:leap_seconds_file", DATADIR"/"PACKAGE_NAME"/leap-seconds.list"},
{NULL}}
},
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/dep/daemonconfig.c 2015-10-14 16:50:33 UTC (rev 592)
@@ -2279,7 +2279,7 @@
return target;
}
- dictionary_del(target);
+ dictionary_del(&target);
return NULL;
@@ -2305,7 +2305,7 @@
HELP_END();
dictionary_merge( dict, *target, 0, NULL);
- dictionary_del(dict);
+ dictionary_del(&dict);
return TRUE;
}
@@ -2404,7 +2404,7 @@
/* NULL will always be returned in this mode */
parseConfig(dict, &rtOpts);
END_SHOWDEFAULT();
- dictionary_del(dict);
+ dictionary_del(&dict);
printf("\n; ========= newline required in the end ==========\n\n");
@@ -2434,7 +2434,7 @@
parseConfig(dict, &rtOpts);
HELP_END();
- dictionary_del(dict);
+ dictionary_del(&dict);
}
@@ -2464,7 +2464,7 @@
printf("Use -H or --long-help to show help for all settings.\n\n");
HELP_END();
- dictionary_del(dict);
+ dictionary_del(&dict);
}
/**
Modified: trunk/src/dep/datatypes_dep.h
===================================================================
--- trunk/src/dep/datatypes_dep.h 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/dep/datatypes_dep.h 2015-10-14 16:50:33 UTC (rev 592)
@@ -133,6 +133,7 @@
Boolean truncateOnReopen;
Boolean unlinkOnClose;
+ uint32_t lastHash;
UInteger32 maxSize;
UInteger32 fileSize;
int maxFiles;
Modified: trunk/src/dep/iniparser/dictionary.c
===================================================================
--- trunk/src/dep/iniparser/dictionary.c 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/dep/iniparser/dictionary.c 2015-10-14 16:50:33 UTC (rev 592)
@@ -140,21 +140,22 @@
Deallocate a dictionary object and all memory associated to it.
*/
/*--------------------------------------------------------------------------*/
-void dictionary_del(dictionary * d)
+void dictionary_del(dictionary ** d)
{
int i ;
- if (d==NULL) return ;
- for (i=0 ; i<d->size ; i++) {
- if (d->key[i]!=NULL)
- free(d->key[i]);
- if (d->val[i]!=NULL)
- free(d->val[i]);
+ if (*d==NULL) return ;
+ for (i=0 ; i<(*d)->size ; i++) {
+ if ((*d)->key[i]!=NULL)
+ free((*d)->key[i]);
+ if ((*d)->val[i]!=NULL)
+ free((*d)->val[i]);
}
- free(d->val);
- free(d->key);
- free(d->hash);
- free(d);
+ free((*d)->val);
+ free((*d)->key);
+ free((*d)->hash);
+ free(*d);
+ *d = NULL;
return ;
}
@@ -500,7 +501,7 @@
printf("error deleting values\n");
}
printf("deallocating...\n");
- dictionary_del(d);
+ dictionary_del(&d);
return 0 ;
}
#endif
Modified: trunk/src/dep/iniparser/dictionary.h
===================================================================
--- trunk/src/dep/iniparser/dictionary.h 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/dep/iniparser/dictionary.h 2015-10-14 16:50:33 UTC (rev 592)
@@ -95,7 +95,7 @@
Deallocate a dictionary object and all memory associated to it.
*/
/*--------------------------------------------------------------------------*/
-void dictionary_del(dictionary * vd);
+void dictionary_del(dictionary ** vd);
/*-------------------------------------------------------------------------*/
/**
Modified: trunk/src/dep/iniparser/iniparser.c
===================================================================
--- trunk/src/dep/iniparser/iniparser.c 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/dep/iniparser/iniparser.c 2015-10-14 16:50:33 UTC (rev 592)
@@ -677,7 +677,7 @@
"iniparser: input line too long or no newline in the end in %s (%d)\n",
ininame,
lineno);
- dictionary_del(dict);
+ dictionary_del(&dict);
fclose(in);
return NULL ;
}
@@ -728,7 +728,7 @@
}
}
if (errs) {
- dictionary_del(dict);
+ dictionary_del(&dict);
dict = NULL ;
}
fclose(in);
@@ -746,7 +746,7 @@
gets out of the current context.
*/
/*--------------------------------------------------------------------------*/
-void iniparser_freedict(dictionary * d)
+void iniparser_freedict(dictionary ** d)
{
dictionary_del(d);
}
Modified: trunk/src/dep/iniparser/iniparser.h
===================================================================
--- trunk/src/dep/iniparser/iniparser.h 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/dep/iniparser/iniparser.h 2015-10-14 16:50:33 UTC (rev 592)
@@ -302,6 +302,6 @@
gets out of the current context.
*/
/*--------------------------------------------------------------------------*/
-void iniparser_freedict(dictionary * d);
+void iniparser_freedict(dictionary ** d);
#endif
Modified: trunk/src/dep/startup.c
===================================================================
--- trunk/src/dep/startup.c 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/dep/startup.c 2015-10-14 16:50:33 UTC (rev 592)
@@ -167,7 +167,7 @@
/* Try reloading the config file */
NOTIFY("Reloading configuration file: %s\n",rtOpts->configFile);
if(!loadConfigFile(&tmpConfig, rtOpts)) {
- dictionary_del(tmpConfig);
+ dictionary_del(&tmpConfig);
goto end;
}
dictionary_merge(rtOpts->cliConfig, tmpConfig, 1, "from command line");
@@ -178,7 +178,7 @@
/* Check the new configuration for errors, fill in the blanks from defaults */
if( ( rtOpts->candidateConfig = parseConfig(tmpConfig,&tmpOpts)) == NULL ) {
WARNING("Configuration file has errors, reload aborted\n");
- dictionary_del(tmpConfig);
+ dictionary_del(&tmpConfig);
goto end;
}
@@ -254,7 +254,7 @@
* disable quiet mode to show what went wrong, then die.
*/
if (rtOpts->currentConfig) {
- dictionary_del(rtOpts->currentConfig);
+ dictionary_del(&rtOpts->currentConfig);
}
if ( (rtOpts->currentConfig = parseConfig(rtOpts->candidateConfig,rtOpts)) == NULL) {
CRITICAL("************ "PTPD_PROGNAME": parseConfig returned NULL during config commit"
@@ -274,8 +274,8 @@
/* clean up */
cleanup:
- dictionary_del(tmpConfig);
- dictionary_del(rtOpts->candidateConfig);
+ dictionary_del(&tmpConfig);
+ dictionary_del(&rtOpts->candidateConfig);
end:
@@ -592,9 +592,9 @@
#endif /* PTPD_STATISTICS */
if (rtOpts.currentConfig != NULL)
- dictionary_del(rtOpts.currentConfig);
+ dictionary_del(&rtOpts.currentConfig);
if(rtOpts.cliConfig != NULL)
- dictionary_del(rtOpts.cliConfig);
+ dictionary_del(&rtOpts.cliConfig);
timerShutdown(ptpClock->timers);
@@ -651,6 +651,7 @@
ptpdStartup(int argc, char **argv, Integer16 * ret, RunTimeOpts * rtOpts)
{
PtpClock * ptpClock;
+ TimeInternal tmpTime;
int i = 0;
/*
@@ -660,6 +661,10 @@
*/
umask(~DEFAULT_FILE_PERMS);
+ /* get some entropy in... */
+ getTime(&tmpTime);
+ srand(tmpTime.seconds ^ tmpTime.nanoseconds);
+
/**
* If a required setting, such as interface name, or a setting
* requiring a range check is to be set via getopts_long,
@@ -669,8 +674,10 @@
* Config parameter evaluation priority order:
* 1. Any dictionary keys set in the getopt_long loop
* 2. CLI long section:key type options
- * 3. Config file (parsed last), merged with 2. and 3 - will be overwritten by CLI options
- * 4. Defaults and any rtOpts fields set in the getopt_long loop
+ * 3. Any built-in config templates
+ * 4. Any templates loaded from template file
+ * 5. Config file (parsed last), merged with 2. and 3 - will be overwritten by CLI options
+ * 6. Defaults and any rtOpts fields set in the getopt_long loop
**/
/**
@@ -726,7 +733,7 @@
*/
if( ( rtOpts->currentConfig = parseConfig(rtOpts->candidateConfig,rtOpts)) == NULL ) {
*ret = 1;
- dictionary_del(rtOpts->candidateConfig);
+ dictionary_del(&rtOpts->candidateConfig);
goto configcheck;
}
@@ -738,7 +745,7 @@
}
/* we don't need the candidate config any more */
- dictionary_del(rtOpts->candidateConfig);
+ dictionary_del(&rtOpts->candidateConfig);
/* Check network before going into background */
if(!testInterface(rtOpts->primaryIfaceName, rtOpts)) {
@@ -764,12 +771,12 @@
}
else
printf("Configuration OK\n");
- return 0;
+ goto fail;
}
/* Previous errors - exit */
if(*ret !=0)
- return 0;
+ goto fail;
/* First lock check, just to be user-friendly to the operator */
if(!rtOpts->ignore_daemon_lock) {
@@ -777,12 +784,12 @@
/* check and create Lock */
ERROR("Error: file lock failed (use -L or global:ignore_lock to ignore lock file)\n");
*ret = 3;
- return 0;
+ goto fail;
}
/* check for potential conflicts when automatic lock files are used */
if(!checkOtherLocks(rtOpts)) {
*ret = 3;
- return 0;
+ goto fail;
}
}
@@ -794,7 +801,7 @@
if (!ptpClock) {
PERROR("Error: Failed to allocate memory for protocol engine data");
*ret = 2;
- return 0;
+ goto fail;
} else {
DBG("allocated %d bytes for protocol engine data\n",
(int)sizeof(PtpClock));
@@ -808,7 +815,7 @@
"master data");
*ret = 2;
free(ptpClock);
- return 0;
+ goto fail;
} else {
DBG("allocated %d bytes for foreign master data\n",
(int)(rtOpts->max_foreign_records *
@@ -847,7 +854,7 @@
if (daemon(1,0) == -1) {
PERROR("Failed to start as daemon");
*ret = 3;
- return 0;
+ goto fail;
}
INFO(" Info: Now running as a daemon\n");
/*
@@ -869,7 +876,7 @@
if(!writeLockFile(rtOpts)){
ERROR("Error: file lock failed (use -L or global:ignore_lock to ignore lock file)\n");
*ret = 3;
- return 0;
+ goto fail;
}
}
@@ -889,7 +896,7 @@
PERROR("failed to set up event timers");
*ret = 2;
free(ptpClock);
- return 0;
+ goto fail;
}
/* establish signal handlers */
@@ -940,12 +947,15 @@
ptpClock->netPath.generalSock = -1;
ptpClock->netPath.eventSock = -1;
-
+
*ret = 0;
+
return ptpClock;
fail:
- dictionary_del(rtOpts->candidateConfig);
+ dictionary_del(&rtOpts->cliConfig);
+ dictionary_del(&rtOpts->candidateConfig);
+ dictionary_del(&rtOpts->currentConfig);
return 0;
}
Modified: trunk/src/dep/sys.c
===================================================================
--- trunk/src/dep/sys.c 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/dep/sys.c 2015-10-14 16:50:33 UTC (rev 592)
@@ -334,14 +334,19 @@
}
/* Write a formatted string to file pointer */
-int writeMessage(FILE* destination, int priority, const char * format, va_list ap) {
+int writeMessage(FILE* destination, uint32_t *lastHash, int priority, const char * format, va_list ap) {
+ char buf[PATH_MAX +1];
extern RunTimeOpts rtOpts;
extern Boolean startupInProgress;
int written;
char time_str[MAXTIMESTR];
struct timeval now;
+#ifndef RUNTIME_DEBUG
+ uint32_t hash;
+ va_list ap1;
+#endif /* RUNTIME_DEBUG */
extern char *translatePortState(PtpClock *ptpClock);
extern PtpClock *G_ptpClock;
@@ -355,6 +360,24 @@
(priority > LOG_WARNING)){
return 1;
}
+
+#ifndef RUNTIME_DEBUG
+ /* check if this message produces the same hash as last */
+ memset(buf, 0, sizeof(buf));
+ va_copy(ap1, ap);
+ vsnprintf(buf, PATH_MAX, format, ap1);
+ hash = fnvHash(buf, sizeof(buf), 0);
+ if(lastHash != NULL) {
+ if(format[0] != '\n' && lastHash != NULL) {
+ /* last message was the same - don't print the next one */
+ if( (lastHash != 0) && (hash == *lastHash)) {
+ return 0;
+ }
+ }
+ *lastHash = hash;
+ }
+#endif /* RUNTIME_DEBUG */
+
/* Print timestamps and prefixes only if we're running in foreground or logging to file*/
if( rtOpts.nonDaemon || destination != stderr) {
@@ -432,7 +455,7 @@
/* If we're using a log file and the message has been written OK, we're done*/
if(rtOpts.eventLog.logEnabled && rtOpts.eventLog.logFP != NULL) {
- if(writeMessage(rtOpts.eventLog.logFP, priority, format, ap) > 0) {
+ if(writeMessage(rtOpts.eventLog.logFP, &rtOpts.eventLog.lastHash, priority, format, ap) > 0) {
maintainLogSize(&rtOpts.eventLog);
if(!startupInProgress)
goto end;
@@ -472,7 +495,7 @@
std_err:
va_start(ap, format);
/* Either all else failed or we're running in foreground - or we also log to stderr */
- writeMessage(stderr, priority, format, ap);
+ writeMessage(stderr, &rtOpts.eventLog.lastHash, priority, format, ap);
end:
va_end(ap);
@@ -487,6 +510,7 @@
/* The FP is open - close it */
if(handler->logFP != NULL) {
+ handler->lastHash=0;
fclose(handler->logFP);
/*
* fclose doesn't do this at least on Linux - changes the underlying FD to -1,
Copied: trunk/src/leap-seconds.list (from rev 585, trunk/src/leap-seconds.list.28dec2015)
===================================================================
--- trunk/src/leap-seconds.list (rev 0)
+++ trunk/src/leap-seconds.list 2015-10-14 16:50:33 UTC (rev 592)
@@ -0,0 +1,249 @@
+#
+# In the following text, the symbol '#' introduces
+# a comment, which continues from that symbol until
+# the end of the line. A plain comment line has a
+# whitespace character following the comment indicator.
+# There are also special comment lines defined below.
+# A special comment will always have a non-whitespace
+# character in column 2.
+#
+# A blank line should be ignored.
+#
+# The following table shows the corrections that must
+# be applied to compute International Atomic Time (TAI)
+# from the Coordinated Universal Time (UTC) values that
+# are transmitted by almost all time services.
+#
+# The first column shows an epoch as a number of seconds
+# since 1 January 1900, 00:00:00 (1900.0 is also used to
+# indicate the same epoch.) Both of these time stamp formats
+# ignore the complexities of the time scales that were
+# used before the current definition of UTC at the start
+# of 1972. (See note 3 below.)
+# The second column shows the number of seconds that
+# must be added to UTC to compute TAI for any timestamp
+# at or after that epoch. The value on each line is
+# valid from the indicated initial instant until the
+# epoch given on the next one or indefinitely into the
+# future if there is no next line.
+# (The comment on each line shows the representation of
+# the corresponding initial epoch in the usual
+# day-month-year format. The epoch always begins at
+# 00:00:00 UTC on the indicated day. See Note 5 below.)
+#
+# Important notes:
+#
+# 1. Coordinated Universal Time (UTC) is often referred to
+# as Greenwich Mean Time (GMT). The GMT time scale is no
+# longer used, and the use of GMT to designate UTC is
+# discouraged.
+#
+# 2. The UTC time scale is realized by many national
+# laboratories and timing centers. Each laboratory
+# identifies its realization with its name: Thus
+# UTC(NIST), UTC(USNO), etc. The differences among
+# these different realizations are typically on the
+# order of a few nanoseconds (i.e., 0.000 000 00x s)
+# and can be ignored for many purposes. These differences
+# are tabulated in Circular T, which is published monthly
+# by the International Bureau of Weights and Measures
+# (BIPM). See www.bipm.org for more information.
+#
+# 3. The current definition of the relationship between UTC
+# and TAI dates from 1 January 1972. A number of different
+# time scales were in use before that epoch, and it can be
+# quite difficult to compute precise timestamps and time
+# intervals in those "prehistoric" days. For more information,
+# consult:
+#
+# The Explanatory Supplement to the Astronomical
+# Ephemeris.
+# or
+# Terry Quinn, "The BIPM and the Accurate Measurement
+# of Time," Proc. of the IEEE, Vol. 79, pp. 894-905,
+# July, 1991.
+#
+# 4. The decision to insert a leap second into UTC is currently
+# the responsibility of the International Earth Rotation and
+# Reference Systems Service. (The name was changed from the
+# International Earth Rotation Service, but the acronym IERS
+# is still used.)
+#
+# Leap seconds are announced by the IERS in its Bulletin C.
+#
+# See www.iers.org for more details.
+#
+# Every national laboratory and timing center uses the
+# data from the BIPM and the IERS to construct UTC(lab),
+# their local realization of UTC.
+#
+# Although the definition also includes the possibility
+# of dropping seconds ("negative" leap seconds), this has
+# never been done and is unlikely to be necessary in the
+# foreseeable future.
+#
+# 5. If your system keeps time as the number of seconds since
+# some epoch (e.g., NTP timestamps), then the algorithm for
+# assigning a UTC time stamp to an event that happens during a positive
+# leap second is not well defined. The official name of that leap
+# second is 23:59:60, but there is no way of representing that time
+# in these systems.
+# Many systems of this type effectively stop the system clock for
+# one second during the leap second and use a time that is equivalent
+# to 23:59:59 UTC twice. For these systems, the corresponding TAI
+# timestamp would be obtained by advancing to the next entry in the
+# following table when the time equivalent to 23:59:59 UTC
+# is used for the second time. Thus the leap second which
+# occurred on 30 June 1972 at 23:59:59 UTC would have TAI
+# timestamps computed as follows:
+#
+# ...
+# 30 June 1972 23:59:59 (2287785599, first time): TAI= UTC + 10 seconds
+# 30 June 1972 23:59:60 (2287785599,second time): TAI= UTC + 11 seconds
+# 1 July 1972 00:00:00 (2287785600) TAI= UTC + 11 seconds
+# ...
+#
+# If your system realizes the leap second by repeating 00:00:00 UTC twice
+# (this is possible but not usual), then the advance to the next entry
+# in the table must occur the second time that a time equivalent to
+# 00:00:00 UTC is used. Thus, using the same example as above:
+#
+# ...
+# 30 June 1972 23:59:59 (2287785599): TAI= UTC + 10 seconds
+# 30 June 1972 23:59:60 (2287785600, first time): TAI= UTC + 10 seconds
+# 1 July 1972 00:00:00 (2287785600,second time): TAI= UTC + 11 seconds
+# ...
+#
+# in both cases the use of timestamps based on TAI produces a smooth
+# time scale with no discontinuity in the time interval. However,
+# although the long-term behavior of the time scale is correct in both
+# methods, the second method is technically not correct because it adds
+# the extra second to the wrong day.
+#
+# This complexity would not be needed for negative leap seconds (if they
+# are ever used). The UTC time would skip 23:59:59 and advance from
+# 23:59:58 to 00:00:00 in that case. The TAI offset would decrease by
+# 1 second at the same instant. This is a much easier situation to deal
+# with, since the difficulty of unambiguously representing the epoch
+# during the leap second does not arise.
+#
+# Some systems implement leap seconds by amortizing the leap second
+# over the last few minutes of the day. The frequency of the local
+# clock is decreased (or increased) to realize the positive (or
+# negative) leap second. This method removes the time step described
+# above. Although the long-term behavior of the time scale is correct
+# in this case, this method introduces an error during the adjustment
+# period both in time and in frequency with respect to the official
+# definition of UTC.
+#
+# Questions or comments to:
+# Judah Levine
+# Time and Frequency Division
+# NIST
+# Boulder, Colorado
+# Jud...@ni...
+#
+# Last Update of leap second values: 5 January 2015
+#
+# The following line shows this last update date in NTP timestamp
+# format. This is the date on which the most recent change to
+# the leap second data was added to the file. This line can
+# be identified by the unique pair of characters in the first two
+# columns as shown below.
+#
+#$ 3629404800
+#
+# The NTP timestamps are in units of seconds since the NTP epoch,
+# which is 1 January 1900, 00:00:00. The Modified Julian Day number
+# corresponding to the NTP time stamp, X, can be computed as
+#
+# X/86400 + 15020
+#
+# where the first term converts seconds to days and the second
+# term adds the MJD corresponding to the time origin defined above.
+# The integer portion of the result is the integer MJD for that
+# day, and any remainder is the time of day, expressed as the
+# fraction of the day since 0 hours UTC. The conversion from day
+# fraction to seconds or to hours, minutes, and seconds may involve
+# rounding or truncation, depending on the method used in the
+# computation.
+#
+# The data in this file will be updated periodically as new leap
+# seconds are announced. In addition to being entered on the line
+# above, the update time (in NTP format) will be added to the basic
+# file name leap-seconds to form the name leap-seconds.<NTP TIME>.
+# In addition, the generic name leap-seconds.list will always point to
+# the most recent version of the file.
+#
+# This update procedure will be performed only when a new leap second
+# is announced.
+#
+# The following entry specifies the expiration date of the data
+# in this file in units of seconds since the origin at the instant
+# 1 January 1900, 00:00:00. This expiration date will be changed
+# at least twice per year whether or not a new leap second is
+# announced. These semi-annual changes will be made no later
+# than 1 June and 1 December of each year to indicate what
+# action (if any) is to be taken on 30 June and 31 December,
+# respectively. (These are the customary effective dates for new
+# leap seconds.) This expiration date will be identified by a
+# unique pair of characters in columns 1 and 2 as shown below.
+# In the unlikely event that a leap second is announced with an
+# effective date other than 30 June or 31 December, then this
+# file will be edited to include that leap second as soon as it is
+# announced or at least one month before the effective date
+# (whichever is later).
+# If an announcement by the IERS specifies that no leap second is
+# scheduled, then only the expiration date of the file will
+# be advanced to show that the information in the file is still
+# current -- the update time stamp, the data and the name of the file
+# will not change.
+#
+# Updated through IERS Bulletin C49
+# File expires on: 28 December 2015
+#
+#@ 3660249600
+#
+2272060800 10 # 1 Jan 1972
+2287785600 11 # 1 Jul 1972
+2303683200 12 # 1 Jan 1973
+2335219200 13 # 1 Jan 1974
+2366755200 14 # 1 Jan 1975
+2398291200 15 # 1 Jan 1976
+2429913600 16 # 1 Jan 1977
+2461449600 17 # 1 Jan 1978
+2492985600 18 # 1 Jan 1979
+2524521600 19 # 1 Jan 1980
+2571782400 20 # 1 Jul 1981
+2603318400 21 # 1 Jul 1982
+2634854400 22 # 1 Jul 1983
+2698012800 23 # 1 Jul 1985
+2776982400 24 # 1 Jan 1988
+2840140800 25 # 1 Jan 1990
+2871676800 26 # 1 Jan 1991
+2918937600 27 # 1 Jul 1992
+2950473600 28 # 1 Jul 1993
+2982009600 29 # 1 Jul 1994
+3029443200 30 # 1 Jan 1996
+3076704000 31 # 1 Jul 1997
+3124137600 32 # 1 Jan 1999
+3345062400 33 # 1 Jan 2006
+3439756800 34 # 1 Jan 2009
+3550089600 35 # 1 Jul 2012
+3644697600 36 # 1 Jul 2015
+#
+# the following special comment contains the
+# hash value of the data in this file computed
+# use the secure hash algorithm as specified
+# by FIPS 180-1. See the files in ~/pub/sha for
+# the details of how this hash value is
+# computed. Note that the hash computation
+# ignores comments and whitespace characters
+# in data lines. It includes the NTP values
+# of both the last modification time and the
+# expiration time of the file, but not the
+# white space on those lines.
+# the hash line is also ignored in the
+# computation.
+#
+#h 45e70fa7 a9df2033 f4a49ab0 ec648273 7b6c22c
\ No newline at end of file
Deleted: trunk/src/leap-seconds.list.28dec2015
===================================================================
--- trunk/src/leap-seconds.list.28dec2015 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/leap-seconds.list.28dec2015 2015-10-14 16:50:33 UTC (rev 592)
@@ -1,249 +0,0 @@
-#
-# In the following text, the symbol '#' introduces
-# a comment, which continues from that symbol until
-# the end of the line. A plain comment line has a
-# whitespace character following the comment indicator.
-# There are also special comment lines defined below.
-# A special comment will always have a non-whitespace
-# character in column 2.
-#
-# A blank line should be ignored.
-#
-# The following table shows the corrections that must
-# be applied to compute International Atomic Time (TAI)
-# from the Coordinated Universal Time (UTC) values that
-# are transmitted by almost all time services.
-#
-# The first column shows an epoch as a number of seconds
-# since 1 January 1900, 00:00:00 (1900.0 is also used to
-# indicate the same epoch.) Both of these time stamp formats
-# ignore the complexities of the time scales that were
-# used before the current definition of UTC at the start
-# of 1972. (See note 3 below.)
-# The second column shows the number of seconds that
-# must be added to UTC to compute TAI for any timestamp
-# at or after that epoch. The value on each line is
-# valid from the indicated initial instant until the
-# epoch given on the next one or indefinitely into the
-# future if there is no next line.
-# (The comment on each line shows the representation of
-# the corresponding initial epoch in the usual
-# day-month-year format. The epoch always begins at
-# 00:00:00 UTC on the indicated day. See Note 5 below.)
-#
-# Important notes:
-#
-# 1. Coordinated Universal Time (UTC) is often referred to
-# as Greenwich Mean Time (GMT). The GMT time scale is no
-# longer used, and the use of GMT to designate UTC is
-# discouraged.
-#
-# 2. The UTC time scale is realized by many national
-# laboratories and timing centers. Each laboratory
-# identifies its realization with its name: Thus
-# UTC(NIST), UTC(USNO), etc. The differences among
-# these different realizations are typically on the
-# order of a few nanoseconds (i.e., 0.000 000 00x s)
-# and can be ignored for many purposes. These differences
-# are tabulated in Circular T, which is published monthly
-# by the International Bureau of Weights and Measures
-# (BIPM). See www.bipm.org for more information.
-#
-# 3. The current definition of the relationship between UTC
-# and TAI dates from 1 January 1972. A number of different
-# time scales were in use before that epoch, and it can be
-# quite difficult to compute precise timestamps and time
-# intervals in those "prehistoric" days. For more information,
-# consult:
-#
-# The Explanatory Supplement to the Astronomical
-# Ephemeris.
-# or
-# Terry Quinn, "The BIPM and the Accurate Measurement
-# of Time," Proc. of the IEEE, Vol. 79, pp. 894-905,
-# July, 1991.
-#
-# 4. The decision to insert a leap second into UTC is currently
-# the responsibility of the International Earth Rotation and
-# Reference Systems Service. (The name was changed from the
-# International Earth Rotation Service, but the acronym IERS
-# is still used.)
-#
-# Leap seconds are announced by the IERS in its Bulletin C.
-#
-# See www.iers.org for more details.
-#
-# Every national laboratory and timing center uses the
-# data from the BIPM and the IERS to construct UTC(lab),
-# their local realization of UTC.
-#
-# Although the definition also includes the possibility
-# of dropping seconds ("negative" leap seconds), this has
-# never been done and is unlikely to be necessary in the
-# foreseeable future.
-#
-# 5. If your system keeps time as the number of seconds since
-# some epoch (e.g., NTP timestamps), then the algorithm for
-# assigning a UTC time stamp to an event that happens during a positive
-# leap second is not well defined. The official name of that leap
-# second is 23:59:60, but there is no way of representing that time
-# in these systems.
-# Many systems of this type effectively stop the system clock for
-# one second during the leap second and use a time that is equivalent
-# to 23:59:59 UTC twice. For these systems, the corresponding TAI
-# timestamp would be obtained by advancing to the next entry in the
-# following table when the time equivalent to 23:59:59 UTC
-# is used for the second time. Thus the leap second which
-# occurred on 30 June 1972 at 23:59:59 UTC would have TAI
-# timestamps computed as follows:
-#
-# ...
-# 30 June 1972 23:59:59 (2287785599, first time): TAI= UTC + 10 seconds
-# 30 June 1972 23:59:60 (2287785599,second time): TAI= UTC + 11 seconds
-# 1 July 1972 00:00:00 (2287785600) TAI= UTC + 11 seconds
-# ...
-#
-# If your system realizes the leap second by repeating 00:00:00 UTC twice
-# (this is possible but not usual), then the advance to the next entry
-# in the table must occur the second time that a time equivalent to
-# 00:00:00 UTC is used. Thus, using the same example as above:
-#
-# ...
-# 30 June 1972 23:59:59 (2287785599): TAI= UTC + 10 seconds
-# 30 June 1972 23:59:60 (2287785600, first time): TAI= UTC + 10 seconds
-# 1 July 1972 00:00:00 (2287785600,second time): TAI= UTC + 11 seconds
-# ...
-#
-# in both cases the use of timestamps based on TAI produces a smooth
-# time scale with no discontinuity in the time interval. However,
-# although the long-term behavior of the time scale is correct in both
-# methods, the second method is technically not correct because it adds
-# the extra second to the wrong day.
-#
-# This complexity would not be needed for negative leap seconds (if they
-# are ever used). The UTC time would skip 23:59:59 and advance from
-# 23:59:58 to 00:00:00 in that case. The TAI offset would decrease by
-# 1 second at the same instant. This is a much easier situation to deal
-# with, since the difficulty of unambiguously representing the epoch
-# during the leap second does not arise.
-#
-# Some systems implement leap seconds by amortizing the leap second
-# over the last few minutes of the day. The frequency of the local
-# clock is decreased (or increased) to realize the positive (or
-# negative) leap second. This method removes the time step described
-# above. Although the long-term behavior of the time scale is correct
-# in this case, this method introduces an error during the adjustment
-# period both in time and in frequency with respect to the official
-# definition of UTC.
-#
-# Questions or comments to:
-# Judah Levine
-# Time and Frequency Division
-# NIST
-# Boulder, Colorado
-# Jud...@ni...
-#
-# Last Update of leap second values: 5 January 2015
-#
-# The following line shows this last update date in NTP timestamp
-# format. This is the date on which the most recent change to
-# the leap second data was added to the file. This line can
-# be identified by the unique pair of characters in the first two
-# columns as shown below.
-#
-#$ 3629404800
-#
-# The NTP timestamps are in units of seconds since the NTP epoch,
-# which is 1 January 1900, 00:00:00. The Modified Julian Day number
-# corresponding to the NTP time stamp, X, can be computed as
-#
-# X/86400 + 15020
-#
-# where the first term converts seconds to days and the second
-# term adds the MJD corresponding to the time origin defined above.
-# The integer portion of the result is the integer MJD for that
-# day, and any remainder is the time of day, expressed as the
-# fraction of the day since 0 hours UTC. The conversion from day
-# fraction to seconds or to hours, minutes, and seconds may involve
-# rounding or truncation, depending on the method used in the
-# computation.
-#
-# The data in this file will be updated periodically as new leap
-# seconds are announced. In addition to being entered on the line
-# above, the update time (in NTP format) will be added to the basic
-# file name leap-seconds to form the name leap-seconds.<NTP TIME>.
-# In addition, the generic name leap-seconds.list will always point to
-# the most recent version of the file.
-#
-# This update procedure will be performed only when a new leap second
-# is announced.
-#
-# The following entry specifies the expiration date of the data
-# in this file in units of seconds since the origin at the instant
-# 1 January 1900, 00:00:00. This expiration date will be changed
-# at least twice per year whether or not a new leap second is
-# announced. These semi-annual changes will be made no later
-# than 1 June and 1 December of each year to indicate what
-# action (if any) is to be taken on 30 June and 31 December,
-# respectively. (These are the customary effective dates for new
-# leap seconds.) This expiration date will be identified by a
-# unique pair of characters in columns 1 and 2 as shown below.
-# In the unlikely event that a leap second is announced with an
-# effective date other than 30 June or 31 December, then this
-# file will be edited to include that leap second as soon as it is
-# announced or at least one month before the effective date
-# (whichever is later).
-# If an announcement by the IERS specifies that no leap second is
-# scheduled, then only the expiration date of the file will
-# be advanced to show that the information in the file is still
-# current -- the update time stamp, the data and the name of the file
-# will not change.
-#
-# Updated through IERS Bulletin C49
-# File expires on: 28 December 2015
-#
-#@ 3660249600
-#
-2272060800 10 # 1 Jan 1972
-2287785600 11 # 1 Jul 1972
-2303683200 12 # 1 Jan 1973
-2335219200 13 # 1 Jan 1974
-2366755200 14 # 1 Jan 1975
-2398291200 15 # 1 Jan 1976
-2429913600 16 # 1 Jan 1977
-2461449600 17 # 1 Jan 1978
-2492985600 18 # 1 Jan 1979
-2524521600 19 # 1 Jan 1980
-2571782400 20 # 1 Jul 1981
-2603318400 21 # 1 Jul 1982
-2634854400 22 # 1 Jul 1983
-2698012800 23 # 1 Jul 1985
-2776982400 24 # 1 Jan 1988
-2840140800 25 # 1 Jan 1990
-2871676800 26 # 1 Jan 1991
-2918937600 27 # 1 Jul 1992
-2950473600 28 # 1 Jul 1993
-2982009600 29 # 1 Jul 1994
-3029443200 30 # 1 Jan 1996
-3076704000 31 # 1 Jul 1997
-3124137600 32 # 1 Jan 1999
-3345062400 33 # 1 Jan 2006
-3439756800 34 # 1 Jan 2009
-3550089600 35 # 1 Jul 2012
-3644697600 36 # 1 Jul 2015
-#
-# the following special comment contains the
-# hash value of the data in this file computed
-# use the secure hash algorithm as specified
-# by FIPS 180-1. See the files in ~/pub/sha for
-# the details of how this hash value is
-# computed. Note that the hash computation
-# ignores comments and whitespace characters
-# in data lines. It includes the NTP values
-# of both the last modification time and the
-# expiration time of the file, but not the
-# white space on those lines.
-# the hash line is also ignored in the
-# computation.
-#
-#h 45e70fa7 a9df2033 f4a49ab0 ec648273 7b6c22c
\ No newline at end of file
Modified: trunk/src/protocol.c
===================================================================
--- trunk/src/protocol.c 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/protocol.c 2015-10-14 16:50:33 UTC (rev 592)
@@ -686,7 +686,7 @@
UInteger8 state;
ptpClock->message_activity = FALSE;
-
+
/* Process record_update (BMC algorithm) before everything else */
switch (ptpClock->portState)
{
Modified: trunk/src/ptpd.h
===================================================================
--- trunk/src/ptpd.h 2015-10-14 07:16:38 UTC (rev 591)
+++ trunk/src/ptpd.h 2015-10-14 16:50:33 UTC (rev 592)
@@ -186,6 +186,12 @@
exit(1); \
}
+#define SAFE_FREE(pointer) \
+ if(pointer != NULL) { \
+ free(pointer); \
+ pointer = NULL; \
+ }
+
#define IS_SET(data, bitpos) \
((data & ( 0x1 << bitpos )) == (0x1 << bitpos))
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-14 07:16:41
|
Revision: 591
http://sourceforge.net/p/ptpd/code/591
Author: wowczarek
Date: 2015-10-14 07:16:38 +0000 (Wed, 14 Oct 2015)
Log Message:
-----------
- typo in template
- config reload flags colliding with failure code fixed
Modified Paths:
--------------
trunk/src/dep/configdefaults.c
trunk/src/dep/startup.c
Modified: trunk/src/dep/configdefaults.c
===================================================================
--- trunk/src/dep/configdefaults.c 2015-10-14 05:58:31 UTC (rev 590)
+++ trunk/src/dep/configdefaults.c 2015-10-14 07:16:38 UTC (rev 591)
@@ -56,7 +56,7 @@
{"ptpengine:unicast_negotiation", "y"},
{"ptpengine:domain", "4"},
{"ptpengine:disable_bmca", "y"},
- {"ptpentine:delay_mechanism", "E2E"},
+ {"ptpengine:delay_mechanism", "E2E"},
{"ptpengine:log_sync_interval", "-6"},
{"ptpengine:log_delayreq_interval", "-6"},
{"ptpengine:announce_receipt_timeout", "3"},
Modified: trunk/src/dep/startup.c
===================================================================
--- trunk/src/dep/startup.c 2015-10-14 05:58:31 UTC (rev 590)
+++ trunk/src/dep/startup.c 2015-10-14 07:16:38 UTC (rev 591)
@@ -147,6 +147,8 @@
do_signal_sighup(RunTimeOpts * rtOpts, PtpClock * ptpClock)
{
+ Boolean reloadSuccessful = TRUE;
+
NOTIFY("SIGHUP received\n");
#ifdef RUNTIME_DEBUG
@@ -198,14 +200,14 @@
/* If we're told to re-check lock files, do it: tmpOpts already has what rtOpts should */
if( (rtOpts->restartSubsystems & PTPD_CHECK_LOCKS) &&
tmpOpts.autoLockFile && !checkOtherLocks(&tmpOpts)) {
- rtOpts->restartSubsystems = -1;
+ reloadSuccessful = FALSE;
}
/* If the network configuration has changed, check if the interface is OK */
if(rtOpts->restartSubsystems & PTPD_RESTART_NETWORK) {
INFO("Network configuration changed - checking interface(s)\n");
if(!testInterface(tmpOpts.primaryIfaceName, &tmpOpts)) {
- rtOpts->restartSubsystems = -1;
+ reloadSuccessful = FALSE;
ERROR("Error: Cannot use %s interface\n",tmpOpts.primaryIfaceName);
}
if(rtOpts->backupIfaceEnabled && !testInterface(tmpOpts.backupIfaceName, &tmpOpts)) {
@@ -224,7 +226,7 @@
} else {
ERROR("Could bind to CPU core %d\n", tmpOpts.cpuNumber);
}
- rtOpts->restartSubsystems = -1;
+ reloadSuccessful = FALSE;
} else {
if(tmpOpts.cpuNumber > -1)
INFO("Successfully bound "PTPD_PROGNAME" to CPU core %d\n", tmpOpts.cpuNumber);
@@ -234,7 +236,7 @@
}
#endif
- if(rtOpts->restartSubsystems == -1) {
+ if(!reloadSuccessful) {
ERROR("New configuration cannot be applied - aborting reload\n");
rtOpts->restartSubsystems = 0;
goto cleanup;
@@ -889,8 +891,8 @@
free(ptpClock);
return 0;
}
-
- /* use new synchronous signal handlers */
+
+ /* establish signal handlers */
signal(SIGINT, catchSignals);
signal(SIGTERM, catchSignals);
signal(SIGHUP, catchSignals);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-14 05:58:34
|
Revision: 590
http://sourceforge.net/p/ptpd/code/590
Author: wowczarek
Date: 2015-10-14 05:58:31 +0000 (Wed, 14 Oct 2015)
Log Message:
-----------
- User variable fix in built-in templates
Modified Paths:
--------------
trunk/src/dep/configdefaults.c
Modified: trunk/src/dep/configdefaults.c
===================================================================
--- trunk/src/dep/configdefaults.c 2015-10-13 21:23:29 UTC (rev 589)
+++ trunk/src/dep/configdefaults.c 2015-10-14 05:58:31 UTC (rev 590)
@@ -114,18 +114,17 @@
{ "full-logging-instance", {
{"global:log_status", "y"},
- {"global:status_file", "/var/run/ptpd2.%instance%.status"},
+ {"global:status_file", "@rundir@/ptpd2.@instance@.status"},
{"global:statistics_log_interval", "1"},
- {"global:lock_file", "/var/run/ptpd2.%instance%.pid"},
+ {"global:lock_file", "@rundir@/ptpd2.@instance@.pid"},
{"global:log_statistics", "y"},
- {"global:statistics_file", "/var/log/ptpd2.%instance%.statistics"},
+ {"global:statistics_file", "@logdir@/ptpd2.@instance@.statistics"},
// {"global:statistics_file_truncate", "n"},
- {"global:log_file", "/var/log/ptpd2.%instance%.log"},
+ {"global:log_file", "@logdir@/ptpd2.@instance@.log"},
{"global:statistics_timestamp_format", "both"},
{NULL}}
},
-
{NULL}
};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-13 21:23:32
|
Revision: 589
http://sourceforge.net/p/ptpd/code/589
Author: wowczarek
Date: 2015-10-13 21:23:29 +0000 (Tue, 13 Oct 2015)
Log Message:
-----------
- config defaults moved to separate source
configdefaults.c
- added support for hard-coded configuration templates,
with initial templates defined - to be finalised
- added support for user variables in configuration:
variables:name=value, used as @name@ elsewhere
- man pages built-in help updated accordingly
- added -t [templates] to use, and -T to show
available templates
- implemented dictionary_replace(dict, char*, char*)
Modified Paths:
--------------
trunk/INSTALL
trunk/src/Makefile.am
trunk/src/constants.h
trunk/src/dep/daemonconfig.c
trunk/src/dep/daemonconfig.h
trunk/src/dep/iniparser/AUTHORS
trunk/src/dep/iniparser/dictionary.c
trunk/src/dep/iniparser/dictionary.h
trunk/src/ptpd2.8.in
trunk/src/ptpd2.conf.5.in
Added Paths:
-----------
trunk/src/dep/configdefaults.c
trunk/src/dep/configdefaults.h
Modified: trunk/INSTALL
===================================================================
--- trunk/INSTALL 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/INSTALL 2015-10-13 21:23:29 UTC (rev 589)
@@ -17,6 +17,9 @@
(optional but recommended) - required for Ethernet transport
and generally recommended for message performance
+ *NOTE: Libpcap seems to be broken on OpenSolaris / OmniOS,
+ builds and runs, but no data is being received.
+
3. SNMP libraries (optional) - will allow building with SNMP
support
@@ -41,6 +44,12 @@
described below. Running ./configure --help will show all available
options.
+ *NOTE* On QNX systems, the configure script may not accept the
+ 'rm' command implementation available, so if it complains,
+ run ./configure with the following environment variable:
+
+ export ACCEPT_INFERIOR_RM_PROGRAM=yes
+
========= configure script options for ptpd ========================
* To disable the statistics code in order to lower computational
@@ -96,6 +105,26 @@
./configure --disable-so-timestamping
+ * To enable experimental options use:
+
+ ./configure --enable-experimental-options
+
+ This enables:
+
+ - running SO_TIMESTAMPING without verifying if NIC driver
+ supports the given timestamping options
+ - running message intervals outside of PTP specification
+
+ *NOTE* On QNX systems, when experimental options are enabled,
+ a clock_gettime approximation using CPU clock counter and
+ attaching to IRQ0 is used, and this is also used to retrieve
+ packet RX and TX timestamps, ignoring PCAP timestamps and
+ socket options. This is recommended for best performance,
+ but requires more testing before becoming the default.
+ by default in QNX, clock is incremented in ticks that
+ can be as long as 10 milliseconds, and PCAP and socket
+ timestamps are only accurate to several milliseconds.
+
5. make
6. Read the manual pages ptpd2(8) and ptpd2.conf(5). The man pages
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/src/Makefile.am 2015-10-13 21:23:29 UTC (rev 589)
@@ -44,6 +44,8 @@
dep/iniparser/iniparser.h \
dep/iniparser/dictionary.c \
dep/iniparser/iniparser.c \
+ dep/configdefaults.h \
+ dep/configdefaults.c \
dep/daemonconfig.h \
dep/daemonconfig.c \
dep/startup.c \
Modified: trunk/src/constants.h
===================================================================
--- trunk/src/constants.h 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/src/constants.h 2015-10-13 21:23:29 UTC (rev 589)
@@ -64,7 +64,7 @@
/* number of announces we need to lose until a time out occurs. Thus it is 12 seconds */
#define DEFAULT_ANNOUNCE_RECEIPT_TIMEOUT 6 /* 3 by default */
-#define DEFAULT_FAILURE_WAITTIME 10 /* sleep for 5 seconds on failure once operational */
+#define DEFAULT_FAILURE_WAITTIME 10 /* sleep for 10 seconds on failure once operational */
#define DEFAULT_QUALIFICATION_TIMEOUT 2
#define DEFAULT_FOREIGN_MASTER_TIME_WINDOW 4
Added: trunk/src/dep/configdefaults.c
===================================================================
--- trunk/src/dep/configdefaults.c (rev 0)
+++ trunk/src/dep/configdefaults.c 2015-10-13 21:23:29 UTC (rev 589)
@@ -0,0 +1,570 @@
+/*-
+ * Copyright (c) 2013-2015 Wojciech Owczarek,
+ *
+ * All Rights Reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file configtemplates.c
+ * @date Mon Oct 12 03:25:32 2015
+ *
+ * @brief Definitions of configuration templates
+ *
+ */
+
+#include "../ptpd.h"
+
+#define CONFIG_ISTRUE(key) \
+ (iniparser_getboolean(dict,key,FALSE)==TRUE)
+
+#define IS_QUIET()\
+ ( CONFIG_ISTRUE("%quiet%:%quiet%") )
+
+/*
+ * static definition of configuration templates - maximum 100 settings per template,
+ * as defined in configtemplates.h. Template for a template below.
+ */
+
+/* =============== configuration templates begin ===============*/
+
+static const ConfigTemplate configTemplates[] = {
+
+ { "g8265-e2e-master", {
+ {"ptpengine:preset", "masteronly"},
+ {"ptpengine:ip_mode", "unicast"},
+ {"ptpengine:unicast_negotiation", "y"},
+ {"ptpengine:domain", "4"},
+ {"ptpengine:disable_bmca", "y"},
+ {"ptpentine:delay_mechanism", "E2E"},
+ {"ptpengine:log_sync_interval", "-6"},
+ {"ptpengine:log_delayreq_interval", "-6"},
+ {"ptpengine:announce_receipt_timeout", "3"},
+ {"ptpengine:priority1", "128"},
+ {"ptpengine:priority2", "128"},
+ {NULL}}
+ },
+
+ { "g8265-e2e-slave", {
+ {"ptpengine:preset", "slaveonly"},
+ {"ptpengine:ip_mode", "unicast"},
+ {"ptpengine:unicast_negotiation", "y"},
+ {"ptpengine:domain", "4"},
+ {"ptpengine:delay_mechanism", "E2E"},
+ {"ptpengine:announce_receipt_timeout", "3"},
+ {NULL}}
+ },
+
+ { "layer2-p2p-master", {
+ {"ptpengine:transport","ethernet"},
+ {"ptpengine:delay_mechanism","P2P"},
+ {"ptpengine:preset","masteronly"},
+// {"",""},
+ {NULL}}
+ },
+
+ { "layer2-p2p-slave", {
+ {"ptpengine:transport","ethernet"},
+ {"ptpengine:delay_mechanism","E2E"},
+ {"ptpengine:preset","slaveonly"},
+// {"",""},
+ {NULL}}
+ },
+
+ { "valid-utc-properties", {
+ {"ptpengine:ptp_timescale","PTP"},
+ {"ptpengine:time_traceable","y"},
+ {"ptpengine:frequency_traceable","y"},
+ {"clock:leap_seconds_file",""},
+ {NULL}}
+ },
+
+ { "full-logging", {
+ {"global:log_status", "y"},
+ {"global:status_file", "/var/run/ptpd2.status"},
+ {"global:statistics_log_interval", "1"},
+ {"global:lock_file", "/var/run/ptpd2.pid"},
+ {"global:log_statistics", "y"},
+ {"global:statistics_file", "/var/log/ptpd2.statistics"},
+// {"global:statistics_file_truncate", "n"},
+ {"global:log_file", "/var/log/ptpd2.log"},
+ {"global:statistics_timestamp_format", "both"},
+ {NULL}}
+ },
+
+ { "full-logging-instance", {
+ {"global:log_status", "y"},
+ {"global:status_file", "/var/run/ptpd2.%instance%.status"},
+ {"global:statistics_log_interval", "1"},
+ {"global:lock_file", "/var/run/ptpd2.%instance%.pid"},
+ {"global:log_statistics", "y"},
+ {"global:statistics_file", "/var/log/ptpd2.%instance%.statistics"},
+// {"global:statistics_file_truncate", "n"},
+ {"global:log_file", "/var/log/ptpd2.%instance%.log"},
+ {"global:statistics_timestamp_format", "both"},
+ {NULL}}
+ },
+
+
+ {NULL}
+};
+
+/* =============== configuration templates end ===============*/
+
+/* template of a template looks like this... */
+
+/*
+ { "template-name", {
+ {"section:key","value"},
+ {"",""},
+ {NULL}}
+ },
+
+ { "", {
+ {"",""},
+ {"",""},
+ {NULL}}
+ },
+
+
+*/
+
+/* Load all rtOpts defaults */
+void
+loadDefaultSettings( RunTimeOpts* rtOpts )
+{
+
+ /* Wipe the memory first to avoid unconsistent behaviour - no need to set Boolean to FALSE, int to 0 etc. */
+ memset(rtOpts, 0, sizeof(RunTimeOpts));
+
+ rtOpts->logAnnounceInterval = DEFAULT_ANNOUNCE_INTERVAL;
+ rtOpts->logSyncInterval = DEFAULT_SYNC_INTERVAL;
+ rtOpts->logMinPdelayReqInterval = DEFAULT_PDELAYREQ_INTERVAL;
+ rtOpts->clockQuality.clockAccuracy = DEFAULT_CLOCK_ACCURACY;
+ rtOpts->clockQuality.clockClass = DEFAULT_CLOCK_CLASS;
+ rtOpts->clockQuality.offsetScaledLogVariance = DEFAULT_CLOCK_VARIANCE;
+ rtOpts->priority1 = DEFAULT_PRIORITY1;
+ rtOpts->priority2 = DEFAULT_PRIORITY2;
+ rtOpts->domainNumber = DEFAULT_DOMAIN_NUMBER;
+ rtOpts->portNumber = NUMBER_PORTS;
+
+ rtOpts->anyDomain = FALSE;
+
+ rtOpts->transport = UDP_IPV4;
+
+ /* timePropertiesDS */
+ rtOpts->timeProperties.currentUtcOffsetValid = DEFAULT_UTC_VALID;
+ rtOpts->timeProperties.currentUtcOffset = DEFAULT_UTC_OFFSET;
+ rtOpts->timeProperties.timeSource = INTERNAL_OSCILLATOR;
+ rtOpts->timeProperties.timeTraceable = FALSE;
+ rtOpts->timeProperties.frequencyTraceable = FALSE;
+ rtOpts->timeProperties.ptpTimescale = TRUE;
+
+ rtOpts->ipMode = IPMODE_MULTICAST;
+ rtOpts->dot2AS = FALSE;
+
+ rtOpts->disableUdpChecksums = TRUE;
+
+ rtOpts->unicastNegotiation = FALSE;
+ rtOpts->unicastNegotiationListening = FALSE;
+ rtOpts->disableBMCA = FALSE;
+ rtOpts->unicastGrantDuration = 300;
+ rtOpts->unicastAcceptAny = FALSE;
+ rtOpts->unicastPortMask = 0;
+
+ rtOpts->noAdjust = NO_ADJUST; // false
+ rtOpts->logStatistics = TRUE;
+ rtOpts->statisticsTimestamp = TIMESTAMP_DATETIME;
+
+ rtOpts->periodicUpdates = FALSE; /* periodically log a status update */
+
+ /* Deep display of all packets seen by the daemon */
+ rtOpts->displayPackets = FALSE;
+
+ rtOpts->s = DEFAULT_DELAY_S;
+ rtOpts->inboundLatency.nanoseconds = DEFAULT_INBOUND_LATENCY;
+ rtOpts->outboundLatency.nanoseconds = DEFAULT_OUTBOUND_LATENCY;
+ rtOpts->max_foreign_records = DEFAULT_MAX_FOREIGN_RECORDS;
+ rtOpts->nonDaemon = FALSE;
+
+ /*
+ * defaults for new options
+ */
+ rtOpts->ignore_delayreq_interval_master = FALSE;
+ rtOpts->do_IGMP_refresh = TRUE;
+ rtOpts->useSysLog = FALSE;
+ rtOpts->announceReceiptTimeout = DEFAULT_ANNOUNCE_RECEIPT_TIMEOUT;
+#ifdef RUNTIME_DEBUG
+ rtOpts->debug_level = LOG_INFO; /* by default debug messages as disabled, but INFO messages and below are printed */
+#endif
+ rtOpts->ttl = 64;
+ rtOpts->delayMechanism = DEFAULT_DELAY_MECHANISM;
+ rtOpts->noResetClock = DEFAULT_NO_RESET_CLOCK;
+ rtOpts->stepOnce = FALSE;
+ rtOpts->stepForce = FALSE;
+#ifdef HAVE_LINUX_RTC_H
+ rtOpts->setRtc = FALSE;
+#endif /* HAVE_LINUX_RTC_H */
+
+ rtOpts->clearCounters = FALSE;
+ rtOpts->statisticsLogInterval = 0;
+
+ rtOpts->initial_delayreq = DEFAULT_DELAYREQ_INTERVAL;
+ rtOpts->logMinDelayReqInterval = DEFAULT_DELAYREQ_INTERVAL;
+ rtOpts->autoDelayReqInterval = TRUE;
+ rtOpts->masterRefreshInterval = 60;
+
+ /* maximum values for unicast negotiation */
+ rtOpts->logMaxPdelayReqInterval = 5;
+ rtOpts->logMaxDelayReqInterval = 5;
+ rtOpts->logMaxSyncInterval = 5;
+ rtOpts->logMaxAnnounceInterval = 5;
+
+ rtOpts->drift_recovery_method = DRIFT_KERNEL;
+ strncpy(rtOpts->lockDirectory, DEFAULT_LOCKDIR, PATH_MAX);
+ strncpy(rtOpts->driftFile, DEFAULT_DRIFTFILE, PATH_MAX);
+/* strncpy(rtOpts->lockFile, DEFAULT_LOCKFILE, PATH_MAX); */
+ rtOpts->autoLockFile = FALSE;
+ rtOpts->snmp_enabled = FALSE;
+ /* This will only be used if the "none" preset is configured */
+#ifndef PTPD_SLAVE_ONLY
+ rtOpts->slaveOnly = FALSE;
+#else
+ rtOpts->slaveOnly = TRUE;
+#endif /* PTPD_SLAVE_ONLY */
+ /* Otherwise default to slave only via the preset */
+ rtOpts->selectedPreset = PTP_PRESET_SLAVEONLY;
+ rtOpts->pidAsClockId = FALSE;
+
+ /* highest possible */
+ rtOpts->logLevel = LOG_ALL;
+
+ /* ADJ_FREQ_MAX by default */
+ rtOpts->servoMaxPpb = ADJ_FREQ_MAX / 1000;
+ /* kP and kI are scaled to 10000 and are gains now - values same as originally */
+ rtOpts->servoKP = 0.1;
+ rtOpts->servoKI = 0.001;
+
+ rtOpts->servoDtMethod = DT_CONSTANT;
+ /* when measuring dT, use a maximum of 5 sync intervals (would correspond to avg 20% discard rate) */
+ rtOpts->servoMaxdT = 5.0;
+
+ /* disabled by default */
+ rtOpts->announceTimeoutGracePeriod = 0;
+
+ /* currentUtcOffsetValid compatibility flags */
+ rtOpts->alwaysRespectUtcOffset = TRUE;
+ rtOpts->preferUtcValid = FALSE;
+ rtOpts->requireUtcValid = FALSE;
+
+ /* Try 46 for expedited forwarding */
+ rtOpts->dscpValue = 0;
+
+#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H) || defined (__QNXNTO__)
+ rtOpts-> cpuNumber = -1;
+#endif /* (linux && HAVE_SCHED_H) || HAVE_SYS_CPUSET_H*/
+
+#ifdef PTPD_STATISTICS
+
+ rtOpts->oFilterMSConfig.enabled = FALSE;
+ rtOpts->oFilterMSConfig.discard = TRUE;
+ rtOpts->oFilterMSConfig.autoTune = TRUE;
+ rtOpts->oFilterMSConfig.stepDelay = FALSE;
+ rtOpts->oFilterMSConfig.alwaysFilter = FALSE;
+ rtOpts->oFilterMSConfig.stepThreshold = 1000000;
+ rtOpts->oFilterMSConfig.stepLevel = 500000;
+ rtOpts->oFilterMSConfig.capacity = 20;
+ rtOpts->oFilterMSConfig.threshold = 1.0;
+ rtOpts->oFilterMSConfig.weight = 1;
+ rtOpts->oFilterMSConfig.minPercent = 20;
+ rtOpts->oFilterMSConfig.maxPercent = 95;
+ rtOpts->oFilterMSConfig.thresholdStep = 0.1;
+ rtOpts->oFilterMSConfig.minThreshold = 0.1;
+ rtOpts->oFilterMSConfig.maxThreshold = 5.0;
+ rtOpts->oFilterMSConfig.delayCredit = 200;
+ rtOpts->oFilterMSConfig.creditIncrement = 10;
+ rtOpts->oFilterMSConfig.maxDelay = 1500;
+
+ rtOpts->oFilterSMConfig.enabled = FALSE;
+ rtOpts->oFilterSMConfig.discard = TRUE;
+ rtOpts->oFilterSMConfig.autoTune = TRUE;
+ rtOpts->oFilterSMConfig.stepDelay = FALSE;
+ rtOpts->oFilterSMConfig.alwaysFilter = FALSE;
+ rtOpts->oFilterSMConfig.stepThreshold = 1000000;
+ rtOpts->oFilterSMConfig.stepLevel = 500000;
+ rtOpts->oFilterSMConfig.capacity = 20;
+ rtOpts->oFilterSMConfig.threshold = 1.0;
+ rtOpts->oFilterSMConfig.weight = 1;
+ rtOpts->oFilterSMConfig.minPercent = 20;
+ rtOpts->oFilterSMConfig.maxPercent = 95;
+ rtOpts->oFilterSMConfig.thresholdStep = 0.1;
+ rtOpts->oFilterSMConfig.minThreshold = 0.1;
+ rtOpts->oFilterSMConfig.maxThreshold = 5.0;
+ rtOpts->oFilterSMConfig.delayCredit = 200;
+ rtOpts->oFilterSMConfig.creditIncrement = 10;
+ rtOpts->oFilterSMConfig.maxDelay = 1500;
+
+ rtOpts->filterMSOpts.enabled = FALSE;
+ rtOpts->filterMSOpts.filterType = FILTER_MIN;
+ rtOpts->filterMSOpts.windowSize = 4;
+ rtOpts->filterMSOpts.windowType = WINDOW_SLIDING;
+
+ rtOpts->filterSMOpts.enabled = FALSE;
+ rtOpts->filterSMOpts.filterType = FILTER_MIN;
+ rtOpts->filterSMOpts.windowSize = 4;
+ rtOpts->filterSMOpts.windowType = WINDOW_SLIDING;
+
+ /* How often refresh statistics (seconds) */
+ rtOpts->statsUpdateInterval = 30;
+ /* Servo stability detection settings follow */
+ rtOpts->servoStabilityDetection = FALSE;
+ /* Stability threshold (ppb) - observed drift std dev value considered stable */
+ rtOpts->servoStabilityThreshold = 10;
+ /* How many consecutive statsUpdateInterval periods of observed drift std dev within threshold means stable servo */
+ rtOpts->servoStabilityPeriod = 1;
+ /* How many minutes without servo stabilisation means servo has not stabilised */
+ rtOpts->servoStabilityTimeout = 10;
+ /* How long to wait for one-way delay prefiltering */
+ rtOpts->calibrationDelay = 0;
+ /* if set to TRUE and maxDelay is defined, only check against threshold if servo is stable */
+ rtOpts->maxDelayStableOnly = FALSE;
+ /* if set to non-zero, reset slave if more than this amount of consecutive delay measurements was above maxDelay */
+ rtOpts->maxDelayMaxRejected = 0;
+#endif
+
+ /* status file options */
+ rtOpts->statusFileUpdateInterval = 1;
+
+ /* panic mode options */
+ rtOpts->enablePanicMode = FALSE;
+ rtOpts->panicModeDuration = 2;
+ rtOpts->panicModeExitThreshold = 0;
+
+ /* full network reset after 5 times in listening */
+ rtOpts->maxListen = 5;
+
+ rtOpts->panicModeReleaseClock = FALSE;
+ rtOpts->ntpOptions.enableEngine = FALSE;
+ rtOpts->ntpOptions.enableControl = FALSE;
+ rtOpts->ntpOptions.enableFailover = FALSE;
+ rtOpts->ntpOptions.failoverTimeout = 120;
+ rtOpts->ntpOptions.checkInterval = 15;
+ rtOpts->ntpOptions.keyId = 0;
+ strncpy(rtOpts->ntpOptions.hostAddress,"localhost",MAXHOSTNAMELEN); /* not configurable, but could be */
+ rtOpts->preferNTP = FALSE;
+
+ rtOpts->leapSecondPausePeriod = 5;
+ /* by default, announce the leap second 12 hours before the event:
+ * Clause 9.4 paragraph 5 */
+ rtOpts->leapSecondNoticePeriod = 43200;
+ rtOpts->leapSecondHandling = LEAP_ACCEPT;
+ rtOpts->leapSecondSmearPeriod = 86400;
+
+/* timing domain */
+ rtOpts->idleTimeout = 120; /* idle timeout */
+ rtOpts->electionDelay = 15; /* anti-flapping delay */
+
+/* Log file settings */
+
+ rtOpts->statisticsLog.logID = "statistics";
+ rtOpts->statisticsLog.openMode = "a+";
+ rtOpts->statisticsLog.logFP = NULL;
+ rtOpts->statisticsLog.truncateOnReopen = FALSE;
+ rtOpts->statisticsLog.unlinkOnClose = FALSE;
+ rtOpts->statisticsLog.maxSize = 0;
+
+ rtOpts->recordLog.logID = "record";
+ rtOpts->recordLog.openMode = "a+";
+ rtOpts->recordLog.logFP = NULL;
+ rtOpts->recordLog.truncateOnReopen = FALSE;
+ rtOpts->recordLog.unlinkOnClose = FALSE;
+ rtOpts->recordLog.maxSize = 0;
+
+ rtOpts->eventLog.logID = "log";
+ rtOpts->eventLog.openMode = "a+";
+ rtOpts->eventLog.logFP = NULL;
+ rtOpts->eventLog.truncateOnReopen = FALSE;
+ rtOpts->eventLog.unlinkOnClose = FALSE;
+ rtOpts->eventLog.maxSize = 0;
+
+ rtOpts->statusLog.logID = "status";
+ rtOpts->statusLog.openMode = "w";
+ strncpy(rtOpts->statusLog.logPath, DEFAULT_STATUSFILE, PATH_MAX);
+ rtOpts->statusLog.logFP = NULL;
+ rtOpts->statusLog.truncateOnReopen = FALSE;
+ rtOpts->statusLog.unlinkOnClose = TRUE;
+
+/* Management message support settings */
+ rtOpts->managementEnabled = TRUE;
+ rtOpts->managementSetEnable = FALSE;
+
+/* IP ACL settings */
+
+ rtOpts->timingAclEnabled = FALSE;
+ rtOpts->managementAclEnabled = FALSE;
+ rtOpts->timingAclOrder = ACL_DENY_PERMIT;
+ rtOpts->managementAclOrder = ACL_DENY_PERMIT;
+
+ // by default we don't check Sync message sequence continuity
+ rtOpts->syncSequenceChecking = FALSE;
+ rtOpts->clockUpdateTimeout = 0;
+
+}
+
+/* The PtpEnginePreset structure for reference:
+
+typedef struct {
+
+ char* presetName;
+ Boolean slaveOnly;
+ Boolean noAdjust;
+ UInteger8_option clockClass;
+
+} PtpEnginePreset;
+*/
+
+PtpEnginePreset
+getPtpPreset(int presetNumber, RunTimeOpts* rtOpts)
+{
+
+ PtpEnginePreset ret;
+
+ memset(&ret,0,sizeof(ret));
+
+ switch(presetNumber) {
+
+ case PTP_PRESET_SLAVEONLY:
+ ret.presetName="slaveonly";
+ ret.slaveOnly = TRUE;
+ ret.noAdjust = FALSE;
+ ret.clockClass.minValue = SLAVE_ONLY_CLOCK_CLASS;
+ ret.clockClass.maxValue = SLAVE_ONLY_CLOCK_CLASS;
+ ret.clockClass.defaultValue = SLAVE_ONLY_CLOCK_CLASS;
+ break;
+ case PTP_PRESET_MASTERSLAVE:
+ ret.presetName = "masterslave";
+ ret.slaveOnly = FALSE;
+ ret.noAdjust = FALSE;
+ ret.clockClass.minValue = 128;
+ ret.clockClass.maxValue = 254;
+ ret.clockClass.defaultValue = DEFAULT_CLOCK_CLASS;
+ break;
+ case PTP_PRESET_MASTERONLY:
+ ret.presetName = "masteronly";
+ ret.slaveOnly = FALSE;
+ ret.noAdjust = TRUE;
+ ret.clockClass.minValue = 0;
+ ret.clockClass.maxValue = 127;
+ ret.clockClass.defaultValue = DEFAULT_CLOCK_CLASS__APPLICATION_SPECIFIC_TIME_SOURCE;
+ break;
+ default:
+ ret.presetName = "none";
+ ret.slaveOnly = rtOpts->slaveOnly;
+ ret.noAdjust = rtOpts->noAdjust;
+ ret.clockClass.minValue = 0;
+ ret.clockClass.maxValue = 255;
+ ret.clockClass.defaultValue = rtOpts->clockQuality.clockClass;
+ }
+
+ return ret;
+}
+
+
+/* split list to tokens, look for each template and apply it if found */
+int
+applyConfigTemplates(char *templateNames, dictionary *dict) {
+
+ ConfigTemplate *template = NULL;
+ TemplateOption *option = NULL;
+ char *templateName = NULL;
+ Boolean found = 0;
+
+ char* stash;
+ char* text_;
+ char* text__;
+
+ if(dict == NULL) {
+ return 0;
+ }
+
+ if(strlen(templateNames)==0) return 0;
+
+ text_=strdup(templateNames);
+
+ for(text__=text_;; text__=NULL) {
+
+ templateName=strtok_r(text__,", ;\t",&stash);
+ if(templateName==NULL) break;
+
+ found = 0;
+ template = (ConfigTemplate*)configTemplates;
+ while(template->name != NULL) {
+ if(!strcmp(template->name, templateName)) {
+ DBG("Loading config template %s\n", template->name);
+ option = (TemplateOption*)template->options;
+ while(option->name != NULL) {
+ dictionary_set(dict, option->name, option->value);
+ DBG("----> %s = %s",option->name, option->value);
+ option++;
+ }
+ found = 1;
+ if (!IS_QUIET()) NOTICE("Applied configuration template \"%s\"\n", templateName);
+ break;
+ }
+ template++;
+ }
+
+ if(!found) {
+ if (!IS_QUIET()) WARNING("Configuration template \"%s\" not found\n", templateName);
+ }
+
+ }
+
+ if(text_ != NULL) {
+ free(text_);
+ }
+
+ return 0;
+
+}
+
+/* dump the list of templates provided */
+void
+dumpConfigTemplates() {
+
+ ConfigTemplate *template = NULL;
+ TemplateOption *option = NULL;
+
+ template = (ConfigTemplate*)configTemplates;
+ while(template->name != NULL) {
+ printf("Template: %s\n\n", template->name);
+ option = (TemplateOption*)template->options;
+ while(option->name != NULL) {
+ printf("\t\t%s=\"%s\"\n", option->name, option->value);
+ option++;
+ }
+ template++;
+ printf("\n");
+ }
+
+}
Added: trunk/src/dep/configdefaults.h
===================================================================
--- trunk/src/dep/configdefaults.h (rev 0)
+++ trunk/src/dep/configdefaults.h 2015-10-13 21:23:29 UTC (rev 589)
@@ -0,0 +1,49 @@
+/**
+ * @file configdefaults.h
+ *
+ * @brief definitions related to config templates and defaults
+ *
+ *
+ */
+
+#ifndef PTPD_CONFIGDEFAULTS_H_
+#define PTPD_CONFIGDEFAULTS_H_
+
+#include <stddef.h>
+#include "iniparser/iniparser.h"
+
+typedef struct {
+ char * name;
+ char * value;
+} TemplateOption;
+
+typedef struct {
+ char * name;
+ TemplateOption options[100];
+} ConfigTemplate;
+
+/* Structure defining a PTP engine preset */
+typedef struct {
+
+ char* presetName;
+ Boolean slaveOnly;
+ Boolean noAdjust;
+ UInteger8_option clockClass;
+
+} PtpEnginePreset;
+
+/* Preset definitions */
+enum {
+ PTP_PRESET_NONE,
+ PTP_PRESET_SLAVEONLY,
+ PTP_PRESET_MASTERSLAVE,
+ PTP_PRESET_MASTERONLY,
+ PTP_PRESET_MAX
+};
+
+void loadDefaultSettings( RunTimeOpts* rtOpts );
+int applyConfigTemplates(char *templateNames, dictionary *dict);
+PtpEnginePreset getPtpPreset(int presetNumber, RunTimeOpts* rtOpts);
+void dumpConfigTemplates();
+
+#endif /* PTPD_CONFIGDEFAULTS_H_ */
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/src/dep/daemonconfig.c 2015-10-13 21:23:29 UTC (rev 589)
@@ -797,348 +797,37 @@
}
}
printf("\n");
-}
-/* Load all rtOpts defaults */
-void
-loadDefaultSettings( RunTimeOpts* rtOpts )
-{
-
- /* Wipe the memory first to avoid unconsistent behaviour - no need to set Boolean to FALSE, int to 0 etc. */
- memset(rtOpts, 0, sizeof(RunTimeOpts));
-
- rtOpts->logAnnounceInterval = DEFAULT_ANNOUNCE_INTERVAL;
- rtOpts->logSyncInterval = DEFAULT_SYNC_INTERVAL;
- rtOpts->logMinPdelayReqInterval = DEFAULT_PDELAYREQ_INTERVAL;
- rtOpts->clockQuality.clockAccuracy = DEFAULT_CLOCK_ACCURACY;
- rtOpts->clockQuality.clockClass = DEFAULT_CLOCK_CLASS;
- rtOpts->clockQuality.offsetScaledLogVariance = DEFAULT_CLOCK_VARIANCE;
- rtOpts->priority1 = DEFAULT_PRIORITY1;
- rtOpts->priority2 = DEFAULT_PRIORITY2;
- rtOpts->domainNumber = DEFAULT_DOMAIN_NUMBER;
- rtOpts->portNumber = NUMBER_PORTS;
-
- rtOpts->anyDomain = FALSE;
-
- rtOpts->transport = UDP_IPV4;
-
- /* timePropertiesDS */
- rtOpts->timeProperties.currentUtcOffsetValid = DEFAULT_UTC_VALID;
- rtOpts->timeProperties.currentUtcOffset = DEFAULT_UTC_OFFSET;
- rtOpts->timeProperties.timeSource = INTERNAL_OSCILLATOR;
- rtOpts->timeProperties.timeTraceable = FALSE;
- rtOpts->timeProperties.frequencyTraceable = FALSE;
- rtOpts->timeProperties.ptpTimescale = TRUE;
-
- rtOpts->ipMode = IPMODE_MULTICAST;
- rtOpts->dot2AS = FALSE;
-
- rtOpts->disableUdpChecksums = TRUE;
-
- rtOpts->unicastNegotiation = FALSE;
- rtOpts->unicastNegotiationListening = FALSE;
- rtOpts->disableBMCA = FALSE;
- rtOpts->unicastGrantDuration = 300;
- rtOpts->unicastAcceptAny = FALSE;
- rtOpts->unicastPortMask = 0;
-
- rtOpts->noAdjust = NO_ADJUST; // false
- rtOpts->logStatistics = TRUE;
- rtOpts->statisticsTimestamp = TIMESTAMP_DATETIME;
-
- rtOpts->periodicUpdates = FALSE; /* periodically log a status update */
-
- /* Deep display of all packets seen by the daemon */
- rtOpts->displayPackets = FALSE;
-
- rtOpts->s = DEFAULT_DELAY_S;
- rtOpts->inboundLatency.nanoseconds = DEFAULT_INBOUND_LATENCY;
- rtOpts->outboundLatency.nanoseconds = DEFAULT_OUTBOUND_LATENCY;
- rtOpts->max_foreign_records = DEFAULT_MAX_FOREIGN_RECORDS;
- rtOpts->nonDaemon = FALSE;
-
- /*
- * defaults for new options
- */
- rtOpts->ignore_delayreq_interval_master = FALSE;
- rtOpts->do_IGMP_refresh = TRUE;
- rtOpts->useSysLog = FALSE;
- rtOpts->announceReceiptTimeout = DEFAULT_ANNOUNCE_RECEIPT_TIMEOUT;
-#ifdef RUNTIME_DEBUG
- rtOpts->debug_level = LOG_INFO; /* by default debug messages as disabled, but INFO messages and below are printed */
-#endif
- rtOpts->ttl = 64;
- rtOpts->delayMechanism = DEFAULT_DELAY_MECHANISM;
- rtOpts->noResetClock = DEFAULT_NO_RESET_CLOCK;
- rtOpts->stepOnce = FALSE;
- rtOpts->stepForce = FALSE;
-#ifdef HAVE_LINUX_RTC_H
- rtOpts->setRtc = FALSE;
-#endif /* HAVE_LINUX_RTC_H */
-
- rtOpts->clearCounters = FALSE;
- rtOpts->statisticsLogInterval = 0;
-
- rtOpts->initial_delayreq = DEFAULT_DELAYREQ_INTERVAL;
- rtOpts->logMinDelayReqInterval = DEFAULT_DELAYREQ_INTERVAL;
- rtOpts->autoDelayReqInterval = TRUE;
- rtOpts->masterRefreshInterval = 60;
-
- /* maximum values for unicast negotiation */
- rtOpts->logMaxPdelayReqInterval = 5;
- rtOpts->logMaxDelayReqInterval = 5;
- rtOpts->logMaxSyncInterval = 5;
- rtOpts->logMaxAnnounceInterval = 5;
-
-
-
- rtOpts->drift_recovery_method = DRIFT_KERNEL;
- strncpy(rtOpts->lockDirectory, DEFAULT_LOCKDIR, PATH_MAX);
- strncpy(rtOpts->driftFile, DEFAULT_DRIFTFILE, PATH_MAX);
-/* strncpy(rtOpts->lockFile, DEFAULT_LOCKFILE, PATH_MAX); */
- rtOpts->autoLockFile = FALSE;
- rtOpts->snmp_enabled = FALSE;
- /* This will only be used if the "none" preset is configured */
-#ifndef PTPD_SLAVE_ONLY
- rtOpts->slaveOnly = FALSE;
-#else
- rtOpts->slaveOnly = TRUE;
-#endif /* PTPD_SLAVE_ONLY */
- /* Otherwise default to slave only via the preset */
- rtOpts->selectedPreset = PTP_PRESET_SLAVEONLY;
- rtOpts->pidAsClockId = FALSE;
-
- /* highest possible */
- rtOpts->logLevel = LOG_ALL;
-
- /* ADJ_FREQ_MAX by default */
- rtOpts->servoMaxPpb = ADJ_FREQ_MAX / 1000;
- /* kP and kI are scaled to 10000 and are gains now - values same as originally */
- rtOpts->servoKP = 0.1;
- rtOpts->servoKI = 0.001;
-
- rtOpts->servoDtMethod = DT_CONSTANT;
- /* when measuring dT, use a maximum of 5 sync intervals (would correspond to avg 20% discard rate) */
- rtOpts->servoMaxdT = 5.0;
-
- /* disabled by default */
- rtOpts->announceTimeoutGracePeriod = 0;
-
- /* currentUtcOffsetValid compatibility flags */
- rtOpts->alwaysRespectUtcOffset = TRUE;
- rtOpts->preferUtcValid = FALSE;
- rtOpts->requireUtcValid = FALSE;
-
- /* Try 46 for expedited forwarding */
- rtOpts->dscpValue = 0;
-
-#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H) || defined (__QNXNTO__)
- rtOpts-> cpuNumber = -1;
-#endif /* (linux && HAVE_SCHED_H) || HAVE_SYS_CPUSET_H*/
-
-#ifdef PTPD_STATISTICS
-
- rtOpts->oFilterMSConfig.enabled = FALSE;
- rtOpts->oFilterMSConfig.discard = TRUE;
- rtOpts->oFilterMSConfig.autoTune = TRUE;
- rtOpts->oFilterMSConfig.stepDelay = FALSE;
- rtOpts->oFilterMSConfig.alwaysFilter = FALSE;
- rtOpts->oFilterMSConfig.stepThreshold = 1000000;
- rtOpts->oFilterMSConfig.stepLevel = 500000;
- rtOpts->oFilterMSConfig.capacity = 20;
- rtOpts->oFilterMSConfig.threshold = 1.0;
- rtOpts->oFilterMSConfig.weight = 1;
- rtOpts->oFilterMSConfig.minPercent = 20;
- rtOpts->oFilterMSConfig.maxPercent = 95;
- rtOpts->oFilterMSConfig.thresholdStep = 0.1;
- rtOpts->oFilterMSConfig.minThreshold = 0.1;
- rtOpts->oFilterMSConfig.maxThreshold = 5.0;
- rtOpts->oFilterMSConfig.delayCredit = 200;
- rtOpts->oFilterMSConfig.creditIncrement = 10;
- rtOpts->oFilterMSConfig.maxDelay = 1500;
-
- rtOpts->oFilterSMConfig.enabled = FALSE;
- rtOpts->oFilterSMConfig.discard = TRUE;
- rtOpts->oFilterSMConfig.autoTune = TRUE;
- rtOpts->oFilterSMConfig.stepDelay = FALSE;
- rtOpts->oFilterSMConfig.alwaysFilter = FALSE;
- rtOpts->oFilterSMConfig.stepThreshold = 1000000;
- rtOpts->oFilterSMConfig.stepLevel = 500000;
- rtOpts->oFilterSMConfig.capacity = 20;
- rtOpts->oFilterSMConfig.threshold = 1.0;
- rtOpts->oFilterSMConfig.weight = 1;
- rtOpts->oFilterSMConfig.minPercent = 20;
- rtOpts->oFilterSMConfig.maxPercent = 95;
- rtOpts->oFilterSMConfig.thresholdStep = 0.1;
- rtOpts->oFilterSMConfig.minThreshold = 0.1;
- rtOpts->oFilterSMConfig.maxThreshold = 5.0;
- rtOpts->oFilterSMConfig.delayCredit = 200;
- rtOpts->oFilterSMConfig.creditIncrement = 10;
- rtOpts->oFilterSMConfig.maxDelay = 1500;
-
- rtOpts->filterMSOpts.enabled = FALSE;
- rtOpts->filterMSOpts.filterType = FILTER_MIN;
- rtOpts->filterMSOpts.windowSize = 4;
- rtOpts->filterMSOpts.windowType = WINDOW_SLIDING;
-
- rtOpts->filterSMOpts.enabled = FALSE;
- rtOpts->filterSMOpts.filterType = FILTER_MIN;
- rtOpts->filterSMOpts.windowSize = 4;
- rtOpts->filterSMOpts.windowType = WINDOW_SLIDING;
-
- /* How often refresh statistics (seconds) */
- rtOpts->statsUpdateInterval = 30;
- /* Servo stability detection settings follow */
- rtOpts->servoStabilityDetection = FALSE;
- /* Stability threshold (ppb) - observed drift std dev value considered stable */
- rtOpts->servoStabilityThreshold = 10;
- /* How many consecutive statsUpdateInterval periods of observed drift std dev within threshold means stable servo */
- rtOpts->servoStabilityPeriod = 1;
- /* How many minutes without servo stabilisation means servo has not stabilised */
- rtOpts->servoStabilityTimeout = 10;
- /* How long to wait for one-way delay prefiltering */
- rtOpts->calibrationDelay = 0;
- /* if set to TRUE and maxDelay is defined, only check against threshold if servo is stable */
- rtOpts->maxDelayStableOnly = FALSE;
- /* if set to non-zero, reset slave if more than this amount of consecutive delay measurements was above maxDelay */
- rtOpts->maxDelayMaxRejected = 0;
-#endif
-
- /* status file options */
- rtOpts->statusFileUpdateInterval = 1;
-
- /* panic mode options */
- rtOpts->enablePanicMode = FALSE;
- rtOpts->panicModeDuration = 2;
- rtOpts->panicModeExitThreshold = 0;
-
- /* full network reset after 5 times in listening */
- rtOpts->maxListen = 5;
-
- rtOpts->panicModeReleaseClock = FALSE;
- rtOpts->ntpOptions.enableEngine = FALSE;
- rtOpts->ntpOptions.enableControl = FALSE;
- rtOpts->ntpOptions.enableFailover = FALSE;
- rtOpts->ntpOptions.failoverTimeout = 120;
- rtOpts->ntpOptions.checkInterval = 15;
- rtOpts->ntpOptions.keyId = 0;
- strncpy(rtOpts->ntpOptions.hostAddress,"localhost",MAXHOSTNAMELEN); /* not configurable, but could be */
- rtOpts->preferNTP = FALSE;
-
- rtOpts->leapSecondPausePeriod = 5;
- /* by default, announce the leap second 12 hours before the event:
- * Clause 9.4 paragraph 5 */
- rtOpts->leapSecondNoticePeriod = 43200;
- rtOpts->leapSecondHandling = LEAP_ACCEPT;
- rtOpts->leapSecondSmearPeriod = 86400;
-
-/* timing domain */
- rtOpts->idleTimeout = 120; /* idle timeout */
- rtOpts->electionDelay = 15; /* anti-flapping delay */
-
-/* Log file settings */
-
- rtOpts->statisticsLog.logID = "statistics";
- rtOpts->statisticsLog.openMode = "a+";
- rtOpts->statisticsLog.logFP = NULL;
- rtOpts->statisticsLog.truncateOnReopen = FALSE;
- rtOpts->statisticsLog.unlinkOnClose = FALSE;
- rtOpts->statisticsLog.maxSize = 0;
-
- rtOpts->recordLog.logID = "record";
- rtOpts->recordLog.openMode = "a+";
- rtOpts->recordLog.logFP = NULL;
- rtOpts->recordLog.truncateOnReopen = FALSE;
- rtOpts->recordLog.unlinkOnClose = FALSE;
- rtOpts->recordLog.maxSize = 0;
-
- rtOpts->eventLog.logID = "log";
- rtOpts->eventLog.openMode = "a+";
- rtOpts->eventLog.logFP = NULL;
- rtOpts->eventLog.truncateOnReopen = FALSE;
- rtOpts->eventLog.unlinkOnClose = FALSE;
- rtOpts->eventLog.maxSize = 0;
-
- rtOpts->statusLog.logID = "status";
- rtOpts->statusLog.openMode = "w";
- strncpy(rtOpts->statusLog.logPath, DEFAULT_STATUSFILE, PATH_MAX);
- rtOpts->statusLog.logFP = NULL;
- rtOpts->statusLog.truncateOnReopen = FALSE;
- rtOpts->statusLog.unlinkOnClose = TRUE;
-
-/* Management message support settings */
- rtOpts->managementEnabled = TRUE;
- rtOpts->managementSetEnable = FALSE;
-
-/* IP ACL settings */
-
- rtOpts->timingAclEnabled = FALSE;
- rtOpts->managementAclEnabled = FALSE;
- rtOpts->timingAclOrder = ACL_DENY_PERMIT;
- rtOpts->managementAclOrder = ACL_DENY_PERMIT;
-
- // by default we don't check Sync message sequence continuity
- rtOpts->syncSequenceChecking = FALSE;
- rtOpts->clockUpdateTimeout = 0;
-
}
-/* The PtpEnginePreset structure for reference:
-
-typedef struct {
-
- char* presetName;
- Boolean slaveOnly;
- Boolean noAdjust;
- UInteger8_option clockClass;
-
-} PtpEnginePreset;
-*/
-
-PtpEnginePreset
-getPtpPreset(int presetNumber, RunTimeOpts* rtOpts)
+static void
+parseUserVariables(dictionary *dict, dictionary *target)
{
- PtpEnginePreset ret;
+ int i = 0;
+ char *search, *replace, *key;
+ char varname[100];
- memset(&ret,0,sizeof(ret));
+ memset(varname, 0, sizeof(varname));
- switch(presetNumber) {
+ if(dict == NULL) return;
- case PTP_PRESET_SLAVEONLY:
- ret.presetName="slaveonly";
- ret.slaveOnly = TRUE;
- ret.noAdjust = FALSE;
- ret.clockClass.minValue = SLAVE_ONLY_CLOCK_CLASS;
- ret.clockClass.maxValue = SLAVE_ONLY_CLOCK_CLASS;
- ret.clockClass.defaultValue = SLAVE_ONLY_CLOCK_CLASS;
- break;
- case PTP_PRESET_MASTERSLAVE:
- ret.presetName = "masterslave";
- ret.slaveOnly = FALSE;
- ret.noAdjust = FALSE;
- ret.clockClass.minValue = 128;
- ret.clockClass.maxValue = 254;
- ret.clockClass.defaultValue = DEFAULT_CLOCK_CLASS;
- break;
- case PTP_PRESET_MASTERONLY:
- ret.presetName = "masteronly";
- ret.slaveOnly = FALSE;
- ret.noAdjust = TRUE;
- ret.clockClass.minValue = 0;
- ret.clockClass.maxValue = 127;
- ret.clockClass.defaultValue = DEFAULT_CLOCK_CLASS__APPLICATION_SPECIFIC_TIME_SOURCE;
- break;
- default:
- ret.presetName = "none";
- ret.slaveOnly = rtOpts->slaveOnly;
- ret.noAdjust = rtOpts->noAdjust;
- ret.clockClass.minValue = 0;
- ret.clockClass.maxValue = 255;
- ret.clockClass.defaultValue = rtOpts->clockQuality.clockClass;
+ for(i = 0; i < dict->n; i++) {
+ key = dict->key[i];
+ /* key starts with "variables" */
+ if(strstr(key,"variables:") == key) {
+ /* this cannot fail if we are here */
+ search = strstr(key,":");
+ search++;
+ replace = dictionary_get(dict, key, "");
+ snprintf(varname, sizeof(varname), "@%s@", search);
+ DBG("replacing %s with %s in config\n", varname, replace);
+ dictionary_replace(dict, varname, replace);
+ dictionary_set(target, key, replace);
}
- return ret;
+ }
+
}
/**
@@ -1198,6 +887,7 @@
* is complete and free of any unknown options. In the end, warning
* is issued for unknown options. On any errors, NULL is returned
*/
+
dictionary* target = dictionary_new(0);
Boolean parseResult = TRUE;
@@ -1208,6 +898,19 @@
INFO("Checking configuration\n");
}
+ /*
+ * apply the configuration template(s) as statically defined in configdefaults.c
+ * The list of templates is a comma, space or tab separated names. Any templates
+ * are applied before anything else: so any settings after this can override
+ */
+ if (CONFIG_ISPRESENT("global:config_templates")) {
+ applyConfigTemplates(dictionary_get(dict, "global:config_templates", ""), dict);
+ /* also set the template names in the target dictionary */
+ dictionary_set(target, "global:config_templates", dictionary_get(dict, "global:config_templates", ""));
+ }
+
+ parseUserVariables(dict, target);
+
/* ============= BEGIN CONFIG MAPPINGS, TRIGGERS AND DEPENDENCIES =========== */
/* ===== ptpengine section ===== */
@@ -2822,15 +2525,17 @@
{"long-help", no_argument, 0, 'H'},
{"explain", required_argument, 0, 'e'},
{"default-config", optional_argument, 0, 'O'},
+ {"templates", required_argument, 0, 't'},
+ {"show-templates", no_argument, 0, 'T'},
{"unicast", optional_argument, 0, 'U'},
{"unicast-negotiation", optional_argument, 0, 'g'},
{"unicast-destinations", required_argument, 0, 'u'},
{0, 0 , 0, 0}
};
- while ((c = getopt_long(argc, argv, "?c:kb:i:d:sgmGMWyUu:nf:S:r:DvCVHhe:Y:tOLEPAaR:l:p", long_options, &opt_index)) != -1) {
+ while ((c = getopt_long(argc, argv, "?c:kb:i:d:sgmGMWyUu:nf:S:r:DvCVHTt:he:Y:tOLEPAaR:l:p", long_options, &opt_index)) != -1) {
#else
- while ((c = getopt(argc, argv, "?c:kb:i:d:sgmGMWyUu:nf:S:r:DvCVHhe:Y:tOLEPAaR:l:p")) != -1) {
+ while ((c = getopt(argc, argv, "?c:kb:i:d:sgmGMWyUu:nf:S:r:DvCVHTt:he:Y:tOLEPAaR:l:p")) != -1) {
#endif
switch(c) {
/* non-config options first */
@@ -2856,6 +2561,9 @@
case 'O':
printDefaultConfig();
return FALSE;
+ case 'T':
+ dumpConfigTemplates();
+ return FALSE;
/* regular ptpd options */
/* config file path */
@@ -2911,8 +2619,6 @@
dictionary_set(dict,"ptpengine:ip_mode", "unicast");
dictionary_set(dict,"ptpengine:unicast_destinations", optarg);
break;
- case 't':
- WARN_DEPRECATED('t', 'n', "noadjust", "clock:no_adjust");
case 'n':
dictionary_set(dict,"clock:no_adjust", "Y");
break;
@@ -2924,6 +2630,8 @@
case 'S':
dictionary_set(dict,"global:statistics_file", optarg);
break;
+ case 't':
+ dictionary_set(dict,"global:config_templates", optarg);
/* Override delay request interval from master */
case 'a':
dictionary_set(dict,"ptpengine:log_delayreq_override", "Y");
@@ -3067,6 +2775,9 @@
"-R --lock-directory [path] Directory to store lock files\n"
"-f --log-file [path] global:log_file=[path] Log file\n"
"-S --statistics-file [path] global:statistics_file=[path] Statistics file\n"
+ "-T --show-templates display available configuration templates\n"
+ "-t --templates [name],[name],[...]\n"
+ " apply configuration template(s) - see man(5) ptpd2.conf\n"
"\n"
"Basic PTP protocol and daemon configuration options: \n"
"\n"
@@ -3145,6 +2856,18 @@
printPresetHelp();
printf("\n"
+ " Configuration templates available (see man(5) ptpd2.conf):\n"
+ "\n usage:\n"
+ " -t [name],[name],...\n"
+ " --templates [name],[name],...\n"
+ " --global:config_templates=[name],[name],...\n\n");
+
+ dumpConfigTemplates();
+
+ printf("========================\n");
+
+
+ printf("\n"
"Possible internal states:\n"
" init: INITIALIZING\n"
" flt: FAULTY\n"
Modified: trunk/src/dep/daemonconfig.h
===================================================================
--- trunk/src/dep/daemonconfig.h 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/src/dep/daemonconfig.h 2015-10-13 21:23:29 UTC (rev 589)
@@ -10,6 +10,7 @@
#define PTPD_DAEMONCONFIG_H_
#include "iniparser/iniparser.h"
+#include "configdefaults.h"
/* Config reload - component restart status flags */
@@ -41,31 +42,9 @@
#define LOG2_HELP "(expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.)"
-/* Structure defining a PTP engine preset */
-typedef struct {
-
- char* presetName;
- Boolean slaveOnly;
- Boolean noAdjust;
- UInteger8_option clockClass;
-
-} PtpEnginePreset;
-
-/* Preset definitions */
-enum {
- PTP_PRESET_NONE,
- PTP_PRESET_SLAVEONLY,
- PTP_PRESET_MASTERSLAVE,
- PTP_PRESET_MASTERONLY,
- PTP_PRESET_MAX
-};
-
-
-void loadDefaultSettings(RunTimeOpts*);
Boolean loadConfigFile (dictionary**, RunTimeOpts*);
void loadCommandLineKeys(dictionary*, int, char**);
Boolean loadCommandLineOptions(RunTimeOpts*, dictionary*, int, char** , Integer16*);
-PtpEnginePreset getPtpPreset(int presetNumber, RunTimeOpts* rtOpts);
dictionary* parseConfig (dictionary*, RunTimeOpts*);
int reloadConfig ( RunTimeOpts*, PtpClock* );
Boolean compareConfig(dictionary* source, dictionary* target);
Modified: trunk/src/dep/iniparser/AUTHORS
===================================================================
--- trunk/src/dep/iniparser/AUTHORS 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/src/dep/iniparser/AUTHORS 2015-10-13 21:23:29 UTC (rev 589)
@@ -4,3 +4,4 @@
not kept track of all the people who contributed. Let them be thanked
for their ideas, code, suggestions, corrections, enhancements!
+Further enhancements by Wojciech Owczarek for the PTPd project
Modified: trunk/src/dep/iniparser/dictionary.c
===================================================================
--- trunk/src/dep/iniparser/dictionary.c 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/src/dep/iniparser/dictionary.c 2015-10-13 21:23:29 UTC (rev 589)
@@ -326,6 +326,85 @@
/*-------------------------------------------------------------------------*/
/**
+ @brief Replace string in all values of a dictionary
+ @param d dictionary object to modify.
+ @param search string to be replaced
+ @param replace string to replace with
+ @return void
+
+ This function globally replaces all occurrences of one string in the ditcionary
+ with another in key values.
+
+ */
+/*--------------------------------------------------------------------------*/
+void dictionary_replace(dictionary * d, const char * search, const char * replace)
+{
+
+ int bufsize = MAXVALSZ;
+ char out[bufsize+1];
+ char *in = NULL;
+ char *val = NULL;
+ char *found = NULL;
+ int i = 0, j = 0;
+ int maxcount = 0;
+ char *pos = NULL;
+ char *data = NULL;
+
+ if (search==NULL || replace==NULL ) return;
+
+ for(i = 0; i < d->n; i++) {
+ memset(out, 0, bufsize+1);
+ /* skip if the key is null or is a section */
+ if(d->key[i] == NULL || strstr(d->key[i],":") == NULL)
+ continue;
+
+ val = dictionary_get(d, d->key[i], "");
+ data = strdup(val);
+ in = data;
+ found=strstr(in, search);
+
+ if(found != NULL) {
+ do {
+ pos=found;
+
+ for (j=0; j < strlen(search); j++) {
+ *pos='\0';
+ pos++;
+ }
+ maxcount = bufsize - strlen(out);
+ maxcount = (maxcount < 0) ? 0 : maxcount;
+ strncat(out,in,maxcount);
+
+ maxcount = bufsize - strlen(out);
+ maxcount = (maxcount < 0) ? 0 : maxcount;
+ strncat(out,replace,maxcount);
+
+ in = pos;
+
+ found=strstr(in, search);
+
+ } while (found != NULL);
+
+ if(*pos != 0) {
+ maxcount = bufsize - strlen(out);
+ maxcount = (maxcount < 0) ? 0 : maxcount;
+ strncat(out,pos,maxcount);
+ }
+
+ dictionary_set(d, d->key[i], out);
+// printf("Replaced token \"%s\" with \"%s\": \"%s\" -> \"%s\"\n",
+// search, replace, val, out);
+ }
+ free(data);
+
+ }
+
+
+}
+
+
+/*-------------------------------------------------------------------------*/
+/**
@brief Dump a dictionary to an opened file pointer.
@param d Dictionary to dump
@param f Opened file pointer.
Modified: trunk/src/dep/iniparser/dictionary.h
===================================================================
--- trunk/src/dep/iniparser/dictionary.h 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/src/dep/iniparser/dictionary.h 2015-10-13 21:23:29 UTC (rev 589)
@@ -155,7 +155,21 @@
/*--------------------------------------------------------------------------*/
void dictionary_unset(dictionary * d, const char * key);
+/*-------------------------------------------------------------------------*/
+/**
+ @brief Replace string in all values of a dictionary
+ @param d dictionary object to modify.
+ @param search string to be replaced
+ @param replace string to replace with
+ @return void
+ This function globally replaces all occurrences of one string in the ditcionary
+ with another in key values.
+
+ */
+/*--------------------------------------------------------------------------*/
+void dictionary_replace(dictionary * d, const char * search, const char * replace);
+
/*-------------------------------------------------------------------------*/
/**
@brief Dump a dictionary to an opened file pointer.
Modified: trunk/src/ptpd2.8.in
===================================================================
--- trunk/src/ptpd2.8.in 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/src/ptpd2.8.in 2015-10-13 21:23:29 UTC (rev 589)
@@ -78,6 +78,16 @@
.TP
\fB-S --statistics-file \fIPATH\fR
Path to statistics file (also \fIglobal:statistics_file\fR)
+.TP
+\fB-T --show-templates
+Display built-in configuration templates
+.TP
+\fB-t --templates \fI[name],[name],...\fR
+Apply one or more configuration templates in this order (\fIsee man(5) ptpd2.conf\fR)
+.TP
+\fB-S --statistics-file \fIPATH\fR
+Path to statistics file (also \fIglobal:statistics_file\fR)
+
.SH BASIC PTP PROTOCOL OPTIONS
.TP
\fB-i --interface \fIDEV\fR
Modified: trunk/src/ptpd2.conf.5.in
===================================================================
--- trunk/src/ptpd2.conf.5.in 2015-10-12 16:57:43 UTC (rev 588)
+++ trunk/src/ptpd2.conf.5.in 2015-10-13 21:23:29 UTC (rev 589)
@@ -19,14 +19,12 @@
PTPd will always attempt to test settings before applying them and once running, will never exit as
a result of configuration errors. If it does exit during config refresh, this is most likely a bug.
-.SH PRIORITY
+.SH COMMAND-LINE PRIORITY
Any setting passed as a command line parameter will always take priority over the configuration file,
so once ptpd is running, those settings cannot be changed - a warning will be logged on every
attempt to change those settings using the configuration file.
.SH CONFIGURATION SECTIONS
-
-.TP
.B ptpengine
PTP protocol specific configuration
.TP
@@ -42,10 +40,36 @@
.B ntpengine
NTP control configuration
.TP
+.B variables
+User-defined variables
+.SH USER-DEFINED VARIABLES
+To allow for easier management and automated generation of configuration, PTPd supports user variables,
+which can be defined in the configuration file or in command line. They are defined as \fIvariables:[name]=[value]\fR,
+or if using .ini style format, in the \fI[variables]\fR section. Once defined, a variable can be referred to
+in the remaining configuration settings as \fI@name@\fR, and is substituted with the value of the variable
+
+\fBExample\fR:
+
+variables:instance=server15
+
+global:status_file=/var/run/ptpd2.@instance@.status
+
+global:log_file=/var/run/ptpd2.@instance@.status
+
+\fBNote:\fR for the same effect, ptpd can be run from command line, such as \fI --config=/path/to/file --variables:instance=server15\fR
+
+.SH CONFIGURATION TEMPLATES
+As of version 2.3.1.1, ptpd enables the user to minimise the configuration effort for common scenarios, using built-in templates.
+A template is a named set of pre-defined settings whic are prepended before any other settings, so user can still overwrite
+settings provided by the template. To use this feature, set \fIglobal:config_templates=[name],[name],...\fR in the configuration file,
+or run ptpd with \fI--global:config_templates=[name],[name],...\fR. Multiple templates can be specified, separated by comma, space
+or tab; they are applied in the order they are provided, so template settings override any overlapping settings from previous
+templates specified.
+
+To see the list of available templates, run ptpd with \fI-T\fR or \fI--templates\fR
+
.SH CONFIGURATION VARIABLES
-.BR
-.TP
.RS 0
.TP 8
\fBptpengine:interface [\fISTRING\fB]\fR
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-10-12 16:57:46
|
Revision: 588
http://sourceforge.net/p/ptpd/code/588
Author: wowczarek
Date: 2015-10-12 16:57:43 +0000 (Mon, 12 Oct 2015)
Log Message:
-----------
- Added QNX support:
- clean build on QNX 6.5 out of the box
- adjfreq emulation using native ClockAdjust
- binding to CPU cores
- Experimental (but yield best results):
* interpolated getTime attached to IRQ0
* RX/TX timestamps in software on send or receive,
bypassing pcap or socket timestampint
- implemented unicast negotiation port mask:
when a node sends signaling and other messages
from a different port number, mask is ORed onto it
- UDP checksums disabled on Linux by default:
enables interop with TCs that don't correct checksums
- added options to accept timing from any GMs when
using negotiation: allows a mix of signaling and
non-signaling GMs
- support for systems without getopt_long (like QNX)
- adjfreq-like behaviour on systems with adjtime only:
properly scaled adjtime() pulled into PI servo
(vastly improved sync on systems like OpenBSD and OSX),
support for drift file for those systems
- critical: added minimum POSIX timer interval to prevent from
timers firing to quickly for the process to handle,
resulting in 100% CPU and endless signal queue
- improved processing of unicast destination, domain
and local preference lists
- CPU affinity setting moved to a separate function
- fixed incorrect PTP_UNICAST flag setting for multicast
- fixed missing management or signalling message acceptance
condition (clockid==clockid, portid=0xffff): ISPCS 2015 plugfest
- signaling.c: fixed order of grant processing for PTP messages
(ann,syn,fup,dresp,pdelayresp) instead of numeric loop,
to assist with interop where transmission request order
makes a difference to the master
- signaling.c: do not reset known clock ID when changing GMs,
to allow to keep accepting announce from other masters
- signaling.c: update unicast index when transport address
match only: fix for cache misses for non-best masters
Modified Paths:
--------------
trunk/ChangeLog
trunk/configure.ac
trunk/src/Makefile.am
trunk/src/bmc.c
trunk/src/constants.h
trunk/src/datatypes.h
trunk/src/dep/constants_dep.h
trunk/src/dep/daemonconfig.c
trunk/src/dep/eventtimer.h
trunk/src/dep/eventtimer_itimer.c
trunk/src/dep/eventtimer_posix.c
trunk/src/dep/ipv4_acl.c
trunk/src/dep/net.c
trunk/src/dep/ptpd_dep.h
trunk/src/dep/servo.c
trunk/src/dep/startup.c
trunk/src/dep/sys.c
trunk/src/protocol.c
trunk/src/ptpd.h
trunk/src/ptpd2.conf.5.in
trunk/src/signaling.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/ChangeLog 2015-10-12 16:57:43 UTC (rev 588)
@@ -1,4 +1,4 @@
-2013-09-22 Wojciech Owczarek <woj...@ow...>
+2013-10-12 Wojciech Owczarek <woj...@ow...>
* 2.3.1.1 minor / bugfix release
@@ -21,7 +21,46 @@
- added Sequence ID to statistics log
- Solaris build fixes - linking lnsl and lsocket when
building without SNMP support
+ - critical: added minimum POSIX timer interval to prevent from
+ timers firing to quickly for the process to handle,
+ resulting in 100% CPU and endless signal queue
+ - improved processing of unicast destination, domain
+ and local preference lists
+ - CPU affinity setting moved to a separate function
+ - fixed incorrect PTP_UNICAST flag setting for multicast
+ - fixed missing management or signalling message acceptance
+ condition (clockid==clockid, portid=0xffff): ISPCS 2015 plugfest
+ - signaling.c: fixed order of grant processing for PTP messages
+ (ann,syn,fup,dresp,pdelayresp) instead of numeric loop,
+ to assist with interop where transmission request order
+ makes a difference to the master
+ - signaling.c: do not reset known clock ID when changing GMs,
+ to allow to keep accepting announce from other masters
+ - signaling.c: update unicast index when transport address
+ match only: fix for cache misses for non-best masters
+ * New features since 2.3.1:
+
+ - unicast port number mask to assist with nodes
+ using different port IDs for negotiation
+ - option to accept any GM when unicast negotiation
+ is enabled
+ - UDP checksums disabled on Linux by default:
+ enables interop with TCs that don't correct checksums
+ - Added QNX support:
+ - clean build on QNX 6.5 out of the box
+ - adjfreq emulation using native ClockAdjust
+ - binding to CPU cores
+ - Experimental (but yield best results):
+ * interpolated getTime attached to IRQ0
+ * RX/TX timestamps in software on send or receive,
+ bypassing pcap or socket timestampint
+ - support for systems without getopt_long (like QNX)
+ - adjfreq-like behaviour on systems with adjtime only:
+ properly scaled adjtime() pulled into PI servo
+ (vastly improved sync on systems like OpenBSD and OSX),
+ support for drift file for those systems
+
2013-06-10 Wojciech Owczarek <woj...@ow...>
* 2.3.1 release
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/configure.ac 2015-10-12 16:57:43 UTC (rev 588)
@@ -84,7 +84,7 @@
# Checks for header files.
AC_HEADER_STDC
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h net/ethernet.h netinet/in.h netinet/in_systm.h netinet/ether.h sys/uio.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/sockio.h ifaddrs.h sys/time.h syslog.h unistd.h glob.h sched.h utmp.h utmpx.h linux/rtc.h sys/timex.h])
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h net/ethernet.h netinet/in.h netinet/in_systm.h netinet/ether.h sys/uio.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/sockio.h ifaddrs.h sys/time.h syslog.h unistd.h glob.h sched.h utmp.h utmpx.h unix.h linux/rtc.h sys/timex.h getopt.h])
AC_CHECK_HEADERS([endian.h machine/endian.h sys/isa_defs.h])
@@ -174,6 +174,11 @@
)
# Check for tick in the timex structure
+AC_CHECK_MEMBERS([struct utmp.ut_time], [], [], [
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+])
AC_CHECK_MEMBERS([struct timex.tick], [], [], [[#include <sys/timex.h>]])
AC_CHECK_MEMBERS([struct timex.tai], [], [], [[#include <sys/timex.h>]])
AC_CHECK_MEMBERS([struct ntptimeval.tai], [], [],
@@ -206,7 +211,7 @@
#endif
])
-# Checks for library functions.
+# Checks for library functions
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MALLOC
AC_FUNC_MEMCMP
@@ -214,8 +219,21 @@
AC_TYPE_SIGNAL
AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gethostbyname2 gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol glob pututline utmpxname updwtmpx setutent endutent signal ntp_gettime])
+AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gethostbyname2 gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol glob pututline utmpxname updwtmpx setutent endutent signal ntp_gettime getopt_long])
+if test -n "$GCC"; then
+ AC_MSG_CHECKING(if GCC -fstack-protector is usable)
+ OLDCFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fstack-protector"
+ AC_TRY_LINK(,,[
+ AC_MSG_RESULT(yes)
+ ], [
+ AC_MSG_RESULT(no)
+ CFLAGS="$OLDCFLAGS"
+ ])
+fi
+
+
AC_MSG_NOTICE([************************************************************])
AC_MSG_NOTICE([* PTPD BUILD FLAG AND LIBRARY DEPENDENCY CHECKS START HERE *])
AC_MSG_NOTICE([************************************************************])
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/Makefile.am 2015-10-12 16:57:43 UTC (rev 588)
@@ -5,7 +5,7 @@
sbin_PROGRAMS = ptpd2
man_MANS = ptpd2.8 ptpd2.conf.5
-AM_CFLAGS = $(SNMP_CFLAGS) $(PCAP_CFLAGS) -Wall -fexceptions -fstack-protector
+AM_CFLAGS = $(SNMP_CFLAGS) $(PCAP_CFLAGS) -Wall -fexceptions
AM_CPPFLAGS = $(SNMP_CPPFLAGS) $(PCAP_CPPFLAGS)
AM_LDFLAGS = $(SNMP_LIBS) $(PCAP_LIBS)
Modified: trunk/src/bmc.c
===================================================================
--- trunk/src/bmc.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/bmc.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -618,7 +618,7 @@
s1(header,announce,ptpClock, rtOpts);
if(rtOpts->unicastNegotiation) {
ptpClock->parentGrants = findUnicastGrants(&ptpClock->parentPortIdentity, 0,
- ptpClock->unicastGrants, ptpClock->unicastGrantIndex, ptpClock->unicastDestinationCount ,
+ ptpClock->unicastGrants, &ptpClock->grantIndex, ptpClock->unicastDestinationCount ,
FALSE);
}
if (newBM) {
@@ -658,6 +658,7 @@
} else if (comp > 0) {
s1(header,announce,ptpClock, rtOpts);
if (newBM) {
+ ptpClock->masterAddr = ptpClock->netPath.lastSourceAddr;
displayPortIdentity(&header->sourcePortIdentity,
"New best master selected:");
ptpClock->counters.masterChanges++;
@@ -679,6 +680,7 @@
"New best master selected:");
ptpClock->counters.masterChanges++;
if(ptpClock->portState == PTP_SLAVE)
+ ptpClock->masterAddr = ptpClock->netPath.lastSourceAddr;
displayStatus(ptpClock, "State: ");
if(rtOpts->calibrationDelay) {
ptpClock->isCalibrated = FALSE;
Modified: trunk/src/constants.h
===================================================================
--- trunk/src/constants.h 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/constants.h 2015-10-12 16:57:43 UTC (rev 588)
@@ -285,6 +285,31 @@
ACKNOWLEDGE
};
+/* Enterprise Profile TLV definitions */
+
+#define IETF_OUI 0x000005
+#define IETF_PROFILE 0x01
+
+/* phase adjustment units */
+
+enum {
+
+ PHASEADJ_UNKNOWN = 0x00,
+ PHASEADJ_S = 0x01, /* seconds */
+ PHASEADJ_MS = 0x03, /* milliseconds */
+ PHASEADJ_US = 0x06, /* microsecondas*/
+ PHASEADJ_NS = 0x09, /* nanoseconds */
+ PHASEADJ_PS = 0x12, /* picoseconds */
+ PHASEADJ_FS = 0x15, /* femtoseconds */
+
+ /* coming soon to a GM near you */
+
+ PHASEADJ_AS = 0x18, /* attoseconds (haha) */
+ PHASEADJ_ZS = 0x21, /* zeptoseconds (schwiiing!) */
+ PHASEADJ_YS = 0x24 /* yoctoseconds (I AM GOD) */
+
+};
+
/**
* \brief flagField1 bit position values (Table 20 in the spec)
*/
@@ -328,6 +353,8 @@
PTP_MAX_MESSAGE
};
+#define PTP_MESSAGETYPE_COUNT 10
+
/* communication technology */
enum {
PTP_ETHER, PTP_DEFAULT
Modified: trunk/src/datatypes.h
===================================================================
--- trunk/src/datatypes.h 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/datatypes.h 2015-10-12 16:57:43 UTC (rev 588)
@@ -669,6 +669,12 @@
TimeInternal lastSyncTimestamp; /* last Sync message timestamp sent */
};
+/* Unicast index holder: data + port mask */
+typedef struct {
+ UnicastGrantTable* data[UNICAST_MAX_DESTINATIONS];
+ UInteger16 portMask;
+} UnicastGrantIndex;
+
/* Unicast destination configuration: Address, domain, preference, last Sync timestamp sent */
typedef struct {
Integer32 transportAddress; /* destination address */
@@ -677,6 +683,8 @@
TimeInternal lastSyncTimestamp; /* last Sync timestamp sent */
} UnicastDestination;
+
+
typedef struct {
Integer32 transportAddress;
} SyncDestEntry;
@@ -766,7 +774,7 @@
/* unicast grant table - our own grants or our slaves' grants or grants to peers */
UnicastGrantTable unicastGrants[UNICAST_MAX_DESTINATIONS];
/* our trivial index table to speed up lookups */
- UnicastGrantTable* unicastGrantIndex[UNICAST_MAX_DESTINATIONS];
+ UnicastGrantIndex grantIndex;
/* current parent from the above table */
UnicastGrantTable *parentGrants;
/* previous parent's grants when changing parents: if not null, this is what should be canceled */
@@ -1040,7 +1048,7 @@
int ttl;
int dscpValue;
-#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H)
+#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H) || defined (__QNXNTO__)
int cpuNumber;
#endif /* linux && HAVE_SCHED_H || HAVE_SYS_CPUSET_H*/
@@ -1102,6 +1110,8 @@
int ipMode; /* IP transmission mode */
Boolean dot2AS; /* 801.2AS support -> transportSpecific field */
+ Boolean disableUdpChecksums; /* disable UDP checksum validation where supported */
+
/* list of unicast destinations for use with unicast with or without signaling */
char unicastDestinations[MAXHOSTNAMELEN * UNICAST_MAX_DESTINATIONS];
char unicastDomains[MAXHOSTNAMELEN * UNICAST_MAX_DESTINATIONS];
@@ -1116,6 +1126,13 @@
Boolean unicastNegotiation; /* Enable unicast negotiation support */
Boolean unicastNegotiationListening; /* Master: Reply to signaling messages when in LISTENING */
Boolean disableBMCA; /* used to achieve master-only for unicast */
+ Boolean unicastAcceptAny; /* Slave: accept messages from all GMs, regardless of grants */
+ /*
+ * port mask to apply to portNumber when using negotiation:
+ * treats different port numbers as the same port ID for clocks which
+ * transmit signaling using one port ID, and rest of messages with another
+ */
+ UInteger16 unicastPortMask; /* port mask to apply to portNumber when using negotiation */
#ifdef RUNTIME_DEBUG
int debug_level;
Modified: trunk/src/dep/constants_dep.h
===================================================================
--- trunk/src/dep/constants_dep.h 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/constants_dep.h 2015-10-12 16:57:43 UTC (rev 588)
@@ -16,7 +16,7 @@
/* platform dependent */
#if !defined(linux) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
- !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__sun)
+ !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__sun) && !defined(__QNXNTO__)
#error PTPD hasn't been ported to this OS - should be possible \
if it's POSIX compatible, if you succeed, report it to ptp...@so...
#endif
@@ -34,7 +34,7 @@
#define octet ether_addr_octet
#endif /* linux */
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__sun)
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__sun) || defined(__QNXNTO__)
# include <sys/types.h>
# include <sys/socket.h>
#ifdef HAVE_SYS_SOCKIO_H
@@ -57,6 +57,17 @@
# define IFACE_NAME_LENGTH IF_NAMESIZE
# define NET_ADDRESS_LENGTH INET_ADDRSTRLEN
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#ifdef __QNXNTO__
+#include <sys/neutrino.h>
+#include <sys/syspage.h>
+#define BSD_INTERFACE_FUNCTIONS
+#endif /* __QNXNTO __ */
+
+
#if !defined(ETHER_ADDR_LEN) && defined(ETHERADDRL)
# define ETHER_ADDR_LEN ETHERADDRL
#endif /* ETHER_ADDR_LEN && ETHERADDRL */
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/daemonconfig.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -833,10 +833,14 @@
rtOpts->ipMode = IPMODE_MULTICAST;
rtOpts->dot2AS = FALSE;
+ rtOpts->disableUdpChecksums = TRUE;
+
rtOpts->unicastNegotiation = FALSE;
rtOpts->unicastNegotiationListening = FALSE;
rtOpts->disableBMCA = FALSE;
rtOpts->unicastGrantDuration = 300;
+ rtOpts->unicastAcceptAny = FALSE;
+ rtOpts->unicastPortMask = 0;
rtOpts->noAdjust = NO_ADJUST; // false
rtOpts->logStatistics = TRUE;
@@ -928,7 +932,7 @@
/* Try 46 for expedited forwarding */
rtOpts->dscpValue = 0;
-#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H)
+#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H) || defined (__QNXNTO__)
rtOpts-> cpuNumber = -1;
#endif /* (linux && HAVE_SCHED_H) || HAVE_SYS_CPUSET_H*/
@@ -1276,6 +1280,17 @@
CONFIG_MAP_BOOLEAN("ptpengine:unicast_negotiation",rtOpts->unicastNegotiation,rtOpts->unicastNegotiation,
"Enable unicast negotiation support using signaling messages\n");
+ CONFIG_MAP_BOOLEAN("ptpengine:unicast_any_master",rtOpts->unicastAcceptAny,rtOpts->unicastAcceptAny,
+ "When using unicast negotiation (slave), accept PTP messages from any master.\n"
+ " By default, only messages from acceptable masters (ptpengine:unicast_destinations)\n"
+ " are accepted, and only if transmission was granted by the master\n");
+
+ CONFIG_MAP_INT_RANGE("ptpengine:unicast_port_mask",rtOpts->unicastPortMask,rtOpts->unicastPortMask,
+ "PTP port number wildcard mask applied onto port identities when running\n"
+ " unicast negotiation: allows multiple port identities to be accepted as one.\n"
+ " This option can be used as a workaround where a node sends signaling messages and\n"
+ " timing messages with different port identities",0,65535);
+
CONFIG_KEY_CONDITIONAL_WARNING_ISSET((rtOpts->transport == IEEE_802_3) && rtOpts->unicastNegotiation,
"ptpengine:unicast_negotiation",
"Unicast negotiation cannot be used with Ethernet transport\n");
@@ -1339,6 +1354,11 @@
#endif /* PTPD_PCAP */
+ CONFIG_MAP_BOOLEAN("ptpengine:disable_udp_checksums",rtOpts->disableUdpChecksums,rtOpts->disableUdpChecksums,
+ "Disable UDP checksum validation on UDP sockets (Linux only).\n"
+ " Workaround for situations where a node (like Transparent Clock).\n"
+ " does not rewrite checksums\n");
+
CONFIG_MAP_SELECTVALUE("ptpengine:delay_mechanism",rtOpts->delayMechanism,rtOpts->delayMechanism,
"Delay detection mode used - use DELAY_DISABLED for syntonisation only\n"
" (no full synchronisation).",
@@ -2383,7 +2403,7 @@
CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->statisticsLog.logEnabled && !rtOpts->logStatistics,
rtOpts->statisticsLog.logEnabled, FALSE, rtOpts->statisticsLog.logEnabled);
-#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H)
+#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H) || defined (__QNXNTO__)
CONFIG_MAP_INT_RANGE("global:cpuaffinity_cpucore",rtOpts->cpuNumber,rtOpts->cpuNumber,
"Bind "PTPD_PROGNAME" process to a selected CPU core number.\n"
" 0 = first CPU core, etc. -1 = do not bind to a single core.",
@@ -2754,8 +2774,9 @@
Boolean loadCommandLineOptions(RunTimeOpts* rtOpts, dictionary* dict, int argc, char** argv, Integer16* ret) {
int c;
+#ifdef HAVE_GETOPT_LONG
int opt_index = 0;
-
+#endif /* HAVE_GETOPT_LONG */
*ret = 0;
/* there's NOTHING wrong with this */
@@ -2764,6 +2785,7 @@
goto short_help;
}
+#ifdef HAVE_GETOPT_LONG
/**
* A minimal set of long and short CLI options,
* for basic operations only. Maintained compatibility
@@ -2807,6 +2829,9 @@
};
while ((c = getopt_long(argc, argv, "?c:kb:i:d:sgmGMWyUu:nf:S:r:DvCVHhe:Y:tOLEPAaR:l:p", long_options, &opt_index)) != -1) {
+#else
+ while ((c = getopt(argc, argv, "?c:kb:i:d:sgmGMWyUu:nf:S:r:DvCVHhe:Y:tOLEPAaR:l:p")) != -1) {
+#endif
switch(c) {
/* non-config options first */
@@ -3021,6 +3046,10 @@
"usage: "PTPD_PROGNAME" <options> < --section:key=value...>\n"
"\n"
"WARNING: Any command-line options take priority over options from config file!\n"
+#ifndef HAVE_GETOPT_LONG
+ "WARNING: *** long options below (--some-option) are not supported on this system! \n"
+ "NOTE: *** config file style options (--section:key=value) are still supported\n"
+#endif
"\n"
"Basic options: \n"
"\n"
@@ -3195,9 +3224,16 @@
COMPONENT_RESTART_REQUIRED("ptpengine:backup_interface", PTPD_RESTART_NETWORK );
COMPONENT_RESTART_REQUIRED("ptpengine:preset", PTPD_RESTART_PROTOCOL );
COMPONENT_RESTART_REQUIRED("ptpengine:ip_mode", PTPD_RESTART_NETWORK );
+
+#ifdef SO_NO_CHECK
+ COMPONENT_RESTART_REQUIRED("ptpengine:disable_udp_checksums", PTPD_RESTART_NETWORK );
+#endif /* SO_NO_CHECK */
+
COMPONENT_RESTART_REQUIRED("ptpengine:unicast_negotiation", PTPD_RESTART_PROTOCOL);
COMPONENT_RESTART_REQUIRED("ptpengine:unicast_grant_duration", PTPD_RESTART_PROTOCOL);
// COMPONENT_RESTART_REQUIRED("ptpengine:unicast_negotiation_listening", PTPD_RESTART_NONE );
+// COMPONENT_RESTART_REQUIRED("ptpengine:unicast_any_master", PTPD_RESTART_NONE );
+ COMPONENT_RESTART_REQUIRED("ptpengine:unicast_port_mask", PTPD_RESTART_PROTOCOL );
COMPONENT_RESTART_REQUIRED("ptpengine:disable_bmca", PTPD_RESTART_PROTOCOL );
COMPONENT_RESTART_REQUIRED("ptpengine:transport", PTPD_RESTART_NETWORK );
COMPONENT_RESTART_REQUIRED("ptpengine:dot2as", PTPD_UPDATE_DATASETS );
@@ -3398,7 +3434,7 @@
COMPONENT_RESTART_REQUIRED("global:foreground", PTPD_RESTART_DAEMON );
COMPONENT_RESTART_REQUIRED("global:verbose_foreground", PTPD_RESTART_DAEMON );
-#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H)
+#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H) || defined(__QNXNTO__)
COMPONENT_RESTART_REQUIRED("global:cpuaffinity_cpucore", PTPD_CHANGE_CPUAFFINITY );
#endif /* (linux && HAVE_SCHED_H) || HAVE_SYS_CPUSET_H */
Modified: trunk/src/dep/eventtimer.h
===================================================================
--- trunk/src/dep/eventtimer.h 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/eventtimer.h 2015-10-12 16:57:43 UTC (rev 588)
@@ -30,7 +30,8 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define EVENTTIMER_MAX_DESC 20
+#define EVENTTIMER_MAX_DESC 20
+#define EVENTTIMER_MIN_INTERVAL_US 250 /* 4000/sec */
typedef struct EventTimer EventTimer;
Modified: trunk/src/dep/eventtimer_itimer.c
===================================================================
--- trunk/src/dep/eventtimer_itimer.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/eventtimer_itimer.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -53,7 +53,7 @@
#include "../ptpd.h"
-#define US_TIMER_INTERVAL (62500)
+#define US_TIMER_INTERVAL (31250)
static volatile unsigned int elapsed;
Modified: trunk/src/dep/eventtimer_posix.c
===================================================================
--- trunk/src/dep/eventtimer_posix.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/eventtimer_posix.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -100,6 +100,10 @@
ts.tv_sec = interval;
ts.tv_nsec = (interval - ts.tv_sec) * 1E9;
+ if(!ts.tv_sec && ts.tv_nsec < EVENTTIMER_MIN_INTERVAL_US * 1000) {
+ ts.tv_nsec = EVENTTIMER_MIN_INTERVAL_US * 1000;
+ }
+
DBGV("Timer %s start requested at %d.%4d sec interval\n", timer->id, ts.tv_sec, ts.tv_nsec);
its.it_interval = ts;
Modified: trunk/src/dep/ipv4_acl.c
===================================================================
--- trunk/src/dep/ipv4_acl.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/ipv4_acl.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -120,7 +120,7 @@
static int parseAclEntry(const char* line, AclEntry* acl) {
int result = 1;
- char* stash;
+ char* stash = NULL;
char* text_;
char* token;
char* endptr;
Modified: trunk/src/dep/net.c
===================================================================
--- trunk/src/dep/net.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/net.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014 Wojciech Owczarek,
+ * Copyright (c) 2014-2015 Wojciech Owczarek,
* George V. Neville-Neil
* Copyright (c) 2012-2013 George V. Neville-Neil,
* Wojciech Owczarek.
@@ -863,12 +863,12 @@
return 0;
}
total = found;
- maxCount = found;
+
found = 0;
text_=strdup(rtOpts->unicastDomains);
- for(text__=text_;found < maxCount; text__=NULL) {
+ for(text__=text_;found < total; text__=NULL) {
token=strtok_r(text__,", ;\t",&stash);
if(token==NULL) break;
@@ -884,21 +884,24 @@
free(text_);
}
- maxCount = found;
found = 0;
text_=strdup(rtOpts->unicastLocalPreference);
- for(text__=text_;found < maxCount; text__=NULL) {
+ for(text__=text_;found < total; text__=NULL) {
token=strtok_r(text__,", ;\t",&stash);
- if(token==NULL) break;
- if (sscanf(token,"%d", &tmp)) {
- DBG("hostList %dth host: preference %d\n", found, tmp);
- output[found].localPreference = tmp;
- found++;
+ tmp = 255;
+ if(token!=NULL) {
+ if (sscanf(token,"%d", &tmp) != 1) {
+ tmp = 255;
+ }
}
+ DBG("hostList %dth host: preference %d\n", found, tmp);
+ output[found].localPreference = tmp;
+ found++;
+
}
if(text_ != NULL) {
@@ -924,7 +927,11 @@
netInit(NetPath * netPath, RunTimeOpts * rtOpts, PtpClock * ptpClock)
{
+#ifdef __QNXNTO__
+ unsigned char temp;
+#else
int temp;
+#endif
struct sockaddr_in addr;
#ifdef PTPD_PCAP
@@ -1115,6 +1122,19 @@
&temp, sizeof(int)) < 0) {
DBG("failed to set socket reuse\n");
}
+
+ /* disable UDP checksum validation (Linux) */
+#ifdef SO_NO_CHECK
+ if(rtOpts->disableUdpChecksums) {
+ if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_NO_CHECK , &temp,
+ sizeof(int)) < 0
+ || setsockopt(netPath->generalSock, SOL_SOCKET, SO_NO_CHECK , &temp,
+ sizeof(int)) < 0) {
+ WARNING("Could not disable UDP checksum validation\n");
+ }
+ }
+#endif /* SO_NO_CHECK */
+
/* bind sockets */
/*
* need INADDR_ANY to receive both unicast and multicast,
@@ -1437,6 +1457,12 @@
const u_char *pkt_data;
#endif
+#if defined(__QNXNTO__) && defined(PTPD_EXPERIMENTAL)
+ TimeInternal tmpTime;
+ /* get system time interpolated with TSC / clockCycles as soon as we have data on the socket */
+ getTime(&tmpTime);
+#endif
+
union {
struct cmsghdr cm;
char control[256];
@@ -1652,6 +1678,11 @@
ret = pkt_header->caplen - netPath->headerOffset;
}
#endif
+
+#if defined(__QNXNTO__) && defined(PTPD_EXPERIMENTAL)
+ *time = tmpTime;
+#endif
+
return ret;
}
@@ -1784,6 +1815,12 @@
addr.sin_family = AF_INET;
addr.sin_port = htons(PTP_EVENT_PORT);
+#if defined(__QNXNTO__) && defined(PTPD_EXPERIMENTAL)
+ TimeInternal tmpTime;
+ /* get system time interpolated with TSC / clockCycles as soon as we have data on the socket */
+ getTime(&tmpTime);
+#endif
+
#ifdef PTPD_PCAP
/* In PCAP Ethernet mode, we use pcapEvent for receiving all messages
@@ -1794,7 +1831,6 @@
&netPath->etherDest,
(struct ether_addr *)netPath->interfaceID,
netPath->pcapGeneral);
-
if (ret <= 0)
DBG("Error sending ether multicast event message\n");
else {
@@ -1824,17 +1860,20 @@
netPath->sentPacketsTotal++;
}
#ifndef SO_TIMESTAMPING
+#if defined(__QNXNTO__) && defined(PTPD_EXPERIMENTAL)
+ *tim = tmpTime;
+#else
/*
* Need to forcibly loop back the packet since
* we are not using multicast.
*/
-
addr.sin_addr.s_addr = netPath->interfaceAddr.s_addr;
ret = sendto(netPath->eventSock, buf, length, 0,
(struct sockaddr *)&addr,
sizeof(struct sockaddr_in));
if (ret <= 0)
DBGV("Error looping back unicast event message\n");
+#endif
#else
Modified: trunk/src/dep/ptpd_dep.h
===================================================================
--- trunk/src/dep/ptpd_dep.h 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/ptpd_dep.h 2015-10-12 16:57:43 UTC (rev 588)
@@ -383,6 +383,7 @@
/** \name startup.c (Unix API dependent)
* -Handle with runtime options*/
/**\{*/
+int setCpuAffinity(int cpu);
int logToFile(RunTimeOpts * rtOpts);
int recordToFile(RunTimeOpts * rtOpts);
PtpClock * ptpdStartup(int,char**,Integer16*,RunTimeOpts*);
@@ -437,18 +438,14 @@
void recordSync(UInteger16 sequenceId, TimeInternal * time);
-#ifndef HAVE_SYS_TIMEX_H
-void adjTime(Integer32);
-#else
+void adjFreq_wrapper(const RunTimeOpts * rtOpts, PtpClock * ptpClock, double adj);
-
-
-void adjFreq_wrapper(const RunTimeOpts * rtOpts, PtpClock * ptpClock, double adj);
Boolean adjFreq(double);
double getAdjFreq(void);
+
+#ifdef HAVE_SYS_TIMEX_H
void informClockSource(PtpClock* ptpClock);
-
/* Helper function to manage ntpadjtime / adjtimex flags */
void setTimexFlags(int flags, Boolean quiet);
void unsetTimexFlags(int flags, Boolean quiet);
@@ -482,4 +479,5 @@
void writeStatusFile(PtpClock *ptpClock, const RunTimeOpts *rtOpts, Boolean quiet);
void updateXtmp (TimeInternal oldTime, TimeInternal newTime);
+
#endif /*PTPD_DEP_H_*/
Modified: trunk/src/dep/servo.c
===================================================================
--- trunk/src/dep/servo.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/servo.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -53,6 +53,15 @@
#include "../ptpd.h"
+#define CLAMP(var,bound) {\
+ if(var < -bound) {\
+ var = -bound;\
+ }\
+ if(var > bound) {\
+ var = bound;\
+ }\
+}
+
#ifdef PTPD_STATISTICS
static void checkServoStable(PtpClock *ptpClock, const RunTimeOpts *rtOpts);
#endif
@@ -71,7 +80,6 @@
{
DBG("initClock\n");
-
/* If we've been suppressing ntpdc error messages, show them once again */
ptpClock->ntpControl.requestFailed = FALSE;
@@ -658,10 +666,9 @@
initClock(rtOpts, ptpClock);
-#ifdef HAVE_SYS_TIMEX_H
if(ptpClock->clockQuality.clockClass > 127)
restoreDrift(ptpClock, rtOpts, TRUE);
-#endif /* HAVE_SYS_TIMEX_H */
+
ptpClock->servo.runningMaxOutput = FALSE;
toState(PTP_FAULTY, rtOpts, ptpClock); /* make a full protocol reset */
@@ -705,7 +712,6 @@
/*
* this is a wrapper around adjFreq to abstract extra operations
*/
-#ifdef HAVE_SYS_TIMEX_H
void
adjFreq_wrapper(const RunTimeOpts * rtOpts, PtpClock * ptpClock, double adj)
@@ -715,13 +721,51 @@
return;
}
- // call original adjtime
+/*
+ * adjFreq simulation for QNX: correct clock by x ns per tick over clock adjust interval,
+ * to make it equal adj ns per second. Makes sense only if intervals are regular.
+ */
+
+#ifdef __QNXNTO__
+
+ struct _clockadjust clockadj;
+ struct _clockperiod period;
+ if (ClockPeriod (CLOCK_REALTIME, 0, &period, 0) < 0)
+ return;
+
+ CLAMP(adj,ptpClock->servo.maxOutput);
+
+ /* adjust clock for the duration of 0.9 clock update period in ticks (so we're done before the next) */
+ clockadj.tick_count = 0.9 * ptpClock->servo.dT * 1E9 / (period.nsec + 0.0);
+
+ /* scale adjustment per second to adjustment per single tick */
+ clockadj.tick_nsec_inc = (adj * ptpClock->servo.dT / clockadj.tick_count) / 0.9;
+
+ DBGV("QNX: adj: %.09f, dt: %.09f, ticks per dt: %d, inc per tick %d\n",
+ adj, ptpClock->servo.dT, clockadj.tick_count, clockadj.tick_nsec_inc);
+
+ if (ClockAdjust(CLOCK_REALTIME, &clockadj, NULL) < 0) {
+ DBGV("QNX: failed to call ClockAdjust: %s\n", strerror(errno));
+ }
+/* regular adjFreq */
+#elif defined(HAVE_SYS_TIMEX_H)
DBG2(" adjFreq2: call adjfreq to %.09f us \n", adj / DBG_UNIT);
adjFreq(adj);
+/* otherwise use adjtime */
+#else
+ struct timeval tv;
+
+ CLAMP(adj,ptpClock->servo.maxOutput);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = (adj / 1000);
+ if((ptpClock->servo.dT > 0) && (ptpClock->servo.dT < 1.0)) {
+ tv.tv_usec *= ptpClock->servo.dT;
+ }
+ adjtime(&tv, NULL);
+#endif
}
-#endif /* HAVE_SYS_TIMEX_H */
-
/* check if it's OK to update the clock, deal with panic mode, call for clock step */
void checkOffset(const RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
@@ -893,14 +937,12 @@
ptpClock->clockControl.stepRequired = FALSE;
return;
} else {
-#ifdef HAVE_SYS_TIMEX_H
if(ptpClock->offsetFromMaster.nanoseconds > 0)
ptpClock->servo.observedDrift = rtOpts->servoMaxPpb;
else
ptpClock->servo.observedDrift = -rtOpts->servoMaxPpb;
warn_operator_slow_slewing(rtOpts, ptpClock);
adjFreq_wrapper(rtOpts, ptpClock, -ptpClock->servo.observedDrift);
-#endif /* HAVE_SYS_TIMEX_H */
ptpClock->clockControl.stepRequired = FALSE;
}
return;
@@ -908,11 +950,6 @@
if (ptpClock->clockControl.granted) {
-
-
-#ifndef HAVE_SYS_TIMEX_H
- adjTime(-ptpClock->offsetFromMaster.nanoseconds);
-#else
/* only run the servo if we are calibrted - if calibration delay configured */
if((!rtOpts->calibrationDelay) || ptpClock->isCalibrated) {
@@ -924,9 +961,8 @@
/* let the clock source know it's being synced */
ptpClock->clockStatus.inSync = TRUE;
ptpClock->clockStatus.clockOffset = (ptpClock->offsetFromMaster.seconds * 1E9 +
- ptpClock->offsetFromMaster.nanoseconds) / 1000;
+ ptpClock->offsetFromMaster.nanoseconds) / 1000;
ptpClock->clockStatus.update = TRUE;
-#endif /* HAVE_SYS_TIMEX_H */
}
/* we are ready to control the clock */
@@ -1085,9 +1121,7 @@
ptpClock->servo.stabilityThreshold);
}
-#ifdef HAVE_SYS_TIMEX_H
saveDrift(ptpClock, rtOpts, ptpClock->servo.isStable);
-#endif /* HAVE_SYS_TIMEX_H */
ptpClock->servo.isStable = TRUE;
ptpClock->servo.stableCount = 0;
@@ -1111,9 +1145,7 @@
} else {
WARNING("Clock servo outside stability threshold %d seconds after last check. Saving current observed drift.\n",
rtOpts->statsUpdateInterval * ptpClock->servo.stabilityTimeout);
-#ifdef HAVE_SYS_TIMEX_H
saveDrift(ptpClock, rtOpts, FALSE);
-#endif /* HAVE_SYS_TIMEX_H */
}
}
}
Modified: trunk/src/dep/startup.c
===================================================================
--- trunk/src/dep/startup.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/startup.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -212,74 +212,26 @@
rtOpts->restartSubsystems = -1;
ERROR("Error: Cannot use %s interface as backup\n",tmpOpts.backupIfaceName);
}
-
-
}
+#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H) || defined(__QNXNTO__)
+ /* Changing the CPU affinity mask */
+ if(rtOpts->restartSubsystems & PTPD_CHANGE_CPUAFFINITY) {
+ NOTIFY("Applying CPU binding configuration: changing selected CPU core\n");
-
-#if defined(linux) && defined(HAVE_SCHED_H)
- /* Changing the CPU affinity mask */
- if(rtOpts->restartSubsystems & PTPD_CHANGE_CPUAFFINITY) {
- NOTIFY("Applying CPU binding configuration: changing selected CPU core\n");
- cpu_set_t mask;
- CPU_ZERO(&mask);
- if(tmpOpts.cpuNumber > -1) {
- CPU_SET(tmpOpts.cpuNumber,&mask);
+ if(setCpuAffinity(tmpOpts.cpuNumber) < 0) {
+ if(tmpOpts.cpuNumber == -1) {
+ ERROR("Could not unbind from CPU core %d\n", rtOpts->cpuNumber);
} else {
- int i;
- for(i = 0; i < CPU_SETSIZE; i++) {
- CPU_SET(i, &mask);
- }
- }
- if(sched_setaffinity(0, sizeof(mask), &mask) < 0) {
- if(tmpOpts.cpuNumber == -1) {
- PERROR("Could not unbind from CPU core %d", rtOpts->cpuNumber);
- } else {
- PERROR("Could bind to CPU core %d", tmpOpts.cpuNumber);
- }
- rtOpts->restartSubsystems = -1;
- } else {
- if(tmpOpts.cpuNumber > -1)
- INFO("Successfully bound "PTPD_PROGNAME" to CPU core %d\n", tmpOpts.cpuNumber);
- else
- INFO("Successfully unbound "PTPD_PROGNAME" from cpu core CPU core %d\n", rtOpts->cpuNumber);
+ ERROR("Could bind to CPU core %d\n", tmpOpts.cpuNumber);
}
- }
-#endif /* linux && HAVE_SCHED_H */
-
-#ifdef HAVE_SYS_CPUSET_H
- /* Changing the CPU affinity mask */
- if (rtOpts->restartSubsystems & PTPD_CHANGE_CPUAFFINITY) {
- NOTIFY("Applying CPU binding configuration:"
- "changing selected CPU core\n");
- cpuset_t mask;
- CPU_ZERO(&mask);
- if (tmpOpts.cpuNumber < 0) {
- if (cpuset_getaffinity(CPU_LEVEL_ROOT, CPU_WHICH_CPUSET, 1,
- sizeof(mask), &mask) < 0)
- PERROR("Could not get affinity.");
- if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
- -1, sizeof(mask), &mask) < 0)
- PERROR("Could not unbind from CPU core %d",
- rtOpts->cpuNumber);
- else
- INFO("Successfully unbound "
- PTPD_PROGNAME" from cpu core CPU core %d\n",
- rtOpts->cpuNumber);
- } else {
- CPU_SET(tmpOpts.cpuNumber,&mask);
- if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
- -1, sizeof(mask), &mask) < 0) {
- PERROR("Could not bind to CPU core %d",
- tmpOpts.cpuNumber);
- rtOpts->restartSubsystems = -1;
- } else {
- INFO("Successfully bound "
- PTPD_PROGNAME" to CPU core %d\n",
- tmpOpts.cpuNumber);
- }
- }
- }
+ rtOpts->restartSubsystems = -1;
+ } else {
+ if(tmpOpts.cpuNumber > -1)
+ INFO("Successfully bound "PTPD_PROGNAME" to CPU core %d\n", tmpOpts.cpuNumber);
+ else
+ INFO("Successfully unbound "PTPD_PROGNAME" from cpu core CPU core %d\n", rtOpts->cpuNumber);
+ }
+ }
#endif
if(rtOpts->restartSubsystems == -1) {
@@ -622,7 +574,6 @@
snmpShutdown();
#endif /* PTPD_SNMP */
-#ifdef HAVE_SYS_TIMEX_H
#ifndef PTPD_STATISTICS
/* Not running statistics code - write observed drift to driftfile if enabled, inform user */
if(ptpClock->slaveOnly && !ptpClock->servo.runningMaxOutput)
@@ -637,7 +588,6 @@
if(!rtOpts.servoStabilityDetection && !ptpClock->servo.runningMaxOutput)
saveDrift(ptpClock, &rtOpts, FALSE);
#endif /* PTPD_STATISTICS */
-#endif /* HAVE_SYS_TIMEX_H */
if (rtOpts.currentConfig != NULL)
dictionary_del(rtOpts.currentConfig);
@@ -921,41 +871,17 @@
}
}
-#if defined(linux) && defined(HAVE_SCHED_H)
+#if (defined(linux) && defined(HAVE_SCHED_H)) || defined(HAVE_SYS_CPUSET_H) || defined(__QNXNTO__)
/* Try binding to a single CPU core if configured to do so */
-
if(rtOpts->cpuNumber > -1) {
-
- cpu_set_t mask;
- CPU_ZERO(&mask);
- CPU_SET(rtOpts->cpuNumber,&mask);
- if(sched_setaffinity(0, sizeof(mask), &mask) < 0) {
- PERROR("Could not bind to CPU core %d", rtOpts->cpuNumber);
+ if(setCpuAffinity(rtOpts->cpuNumber) < 0) {
+ ERROR("Could not bind to CPU core %d\n", rtOpts->cpuNumber);
} else {
INFO("Successfully bound "PTPD_PROGNAME" to CPU core %d\n", rtOpts->cpuNumber);
}
}
-#endif /* linux && HAVE_SCHED_H */
+#endif
-#ifdef HAVE_SYS_CPUSET_H
-
- /* Try binding to a single CPU core if configured to do so */
-
- if(rtOpts->cpuNumber > -1) {
- cpuset_t mask;
- CPU_ZERO(&mask);
- CPU_SET(rtOpts->cpuNumber,&mask);
- if(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
- -1, sizeof(mask), &mask) < 0) {
- PERROR("Could not bind to CPU core %d",
- rtOpts->cpuNumber);
- } else {
- INFO("Successfully bound "PTPD_PROGNAME" to CPU core %d\n",
- rtOpts->cpuNumber);
- }
- }
-#endif /* HAVE_SYS_CPUSET_H */
-
/* set up timers */
if(!timerSetup(ptpClock->timers)) {
PERROR("failed to set up event timers");
Modified: trunk/src/dep/sys.c
===================================================================
--- trunk/src/dep/sys.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/dep/sys.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -74,6 +74,24 @@
static int closeLog(LogFileHandler* handler);
+#ifdef __QNXNTO__
+typedef struct {
+ _uint64 counter; /* iteration counter */
+ _uint64 prev_tsc; /* previous clock cycles */
+ _uint64 last_clock; /* clock reading at last timer interrupt */
+ _uint64 cps; /* cycles per second */
+ _uint64 prev_delta; /* previous clock cycle delta */
+ _uint64 cur_delta; /* last clock cycle delta */
+ _uint64 filtered_delta; /* filtered delta */
+ double ns_per_tick; /* nanoseconds per cycle */
+} TimerIntData;
+
+/* do not access directly! tied to clock interrupt! */
+static TimerIntData tData;
+static Boolean tDataUpdated = FALSE;
+
+#endif /* __QNXNTO__ */
+
/*
returns a static char * for the representation of time, for debug purposes
DO NOT call this twice in the same printf!
@@ -1349,9 +1367,92 @@
return TRUE;
}
-void
-getTime(TimeInternal * time)
-{
+#ifdef __QNXNTO__
+
+static const struct sigevent* timerIntHandler(void* data, int id) {
+ struct timespec tp;
+ TimerIntData* myData = (TimerIntData*)data;
+ uint64_t new_tsc = ClockCycles();
+
+ clock_gettime(CLOCK_REALTIME, &tp);
+
+ if(new_tsc > myData->prev_tsc) {
+ myData->cur_delta = new_tsc - myData->prev_tsc;
+ /* when hell freezeth over, thy TSC shall roll over */
+ } else {
+ myData->cur_delta = myData->prev_delta;
+ }
+ /* 4/6 weighted average */
+ myData->filtered_delta = (40 * myData->cur_delta + 60 * myData->prev_delta) / 100;
+ myData->prev_delta = myData->cur_delta;
+ myData->prev_tsc = new_tsc;
+
+ if(myData->counter < 2) {
+ myData->counter++;
+ }
+
+ myData->last_clock = timespec2nsec(&tp);
+ return NULL;
+
+}
+#endif
+
+ void getTime(TimeInternal *time)
+ {
+#ifdef __QNXNTO__
+ static TimerIntData tmpData;
+ int ret;
+ uint64_t delta;
+ double tick_delay;
+ uint64_t clock_offset;
+ struct timespec tp;
+ if(!tDataUpdated) {
+ memset(&tData, 0, sizeof(TimerIntData));
+ if(ThreadCtl(_NTO_TCTL_IO, 0) == -1) {
+ ERROR("QNX: could not give process I/O privileges");
+ return;
+ }
+
+ tData.cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
+ tData.ns_per_tick = 1000000000.0 / tData.cps;
+ tData.prev_tsc = ClockCycles();
+ clock_gettime(CLOCK_REALTIME, &tp);
+ tData.last_clock = timespec2nsec(&tp);
+ ret = InterruptAttach(0, timerIntHandler, &tData, sizeof(TimerIntData), _NTO_INTR_FLAGS_END | _NTO_INTR_FLAGS_TRK_MSK);
+
+ if(ret == -1) {
+ ERROR("QNX: could not attach to timer interrupt");
+ return ;
+ }
+ tDataUpdated = TRUE;
+ time->seconds = tp.tv_sec;
+ time->nanoseconds = tp.tv_nsec;
+ return;
+ }
+
+ memcpy(&tmpData, &tData, sizeof(TimerIntData));
+
+ delta = ClockCycles() - tmpData.prev_tsc;
+
+ /* compute time since last clock update */
+ tick_delay = (double)delta / (double)tmpData.filtered_delta;
+ clock_offset = (uint64_t)(tick_delay * tmpData.ns_per_tick * (double)tmpData.filtered_delta);
+
+ /* not filtered yet */
+ if(tData.counter < 2) {
+ clock_offset = 0;
+ }
+
+ DBGV("QNX getTime cps: %lld tick interval: %.09f, time since last tick: %lld\n",
+ tmpData.cps, tmpData.filtered_delta * tmpData.ns_per_tick, clock_offset);
+
+ nsec2timespec(&tp, tmpData.last_clock + clock_offset);
+
+ time->seconds = tp.tv_sec;
+ time->nanoseconds = tp.tv_nsec;
+ return;
+#else
+
#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
struct timespec tp;
@@ -1370,6 +1471,7 @@
time->nanoseconds = tv.tv_usec * 1000;
#endif /* _POSIX_TIMERS */
+#endif /* __QNXNTO__ */
}
void
@@ -2018,24 +2120,8 @@
}
}
-#else /* SYS_TIMEX_H */
+#endif /* SYS_TIMEX_H */
-void
-adjTime(Integer32 nanoseconds)
-{
-
- struct timeval t;
-
- t.tv_sec = 0;
- t.tv_usec = nanoseconds / 1000;
-
- if (adjtime(&t, NULL) < 0)
- PERROR("failed to ajdtime");
-
-}
-
-#endif /* HAVE_SYS_TIMEX_H */
-
#define DRIFTFORMAT "%.0f"
void
@@ -2051,11 +2137,7 @@
if (ptpClock->drift_saved && rtOpts->drift_recovery_method > 0 ) {
ptpClock->servo.observedDrift = ptpClock->last_saved_drift;
if (!rtOpts->noAdjust && ptpClock->clockControl.granted) {
-#ifndef HAVE_SYS_TIMEX_H
- adjTime(-ptpClock->last_saved_drift);
-#else
adjFreq_wrapper(rtOpts, ptpClock, -ptpClock->last_saved_drift);
-#endif /* HAVE_SYS_TIMEX_H */
}
DBG("loaded cached drift");
return;
@@ -2118,10 +2200,8 @@
}
if (reset_offset) {
-#ifdef HAVE_SYS_TIMEX_H
if (!rtOpts->noAdjust && ptpClock->clockControl.granted)
adjFreq_wrapper(rtOpts, ptpClock, 0);
-#endif /* HAVE_SYS_TIMEX_H */
ptpClock->servo.observedDrift = 0;
return;
}
@@ -2131,10 +2211,9 @@
ptpClock->drift_saved = TRUE;
ptpClock->last_saved_drift = recovered_drift;
-#ifdef HAVE_SYS_TIMEX_H
if (!rtOpts->noAdjust)
- adjFreq(-recovered_drift);
-#endif /* HAVE_SYS_TIMEX_H */
+ adjFreq_wrapper(rtOpts, ptpClock, -recovered_drift);
+
}
@@ -2334,8 +2413,14 @@
#endif /* OTIME_MSG */
#ifdef OLD_TIME
+
+#ifdef HAVE_STRUCT_UTMP_UT_TIME
+ ut.ut_time = oldTime.seconds;
+#else
ut.ut_tv.tv_sec = oldTime.seconds;
ut.ut_tv.tv_usec = oldTime.nanoseconds / 1000;
+#endif /* HAVE_STRUCT_UTMP_UT_TIME */
+
ut.ut_type = OLD_TIME;
#else /* no ut_type */
ut.ut_time = oldTime.seconds;
@@ -2412,8 +2497,13 @@
strncpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line));
#endif /* NTIME_MSG */
#ifdef NEW_TIME
+
+#ifdef HAVE_STRUCT_UTMP_UT_TIME
+ ut.ut_time = newTime.seconds;
+#else
ut.ut_tv.tv_sec = newTime.seconds;
ut.ut_tv.tv_usec = newTime.nanoseconds / 1000;
+#endif /* HAVE_STRUCT_UTMP_UT_TIME */
ut.ut_type = NEW_TIME;
#else /* no ut_type */
ut.ut_time = newTime.seconds;
@@ -2450,3 +2540,81 @@
#endif /* HAVE_UTMPX_H */
}
+
+int setCpuAffinity(int cpu) {
+
+#ifdef __QNXNTO__
+ unsigned num_elements = 0;
+ int *rsizep, masksize_bytes, size;
+ int *rmaskp, *imaskp;
+ void *my_data;
+ uint32_t cpun;
+ num_elements = RMSK_SIZE(_syspage_ptr->num_cpu);
+
+ masksize_bytes = num_elements * sizeof(unsigned);
+
+ size = sizeof(int) + 2 * masksize_bytes;
+ if ((my_data = malloc(size)) == NULL) {
+ return -1;
+ } else {
+ memset(my_data, 0x00, size);
+
+ rsizep = (int *)my_data;
+ rmaskp = rsizep + 1;
+ imaskp = rmaskp + num_elements;
+
+ *rsizep = num_elements;
+
+ if(cpu > _syspage_ptr->num_cpu) {
+ return -1;
+ }
+
+ if(cpu >= 0) {
+ cpun = (uint32_t)cpu;
+ RMSK_SET(cpun, rmaskp);
+ RMSK_SET(cpun, imaskp);
+ } else {
+ for(cpun = 0; cpun < num_elements; cpun++) {
+ RMSK_SET(cpun, rmaskp);
+ RMSK_SET(cpun, imaskp);
+ }
+ }
+ int ret = ThreadCtl( _NTO_TCTL_RUNMASK_GET_AND_SET_INHERIT, my_data);
+ free(my_data);
+ return ret;
+ }
+
+#endif
+
+#ifdef HAVE_SYS_CPUSET_H
+ cpuset_t mask;
+ CPU_ZERO(&mask);
+ if(cpu >= 0) {
+ CPU_SET(cpu,&mask);
+ } else {
+ int i;
+ for(i = 0; i < CPU_SETSIZE; i++) {
+ CPU_SET(i, &mask);
+ }
+ }
+ return(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, sizeof(mask), &mask));
+#endif /* HAVE_SYS_CPUSET_H */
+
+#if defined(linux) && defined(HAVE_SCHED_H)
+ cpu_set_t mask;
+ CPU_ZERO(&mask);
+ if(cpu >= 0) {
+ CPU_SET(cpu,&mask);
+ } else {
+ int i;
+ for(i = 0; i < CPU_SETSIZE; i++) {
+ CPU_SET(i, &mask);
+ }
+ }
+ return sched_setaffinity(0, sizeof(mask), &mask);
+#endif /* linux && HAVE_SCHED_H */
+
+return -1;
+
+}
Modified: trunk/src/protocol.c
===================================================================
--- trunk/src/protocol.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/protocol.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -821,7 +821,6 @@
}
}
-
}
/* Reset the slave if clock update timeout configured */
@@ -855,7 +854,7 @@
if (ptpClock->delayMechanism == E2E) {
if(timerExpired(&ptpClock->timers[DELAYREQ_INTERVAL_TIMER])) {
- DBG2("event DELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n");
+ DBG("event DELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n");
/* if unicast negotiation is enabled, only request if granted */
if(!rtOpts->unicastNegotiation ||
(ptpClock->parentGrants &&
@@ -1456,13 +1455,15 @@
if(rtOpts->unicastNegotiation && rtOpts->ipMode == IPMODE_UNICAST) {
- nodeTable = findUnicastGrants(&header->sourcePortIdentity, 0,
- ptpClock->unicastGrants, ptpClock->unicastGrantIndex, UNICAST_MAX_DESTINATIONS,
+ nodeTable = findUnicastGrants(&header->sourcePortIdentity, 0,
+ ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
if(nodeTable == NULL || !(nodeTable->grantData[ANNOUNCE].granted)) {
- DBG("Ignoring announce from master: unicast transmission not granted\n");
- ptpClock->counters.discardedMessages++;
- return;
+ if(!rtOpts->unicastAcceptAny) {
+ DBG("Ignoring announce from master: unicast transmission not granted\n");
+ ptpClock->counters.discardedMessages++;
+ return;
+ }
} else {
localPreference = nodeTable->localPreference;
nodeTable->grantData[ANNOUNCE].receiving = header->sequenceId;
@@ -1685,7 +1686,7 @@
Integer32 dst = 0;
- if(destinationAddress) {
+ if((rtOpts->ipMode == IPMODE_UNICAST) && destinationAddress) {
dst = destinationAddress;
} else {
dst = 0;
@@ -1702,7 +1703,7 @@
if(!isFromSelf && rtOpts->unicastNegotiation && rtOpts->ipMode == IPMODE_UNICAST) {
UnicastGrantTable *nodeTable = NULL;
nodeTable = findUnicastGrants(&header->sourcePortIdentity, 0,
- ptpClock->unicastGrants, ptpClock->unicastGrantIndex, UNICAST_MAX_DESTINATIONS,
+ ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
if(nodeTable != NULL) {
nodeTable->grantData[SYNC].receiving = header->sequenceId;
@@ -1884,7 +1885,6 @@
}
-
#ifndef PTPD_SLAVE_ONLY /* does not get compiled when building slave only */
processSyncFromSelf(tint, rtOpts, ptpClock, dst, header->sequenceId);
#endif /* PTPD_SLAVE_ONLY */
@@ -2028,7 +2028,7 @@
if(!isFromSelf && rtOpts->unicastNegotiation && rtOpts->ipMode == IPMODE_UNICAST) {
nodeTable = findUnicastGrants(&header->sourcePortIdentity, 0,
- ptpClock->unicastGrants, ptpClock->unicastGrantIndex, UNICAST_MAX_DESTINATIONS,
+ ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
if(nodeTable == NULL || !(nodeTable->grantData[DELAY_RESP].granted)) {
DBG("Ignoring Delay Request from slave: unicast transmission not granted\n");
@@ -2041,7 +2041,7 @@
}
- DBGV("delayReq message received : \n");
+ DBG("delayReq message received : \n");
if (length < DELAY_REQ_LENGTH) {
DBG("Error: DelayReq message too short\n");
@@ -2130,6 +2130,7 @@
static void
processDelayReqFromSelf(const TimeInternal * tint, const RunTimeOpts * rtOpts, PtpClock * ptpClock) {
+
ptpClock->waitingForDelayResp = TRUE;
ptpClock->delay_req_send_time.seconds = tint->seconds;
@@ -2160,10 +2161,12 @@
if(rtOpts->unicastNegotiation && rtOpts->ipMode == IPMODE_UNICAST) {
UnicastGrantTable *nodeTable = NULL;
nodeTable = findUnicastGrants(&header->sourcePortIdentity, 0,
- ptpClock->unicastGrants, ptpClock->unicastGrantIndex, UNICAST_MAX_DESTINATIONS,
+ ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
if(nodeTable != NULL) {
nodeTable->grantData[DELAY_RESP].receiving = header->sequenceId;
+ } else {
+ DBG("delayResp - unicast master not identified\n");
}
}
@@ -2318,7 +2321,7 @@
if(!isFromSelf && rtOpts->unicastNegotiation && rtOpts->ipMode == IPMODE_UNICAST) {
nodeTable = findUnicastGrants(&header->sourcePortIdentity, 0,
- ptpClock->unicastGrants, ptpClock->unicastGrantIndex, UNICAST_MAX_DESTINATIONS,
+ ptpClock->unicastGrants, &ptpClock->grantIndex, UNICAST_MAX_DESTINATIONS,
FALSE);
if(nodeTable == NULL || !(nodeTable->grantData[PDELAY_RESP].granted)) {
DBG("Ignoring Peer Delay Request from peer: unicast transmission not granted\n");
@@ -2695,11 +2698,19 @@
UInteger16 allOnesPortNumber = 0xFFFF;
memset(allOnesClkIdentity, 0xFF, sizeof(allOnesClkIdentity));
+ /* equal port IDs: equal clock ID and equal port ID */
if(!memcmp(targetPort.clockIdentity, thisPort.clockIdentity, CLOCK_IDENTITY_LENGTH) &&
(targetPort.portNumber == thisPort.portNumber)) {
return TRUE;
}
+ /* equal clockIDs and target port number is wildcard - this was missing up to 12oct15 */
+ if(!memcmp(targetPort.clockIdentity, thisPort.clockIdentity, CLOCK_IDENTITY_LENGTH) &&
+ (targetPort.portNumber == allOnesPortNumber)) {
+ return TRUE;
+ }
+
+ /* target port and clock IDs are both wildcard */
if(!memcmp(targetPort.clockIdentity, allOnesClkIdentity, CLOCK_IDENTITY_LENGTH) &&
(targetPort.portNumber == allOnesPortNumber)) {
return TRUE;
@@ -3182,6 +3193,16 @@
}
#endif
+#if defined(__QNXNTO__) && defined(PTPD_EXPERIMENTAL)
+ if(internalTime.seconds && internalTime.nanoseconds) {
+ if (respectUtcOffset(rtOpts, ptpClock) == TRUE) {
+ internalTime.seconds += ptpClock->timePropertiesDS.currentUtcOffset;
+ }
+ processSyncFromSelf(&internalTime, rtOpts, ptpClock, dst, *sequenceId);
+ }
+#endif
+
+
ptpClock->lastSyncDst = dst;
if(!internalTime.seconds && !internalTime.nanoseconds) {
@@ -3282,7 +3303,15 @@
processDelayReqFromSelf(&internalTime, rtOpts, ptpClock);
}
#endif
-
+
+#if defined(__QNXNTO__) && defined(PTPD_EXPERIMENTAL)
+ if (respectUtcOffset(rtOpts, ptpClock) == TRUE) {
+ internalTime.seconds += ptpClock->timePropertiesDS.currentUtcOffset;
+ }
+
+ processDelayReqFromSelf(&internalTime, rtOpts, ptpClock);
+#endif
+
ptpClock->sentDelayReqSequenceId++;
ptpClock->counters.delayReqMessagesSent++;
Modified: trunk/src/ptpd.h
===================================================================
--- trunk/src/ptpd.h 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/ptpd.h 2015-10-12 16:57:43 UTC (rev 588)
@@ -69,7 +69,9 @@
#include <stdarg.h>
#include <syslog.h>
#include <limits.h>
+#ifdef HAVE_GETOPT_H
#include <getopt.h>
+#endif /* HAVE_GETOPT_H */
#include <ctype.h>
#include <glob.h>
#include <stddef.h>
@@ -86,6 +88,10 @@
#include <net/ethernet.h>
#endif /* HAVE_NET_ETHERNET_H */
+#ifdef HAVE_UNIX_H /* setlinebuf() on QNX */
+#include <unix.h>
+#endif /* HAVE_UNIX_H */
+
#include <netinet/in.h>
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
@@ -186,8 +192,13 @@
#define SET_FIELD(data, bitpos) \
data << bitpos
+#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
+#endif /* min */
+
+#ifndef max
#define max(a,b) (((a)>(b))?(a):(b))
+#endif /* max */
#ifdef HAVE_LINUX_RTC_H
#include <linux/rtc.h>
@@ -344,7 +355,7 @@
/**
* \brief Signaling message support
*/
-UnicastGrantTable* findUnicastGrants(const PortIdentity* portIdentity, Integer32 TransportAddress, UnicastGrantTable *grantTable, UnicastGrantTable **index, int nodeCount, Boolean update);
+UnicastGrantTable* findUnicastGrants(const PortIdentity* portIdentity, Integer32 TransportAddress, UnicastGrantTable *grantTable, UnicastGrantIndex *index, int nodeCount, Boolean update);
void initUnicastGrantTable(UnicastGrantTable *grantTable, Enumeration8 delayMechanism, int nodeCount, UnicastDestination *destinations, const RunTimeOpts *rtOpts, PtpClock *ptpClock);
void handleSMRequestUnicastTransmission(MsgSignaling*, MsgSignaling*, Integer32, const RunTimeOpts*, PtpClock*);
Boolean handleSMCancelUnicastTransmission(MsgSignaling*, MsgSignaling*, Integer32, PtpClock*);
Modified: trunk/src/ptpd2.conf.5.in
===================================================================
--- trunk/src/ptpd2.conf.5.in 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/ptpd2.conf.5.in 2015-10-12 16:57:43 UTC (rev 588)
@@ -215,6 +215,54 @@
.RE
.RS 0
.TP 8
+\fBptpengine:unicast_any_master [\fIBOOLEAN\fB]\fR
+.RS 8
+.TP 8
+\fBusage\fR
+When using unicast negotiation (slave), accept PTP messages from any grandmaster.
+By default, only messages from acceptable masters (\fIptpengine:unicast_destinations\fR)
+are accepted, and only if transmission was granted by the GM. This setting can be used
+when mixing GMs supporting G.8265.1 and manual unicast (no negotiation), or to assist
+with interoperability issues where signaling messages and timing messages come from
+different port identities.
+.TP 8
+\fBdefault\fR
+\fIN\fR
+
+.RE
+.RE
+.RS 0
+.TP 8
+\fBptpengine:unicast_port_mask [\fIINT\fB: 0 .. 65535 (0xFFFF)]\fR
+.RS 8
+.TP 8
+\fBusage\fR
+PTP port number wildcard mask (16-bit) applied onto port identities when running unicast negotiation:
+allows multiple port identities (with the same clock ID) to be accepted as coming from the same port.
+This option can be used as a workaround where a node sends signaling messages and timing messages
+with different port identities. \fBNOTE:\fR This can also be entered in hexadecimal notation (0xNNNN).
+.TP 8
+\fBdefault\fR
+\fI0\fR
+
+.RE
+.RE
+.RS 0
+.TP 8
+\fBptpengine:disable_udp_checksums [\fIBOOLEAN\fB]\fR
+.RS 8
+.TP 8
+\fBusage\fR
+Disable UDP checksum validation on UDP sockets (Linux only). Workaround for situations where a node
+(like Transparent Clock) does not rewrite checksums. Enabled by default.
+.TP 8
+\fBdefault\fR
+\fIY\fR
+
+.RE
+.RE
+.RS 0
+.TP 8
\fBptpengine:use_libpcap [\fIBOOLEAN\fB]\fR
.RS 8
.TP 8
@@ -770,9 +818,6 @@
\fBdefault\fR
\fI[none]\fR
-
-
-
.RE
.RE
.RS 0
@@ -782,7 +827,7 @@
.TP 8
\fBusage\fR
Specify PTP domain number for each configured unicast destination (\fIptpengine:unicast_destinations\fR).
-This is only used by slave-only clocks using unicast destinations to allow for each master
+This is only used by slave-only clocks using multiple unicast destinations to allow for each master
to be in a separate domain, such as with Telecom Profile. The number of entries should match the number
of unicast destinations, otherwise unconfigured domains or domains set to 0 are set to domain configured in \fIptpengine:domain\fR.
The format is a comma, tab or space-separated list of 8-bit unsigned integers (0 .. 255).
@@ -799,10 +844,10 @@
.TP 8
\fBusage\fR
Specify a local preference for each configured unicast destination (\fIptpengine:unicast_destinations\fR).
-This is only used by slave-only clocks using unicast destinations to allow for each master's
+This is only used by slave-only clocks using multiple unicast destinations to allow for each master's
BMC selection to be influenced locally by the slave, such as with Telecom Profile. The number of entries should match the number
-of unicast destinations, otherwise unconfigured preference is set to 0 (highest).
-The format is a comma, tab or space-separated list of 8-bit unsigned integers (0 .. 255).
+of unicast destinations, otherwise unconfigured preference is set to 255 (lowest), so that the unconfigurest entries do not
+pre-empt the configured entries. The format is a comma, tab or space-separated list of 8-bit unsigned integers (0 .. 255).
.TP 8
\fBdefault\fR
\fI[none]\fR
Modified: trunk/src/signaling.c
===================================================================
--- trunk/src/signaling.c 2015-09-21 17:27:42 UTC (rev 587)
+++ trunk/src/signaling.c 2015-10-12 16:57:43 UTC (rev 588)
@@ -44,26 +44,27 @@
/* maximum number of missed messages of given type before we re-request */
#define GRANT_MAX_MISSED 10
-static void updateUnicastIndex(UnicastGrantTable *table, UnicastGrantTable **index);
-static UnicastGrantTable* lookupUnicastIndex(const PortIdentity *portIdentity, Integer32 transportAddress, UnicastGrantTable **index);
+static void updateUnicastIndex(UnicastGrantTable *table, UnicastGrantIndex *index);
+static UnicastGrantTable* lookupUnicastIndex(PortIdentity *portIdentity, Integer32 transportAddress, UnicastGrantIndex *index);
/* update index table */
static void
-updateUnicastIndex(UnicastGrantTable *table, UnicastGrantTable **index)
+updateUnicastIndex(UnicastGrantTable *table, UnicastGrantIndex *index)
{
uint32_t hash = fnvHash(&table->portIdentity, sizeof(PortIdentity), UNICAST_MAX_DESTINATIONS);
/* peer table normally has one entry: if we got here, we might pollute the main index */
if(!table->isPeer && index != NULL) {
- index[hash] = table;
+ index->data[hash] = table;
}
}
/* return matching entry from index table */
static UnicastGrantTable*
-lookupUnicastIndex(const PortIdentity *portIdentity, Integer32 transportAddress, UnicastGrantTable **index)
+lookupUnicastIndex(PortIdentity *portIdentity, Integer32 transportAddress, UnicastGrantIndex *index)
{
+
uint32_t hash = fnvHash((void*)portIdentity, sizeof(PortIdentity), UNICAST_MAX_DESTINATIONS);
UnicastGrantTable* table;
@@ -72,9 +73,14 @@
return NULL;
}
- table = index[hash];
+ table = index->data[hash];
- if(table != NULL && (!cmpPortIdentity(portIdentity, &table->portIdent...
[truncated message content] |
|
From: <wow...@us...> - 2015-09-21 17:27:44
|
Revision: 587
http://sourceforge.net/p/ptpd/code/587
Author: wowczarek
Date: 2015-09-21 17:27:42 +0000 (Mon, 21 Sep 2015)
Log Message:
-----------
- 2.3.1.1 changelog added
- man page updated to reflect changes in 2.3.1.1
Modified Paths:
--------------
trunk/ChangeLog
trunk/src/ptpd2.8.in
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2015-09-17 15:54:04 UTC (rev 586)
+++ trunk/ChangeLog 2015-09-21 17:27:42 UTC (rev 587)
@@ -1,3 +1,27 @@
+2013-09-22 Wojciech Owczarek <woj...@ow...>
+
+ * 2.3.1.1 minor / bugfix release
+
+ * Bug fixes / improvements since 2.3.1:
+
+ - systemd service file added and RPM spec updated
+ to handle systemd
+ - fixed segfault when shutting down NTP time service
+ - ptpengine:always_respect_utc_offset is now enabled
+ by default, to protect from clock jumps when GM
+ stops announcing currentUtcOffsetValid flag
+ - re-arranged order of InterfaceInfo fields to
+ fix memory alignment issues (SF bug #70)
+ - corrected logMessageInterval field values
+ for hybrid mode (SF bug #69)
+ - fixed NTPd check failures resulting from signals
+ interrupting select()
+ - increased statistics file line buffer size to prevent
+ truncation and merging of lines
+ - added Sequence ID to statistics log
+ - Solaris build fixes - linking lnsl and lsocket when
+ building without SNMP support
+
2013-06-10 Wojciech Owczarek <woj...@ow...>
* 2.3.1 release
Modified: trunk/src/ptpd2.8.in
===================================================================
--- trunk/src/ptpd2.8.in 2015-09-17 15:54:04 UTC (rev 586)
+++ trunk/src/ptpd2.8.in 2015-09-21 17:27:42 UTC (rev 587)
@@ -150,18 +150,12 @@
\fB-i \fINUMBER\fR
PTP domain number
.TP 8
-\fB-g\fR
-Slave only mode
-.TP 8
\fB-G\fR
\'Master mode with NTP\' (master only mode)
.TP 8
\fB-W\fR
\'Master mode without NTP\' (master / slave mode)
.TP 8
-\fB-U\fR
-Hybrid mode (mixed unicast + multicast operation)
-.TP 8
\fB-Y \fINUMBER\fR
Delay request interval (log 2)
.TP 8
@@ -269,9 +263,16 @@
clock stability.
.TP 8
\fBLast Packet Received\fR
-This field shows what message was received last - this will be S for Sync and D for Delay Response. If a slave
-logs no D entries, this means it's not receiving Delay Response messages, which could be a network issue.
+This field shows what message was received last - this will be S for Sync, D for Delay Response and P for Peer
+Delay Response when using P2P delay mode. If a slave logs no D (or P) entries, this means it's not receiving
+Delay Response messages, which could be a network issue. For two-step clocks, "S" will still be printed when
+Follow-up was received.
.TP 8
+\fBSequence ID\fR
+Sequence number of the last received message (Sync, Follow-Up, Delay Response, Peer Delay Response). Sequence
+numbers in the statistics log file can help identify timing issues when analysing capture files; a change of
+offset or path delay can be traced to a particular packet that matches the sequence ID.
+.TP 8
\fBOne Way Delay Mean\fR
One-way delay mean computed over the last sampling window.
.TP 8
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-09-17 15:54:05
|
Revision: 586
http://sourceforge.net/p/ptpd/code/586
Author: wowczarek
Date: 2015-09-17 15:54:04 +0000 (Thu, 17 Sep 2015)
Log Message:
-----------
- added lib check for lnsl and lsocket on Solaris
to fix builds without snmp
- replaced AC_CHECK_LIB with AC_SEARCH_LIBS so that
lnsl is not included on Linux if not necessary
- added lrt check for POSIX timers: clock_gettime()
is not in lrt on FreeBSD, but POSIX timers are
Modified Paths:
--------------
trunk/configure.ac
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2015-09-11 13:24:16 UTC (rev 585)
+++ trunk/configure.ac 2015-09-17 15:54:04 UTC (rev 586)
@@ -1,4 +1,3 @@
-# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
m4_include([m4/version.m4])
@@ -76,8 +75,11 @@
AC_SUBST(LINUX_KERNEL_INCLUDES)
# Checks for libraries.
-AC_CHECK_LIB([m], [pow])
-AC_CHECK_LIB([rt], [clock_gettime])
+AC_SEARCH_LIBS([pow], [m])
+AC_SEARCH_LIBS([clock_gettime], [rt])
+AC_SEARCH_LIBS([timer_create], [rt])
+AC_SEARCH_LIBS([connect], [socket])
+AC_SEARCH_LIBS([gethostbyname], [nsl])
# Checks for header files.
AC_HEADER_STDC
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-09-11 13:24:18
|
Revision: 585
http://sourceforge.net/p/ptpd/code/585
Author: wowczarek
Date: 2015-09-11 13:24:16 +0000 (Fri, 11 Sep 2015)
Log Message:
-----------
- Make alwaysRespectUtcOffset true by default:
this makes more sense than previous behaviour,
if the UTC offset is there, use it.
Modified Paths:
--------------
trunk/src/dep/daemonconfig.c
Modified: trunk/src/dep/daemonconfig.c
===================================================================
--- trunk/src/dep/daemonconfig.c 2015-08-28 14:47:19 UTC (rev 584)
+++ trunk/src/dep/daemonconfig.c 2015-09-11 13:24:16 UTC (rev 585)
@@ -919,10 +919,12 @@
/* disabled by default */
rtOpts->announceTimeoutGracePeriod = 0;
- rtOpts->alwaysRespectUtcOffset=FALSE;
- rtOpts->preferUtcValid=FALSE;
- rtOpts->requireUtcValid=FALSE;
+ /* currentUtcOffsetValid compatibility flags */
+ rtOpts->alwaysRespectUtcOffset = TRUE;
+ rtOpts->preferUtcValid = FALSE;
+ rtOpts->requireUtcValid = FALSE;
+
/* Try 46 for expedited forwarding */
rtOpts->dscpValue = 0;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-08-28 14:47:21
|
Revision: 584
http://sourceforge.net/p/ptpd/code/584
Author: wowczarek
Date: 2015-08-28 14:47:19 +0000 (Fri, 28 Aug 2015)
Log Message:
-----------
- fix for bug #69: incorrect logMessageInterval values
for different message types in Hybrid mode
- fix for bug #70: re-arranged fields in the interfaceInfo
struct to prevent alignment errors on some platforms
Modified Paths:
--------------
trunk/m4/version.m4
trunk/src/dep/datatypes_dep.h
trunk/src/dep/msg.c
trunk/src/protocol.c
Modified: trunk/m4/version.m4
===================================================================
--- trunk/m4/version.m4 2015-07-14 16:25:43 UTC (rev 583)
+++ trunk/m4/version.m4 2015-08-28 14:47:19 UTC (rev 584)
@@ -1,4 +1,4 @@
m4_define([PTPD_URL],[http://ptpd.sourceforge.net])
-m4_define([RELEASE_DATE],[June, 2015])
+m4_define([RELEASE_DATE],[September, 2015])
m4_define([VERSION_NUMBER],[2.3.1.1])
Modified: trunk/src/dep/datatypes_dep.h
===================================================================
--- trunk/src/dep/datatypes_dep.h 2015-07-14 16:25:43 UTC (rev 583)
+++ trunk/src/dep/datatypes_dep.h 2015-08-28 14:47:19 UTC (rev 584)
@@ -67,12 +67,12 @@
* \brief Struct containing interface information and capabilities
*/
typedef struct {
- unsigned int flags;
- int addressFamily;
+ struct sockaddr afAddress;
+ unsigned char hwAddress[14];
Boolean hasHwAddress;
Boolean hasAfAddress;
- unsigned char hwAddress[14];
- struct sockaddr afAddress;
+ int addressFamily;
+ unsigned int flags;
} InterfaceInfo;
Modified: trunk/src/dep/msg.c
===================================================================
--- trunk/src/dep/msg.c 2015-07-14 16:25:43 UTC (rev 583)
+++ trunk/src/dep/msg.c 2015-08-28 14:47:19 UTC (rev 584)
@@ -1543,7 +1543,7 @@
*(UInteger8 *) (buf + 32) = 0x00;
/* Table 24 - unless it's multicast, logMessageInterval remains 0x7F */
- if(rtOpts.transport == IEEE_802_3 || rtOpts.ipMode == IPMODE_MULTICAST)
+ if(rtOpts.transport == IEEE_802_3 || rtOpts.ipMode != IPMODE_UNICAST )
*(Integer8 *) (buf + 33) = ptpClock->logSyncInterval;
memset((buf + 8), 0, 8);
@@ -1589,9 +1589,8 @@
*(UInteger16 *) (buf + 2) = flip16(ANNOUNCE_LENGTH);
*(UInteger16 *) (buf + 30) = flip16(sequenceId);
*(UInteger8 *) (buf + 32) = 0x05;
- /* Table 24 - unless it's multicast, logMessageInterval remains 0x7F */
- if(rtOpts.transport == IEEE_802_3 || rtOpts.ipMode == IPMODE_MULTICAST)
- *(Integer8 *) (buf + 33) = ptpClock->logAnnounceInterval;
+ /* Table 24: for Announce, logMessageInterval is never 0x7F */
+ *(Integer8 *) (buf + 33) = ptpClock->logAnnounceInterval;
/* Announce message */
memset((buf + 34), 0, 10);
@@ -1670,7 +1669,7 @@
*(UInteger8 *) (buf + 32) = 0x02;
/* Table 24 - unless it's multicast, logMessageInterval remains 0x7F */
- if(rtOpts.transport == IEEE_802_3 || rtOpts.ipMode == IPMODE_MULTICAST)
+ if(rtOpts.transport == IEEE_802_3 || rtOpts.ipMode != IPMODE_UNICAST)
*(Integer8 *) (buf + 33) = ptpClock->logSyncInterval;
/* Follow_up message */
@@ -1783,8 +1782,10 @@
*(UInteger8 *) (buf + 32) = 0x03;
/* Table 24 - unless it's multicast, logMessageInterval remains 0x7F */
- if(rtOpts.transport == IEEE_802_3 || rtOpts.ipMode == IPMODE_MULTICAST)
- *(Integer8 *) (buf + 33) = ptpClock->logMinDelayReqInterval;
+ /* really tempting to cheat here, at least for hybrid, but standard is a standard */
+ if ((header->flagField0 & PTP_UNICAST) != PTP_UNICAST) {
+ *(Integer8 *) (buf + 33) = ptpClock->logMinDelayReqInterval;
+ }
/* Pdelay_resp message */
*(UInteger16 *) (buf + 34) =
Modified: trunk/src/protocol.c
===================================================================
--- trunk/src/protocol.c 2015-07-14 16:25:43 UTC (rev 583)
+++ trunk/src/protocol.c 2015-08-28 14:47:19 UTC (rev 584)
@@ -3416,16 +3416,18 @@
issueDelayResp(const TimeInternal *tint,MsgHeader *header,Integer32 sourceAddress, const RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
Timestamp requestReceiptTimestamp;
+ Integer32 dst;
+
fromInternalTime(tint,&requestReceiptTimestamp);
msgPackDelayResp(ptpClock->msgObuf,header,&requestReceiptTimestamp,
ptpClock);
- Integer32 dst = 0;
-
/* if request was unicast and we're running unicast, reply to source */
if ( (rtOpts->ipMode != IPMODE_MULTICAST) &&
(header->flagField0 & PTP_UNICAST) == PTP_UNICAST) {
dst = sourceAddress;
+ } else {
+ dst = 0;
}
if (!netSendGeneral(ptpClock->msgObuf, DELAY_RESP_LENGTH,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-07-14 16:25:46
|
Revision: 583
http://sourceforge.net/p/ptpd/code/583
Author: wowczarek
Date: 2015-07-14 16:25:43 +0000 (Tue, 14 Jul 2015)
Log Message:
-----------
Continued NTP select() EINTR fix
Modified Paths:
--------------
trunk/src/dep/ntpengine/ntpdcontrol.c
Modified: trunk/src/dep/ntpengine/ntpdcontrol.c
===================================================================
--- trunk/src/dep/ntpengine/ntpdcontrol.c 2015-07-14 16:16:19 UTC (rev 582)
+++ trunk/src/dep/ntpengine/ntpdcontrol.c 2015-07-14 16:25:43 UTC (rev 583)
@@ -405,21 +405,24 @@
lastseq = 999; /* too big to be a sequence number */
memset(haveseq, 0, sizeof(haveseq));
- FD_ZERO(&fds);
+
again:
if (firstpkt)
tvo = tvout;
else
tvo = tvsout;
-
- FD_SET(control->sockFD, &fds);
-
do {
+ FD_ZERO(&fds);
+ FD_SET(control->sockFD, &fds);
n = select(control->sockFD+1, &fds, (fd_set *)0, (fd_set *)0, &tvo);
- if( n == -1 && errno == EINTR) {
+ if(n == -1) {
+ if(errno == EINTR) {
DBG("NTPDCresponse(): EINTR caught\n");
- retries--;
+ retries--;
+ } else {
+ retries = 0;
+ }
}
} while ((n == -1) && retries);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-07-14 16:16:21
|
Revision: 582
http://sourceforge.net/p/ptpd/code/582
Author: wowczarek
Date: 2015-07-14 16:16:19 +0000 (Tue, 14 Jul 2015)
Log Message:
-----------
Added NTP engine select() EINTR signal handling,
was giving unnecessary errors on some platforms
where timer signal would collide with select()
for NTP.
Modified Paths:
--------------
trunk/src/dep/ntpengine/ntpdcontrol.c
trunk/src/dep/ntpengine/ntpdcontrol.h
Modified: trunk/src/dep/ntpengine/ntpdcontrol.c
===================================================================
--- trunk/src/dep/ntpengine/ntpdcontrol.c 2015-07-09 16:30:41 UTC (rev 581)
+++ trunk/src/dep/ntpengine/ntpdcontrol.c 2015-07-14 16:16:19 UTC (rev 582)
@@ -377,8 +377,8 @@
fd_set fds;
int n;
int pad;
+ int retries = NTP_EINTR_RETRIES;
-
int ntpdc_pktdatasize;
int implcode=(u_char)3;
@@ -414,43 +414,33 @@
tvo = tvsout;
FD_SET(control->sockFD, &fds);
- n = select(control->sockFD+1, &fds, (fd_set *)0, (fd_set *)0, &tvo);
+
+ do {
+ n = select(control->sockFD+1, &fds, (fd_set *)0, (fd_set *)0, &tvo);
+ if( n == -1 && errno == EINTR) {
+ DBG("NTPDCresponse(): EINTR caught\n");
+ retries--;
+ }
+ } while ((n == -1) && retries);
if (n == -1) {
- /* warning("select fails", "", "");*/
+ DBG("NTPDCresponse(): select failed - not EINTR: %s\n", strerror(errno));
return -1;
}
if (n == 0) {
- /*
- * Timed out. Return what we have
- */
+ DBG("NTP response select timeout");
if (firstpkt) {
return ERR_TIMEOUT;
-///timeout?
} else {
-/* (void) fprintf(stderr,
- "%s: timed out with incomplete data\n",
- currenthost);
-*/
-/* if (debug) {
- printf("Received sequence numbers");
- for (n = 0; n <= MAXSEQ; n++)
- if (haveseq[n])
- printf(" %d,", n);
- if (lastseq != 999)
- printf(" last frame received\n");
- else
- printf(" last frame not received\n");
- }
-*/
return ERR_INCOMPLETE;
}
}
n = recv(control->sockFD, (char *)&rpkt, sizeof(rpkt), 0);
+
if (n == -1) {
- /* warning("read", "", "");*/
- return -1;
+ DBG("NTP response recv failed\n");
+ return -1;
}
@@ -458,10 +448,6 @@
* Check for format errors. Bug proofing.
*/
if (n < RESP_HEADER_SIZE) {
-/* if (debug)
- printf("Short (%d byte) packet received\n", n);
-*/
-
goto again;
}
@@ -653,6 +639,7 @@
)
{
int res;
+ int retries = NTP_EINTR_RETRIES;
char junk[512];
fd_set fds;
struct timeval tvzero;
@@ -669,19 +656,24 @@
res = select(control->sockFD+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero);
if (res == -1) {
-// INFO("junk cleanup - select fails");
-// warning("polling select", "", "");
+ if((errno == EINTR) && retries ) {
+ DBG("NTPDCquery(): select EINTR caught");
+ retries--;
+ res = 1;
+ continue;
+ }
+ DBG("NTPDCquery(): select() error - not EINTR: %s\n", strerror(errno));
return -1;
- } else if (res > 0)
-
+ } else if (res > 0) {
(void) recv(control->sockFD, junk, sizeof junk, 0);
+ }
} while (res > 0);
/*
* send a request
*/
res = NTPDCrequest(options, control, reqcode, auth, qitems, qsize, qdata);
- if (res <= 0) {
+ if (res <= 0) {
return res;
}
/*
Modified: trunk/src/dep/ntpengine/ntpdcontrol.h
===================================================================
--- trunk/src/dep/ntpengine/ntpdcontrol.h 2015-07-09 16:30:41 UTC (rev 581)
+++ trunk/src/dep/ntpengine/ntpdcontrol.h 2015-07-14 16:16:19 UTC (rev 582)
@@ -356,4 +356,7 @@
#define INITDATASIZE (sizeof(struct resp_pkt) * 16)
#define INCDATASIZE (sizeof(struct resp_pkt) * 8)
+/* how many time select() will retry on EINTR */
+#define NTP_EINTR_RETRIES 5
+
#endif /* NTPDCONTROL_H */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wow...@us...> - 2015-07-09 16:30:43
|
Revision: 581
http://sourceforge.net/p/ptpd/code/581
Author: wowczarek
Date: 2015-07-09 16:30:41 +0000 (Thu, 09 Jul 2015)
Log Message:
-----------
2.3.1.1 minor fix release preparations:
- version bump
- TimingDomain shutdown order fixed to
prevent segfault when shutting down NTP
- Cleaner NTP shutdown message
- Sequence numbers added to statistics file
- RPM spec versions updated
- default config file version number fix
Modified Paths:
--------------
trunk/m4/version.m4
trunk/packagebuild/rpm-rh/ptpd.init
trunk/packagebuild/rpm-rh/ptpd.spec
trunk/src/Makefile.am
trunk/src/dep/sys.c
trunk/src/ptpd2.conf.default-full
trunk/src/timingdomain.c
Modified: trunk/m4/version.m4
===================================================================
--- trunk/m4/version.m4 2015-07-02 08:11:00 UTC (rev 580)
+++ trunk/m4/version.m4 2015-07-09 16:30:41 UTC (rev 581)
@@ -1,4 +1,4 @@
m4_define([PTPD_URL],[http://ptpd.sourceforge.net])
m4_define([RELEASE_DATE],[June, 2015])
-m4_define([VERSION_NUMBER],[2.3.1])
+m4_define([VERSION_NUMBER],[2.3.1.1])
Modified: trunk/packagebuild/rpm-rh/ptpd.init
===================================================================
--- trunk/packagebuild/rpm-rh/ptpd.init 2015-07-02 08:11:00 UTC (rev 580)
+++ trunk/packagebuild/rpm-rh/ptpd.init 2015-07-09 16:30:41 UTC (rev 581)
@@ -202,4 +202,4 @@
esac
-exit $RETVAL
\ No newline at end of file
+exit $RETVAL
Modified: trunk/packagebuild/rpm-rh/ptpd.spec
===================================================================
--- trunk/packagebuild/rpm-rh/ptpd.spec 2015-07-02 08:11:00 UTC (rev 580)
+++ trunk/packagebuild/rpm-rh/ptpd.spec 2015-07-09 16:30:41 UTC (rev 581)
@@ -22,12 +22,12 @@
Name: ptpd
Summary: Synchronises system time using the Precision Time Protocol (PTP) implementing the IEEE 1588-2008 (PTP v 2) standard. Full version with master and slave support.
%endif
-Version: 2.3.1
-Release: 2%{distver}
+Version: 2.3.1.1
+Release: 1%{distver}
License: distributable
Group: System Environment/Daemons
Vendor: PTPd project team
-Source0: ptpd-2.3.1.tar.gz
+Source0: ptpd-2.3.1.1.tar.gz
Source2: ptpd.sysconfig
Source3: ptpd.conf
@@ -68,7 +68,7 @@
%prep
-%setup -n ptpd-2.3.1
+%setup -n ptpd-2.3.1.1
%build
@@ -215,6 +215,8 @@
%{_datadir}/ptpd/*
%changelog
+* Thu Jul 09 2015 Wojciech Owczarek <woj...@ow...> 2.3.1.1-1
+- minor version 2.3.1.1 with NTP shutdown fix
* Wed Jul 1 2015 Wojciech Owczarek <woj...@ow...> 2.3.1-2
- spec updated for OSes with systemd
- chrony detection added to postinstall checks
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2015-07-02 08:11:00 UTC (rev 580)
+++ trunk/src/Makefile.am 2015-07-09 16:30:41 UTC (rev 581)
@@ -5,7 +5,7 @@
sbin_PROGRAMS = ptpd2
man_MANS = ptpd2.8 ptpd2.conf.5
-AM_CFLAGS = $(SNMP_CFLAGS) $(PCAP_CFLAGS) -Wall
+AM_CFLAGS = $(SNMP_CFLAGS) $(PCAP_CFLAGS) -Wall -fexceptions -fstack-protector
AM_CPPFLAGS = $(SNMP_CPPFLAGS) $(PCAP_CPPFLAGS)
AM_LDFLAGS = $(SNMP_LIBS) $(PCAP_LIBS)
Modified: trunk/src/dep/sys.c
===================================================================
--- trunk/src/dep/sys.c 2015-07-02 08:11:00 UTC (rev 580)
+++ trunk/src/dep/sys.c 2015-07-09 16:30:41 UTC (rev 581)
@@ -620,7 +620,7 @@
{
extern RunTimeOpts rtOpts;
static int errorMsg = 0;
- static char sbuf[SCREEN_BUFSZ];
+ static char sbuf[SCREEN_BUFSZ * 2];
int len = 0;
TimeInternal now;
time_t time_s;
@@ -641,14 +641,15 @@
ptpClock->resetStatisticsLog = FALSE;
fprintf(destination,"# %s, State, Clock ID, One Way Delay, "
"Offset From Master, Slave to Master, "
- "Master to Slave, Observed Drift, Last packet Received"
+ "Master to Slave, Observed Drift, Last packet Received, Sequence ID"
#ifdef PTPD_STATISTICS
", One Way Delay Mean, One Way Delay Std Dev, Offset From Master Mean, Offset From Master Std Dev, Observed Drift Mean, Observed Drift Std Dev, raw delayMS, raw delaySM"
#endif
"\n", (rtOpts.statisticsTimestamp == TIMESTAMP_BOTH) ? "Timestamp, Unix timestamp" : "Timestamp");
}
- memset(sbuf, ' ', sizeof(sbuf));
+ memset(sbuf, 0, sizeof(sbuf));
+
getTime(&now);
/*
@@ -677,7 +678,6 @@
}
}
-
time_s = now.seconds;
/* output date-time timestamp if configured */
@@ -744,9 +744,10 @@
len += snprint_TimeInternal(sbuf + len, sizeof(sbuf) - len,
&(ptpClock->delayMS));
- len += snprintf(sbuf + len, sizeof(sbuf) - len, ", %.09f, %c",
+ len += snprintf(sbuf + len, sizeof(sbuf) - len, ", %.09f, %c, %05d",
ptpClock->servo.observedDrift,
- ptpClock->char_last_msg);
+ ptpClock->char_last_msg,
+ ptpClock->msgTmpHeader.sequenceId);
#ifdef PTPD_STATISTICS
@@ -796,6 +797,7 @@
len += snprintf(sbuf + len, sizeof(sbuf) - len, "\n");
}
#endif
+
/* fprintf may get interrupted by a signal - silently retry once */
if (fprintf(destination, "%s", sbuf) < len) {
if (fprintf(destination, "%s", sbuf) < len) {
Modified: trunk/src/ptpd2.conf.default-full
===================================================================
--- trunk/src/ptpd2.conf.default-full 2015-07-02 08:11:00 UTC (rev 580)
+++ trunk/src/ptpd2.conf.default-full 2015-07-09 16:30:41 UTC (rev 581)
@@ -1,5 +1,5 @@
; ========================================
-; PTPDv2 version 2.3.1-rc5 default configuration
+; PTPDv2 version 2.3.1.1 default configuration
; ========================================
; NOTE: the following settings are affected by ptpengine:preset selection:
Modified: trunk/src/timingdomain.c
===================================================================
--- trunk/src/timingdomain.c 2015-07-02 08:11:00 UTC (rev 580)
+++ trunk/src/timingdomain.c 2015-07-09 16:30:41 UTC (rev 581)
@@ -533,8 +533,13 @@
NTPoptions *config = (NTPoptions*) service->config;
NTPcontrol *controller = (NTPcontrol*) service->controller;
- INFO_LOCAL_ID(service,"NTP service shutting down. Restoring original NTP state\n");
- ntpShutdown(config, controller);
+ INFO_LOCAL_ID(service,"NTP service shutting down\n");
+
+ if(controller->flagsCaptured) {
+ INFO_LOCAL_ID(service,"Restoring original NTP state\n");
+ ntpShutdown(config, controller);
+ }
+
FLAGS_UNSET(service->flags, TIMINGSERVICE_OPERATIONAL);
FLAGS_UNSET(service->flags, TIMINGSERVICE_AVAILABLE);
return 1;
@@ -693,11 +698,15 @@
INFO_LOCAL("Timing domain shutting down\n");
- for(i=0; i < domain->serviceCount; i++) {
+ for(i=domain->serviceCount - 1; i >= 0; i--) {
service = domain->services[i];
- service->shutdown(service);
+ if(service != NULL) {
+ service->shutdown(service);
+ }
}
+ INFO_LOCAL("Timing domain shutdown complete\n");
+
return 1;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|