From: <gn...@us...> - 2011-02-01 19:39:31
|
Revision: 121 http://ptpd.svn.sourceforge.net/ptpd/?rev=121&view=rev Author: gnn Date: 2011-02-01 19:39:25 +0000 (Tue, 01 Feb 2011) Log Message: ----------- Add support for DNS lookups of the grandmaster when using unicast. Clean up include file locations. Clean up X axis label in quality_correlate script. Modified Paths: -------------- trunk/ChangeLog trunk/src/datatypes.h trunk/src/dep/msg.c trunk/src/dep/net.c trunk/src/dep/ptpd_dep.h trunk/src/dep/startup.c trunk/src/ptpd.h trunk/tools/quality_correlate.py Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2011-02-01 19:37:00 UTC (rev 120) +++ trunk/ChangeLog 2011-02-01 19:39:25 UTC (rev 121) @@ -1,3 +1,12 @@ +2011-02-01 George Neville-Neil <gn...@ne...> + + * Add support for DNS lookup of timeserver for unicast. + + * Add support for unicasting delay requests. + + * Add code to dump packets on demand via the -P flag as well as in + response to updates that violate either the -M or -O flags. + 2010-10-12 George Neville-Neil <gn...@ne...> * 1.1.0 Release Modified: trunk/src/datatypes.h =================================================================== --- trunk/src/datatypes.h 2011-02-01 19:37:00 UTC (rev 120) +++ trunk/src/datatypes.h 2011-02-01 19:39:25 UTC (rev 121) @@ -12,6 +12,7 @@ #define DATATYPES_H #include <stdio.h> +#include <sys/param.h> typedef struct { UInteger32 seconds; @@ -338,7 +339,7 @@ Boolean displayStats; Boolean csvStats; Boolean displayPackets; - Octet unicastAddress[NET_ADDRESS_LENGTH]; + Octet unicastAddress[MAXHOSTNAMELEN]; Integer16 ap, ai; Integer16 s; TimeInternal inboundLatency, outboundLatency; Modified: trunk/src/dep/msg.c =================================================================== --- trunk/src/dep/msg.c 2011-02-01 19:37:00 UTC (rev 120) +++ trunk/src/dep/msg.c 2011-02-01 19:39:25 UTC (rev 121) @@ -678,7 +678,9 @@ void msgDump(PtpClock *ptpClock) { +#if defined(freebsd) static int dumped = 0; +#endif /* FreeBSD */ msgDebugHeader(&ptpClock->msgTmpHeader); switch (ptpClock->msgTmpHeader.control) { @@ -707,6 +709,7 @@ break; } +#if defined(freebsd) /* Only dump the first time, after that just do a message. */ if (dumped != 0) return; @@ -724,7 +727,7 @@ /* This default intentionally left blank. */ break; } - +#endif /* FreeBSD */ } /** Modified: trunk/src/dep/net.c =================================================================== --- trunk/src/dep/net.c 2011-02-01 19:37:00 UTC (rev 120) +++ trunk/src/dep/net.c 2011-02-01 19:39:25 UTC (rev 121) @@ -261,14 +261,30 @@ /* send a uni-cast address if specified (useful for testing) */ if (rtOpts->unicastAddress[0]) { - if (!inet_aton(rtOpts->unicastAddress, &netAddr)) { - ERROR("failed to encode uni-cast address: %s\n", rtOpts->unicastAddress); - return FALSE; + /* Attempt a DNS lookup first. */ + struct hostent *host; + host = gethostbyname2(rtOpts->unicastAddress, AF_INET); + if (host != NULL) { + if (host->h_length != 4) { + PERROR("unicast host resolved to non ipv4" + "address"); + return FALSE; + } + netPath->unicastAddr = + *(uint32_t *)host->h_addr_list[0]; + } else { + /* Maybe it's a dotted quad. */ + if (!inet_aton(rtOpts->unicastAddress, &netAddr)) { + ERROR("failed to encode uni-cast address: %s\n", + rtOpts->unicastAddress); + return FALSE; + netPath->unicastAddr = netAddr.s_addr; + } } - netPath->unicastAddr = netAddr.s_addr; } else netPath->unicastAddr = 0; + /* resolve PTP subdomain */ if (!lookupSubdomainAddress(rtOpts->subdomainName, addrStr)) return FALSE; Modified: trunk/src/dep/ptpd_dep.h =================================================================== --- trunk/src/dep/ptpd_dep.h 2011-02-01 19:37:00 UTC (rev 120) +++ trunk/src/dep/ptpd_dep.h 2011-02-01 19:39:25 UTC (rev 121) @@ -10,25 +10,6 @@ #ifndef PTPD_DEP_H #define PTPD_DEP_H -#include<stdlib.h> -#include<stdio.h> -#include<string.h> -#include<unistd.h> -#include<errno.h> -#include<signal.h> -#include<fcntl.h> -#include<sys/stat.h> -#include<time.h> -#include<sys/time.h> -#include<sys/timex.h> -#include<sys/socket.h> -#include<sys/select.h> -#include<sys/ioctl.h> -#include<arpa/inet.h> -#include<stdarg.h> -#include<syslog.h> -#include<limits.h> - /* system messages */ #define ERROR(x, ...) message(LOG_ERR, x, ##__VA_ARGS__) #define PERROR(x, ...) message(LOG_ERR, x ": %m\n", ##__VA_ARGS__) Modified: trunk/src/dep/startup.c =================================================================== --- trunk/src/dep/startup.c 2011-02-01 19:37:00 UTC (rev 120) +++ trunk/src/dep/startup.c 2011-02-01 19:39:25 UTC (rev 121) @@ -247,7 +247,8 @@ break; case 'u': - strncpy(rtOpts->unicastAddress, optarg, NET_ADDRESS_LENGTH); + strncpy(rtOpts->unicastAddress, optarg, + MAXHOSTNAMELEN); break; case 'l': Modified: trunk/src/ptpd.h =================================================================== --- trunk/src/ptpd.h 2011-02-01 19:37:00 UTC (rev 120) +++ trunk/src/ptpd.h 2011-02-01 19:39:25 UTC (rev 121) @@ -12,6 +12,26 @@ #ifndef PTPD_H #define PTPD_H +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <signal.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <time.h> +#include <netdb.h> +#include <sys/time.h> +#include <sys/timex.h> +#include <sys/socket.h> +#include <sys/select.h> +#include <sys/ioctl.h> +#include <arpa/inet.h> +#include <stdarg.h> +#include <syslog.h> +#include <limits.h> + #include "constants.h" #include "dep/constants_dep.h" #include "dep/datatypes_dep.h" Modified: trunk/tools/quality_correlate.py =================================================================== --- trunk/tools/quality_correlate.py 2011-02-01 19:37:00 UTC (rev 120) +++ trunk/tools/quality_correlate.py 2011-02-01 19:39:25 UTC (rev 121) @@ -173,8 +173,9 @@ if ((options.ymin != 0) or (options.ymax != 10)): plotter.set_range('yrange', [options.ymin, options.ymax]) + plotter.xlabel(options.hosts[0] + "\\n" + options.hosts[1] + "\\n" + + str(start) + " - " + str(end) + "\\n" + 'Sample Number') plotter.ylabel('Time Difference\\nNanoseconds') - plotter.xlabel('Sample Number') plotter.plot(graph) if (options.png != None): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gn...@us...> - 2011-02-02 20:15:38
|
Revision: 122 http://ptpd.svn.sourceforge.net/ptpd/?rev=122&view=rev Author: gnn Date: 2011-02-02 20:15:32 +0000 (Wed, 02 Feb 2011) Log Message: ----------- Add a tests/ subdirectory to contain internal and unit tests. Add a new function, divTime, which correctly divides and internal time value by an integer divisor. Correct the calculation of one way delay for delays greater than one second by using the new divTime function. Add a test for the divTime function. Bug Tracker ID: 3089966 Modified Paths: -------------- trunk/src/arith.c trunk/src/dep/servo.c trunk/src/ptpd.h Added Paths: ----------- trunk/tests/ trunk/tests/divtest.c Modified: trunk/src/arith.c =================================================================== --- trunk/src/arith.c 2011-02-01 19:39:25 UTC (rev 121) +++ trunk/src/arith.c 2011-02-02 20:15:32 UTC (rev 122) @@ -111,3 +111,25 @@ normalizeTime(r); } + +/// Divide an internal time value +/// +/// @param r the time to convert +/// @param divisor +/// +void +divTime(TimeInternal *r, int divisor) +{ + + uint64_t nanoseconds; + + if (divisor <= 0) + return; + + nanoseconds = ((uint64_t)r->seconds * 1000000000) + r->nanoseconds; + nanoseconds /= divisor; + + r->seconds = nanoseconds / 1000000000; + r->nanoseconds = nanoseconds % 1000000000; + +} Modified: trunk/src/dep/servo.c =================================================================== --- trunk/src/dep/servo.c 2011-02-01 19:39:25 UTC (rev 121) +++ trunk/src/dep/servo.c 2011-02-02 20:15:32 UTC (rev 122) @@ -62,10 +62,11 @@ ptpClock->slave_to_master_delay = slave_to_master_delay; /* update 'one_way_delay' */ - addTime(&ptpClock->one_way_delay, &ptpClock->master_to_slave_delay, &ptpClock->slave_to_master_delay); - ptpClock->one_way_delay.seconds /= 2; - ptpClock->one_way_delay.nanoseconds /= 2; + addTime(&ptpClock->one_way_delay, &ptpClock->master_to_slave_delay, + &ptpClock->slave_to_master_delay); + divTime(&ptpClock->one_way_delay, 2); + if (ptpClock->one_way_delay.seconds) { /* cannot filter with secs, clear filter */ owd_filt->s_exp = owd_filt->nsec_prev = 0; Modified: trunk/src/ptpd.h =================================================================== --- trunk/src/ptpd.h 2011-02-01 19:39:25 UTC (rev 121) +++ trunk/src/ptpd.h 2011-02-02 20:15:32 UTC (rev 122) @@ -46,6 +46,7 @@ void normalizeTime(TimeInternal *); void addTime(TimeInternal *, TimeInternal *, TimeInternal *); void subTime(TimeInternal *, TimeInternal *, TimeInternal *); +void divTime(TimeInternal *, int); /* bmc.c */ UInteger8 bmc(ForeignMasterRecord *, RunTimeOpts *, PtpClock *); Added: trunk/tests/divtest.c =================================================================== --- trunk/tests/divtest.c (rev 0) +++ trunk/tests/divtest.c 2011-02-02 20:15:32 UTC (rev 122) @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011, Neville-Neil Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of Neville-Neil Consulting nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER 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. + * + * $Id$ + * + * Author: George V. Neville-Neil + * + * + */ + +#include "../src/ptpd.h" + +int rtOpts; + +int main(int argc, char **argv) +{ + + int count = 0; + for (count; count < 100; count++) { + TimeInternal result; + + getTime(&result); + result.seconds = count; + printf("Before: %d %d\n", result.seconds, result.nanoseconds); + divTime(&result, 2); + printf("1/2 %d %d\n", result.seconds, result.nanoseconds); + + } +} Property changes on: trunk/tests/divtest.c ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + FreeBSD=%H Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gn...@us...> - 2011-02-22 18:18:04
|
Revision: 132 http://ptpd.svn.sourceforge.net/ptpd/?rev=132&view=rev Author: gnn Date: 2011-02-22 18:17:57 +0000 (Tue, 22 Feb 2011) Log Message: ----------- Update the COPYRIGHT file to just contain the proper template for the BSD 2 clause license. Add 2 clause license to all C source files. Update the copyright year to 2011. This must be done each and every year that the project is active. Modified Paths: -------------- trunk/COPYRIGHT trunk/src/arith.c trunk/src/bmc.c trunk/src/dep/msg.c trunk/src/dep/net.c trunk/src/dep/servo.c trunk/src/dep/startup.c trunk/src/dep/sys.c trunk/src/dep/timer.c trunk/src/probe.c trunk/src/protocol.c trunk/src/ptpd.c Modified: trunk/COPYRIGHT =================================================================== --- trunk/COPYRIGHT 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/COPYRIGHT 2011-02-22 18:17:57 UTC (rev 132) @@ -1,18 +1,28 @@ -The following copyright notice applies to all files which compose the -PTPd. This notice applies as if the text was explicitly included each -file. - -Copyright (c) 2009-2010 George V. Neville-Neil, Steven Kreuzer, Martin Burnicki -Copyright (c) 2005-2008 Kendall Correll, Aidan Williams - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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. + */ Modified: trunk/src/arith.c =================================================================== --- trunk/src/arith.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/arith.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 arith.c * @date Tue Jul 20 16:12:51 2010 Modified: trunk/src/bmc.c =================================================================== --- trunk/src/bmc.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/bmc.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 bmc.c * @date Wed Jun 23 09:36:09 2010 Modified: trunk/src/dep/msg.c =================================================================== --- trunk/src/dep/msg.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/dep/msg.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 msg.c * @author George Neville-Neil <gn...@ne...> Modified: trunk/src/dep/net.c =================================================================== --- trunk/src/dep/net.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/dep/net.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 net.c * @date Tue Jul 20 16:17:49 2010 Modified: trunk/src/dep/servo.c =================================================================== --- trunk/src/dep/servo.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/dep/servo.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 servo.c * @date Tue Jul 20 16:19:19 2010 Modified: trunk/src/dep/startup.c =================================================================== --- trunk/src/dep/startup.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/dep/startup.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 startup.c * @date Wed Jun 23 09:33:27 2010 Modified: trunk/src/dep/sys.c =================================================================== --- trunk/src/dep/sys.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/dep/sys.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 sys.c * @date Tue Jul 20 16:19:46 2010 Modified: trunk/src/dep/timer.c =================================================================== --- trunk/src/dep/timer.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/dep/timer.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 timer.c * @date Wed Jun 23 09:41:26 2010 Modified: trunk/src/probe.c =================================================================== --- trunk/src/probe.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/probe.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 probe.c * @date Tue Jul 20 16:13:30 2010 Modified: trunk/src/protocol.c =================================================================== --- trunk/src/protocol.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/protocol.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 protocol.c * @date Wed Jun 23 09:40:39 2010 Modified: trunk/src/ptpd.c =================================================================== --- trunk/src/ptpd.c 2011-02-17 19:08:13 UTC (rev 131) +++ trunk/src/ptpd.c 2011-02-22 18:17:57 UTC (rev 132) @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, + * Martin Burnicki + * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams + * + * 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 ptpd.c * @date Wed Jun 23 10:13:38 2010 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gn...@us...> - 2011-02-22 18:56:30
|
Revision: 134 http://ptpd.svn.sourceforge.net/ptpd/?rev=134&view=rev Author: gnn Date: 2011-02-22 18:56:24 +0000 (Tue, 22 Feb 2011) Log Message: ----------- Add support for Mac OS X (Snow Leopard) Modified Paths: -------------- trunk/INSTALL trunk/src/dep/constants_dep.h trunk/src/dep/net.c trunk/src/dep/ptpd_dep.h trunk/src/dep/servo.c trunk/src/dep/sys.c trunk/src/ptpd.h Modified: trunk/INSTALL =================================================================== --- trunk/INSTALL 2011-02-22 18:18:30 UTC (rev 133) +++ trunk/INSTALL 2011-02-22 18:56:24 UTC (rev 134) @@ -1,12 +1,12 @@ PTP Daemon Installation Instructions -11 October 2010 +22 February 2011 George V. Neville-Neil -The PTP Daemon is known to work on FreeBSD and Linux systems. +The PTP Daemon is known to work on FreeBSD, Mac, and Linux systems. -*) Building on FreeBSD +*) Building on FreeBSD and Mac OS X (Snow Leopard) 1) cd into the src/ directory 2) Un comment the #-DBSD_INTERFACE_FUNCTIONS option: Modified: trunk/src/dep/constants_dep.h =================================================================== --- trunk/src/dep/constants_dep.h 2011-02-22 18:18:30 UTC (rev 133) +++ trunk/src/dep/constants_dep.h 2011-02-22 18:56:24 UTC (rev 134) @@ -12,7 +12,8 @@ #include <limits.h> -#if !defined(linux) && !defined(__NetBSD__) && !defined(__FreeBSD__) +#if !defined(linux) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \ + !defined(__APPLE__) #error Not ported to this architecture, please update. #endif @@ -34,14 +35,14 @@ #endif /* linux */ -#if defined(__NetBSD__) || defined(__FreeBSD__) +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__) #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__APPLE__) #include <net/ethernet.h> #include <sys/uio.h> #else Modified: trunk/src/dep/net.c =================================================================== --- trunk/src/dep/net.c 2011-02-22 18:18:30 UTC (rev 133) +++ trunk/src/dep/net.c 2011-02-22 18:56:24 UTC (rev 134) @@ -364,7 +364,7 @@ /* make timestamps available through recvmsg() */ temp = 1; -#if defined(linux) +#if defined(linux) || defined(__APPLE__) if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0 || setsockopt(netPath->generalSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0) { #else /* BSD */ @@ -450,7 +450,7 @@ char control[CMSG_SPACE(sizeof(struct timeval))]; } cmsg_un; struct cmsghdr *cmsg; -#if defined(linux) +#if defined(linux) || defined(__APPLE__) struct timeval *tv; #else /* FreeBSD */ struct timespec ts; @@ -499,7 +499,7 @@ return 0; } -#if defined(linux) +#if defined(linux) || defined(__APPLE__) tv = 0; for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) Modified: trunk/src/dep/ptpd_dep.h =================================================================== --- trunk/src/dep/ptpd_dep.h 2011-02-22 18:18:30 UTC (rev 133) +++ trunk/src/dep/ptpd_dep.h 2011-02-22 18:56:24 UTC (rev 134) @@ -132,6 +132,10 @@ UInteger16 getRand(UInteger32 *); Boolean adjFreq(Integer32); +#if defined(__APPLE__) +void adjTime(Integer32); +#endif /* __APPLE__ */ + /* timer.c */ void initTimer(void); void timerUpdate(IntervalTimer *); Modified: trunk/src/dep/servo.c =================================================================== --- trunk/src/dep/servo.c 2011-02-22 18:18:30 UTC (rev 133) +++ trunk/src/dep/servo.c 2011-02-22 18:56:24 UTC (rev 134) @@ -54,8 +54,10 @@ rtOpts->halfEpoch = 0; /* level clock */ +#if !defined(__APPLE__) if (!rtOpts->noAdjust) adjFreq(0); +#endif /* __APPLE__ */ } void @@ -205,8 +207,10 @@ setTime(&timeTmp); initClock(rtOpts, ptpClock); } else { +#if !defined(__APPLE__) adj = ptpClock->offset_from_master.nanoseconds > 0 ? ADJ_FREQ_MAX : -ADJ_FREQ_MAX; adjFreq(-adj); +#endif /* __APPLE__ */ } } } else { @@ -231,7 +235,11 @@ /* apply controller output as a clock tick rate adjustment */ if (!rtOpts->noAdjust) +#if defined(__APPLE__) + adjTime(ptpClock->offset_from_master.nanoseconds); +#else adjFreq(-adj); +#endif /* __APPLE__ */ } display: Modified: trunk/src/dep/sys.c =================================================================== --- trunk/src/dep/sys.c 2011-02-22 18:18:30 UTC (rev 133) +++ trunk/src/dep/sys.c 2011-02-22 18:56:24 UTC (rev 134) @@ -256,7 +256,7 @@ void getTime(TimeInternal * time) { -#if defined(linux) +#if defined(linux) || defined(__APPLE__) struct timeval tv; gettimeofday(&tv, 0); @@ -294,6 +294,7 @@ return rand_r((unsigned int *)seed); } +#if !defined(__APPLE__) Boolean adjFreq(Integer32 adj) { @@ -309,3 +310,21 @@ return !adjtimex(&t); } + +#else + +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 /* __APPLE__ */ Modified: trunk/src/ptpd.h =================================================================== --- trunk/src/ptpd.h 2011-02-22 18:18:30 UTC (rev 133) +++ trunk/src/ptpd.h 2011-02-22 18:56:24 UTC (rev 134) @@ -23,7 +23,9 @@ #include <time.h> #include <netdb.h> #include <sys/time.h> +#ifndef __APPLE__ #include <sys/timex.h> +#endif #include <sys/socket.h> #include <sys/select.h> #include <sys/ioctl.h> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <id...@us...> - 2012-03-21 15:53:22
|
Revision: 185 http://ptpd.svn.sourceforge.net/ptpd/?rev=185&view=rev Author: idfg Date: 2012-03-21 15:53:08 +0000 (Wed, 21 Mar 2012) Log Message: ----------- adding support for management messages, and compiling ptpd as a static and dynamic library Modified Paths: -------------- trunk/COPYRIGHT trunk/src/Makefile trunk/src/arith.c trunk/src/bmc.c trunk/src/constants.h trunk/src/datatypes.h trunk/src/dep/datatypes_dep.h trunk/src/dep/msg.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/dep/timer.c trunk/src/display.c trunk/src/protocol.c trunk/src/ptpd.c trunk/src/ptpd.h Added Paths: ----------- trunk/src/def/ trunk/src/def/README trunk/src/def/derivedData/ trunk/src/def/derivedData/clockQuality.def trunk/src/def/derivedData/faultRecord.def trunk/src/def/derivedData/physicalAddress.def trunk/src/def/derivedData/portAddress.def trunk/src/def/derivedData/portIdentity.def trunk/src/def/derivedData/ptpText.def trunk/src/def/derivedData/timeInterval.def trunk/src/def/derivedData/timestamp.def trunk/src/def/derivedData/tlv.def trunk/src/def/managementTLV/ trunk/src/def/managementTLV/announceReceiptTimeout.def trunk/src/def/managementTLV/clockAccuracy.def trunk/src/def/managementTLV/clockDescription.def trunk/src/def/managementTLV/currentDataSet.def trunk/src/def/managementTLV/defaultDataSet.def trunk/src/def/managementTLV/delayMechanism.def trunk/src/def/managementTLV/domain.def trunk/src/def/managementTLV/errorStatus.def trunk/src/def/managementTLV/initialize.def trunk/src/def/managementTLV/logAnnounceInterval.def trunk/src/def/managementTLV/logMinPdelayReqInterval.def trunk/src/def/managementTLV/logSyncInterval.def trunk/src/def/managementTLV/managementTLV.def trunk/src/def/managementTLV/parentDataSet.def trunk/src/def/managementTLV/portDataSet.def trunk/src/def/managementTLV/priority1.def trunk/src/def/managementTLV/priority2.def trunk/src/def/managementTLV/slaveOnly.def trunk/src/def/managementTLV/time.def trunk/src/def/managementTLV/timePropertiesDataSet.def trunk/src/def/managementTLV/traceabilityProperties.def trunk/src/def/managementTLV/userDescription.def trunk/src/def/managementTLV/utcProperties.def trunk/src/def/managementTLV/versionNumber.def trunk/src/def/message/ trunk/src/def/message/header.def trunk/src/def/message/management.def trunk/src/management.c Modified: trunk/COPYRIGHT =================================================================== --- trunk/COPYRIGHT 2012-03-07 19:14:59 UTC (rev 184) +++ trunk/COPYRIGHT 2012-03-21 15:53:08 UTC (rev 185) @@ -1,9 +1,18 @@ /*- - * Copyright (c) 2009-2012 George V. Neville-Neil, + * Copyright (c) 2011-2012 George V. Neville-Neil, * Steven Kreuzer, * Martin Burnicki, * Jan Breuer, * Gael Mace, + * Alexandre Van Kempen, + * Inaqui Delgado, + * Rick Ratzel, + * National Instruments. + * Copyright (c) 2009-2010 George V. Neville-Neil, + * Steven Kreuzer, + * Martin Burnicki, + * Jan Breuer, + * Gael Mace, * Alexandre Van Kempen * * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams Modified: trunk/src/Makefile =================================================================== --- trunk/src/Makefile 2012-03-07 19:14:59 UTC (rev 184) +++ trunk/src/Makefile 2012-03-21 15:53:08 UTC (rev 185) @@ -24,10 +24,13 @@ # ####### +VERSION = 2.2.0 + RM = rm -f +SYMLINK = ln -s # start with CFLAGS += ..., so additional CFLAGs can be specified e.g. on the make command line -CFLAGS += -Wall -g +CFLAGS += -Wall -g -fPIC CFLAGS += -DRUNTIME_DEBUG #CFLAGS += -DPTPD_DBG @@ -40,10 +43,16 @@ CFLAGS += -DPTP_EXPERIMENTAL -LDFLAGS+= -lm -lrt +LDFLAGS = -lm -lrt +STATICLIBFLAGS = rcs +SHAREDLIBFLAGS = -shared -Wl,-soname PROG = ptpd2 -SRCS = ptpd.c arith.c bmc.c protocol.c display.c\ +STATICLIB = libptpd2.a +SHAREDLIB = libptpd2.so +SHAREDLIBVER = $(SHAREDLIB).$(VERSION) + +SRCS = ptpd.c arith.c bmc.c protocol.c display.c management.c \ dep/msg.c dep/net.c dep/servo.c dep/startup.c dep/sys.c dep/timer.c OBJS = $(SRCS:.c=.o) @@ -60,11 +69,20 @@ .c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< -all: $(PROG) $(PROG): $(OBJS) $(CC) -o $@ $(OBJS) $(LDFLAGS) +$(STATICLIB): $(OBJS) + $(AR) $(STATICLIBFLAGS) $(STATICLIB) $(OBJS) + +$(SHAREDLIB): $(OBJS) + $(CC) $(SHAREDLIBFLAGS),$(SHAREDLIB) -o $(SHAREDLIB) $(OBJS) + # create shared lib symlink with ptpd version extension + $(SYMLINK) $(SHAREDLIB) $(SHAREDLIBVER) + +all: $(PROG) $(STATICLIB) $(SHAREDLIB) + $(OBJS): $(HDRS) tags: @@ -73,7 +91,7 @@ $(DOXYGEN) Doxyfile clean: - $(RM) $(PROG) $(OBJS) make.out + $(RM) $(PROG) $(STATICLIB) $(SHAREDLIB) $(SHAREDLIBVER) $(OBJS) $(TAGFILES) make.out -realclean: - $(RM) $(PROG) $(OBJS) $(TAGFILES) make.out +realclean: clean + $(RM) $(TAGFILES) Modified: trunk/src/arith.c =================================================================== --- trunk/src/arith.c 2012-03-07 19:14:59 UTC (rev 184) +++ trunk/src/arith.c 2012-03-21 15:53:08 UTC (rev 185) @@ -1,6 +1,20 @@ /*- - * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, - * Martin Burnicki, Gael Mace, Alexandre Van Kempen + * Copyright (c) 2011-2012 George V. Neville-Neil, + * Steven Kreuzer, + * Martin Burnicki, + * Jan Breuer, + * Gael Mace, + * Alexandre Van Kempen, + * Inaqui Delgado, + * Rick Ratzel, + * National Instruments. + * Copyright (c) 2009-2010 George V. Neville-Neil, + * Steven Kreuzer, + * Martin Burnicki, + * Jan Breuer, + * Gael Mace, + * Alexandre Van Kempen + * * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams * * All Rights Reserved @@ -38,6 +52,11 @@ #include "ptpd.h" +void +internalTime_to_integer64(TimeInternal internal, Integer64 *bigint) +{ + /* TODO: implement me */ +} void integer64_to_internalTime(Integer64 bigint, TimeInternal * internal) Modified: trunk/src/bmc.c =================================================================== --- trunk/src/bmc.c 2012-03-07 19:14:59 UTC (rev 184) +++ trunk/src/bmc.c 2012-03-21 15:53:08 UTC (rev 185) @@ -1,6 +1,20 @@ /*- - * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, - * Martin Burnicki, Gael Mace, Alexandre Van Kempen + * Copyright (c) 2011-2012 George V. Neville-Neil, + * Steven Kreuzer, + * Martin Burnicki, + * Jan Breuer, + * Gael Mace, + * Alexandre Van Kempen, + * Inaqui Delgado, + * Rick Ratzel, + * National Instruments. + * Copyright (c) 2009-2010 George V. Neville-Neil, + * Steven Kreuzer, + * Martin Burnicki, + * Jan Breuer, + * Gael Mace, + * Alexandre Van Kempen + * * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams * * All Rights Reserved @@ -78,7 +92,7 @@ ptpClock->domainNumber = rtOpts->domainNumber; ptpClock->slaveOnly = rtOpts->slaveOnly; if(rtOpts->slaveOnly) - rtOpts->clockQuality.clockClass = 255; + rtOpts->clockQuality.clockClass = SLAVE_ONLY_CLOCK_CLASS; /* Port configuration data set */ @@ -86,8 +100,8 @@ * PortIdentity Init (portNumber = 1 for an ardinary clock spec * 7.5.2.3) */ - memcpy(ptpClock->portIdentity.clockIdentity,ptpClock->clockIdentity, - CLOCK_IDENTITY_LENGTH); + copyClockIdentity(ptpClock->portIdentity.clockIdentity, + ptpClock->clockIdentity); ptpClock->portIdentity.portNumber = NUMBER_PORTS; /* select the initial rate of delayreqs until we receive the first announce message */ @@ -124,14 +138,14 @@ clearTime(&ptpClock->meanPathDelay); /*Parent data set*/ - memcpy(ptpClock->parentPortIdentity.clockIdentity, - ptpClock->clockIdentity,CLOCK_IDENTITY_LENGTH); + copyClockIdentity(ptpClock->parentPortIdentity.clockIdentity, + ptpClock->clockIdentity); ptpClock->parentPortIdentity.portNumber = 0; ptpClock->parentStats = DEFAULT_PARENTS_STATS; ptpClock->observedParentClockPhaseChangeRate = 0; ptpClock->observedParentOffsetScaledLogVariance = 0; - memcpy(ptpClock->grandmasterIdentity,ptpClock->clockIdentity, - CLOCK_IDENTITY_LENGTH); + copyClockIdentity(ptpClock->grandmasterIdentity, + ptpClock->clockIdentity); ptpClock->grandmasterClockQuality.clockAccuracy = ptpClock->clockQuality.clockAccuracy; ptpClock->grandmasterClockQuality.clockClass = @@ -170,12 +184,12 @@ ptpClock->stepsRemoved = announce->stepsRemoved + 1; /* Parent DS */ - memcpy(ptpClock->parentPortIdentity.clockIdentity, - header->sourcePortIdentity.clockIdentity,CLOCK_IDENTITY_LENGTH); + copyClockIdentity(ptpClock->parentPortIdentity.clockIdentity, + header->sourcePortIdentity.clockIdentity); ptpClock->parentPortIdentity.portNumber = header->sourcePortIdentity.portNumber; - memcpy(ptpClock->grandmasterIdentity,announce->grandmasterIdentity, - CLOCK_IDENTITY_LENGTH); + copyClockIdentity(ptpClock->grandmasterIdentity, + announce->grandmasterIdentity); ptpClock->grandmasterClockQuality.clockAccuracy = announce->grandmasterClockQuality.clockAccuracy; ptpClock->grandmasterClockQuality.clockClass = @@ -188,17 +202,17 @@ /* Timeproperties DS */ ptpClock->currentUtcOffset = announce->currentUtcOffset; /* "Valid" is bit 2 in second octet of flagfield */ - ptpClock->currentUtcOffsetValid = ((header->flagField[1] & PTP_UTC_REASONABLE) == PTP_UTC_REASONABLE); + ptpClock->currentUtcOffsetValid = IS_SET(header->flagField1, UTCV); /* set PTP_PASSIVE-specific state */ p1(ptpClock, rtOpts); - ptpClock->leap59 = ((header->flagField[1] & PTP_LI_61) == PTP_LI_59); - ptpClock->leap61 = ((header->flagField[1] & PTP_LI_61) == PTP_LI_61); - ptpClock->timeTraceable = ((header->flagField[1] & TIME_TRACEABLE) == TIME_TRACEABLE); - ptpClock->frequencyTraceable = ((header->flagField[1] & FREQUENCY_TRACEABLE) == FREQUENCY_TRACEABLE); - ptpClock->ptpTimescale = ((header->flagField[1] & PTP_TIMESCALE) == PTP_TIMESCALE); - ptpClock->timeSource = announce->timeSource; + ptpClock->leap59 = IS_SET(header->flagField1, LI59); + ptpClock->leap61 = IS_SET(header->flagField1, LI61); + ptpClock->timeTraceable = IS_SET(header->flagField1, TTRA); + ptpClock->frequencyTraceable = IS_SET(header->flagField1, FTRA); + ptpClock->ptpTimescale = IS_SET(header->flagField1, PTPT); + ptpClock->timeSource = announce->timeSource; } @@ -206,8 +220,8 @@ void copyD0(MsgHeader *header, MsgAnnounce *announce, PtpClock *ptpClock) { announce->grandmasterPriority1 = ptpClock->priority1; - memcpy(announce->grandmasterIdentity,ptpClock->clockIdentity, - CLOCK_IDENTITY_LENGTH); + copyClockIdentity(announce->grandmasterIdentity, + ptpClock->clockIdentity); announce->grandmasterClockQuality.clockClass = ptpClock->clockQuality.clockClass; announce->grandmasterClockQuality.clockAccuracy = @@ -216,8 +230,8 @@ ptpClock->clockQuality.offsetScaledLogVariance; announce->grandmasterPriority2 = ptpClock->priority2; announce->stepsRemoved = 0; - memcpy(header->sourcePortIdentity.clockIdentity, - ptpClock->clockIdentity,CLOCK_IDENTITY_LENGTH); + copyClockIdentity(header->sourcePortIdentity.clockIdentity, + ptpClock->clockIdentity); } Modified: trunk/src/constants.h =================================================================== --- trunk/src/constants.h 2012-03-07 19:14:59 UTC (rev 184) +++ trunk/src/constants.h 2012-03-21 15:53:08 UTC (rev 185) @@ -9,10 +9,25 @@ * and enumeration defined in the spec */ +/* FIXME: make these parameterized, either through command-line options or make variables */ #define MANUFACTURER_ID \ "MaceG VanKempen;2.0.0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +#define MANUFACTURER_ID_OUI0 \ + 0xFF +#define MANUFACTURER_ID_OUI1 \ + 0xFF +#define MANUFACTURER_ID_OUI2 \ + 0xFF +#define PROTOCOL \ + "IEEE 802.3" +#define PRODUCT_DESCRIPTION \ + ";;" +#define REVISION \ + ";;2.1" +#define USER_DESCRIPTION \ + "PTPDv2" +#define USER_DESCRIPTION_MAX 128 - /* implementation specific constants */ #define DEFAULT_INBOUND_LATENCY 0 /* in nsec */ #define DEFAULT_OUTBOUND_LATENCY 0 /* in nsec */ @@ -51,8 +66,9 @@ 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. */ -#define DEFAULT_CLOCK_CLASS 248 +#define DEFAULT_CLOCK_CLASS 248 #define DEFAULT_CLOCK_CLASS__APPLICATION_SPECIFIC_TIME_SOURCE 13 +#define SLAVE_ONLY_CLOCK_CLASS 255 /* section 7.6.2.5, page 56: @@ -84,7 +100,6 @@ #define NO_ADJUST FALSE - /** \name Packet length Minimal length values for each message. If TLV used length could be higher.*/ @@ -99,6 +114,7 @@ #define PDELAY_RESP_LENGTH 54 #define PDELAY_RESP_FOLLOW_UP_LENGTH 54 #define MANAGEMENT_LENGTH 48 +#define TLV_LENGTH 6 /** \}*/ /*Enumeration defined in tables of the spec*/ @@ -124,12 +140,6 @@ /** - * \brief PTP State (Table 8 in the spec)*/ -enum { - INITIALIZING=1, FAULTY,DISABLED,LISTENING,PRE_MASTER,MASTER,PASSIVE,UNCALIBRATED,SLAVE -}; - -/** * \brief Delay mechanism (Table 9 in the spec)*/ enum { E2E=1,P2P=2,DELAY_DISABLED=0xFE @@ -152,10 +162,148 @@ }; /** + * \brief PTP Management Message managementId values (Table 40 in the spec) + */ +/* SLAVE_ONLY conflicts with another constant, so scope with MM_ */ +enum { + /* Applicable to all node types */ + MM_NULL_MANAGEMENT=0x0000, + MM_CLOCK_DESCRIPTION=0x0001, + MM_USER_DESCRIPTION=0x0002, + MM_SAVE_IN_NON_VOLATILE_STORAGE=0x0003, + MM_RESET_NON_VOLATILE_STORAGE=0x0004, + MM_INITIALIZE=0x0005, + MM_FAULT_LOG=0x0006, + MM_FAULT_LOG_RESET=0x0007, + + /* Reserved: 0x0008 - 0x1FFF */ + + /* Applicable to ordinary and boundary clocks */ + MM_DEFAULT_DATA_SET=0x2000, + MM_CURRENT_DATA_SET=0x2001, + MM_PARENT_DATA_SET=0x2002, + MM_TIME_PROPERTIES_DATA_SET=0x2003, + MM_PORT_DATA_SET=0x2004, + MM_PRIORITY1=0x2005, + MM_PRIORITY2=0x2006, + MM_DOMAIN=0x2007, + MM_SLAVE_ONLY=0x2008, + MM_LOG_ANNOUNCE_INTERVAL=0x2009, + MM_ANNOUNCE_RECEIPT_TIMEOUT=0x200A, + MM_LOG_SYNC_INTERVAL=0x200B, + MM_VERSION_NUMBER=0x200C, + MM_ENABLE_PORT=0x200D, + MM_DISABLE_PORT=0x200E, + MM_TIME=0x200F, + MM_CLOCK_ACCURACY=0x2010, + MM_UTC_PROPERTIES=0x2011, + MM_TRACEABILITY_PROPERTIES=0x2012, + MM_TIMESCALE_PROPERTIES=0x2013, + MM_UNICAST_NEGOTIATION_ENABLE=0x2014, + MM_PATH_TRACE_LIST=0x2015, + MM_PATH_TRACE_ENABLE=0x2016, + MM_GRANDMASTER_CLUSTER_TABLE=0x2017, + MM_UNICAST_MASTER_TABLE=0x2018, + MM_UNICAST_MASTER_MAX_TABLE_SIZE=0x2019, + MM_ACCEPTABLE_MASTER_TABLE=0x201A, + MM_ACCEPTABLE_MASTER_TABLE_ENABLED=0x201B, + MM_ACCEPTABLE_MASTER_MAX_TABLE_SIZE=0x201C, + MM_ALTERNATE_MASTER=0x201D, + MM_ALTERNATE_TIME_OFFSET_ENABLE=0x201E, + MM_ALTERNATE_TIME_OFFSET_NAME=0x201F, + MM_ALTERNATE_TIME_OFFSET_MAX_KEY=0x2020, + MM_ALTERNATE_TIME_OFFSET_PROPERTIES=0x2021, + + /* Reserved: 0x2022 - 0x3FFF */ + + /* Applicable to transparent clocks */ + MM_TRANSPARENT_CLOCK_DEFAULT_DATA_SET=0x4000, + MM_TRANSPARENT_CLOCK_PORT_DATA_SET=0x4001, + MM_PRIMARY_DOMAIN=0x4002, + + /* Reserved: 0x4003 - 0x5FFF */ + + /* Applicable to ordinary, boundary, and transparent clocks */ + MM_DELAY_MECHANISM=0x6000, + MM_LOG_MIN_PDELAY_REQ_INTERVAL=0x6001, + + /* Reserved: 0x6002 - 0xBFFF */ + /* Implementation-specific identifiers: 0xC000 - 0xDFFF */ + /* Assigned by alternate PTP profile: 0xE000 - 0xFFFE */ + /* Reserved: 0xFFFF */ +}; + +/** + * \brief MANAGEMENT MESSAGE INITIALIZE (Table 44 in the spec) + */ +#define INITIALIZE_EVENT 0x0 + +/** + * \brief MANAGEMENT ERROR STATUS managementErrorId (Table 72 in the spec) + */ +enum { + RESPONSE_TOO_BIG=0x0001, + NO_SUCH_ID=0x0002, + WRONG_LENGTH=0x0003, + WRONG_VALUE=0x0004, + NOT_SETABLE=0x0005, + NOT_SUPPORTED=0x0006, + GENERAL_ERROR=0xFFFE +}; + +/* + * \brief PTP tlvType values (Table 34 in the spec) + */ +enum { + /* Standard TLVs */ + TLV_MANAGEMENT=0x0001, + TLV_MANAGEMENT_ERROR_STATUS=0x0002, + TLV_ORGANIZATION_EXTENSION=0x0003, + /* Optional unicast message negotiation TLVs */ + TLV_REQUEST_UNICAST_TRANSMISSION=0x0004, + TLV_GRANT_UNICAST_TRANSMISSION=0x0005, + TLV_CANCEL_UNICAST_TRANSMISSION=0x0006, + TLV_ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION=0x0007, + /* Optional path trace mechanism TLV */ + TLV_PATH_TRACE=0x0008, + /* Optional alternate timescale TLV */ + ALTERNATE_TIME_OFFSET_INDICATOR=0x0009, + /*Security TLVs */ + AUTHENTICATION=0x2000, + AUTHENTICATION_CHALLENGE=0x2001, + SECURITY_ASSOCIATION_UPDATE=0x2002, + /* Cumulative frequency scale factor offset */ + CUM_FREQ_SCALE_FACTOR_OFFSET=0x2003 +}; + +/** + * \brief Management Message actions (Table 38 in the spec) + */ +enum { + GET=0, + SET, + RESPONSE, + COMMAND, + ACKNOWLEDGE +}; + +/** + * \brief flagField1 bit position values (Table 20 in the spec) + */ +enum { + LI61=0, + LI59, + UTCV, + PTPT, /* this is referred to as PTP in the spec but already defined above */ + TTRA, + FTRA +}; + +/** * \brief PTP states */ enum { - PTP_INITIALIZING=0, PTP_FAULTY, PTP_DISABLED, + PTP_INITIALIZING=1, PTP_FAULTY, PTP_DISABLED, PTP_LISTENING, PTP_PRE_MASTER, PTP_MASTER, PTP_PASSIVE, PTP_UNCALIBRATED, PTP_SLAVE }; Modified: trunk/src/datatypes.h =================================================================== --- trunk/src/datatypes.h 2012-03-07 19:14:59 UTC (rev 184) +++ trunk/src/datatypes.h 2012-03-21 15:53:08 UTC (rev 185) @@ -19,15 +19,17 @@ * \brief The TimeInterval type represents time intervals */ typedef struct { - Integer64 scaledNanoseconds; + /* see src/def/README for a note on this X-macro */ + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/timeInterval.def" } TimeInterval; /** * \brief The Timestamp type represents a positive time with respect to the epoch */ typedef struct { - UInteger48 secondsField; - UInteger32 nanosecondsField; + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/timestamp.def" } Timestamp; /** @@ -39,77 +41,68 @@ * \brief The PortIdentity identifies a PTP port. */ typedef struct { - ClockIdentity clockIdentity; - UInteger16 portNumber; + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/portIdentity.def" } PortIdentity; /** * \brief The PortAdress type represents the protocol address of a PTP port */ typedef struct { - Enumeration16 networkProtocol; - UInteger16 adressLength; - Octet* adressField; -} PortAdress; + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/portAddress.def" +} PortAddress; /** * \brief The ClockQuality represents the quality of a clock */ typedef struct { - UInteger8 clockClass; - Enumeration8 clockAccuracy; - UInteger16 offsetScaledLogVariance; + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/clockQuality.def" } ClockQuality; /** * \brief The TLV type represents TLV extension fields */ typedef struct { - Enumeration16 tlvType; - UInteger16 lengthField; - Octet* valueField; + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/tlv.def" } TLV; /** * \brief The PTPText data type is used to represent textual material in PTP messages */ typedef struct { - UInteger8 lengthField; - Octet* textField; + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/ptpText.def" } PTPText; /** * \brief The FaultRecord type is used to construct fault logs */ typedef struct { - UInteger16 faultRecordLength; - Timestamp faultTime; - Enumeration8 severityCode; - PTPText faultName; - PTPText faultValue; - PTPText faultDescription; + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/faultRecord.def" } FaultRecord; +/** +* \brief The PhysicalAddress type is used to represent a physical address + */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/physicalAddress.def" +} PhysicalAddress; + /** * \brief The common header for all PTP messages (Table 18 of the spec) */ /* Message header */ typedef struct { - Nibble transportSpecific; - Enumeration4 messageType; - UInteger4 versionPTP; - UInteger16 messageLength; - UInteger8 domainNumber; - Octet flagField[2]; - Integer64 correctionfield; - PortIdentity sourcePortIdentity; - UInteger16 sequenceId; - UInteger8 controlField; - Integer8 logMessageInterval; + #define OPERATE( name, size, type ) type name; + #include "def/message/header.def" } MsgHeader; - /** * \brief Announce message fields (Table 25 of the spec) */ @@ -194,20 +187,234 @@ char* tlv; }MsgSignaling; + /** + * \brief Management TLV message fields + */ +/* Management TLV Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/managementTLV.def" + Octet* dataField; +} ManagementTLV; + +/** + * \brief Management TLV Clock Description fields (Table 41 of the spec) + */ +/* Management TLV Clock Description Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/clockDescription.def" +} MMClockDescription; + +/** + * \brief Management TLV User Description fields (Table 43 of the spec) + */ +/* Management TLV User Description Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/userDescription.def" +} MMUserDescription; + +/** + * \brief Management TLV Initialize fields (Table 44 of the spec) + */ +/* Management TLV Initialize Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/initialize.def" +} MMInitialize; + +/** + * \brief Management TLV Default Data Set fields (Table 50 of the spec) + */ +/* Management TLV Default Data Set Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/defaultDataSet.def" +} MMDefaultDataSet; + +/** + * \brief Management TLV Current Data Set fields (Table 55 of the spec) + */ +/* Management TLV Current Data Set Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/currentDataSet.def" +} MMCurrentDataSet; + +/** + * \brief Management TLV Parent Data Set fields (Table 56 of the spec) + */ +/* Management TLV Parent Data Set Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/parentDataSet.def" +} MMParentDataSet; + +/** + * \brief Management TLV Time Properties Data Set fields (Table 57 of the spec) + */ +/* Management TLV Time Properties Data Set Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/timePropertiesDataSet.def" +} MMTimePropertiesDataSet; + +/** + * \brief Management TLV Port Data Set fields (Table 61 of the spec) + */ +/* Management TLV Port Data Set Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/portDataSet.def" +} MMPortDataSet; + +/** + * \brief Management TLV Priority1 fields (Table 51 of the spec) + */ +/* Management TLV Priority1 Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/priority1.def" +} MMPriority1; + +/** + * \brief Management TLV Priority2 fields (Table 52 of the spec) + */ +/* Management TLV Priority2 Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/priority2.def" +} MMPriority2; + +/** + * \brief Management TLV Domain fields (Table 53 of the spec) + */ +/* Management TLV Domain Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/domain.def" +} MMDomain; + +/** + * \brief Management TLV Slave Only fields (Table 54 of the spec) + */ +/* Management TLV Slave Only Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/slaveOnly.def" +} MMSlaveOnly; + +/** + * \brief Management TLV Log Announce Interval fields (Table 62 of the spec) + */ +/* Management TLV Log Announce Interval Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/logAnnounceInterval.def" +} MMLogAnnounceInterval; + +/** + * \brief Management TLV Announce Receipt Timeout fields (Table 63 of the spec) + */ +/* Management TLV Announce Receipt Timeout Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/announceReceiptTimeout.def" +} MMAnnounceReceiptTimeout; + +/** + * \brief Management TLV Log Sync Interval fields (Table 64 of the spec) + */ +/* Management TLV Log Sync Interval Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/logSyncInterval.def" +} MMLogSyncInterval; + +/** + * \brief Management TLV Version Number fields (Table 67 of the spec) + */ +/* Management TLV Version Number Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/versionNumber.def" +} MMVersionNumber; + +/** + * \brief Management TLV Time fields (Table 48 of the spec) + */ +/* Management TLV Time Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/time.def" +} MMTime; + +/** + * \brief Management TLV Clock Accuracy fields (Table 49 of the spec) + */ +/* Management TLV Clock Accuracy Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/clockAccuracy.def" +} MMClockAccuracy; + +/** + * \brief Management TLV UTC Properties fields (Table 58 of the spec) + */ +/* Management TLV UTC Properties Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/utcProperties.def" +} MMUtcProperties; + +/** + * \brief Management TLV Traceability Properties fields (Table 59 of the spec) + */ +/* Management TLV Traceability Properties Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/traceabilityProperties.def" +} MMTraceabilityProperties; + +/** + * \brief Management TLV Delay Mechanism fields (Table 65 of the spec) + */ +/* Management TLV Delay Mechanism Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/delayMechanism.def" +} MMDelayMechanism; + +/** + * \brief Management TLV Log Min Pdelay Req Interval fields (Table 66 of the spec) + */ +/* Management TLV Log Min Pdelay Req Interval Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/logMinPdelayReqInterval.def" +} MMLogMinPdelayReqInterval; + +/** + * \brief Management TLV Error Status fields (Table 71 of the spec) + */ +/* Management TLV Error Status Message */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/managementTLV/errorStatus.def" +} MMErrorStatus; + +/** * \brief Management message fields (Table 37 of the spec) */ /*management Message*/ typedef struct { - PortIdentity targetPortIdentity; - UInteger8 startingBoundaryHops; - UInteger8 boundaryHops; - Enumeration4 actionField; - char* tlv; + #define OPERATE( name, size, type ) type name; + #include "def/message/management.def" + ManagementTLV* tlv; }MsgManagement; - - /** * \brief Time structure to handle Linux time information */ @@ -225,7 +432,6 @@ Boolean expire; } IntervalTimer; - /** * \brief ForeignMasterRecord is used to manage foreign masters */ @@ -239,7 +445,6 @@ MsgHeader header; } ForeignMasterRecord; - /** * \struct PtpClock * \brief Main program data structure @@ -341,6 +546,7 @@ MsgSignaling signaling; } msgTmp; + MsgManagement outgoingManageTmp; Octet msgObuf[PACKET_SIZE]; Octet msgIbuf[PACKET_SIZE]; @@ -383,7 +589,6 @@ Boolean waitingForFollow; Boolean waitingForDelayResp; - offset_from_master_filter ofm_filt; one_way_delay_filter owd_filt; @@ -410,6 +615,9 @@ int waiting_for_first_delayresp; /* Just for information purposes */ Boolean startup_in_progress; + /* user description is max size + 1 to leave space for a null terminator */ + Octet user_description[USER_DESCRIPTION_MAX + 1]; + #ifdef PTP_EXPERIMENTAL Integer32 MasterAddr; // used for hybrid mode, when receiving announces Integer32 LastSlaveAddr; // used for hybrid mode, when receiving delayreqs Added: trunk/src/def/README =================================================================== --- trunk/src/def/README (rev 0) +++ trunk/src/def/README 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,11 @@ +This directory contains component macro .def files that are referenced by X-Macros in +the ptpd source code. + +The component macros are used to define message, derived data +types, and management TLV fields. + +The X-Macros are used to automatically generate most of +the code used to pack, unpack, and free ptp data fields. + +Documentation on how to use X-Macros can be found at: +http://en.wikibooks.org/wiki/C_Programming/Preprocessor#X-Macros Added: trunk/src/def/derivedData/clockQuality.def =================================================================== --- trunk/src/def/derivedData/clockQuality.def (rev 0) +++ trunk/src/def/derivedData/clockQuality.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec 5.3.7 ClockQuality */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( clockClass, 1, UInteger8 ) +OPERATE( clockAccuracy, 1, Enumeration8 ) +OPERATE( offsetScaledLogVariance, 2, UInteger16) + +#undef OPERATE Added: trunk/src/def/derivedData/faultRecord.def =================================================================== --- trunk/src/def/derivedData/faultRecord.def (rev 0) +++ trunk/src/def/derivedData/faultRecord.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,11 @@ +/* Spec 5.3.10 FaultRecord */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( faultRecordLength, 2, UInteger16) +OPERATE( faultTime, 10, Timestamp) +OPERATE( severityCode, 1, Enumeration8) +OPERATE( faultName, 1 + data->faultName.lengthField, PTPText) +OPERATE( faultValue, 1 + data->faultValue.lengthField, PTPText) +OPERATE( faultDescription, 1 + data->faultDescription.lengthField, PTPText) + +#undef OPERATE Added: trunk/src/def/derivedData/physicalAddress.def =================================================================== --- trunk/src/def/derivedData/physicalAddress.def (rev 0) +++ trunk/src/def/derivedData/physicalAddress.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,13 @@ +/* PhysicalAddress */ + +/* + * This is not a derived data type from the standard. + * Defining this type simplifies the implementation of + * the Management Clock Description message + */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( addressLength, 2, UInteger16) +OPERATE( addressField, data->addressLength, Octet*) + +#undef OPERATE Added: trunk/src/def/derivedData/portAddress.def =================================================================== --- trunk/src/def/derivedData/portAddress.def (rev 0) +++ trunk/src/def/derivedData/portAddress.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec 5.3.6 PortAddress */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( networkProtocol, 2, Enumeration16) +OPERATE( addressLength, 2, UInteger16) +OPERATE( addressField, data->addressLength, Octet*) + +#undef OPERATE Added: trunk/src/def/derivedData/portIdentity.def =================================================================== --- trunk/src/def/derivedData/portIdentity.def (rev 0) +++ trunk/src/def/derivedData/portIdentity.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec 5.3.5 PortIdentity */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( clockIdentity, CLOCK_IDENTITY_LENGTH, ClockIdentity) +OPERATE( portNumber, 2, UInteger16) + +#undef OPERATE Added: trunk/src/def/derivedData/ptpText.def =================================================================== --- trunk/src/def/derivedData/ptpText.def (rev 0) +++ trunk/src/def/derivedData/ptpText.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec 5.3.9 PTPText */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( lengthField, 1, UInteger8) +OPERATE( textField, data->lengthField, Octet*) + +#undef OPERATE Added: trunk/src/def/derivedData/timeInterval.def =================================================================== --- trunk/src/def/derivedData/timeInterval.def (rev 0) +++ trunk/src/def/derivedData/timeInterval.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,6 @@ +/* Spec 5.3.2 TimeInterval*/ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( scaledNanoseconds, 8, Integer64) + +#undef OPERATE Added: trunk/src/def/derivedData/timestamp.def =================================================================== --- trunk/src/def/derivedData/timestamp.def (rev 0) +++ trunk/src/def/derivedData/timestamp.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec 5.3.3 Timestamp */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( secondsField, 6, UInteger48) +OPERATE( nanosecondsField, 4, UInteger32) + +#undef OPERATE Added: trunk/src/def/derivedData/tlv.def =================================================================== --- trunk/src/def/derivedData/tlv.def (rev 0) +++ trunk/src/def/derivedData/tlv.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec 5.3.8 TLV */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( tlvType, 2, Enumeration16) +OPERATE( lengthField, 2, UInteger16) +OPERATE( valueField, data->lengthField, Octet*) + +#undef OPERATE Added: trunk/src/def/managementTLV/announceReceiptTimeout.def =================================================================== --- trunk/src/def/managementTLV/announceReceiptTimeout.def (rev 0) +++ trunk/src/def/managementTLV/announceReceiptTimeout.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 63 - ANNOUNCE_RECEIPT_TIMEOUT management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( announceReceiptTimeout, 1, UInteger8) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/clockAccuracy.def =================================================================== --- trunk/src/def/managementTLV/clockAccuracy.def (rev 0) +++ trunk/src/def/managementTLV/clockAccuracy.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 49 - CLOCK_ACCURACY management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( clockAccuracy, 1, Enumeration8) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/clockDescription.def =================================================================== --- trunk/src/def/managementTLV/clockDescription.def (rev 0) +++ trunk/src/def/managementTLV/clockDescription.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,35 @@ +/* Spec Table 41 - CLOCK_DESCRIPTION management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( clockType0, 1, Octet) +OPERATE( clockType1, 1, Octet) +OPERATE( physicalLayerProtocol, + 1 + data->physicalLayerProtocol.lengthField, + PTPText) +OPERATE( physicalAddress, + 2 + data->physicalAddress.addressLength, + PhysicalAddress) +OPERATE( protocolAddress, + 4 + data->protocolAddress.addressLength, + PortAddress) +OPERATE( manufacturerIdentity0, 1, Octet) +OPERATE( manufacturerIdentity1, 1, Octet) +OPERATE( manufacturerIdentity2, 1, Octet) +OPERATE( reserved, 1, Octet) +OPERATE( productDescription, + 1 + data->productDescription.lengthField, + PTPText) +OPERATE( revisionData, + 1 + data->revisionData.lengthField, + PTPText) +OPERATE( userDescription, + 1 + data->userDescription.lengthField, + PTPText) +OPERATE( profileIdentity0, 1, Octet) +OPERATE( profileIdentity1, 1, Octet) +OPERATE( profileIdentity2, 1, Octet) +OPERATE( profileIdentity3, 1, Octet) +OPERATE( profileIdentity4, 1, Octet) +OPERATE( profileIdentity5, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/currentDataSet.def =================================================================== --- trunk/src/def/managementTLV/currentDataSet.def (rev 0) +++ trunk/src/def/managementTLV/currentDataSet.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec Table 55 - CURRENT_DATA_SET management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( stepsRemoved, 2, UInteger16) +OPERATE( offsetFromMaster, 8, TimeInterval) +OPERATE( meanPathDelay, 8, TimeInterval) + +#undef OPERATE Added: trunk/src/def/managementTLV/defaultDataSet.def =================================================================== --- trunk/src/def/managementTLV/defaultDataSet.def (rev 0) +++ trunk/src/def/managementTLV/defaultDataSet.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,14 @@ +/* Spec Table 50 - DEFAULT_DATA_SET management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( so_tsc, 1, Octet) +OPERATE( reserved0, 1, Octet) +OPERATE( numberPorts, 2, UInteger16) +OPERATE( priority1, 1, UInteger8) +OPERATE( clockQuality, 4, ClockQuality) +OPERATE( priority2, 1, UInteger8) +OPERATE( clockIdentity, 8, ClockIdentity) +OPERATE( domainNumber, 1, UInteger8) +OPERATE( reserved1, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/delayMechanism.def =================================================================== --- trunk/src/def/managementTLV/delayMechanism.def (rev 0) +++ trunk/src/def/managementTLV/delayMechanism.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 65 - DELAY_MECHANISM management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( delayMechanism, 1, Enumeration8) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/domain.def =================================================================== --- trunk/src/def/managementTLV/domain.def (rev 0) +++ trunk/src/def/managementTLV/domain.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 53 - DOMAIN management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( domainNumber, 1, UInteger8) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/errorStatus.def =================================================================== --- trunk/src/def/managementTLV/errorStatus.def (rev 0) +++ trunk/src/def/managementTLV/errorStatus.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec Table 71 - MANAGEMENT_ERROR_STATUS TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( managementId, 2, Enumeration16) +OPERATE( reserved, 4, UInteger32) +OPERATE( displayData, 1 + data->displayData.lengthField, PTPText) + +#undef OPERATE Added: trunk/src/def/managementTLV/initialize.def =================================================================== --- trunk/src/def/managementTLV/initialize.def (rev 0) +++ trunk/src/def/managementTLV/initialize.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,6 @@ +/* Spec Table 43 - USER_DESCRIPTION management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( initializeKey, 2, UInteger16) + +#undef OPERATE Added: trunk/src/def/managementTLV/logAnnounceInterval.def =================================================================== --- trunk/src/def/managementTLV/logAnnounceInterval.def (rev 0) +++ trunk/src/def/managementTLV/logAnnounceInterval.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 62 - LOG_ANNOUNCE_INTERVAL management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( logAnnounceInterval, 1, Integer8) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/logMinPdelayReqInterval.def =================================================================== --- trunk/src/def/managementTLV/logMinPdelayReqInterval.def (rev 0) +++ trunk/src/def/managementTLV/logMinPdelayReqInterval.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 66 - LOG_MIN_PDELAY_REQ_INTERVAL management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( logMinPdelayReqInterval, 1, Integer8) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/logSyncInterval.def =================================================================== --- trunk/src/def/managementTLV/logSyncInterval.def (rev 0) +++ trunk/src/def/managementTLV/logSyncInterval.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 64 - LOG_SYNC_INTERVAL management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( logSyncInterval, 1, Integer8) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/managementTLV.def =================================================================== --- trunk/src/def/managementTLV/managementTLV.def (rev 0) +++ trunk/src/def/managementTLV/managementTLV.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec Table 39 - Management TLV fields */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( tlvType, 2, Enumeration16) +OPERATE( lengthField, 2, UInteger16) +OPERATE( managementId, 2, Enumeration16) + +#undef OPERATE Added: trunk/src/def/managementTLV/parentDataSet.def =================================================================== --- trunk/src/def/managementTLV/parentDataSet.def (rev 0) +++ trunk/src/def/managementTLV/parentDataSet.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,14 @@ +/* Spec Table 56 - PARENT_DATA_SET management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( parentPortIdentity, 10, PortIdentity) +OPERATE( PS, 1, Boolean) +OPERATE( reserved, 1, Octet) +OPERATE( observedParentOffsetScaledLogVariance, 2, UInteger16) +OPERATE( observedParentClockPhaseChangeRate, 4, Integer32) +OPERATE( grandmasterPriority1, 1, UInteger8) +OPERATE( grandmasterClockQuality, 4, ClockQuality) +OPERATE( grandmasterPriority2, 1, UInteger8) +OPERATE( grandmasterIdentity, 8, ClockIdentity) + +#undef OPERATE Added: trunk/src/def/managementTLV/portDataSet.def =================================================================== --- trunk/src/def/managementTLV/portDataSet.def (rev 0) +++ trunk/src/def/managementTLV/portDataSet.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,16 @@ +/* Spec Table 61 - PORT_DATA_SET management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( portIdentity, 10, PortIdentity) +OPERATE( portState, 1, Enumeration8) +OPERATE( logMinDelayReqInterval, 1, Integer8) +OPERATE( peerMeanPathDelay, 8, TimeInterval) +OPERATE( logAnnounceInterval, 1, Integer8) +OPERATE( announceReceiptTimeout, 1, UInteger8) +OPERATE( logSyncInterval, 1, Integer8) +OPERATE( delayMechanism, 1, Enumeration8) +OPERATE( logMinPdelayReqInterval, 1, Integer8) +OPERATE( reserved, 0, NibbleUpper) +OPERATE( versionNumber, 1, UInteger4Lower) + +#undef OPERATE Added: trunk/src/def/managementTLV/priority1.def =================================================================== --- trunk/src/def/managementTLV/priority1.def (rev 0) +++ trunk/src/def/managementTLV/priority1.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 51 - PRIORITY1 management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( priority1, 1, UInteger8) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/priority2.def =================================================================== --- trunk/src/def/managementTLV/priority2.def (rev 0) +++ trunk/src/def/managementTLV/priority2.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 52 - PRIORITY2 management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( priority2, 1, UInteger8) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/slaveOnly.def =================================================================== --- trunk/src/def/managementTLV/slaveOnly.def (rev 0) +++ trunk/src/def/managementTLV/slaveOnly.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 54 - SLAVE_ONLY management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( so, 1, Boolean) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/time.def =================================================================== --- trunk/src/def/managementTLV/time.def (rev 0) +++ trunk/src/def/managementTLV/time.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,6 @@ +/* Spec Table 48 - TIME management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( currentTime, 10, Timestamp) + +#undef OPERATE Added: trunk/src/def/managementTLV/timePropertiesDataSet.def =================================================================== --- trunk/src/def/managementTLV/timePropertiesDataSet.def (rev 0) +++ trunk/src/def/managementTLV/timePropertiesDataSet.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec Table 57 - TIME_PROPERTIES_DATA_SET management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( currentUtcOffset, 2, Integer16) +OPERATE( ftra_ttra_ptp_utcv_li59_li61, 1, Octet) +OPERATE( timeSource, 1, Enumeration8) + +#undef OPERATE Added: trunk/src/def/managementTLV/traceabilityProperties.def =================================================================== --- trunk/src/def/managementTLV/traceabilityProperties.def (rev 0) +++ trunk/src/def/managementTLV/traceabilityProperties.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,7 @@ +/* Spec Table 59 - TRACEABILITY_PROPERTIES management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( ftra_ttra, 1, Octet) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/userDescription.def =================================================================== --- trunk/src/def/managementTLV/userDescription.def (rev 0) +++ trunk/src/def/managementTLV/userDescription.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec Table 43 - USER_DESCRIPTION management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( userDescription, + 1 + data->userDescription.lengthField, + PTPText) + +#undef OPERATE Added: trunk/src/def/managementTLV/utcProperties.def =================================================================== --- trunk/src/def/managementTLV/utcProperties.def (rev 0) +++ trunk/src/def/managementTLV/utcProperties.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec Table 58 - UTC_PROPERTIES management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( currentUtcOffset, 2, Integer16) +OPERATE( utcv_li59_li61, 1, Octet) +OPERATE( reserved, 1, Octet) + +#undef OPERATE Added: trunk/src/def/managementTLV/versionNumber.def =================================================================== --- trunk/src/def/managementTLV/versionNumber.def (rev 0) +++ trunk/src/def/managementTLV/versionNumber.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,8 @@ +/* Spec Table 67 - VERSION_NUMBER management TLV data field */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( reserved0, 0, NibbleUpper) +OPERATE( versionNumber, 1, UInteger4Lower) +OPERATE( reserved1, 1, Octet) + +#undef OPERATE Added: trunk/src/def/message/header.def =================================================================== --- trunk/src/def/message/header.def (rev 0) +++ trunk/src/def/message/header.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,20 @@ +/* Spec Table 18 - Common message header */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( transportSpecific, 0, NibbleUpper) +OPERATE( messageType, 1, Enumeration4Lower) +OPERATE( reserved0, 0, NibbleUpper) +OPERATE( versionPTP, 1, UInteger4Lower) +OPERATE( messageLength, 2, UInteger16) +OPERATE( domainNumber, 1, UInteger8) +OPERATE( reserved1, 1, Octet) +OPERATE( flagField0, 1, Octet) +OPERATE( flagField1, 1, Octet) +OPERATE( correctionField, 8, Integer64) +OPERATE( reserved2, 4, UInteger32) +OPERATE( sourcePortIdentity, 10, PortIdentity) +OPERATE( sequenceId, 2, UInteger16) +OPERATE( controlField, 1, UInteger8) +OPERATE( logMessageInterval, 1, Integer8) + +#undef OPERATE Added: trunk/src/def/message/management.def =================================================================== --- trunk/src/def/message/management.def (rev 0) +++ trunk/src/def/message/management.def 2012-03-21 15:53:08 UTC (rev 185) @@ -0,0 +1,12 @@ +/* Spec Table 37 - Management message fields */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( header, 34, MsgHeader) +OPERATE( targetPortIdentity, 10, PortIdentity) +OPERATE( startingBoundaryHops, 1, UInteger8) +OPERATE( boundaryHops, 1, UInteger8) +OPERATE( reserved0, 0, NibbleUpper) +OPERATE( actionField, 1, Enumeration4Lower) +OPERATE( reserved1, 1, Octet) + +#undef OPERATE Modified: trunk/src/dep/datatypes_dep.h =================================================================== --- trunk/src/dep/datatypes_dep.h 2012-03-07 19:14:59 UTC (rev 184) +++ trunk/src/dep/datatypes_dep.h 2012-03-21 15:53:08 UTC (rev 185) @@ -18,8 +18,14 @@ typedef unsigned short Enumeration16; typedef unsigned char Enumeration8; typedef unsigned char Enumeration4; +typedef unsigned char Enumeration4Upper; +typedef unsigned char Enumeration4Lower; typedef unsigned char UInteger4; +typedef unsigned char UInteger4Upper; +typedef unsigned char UInteger4Lower; typedef unsigned char Nibble; +typedef unsigned char NibbleUpper; +typedef unsigned char NibbleLower; /** * \brief Implementation specific of UInteger48 type Modified: trunk/src/dep/msg.c =================================================================== --- trunk/src/dep/msg.c 2012-03-07 19:14:59 UTC (rev 184) +++ trunk/src/dep/msg.c 2012-03-21 15:53:08 UTC (rev 185) @@ -1,6 +1,20 @@ /*- - * Copyright (c) 2009-2011 George V. Neville-Neil, Steven Kreuzer, - * Martin Burnicki, Gael Mace, Alexandre Van Kempen + * Copyright (c) 2011-2012 George V. Neville-Neil, + * Steven Kreuzer, + * Martin Burnicki, + * Jan Breuer, + * Gael Mace, + * Alexandre Van Kempen, + * Inaqui Delgado, + * Rick Ratzel, + * National Instruments. + * Copyright (c) 2009-2010 George V. Neville-Neil, + * Steven Kreuzer, + * Martin Burnicki, + * Jan Breuer, + * Gael Mace, + * Alexandre Van Kempen + * * Copyright (c) 2005-2008 Kendall Correll, Aidan Williams * * All Rights Reserved @@ -31,9 +45,9 @@ * @file msg.c * @author George Neville-Neil <gn...@ne...> * @date Tue Jul 20 16:17:05 2010 - * + * * @brief Functions to pack and unpack messages. - * + * * See spec annex d */ @@ -43,8 +57,1227 @@ extern RunTimeOpts rtOpts; #endif +#define PACK_SIMPLE( type ) \ +void pack##type( void* from, void* to ) \ +{ \ + *(type *)to = *(type *)from; \ +} \ +void unpack##type( void* from, void* to, PtpClock *ptpClock ) \ +{ \ + pack##type( from, to ); \ +} + +#define PACK_ENDIAN( type, size ) \ +void pack##type( void* from, void* to ) \ +{ \ + *(type *)to = flip##size( *(type *)from ); \ +} \ +void unpack##type( void* from, void* to, PtpClock *ptpClock ) \ +{ \ + pack##type( from, to ); \ +} + +#define PACK_LOWER_AND_UPPER( type ) \ +void pack##type##Lower( void* from, void* to ) \ +{ \ + *(char *)to = *(char *)to & 0xF0; \ + *(char *)to = *(char *)to | *(type *)from; \ +} \ +\ +void pack##type##Upper( void* from, void* to ) \ +{ \ + *(char *)to = *(char *)to & 0x0F; \ + *(char *)to = *(char *)to | (*(type *)from << 4); \ +} \ +\ +void unpack##type##Lower( void* from, void* to, PtpClock *ptpClock ) \ +{ \ + *(type *)to = *(char *)from & 0x0F; \ +} \ +\ +void unpack##type##Upper( void* from, void* to, PtpClock *ptpClock ) \ +{ \ + *(type *)to = *(char *)from & 0xF0; \ +} + +PACK_SIMPLE( Boolean ) +PACK_SIMPLE( UInteger8 ) +PACK_SIMPLE( Octet ) +PACK_SIMPLE( Enumeration8 ) +PACK_SIMPLE( Integer8 ) + +PACK_ENDIAN( Enumeration16, 16 ) +PACK_ENDIAN( Integer16, 16 ) +PACK_ENDIAN( UInteger16, 16 ) +PACK_ENDIAN( Integer32, 32 ) +PACK_ENDIAN( UInteger32, 32 ) + +PACK_LOWER_AND_UPPER( Enumeration4 ) +PACK_LOWER_AND_UPPER( UInteger4 ) +PACK_LOWER_AND_UPPER( Nibble ) + +/* The free function is intentionally empty. However, this simplifies + * the procedure to deallocate complex data types + */ +#define FREE( type ) \ +void free##type( void* x) \ +{} + +FREE ( Boolean ) +FREE ( UInteger8 ) +FREE ( Octet ) +FREE ( Enumeration8 ) +FREE ( Integer8 ) +FREE ( Enumeration16 ) +FREE ( Integer16 ) +FREE ( UInteger16 ) +FREE ( Integer32 ) +FREE ( UInteger32 ) +FREE ( Enumeration4 ) +FREE ( UInteger4 ) +FREE ( Nibble ) + +void +unpackUInteger48( void *buf, void *i, PtpClock *ptpClock) +{ + unpackUInteger32(buf, &((UInteger48*)i)->lsb, ptpClock); + unpackUInteger16(buf + 4, &((UInteger48*)i)->msb, ptpClock); +} + +void +packUInteger48( void *i, void *buf) +{ + packUInteger32(&((UInteger48*)i)->lsb, buf); + packUInteger16(&((UInteger48*)i)->msb, buf + 4); +} + +void +unpackInteger64( void *buf, void *i, PtpClock *ptpClock) +{ + unpackUInteger32(buf, &((Integer64*)i)->lsb, ptpClock); + unpackInteger32(buf + 4, &((Integer64*)i)->msb, ptpClock); +} + +void +packInteger64( void* i, void *buf ) +{ + packUInteger32(&((Integer64*)i)->lsb, buf); + packInteger32(&((Integer64*)i)->msb, buf + 4); +} + +/* NOTE: the unpack functions for management messages can probably be refactored into a macro */ +void +unpackMMSlaveOnly( Octet *buf, MsgManagement* m, PtpClock* ptpClock) +{ + int offset = 0; + XMALLOC(m->tlv->dataField, sizeof(MMSlaveOnly)); + MMSlaveOnly* data = (MMSlaveOnly*)m->tlv->dataField; + /* see src/def/README for a note on this X-macro */ + #define OPERATE( name, size, type ) \ + unpack##type( buf + MANAGEMENT_LENGTH + TLV_LENGTH + offset,\ + &data->name, ptpClock ); \ + offset = offset + size; + #include "../def/managementTLV/slaveOnly.def" + + #ifdef PTPD_DBG + mMSlaveOnly_display(data, ptpClock); + #endif /* PTPD_DBG */ +} + +/* NOTE: the pack functions for management messsages can probably be refactored into a macro */ +UInteger16 +packMMSlaveOnly( MsgManagement* m, Octet *buf) +{ + int offset = 0; + MMSlaveOnly* data = (MMSlaveOnly*)m->tlv->dataField; + #define OPERATE( name, size, type ) \ + pack##type( &data->name,\ + buf + MANAGEMENT_LENGTH + TLV_LENGTH + offset ); \ + offset = offset + size; + #include "../def/managementTLV/slaveOnly.def" + + /* return length */ + return offset; +} + +void +unpackMMClockDescription( Octet *buf, MsgManagement* m, PtpClock* ptpClock) +{ + int offset = 0; + XMALLOC(m->tlv->dataField, sizeof(MMClockDescription)); + MMClockDescription* data = (MMClockDescription*)m->tlv->dataField; + memset(data, 0, sizeof(MMClockDescription)); + #define OPERATE( name, size, type ) \ + unpack##type( buf + MANAGEMENT_LENGTH + TLV_LENGTH + offset,\ + &data->name, ptpClock ); \ + offset = offset + size; + #include "../def/managementTLV/clockDescription.def" + + #ifdef PTPD_DBG + mMClockDescription_display(data, ptpClock); + #endif /* PTPD_DBG */ +} + +UInteger16 +packMMClockDescription( MsgManagement* m, Octet *buf) +{ + int offset = 0; + Octet pad = 0; + MMClockDescription* data = (MMClockDescription*)m->tlv->dataField; + data->reserved = 0; + #define OPERATE( name, size, type ) \ + pack##type( &data->name,\ + buf + MANAGEMENT_LENGTH + TLV_LENGTH + offset); \ + offset = offset + size; + #include "../def/managementTLV/clockDescription.def" + + /* is the TLV length odd? TLV must be even according to Spec 5.3.8 */ + if(offset % 2) { + /* add pad of 1 according to Table 41 to make TLV length even */ + packOctet(&pad, buf + MANAGEMENT_LENGTH + TLV_LENGTH + offset); + offset = offset + 1; + } + + /* return length */ + return offset; +} + +void +freeMMClockDescription( MMClockDescription* data) +{ + #define OPERATE( name, size, type ) \ + free##type( &data->name); + #include "../def/managementTLV/clockDescription.def" +} + +void +unpackMMUserDescription( Octet *buf, MsgManagement* m, PtpClock* ptpClock) +{ + int offset = 0; + XMALLOC(m->tlv->dataField, sizeof(MMUserDescription)); + MMUserDescription* data = (MMUserDescription*)m->tlv->dataField; + memset(data, 0, sizeof(MMUserDescription)); + #define OPERATE( name, size, type ) \ + unpack##type( buf + MANAGEMENT_LENGTH + TLV_LENGTH + offset,\ + &data->name, ptpClock ); \ + offset = offset + size; + #include "../def/managementTLV/userDescription.def" + + #ifdef PTPD_DBG + /* mMUserDescription_display(data, ptpClock); */ + #endif /* PTPD_DBG */ +} + +UInteger16 +packMMUserDescription( MsgManagement* m, Octet *buf) +{ + int offset = 0; + Octet pad = 0; + MMUserDescription* data = (MMUserDescription*)m->tlv->dataFie... [truncated message content] |
From: <skr...@us...> - 2012-07-05 18:18:59
|
Revision: 239 http://ptpd.svn.sourceforge.net/ptpd/?rev=239&view=rev Author: skreuzer Date: 2012-07-05 18:18:51 +0000 (Thu, 05 Jul 2012) Log Message: ----------- Add SNMP suppport Currently Supported Tables: - ptpbaseSystemTable - ptpbaseSystemDomainTable - ptpbaseClockCurrentDSTable - ptpbaseClockParentDSTable - ptpbaseClockDefaultDSTable - ptpbaseClockTimePropertiesDSTable - ptpbaseClockPortTable - ptpbaseClockPortDSTable - ptpbaseClockPortRunningTable Submitted by: Vincent Bernat <be...@lu...> Reviewed by: skreuzer@FreeBSD.org, gnn@FreeBSD.org Modified Paths: -------------- trunk/src/Makefile trunk/src/arith.c trunk/src/dep/datatypes_dep.h trunk/src/dep/net.c trunk/src/dep/ptpd_dep.h trunk/src/dep/startup.c Added Paths: ----------- trunk/doc/PTPBASE-MIB trunk/doc/draft-ietf-tictoc-ptp-mib-01.txt trunk/src/dep/snmp.c Added: trunk/doc/PTPBASE-MIB =================================================================== --- trunk/doc/PTPBASE-MIB (rev 0) +++ trunk/doc/PTPBASE-MIB 2012-07-05 18:18:51 UTC (rev 239) @@ -0,0 +1,2928 @@ +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; + + +ptpbaseMIB MODULE-IDENTITY + LAST-UPDATED "201201230000Z" + ORGANIZATION "TICTOC Working Group" + CONTACT-INFO + "WG Email: ti...@ie... + + Vinay Shankarkumar + Cisco Systems, + Email: vi...@ci... + + Laurent Montini, + Cisco Systems, + Email: lmo...@ci... + + Tim Frost, + Symmetricom Inc., + Email: tf...@sy... + + Greg Dowd, + Symmetricom Inc., + Email: gd...@sy..." + + + DESCRIPTION + "The MIB module for 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. + + 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 + + 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. + + 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. + + + 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 + + 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. + + + 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. + + 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 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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 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 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. + + Requestor: + The port implementing the peer-to-peer delay mechanism that + initiates the mechanism by sending a Pdelay_Req message. + + Responder: + + 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. + + 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. + + 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. + + 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. + + 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. + + 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 + + + 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 | + +-----------+ +-----------+ + + Grandmaster + + 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) + + 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 | + +----------------------+ + + + The MIB refers to the sections of [IEEE 1588-2008]." + + -- revision log + + -- ::= { mib-2 XXX } + ::= { enterprises 39178 100 2 } -- Temporary assignment under IMSCO OID + + + +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. + + 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" + + 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: + + 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]. + + 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." + + 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]. + + 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) + + +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]. + + 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) + } + +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) + +ClockPortNumber ::= TEXTUAL-CONVENTION + 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) + +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 + ----------------------------------------------------------- + + 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) + } + +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." + + + 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]. + + The following values are not represented in the enumerated + values. + + 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." + + 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]. + + 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 + + the domain. + 53-57 Reserved. + 58 Degradation alternative A for a clock of + clockClass 14 that is not within holdover + specification. A clock of clockClass 58 shall + not be a slave to another clock in the domain. + 59-67 Reserved. + 68-122 For use by alternate PTP profiles. + 123-127 Reserved. + 128-132 Reserved. + 133-170 For use by alternate PTP profiles. + 171-186 Reserved. + + 187 Degradation alternative B for a clock of + clockClass 7 that is not within holdover + specification. A clock of clockClass 187 may + be a slave to another clock in the domain. + 188-192 Reserved. + 193 Degradation alternative B for a clock of + clockClass 14 that is not within holdover + specification. A clock of clockClass 193 may + be a slave to another clock in the domain. + 194-215 Reserved. + 216-232 For use by alternate PTP profiles. + 233-247 Reserved. + 248 Default. This clockClass shall be used if + none of the other clockClass definitions apply. + 249-250 Reserved. + 251 Reserved for version 1 compatibility; see Clause 18. + 252-254 Reserved. + 255 Shall be the clockClass of a slave-only clock; see + 9.2.2." + + REFERENCE "Section 5.3.7, 7.6.2.4 and Table 5 of + [IEEE 1588-2008]." + SYNTAX Unsigned32 (0..255) + +ClockRoleType ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "The Clock Role. The protocol generates a Master Slave + relationship among the clocks in the system. + + Clock Role Value Description + -------------------------------------------------------------- + Master clock 1 A clock that is the source of + time to which all other clocks on + that path synchronize. + + + Slave clock 2 A clock which synchronizes to + another clock (master)." + SYNTAX INTEGER { + master(1), + slave(2) + } + +ClockStateType ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "The clock state returned by PTP engine. + + Clock State Value Description + -------------------------------------------------------------- + Freerun state 1 Applies to a slave device that is not + locked to a master. This is the initial + state a slave starts out with when it + is not getting any PTP packets from the + master or because of some other input + error (erroneous packets, etc). + + Holdover state 2 In this state the slave device is + locked to a master but communication + with the master is lost or the + timestamps in the ptp packets are + incorrect. But since the slave was + locked to the master, it can run with + the same accuracy for sometime. The + slave can continue to operate in this + state for some time. If communication + with the master is not restored for a + while, the device is moved to the + FREERUN state. + + Acquiring state 3 The slave device is receiving packets + from a master and is trying to acquire + a lock. + + Freq_locked state 4 Slave device is locked to the Master + with respect to frequency, but not phase + aligned + + Phase_aligned state 5 Locked to the master with respect to + frequency and phase." + SYNTAX INTEGER { + freerun(1), + holdover(2), + acquiring(3), + frequencyLocked(4), + + phaseAligned(5) + } + +ClockTimeSourceType ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "The ClockQuality as specified in section 5.3.7, 7.6.2.6 and + Table 7 of [IEEE 1588-2008]. + + The following values are not represented in the enumerated + values. + + 0xF0-0xFE For use by alternate PTP profiles + 0xFF 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." + + REFERENCE "Section 5.3.7, 7.6.2.6 and Table 7 of + [IEEE 1588-2008]." + SYNTAX INTEGER { + atomicClock(16), -- 0x10 + gps(32), -- 0x20 + terrestrialRadio(48), -- 0x22 + ptp(64), -- 0x40 + ntp(80), -- 0x50 + handSet(96), -- 0x60 + other(144), -- 0x90 + internalOsillator(160) -- 0xA0 + } + +ClockTimeInterval ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "This textual convention corresponds to the TimeInterval + structure indicated in section 5.3.2 of [IEEE 1588-2008]. + It will be presented in the form of a character array. + + The TimeInterval type represents time intervals. + + struct TimeInterval + { + Integer64 scaledNanoseconds; + }; + + The scaledNanoseconds member is the time interval expressed in + units of nanoseconds and multiplied by 2**16. + + + Positive or negative time intervals outside the maximum range + of this data type shall be encoded as the largest positive and + negative values of the data type, respectively. + + For example, 2.5 ns is expressed as 0000 0000 0002 8000 in + Base16." + + REFERENCE + "Section 5.3.2 and setion 7.7.2.1 Timer interval + specification of [IEEE 1588-2008]" + SYNTAX OCTET STRING (SIZE (1..255)) + +ClockTxModeType ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "Transmission mode. + + unicast. Using unicast communication channel. + + multicast. Using Multicast communication channel. + + multicast-mix. Using multicast-unicast communication channel" + SYNTAX INTEGER { + unicast(1), + multicast(2), + multicastmix(3) + } + +ClockType ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "The clock types as defined in the MIB module description." + + REFERENCE "Section 6.5.1 of [IEEE 1588-2008]." + SYNTAX INTEGER { + ordinaryClock(1), + boundaryClock(2), + transparentClock(3), + boundaryNode(4) + } +ptpbaseMIBNotifs OBJECT IDENTIFIER + ::= { ptpbaseMIB 0 } + +ptpbaseMIBObjects OBJECT IDENTIFIER + ::= { ptpbaseMIB 1 } + +ptpbaseMIBConformance OBJECT IDENTIFIER + ::= { ptpbaseMIB 2 } + + +ptpbaseMIBSystemInfo OBJECT IDENTIFIER + ::= { ptpbaseMIBObjects 1 } + +-- Conformance Information Definition + +ptpbaseMIBCompliances OBJECT IDENTIFIER + ::= { ptpbaseMIBConformance 1 } + +ptpbaseMIBGroups OBJECT IDENTIFIER + ::= { ptpbaseMIBConformance 2 } + + +ptpbaseMIBCompliances1 MODULE-COMPLIANCE + STATUS current + DESCRIPTION + "Compliance statement for agents that provide read-only support + for PTPBASE-MIB. Such devices can only be monitored using this + MIB module. + + The Module is implemented with support for read-only. In other + words, only monitoring is available by implementing this + MODULE-COMPLIANCE." + MODULE -- this module + MANDATORY-GROUPS { ptpbaseMIBSystemInfoGroup } + ::= { ptpbaseMIBCompliances 1 } + +ptpbaseMIBCompliances2 MODULE-COMPLIANCE + STATUS current + DESCRIPTION + "Compliance statement for agents that provide read-only support + for PTPBASE-MIB. Such devices can only be monitored using this + MIB module. + + The Module is implemented with support for read-only. In other + words, only monitoring is available by implementing this + MODULE-COMPLIANCE." + MODULE -- this module + MANDATORY-GROUPS { + ptpbaseMIBClockCurrentDSGroup, + ptpbaseMIBClockParentDSGroup, + ptpbaseMIBClockDefaultDSGroup, + ptpbaseMIBClockRunningGroup, + ptpbaseMIBClockTimepropertiesGroup + } + ::= { ptpbaseMIBCompliances 2 } + +ptpbaseMIBCompliances3 MODULE-COMPLIANCE + STATUS current + DESCRIPTION + + "Compliance statement for agents that provide read-only support + for PTPBASE-MIB. Such devices can only be monitored using this + MIB module. + + The Module is implemented with support for read-only. In other + words, only monitoring is available by implementing this + MODULE-COMPLIANCE." + MODULE -- this module + MANDATORY-GROUPS { + ptpbaseMIBClockPortGroup, + ptpbaseMIBClockPortDSGroup, + ptpbaseMIBClockPortRunningGroup, + ptpbaseMIBClockPortAssociateGroup + } + ::= { ptpbaseMIBCompliances 3 } + +ptpbaseMIBCompliances4 MODULE-COMPLIANCE + STATUS current + DESCRIPTION + "Compliance statement for agents that provide read-only support + for PTPBASE-MIB. Such devices can only be monitored using this + MIB module. + + The Module is implemented with support for read-only. In other + words, only monitoring is available by implementing this + MODULE-COMPLIANCE." + MODULE -- this module + MANDATORY-GROUPS { + ptpbaseMIBClockTranparentDSGroup, + ptpbaseMIBClockPortTransDSGroup + } + ::= { ptpbaseMIBCompliances 4 } + +ptpbaseMIBSystemInfoGroup OBJECT-GROUP + OBJECTS { + ptpbaseSystemDomainTotals, + ptpDomainClockPortsTotal, + ptpbaseSystemProfile + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing system-wide + information" + ::= { ptpbaseMIBGroups 1 } + +ptpbaseMIBClockCurrentDSGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockCurrentDSStepsRemoved, + ptpbaseClockCurrentDSOffsetFromMaster, + + ptpbaseClockCurrentDSMeanPathDelay + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing PTP Current Dataset + information" + ::= { ptpbaseMIBGroups 2 } + +ptpbaseMIBClockParentDSGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockParentDSParentPortIdentity, + ptpbaseClockParentDSParentStats, + ptpbaseClockParentDSOffset, + ptpbaseClockParentDSClockPhChRate, + ptpbaseClockParentDSGMClockIdentity, + ptpbaseClockParentDSGMClockPriority1, + ptpbaseClockParentDSGMClockPriority2, + ptpbaseClockParentDSGMClockQualityClass, + ptpbaseClockParentDSGMClockQualityAccuracy, + ptpbaseClockParentDSGMClockQualityOffset + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing PTP Parent Dataset + information" + ::= { ptpbaseMIBGroups 3 } + +ptpbaseMIBClockDefaultDSGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockDefaultDSTwoStepFlag, + ptpbaseClockDefaultDSClockIdentity, + ptpbaseClockDefaultDSPriority1, + ptpbaseClockDefaultDSPriority2, + ptpbaseClockDefaultDSSlaveOnly, + ptpbaseClockDefaultDSQualityClass, + ptpbaseClockDefaultDSQualityAccuracy, + ptpbaseClockDefaultDSQualityOffset + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing PTP Default Dataset + information" + ::= { ptpbaseMIBGroups 4 } + +ptpbaseMIBClockRunningGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockRunningState, + ptpbaseClockRunningPacketsSent, + ptpbaseClockRunningPacketsReceived + + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing PTP running state + information" + ::= { ptpbaseMIBGroups 5 } + +ptpbaseMIBClockTimepropertiesGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockTimePropertiesDSCurrentUTCOffsetValid, + ptpbaseClockTimePropertiesDSCurrentUTCOffset, + ptpbaseClockTimePropertiesDSLeap59, + ptpbaseClockTimePropertiesDSLeap61, + ptpbaseClockTimePropertiesDSTimeTraceable, + ptpbaseClockTimePropertiesDSFreqTraceable, + ptpbaseClockTimePropertiesDSPTPTimescale, + ptpbaseClockTimePropertiesDSSource + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing PTP Time Properties + information" + ::= { ptpbaseMIBGroups 6 } + +ptpbaseMIBClockTranparentDSGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockTransDefaultDSClockIdentity, + ptpbaseClockTransDefaultDSNumOfPorts, + ptpbaseClockTransDefaultDSDelay, + ptpbaseClockTransDefaultDSPrimaryDomain + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing PTP Transparent + Dataset + information" + ::= { ptpbaseMIBGroups 7 } + +ptpbaseMIBClockPortGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockPortName, + ptpbaseClockPortSyncOneStep, + ptpbaseClockPortCurrentPeerAddress, + ptpbaseClockPortNumOfAssociatedPorts, + ptpbaseClockPortCurrentPeerAddressType, + ptpbaseClockPortRole + } + STATUS current + DESCRIPTION + + "Group which aggregates objects describing information for a + given PTP Port." + ::= { ptpbaseMIBGroups 8 } + +ptpbaseMIBClockPortDSGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockPortDSName, + ptpbaseClockPortDSPortIdentity, + ptpbaseClockPortDSAnnouncementInterval, + ptpbaseClockPortDSAnnounceRctTimeout, + ptpbaseClockPortDSSyncInterval, + ptpbaseClockPortDSMinDelayReqInterval, + ptpbaseClockPortDSPeerDelayReqInterval, + ptpbaseClockPortDSDelayMech, + ptpbaseClockPortDSPeerMeanPathDelay, + ptpbaseClockPortDSGrantDuration, + ptpbaseClockPortDSPTPVersion + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing PTP Port Dataset + information" + ::= { ptpbaseMIBGroups 9 } + +ptpbaseMIBClockPortRunningGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockPortRunningName, + ptpbaseClockPortRunningState, + ptpbaseClockPortRunningRole, + ptpbaseClockPortRunningInterfaceIndex, + ptpbaseClockPortRunningIPversion, + ptpbaseClockPortRunningEncapsulationType, + ptpbaseClockPortRunningTxMode, + ptpbaseClockPortRunningRxMode, + ptpbaseClockPortRunningPacketsReceived, + ptpbaseClockPortRunningPacketsSent + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing PTP running interface + information" + ::= { ptpbaseMIBGroups 10 } + +ptpbaseMIBClockPortTransDSGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockPortTransDSPortIdentity, + ptpbaseClockPortTransDSlogMinPdelayReqInt, + ptpbaseClockPortTransDSFaultyFlag, + ptpbaseClockPortTransDSPeerMeanPathDelay + + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing PTP TransparentDS + Dataset + information" + ::= { ptpbaseMIBGroups 11 } + +ptpbaseMIBClockPortAssociateGroup OBJECT-GROUP + OBJECTS { + ptpbaseClockPortAssociatePacketsSent, + ptpbaseClockPortAssociatePacketsReceived, + ptpbaseClockPortAssociateAddress, + ptpbaseClockPortAssociateAddressType, + ptpbaseClockPortAssociateInErrors, + ptpbaseClockPortAssociateOutErrors + } + STATUS current + DESCRIPTION + "Group which aggregates objects describing information on peer + PTP ports for a given PTP clock-port." + ::= { ptpbaseMIBGroups 12 } +ptpbaseMIBClockInfo OBJECT IDENTIFIER + ::= { ptpbaseMIBObjects 2 } + + +ptpbaseSystemTable OBJECT-TYPE + SYNTAX SEQUENCE OF PtpbaseSystemEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table of count information about the PTP system for all + domains." + ::= { ptpbaseMIBSystemInfo 1 } + +ptpbaseSystemEntry OBJECT-TYPE + SYNTAX PtpbaseSystemEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "An entry in the table, containing count information about a + single domain. New row entries are added when the PTP clock for + this domain is configured, while the unconfiguration of the PTP + clock removes it." + INDEX { + ptpDomainIndex, + ptpInstanceIndex + } + ::= { ptpbaseSystemTable 1 } + + +PtpbaseSystemEntry ::= SEQUENCE { + ptpDomainIndex ClockDomainType, + ptpInstanceIndex ClockInstanceType, + ptpDomainClockPortsTotal Gauge32 +} + +ptpDomainIndex OBJECT-TYPE + SYNTAX ClockDomainType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This object specifies the domain number used to create logical + group of PTP devices. The Clock Domain is a logical group of + clocks and devices that synchronize with each other using the + PTP protocol. + + 0 Default domain + 1 Alternate domain 1 + 2 Alternate domain 2 + 3 Alternate domain 3 + 4 - 127 User-defined domains + 128 - 255 Reserved" + ::= { ptpbaseSystemEntry 1 } + +ptpInstanceIndex OBJECT-TYPE + SYNTAX ClockInstanceType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This object specifies the instance of the Clock for this + domain." + ::= { ptpbaseSystemEntry 2 } + +ptpDomainClockPortsTotal OBJECT-TYPE + SYNTAX Gauge32 + UNITS "ptp ports" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This object specifies the total number of clock ports + configured within a domain." + ::= { ptpbaseSystemEntry 3 } + + + +ptpbaseSystemDomainTable OBJECT-TYPE + SYNTAX SEQUENCE OF PtpbaseSystemDomainEntry + MAX-ACCESS not-accessible + + STATUS current + DESCRIPTION + "Table of information about the PTP system for all clock modes + -- ordinary, boundary or transparent." + ::= { ptpbaseMIBSystemInfo 2 } + +ptpbaseSystemDomainEntry OBJECT-TYPE + SYNTAX PtpbaseSystemDomainEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "An entry in the table, containing information about a single + clock mode for the PTP system. A row entry gets added when PTP + clocks are configured on the router." + INDEX { ptpbaseSystemDomainClockTypeIndex } + ::= { ptpbaseSystemDomainTable 1 } + +PtpbaseSystemDomainEntry ::= SEQUENCE { + ptpbaseSystemDomainClockTypeIndex ClockType, + ptpbaseSystemDomainTotals Unsigned32 +} + +ptpbaseSystemDomainClockTypeIndex OBJECT-TYPE + SYNTAX ClockType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This object specifies the clock type as defined in the + Textual convention description." + ::= { ptpbaseSystemDomainEntry 1 } + +ptpbaseSystemDomainTotals OBJECT-TYPE + SYNTAX Unsigned32 + UNITS "domains" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This object specifies the total number of PTP domains for this + particular clock type configured in this node." + ::= { ptpbaseSystemDomainEntry 2 } + + + +ptpbaseSystemProfile OBJECT-TYPE + SYNTAX ClockProfileType + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This object specifies the PTP Profile implemented on the + + system." + REFERENCE "Section 19.3 PTP profiles of [IEEE 1588-2008]" + ::= { ptpbaseMIBSystemInfo 3 } + +ptpbaseClockCurrentDSTable OBJECT-TYPE + SYNTAX SEQUENCE OF PtpbaseClockCurrentDSEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table of information about the PTP clock Current Datasets for + all domains." + ::= { ptpbaseMIBClockInfo 1 } + +ptpbaseClockCurrentDSEntry OBJECT-TYPE + SYNTAX PtpbaseClockCurrentDSEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "An entry in the table, containing information about a single + PTP clock Current Datasets for a domain." + REFERENCE + "1588 Version 2.0 Section 8.2.2 currentDS data set member + specifications of [IEEE 1588-2008]" + INDEX { + ptpbaseClockCurrentDSDomainIndex, + ptpbaseClockCurrentDSClockTypeIndex, + ptpbaseClockCurrentDSInstanceIndex + } + ::= { ptpbaseClockCurrentDSTable 1 } + +PtpbaseClockCurrentDSEntry ::= SEQUENCE { + ptpbaseClockCurrentDSDomainIndex ClockDomainType, + ptpbaseClockCurrentDSClockTypeIndex ClockType, + ptpbaseClockCurrentDSInstanceIndex ClockInstanceType, + ptpbaseClockCurrentDSStepsRemoved Unsigned32, + ptpbaseClockCurrentDSOffsetFromMaster ClockTimeInterval, + ptpbaseClockCurrentDSMeanPathDelay ClockTimeInterval +} + +ptpbaseClockCurrentDSDomainIndex OBJECT-TYPE + SYNTAX ClockDomainType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This object specifies the domain number used to create logical + group of PTP devices." + ::= { ptpbaseClockCurrentDSEntry 1 } + +ptpbaseClockCurrentDSClockTypeIndex OBJECT-TYPE + + SYNTAX ClockType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This object specifies the clock type as defined in the + Textual convention description." + ::= { ptpbaseClockCurrentDSEntry 2 } + +ptpbaseClockCurrentDSInstanceIndex OBJECT-TYPE + SYNTAX ClockInstanceType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This object specifies the instance of the clock for this clock + type in the given domain." + ::= { ptpbaseClockCurrentDSEntry 3 } + +ptpbaseClockCurrentDSStepsRemoved OBJECT-TYPE + SYNTAX Unsigned32 + UNITS "Steps" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The current clock dataset StepsRemoved value. + + This object specifies the distance measured by the number of + Boundary clocks between the local clock and the Foreign master + as indicated in the stepsRemoved field of Announce messages." + REFERENCE "1588 Version 2.0 Section 8.2.2.2 stepsRemoved" + ::= { ptpbaseClockCurrentDSEntry 4 } + +ptpbaseClockCurrentDSOffsetFromMaster OBJECT-TYPE + SYNTAX ClockTimeInterval + UNITS "Time Interval" + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This object specifies the current clock dataset ClockOffset + value. The value of the computation of the offset in time + between a slave and a master clock." + REFERENCE "1588 Version 2.0 Section 8.2.2.3 of + [IEEE 1588-2008]" + ::= { ptpbaseClockCurrentDSEntry 5 } + +ptpbaseClockCurrentDSMeanPathDelay OBJECT-TYPE + SYNTAX ClockTimeInterval + MAX-ACCESS read-only + STATUS current + DESCRIPTION + + "This object specifies the current clock dataset + MeanPathDelay value. + + The mean path delay between a pair of ports as measure by the + delay request-response mechanism." + REFERENCE "1588 Version 2.0 Section 8.2.2.4 mean path delay" + ::= { ptpbaseClockCurrentDSEntry 6 } + + + +ptpbaseClockParentDSTable OBJECT-TYPE + SYNTAX SEQUENCE OF PtpbaseClockParentDSEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table of information about the PTP clock Parent Datasets for + all domains." + ::= { ptpbaseMIBClockInfo 2 } + +ptpbaseClockParentDSEntry OBJECT-TYPE + SYNTAX PtpbaseClockParentDSEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "An entry in the table, containing information about a single + PTP clock Parent Datasets for a domain." + REFERENCE + "Section 8.2.3 parentDS data set member specifications of + [IEEE 1588-2008]" + INDEX { + ptpbaseClockParentDSDomainIndex, + ptpbaseClockParentDSClockTypeIndex, + ptpbaseClockParentDSInstanceIndex + } + ::= { ptpbaseClockParentDSTable 1 } + +PtpbaseClockParentDSEntry ::= SEQUENCE { + ptpbaseClockParentDSDomainIndex ClockDomainType, + ptpbaseClockParentDSClockTypeIndex ClockType, + ptpbaseClockParentDSInstanceIndex ClockInstanceType, + ptpbaseClockParentDSParentPortIdentity OCTET STRING, + ptpbaseClockParentDSParentStats TruthValue, + ptpbaseClockParentDSOffset ClockIntervalBase2, + ptpbaseClockParentDSClockPhChRate Integer32, + ptpbaseClockParentDSGMClockIdentity ClockIdentity, + ptpbaseClockParentDSGMClockPriority1 Unsigned32, + ptpbaseClockParentDSGMClockPriority2 Unsigned32, + ptpbaseClockParentDSGMClockQualityClass ClockQualityClassType, + ptpbaseClockParentDSGMClockQualityAccuracy ClockQualityAccuracyType, + + ptpbaseClockParentDSGMClockQualityOffset Unsigned32 +} + +ptpbaseClockParentDSDomainIndex OBJECT-TYPE + SYNTAX ClockDomainType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This object specifies the domain number used to create logical + group of PTP devices." + ::= { ptpbaseClockParentDSEntry 1 } + +ptpbaseClockParentDSClockTypeIndex OBJECT-TYPE + SYNTAX ClockType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This object specifies the clock type as defined in the + Textual convention description." + ::= { ptpbaseClockParentDSEntry 2 } + +ptpbaseClockParentDSInstanceIndex OBJECT-TYPE + SYNTAX ClockInstanceType + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "This object specifies the instance of the clock for this clock + type in the given domain." + ::= { ptpbaseClockParentDSEntry 3 } + +ptpbaseClockParentDSParentPortIdentity OBJECT-TYPE + SYNTAX OCTET STRING(SIZE(1..256)) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This object specifies the value of portIdentity of the port on + the master that issues the Sync me... [truncated message content] |
From: <gn...@us...> - 2012-12-01 22:46:15
|
Revision: 295 http://sourceforge.net/p/ptpd/code/295 Author: gnn Date: 2012-12-01 22:46:12 +0000 (Sat, 01 Dec 2012) Log Message: ----------- Remove references to release notes both from the Makefile and the README file. Pointed out by: Harlan Stenn Modified Paths: -------------- trunk/Makefile trunk/README Modified: trunk/Makefile =================================================================== --- trunk/Makefile 2012-11-25 00:18:05 UTC (rev 294) +++ trunk/Makefile 2012-12-01 22:46:12 UTC (rev 295) @@ -14,8 +14,7 @@ ln -s ../COPYRIGHT .; \ ln -s ../ChangeLog .; \ ln -s ../Makefile .; \ - ln -s ../README .; \ - ln -s ../RELEASE_NOTES .) + ln -s ../README .) tar cvzf $(RC).tar.gz -L --exclude .o --exclude Doxygen --exclude .svn --exclude .dep --exclude core $(RC) release: @@ -28,6 +27,5 @@ ln -s ../COPYRIGHT .; \ ln -s ../ChangeLog .; \ ln -s ../Makefile .; \ - ln -s ../README .; \ - ln -s ../RELEASE_NOTES .) + ln -s ../README .) tar cvzf $(VERSION).tar.gz -L --exclude .o --exclude Doxygen --exclude .svn --exclude .dep --exclude core $(VERSION) Modified: trunk/README =================================================================== --- trunk/README 2012-11-25 00:18:05 UTC (rev 294) +++ trunk/README 2012-12-01 22:46:12 UTC (rev 295) @@ -13,10 +13,10 @@ other. It has been shown to achieve microsecond level coordination, even on limited platforms. -The 'ptpd' program can be built from the included source code; see the release -notes about platform compatibility. To use the program, run 'ptpd' on a group of -LAN connected computers. Compile with 'PTPD_DBG' defined and run with the '-c' -argument to watch what's going on. +The 'ptpd' program can be built from the included source code. To use +the program, run 'ptpd' on a group of LAN connected computers. Compile +with 'PTPD_DBG' defined and run with the '-c' argument to watch what's +going on. If you are just looking for software to update the time on your desktop, you probably want something that implements the Network Time Protocol. It can This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gn...@us...> - 2013-02-26 19:55:19
|
Revision: 307 http://sourceforge.net/p/ptpd/code/307 Author: gnn Date: 2013-02-26 19:55:16 +0000 (Tue, 26 Feb 2013) Log Message: ----------- Merge support for building with autotools. Obtained from: Harlan Stenn Modified Paths: -------------- trunk/src/protocol.c Added Paths: ----------- trunk/Makefile.am trunk/Makefile.old trunk/README.repocheckout trunk/configure.ac trunk/m4/ trunk/src/Makefile.am trunk/src/Makefile.old Removed Paths: ------------- trunk/Makefile trunk/src/Makefile Property Changed: ---------------- trunk/ Index: trunk =================================================================== --- trunk 2013-02-25 19:09:44 UTC (rev 306) +++ trunk 2013-02-26 19:55:16 UTC (rev 307) Property changes on: trunk ___________________________________________________________________ Added: svn:mergeinfo ## -0,0 +1 ## +/branches/hms-autotools:287-306 \ No newline at end of property Deleted: trunk/Makefile =================================================================== --- trunk/Makefile 2013-02-25 19:09:44 UTC (rev 306) +++ trunk/Makefile 2013-02-26 19:55:16 UTC (rev 307) @@ -1,31 +0,0 @@ -# Root Makefile for ptpd, used for cutting releases and release candidates - -NAME = ptpd -VERSION = ${NAME}-2.2.2 -RC = ${NAME}-2-RC-0 - -rc: - (cd src; make clean) - mkdir $(RC) - (cd $(RC); \ - ln -s ../src .; \ - ln -s ../doc .; \ - ln -s ../tools .; \ - ln -s ../COPYRIGHT .; \ - ln -s ../ChangeLog .; \ - ln -s ../Makefile .; \ - ln -s ../README .) - tar cvzf $(RC).tar.gz -L --exclude .o --exclude Doxygen --exclude .svn --exclude .dep --exclude core $(RC) - -release: - (cd src; make clean) - mkdir $(VERSION) - (cd $(VERSION); \ - ln -s ../src .; \ - ln -s ../doc .; \ - ln -s ../tools .; \ - ln -s ../COPYRIGHT .; \ - ln -s ../ChangeLog .; \ - ln -s ../Makefile .; \ - ln -s ../README .) - tar cvzf $(VERSION).tar.gz -L --exclude .o --exclude Doxygen --exclude .svn --exclude .dep --exclude core $(VERSION) Copied: trunk/Makefile.am (from rev 306, branches/hms-autotools/Makefile.am) =================================================================== --- trunk/Makefile.am (rev 0) +++ trunk/Makefile.am 2013-02-26 19:55:16 UTC (rev 307) @@ -0,0 +1,31 @@ +ACLOCAL_AMFLAGS = -I m4 + +NULL = + +SUBDIRS = \ + src \ + $(NULL) + +EXTRA_DIST = \ + ChangeLog \ + NEWS \ + README \ + \ + doc \ + tools \ + \ + $(NULL) + +CLEANFILES = +#DISTCLEANFILES = .gcc-warning + +BUILT_SOURCES = \ + libtool \ + $(NULL) + +#dist-hook: +# @find $(distdir) -type d -name SCCS -print | xargs rm -rf + +libtool: $(LIBTOOL_DEPS) + ./config.status --recheck + Copied: trunk/Makefile.old (from rev 306, branches/hms-autotools/Makefile.old) =================================================================== --- trunk/Makefile.old (rev 0) +++ trunk/Makefile.old 2013-02-26 19:55:16 UTC (rev 307) @@ -0,0 +1,33 @@ +# Root Makefile for ptpd, used for cutting releases and release candidates + +NAME = ptpd +VERSION = ${NAME}-2.2.2 +RC = ${NAME}-2-RC-0 + +rc: + (cd src; make clean) + mkdir $(RC) + (cd $(RC); \ + ln -s ../src .; \ + ln -s ../doc .; \ + ln -s ../tools .; \ + ln -s ../COPYRIGHT .; \ + ln -s ../ChangeLog .; \ + ln -s ../Makefile .; \ + ln -s ../README .; \ + ln -s ../RELEASE_NOTES .) + tar cvzf $(RC).tar.gz -L --exclude .o --exclude Doxygen --exclude .svn --exclude .dep --exclude core $(RC) + +release: + (cd src; make clean) + mkdir $(VERSION) + (cd $(VERSION); \ + ln -s ../src .; \ + ln -s ../doc .; \ + ln -s ../tools .; \ + ln -s ../COPYRIGHT .; \ + ln -s ../ChangeLog .; \ + ln -s ../Makefile .; \ + ln -s ../README .; \ + ln -s ../RELEASE_NOTES .) + tar cvzf $(VERSION).tar.gz -L --exclude .o --exclude Doxygen --exclude .svn --exclude .dep --exclude core $(VERSION) Copied: trunk/README.repocheckout (from rev 306, branches/hms-autotools/README.repocheckout) =================================================================== --- trunk/README.repocheckout (rev 0) +++ trunk/README.repocheckout 2013-02-26 19:55:16 UTC (rev 307) @@ -0,0 +1,11 @@ +If you are getting this code from a tarball distribution, this +file does not apply to you. + +If you are getting this code from a repo checkout, you will need to +have autoconf, automake, and libtool installed. + +Run: + + % autoreconf -vi + +to generate the build environment. Copied: trunk/configure.ac (from rev 306, branches/hms-autotools/configure.ac) =================================================================== --- trunk/configure.ac (rev 0) +++ trunk/configure.ac 2013-02-26 19:55:16 UTC (rev 307) @@ -0,0 +1,269 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +m4_include([m4/version.m4]) +AC_PREREQ(2.61) +AC_INIT( + [ptpd2], + [VERSION_NUMBER], + [ptp...@nw...], + [], + [PTPD_URL]dnl +) +AC_CONFIG_SRCDIR([src/arith.c]) +AC_CONFIG_HEADER([config.h]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE([1.10 foreign -Wall]) + +# Checks for programs. +AC_PROG_CXX +AC_PROG_AWK +AC_PROG_CC +AC_PROG_LIBTOOL + +AC_ARG_WITH( + [net-snmp-config], + [AS_HELP_STRING( + [--with-net-snmp-config], + [+ =net-snmp-config] + )], + [ans=$withval], + [ans=yes] +) +case "$ans" in + no) + ;; + yes) + ans=net-snmp-config + ;; + /*) + ;; + */*) + AC_MSG_ERROR([--with-net-snmp-config takes either a name or an absolute path]) + ;; + *) + ;; +esac +PROG_NET_SNMP_CONFIG=$ans +case "$PROG_NET_SNMP_CONFIG" in + no) + ;; + *) + AC_PATH_PROG([PATH_NET_SNMP_CONFIG], [$PROG_NET_SNMP_CONFIG]) + AS_UNSET([ac_cv_path_PATH_NET_SNMP_CONFIG]) + ;; +esac + +AC_MSG_CHECKING([if we want to build SNMP support]) +AC_ARG_ENABLE( + [snmp], + [AS_HELP_STRING( + [--enable-snmp], + [disable support for SNMP] + )], + [ptpd_ok=$enableval], + [case "$PATH_NET_SNMP_CONFIG" in + /*) + ptpd_ok=yes + ;; + *) + ptpd_ok=no + ;; + esac] +) + +ptpd_snmp_enabled=0 +case "$ptpd_ok" in + yes) + ptpd_snmp_enabled=1 + PTP_SNMP="-DPTPD_SNMP" + ;; +esac +AM_CONDITIONAL([SNMP], [test x$ptpd_snmp_enabled = x1]) +AC_MSG_RESULT([$ptpd_ok]) + +case "$ptpd_ok" in + yes) + case "$PATH_NET_SNMP_CONFIG" in + /*) + SNMP_LIBS=`$PATH_NET_SNMP_CONFIG --agent-libs` + AC_SUBST([SNMP_LIBS]) + # HMS: we really want to separate CPPFLAGS and CFLAGS + foo=`$PATH_NET_SNMP_CONFIG --base-cflags` + SNMP_CPPFLAGS= + SNMP_CFLAGS= + for i in $foo; do + case "$i" in + -D*|-F*|-U*|-I*) + SNMP_CPPFLAGS="$SNMP_CPPFLAGS $i" + ;; + *) SNMP_CFLAGS="$SNMP_CFLAGS $i" + ;; + esac + done + AC_SUBST([SNMP_CPPFLAGS]) + AC_SUBST([SNMP_CFLAGS]) + + save_CFLAGS=$CFLAGS + save_CPPFLAGS=$CPPFLAGS + save_LIBS=$LIBS + CFLAGS=$SNMP_CFLAGS + CPPFLAGS=$SNMP_CPPFLAGS + + AC_CHECK_HEADER( + [net-snmp/net-snmp-config.h], + [], + [AC_MSG_WARN([net-snmp-config present but net-snmp headers are not available!])] + ) + + CFLAGS=$save_CFLAGS + AS_UNSET([save_CFLAGS]) + CPPFLAGS=$save_CPPFLAGS + AS_UNSET([save_CPPFLAGS]) + LIBS=$save_LIBS + AS_UNSET([save_LIBS]) + ;; + *) + AC_MSG_WARN([Cannot build with SNMP support - net-snmp-config cannot be found]) + ;; + esac + ;; +esac + +# Checks for libraries. +AC_CHECK_LIB([m], [pow]) +AC_CHECK_LIB([rt], [clock_gettime]) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_HEADER_STDBOOL +AC_TYPE_INT64_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_HEADER_TIME +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T +AC_C_VOLATILE + +# Checks for library functions. +AC_PROG_GCC_TRADITIONAL +AC_FUNC_MALLOC +AC_FUNC_MEMCMP +AC_FUNC_SELECT_ARGTYPES +AC_TYPE_SIGNAL +AC_FUNC_STRFTIME +AC_FUNC_VPRINTF +AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol]) + +AC_MSG_CHECKING([for RUNTIME_DEBUG]) +AC_ARG_ENABLE( + [runtime-debug], + [AS_HELP_STRING( + [--enable-runtime-debug], + [Enable all debug messages] + )], + [ptp_runtime=$enableval], + [ptp_runtime=no] +) +AC_MSG_RESULT([$ptp_runtime]) +case "$ptp_runtime" in + yes) + PTP_DBL="-DRUNTIME_DEBUG" + ;; + *) + AC_MSG_CHECKING([for (old-style) debug message level]) + AC_ARG_ENABLE( + [debug-level], + [AS_HELP_STRING( + [--enable-debug-level={basic,medium,all}], + [debug message level: basic, medium, all] + )], + [ptp_dblevel=$enableval], + [ptp_dblevel=no] + ) + AC_MSG_RESULT([$ptp_dblevel]) + case "$ptp_dblevel" in + "basic") + PTP_DBL="-DPTPD_DBG" + ;; + "medium") + PTP_DBL="-DPTPD_DBG2" + ;; + "all") + PTP_DBL="-DPTPD_DBGV" + ;; + *) PTP_DBL="" + ;; + esac + ;; +esac +AC_SUBST(PTP_DBL) + +AC_MSG_CHECKING([for daemon mode]) +AC_ARG_ENABLE( + [daemon], + [AS_HELP_STRING( + [--disable-daemon], + [Disable daemon mode (enabled by default)] + )], + [ptp_daemon=$enableval], + [ptp_daemon=yes] +) +AC_MSG_RESULT([$ptp_daemon]) +case "$ptp_daemon" in + no) + PTP_DAEMON="-DPTPD_NO_DAEMON" + ;; +esac +AC_SUBST(PTP_DAEMON) + +AC_MSG_CHECKING([for experimental options]) +AC_ARG_ENABLE( + [experimental-options], + [AS_HELP_STRING( + [--enable-experimental-options], + [Enable experimental options (disabled by default)] + )], + [ptp_exp=$enableval], + [ptp_exp=no] +) +AC_MSG_RESULT([$ptp_exp]) +case "$ptp_exp" in + yes) + PTP_EXP="-DPTPD_EXPERIMENTAL" + ;; +esac +AC_SUBST(PTP_EXP) + +AC_MSG_CHECKING([for SIGUSR2 support]) +AC_ARG_ENABLE( + [sigusr2], + [AS_HELP_STRING( + [--enable-sigusr2={domain,debug}], + [Enable SIGUSR2 support, cycle PTP domain #, or debug level (disabled by default)] + )], + [ptp_sigusr2=$enableval], + [ptp_sigusr2=no] +) +AC_MSG_RESULT([$ptp_sigusr2]) +case "$ptp_sigusr2" in + domain) + PTP_SIGUSR2="-DDBG_SIGUSR2_CHANGE_DOMAIN" + ;; + debug) + # We could/should check to be sure that RUNTIME_DEBUG is set... + PTP_SIGUSR2="-DDBG_SIGUSR2_CHANGE_DEBUG" + ;; +esac +AC_SUBST(PTP_SIGUSR2) + +AC_CONFIG_FILES([Makefile + src/Makefile]) +AC_OUTPUT Deleted: trunk/src/Makefile =================================================================== --- trunk/src/Makefile 2013-02-25 19:09:44 UTC (rev 306) +++ trunk/src/Makefile 2013-02-26 19:55:16 UTC (rev 307) @@ -1,109 +0,0 @@ -# Makefile for ptpd2 - -# -# Compile time defines: -# -DRUNTIME_DEBUG -# if defined: all debug messages are included, and are either selected at startup (-B) -# and runtime (SIGUSR2) (implies -DPTPD_DBGV) using syslog, -# add "*.debug /var/log/debug" to /etc/rsyslog.conf to see debug messages -# if undefined: individual defines select which messages will be included and presented (old behaviour) -# -# -DPTPD_DBG basic debug messages -# -DPTPD_DBG2 adds basic protocol messages, +ignored messages reasons -# -DPTPD_DBGV adds all debug messages -# -# -DPTPD_NO_DAEMON forces option -c -# -# -DPTPD_EXPERIMENTAL Allows non-standard compliant experimental options: -# -U: Hybrid mode -# -I: choose multicast group -# -DPTPD_SNMP Enables SNMP agent support (PTP-MIB) -# -# Mutually exclusive defines (useful for testing): -# -DDBG_SIGUSR2_CHANGE_DOMAIN: SIGUSR2 cycles the PTP domain number -# -DDBG_SIGUSR2_CHANGE_DEBUG: SIGUSR2 cycles the current debug level (if RUNTIME_DEBUG is defined) -# -####### - -VERSION = 2.3.0 - -RM = rm -f -SYMLINK = ln -s - -# SNMP support? -SNMP = yes - -# start with CFLAGS += ..., so additional CFLAGs can be specified e.g. on the make command line -CFLAGS += -Wall -g -fPIC - -CFLAGS += -DRUNTIME_DEBUG -#CFLAGS += -DPTPD_DBG -#CFLAGS += -DPTPD_DBG2 -#CFLAGS += -DPTPD_DBGV - -#CFLAGS += -DPTPD_NO_DAEMON -#CFLAGS += -DDBG_SIGUSR2_CHANGE_DOMAIN -CFLAGS += -DDBG_SIGUSR2_CHANGE_DEBUG - -CFLAGS += -DPTPD_EXPERIMENTAL - -LDFLAGS = -lm -lrt -STATICLIBFLAGS = rcs -SHAREDLIBFLAGS = -shared -Wl,-soname - -PROG = ptpd2 -STATICLIB = libptpd2.a -SHAREDLIB = libptpd2.so -SHAREDLIBVER = $(SHAREDLIB).$(VERSION) - -SRCS = ptpd.c arith.c bmc.c protocol.c display.c management.c \ - dep/msg.c dep/net.c dep/servo.c dep/startup.c dep/sys.c dep/timer.c - -# SNMP -ifeq ($(SNMP),yes) -LDFLAGS += `net-snmp-config --agent-libs` -CFLAGS += `net-snmp-config --base-cflags` -CFLAGS += -DPTPD_SNMP -SRCS += dep/snmp.c -endif - -OBJS = $(SRCS:.c=.o) - -HDRS = ptpd.h constants.h datatypes.h \ - dep/ptpd_dep.h dep/constants_dep.h dep/datatypes_dep.h - -CSCOPE = cscope -GTAGS = gtags -DOXYGEN = doxygen - -TAGFILES = GPATH GRTAGS GSYMS GTAGS cscope.in.out cscope.out cscope.po.out - -.c.o: - $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< - - -$(PROG): $(OBJS) - $(CC) -o $@ $(OBJS) $(LDFLAGS) - -$(STATICLIB): $(OBJS) - $(AR) $(STATICLIBFLAGS) $(STATICLIB) $(OBJS) - -$(SHAREDLIB): $(OBJS) - $(CC) $(SHAREDLIBFLAGS),$(SHAREDLIB) -o $(SHAREDLIB) $(OBJS) - # create shared lib symlink with ptpd version extension - $(SYMLINK) $(SHAREDLIB) $(SHAREDLIBVER) - -all: $(PROG) $(STATICLIB) $(SHAREDLIB) - -$(OBJS): $(HDRS) - -tags: - $(CSCOPE) -R -q -b - $(GTAGS) - $(DOXYGEN) Doxyfile - -clean: - $(RM) $(PROG) $(STATICLIB) $(SHAREDLIB) $(SHAREDLIBVER) $(OBJS) $(TAGFILES) make.out - -realclean: clean - $(RM) $(TAGFILES) Copied: trunk/src/Makefile.am (from rev 306, branches/hms-autotools/src/Makefile.am) =================================================================== --- trunk/src/Makefile.am (rev 0) +++ trunk/src/Makefile.am 2013-02-26 19:55:16 UTC (rev 307) @@ -0,0 +1,52 @@ +# Makefile for ptpd2 + +lib_LTLIBRARIES = $(LIBPTPD2_LIBS_LA) +bin_PROGRAMS = ptpd2 + +AM_CFLAGS = $(SNMP_CFLAGS) +AM_CPPFLAGS = $(SNMP_CPPFLAGS) +AM_LDFLAGS = $(SNMP_LIBS) + +AM_CPPFLAGS += $(PTP_DBL) $(PTP_DAEMON) $(PTP_EXP) $(PTP_SNMP) $(PTP_SIGUSR2) + +NULL= + +#VERSION = 2.3.0 +#SHAREDLIBVER = $(SHAREDLIB).$(VERSION) + +ptpd2_SOURCES = \ + arith.c \ + bmc.c \ + constants.h \ + datatypes.h \ + dep/constants_dep.h \ + dep/datatypes_dep.h \ + dep/msg.c \ + dep/net.c \ + dep/ptpd_dep.h \ + dep/servo.c \ + dep/startup.c \ + dep/sys.c \ + dep/timer.c \ + display.c \ + management.c \ + protocol.c \ + ptpd.c \ + ptpd.h \ + $(NULL) + +# SNMP +if SNMP +ptpd2_SOURCES += dep/snmp.c +endif + +CSCOPE = cscope +GTAGS = gtags +DOXYGEN = doxygen + +TAGFILES = GPATH GRTAGS GSYMS GTAGS cscope.in.out cscope.out cscope.po.out + +#tags: +# $(CSCOPE) -R -q -b +# $(GTAGS) +# $(DOXYGEN) Doxyfile Copied: trunk/src/Makefile.old (from rev 306, branches/hms-autotools/src/Makefile.old) =================================================================== --- trunk/src/Makefile.old (rev 0) +++ trunk/src/Makefile.old 2013-02-26 19:55:16 UTC (rev 307) @@ -0,0 +1,109 @@ +# Makefile for ptpd2 + +# +# Compile time defines: +# -DRUNTIME_DEBUG +# if defined: all debug messages are included, and are either selected at startup (-B) +# and runtime (SIGUSR2) (implies -DPTPD_DBGV) using syslog, +# add "*.debug /var/log/debug" to /etc/rsyslog.conf to see debug messages +# if undefined: individual defines select which messages will be included and presented (old behaviour) +# +# -DPTPD_DBG basic debug messages +# -DPTPD_DBG2 adds basic protocol messages, +ignored messages reasons +# -DPTPD_DBGV adds all debug messages +# +# -DPTPD_NO_DAEMON forces option -c +# +# -DPTPD_EXPERIMENTAL Allows non-standard compliant experimental options: +# -U: Hybrid mode +# -I: choose multicast group +# -DPTPD_SNMP Enables SNMP agent support (PTP-MIB) +# +# Mutually exclusive defines (useful for testing): +# -DDBG_SIGUSR2_CHANGE_DOMAIN: SIGUSR2 cycles the PTP domain number +# -DDBG_SIGUSR2_CHANGE_DEBUG: SIGUSR2 cycles the current debug level (if RUNTIME_DEBUG is defined) +# +####### + +VERSION = 2.3.0 + +RM = rm -f +SYMLINK = ln -s + +# SNMP support? +SNMP = yes + +# start with CFLAGS += ..., so additional CFLAGs can be specified e.g. on the make command line +CFLAGS += -Wall -g -fPIC + +CFLAGS += -DRUNTIME_DEBUG +#CFLAGS += -DPTPD_DBG +#CFLAGS += -DPTPD_DBG2 +#CFLAGS += -DPTPD_DBGV + +#CFLAGS += -DPTPD_NO_DAEMON +#CFLAGS += -DDBG_SIGUSR2_CHANGE_DOMAIN +CFLAGS += -DDBG_SIGUSR2_CHANGE_DEBUG + +CFLAGS += -DPTPD_EXPERIMENTAL + +LDFLAGS = -lm -lrt +STATICLIBFLAGS = rcs +SHAREDLIBFLAGS = -shared -Wl,-soname + +PROG = ptpd2 +STATICLIB = libptpd2.a +SHAREDLIB = libptpd2.so +SHAREDLIBVER = $(SHAREDLIB).$(VERSION) + +SRCS = ptpd.c arith.c bmc.c protocol.c display.c management.c \ + dep/msg.c dep/net.c dep/servo.c dep/startup.c dep/sys.c dep/timer.c + +# SNMP +ifeq ($(SNMP),yes) +LDFLAGS += `net-snmp-config --agent-libs` +CFLAGS += `net-snmp-config --base-cflags` +CFLAGS += -DPTPD_SNMP +SRCS += dep/snmp.c +endif + +OBJS = $(SRCS:.c=.o) + +HDRS = ptpd.h constants.h datatypes.h \ + dep/ptpd_dep.h dep/constants_dep.h dep/datatypes_dep.h + +CSCOPE = cscope +GTAGS = gtags +DOXYGEN = doxygen + +TAGFILES = GPATH GRTAGS GSYMS GTAGS cscope.in.out cscope.out cscope.po.out + +.c.o: + $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< + + +$(PROG): $(OBJS) + $(CC) -o $@ $(OBJS) $(LDFLAGS) + +$(STATICLIB): $(OBJS) + $(AR) $(STATICLIBFLAGS) $(STATICLIB) $(OBJS) + +$(SHAREDLIB): $(OBJS) + $(CC) $(SHAREDLIBFLAGS),$(SHAREDLIB) -o $(SHAREDLIB) $(OBJS) + # create shared lib symlink with ptpd version extension + $(SYMLINK) $(SHAREDLIB) $(SHAREDLIBVER) + +all: $(PROG) $(STATICLIB) $(SHAREDLIB) + +$(OBJS): $(HDRS) + +tags: + $(CSCOPE) -R -q -b + $(GTAGS) + $(DOXYGEN) Doxyfile + +clean: + $(RM) $(PROG) $(STATICLIB) $(SHAREDLIB) $(SHAREDLIBVER) $(OBJS) $(TAGFILES) make.out + +realclean: clean + $(RM) $(TAGFILES) Modified: trunk/src/protocol.c =================================================================== --- trunk/src/protocol.c 2013-02-25 19:09:44 UTC (rev 306) +++ trunk/src/protocol.c 2013-02-26 19:55:16 UTC (rev 307) @@ -836,7 +836,9 @@ ptpClock->leapSecondInProgress=FALSE; ptpClock->leap59 = FALSE; ptpClock->leap61 = FALSE; +#if !defined(__APPLE__) unsetTimexFlags(STA_INS | STA_DEL, TRUE); +#endif /* apple */ } } DBG2("___ Announce: received Announce from current Master, so reset the Announce timer\n"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ha...@us...> - 2013-03-12 09:44:45
|
Revision: 311 http://sourceforge.net/p/ptpd/code/311 Author: harlan Date: 2013-03-12 09:44:43 +0000 (Tue, 12 Mar 2013) Log Message: ----------- auto* patches from Jan Breuer Modified Paths: -------------- trunk/configure.ac trunk/src/dep/startup.c Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-03-04 02:43:41 UTC (rev 310) +++ trunk/configure.ac 2013-03-12 09:44:43 UTC (rev 311) @@ -61,7 +61,7 @@ [snmp], [AS_HELP_STRING( [--enable-snmp], - [disable support for SNMP] + [enable support for SNMP (disabled by default)] )], [ptpd_ok=$enableval], [case "$PATH_NET_SNMP_CONFIG" in Modified: trunk/src/dep/startup.c =================================================================== --- trunk/src/dep/startup.c 2013-03-04 02:43:41 UTC (rev 310) +++ trunk/src/dep/startup.c 2013-03-12 09:44:43 UTC (rev 311) @@ -539,7 +539,11 @@ " -b <dev> Interface to use\n" "\n" " -cC -DVfS Console / verbose console; Dump stats / Interval / Output file / no Syslog\n" +#ifdef PTPD_EXPERIMENTAL " -uU Unicast/Hybrid mode\n" +#else + " -u Unicast mode\n" +#endif "\n" "\n" " -hHB Summary / Complete help file / run-time debug level\n" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wow...@us...> - 2013-05-24 15:57:08
|
Revision: 326 http://sourceforge.net/p/ptpd/code/326 Author: wowczarek Date: 2013-05-24 15:57:05 +0000 (Fri, 24 May 2013) Log Message: ----------- - Imported libiniparser (http://ndevilla.free.fr/iniparser/) for config file support [MIT licence] - Now that libpcap required, added explicit configure error if not operational - Added type cast to prevent compiler warning in net.c Modified Paths: -------------- trunk/configure.ac trunk/src/Makefile.am trunk/src/dep/net.c Added Paths: ----------- trunk/src/dep/iniparser/ trunk/src/dep/iniparser/AUTHORS trunk/src/dep/iniparser/LICENSE trunk/src/dep/iniparser/README trunk/src/dep/iniparser/dictionary.c trunk/src/dep/iniparser/dictionary.h trunk/src/dep/iniparser/iniparser.c trunk/src/dep/iniparser/iniparser.h Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-05-23 18:47:27 UTC (rev 325) +++ trunk/configure.ac 2013-05-24 15:57:05 UTC (rev 326) @@ -135,7 +135,12 @@ # Checks for libraries. AC_CHECK_LIB([m], [pow]) AC_CHECK_LIB([rt], [clock_gettime]) -AC_CHECK_LIB([pcap], [pcap_inject]) +AC_CHECK_LIB( + [pcap], + [pcap_inject], + [], + [AC_MSG_ERROR([Cannot build with libpcap - required for pcap / BPF timestamping!])] +) # Checks for header files. AC_HEADER_STDC Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2013-05-23 18:47:27 UTC (rev 325) +++ trunk/src/Makefile.am 2013-05-24 15:57:05 UTC (rev 326) @@ -14,25 +14,29 @@ #VERSION = 2.3.0 #SHAREDLIBVER = $(SHAREDLIB).$(VERSION) -ptpd2_SOURCES = \ - arith.c \ - bmc.c \ - constants.h \ - datatypes.h \ - dep/constants_dep.h \ - dep/datatypes_dep.h \ - dep/msg.c \ - dep/net.c \ - dep/ptpd_dep.h \ - dep/servo.c \ - dep/startup.c \ - dep/sys.c \ - dep/timer.c \ - display.c \ - management.c \ - protocol.c \ - ptpd.c \ - ptpd.h \ +ptpd2_SOURCES = \ + arith.c \ + bmc.c \ + constants.h \ + datatypes.h \ + dep/constants_dep.h \ + dep/datatypes_dep.h \ + dep/msg.c \ + dep/net.c \ + dep/ptpd_dep.h \ + dep/servo.c \ + dep/iniparser/dictionary.h \ + dep/iniparser/iniparser.h \ + dep/iniparser/dictionary.c \ + dep/iniparser/iniparser.c \ + dep/startup.c \ + dep/sys.c \ + dep/timer.c \ + display.c \ + management.c \ + protocol.c \ + ptpd.c \ + ptpd.h \ $(NULL) # SNMP Added: trunk/src/dep/iniparser/AUTHORS =================================================================== --- trunk/src/dep/iniparser/AUTHORS (rev 0) +++ trunk/src/dep/iniparser/AUTHORS 2013-05-24 15:57:05 UTC (rev 326) @@ -0,0 +1,6 @@ +Author: Nicolas Devillard <nde...@fr...> + +This tiny library has received countless contributions and I have +not kept track of all the people who contributed. Let them be thanked +for their ideas, code, suggestions, corrections, enhancements! + Added: trunk/src/dep/iniparser/LICENSE =================================================================== --- trunk/src/dep/iniparser/LICENSE (rev 0) +++ trunk/src/dep/iniparser/LICENSE 2013-05-24 15:57:05 UTC (rev 326) @@ -0,0 +1,21 @@ +Copyright (c) 2000-2011 by Nicolas Devillard. +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + Added: trunk/src/dep/iniparser/README =================================================================== --- trunk/src/dep/iniparser/README (rev 0) +++ trunk/src/dep/iniparser/README 2013-05-24 15:57:05 UTC (rev 326) @@ -0,0 +1,12 @@ + +Welcome to iniParser -- version 3.1 +released 08 Apr 2012 + +This modules offers parsing of ini files from the C level. +See a complete documentation in HTML format, from this directory +open the file html/index.html with any HTML-capable browser. + +Enjoy! + +N.Devillard +Sun Apr 8 16:38:09 CEST 2012 Added: trunk/src/dep/iniparser/dictionary.c =================================================================== --- trunk/src/dep/iniparser/dictionary.c (rev 0) +++ trunk/src/dep/iniparser/dictionary.c 2013-05-24 15:57:05 UTC (rev 326) @@ -0,0 +1,398 @@ +/*-------------------------------------------------------------------------*/ +/** + @file dictionary.c + @author N. Devillard + @brief Implements a dictionary for string variables. + + This module implements a simple dictionary object, i.e. a list + of string/string associations. This object is useful to store e.g. + informations retrieved from a configuration file (ini files). +*/ +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ +#include "dictionary.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +/** Maximum value size for integers and doubles. */ +#define MAXVALSZ 1024 + +/** Minimal allocated number of entries in a dictionary */ +#define DICTMINSZ 128 + +/** Invalid key token */ +#define DICT_INVALID_KEY ((char*)-1) + +/*--------------------------------------------------------------------------- + Private functions + ---------------------------------------------------------------------------*/ + +/* Doubles the allocated size associated to a pointer */ +/* 'size' is the current allocated size. */ +static void * mem_double(void * ptr, int size) +{ + void * newptr ; + + newptr = calloc(2*size, 1); + if (newptr==NULL) { + return NULL ; + } + memcpy(newptr, ptr, size); + free(ptr); + return newptr ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Duplicate a string + @param s String to duplicate + @return Pointer to a newly allocated string, to be freed with free() + + This is a replacement for strdup(). This implementation is provided + for systems that do not have it. + */ +/*--------------------------------------------------------------------------*/ +static char * xstrdup(const char * s) +{ + char * t ; + if (!s) + return NULL ; + t = (char*)malloc(strlen(s)+1) ; + if (t) { + strcpy(t,s); + } + return t ; +} + +/*--------------------------------------------------------------------------- + Function codes + ---------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------*/ +/** + @brief Compute the hash key for a string. + @param key Character string to use for key. + @return 1 unsigned int on at least 32 bits. + + This hash function has been taken from an Article in Dr Dobbs Journal. + This is normally a collision-free function, distributing keys evenly. + The key is stored anyway in the struct so that collision can be avoided + by comparing the key itself in last resort. + */ +/*--------------------------------------------------------------------------*/ +unsigned dictionary_hash(const char * key) +{ + int len ; + unsigned hash ; + int i ; + + len = strlen(key); + for (hash=0, i=0 ; i<len ; i++) { + hash += (unsigned)key[i] ; + hash += (hash<<10); + hash ^= (hash>>6) ; + } + hash += (hash <<3); + hash ^= (hash >>11); + hash += (hash <<15); + return hash ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Create a new dictionary object. + @param size Optional initial size of the dictionary. + @return 1 newly allocated dictionary objet. + + This function allocates a new dictionary object of given size and returns + it. If you do not know in advance (roughly) the number of entries in the + dictionary, give size=0. + */ +/*--------------------------------------------------------------------------*/ +dictionary * dictionary_new(int size) +{ + dictionary * d ; + + /* If no size was specified, allocate space for DICTMINSZ */ + if (size<DICTMINSZ) size=DICTMINSZ ; + + if (!(d = (dictionary *)calloc(1, sizeof(dictionary)))) { + return NULL; + } + d->size = size ; + d->val = (char **)calloc(size, sizeof(char*)); + d->key = (char **)calloc(size, sizeof(char*)); + d->hash = (unsigned int *)calloc(size, sizeof(unsigned)); + return d ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a dictionary object + @param d dictionary object to deallocate. + @return void + + Deallocate a dictionary object and all memory associated to it. + */ +/*--------------------------------------------------------------------------*/ +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]); + } + free(d->val); + free(d->key); + free(d->hash); + free(d); + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get a value from a dictionary. + @param d dictionary object to search. + @param key Key to look for in the dictionary. + @param def Default value to return if key not found. + @return 1 pointer to internally allocated character string. + + This function locates a key in a dictionary and returns a pointer to its + value, or the passed 'def' pointer if no such key can be found in + dictionary. The returned character pointer points to data internal to the + dictionary object, you should not try to free it or modify it. + */ +/*--------------------------------------------------------------------------*/ +char * dictionary_get(dictionary * d, const char * key, char * def) +{ + unsigned hash ; + int i ; + + hash = dictionary_hash(key); + for (i=0 ; i<d->size ; i++) { + if (d->key[i]==NULL) + continue ; + /* Compare hash */ + if (hash==d->hash[i]) { + /* Compare string, to avoid hash collisions */ + if (!strcmp(key, d->key[i])) { + return d->val[i] ; + } + } + } + return def ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Set a value in a dictionary. + @param d dictionary object to modify. + @param key Key to modify or add. + @param val Value to add. + @return int 0 if Ok, anything else otherwise + + If the given key is found in the dictionary, the associated value is + replaced by the provided one. If the key cannot be found in the + dictionary, it is added to it. + + It is Ok to provide a NULL value for val, but NULL values for the dictionary + or the key are considered as errors: the function will return immediately + in such a case. + + Notice that if you dictionary_set a variable to NULL, a call to + dictionary_get will return a NULL value: the variable will be found, and + its value (NULL) is returned. In other words, setting the variable + content to NULL is equivalent to deleting the variable from the + dictionary. It is not possible (in this implementation) to have a key in + the dictionary without value. + + This function returns non-zero in case of failure. + */ +/*--------------------------------------------------------------------------*/ +int dictionary_set(dictionary * d, const char * key, const char * val) +{ + int i ; + unsigned hash ; + + if (d==NULL || key==NULL) return -1 ; + + /* Compute hash for this key */ + hash = dictionary_hash(key) ; + /* Find if value is already in dictionary */ + if (d->n>0) { + for (i=0 ; i<d->size ; i++) { + if (d->key[i]==NULL) + continue ; + if (hash==d->hash[i]) { /* Same hash value */ + if (!strcmp(key, d->key[i])) { /* Same key */ + /* Found a value: modify and return */ + if (d->val[i]!=NULL) + free(d->val[i]); + d->val[i] = val ? xstrdup(val) : NULL ; + /* Value has been modified: return */ + return 0 ; + } + } + } + } + /* Add a new value */ + /* See if dictionary needs to grow */ + if (d->n==d->size) { + + /* Reached maximum size: reallocate dictionary */ + d->val = (char **)mem_double(d->val, d->size * sizeof(char*)) ; + d->key = (char **)mem_double(d->key, d->size * sizeof(char*)) ; + d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ; + if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) { + /* Cannot grow dictionary */ + return -1 ; + } + /* Double size */ + d->size *= 2 ; + } + + /* Insert key in the first empty slot. Start at d->n and wrap at + d->size. Because d->n < d->size this will necessarily + terminate. */ + for (i=d->n ; d->key[i] ; ) { + if(++i == d->size) i = 0; + } + /* Copy key */ + d->key[i] = xstrdup(key); + d->val[i] = val ? xstrdup(val) : NULL ; + d->hash[i] = hash; + d->n ++ ; + return 0 ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a key in a dictionary + @param d dictionary object to modify. + @param key Key to remove. + @return void + + This function deletes a key in a dictionary. Nothing is done if the + key cannot be found. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_unset(dictionary * d, const char * key) +{ + unsigned hash ; + int i ; + + if (key == NULL) { + return; + } + + hash = dictionary_hash(key); + for (i=0 ; i<d->size ; i++) { + if (d->key[i]==NULL) + continue ; + /* Compare hash */ + if (hash==d->hash[i]) { + /* Compare string, to avoid hash collisions */ + if (!strcmp(key, d->key[i])) { + /* Found key */ + break ; + } + } + } + if (i>=d->size) + /* Key not found */ + return ; + + free(d->key[i]); + d->key[i] = NULL ; + if (d->val[i]!=NULL) { + free(d->val[i]); + d->val[i] = NULL ; + } + d->hash[i] = 0 ; + d->n -- ; + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump + @param f Opened file pointer. + @return void + + Dumps a dictionary onto an opened file pointer. Key pairs are printed out + as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as + output file pointers. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_dump(dictionary * d, FILE * out) +{ + int i ; + + if (d==NULL || out==NULL) return ; + if (d->n<1) { + fprintf(out, "empty dictionary\n"); + return ; + } + for (i=0 ; i<d->size ; i++) { + if (d->key[i]) { + fprintf(out, "%20s\t[%s]\n", + d->key[i], + d->val[i] ? d->val[i] : "UNDEF"); + } + } + return ; +} + + +/* Test code */ +#ifdef TESTDIC +#define NVALS 20000 +int main(int argc, char *argv[]) +{ + dictionary * d ; + char * val ; + int i ; + char cval[90] ; + + /* Allocate dictionary */ + printf("allocating...\n"); + d = dictionary_new(0); + + /* Set values in dictionary */ + printf("setting %d values...\n", NVALS); + for (i=0 ; i<NVALS ; i++) { + sprintf(cval, "%04d", i); + dictionary_set(d, cval, "salut"); + } + printf("getting %d values...\n", NVALS); + for (i=0 ; i<NVALS ; i++) { + sprintf(cval, "%04d", i); + val = dictionary_get(d, cval, DICT_INVALID_KEY); + if (val==DICT_INVALID_KEY) { + printf("cannot get value for key [%s]\n", cval); + } + } + printf("unsetting %d values...\n", NVALS); + for (i=0 ; i<NVALS ; i++) { + sprintf(cval, "%04d", i); + dictionary_unset(d, cval); + } + if (d->n != 0) { + printf("error deleting values\n"); + } + printf("deallocating...\n"); + dictionary_del(d); + return 0 ; +} +#endif +/* vim: set ts=4 et sw=4 tw=75 */ Added: trunk/src/dep/iniparser/dictionary.h =================================================================== --- trunk/src/dep/iniparser/dictionary.h (rev 0) +++ trunk/src/dep/iniparser/dictionary.h 2013-05-24 15:57:05 UTC (rev 326) @@ -0,0 +1,165 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file dictionary.h + @author N. Devillard + @brief Implements a dictionary for string variables. + + This module implements a simple dictionary object, i.e. a list + of string/string associations. This object is useful to store e.g. + informations retrieved from a configuration file (ini files). +*/ +/*--------------------------------------------------------------------------*/ + +#ifndef _DICTIONARY_H_ +#define _DICTIONARY_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +/*--------------------------------------------------------------------------- + New types + ---------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------*/ +/** + @brief Dictionary object + + This object contains a list of string/string associations. Each + association is identified by a unique string key. Looking up values + in the dictionary is speeded up by the use of a (hopefully collision-free) + hash function. + */ +/*-------------------------------------------------------------------------*/ +typedef struct _dictionary_ { + int n ; /** Number of entries in dictionary */ + int size ; /** Storage size */ + char ** val ; /** List of string values */ + char ** key ; /** List of string keys */ + unsigned * hash ; /** List of hash values for keys */ +} dictionary ; + + +/*--------------------------------------------------------------------------- + Function prototypes + ---------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ +/** + @brief Compute the hash key for a string. + @param key Character string to use for key. + @return 1 unsigned int on at least 32 bits. + + This hash function has been taken from an Article in Dr Dobbs Journal. + This is normally a collision-free function, distributing keys evenly. + The key is stored anyway in the struct so that collision can be avoided + by comparing the key itself in last resort. + */ +/*--------------------------------------------------------------------------*/ +unsigned dictionary_hash(const char * key); + +/*-------------------------------------------------------------------------*/ +/** + @brief Create a new dictionary object. + @param size Optional initial size of the dictionary. + @return 1 newly allocated dictionary objet. + + This function allocates a new dictionary object of given size and returns + it. If you do not know in advance (roughly) the number of entries in the + dictionary, give size=0. + */ +/*--------------------------------------------------------------------------*/ +dictionary * dictionary_new(int size); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a dictionary object + @param d dictionary object to deallocate. + @return void + + Deallocate a dictionary object and all memory associated to it. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_del(dictionary * vd); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get a value from a dictionary. + @param d dictionary object to search. + @param key Key to look for in the dictionary. + @param def Default value to return if key not found. + @return 1 pointer to internally allocated character string. + + This function locates a key in a dictionary and returns a pointer to its + value, or the passed 'def' pointer if no such key can be found in + dictionary. The returned character pointer points to data internal to the + dictionary object, you should not try to free it or modify it. + */ +/*--------------------------------------------------------------------------*/ +char * dictionary_get(dictionary * d, const char * key, char * def); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Set a value in a dictionary. + @param d dictionary object to modify. + @param key Key to modify or add. + @param val Value to add. + @return int 0 if Ok, anything else otherwise + + If the given key is found in the dictionary, the associated value is + replaced by the provided one. If the key cannot be found in the + dictionary, it is added to it. + + It is Ok to provide a NULL value for val, but NULL values for the dictionary + or the key are considered as errors: the function will return immediately + in such a case. + + Notice that if you dictionary_set a variable to NULL, a call to + dictionary_get will return a NULL value: the variable will be found, and + its value (NULL) is returned. In other words, setting the variable + content to NULL is equivalent to deleting the variable from the + dictionary. It is not possible (in this implementation) to have a key in + the dictionary without value. + + This function returns non-zero in case of failure. + */ +/*--------------------------------------------------------------------------*/ +int dictionary_set(dictionary * vd, const char * key, const char * val); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a key in a dictionary + @param d dictionary object to modify. + @param key Key to remove. + @return void + + This function deletes a key in a dictionary. Nothing is done if the + key cannot be found. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_unset(dictionary * d, const char * key); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump + @param f Opened file pointer. + @return void + + Dumps a dictionary onto an opened file pointer. Key pairs are printed out + as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as + output file pointers. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_dump(dictionary * d, FILE * out); + +#endif Added: trunk/src/dep/iniparser/iniparser.c =================================================================== --- trunk/src/dep/iniparser/iniparser.c (rev 0) +++ trunk/src/dep/iniparser/iniparser.c 2013-05-24 15:57:05 UTC (rev 326) @@ -0,0 +1,748 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file iniparser.c + @author N. Devillard + @brief Parser for ini files. +*/ +/*--------------------------------------------------------------------------*/ +/*---------------------------- Includes ------------------------------------*/ +#include <ctype.h> +#include "iniparser.h" + +/*---------------------------- Defines -------------------------------------*/ +#define ASCIILINESZ (1024) +#define INI_INVALID_KEY ((char*)-1) + +/*--------------------------------------------------------------------------- + Private to this module + ---------------------------------------------------------------------------*/ +/** + * This enum stores the status for each parsed line (internal use only). + */ +typedef enum _line_status_ { + LINE_UNPROCESSED, + LINE_ERROR, + LINE_EMPTY, + LINE_COMMENT, + LINE_SECTION, + LINE_VALUE +} line_status ; + +/*-------------------------------------------------------------------------*/ +/** + @brief Convert a string to lowercase. + @param s String to convert. + @return ptr to statically allocated string. + + This function returns a pointer to a statically allocated string + containing a lowercased version of the input string. Do not free + or modify the returned string! Since the returned string is statically + allocated, it will be modified at each function call (not re-entrant). + */ +/*--------------------------------------------------------------------------*/ +static char * strlwc(const char * s) +{ + static char l[ASCIILINESZ+1]; + int i ; + + if (s==NULL) return NULL ; + memset(l, 0, ASCIILINESZ+1); + i=0 ; + while (s[i] && i<ASCIILINESZ) { + l[i] = (char)tolower((int)s[i]); + i++ ; + } + l[ASCIILINESZ]=(char)0; + return l ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Remove blanks at the beginning and the end of a string. + @param s String to parse. + @return ptr to statically allocated string. + + This function returns a pointer to a statically allocated string, + which is identical to the input string, except that all blank + characters at the end and the beg. of the string have been removed. + Do not free or modify the returned string! Since the returned string + is statically allocated, it will be modified at each function call + (not re-entrant). + */ +/*--------------------------------------------------------------------------*/ +static char * strstrip(const char * s) +{ + static char l[ASCIILINESZ+1]; + char * last ; + + if (s==NULL) return NULL ; + + while (isspace((int)*s) && *s) s++; + memset(l, 0, ASCIILINESZ+1); + strcpy(l, s); + last = l + strlen(l); + while (last > l) { + if (!isspace((int)*(last-1))) + break ; + last -- ; + } + *last = (char)0; + return (char*)l ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get number of sections in a dictionary + @param d Dictionary to examine + @return int Number of sections found in dictionary + + This function returns the number of sections found in a dictionary. + The test to recognize sections is done on the string stored in the + dictionary: a section name is given as "section" whereas a key is + stored as "section:key", thus the test looks for entries that do not + contain a colon. + + This clearly fails in the case a section name contains a colon, but + this should simply be avoided. + + This function returns -1 in case of error. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getnsec(dictionary * d) +{ + int i ; + int nsec ; + + if (d==NULL) return -1 ; + nsec=0 ; + for (i=0 ; i<d->size ; i++) { + if (d->key[i]==NULL) + continue ; + if (strchr(d->key[i], ':')==NULL) { + nsec ++ ; + } + } + return nsec ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get name for section n in a dictionary. + @param d Dictionary to examine + @param n Section number (from 0 to nsec-1). + @return Pointer to char string + + This function locates the n-th section in a dictionary and returns + its name as a pointer to a string statically allocated inside the + dictionary. Do not free or modify the returned string! + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ +char * iniparser_getsecname(dictionary * d, int n) +{ + int i ; + int foundsec ; + + if (d==NULL || n<0) return NULL ; + foundsec=0 ; + for (i=0 ; i<d->size ; i++) { + if (d->key[i]==NULL) + continue ; + if (strchr(d->key[i], ':')==NULL) { + foundsec++ ; + if (foundsec>n) + break ; + } + } + if (foundsec<=n) { + return NULL ; + } + return d->key[i] ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump. + @param f Opened file pointer to dump to. + @return void + + This function prints out the contents of a dictionary, one element by + line, onto the provided file pointer. It is OK to specify @c stderr + or @c stdout as output files. This function is meant for debugging + purposes mostly. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump(dictionary * d, FILE * f) +{ + int i ; + + if (d==NULL || f==NULL) return ; + for (i=0 ; i<d->size ; i++) { + if (d->key[i]==NULL) + continue ; + if (d->val[i]!=NULL) { + fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]); + } else { + fprintf(f, "[%s]=UNDEF\n", d->key[i]); + } + } + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary to a loadable ini file + @param d Dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given dictionary into a loadable ini file. + It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump_ini(dictionary * d, FILE * f) +{ + int i ; + int nsec ; + char * secname ; + + if (d==NULL || f==NULL) return ; + + nsec = iniparser_getnsec(d); + if (nsec<1) { + /* No section in file: dump all keys as they are */ + for (i=0 ; i<d->size ; i++) { + if (d->key[i]==NULL) + continue ; + fprintf(f, "%s = %s\n", d->key[i], d->val[i]); + } + return ; + } + for (i=0 ; i<nsec ; i++) { + secname = iniparser_getsecname(d, i) ; + iniparser_dumpsection_ini(d, secname, f) ; + } + fprintf(f, "\n"); + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary section to a loadable ini file + @param d Dictionary to dump + @param s Section name of dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given section of a given dictionary into a loadable ini + file. It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f) +{ + int j ; + char keym[ASCIILINESZ+1]; + int seclen ; + + if (d==NULL || f==NULL) return ; + if (! iniparser_find_entry(d, s)) return ; + + seclen = (int)strlen(s); + fprintf(f, "\n[%s]\n", s); + sprintf(keym, "%s:", s); + for (j=0 ; j<d->size ; j++) { + if (d->key[j]==NULL) + continue ; + if (!strncmp(d->key[j], keym, seclen+1)) { + fprintf(f, + "%-30s = %s\n", + d->key[j]+seclen+1, + d->val[j] ? d->val[j] : ""); + } + } + fprintf(f, "\n"); + return ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @return Number of keys in section + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getsecnkeys(dictionary * d, char * s) +{ + int seclen, nkeys ; + char keym[ASCIILINESZ+1]; + int j ; + + nkeys = 0; + + if (d==NULL) return nkeys; + if (! iniparser_find_entry(d, s)) return nkeys; + + seclen = (int)strlen(s); + sprintf(keym, "%s:", s); + + for (j=0 ; j<d->size ; j++) { + if (d->key[j]==NULL) + continue ; + if (!strncmp(d->key[j], keym, seclen+1)) + nkeys++; + } + + return nkeys; + +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @return pointer to statically allocated character strings + + This function queries a dictionary and finds all keys in a given section. + Each pointer in the returned char pointer-to-pointer is pointing to + a string allocated in the dictionary; do not free or modify them. + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ +char ** iniparser_getseckeys(dictionary * d, char * s) +{ + + char **keys; + + int i, j ; + char keym[ASCIILINESZ+1]; + int seclen, nkeys ; + + keys = NULL; + + if (d==NULL) return keys; + if (! iniparser_find_entry(d, s)) return keys; + + nkeys = iniparser_getsecnkeys(d, s); + + keys = (char**) malloc(nkeys*sizeof(char*)); + + seclen = (int)strlen(s); + sprintf(keym, "%s:", s); + + i = 0; + + for (j=0 ; j<d->size ; j++) { + if (d->key[j]==NULL) + continue ; + if (!strncmp(d->key[j], keym, seclen+1)) { + keys[i] = d->key[j]; + i++; + } + } + + return keys; + +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key + @param d Dictionary to search + @param key Key string to look for + @param def Default value to return if key not found. + @return pointer to statically allocated character string + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the pointer passed as 'def' is returned. + The returned char pointer is pointing to a string allocated in + the dictionary, do not free or modify it. + */ +/*--------------------------------------------------------------------------*/ +char * iniparser_getstring(dictionary * d, const char * key, char * def) +{ + char * lc_key ; + char * sval ; + + if (d==NULL || key==NULL) + return def ; + + lc_key = strlwc(key); + sval = dictionary_get(d, lc_key, def); + return sval ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + "42" -> 42 + "042" -> 34 (octal -> decimal) + "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(dictionary * d, const char * key, int notfound) +{ + char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==INI_INVALID_KEY) return notfound ; + return (int)strtol(str, NULL, 0); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a double + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return double + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + */ +/*--------------------------------------------------------------------------*/ +double iniparser_getdouble(dictionary * d, const char * key, double notfound) +{ + char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==INI_INVALID_KEY) return notfound ; + return atof(str); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a boolean + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + A true boolean is found if one of the following is matched: + + - A string starting with 'y' + - A string starting with 'Y' + - A string starting with 't' + - A string starting with 'T' + - A string starting with '1' + + A false boolean is found if one of the following is matched: + + - A string starting with 'n' + - A string starting with 'N' + - A string starting with 'f' + - A string starting with 'F' + - A string starting with '0' + + The notfound value returned if no boolean is identified, does not + necessarily have to be 0 or 1. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getboolean(dictionary * d, const char * key, int notfound) +{ + char * c ; + int ret ; + + c = iniparser_getstring(d, key, INI_INVALID_KEY); + if (c==INI_INVALID_KEY) return notfound ; + if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') { + ret = 1 ; + } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') { + ret = 0 ; + } else { + ret = notfound ; + } + return ret; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Finds out if a given entry exists in a dictionary + @param ini Dictionary to search + @param entry Name of the entry to look for + @return integer 1 if entry exists, 0 otherwise + + Finds out if a given entry exists in the dictionary. Since sections + are stored as keys with NULL associated values, this is the only way + of querying for the presence of sections in a dictionary. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_find_entry( + dictionary * ini, + const char * entry +) +{ + int found=0 ; + if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) { + found = 1 ; + } + return found ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Set an entry in a dictionary. + @param ini Dictionary to modify. + @param entry Entry to modify (entry name) + @param val New value to associate to the entry. + @return int 0 if Ok, -1 otherwise. + + If the given entry can be found in the dictionary, it is modified to + contain the provided value. If it cannot be found, -1 is returned. + It is Ok to set val to NULL. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_set(dictionary * ini, const char * entry, const char * val) +{ + return dictionary_set(ini, strlwc(entry), val) ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete an entry in a dictionary + @param ini Dictionary to modify + @param entry Entry to delete (entry name) + @return void + + If the given entry can be found, it is deleted from the dictionary. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_unset(dictionary * ini, const char * entry) +{ + dictionary_unset(ini, strlwc(entry)); +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Load a single line from an INI file + @param input_line Input line, may be concatenated multi-line input + @param section Output space to store section + @param key Output space to store key + @param value Output space to store value + @return line_status value + */ +/*--------------------------------------------------------------------------*/ +static line_status iniparser_line( + const char * input_line, + char * section, + char * key, + char * value) +{ + line_status sta ; + char line[ASCIILINESZ+1]; + int len ; + + strcpy(line, strstrip(input_line)); + len = (int)strlen(line); + + sta = LINE_UNPROCESSED ; + if (len<1) { + /* Empty line */ + sta = LINE_EMPTY ; + } else if (line[0]=='#' || line[0]==';') { + /* Comment line */ + sta = LINE_COMMENT ; + } else if (line[0]=='[' && line[len-1]==']') { + /* Section name */ + sscanf(line, "[%[^]]", section); + strcpy(section, strstrip(section)); + strcpy(section, strlwc(section)); + sta = LINE_SECTION ; + } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2 + || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2 + || sscanf (line, "%[^=] = %[^;#]", key, value) == 2) { + /* Usual key=value, with or without comments */ + strcpy(key, strstrip(key)); + strcpy(key, strlwc(key)); + strcpy(value, strstrip(value)); + /* + * sscanf cannot handle '' or "" as empty values + * this is done here + */ + if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) { + value[0]=0 ; + } + sta = LINE_VALUE ; + } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2 + || sscanf(line, "%[^=] %[=]", key, value) == 2) { + /* + * Special cases: + * key= + * key=; + * key=# + */ + strcpy(key, strstrip(key)); + strcpy(key, strlwc(key)); + value[0]=0 ; + sta = LINE_VALUE ; + } else { + /* Generate syntax error */ + sta = LINE_ERROR ; + } + return sta ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param ininame Name of the ini file to read. + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the name of the file to be read. It returns a dictionary object that + should not be accessed directly, but through accessor functions + instead. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary * iniparser_load(const char * ininame) +{ + FILE * in ; + + char line [ASCIILINESZ+1] ; + char section [ASCIILINESZ+1] ; + char key [ASCIILINESZ+1] ; + char tmp [ASCIILINESZ+1] ; + char val [ASCIILINESZ+1] ; + + int last=0 ; + int len ; + int lineno=0 ; + int errs=0; + + dictionary * dict ; + + if ((in=fopen(ininame, "r"))==NULL) { + fprintf(stderr, "iniparser: cannot open %s\n", ininame); + return NULL ; + } + + dict = dictionary_new(0) ; + if (!dict) { + fclose(in); + return NULL ; + } + + memset(line, 0, ASCIILINESZ); + memset(section, 0, ASCIILINESZ); + memset(key, 0, ASCIILINESZ); + memset(val, 0, ASCIILINESZ); + last=0 ; + + while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) { + lineno++ ; + len = (int)strlen(line)-1; + if (len==0) + continue; + /* Safety check against buffer overflows */ + if (line[len]!='\n') { + fprintf(stderr, + "iniparser: input line too long in %s (%d)\n", + ininame, + lineno); + dictionary_del(dict); + fclose(in); + return NULL ; + } + /* Get rid of \n and spaces at end of line */ + while ((len>=0) && + ((line[len]=='\n') || (isspace(line[len])))) { + line[len]=0 ; + len-- ; + } + /* Detect multi-line */ + if (line[len]=='\\') { + /* Multi-line value */ + last=len ; + continue ; + } else { + last=0 ; + } + switch (iniparser_line(line, section, key, val)) { + case LINE_EMPTY: + case LINE_COMMENT: + break ; + + case LINE_SECTION: + errs = dictionary_set(dict, section, NULL); + break ; + + case LINE_VALUE: + sprintf(tmp, "%s:%s", section, key); + errs = dictionary_set(dict, tmp, val) ; + break ; + + case LINE_ERROR: + fprintf(stderr, "iniparser: syntax error in %s (%d):\n", + ininame, + lineno); + fprintf(stderr, "-> %s\n", line); + errs++ ; + break; + + default: + break ; + } + memset(line, 0, ASCIILINESZ); + last=0; + if (errs<0) { + fprintf(stderr, "iniparser: memory allocation failure\n"); + break ; + } + } + if (errs) { + dictionary_del(dict); + dict = NULL ; + } + fclose(in); + return dict ; +} + +/*-------------------------------------------------------------------------*/ +/** + @brief Free all memory associated to an ini dictionary + @param d Dictionary to free + @return void + + Free all memory associated to an ini dictionary. + It is mandatory to call this function before the dictionary object + gets out of the current context. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_freedict(dictionary * d) +{ + dictionary_del(d); +} + +/* vim: set ts=4 et sw=4 tw=75 */ Added: trunk/src/dep/iniparser/iniparser.h =================================================================== --- trunk/src/dep/iniparser/iniparser.h (rev 0) +++ trunk/src/dep/iniparser/iniparser.h 2013-05-24 15:57:05 UTC (rev 326) @@ -0,0 +1,307 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file iniparser.h + @author N. Devillard + @brief Parser for ini files. +*/ +/*--------------------------------------------------------------------------*/ + +#ifndef _INIPARSER_H_ +#define _INIPARSER_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* + * The following #include is necessary on many Unixes but not Linux. + * It is not needed for Windows platforms. + * Uncomment it if needed. + */ +/* #include <unistd.h> */ + +#include "dictionary.h" + +/*-------------------------------------------------------------------------*/ +/** + @brief Get number of sections in a dictionary + @param d Dictionary to examine + @return int Number of sections found in dictionary + + This function returns the number of sections found in a dictionary. + The test to recognize sections is done on the string stored in the + dictionary: a section name is given as "section" whereas a key is + stored as "section:key", thus the test looks for entries that do not + contain a colon. + + This clearly fails in the case a section name contains a colon, but + this should simply be avoided. + + This function returns -1 in case of error. + */ +/*--------------------------------------------------------------------------*/ + +int iniparser_getnsec(dictionary * d); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Get name for section n in a dictionary. + @param d Dictionary to examine + @param n Section number (from 0 to nsec-1). + @return Pointer to char string + + This function locates the n-th section in a dictionary and returns + its name as a pointer to a string statically allocated inside the + dictionary. Do not free or modify the returned string! + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ + +char * iniparser_getsecname(dictionary * d, int n); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary to a loadable ini file + @param d Dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given dictionary into a loadable ini file. + It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_dump_ini(dictionary * d, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary section to a loadable ini file + @param d Dictionary to dump + @param s Section name of dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given section of a given dictionary into a loadable ini + file. It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump. + @param f Opened file pointer to dump to. + @return void + + This function prints out the contents of a dictionary, one element by + line, onto the provided file pointer. It is OK to specify @c stderr + or @c stdout as output files. This function is meant for debugging + purposes mostly. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump(dictionary * d, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @return Number of keys in section + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getsecnkeys(dictionary * d, char * s); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @return pointer to statically allocated character strings + + This function queries a dictionary and finds all keys in a given section. + Each pointer in the returned char pointer-to-pointer is pointing to + a string allocated in the dictionary; do not free or modify them. + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ +char ** iniparser_getseckeys(dictionary * d, char * s); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key + @param d Dictionary to search + @param key Key string to look for + @param def Default value to return if key not found. + @return pointer to statically allocated character string + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the pointer passed as 'def' is returned. + The returned char pointer is pointing to a string allocated in + the dictionary, do not free or modify it. + */ +/*--------------------------------------------------------------------------*/ +char * iniparser_getstring(dictionary * d, const char * key, char * def); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(dictionary * d, const char * key, int notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a double + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return double + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + */ +/*--------------------------------------------------------------------------*/ +double iniparser_getdouble(dictionary * d, const char * key, double notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a boolean + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + A true boolean is found if one of the following is matched: + + - A string starting with 'y' + - A string starting with 'Y' + - A string starting with 't' + - A string starting with 'T' + - A string starting with '1' + + A false boolean is found if one of the following is matched: + + - A string starting with 'n' + - A string starting with 'N' + - A string starting with 'f' + - A string starting with 'F' + - A string starting with '0' + + The notfound value returned if no boolean is identified, does not + necessarily have to be 0 or 1. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getboolean(dictionary * d, const char * key, int notfound); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Set an entry in a dictionary. + @param ini Dictionary to modify. + @param entry Entry to modify (entry name) + @param val New value to associate to the entry. + @return int 0 if Ok, -1 otherwise. + + If the given entry can be found in the dictionary, it is modified to + contain the provided value. If it cannot be found, -1 is returned. + It is Ok to set val to NULL. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_set(dictionary * ini, const char * entry, const char * val); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete an entry in a dictionary + @param ini Dictionary to modify + @param entry Entry to delete (entry name) + @return void + + If the given entry can be found, it is deleted from the dictionary. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_unset(dictionary * ini, const char * entry); + +/*-------------------------------------------------------------------------*/ +/** + @brief Finds out if a given entry exists in a dictionary + @param ini Dictionary to search + @param entry Name of the entry to look for + @return integer 1 if entry exists, 0 otherwise + + Finds out if a given entry exists in the dictionary. Since sections + are stored as keys with NULL associated values, this is the only way + of querying for the presence of sections in a dictionary. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_find_entry(dictionary * ini, const char * entry) ; + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param ininame Name of the ini file to read. + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the name of the file to be read. It returns a dictionary object that + should not be accessed directly, but through accessor functions + instead. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary * iniparser_load(const char * ininame); + +/*-------------------------------------------------------------------------*/ +/** + @brief Free all memory associated to an ini dictionary + @param d Dictionary to free + @return void + + Free all memory associated to an ini dictionary. + It is mandatory to call this function before the dictionary object + gets out of the current ... [truncated message content] |
From: <wow...@us...> - 2013-07-04 17:03:58
|
Revision: 333 http://sourceforge.net/p/ptpd/code/333 Author: wowczarek Date: 2013-07-04 17:03:52 +0000 (Thu, 04 Jul 2013) Log Message: ----------- Jumbo patch for pre-2.3, major rework. New features: - Configuration file support, multiple previously unsupported options - Rewritten command line parameter handling, new parameters - Command line options to print default configuration, print lock file, check configuration and more, - Full help (-H) for all configuration options, - Configuration reload support with SIGHUP, - Rewritten logging subsystem, - Separate log file and statistics file, SIGHUP reprints the headers, So if logrotate moves files around and calls SIGUP in the end, header is always at the very top of the file, - Support for mode and interface specific lock files - Network interface checks before startup and during config reload (if interface changed), - Added ./configure --sigusr2=counters - will dump PTP engine counters to current log target when SIGUSR2 received, - Support for presets - groups of PTP protocol options defining ptpd behaviour: presets available: slaveonly, masteronly, masterslave - Support for tick adjustment as well as frequency, maximum frequency offset is now configurable and can be above 512 ppm - tick is used above 512 ppm, - Added a compatibility option to always honour the UTC offset announced by a GM when in slave state - useful for some GMs - Added an announce receipt timeout "grace period" for slave state - slave can wait n times timeout without fully resetting - allows a seamless failover without resetting delay values etc., - Added support for DELAY_DISABLED delay mode - syntonisation only, - Ptpd now has initial support for informing the clock subsystem about the sync status: STA_UNSYNC is unset when adjusting the clock (allows syncing hardware RTC clocks with the system clock) - also maxerror and esterror are set, - Support for legacy command line switches from previous versions - warning will be issued if usesd, - Configurable log level for normal logs, not only debug logs. Bug fixes: - TTL no longer defaults to 64 in P2P mode - in P2P it's set to 1, - Fixed an issue whereby observed drift would be reset to 0 if it could not be read from the drift file (empty or nonexistent drift file), now the kernel value is used if read from file fails. Cleanups and other changes: - Major startup.c cleanup, removed the parallel daemon checks, in favour of better lock handling and the automatic lock file name support, - Some minor refactoring, - Added a TimePropertiesDS structure and removed its fields from PtpClock - Improved log file format with full date and interface name, removed the "===" indents - Delay Request interval no longer mandatory in hybrid mode, but a warning will be issued if it's not explicitly defined - default of 0 is used, - Removed the experimental status of hybrid mode, - Manual stepping of the clock no longer just resets the observed drift: resets it or restores it based on the drift handling setting, and sets the time immediately before writing any logs - this allows to re-sync and stabilise time almost instantly Modified Paths: -------------- trunk/COPYRIGHT 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/datatypes_dep.h trunk/src/dep/iniparser/dictionary.c trunk/src/dep/iniparser/dictionary.h trunk/src/dep/iniparser/iniparser.c trunk/src/dep/msg.c trunk/src/dep/net.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.c trunk/src/ptpd.h Added Paths: ----------- trunk/src/def/derivedData/timePropertiesDS.def trunk/src/dep/daemonconfig.c trunk/src/dep/daemonconfig.h trunk/src/ptpd2.conf.default-full trunk/src/ptpd2.conf.minimal Modified: trunk/COPYRIGHT =================================================================== --- trunk/COPYRIGHT 2013-06-25 17:38:10 UTC (rev 332) +++ trunk/COPYRIGHT 2013-07-04 17:03:52 UTC (rev 333) @@ -1,9 +1,12 @@ /*- - * Copyright (c) 2013 Harlan Stenn + * Copyright (c) 2013 Harlan Stenn, + * George N. Neville-Neil, + * Wojciech Owczarek * Copyright (c) 2011-2012 George V. Neville-Neil, * Steven Kreuzer, * Martin Burnicki, * Jan Breuer, + * Wojciech Owczarek, * Gael Mace, * Alexandre Van Kempen, * Inaqui Delgado, Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-06-25 17:38:10 UTC (rev 332) +++ trunk/configure.ac 2013-07-04 17:03:52 UTC (rev 333) @@ -11,7 +11,7 @@ [PTPD_URL]dnl ) AC_CONFIG_SRCDIR([src/arith.c]) -AC_CONFIG_HEADER([src/config.h]) +AC_CONFIG_HEADER([config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) @@ -144,7 +144,7 @@ # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/ether.h netinet/in.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h]) +AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h netinet/ether.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h glob.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -252,8 +252,8 @@ AC_ARG_ENABLE( [sigusr2], [AS_HELP_STRING( - [--enable-sigusr2={domain,debug}], - [Enable SIGUSR2 support, cycle PTP domain #, or debug level (disabled by default)] + [--enable-sigusr2={domain,debug,counters}], + [Enable SIGUSR2 support to: cycle PTP domain #, debug level or dump PTP engine counters (disabled by default)] )], [ptp_sigusr2=$enableval], [ptp_sigusr2=no] @@ -267,6 +267,9 @@ # We could/should check to be sure that RUNTIME_DEBUG is set... PTP_SIGUSR2="-DDBG_SIGUSR2_CHANGE_DEBUG" ;; + counters) + PTP_SIGUSR2="-DDBG_SIGUSR2_DUMP_COUNTERS" + ;; esac AC_SUBST(PTP_SIGUSR2) Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2013-06-25 17:38:10 UTC (rev 332) +++ trunk/src/Makefile.am 2013-07-04 17:03:52 UTC (rev 333) @@ -31,6 +31,8 @@ dep/iniparser/iniparser.h \ dep/iniparser/dictionary.c \ dep/iniparser/iniparser.c \ + dep/daemonconfig.h \ + dep/daemonconfig.c \ dep/startup.c \ dep/sys.c \ dep/timer.c \ Modified: trunk/src/bmc.c =================================================================== --- trunk/src/bmc.c 2013-06-25 17:38:10 UTC (rev 332) +++ trunk/src/bmc.c 2013-07-04 17:03:52 UTC (rev 333) @@ -90,9 +90,10 @@ ptpClock->priority2 = rtOpts->priority2; ptpClock->domainNumber = rtOpts->domainNumber; - ptpClock->slaveOnly = rtOpts->slaveOnly; - if(rtOpts->slaveOnly) + if(rtOpts->slaveOnly) { + ptpClock->slaveOnly = TRUE; rtOpts->clockQuality.clockClass = SLAVE_ONLY_CLOCK_CLASS; + } /* Port configuration data set */ @@ -113,7 +114,7 @@ ptpClock->announceReceiptTimeout = rtOpts->announceReceiptTimeout; ptpClock->logSyncInterval = rtOpts->syncInterval; ptpClock->delayMechanism = rtOpts->delayMechanism; - ptpClock->logMinPdelayReqInterval = DEFAULT_PDELAYREQ_INTERVAL; + ptpClock->logMinPdelayReqInterval = rtOpts->logMinPdelayReqInterval; ptpClock->versionNumber = VERSION_PTP; /* @@ -157,12 +158,12 @@ ptpClock->grandmasterPriority2 = ptpClock->priority2; /*Time Properties data set*/ - ptpClock->timeSource = INTERNAL_OSCILLATOR; - - /* UTC vs TAI timescales */ - ptpClock->currentUtcOffsetValid = DEFAULT_UTC_VALID; - ptpClock->currentUtcOffset = rtOpts->currentUtcOffset; - + ptpClock->timePropertiesDS.currentUtcOffsetValid = rtOpts->timeProperties.currentUtcOffsetValid; + ptpClock->timePropertiesDS.currentUtcOffset = rtOpts->timeProperties.currentUtcOffset; + ptpClock->timePropertiesDS.timeTraceable = rtOpts->timeProperties.timeTraceable; + ptpClock->timePropertiesDS.frequencyTraceable = rtOpts->timeProperties.frequencyTraceable; + ptpClock->timePropertiesDS.ptpTimescale = rtOpts->timeProperties.ptpTimescale; + ptpClock->timePropertiesDS.timeSource = rtOpts->timeProperties.timeSource; } @@ -171,8 +172,8 @@ { /* make sure we revert to ARB timescale in Passive mode*/ if(ptpClock->portState == PTP_PASSIVE){ - ptpClock->currentUtcOffsetValid = DEFAULT_UTC_VALID; - ptpClock->currentUtcOffset = rtOpts->currentUtcOffset; + ptpClock->timePropertiesDS.currentUtcOffsetValid = rtOpts->timeProperties.currentUtcOffsetValid; + ptpClock->timePropertiesDS.currentUtcOffset = rtOpts->timeProperties.currentUtcOffset; } } @@ -186,9 +187,9 @@ Integer16 previousUtcOffset = 0; if (ptpClock->portState == PTP_SLAVE) { - previousLeap59 = ptpClock->leap59; - previousLeap61 = ptpClock->leap61; - previousUtcOffset = ptpClock->currentUtcOffset; + previousLeap59 = ptpClock->timePropertiesDS.leap59; + previousLeap61 = ptpClock->timePropertiesDS.leap61; + previousUtcOffset = ptpClock->timePropertiesDS.currentUtcOffset; } /* Current DS */ @@ -211,40 +212,44 @@ ptpClock->grandmasterPriority2 = announce->grandmasterPriority2; /* Timeproperties DS */ - ptpClock->currentUtcOffset = announce->currentUtcOffset; + ptpClock->timePropertiesDS.currentUtcOffset = announce->currentUtcOffset; + if (ptpClock->timePropertiesDS.currentUtcOffsetValid && !IS_SET(header->flagField1, UTCV)) { + WARNING("UTC Offset no longer valid. Clock may jump unless ptpengine:always_respect_utc_offset is set\n"); + } + /* "Valid" is bit 2 in second octet of flagfield */ - ptpClock->currentUtcOffsetValid = IS_SET(header->flagField1, UTCV); + ptpClock->timePropertiesDS.currentUtcOffsetValid = IS_SET(header->flagField1, UTCV); /* set PTP_PASSIVE-specific state */ p1(ptpClock, rtOpts); /* only set leap state in slave mode */ if (ptpClock->portState == PTP_SLAVE) { - ptpClock->leap59 = IS_SET(header->flagField1, LI59); - ptpClock->leap61 = IS_SET(header->flagField1, LI61); + ptpClock->timePropertiesDS.leap59 = IS_SET(header->flagField1, LI59); + ptpClock->timePropertiesDS.leap61 = IS_SET(header->flagField1, LI61); } - ptpClock->timeTraceable = IS_SET(header->flagField1, TTRA); - ptpClock->frequencyTraceable = IS_SET(header->flagField1, FTRA); - ptpClock->ptpTimescale = IS_SET(header->flagField1, PTPT); - ptpClock->timeSource = announce->timeSource; + ptpClock->timePropertiesDS.timeTraceable = IS_SET(header->flagField1, TTRA); + ptpClock->timePropertiesDS.frequencyTraceable = IS_SET(header->flagField1, FTRA); + ptpClock->timePropertiesDS.ptpTimescale = IS_SET(header->flagField1, PTPT); + ptpClock->timePropertiesDS.timeSource = announce->timeSource; #if defined(MOD_TAI) && NTP_API == 4 /* * update kernel TAI offset, but only if timescale is * PTP not ARB - spec section 7.2 */ - if (ptpClock->ptpTimescale && - (ptpClock->currentUtcOffset != previousUtcOffset)) { - setKernelUtcOffset(ptpClock->currentUtcOffset); + if (ptpClock->timePropertiesDS.ptpTimescale && + (ptpClock->timePropertiesDS.currentUtcOffset != previousUtcOffset)) { + setKernelUtcOffset(ptpClock->timePropertiesDS.currentUtcOffset); } #endif /* MOD_TAI */ /* Leap second handling */ if (ptpClock->portState == PTP_SLAVE) { - if(ptpClock->leap59 && ptpClock->leap61) { + if(ptpClock->timePropertiesDS.leap59 && ptpClock->timePropertiesDS.leap61) { DBG("Both Leap59 and Leap61 flags set!\n"); ptpClock->counters.protocolErrors++; return; @@ -253,9 +258,9 @@ /* one of the leap second flags has suddenly been unset */ if(ptpClock->leapSecondPending && !ptpClock->leapSecondInProgress && - ((previousLeap59 != ptpClock->leap59) || - (previousLeap61 != ptpClock->leap61))) { - WARNING(INFO_PREFIX "Leap second event aborted by GM!"); + ((previousLeap59 != ptpClock->timePropertiesDS.leap59) || + (previousLeap61 != ptpClock->timePropertiesDS.leap61))) { + WARNING("Leap second event aborted by GM!"); ptpClock->leapSecondPending = FALSE; ptpClock->leapSecondInProgress = FALSE; timerStop(LEAP_SECOND_PAUSE_TIMER, ptpClock->itimer); @@ -268,23 +273,23 @@ * one of the leap second flags has been set * or flags are lit but we have no event pending */ - if( (ptpClock->leap59 || ptpClock->leap61) && ( + if( (ptpClock->timePropertiesDS.leap59 || ptpClock->timePropertiesDS.leap61) && ( (!ptpClock->leapSecondPending && !ptpClock->leapSecondInProgress ) || - ((!previousLeap59 && ptpClock->leap59) || - (!previousLeap61 && ptpClock->leap61)))) { + ((!previousLeap59 && ptpClock->timePropertiesDS.leap59) || + (!previousLeap61 && ptpClock->timePropertiesDS.leap61)))) { #if !defined(__APPLE__) - WARNING(INFO_PREFIX "Leap second pending! Setting kernel to %s " + WARNING("Leap second pending! Setting kernel to %s " "one second at midnight\n", - ptpClock->leap61 ? "add" : "delete"); - if (!checkTimexFlags(ptpClock->leap61 ? STA_INS : STA_DEL)) { - unsetTimexFlags(ptpClock->leap61 ? STA_DEL : STA_INS, + ptpClock->timePropertiesDS.leap61 ? "add" : "delete"); + if (!checkTimexFlags(ptpClock->timePropertiesDS.leap61 ? STA_INS : STA_DEL)) { + unsetTimexFlags(ptpClock->timePropertiesDS.leap61 ? STA_DEL : STA_INS, TRUE); - setTimexFlags(ptpClock->leap61 ? STA_INS : STA_DEL, + setTimexFlags(ptpClock->timePropertiesDS.leap61 ? STA_INS : STA_DEL, FALSE); } #else - WARNING(INFO_PREFIX "Leap second pending! No kernel leap second " + WARNING("Leap second pending! No kernel leap second " "API support - expect a clock jump at " "midnight!\n"); #endif /* apple */ @@ -292,15 +297,15 @@ ptpClock->leapSecondPending = TRUE; } - if((previousUtcOffset != ptpClock->currentUtcOffset) && + if((previousUtcOffset != ptpClock->timePropertiesDS.currentUtcOffset) && !ptpClock->leapSecondPending && !ptpClock->leapSecondInProgress ) { - WARNING(INFO_PREFIX "UTC offset changed from %d to %d with " + WARNING("UTC offset changed from %d to %d with " "no leap second pending!\n", - previousUtcOffset, ptpClock->currentUtcOffset); - } else if( previousUtcOffset != ptpClock->currentUtcOffset) { - WARNING(INFO_PREFIX "UTC offset changed from %d to %d\n", - previousUtcOffset,ptpClock->currentUtcOffset); + previousUtcOffset, ptpClock->timePropertiesDS.currentUtcOffset); + } else if( previousUtcOffset != ptpClock->timePropertiesDS.currentUtcOffset) { + WARNING("UTC offset changed from %d to %d\n", + previousUtcOffset,ptpClock->timePropertiesDS.currentUtcOffset); } } } @@ -453,7 +458,7 @@ ptpClock->parentPortIdentity.clockIdentity,CLOCK_IDENTITY_LENGTH)) || (header->sourcePortIdentity.portNumber != ptpClock->parentPortIdentity.portNumber)); - if (rtOpts->slaveOnly) { + if (ptpClock->slaveOnly) { s1(header,announce,ptpClock, rtOpts); if (newBM) { displayPortIdentity(&header->sourcePortIdentity, Modified: trunk/src/constants.h =================================================================== --- trunk/src/constants.h 2013-06-25 17:38:10 UTC (rev 332) +++ trunk/src/constants.h 2013-07-04 17:03:52 UTC (rev 333) @@ -140,7 +140,7 @@ /** * \brief Network Protocol (Table 3 in the spec)*/ enum { - UDP_IPV4=1,UDP_IPV6,IEE_802_3,DeviceNet,ControlNet,PROFINET + UDP_IPV4=1,UDP_IPV6,IEEE_802_3,DeviceNet,ControlNet,PROFINET }; /** Modified: trunk/src/datatypes.h =================================================================== --- trunk/src/datatypes.h 2013-06-25 17:38:10 UTC (rev 332) +++ trunk/src/datatypes.h 2013-07-04 17:03:52 UTC (rev 333) @@ -2,6 +2,7 @@ #define DATATYPES_H_ #include <stdio.h> +#include <dep/iniparser/dictionary.h> /*Struct defined in spec*/ @@ -62,6 +63,14 @@ } ClockQuality; /** +* \brief The TimePropertiesDS type represent time source and traceability properties of a clock + */ +typedef struct { + #define OPERATE( name, size, type ) type name; + #include "def/derivedData/timePropertiesDS.def" +} TimePropertiesDS; + +/** * \brief The TLV type represents TLV extension fields */ typedef struct { @@ -557,7 +566,6 @@ TimeInternal offsetFromMaster; TimeInternal meanPathDelay; - /* Parent data set */ /*Dynamic members*/ @@ -571,18 +579,11 @@ UInteger8 grandmasterPriority2; /* Global time properties data set */ + TimePropertiesDS timePropertiesDS; - /*Dynamic members*/ - Integer16 currentUtcOffset; - Boolean currentUtcOffsetValid; - Boolean leap59; - Boolean leap61; - Boolean timeTraceable; - Boolean frequencyTraceable; - Boolean ptpTimescale; + /* Leap second related flags */ Boolean leapSecondInProgress; Boolean leapSecondPending; - Enumeration8 timeSource; /* Port configuration data set */ @@ -685,7 +686,11 @@ /*Usefull to init network stuff*/ UInteger8 port_communication_technology; + /*Stats header will be re-printed when set to true*/ + Boolean resetStatisticsLog; + int reset_count; + int announceTimeouts; int current_init_clock; int can_step_clock; int warned_operator_slow_slewing; @@ -706,11 +711,9 @@ /* user description is max size + 1 to leave space for a null terminator */ Octet user_description[USER_DESCRIPTION_MAX + 1]; -#ifdef PTPD_EXPERIMENTAL + Integer32 MasterAddr; // used for hybrid mode, when receiving announces Integer32 LastSlaveAddr; // used for hybrid mode, when receiving delayreqs -#endif - Integer32 discardedPacketCount; // used for autotuning the maxDelay threshold /* * counters - useful for debugging and monitoring, @@ -737,25 +740,37 @@ typedef struct { Integer8 announceInterval; Integer8 announceReceiptTimeout; - + Boolean slaveOnly; Integer8 syncInterval; + Integer8 logMinPdelayReqInterval; ClockQuality clockQuality; + TimePropertiesDS timeProperties; UInteger8 priority1; UInteger8 priority2; UInteger8 domainNumber; +// UInteger8 timeSource; #ifdef PTPD_EXPERIMENTAL UInteger8 mcast_group_Number; #endif - Boolean slaveOnly; - Integer16 currentUtcOffset; + /* + * For slave state, grace period of n * announceReceiptTimeout + * before going into LISTENING again - we disqualify the best GM + * and keep waiting for BMC to act - if a new GM picks up, + * we don't lose the calculated offsets etc. Allows seamless GM + * failover with little time variation + */ + + int announceTimeoutGracePeriod; +// Integer16 currentUtcOffset; + Octet ifaceName[IFACE_NAME_LENGTH]; Boolean noResetClock; Integer32 maxReset; /* Maximum number of nanoseconds to reset */ Integer32 maxDelay; /* Maximum number of nanoseconds of delay */ Integer32 origMaxDelay; /* Lower bound of nanoseconds of delay */ Boolean noAdjust; - Boolean displayStats; + Boolean displayPackets; Octet unicastAddress[MAXHOSTNAMELEN]; Integer32 ap, ai; @@ -764,27 +779,42 @@ Integer16 max_foreign_records; Enumeration8 delayMechanism; Boolean offset_first_updated; + int ttl; + Boolean alwaysRespectUtcOffset; + Boolean useSysLog; + Boolean checkConfigOnly; + Boolean printLockFile; + char configFile[PATH_MAX]; - char file[PATH_MAX]; - int logFd; - Boolean useSysLog; - int ttl; + + char logFile[PATH_MAX]; + FILE *logFP; + Boolean useLogFile; + int logLevel; + + char statisticsFile[PATH_MAX]; + FILE *statisticsFP; + Boolean useStatisticsFile; + Boolean logStatistics; + char recordFile[PATH_MAX]; FILE *recordFP; + Boolean useRecordFile; - int log_seconds_between_message; + int statisticsInterval; Boolean ignore_daemon_lock; Boolean do_IGMP_refresh; - int nonDaemon; - Boolean do_log_to_file; - Boolean do_record_quality_file; - + Boolean nonDaemon; + int initial_delayreq; int subsequent_delayreq; Boolean ignore_delayreq_interval_master; - Boolean syslog_startup_messages_also_to_stdout; + Boolean autoLockFile; /* mode and interface specific lock files are used + * when set to TRUE */ + char lockDirectory[PATH_MAX]; /* Directory to store lock files + * When automatic lock files used */ char lockFile[PATH_MAX]; /* lock file location */ char driftFile[PATH_MAX]; /* drift file location */ int drift_recovery_method; /* how the observed drift is managed @@ -801,6 +831,21 @@ int debug_level; #endif Boolean jobid; /* use jobid aka PID for UUID */ + + /** + * This field holds the flags denoting which subsystems + * have to be re-initialised as a result of config reload. + * Flags are defined in daemonconfig.h + * 0 = no change + */ + int restartSubsystems; + /* config dictionary containers - current and candidate */ + dictionary *currentConfig, *candidateConfig; + + int selectedPreset; + + int servoMaxPpb; + } RunTimeOpts; #endif /*DATATYPES_H_*/ Added: trunk/src/def/derivedData/timePropertiesDS.def =================================================================== --- trunk/src/def/derivedData/timePropertiesDS.def (rev 0) +++ trunk/src/def/derivedData/timePropertiesDS.def 2013-07-04 17:03:52 UTC (rev 333) @@ -0,0 +1,13 @@ +/* Spec 8.2.4 timePropertiesDS */ + +/* to use these definitions, #define OPERATE then #include this file in your source */ +OPERATE( currentUtcOffset, 2, UInteger16 ) +OPERATE( currentUtcOffsetValid, 1, Boolean ) +OPERATE( leap59, 2, Boolean ) +OPERATE( leap61, 1, Boolean ) +OPERATE( timeTraceable, 1, Boolean ) +OPERATE( frequencyTraceable, 1, Boolean ) +OPERATE( ptpTimescale, 1, Boolean ) +OPERATE( timeSource, 1, Enumeration8 ) + +#undef OPERATE Modified: trunk/src/dep/constants_dep.h =================================================================== --- trunk/src/dep/constants_dep.h 2013-06-25 17:38:10 UTC (rev 332) +++ trunk/src/dep/constants_dep.h 2013-07-04 17:03:52 UTC (rev 333) @@ -104,13 +104,21 @@ #define PTP_ETHER_TYPE 0x88f7 #define PTP_ETHER_PEER "01:80:c2:00:00:0E" +/* dummy clock driver designation in preparation for generic clock driver API */ +#define DEFAULT_CLOCKDRIVER "kernelclock" /* default lock file location and mode */ -#define DEFAULT_LOCKFILE "/var/run/kernel_clock" -#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) +#define DEFAULT_LOCKMODE F_WRLCK +#define DEFAULT_LOCKDIR "/var/run" +#define DEFAULT_LOCKFILE_NAME PTPD_PROGNAME".lock" +//define DEFAULT_LOCKFILE_PATH DEFAULT_LOCKDIR"/"DEFAULT_LOCKFILE_NAME +#define DEFAULT_UMASK (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) /* default drift file location */ -#define DEFAULT_DRIFTFILE "/etc/ptpd_osclock.drift" +#define DEFAULT_DRIFTFILE "/etc/"PTPD_PROGNAME"_"DEFAULT_CLOCKDRIVER".drift" +/* Highest log level (default) catches all */ +#define LOG_ALL LOG_DEBUGV + /* drift recovery metod for use with -F */ enum { DRIFT_RESET = 0, @@ -121,19 +129,11 @@ enum { IPMODE_MULTICAST = 0, IPMODE_UNICAST, -#ifdef PTPD_EXPERIMENTAL IPMODE_HYBRID, +#if 0 + IPMODE_UNICAST_SIGNALING #endif - IPMODE_UNICAST_SIGNALING }; -/* Transport type */ -enum { - TRANSPORT_IP = 0, - TRANSPORT_ETHERNET -}; - - - #define MM_STARTING_BOUNDARY_HOPS 0x7fff /* others */ Added: trunk/src/dep/daemonconfig.c =================================================================== --- trunk/src/dep/daemonconfig.c (rev 0) +++ trunk/src/dep/daemonconfig.c 2013-07-04 17:03:52 UTC (rev 333) @@ -0,0 +1,2144 @@ +/*- + * Copyright (c) 2013 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 daemonconfig.c + * @date Sun May 27 00:45:32 2013 + * + * @brief Code to handle configuration file and default settings + * + * Functions in this file deal with config file parsing, reloading, + * loading default parameters, parsing command-line options, printing + * help output, etc. + * + */ + +#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. + * This allows the parseConfig() function to be very straightforward and easy to expand + * - it pretty much only uses macros at this stage. The use of macros reduces the + * complexity of the parseConfig fuction. A lot of the macros are designed to work + * within parseConfig - they assume the existence of the "dictionary*" dict variable. + */ + + +/* Basic helper macros */ + +#define STRING_EMPTY(string)\ + (!strcmp(string,"")) + +#define CONFIG_ISSET(key) \ + (strcmp(iniparser_getstring(dict, key, ""),"") != 0) + +#define CONFIG_ISTRUE(key) \ + (iniparser_getboolean(dict,key,FALSE)==TRUE) + +#define DICT_ISTRUE(dict,key) \ + (iniparser_getboolean(dict,key,FALSE)==TRUE) + + +/* + * 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 + */ + +#define SET_QUIET() \ + dictionary_set(dict,"%quiet%:%quiet%","Y"); + +#define END_QUIET() \ + dictionary_unset(dict,"%quiet%:%quiet%"); + +#define IS_QUIET()\ + ( CONFIG_ISTRUE("%quiet%:%quiet%") ) + +#define SET_SHOWDEFAULT() \ + SET_QUIET();\ + dictionary_set(dict,"%showdefault%:%showdefault%","Y"); + +#define END_SHOWDEFAULT() \ + END_QUIET();\ + dictionary_unset(dict,"%showdefault%:%showdefault%"); + +#define IS_SHOWDEFAULT()\ + ( CONFIG_ISTRUE("%showdefault%:%showdefault%") ) + +#define HELP_START() \ + SET_QUIET();\ + dictionary_set(dict,"%helponly%:%helponly%","T"); + +#define HELP_ITEM(key) \ + SET_QUIET();\ + dictionary_set(dict,"%helponly%:%helpitem%",key); + +#define HELP_ITEM_COMPLETE() \ + dictionary_set(dict,"%helponly%:%helpitem%","%complete%"); + +#define HELP_ITEM_FOUND() \ + (strcmp(iniparser_getstring(dict, "%helponly%:%helpitem%" , ""),"%complete%") == 0) + +#define HELP_END() \ + dictionary_unset(dict,"%helponly%:%helponly%");\ + dictionary_unset(dict,"%helponly%:%helpitem%");\ + END_QUIET(); + +#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) )\ + { \ + ERROR("Configuration error: option \"%s\" is required\n", key); \ + parseResult = FALSE;\ + } + +#define CONFIG_KEY_DEPENDENCY(key1, key2) \ + if( CONFIG_ISSET(key1) && \ + !CONFIG_ISSET(key2)) \ + { \ + if(!IS_QUIET())\ + ERROR("Configuration error: option \"%s\" requires option \"%s\"\n", key1, key2); \ + parseResult = FALSE;\ + } + +#define CONFIG_KEY_CONFLICT(key1, key2) \ + if( CONFIG_ISSET(key1) && \ + CONFIG_ISSET(key2)) \ + { \ + if(!IS_QUIET())\ + ERROR("Configuration error: option \"%s\" cannot be used with option \"%s\"\n", key1, key2); \ + parseResult = FALSE;\ + } + +#define CONFIG_KEY_CONDITIONAL_WARNING(condition,dep,messageText) \ + if ( (condition) && \ + !CONFIG_ISSET(dep) ) \ + { \ + if(!IS_QUIET())\ + WARNING("Warning: %s\n", messageText); \ + } + +#define CONFIG_KEY_CONDITIONAL_DEPENDENCY(key,condition,stringval,dep) \ + if ( (condition) && \ + !CONFIG_ISSET(dep) ) \ + { \ + if(!IS_QUIET())\ + ERROR("Configuration error: option \"%s=%s\" requires option \"%s\"\n", key, stringval, dep); \ + parseResult = FALSE;\ + } + +#define CONFIG_KEY_CONDITIONAL_CONFLICT(key,condition,stringval,dep) \ + if ( (condition) && \ + CONFIG_ISSET(dep) ) \ + { \ + if(!IS_QUIET())\ + ERROR("Configuration error: option \"%s=%s\" cannot be used with option \"%s\"\n", key, stringval, dep); \ + parseResult = FALSE;\ + } + +#define CONFIG_KEY_TRIGGER(key,variable,value, otherwise) \ + if (CONFIG_ISSET(key) ) \ + { \ + variable = value;\ + } else { \ + variable = otherwise;\ + } + +#define CONFIG_KEY_CONDITIONAL_TRIGGER(condition,variable,value,otherwise) \ + if ((condition)) \ + { \ + variable = value; \ + } else { \ + variable = otherwise; \ + } + + +/* 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); \ + 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_ISSET(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(iniparser_getboolean(dict,key,default) == -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,""));\ + 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)", 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 {\ + if ( (variable = selectKeyValue(\ + dict, key, default,NUMARGS(__VA_ARGS__),\ + __VA_ARGS__\ + )) == -1) {\ + variable = default;\ + parseResult = FALSE;\ + }\ + {\ + 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",\ + old, comment, new, long, key); + +#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;\ + } + +/* concatenate every second vararg argument for string, int pairs and print it */ +static void +printKeyOptions( int count, ... ) +{ + + + char *optionvalue; + va_list va; + int i, optionnumber; + + /* if we got an incomplete argument list, cut it down to the last pair or nothing */ + if(count % 2 == 1) { + + count--; + + } + + count/=2; + + va_start(va, count); + + for(i = 0; i < count; i++) { + + optionvalue = (char *)va_arg(va, char *); + optionnumber = (int)va_arg(va, int); + + printf("%s ", optionvalue); + + } + + va_end(va); + +} + +/* 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, ... ) +{ + + char sbuf[SCREEN_BUFSZ]; + int len = 0; + + char *keyvalue, *optionvalue; + va_list va; + int ret, i, optionnumber; + + /* if we got an incomplete argument list, cut it down to the last pair or nothing */ + if(count % 2 == 1) { + + count--; + + } + + count/=2; + + if ( !CONFIG_ISSET(keyname) ) { + ret = default_option; + goto end; + } + + memset(sbuf, 0, sizeof(sbuf)); + + keyvalue = iniparser_getstring(dict, keyname, ""); + + va_start(va, count); + + for(i = 0; i < count; i++) { + + optionvalue = (char *)va_arg(va, char *); + optionnumber = (int)va_arg(va, int); + + len += snprintf(sbuf + len, sizeof(sbuf) - len, "%s ", optionvalue); + + if ( strcmp(keyvalue, optionvalue) == 0) { + + ret = optionnumber; + goto end; /* must call va_end */ + + } + + } + + ERROR("Configuration error: option \"%s\" has unknown value: %s - allowed values: %s\n", keyname, keyvalue,sbuf); + + ret = -1; + +end: + + va_end(va); + return ret; + +} + +/* Return the string value for the given number value of string, int pairs */ +static char* +selectOptionName( int value, int count, ... ) +{ + 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) { + + count--; + + } + + ret = "[none]"; + + count/=2; + + va_start(va, count); + + for(i = 0; i < count; i++) { + + optionvalue = (char *)va_arg(va, char *); + optionnumber = (int)va_arg(va, int); + + if ( optionnumber == value ) { + + ret = optionvalue; + goto end; /* must call va_end */ + + } + + } + +end: + + va_end(va); + return ret; + +} + +/* 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; + } + } + } + } + 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->announceInterval = DEFAULT_ANNOUNCE_INTERVAL; + rtOpts->syncInterval = 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->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 = FALSE; + +#ifdef PTPD_EXPERIMENTAL + rtOpts->mcast_group_Number = 0; +#endif + rtOpts->ip_mode = IPMODE_MULTICAST; + + + rtOpts->noAdjust = NO_ADJUST; // false + rtOpts->logStatistics = TRUE; + /* Deep display of all packets seen by the daemon */ + rtOpts->displayPackets = FALSE; + // rtOpts->unicastAddress + rtOpts->ap = DEFAULT_AP; + rtOpts->ai = DEFAULT_AI; + 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->offset_first_updated = FALSE; + rtOpts->logFP = NULL; + rtOpts->recordFP = NULL; + rtOpts->statisticsFP = NULL; + rtOpts->useLogFile = FALSE; + rtOpts->useRecordFile = FALSE; + 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->statisticsInterval = 0; + + rtOpts->initial_delayreq = DEFAULT_DELAYREQ_INTERVAL; + rtOpts->subsequent_delayreq = DEFAULT_DELAYREQ_INTERVAL; // this will be updated if -g is given + + 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 */ + rtOpts->slaveOnly = FALSE; + /* Otherwise default to slave only via the preset */ + rtOpts->selectedPreset = PTP_PRESET_SLAVEONLY; + rtOpts->jobid=FALSE; + + /* highest possible */ + rtOpts->logLevel = LOG_ALL; + + /* ADJ_FREQ_MAX by default */ + rtOpts->servoMaxPpb = ADJ_FREQ_MAX / 1000; + + /* disabled by default */ + rtOpts->announceTimeoutGracePeriod = 0; + rtOpts->alwaysRespectUtcOffset=FALSE; + +} + +/* The PtpEnginePreset structure: + +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; +} + +/** + * Iterate through dictionary dict (template) and check for keys in source + * that are not present in the template - display only. + */ +static void +findUnknownSettings(dictionary* source, dictionary* dict) +{ + + int i = 0; + + if( source == NULL || dict == NULL) return; + + for(i = 0; i < source->n; i++) { + /* 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() ) + WARNING("Unknown configuration entry: %s - setting will be ignored\n", source->key[i]); + } +} + +/* + * IT HAPPENS HERE + * + * Map all options from @dict dictionary to corresponding @rtopts fields, + * using existing @rtopts fields as defaults. Return a dictionary free + * of unknown options, with explicitly set defaults. + * NOTE: when adding options, also map them in checkSubsystemRestart to + * ensure correct config reload behaviour. + */ +dictionary* +parseConfig ( dictionary* dict, RunTimeOpts *rtOpts ) +{ + +/*- + * This function assumes that rtOpts has got all the defaults loaded, + * hence the default values for all options are taken from rtOpts. + * 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 + * you check it for inconsistencies. If we decide to + * drop all short options in favour of section:key only, + * this warning can be removed. + */ + /** + * Prepare the target dictionary. Every mapped option will be set in + * the target dictionary, including the defaults which are typically + * not present in the original dictionary. As a result, the target + * will contain all the mapped options with explicitly set defaults + * if they were not present in the original dictionary. In the end + * of this function we return this pointer. The resulting dictionary + * 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; + + PtpEnginePreset ptpPreset; + + if(!IS_QUIET()) { + INFO("Checking configuration\n"); + } + +/* ============= BEGIN CONFIG MAPPINGS, TRIGGERS AND DEPENDENCIES =========== */ + +/* ===== ptpengine section ===== */ + + CONFIG_KEY_REQUIRED("ptpengine:interface"); + + CONFIG_MAP_CHARARRAY("ptpengine:interface",rtOpts->ifaceName,rtOpts->ifaceName, + "Network interface to use (required)"); + + /* Preset option names have to be mapped to defined presets - no free strings here */ + CONFIG_MAP_SELECTVALUE("ptpengine:preset",rtOpts->selectedPreset,rtOpts->selectedPreset, + "PTP engine preset:\n" + " none = Defaults, no clock class restrictions\n" + " slaveonly = Slave only (clock class 255 only)\n" + " masteronly = Master, passive when not best master (clock class 0..127)\n" + " masterslave = Full IEEE 1588 implementation:\n" + " Master, slave when not best master\n" + " (clock class 128..254)\n", + (getPtpPreset(PTP_PRESET_NONE,rtOpts)).presetName, PTP_PRESET_NONE, + (getPtpPreset(PTP_PRESET_SLAVEONLY,rtOpts)).presetName, PTP_PRESET_SLAVEONLY, + (getPtpPreset(PTP_PRESET_MASTERONLY,rtOpts)).presetName, PTP_PRESET_MASTERONLY, + (getPtpPreset(PTP_PRESET_MASTERSLAVE,rtOpts)).presetName, PTP_PRESET_MASTERSLAVE + ); + + ptpPreset = getPtpPreset(rtOpts->selectedPreset, rtOpts); + + CONFIG_MAP_SELECTVALUE("ptpengine:ip_mode", rtOpts->ip_mode, rtOpts->ip_mode, + "IP transmission mode (requires IP transport) - hybrid mode uses multicast for sync and announce,\n" + " and unicast for delay request / response", + "multicast", IPMODE_MULTICAST, + "unicast", IPMODE_UNICAST, + "hybrid", IPMODE_HYBRID + ); + + CONFIG_MAP_SELECTVALUE("ptpengine:transport",rtOpts->transport,rtOpts->transport, + "Transport type for PTP packets", + "ipv4", UDP_IPV4, +#if 0 + "ipv6", UDP_IPV6, +#endif + "ethernet", IEEE_802_3 + ); + + /* ethernet mode - cannot specify IP mode */ + CONFIG_KEY_CONDITIONAL_CONFLICT("ptpengine:ip_mode", + rtOpts->transport == IEEE_802_3, + "ethernet", + "ptpengine:ip_mode"); + + CONFIG_MAP_BOOLEAN("ptpengine:use_libpcap",rtOpts->pcap,rtOpts->pcap, + "Use libpcap for sending and receiving traffic (automatically enabled in Ethernet mode)"); + + /* in ethernet mode, activate pcap and overwrite previous setting */ + CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport==IEEE_802_3,rtOpts->pcap,TRUE,FALSE); + + CONFIG_MAP_SELECTVALUE("ptpengine:delay_mechanism",rtOpts->delayMechanism,rtOpts->delayMechanism, + "Delay detection mode used - use DELAY_DISABLED for syntonisation only (no synchronisation)", + "E2E", E2E, + "P2P", P2P, + "DELAY_DISABLED", DELAY_DISABLED + ); + + CONFIG_MAP_INT_RANGE("ptpengine:domain",rtOpts->domainNumber,rtOpts->domainNumber,"PTP domain number",0,127); + + CONFIG_MAP_BOOLEAN("ptpengine:slave_only",rtOpts->slaveOnly, ptpPreset.slaveOnly, + "Slave only mode (if set, overrides preset setting and sets clock class to 255)"); + + CONFIG_MAP_INT( "ptpengine:inbound_latency",rtOpts->inboundLatency.nanoseconds,rtOpts->inboundLatency.nanoseconds, + "Specify latency correction for incoming packets"); + + CONFIG_MAP_INT( "ptpengine:outbound_latency",rtOpts->outboundLatency.nanoseconds,rtOpts->outboundLatency.nanoseconds, + "Specify latency correction for outgoing packets"); + + CONFIG_MAP_BOOLEAN("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"); + + CONFIG_MAP_INT_RANGE("ptpengine:log_announce_interval",rtOpts->announceInterval,rtOpts->announceInterval, + "PTP announce message interval in master state "LOG2_HELP,-1,7); + + CONFIG_MAP_INT_RANGE("ptpengine:announce_timeout",rtOpts->announceReceiptTimeout,rtOpts->announceReceiptTimeout, + "PTP announce receipt timeout announced in master state",2,255); + + CONFIG_MAP_INT_RANGE("ptpengine:announce_timeout_grace_period",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 to react.\n" + " When set to 0, this option is not used.", + 0,20); + + CONFIG_MAP_INT_RANGE("ptpengine:log_sync_interval",rtOpts->syncInterval,rtOpts->syncInterval, + "PTP sync message interval in master state "LOG2_HELP,-7,7); + + /* if delayreq_interval defined, set the ignore_master to TRUE */ + CONFIG_KEY_TRIGGER("ptpengine:log_delayreq_interval",rtOpts->ignore_delayreq_interval_master,TRUE,FALSE); + + CONFIG_MAP_INT_RANGE("ptpengine:log_delayreq_interval_initial",rtOpts->initial_delayreq,rtOpts->initial_delayreq, + "Initial delay request message interval for slave mode, before first delay response is received "LOG2_HELP,-7,7); + + /* take the delayreq_interval from config, otherwise use the initial setting as default */ + CONFIG_MAP_INT_RANGE("ptpengine:log_delayreq_interval",rtOpts->subsequent_delayreq,rtOpts->initial_delayreq, + "Minimum delay request message interval in master state, in slave mode overrides the master interval,\n" + " required in hybrid mode "LOG2_HELP,-7,7); + + CONFIG_MAP_INT_RANGE("ptpengine:log_peer_delayreq_interval",rtOpts->logMinPdelayReqInterval,rtOpts->logMinPdelayReqInterval, + "Minimum peer delay request message interval in master state.\n" + " "LOG2_HELP,-7,7); + + CONFIG_MAP_INT_RANGE("ptpengine:foreignrecord_capacity",rtOpts->max_foreign_records,rtOpts->max_foreign_records, + "Maximum number of foreign masters (foreign master record size allocated at startup)",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); + + CONFIG_MAP_SELECTVALUE("ptpengine:ptp_clock_accuracy",rtOpts->clockQuality.clockAccuracy,rtOpts->clockQuality.clockAccuracy, + "Clock accuracy range announced in master state", + "ACC_25NS", 0x20, + "ACC_100NS", 0x21, + "ACC_250NS", 0x22, + "ACC_1US", 0x23, + "ACC_2.5US", 0x24, + "ACC_10US", 0x25, + "ACC_25US", 0x26, + "ACC_100US", 0x27, + "ACC_250US", 0x28, + "ACC_1MS", 0x29, + "ACC_2.5MS", 0x2A, + "ACC_10MS", 0x2B, + "ACC_25MS", 0X2C, + "ACC_100MS", 0x2D, + "ACC_250MS", 0x2E, + "ACC_1S", 0x2F, + "ACC_10S", 0x30, + "ACC_10SPLUS", 0x31, + "ACC_UNKNOWN", 0xFE ... [truncated message content] |
From: <wow...@us...> - 2013-07-05 12:21:04
|
Revision: 334 http://sourceforge.net/p/ptpd/code/334 Author: wowczarek Date: 2013-07-05 12:21:00 +0000 (Fri, 05 Jul 2013) Log Message: ----------- Additional fixes after the previous commit: - Corrected Wrong field width for leap59 in timePropertiesDS.def - Added support for configurable DSCP value (unused by default), needs tested on non-Linux - Updated default config file - option changes - Renamed UTC_REASONABLE reference in constants - this was PTPv1 specific - Multicast TTL is set to 1 only for P2P messages - Removed the now irrelevant scripts checking getopt arguments - Renamed ip_ttl setting to multicast_ttl Modified Paths: -------------- trunk/src/constants.h trunk/src/datatypes.h trunk/src/def/derivedData/timePropertiesDS.def trunk/src/dep/daemonconfig.c trunk/src/dep/msg.c trunk/src/dep/net.c trunk/src/dep/servo.c trunk/src/dep/startup.c trunk/src/ptpd2.conf.default-full Removed Paths: ------------- trunk/src/check_startup.sh trunk/tools/check_cmdline.sh Deleted: trunk/src/check_startup.sh =================================================================== --- trunk/src/check_startup.sh 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/check_startup.sh 2013-07-05 12:21:00 UTC (rev 334) @@ -1,39 +0,0 @@ -#!/bin/bash - -## -## use this quick and dirty shell script to manage the flags in dep/startup.c -## -## outputs are: -## - which flags are duplicated -## - which flags are still available to use (set is: a..z, A..Z, ?) -## - the getopt string to put in the beginning of ptpdStartup() -## -## limitations: only the internal help text is parsed. Explanations are assumed to start at position 19. -## - -TMP_BASE="/tmp/tmp_ptp_startup" -FILE="dep/startup.c" -TMP1="${TMP_BASE}.1" -TMP2="${TMP_BASE}.2" -TMP3="${TMP_BASE}.3" - -L=`cat "$FILE" | awk '/GETOPT_START_OF_OPTIONS/{A=1} /GETOPT_END_OF_OPTIONS/{A=0;} {if(A){print}}' | cut -b1-23 ` -A=`echo "$L" | awk -F"\"" '{print $2}' | awk '{print $1}'| awk '/^-/' | awk '{print $1}' | tr -d "-" | sort` -B=`echo "?" {a..z} {A..Z} | sed 's/ /\n/g' | sort ` - -echo "$A" > "$TMP1" -echo "$A" | sort -u > "$TMP2" -echo "$B" > "$TMP3" - -C=` echo "$L" | awk -F"\"" '{print $2 $3}' | awk '/^[ ]*-/' | cut -b1-18 ` -CC=`echo "$C" | awk 'BEGIN{print ""}; {print $1; if(NF>1){print ":"}}' | paste -s -d "" | sed 's/\-//g'` - -echo "Possible Duplicated: `cat "$TMP1" | uniq -d | paste -s `" -echo "Available flags: `diff -d "$TMP2" "$TMP3" | grep ">" | awk '{print $2}'| paste -s`" -echo "GetOpt String: const char *getopt_string = \"$CC\";" - - - - -exit 0 - Modified: trunk/src/constants.h =================================================================== --- trunk/src/constants.h 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/constants.h 2013-07-05 12:21:00 UTC (rev 334) @@ -362,7 +362,7 @@ { PTP_LI_61 = 0x01, PTP_LI_59 = 0x02, - PTP_UTC_REASONABLE = 0x04, + PTP_UTC_OFFSET_VALID = 0x04, PTP_TIMESCALE = 0x08, TIME_TRACEABLE = 0x10, FREQUENCY_TRACEABLE = 0x20, Modified: trunk/src/datatypes.h =================================================================== --- trunk/src/datatypes.h 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/datatypes.h 2013-07-05 12:21:00 UTC (rev 334) @@ -780,6 +780,7 @@ Enumeration8 delayMechanism; Boolean offset_first_updated; int ttl; + int dscpValue; Boolean alwaysRespectUtcOffset; Boolean useSysLog; Boolean checkConfigOnly; Modified: trunk/src/def/derivedData/timePropertiesDS.def =================================================================== --- trunk/src/def/derivedData/timePropertiesDS.def 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/def/derivedData/timePropertiesDS.def 2013-07-05 12:21:00 UTC (rev 334) @@ -3,7 +3,7 @@ /* to use these definitions, #define OPERATE then #include this file in your source */ OPERATE( currentUtcOffset, 2, UInteger16 ) OPERATE( currentUtcOffsetValid, 1, Boolean ) -OPERATE( leap59, 2, Boolean ) +OPERATE( leap59, 1, Boolean ) OPERATE( leap61, 1, Boolean ) OPERATE( timeTraceable, 1, Boolean ) OPERATE( frequencyTraceable, 1, Boolean ) Modified: trunk/src/dep/daemonconfig.c =================================================================== --- trunk/src/dep/daemonconfig.c 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/dep/daemonconfig.c 2013-07-05 12:21:00 UTC (rev 334) @@ -841,6 +841,9 @@ rtOpts->announceTimeoutGracePeriod = 0; rtOpts->alwaysRespectUtcOffset=FALSE; + /* Try 46 for expedited forwarding */ + rtOpts->dscpValue = 0; + } /* The PtpEnginePreset structure: @@ -1198,12 +1201,14 @@ CONFIG_MAP_BOOLEAN("ptpengine:igmp_refresh",rtOpts->do_IGMP_refresh,rtOpts->do_IGMP_refresh, "Send explicit IGMP joins between servo resets"); - CONFIG_MAP_INT_RANGE("ptpengine:ip_ttl",rtOpts->ttl,rtOpts->ttl, - "Multicast time to live for PTP packets (ignored and set to 1 in peer to peer delay detection mode)",1,64); + CONFIG_MAP_INT_RANGE("ptpengine:multicast_ttl",rtOpts->ttl,rtOpts->ttl, + "Multicast time to live for multicast PTP packets (ignored and set to 1 for peer to peer messages)",1,64); - /* P2P mode, set TTL to 1 */ - CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->delayMechanism==P2P,rtOpts->ttl, 1, rtOpts->ttl); + CONFIG_MAP_INT_RANGE("ptpengine:ip_dscp",rtOpts->dscpValue,rtOpts->dscpValue, + "DiffServ CodepPoint for packet prioritisation (decimal). When set to zero, this option is not used.\n" + " 46 = Expedited Forwarding (0x2e)",0,63); + #ifdef PTPD_EXPERIMENTAL CONFIG_MAP_INT_RANGE("ptpengine:alt_mcast_group",rtOpts->mcast_group_Number,rtOpts->mcast_group_Number, "Use PTP alternative multicast group like PTPv1 (if compiled with PTPD_EXPERIMENTAL):\n" @@ -1394,6 +1399,9 @@ /* Scale the maxPPM to PPB */ rtOpts->servoMaxPpb *= 1000; + /* Shift DSCP to accept the 6-bit value */ + rtOpts->dscpValue = rtOpts->dscpValue << 2; + /* * We're in hybrid mode and we haven't specified the delay request interval: * use override with a default value @@ -2077,7 +2085,9 @@ // COMPONENT_RESTART_REQUIRED("ptpengine:announce_timeout_grace_period", PTPD_RESTART_NONE ); COMPONENT_RESTART_REQUIRED("ptpengine:unicast_address", PTPD_RESTART_NETWORK ); // COMPONENT_RESTART_REQUIRED("ptpengine:igmp_refresh", PTPD_RESTART_NONE ); -// COMPONENT_RESTART_REQUIRED("ptpengine:ip_ttl", PTPD_RESTART_NONE ); + COMPONENT_RESTART_REQUIRED("ptpengine:multicast_ttl", PTPD_RESTART_NETWORK ); + COMPONENT_RESTART_REQUIRED("ptpengine:ip_dscp", PTPD_RESTART_NETWORK ); + COMPONENT_RESTART_REQUIRED("ptpengine:alt_mcast_group", PTPD_RESTART_NETWORK ); // COMPONENT_RESTART_REQUIRED("clock:no_adjust", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("clock:no_reset", PTPD_RESTART_NONE ); Modified: trunk/src/dep/msg.c =================================================================== --- trunk/src/dep/msg.c 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/dep/msg.c 2013-07-05 12:21:00 UTC (rev 334) @@ -1400,6 +1400,17 @@ copyClockIdentity((buf + 53), ptpClock->grandmasterIdentity); *(UInteger16 *) (buf + 61) = flip16(ptpClock->stepsRemoved); *(Enumeration8 *) (buf + 63) = ptpClock->timePropertiesDS.timeSource; + + /* + * TimePropertiesDS in FlagField, 2nd octet - spec 13.3.2.6 table 20 + * Could / should have used constants here PTP_LI_61 etc, but this is clean + */ + *(UInteger8*) (buf + 7) |= ptpClock->timePropertiesDS.leap61 << 0; + *(UInteger8*) (buf + 7) |= (ptpClock->timePropertiesDS.leap59) << 1; + *(UInteger8*) (buf + 7) |= (ptpClock->timePropertiesDS.currentUtcOffsetValid) << 2; + *(UInteger8*) (buf + 7) |= (ptpClock->timePropertiesDS.ptpTimescale) << 3; + *(UInteger8*) (buf + 7) |= (ptpClock->timePropertiesDS.timeTraceable) << 4; + *(UInteger8*) (buf + 7) |= (ptpClock->timePropertiesDS.frequencyTraceable) << 5; } /*Unpack Announce message from IN buffer of ptpClock to msgtmp.Announce*/ Modified: trunk/src/dep/net.c =================================================================== --- trunk/src/dep/net.c 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/dep/net.c 2013-07-05 12:21:00 UTC (rev 334) @@ -700,6 +700,19 @@ #endif #endif + /* Set socket dscp */ + if(rtOpts->dscpValue) { + + if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_TOS, + &rtOpts->dscpValue, sizeof(int)) < 0 + || setsockopt(netPath->generalSock, IPPROTO_IP, IP_TOS, + &rtOpts->dscpValue, sizeof(int)) < 0) { + PERROR("Dailed to set socket DSCP bits"); + return FALSE; + } + } + + /* send a uni-cast address if specified (useful for testing) */ if (rtOpts->unicastAddress[0]) { /* Attempt a DNS lookup first. */ @@ -730,16 +743,13 @@ if (!netInitMulticast(netPath, rtOpts)) return FALSE; - - /* TODO: set socket dscp */ - /* set socket time-to-live */ - if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_TTL, + if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_TTL, &rtOpts->ttl, sizeof(int)) < 0 - || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_TTL, + || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_TTL, &rtOpts->ttl, sizeof(int)) < 0) { - PERROR("failed to set the multi-cast time-to-live"); + PERROR("Failed to set socket multicast time-to-live"); return FALSE; } @@ -752,7 +762,7 @@ &temp, sizeof(int)) < 0 || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_LOOP, &temp, sizeof(int)) < 0) { - PERROR("failed to enable multi-cast loopback"); + PERROR("Failed to enable multicast loopback"); return FALSE; } @@ -1228,7 +1238,7 @@ ret = pcap_inject(netPath->pcapEvent, ether, ETHER_HDR_LEN + length); if (ret <= 0) - DBG("error sending ether multi-cast event message\n"); + DBG("Error sending ether multicast event message\n"); else netPath->sentPackets++; @@ -1244,7 +1254,7 @@ (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error sending uni-cast event message\n"); + DBG("Error sending unicast event message\n"); else netPath->sentPackets++; /* @@ -1257,7 +1267,7 @@ (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error looping back uni-cast event message\n"); + DBG("Error looping back unicast event message\n"); } else { addr.sin_addr.s_addr = netPath->multicastAddr; @@ -1266,7 +1276,7 @@ (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error sending multi-cast event message\n"); + DBG("Error sending multicast event message\n"); else netPath->sentPackets++; } @@ -1294,7 +1304,7 @@ ret = pcap_inject(netPath->pcapGeneral, ether, ETHER_HDR_LEN + length); if (ret <= 0) - DBG("error sending ether multi-cast general message\n"); + DBG("Error sending ether multicast general message\n"); else netPath->sentPackets++; @@ -1311,7 +1321,7 @@ (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error sending uni-cast general message\n"); + DBG("Error sending unicast general message\n"); else netPath->sentPackets++; } else { @@ -1321,7 +1331,7 @@ (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error sending multi-cast general message\n"); + DBG("Error sending multicast general message\n"); else netPath->sentPackets++; } @@ -1346,16 +1356,21 @@ (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error sending uni-cast general message\n"); + DBG("Error sending unicast peer general message\n"); } else { addr.sin_addr.s_addr = netPath->peerMulticastAddr; + int ttl = 1; + /* Try setting TTL to 1 */ + setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_TTL, + &ttl, sizeof(int)); + ret = sendto(netPath->generalSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error sending multi-cast general message\n"); + DBG("Error sending multicast peer general message\n"); } return ret; @@ -1377,7 +1392,7 @@ (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error sending uni-cast event message\n"); + DBG("Error sending unicast peer event message\n"); else netPath->sentPackets++; @@ -1391,15 +1406,20 @@ (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error looping back uni-cast event message\n"); + DBG("Error looping back unicast peer event message\n"); } else { addr.sin_addr.s_addr = netPath->peerMulticastAddr; + int ttl = 1; + /* Try setting TTL to 1 */ + setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_TTL, + &ttl, sizeof(int)); + ret = sendto(netPath->eventSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) - DBG("error sending multi-cast event message\n"); + DBG("Error sending multicast peer event message\n"); else netPath->sentPackets++; } Modified: trunk/src/dep/servo.c =================================================================== --- trunk/src/dep/servo.c 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/dep/servo.c 2013-07-05 12:21:00 UTC (rev 334) @@ -612,7 +612,7 @@ /* Adjust the clock first */ adjFreq_wrapper(rtOpts, ptpClock, -adj); /* Unset STA_UNSYNC */ - unsetTimexFlags(STA_UNSYNC, FALSE); + unsetTimexFlags(STA_UNSYNC, TRUE); /* "Tell" the clock about maxerror, esterror etc. */ informClockSource(ptpClock); #endif /* __APPLE__ */ Modified: trunk/src/dep/startup.c =================================================================== --- trunk/src/dep/startup.c 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/dep/startup.c 2013-07-05 12:21:00 UTC (rev 334) @@ -672,6 +672,6 @@ rtOpts->ifaceName, (getPtpPreset(rtOpts->selectedPreset,rtOpts)).presetName, getpid()); - + ptpClock->resetStatisticsLog = TRUE; return ptpClock; } Modified: trunk/src/ptpd2.conf.default-full =================================================================== --- trunk/src/ptpd2.conf.default-full 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/src/ptpd2.conf.default-full 2013-07-05 12:21:00 UTC (rev 334) @@ -134,9 +134,13 @@ ; Send explicit IGMP joins between servo resets ptpengine:igmp_refresh = Y -; Multicast time to live for PTP packets (ignored and set to 1 in peer to peer delay detection mode) -ptpengine:ip_ttl = 64 +; Multicast time to live for multicast PTP packets (ignored and set to 1 for peer to peer messages) +ptpengine:multicast_ttl = 64 +; DiffServ CodepPoint for packet prioritisation (decimal). When set to zero, this option is not used. +; 46 = Expedited Forwarding (0x2e) +ptpengine:ip_dscp = 0 + ; Use PTP alternative multicast group like PTPv1 (if compiled with PTPD_EXPERIMENTAL): ; 0 = 224.0.1.129, 1 = 224.0.1.130, 2 = 224.0.1.131, 3 = 224.0.1.132 ptpengine:alt_mcast_group = 0 Deleted: trunk/tools/check_cmdline.sh =================================================================== --- trunk/tools/check_cmdline.sh 2013-07-04 17:03:52 UTC (rev 333) +++ trunk/tools/check_cmdline.sh 2013-07-05 12:21:00 UTC (rev 334) @@ -1,57 +0,0 @@ -#!/bin/bash - -# -# This simple script helps manage the command line options defined in startup.c: -# -# - getopt string -# - case statements (handling options) -# - help output -# -# This tool is meant to complement / replace the src/check_startup.sh script -# -# The sript will show which options are used, which aren't and where, -# prints out a visual comparison and detects duplicates, to minimise -# false matches, only the ptpdStartup() function is analysed, under -# the assumption that it's the last function in the file. -# -# Todo: reconstruct / suggest getopt string -# -# Wojciech Owczarek, 2012, ptpd.sf.net -# -export LC_ALL=C - -SOURCEFILE="../src/dep/startup.c" - -START_LINE=`grep -n "ptpdStartup(int" $SOURCEFILE | cut -d ":" -f 1` -TOTAL_LINES=`wc -l < $SOURCEFILE` - -TMPFILE=`mktemp ptpd_check_cmdlineXXXXXXXX` -tail -n $[ $TOTAL_LINES - $START_LINE ] $SOURCEFILE > $TMPFILE - -echo -e "\n=======\n" -ALPHABET=`echo ? {A..Z} {a..z}` -GETOPT_HANDLED=`grep -e "case '[a-zA-Z]'" $TMPFILE | cut -d "'" -s -f 2 | sort | tr "\n\r" " "` -GETOPT_DEFINED=`grep "const char \*getopt_string" $TMPFILE | cut -d '"' -f 2 | tr -d ":" | grep -o . | sort | tr "\n\r" " "` -HELP_HANDLED=`grep -e "^[[:space:]]*\"-[a-zA-Z] " $TMPFILE | cut -d '"' -f 2 | tr -d "-" | cut -d " " -f 1 | sort | tr "\n\r" " "` - -echo -e "getopt not defined:\t " `echo $ALPHABET | tr -d "$GETOPT_DEFINED" | sed 's/[ ]*/ /g'` -echo -e "getopt not handled:\t " `echo $ALPHABET | tr -d "$GETOPT_HANDLED" | sed 's/[ ]*/ /g'` -echo -e " help not handled:\t " `echo $ALPHABET | tr -d "$HELP_HANDLED" | sed 's/[ ]*/ /g'` -echo -e "\n=======\n" -echo -e -n "options usable:\t | " -echo $ALPHABET -echo -e -n "getopt defined:\t | " -echo $ALPHABET | tr -c `echo $GETOPT_DEFINED | tr -d " "` " " -echo -e -n "\ngetopt handled:\t | " -echo $ALPHABET | tr -c `echo $GETOPT_HANDLED | tr -d " "` " " -echo -e -n "\nhelp handled: \t | " -echo $ALPHABET | tr -c `echo $HELP_HANDLED | tr -d " "` " " -echo -e "\n\n=======\n" -echo -e "getopt defined duplicates:\t "`echo $GETOPT_DEFINED | tr -d " " | grep -o . | sort | uniq -d | tr "\r\n" " "` -echo -e "getopt handled duplicates:\t "`echo $GETOPT_HANDLED | tr -d " " | grep -o . | sort | uniq -d | tr "\r\n" " "` -echo -e " help handled duplicates:\t "`echo $HELP_HANDLED | tr -d " " | grep -o . | sort | uniq -d | tr "\r\n" " "` -echo - -rm $TMPFILE - -exit 0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wow...@us...> - 2013-07-05 17:53:11
|
Revision: 336 http://sourceforge.net/p/ptpd/code/336 Author: wowczarek Date: 2013-07-05 17:53:07 +0000 (Fri, 05 Jul 2013) Log Message: ----------- - Removed PTPD_EXPERIMENTAL define check causing compile error - New feature: Bind to selected single CPU core (Linux only), option: global:cpuaffinity_cpucore. This usually reduces packet delay variation / improves stability Modified Paths: -------------- trunk/configure.ac trunk/src/datatypes.h trunk/src/dep/daemonconfig.c trunk/src/dep/daemonconfig.h trunk/src/dep/msg.c trunk/src/dep/startup.c trunk/src/protocol.c trunk/src/ptpd.h trunk/src/ptpd2.conf.default-full Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-07-05 14:10:41 UTC (rev 335) +++ trunk/configure.ac 2013-07-05 17:53:07 UTC (rev 336) @@ -144,7 +144,7 @@ # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h netinet/ether.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h glob.h]) +AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h netinet/ether.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h glob.h sched.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST Modified: trunk/src/datatypes.h =================================================================== --- trunk/src/datatypes.h 2013-07-05 14:10:41 UTC (rev 335) +++ trunk/src/datatypes.h 2013-07-05 17:53:07 UTC (rev 336) @@ -781,6 +781,9 @@ Boolean offset_first_updated; int ttl; int dscpValue; +#ifdef linux + int cpuNumber; +#endif /* linux */ Boolean alwaysRespectUtcOffset; Boolean useSysLog; Boolean checkConfigOnly; Modified: trunk/src/dep/daemonconfig.c =================================================================== --- trunk/src/dep/daemonconfig.c 2013-07-05 14:10:41 UTC (rev 335) +++ trunk/src/dep/daemonconfig.c 2013-07-05 17:53:07 UTC (rev 336) @@ -844,6 +844,13 @@ /* Try 46 for expedited forwarding */ rtOpts->dscpValue = 0; +#ifdef linux +#ifdef HAVE_SCHED_H + /* Linux only (for now) - CPU core number */ + rtOpts-> cpuNumber = -1; +#endif /* HAVE_SCHED_H */ +#endif /* linux */ + } /* The PtpEnginePreset structure: @@ -1235,7 +1242,7 @@ " reset: set to zero (not recommended)\n" " preserve: use kernel value,\n" " file: load and save to drift file on startup/shutdown, use kernel value inbetween.\n" - " To specify drift file, use the global:drift_file setting." + " To specify drift file, use the clock:drift_file setting." , "reset", DRIFT_RESET, "preserve", DRIFT_KERNEL, @@ -1392,6 +1399,15 @@ CONFIG_MAP_BOOLEAN("global:log_statistics",rtOpts->logStatistics,rtOpts->logStatistics, "Log timing statistics for every PTP packet received"); +#ifdef linux +#ifdef HAVE_SCHED_H + CONFIG_MAP_INT_RANGE("global:cpuaffinity_cpucore",rtOpts->cpuNumber,rtOpts->cpuNumber, + "Linux only: bind "PTPD_PROGNAME" process to a selected CPU core number.\n" + " 0 = first CPU core, etc. -1 = do not bind to a single core.", + 0,255); +#endif /* HAVE_SCHED_H */ +#endif /* linux */ + /* ============== END CONFIG MAPPINGS, TRIGGERS AND DEPENDENCIES =========== */ /* ==== Any additional logic should go here ===== */ @@ -2117,8 +2133,13 @@ COMPONENT_RESTART_REQUIRED("global:foreground", PTPD_RESTART_DAEMON ); COMPONENT_RESTART_REQUIRED("global:verbose_foreground", PTPD_RESTART_DAEMON ); +#ifdef linux +#ifdef HAVE_SCHED_H + COMPONENT_RESTART_REQUIRED("global:cpuaffinity_cpucore", PTPD_CHANGE_CPUAFFINITY ); +#endif /* HAVE_SCHED_H */ +#endif /* linux */ -/* ========= Any additiona logic goes here =========== */ +/* ========= Any additional logic goes here =========== */ /* Set of possible PTP port states has changed */ if(SETTING_CHANGED("ptpengine:slave_only") || Modified: trunk/src/dep/daemonconfig.h =================================================================== --- trunk/src/dep/daemonconfig.h 2013-07-05 14:10:41 UTC (rev 335) +++ trunk/src/dep/daemonconfig.h 2013-07-05 17:53:07 UTC (rev 336) @@ -25,8 +25,10 @@ #define PTPD_RESTART_LOGGING 16 /* Configuration changes need checking lock files */ #define PTPD_CHECK_LOCKS 32 +/* CPU core has changed */ +#define PTPD_CHANGE_CPUAFFINITY 64 /* Configuration changes require daemon restart */ -#define PTPD_RESTART_DAEMON 64 +#define PTPD_RESTART_DAEMON 128 #define LOG2_HELP "(expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.)" Modified: trunk/src/dep/msg.c =================================================================== --- trunk/src/dep/msg.c 2013-07-05 14:10:41 UTC (rev 335) +++ trunk/src/dep/msg.c 2013-07-05 17:53:07 UTC (rev 336) @@ -53,9 +53,7 @@ #include "../ptpd.h" -#ifdef PTPD_EXPERIMENTAL -extern RunTimeOpts rtOpts; -#endif +extern RunTimeOpts rtOpts; #define PACK_SIMPLE( type ) \ void pack##type( void* from, void* to ) \ @@ -1526,11 +1524,9 @@ /* Table 19 */ *(UInteger16 *) (buf + 2) = flip16(DELAY_REQ_LENGTH); - if(rtOpts.ip_mode == IPMODE_HYBRID) *(char *)(buf + 6) |= PTP_UNICAST; - *(UInteger16 *) (buf + 30) = flip16(ptpClock->sentDelayReqSequenceId); *(UInteger8 *) (buf + 32) = 0x01; /* Table 23 */ Modified: trunk/src/dep/startup.c =================================================================== --- trunk/src/dep/startup.c 2013-07-05 14:10:41 UTC (rev 335) +++ trunk/src/dep/startup.c 2013-07-05 17:53:07 UTC (rev 336) @@ -200,13 +200,46 @@ } } - if(rtOpts->restartSubsystems == -1) { - ERROR("New configuration cannot be applied - aborting reload\n"); - rtOpts->restartSubsystems = 0; - goto cleanup; - } +#ifdef linux +#ifdef 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); + } 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); + } + } +#endif /* HAVE_SCHED_H */ +#endif /* linux */ + if(rtOpts->restartSubsystems == -1) { + ERROR("New configuration cannot be applied - aborting reload\n"); + rtOpts->restartSubsystems = 0; + goto cleanup; + } + + /* Tell parseConfig to shut up - it's had its chance already */ dictionary_set(rtOpts->candidateConfig,"%quiet%:%quiet%","Y"); @@ -651,7 +684,26 @@ return 0; } } - + +#ifdef linux +#ifdef HAVE_SCHED_H + + /* 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); + } else { + INFO("Successfully bound "PTPD_PROGNAME" to CPU core %d\n", rtOpts->cpuNumber); + } + } +#endif /* HAVE_SCHED_H */ +#endif /* linux */ + /* use new synchronous signal handlers */ signal(SIGINT, catchSignals); signal(SIGTERM, catchSignals); Modified: trunk/src/protocol.c =================================================================== --- trunk/src/protocol.c 2013-07-05 14:10:41 UTC (rev 335) +++ trunk/src/protocol.c 2013-07-05 17:53:07 UTC (rev 336) @@ -139,13 +139,13 @@ if(rtOpts->restartSubsystems & PTPD_RESTART_LOGGING) { NOTIFY("Applying logging configuration: restarting logging\n"); } - /* Config changes don't require subsystem restarts - acknowledge it */ if(rtOpts->restartSubsystems == PTPD_RESTART_NONE) { NOTIFY("Applying configuration\n"); } - rtOpts->restartSubsystems = 0; + if(rtOpts->restartSubsystems != -1) + rtOpts->restartSubsystems = 0; } /* Perform the heavy signal processing synchronously */ Modified: trunk/src/ptpd.h =================================================================== --- trunk/src/ptpd.h 2013-07-05 14:10:41 UTC (rev 335) +++ trunk/src/ptpd.h 2013-07-05 17:53:07 UTC (rev 336) @@ -57,6 +57,12 @@ #include <netinet/udp.h> #include <pcap/pcap.h> +#ifdef linux +#ifdef HAVE_SCHED_H +#include <sched.h> +#endif /* HAVE_SCHED_H */ +#endif /* linux */ + #include "constants.h" #include "limits.h" #include "dep/constants_dep.h" Modified: trunk/src/ptpd2.conf.default-full =================================================================== --- trunk/src/ptpd2.conf.default-full 2013-07-05 14:10:41 UTC (rev 335) +++ trunk/src/ptpd2.conf.default-full 2013-07-05 17:53:07 UTC (rev 336) @@ -141,10 +141,6 @@ ; 46 = Expedited Forwarding (0x2e) ptpengine:ip_dscp = 0 -; Use PTP alternative multicast group like PTPv1 (if compiled with PTPD_EXPERIMENTAL): -; 0 = 224.0.1.129, 1 = 224.0.1.130, 2 = 224.0.1.131, 3 = 224.0.1.132 -ptpengine:alt_mcast_group = 0 - ; Use JobID (PID) for UUID ptpengine:pid_as_clock_idendity = N @@ -158,7 +154,7 @@ ; reset: set to zero (not recommended) ; preserve: use kernel value, ; file: load and save to drift file on startup/shutdown, use kernel value inbetween. -; To specify drift file, use the global:drift_file setting. +; To specify drift file, use the clock:drift_file setting. ; Options: reset preserve file clock:drift_handling = preserve @@ -242,5 +238,9 @@ ; Log timing statistics for every PTP packet received global:log_statistics = N +; Linux only: bind ptpd2 process to a selected CPU core number. +; 0 = first CPU core, etc. -1 = do not bind to a single core. +global:cpuaffinity_cpucore = -1 + ; ========= newline required in the end ========== This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gn...@us...> - 2013-07-09 19:08:19
|
Revision: 338 http://sourceforge.net/p/ptpd/code/338 Author: gnn Date: 2013-07-09 19:08:13 +0000 (Tue, 09 Jul 2013) Log Message: ----------- There is no tick in the timex structure on FreeBSD. Add a new configure check and #define for this case. Modified Paths: -------------- trunk/configure.ac trunk/src/dep/sys.c Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-07-09 18:11:05 UTC (rev 337) +++ trunk/configure.ac 2013-07-09 19:08:13 UTC (rev 338) @@ -158,6 +158,9 @@ AC_TYPE_UINT8_T AC_C_VOLATILE +# Check for tick in the timex structure +AC_CHECK_MEMBERS([struct timex.tick], [], [], [[#include <sys/timex.h>]]) + # Checks for library functions. AC_PROG_GCC_TRADITIONAL AC_FUNC_MALLOC Modified: trunk/src/dep/sys.c =================================================================== --- trunk/src/dep/sys.c 2013-07-09 18:11:05 UTC (rev 337) +++ trunk/src/dep/sys.c 2013-07-09 19:08:13 UTC (rev 338) @@ -985,12 +985,16 @@ adj += tickRes; } } +#ifdef HAVE_STRUCT_TIMEX_TICK /* Base tick duration - 10000 when userHZ = 100 */ t.tick = 1E6 / userHZ; /* Tick adjustment if necessary */ t.tick += tickAdj; t.modes = MOD_FREQUENCY | ADJ_TICK; +#else + t.modes = MOD_FREQUENCY; +#endif /* HAVE_STRUCT_TIMEX_TICK */ t.freq = adj * ((1 << 16) / 1000); /* do calculation in double precision, instead of Integer32 */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wow...@us...> - 2013-07-23 18:24:58
|
Revision: 339 http://sourceforge.net/p/ptpd/code/339 Author: wowczarek Date: 2013-07-23 18:24:55 +0000 (Tue, 23 Jul 2013) Log Message: ----------- Second batch of functionality and bugfix updates for 2.3. New features: - Generic log file handler mechanism with a simple built-in logrotate implementation - for each log file container you can specify max size and max number of files - Extensive support for realtime statistics: online long term statistics and moving statistics - mean and std dev. Some new features included depend on statistics support. Enabled with the --enable-statistics configure switch. Statistics rely on double precision so may be disabled for simple embedded systems - Outlier filters based on Peirce's criterion: blocks / filters spikes from delayMS and delaySM - Generic PI controler model (structure and a runPIservo() function) - P and I components changed from attenuations to gains (scaled to 1/1000) - Optional double precision servo: configure --enable-double-servo: Allows for tighter clock control - Clock stabilisation detection based on the standard dev of observed drift - Clock "calibration delay" - allow a configurable delay between seeing a GM for the first time and enabling clock control - Realtime statistics - mean and std dev of one-way delay, ofm and observed drift - Status file: one-screen dump of information about the current state of ptpd, updated in configurable intervals. - Support for "panic mode" - when enabled, if ptpd sees offset from master above 1 second, it will pause clock updates for a given amount of time - NTPd integration and failover: ptpd can now connect to local ntpd using mode 7 packets (code derived from ntpdc) and using authenticated requests can enable/disable ntpd clock control. Enable with configure --enable-ntpdc - Another configurable option for the SIGUSR2 handler: configure --enable-sigusr2=counters causes ptpd2 to dump all counters to the log file on SIGUSR2 Bug fixes / feature enhancements / patches: - Support for updating utmp/wtmp when stepping the clock (FR #38) - Mean Path Delay filtering now done in float (patch #49) Todo: - Full man pages for ptpd2 and ptpd2.conf - RESTART_SUBSYSTEMS* for NTP related options - Restarting / re-arming of panic mode and ntp related timers on SIGHUP Modified Paths: -------------- trunk/Makefile.am trunk/README.repocheckout trunk/configure.ac trunk/src/Makefile.am trunk/src/arith.c 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/daemonconfig.h trunk/src/dep/datatypes_dep.h 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/dep/timer.c trunk/src/display.c trunk/src/protocol.c trunk/src/ptpd.h trunk/src/ptpd2.conf.default-full trunk/src/ptpd2.conf.minimal Added Paths: ----------- trunk/src/dep/ntpengine/ trunk/src/dep/ntpengine/ntp_isc_md5.c trunk/src/dep/ntpengine/ntp_isc_md5.h trunk/src/dep/ntpengine/ntpdcontrol.c trunk/src/dep/ntpengine/ntpdcontrol.h trunk/src/dep/statistics.c trunk/src/dep/statistics.h trunk/src/ptpd2.conf.8 Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/Makefile.am 2013-07-23 18:24:55 UTC (rev 339) @@ -8,11 +8,13 @@ EXTRA_DIST = \ ChangeLog \ - NEWS \ README \ \ doc \ tools \ + src/ptpd2.conf.minimal\ + src/ptpd2.8\ + src/ptpd2.conf.8\ \ $(NULL) Modified: trunk/README.repocheckout =================================================================== --- trunk/README.repocheckout 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/README.repocheckout 2013-07-23 18:24:55 UTC (rev 339) @@ -1,6 +1,5 @@ -If you are getting this code from a tarball distribution, the -information in this file does not apply to you. If you do the -following anyway, it won't cause any problems. +If you are getting this code from a tarball distribution, this +file does not apply to you. If you are getting this code from a repo checkout, you will need to have autoconf, automake, and libtool installed. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/configure.ac 2013-07-23 18:24:55 UTC (rev 339) @@ -144,7 +144,7 @@ # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h netinet/ether.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h glob.h sched.h]) +AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h netinet/ether.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h glob.h sched.h utmp.h utmpx.h pcap/pcap.h pcap.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -169,7 +169,7 @@ AC_TYPE_SIGNAL AC_FUNC_STRFTIME AC_FUNC_VPRINTF -AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol]) +AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol glob]) AC_MSG_CHECKING([for RUNTIME_DEBUG]) AC_ARG_ENABLE( @@ -251,6 +251,63 @@ esac AC_SUBST(PTP_EXP) +AC_MSG_CHECKING([for realtime statistics support]) +AC_ARG_ENABLE( + [statistics], + [AS_HELP_STRING( + [--enable-statistics], + [Enable support for realtime statistics and statistics based filtering] + )], + [ptp_statistics=$enableval], + [ptp_statistics=no] +) +AC_MSG_RESULT([$ptp_statistics]) +case "$ptp_statistics" in + yes) + PTP_STATISTICS="-DPTPD_STATISTICS" + ;; +esac +AC_SUBST(PTP_STATISTICS) +AM_CONDITIONAL([STATISTICS], [test x$ptp_statistics = xyes]) + +AC_MSG_CHECKING([ntpd control / failover support]) +AC_ARG_ENABLE( + [ntpdc], + [AS_HELP_STRING( + [--enable-ntpdc], + [Enable control of local NTP daemon and failover to local NTP] + )], + [ptp_ntpdc=$enableval], + [ptp_ntpdc=no] +) +AC_MSG_RESULT([$ptp_ntpdc]) +case "$ptp_ntpdc" in + yes) + PTP_NTPDC="-DPTPD_NTPDC" + ;; +esac +AC_SUBST(PTP_NTPDC) +AM_CONDITIONAL([NTPDC], [test x$ptp_ntpdc = xyes]) + +AC_MSG_CHECKING([for double precision PI servo support]) +AC_ARG_ENABLE( + [double-servo], + [AS_HELP_STRING( + [--enable-double-servo], + [Enable support for double precision PI servo] + )], + [ptp_double_servo=$enableval], + [ptp_double_servo=no] +) +AC_MSG_RESULT([$ptp_double_servo]) +case "$ptp_double_servo" in + yes) + PTP_DOUBLE_SERVO="-DPTPD_DOUBLE_SERVO" + ;; +esac +AC_SUBST(PTP_DOUBLE_SERVO) +AM_CONDITIONAL([DOUBLE_SERVO], [test x$ptp_double_servo = xyes]) + AC_MSG_CHECKING([for SIGUSR2 support]) AC_ARG_ENABLE( [sigusr2], Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/Makefile.am 2013-07-23 18:24:55 UTC (rev 339) @@ -1,13 +1,14 @@ # Makefile for ptpd2 lib_LTLIBRARIES = $(LIBPTPD2_LIBS_LA) -bin_PROGRAMS = ptpd2 +sbin_PROGRAMS = ptpd2 +man_MANS = ptpd2.8 ptpd2.conf.8 AM_CFLAGS = $(SNMP_CFLAGS) AM_CPPFLAGS = $(SNMP_CPPFLAGS) AM_LDFLAGS = $(SNMP_LIBS) -AM_CPPFLAGS += $(PTP_DBL) $(PTP_DAEMON) $(PTP_EXP) $(PTP_SNMP) $(PTP_SIGUSR2) +AM_CPPFLAGS += $(PTP_DBL) $(PTP_DAEMON) $(PTP_EXP) $(PTP_SNMP) $(PTP_SIGUSR2) $(PTP_STATISTICS) $(PTP_DOUBLE_SERVO) $(PTP_NTPDC) NULL= @@ -48,6 +49,20 @@ ptpd2_SOURCES += dep/snmp.c endif +# STATISTICS +if STATISTICS +ptpd2_SOURCES += dep/statistics.h +ptpd2_SOURCES += dep/statistics.c +endif + +# NTP control +if NTPDC +ptpd2_SOURCES += dep/ntpengine/ntp_isc_md5.c +ptpd2_SOURCES += dep/ntpengine/ntp_isc_md5.h +ptpd2_SOURCES += dep/ntpengine/ntpdcontrol.c +ptpd2_SOURCES += dep/ntpengine/ntpdcontrol.h +endif + CSCOPE = cscope GTAGS = gtags DOXYGEN = doxygen Modified: trunk/src/arith.c =================================================================== --- trunk/src/arith.c 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/arith.c 2013-07-23 18:24:55 UTC (rev 339) @@ -323,3 +323,25 @@ else return (2.0f * ai); } + +double +timeInternalToDouble(const TimeInternal * p) +{ + + double sign = (p->seconds < 0 || p->nanoseconds < 0 ) ? -1.0 : 1.0; + return (sign * ( abs(p->seconds) + abs(p->nanoseconds) / 1E9 )); + +} + +TimeInternal +doubleToTimeInternal(const double d) +{ + + TimeInternal t = {0, 0}; + + t.seconds = trunc(d); + t.nanoseconds = (d - (t.seconds + 0.0)) * 1E9; + + return t; + +} Modified: trunk/src/bmc.c =================================================================== --- trunk/src/bmc.c 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/bmc.c 2013-07-23 18:24:55 UTC (rev 339) @@ -139,10 +139,10 @@ clearTime(&ptpClock->offsetFromMaster); clearTime(&ptpClock->meanPathDelay); - /*Parent data set*/ copyClockIdentity(ptpClock->parentPortIdentity.clockIdentity, ptpClock->clockIdentity); - ptpClock->parentPortIdentity.portNumber = 0; + + ptpClock->parentPortIdentity.portNumber = ptpClock->numberPorts; ptpClock->parentStats = DEFAULT_PARENTS_STATS; ptpClock->observedParentClockPhaseChangeRate = 0; ptpClock->observedParentOffsetScaledLogVariance = 0; @@ -215,7 +215,10 @@ ptpClock->timePropertiesDS.currentUtcOffset = announce->currentUtcOffset; if (ptpClock->timePropertiesDS.currentUtcOffsetValid && !IS_SET(header->flagField1, UTCV)) { - WARNING("UTC Offset no longer valid. Clock may jump unless ptpengine:always_respect_utc_offset is set\n"); + if(rtOpts->alwaysRespectUtcOffset) + WARNING("UTC Offset no longer valid and ptpengine:always_respect_utc_offset is set: continuing as normal\n"); + else + WARNING("UTC Offset no longer valid - clock jump expected\n"); } /* "Valid" is bit 2 in second octet of flagfield */ @@ -466,6 +469,12 @@ ptpClock->counters.masterChanges++; if (ptpClock->portState == PTP_SLAVE) displayStatus(ptpClock, "State: "); +#ifdef PTPD_STATISTICS + if(rtOpts->calibrationDelay) { + ptpClock->isCalibrated = FALSE; + ptpClock->statsUpdates = 0; + } +#endif /* PTPD_STATISTICS */ } return PTP_SLAVE; } @@ -507,6 +516,12 @@ ptpClock->counters.masterChanges++; if(ptpClock->portState == PTP_SLAVE) displayStatus(ptpClock, "State: "); +#ifdef PTPD_STATISTICS + if(rtOpts->calibrationDelay) { + ptpClock->isCalibrated = FALSE; + ptpClock->statsUpdates = 0; + } +#endif /* PTPD_STATISTICS */ } return PTP_SLAVE; } else { Modified: trunk/src/constants.h =================================================================== --- trunk/src/constants.h 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/constants.h 2013-07-23 18:24:55 UTC (rev 339) @@ -32,10 +32,6 @@ "PTPDv2" #define USER_DESCRIPTION_MAX 128 -/* Indentation string used in logs */ -#define INFO_PREFIX \ - "=== " - /* implementation specific constants */ #define DEFAULT_INBOUND_LATENCY 0 /* in nsec */ #define DEFAULT_OUTBOUND_LATENCY 0 /* in nsec */ @@ -170,6 +166,15 @@ /* non-spec timers */ OPERATOR_MESSAGES_TIMER, /* used to limit the operator messages */ LEAP_SECOND_PAUSE_TIMER, /* timer used for pausing updates when leap second is imminent */ + STATUSFILE_UPDATE_TIMER, /* timer used for refreshing status file */ + PANIC_MODE_TIMER, /* timer used for the duration of "panic mode" */ +#ifdef PTPD_STATISTICS + STATISTICS_UPDATE_TIMER, /* online mean / std dev updare interval (non-moving statistics) */ +#endif /* PTPD_STATISTICS */ +#ifdef PTPD_NTPDC + NTPD_CHECK_TIMER, + NTPD_FAILOVER_TIMER, +#endif TIMER_ARRAY_SIZE }; Modified: trunk/src/datatypes.h =================================================================== --- trunk/src/datatypes.h 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/datatypes.h 2013-07-23 18:24:55 UTC (rev 339) @@ -3,7 +3,7 @@ #include <stdio.h> #include <dep/iniparser/dictionary.h> - +#include <dep/statistics.h> /*Struct defined in spec*/ @@ -517,25 +517,68 @@ uint32_t sequenceMismatchErrors; /* mismatched sequence IDs - also increments discarded */ uint32_t delayModeMismatchErrors; /* P2P received, E2E expected or vice versa - incremets discarded */ +#ifdef PTPD_STATISTICS + uint32_t delayMSOutliersFound; /* Number of outliers found by the delayMS filter */ + uint32_t delaySMOutliersFound; /* Number of outliers found by the delaySM filter */ +#endif /* PTPD_STATISTICS */ + } PtpdCounters; /** - * \struct PtpdStats - * \brief Ptpd clock statistics per port + * \struct PIservo + * \brief PI controller model structure */ -typedef struct -{ - Integer32 ofmMean; /* mean offset from master - accuracy*/ - Integer32 ofmStdDev; /* offset from master standard deviation - precision */ - /* TODO: investigate MAD - Mean Absolute Deviation */ - Integer32 ofmMedian; /* offset from master median - effective accuracy*/ - /* TODO: investigate velocity/acceleration as statistical measures */ - Integer32 driftStdDev; /* observed drift standard deviation */ +#ifndef PTPD_DOUBLE_SERVO +typedef struct{ -} PtpdStats; + int maxOutput; + Integer32 input; + Integer32 output; + Integer32 observedDrift; + Integer32 kP, kI; + TimeInternal lastUpdate; + Boolean runningMaxOutput; +#ifdef PTPD_STATISTICS + int updateCount; + int stableCount; + Boolean statsCalculated; + Boolean isStable; + Integer32 stabilityThreshold; + int stabilityPeriod; + int stabilityTimeout; + Integer32 driftMean; + Integer32 driftStdDev; + IntPermanentStdDev driftStats; +#endif /* PTPD_STATISTICS */ +} PIservo; +#else +typedef struct{ + int maxOutput; + Integer32 input; + double output; + double observedDrift; + double kP, kI; + TimeInternal lastUpdate; + Boolean runningMaxOutput; +#ifdef PTPD_STATISTICS + int updateCount; + int stableCount; + Boolean statsCalculated; + Boolean isStable; + double stabilityThreshold; + int stabilityPeriod; + int stabilityTimeout; + double driftMean; + double driftStdDev; + DoublePermanentStdDev driftStats; +#endif /* PTPD_STATISTICS */ +} PIservo; +#endif /* PTPD_DOUBLE_SERVO */ + + /** * \struct PtpClock * \brief Main program data structure @@ -643,7 +686,6 @@ TimeInternal slave_to_master_delay; */ - Integer32 observed_drift; TimeInternal pdelay_req_receive_time; TimeInternal pdelay_req_send_time; @@ -656,13 +698,11 @@ MsgHeader delayReqHeader; TimeInternal pdelayMS; TimeInternal pdelaySM; - TimeInternal delayMS; + TimeInternal delayMS; TimeInternal delaySM; TimeInternal lastSyncCorrectionField; TimeInternal lastPdelayRespCorrectionField; - - Boolean sentPDelayReq; UInteger16 sentPDelayReqSequenceId; UInteger16 sentDelayReqSequenceId; @@ -689,7 +729,7 @@ /*Stats header will be re-printed when set to true*/ Boolean resetStatisticsLog; - int reset_count; + int resetCount; int announceTimeouts; int current_init_clock; int can_step_clock; @@ -697,22 +737,25 @@ int warned_operator_fast_slewing; char char_last_msg; /* representation of last message processed by servo */ - Boolean last_packet_was_sync; /* used to limit logging of Sync messages */ - + int waiting_for_first_sync; /* we'll only start the delayReq timer after the first sync */ int waiting_for_first_delayresp; /* Just for information purposes */ Boolean startup_in_progress; uint32_t init_timestamp; /* When the clock was last initialised */ Integer32 stabilisation_time; /* How long (seconds) it took to stabilise the clock */ +#ifndef PTPD_DOUBLE_SERVO Integer32 last_saved_drift; /* Last observed drift value written to file */ +#else + double last_saved_drift; /* Last observed drift value written to file */ +#endif /* PTPD_DOUBLE_SERVO */ Boolean drift_saved; /* Did we save a drift value already? */ /* 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 masterAddr; // used for hybrid mode, when receiving announces Integer32 LastSlaveAddr; // used for hybrid mode, when receiving delayreqs /* @@ -722,14 +765,43 @@ */ PtpdCounters counters; + /* PI servo model */ + PIservo servo; + + /* "panic mode" support */ + Boolean panicMode; /* in panic mode - do not update clock or calculate offsets */ + Boolean panicOver; /* panic mode is over, we can reset the clock */ + int panicModeTimeLeft; /* How many 30-second periods left in panic mode */ + +#ifdef PTPD_STATISTICS /* * basic clock statistics information, useful * for monitoring servo performance and estimating * clock stability - should be exposed through * management messages and SNMP eventually */ - PtpdStats stats; + PtpEngineSlaveStats slaveStats; + TimeInternal rawDelayMS; + TimeInternal rawDelaySM; + TimeInternal rawPdelayMS; + TimeInternal rawPdelaySM; + DoubleMovingStdDev* delayMSRawStats; + DoubleMovingStdDev* delaySMRawStats; + DoubleMovingMean* delaySMFiltered; + DoubleMovingMean* delayMSFiltered; + Boolean delayMSoutlier; + Boolean delaySMoutlier; + + int statsUpdates; + Boolean isCalibrated; + +#endif + +#ifdef PTPD_NTPDC + NTPcontrol ntpControl; +#endif + } PtpClock; /** @@ -773,7 +845,6 @@ Boolean displayPackets; Octet unicastAddress[MAXHOSTNAMELEN]; - Integer32 ap, ai; Integer16 s; TimeInternal inboundLatency, outboundLatency; Integer16 max_foreign_records; @@ -782,8 +853,11 @@ int ttl; int dscpValue; #ifdef linux +#ifdef HAVE_SCHED_H int cpuNumber; +#endif /* HAVE_SCHED_H */ #endif /* linux */ + Boolean alwaysRespectUtcOffset; Boolean useSysLog; Boolean checkConfigOnly; @@ -791,21 +865,17 @@ char configFile[PATH_MAX]; - char logFile[PATH_MAX]; - FILE *logFP; - Boolean useLogFile; - int logLevel; + LogFileHandler statisticsLog; + LogFileHandler recordLog; + LogFileHandler eventLog; + LogFileHandler statusLog; - char statisticsFile[PATH_MAX]; - FILE *statisticsFP; - Boolean useStatisticsFile; Boolean logStatistics; - char recordFile[PATH_MAX]; - FILE *recordFP; - Boolean useRecordFile; + int logLevel; + int statisticsLogInterval; - int statisticsInterval; + int statusFileUpdateInterval; Boolean ignore_daemon_lock; Boolean do_IGMP_refresh; @@ -849,7 +919,54 @@ int selectedPreset; int servoMaxPpb; +#ifndef PTPD_DOUBLE_SERVO + int servoKP; + int servoKI; +#else + double servoKP; + double servoKI; +#endif /* PTPD_DOUBLE_SERVO */ +#ifdef PTPD_STATISTICS + + Boolean delayMSOutlierFilterEnabled; + int delayMSOutlierFilterCapacity; + double delayMSOutlierFilterThreshold; + Boolean delayMSOutlierFilterDiscard; + double delayMSOutlierWeight; + + Boolean delaySMOutlierFilterEnabled; + int delaySMOutlierFilterCapacity; + double delaySMOutlierFilterThreshold; + Boolean delaySMOutlierFilterDiscard; + double delaySMOutlierWeight; + + int calibrationDelay; + + int statsUpdateInterval; + Boolean servoStabilityDetection; +#ifdef PTPD_DOUBLE_SERVO + double servoStabilityThreshold; +#else + Integer32 servoStabilityThreshold; +#endif /* PTPD_DOUBLE_SERVO */ + int servoStabilityTimeout; + int servoStabilityPeriod; + +#endif + + Boolean enablePanicMode; + int panicModeDuration; + + +#ifdef PTPD_NTPDC + Boolean panicModeNtp; + NTPoptions ntpOptions; +#endif + + } RunTimeOpts; + + #endif /*DATATYPES_H_*/ Modified: trunk/src/dep/constants_dep.h =================================================================== --- trunk/src/dep/constants_dep.h 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/dep/constants_dep.h 2013-07-23 18:24:55 UTC (rev 339) @@ -69,7 +69,7 @@ #endif #define CLOCK_IDENTITY_LENGTH 8 -#define ADJ_FREQ_MAX 512000 +#define ADJ_FREQ_MAX 512000 /* UDP/IPv4 dependent */ #ifndef INADDR_LOOPBACK @@ -116,6 +116,9 @@ /* default drift file location */ #define DEFAULT_DRIFTFILE "/etc/"PTPD_PROGNAME"_"DEFAULT_CLOCKDRIVER".drift" +/* default status file location */ +#define DEFAULT_STATUSFILE DEFAULT_LOCKDIR"/"PTPD_PROGNAME".status" + /* Highest log level (default) catches all */ #define LOG_ALL LOG_DEBUGV Modified: trunk/src/dep/daemonconfig.c =================================================================== --- trunk/src/dep/daemonconfig.c 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/dep/daemonconfig.c 2013-07-23 18:24:55 UTC (rev 339) @@ -213,7 +213,23 @@ variable = otherwise; \ } +#define CONFIG_KEY_CONDITIONAL_ASSERTION(key,condition,warningtext) \ + if ( (condition) && \ + CONFIG_ISSET(key) ) \ + { \ + if(!IS_QUIET())\ + ERROR("%s\n", warningtext); \ + parseResult = FALSE;\ + } +#define CONFIG_CONDITIONAL_ASSERTION(condition,warningtext) \ + if ( (condition) ) \ + { \ + if(!IS_QUIET())\ + ERROR("%s\n", warningtext); \ + parseResult = FALSE;\ + } + /* Range check macros */ /* surrounded with {}s to limit the scope of the temporary variable */ @@ -787,18 +803,13 @@ /* Deep display of all packets seen by the daemon */ rtOpts->displayPackets = FALSE; // rtOpts->unicastAddress - rtOpts->ap = DEFAULT_AP; - rtOpts->ai = DEFAULT_AI; + 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->offset_first_updated = FALSE; - rtOpts->logFP = NULL; - rtOpts->recordFP = NULL; - rtOpts->statisticsFP = NULL; - rtOpts->useLogFile = FALSE; - rtOpts->useRecordFile = FALSE; + rtOpts->nonDaemon = FALSE; /* @@ -814,7 +825,7 @@ rtOpts->ttl = 64; rtOpts->delayMechanism = DEFAULT_DELAY_MECHANISM; rtOpts->noResetClock = DEFAULT_NO_RESET_CLOCK; - rtOpts->statisticsInterval = 0; + rtOpts->statisticsLogInterval = 0; rtOpts->initial_delayreq = DEFAULT_DELAYREQ_INTERVAL; rtOpts->subsequent_delayreq = DEFAULT_DELAYREQ_INTERVAL; // this will be updated if -g is given @@ -836,6 +847,9 @@ /* 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 = 1000; + rtOpts->servoKI = 10; /* disabled by default */ rtOpts->announceTimeoutGracePeriod = 0; @@ -851,9 +865,88 @@ #endif /* HAVE_SCHED_H */ #endif /* linux */ +#ifdef PTPD_STATISTICS + + rtOpts->delayMSOutlierFilterEnabled = FALSE; + rtOpts->delayMSOutlierFilterDiscard = FALSE; + rtOpts->delayMSOutlierFilterCapacity = 20; + rtOpts->delayMSOutlierFilterThreshold = 1.0; + rtOpts->delayMSOutlierWeight = 1; + rtOpts->delaySMOutlierFilterEnabled = FALSE; + rtOpts->delaySMOutlierFilterDiscard = FALSE; + rtOpts->delaySMOutlierFilterCapacity = 20; + rtOpts->delaySMOutlierFilterThreshold = 1.0; + rtOpts->delaySMOutlierWeight = 1; + + /* How often refresh statistics (seconds) */ + rtOpts->statsUpdateInterval = 5; + /* Servo stability detection settings follow */ + rtOpts->servoStabilityDetection = FALSE; + /* Stability threshold (ppb) - observed drift std dev value considered stable */ + rtOpts->servoStabilityThreshold = 5; + /* How many consecutive statsUpdateInterval periods of observed drift std dev within threshold means stable servo */ + rtOpts->servoStabilityPeriod = 3; + /* How many minutes without servo stabilisation means servo has not stabilised */ + rtOpts->servoStabilityTimeout = 10; + /* How many statsUpdateInterval periods to wait for one-way delay prefiltering */ + rtOpts->calibrationDelay = 0; + +#endif + + /* status file options */ + rtOpts->statusFileUpdateInterval = 1; + + /* panic mode options */ + rtOpts->enablePanicMode = FALSE; + rtOpts->panicModeDuration = 2; + + + +#ifdef PTPD_NTPDC + rtOpts->panicModeNtp = FALSE; + rtOpts->ntpOptions.enableEngine = FALSE; + rtOpts->ntpOptions.enableControl = FALSE; + rtOpts->ntpOptions.enableFailover = FALSE; + rtOpts->ntpOptions.ntpInControl = FALSE; + rtOpts->ntpOptions.failoverTimeout = 60; + rtOpts->ntpOptions.checkInterval = 15; + rtOpts->ntpOptions.keyId = 0; + strncpy(rtOpts->ntpOptions.hostAddress,"localhost",MAXHOSTNAMELEN); /* not configurable */ +#endif + +/* 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; + } -/* The PtpEnginePreset structure: +/* The PtpEnginePreset structure for reference: typedef struct { @@ -1226,9 +1319,93 @@ "to use ptpengine:v1style_mcast_group\n"); #endif /* PTPD_EXPERIMENTAL */ +#ifdef PTPD_STATISTICS + + CONFIG_MAP_BOOLEAN("ptpengine:delay_outlier_filter_enable",rtOpts->delaySMOutlierFilterEnabled,rtOpts->delaySMOutlierFilterEnabled, + "Enable outlier filter for the Delay Response component in slave state"); + + CONFIG_MAP_SELECTVALUE("ptpengine:delay_outlier_filter_action",rtOpts->delaySMOutlierFilterDiscard,rtOpts->delaySMOutlierFilterDiscard, + "Delay Response outlier filter action. If set to 'filter', outliers are replaced with moving average", + "discard", TRUE, + "filter", FALSE); + + CONFIG_MAP_INT_RANGE("ptpengine:delay_outlier_filter_capacity",rtOpts->delaySMOutlierFilterCapacity,rtOpts->delaySMOutlierFilterCapacity, + "Number of samples in the Delay Response outlier filter buffer",4,STATCONTAINER_MAX_SAMPLES); + + CONFIG_MAP_DOUBLE_RANGE("ptpengine:delay_outlier_filter_threshold",rtOpts->delaySMOutlierFilterThreshold,rtOpts->delaySMOutlierFilterThreshold, + "Delay Response outlier filter threshold: multiplier for the Peirce's maximum standard deviation. When set below 1.0,\n" + " filter is tighter, when set above 1.0, filter is looser than standard Peirce's test.", 0.001, 1000.0); + + CONFIG_MAP_DOUBLE_RANGE("ptpengine:delay_outlier_weight",rtOpts->delaySMOutlierWeight,rtOpts->delaySMOutlierWeight, + "Delay Response outlier weight: if an outlier is detected, this value determines the amount of its deviation\n" + " from mean that is used to build the standard deviation statistics and influence further outlier detection.\n" + " When set to 1.0, the outlier is used as is.\n", 0.01, 2.0); + + CONFIG_MAP_BOOLEAN("ptpengine:sync_outlier_filter_enable",rtOpts->delayMSOutlierFilterEnabled,rtOpts->delayMSOutlierFilterEnabled, + "Enable outlier filter for the Sync component in slave state"); + + CONFIG_MAP_SELECTVALUE("ptpengine:sync_outlier_filter_action",rtOpts->delayMSOutlierFilterDiscard,rtOpts->delayMSOutlierFilterDiscard, + "Sync outlier filter action. If set to 'filter', outliers are replaced with moving average", + "discard", TRUE, + "filter", FALSE); + + CONFIG_MAP_INT_RANGE("ptpengine:sync_outlier_filter_capacity",rtOpts->delayMSOutlierFilterCapacity,rtOpts->delayMSOutlierFilterCapacity, + "Number of samples in the Sync outlier filter buffer",4,STATCONTAINER_MAX_SAMPLES); + + CONFIG_MAP_DOUBLE_RANGE("ptpengine:sync_outlier_filter_threshold",rtOpts->delayMSOutlierFilterThreshold,rtOpts->delayMSOutlierFilterThreshold, + "Sync outlier filter threshold: multiplier for the Peirce's maximum standard deviation. When set below 1.0,\n" + " filter is tighter, when set above 1.0, filter is looser than standard Peirce's test.", 0.001, 1000.0); + + CONFIG_MAP_DOUBLE_RANGE("ptpengine:sync_outlier_weight",rtOpts->delaySMOutlierWeight,rtOpts->delaySMOutlierWeight, + "Sync outlier weight: if an outlier is detected, this value determines the amount of its deviation\n" + " from mean that is used to build the standard deviation statistics and influence further outlier detection.\n" + " When set to 1.0, the outlier is used as is.", 0.01, 2.0); + + CONFIG_MAP_INT_RANGE("ptpengine:calibration_delay",rtOpts->calibrationDelay,rtOpts->calibrationDelay, + "Delay between moving to slave state and enabling clock updates expressed as number of statistics update periods\n" + " (see global:statistics_update_interval). This allows one-way delay to stabilise before starting\n" + " clock updates. Activated when going into slave state and during GM failover in slave state.\n" + " 0 - not used.",0,100); + +#endif /* PTPD_STATISTICS */ + + CONFIG_MAP_BOOLEAN("ptpengine:panic_mode",rtOpts->enablePanicMode,rtOpts->enablePanicMode, + "Enable panic mode: when offset from master is above 1 second, stop updating the clock for a period of\n" + " time and then step the clock if offset remains above 1 second."); + + CONFIG_MAP_INT_RANGE("ptpengine:panic_mode_duration",rtOpts->panicModeDuration,rtOpts->panicModeDuration, + "Duration of the panic mode period (no clock updates) when offset above 1 second detected\n",1,60); + CONFIG_MAP_BOOLEAN("ptpengine:pid_as_clock_idendity",rtOpts->jobid,rtOpts->jobid, "Use JobID (PID) for UUID"); +#ifdef PTPD_NTPDC + + CONFIG_MAP_BOOLEAN("ptpengine:ntp_failover",rtOpts->ntpOptions.enableFailover,rtOpts->ntpOptions.enableFailover, + "Fail over to NTP when PTP time sync not available - requires ntpengine:enabled but does not require\n" + " the rest of NTP configuration - will warn instead of failing over if cannot control ntpd."); + + CONFIG_KEY_DEPENDENCY("ptpengine:ntp_failover", "ntpengine:enabled"); + + CONFIG_MAP_INT_RANGE("ptpengine:ntp_failover_timeout",rtOpts->ntpOptions.failoverTimeout, + rtOpts->ntpOptions.failoverTimeout, + "NTP failover timeout in seconds: time between PTP slave going into LISTENING state,\n" + " and failing over to NTP. 0 = fail over immediately.\n", 0, 1800); + + CONFIG_MAP_BOOLEAN("ptpengine:prefer_ntp",rtOpts->ntpOptions.ntpInControl,rtOpts->ntpOptions.ntpInControl, + "Prefer NTP time synchronisation when not controlling the clock (all states, including slave when\n" + " clock:no_adjust set)"); + + CONFIG_MAP_BOOLEAN("ptpengine:panic_mode_ntp",rtOpts->panicModeNtp,rtOpts->panicModeNtp, + "When entering panic mode, fail over to NTP (after the NTP failover timeout period) - \n" + " requires ntpengine:enabled but does not require the rest of NTP configuration -\n" + " will warn instead of failing over if it cannot control ntpd."); + + CONFIG_KEY_DEPENDENCY("ptpengine:panic_mode_ntp", "ntpengine:enabled"); + + +#endif /* PTPD_NTPDC */ + /* ===== clock section ===== */ CONFIG_MAP_BOOLEAN("clock:no_adjust",rtOpts->noAdjust,ptpPreset.noAdjust, @@ -1252,6 +1429,7 @@ CONFIG_MAP_CHARARRAY("clock:drift_file",rtOpts->driftFile,rtOpts->driftFile, "Specify drift file"); +#ifdef HAVE_STRUCT_TIMEX_TICK /* This really is clock specific - different clocks may allow different ranges */ CONFIG_MAP_INT_RANGE("clock:max_offset_ppm",rtOpts->servoMaxPpb,rtOpts->servoMaxPpb, "Maximum absolute frequency shift which can be applied to the clock servo\n" @@ -1259,6 +1437,7 @@ " 1 us per second. Values above 512 will use the tick duration correction\n" " to allow even faster slewing. Default maximum is 512 without using tick.", 512,1024); +#endif /* HAVE_STRUCT_TIMEX_TICK */ /* * TimeProperties DS - in future when clock driver API is implemented, @@ -1273,17 +1452,61 @@ CONFIG_MAP_INT( "servo:delayfilter_stiffness",rtOpts->s,rtOpts->s, "One-way delay filter stiffness"); - CONFIG_MAP_INT_MIN("servo:ap",rtOpts->ap,rtOpts->ap, - "Clock servo PI controller proportional component attenuation",1); - - CONFIG_MAP_INT_MIN("servo:ai",rtOpts->ai,rtOpts->ai, - "Clock servo PI controller integral component attenuation",1); - +#ifndef PTPD_DOUBLE_SERVO + CONFIG_MAP_INT_MIN("servo:kp",rtOpts->servoKP,rtOpts->servoKP, + "Clock servo PI controller proportional component gain (kP)",1); + CONFIG_MAP_INT_MIN("servo:ki",rtOpts->servoKI,rtOpts->servoKI, + "Clock servo PI controller integral component gain (kI)",1); +#else + CONFIG_MAP_DOUBLE_MIN("servo:kp",rtOpts->servoKP,rtOpts->servoKP, + "Clock servo PI controller proportional component gain (kP)",0.01); + CONFIG_MAP_DOUBLE_MIN("servo:ki",rtOpts->servoKI,rtOpts->servoKI, + "Clock servo PI controller integral component gain (kI)",0.01); +#endif /* PTPD_DOUBLE_SERVO */ CONFIG_MAP_INT_RANGE("servo:max_delay",rtOpts->maxDelay,rtOpts->maxDelay, "Maximum accepted delayMS value in nanoseconds (Sync).\n" " 0 = not checked." ,0,NANOSECONDS_MAX); +#ifdef PTPD_STATISTICS + CONFIG_MAP_BOOLEAN("servo:stability_detection",rtOpts->servoStabilityDetection, + rtOpts->servoStabilityDetection, + "Enable clock synchronisation servo stability detection\n" + " (based on standard deviation of the observed drift value)\n" + " - drift will be saved to drift file / cached when considered stable,\n" + " also clock stability status will be logged\n"); + +#ifdef PTPD_DOUBLE_SERVO + CONFIG_MAP_DOUBLE_RANGE("servo:stability_threshold",rtOpts->servoStabilityThreshold, + rtOpts->servoStabilityThreshold, + "Specify the observed drift standard deviation threshold in parts per billion\n" + " (ppb) - if stanard deviation is within the threshold, servo is considered\n" + " stable.", + 1.0,10000.0); +#else + CONFIG_MAP_INT_RANGE("servo:stability_threshold",rtOpts->servoStabilityThreshold, + rtOpts->servoStabilityThreshold, + "Specify the observed drift standard deviation threshold in parts per billion\n" + " (ppb) - if stanard deviation is within the threshold, servo is considered\n" + " stable.", + 1,10000); +#endif /* PTPD_DOUBLE_SERVO */ + + CONFIG_MAP_INT_RANGE("servo:stability_period",rtOpts->servoStabilityPeriod, + rtOpts->servoStabilityPeriod, + "Specify for how many statistics update intervals the observed drift standard\n" + " deviation has to stay within threshold to be considered stable\n", + 1,100); + + CONFIG_MAP_INT_RANGE("servo:stability_timeout",rtOpts->servoStabilityTimeout, + rtOpts->servoStabilityTimeout, + "Specify after how many minutes without stabilisation servo is considered\n" + " unstable. Assists with logging servo stability information and\n" + " allows to preserve observed drift if servo cannot stabilise.\n", + 1,60); + +#endif + /** * Initialise the origMaxDelay to the maxDelay value if max_delay not set. * Help string is empty here because we've just mapped this value above, @@ -1328,10 +1551,32 @@ "Skip lock file checking and locking"); /* if quality file specified, enable quality recording */ - CONFIG_KEY_TRIGGER("global:quality_file",rtOpts->useRecordFile,TRUE,FALSE); - CONFIG_MAP_CHARARRAY("global:quality_file",rtOpts->recordFile,rtOpts->recordFile, + CONFIG_KEY_TRIGGER("global:quality_file",rtOpts->recordLog.logEnabled,TRUE,FALSE); + CONFIG_MAP_CHARARRAY("global:quality_file",rtOpts->recordLog.logPath,rtOpts->recordLog.logPath, "File used to record data about sync packets. Setting this enables recording."); + CONFIG_MAP_INT_MIN("global:quality_file_max_size",rtOpts->recordLog.maxSize,rtOpts->recordLog.maxSize, + "Maximum sync packet record file size (in kB) - file will be truncated if size exceeds the limit.\n" + " 0 - no limit.", 0); + + CONFIG_MAP_INT_RANGE("global:quality_file_max_files",rtOpts->recordLog.maxFiles,rtOpts->recordLog.maxFiles, + "Enable log rotation of the sync packet record file up to n files. 0 - do not rotate.\n", 0, 100); + + CONFIG_MAP_BOOLEAN("global:quality_file_truncate",rtOpts->recordLog.truncateOnReopen,rtOpts->recordLog.truncateOnReopen, + "Truncate the sync packet record file every time it is (re) opened - on startup and SIGHUP"); + + /* if status file specified, enable status logging*/ + CONFIG_KEY_TRIGGER("global:status_file",rtOpts->statusLog.logEnabled,TRUE,FALSE); + CONFIG_MAP_CHARARRAY("global:status_file",rtOpts->statusLog.logPath,rtOpts->statusLog.logPath, + "File used to log "PTPD_PROGNAME" status information"); + /* status file can be disabled even if specified */ + CONFIG_MAP_BOOLEAN("global:log_status",rtOpts->statusLog.logEnabled, rtOpts->statusLog.logEnabled, + "Enable / disable writing status information to file"); + + CONFIG_MAP_INT_RANGE("global:status_update_interval",rtOpts->statusFileUpdateInterval,rtOpts->statusFileUpdateInterval, + "Status file update interval in seconds\n", + 1,30); + #ifdef RUNTIME_DEBUG CONFIG_MAP_SELECTVALUE("global:debug_level",rtOpts->debug_level,rtOpts->debug_level, "Specify debug level (if compiled with RUNTIME_DEBUG)", @@ -1347,10 +1592,20 @@ #endif /* RUNTIME_DEBUG */ /* if log file specified, enable file logging - otherwise disable */ - CONFIG_KEY_TRIGGER("global:log_file",rtOpts->useLogFile,TRUE,FALSE); - CONFIG_MAP_CHARARRAY("global:log_file",rtOpts->logFile,rtOpts->logFile, - "Specify log file path. Setting this enables logging to file."); + CONFIG_KEY_TRIGGER("global:log_file",rtOpts->eventLog.logEnabled,TRUE,FALSE); + CONFIG_MAP_CHARARRAY("global:log_file",rtOpts->eventLog.logPath, rtOpts->eventLog.logPath, + "Specify log file path (event log). Setting this enables logging to file."); + CONFIG_MAP_INT_MIN("global:log_file_max_size",rtOpts->eventLog.maxSize,rtOpts->eventLog.maxSize, + "Maximum log file size (in kB) - log file will be truncated if size exceeds the limit.\n" + " 0 - no limit.", 0); + + CONFIG_MAP_INT_RANGE("global:log_file_max_files",rtOpts->eventLog.maxFiles,rtOpts->eventLog.maxFiles, + "Enable log rotation of the sync packet record file up to n files. 0 - do not rotate\n", 0, 100); + + CONFIG_MAP_BOOLEAN("global:log_file_truncate",rtOpts->eventLog.truncateOnReopen,rtOpts->eventLog.truncateOnReopen, + "Truncate the log file every time it is (re) opened - on startup and SIGHUP"); + CONFIG_MAP_SELECTVALUE("global:log_level",rtOpts->logLevel,rtOpts->logLevel, "Specify log level (only messages of the specified priority or higer will be logged).\n" " The minimal level is LOG_ERR. LOG_ALL enables debug output if compiled with\n" @@ -1363,14 +1618,24 @@ ); /* if statistics file specified, enable statistics logging - otherwise disable - log_statistics also controlled further below*/ - CONFIG_KEY_TRIGGER("global:statistics_file",rtOpts->useStatisticsFile,TRUE,FALSE); + CONFIG_KEY_TRIGGER("global:statistics_file",rtOpts->statisticsLog.logEnabled,TRUE,FALSE); CONFIG_KEY_TRIGGER("global:statistics_file",rtOpts->logStatistics,TRUE,FALSE); - CONFIG_MAP_CHARARRAY("global:statistics_file",rtOpts->statisticsFile,rtOpts->statisticsFile, - "Specify statistics file path. Setting this enables logging of statistics but can be overriden with global:log_statistics"); + CONFIG_MAP_CHARARRAY("global:statistics_file",rtOpts->statisticsLog.logPath,rtOpts->statisticsLog.logPath, + "Specify statistics log file path. Setting this enables logging of statistics but can be overriden with global:log_statistics"); - CONFIG_MAP_INT_MIN("global:statistics_interval",rtOpts->statisticsInterval,rtOpts->statisticsInterval, - "Log timing statistics every n seconds (0 - log all)",0); + CONFIG_MAP_INT_MIN("global:statistics_log_interval",rtOpts->statisticsLogInterval,rtOpts->statisticsLogInterval, + "Log timing statistics every n seconds for Sync and Delay Response messages (0 - log all)",0); + CONFIG_MAP_INT_MIN("global:statistics_file_max_size",rtOpts->statisticsLog.maxSize,rtOpts->statisticsLog.maxSize, + "Maximum statistics log file size (in kB) - log file will be truncated if size exceeds the limit.\n" + " 0 - no limit.", 0); + + CONFIG_MAP_INT_RANGE("global:statistics_file_max_files",rtOpts->statisticsLog.maxFiles,rtOpts->statisticsLog.maxFiles, + "Enable log rotation of the statistics file up to n files. 0 - do not rotate\n", 0, 100); + + CONFIG_MAP_BOOLEAN("global:statistics_file_truncate",rtOpts->statisticsLog.truncateOnReopen,rtOpts->statisticsLog.truncateOnReopen, + "Truncate the statistics file every time it is (re) opened - on startup and SIGHUP"); + CONFIG_MAP_BOOLEAN("global:dump_packets",rtOpts->displayPackets,rtOpts->displayPackets, "Dump the contents of every PTP packet"); @@ -1382,9 +1647,9 @@ if(CONFIG_ISTRUE("global:verbose_foreground")) { rtOpts->useSysLog = FALSE; rtOpts->logStatistics = TRUE; - rtOpts->statisticsInterval = 0; - rtOpts->useLogFile = FALSE; - rtOpts->useStatisticsFile = FALSE; + rtOpts->statisticsLogInterval = 0; + rtOpts->eventLog.logEnabled = FALSE; + rtOpts->statisticsLog.logEnabled = FALSE; } /* @@ -1399,6 +1664,10 @@ CONFIG_MAP_BOOLEAN("global:log_statistics",rtOpts->logStatistics,rtOpts->logStatistics, "Log timing statistics for every PTP packet received"); + /* If statistics file is enabled but logStatistics isn't, disable logging to file */ + CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->statisticsLog.logEnabled && !rtOpts->logStatistics, + rtOpts->statisticsLog.logEnabled, FALSE, rtOpts->statisticsLog.logEnabled); + #ifdef linux #ifdef HAVE_SCHED_H CONFIG_MAP_INT_RANGE("global:cpuaffinity_cpucore",rtOpts->cpuNumber,rtOpts->cpuNumber, @@ -1408,6 +1677,51 @@ #endif /* HAVE_SCHED_H */ #endif /* linux */ +#ifdef PTPD_STATISTICS + CONFIG_MAP_INT_RANGE("global:statistics_update_interval",rtOpts->statsUpdateInterval, + rtOpts->statsUpdateInterval, + "Clock synchronisation statistics update interval in seconds\n", 1, 60); + + CONFIG_CONDITIONAL_ASSERTION( rtOpts->servoStabilityDetection && ( + (rtOpts->statsUpdateInterval * rtOpts->servoStabilityPeriod) / 60 >= + rtOpts->servoStabilityTimeout), + "The configured servo stabilisation timeout has to be longer than\n" + " servo stabilisation period"); + +#endif /* PTPD_STATISTICS */ + + +#ifdef PTPD_NTPDC + +/* ===== ntpengine section ===== */ + + CONFIG_MAP_BOOLEAN("ntpengine:enabled",rtOpts->ntpOptions.enableEngine,rtOpts->ntpOptions.enableEngine, + "Enable NTPd integration"); + + CONFIG_MAP_BOOLEAN("ntpengine:control_enabled",rtOpts->ntpOptions.enableControl,rtOpts->ntpOptions.enableControl, + "Enable control over local NTPd daemon"); + + CONFIG_KEY_DEPENDENCY("ntpengine:control_enabled", "ntpengine:enabled"); + + CONFIG_MAP_INT_RANGE("ntpengine:check_interval",rtOpts->ntpOptions.checkInterval, + rtOpts->ntpOptions.checkInterval, + "NTP control check interval in seconds\n", 5, 600); + + CONFIG_MAP_INT_RANGE("ntpengine:key_id",rtOpts->ntpOptions.keyId, rtOpts->ntpOptions.keyId, + "NTP key number - must be configured as a trusted control key in ntp.conf,\n" + " and must be non-zero for the ntpengine:control_enabled setting to take effect.\n", 0, 65535); + + CONFIG_MAP_CHARARRAY("ntpengine:key",rtOpts->ntpOptions.key, rtOpts->ntpOptions.key, + "NTP key (plain text, max. 20 characters) - must match the key configured in ntpd's keys file, and must\n" + " be non-zero for the ntpengine:control_enabled setting to take effect.\n"); + + CONFIG_KEY_DEPENDENCY("ntpengine:control:enabled", "ntpengine:key_id"); + CONFIG_KEY_DEPENDENCY("ntpengine:control:enabled", "ntpengine:key"); + +#endif /* PTPD_NTPDC */ + + + /* ============== END CONFIG MAPPINGS, TRIGGERS AND DEPENDENCIES =========== */ /* ==== Any additional logic should go here ===== */ @@ -1906,7 +2220,7 @@ "Basic options: \n" "\n" "-c --config-file [path] Configuration file\n" - "-C --check-config Check configuration and exit\n" + "-k --check-config Check configuration and exit\n" "-v --version Print version string\n" "-h --help Show this help screen\n" "-H --long-help Show detailed help for all settings and behaviours\n" @@ -2105,31 +2419,74 @@ COMPONENT_RESTART_REQUIRED("ptpengine:ip_dscp", PTPD_RESTART_NETWORK ); COMPONENT_RESTART_REQUIRED("ptpengine:alt_mcast_group", PTPD_RESTART_NETWORK ); + +#ifdef PTPD_STATISTICS + COMPONENT_RESTART_REQUIRED("ptpengine:delay_outlier_filter_enable", PTPD_RESTART_PEIRCE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:delay_outlier_filter_action", PTPD_RESTART_NONE ); + COMPONENT_RESTART_REQUIRED("ptpengine:delay_outlier_filter_capacity", PTPD_RESTART_PEIRCE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:delay_outlier_filter_threshold", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:delay_outlier_weight", PTPD_RESTART_NONE ); + + + COMPONENT_RESTART_REQUIRED("ptpengine:sync_outlier_filter_enable", PTPD_RESTART_PEIRCE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:sync_outlier_filter_action", PTPD_RESTART_NONE ); + COMPONENT_RESTART_REQUIRED("ptpengine:sync_outlier_filter_capacity", PTPD_RESTART_PEIRCE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:sync_outlier_filter_threshold", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:sync_outlier_weight", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:calibration_delay", PTPD_RESTART_NONE ); + +#endif /* PTPD_STATISTICS */ + +// COMPONENT_RESTART_REQUIRED("ptpengine:panic_mode", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:panic_mode_duration", PTPD_RESTART_NONE ); + // COMPONENT_RESTART_REQUIRED("clock:no_adjust", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("clock:no_reset", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("clock:drift_file", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("clock:drift_handling", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("clock:max_offset_ppm", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("servo:owdfilter_stiffness", PTPD_RESTART_NONE ); -// COMPONENT_RESTART_REQUIRED("servo:ap", PTPD_RESTART_NONE ); -// COMPONENT_RESTART_REQUIRED("servo:ai", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("servo:kp", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("servo:ki", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("servo:max_delay", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("servo:max_delay", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("servo:max_offset", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("global:use_syslog", PTPD_RESTART_LOGGING ); + +#ifdef PTPD_STATISTICS +// COMPONENT_RESTART_REQUIRED("servo:stability_detection", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("servo:stability_threshold", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("servo:stability_period", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("servo:stability_timeout", PTPD_RESTART_NONE ); +#endif + + COMPONENT_RESTART_REQUIRED("global:lock_file", PTPD_RESTART_DAEMON ); COMPONENT_RESTART_REQUIRED("global:auto_lockfile", PTPD_RESTART_DAEMON ); COMPONENT_RESTART_REQUIRED("global:lock_directory", PTPD_RESTART_DAEMON ); COMPONENT_RESTART_REQUIRED("global:ignore_lock", PTPD_RESTART_DAEMON ); // COMPONENT_RESTART_REQUIRED("global:quality_file", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:quality_file_max_size", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:quality_file_truncate", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:quality_file_max_files", PTPD_RESTART_LOGGING ); COMPONENT_RESTART_REQUIRED("global:log_file", PTPD_RESTART_LOGGING ); - COMPONENT_RESTART_REQUIRED("global:log_file", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:log_file_max_size", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:log_file_truncate", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:log_file_file_max_files", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:status_update_interval", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:status_file", PTPD_RESTART_LOGGING ); // COMPONENT_RESTART_REQUIRED("global:log_level", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("global:debug_level", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("global:statistics_file", PTPD_RESTART_LOGGING ); -// COMPONENT_RESTART_REQUIRED("global:statistics_interval", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("global:statistics_file_max_size", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:statistics_file_truncate", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:statistics_file_max_files", PTPD_RESTART_LOGGING ); +// COMPONENT_RESTART_REQUIRED("global:statistics_log_interval", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("global:log_stats", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("global:dump_packets", PTPD_RESTART_NONE ); +#ifdef PTPD_STATISTICS +// COMPONENT_RESTART_REQUIRED("global:statistics_update_interval", PTPD_RESTART_NONE ); +#endif COMPONENT_RESTART_REQUIRED("global:foreground", PTPD_RESTART_DAEMON ); COMPONENT_RESTART_REQUIRED("global:verbose_foreground", PTPD_RESTART_DAEMON ); Modified: trunk/src/dep/daemonconfig.h =================================================================== --- trunk/src/dep/daemonconfig.h 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/dep/daemonconfig.h 2013-07-23 18:24:55 UTC (rev 339) @@ -14,22 +14,31 @@ /* Config reload - component restart status flags */ /* No restart required - can continue with new config */ -#define PTPD_RESTART_NONE 1 +#define PTPD_RESTART_NONE 1 << 0 /* PTP port datasetw can be updated without restarting FSM */ -#define PTPD_UPDATE_DATASETS 2 +#define PTPD_UPDATE_DATASETS 1 << 1 /* PTP FSM port re-initialisation required (PTP_INITIALIZING) */ -#define PTPD_RESTART_PROTOCOL 4 +#define PTPD_RESTART_PROTOCOL 1 << 2 /* Network config changed: PTP_INITIALIZING handles this so far */ -#define PTPD_RESTART_NETWORK 8 +#define PTPD_RESTART_NETWORK 1 << 3 /* Logging config changes: log files need closed / reopened */ -#define PTPD_RESTART_LOGGING 16 +#define PTPD_RESTART_LOGGING 1 << 4 /* Configuration changes need checking lock files */ -#define PTPD_CHECK_LOCKS 32 +#define PTPD_CHECK_LOCKS 1 << 5 /* CPU core has changed */ -#define PTPD_CHANGE_CPUAFFINITY 64 +#define PTPD_CHANGE_CPUAFFINITY 1 << 6 /* Configuration changes require daemon restart */ -#define PTPD_RESTART_DAEMON 128 +#define PTPD_RESTART_DAEMON 1 << 7 +#ifdef PTPD_STATISTICS +/* Configuration changes require outlier filter restart */ +#define PTPD_RESTART_PEIRCE 1 << 8 +#endif + +#ifdef PTPD_NTPDC +#define PTPD_RESTART_NTPENGINE 1 << 9 +#endif /* PTPD_NTPDC */ + #define LOG2_HELP "(expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.)" /* Structure defining a PTP engine preset */ Modified: trunk/src/dep/datatypes_dep.h =================================================================== --- trunk/src/dep/datatypes_dep.h 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/dep/datatypes_dep.h 2013-07-23 18:24:55 UTC (rev 339) @@ -75,7 +75,6 @@ struct in_addr interfaceAddr; Octet port_uuid_field[PTP_UUID_LENGTH]; - /* used for Hybrid mode */ Integer32 lastRecvAddr; @@ -90,6 +89,24 @@ struct ether_addr *etherDest; } NetPath; +typedef struct { + + char* logID; + char* openMode; + char logPath[PATH_MAX]; + FILE* logFP; + + Boolean logEnabled; + Boolean truncateOnReopen; + Boolean unlinkOnClose; + + UInteger32 maxSize; + UInteger32 fileSize; + int maxFiles; + +} LogFileHandler; + + typedef struct{ UInteger8 minValue; @@ -130,5 +147,4 @@ } UInteger16_option; - #endif /*DATATYPES_DEP_H_*/ Modified: trunk/src/dep/net.c =================================================================== --- trunk/src/dep/net.c 2013-07-09 19:08:13 UTC (rev 338) +++ trunk/src/dep/net.c 2013-07-23 18:24:55 UTC (rev 339) @@ -516,6 +516,40 @@ return result; } +Boolean +hostLookup(const char* hostname, Integer32* addr) +{ + if (hostname[0]) { + /* Attempt a DNS lookup first. */ + struct hostent *host; + host = gethostbyname2(hostname, AF_INET); + if (host != NULL) { + if (host->h_length != 4) { + PERROR("unicast host resolved to non ipv4" + "address"); + return FALSE; + } + *addr = + *(uint32_t *)host->h_addr_list[0]; + return TRUE; + } else { + struct in_addr netAddr; + /* Maybe it's a dotted quad. */ + if (!inet_aton(hostname, &netAddr)) { + ERROR("failed to encode unicast address: %s\n", + hostname); + return FALSE; + *addr = netAddr.s_addr; + return TRUE; + } + } + } + +return FALSE; + +} + + /** * start all of the UDP stuff * must specify 'subdomainName', and optionally 'ifaceName', @@ -532,7 +566,7 @@ netInit(NetPath * netPath, RunTimeOpts * rtOpts, PtpClock * ptpClock) { int temp; - struct in_addr interfaceAddr, netAddr; + struct in_addr interfaceAddr; struct sockaddr_in addr; struct bpf_program program; char errbuf[PCAP_ERRBUF_SIZE]; @@ -545,7 +579,6 @@ netPath->pcapEventSock = -1; netPath->pcapGeneralSock = -1; - if (rtOpts->transport == IEEE_802_3) { netPath->headerOffset = PACKET_BEGIN_ETHER; netPath->etherDest = (struct ether_addr *)ether_aton(PTP_ETHER_DST); @@ -712,30 +745,8 @@ } } - /* send a uni-cast address if specified (useful for testing) */ - if (rtOpts->unicastAddress[0]) { - /* Attempt a DNS lookup first. */ - struct hostent *host; - host = gethostbyname2(rtOpts->unicastAddress, AF_INET); - if (host != NULL) { - if (host->h_length != 4) { - PERROR("unicast host resolved to non ipv4" - "address"); - return FALSE; - } - netPath->unicastAddr = - *(uint32_t *)host->h_addr_list[0]; - } else { - /* Maybe it's a dotted quad. */ - if (!inet_aton(rtOpts->unicastAddress, &netAddr)) { - ERROR("failed to encode uni-cast address: %s\n", - rtOpts->unicastAddress); - return FALSE; - netPath->unicastAddr = netAddr.s_addr; - } - } - } else { + if(!hostLookup(rtOpts->unicastAddress, &netPath->unicastAddr)) { netPath->unicastAddr = 0; } Added: trunk/src/dep/ntpengine/ntp_isc_md5.c =================================================================== --- trunk/src/dep/ntpengine/ntp_isc_md5.c (rev 0) +++ trunk/src/dep/ntpengine/ntp_isc_md5.c 2013-07-23 18:24:55 UTC (rev 339) @@ -0,0 +1,274 @@ +/* + * This file contains the minimal set of declarations and constants + * extracted from the ISC MD5 code and ntpdc code included with NTP 4 + * distribution version 4.2.6p5 to allow computing the MD5 digest + * for NTP type 7 packets + */ + +/* Original copyright notice */ + +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "../../ptpd.h" + +#include "ntp_isc_md5.h" + +void ntp_memset (char *, int, int); + +#define memcmp(a, b, c) bcmp(a, b, (int)(c)) +#define memmove(t, f, c) bcopy(f, t, (int)(c)) +#define memcpy(t, f, c) bcopy(f, t, (int)(c)) +#define memset(a, x, c) if (0 == (x)) \ + bzero(a, (int)(c)); \ + else \ + ntp_memset((char *)(a), x, c) + + +static void +byteSwap(uint32_t *buf, unsigned words) +{ + unsigned char *p = (unsigned char *)buf; + + do { + *buf++ = (uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 | + ((unsigned)p[1] << 8 | p[0]); + p += 4; + } while (--words); +} + +/*! + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +isc_md5_init(isc_md5_t *ctx) { + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bytes[0] = 0; + ctx->bytes[1] = 0; +} + +void +isc_md5_invalidate(isc_md5_t *ctx) { + memset(ctx, 0, sizeof(isc_md5_t)); +} + +/*@{*/ +/*! The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) +/*@}*/ + +/*! This is the central step in the MD5 algorithm. */ +#define MD5STEP(f,w,x,y,z,in,s) \ + (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x) + +/*! + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void +transform(uint32_t buf[4], uint32_t const in[16]) { + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F... [truncated message content] |
From: <gn...@us...> - 2013-07-24 12:53:17
|
Revision: 343 http://sourceforge.net/p/ptpd/code/343 Author: gnn Date: 2013-07-24 12:53:11 +0000 (Wed, 24 Jul 2013) Log Message: ----------- Fix compilation errors on FreeBSD and on systems with the default build macros. Add configure checks for utmpxname() and updwtmpx(). Modified Paths: -------------- trunk/configure.ac trunk/src/dep/servo.c trunk/src/dep/sys.c Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-07-23 21:26:46 UTC (rev 342) +++ trunk/configure.ac 2013-07-24 12:53:11 UTC (rev 343) @@ -169,7 +169,7 @@ AC_TYPE_SIGNAL AC_FUNC_STRFTIME AC_FUNC_VPRINTF -AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol glob]) +AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol glob utmpxname updwtmpx]) AC_MSG_CHECKING([for RUNTIME_DEBUG]) AC_ARG_ENABLE( Modified: trunk/src/dep/servo.c =================================================================== --- trunk/src/dep/servo.c 2013-07-23 21:26:46 UTC (rev 342) +++ trunk/src/dep/servo.c 2013-07-24 12:53:11 UTC (rev 343) @@ -528,11 +528,15 @@ #endif /* OLD_TIME */ /* ======== BEGIN OLD TIME EVENT - UTMPX / WTMPX =========== */ - utmpxname(UTMPX_FILE); +#ifdef HAVE_UTMPXNAME + utmpxname("/var/log/utmp"); +#endif /* HAVE_UTMPXNAME */ setutxent(); pututxline(&utx); endutxent(); - updwtmpx(WTMPX_FILE, &utx); +#ifdef HAVE_UPDWTMPX + updwtmpx("/var/log/wtmp", &utx); +#endif /* HAVE_IPDWTMPX */ /* ======== END OLD TIME EVENT - UTMPX / WTMPX =========== */ #else /* NO UTMPX_H */ @@ -588,11 +592,15 @@ #endif /* NEW_TIME */ /* ======== BEGIN NEW TIME EVENT - UTMPX / WTMPX =========== */ - utmpxname(UTMPX_FILE); +#ifdef HAVE_UTMPXNAME + utmpxname("/var/log/utmp"); +#endif /* HAVE_UTMPXNAME */ setutxent(); pututxline(&utx); endutxent(); - updwtmpx(WTMPX_FILE, &utx); +#ifdef HAVE_UPDWTMPX + updwtmpx("/var/log/wtmp", &utx); +#endif /* HAVE_UPDWTMPX */ /* ======== END NEW TIME EVENT - UTMPX / WTMPX =========== */ #else /* NO UTMPX_H */ Modified: trunk/src/dep/sys.c =================================================================== --- trunk/src/dep/sys.c 2013-07-23 21:26:46 UTC (rev 342) +++ trunk/src/dep/sys.c 2013-07-24 12:53:11 UTC (rev 343) @@ -868,19 +868,13 @@ #endif /* PTPD_STATISTICS */ fprintf(out,"\n"); #ifndef PTPD_STATISTICS -if(rtOpts->enablePanicMode || rtOpts->calibrationDelay) +if(rtOpts->enablePanicMode) fprintf(out, STATUSPREFIX" ","Clock status"); if(rtOpts->enablePanicMode) { if(ptpClock->panicMode) { fprintf(out,"panic mode"); - if (rtOpts->calibrationDelay) - fprintf(out, ", "); } } - if(rtOpts->calibrationDelay) { - fprintf(out, "%s", - ptpClock->isCalibrated ? "calibrated" : "not calibrated"); - } #else if(rtOpts->enablePanicMode || rtOpts->calibrationDelay || rtOpts->servoStabilityDetection) { fprintf(out, STATUSPREFIX" ","Clock status"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wow...@us...> - 2013-09-18 02:48:29
|
Revision: 372 http://sourceforge.net/p/ptpd/code/372 Author: wowczarek Date: 2013-09-18 02:48:25 +0000 (Wed, 18 Sep 2013) Log Message: ----------- - updated m4 version tags - changed PTPD_DOUBLE_SERVO to optional PTPD_INTEGER_SERVO - INFO() is now issued to indicate that kernel UTC offset has been set and its value - added ptpengine:management_enable and management_readwrite settings to control management message handling - fixed newlines not printed after master info in the status file when ptpd was active master - servo_max_ppm default was outside the allowed range, causing an assertion / shutdown on SIGHUP. Changed min and max values from hard-coded ones to adj_freq_max (ppm) and 2 * adj_freq_max - help text corrections / alignment fixes Modified Paths: -------------- trunk/configure.ac trunk/m4/version.m4 trunk/src/Makefile.am trunk/src/bmc.c trunk/src/datatypes.h trunk/src/dep/daemonconfig.c trunk/src/dep/ptpd_dep.h trunk/src/dep/servo.c trunk/src/dep/sys.c trunk/src/display.c trunk/src/protocol.c trunk/src/ptpd.h Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/configure.ac 2013-09-18 02:48:25 UTC (rev 372) @@ -303,24 +303,24 @@ AC_SUBST(PTP_NTPDC) AM_CONDITIONAL([NTPDC], [test x$ptp_ntpdc = xyes]) -AC_MSG_CHECKING([for double precision PI servo support]) +AC_MSG_CHECKING([for integer-based PI servo support]) AC_ARG_ENABLE( - [double-servo], + [integer-servo], [AS_HELP_STRING( - [--enable-double-servo], - [Enable support for double precision PI servo] + [--enable-integer-servo], + [Enable support for integer-based PI servo] )], - [ptp_double_servo=$enableval], - [ptp_double_servo=no] + [ptp_integer_servo=$enableval], + [ptp_integer_servo=no] ) -AC_MSG_RESULT([$ptp_double_servo]) -case "$ptp_double_servo" in +AC_MSG_RESULT([$ptp_integer_servo]) +case "$ptp_integer_servo" in yes) - PTP_DOUBLE_SERVO="-DPTPD_DOUBLE_SERVO" + PTP_INTEGER_SERVO="-DPTPD_INTEGER_SERVO" ;; esac -AC_SUBST(PTP_DOUBLE_SERVO) -AM_CONDITIONAL([DOUBLE_SERVO], [test x$ptp_double_servo = xyes]) +AC_SUBST(PTP_INTEGER_SERVO) +AM_CONDITIONAL([INTEGER_SERVO], [test x$ptp_integer_servo = xyes]) AC_MSG_CHECKING([for SIGUSR2 support]) AC_ARG_ENABLE( Modified: trunk/m4/version.m4 =================================================================== --- trunk/m4/version.m4 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/m4/version.m4 2013-09-18 02:48:25 UTC (rev 372) @@ -1,3 +1,3 @@ m4_define([PTPD_URL],[http://ptpd.sourceforge.net]) -m4_define([RELEASE_DATE],[August, 2013]) -m4_define([VERSION_NUMBER],[2.2.3]) +m4_define([RELEASE_DATE],[October, 2013]) +m4_define([VERSION_NUMBER],[2.3.0]) Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/Makefile.am 2013-09-18 02:48:25 UTC (rev 372) @@ -8,7 +8,7 @@ AM_CPPFLAGS = $(SNMP_CPPFLAGS) AM_LDFLAGS = $(SNMP_LIBS) -AM_CPPFLAGS += $(PTP_DBL) $(PTP_DAEMON) $(PTP_EXP) $(PTP_SNMP) $(PTP_SIGUSR2) $(PTP_STATISTICS) $(PTP_DOUBLE_SERVO) $(PTP_NTPDC) +AM_CPPFLAGS += $(PTP_DBL) $(PTP_DAEMON) $(PTP_EXP) $(PTP_SNMP) $(PTP_SIGUSR2) $(PTP_STATISTICS) $(PTP_INTEGER_SERVO) $(PTP_NTPDC) NULL= Modified: trunk/src/bmc.c =================================================================== --- trunk/src/bmc.c 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/bmc.c 2013-09-18 02:48:25 UTC (rev 372) @@ -244,8 +244,10 @@ * PTP not ARB - spec section 7.2 */ if (ptpClock->timePropertiesDS.ptpTimescale && + (ptpClock->timePropertiesDS.currentUtcOffsetValid || rtOpts->alwaysRespectUtcOffset) && (ptpClock->timePropertiesDS.currentUtcOffset != previousUtcOffset)) { setKernelUtcOffset(ptpClock->timePropertiesDS.currentUtcOffset); + INFO("Set kernel UTC offset to %d\n", ptpClock->timePropertiesDS.currentUtcOffset); } #endif /* MOD_TAI */ Modified: trunk/src/datatypes.h =================================================================== --- trunk/src/datatypes.h 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/datatypes.h 2013-09-18 02:48:25 UTC (rev 372) @@ -532,7 +532,7 @@ * \brief PI controller model structure */ -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO typedef struct{ int maxOutput; @@ -579,7 +579,7 @@ #endif /* PTPD_STATISTICS */ } PIservo; -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ /** @@ -747,11 +747,11 @@ uint32_t init_timestamp; /* When the clock was last initialised */ Integer32 stabilisation_time; /* How long (seconds) it took to stabilise the clock */ -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO Integer32 last_saved_drift; /* Last observed drift value written to file */ #else double last_saved_drift; /* Last observed drift value written to file */ -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ Boolean drift_saved; /* Did we save a drift value already? */ /* user description is max size + 1 to leave space for a null terminator */ @@ -922,13 +922,13 @@ int selectedPreset; int servoMaxPpb; -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO int servoKP; int servoKI; #else double servoKP; double servoKI; -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ #ifdef PTPD_STATISTICS @@ -948,11 +948,11 @@ int statsUpdateInterval; Boolean servoStabilityDetection; -#ifdef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO + Integer32 servoStabilityThreshold; +#else double servoStabilityThreshold; -#else - Integer32 servoStabilityThreshold; -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ int servoStabilityTimeout; int servoStabilityPeriod; @@ -967,6 +967,8 @@ NTPoptions ntpOptions; #endif + Boolean managementEnabled; + Boolean managementReadWrite; } RunTimeOpts; Modified: trunk/src/dep/daemonconfig.c =================================================================== --- trunk/src/dep/daemonconfig.c 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/dep/daemonconfig.c 2013-09-18 02:48:25 UTC (rev 372) @@ -363,7 +363,7 @@ 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,""));\ + 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 {\ @@ -951,6 +951,10 @@ rtOpts->statusLog.truncateOnReopen = FALSE; rtOpts->statusLog.unlinkOnClose = TRUE; +/* Management message support settings */ + rtOpts->managementEnabled = TRUE; + rtOpts->managementReadWrite = FALSE; + } /* The PtpEnginePreset structure for reference: @@ -1305,6 +1309,12 @@ CONFIG_MAP_CHARARRAY("ptpengine:unicast_address",rtOpts->unicastAddress,rtOpts->unicastAddress, "Specify unicast destination for unicast master mode (in unicast slave mode overrides delay request destination)"); + CONFIG_MAP_BOOLEAN("ptpengine:management_enable",rtOpts->managementEnabled,rtOpts->managementEnabled, + "Enable handling of PTP management messages"); + + CONFIG_MAP_BOOLEAN("ptpengine:management_readwrite",rtOpts->managementReadWrite,rtOpts->managementReadWrite, + "Accept SET and COMMAND management messages"); + CONFIG_MAP_BOOLEAN("ptpengine:igmp_refresh",rtOpts->do_IGMP_refresh,rtOpts->do_IGMP_refresh, "Send explicit IGMP joins between servo resets"); @@ -1443,7 +1453,7 @@ " when slewing the clock. Expressed in parts per million (1 ppm = shift of\n" " 1 us per second. Values above 512 will use the tick duration correction\n" " to allow even faster slewing. Default maximum is 512 without using tick.", - 512,1024); + ADJ_FREQ_MAX/1000,ADJ_FREQ_MAX/500); #endif /* HAVE_STRUCT_TIMEX_TICK */ /* @@ -1459,7 +1469,7 @@ CONFIG_MAP_INT( "servo:delayfilter_stiffness",rtOpts->s,rtOpts->s, "One-way delay filter stiffness"); -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO CONFIG_MAP_INT_MIN("servo:kp",rtOpts->servoKP,rtOpts->servoKP, "Clock servo PI controller proportional component gain (kP)",1); CONFIG_MAP_INT_MIN("servo:ki",rtOpts->servoKI,rtOpts->servoKI, @@ -1469,7 +1479,7 @@ "Clock servo PI controller proportional component gain (kP)",0.01); CONFIG_MAP_DOUBLE_MIN("servo:ki",rtOpts->servoKI,rtOpts->servoKI, "Clock servo PI controller integral component gain (kI)",0.01); -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ CONFIG_MAP_INT_RANGE("servo:max_delay",rtOpts->maxDelay,rtOpts->maxDelay, "Maximum accepted delayMS value in nanoseconds (Sync).\n" " 0 = not checked." @@ -1483,21 +1493,21 @@ " - drift will be saved to drift file / cached when considered stable,\n" " also clock stability status will be logged\n"); -#ifdef PTPD_DOUBLE_SERVO - CONFIG_MAP_DOUBLE_RANGE("servo:stability_threshold",rtOpts->servoStabilityThreshold, +#ifdef PTPD_INTEGER_SERVO + CONFIG_MAP_INT_RANGE("servo:stability_threshold",rtOpts->servoStabilityThreshold, rtOpts->servoStabilityThreshold, "Specify the observed drift standard deviation threshold in parts per billion\n" " (ppb) - if stanard deviation is within the threshold, servo is considered\n" " stable.", - 1.0,10000.0); + 1,10000); #else - CONFIG_MAP_INT_RANGE("servo:stability_threshold",rtOpts->servoStabilityThreshold, + CONFIG_MAP_DOUBLE_RANGE("servo:stability_threshold",rtOpts->servoStabilityThreshold, rtOpts->servoStabilityThreshold, "Specify the observed drift standard deviation threshold in parts per billion\n" " (ppb) - if stanard deviation is within the threshold, servo is considered\n" " stable.", - 1,10000); -#endif /* PTPD_DOUBLE_SERVO */ + 1.0,10000.0); +#endif /* PTPD_INTEGER_SERVO */ CONFIG_MAP_INT_RANGE("servo:stability_period",rtOpts->servoStabilityPeriod, rtOpts->servoStabilityPeriod, @@ -2253,20 +2263,20 @@ "Command-line option Config key Description\n" "------------------------------------------------------------------------------------\n" - "-i --interface [dev] ptpengine:interface=<dev> Interface to use (required)\n" + "-i --interface [dev] ptpengine:interface=<dev> Interface to use (required)\n" "-d --domain [n] ptpengine:domain=<n> PTP domain number\n" - "-s --slaveonly ptpengine:preset=slaveonly Slave only mode\n" - "-m --masterslave ptpengine:preset=masterslave Master, slave when not best GM\n" - "-M --masteronly ptpengine:preset=masteronly Master, passive when not best GM\n" - "-y --hybrid ptpengine:ip_mode=hybrid Hybrid mode" + "-s --slaveonly ptpengine:preset=slaveonly Slave only mode\n" + "-m --masterslave ptpengine:preset=masterslave Master, slave when not best GM\n" + "-M --masteronly ptpengine:preset=masteronly Master, passive when not best GM\n" + "-y --hybrid ptpengine:ip_mode=hybrid Hybrid mode" "\n" - "-u --unicast [IP] ptpengine:ip_mode=unicast Unicast mode for delay and response packets\n" - "-E --e2e ptpengine:delay_mechanism=E2E End to end delay detection\n" - "-P --p2p ptpengine:delay_mechanism=P2P Peer to peer delay detection\n" - " ptpengine:unicast_address=<IP>\n" + "-u --unicast [IP] ptpengine:ip_mode=unicast Unicast mode for delay and response packets\n" + " ptpengine:unicast_address=<IP>\n\n" + "-E --e2e ptpengine:delay_mechanism=E2E End to end delay detection\n" + "-P --p2p ptpengine:delay_mechanism=P2P Peer to peer delay detection\n" "\n" "-r --delay-interval [n] ptpengine:log_delayreq_interval=<n> Delay request interval\n" - " (log 2, overrides master)\n" + " (log 2, overrides master)\n" "\n" "-n --noadjust clock:no_adjust Do not adjust the clock\n" "-D<DD...> --debug global:debug_level=<level> Debug level\n" @@ -2297,9 +2307,9 @@ "\n" "-b [dev] Network interface to use\n" "-i [n] PTP domain number\n" - "-g Slave only mode\n" - "-G 'Master mode with NTP' = Master / Passive only\n" - "-W 'Master mode without NTP' = Master / Slave only\n" + "-g Slave only mode (ptpengine:preset=slaveonly)\n" + "-G 'Master mode with NTP' (ptpengine:preset=masteronly)\n" + "-W 'Master mode without NTP' (ptpengine:preset=masterslave) \n" "-U Hybrid mode\n" "-Y [n] Delay request interval (log 2)\n" "-t Do not adjust the clock\n" @@ -2430,6 +2440,8 @@ // COMPONENT_RESTART_REQUIRED("ptpengine:always_respect_utc_offset", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("ptpengine:announce_timeout_grace_period", PTPD_RESTART_NONE ); COMPONENT_RESTART_REQUIRED("ptpengine:unicast_address", PTPD_RESTART_NETWORK ); +// COMPONENT_RESTART_REQUIRED("ptpengine:management_enable", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:management_readwrite", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("ptpengine:igmp_refresh", PTPD_RESTART_NONE ); COMPONENT_RESTART_REQUIRED("ptpengine:multicast_ttl", PTPD_RESTART_NETWORK ); COMPONENT_RESTART_REQUIRED("ptpengine:ip_dscp", PTPD_RESTART_NETWORK ); Modified: trunk/src/dep/ptpd_dep.h =================================================================== --- trunk/src/dep/ptpd_dep.h 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/dep/ptpd_dep.h 2013-09-18 02:48:25 UTC (rev 372) @@ -387,7 +387,7 @@ #if !defined(__APPLE__) -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO void adjFreq_wrapper(RunTimeOpts * rtOpts, PtpClock * ptpClock, Integer32 adj); Boolean adjFreq(Integer32); @@ -401,7 +401,7 @@ double getAdjFreq(void); void informClockSource(PtpClock* ptpClock); -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ /* Observed drift save / recovery functions */ void restoreDrift(PtpClock * ptpClock, RunTimeOpts * rtOpts, Boolean quiet); @@ -447,16 +447,12 @@ void setupPIservo(PIservo* servo, const RunTimeOpts* rtOpts); void resetPIservo(PIservo* servo); -#ifdef PTPD_DOUBLE_SERVO - +#ifdef PTPD_INTEGER_SERVO +Integer32 runPIservo(PIservo* servo, const Integer32 input); +#else double runPIservo(PIservo* servo, const Integer32 input); +#endif /* PTPD_INTEGER_SERVO */ -#else - -Integer32 runPIservo(PIservo* servo, const Integer32 input); - -#endif /* PTPD_DOUBLE_SERVO */ - #ifdef PTPD_STATISTICS void updatePtpEngineStats (PtpClock* ptpClock, RunTimeOpts* rtOpts); #endif /* PTPD_STATISTICS */ Modified: trunk/src/dep/servo.c =================================================================== --- trunk/src/dep/servo.c 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/dep/servo.c 2013-09-18 02:48:25 UTC (rev 372) @@ -639,13 +639,13 @@ } -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO void warn_operator_fast_slewing(RunTimeOpts * rtOpts, PtpClock * ptpClock, Integer32 adj) #else void warn_operator_fast_slewing(RunTimeOpts * rtOpts, PtpClock * ptpClock, double adj) -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ { if(ptpClock->warned_operator_fast_slewing == 0){ if ((adj >= rtOpts->servoMaxPpb) || ((adj <= -rtOpts->servoMaxPpb))){ @@ -681,7 +681,7 @@ */ #if !defined(__APPLE__) -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO void adjFreq_wrapper(RunTimeOpts * rtOpts, PtpClock * ptpClock, Integer32 adj) @@ -716,7 +716,7 @@ } -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ #endif /* __APPLE__ */ @@ -912,11 +912,11 @@ feedDoubleMovingMean(ptpClock->delayMSFiltered, timeInternalToDouble(&ptpClock->delayMS)); } feedDoublePermanentStdDev(&ptpClock->slaveStats.ofmStats, timeInternalToDouble(&ptpClock->offsetFromMaster)); -#ifdef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO + feedIntPermanentStdDev(&ptpClock->servo.driftStats, ptpClock->servo.observedDrift); +#else feedDoublePermanentStdDev(&ptpClock->servo.driftStats, ptpClock->servo.observedDrift); -#else - feedIntPermanentStdDev(&ptpClock->servo.driftStats, ptpClock->servo.observedDrift); -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ #endif /* PTPD_STATISTICS */ @@ -971,7 +971,7 @@ } -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO Integer32 runPIservo(PIservo* servo, const Integer32 input) @@ -1128,7 +1128,7 @@ -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ #ifdef PTPD_STATISTICS void @@ -1194,11 +1194,11 @@ resetDoublePermanentStdDev(&ptpClock->slaveStats.owdStats); resetDoublePermanentStdDev(&ptpClock->slaveStats.ofmStats); -#ifdef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO + resetIntPermanentStdDev(&ptpClock->servo.driftStats); +#else resetDoublePermanentStdDev(&ptpClock->servo.driftStats); -#else - resetIntPermanentStdDev(&ptpClock->servo.driftStats); -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ } Modified: trunk/src/dep/sys.c =================================================================== --- trunk/src/dep/sys.c 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/dep/sys.c 2013-09-18 02:48:25 UTC (rev 372) @@ -691,7 +691,7 @@ len += snprint_TimeInternal(sbuf + len, sizeof(sbuf) - len, &(ptpClock->delayMS)); -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO len += snprintf(sbuf + len, sizeof(sbuf) - len, ", %d, %c", ptpClock->servo.observedDrift, ptpClock->char_last_msg); @@ -700,7 +700,7 @@ ptpClock->servo.observedDrift, ptpClock->char_last_msg); -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ #ifdef PTPD_STATISTICS @@ -710,11 +710,11 @@ ptpClock->slaveStats.ofmMean, ptpClock->slaveStats.ofmStdDev * 1E9); -#ifdef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO + len += snprintf(sbuf + len, sizeof(sbuf) - len, ", %d, %d", +#else len += snprintf(sbuf + len, sizeof(sbuf) - len, ", %.0f, %.0f", -#else - len += snprintf(sbuf + len, sizeof(sbuf) - len, ", %d, %d", -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ ptpClock->servo.driftMean, ptpClock->servo.driftStdDev ); @@ -971,14 +971,17 @@ if(ptpClock->portState == PTP_MASTER || ptpClock->portState == PTP_PASSIVE) { fprintf(out, STATUSPREFIX" %d","Priority1 ", ptpClock->priority1); - if(ptpClock->portState > PTP_MASTER) - fprintf(out, " (master: %d)\n", ptpClock->grandmasterPriority1); + if(ptpClock->portState == PTP_PASSIVE) + fprintf(out, " (best master: %d)", ptpClock->grandmasterPriority1); + fprintf(out,"\n"); fprintf(out, STATUSPREFIX" %d","Priority2 ", ptpClock->priority2); - if(ptpClock->portState > PTP_MASTER) - fprintf(out, " (master: %d)\n", ptpClock->grandmasterPriority2); + if(ptpClock->portState == PTP_PASSIVE) + fprintf(out, " (best master: %d)", ptpClock->grandmasterPriority2); + fprintf(out,"\n"); fprintf(out, STATUSPREFIX" %d","ClockClass ", ptpClock->clockQuality.clockClass); - if(ptpClock->portState > PTP_MASTER) - fprintf(out, " (master: %d)\n", ptpClock->grandmasterClockQuality.clockClass); + if(ptpClock->portState == PTP_PASSIVE) + fprintf(out, " (best master: %d)", ptpClock->grandmasterClockQuality.clockClass); + fprintf(out,"\n"); } @@ -1321,7 +1324,7 @@ */ /* Integer32 version */ -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO Boolean adjFreq(Integer32 adj) @@ -1500,15 +1503,15 @@ return !adjtimex(&t); } -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO Integer32 getAdjFreq(void) #else double getAdjFreq(void) -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ { struct timex t; Integer32 freq; @@ -1527,18 +1530,18 @@ DBGV(" kernel adj is: float %f, Integer32 %d, kernel freq is: %d", dFreq, freq, t.freq); -#ifdef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO + return(freq); +#else return(dFreq); -#else - return(freq); -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ } -#ifdef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO +#define DRIFTFORMAT "%d" +#else #define DRIFTFORMAT "%.0f" -#else -#define DRIFTFORMAT "%d" -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ void restoreDrift(PtpClock * ptpClock, RunTimeOpts * rtOpts, Boolean quiet) @@ -1546,11 +1549,11 @@ FILE *driftFP; Boolean reset_offset = FALSE; -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO Integer32 recovered_drift; #else double recovered_drift; -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ DBGV("restoreDrift called\n"); @@ -1576,11 +1579,11 @@ rtOpts->driftFile); } else -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO if (fscanf(driftFP, "%d", &recovered_drift) != 1) { #else if (fscanf(driftFP, "%lf", &recovered_drift) != 1) { -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ PERROR("Could not load saved offset from drift file - using current kernel frequency offset"); } else { @@ -1657,12 +1660,12 @@ return; } -#ifndef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO fprintf(driftFP, "%d\n", ptpClock->servo.observedDrift); #else /* The fractional part really won't make a difference here */ fprintf(driftFP, "%d\n", (int)round(ptpClock->servo.observedDrift)); -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ if (quiet) { DBGV("Wrote observed drift to %s\n", rtOpts->driftFile); Modified: trunk/src/display.c =================================================================== --- trunk/src/display.c 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/display.c 2013-09-18 02:48:25 UTC (rev 372) @@ -487,11 +487,11 @@ /* TODO: implement me */ } -#ifdef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO +#define FORMAT_SERVO "%d" +#else #define FORMAT_SERVO "%f" -#else -#define FORMAT_SERVO "%d" -#endif +#endif /* PTPD_INTEGER_SERVO */ /**\brief Display runTimeOptions structure*/ void Modified: trunk/src/protocol.c =================================================================== --- trunk/src/protocol.c 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/protocol.c 2013-09-18 02:48:25 UTC (rev 372) @@ -509,11 +509,11 @@ ptpClock->servo.driftStdDev = 0; ptpClock->servo.isStable = FALSE; ptpClock->servo.statsCalculated = FALSE; -#ifdef PTPD_DOUBLE_SERVO +#ifdef PTPD_INTEGER_SERVO + resetIntPermanentStdDev(&ptpClock->servo.driftStats); +#else resetDoublePermanentStdDev(&ptpClock->servo.driftStats); -#else - resetIntPermanentStdDev(&ptpClock->servo.driftStats); -#endif /* PTPD_DOUBLE_SERVO */ +#endif /* PTPD_INTEGER_SERVO */ timerStart(STATISTICS_UPDATE_TIMER, rtOpts->statsUpdateInterval, ptpClock->itimer); #endif /* PTPD_STATISTICS */ @@ -2041,12 +2041,19 @@ (targetPort.portNumber == allOnesPortNumber)); } -static void + +static void handleManagement(MsgHeader *header, Boolean isFromSelf, RunTimeOpts *rtOpts, PtpClock *ptpClock) { DBGV("Management message received : \n"); + if(!rtOpts->managementEnabled) { + DBGV("Dropping management message - management message support disabled"); + ptpClock->counters.discardedMessages++; + return; + } + if (isFromSelf) { DBGV("handleManagement: Ignore message from self \n"); return; @@ -2063,9 +2070,18 @@ if(!acceptManagementMessage(ptpClock->portIdentity, ptpClock->msgTmp.manage.targetPortIdentity)) { DBGV("handleManagement: The management message was not accepted"); + ptpClock->counters.discardedMessages++; return; } + if(!rtOpts->managementReadWrite && + (ptpClock->msgTmp.manage.actionField == SET || + ptpClock->msgTmp.manage.actionField == COMMAND)) { + DBGV("Dropping SET/COMMAND management message - read-only mode enabled"); + ptpClock->counters.discardedMessages++; + return; + } + /* is this an error status management TLV? */ if(ptpClock->msgTmp.manage.tlv->tlvType == TLV_MANAGEMENT_ERROR_STATUS) { DBGV("handleManagement: Error Status TLV\n"); Modified: trunk/src/ptpd.h =================================================================== --- trunk/src/ptpd.h 2013-09-17 14:52:47 UTC (rev 371) +++ trunk/src/ptpd.h 2013-09-18 02:48:25 UTC (rev 372) @@ -104,7 +104,9 @@ /* No support for double precision servo for Apple */ #ifdef __APPLE__ -#undef PTPD_DOUBLE_SERVO +#ifndef PTPD_INTEGER_SERVO +#define PTPD_INTEGER_SERVO +#endif /* PTPD_INTEGER_SERVO */ #endif /* APPLE */ /* NOTE: this macro can be refactored into a function */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gn...@us...> - 2013-09-18 20:53:33
|
Revision: 374 http://sourceforge.net/p/ptpd/code/374 Author: gnn Date: 2013-09-18 20:53:29 +0000 (Wed, 18 Sep 2013) Log Message: ----------- Fix problems relating to various versions of utmp and utmpx on various operating systems. Code compiles and runs on FreeBSD 8, 9, 10 and Ubuntu. Modified Paths: -------------- trunk/configure.ac trunk/src/dep/servo.c Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-09-18 03:09:24 UTC (rev 373) +++ trunk/configure.ac 2013-09-18 20:53:29 UTC (rev 374) @@ -183,7 +183,7 @@ AC_TYPE_SIGNAL AC_FUNC_STRFTIME AC_FUNC_VPRINTF -AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol glob utmpxname updwtmpx]) +AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol glob pututline utmpxname updwtmpx]) AC_MSG_CHECKING([for RUNTIME_DEBUG]) AC_ARG_ENABLE( Modified: trunk/src/dep/servo.c =================================================================== --- trunk/src/dep/servo.c 2013-09-18 03:09:24 UTC (rev 373) +++ trunk/src/dep/servo.c 2013-09-18 20:53:29 UTC (rev 374) @@ -560,13 +560,21 @@ #endif /* OLD_TIME */ /* ======== BEGIN OLD TIME EVENT - UTMP / WTMP =========== */ +#ifdef HAVE_UTMPNAME utmpname(UTMP_FILE); +#endif /* HAVE_UTMPNAME */ setutent(); +#ifdef HAVE_PUTUTLINE pututline(&ut); +#endif /* HAVE_PUTUTLINE */ endutent(); +#ifdef HAVE_UTMPNAME utmpname(WTMP_FILE); +#endif /* HAVE_UTMPNAME */ setutent(); +#ifdef HAVE_PUTUTLINE pututline(&ut); +#endif /* HAVE_PUTUTLINE */ endutent(); /* ======== END OLD TIME EVENT - UTMP / WTMP =========== */ @@ -622,13 +630,21 @@ #endif /* NEW_TIME */ /* ======== BEGIN NEW TIME EVENT - UTMP / WTMP =========== */ +#ifdef HAVE_UTMPNAME utmpname(UTMP_FILE); +#endif /* HAVE_UTMPNAME */ setutent(); +#ifdef HAVE_PUTUTLINE pututline(&ut); +#endif /* HAVE_PUTUTLINE */ endutent(); +#ifdef HAVE_UTMPNAME utmpname(WTMP_FILE); +#endif /* HAVE_UTMPNAME */ setutent(); +#ifdef HAVE_PUTUTLINE pututline(&ut); +#endif /* HAVE_PUTUTLINE */ endutent(); /* ======== END NEW TIME EVENT - UTMP / WTMP =========== */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gn...@us...> - 2013-10-04 19:15:44
|
Revision: 392 http://sourceforge.net/p/ptpd/code/392 Author: gnn Date: 2013-10-04 19:15:41 +0000 (Fri, 04 Oct 2013) Log Message: ----------- Add the beginnings of a test plan a configuration files to be used in testing the client. Added Paths: ----------- trunk/test/ trunk/test/client-e2e-pcap.conf trunk/test/client-e2e-socket.conf trunk/test/testing.org Added: trunk/test/client-e2e-pcap.conf =================================================================== --- trunk/test/client-e2e-pcap.conf (rev 0) +++ trunk/test/client-e2e-pcap.conf 2013-10-04 19:15:41 UTC (rev 392) @@ -0,0 +1,452 @@ +; ======================================== +; PTPDv2 version 2.3.0 PCAP client configuration +; ======================================== + +; NOTE: the following settings are affected by ptpengine:preset selection: +; ptpengine:slave_only +; clock:no_adjust +; ptpengine:clock_class - allowed range and default value +; To see all preset settings, run ptpd2 -H (--long-help) + +; Network interface to use (required) +ptpengine:interface = + +; PTP engine preset: +; none = Defaults, no clock class restrictions +; slaveonly = Slave only (clock class 255 only) +; masteronly = Master, passive when not best master (clock class 0..127) +; masterslave = Full IEEE 1588 implementation: +; Master, slave when not best master +; (clock class 128..254) +; +; Options: none slaveonly masteronly masterslave +ptpengine:preset = slaveonly + +; IP transmission mode (requires IP transport) - hybrid mode uses +; multicast for sync and announce, and unicast for delay request / +; response +; Options: multicast unicast hybrid +ptpengine:ip_mode = multicast + +; Transport type for PTP packets +; Options: ipv4 ethernet +ptpengine:transport = ethernet + +; Use libpcap for sending and receiving traffic (automatically enabled +; in Ethernet mode) +ptpengine:use_libpcap = N + +; Delay detection mode used - use DELAY_DISABLED for syntonisation +; only (no synchronisation) +; Options: E2E P2P DELAY_DISABLED +ptpengine:delay_mechanism = E2E + +; PTP domain number +ptpengine:domain = 0 + +; Slave only mode (if set, overrides preset setting and sets clock class to 255) +ptpengine:slave_only = Y + +; Specify latency correction for incoming packets +ptpengine:inbound_latency = 0 + +; Specify latency correction for outgoing packets +ptpengine:outbound_latency = 0 + +; Compatibility option: In slave state, always respect UTC offset +; announced by best master, even if the the +; currrentUtcOffsetValid flag is announced FALSE +ptpengine:always_respect_utc_offset = N + +; PTP announce message interval in master state (expressed as log 2 +; i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_announce_interval = 1 + +; PTP announce receipt timeout announced in master state +ptpengine:announce_timeout = 6 + +; PTP announce receipt timeout grace period in slave state: +; when announce receipt timeout occurs, disqualify current best GM, +; then wait n times announce receipt timeout before resetting. +; Allows for a seamless GM failover when standby GMs are slow to react. +; When set to 0, this option is not used. +ptpengine:announce_timeout_grace_period = 0 + +; PTP sync message interval in master state (expressed as log 2 +; i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_sync_interval = 0 + +; Initial delay request message interval for slave mode, before first +; delay response is received (expressed as log 2 i.e. -1=0.5s, 0=1s, +; 1=2s etc.) +ptpengine:log_delayreq_interval_initial = 0 + +; Minimum delay request message interval in master state, in slave +; mode overrides the master interval, required in hybrid mode +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_delayreq_interval = 0 + +; Minimum peer delay request message interval in master state. +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_peer_delayreq_interval = 1 + +; Maximum number of foreign masters (foreign master record size +; allocated at startup) + +ptpengine:foreignrecord_capacity = 5 + +; Specify Allan variance announced in master state +ptpengine:ptp_allan_variance = 28768 + +; Clock accuracy range announced in master state +; Options: ACC_25NS ACC_100NS ACC_250NS ACC_1US ACC_2.5US ACC_10US +; ACC_25US ACC_100US ACC_250US ACC_1MS ACC_2.5MS ACC_10MS ACC_25MS +; ACC_100MS ACC_250MS ACC_1S ACC_10S ACC_10SPLUS ACC_UNKNOWN +ptpengine:ptp_clock_accuracy = ACC_UNKNOWN + +; underlying time source UTC offset announced in master state +ptpengine:utc_offset = 0 + +; underlying time source UTC offset validity announced in master state +ptpengine:utc_offset_valid = N + +; underlying time source time traceability announced in master state +ptpengine:time_traceable = N + +; underlying time source frequency traceability announced in master state +ptpengine:frequency_traceable = N + +; Time scale announced in master state (with ARB timescale, UTC +; properties are ignored by slaves), when clock class 13 (application +; specific), this value is ignored and ARB is used. +; Options: PTP ARB +ptpengine:ptp_timescale = ARB + +; Time source announced in master state +; Options: ATOMIC_CLOCK GPS TERRESTRIAL_RADIO PTP NTP HAND_SET OTHER +; INTERNAL_OSCILLATOR +ptpengine:ptp_timesource = INTERNAL_OSCILLATOR + +; Clock class - announced in master state. Always 255 for slave-only mode. +; Minimum, maximum and default values are controlled by presets. +; If set to 13 (application specific time source), announced +; time scale is always set to ARB. This setting controls the +; states a PTP port can be in. If below 128, port will only +; be in MASTER or PASSIVE states (master only). If above 127, +; port will be in MASTER or SLAVE states. +ptpengine:clock_class = 255 + +; Priority 1 value announced in master state and used for Best Master +; Clock selection +ptpengine:priority1 = 128 + +; Priority 2 value announced in master state and used for Best Master +; Clock selection +ptpengine:priority2 = 128 + +; Specify unicast destination for unicast master mode (in unicast +; slave mode overrides delay request destination) +ptpengine:unicast_address = + +; Send explicit IGMP joins between servo resets +ptpengine:igmp_refresh = Y + +; Multicast time to live for multicast PTP packets (ignored and set to +; 1 for peer to peer messages) +ptpengine:multicast_ttl = 64 + +; DiffServ CodepPoint for packet prioritisation (decimal). When set to +; zero, this option is not used. +; 46 = Expedited Forwarding (0x2e) +ptpengine:ip_dscp = 0 + +; Use PTP alternative multicast group like PTPv1 (if compiled with +; PTPD_EXPERIMENTAL): +; 0 = 224.0.1.129, 1 = 224.0.1.130, 2 = 224.0.1.131, 3 = 224.0.1.132 +ptpengine:alt_mcast_group = 0 + +; Enable outlier filter for the Delay Response component in slave state +ptpengine:delay_outlier_filter_enable = N + +; Delay Response outlier filter action. If set to 'filter', outliers +; are replaced with moving average +; Options: discard filter +ptpengine:delay_outlier_filter_action = filter + +; Number of samples in the Delay Response outlier filter buffer +ptpengine:delay_outlier_filter_capacity = 20 + +; Delay Response outlier filter threshold: multiplier for the Peirce's +; maximum standard deviation. When set below 1.0, filter is tighter, +; when set above 1.0, filter is looser than standard Peirce's test. +ptpengine:delay_outlier_filter_threshold = 1.000000 + +; Delay Response outlier weight: if an outlier is detected, this value +; determines the amount of its deviation from mean that is used to +; build the standard deviation statistics and influence further +; outlier detection. +; When set to 1.0, the outlier is used as is. +; +ptpengine:delay_outlier_weight = 1.000000 + +; Enable outlier filter for the Sync component in slave state +ptpengine:sync_outlier_filter_enable = N + +; Sync outlier filter action. If set to 'filter', outliers are +; replaced with moving average +; Options: discard filter +ptpengine:sync_outlier_filter_action = filter + +; Number of samples in the Sync outlier filter buffer +ptpengine:sync_outlier_filter_capacity = 20 + +; Sync outlier filter threshold: multiplier for the Peirce's maximum +; standard deviation. When set below 1.0, filter is tighter, when set +; above 1.0, filter is looser than standard Peirce's test. +ptpengine:sync_outlier_filter_threshold = 1.000000 + +; Sync outlier weight: if an outlier is detected, this value +; determines the amount of its deviation from mean that is used to +; build the standard deviation statistics and influence further +; outlier detection. When set to 1.0, the outlier is used as is. +ptpengine:sync_outlier_weight = 1.000000 + +; Delay between moving to slave state and enabling clock updates +; expressed as number of statistics update periods (see +; global:statistics_update_interval). This allows one-way delay to +; stabilise before starting clock updates. Activated when going into +; slave state and during GM failover in slave state. +; 0 - not used. +ptpengine:calibration_delay = 0 + +; Enable panic mode: when offset from master is above 1 second, stop +; updating the clock for a period of time and then step the clock if +; offset remains above 1 second. +ptpengine:panic_mode = N + +; Duration of the panic mode period (no clock updates) when offset +; above 1 second detected +ptpengine:panic_mode_duration = 2 + +; Use JobID (PID) for UUID +ptpengine:pid_as_clock_idendity = N + +; Fail over to NTP when PTP time sync not available - requires +; ntpengine:enabled but does not require the rest of NTP configuration +; - will warn instead of failing over if cannot control ntpd. +ptpengine:ntp_failover = N + +; NTP failover timeout in seconds: time between PTP slave going into +; LISTENING state, and failing over to NTP. 0 = fail over immediately. +ptpengine:ntp_failover_timeout = 60 + +; Prefer NTP time synchronisation when not controlling the clock (all +; states, including slave when clock:no_adjust set) +ptpengine:prefer_ntp = N + +; When entering panic mode, fail over to NTP (after the NTP failover +; timeout period) - requires ntpengine:enabled but does not require +; the rest of NTP configuration - will warn instead of failing over if +; it cannot control ntpd. +ptpengine:panic_mode_ntp = N + +; Do not adjust the clock +clock:no_adjust = N + +; Do not reset the clock - only slew +clock:no_reset = N + +; Observed drift handling method between servo restarts: +; reset: set to zero (not recommended) +; preserve: use kernel value, +; file: load and save to drift file on startup/shutdown, use kernel +; value inbetween. +; To specify drift file, use the clock:drift_file setting. +; Options: reset preserve file +clock:drift_handling = preserve + +; Specify drift file +clock:drift_file = /etc/ptpd2_kernelclock.drift + +; Maximum absolute frequency shift which can be applied to the clock servo +; when slewing the clock. Expressed in parts per million (1 ppm = shift of +; 1 us per second. Values above 512 will use the tick duration correction +; to allow even faster slewing. Default maximum is 512 without using tick. +clock:max_offset_ppm = 512 + +; One-way delay filter stiffness +servo:delayfilter_stiffness = 6 + +; Clock servo PI controller proportional component gain (kP) +servo:kp = 1000.000000 + +; Clock servo PI controller integral component gain (kI) +servo:ki = 10.000000 + +; Maximum accepted delayMS value in nanoseconds (Sync). +; 0 = not checked. +servo:max_delay = 0 + +; Enable clock synchronisation servo stability detection +; (based on standard deviation of the observed drift value) +; - drift will be saved to drift file / cached when considered stable, +; also clock stability status will be logged +; +servo:stability_detection = N + +; Specify the observed drift standard deviation threshold in parts per billion +; (ppb) - if stanard deviation is within the threshold, servo is considered +; stable. +servo:stability_threshold = 5.000000 + +; Specify for how many statistics update intervals the observed drift standard +; deviation has to stay within threshold to be considered stable +; +servo:stability_period = 3 + +; Specify after how many minutes without stabilisation servo is considered +; unstable. Assists with logging servo stability information and +; allows to preserve observed drift if servo cannot stabilise. +; +servo:stability_timeout = 10 + +; Do not update one-way delay if slave to master delay (from Delay Response) +; is greater than this value (nanoseconds). 0 = not used. +servo:max_delay = 0 + +; Do not reset the clock if offset from master is greater +; than this value (nanoseconds). 0 = not used. +servo:max_offset = 0 + +; Send log messages to syslog. Disabling this +; sends all messages to stdout (or speficied log file) +global:use_syslog = N + +; Lock file location +global:lock_file = + +; Use mode specific and interface specific lock files (overrides +; global:lock_file) +global:auto_lockfile = N + +; Lock file directory: used with automatic mode-specific lock files, +; also used when no lock file is specified. When lock file +; is specified, it's expected to be an absolute path. +global:lock_directory = /var/run + +; Skip lock file checking and locking +global:ignore_lock = N + +; File used to record data about sync packets. Setting this enables recording. +global:quality_file = + +; Maximum sync packet record file size (in kB) - file will be +; truncated if size exceeds the limit. +; 0 - no limit. +global:quality_file_max_size = 0 + +; Enable log rotation of the sync packet record file up to n files. +; 0 - do not rotate. +global:quality_file_max_files = 0 + +; Truncate the sync packet record file every time it is (re) opened - +; on startup and SIGHUP +global:quality_file_truncate = N + +; File used to log ptpd2 status information +global:status_file = /var/run/ptpd2.status.log + +; Enable / disable writing status information to file +global:log_status = Y + +; Status file update interval in seconds +; +global:status_update_interval = 1 + +; Specify log file path (event log). Setting this enables logging to file. +global:log_file = /var/run/ptpd2.event.log + +; Maximum log file size (in kB) - log file will be truncated if size +; exceeds the limit. +; 0 - no limit. +global:log_file_max_size = 0 + +; Enable log rotation of the sync packet record file up to n files. +; 0 - do not rotate +global:log_file_max_files = 0 + +; Truncate the log file every time it is (re) opened - on startup and SIGHUP +global:log_file_truncate = N + +; Specify log level (only messages of the specified priority or higer +; will be logged). +; The minimal level is LOG_ERR. LOG_ALL enables debug output if compiled with +; RUNTIME_DEBUG +; Options: LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_ALL +global:log_level = LOG_ALL + +; Specify statistics log file path. Setting this enables logging of +; statistics but can be overriden with global:log_statistics +global:statistics_file = /var/run/ptpd2.stats.log + +; Log timing statistics every n seconds for Sync and Delay Response +; messages (0 - log all) +global:statistics_log_interval = 0 + +; Maximum statistics log file size (in kB) - log file will be +; truncated if size exceeds the limit. +; 0 - no limit. +global:statistics_file_max_size = 0 + +; Enable log rotation of the statistics file up to n files. 0 - do not rotate +; +global:statistics_file_max_files = 0 + +; Truncate the statistics file every time it is (re) opened - on +; startup and SIGHUP +global:statistics_file_truncate = N + +; Dump the contents of every PTP packet +global:dump_packets = N + +; Run in foreground with statistics and all messages logged to stdout. +; Overrides log file and statistics file settings and disables syslog. +; +global:verbose_foreground = N + +; Run in foreground +global:foreground = N + +; Log timing statistics for every PTP packet received +global:log_statistics = Y + +; Linux only: bind ptpd2 process to a selected CPU core number. +; 0 = first CPU core, etc. -1 = do not bind to a single core. +global:cpuaffinity_cpucore = -1 + +; Clock synchronisation statistics update interval in seconds +; +global:statistics_update_interval = 5 + +; Enable NTPd integration +ntpengine:enabled = N + +; Enable control over local NTPd daemon +ntpengine:control_enabled = N + +; NTP control check interval in seconds +; +ntpengine:check_interval = 15 + +; NTP key number - must be configured as a trusted control key in ntp.conf, +; and must be non-zero for the ntpengine:control_enabled setting to take effect. +; +ntpengine:key_id = 0 + +; NTP key (plain text, max. 20 characters) - must match the key +; configured in ntpd's keys file, and must be non-zero for the +; ntpengine:control_enabled setting to take effect. +ntpengine:key = + +; ========= newline required in the end ========== + Property changes on: trunk/test/client-e2e-pcap.conf ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/test/client-e2e-socket.conf =================================================================== --- trunk/test/client-e2e-socket.conf (rev 0) +++ trunk/test/client-e2e-socket.conf 2013-10-04 19:15:41 UTC (rev 392) @@ -0,0 +1,452 @@ +; ======================================== +; PTPDv2 version 2.3.0-svn default configuration +; ======================================== + +; NOTE: the following settings are affected by ptpengine:preset selection: +; ptpengine:slave_only +; clock:no_adjust +; ptpengine:clock_class - allowed range and default value +; To see all preset settings, run ptpd2 -H (--long-help) + +; Network interface to use (required) +ptpengine:interface = + +; PTP engine preset: +; none = Defaults, no clock class restrictions +; slaveonly = Slave only (clock class 255 only) +; masteronly = Master, passive when not best master (clock class 0..127) +; masterslave = Full IEEE 1588 implementation: +; Master, slave when not best master +; (clock class 128..254) +; +; Options: none slaveonly masteronly masterslave +ptpengine:preset = slaveonly + +; IP transmission mode (requires IP transport) - hybrid mode uses +; multicast for sync and announce, and unicast for delay request / +; response +; Options: multicast unicast hybrid +ptpengine:ip_mode = multicast + +; Transport type for PTP packets +; Options: ipv4 ethernet +ptpengine:transport = ipv4 + +; Use libpcap for sending and receiving traffic (automatically enabled +; in Ethernet mode) +ptpengine:use_libpcap = N + +; Delay detection mode used - use DELAY_DISABLED for syntonisation +; only (no synchronisation) +; Options: E2E P2P DELAY_DISABLED +ptpengine:delay_mechanism = E2E + +; PTP domain number +ptpengine:domain = 0 + +; Slave only mode (if set, overrides preset setting and sets clock class to 255) +ptpengine:slave_only = Y + +; Specify latency correction for incoming packets +ptpengine:inbound_latency = 0 + +; Specify latency correction for outgoing packets +ptpengine:outbound_latency = 0 + +; Compatibility option: In slave state, always respect UTC offset +; announced by best master, even if the the +; currrentUtcOffsetValid flag is announced FALSE +ptpengine:always_respect_utc_offset = N + +; PTP announce message interval in master state (expressed as log 2 +; i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_announce_interval = 1 + +; PTP announce receipt timeout announced in master state +ptpengine:announce_timeout = 6 + +; PTP announce receipt timeout grace period in slave state: +; when announce receipt timeout occurs, disqualify current best GM, +; then wait n times announce receipt timeout before resetting. +; Allows for a seamless GM failover when standby GMs are slow to react. +; When set to 0, this option is not used. +ptpengine:announce_timeout_grace_period = 0 + +; PTP sync message interval in master state (expressed as log 2 +; i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_sync_interval = 0 + +; Initial delay request message interval for slave mode, before first +; delay response is received (expressed as log 2 i.e. -1=0.5s, 0=1s, +; 1=2s etc.) +ptpengine:log_delayreq_interval_initial = 0 + +; Minimum delay request message interval in master state, in slave +; mode overrides the master interval, required in hybrid mode +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_delayreq_interval = 0 + +; Minimum peer delay request message interval in master state. +; (expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.) +ptpengine:log_peer_delayreq_interval = 1 + +; Maximum number of foreign masters (foreign master record size +; allocated at startup) + +ptpengine:foreignrecord_capacity = 5 + +; Specify Allan variance announced in master state +ptpengine:ptp_allan_variance = 28768 + +; Clock accuracy range announced in master state +; Options: ACC_25NS ACC_100NS ACC_250NS ACC_1US ACC_2.5US ACC_10US +; ACC_25US ACC_100US ACC_250US ACC_1MS ACC_2.5MS ACC_10MS ACC_25MS +; ACC_100MS ACC_250MS ACC_1S ACC_10S ACC_10SPLUS ACC_UNKNOWN +ptpengine:ptp_clock_accuracy = ACC_UNKNOWN + +; underlying time source UTC offset announced in master state +ptpengine:utc_offset = 0 + +; underlying time source UTC offset validity announced in master state +ptpengine:utc_offset_valid = N + +; underlying time source time traceability announced in master state +ptpengine:time_traceable = N + +; underlying time source frequency traceability announced in master state +ptpengine:frequency_traceable = N + +; Time scale announced in master state (with ARB timescale, UTC +; properties are ignored by slaves), when clock class 13 (application +; specific), this value is ignored and ARB is used. +; Options: PTP ARB +ptpengine:ptp_timescale = ARB + +; Time source announced in master state +; Options: ATOMIC_CLOCK GPS TERRESTRIAL_RADIO PTP NTP HAND_SET OTHER +; INTERNAL_OSCILLATOR +ptpengine:ptp_timesource = INTERNAL_OSCILLATOR + +; Clock class - announced in master state. Always 255 for slave-only mode. +; Minimum, maximum and default values are controlled by presets. +; If set to 13 (application specific time source), announced +; time scale is always set to ARB. This setting controls the +; states a PTP port can be in. If below 128, port will only +; be in MASTER or PASSIVE states (master only). If above 127, +; port will be in MASTER or SLAVE states. +ptpengine:clock_class = 255 + +; Priority 1 value announced in master state and used for Best Master +; Clock selection +ptpengine:priority1 = 128 + +; Priority 2 value announced in master state and used for Best Master +; Clock selection +ptpengine:priority2 = 128 + +; Specify unicast destination for unicast master mode (in unicast +; slave mode overrides delay request destination) +ptpengine:unicast_address = + +; Send explicit IGMP joins between servo resets +ptpengine:igmp_refresh = Y + +; Multicast time to live for multicast PTP packets (ignored and set to +; 1 for peer to peer messages) +ptpengine:multicast_ttl = 64 + +; DiffServ CodepPoint for packet prioritisation (decimal). When set to +; zero, this option is not used. +; 46 = Expedited Forwarding (0x2e) +ptpengine:ip_dscp = 0 + +; Use PTP alternative multicast group like PTPv1 (if compiled with +; PTPD_EXPERIMENTAL): +; 0 = 224.0.1.129, 1 = 224.0.1.130, 2 = 224.0.1.131, 3 = 224.0.1.132 +ptpengine:alt_mcast_group = 0 + +; Enable outlier filter for the Delay Response component in slave state +ptpengine:delay_outlier_filter_enable = N + +; Delay Response outlier filter action. If set to 'filter', outliers +; are replaced with moving average +; Options: discard filter +ptpengine:delay_outlier_filter_action = filter + +; Number of samples in the Delay Response outlier filter buffer +ptpengine:delay_outlier_filter_capacity = 20 + +; Delay Response outlier filter threshold: multiplier for the Peirce's +; maximum standard deviation. When set below 1.0, filter is tighter, +; when set above 1.0, filter is looser than standard Peirce's test. +ptpengine:delay_outlier_filter_threshold = 1.000000 + +; Delay Response outlier weight: if an outlier is detected, this value +; determines the amount of its deviation from mean that is used to +; build the standard deviation statistics and influence further +; outlier detection. +; When set to 1.0, the outlier is used as is. +; +ptpengine:delay_outlier_weight = 1.000000 + +; Enable outlier filter for the Sync component in slave state +ptpengine:sync_outlier_filter_enable = N + +; Sync outlier filter action. If set to 'filter', outliers are +; replaced with moving average +; Options: discard filter +ptpengine:sync_outlier_filter_action = filter + +; Number of samples in the Sync outlier filter buffer +ptpengine:sync_outlier_filter_capacity = 20 + +; Sync outlier filter threshold: multiplier for the Peirce's maximum +; standard deviation. When set below 1.0, filter is tighter, when set +; above 1.0, filter is looser than standard Peirce's test. +ptpengine:sync_outlier_filter_threshold = 1.000000 + +; Sync outlier weight: if an outlier is detected, this value +; determines the amount of its deviation from mean that is used to +; build the standard deviation statistics and influence further +; outlier detection. When set to 1.0, the outlier is used as is. +ptpengine:sync_outlier_weight = 1.000000 + +; Delay between moving to slave state and enabling clock updates +; expressed as number of statistics update periods (see +; global:statistics_update_interval). This allows one-way delay to +; stabilise before starting clock updates. Activated when going into +; slave state and during GM failover in slave state. +; 0 - not used. +ptpengine:calibration_delay = 0 + +; Enable panic mode: when offset from master is above 1 second, stop +; updating the clock for a period of time and then step the clock if +; offset remains above 1 second. +ptpengine:panic_mode = N + +; Duration of the panic mode period (no clock updates) when offset +; above 1 second detected +ptpengine:panic_mode_duration = 2 + +; Use JobID (PID) for UUID +ptpengine:pid_as_clock_idendity = N + +; Fail over to NTP when PTP time sync not available - requires +; ntpengine:enabled but does not require the rest of NTP configuration +; - will warn instead of failing over if cannot control ntpd. +ptpengine:ntp_failover = N + +; NTP failover timeout in seconds: time between PTP slave going into +; LISTENING state, and failing over to NTP. 0 = fail over immediately. +ptpengine:ntp_failover_timeout = 60 + +; Prefer NTP time synchronisation when not controlling the clock (all +; states, including slave when clock:no_adjust set) +ptpengine:prefer_ntp = N + +; When entering panic mode, fail over to NTP (after the NTP failover +; timeout period) - requires ntpengine:enabled but does not require +; the rest of NTP configuration - will warn instead of failing over if +; it cannot control ntpd. +ptpengine:panic_mode_ntp = N + +; Do not adjust the clock +clock:no_adjust = N + +; Do not reset the clock - only slew +clock:no_reset = N + +; Observed drift handling method between servo restarts: +; reset: set to zero (not recommended) +; preserve: use kernel value, +; file: load and save to drift file on startup/shutdown, use kernel +; value inbetween. +; To specify drift file, use the clock:drift_file setting. +; Options: reset preserve file +clock:drift_handling = preserve + +; Specify drift file +clock:drift_file = /etc/ptpd2_kernelclock.drift + +; Maximum absolute frequency shift which can be applied to the clock servo +; when slewing the clock. Expressed in parts per million (1 ppm = shift of +; 1 us per second. Values above 512 will use the tick duration correction +; to allow even faster slewing. Default maximum is 512 without using tick. +clock:max_offset_ppm = 512 + +; One-way delay filter stiffness +servo:delayfilter_stiffness = 6 + +; Clock servo PI controller proportional component gain (kP) +servo:kp = 1000.000000 + +; Clock servo PI controller integral component gain (kI) +servo:ki = 10.000000 + +; Maximum accepted delayMS value in nanoseconds (Sync). +; 0 = not checked. +servo:max_delay = 0 + +; Enable clock synchronisation servo stability detection +; (based on standard deviation of the observed drift value) +; - drift will be saved to drift file / cached when considered stable, +; also clock stability status will be logged +; +servo:stability_detection = N + +; Specify the observed drift standard deviation threshold in parts per billion +; (ppb) - if stanard deviation is within the threshold, servo is considered +; stable. +servo:stability_threshold = 5.000000 + +; Specify for how many statistics update intervals the observed drift standard +; deviation has to stay within threshold to be considered stable +; +servo:stability_period = 3 + +; Specify after how many minutes without stabilisation servo is considered +; unstable. Assists with logging servo stability information and +; allows to preserve observed drift if servo cannot stabilise. +; +servo:stability_timeout = 10 + +; Do not update one-way delay if slave to master delay (from Delay Response) +; is greater than this value (nanoseconds). 0 = not used. +servo:max_delay = 0 + +; Do not reset the clock if offset from master is greater +; than this value (nanoseconds). 0 = not used. +servo:max_offset = 0 + +; Send log messages to syslog. Disabling this +; sends all messages to stdout (or speficied log file) +global:use_syslog = N + +; Lock file location +global:lock_file = + +; Use mode specific and interface specific lock files (overrides +; global:lock_file) +global:auto_lockfile = N + +; Lock file directory: used with automatic mode-specific lock files, +; also used when no lock file is specified. When lock file +; is specified, it's expected to be an absolute path. +global:lock_directory = /var/run + +; Skip lock file checking and locking +global:ignore_lock = N + +; File used to record data about sync packets. Setting this enables recording. +global:quality_file = + +; Maximum sync packet record file size (in kB) - file will be +; truncated if size exceeds the limit. +; 0 - no limit. +global:quality_file_max_size = 0 + +; Enable log rotation of the sync packet record file up to n files. +; 0 - do not rotate. +global:quality_file_max_files = 0 + +; Truncate the sync packet record file every time it is (re) opened - +; on startup and SIGHUP +global:quality_file_truncate = N + +; File used to log ptpd2 status information +global:status_file = /var/run/ptpd2.status.log + +; Enable / disable writing status information to file +global:log_status = Y + +; Status file update interval in seconds +; +global:status_update_interval = 1 + +; Specify log file path (event log). Setting this enables logging to file. +global:log_file = /var/run/ptpd2.event.log + +; Maximum log file size (in kB) - log file will be truncated if size +; exceeds the limit. +; 0 - no limit. +global:log_file_max_size = 0 + +; Enable log rotation of the sync packet record file up to n files. +; 0 - do not rotate +global:log_file_max_files = 0 + +; Truncate the log file every time it is (re) opened - on startup and SIGHUP +global:log_file_truncate = N + +; Specify log level (only messages of the specified priority or higer +; will be logged). +; The minimal level is LOG_ERR. LOG_ALL enables debug output if compiled with +; RUNTIME_DEBUG +; Options: LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_ALL +global:log_level = LOG_ALL + +; Specify statistics log file path. Setting this enables logging of +; statistics but can be overriden with global:log_statistics +global:statistics_file = /var/run/ptpd2.stats.log + +; Log timing statistics every n seconds for Sync and Delay Response +; messages (0 - log all) +global:statistics_log_interval = 0 + +; Maximum statistics log file size (in kB) - log file will be +; truncated if size exceeds the limit. +; 0 - no limit. +global:statistics_file_max_size = 0 + +; Enable log rotation of the statistics file up to n files. 0 - do not rotate +; +global:statistics_file_max_files = 0 + +; Truncate the statistics file every time it is (re) opened - on +; startup and SIGHUP +global:statistics_file_truncate = N + +; Dump the contents of every PTP packet +global:dump_packets = N + +; Run in foreground with statistics and all messages logged to stdout. +; Overrides log file and statistics file settings and disables syslog. +; +global:verbose_foreground = N + +; Run in foreground +global:foreground = N + +; Log timing statistics for every PTP packet received +global:log_statistics = Y + +; Linux only: bind ptpd2 process to a selected CPU core number. +; 0 = first CPU core, etc. -1 = do not bind to a single core. +global:cpuaffinity_cpucore = -1 + +; Clock synchronisation statistics update interval in seconds +; +global:statistics_update_interval = 5 + +; Enable NTPd integration +ntpengine:enabled = N + +; Enable control over local NTPd daemon +ntpengine:control_enabled = N + +; NTP control check interval in seconds +; +ntpengine:check_interval = 15 + +; NTP key number - must be configured as a trusted control key in ntp.conf, +; and must be non-zero for the ntpengine:control_enabled setting to take effect. +; +ntpengine:key_id = 0 + +; NTP key (plain text, max. 20 characters) - must match the key +; configured in ntpd's keys file, and must be non-zero for the +; ntpengine:control_enabled setting to take effect. +ntpengine:key = + +; ========= newline required in the end ========== + Property changes on: trunk/test/client-e2e-socket.conf ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: trunk/test/testing.org =================================================================== --- trunk/test/testing.org (rev 0) +++ trunk/test/testing.org 2013-10-04 19:15:41 UTC (rev 392) @@ -0,0 +1,18 @@ +Unified Test Plan for PTPd Versions + +NOTE: This file is in Emacs org mode, do not adjust the markup unless +absolutely necessary. + +* Client + +The client needs to be tested in the following matrix. For each test +there is a relevant config file listed. + +| | E2E | P2P | +| Socket | client-e2e-socket.conf | | +| PCAP | client-e2e-pcap.conf | | + +* Server + +The server is tested with a series of its own clients. Not optimal + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wow...@us...> - 2013-10-10 15:12:15
|
Revision: 399 http://sourceforge.net/p/ptpd/code/399 Author: wowczarek Date: 2013-10-10 15:12:12 +0000 (Thu, 10 Oct 2013) Log Message: ----------- - Fix for feature request #17: CLI options now take priority over config file settings, sufficient warning is issued for every setting affected, - Updated INSTALL file with more help details and configure options Modified Paths: -------------- trunk/INSTALL trunk/src/datatypes.h trunk/src/dep/daemonconfig.c trunk/src/dep/iniparser/dictionary.c trunk/src/dep/iniparser/dictionary.h trunk/src/dep/startup.c Modified: trunk/INSTALL =================================================================== --- trunk/INSTALL 2013-10-10 05:45:22 UTC (rev 398) +++ trunk/INSTALL 2013-10-10 15:12:12 UTC (rev 399) @@ -2,7 +2,7 @@ 4 October 2013 -George V. Neville-Neil +George V. Neville-Neil, Wojciech Owczarek The PTP Daemon is known to work on FreeBSD, NetBSD, Mac OS X and Linux systems. @@ -18,17 +18,38 @@ 1. cd into the root of the tree (which is where the file you're reading resides) + 2. autoreconf -vi + 3. ./configure + + To make use of all advanced functions it is recommended to + configure the build with the following options: + + ./configure --enable-statistics --enable-ntpdc + + To add support for printing all message counters on a SIGUSR2, + add --enable-sigusr2=counters to the configure parameters. + 4. make -5. Read the manual pages + +5. Read the manual pages. ptpd2 itself also provides an extensive help: + run ptpd2 --help to see the short help + run ptpd2 --long-help to see the long help for all settings + run ptpd2 -e [key:setting] to display help for a single setting + 6. Update test/client-e2e-socket.conf so that its "ptpengine:interface = " setting points to a network interface on your test machine that can see PTP packets from a grandmaster. -6. Test it in place: ./src/ptpd2 test/client-e2e-socket.conf -7. Check the output of the daemon in /var/run/ptpd2.stats.log -8. If the results look good make install +6. Test it in place: ./src/ptpd2 -c test/client-e2e-socket.conf + +7. Check the log output of the daemon in /var/run/ptpd2.event.log + Check statistics output of the daemon in /var/run/ptpd2.stats.log + Check the status file /var/run/ptpd2.status.log + +8. If the results look good, make install + The daemon may work on other Posix based systems but this is not guaranteed. Patches and fixes are welcome on the source forge page Modified: trunk/src/datatypes.h =================================================================== --- trunk/src/datatypes.h 2013-10-10 05:45:22 UTC (rev 398) +++ trunk/src/datatypes.h 2013-10-10 15:12:12 UTC (rev 399) @@ -891,8 +891,8 @@ * 0 = no change */ UInteger32 restartSubsystems; - /* config dictionary containers - current and candidate */ - dictionary *currentConfig, *candidateConfig; + /* config dictionary containers - current, candidate and from CLI*/ + dictionary *currentConfig, *candidateConfig, *cliConfig; int selectedPreset; Modified: trunk/src/dep/daemonconfig.c =================================================================== --- trunk/src/dep/daemonconfig.c 2013-10-10 05:45:22 UTC (rev 398) +++ trunk/src/dep/daemonconfig.c 2013-10-10 15:12:12 UTC (rev 399) @@ -1837,7 +1837,7 @@ /* make sure the %x% special keys are unset */ HELP_END(); - dictionary_merge( dict, *target); + dictionary_merge( dict, *target, 0, NULL); dictionary_del(dict); return TRUE; @@ -2258,6 +2258,8 @@ "\n" "usage: "PTPD_PROGNAME" <options> < --section:key=value...>\n" "\n" + "WARNING: Any command-line options take priority over options from config file!\n" + "\n" "Basic options: \n" "\n" "-c --config-file [path] Configuration file\n" Modified: trunk/src/dep/iniparser/dictionary.c =================================================================== --- trunk/src/dep/iniparser/dictionary.c 2013-10-10 05:45:22 UTC (rev 398) +++ trunk/src/dep/iniparser/dictionary.c 2013-10-10 15:12:12 UTC (rev 399) @@ -355,7 +355,7 @@ return ; } -int dictionary_merge(dictionary* source, dictionary* dest) +int dictionary_merge(dictionary* source, dictionary* dest, int warn, const char* warnStr) { int i = 0; @@ -369,6 +369,11 @@ /* do not overwrite with an empty key */ if((source->val[i] == NULL) || (strlen(source->val[i])==0)) continue; + if(warn && strcmp(dictionary_get(dest,source->key[i],""),"") != 0) { + WARNING("Warning: %s=\"%s\" setting will be overwritten with \"%s\" %s\n", + source->key[i], source->val[i], + dictionary_get(dest,source->key[i],""), warnStr); + } if ( dictionary_set( dest, source->key[i], source->val[i]) != 0) return -1; } Modified: trunk/src/dep/iniparser/dictionary.h =================================================================== --- trunk/src/dep/iniparser/dictionary.h 2013-10-10 05:45:22 UTC (rev 398) +++ trunk/src/dep/iniparser/dictionary.h 2013-10-10 15:12:12 UTC (rev 399) @@ -18,6 +18,12 @@ Includes ---------------------------------------------------------------------------*/ +#include <syslog.h> + +#ifndef WARNING +#define WARNING(x, ...) logMessage(LOG_WARNING, x, ##__VA_ARGS__) +#endif /* WARNING */ + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -162,6 +168,6 @@ /*--------------------------------------------------------------------------*/ void dictionary_dump(dictionary * d, FILE * out); -int dictionary_merge(dictionary * source, dictionary * dest); +int dictionary_merge(dictionary * source, dictionary * dest, int warn, const char* warnStr); #endif Modified: trunk/src/dep/startup.c =================================================================== --- trunk/src/dep/startup.c 2013-10-10 05:45:22 UTC (rev 398) +++ trunk/src/dep/startup.c 2013-10-10 15:12:12 UTC (rev 399) @@ -158,7 +158,7 @@ dictionary_del(tmpConfig); goto end; } - + dictionary_merge(rtOpts->cliConfig, tmpConfig, 1, "from command line"); /* Load default config to fill in the blanks in the config file */ RunTimeOpts tmpOpts; loadDefaultSettings(&tmpOpts); @@ -458,7 +458,9 @@ if (rtOpts.currentConfig != NULL) dictionary_del(rtOpts.currentConfig); - + if(rtOpts.cliConfig != NULL) + dictionary_del(rtOpts.cliConfig); + free(ptpClock); ptpClock = NULL; @@ -518,9 +520,9 @@ * instead of just setting the rtOpts field. * * Config parameter evaluation priority order: - * 1. Config file (parsed last), merged with 2. and 3. - * 2. Any dictionary keys set in the getopt_long loop - * 3. CLI long section:key type options + * 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 CLO options * 4. Defaults and any rtOpts fields set in the getopt_long loop **/ @@ -532,10 +534,11 @@ loadDefaultSettings(rtOpts); /* initialise the config dictionary */ rtOpts->candidateConfig = dictionary_new(0); + rtOpts->cliConfig = dictionary_new(0); /* parse all long section:key options and clean up argv for getopt */ - loadCommandLineKeys(rtOpts->candidateConfig,argc,argv); + loadCommandLineKeys(rtOpts->cliConfig,argc,argv); /* parse the normal short and long option, exit on error */ - if (!loadCommandLineOptions(rtOpts, rtOpts->candidateConfig, argc, argv, ret)) { + if (!loadCommandLineOptions(rtOpts, rtOpts->cliConfig, argc, argv, ret)) { goto fail; } @@ -559,12 +562,15 @@ /* 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"); } else { *ret = 1; + dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 1, "from command line"); goto configcheck; } + } else { + dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 1, "from command line"); } - /** * This is where the final checking of the candidate settings container happens. * A dictionary is returned with only the known options, explicitly set to defaults This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wow...@us...> - 2013-10-16 05:46:38
|
Revision: 404 http://sourceforge.net/p/ptpd/code/404 Author: wowczarek Date: 2013-10-16 05:46:34 +0000 (Wed, 16 Oct 2013) Log Message: ----------- Pre-release batch #4 - final functionality additions - Corrected delay request interval initialisation for master mode - Support for SO_TIMESTAMPING software timestamping with fixes from Jan - Beginnings of network code cleanup - Added support for ACLs (management and timing) - Added message rates and GM info to status file - Updated (re-generated) the default config file - Fixed IFDEF typo disabling a block of code in updateDelay - Renamed ptpengine:announce_timeout to ptpengine:announce_receipt_timeout - Renamed ptpengine:announce_timeout_grace_period to ptpengine: announce_receipt_grace_period Modified Paths: -------------- trunk/configure.ac trunk/src/Makefile.am trunk/src/bmc.c trunk/src/datatypes.h trunk/src/dep/daemonconfig.c trunk/src/dep/daemonconfig.h trunk/src/dep/datatypes_dep.h trunk/src/dep/iniparser/dictionary.c trunk/src/dep/iniparser/dictionary.h trunk/src/dep/msg.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/display.c trunk/src/protocol.c trunk/src/ptpd.h trunk/src/ptpd2.conf.5.in trunk/src/ptpd2.conf.default-full Added Paths: ----------- trunk/src/dep/ipv4_acl.c trunk/src/dep/ipv4_acl.h Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/configure.ac 2013-10-16 05:46:34 UTC (rev 404) @@ -23,7 +23,6 @@ AC_SUBST([VERSION_NUMBER]) # Checks for programs. -AC_PROG_CXX AC_PROG_AWK AC_PROG_CC AC_PROG_LIBTOOL Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/Makefile.am 2013-10-16 05:46:34 UTC (rev 404) @@ -4,7 +4,7 @@ sbin_PROGRAMS = ptpd2 man_MANS = ptpd2.8 ptpd2.conf.8 -AM_CFLAGS = $(SNMP_CFLAGS) +AM_CFLAGS = $(SNMP_CFLAGS) -Wall AM_CPPFLAGS = $(SNMP_CPPFLAGS) AM_LDFLAGS = $(SNMP_LIBS) @@ -24,6 +24,8 @@ datatypes.h \ dep/constants_dep.h \ dep/datatypes_dep.h \ + dep/ipv4_acl.h \ + dep/ipv4_acl.c \ dep/msg.c \ dep/net.c \ dep/ptpd_dep.h \ Modified: trunk/src/bmc.c =================================================================== --- trunk/src/bmc.c 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/bmc.c 2013-10-16 05:46:34 UTC (rev 404) @@ -106,6 +106,7 @@ ptpClock->portIdentity.portNumber = NUMBER_PORTS; /* select the initial rate of delayreqs until we receive the first announce message */ + ptpClock->logMinDelayReqInterval = rtOpts->initial_delayreq; clearTime(&ptpClock->peerMeanPathDelay); @@ -156,6 +157,7 @@ ptpClock->clockQuality.offsetScaledLogVariance; ptpClock->grandmasterPriority1 = ptpClock->priority1; ptpClock->grandmasterPriority2 = ptpClock->priority2; + ptpClock->logMinDelayReqInterval = rtOpts->subsequent_delayreq; /*Time Properties data set*/ ptpClock->timePropertiesDS.currentUtcOffsetValid = rtOpts->timeProperties.currentUtcOffsetValid; Modified: trunk/src/datatypes.h =================================================================== --- trunk/src/datatypes.h 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/datatypes.h 2013-10-16 05:46:34 UTC (rev 404) @@ -510,6 +510,8 @@ uint32_t discardedMessages; /* only messages we shouldn't be receiving - ignored from self don't count */ uint32_t unknownMessages; /* unknown type - also increments discarded */ uint32_t ignoredAnnounce; /* ignored Announce messages: acl / security / preference */ + uint32_t aclTimingDiscardedMessages; /* Timing messages discarded by access lists */ + uint32_t aclManagementDiscardedMessages; /* Timing messages discarded by access lists */ /* error counters */ uint32_t messageRecvErrors; /* message receive errors */ @@ -935,8 +937,18 @@ #endif Boolean managementEnabled; - Boolean managementReadWrite; + Boolean managementSetEnable; + /* Access list settings */ + Boolean timingAclEnabled; + Boolean managementAclEnabled; + char timingAclPermitText[PATH_MAX]; + char timingAclDenyText[PATH_MAX]; + char managementAclPermitText[PATH_MAX]; + char managementAclDenyText[PATH_MAX]; + int timingAclOrder; + int managementAclOrder; + } RunTimeOpts; Modified: trunk/src/dep/daemonconfig.c =================================================================== --- trunk/src/dep/daemonconfig.c 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/daemonconfig.c 2013-10-16 05:46:34 UTC (rev 404) @@ -957,8 +957,14 @@ /* Management message support settings */ rtOpts->managementEnabled = TRUE; - rtOpts->managementReadWrite = FALSE; + rtOpts->managementSetEnable = FALSE; +/* IP ACL settings */ + + rtOpts->timingAclEnabled = FALSE; + rtOpts->managementAclEnabled = FALSE; + rtOpts->timingAclOrder = ACL_DENY_PERMIT; + rtOpts->managementAclOrder = ACL_DENY_PERMIT; } /* The PtpEnginePreset structure for reference: @@ -1179,10 +1185,10 @@ CONFIG_MAP_INT_RANGE("ptpengine:log_announce_interval",rtOpts->announceInterval,rtOpts->announceInterval, "PTP announce message interval in master state "LOG2_HELP,-1,7); - CONFIG_MAP_INT_RANGE("ptpengine:announce_timeout",rtOpts->announceReceiptTimeout,rtOpts->announceReceiptTimeout, + CONFIG_MAP_INT_RANGE("ptpengine:announce_receipt_timeout",rtOpts->announceReceiptTimeout,rtOpts->announceReceiptTimeout, "PTP announce receipt timeout announced in master state",2,255); - CONFIG_MAP_INT_RANGE("ptpengine:announce_timeout_grace_period",rtOpts->announceTimeoutGracePeriod,rtOpts->announceTimeoutGracePeriod, + CONFIG_MAP_INT_RANGE("ptpengine:announce_receipt_grace_period",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" @@ -1305,9 +1311,10 @@ CONFIG_KEY_CONDITIONAL_WARNING(rtOpts->ip_mode == IPMODE_HYBRID, "ptpengine:log_delayreq_interval", "It is recommended to set the delay request interval (ptpengine:log_delayreq_interval) in hybrid mode"); - /* unicast mode -> must specify delayreq interval */ + + /* unicast mode -> must specify delayreq interval if we can become a slave */ CONFIG_KEY_CONDITIONAL_DEPENDENCY("ptpengine:ip_mode", - rtOpts->ip_mode == IPMODE_UNICAST, + rtOpts->ip_mode == IPMODE_UNICAST && rtOpts->clockQuality.clockClass > 127, "unicast", "ptpengine:log_delayreq_interval"); /* @@ -1328,7 +1335,7 @@ CONFIG_MAP_BOOLEAN("ptpengine:management_enable",rtOpts->managementEnabled,rtOpts->managementEnabled, "Enable handling of PTP management messages"); - CONFIG_MAP_BOOLEAN("ptpengine:management_readwrite",rtOpts->managementReadWrite,rtOpts->managementReadWrite, + CONFIG_MAP_BOOLEAN("ptpengine:management_set_enable",rtOpts->managementSetEnable,rtOpts->managementSetEnable, "Accept SET and COMMAND management messages"); CONFIG_MAP_BOOLEAN("ptpengine:igmp_refresh",rtOpts->do_IGMP_refresh,rtOpts->do_IGMP_refresh, @@ -1440,9 +1447,63 @@ CONFIG_KEY_DEPENDENCY("ptpengine:panic_mode_ntp", "ntpengine:enabled"); - #endif /* PTPD_NTPDC */ + /* Defining the ACLs enables ACL matching */ + CONFIG_KEY_TRIGGER("ptpengine:timing_acl_permit",rtOpts->timingAclEnabled,TRUE,FALSE); + CONFIG_KEY_TRIGGER("ptpengine:timing_acl_deny",rtOpts->timingAclEnabled,TRUE,FALSE); + CONFIG_KEY_TRIGGER("ptpengine:management_acl_permit",rtOpts->managementAclEnabled,TRUE,FALSE); + CONFIG_KEY_TRIGGER("ptpengine:management_acl_deny",rtOpts->managementAclEnabled,TRUE,FALSE); + + CONFIG_MAP_CHARARRAY("ptpengine:timing_acl_permit",rtOpts->timingAclPermitText, rtOpts->timingAclPermitText, + "Permit access control list for timing packets. The format is a series of comma-separated\n" + " network prefixes in full CIDR notation a.b.c.d/x where a.b.c.d is the subnet and x is the mask.\n" + " For single IP addresses, a /32 mask is required for the ACL to be parsed correctly.\n" + " The match is performed on the source IP address of the incoming messages.\n" + " IP access lists are only supported when using the IP transport"); + + CONFIG_MAP_CHARARRAY("ptpengine:timing_acl_deny",rtOpts->timingAclDenyText, rtOpts->timingAclDenyText, + "Deny access control list for timing packets. The format is a series of comma-separated\n" + " network prefixes in full CIDR notation a.b.c.d/x where a.b.c.d is the subnet and x is the mask.\n" + " For single IP addresses, a /32 mask is required for the ACL to be parsed correctly.\n" + " The match is performed on the source IP address of the incoming messages.\n" + " IP access lists are only supported when using the IP transport"); + + CONFIG_MAP_CHARARRAY("ptpengine:management_acl_permit",rtOpts->managementAclPermitText, rtOpts->managementAclPermitText, + "Permit access control list for management messages. The format is a series of comma-separated\n" + " network prefixes in full CIDR notation a.b.c.d/x where a.b.c.d is the subnet and x is the mask.\n" + " For single IP addresses, a /32 mask is required for the ACL to be parsed correctly.\n" + " The match is performed on the source IP address of the incoming messages.\n" + " IP access lists are only supported when using the IP transport"); + + CONFIG_MAP_CHARARRAY("ptpengine:management_acl_deny",rtOpts->managementAclDenyText, rtOpts->managementAclDenyText, + "Deny access control list for management messages. The format is a series of comma-separated\n" + " network prefixes in full CIDR notation a.b.c.d/x where a.b.c.d is the subnet and x is the mask.\n" + " For single IP addresses, a /32 mask is required for the ACL to be parsed correctly.\n" + " The match is performed on the source IP address of the incoming messages.\n" + " IP access lists are only supported when using the IP transport"); + + CONFIG_MAP_SELECTVALUE("ptpengine:timing_acl_order",rtOpts->timingAclOrder,rtOpts->timingAclOrder, + "Order in which permit and deny access lists are evaluated for timing packets,\n" + " the evaluation process is the same as for Apache httpd.", + "permit-deny", ACL_PERMIT_DENY, + "deny-permit", ACL_DENY_PERMIT + ); + + CONFIG_MAP_SELECTVALUE("ptpengine:management_acl_order",rtOpts->managementAclOrder,rtOpts->managementAclOrder, + "Order in which permit and deny access lists are evaluated for management messages,\n" + " the evaluation process is the same as for Apache httpd.", + "permit-deny", ACL_PERMIT_DENY, + "deny-permit", ACL_DENY_PERMIT + ); + + + /* Ethernet mode disables ACL processing*/ + CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport == IEEE_802_3,rtOpts->timingAclEnabled,FALSE,rtOpts->timingAclEnabled); + CONFIG_KEY_CONDITIONAL_TRIGGER(rtOpts->transport == IEEE_802_3,rtOpts->managementAclEnabled,FALSE,rtOpts->managementAclEnabled); + + + /* ===== clock section ===== */ CONFIG_MAP_BOOLEAN("clock:no_adjust",rtOpts->noAdjust,ptpPreset.noAdjust, @@ -1689,9 +1750,14 @@ * default field used for both. verbose_foreground triggers nonDaemon which is OK, * but we don't want foreground=y to switch on verbose_foreground if not set. */ + CONFIG_MAP_BOOLEAN("global:foreground",rtOpts->nonDaemon,rtOpts->nonDaemon, - "Run in foreground"); + "Run in foreground - this setting is ignored when global:verbose_foreground is set"); + if(CONFIG_ISTRUE("global:verbose_foreground")) { + rtOpts->nonDaemon = TRUE; + } + /* If this is processed after verbose_foreground, we can still control logStatistics */ CONFIG_MAP_BOOLEAN("global:log_statistics",rtOpts->logStatistics,rtOpts->logStatistics, "Log timing statistics for every PTP packet received"); @@ -1758,6 +1824,51 @@ /* ==== Any additional logic should go here ===== */ + /* Check timing packet ACLs */ + if(rtOpts->timingAclEnabled) { + + int pResult, dResult; + + if((pResult = maskParser(rtOpts->timingAclPermitText, NULL)) == -1) + ERROR("Error while parsing timing permit access list: \"%s\"\n", + rtOpts->timingAclPermitText); + if((dResult = maskParser(rtOpts->timingAclDenyText, NULL)) == -1) + ERROR("Error while parsing timing deny access list: \"%s\"\n", + rtOpts->timingAclDenyText); + + /* -1 = ACL format error*/ + if(pResult == -1 || dResult == -1) { + parseResult = FALSE; + rtOpts->timingAclEnabled = FALSE; + } + /* 0 = no entries - we simply don't match */ + if(pResult == 0 && dResult == 0) { + rtOpts->timingAclEnabled = FALSE; + } + } + + /* Check management message ACLs */ + if(rtOpts->managementAclEnabled) { + int pResult, dResult; + + if((pResult = maskParser(rtOpts->managementAclPermitText, NULL)) == -1) + ERROR("Error while parsing management permit access list: \"%s\"\n", + rtOpts->managementAclPermitText); + if((dResult = maskParser(rtOpts->managementAclDenyText, NULL)) == -1) + ERROR("Error while parsing management deny access list: \"%s\"\n", + rtOpts->managementAclDenyText); + + /* -1 = ACL format error*/ + if(pResult == -1 || dResult == -1) { + parseResult = FALSE; + rtOpts->managementAclEnabled = FALSE; + } + /* 0 = no entries - we simply don't match */ + if(pResult == 0 && dResult == 0) { + rtOpts->managementAclEnabled = FALSE; + } + } + /* Scale the maxPPM to PPB */ rtOpts->servoMaxPpb *= 1000; @@ -1919,7 +2030,7 @@ { RunTimeOpts rtOpts; - dictionary *dict, *tmp; + dictionary *dict; loadDefaultSettings(&rtOpts); dict = dictionary_new(0); @@ -1935,7 +2046,7 @@ SET_SHOWDEFAULT(); /* NULL will always be returned in this mode */ - tmp = parseConfig(dict, &rtOpts); + parseConfig(dict, &rtOpts); END_SHOWDEFAULT(); dictionary_del(dict); @@ -1955,7 +2066,7 @@ { RunTimeOpts rtOpts; - dictionary *dict, *tmp; + dictionary *dict; loadDefaultSettings(&rtOpts); dict = dictionary_new(0); @@ -1964,7 +2075,7 @@ printf("\n============== Full list of "PTPD_PROGNAME" settings ========\n\n"); /* NULL will always be returned in this mode */ - tmp = parseConfig(dict, &rtOpts); + parseConfig(dict, &rtOpts); HELP_END(); dictionary_del(dict); @@ -1981,7 +2092,7 @@ { RunTimeOpts rtOpts; - dictionary *dict, *tmp; + dictionary *dict; loadDefaultSettings(&rtOpts); dict = dictionary_new(0); @@ -1990,7 +2101,7 @@ printf("\n"); /* NULL will always be returned in this mode */ - tmp = parseConfig(dict, &rtOpts); + parseConfig(dict, &rtOpts); if(!HELP_ITEM_FOUND()) printf("Unknown setting: %s\n\n", key); @@ -2440,7 +2551,7 @@ COMPONENT_RESTART_REQUIRED("ptpengine:pid_as_clock_idendity", PTPD_RESTART_PROTOCOL ); COMPONENT_RESTART_REQUIRED("ptpengine:ptp_slaveonly", PTPD_RESTART_PROTOCOL ); COMPONENT_RESTART_REQUIRED("ptpengine:log_announce_interval", PTPD_UPDATE_DATASETS ); - COMPONENT_RESTART_REQUIRED("ptpengine:announce_timeout", PTPD_UPDATE_DATASETS ); + COMPONENT_RESTART_REQUIRED("ptpengine:announce_receipt_timeout", PTPD_UPDATE_DATASETS ); COMPONENT_RESTART_REQUIRED("ptpengine:log_sync_interval", PTPD_UPDATE_DATASETS ); // COMPONENT_RESTART_REQUIRED("ptpengine:log_delayreq_interval_initial",PTPD_RESTART_NONE ); COMPONENT_RESTART_REQUIRED("ptpengine:log_delayreq_interval", PTPD_UPDATE_DATASETS ); @@ -2460,10 +2571,10 @@ // COMPONENT_RESTART_REQUIRED("ptpengine:always_respect_utc_offset", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("ptpengine:prefer_utc_offset_valid", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("ptpengine:require_utc_offset_valid", PTPD_RESTART_NONE ); -// COMPONENT_RESTART_REQUIRED("ptpengine:announce_timeout_grace_period", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:announce_receipt_grace_period", PTPD_RESTART_NONE ); COMPONENT_RESTART_REQUIRED("ptpengine:unicast_address", PTPD_RESTART_NETWORK ); // COMPONENT_RESTART_REQUIRED("ptpengine:management_enable", PTPD_RESTART_NONE ); -// COMPONENT_RESTART_REQUIRED("ptpengine:management_readwrite", PTPD_RESTART_NONE ); +// COMPONENT_RESTART_REQUIRED("ptpengine:management_set_enable", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("ptpengine:igmp_refresh", PTPD_RESTART_NONE ); COMPONENT_RESTART_REQUIRED("ptpengine:multicast_ttl", PTPD_RESTART_NETWORK ); COMPONENT_RESTART_REQUIRED("ptpengine:ip_dscp", PTPD_RESTART_NETWORK ); @@ -2485,6 +2596,14 @@ // COMPONENT_RESTART_REQUIRED("ptpengine:sync_outlier_weight", PTPD_RESTART_NONE ); // COMPONENT_RESTART_REQUIRED("ptpengine:calibration_delay", PTPD_RESTART_NONE ); + COMPONENT_RESTART_REQUIRED("ptpengine:timing_acl_permit", PTPD_RESTART_ACLS); + COMPONENT_RESTART_REQUIRED("ptpengine:timing_acl_deny", PTPD_RESTART_ACLS); + COMPONENT_RESTART_REQUIRED("ptpengine:management_acl_permit", PTPD_RESTART_ACLS); + COMPONENT_RESTART_REQUIRED("ptpengine:management_acl_deny", PTPD_RESTART_ACLS); + COMPONENT_RESTART_REQUIRED("ptpengine:timing_acl_order", PTPD_RESTART_ACLS); + COMPONENT_RESTART_REQUIRED("ptpengine:management_acl_order", PTPD_RESTART_ACLS); + + #endif /* PTPD_STATISTICS */ // COMPONENT_RESTART_REQUIRED("ptpengine:panic_mode", PTPD_RESTART_NONE ); Modified: trunk/src/dep/daemonconfig.h =================================================================== --- trunk/src/dep/daemonconfig.h 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/daemonconfig.h 2013-10-16 05:46:34 UTC (rev 404) @@ -35,11 +35,14 @@ #define PTPD_RESTART_PEIRCE 1 << 8 #endif +#define PTPD_RESTART_ACLS 1 << 9 + #ifdef PTPD_NTPDC -#define PTPD_RESTART_NTPENGINE 1 << 9 -#define PTPD_RESTART_NTPCONTROL 1 << 10 +#define PTPD_RESTART_NTPENGINE 1 << 10 +#define PTPD_RESTART_NTPCONTROL 1 << 11 #endif /* PTPD_NTPDC */ + #define LOG2_HELP "(expressed as log 2 i.e. -1=0.5s, 0=1s, 1=2s etc.)" /* Structure defining a PTP engine preset */ Modified: trunk/src/dep/datatypes_dep.h =================================================================== --- trunk/src/dep/datatypes_dep.h 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/datatypes_dep.h 2013-10-16 05:46:34 UTC (rev 404) @@ -91,7 +91,14 @@ int ttlGeneral; int ttlEvent; struct ether_addr etherDest; - struct ether_addr peerEtherDest; + struct ether_addr peerEtherDest; +#ifdef SO_TIMESTAMPING + Boolean txTimestampFailure; +#endif /* SO_TIMESTAMPING */ + + Ipv4AccessList* timingAcl; + Ipv4AccessList* managementAcl; + } NetPath; typedef struct { Modified: trunk/src/dep/iniparser/dictionary.c =================================================================== --- trunk/src/dep/iniparser/dictionary.c 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/iniparser/dictionary.c 2013-10-16 05:46:34 UTC (rev 404) @@ -369,8 +369,10 @@ /* do not overwrite with an empty key */ if((source->val[i] == NULL) || (strlen(source->val[i])==0)) continue; - if(warn && strcmp(dictionary_get(dest,source->key[i],""),"") != 0) { - WARNING("Warning: %s=\"%s\" setting will be overwritten with \"%s\" %s\n", + /* no need to warn for settings whose value will not change */ + if(warn && (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); } Modified: trunk/src/dep/iniparser/dictionary.h =================================================================== --- trunk/src/dep/iniparser/dictionary.h 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/iniparser/dictionary.h 2013-10-16 05:46:34 UTC (rev 404) @@ -20,6 +20,8 @@ #include <syslog.h> +void logMessage(int priority, const char *format, ...); + #ifndef WARNING #define WARNING(x, ...) logMessage(LOG_WARNING, x, ##__VA_ARGS__) #endif /* WARNING */ Added: trunk/src/dep/ipv4_acl.c =================================================================== --- trunk/src/dep/ipv4_acl.c (rev 0) +++ trunk/src/dep/ipv4_acl.c 2013-10-16 05:46:34 UTC (rev 404) @@ -0,0 +1,335 @@ +/*- + * Copyright (c) 2013 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 ipv4_acl.c + * @date Sun Oct 13 21:02:23 2013 + * + * @brief Code to handle IPv4 access control lists + * + * Functions in this file parse, create and match IPv4 ACLs. + * + */ + +#include "../ptpd.h" + +/* qsort() compare function for sorting ACL entries */ +static int +cmpAclEntry(const void *p1, const void *p2) +{ + + const AclEntry *left = p1; + const AclEntry *right = p2; + + if(left->network > right->network) + return 1; + if(left->network < right->network) + return -1; + return 0; + +} + +/* Parse an ACL string into an aclEntry table and return number of entries. output can be NULL */ +int +maskParser(const char* input, AclEntry* output) +{ + int i; + int offset=0; + int masks_found=0; + int matches; + int oct1,oct2,oct3,oct4,mask; + uint32_t network, bitmask; + + static char* expr1="%d.%d.%d.%d/%d%[, ]"; + static char* expr2="%d.%d.%d.%d/%d"; + + char** expr = &expr1; + char junk[10]; + char buf[PATH_MAX]; + + int len = strlen(input); + + for(i=0; i <= len; i++) { + + memset(buf,0,PATH_MAX); + strncpy(buf,input+offset,i-offset); + if(i==len) expr = &expr2; + matches=sscanf(buf,*expr,&oct1,&oct2,&oct3,&oct4,&mask,&junk); +// printf("%d + %d of %d, buf: %s , matches: %d\n",offset,i,len,buf,matches); + if(matches==6 || (i==len && matches==5)) { + + offset = i; + if(!IN_RANGE(oct1,0,255)) + return -1; + if(!IN_RANGE(oct2,0,255)) + return -1; + if(!IN_RANGE(oct3,0,255)) + return -1; + if(!IN_RANGE(oct4,0,255)) + return -1; + if(!IN_RANGE(mask,0,32)) + return -1; + network = (oct1 << 24) | (oct2 << 16) | (oct3 << 8) | oct4; + /* shifting a 32-bit field by 32 bits is undefined in C */ + if(mask==0) + bitmask = 0; + else + bitmask = ~0 << (32 - mask); + network &= bitmask; + if(output != NULL) { + output[masks_found].bitmask = bitmask; + output[masks_found].network = network; + output[masks_found].netmask = (uint16_t)mask; + } + DBGV("Got mask: %d.%d.%d.%d/%d, network: %08x, netmask %08x\n", + oct1, oct2, oct3, oct4, mask, network, bitmask); + masks_found++; + } + + } + if(output != NULL) + qsort(output, masks_found, sizeof(AclEntry), cmpAclEntry); + return masks_found; + +} + + +/* Create a maskTable from a text ACL */ +static MaskTable* +createMaskTable(const char* input) +{ + MaskTable* ret; + int masksFound = maskParser(input, NULL); + if(masksFound>0) { + ret=(MaskTable*)calloc(1,sizeof(MaskTable)); + ret->entries = (AclEntry*)calloc(masksFound, sizeof(AclEntry)); + ret->numEntries = maskParser(input,ret->entries); + } else { + if(masksFound < 0) + ERROR("Error while parsing access list: \"%s\"\n", input); + return NULL; + } + return ret; +} + +/* Print the contents of a single mask table */ +static void +dumpMaskTable(MaskTable* table) +{ + int i; + uint32_t network; + if(table == NULL) + return; + INFO("number of entries: %d\n",table->numEntries); + if(table->entries != NULL) { + for(i = 0; i < table->numEntries; i++) { + AclEntry this = table->entries[i]; +#ifdef PTPD_MSBF + network = this.network; +#else + network = htonl(this.network); +#endif + INFO("%d.%d.%d.%d/%d (0x%.8x / 0x%.8x), matches: %d\n", + *((uint8_t*)&network), *((uint8_t*)&network+1), + *((uint8_t*)&network+2), *((uint8_t*)&network+3), this.netmask, + this.network, this.bitmask, this.hitCount); + } + } + +} + +/* Destroy an Ipv4AccessList structure */ +void +freeIpv4AccessList(Ipv4AccessList* acl) +{ + if(acl==NULL) + return; + if(acl->permitEntries!=NULL && acl->permitEntries->entries != NULL) + free(acl->permitEntries->entries); + if(acl->permitEntries != NULL) + free(acl->permitEntries); + if(acl!=NULL) + free(acl); +} + +/* Structure initialisation for Ipv4AccessList */ +Ipv4AccessList* +createIpv4AccessList(const char* permitList, const char* denyList, int processingOrder) +{ + Ipv4AccessList* ret; + ret=(Ipv4AccessList*)calloc(1,sizeof(Ipv4AccessList)); + ret->permitEntries = createMaskTable(permitList); + ret->denyEntries = createMaskTable(denyList); + if(ret->permitEntries == NULL || ret->denyEntries == NULL) { + freeIpv4AccessList(ret); + return NULL; + } + ret->processingOrder = processingOrder; + return ret; +} + + +/* Match an IP address against a MaskTable */ +static int +matchAddress(const uint32_t addr, MaskTable* table) +{ + + int i; + if(table == NULL || table->entries == NULL || table->numEntries==0) + return -1; + for(i = 0; i < table->numEntries; i++) { + DBGV("addr: %08x, addr & mask: %08x, network: %08x\n",addr, table->entries[i].bitmask & addr, table->entries[i].network); + if((table->entries[i].bitmask & addr) == table->entries[i].network) { + table->entries[i].hitCount++; + return 1; + } + } + + return 0; + +} + +/* Test an IP address against an ACL */ +int +matchIpv4AccessList(Ipv4AccessList* acl, const uint32_t addr) +{ + + int ret; + + int matchPermit = 0; + int matchDeny = 0; + + /* Non-functional ACL permits everything */ + if(acl == NULL) { + ret = 1; + goto end; + } + + if(acl->permitEntries != NULL) + matchPermit = matchAddress(addr,acl->permitEntries) > 0; + if(acl->denyEntries != NULL) + matchDeny = matchAddress(addr,acl->denyEntries) > 0; + + switch(acl->processingOrder) { + case ACL_PERMIT_DENY: + if(!matchPermit) { + ret = 0; + break; + } + if(matchDeny) { + ret = 0; + break; + } + ret = 1; + break; + default: + case ACL_DENY_PERMIT: + if (matchDeny && !matchPermit) { + ret = 0; + break; + } + else { + ret = 1; + break; + } + } + + end: + + if(ret) + acl->passedCounter++; + else + acl->droppedCounter++; + + return ret; + +} + +/* Dump the contents and hit counters of an ACL */ +void dumpIpv4AccessList(Ipv4AccessList* acl) +{ + + INFO("\n\n"); + if(acl == NULL) { + INFO("(uninitialised ACL)\n"); + return; + } + switch(acl->processingOrder) { + case ACL_DENY_PERMIT: + INFO("ACL order: deny,permit\n"); + INFO("Passed packets: %d, dropped packets: %d\n", + acl->passedCounter, acl->droppedCounter); + INFO("--------\n"); + INFO("Deny list:\n"); + dumpMaskTable(acl->denyEntries); + INFO("--------\n"); + INFO("Permit list:\n"); + dumpMaskTable(acl->permitEntries); + break; + case ACL_PERMIT_DENY: + default: + INFO("ACL order: permit,deny\n"); + INFO("Passed packets: %d, dropped packets: %d\n", + acl->passedCounter, acl->droppedCounter); + INFO("--------\n"); + INFO("Permit list:\n"); + dumpMaskTable(acl->permitEntries); + INFO("--------\n"); + INFO("Deny list:\n"); + dumpMaskTable(acl->denyEntries); + break; + } + INFO("\n\n"); +} + +/* Clear counters in a MaskTable */ +static void +clearMaskTableCounters(MaskTable* table) +{ + + int i, count; + if(table==NULL || table->numEntries==0) + return; + count = table->numEntries; + + for(i=0; i<count; i++) { + table->entries[i].hitCount = 0; + } + +} + +/* Clear ACL counter */ +void clearIpv4AccessListCounters(Ipv4AccessList* acl) { + + if(acl == NULL) + return; + acl->passedCounter=0; + acl->droppedCounter=0; + clearMaskTableCounters(acl->permitEntries); + clearMaskTableCounters(acl->denyEntries); + +} \ No newline at end of file Added: trunk/src/dep/ipv4_acl.h =================================================================== --- trunk/src/dep/ipv4_acl.h (rev 0) +++ trunk/src/dep/ipv4_acl.h 2013-10-16 05:46:34 UTC (rev 404) @@ -0,0 +1,52 @@ +/** + * @file ipv4_acl.h + * + * @brief definitions related to IPv4 access control list handling + * + */ + +#ifndef PTPD_IPV4_ACL_H_ +#define PTPD_IPV4_ACL_H_ + +#define IN_RANGE(num, min,max) \ + (num >= min && num <= max) + +enum { + ACL_PERMIT_DENY, + ACL_DENY_PERMIT +}; + +typedef struct { + uint32_t network; + uint32_t bitmask; + uint16_t netmask; + uint32_t hitCount; +} AclEntry; + +typedef struct { + int numEntries; + AclEntry* entries; +} MaskTable; + +typedef struct { + MaskTable* permitEntries; + MaskTable* denyEntries; + int processingOrder; + uint32_t passedCounter; + uint32_t droppedCounter; +} Ipv4AccessList; + +/* Parse string into AclEntry array */ +int maskParser(const char* input, AclEntry* output); +/* Destroy an Ipv4AccessList structure */ +void freeIpv4AccessList(Ipv4AccessList* acl); +/* Initialise an Ipv4AccessList structure */ +Ipv4AccessList* createIpv4AccessList(const char* permitList, const char* denyList, int processingOrder); +/* Match on an IP address */ +int matchIpv4AccessList(Ipv4AccessList* acl, const uint32_t addr); +/* Display the contents and hit counters of an access list */ +void dumpIpv4AccessList(Ipv4AccessList* acl); +/* Clear counters */ +void clearIpv4AccessListCounters(Ipv4AccessList* acl); + +#endif /* PTPD_IPV4_ACL_H_ */ Modified: trunk/src/dep/msg.c =================================================================== --- trunk/src/dep/msg.c 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/msg.c 2013-10-16 05:46:34 UTC (rev 404) @@ -1450,7 +1450,7 @@ /*pack Follow_up message into OUT buffer of ptpClock*/ void -msgPackFollowUp(Octet * buf, Timestamp * preciseOriginTimestamp, PtpClock * ptpClock) +msgPackFollowUp(Octet * buf, Timestamp * preciseOriginTimestamp, PtpClock * ptpClock, const UInteger16 sequenceId) { msgPackHeader(buf, ptpClock); @@ -1460,8 +1460,7 @@ *(char *)(buf + 0) = *(char *)(buf + 0) | 0x08; /* Table 19 */ *(UInteger16 *) (buf + 2) = flip16(FOLLOW_UP_LENGTH); - *(UInteger16 *) (buf + 30) = flip16(ptpClock->sentSyncSequenceId - 1); - /* sentSyncSequenceId has already been incremented in "issueSync" */ + *(UInteger16 *) (buf + 30) = flip16(sequenceId); *(UInteger8 *) (buf + 32) = 0x02; /* Table 23 */ *(Integer8 *) (buf + 33) = ptpClock->logSyncInterval; @@ -1705,7 +1704,7 @@ /*pack PdelayRespfollowup message into OUT buffer of ptpClock*/ void -msgPackPDelayRespFollowUp(Octet * buf, MsgHeader * header, Timestamp * responseOriginTimestamp, PtpClock * ptpClock) +msgPackPDelayRespFollowUp(Octet * buf, MsgHeader * header, Timestamp * responseOriginTimestamp, PtpClock * ptpClock, const UInteger16 sequenceId) { msgPackHeader(buf, ptpClock); @@ -1715,7 +1714,7 @@ *(char *)(buf + 0) = *(char *)(buf + 0) | 0x0A; /* Table 19 */ *(UInteger16 *) (buf + 2) = flip16(PDELAY_RESP_FOLLOW_UP_LENGTH); - *(UInteger16 *) (buf + 30) = flip16(ptpClock->PdelayReqHeader.sequenceId); + *(UInteger16 *) (buf + 30) = flip16(sequenceId); *(UInteger8 *) (buf + 32) = 0x05; /* Table 23 */ *(Integer8 *) (buf + 33) = 0x7F; Modified: trunk/src/dep/net.c =================================================================== --- trunk/src/dep/net.c 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/net.c 2013-10-16 05:46:34 UTC (rev 404) @@ -78,10 +78,16 @@ /* choose kernel-level nanoseconds or microseconds resolution on the client-side */ -#if !defined(SO_TIMESTAMPNS) && !defined(SO_TIMESTAMP) && !defined(SO_BINTIME) -#error kernel-level timestamps not detected +#if !defined(SO_TIMESTAMPING) && !defined(SO_TIMESTAMPNS) && !defined(SO_TIMESTAMP) && !defined(SO_BINTIME) +#error No kernel-level support for packet timestamping detected! #endif +#ifdef SO_TIMESTAMPING +#include <linux/net_tstamp.h> +#include <linux/sockios.h> +#include <linux/ethtool.h> +#endif /* SO_TIMESTAMPING */ + /** * shutdown the IPv4 multicast for specific address * @@ -154,6 +160,9 @@ netPath->pcapGeneralSock = -1; } + freeIpv4AccessList(netPath->timingAcl); + freeIpv4AccessList(netPath->managementAcl); + return TRUE; } @@ -482,6 +491,66 @@ return TRUE; } +Boolean +netSetMulticastLoopback(NetPath * netPath, Boolean value) { + int temp = value ? 1 : 0; + + DBG("Going to set multicast loopback with %d \n", temp); + + if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_LOOP, + &temp, sizeof(int)) < 0) { + PERROR("Failed to set multicast loopback"); + return FALSE; + } + + return TRUE; +} + +#if defined(SO_TIMESTAMPING) && defined(SO_TIMESTAMPNS) +static Boolean +getTxTimestamp(NetPath* netPath,TimeInternal* timeStamp) { + extern PtpClock *G_ptpClock; + ssize_t length; + fd_set tmpSet; + struct timeval timeOut = {0,0}; + int val = 1; + if(netPath->txTimestampFailure) + goto end; + + FD_ZERO(&tmpSet); + FD_SET(netPath->eventSock, &tmpSet); + + if(select(netPath->eventSock + 1, &tmpSet, NULL, NULL, &timeOut) > 0) { + if (FD_ISSET(netPath->eventSock, &tmpSet)) { + length = netRecvEvent(G_ptpClock->msgIbuf, timeStamp, + netPath, MSG_ERRQUEUE); + + if (length > 0) { + DBG("Grabbed sent msg via errqueue: %d bytes, at %d.%d\n", length, timeStamp->seconds, timeStamp->nanoseconds); + return TRUE; + } else if (length < 0) { + DBG("Failed to poll error queue for SO_TIMESTAMPING transmit time"); + G_ptpClock->counters.messageRecvErrors++; + goto end; + } else if (length == 0) { + DBG("Received no data from TX error queue"); + goto end; + } + } + } else { + DBG("SO_TIMESTAMPING - t timeout on TX timestamp - will use loop from now on\n"); + return FALSE; + } +end: + if(setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMPNS, &val, sizeof(int)) < 0) { + DBG("gettxtimestamp: failed to revert to SO_TIMESTAMPNS"); + } + + return FALSE; +} +#endif /* SO_TIMESTAMPING */ + + /** * Initialize timestamping of packets * @@ -490,24 +559,69 @@ * @return TRUE if successful */ Boolean -netInitTimestamping(NetPath * netPath) +netInitTimestamping(NetPath * netPath, RunTimeOpts * rtOpts) { + int val = 1; Boolean result = TRUE; - -#if defined(SO_TIMESTAMPNS) /* Linux, Apple */ +#if defined(SO_TIMESTAMPING) && defined(SO_TIMESTAMPNS)/* Linux - current API */ + DBG("netInitTimestamping: trying to use SO_TIMESTAMPING\n"); + val = SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE; + +/* unless compiled with PTPD_EXPERIMENTAL, check if we support the desired tstamp capabilities */ +#ifndef PTPD_EXPERIMENTAL +#ifdef ETHTOOL_GET_TS_INFO + + struct ethtool_ts_info tsInfo; + struct ifreq ifRequest; + int res; + + memset(&tsInfo, 0, sizeof(tsInfo)); + memset(&ifRequest, 0, sizeof(ifRequest)); + tsInfo.cmd = ETHTOOL_GET_TS_INFO; + strncpy( ifRequest.ifr_name, rtOpts->ifaceName, IFNAMSIZ - 1); + ifRequest.ifr_data = (char *) &tsInfo; + res = ioctl(netPath->eventSock, SIOCETHTOOL, &ifRequest); + + if (res < 0) { + PERROR("Could not retrieve ethtool information for %s", + rtOpts->ifaceName; + return FALSE; + } + + if(!(tsInfo.so_timestamping & val)) { + DBGV("Required SO_TIMESTAMPING flags not supported - reverting to SO_TIMESTAMPNS\n"); + val = 1; + netPath->txTimestampFailure = FALSE; + } + + +#else + netPath->txTimestampFailure = FALSE; + val = 1; +#endif /* ETHTOOL_GET_TS_INFO */ +#endif /* PTPD_EXPERIMENTAL */ + + if((val==1 && (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMPNS, &val, sizeof(int)) < 0)) || + (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMPING, &val, sizeof(int)) < 0)) { + PERROR("netInitTimestamping: failed to enable SO_TIMESTAMPING"); + result = FALSE; + } else { + DBG("SO_TIMESTAMP%s initialised\n",(val==1)?"NS":"ING"); + } +#elif defined(SO_TIMESTAMPNS) /* Linux, Apple */ DBG("netInitTimestamping: trying to use SO_TIMESTAMPNS\n"); - if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMPNS, &val, sizeof(int)) < 0 - || setsockopt(netPath->generalSock, SOL_SOCKET, SO_TIMESTAMPNS, &val, sizeof(int)) < 0) { + if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMPNS, &val, sizeof(int)) < 0) { PERROR("netInitTimestamping: failed to enable SO_TIMESTAMPNS"); result = FALSE; } #elif defined(SO_BINTIME) /* FreeBSD */ DBG("netInitTimestamping: trying to use SO_BINTIME\n"); - if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_BINTIME, &val, sizeof(int)) < 0 - || setsockopt(netPath->generalSock, SOL_SOCKET, SO_BINTIME, &val, sizeof(int)) < 0) { + if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_BINTIME, &val, sizeof(int)) < 0) { PERROR("netInitTimestamping: failed to enable SO_BINTIME"); result = FALSE; } @@ -520,8 +634,7 @@ if (!result) { DBG("netInitTimestamping: trying to use SO_TIMESTAMP\n"); - if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMP, &val, sizeof(int)) < 0 - || setsockopt(netPath->generalSock, SOL_SOCKET, SO_TIMESTAMP, &val, sizeof(int)) < 0) { + if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMP, &val, sizeof(int)) < 0) { PERROR("netInitTimestamping: failed to enable SO_TIMESTAMP"); result = FALSE; } @@ -796,26 +909,48 @@ } + +#ifdef SO_TIMESTAMPING + /* Reset the failure indicator when (re)starting network */ + netPath->txTimestampFailure = FALSE; + /* for SO_TIMESTAMPING we're receiving transmitted packets via ERRQUEUE */ + temp = 0; +#else /* enable loopback */ temp = 1; +#endif - DBG("Going to set IP_MULTICAST_LOOP with %d \n", temp); + /* make timestamps available through recvmsg() */ + if (!netInitTimestamping(netPath,rtOpts)) { + ERROR("failed to enable receive time stamps"); + return FALSE; + } - if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_LOOP, - &temp, sizeof(int)) < 0 - || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_LOOP, - &temp, sizeof(int)) < 0) { - PERROR("Failed to enable multicast loopback"); +#ifdef SO_TIMESTAMPING + /* If we failed to initialise SO_TIMESTAMPING, enable mcast loopback */ + if(netPath->txTimestampFailure) + temp = 1; +#endif + + if(!netSetMulticastLoopback(netPath, temp)) { return FALSE; } - /* make timestamps available through recvmsg() */ - if (!netInitTimestamping(netPath)) { - ERROR("failed to enable receive time stamps"); - return FALSE; - } + } - + + /* Compile ACLs */ + if(rtOpts->timingAclEnabled) { + freeIpv4AccessList(netPath->timingAcl); + netPath->timingAcl=createIpv4AccessList(rtOpts->timingAclPermitText, + rtOpts->timingAclDenyText, rtOpts->timingAclOrder); + } + if(rtOpts->managementAclEnabled) { + freeIpv4AccessList(netPath->managementAcl); + netPath->managementAcl=createIpv4AccessList(rtOpts->managementAclPermitText, + rtOpts->managementAclDenyText, rtOpts->managementAclOrder); + } + return TRUE; } @@ -901,9 +1036,6 @@ return ret; } - - - /** * store received data from network to "buf" , get and store the * SO_TIMESTAMP value in "time" for an event message @@ -922,7 +1054,7 @@ */ ssize_t -netRecvEvent(Octet * buf, TimeInternal * time, NetPath * netPath) +netRecvEvent(Octet * buf, TimeInternal * time, NetPath * netPath, int flags) { ssize_t ret = 0; struct msghdr msg; @@ -934,12 +1066,12 @@ union { struct cmsghdr cm; - char control[CMSG_SPACE(sizeof(struct timeval))]; + char control[256]; } cmsg_un; struct cmsghdr *cmsg; -#if defined(SO_TIMESTAMPNS) +#if defined(SO_TIMESTAMPNS) || defined(SO_TIMESTAMPING) struct timespec * ts; #elif defined(SO_BINTIME) struct bintime * bt; @@ -968,13 +1100,13 @@ msg.msg_controllen = sizeof(cmsg_un.control); msg.msg_flags = 0; - ret = recvmsg(netPath->eventSock, &msg, MSG_DONTWAIT); + ret = recvmsg(netPath->eventSock, &msg, flags | MSG_DONTWAIT); if (ret <= 0) { if (errno == EAGAIN || errno == EINTR) return 0; return ret; - } + }; if (msg.msg_flags & MSG_TRUNC) { ERROR("received truncated message\n"); return 0; @@ -989,7 +1121,8 @@ return 0; } - netPath->lastRecvAddr = from_addr.sin_addr.s_addr; + if(!(flags & MSG_ERRQUEUE)) + netPath->lastRecvAddr = from_addr.sin_addr.s_addr; netPath->receivedPackets++; if (msg.msg_controllen <= 0) { @@ -1002,7 +1135,19 @@ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == SOL_SOCKET) { -#if defined(SO_TIMESTAMPNS) +#if defined(SO_TIMESTAMPING) && defined(SO_TIMESTAMPNS) + if(cmsg->cmsg_type == SO_TIMESTAMPING || + cmsg->cmsg_type == SO_TIMESTAMPNS) { + ts = (struct timespec *)CMSG_DATA(cmsg); + time->seconds = ts->tv_sec; + time->nanoseconds = ts->tv_nsec; + timestampValid = TRUE; + DBG("rcvevent: SO_TIMESTAMP%s %s time stamp: %us %dns\n", netPath->txTimestampFailure ? + "NS" : "ING", + (flags & MSG_ERRQUEUE) ? "(TX)" : "(RX)" , time->seconds, time->nanoseconds); + break; + } +#elif defined(SO_TIMESTAMPNS) if(cmsg->cmsg_type == SCM_TIMESTAMPNS) { ts = (struct timespec *)CMSG_DATA(cmsg); time->seconds = ts->tv_sec; @@ -1099,126 +1244,23 @@ */ ssize_t -netRecvGeneral(Octet * buf, TimeInternal * time, NetPath * netPath) +netRecvGeneral(Octet * buf, NetPath * netPath) { ssize_t ret; - struct msghdr msg; - struct iovec vec[1]; struct sockaddr_in from_addr; - struct pcap_pkthdr *pkt_header; const u_char *pkt_data; + socklen_t from_addr_len = sizeof(from_addr); - union { - struct cmsghdr cm; - char control[CMSG_SPACE(sizeof(struct timeval))]; - } cmsg_un; - - struct cmsghdr *cmsg; - -#if defined(SO_TIMESTAMPNS) - struct timespec * ts; -#elif defined(SO_BINTIME) - struct bintime * bt; - struct timespec ts; -#endif - -#if defined(SO_TIMESTAMP) - struct timeval * tv; -#endif - Boolean timestampValid = FALSE; - if (netPath->pcapGeneral == NULL) { - vec[0].iov_base = buf; - vec[0].iov_len = PACKET_SIZE; - - memset(&msg, 0, sizeof(msg)); - memset(&from_addr, 0, sizeof(from_addr)); - memset(buf, 0, PACKET_SIZE); - memset(&cmsg_un, 0, sizeof(cmsg_un)); - - msg.msg_name = (caddr_t)&from_addr; - msg.msg_namelen = sizeof(from_addr); - msg.msg_iov = vec; - msg.msg_iovlen = 1; - msg.msg_control = cmsg_un.control; - msg.msg_controllen = sizeof(cmsg_un.control); - msg.msg_flags = 0; - - ret = recvmsg(netPath->generalSock, &msg, MSG_DONTWAIT); - if (ret <= 0) { - if (errno == EAGAIN || errno == EINTR) - return 0; - - return ret; - } - if (msg.msg_flags & MSG_TRUNC) { - ERROR("received truncated message\n"); - return 0; - } - /* get time stamp of packet */ - if (!time) { - ERROR("null receive time stamp argument\n"); - return 0; - } - if (msg.msg_flags & MSG_CTRUNC) { - ERROR("received truncated ancillary data\n"); - return 0; - } - + ret=recvfrom(netPath->generalSock, buf, PACKET_SIZE, MSG_DONTWAIT, &from_addr, &from_addr_len); netPath->lastRecvAddr = from_addr.sin_addr.s_addr; - - netPath->receivedPackets++; - - if (msg.msg_controllen <= 0) { - ERROR("received short ancillary data (%ld/%ld)\n", - (long)msg.msg_controllen, (long)sizeof(cmsg_un.control)); - - return 0; - } - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET) { -#if defined(SO_TIMESTAMPNS) - if(cmsg->cmsg_type == SCM_TIMESTAMPNS) { - ts = (struct timespec *)CMSG_DATA(cmsg); - time->seconds = ts->tv_sec; - time->nanoseconds = ts->tv_nsec; - timestampValid = TRUE; - DBGV("kernel NANO recv time stamp %us %dns\n", - time->seconds, time->nanoseconds); - break; - } -#elif defined(SO_BINTIME) - if(cmsg->cmsg_type == SCM_BINTIME) { - bt = (struct bintime *)CMSG_DATA(cmsg); - bintime2timespec(bt, &ts); - time->seconds = ts.tv_sec; - time->nanoseconds = ts.tv_nsec; - timestampValid = TRUE; - DBGV("kernel NANO recv time stamp %us %dns\n", - time->seconds, time->nanoseconds); - break; - } -#endif - -#if defined(SO_TIMESTAMP) - if(cmsg->cmsg_type == SCM_TIMESTAMP) { - tv = (struct timeval *)CMSG_DATA(cmsg); - time->seconds = tv->tv_sec; - time->nanoseconds = tv->tv_usec * 1000; - timestampValid = TRUE; - DBGV("kernel MICRO recv time stamp %us %dns\n", - time->seconds, time->nanoseconds); - } -#endif - } - } + return ret; } else { /* Using PCAP */ /* Discard packet on socket */ if (netPath->generalSock >= 0) recv(netPath->generalSock, buf, PACKET_SIZE, MSG_DONTWAIT); + if (( ret = pcap_next_ex(netPath->pcapGeneral, &pkt_header, &pkt_data)) < 1) { @@ -1227,8 +1269,6 @@ ret, pcap_geterr(netPath->pcapGeneral)); return 0; } - - /* Make sure this is IP (could dot1q get here?) */ if( ntohs(*(u_short *)(pkt_data + 12)) != ETHERTYPE_IP) DBGV("PCAP payload received is not Ethernet: 0x%04x\n", @@ -1240,26 +1280,10 @@ /* XXX Total cheat */ memcpy(buf, pkt_data + netPath->headerOffset, pkt_header->caplen - netPath->headerOffset); - time->seconds = pkt_header->ts.tv_sec; - time->nanoseconds = pkt_header->ts.tv_usec * 1000; - timestampValid = TRUE; - DBGV("netRecvGeneral: kernel PCAP recv time stamp %us %dns\n", - time->seconds, time->nanoseconds); fflush(NULL); ret = pkt_header->caplen - netPath->headerOffset; } - if (!timestampValid) { - /* - * do not try to get by with recording the time here, better - * to fail because the time recorded could be well after the - * message receive, which would put a big spike in the - * offset signal sent to the clock servo - */ - DBG("netRecvGeneral: no receive time stamp\n"); - return 0; - } - return ret; } @@ -1288,7 +1312,7 @@ /// ssize_t netSendEvent(Octet * buf, UInteger16 length, NetPath * netPath, - RunTimeOpts *rtOpts, Integer32 alt_dst) + RunTimeOpts *rtOpts, Integer32 alt_dst, TimeInternal * tim) { ssize_t ret; struct sockaddr_in addr; @@ -1326,34 +1350,49 @@ DBG("Error sending unicast event message\n"); else netPath->sentPackets++; +#ifndef SO_TIMESTAMPING /* * 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) DBG("Error looping back unicast event message\n"); - +#else + if(!netPath->txTimestampFailure) { + if(!getTxTimestamp(netPath, tim)) { + netPath->txTimestampFailure = TRUE; + if (tim) { + clearTime(tim); + } + } + } + + if(netPath->txTimestampFailure) + { + /* We've had a TX timestamp receipt timeout - falling back to packet looping */ + 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) + DBG("Error looping back unicast event message\n"); + } +#endif /* SO_TIMESTAMPING */ } else { addr.sin_addr.s_addr = netPath->multicastAddr; - /* Is TTL OK? */ if(netPath->ttlEvent != rtOpts->ttl) { /* Try restoring TTL */ if(setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_TTL, &rtOpts->ttl, sizeof(int)) >= 0) { - netPath->ttlEvent = rtOpts->ttl; - } - } - ret = sendto(netPath->eventSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); @@ -1361,6 +1400,20 @@ DBG("Error sending multicast event message\n"); else netPath->sentPackets++; +#ifdef SO_TIMESTAMPING + if(!netPath->txTimestampFailure) { + if(!getTxTimestamp(netPath, tim)) { + if (tim) { + clearTime(tim); + } + + netPath->txTimestampFailure = TRUE; + + /* Try re-enabling MULTICAST_LOOP */ + netSetMulticastLoopback(netPath, TRUE); + } + } +#endif /* SO_TIMESTAMPING */ } } return ret; @@ -1436,7 +1489,6 @@ ssize_t ret; struct sockaddr_in addr; - addr.sin_family = AF_INET; addr.sin_port = htons(PTP_GENERAL_PORT); @@ -1486,7 +1538,7 @@ } ssize_t -netSendPeerEvent(Octet * buf, UInteger16 length, NetPath * netPath, RunTimeOpts *rtOpts) +netSendPeerEvent(Octet * buf, UInteger16 length, NetPath * netPath, RunTimeOpts *rtOpts, TimeInternal * tim) { ssize_t ret; struct sockaddr_in addr; @@ -1513,6 +1565,7 @@ else netPath->sentPackets++; +#ifndef SO_TIMESTAMPING /* * Need to forcibly loop back the packet since * we are not using multicast. @@ -1524,6 +1577,27 @@ sizeof(struct sockaddr_in)); if (ret <= 0) DBG("Error looping back unicast peer event message\n"); +#else + if(!netPath->txTimestampFailure) { + if(!getTxTimestamp(netPath, tim)) { + netPath->txTimestampFailure = TRUE; + if (tim) { + clearTime(tim); + } + } + } + + if(netPath->txTimestampFailure) { + /* We've had a TX timestamp receipt timeout - falling back to packet looping */ + 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) + DBG("Error looping back unicast event message\n"); + } +#endif /* SO_TIMESTAMPING */ + } else { addr.sin_addr.s_addr = netPath->peerMulticastAddr; @@ -1545,6 +1619,20 @@ DBG("Error sending multicast peer event message\n"); else netPath->sentPackets++; +#ifdef SO_TIMESTAMPING + if(!netPath->txTimestampFailure) { + if(!getTxTimestamp(netPath, tim)) { + if (tim) { + clearTime(tim); + } + + netPath->txTimestampFailure = TRUE; + + /* Try re-enabling MULTICAST_LOOP */ + netSetMulticastLoopback(netPath, TRUE); + } + } +#endif /* SO_TIMESTAMPING */ } if (ret > 0) Modified: trunk/src/dep/ptpd_dep.h =================================================================== --- trunk/src/dep/ptpd_dep.h 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/ptpd_dep.h 2013-10-16 05:46:34 UTC (rev 404) @@ -178,12 +178,12 @@ void msgPackHeader(Octet * buf,PtpClock*); void msgPackAnnounce(Octet * buf,PtpClock*); void msgPackSync(Octet * buf,Timestamp*,PtpClock*); -void msgPackFollowUp(Octet * buf,Timestamp*,PtpClock*); +void msgPackFollowUp(Octet * buf,Timestamp*,PtpClock*, const UInteger16); void msgPackDelayReq(Octet * buf,Timestamp *,PtpClock *); void msgPackDelayResp(Octet * buf,MsgHeader *,Timestamp *,PtpClock *); void msgPackPDelayReq(Octet * buf,Timestamp*,PtpClock*); void msgPackPDelayResp(Octet * buf,MsgHeader*,Timestamp*,PtpClock*); -void msgPackPDelayRespFollowUp(Octet * buf,MsgHeader*,Timestamp*,PtpClock*); +void msgPackPDelayRespFollowUp(Octet * buf,MsgHeader*,Timestamp*,PtpClock*, const UInteger16); void msgPackManagement(Octet * buf,MsgManagement*,PtpClock*); void msgPackManagementRespAck(Octet *,MsgManagement*,PtpClock*); void msgPackManagementTLV(Octet *,MsgManagement*, PtpClock*); @@ -296,12 +296,12 @@ UInteger32 findIface(Octet * ifaceName, UInteger8 * communicationTechnology, Octet * uuid, NetPath * netPath); Boolean netShutdown(NetPath*); int netSelect(TimeInternal*,NetPath*,fd_set*); -ssize_t netRecvEvent(Octet*,TimeInternal*,NetPath*); -ssize_t netRecvGeneral(Octet*,TimeInternal*,NetPath*); -ssize_t netSendEvent(Octet*,UInteger16,NetPath*,RunTimeOpts*,Integer32 ); +ssize_t netRecvEvent(Octet*,TimeInternal*,NetPath*,int); +ssize_t netRecvGeneral(Octet*,NetPath*); +ssize_t netSendEvent(Octet*,UInteger16,NetPath*,RunTimeOpts*,Integer32,TimeInternal*); ssize_t netSendGeneral(Octet*,UInteger16,NetPath*,RunTimeOpts*,Integer32 ); ssize_t netSendPeerGeneral(Octet*,UInteger16,NetPath*,RunTimeOpts*); -ssize_t netSendPeerEvent(Octet*,UInteger16,NetPath*,RunTimeOpts*); +ssize_t netSendPeerEvent(Octet*,UInteger16,NetPath*,RunTimeOpts*,TimeInternal*); Boolean netRefreshIGMP(NetPath *, RunTimeOpts *, PtpClock *); Boolean hostLookup(const char* hostname, Integer32* addr); Modified: trunk/src/dep/servo.c =================================================================== --- trunk/src/dep/servo.c 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/servo.c 2013-10-16 05:46:34 UTC (rev 404) @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2012-2013 Wojciech Owczarek, * Copyright (c) 2011-2012 George V. Neville-Neil, * Steven Kreuzer, * Martin Burnicki, @@ -238,7 +239,7 @@ ptpClock->meanPathDelay.nanoseconds); /* revert back to previous value */ ptpClock->meanPathDelay = prev_meanPathDelay; -#ifdef PTPD_STATISTICE +#ifdef PTPD_STATISTICS goto statistics; #else goto display; @@ -379,7 +380,7 @@ DBGV("delay filter %d, %d\n", owd_filt->y, owd_filt->s_exp); -display: +//display: if(ptpClock->portState == PTP_SLAVE) logStatistics(rtOpts, ptpClock); } @@ -863,7 +864,8 @@ } else { /* If we're in panic mode, either exit if no threshold configured, or exit if we're outside the exit threshold */ - if(rtOpts->enablePanicMode && (ptpClock->panicMode && ( rtOpts->panicModeExitThreshold == 0 || (rtOpts->panicModeExitThreshold > 0 && (ptpClock->offsetFromMaster.seconds == 0 && ptpClock->offsetFromMaster.nanoseconds < rtOpts->panicModeExitThreshold))) ) || ptpClock->panicOver) { + if(rtOpts->enablePanicMode && + ((ptpClock->panicMode && ( rtOpts->panicModeExitThreshold == 0 || ((rtOpts->panicModeExitThreshold > 0) && ((ptpClock->offsetFromMaster.seconds == 0) && (ptpClock->offsetFromMaster.nanoseconds < rtOpts->panicModeExitThreshold)))) ) || ptpClock->panicOver)) { ptpClock->panicMode = FALSE; ptpClock->panicOver = FALSE; timerStop(PANIC_MODE_TIMER, ptpClock->itimer); Modified: trunk/src/dep/startup.c =================================================================== --- trunk/src/dep/startup.c 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/startup.c 2013-10-16 05:46:34 UTC (rev 404) @@ -233,6 +233,22 @@ #endif /* HAVE_SCHED_H */ #endif /* linux */ + if(rtOpts->restartSubsystems & PTPD_RESTART_ACLS) { + NOTIFY("Applying access control list configuration\n"); + /* re-compile ACLs */ + freeIpv4AccessList(ptpClock->netPath.timingAcl); + freeIpv4AccessList(ptpClock->netPath.managementAcl); + if(rtOpts->timingAclEnabled) { + ptpClock->netPath.timingAcl=createIpv4AccessList(rtOpts->timingAclPermitText, + rtOpts->timingAclDenyText, rtOpts->timingAclOrder); + } + if(rtOpts->managementAclEnabled) { + freeIpv4AccessList(ptpClock->netPath.managementAcl); + ptpClock->netPath.managementAcl=createIpv4AccessList(rtOpts->managementAclPermitText, + rtOpts->managementAclDenyText, rtOpts->managementAclOrder); + } + } + if(rtOpts->restartSubsystems == -1) { ERROR("New configuration cannot be applied - aborting reload\n"); rtOpts->restartSubsystems = 0; @@ -346,6 +362,16 @@ #ifdef DBG_SIGUSR2_DUMP_COUNTERS if(sigusr2_received){ displayCounters(ptpClock); + if(rtOpts->timingAclEnabled) { + INFO("\n\n"); + INFO("** Timing message ACL:\n"); + dumpIpv4AccessList(ptpClock->netPath.timingAcl); + } + if(rtOpts->managementAclEnabled) { + INFO("\n\n"); + INFO("** Management message ACL:\n"); + dumpIpv4AccessList(ptpClock->netPath.managementAcl); + } sigusr2_received = 0; } #endif Modified: trunk/src/dep/sys.c =================================================================== --- trunk/src/dep/sys.c 2013-10-15 19:28:47 UTC (rev 403) +++ trunk/src/dep/sys.c 2013-10-16 05:46:34 UTC (rev 404) @@ -832,7 +832,28 @@ } } + if(ptpClock->portState == PTP_SLAVE) { + fprintf(out, STATUSPREFIX" Priority1 %d, Priority2 %d, clockClass %d\n","GM info", + ptpClock->grandmasterPriority1, ptpClock->grandmasterPriority2, ptpClock->grandmasterClockQuality.clockClass); + } + if(ptpClock->clockQuality.clockClass < 128 || + ptpClock->portState == PTP_SLAVE || + ptpClock->portState == PTP_PASSIVE){ + fprintf(out, STATUSPREFIX" ","Time properties"); + fprintf(out, "%s timescale, ",ptpClock->timePropertiesDS.ptpTimescale ? "PTP":"ARB"); + fprintf(out, "traceable: time %s, freq %s\n", ptpClock->timePropertiesDS.timeTraceable ? "Y" : "N", + ptpClock->timePropertiesDS.frequencyTraceable ? "Y" : "N"); + fprintf(out, STATUSPREFIX" ","UTC properties"); + fprintf(out, "UTC valid: %s", ptpClock->timePropertiesDS.currentUtcOffsetValid ? "Y" : "N"); + fprintf(out, ", UTC offset: %d",ptpClock->timePropertiesDS.currentUtcOffset); + fprintf(out, "%s",ptpClock->timePropertiesDS.leap61 ? + ", LEAP61 pending" : ptpClock->timePropertiesDS.leap59 ? ", LEAP59 pending" : ""); + fprintf(out, "%s", rtOpts->preferUtcValid ? ", prefer UTC" : ""); + fprintf(out, "%s", rtOpts->requireUtcValid ? ", require UTC" : ""); + fprintf(out,"\n"); + } + if(ptpClock->portState == PTP_SLAVE) { memset(tmpBuf, 0, sizeof(tmpBuf)); snprint_TimeInternal(tmpBuf, sizeof(tmpBuf), @@ -847,6 +868,7 @@ #endif /* PTPD_STATISTICS */ fprintf(out,"\n"); + if(ptpClock->delayMechanism == E2E) { memset(tmpBuf, 0, sizeof(tmpBuf)); snprint_TimeInternal(tmpBuf, sizeof(tmpBuf), &ptpClock->meanPathDelay); @@ -859,6 +881,15 @@ ); #endif /* PTPD_STATISTICS */ fprintf(out,"\n"); + } + if(ptpClock->delayMechanism == P2P) { + memset(tmpBuf, 0, sizeof(tmpBuf)); + snprint_TimeInternal(tmpBuf, sizeof(tmpBuf), + &ptpClock->peerMeanPathDelay); + fprintf(out, STATUSPREFIX" %s s","One-way pDelay", tmpBuf); + fprintf(out,"\n"); + } + #ifndef PTPD_STATISTICS if(rtOpts->enablePanicMode) fprintf(out, STATUSPREFIX" ","Clock status"); @@ -905,6 +936,38 @@ } fprintf(out,"\n"); + + } + + + + if(ptpClock->portState == PTP_MASTER || ptpClock->portState == PTP_PASSIVE) { + + fprintf(out, STATUSPREFIX" %d","Priority1 ", ptpClock->priority1); + if(ptpClock->portState == PTP_PASSIVE) + fprintf(out, " (best master: %d)", ptpClock->grandmasterPriority1); + fprintf(out,"\n"); + fprintf(out, STATUSPREFIX" %d","Priority2 ", ptpClock->priority2); + if(ptpClock->portState == PTP_PASSIVE) + fprintf(out, " (best master: %d)", ptpClock->grandmasterPriority2); + fprintf(out,"\n"); + fprintf(out, STATUSPREFIX" %d","ClockClass ", ptpClock->clockQuality.clockClass); + if(ptpClock->portState == PTP_PASSIVE) + fprintf(out, " (best master: %d)", ptpClock->grandmasterClockQuality.clockClass); + fprintf(out,"\n"); + if(ptpClock->delayMechanism == P2P) { + memset(tmpBuf, 0, sizeof(tmpBuf)); + snprint_TimeInternal(tmpBuf, sizeof(tmpBuf), + &ptpClock->peerMeanPathDelay); + fprintf(out, STATUSPREFIX" %s s","One-way pDelay", tmpBuf); + fprintf(out,"\n"); + } + + } + + if(ptpClock->portState == PTP_MASTER || ptpClock->portState == PTP_PASSIVE || + ptpClock->portState == PTP_SLAVE) { + fprintf(out, STATUSPREFIX" ","Message rates"); if (ptpClock->logSyncInterval <= 0) @@ -913,6 +976,7 @@ fprintf(out,"1/%.0fs",pow(2,ptpClock->logSyncInterval)); fprintf(out, " sync"); + if(ptpClock->delayMechanism == E2E) { if (ptpClock->logMinDelayReqInterval <= 0) fprintf(out,", %.0f/s",pow(2,-ptpClock->logMinDelayReqInterval)); @@ -929,26 +993,19 @@ ... [truncated message content] |
From: <wow...@us...> - 2013-11-08 15:21:41
|
Revision: 414 http://sourceforge.net/p/ptpd/code/414 Author: wowczarek Date: 2013-11-08 15:21:38 +0000 (Fri, 08 Nov 2013) Log Message: ----------- - Fixed incorrect MSG_ERRQUEUE detection resulting in a configure error - Added detection of the Linux kernel header includes directory, for cases like RHEL6 where net_tstamp.h is in /usr/src/.... but not in /usr/include/... - ptpd now builds correctly under RHEL6 Modified Paths: -------------- trunk/configure.ac trunk/src/Makefile.am trunk/src/dep/daemonconfig.c Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-11-04 20:23:26 UTC (rev 413) +++ trunk/configure.ac 2013-11-08 15:21:38 UTC (rev 414) @@ -145,6 +145,29 @@ AC_SUBST(PTP_SNMP) AM_CONDITIONAL([SNMP], [test x$ptpd_snmp_enabled = x1]) +case $host in +*linux*) + + AC_CHECK_HEADERS([linux/net_tstamp.h], [], [ + + if [ test -d "/usr/src/kernels/`uname -r`/include" ]; then + LINUX_KERNEL_INCLUDES="-I/usr/src/kernels/`uname -r`/include" + LINUX_KERNEL_HEADERS=yes + fi + + if [ test -d "/usr/src/linux-headers-`uname -r`/include" ]; then + LINUX_KERNEL_INCLUDES="-I/usr/src/linux-headers-`uname -r`/include" + LINUX_KERNEL_HEADERS=yes + fi + + ]) + + ;; +esac + +AM_CONDITIONAL(LINUX_KERNEL_HEADERS, test x$LINUX_KERNEL_HEADERS = xyes) +AC_SUBST(LINUX_KERNEL_INCLUDES) + # Checks for libraries. AC_CHECK_LIB([m], [pow]) AC_CHECK_LIB([rt], [clock_gettime]) @@ -184,7 +207,7 @@ AC_FUNC_VPRINTF AC_CHECK_FUNCS([clock_gettime dup2 ftruncate gettimeofday inet_ntoa memset pow select socket strchr strdup strerror strtol glob pututline utmpxname updwtmpx]) -AC_CHECK_DECL(MSG_ERRQUEUE, [[#include <sys/socket.h]]) +AC_CHECK_DECLS([MSG_ERRQUEUE], [], [], [[#include <sys/socket.h>]]) AC_MSG_CHECKING([for RUNTIME_DEBUG]) AC_ARG_ENABLE( Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2013-11-04 20:23:26 UTC (rev 413) +++ trunk/src/Makefile.am 2013-11-08 15:21:38 UTC (rev 414) @@ -8,6 +8,10 @@ AM_CPPFLAGS = $(SNMP_CPPFLAGS) AM_LDFLAGS = $(SNMP_LIBS) +if LINUX_KERNEL_HEADERS +AM_CFLAGS += $(LINUX_KERNEL_INCLUDES) +endif + AM_CPPFLAGS += $(PTP_DBL) $(PTP_DAEMON) $(PTP_EXP) $(PTP_SNMP) $(PTP_SIGUSR2) $(PTP_STATISTICS) $(PTP_NTPDC) NULL= Modified: trunk/src/dep/daemonconfig.c =================================================================== --- trunk/src/dep/daemonconfig.c 2013-11-04 20:23:26 UTC (rev 413) +++ trunk/src/dep/daemonconfig.c 2013-11-08 15:21:38 UTC (rev 414) @@ -622,6 +622,7 @@ char *optionvalue; va_list va; +#pragma message "Do NOT try fixing the 'set but not used' warning for optionnumber => segfaults" int i, optionnumber; /* if we got an incomplete argument list, cut it down to the last pair or nothing */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wow...@us...> - 2013-11-12 13:44:51
|
Revision: 416 http://sourceforge.net/p/ptpd/code/416 Author: wowczarek Date: 2013-11-12 13:44:49 +0000 (Tue, 12 Nov 2013) Log Message: ----------- Autotools compatibility fixes for RHEL5: - Lowered required automake & autoconf version - Fix for commas in AS_HELP_STRING - Added a readme note for cases with libtool errors Modified Paths: -------------- trunk/README.repocheckout trunk/configure.ac Modified: trunk/README.repocheckout =================================================================== --- trunk/README.repocheckout 2013-11-08 19:05:26 UTC (rev 415) +++ trunk/README.repocheckout 2013-11-12 13:44:49 UTC (rev 416) @@ -8,4 +8,11 @@ % autoreconf -vi -to generate the build environment. +to generate the build environment. On some older systems you may get +libtool errors (./libtool: line nnnn: X[command]: command not found) - +in that case use: + + % libtoolize --force --copy; aclocal; autoconf; automake + + + Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-11-08 19:05:26 UTC (rev 415) +++ trunk/configure.ac 2013-11-12 13:44:49 UTC (rev 416) @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. m4_include([m4/version.m4]) -AC_PREREQ(2.61) +AC_PREREQ(2.59) AC_INIT( [ptpd2], [VERSION_NUMBER], @@ -15,7 +15,7 @@ AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.10 foreign -Wall]) +AM_INIT_AUTOMAKE([1.9 foreign -Wall]) [RELEASE_DATE]="RELEASE_DATE" AC_SUBST([RELEASE_DATE]) @@ -185,15 +185,21 @@ # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_HEADER_STDBOOL -AC_TYPE_INT64_T -AC_TYPE_SIZE_T -AC_TYPE_SSIZE_T AC_HEADER_TIME -AC_TYPE_UINT32_T -AC_TYPE_UINT64_T -AC_TYPE_UINT8_T AC_C_VOLATILE +# Automake 2.59 has a problem with those on RHEL5 +m4_version_prereq(2.60,[ + AC_TYPE_UINT32_T + AC_TYPE_UINT64_T + AC_TYPE_UINT8_T + AC_TYPE_SIZE_T + AC_TYPE_SSIZE_T + AC_TYPE_INT64_T + ], + [AC_TYPE_SIZE_T] +) + # Check for tick in the timex structure AC_CHECK_MEMBERS([struct timex.tick], [], [], [[#include <sys/timex.h>]]) @@ -229,8 +235,9 @@ AC_ARG_ENABLE( [debug-level], [AS_HELP_STRING( - [--enable-debug-level={basic,medium,all}], + [[[[--enable-debug-level={basic,medium,all}]]]], [debug message level: basic, medium, all] + )], [ptp_dblevel=$enableval], [ptp_dblevel=no] @@ -331,7 +338,7 @@ AC_ARG_ENABLE( [sigusr2], [AS_HELP_STRING( - [--enable-sigusr2={domain,debug,counters}], + [[[[--enable-sigusr2={domain,debug,counters}]]]], [Enable SIGUSR2 support to: cycle PTP domain #, debug level or dump PTP engine counters (disabled by default)] )], [ptp_sigusr2=$enableval], This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wow...@us...> - 2013-11-12 17:18:16
|
Revision: 417 http://sourceforge.net/p/ptpd/code/417 Author: wowczarek Date: 2013-11-12 17:18:13 +0000 (Tue, 12 Nov 2013) Log Message: ----------- Packaging + lock file fixes: - Changed autoconf package name to ptpd to retain the ptpd-2.x.x naming convention for "make dist" tarballs - Added man 5 ptpd2.conf to distribution, removed the dummy man 8 ptpd2.conf from makefiles - Added missing fflush() - PID was not being written to lock file Modified Paths: -------------- trunk/Makefile.am trunk/configure.ac trunk/src/Makefile.am trunk/src/dep/startup.c Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2013-11-12 13:44:49 UTC (rev 416) +++ trunk/Makefile.am 2013-11-12 17:18:13 UTC (rev 417) @@ -12,9 +12,10 @@ \ doc \ tools \ + test \ src/ptpd2.conf.minimal\ src/ptpd2.8\ - src/ptpd2.conf.8\ + src/ptpd2.conf.5\ \ $(NULL) Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2013-11-12 13:44:49 UTC (rev 416) +++ trunk/configure.ac 2013-11-12 17:18:13 UTC (rev 417) @@ -4,7 +4,7 @@ m4_include([m4/version.m4]) AC_PREREQ(2.59) AC_INIT( - [ptpd2], + [ptpd], [VERSION_NUMBER], [ptp...@nw...], [], @@ -235,7 +235,7 @@ AC_ARG_ENABLE( [debug-level], [AS_HELP_STRING( - [[[[--enable-debug-level={basic,medium,all}]]]], + [[[[--enable-debug-level={basic,medium,all}]]]], [debug message level: basic, medium, all] )], @@ -363,6 +363,5 @@ AC_CONFIG_FILES([src/Makefile]) AC_CONFIG_FILES([src/ptpd2.8]) AC_CONFIG_FILES([src/ptpd2.conf.5]) -AC_CONFIG_FILES([src/ptpd2.conf.8]) AC_OUTPUT Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2013-11-12 13:44:49 UTC (rev 416) +++ trunk/src/Makefile.am 2013-11-12 17:18:13 UTC (rev 417) @@ -2,7 +2,7 @@ lib_LTLIBRARIES = $(LIBPTPD2_LIBS_LA) sbin_PROGRAMS = ptpd2 -man_MANS = ptpd2.8 ptpd2.conf.8 +man_MANS = ptpd2.8 ptpd2.conf.5 AM_CFLAGS = $(SNMP_CFLAGS) -Wall AM_CPPFLAGS = $(SNMP_CPPFLAGS) Modified: trunk/src/dep/startup.c =================================================================== --- trunk/src/dep/startup.c 2013-11-12 13:44:49 UTC (rev 416) +++ trunk/src/dep/startup.c 2013-11-12 17:18:13 UTC (rev 417) @@ -419,7 +419,7 @@ int lockPid = 0; -// INFO("Checking lock file: %s\n", rtOpts->lockFile); + DBGV("Checking lock file: %s\n", rtOpts->lockFile); if ( (G_lockFilePointer=fopen(rtOpts->lockFile, "w+")) == NULL) { PERROR("Could not open lock file %s for writing", rtOpts->lockFile); @@ -446,6 +446,7 @@ goto failure; } INFO("Successfully acquired lock on %s\n", rtOpts->lockFile); + fflush(G_lockFilePointer); return(1); failure: fclose(G_lockFilePointer); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wow...@us...> - 2013-11-13 18:43:41
|
Revision: 419 http://sourceforge.net/p/ptpd/code/419 Author: wowczarek Date: 2013-11-13 18:43:39 +0000 (Wed, 13 Nov 2013) Log Message: ----------- Version strings set to RC2 Modified Paths: -------------- trunk/m4/version.m4 trunk/src/constants.h Modified: trunk/m4/version.m4 =================================================================== --- trunk/m4/version.m4 2013-11-13 18:37:23 UTC (rev 418) +++ trunk/m4/version.m4 2013-11-13 18:43:39 UTC (rev 419) @@ -1,3 +1,3 @@ m4_define([PTPD_URL],[http://ptpd.sourceforge.net]) m4_define([RELEASE_DATE],[October, 2013]) -m4_define([VERSION_NUMBER],[2.3.0]) +m4_define([VERSION_NUMBER],[2.3.0-RC2]) Modified: trunk/src/constants.h =================================================================== --- trunk/src/constants.h 2013-11-13 18:37:23 UTC (rev 418) +++ trunk/src/constants.h 2013-11-13 18:43:39 UTC (rev 419) @@ -27,7 +27,7 @@ #define REVISION \ ";;2.3" #define USER_VERSION \ - "2.3.0-svn" + "2.3.0-RC2" #define USER_DESCRIPTION \ "PTPDv2" #define USER_DESCRIPTION_MAX 128 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |