Update directory structure, readmes, add gptp
authorintel-ethernet <eric_mann@mail.intel.com>
Thu, 1 Nov 2012 23:54:25 +0000 (16:54 -0700)
committerintel-ethernet <eric_mann@mail.intel.com>
Thu, 1 Nov 2012 23:54:25 +0000 (16:54 -0700)
139 files changed:
README
daemons/gptp/common/CVS/Entries [new file with mode: 0644]
daemons/gptp/common/CVS/Repository [new file with mode: 0644]
daemons/gptp/common/CVS/Root [new file with mode: 0644]
daemons/gptp/common/avbts_clock.hpp [new file with mode: 0644]
daemons/gptp/common/avbts_message.hpp [new file with mode: 0644]
daemons/gptp/common/avbts_oscondition.hpp [new file with mode: 0644]
daemons/gptp/common/avbts_osipc.hpp [new file with mode: 0644]
daemons/gptp/common/avbts_oslock.hpp [new file with mode: 0644]
daemons/gptp/common/avbts_osnet.cpp [new file with mode: 0644]
daemons/gptp/common/avbts_osnet.hpp [new file with mode: 0644]
daemons/gptp/common/avbts_osthread.hpp [new file with mode: 0644]
daemons/gptp/common/avbts_ostimer.hpp [new file with mode: 0644]
daemons/gptp/common/avbts_ostimerq.hpp [new file with mode: 0644]
daemons/gptp/common/avbts_port.hpp [new file with mode: 0644]
daemons/gptp/common/ieee1588.hpp [new file with mode: 0644]
daemons/gptp/common/ieee1588clock.cpp [new file with mode: 0644]
daemons/gptp/common/ieee1588port.cpp [new file with mode: 0644]
daemons/gptp/common/ptp_message.cpp [new file with mode: 0644]
daemons/gptp/linux/CVS/Entries [new file with mode: 0644]
daemons/gptp/linux/CVS/Repository [new file with mode: 0644]
daemons/gptp/linux/CVS/Root [new file with mode: 0644]
daemons/gptp/linux/build/CVS/Entries [new file with mode: 0644]
daemons/gptp/linux/build/CVS/Repository [new file with mode: 0644]
daemons/gptp/linux/build/CVS/Root [new file with mode: 0644]
daemons/gptp/linux/build/Makefile [new file with mode: 0644]
daemons/gptp/linux/build/obj/.dir [new file with mode: 0644]
daemons/gptp/linux/build/obj/CVS/Entries [new file with mode: 0644]
daemons/gptp/linux/build/obj/CVS/Repository [new file with mode: 0644]
daemons/gptp/linux/build/obj/CVS/Root [new file with mode: 0644]
daemons/gptp/linux/build/obj/avbts_osnet.o [new file with mode: 0644]
daemons/gptp/linux/build/obj/daemon_cl [new file with mode: 0755]
daemons/gptp/linux/build/obj/ieee1588clock.o [new file with mode: 0644]
daemons/gptp/linux/build/obj/ieee1588port.o [new file with mode: 0644]
daemons/gptp/linux/build/obj/ptp_message.o [new file with mode: 0644]
daemons/gptp/linux/src/CVS/Entries [new file with mode: 0644]
daemons/gptp/linux/src/CVS/Repository [new file with mode: 0644]
daemons/gptp/linux/src/CVS/Root [new file with mode: 0644]
daemons/gptp/linux/src/daemon_cl.cpp [new file with mode: 0644]
daemons/gptp/linux/src/linux_hal.hpp [new file with mode: 0644]
daemons/gptp/linux/src/platform.hpp [new file with mode: 0644]
daemons/gptp/windows/CVS/Entries [new file with mode: 0644]
daemons/gptp/windows/CVS/Repository [new file with mode: 0644]
daemons/gptp/windows/CVS/Root [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/CVS/Entries [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/CVS/Repository [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/CVS/Root [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/ReadMe.txt [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/daemon_cl.cpp [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.filters [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.user [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/ipcdef.hpp [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/packet.cpp [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/packet.hpp [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/platform.hpp [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/stdafx.cpp [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/stdafx.h [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/targetver.h [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/tsc.hpp [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/windows_hal.hpp [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/x64/CVS/Entries [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/x64/CVS/Repository [new file with mode: 0644]
daemons/gptp/windows/daemon_cl/x64/CVS/Root [new file with mode: 0644]
daemons/gptp/windows/gptp.sln [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/CVS/Entries [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/CVS/Repository [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/CVS/Root [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/ReadMe.txt [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/named_pipe_test.cpp [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.filters [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.user [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/stdafx.cpp [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/stdafx.h [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/targetver.h [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/x64/Release/named_pipe_test.Build.CppClean.log [new file with mode: 0644]
daemons/gptp/windows/named_pipe_test/x64/Release/named_pipe_test.log [new file with mode: 0644]
daemons/gptp/windows/x64/CVS/Entries [new file with mode: 0644]
daemons/gptp/windows/x64/CVS/Repository [new file with mode: 0644]
daemons/gptp/windows/x64/CVS/Root [new file with mode: 0644]
daemons/gptp/windows/x64/Release/daemon_cl.map [new file with mode: 0644]
daemons/mrpd/README [new file with mode: 0644]
examples/Makefile [deleted file]
examples/latency_test.c [deleted file]
examples/mrp_client/Makefile [new file with mode: 0644]
examples/mrp_client/mrpl.c [moved from examples/mrpl.c with 100% similarity]
examples/mrp_client/mrpq.c [moved from examples/mrpq.c with 100% similarity]
examples/simple_talker.c [deleted file]
examples/simple_talker/Makefile [new file with mode: 0644]
examples/simple_talker/README [new file with mode: 0644]
examples/simple_talker/simple_talker.c [new file with mode: 0755]
examples/test.c [deleted file]
kmod/igb/LICENSE [moved from kmod/LICENSE with 100% similarity]
kmod/igb/Makefile [moved from kmod/Makefile with 100% similarity]
kmod/igb/README [new file with mode: 0644]
kmod/igb/e1000_82575.c [moved from kmod/e1000_82575.c with 100% similarity]
kmod/igb/e1000_82575.h [moved from kmod/e1000_82575.h with 100% similarity]
kmod/igb/e1000_api.c [moved from kmod/e1000_api.c with 100% similarity]
kmod/igb/e1000_api.h [moved from kmod/e1000_api.h with 100% similarity]
kmod/igb/e1000_defines.h [moved from kmod/e1000_defines.h with 100% similarity]
kmod/igb/e1000_hw.h [moved from kmod/e1000_hw.h with 100% similarity]
kmod/igb/e1000_i210.c [moved from kmod/e1000_i210.c with 100% similarity]
kmod/igb/e1000_i210.h [moved from kmod/e1000_i210.h with 100% similarity]
kmod/igb/e1000_mac.c [moved from kmod/e1000_mac.c with 100% similarity]
kmod/igb/e1000_mac.h [moved from kmod/e1000_mac.h with 100% similarity]
kmod/igb/e1000_manage.c [moved from kmod/e1000_manage.c with 100% similarity]
kmod/igb/e1000_manage.h [moved from kmod/e1000_manage.h with 100% similarity]
kmod/igb/e1000_mbx.c [moved from kmod/e1000_mbx.c with 100% similarity]
kmod/igb/e1000_mbx.h [moved from kmod/e1000_mbx.h with 100% similarity]
kmod/igb/e1000_nvm.c [moved from kmod/e1000_nvm.c with 100% similarity]
kmod/igb/e1000_nvm.h [moved from kmod/e1000_nvm.h with 100% similarity]
kmod/igb/e1000_osdep.h [moved from kmod/e1000_osdep.h with 100% similarity]
kmod/igb/e1000_phy.c [moved from kmod/e1000_phy.c with 100% similarity]
kmod/igb/e1000_phy.h [moved from kmod/e1000_phy.h with 100% similarity]
kmod/igb/e1000_regs.h [moved from kmod/e1000_regs.h with 100% similarity]
kmod/igb/igb.h [moved from kmod/igb.h with 100% similarity]
kmod/igb/igb_ethtool.c [moved from kmod/igb_ethtool.c with 100% similarity]
kmod/igb/igb_main.c [moved from kmod/igb_main.c with 100% similarity]
kmod/igb/igb_param.c [moved from kmod/igb_param.c with 100% similarity]
kmod/igb/igb_procfs.c [moved from kmod/igb_procfs.c with 100% similarity]
kmod/igb/igb_ptp.c [moved from kmod/igb_ptp.c with 100% similarity]
kmod/igb/igb_regtest.h [moved from kmod/igb_regtest.h with 100% similarity]
kmod/igb/igb_sysfs.c [moved from kmod/igb_sysfs.c with 100% similarity]
kmod/igb/igb_vmdq.c [moved from kmod/igb_vmdq.c with 100% similarity]
kmod/igb/igb_vmdq.h [moved from kmod/igb_vmdq.h with 100% similarity]
kmod/igb/kcompat.c [moved from kmod/kcompat.c with 100% similarity]
kmod/igb/kcompat.h [moved from kmod/kcompat.h with 100% similarity]
kmod/igb/kcompat_ethtool.c [moved from kmod/kcompat_ethtool.c with 100% similarity]
lib/igb/LICENSE [moved from lib/LICENSE with 100% similarity]
lib/igb/Makefile [moved from lib/Makefile with 100% similarity]
lib/igb/e1000_82575.h [moved from lib/e1000_82575.h with 100% similarity]
lib/igb/e1000_defines.h [moved from lib/e1000_defines.h with 100% similarity]
lib/igb/e1000_hw.h [moved from lib/e1000_hw.h with 100% similarity]
lib/igb/e1000_osdep.h [moved from lib/e1000_osdep.h with 100% similarity]
lib/igb/e1000_regs.h [moved from lib/e1000_regs.h with 100% similarity]
lib/igb/igb.c [moved from lib/igb.c with 91% similarity]
lib/igb/igb.h [moved from lib/igb.h with 98% similarity]
lib/igb/igb_internal.h [moved from lib/igb_internal.h with 100% similarity]

diff --git a/README b/README
index c4f87bc..b1e720b 100644 (file)
--- a/README
+++ b/README
@@ -1,87 +1,66 @@
-INTRODUCTION
+Open AVB
+========
+maintainer: eric.mann AT intel.com
+
+Intel created the Open AVB repository to encourage collaborative source code 
+development for AVB technology enabling. By publishing the source code, our 
+intent is to encourage standardization, stability and inter-operability between 
+multiple vendors. This repository - created by the Intel LAN Access Division - 
+is open for contributions from other vendors. The repository contains primarily 
+network building block components - drivers, libraries, example applications 
+and daemon source code - required to build an AVB system. It is planned to 
+eventually include the various packet encapsulation types, protocol discovery 
+daemons, libraries to convert media clocks to AVB clocks (and vice 
+versa), and drivers.
+
+This repository does not include all components required to build a full 
+production AVB system (e.g. a turnkey solution to stream stored or live audio 
+or video content). Some simple example applications are provided which 
+illustrate the flow - but a professional AVB system requires a full media stack 
+- including audio and video inputs and outputs, media processing elements, and 
+various graphical user interfaces. Various companies provide such integrated 
+solutions.
+
+LICENSING AND CONTRIBUTION GUIDELINES
+======================================
+To the extent possible, content is licensed under BSD licensing terms. Linux 
+kernel mode components are provided under a GPLv2 license. The specific license 
+information is included in the various directories to eliminate confusion. We 
+encourage you to review the ‘LICENSE’ file included in the head of the 
+various subdirectories for details.
+
+Third party submissions are welcomed. Our intent for third party content 
+contributions is to enable derivative products with minimal licensing 
+entanglements. Practically speaking, this means we would enforce (a) an 
+original-source attestation for any contributed content, and (b) rejecting 
+patches with GPL content into existing “BSD” licensed components. Third 
+party copyrights can be included provided they do not narrow the licensing 
+terms of an existing component.
+
+Prior to accepting a commit, Intel may perform scans using third-party tools 
+to identify suspected hits of GPL code. Intel may also perform vulnerability 
+scans of patches in an attempt to find various coding errors such as memory 
+leaks, buffer overflows and usage of uninitialized variables. The submitter 
+will be asked to correct any detected issues prior to a commit. Owners
+of submitted third-party content are free to apply changes without supervision
+by Intel.
+
+RELATED OPEN SOURCE PROJECTS
+============================
+
+AVDECC
+------
+Jeff Koftinoff maintains a repository of AVDECC example open 
+source code. AVDECC is a management layer, similar to SNMP MIB formats, 
+which enables remote devices to detect, enumerate and configure AVB-related 
+devices based on their standardized management properties.
+
++ https://github.com/jdkoftinoff/avdecc
++ https://github.com/jdkoftinoff/avdecc-examples
+
+XMOS
+----
+XMOS is a semiconductor company providing a reference design for AVB 
+endpoints in pro audio and automotive. Our source code is open source 
+and available on Github - https://github.com/xcore/sw_avb
 
-This component demonstrates various features of the Intel I210 Ethernet controller.
-These features can be used for developing Audio/Video Bridging applications, 
-Industrial Ethernet applications which require precise timing control over frame 
-transmission, or test harnesses for measuring system latencies and sampling events.
-
-This component - igb_avb - is limited to the Intel I210 Ethernet controller. The kernel
-module can be loaded in parallel to existing in-kernel igb modules which may be 
-used on other supported Intel LAN controllers. Modifications are required to
-the in-kernel drivers if the existing in-kernel igb driver has support for the Intel I210.
-
-BUILDING
-
-There are four primary components - kmod (for the kernel-mode igb_avb driver), 
-lib (for the user-mode driver library), examples (for test applications), and
-daemons (at present an MRP daemon required for establishing AVB streams).
-
-To build, 'cd' into each of the respective directories, and execute 'make'.
-
-The kernel igb module can be built which supports the latest Linux kernel
-3.x PTP clock support - to enable, modify kmod/Makefile and enable -DCONFIG_PTP
-as a build option (e.g. EXTRA_CFLAGS += -DCONFIG_PTP).
-
-The example application uses the pciutils library - the latest version 
-can be downloaded from < ftp://ftp.kernel.org/pub/software/utils/pciutils/ >.
-Download and extract the library, and run 'make;make install;make install-lib'.
-
-RUNNING
-
-To install the kernel mode driver, you must have root permissions. Typically,
-the driver is loaded by:
-       <optional> sudo modprobe dca
-       <optional> sudo modprobe ptp
-       sudo insmod ./igb_avb.ko
-
-As 3.4 and later kernels include support for the I210, you may need to 'rmmod igb'
-before loading the igb_avb module.
-
-Note that packets generated from the 'user-mode' libraries are not counted in 
-ifconfig output, and likewise, if generating multicast traffic, the receiving
-node must be registered to receive the traffic (or run the interface in promiscious
-mode).
-
-TIME SYNC
-
-This package relies on using the linuxptp daemon to establish time
-synchronization. The latest source for this is available here:
-
-       git clone git://git.code.sf.net/p/linuxptp/code linuxptp-code
-
-Type 'make' to build. This version has been tested with kernel 3.5.1.
-Assuming kernel support is enabled, simply 'modprobe ptp' to load the 
-required kernel mode components. Example command line to the daemon is:
-
-       ptp4l -f gPTP.cfg -2 -P -i p11p1
-
-Note the default gPTP.cfg file queries and times out relatively fast while
-awaiting the transmit timestamps to complete. To adjust this, modify the
-'tx_timestamp_retries' parameter to 400 (which roughly corresponds to 400 usec).
-
-EXAMPLE APPLICATIONS
-
-The test application - which simply streams timed packets - requires root permissions 
-as well to execute and attach to the driver.
-       sudo ./test
-
-To exit the test app, hit Ctrl-C. The application gracefully tears down
-the connection to the driver. If the application unexpectedly aborts the
-kernel-mode driver also reclaims the various buffers and attempts to clean up.
-The application should be able to re-initialize and use the transmit queues
-without restarting the driver.
-
-The 'simple_talker' application illustrates the various steps to publish a stream
-and being streaming after a listener connects.
-
-MRPD DAEMON
-
-The MRP daemon is required to establish stream reservations with compatible AVB
-infrastructure devices. The command line selectively enables MMRP (via the -m option),
-MVRP (via the -v option), and MSRP (via the -s option). You must also specify the 
-interface on which you want to bind the daemon to (e.g. -i eth2). The full command line 
-typically appears as follows:
-       sudo ./mrpd -mvs -i eth2
-
-Sample client applications - mrpctl, mrpq, mrpl - illustrates how to connect, query 
-and add attributes to the MRP daemon.
diff --git a/daemons/gptp/common/CVS/Entries b/daemons/gptp/common/CVS/Entries
new file mode 100644 (file)
index 0000000..fb8a7b1
--- /dev/null
@@ -0,0 +1,16 @@
+/avbts_clock.hpp/1.1/Fri Sep 21 15:48:06 2012//
+/avbts_message.hpp/1.1/Fri Sep  7 19:02:51 2012//
+/avbts_oscondition.hpp/1.1/Fri Sep 21 20:14:21 2012//
+/avbts_osipc.hpp/1.1/Fri Sep  7 19:03:47 2012//
+/avbts_oslock.hpp/1.1/Fri Sep  7 19:03:59 2012//
+/avbts_osnet.cpp/1.1/Fri Sep  7 19:02:51 2012//
+/avbts_osnet.hpp/1.1/Fri Sep 21 20:12:53 2012//
+/avbts_osthread.hpp/1.1/Fri Sep  7 19:04:20 2012//
+/avbts_ostimer.hpp/1.1/Fri Sep  7 19:04:50 2012//
+/avbts_ostimerq.hpp/1.1/Fri Sep  7 19:02:51 2012//
+/avbts_port.hpp/1.1/Fri Sep 21 20:11:27 2012//
+/ieee1588.hpp/1.1/Fri Sep 21 15:56:15 2012//
+/ieee1588clock.cpp/1.1/Fri Sep 21 15:57:08 2012//
+/ieee1588port.cpp/1.1/Fri Sep 21 20:05:48 2012//
+/ptp_message.cpp/1.1/Fri Sep 21 18:27:54 2012//
+D
diff --git a/daemons/gptp/common/CVS/Repository b/daemons/gptp/common/CVS/Repository
new file mode 100644 (file)
index 0000000..95ecafe
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/common
diff --git a/daemons/gptp/common/CVS/Root b/daemons/gptp/common/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/common/avbts_clock.hpp b/daemons/gptp/common/avbts_clock.hpp
new file mode 100644 (file)
index 0000000..b02fd55
--- /dev/null
@@ -0,0 +1,208 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_CLOCK_HPP
+#define AVBTS_CLOCK_HPP
+
+#include <stdint.h>
+#include <ieee1588.hpp>
+#include <avbts_port.hpp>
+#include <avbts_ostimerq.hpp>
+#include <avbts_osipc.hpp>
+
+#define EVENT_TIMER_GRANULARITY 5000000
+
+struct ClockQuality {
+       unsigned char cq_class;
+       unsigned char clockAccuracy;
+       int16_t offsetScaledLogVariance;
+};
+
+class IEEE1588Clock {
+ private:
+       ClockIdentity clock_identity;
+       ClockQuality clock_quality;
+       unsigned char priority1;
+       unsigned char priority2;
+       bool initializable;
+       bool is_boundary_clock;
+       bool two_step_clock;
+       unsigned char domain_number;
+       uint16_t number_ports;
+       uint16_t number_foreign_records;
+       bool slave_only;
+       int16_t current_utc_offset;
+       bool leap_59;
+       bool leap_61;
+       uint16_t epoch_number;
+       uint16_t steps_removed;
+       int64_t offset_from_master;
+       Timestamp one_way_delay;
+       PortIdentity parent_identity;
+       PortIdentity grandmaster_port_identity;
+       ClockQuality grandmaster_clock_quality;
+       unsigned char grandmaster_priority1;
+       unsigned char grandmaster_priority2;
+       bool grandmaster_is_boundary_clock;
+       uint8_t time_source;
+
+       int32_t master_local_offset_125us_offset;
+       uint64_t master_local_offset_nrst125us_initial;
+       bool master_local_offset_nrst125us_initialized;
+
+  ClockIdentity LastEBestIdentity;
+
+       IEEE1588Port *port_list[MAX_PORTS];
+
+       static Timestamp start_time;
+       Timestamp last_sync_time;
+
+       OS_IPC *ipc;
+
+       OSTimerQueue *timerq;
+
+       bool forceOrdinarySlave;
+ public:
+        IEEE1588Clock(bool forceOrdinarySlave,
+                      OSTimerQueueFactory * timerq_factory, OS_IPC * ipc);
+       ~IEEE1588Clock(void);
+
+       Timestamp getTime(void);
+       Timestamp getPreciseTime(void);
+
+       bool isBetterThan(PTPMessageAnnounce * msg);
+
+  ClockIdentity getLastEBestIdentity( void ) {
+    return LastEBestIdentity;
+       }
+  void setLastEBestIdentity( ClockIdentity id ) {
+    LastEBestIdentity = id;
+               return;
+       }
+
+       void setClockIdentity(char *id) {
+               clock_identity.set((uint8_t *) id);
+       }
+       void setClockIdentity(LinkLayerAddress * addr) {
+               clock_identity.set(addr);
+       }
+
+       unsigned char getDomain(void) {
+               return domain_number;
+       }
+
+       PortIdentity getGrandmasterPortIdentity(void) {
+               return grandmaster_port_identity;
+       }
+       void setGrandmasterPortIdentity(PortIdentity id) {
+               grandmaster_port_identity = id;
+       }
+
+       ClockQuality getGrandmasterClockQuality(void) {
+               return grandmaster_clock_quality;
+       }
+
+       ClockQuality getClockQuality(void) {
+               return clock_quality;
+       }
+
+       unsigned char getGrandmasterPriority1(void) {
+               return grandmaster_priority1;
+       }
+
+       unsigned char getGrandmasterPriority2(void) {
+               return grandmaster_priority2;
+       }
+
+       uint16_t getMasterStepsRemoved(void) {
+               return steps_removed;
+       }
+
+       uint16_t getCurrentUtcOffset(void) {
+               return current_utc_offset;
+       }
+
+       uint8_t getTimeSource(void) {
+               return time_source;
+       }
+
+       void getGrandmasterIdentity(char *id);
+
+       unsigned char getPriority1(void) {
+               return priority1;
+       }
+
+       unsigned char getPriority2(void) {
+               return priority2;
+       }
+       uint16_t getNextPortId(void) {
+               return (number_ports++ % (MAX_PORTS + 1)) + 1;
+       }
+       void registerPort(IEEE1588Port * port, uint16_t index) {
+               if (index < MAX_PORTS) {
+                       port_list[index - 1] = port;
+               }
+               ++number_ports;
+       }
+       void getPortList(int &count, IEEE1588Port ** &ports) {
+               ports = this->port_list;
+               count = number_ports;
+               return;
+       }
+
+       static Timestamp getSystemTime(void);
+
+       void addEventTimer(IEEE1588Port * target, Event e,
+                          unsigned long long time_ns);
+       void deleteEventTimer(IEEE1588Port * target, Event e);
+
+#define SHM_SIZE  2*sizeof( int64_t )                                  \
+    + 2*(sizeof( last_sync_time.seconds_ms ) + sizeof( last_sync_time.seconds_ls ) + sizeof( last_sync_time.nanoseconds )) \
+    + 4*sizeof(uint32_t) + sizeof( uint16_t )
+
+       void setMasterOffset(int64_t master_local_offset, Timestamp local_time,
+                            int32_t master_local_freq_offset,
+                            int64_t local_system_offset, Timestamp system_time,
+                            int32_t local_system_freq_offset,
+                            uint32_t nominal_clock_rate, uint32_t local_clock);
+
+       ClockIdentity getClockIdentity() {
+               return clock_identity;
+       }
+
+       friend void tick_handler(int sig);
+};
+
+void tick_handler(int sig);
+
+#endif
diff --git a/daemons/gptp/common/avbts_message.hpp b/daemons/gptp/common/avbts_message.hpp
new file mode 100644 (file)
index 0000000..fa8eff8
--- /dev/null
@@ -0,0 +1,462 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_MESSAGE_HPP
+#define AVBTS_MESSAGE_HPP
+
+#include <stdint.h>
+#include <avbts_osnet.hpp>
+#include <ieee1588.hpp>
+
+#define PTP_CODE_STRING_LENGTH 4
+#define PTP_SUBDOMAIN_NAME_LENGTH 16
+#define PTP_FLAGS_LENGTH 2
+
+#define GPTP_VERSION 2
+#define PTP_NETWORK_VERSION 1
+
+#define PTP_ETHER 1
+#define PTP_DEFAULT 255
+
+#define PTP_COMMON_HDR_OFFSET 0
+#define PTP_COMMON_HDR_LENGTH 34
+#define PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(x) x
+#define PTP_COMMON_HDR_PTP_VERSION(x) x+1
+#define PTP_COMMON_HDR_MSG_LENGTH(x) x+2
+#define PTP_COMMON_HDR_DOMAIN_NUMBER(x) x+4
+#define PTP_COMMON_HDR_FLAGS(x) x+6
+#define PTP_COMMON_HDR_CORRECTION(x) x+8
+#define PTP_COMMON_HDR_SOURCE_CLOCK_ID(x) x+20
+#define PTP_COMMON_HDR_SOURCE_PORT_ID(x) x+28
+#define PTP_COMMON_HDR_SEQUENCE_ID(x) x+30
+#define PTP_COMMON_HDR_CONTROL(x) x+32
+#define PTP_COMMON_HDR_LOG_MSG_INTRVL(x) x+33
+
+#define PTP_ANNOUNCE_OFFSET 34
+#define PTP_ANNOUNCE_LENGTH 30
+#define PTP_ANNOUNCE_CURRENT_UTC_OFFSET(x) x+10
+#define PTP_ANNOUNCE_GRANDMASTER_PRIORITY1(x) x+13
+#define PTP_ANNOUNCE_GRANDMASTER_CLOCK_QUALITY(x) x+14
+#define PTP_ANNOUNCE_GRANDMASTER_PRIORITY2(x) x+18
+#define PTP_ANNOUNCE_GRANDMASTER_IDENTITY(x) x+19
+#define PTP_ANNOUNCE_STEPS_REMOVED(x) x+27
+#define PTP_ANNOUNCE_TIME_SOURCE(x) x+29
+
+#define PTP_SYNC_OFFSET 34
+#define PTP_SYNC_LENGTH 10
+#define PTP_SYNC_SEC_MS(x) x
+#define PTP_SYNC_SEC_LS(x) x+2
+#define PTP_SYNC_NSEC(x) x+6
+
+#define PTP_FOLLOWUP_OFFSET 34
+#define PTP_FOLLOWUP_LENGTH 10
+#define PTP_FOLLOWUP_SEC_MS(x) x
+#define PTP_FOLLOWUP_SEC_LS(x) x+2
+#define PTP_FOLLOWUP_NSEC(x) x+6
+
+#define PTP_PDELAY_REQ_OFFSET 34
+#define PTP_PDELAY_REQ_LENGTH 20
+#define PTP_PDELAY_REQ_SEC_MS(x) x
+#define PTP_PDELAY_REQ_SEC_LS(x) x+2
+#define PTP_PDELAY_REQ_NSEC(x) x+6
+
+#define PTP_PDELAY_RESP_OFFSET 34
+#define PTP_PDELAY_RESP_LENGTH 20
+#define PTP_PDELAY_RESP_SEC_MS(x) x
+#define PTP_PDELAY_RESP_SEC_LS(x) x+2
+#define PTP_PDELAY_RESP_NSEC(x) x+6
+#define PTP_PDELAY_RESP_REQ_CLOCK_ID(x) x+10
+#define PTP_PDELAY_RESP_REQ_PORT_ID(x) x+18
+
+#define PTP_PDELAY_FOLLOWUP_OFFSET 34
+#define PTP_PDELAY_FOLLOWUP_LENGTH 20
+#define PTP_PDELAY_FOLLOWUP_SEC_MS(x) x
+#define PTP_PDELAY_FOLLOWUP_SEC_LS(x) x+2
+#define PTP_PDELAY_FOLLOWUP_NSEC(x) x+6
+#define PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID(x) x+10
+#define PTP_PDELAY_FOLLOWUP_REQ_PORT_ID(x) x+18
+
+#define PTP_LI_61_BYTE 0
+#define PTP_LI_61_BIT 0
+#define PTP_LI_59_BYTE 0
+#define PTP_LI_59_BIT 1
+#define PTP_ASSIST_BYTE 0
+#define PTP_ASSIST_BIT 1
+
+enum MessageType {
+       SYNC_MESSAGE = 0,
+       DELAY_REQ_MESSAGE = 1,
+       PATH_DELAY_REQ_MESSAGE = 2,
+       PATH_DELAY_RESP_MESSAGE = 3,
+       FOLLOWUP_MESSAGE = 8,
+       DELAY_RESP_MESSAGE = 9,
+       PATH_DELAY_FOLLOWUP_MESSAGE = 0xA,
+       ANNOUNCE_MESSAGE = 0xB,
+       SIGNALLING_MESSAGE = 0xC,
+       MANAGEMENT_MESSAGE = 0xD,
+};
+
+enum LegacyMessageType {
+       SYNC,
+       DELAY_REQ,
+       FOLLOWUP,
+       DELAY_RESP,
+       MANAGEMENT,
+       MESSAGE_OTHER
+};
+
+enum MulticastType {
+       MCAST_NONE,
+       MCAST_PDELAY,
+       MCAST_OTHER
+};
+
+class PTPMessageCommon {
+ protected:
+       unsigned char versionPTP;
+       uint16_t versionNetwork;
+       MessageType messageType;
+
+       PortIdentity *sourcePortIdentity;
+
+       uint16_t sequenceId;
+       LegacyMessageType control;
+       unsigned char flags[2];
+
+       uint16_t messageLength;
+       char logMeanMessageInterval;
+       long long correctionField;
+       unsigned char domainNumber;
+
+       Timestamp _timestamp;
+       unsigned _timestamp_counter_value;
+       bool _gc;
+
+        PTPMessageCommon(void) {
+       };
+ public:
+       PTPMessageCommon(IEEE1588Port * port);
+       virtual ~ PTPMessageCommon(void);
+
+       unsigned char *getFlags(void) {
+               return flags;
+       }
+
+       uint16_t getSequenceId(void) {
+               return sequenceId;
+       }
+       void setSequenceId(uint16_t seq) {
+               sequenceId = seq;
+       }
+
+       MessageType getMessageType(void) {
+               return messageType;
+       }
+
+       long long getCorrectionField(void) {
+               return correctionField;
+       }
+       void setCorrectionField(long long correctionAmount) {
+               correctionField = correctionAmount;
+       }
+
+       void getPortIdentity(PortIdentity * identity);
+       void setPortIdentity(PortIdentity * identity);
+
+       Timestamp getTimestamp(void) {
+               return _timestamp;
+       }
+       uint32_t getTimestampCounterValue(void) {
+               return _timestamp_counter_value;;
+       }
+       void setTimestamp(Timestamp & timestamp) {
+               _timestamp = timestamp;
+       }
+
+       bool garbage() {
+               return _gc;
+       }
+
+       bool isSenderEqual(PortIdentity portIdentity);
+
+       virtual void processMessage(IEEE1588Port * port);
+
+       void buildCommonHeader(uint8_t * buf);
+
+       friend PTPMessageCommon *buildPTPMessage(char *buf, int size,
+                                                LinkLayerAddress * remote,
+                                                IEEE1588Port * port);
+};
+
+#pragma pack(push,1)
+
+class PathTraceTLV {
+ private:
+       uint16_t tlvType;
+       uint16_t lengthField;
+       ClockIdentity identity;
+ public:
+        PathTraceTLV() {
+               tlvType = PLAT_htons(0x8);
+               lengthField = PLAT_htons(sizeof(identity));
+       }
+       void setClockIdentity(ClockIdentity * id) {
+               identity = *id;
+       }
+       void toByteString(uint8_t * byte_str) {
+               memcpy(byte_str, this, sizeof(*this));
+       }
+};
+
+#pragma pack(pop)
+
+class PTPMessageAnnounce:public PTPMessageCommon {
+ private:
+       char grandmasterIdentity[PTP_CLOCK_IDENTITY_LENGTH];
+
+       PathTraceTLV tlv;
+
+       uint16_t currentUtcOffset;
+       unsigned char grandmasterPriority1;
+       unsigned char grandmasterPriority2;
+       ClockQuality *clockQuality;
+       uint16_t stepsRemoved;
+       unsigned char timeSource;
+
+        PTPMessageAnnounce(void);
+ public:
+        PTPMessageAnnounce(IEEE1588Port * port);
+       ~PTPMessageAnnounce();
+
+       bool isBetterThan(PTPMessageAnnounce * msg);
+
+       unsigned char getGrandmasterPriority1(void) {
+               return grandmasterPriority1;
+       }
+       unsigned char getGrandmasterPriority2(void) {
+               return grandmasterPriority2;
+       }
+
+       ClockQuality *getGrandmasterClockQuality(void) {
+               return clockQuality;
+       }
+
+       uint16_t getStepsRemoved(void) {
+               return stepsRemoved;
+       }
+
+       void getGrandmasterIdentity(char *identity) {
+               memcpy(identity, grandmasterIdentity,
+                      PTP_CLOCK_IDENTITY_LENGTH);
+       }
+
+       void processMessage(IEEE1588Port * port);
+
+       void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+
+       friend PTPMessageCommon *buildPTPMessage(char *buf, int size,
+                                                LinkLayerAddress * remote,
+                                                IEEE1588Port * port);
+};
+
+class PTPMessageSync:public PTPMessageCommon {
+ private:
+       Timestamp originTimestamp;
+
+       PTPMessageSync() {
+               return;
+       }
+ public:
+        PTPMessageSync(IEEE1588Port * port);
+       void processMessage(IEEE1588Port * port);
+
+       Timestamp getOriginTimestamp(void) {
+               return originTimestamp;
+       }
+
+       void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+
+       friend PTPMessageCommon *buildPTPMessage(char *buf, int size,
+                                                LinkLayerAddress * remote,
+                                                IEEE1588Port * port);
+};
+
+#pragma pack(push,1)
+
+class scaledNs {
+ private:
+       int32_t ms;
+       uint64_t ls;
+ public:
+        scaledNs() {
+               ms = 0;
+               ls = 0;
+       } void toByteString(uint8_t * byte_str) {
+               memcpy(byte_str, this, sizeof(*this));
+       }
+};
+
+class FollowUpTLV {
+ private:
+       uint16_t tlvType;
+       uint16_t lengthField;
+       uint8_t organizationId[3];
+       uint8_t organizationSubType_ms;
+       uint16_t organizationSubType_ls;
+       int32_t cumulativeScaledRateOffset;
+       uint16_t gmTimeBaseIndicator;
+       scaledNs scaledLastGmPhaseChange;
+       int32_t scaledLastGmFreqChange;
+ public:
+        FollowUpTLV() {
+               tlvType = PLAT_htons(0x3);
+               lengthField = PLAT_htons(28);
+               organizationId[0] = '\x00';
+               organizationId[1] = '\x80';
+               organizationId[2] = '\xC2';
+               organizationSubType_ms = 0;
+               organizationSubType_ls = PLAT_htons(1);
+               cumulativeScaledRateOffset = PLAT_htonl(0);
+               gmTimeBaseIndicator = PLAT_htons(0);
+               scaledLastGmFreqChange = PLAT_htonl(0);
+       }
+       void toByteString(uint8_t * byte_str) {
+               memcpy(byte_str, this, sizeof(*this));
+       }
+};
+
+#pragma pack(pop)
+
+class PTPMessageFollowUp:public PTPMessageCommon {
+ private:
+       Timestamp preciseOriginTimestamp;
+
+       FollowUpTLV tlv;
+
+        PTPMessageFollowUp(void) {
+ } public:
+        PTPMessageFollowUp(IEEE1588Port * port);
+       void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+       void processMessage(IEEE1588Port * port);
+
+       Timestamp getPreciseOriginTimestamp(void) {
+               return preciseOriginTimestamp;
+       }
+       void setPreciseOriginTimestamp(Timestamp & timestamp) {
+               preciseOriginTimestamp = timestamp;
+       }
+
+       friend PTPMessageCommon *buildPTPMessage(char *buf, int size,
+                                                LinkLayerAddress * remote,
+                                                IEEE1588Port * port);
+};
+
+class PTPMessagePathDelayReq:public PTPMessageCommon {
+ private:
+       Timestamp originTimestamp;
+
+       PTPMessagePathDelayReq() {
+               return;
+       }
+ public:
+        PTPMessagePathDelayReq(IEEE1588Port * port);
+       void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+       void processMessage(IEEE1588Port * port);
+
+       Timestamp getOriginTimestamp(void) {
+               return originTimestamp;
+       }
+
+       friend PTPMessageCommon *buildPTPMessage(char *buf, int size,
+                                                LinkLayerAddress * remote,
+                                                IEEE1588Port * port);
+};
+
+class PTPMessagePathDelayResp:public PTPMessageCommon {
+ private:
+       PortIdentity * requestingPortIdentity;
+       Timestamp requestReceiptTimestamp;
+
+        PTPMessagePathDelayResp(void) {
+ } public:
+       ~PTPMessagePathDelayResp();
+       PTPMessagePathDelayResp(IEEE1588Port * port);
+       void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+       void processMessage(IEEE1588Port * port);
+
+       void setRequestReceiptTimestamp(Timestamp timestamp) {
+               requestReceiptTimestamp = timestamp;
+       }
+
+       void setRequestingPortIdentity(PortIdentity * identity);
+       void getRequestingPortIdentity(PortIdentity * identity);
+
+       Timestamp getRequestReceiptTimestamp(void) {
+               return requestReceiptTimestamp;
+       }
+
+       friend PTPMessageCommon *buildPTPMessage(char *buf, int size,
+                                                LinkLayerAddress * remote,
+                                                IEEE1588Port * port);
+};
+
+class PTPMessagePathDelayRespFollowUp:public PTPMessageCommon {
+ private:
+       Timestamp responseOriginTimestamp;
+       PortIdentity *requestingPortIdentity;
+
+        PTPMessagePathDelayRespFollowUp(void) {
+ } public:
+        PTPMessagePathDelayRespFollowUp(IEEE1588Port * port);
+       ~PTPMessagePathDelayRespFollowUp();
+       void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
+       void processMessage(IEEE1588Port * port);
+
+       void setResponseOriginTimestamp(Timestamp timestamp) {
+               responseOriginTimestamp = timestamp;
+       }
+       void setRequestingPortIdentity(PortIdentity * identity);
+
+       Timestamp getResponseOriginTimestamp(void) {
+               return responseOriginTimestamp;
+       }
+       PortIdentity *getRequestingPortIdentity(void) {
+               return requestingPortIdentity;
+       }
+
+       friend PTPMessageCommon *buildPTPMessage(char *buf, int size,
+                                                LinkLayerAddress * remote,
+                                                IEEE1588Port * port);
+};
+
+#endif
diff --git a/daemons/gptp/common/avbts_oscondition.hpp b/daemons/gptp/common/avbts_oscondition.hpp
new file mode 100644 (file)
index 0000000..90232f0
--- /dev/null
@@ -0,0 +1,63 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_OSSIGNAL_HPP
+#define AVBTS_OSSIGNAL_HPP
+ class OSCondition {
+private:
+       int wait_count;
+public:
+       virtual bool wait() = 0;
+       virtual bool wait_prelock() = 0;
+       virtual bool signal() = 0;
+protected:
+       OSCondition() {
+               wait_count = 0;
+       };
+       void up() {
+               ++wait_count;
+       } 
+       void down() {
+               --wait_count;
+       } 
+       bool waiting() {
+               return wait_count > 0;
+       }
+};
+
+ class OSConditionFactory {
+ public:virtual OSCondition * createCondition() = 0;
+};
+
+
+#endif
diff --git a/daemons/gptp/common/avbts_osipc.hpp b/daemons/gptp/common/avbts_osipc.hpp
new file mode 100644 (file)
index 0000000..ce7f576
--- /dev/null
@@ -0,0 +1,44 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_OSIPC_HPP
+#define AVBTS_OSIPC_HPP
+ class OS_IPC {
+ public:virtual bool init() = 0;
+       virtual bool update(int64_t ml_phoffset, int64_t ls_phoffset,
+                            int32_t ml_freqoffset, int32_t ls_freq_offset,
+                            uint64_t local_time) = 0;
+};
+
+
+#endif
diff --git a/daemons/gptp/common/avbts_oslock.hpp b/daemons/gptp/common/avbts_oslock.hpp
new file mode 100644 (file)
index 0000000..8877ada
--- /dev/null
@@ -0,0 +1,54 @@
+/******************************************************************************
+
+  Copyright (c) 2001-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_OSLOCK_HPP
+#define AVBTS_OSLOCK_HPP
+ typedef enum { oslock_recursive, oslock_nonrecursive } OSLockType;
+typedef enum { oslock_ok, oslock_self, oslock_held, oslock_fail } OSLockResult;
+ class OSLock {
+ public:virtual OSLockResult lock() = 0;
+       virtual OSLockResult unlock() = 0;
+       virtual OSLockResult trylock() = 0;
+ protected:OSLock() {
+       };
+       bool initialize(OSLockType type) {
+               return false;
+       };
+};
+
+ class OSLockFactory {
+ public:virtual OSLock * createLock(OSLockType type) = 0;
+};
+
+
+#endif
diff --git a/daemons/gptp/common/avbts_osnet.cpp b/daemons/gptp/common/avbts_osnet.cpp
new file mode 100644 (file)
index 0000000..2039f23
--- /dev/null
@@ -0,0 +1,37 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#include <avbts_osnet.hpp>
+
+std::map < factory_name_t,
+    OSNetworkInterfaceFactory * >OSNetworkInterfaceFactory::factoryMap;
diff --git a/daemons/gptp/common/avbts_osnet.hpp b/daemons/gptp/common/avbts_osnet.hpp
new file mode 100644 (file)
index 0000000..5656072
--- /dev/null
@@ -0,0 +1,176 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_OSNET_HPP
+#define AVBTS_OSNET_HPP
+
+#include <stdint.h>
+#include <string.h>
+#include <map>
+#include <ieee1588.hpp>
+
+#define FACTORY_NAME_LENGTH 48
+#define ETHER_ADDR_OCTETS 6
+#define PTP_ETHERTYPE 0x88F7
+#define DEFAULT_TIMEOUT 1      // milliseconds
+
+class LinkLayerAddress:public InterfaceLabel {
+ private:
+       uint8_t addr[ETHER_ADDR_OCTETS];
+ public:
+       LinkLayerAddress() {
+       };
+       LinkLayerAddress(uint64_t address_scalar) {
+               uint8_t *ptr;
+               address_scalar <<= 16;
+               for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS; ++ptr) {
+                       *ptr = (address_scalar & 0xFF00000000000000ULL) >> 56;
+                       address_scalar <<= 8;
+               }
+       }
+       LinkLayerAddress(uint8_t * address_octet_array) {
+               uint8_t *ptr;
+               for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS;
+                    ++ptr, ++address_octet_array) {
+                       *ptr = *address_octet_array;
+               }
+       }
+       bool operator==(const LinkLayerAddress & cmp) const {
+               return memcmp(this->addr, cmp.addr,
+                             ETHER_ADDR_OCTETS) == 0 ? true : false;
+       }
+       bool operator<(const LinkLayerAddress & cmp)const {
+               return memcmp(this->addr, cmp.addr,
+                             ETHER_ADDR_OCTETS) < 0 ? true : false;
+       }
+       bool operator>(const LinkLayerAddress & cmp)const {
+               return memcmp(this->addr, cmp.addr,
+                             ETHER_ADDR_OCTETS) < 0 ? true : false;
+       }
+       void toOctetArray(uint8_t * address_octet_array) {
+               uint8_t *ptr;
+               for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS;
+                    ++ptr, ++address_octet_array) {
+                       *address_octet_array = *ptr;
+               }
+       }
+};
+
+class InterfaceName:public InterfaceLabel {
+ private:
+       char *name;
+ public:
+        InterfaceName() {
+       };
+       InterfaceName(char *name, int length) {
+               this->name = new char[length + 1];
+               PLAT_strncpy(this->name, name, length);
+       }
+       bool operator==(const InterfaceName & cmp) const {
+               return strcmp(name, cmp.name) == 0 ? true : false;
+       }
+       bool operator<(const InterfaceName & cmp)const {
+               return strcmp(name, cmp.name) < 0 ? true : false;
+       }
+       bool operator>(const InterfaceName & cmp)const {
+               return strcmp(name, cmp.name) < 0 ? true : false;
+       } 
+       bool toString(char *string, size_t length) {
+               if (length >= strlen(name) + 1) {
+                       PLAT_strncpy(string, name, length);
+                       return true;
+               }
+               return false;
+       }
+};
+
+class factory_name_t {
+ private:
+       char name[FACTORY_NAME_LENGTH];
+        factory_name_t();
+ public:
+        factory_name_t(const char *name_a) {
+               PLAT_strncpy(name, name_a, FACTORY_NAME_LENGTH - 1);
+       } 
+       bool operator==(const factory_name_t & cmp) {
+               return strcmp(cmp.name, this->name) == 0 ? true : false;
+       }
+       bool operator<(const factory_name_t & cmp)const {
+               return strcmp(cmp.name, this->name) < 0 ? true : false;
+       }
+       bool operator>(const factory_name_t & cmp)const {
+               return strcmp(cmp.name, this->name) > 0 ? true : false;
+       }
+};
+
+typedef enum { net_trfail, net_fatal, net_succeed } net_result;
+
+class OSNetworkInterface {
+ public:
+       virtual net_result send(LinkLayerAddress * addr, uint8_t * payload,
+                               size_t length, bool timestamp) = 0;
+       virtual net_result recv(LinkLayerAddress * addr, uint8_t * payload,
+                               size_t & length) = 0;
+       virtual void getLinkLayerAddress(LinkLayerAddress * addr) = 0;
+       virtual unsigned getPayloadOffset() = 0;
+};
+
+class OSNetworkInterfaceFactory;
+
+typedef std::map < factory_name_t, OSNetworkInterfaceFactory * >FactoryMap_t;
+
+class OSNetworkInterfaceFactory {
+ public:
+       static bool registerFactory(factory_name_t id,
+                                   OSNetworkInterfaceFactory * factory) {
+               FactoryMap_t::iterator iter = factoryMap.find(id);
+               if (iter != factoryMap.end())
+                       return false;
+               factoryMap[id] = factory;
+               return true;
+       }
+       static bool buildInterface(OSNetworkInterface ** iface,
+                                  factory_name_t id,
+                                  InterfaceLabel * iflabel,
+                                  HWTimestamper * timestamper) {
+               return factoryMap[id]->createInterface(iface, iflabel,
+                                                      timestamper);
+       }
+ private:
+       virtual bool createInterface(OSNetworkInterface ** iface,
+                                    InterfaceLabel * iflabel,
+                                    HWTimestamper * timestamper) = 0;
+       static FactoryMap_t factoryMap;
+};
+
+#endif
diff --git a/daemons/gptp/common/avbts_osthread.hpp b/daemons/gptp/common/avbts_osthread.hpp
new file mode 100644 (file)
index 0000000..24520ce
--- /dev/null
@@ -0,0 +1,48 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_OSTHREAD_HPP
+#define AVBTS_OSTHREAD_HPP
+ typedef enum { osthread_ok, osthread_error } OSThreadExitCode;
+typedef OSThreadExitCode(*OSThreadFunction) (void *);
+ class OSThread {
+ public:virtual bool start(OSThreadFunction function, void *arg) = 0;
+       virtual bool join(OSThreadExitCode & exit_code) = 0;
+};
+
+ class OSThreadFactory {
+ public:virtual OSThread * createThread() = 0;
+};
+
+
+#endif
diff --git a/daemons/gptp/common/avbts_ostimer.hpp b/daemons/gptp/common/avbts_ostimer.hpp
new file mode 100644 (file)
index 0000000..8fda4c1
--- /dev/null
@@ -0,0 +1,46 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_OSTIMER_HPP
+#define AVBTS_OSTIMER_HPP
+
+class OSTimer {
+ public:virtual unsigned long sleep(unsigned long micro) = 0;
+};
+
+class OSTimerFactory {
+ public:virtual OSTimer * createTimer() = 0;
+};
+
+
+#endif
diff --git a/daemons/gptp/common/avbts_ostimerq.hpp b/daemons/gptp/common/avbts_ostimerq.hpp
new file mode 100644 (file)
index 0000000..a0b1163
--- /dev/null
@@ -0,0 +1,52 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_OSTIMERQ_HPP
+#define AVBTS_OSTIMERQ_HPP
+
+typedef void (*ostimerq_handler) (void *);
+
+class OSTimerQueue {
+ public:
+       virtual bool addEvent(unsigned long micros, int type,
+                             ostimerq_handler func, event_descriptor_t * arg,
+                             bool dynamic, unsigned *event) = 0;
+       virtual bool cancelEvent(int type, unsigned *event) = 0;
+};
+
+class OSTimerQueueFactory {
+ public:
+       virtual OSTimerQueue * createOSTimerQueue() = 0;
+};
+
+#endif
diff --git a/daemons/gptp/common/avbts_port.hpp b/daemons/gptp/common/avbts_port.hpp
new file mode 100644 (file)
index 0000000..32d2e29
--- /dev/null
@@ -0,0 +1,450 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef AVBTS_PORT_HPP
+#define AVBTS_PORT_HPP
+
+#include <ieee1588.hpp>
+#include <avbts_message.hpp>
+
+#include <avbts_ostimer.hpp>
+#include <avbts_oslock.hpp>
+#include <avbts_osnet.hpp>
+#include <avbts_osthread.hpp>
+#include <avbts_oscondition.hpp>
+
+#include <stdint.h>
+
+#include <map>
+#include <list>
+
+#define GPTP_MULTICAST 0x0180C200000EULL
+#define PDELAY_MULTICAST GPTP_MULTICAST
+#define OTHER_MULTICAST GPTP_MULTICAST
+
+#define PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER 3
+#define SYNC_RECEIPT_TIMEOUT_MULTIPLIER 10
+#define ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER 10
+
+typedef enum {
+       PTP_MASTER,
+       PTP_PRE_MASTER,
+       PTP_SLAVE,
+       PTP_UNCALIBRATED,
+       PTP_DISABLED,
+       PTP_FAULTY,
+       PTP_INITIALIZING,
+       PTP_LISTENING
+} PortState;
+
+typedef enum {
+       V1,
+       V2_E2E,
+       V2_P2P
+} PortType;
+
+class PortIdentity {
+ private:
+       ClockIdentity clock_id;
+       uint16_t portNumber;
+ public:
+        PortIdentity() {
+       };
+       PortIdentity(uint8_t * clock_id, uint16_t * portNumber) {
+               this->portNumber = *portNumber;
+               this->portNumber = PLAT_ntohs(this->portNumber);
+               this->clock_id.set(clock_id);
+       }
+       bool operator!=(const PortIdentity & cmp) const {
+               return !(this->clock_id == cmp.clock_id)
+                   || this->portNumber != cmp.portNumber ? true : false;
+       }
+       bool operator==(const PortIdentity & cmp)const {
+               return this->clock_id == cmp.clock_id
+                   && this->portNumber == cmp.portNumber ? true : false;
+       }
+       bool operator<(const PortIdentity & cmp)const {
+               return this->clock_id < cmp.clock_id ? true :
+                   this->clock_id == cmp.clock_id
+                   && this->portNumber < cmp.portNumber ? true : false;
+       }
+       bool operator>(const PortIdentity & cmp)const {
+               return this->clock_id > cmp.clock_id ? true :
+                   this->clock_id == cmp.clock_id
+                   && this->portNumber > cmp.portNumber ? true : false;
+       }
+       void getClockIdentityString(char *id) {
+               clock_id.getIdentityString(id);
+       }
+       void setClockIdentity(ClockIdentity clock_id) {
+               this->clock_id = clock_id;
+       }
+    ClockIdentity getClockIdentity( void ) {
+        return this->clock_id;
+    }
+       void getPortNumberNO(uint16_t * id) {   // Network byte order
+               uint16_t portNumberNO = PLAT_htons(portNumber);
+               *id = portNumberNO;
+       }
+       void getPortNumber(uint16_t * id) {     // Host byte order
+               *id = portNumber;
+       }
+       void setPortNumber(uint16_t * id) {
+               portNumber = *id;
+       }
+};
+
+typedef std::map < PortIdentity, LinkLayerAddress > IdentityMap_t;
+
+typedef std::list < PTPMessageAnnounce * >AnnounceList_t;
+
+class IEEE1588Port {
+       static LinkLayerAddress other_multicast;
+       static LinkLayerAddress pdelay_multicast;
+
+       PortIdentity port_identity;
+       // directly connected node
+       PortIdentity peer_identity;
+
+       OSNetworkInterface *net_iface;
+       LinkLayerAddress local_addr;
+
+       // Port Configuration
+       unsigned char delay_mechanism;
+       PortState port_state;
+       char log_mean_unicast_sync_interval;
+       char log_mean_sync_interval;
+       char log_mean_announce_interval;
+       char log_min_mean_delay_req_interval;
+       char log_min_mean_pdelay_req_interval;
+       bool burst_enabled;
+       int64_t one_way_delay;  // Allow this to be negative result of a large clock skew
+       // Implementation Specific data/methods
+       IEEE1588Clock *clock;   // Pointer to clock object with which the port is associated
+
+       bool _syntonize;
+
+       bool asCapable;
+
+       int32_t *rate_offset_array;
+       uint32_t rate_offset_array_size;
+       uint32_t rate_offset_count;
+       uint32_t rate_offset_index;
+
+       int32_t _peer_rate_offset;
+       Timestamp _peer_offset_ts_theirs;
+       Timestamp _peer_offset_ts_mine;
+       bool _peer_offset_init;
+
+       int32_t _master_rate_offset;
+
+       int32_t _initial_clock_offset;
+       int32_t _current_clock_offset;
+
+       bool _master_local_freq_offset_init;
+       int64_t _prev_master_local_offset;
+       Timestamp _prev_sync_time;
+
+       bool _local_system_freq_offset_init;
+       int64_t _prev_local_system_offset;
+       Timestamp _prev_system_time;
+
+       AnnounceList_t qualified_announce;
+
+       uint16_t announce_sequence_id;
+       uint16_t sync_sequence_id;
+
+       uint16_t pdelay_sequence_id;
+       PTPMessagePathDelayReq *last_pdelay_req;
+       PTPMessagePathDelayResp *last_pdelay_resp;
+       PTPMessagePathDelayRespFollowUp *last_pdelay_resp_fwup;
+
+       // Network socket description
+       uint16_t ifindex;       // physical interface number that object represents
+
+       IdentityMap_t identity_map;
+
+       PTPMessageSync *last_sync;
+
+       OSThread *listening_thread;
+
+       OSCondition *port_ready_condition;
+
+       OSLock *pdelay_rx_lock;
+       OSLock *port_tx_lock;
+
+       OSThreadFactory *thread_factory;
+       OSTimerFactory *timer_factory;
+
+       HWTimestamper *_hw_timestamper;
+
+       net_result port_send(uint8_t * buf, int size, MulticastType mcast_type,
+                            PortIdentity * destIdentity, bool timestamp);
+
+       InterfaceLabel *net_label;
+
+       OSLockFactory *lock_factory;
+       OSConditionFactory *condition_factory;
+ public:
+       // Added for testing
+       bool forceSlave;
+
+       OSTimerFactory *getTimerFactory() {
+               return timer_factory;
+       }
+       void setAsCapable(bool ascap) {
+               if (ascap != asCapable) {
+                       fprintf(stderr, "AsCapable: %s\n",
+                               ascap == true ? "Enabled" : "Disabled");
+               }
+               asCapable = ascap;
+       }
+
+       ~IEEE1588Port();
+       IEEE1588Port(IEEE1588Clock * clock, uint16_t index, bool forceSlave,
+                    HWTimestamper * timestamper, bool syntonize,
+                    int32_t offset, InterfaceLabel * net_label,
+                    OSConditionFactory * condition_factory,
+                    OSThreadFactory * thread_factory,
+                    OSTimerFactory * timer_factory,
+                    OSLockFactory * lock_factory);
+       bool init_port();
+
+       void recoverPort(void);
+       void *openPort(void);
+       unsigned getPayloadOffset();
+       void sendEventPort(uint8_t * buf, int len, MulticastType mcast_type,
+                          PortIdentity * destIdentity);
+       void sendGeneralPort(uint8_t * buf, int len, MulticastType mcast_type,
+                            PortIdentity * destIdentity);
+       void processEvent(Event e);
+
+       PTPMessageAnnounce *calculateERBest(void);
+
+       void addForeignMaster(PTPMessageAnnounce * msg);
+       void removeForeignMaster(PTPMessageAnnounce * msg);
+       void removeForeignMasterAll(void);
+
+       void addQualifiedAnnounce(PTPMessageAnnounce * msg) {
+               qualified_announce.push_front(msg);
+       }
+
+       void removeQualifiedAnnounce(PTPMessageAnnounce * msg) {
+               qualified_announce.remove(msg);
+       }
+
+       char getSyncInterval(void) {
+               return log_mean_sync_interval;
+       }
+       char getAnnounceInterval(void) {
+               return log_mean_announce_interval;
+       }
+       char getPDelayInterval(void) {
+               return log_min_mean_pdelay_req_interval;
+       }
+       PortState getPortState(void) {
+               return port_state;
+       }
+       void getPortIdentity(PortIdentity & identity) {
+               identity = this->port_identity;
+       }
+       bool burstEnabled(void) {
+               return burst_enabled;
+       }
+       uint16_t getNextAnnounceSequenceId(void) {
+               return announce_sequence_id++;
+       }
+       uint16_t getNextSyncSequenceId(void) {
+               return sync_sequence_id++;
+       }
+       uint16_t getNextPDelaySequenceId(void) {
+               return pdelay_sequence_id++;
+       }
+
+       uint16_t getParentLastSyncSequenceNumber(void);
+       void setParentLastSyncSequenceNumber(uint16_t num);
+
+       IEEE1588Clock *getClock(void);
+
+       void setLastSync(PTPMessageSync * msg) {
+               last_sync = msg;
+       }
+       PTPMessageSync *getLastSync(void) {
+               return last_sync;
+       }
+
+       bool getPDelayRxLock() {
+               return pdelay_rx_lock->lock() == oslock_ok ? true : false;
+       }
+
+       bool tryPDelayRxLock() {
+               return pdelay_rx_lock->trylock() == oslock_ok ? true : false;
+       }
+
+       bool putPDelayRxLock() {
+               return pdelay_rx_lock->unlock() == oslock_ok ? true : false;
+       }
+
+       int getTxLock() {
+               return port_tx_lock->lock() == oslock_ok ? true : false;
+       }
+       int putTxLock() {
+               return port_tx_lock->unlock() == oslock_ok ? true : false;
+       }
+
+       void setLastPDelayReq(PTPMessagePathDelayReq * msg) {
+               last_pdelay_req = msg;
+       }
+       PTPMessagePathDelayReq *getLastPDelayReq(void) {
+               return last_pdelay_req;
+       }
+
+       void setLastPDelayResp(PTPMessagePathDelayResp * msg) {
+               last_pdelay_resp = msg;
+       }
+       PTPMessagePathDelayResp *getLastPDelayResp(void) {
+               return last_pdelay_resp;
+       }
+
+       void setLastPDelayRespFollowUp(PTPMessagePathDelayRespFollowUp * msg) {
+               last_pdelay_resp_fwup = msg;
+       }
+       PTPMessagePathDelayRespFollowUp *getLastPDelayRespFollowUp(void) {
+               return last_pdelay_resp_fwup;
+       }
+
+       int calcMasterLocalClockRateDifference(signed long long offset,
+                                              Timestamp sync_time);
+       int calcLocalSystemClockRateDifference(signed long long offset,
+                                              Timestamp sync_time);
+
+       int32_t getMasterRateOffset(void) {
+               return _master_rate_offset;
+       }
+       void setMasterRateOffset(int32_t offset
+                                /* parts-per-trillion frequency offset */ ) {
+               _master_rate_offset = offset;
+       }
+       int32_t getPeerRateOffset(void) {
+               return _peer_rate_offset;
+       }
+       void setPeerRateOffset(int32_t offset
+                              /* parts-per-trillion frequency offset */ ) {
+               _peer_rate_offset = offset;
+       }
+       void setPeerOffset(Timestamp mine, Timestamp theirs) {
+               _peer_offset_ts_mine = mine;
+               _peer_offset_ts_theirs = theirs;
+               _peer_offset_init = true;
+       }
+       bool getPeerOffset(Timestamp & mine, Timestamp & theirs) {
+               mine = _peer_offset_ts_mine;
+               theirs = _peer_offset_ts_theirs;
+               return _peer_offset_init;
+       }
+
+       bool _adjustClockRate(int32_t freq_offset, unsigned counter_value,
+                             Timestamp master_timestamp, int64_t offset,
+                             bool change_master) {
+               if (_hw_timestamper) {
+                       return
+                           _hw_timestamper->HWTimestamper_adjclockrate
+                           (freq_offset, counter_value, master_timestamp,
+                            offset, change_master);
+               }
+               return false;
+       }
+       bool adjustClockRate(int32_t freq_offset, unsigned counter_value,
+                            Timestamp master_timestamp, int64_t offset,
+                            bool change_master) {
+               return _adjustClockRate(freq_offset, counter_value,
+                                       master_timestamp, offset,
+                                       change_master);
+       }
+
+       bool doSyntonization(void) {
+               return _syntonize;
+       }
+
+       void getExtendedError(char *msg) {
+               if (_hw_timestamper) {
+                       _hw_timestamper->HWTimestamper_get_extderror(msg);
+               } else {
+                       *msg = '\0';
+               }
+       }
+
+       bool getExternalClockRate(Timestamp & local_time,
+                                 int64_t & external_local_offset,
+                                 int32_t & external_local_freq_offset) {
+               bool s = false;
+               if (_hw_timestamper) {
+                       s = _hw_timestamper->HWTimestamper_get_extclk_offset
+                           (&local_time, &external_local_offset,
+                            &external_local_freq_offset);
+               }
+               return s;
+       }
+
+       int getRxTimestamp(PortIdentity * sourcePortIdentity,
+                          uint16_t sequenceId, Timestamp & timestamp,
+                          unsigned &counter_value, bool last);
+       int getTxTimestamp(PortIdentity * sourcePortIdentity,
+                          uint16_t sequenceId, Timestamp & timestamp,
+                          unsigned &counter_value, bool last);
+
+       int getTxTimestamp(PTPMessageCommon * msg, Timestamp & timestamp,
+                          unsigned &counter_value, bool last);
+       int getRxTimestamp(PTPMessageCommon * msg, Timestamp & timestamp,
+                          unsigned &counter_value, bool last);
+
+       void getDeviceTime(Timestamp & system_time, Timestamp & device_time,
+                          uint32_t & local_clock,
+                          uint32_t & nominal_clock_rate);
+
+       int64_t getLinkDelay(void) {
+               return one_way_delay;
+       }
+       void setLinkDelay(int64_t delay) {
+               one_way_delay = delay;
+       }
+
+       void recommendState(PortState state, bool changed_master);
+
+       void mapSocketAddr(PortIdentity * destIdentity,
+                          LinkLayerAddress * remote);
+       void addSockAddrMap(PortIdentity * destIdentity,
+                           LinkLayerAddress * remote);
+};
+
+#endif
diff --git a/daemons/gptp/common/ieee1588.hpp b/daemons/gptp/common/ieee1588.hpp
new file mode 100644 (file)
index 0000000..bffd555
--- /dev/null
@@ -0,0 +1,231 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef IEEE1588_HPP
+#define IEEE1588_HPP
+
+#include <stdint.h>
+
+#include <string.h>
+
+#include <signal.h>
+
+#include <stdio.h>
+
+#include <platform.hpp>
+
+#define MAX_PORTS 32
+
+#define PTP_CLOCK_IDENTITY_LENGTH 8
+
+class LinkLayerAddress;
+struct ClockQuality;
+class PortIdentity;
+class IEEE1588Clock;
+class PTPMessageCommon;
+class PTPMessageSync;
+class PTPMessageAnnounce;
+class PTPMessagePathDelayReq;
+class PTPMessagePathDelayResp;
+class PTPMessagePathDelayRespFollowUp;
+class IEEE1588Port;
+
+typedef enum {
+       NULL_EVENT = 0,
+       POWERUP = 5,
+       INITIALIZE,
+       STATE_CHANGE_EVENT,
+       SYNC_INTERVAL_TIMEOUT_EXPIRES,
+       PDELAY_INTERVAL_TIMEOUT_EXPIRES,
+       SYNC_RECEIPT_TIMEOUT_EXPIRES,
+       QUALIFICATION_TIMEOUT_EXPIRES,
+       ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
+       ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES,
+       FAULT_DETECTED,
+       PDELAY_DEFERRED_PROCESSING,
+       PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES,
+} Event;
+
+typedef struct {
+       IEEE1588Port *port;
+       Event event;
+} event_descriptor_t;
+
+class InterfaceLabel {
+ public:
+       virtual ~ InterfaceLabel() {
+       };
+};
+
+class ClockIdentity {
+ private:
+       uint8_t id[PTP_CLOCK_IDENTITY_LENGTH];
+ public:
+       bool operator==(const ClockIdentity & cmp) const {
+               return memcmp(this->id, cmp.id,
+                             PTP_CLOCK_IDENTITY_LENGTH) == 0 ? true : false;
+       }
+    bool operator!=( const ClockIdentity &cmp ) const {
+        return memcmp( this->id, cmp.id, PTP_CLOCK_IDENTITY_LENGTH ) != 0 ? true : false;
+       }
+       bool operator<(const ClockIdentity & cmp)const {
+               return memcmp(this->id, cmp.id,
+                             PTP_CLOCK_IDENTITY_LENGTH) < 0 ? true : false;
+       }
+       bool operator>(const ClockIdentity & cmp)const {
+               return memcmp(this->id, cmp.id,
+                             PTP_CLOCK_IDENTITY_LENGTH) < 0 ? true : false;
+       }
+       void getIdentityString(char *id) {
+               memcpy(id, this->id, PTP_CLOCK_IDENTITY_LENGTH);
+       } 
+       void set(uint8_t * id) {
+               memcpy(this->id, id, PTP_CLOCK_IDENTITY_LENGTH);
+       }
+       void set(LinkLayerAddress * address);
+};
+
+class Timestamp {
+ public:
+       Timestamp(uint32_t ns, uint32_t s_l, uint16_t s_m) {
+               nanoseconds = ns;
+               seconds_ls = s_l;
+               seconds_ms = s_m;
+       } 
+       Timestamp() {
+       };
+       uint32_t nanoseconds;
+       uint32_t seconds_ls;
+       uint16_t seconds_ms;
+};
+
+#define INVALID_TIMESTAMP (Timestamp( 0xC0000000, 0, 0 ))
+#define PDELAY_PENDING_TIMESTAMP (Timestamp( 0xC0000001, 0, 0 ))
+
+#define TIMESTAMP_TO_NS(ts) (((static_cast<long long int>(ts.seconds_ms) << sizeof(ts.seconds_ls)*8) + ts.seconds_ls)*1000000000LL + \
+                            ts.nanoseconds)
+
+static inline uint64_t bswap_64(uint64_t in)
+{
+       uint8_t *s = (uint8_t *) & in;
+       uint8_t *e = s + 7;
+       while (e > s) {
+               uint8_t t;
+               t = *s;
+               *s = *e;
+               *e = t;
+               ++s;
+               --e;
+       }
+       return in;
+}
+
+static inline void TIMESTAMP_SUB_NS(Timestamp & ts, uint64_t ns)
+{
+       while (ns >= 1000000000) {
+               if (ts.seconds_ls != 0) {
+                       --ts.seconds_ls;
+               } else {
+                       --ts.seconds_ms;
+                       ts.seconds_ls = 0xFFFFFFFF;
+               }
+               ns -= 1000000000;
+       }
+       ts.nanoseconds -= (uint32_t) ns;
+}
+
+#define XPTPD_ERROR(fmt,...) fprintf( stderr, "ERROR at %u in %s: " fmt "\n", __LINE__, __FILE__ ,## __VA_ARGS__)
+#ifdef PTP_DEBUG
+#define XPTPD_INFO(fmt,...) fprintf( stderr, "DEBUG at %u in %s: " fmt "\n", __LINE__, __FILE__ ,## __VA_ARGS__)
+#else
+#define XPTPD_INFO(fmt,...)
+#endif
+
+#define HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE 4096
+
+class HWTimestamper {
+ public:
+       virtual bool HWTimestamper_init(InterfaceLabel * iface_label) {
+               return true;
+       }
+       virtual void HWTimestamper_final(void) {
+       }
+
+       virtual bool HWTimestamper_adjclockrate(int32_t frequency_offset,
+                                               unsigned counter_value,
+                                               Timestamp master_timestamp,
+                                               int64_t offset,
+                                               bool changed_master) {
+               return false;
+       }
+       virtual bool HWTimestamper_adjclockrate2(int32_t ppt_adjustment) {
+               return false;
+       }
+
+       virtual bool HWTimestamper_gettime(Timestamp * system_time,
+                                          Timestamp * device_time,
+                                          uint32_t * local_clock,
+                                          uint32_t * nominal_clock_rate) = 0;
+
+       virtual int HWTimestamper_txtimestamp(PortIdentity * identity,
+                                             uint16_t sequenceId,
+                                             Timestamp & timestamp,
+                                             unsigned &clock_value,
+                                             bool last) = 0;
+
+       virtual int HWTimestamper_rxtimestamp(PortIdentity * identity,
+                                             uint16_t sequenceId,
+                                             Timestamp & timestamp,
+                                             unsigned &clock_value,
+                                             bool last) = 0;
+
+       virtual bool HWTimestamper_get_extclk_offset(Timestamp * local_time,
+                                                    int64_t * clk_offset,
+                                                    int32_t *
+                                                    ppt_freq_offset) {
+               return false;
+       }
+
+       virtual void HWTimestamper_get_extderror(char *msg) {
+               *msg = '\0';
+       }
+
+       virtual ~ HWTimestamper() {
+       }
+};
+
+PTPMessageCommon *buildPTPMessage(char *buf, int size,
+                                 LinkLayerAddress * remote,
+                                 IEEE1588Port * port);
+
+#endif
diff --git a/daemons/gptp/common/ieee1588clock.cpp b/daemons/gptp/common/ieee1588clock.cpp
new file mode 100644 (file)
index 0000000..6f289fc
--- /dev/null
@@ -0,0 +1,197 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#include <ieee1588.hpp>
+
+#include <avbts_clock.hpp>
+#include <avbts_oslock.hpp>
+#include <avbts_ostimerq.hpp>
+
+#include <stdio.h>
+
+#include <string.h>
+
+#include <stdlib.h>
+
+#include <string.h>
+
+void ClockIdentity::set(LinkLayerAddress * addr)
+{
+       uint64_t tmp1 = 0;
+       uint32_t tmp2;
+       addr->toOctetArray((uint8_t *) & tmp1);
+       tmp2 = tmp1 & 0xFFFFFF;
+       tmp1 >>= 24;
+       tmp1 <<= 16;
+       tmp1 |= 0xFEFF;
+       tmp1 <<= 24;
+       tmp1 |= tmp2;
+       memcpy(id, &tmp1, PTP_CLOCK_IDENTITY_LENGTH);
+}
+
+IEEE1588Clock::IEEE1588Clock(bool forceOrdinarySlave,
+                            OSTimerQueueFactory * timerq_factory, OS_IPC * ipc)
+{
+       timerq = timerq_factory->createOSTimerQueue();
+
+       priority1 = 248;
+       priority2 = 248;
+
+       master_local_offset_nrst125us_initialized = false;
+
+       number_ports = 0;
+
+       this->forceOrdinarySlave = forceOrdinarySlave;
+
+       clock_quality.clockAccuracy = 0xfe;
+       clock_quality.cq_class = 248;
+       clock_quality.offsetScaledLogVariance = 16640;
+
+       time_source = 160;
+
+       domain_number = 0;
+
+       this->ipc = ipc;
+
+       memset( &LastEBestIdentity, 0xFF, sizeof( LastEBestIdentity ));
+       return;
+}
+
+Timestamp IEEE1588Clock::getSystemTime(void)
+{
+       return (Timestamp(0, 0, 0));
+}
+
+void timerq_handler(void *arg)
+{
+       event_descriptor_t *event_descriptor = (event_descriptor_t *) arg;
+       event_descriptor->port->processEvent(event_descriptor->event);
+}
+
+void IEEE1588Clock::addEventTimer(IEEE1588Port * target, Event e,
+                                 unsigned long long time_ns)
+{
+       event_descriptor_t *event_descriptor = new event_descriptor_t();
+       event_descriptor->event = e;
+       event_descriptor->port = target;
+       timerq->addEvent((unsigned)time_ns / 1000, (int)e, timerq_handler,
+                        event_descriptor, true, NULL);
+}
+
+void IEEE1588Clock::deleteEventTimer(IEEE1588Port * target, Event event)
+{
+       timerq->cancelEvent((int)event, NULL);
+}
+
+// Sync clock to argument time
+void IEEE1588Clock::setMasterOffset(int64_t master_local_offset,
+                                   Timestamp local_time,
+                                   int32_t master_local_freq_offset,
+                                   int64_t local_system_offset,
+                                   Timestamp system_time,
+                                   int32_t local_system_freq_offset,
+                                   uint32_t nominal_clock_rate,
+                                   uint32_t local_clock)
+{
+
+       if (ipc != NULL)
+               ipc->update(master_local_offset, local_system_offset,
+                           master_local_freq_offset, local_system_freq_offset,
+                           TIMESTAMP_TO_NS(local_time));
+       return;
+}
+
+void IEEE1588Clock::getGrandmasterIdentity(char *id)
+{
+       grandmaster_port_identity.getClockIdentityString(id);
+}
+
+// Get current time from system clock
+Timestamp IEEE1588Clock::getTime(void)
+{
+       return getSystemTime();
+}
+
+// Get timestamp from hardware
+Timestamp IEEE1588Clock::getPreciseTime(void)
+{
+       return getSystemTime();
+}
+
+bool IEEE1588Clock::isBetterThan(PTPMessageAnnounce * msg)
+{
+       unsigned char this1[14];
+       unsigned char that1[14];
+       uint16_t tmp;
+
+       this1[0] = priority1;
+       that1[0] = msg->getGrandmasterPriority1();
+
+       this1[1] = clock_quality.cq_class;
+       that1[1] = msg->getGrandmasterClockQuality()->cq_class;
+
+       this1[2] = clock_quality.clockAccuracy;
+       that1[2] = msg->getGrandmasterClockQuality()->clockAccuracy;
+
+       tmp = clock_quality.offsetScaledLogVariance;
+       tmp = PLAT_htons(tmp);
+       memcpy(this1 + 3, &tmp, sizeof(tmp));
+       tmp = msg->getGrandmasterClockQuality()->offsetScaledLogVariance;
+       tmp = PLAT_htons(tmp);
+       memcpy(that1 + 3, &tmp, sizeof(tmp));
+
+       this1[5] = priority2;
+       that1[5] = msg->getGrandmasterPriority2();
+
+       clock_identity.getIdentityString((char *)this1 + 6);
+       //memcpy( this1+6, clock_identity, PTP_CLOCK_IDENTITY_LENGTH );
+       msg->getGrandmasterIdentity((char *)that1 + 6);
+
+#if 0
+       fprintf(stderr, "(Clk)Us: ");
+       for (int i = 0; i < 14; ++i)
+               fprintf(stderr, "%hhx ", this1[i]);
+       fprintf(stderr, "\n");
+       fprintf(stderr, "(Clk)Them: ");
+       for (int i = 0; i < 14; ++i)
+               fprintf(stderr, "%hhx ", that1[i]);
+       fprintf(stderr, "\n");
+#endif
+
+       return (memcmp(this1, that1, 14) < 0) ? true : false;
+}
+
+IEEE1588Clock::~IEEE1588Clock(void)
+{
+       // Unmap shared memory
+}
diff --git a/daemons/gptp/common/ieee1588port.cpp b/daemons/gptp/common/ieee1588port.cpp
new file mode 100644 (file)
index 0000000..cf62fd2
--- /dev/null
@@ -0,0 +1,1031 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#include <ieee1588.hpp>
+
+#include <avbts_port.hpp>
+#include <avbts_message.hpp>
+#include <avbts_clock.hpp>
+
+#include <avbts_oslock.hpp>
+#include <avbts_osnet.hpp>
+#include <avbts_oscondition.hpp>
+
+#include <stdio.h>
+
+#include <math.h>
+
+#include <stdlib.h>
+
+LinkLayerAddress IEEE1588Port::other_multicast(OTHER_MULTICAST);
+LinkLayerAddress IEEE1588Port::pdelay_multicast(PDELAY_MULTICAST);
+
+OSThreadExitCode openPortWrapper(void *arg)
+{
+       IEEE1588Port *port;
+
+       port = (IEEE1588Port *) arg;
+       if (port->openPort() == NULL)
+               return osthread_ok;
+       else
+               return osthread_error;
+}
+
+IEEE1588Port::~IEEE1588Port()
+{
+       delete port_ready_condition;
+       delete [] rate_offset_array;
+}
+
+IEEE1588Port::IEEE1588Port(IEEE1588Clock * clock, uint16_t index,
+                          bool forceSlave, HWTimestamper * timestamper,
+                          bool syntonize, int32_t offset,
+                          InterfaceLabel * net_label,
+                          OSConditionFactory * condition_factory,
+                          OSThreadFactory * thread_factory,
+                          OSTimerFactory * timer_factory,
+                          OSLockFactory * lock_factory)
+{
+       sync_sequence_id = 0;
+       last_pdelay_req = NULL;
+
+       clock->registerPort(this, index);
+       this->clock = clock;
+       ifindex = index;
+
+       this->forceSlave = forceSlave;
+
+       asCapable = false;
+
+       announce_sequence_id = 0;
+       sync_sequence_id = 0;
+       pdelay_sequence_id = 0;
+
+       sync_sequence_id = 0;
+
+       log_mean_sync_interval = -3;
+       log_mean_announce_interval = 0;
+       log_min_mean_pdelay_req_interval = 0;
+
+       _current_clock_offset = _initial_clock_offset = offset;
+
+       rate_offset_array = NULL;
+
+       _hw_timestamper = timestamper;
+
+       if (_hw_timestamper != NULL) {
+               if (!_hw_timestamper->HWTimestamper_init(net_label)) {
+                       XPTPD_ERROR
+                           ("Failed to initialize hardware timestamper, falling back to software timestamping");
+                       _hw_timestamper = NULL;
+               }
+       }
+
+       _syntonize = syntonize;
+       _master_local_freq_offset_init = false;
+       _local_system_freq_offset_init = false;
+
+       one_way_delay = 3600000000000;
+
+       _peer_rate_offset = 0;
+       _master_rate_offset = 0;
+
+       last_sync = NULL;
+       last_pdelay_req = NULL;
+       last_pdelay_resp = NULL;
+       last_pdelay_resp_fwup = NULL;
+
+       this->net_label = net_label;
+
+       this->timer_factory = timer_factory;
+       this->thread_factory = thread_factory;
+
+       this->condition_factory = condition_factory;
+       this->lock_factory = lock_factory;
+}
+
+bool IEEE1588Port::init_port()
+{
+       if (!OSNetworkInterfaceFactory::buildInterface
+           (&net_iface, factory_name_t("default"), net_label, _hw_timestamper))
+               return false;
+
+       this->net_iface = net_iface;
+       this->net_iface->getLinkLayerAddress(&local_addr);
+       clock->setClockIdentity(&local_addr);
+
+       pdelay_rx_lock = lock_factory->createLock(oslock_recursive);
+       port_tx_lock = lock_factory->createLock(oslock_recursive);
+
+       port_identity.setClockIdentity(clock->getClockIdentity());
+       port_identity.setPortNumber(&ifindex);
+
+       port_ready_condition = condition_factory->createCondition();
+
+       return true;
+}
+
+void *IEEE1588Port::openPort(void)
+{
+       fprintf(stderr, "openPort: thread started\n");
+
+       port_ready_condition->signal();
+
+       while (1) {
+               PTPMessageCommon *msg;
+               uint8_t buf[128];
+               LinkLayerAddress remote;
+               net_result rrecv;
+               size_t length = sizeof(buf);
+
+               if ((rrecv = net_iface->recv(&remote, buf, length)) == net_succeed) {
+                       XPTPD_INFO("Processing network buffer");
+                       msg = buildPTPMessage((char *)buf, (int)length, &remote,
+                                           this);
+                       if (msg != NULL) {
+                               XPTPD_INFO("Processing message");
+                               msg->processMessage(this);
+                               if (msg->garbage()) {
+                                       delete msg;
+                               }
+                       } else {
+                               XPTPD_ERROR("Discarding invalid message");
+                       }
+               } else if (rrecv == net_fatal) {
+                       XPTPD_ERROR("read from network interface failed");
+                       this->processEvent(FAULT_DETECTED);
+                       break;
+               }
+       }
+
+       return NULL;
+}
+
+net_result IEEE1588Port::port_send(uint8_t * buf, int size,
+                                  MulticastType mcast_type,
+                                  PortIdentity * destIdentity, bool timestamp)
+{
+       LinkLayerAddress dest;
+
+       if (mcast_type != MCAST_NONE) {
+               if (mcast_type == MCAST_PDELAY) {
+                       dest = pdelay_multicast;
+               } else {
+                       dest = other_multicast;
+               }
+       } else {
+               mapSocketAddr(destIdentity, &dest);
+       }
+
+       return net_iface->send(&dest, (uint8_t *) buf, size, timestamp);
+}
+
+unsigned IEEE1588Port::getPayloadOffset()
+{
+       return net_iface->getPayloadOffset();
+}
+
+void IEEE1588Port::sendEventPort(uint8_t * buf, int size,
+                                MulticastType mcast_type,
+                                PortIdentity * destIdentity)
+{
+       net_result rtx = port_send(buf, size, mcast_type, destIdentity, true);
+       if (rtx != net_succeed) {
+               XPTPD_ERROR("sendEventPort(): failure");
+       }
+
+       return;
+}
+
+void IEEE1588Port::sendGeneralPort(uint8_t * buf, int size,
+                                  MulticastType mcast_type,
+                                  PortIdentity * destIdentity)
+{
+       net_result rtx = port_send(buf, size, mcast_type, destIdentity, false);
+       if (rtx != net_succeed) {
+               XPTPD_ERROR("sendEventPort(): failure");
+       }
+
+       return;
+}
+
+void IEEE1588Port::processEvent(Event e)
+{
+       bool changed_master;
+       OSTimer *timer = timer_factory->createTimer();
+
+       switch (e) {
+       case POWERUP:
+       case INITIALIZE:
+               XPTPD_INFO("Received POWERUP/INITIALIZE event");
+               {
+                       unsigned long long interval1;
+                       unsigned long long interval3;
+                       unsigned long long interval4;
+                       Event e1 = NULL_EVENT;
+                       Event e3 = NULL_EVENT;
+                       Event e4 = NULL_EVENT;
+
+                       if (forceSlave) {
+                               port_state = PTP_SLAVE;
+                               e1 = PDELAY_INTERVAL_TIMEOUT_EXPIRES;
+                               interval1 =
+                                   (unsigned long
+                                    long)(pow((double)2,
+                                              getPDelayInterval()) *
+                                          1000000000.0);
+                       } else {
+                               port_state = PTP_LISTENING;
+                               e1 = PDELAY_INTERVAL_TIMEOUT_EXPIRES;
+                               e3 = SYNC_RECEIPT_TIMEOUT_EXPIRES;
+                               e4 = ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES;
+                               interval1 =
+                                   (unsigned long
+                                    long)(pow((double)2,
+                                              getPDelayInterval()) *
+                                          1000000000.0);
+                               interval3 =
+                                   (unsigned long
+                                    long)(SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
+                                          pow((double)2,
+                                              getSyncInterval()) *
+                                          1000000000.0);
+                               interval4 =
+                                   (unsigned long
+                                    long)(ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER *
+                                          pow((double)2,
+                                              getAnnounceInterval()) *
+                                          1000000000.0);
+                       }
+
+                       fprintf(stderr, "Starting port thread\n");
+                       port_ready_condition->wait_prelock();
+                       listening_thread = thread_factory->createThread();
+                       if (!listening_thread->start
+                           (openPortWrapper, (void *)this)) {
+                               XPTPD_ERROR("Error creating port thread\n");
+                               return;
+                       }
+                       port_ready_condition->wait();
+
+                       if (e1 != NULL_EVENT)
+                               clock->addEventTimer(this, e1, interval1);
+                       if (e3 != NULL_EVENT)
+                               clock->addEventTimer(this, e3, interval3);
+                       if (e4 != NULL_EVENT)
+                               clock->addEventTimer(this, e4, interval4);
+               }
+               break;
+       case STATE_CHANGE_EVENT:
+               if (!forceSlave) {
+                       int number_ports, j;
+                       PTPMessageAnnounce *EBest = NULL;
+                       PortIdentity EBestPortIdentity;
+
+                       IEEE1588Port **ports;
+                       clock->getPortList(number_ports, ports);
+                       // If ANY ports are in PTP_INTIALIZING state, STATE_CHANGE_EVENT cannot be processed
+#if 0
+                       for (int i = 0; i < number_ports; ++i) {
+                               if (ports[i]->port_state == PTP_INITIALIZING) {
+                                       break;
+                               }
+                       }
+#endif
+                       //fprintf( stderr, "State Change Event\n" );
+
+                       // Find EBest for all ports
+                       j = 0;
+                       for (int i = 0; i < number_ports; ++i) {
+                               while (ports[j] == NULL)
+                                       ++j;
+                               if (ports[j]->port_state == PTP_DISABLED
+                                   || ports[j]->port_state == PTP_FAULTY) {
+                                       continue;
+                               }
+                               if (EBest == NULL) {
+                                       EBest = ports[j]->calculateERBest();
+                               } else {
+                                       if (ports[j]->calculateERBest()->isBetterThan(EBest)) {
+                                               EBest = ports[j]->calculateERBest();
+                                       }
+                               }
+                       }
+
+                       // Check if we've changed
+                       EBest->getPortIdentity( &EBestPortIdentity );
+                       if( EBestPortIdentity.getClockIdentity() != clock->getLastEBestIdentity() ) {
+                               fprintf( stderr, "Changed master!\n" );
+                               changed_master = true;
+                       } else {
+                               changed_master = false;
+                       }
+
+                       j = 0;
+                       for (int i = 0; i < number_ports; ++i) {
+                               while (ports[j] == NULL)
+                                       ++j;
+                               if (ports[j]->port_state == PTP_DISABLED
+                                   || ports[j]->port_state == PTP_FAULTY) {
+                                       continue;
+                               }
+                               if (clock->isBetterThan(EBest)) {
+                                       // We are the GrandMaster, all ports are master
+                                       fprintf(stderr, "\n");
+                                       EBest = NULL;   // EBest == NULL : we were grandmaster
+                                       ports[j]->recommendState(PTP_MASTER,
+                                                                changed_master);
+                               } else {
+                                       if (EBest == calculateERBest()) {
+                                               // The "best" sync was recieved on this port
+                                               ports[j]->recommendState
+                                                   (PTP_SLAVE, changed_master);
+                                       } else {
+                                               // Otherwise we are the master because we have sync'd to a better clock 
+                                               ports[j]->recommendState
+                                                   (PTP_MASTER,
+                                                    changed_master);
+                                       }
+                               }
+                       }
+                       clock->setLastEBestIdentity( EBestPortIdentity.getClockIdentity() );
+               }
+               break;
+       case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
+       case SYNC_RECEIPT_TIMEOUT_EXPIRES:
+               {
+                       if (forceSlave) {
+                               break;
+                       }
+                       if (port_state == PTP_LISTENING
+                           || port_state == PTP_UNCALIBRATED
+                           || port_state == PTP_SLAVE
+                           || port_state == PTP_PRE_MASTER) {
+                               fprintf(stderr,
+                                       "***Sync Timeout Expired - Becoming Master: %d\n",
+                                       e);
+                               port_state = PTP_MASTER;
+                               Timestamp system_time;
+                               Timestamp device_time;
+                               int64_t local_system_offset;
+
+#if 0
+                               Timestamp crstamp_device_time;
+                               int64_t external_local_offset;
+                               int32_t external_local_freq_offset;
+#endif
+                               uint32_t local_clock, nominal_clock_rate;
+
+                               getDeviceTime(system_time, device_time,
+                                             local_clock, nominal_clock_rate);
+
+                               local_system_offset =
+                                   TIMESTAMP_TO_NS(system_time) -
+                                   TIMESTAMP_TO_NS(device_time);
+#if 0
+                               local_system_offset = device_time.nanoseconds +
+                                   (((unsigned long long)device_time.seconds_ms
+                                     << sizeof(device_time.seconds_ls) * 8) +
+                                    device_time.seconds_ls) * 1000000000LL;
+                               local_system_offset -=
+                                   system_time.nanoseconds +
+                                   (((unsigned long long)system_time.seconds_ms
+                                     << sizeof(system_time.seconds_ls) * 8) +
+                                    system_time.seconds_ls) * 1000000000LL;
+#endif
+
+                               (void)
+                                   calcLocalSystemClockRateDifference
+                                   (local_system_offset, system_time);
+
+                               //getExternalClockRate( crstamp_device_time, external_local_offset, external_local_freq_offset );
+
+#if 0
+                               clock->setMasterOffset(0, device_time, 0,
+                                                      local_system_offset,
+                                                      system_time,
+                                                      local_system_freq_offset,
+                                                      nominal_clock_rate,
+                                                      local_clock);
+#endif
+                               if (this->doSyntonization()) {
+                                       this->adjustClockRate(0, local_clock,
+                                                             device_time, 0,
+                                                             false);
+                               }
+                               // "Expire" all previously received announce messages on this port
+                               while (!qualified_announce.empty()) {
+                                       delete qualified_announce.back();
+                                       qualified_announce.pop_back();
+                               }
+
+                               // Add timers for Announce and Sync, this is as close to immediately as we get
+                               clock->addEventTimer(this,
+                                                    ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES,
+                                                    8000000);
+                               clock->addEventTimer(this,
+                                                    SYNC_INTERVAL_TIMEOUT_EXPIRES,
+                                                    8000000);
+                       }
+                       break;
+       case PDELAY_INTERVAL_TIMEOUT_EXPIRES:
+                       XPTPD_INFO("PDELAY_INTERVAL_TIMEOUT_EXPIRES occured");
+                       {
+                               int ts_good;
+                               int iter = 2;
+                               Timestamp req_timestamp;
+                               long req = 1000;        // = 1 ms
+                               unsigned req_timestamp_counter_value;
+
+                               PTPMessagePathDelayReq *pdelay_req =
+                                   new PTPMessagePathDelayReq(this);
+                               PortIdentity dest_id;
+                               getPortIdentity(dest_id);
+                               pdelay_req->setPortIdentity(&dest_id);
+
+                               {
+                                       Timestamp pending =
+                                           PDELAY_PENDING_TIMESTAMP;
+                                       pdelay_req->setTimestamp(pending);
+                               }
+
+                               if (last_pdelay_req != NULL) {
+                                       delete last_pdelay_req;
+                               }
+                               setLastPDelayReq(pdelay_req);
+
+                               XPTPD_INFO("Preparing to send PDelay Request");
+                               getTxLock();
+                               pdelay_req->sendPort(this, NULL);
+                               XPTPD_INFO("Sent PDelay Request");
+
+                               ts_good =
+                                   getTxTimestamp(pdelay_req, req_timestamp,
+                                                  req_timestamp_counter_value,
+                                                  false);
+                               while (ts_good != 0 && iter-- != 0) {
+                                       timer->sleep(req);
+                                       if (ts_good != -72 && iter < 1)
+                                               fprintf(stderr,
+                                                       "Error (TX) timestamping PDelay request (Retrying-%d), error=%d\n",
+                                                       iter, ts_good);
+                                       ts_good =
+                                           getTxTimestamp(pdelay_req,
+                                                          req_timestamp,
+                                                          req_timestamp_counter_value,
+                                                          iter == 0);
+                                       req *= 2;
+                               }
+                               putTxLock();
+
+                               //fprintf( stderr, "Sequence = %hu\n", pdelay_req->getSequenceId() );
+
+                               if (pdelay_req == NULL) {
+                                       fprintf(stderr,
+                                               "PDelay request is NULL!\n");
+                                       abort();
+                               }
+
+                               if (ts_good == 0) {
+                                       pdelay_req->setTimestamp(req_timestamp);
+                               } else {
+                                       Timestamp failed = INVALID_TIMESTAMP;
+                                       pdelay_req->setTimestamp(failed);
+                               }
+
+                               if (ts_good != 0) {
+                                       char msg
+                                           [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
+                                       getExtendedError(msg);
+                                       fprintf(stderr,
+                                               "Error (TX) timestamping PDelay request, error=%d\n%s",
+                                               ts_good, msg);
+                                       //_exit(-1);
+                               }
+#ifdef DEBUG
+                               if (ts_good == 0) {
+                                       XPTPD_INFO
+                                           ("Successful PDelay Req timestamp, %u,%u",
+                                            req_timestamp.seconds_ls,
+                                            req_timestamp.nanoseconds);
+                               } else {
+                                       XPTPD_INFO
+                                           ("*** Unsuccessful PDelay Req timestamp");
+                               }
+#endif
+
+                       }
+                       clock->addEventTimer(this,
+                                            PDELAY_INTERVAL_TIMEOUT_EXPIRES,
+                                            (unsigned long
+                                             long)(pow((double)2,
+                                                       getPDelayInterval()) *
+                                                   1000000000.0));
+                       break;
+       case SYNC_INTERVAL_TIMEOUT_EXPIRES:
+                       XPTPD_INFO("SYNC_INTERVAL_TIMEOUT_EXPIRES occured");
+                       // Set offset from master to zero, update device vs system time offset
+                       Timestamp system_time;
+                       Timestamp device_time;
+                       int32_t local_system_freq_offset;
+                       int64_t local_system_offset;
+                       static bool adj_up = true;
+
+#if 0
+                       Timestamp crstamp_device_time;
+                       int64_t external_local_offset;
+                       int32_t external_local_freq_offset;
+#endif
+                       uint32_t local_clock, nominal_clock_rate;
+
+                       getDeviceTime(system_time, device_time, local_clock,
+                                     nominal_clock_rate);
+                       //fprintf( stderr, "Device Time = %llu,System Time = %llu\n", TIMESTAMP_TO_NS(device_time), TIMESTAMP_TO_NS(system_time));
+
+                       XPTPD_INFO
+                           ("port::processEvent(): System time: %u,%u Device Time: %u,%u",
+                            system_time.seconds_ls, system_time.nanoseconds,
+                            device_time.seconds_ls, device_time.nanoseconds);
+
+                       local_system_offset =
+                           TIMESTAMP_TO_NS(system_time) -
+                           TIMESTAMP_TO_NS(device_time);
+#if 0
+                       local_system_offset = device_time.nanoseconds +
+                           (((unsigned long long)device_time.seconds_ms <<
+                             sizeof(device_time.seconds_ls) * 8) +
+                            device_time.seconds_ls) * 1000000000LL;
+                       local_system_offset -=
+                           system_time.nanoseconds +
+                           (((unsigned long long)system_time.seconds_ms <<
+                             sizeof(system_time.seconds_ls) * 8) +
+                            system_time.seconds_ls) * 1000000000LL;
+#endif
+
+                       local_system_freq_offset =
+                           calcLocalSystemClockRateDifference
+                           (local_system_offset, system_time);
+
+                       //getExternalClockRate( crstamp_device_time, external_local_offset, external_local_freq_offset );
+
+                       clock->setMasterOffset(0, device_time, 0,
+                                              local_system_offset, system_time,
+                                              local_system_freq_offset,
+                                              nominal_clock_rate, local_clock);
+                       if (this->doSyntonization()) {
+                               this->adjustClockRate(0, local_clock,
+                                                     device_time, 0, false);
+                       }
+
+                       if (_hw_timestamper != NULL
+                           && _initial_clock_offset != 0) {
+                               if (adj_up) {
+                                       _hw_timestamper->HWTimestamper_adjclockrate2
+                                           (_current_clock_offset += 2500);
+                               } else {
+                                       _hw_timestamper->HWTimestamper_adjclockrate2
+                                           (_current_clock_offset -= 2500);
+                               }
+                               XPTPD_INFO("Adjust clock rate current: %d",
+                                          _current_clock_offset);
+                       }
+                       if (_current_clock_offset >
+                           _initial_clock_offset + 5000000
+                           || _current_clock_offset <
+                           _initial_clock_offset - 5000000) {
+                               adj_up = !adj_up;
+                       }
+                       // Send a sync message and then a followup to broadcast
+                       if (asCapable) {
+                               PTPMessageSync *sync = new PTPMessageSync(this);
+                               PortIdentity dest_id;
+                               getPortIdentity(dest_id);
+                               sync->setPortIdentity(&dest_id);
+                               getTxLock();
+                               sync->sendPort(this, NULL);
+                               XPTPD_INFO("Sent SYNC message");
+
+                               int ts_good;
+                               int iter = 2;
+                               Timestamp sync_timestamp;
+                               unsigned sync_timestamp_counter_value;
+                               long req = 1000;        // = 1 ms
+                               XPTPD_INFO("Start TS Read");
+                               ts_good =
+                                   getTxTimestamp(sync, sync_timestamp,
+                                                  sync_timestamp_counter_value,
+                                                  false);
+                               XPTPD_INFO("Done TS Read");
+                               while (ts_good != 0 && iter-- != 0) {
+                                       timer->sleep(req);
+                                       if (ts_good != -72 && iter < 1)
+                                               fprintf(stderr,
+                                                       "Error (TX) timestamping Sync (Retrying), error=%d\n",
+                                                       ts_good);
+                                       ts_good =
+                                           getTxTimestamp(sync, sync_timestamp,
+                                                          sync_timestamp_counter_value,
+                                                          iter == 0);
+                                       req *= 2;
+                               }
+                               putTxLock();
+
+                               if (ts_good != 0) {
+                                       char msg
+                                           [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
+                                       getExtendedError(msg);
+                                       fprintf(stderr,
+                                               "Error (TX) timestamping Sync, error=%d\n%s",
+                                               ts_good, msg);
+                                       //_exit(-1);
+                               }
+
+                               if (ts_good == 0) {
+                                       XPTPD_INFO("Successful Sync timestamp");
+                                       XPTPD_INFO("Seconds: %u",
+                                                  sync_timestamp.seconds_ls);
+                                       XPTPD_INFO("Nanoseconds: %u",
+                                                  sync_timestamp.nanoseconds);
+                               } else {
+                                       XPTPD_INFO
+                                           ("*** Unsuccessful Sync timestamp");
+                               }
+
+                               PTPMessageFollowUp *follow_up;
+                               if (ts_good == 0) {
+                                       follow_up =
+                                           new PTPMessageFollowUp(this);
+                                       PortIdentity dest_id;
+                                       getPortIdentity(dest_id);
+                                       follow_up->setPortIdentity(&dest_id);
+                                       follow_up->setSequenceId(sync->getSequenceId());
+                                       follow_up->setPreciseOriginTimestamp(sync_timestamp);
+                                       follow_up->sendPort(this, NULL);
+                                       delete follow_up;
+                               } else {
+                                       // Re-add the timer, since we failed re-send sooner?
+                                       //clock->addEventTimer( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, (unsigned long long) (pow(2,getSyncInterval())*1000000000.0));
+                               }
+                               delete sync;
+                       }
+               }
+               clock->addEventTimer(this, SYNC_INTERVAL_TIMEOUT_EXPIRES,
+                                    (unsigned long
+                                     long)(pow((double)2,
+                                               getSyncInterval()) *
+                                           1000000000.0));
+               break;
+       case ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES:
+               if (asCapable) {
+                       // Send an announce message
+                       PTPMessageAnnounce *annc = new PTPMessageAnnounce(this);
+                       PortIdentity dest_id;
+                       PortIdentity gmId;
+                       ClockIdentity clock_id = clock->getClockIdentity();
+                       gmId.setClockIdentity(clock_id);
+                       clock->setGrandmasterPortIdentity(gmId);
+                       getPortIdentity(dest_id);
+                       annc->setPortIdentity(&dest_id);
+                       annc->sendPort(this, NULL);
+                       delete annc;
+               }
+               clock->addEventTimer(this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES,
+                                    (unsigned)(pow
+                                               ((double)2,
+                                                getAnnounceInterval()) *
+                                               1000000000.0));
+               break;
+       case FAULT_DETECTED:
+               XPTPD_INFO("Received FAULT_DETECTED event");
+               break;
+       case PDELAY_DEFERRED_PROCESSING:
+               pdelay_rx_lock->lock();
+               if (last_pdelay_resp_fwup == NULL) {
+                       fprintf(stderr, "PDelay Response Followup is NULL!\n");
+                       abort();
+               }
+               last_pdelay_resp_fwup->processMessage(this);
+               if (last_pdelay_resp_fwup->garbage()) {
+                       delete last_pdelay_resp_fwup;
+                       this->setLastPDelayRespFollowUp(NULL);
+               }
+               pdelay_rx_lock->unlock();
+               break;
+       case PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES:
+               setAsCapable(false);
+               break;
+       default:
+               XPTPD_INFO
+                   ("Unhandled event type in IEEE1588Port::processEvent(), %d",
+                    e);
+               break;
+       }
+       return;
+}
+
+PTPMessageAnnounce *IEEE1588Port::calculateERBest(void)
+{
+       if (qualified_announce.empty()) {
+               return NULL;
+       }
+       if (qualified_announce.size() == 1) {
+               return qualified_announce.front();
+       }
+
+       AnnounceList_t::iterator iter_l = qualified_announce.begin();
+       PTPMessageAnnounce *best = *iter_l;
+       ++iter_l;
+       while (iter_l != qualified_announce.end()) {
+               if ((*iter_l)->isBetterThan(best))
+                       best = *iter_l;
+               iter_l = qualified_announce.erase(iter_l);
+       }
+
+       return best;
+}
+
+void IEEE1588Port::recoverPort(void)
+{
+       return;
+}
+
+IEEE1588Clock *IEEE1588Port::getClock(void)
+{
+       return clock;
+}
+
+void IEEE1588Port::getDeviceTime(Timestamp & system_time,
+                                Timestamp & device_time,
+                                uint32_t & local_clock,
+                                uint32_t & nominal_clock_rate)
+{
+       if (_hw_timestamper) {
+               _hw_timestamper->HWTimestamper_gettime(&system_time,
+                                                      &device_time,
+                                                      &local_clock,
+                                                      &nominal_clock_rate);
+       } else {
+               device_time = system_time = clock->getSystemTime();
+               local_clock = nominal_clock_rate = 0;
+       }
+       return;
+}
+
+void IEEE1588Port::recommendState(PortState state, bool changed_master)
+{
+       switch (state) {
+       case PTP_MASTER:
+               if (port_state != PTP_MASTER) {
+                       port_state = PTP_MASTER;
+                       // Start announce receipt timeout timer
+                       // Start sync receipt timeout timer
+                       clock->addEventTimer(this,
+                                            ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES,
+                                            8000000);
+                       clock->addEventTimer(this,
+                                            SYNC_INTERVAL_TIMEOUT_EXPIRES,
+                                            8000000);
+                       fprintf(stderr, "Switching to Master\n");
+               } else {
+                       port_state = PTP_MASTER;
+               }
+               break;
+       case PTP_SLAVE:
+               // Stop sending announce messages
+               // Stop sending sync messages
+               if (port_state != PTP_SLAVE) {
+                       port_state = PTP_SLAVE;
+                       clock->deleteEventTimer(this,
+                                               ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES);
+                       clock->deleteEventTimer(this,
+                                               SYNC_INTERVAL_TIMEOUT_EXPIRES);
+                       clock->addEventTimer(this, SYNC_RECEIPT_TIMEOUT_EXPIRES,
+                                            (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
+                                             (unsigned long
+                                              long)(pow((double)2,
+                                                        getSyncInterval()) *
+                                                    1000000000.0)));
+                       clock->addEventTimer(this,
+                                            ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
+                                            (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER
+                                             *
+                                             (unsigned long
+                                              long)(pow((double)2,
+                                                        getAnnounceInterval())
+                                                    * 1000000000.0)));
+                       fprintf(stderr, "Switching to Slave\n");
+               } else {
+                       if (changed_master) {
+                               port_state = PTP_SLAVE;
+                       } else {
+                               port_state = PTP_SLAVE;
+                       }
+               }
+               break;
+       default:
+               XPTPD_INFO
+                   ("Invalid state change requested by call to 1588Port::recommendState()");
+               break;
+       }
+       return;
+}
+
+#define FIR_SAMPLE_TIME 1      // Seconds
+
+int IEEE1588Port::calcMasterLocalClockRateDifference(signed long long offset,
+                                                    Timestamp sync_time)
+{
+       long long inter_sync_time;
+       signed long long offset_delta;
+       int ppt_offset;
+
+       XPTPD_INFO("Calculated master to local PTP clock rate difference");
+
+       if (!_master_local_freq_offset_init) {
+               _prev_sync_time = sync_time;
+               _prev_master_local_offset = offset;
+
+               _master_local_freq_offset_init = true;
+
+               return 0;
+       }
+
+       inter_sync_time =
+           TIMESTAMP_TO_NS(sync_time) - TIMESTAMP_TO_NS(_prev_sync_time);
+       offset_delta = offset - _prev_master_local_offset;
+
+       if (rate_offset_array == NULL) {
+               rate_offset_array_size = 4;
+               ++rate_offset_array_size;
+               rate_offset_array = new int32_t[rate_offset_array_size];
+               rate_offset_count = 0;
+               rate_offset_index = 0;
+       }
+       //fprintf( stderr, "Calculated master to local PTP clock rate difference, offset=%lld,sync_time = %lld\n", offset_delta, inter_sync_time );
+
+       if (inter_sync_time != 0) {
+               //fprintf( stderr, "Offset Delta: %lld, IST: %llu(%llu,%llu)\n", offset_delta, inter_sync_time, TIMESTAMP_TO_NS(sync_time),TIMESTAMP_TO_NS(_prev_sync_time) );
+               ppt_offset =
+                   int (((offset_delta * 1000000000000LL) / inter_sync_time));
+       } else {
+               ppt_offset = 0;
+       }
+
+       _prev_sync_time = sync_time;
+       _prev_master_local_offset = offset;
+
+       return ppt_offset;
+}
+
+int IEEE1588Port::calcLocalSystemClockRateDifference(signed long long offset,
+                                                    Timestamp system_time)
+{
+       unsigned long long inter_system_time;
+       signed long long offset_delta;
+       int ppt_offset;
+
+       XPTPD_INFO("Calculated local to system clock rate difference");
+
+       if (!_local_system_freq_offset_init) {
+               _prev_system_time = system_time;
+               _prev_local_system_offset = offset;
+
+               _local_system_freq_offset_init = true;
+
+               return 0;
+       }
+
+       inter_system_time =
+           TIMESTAMP_TO_NS(system_time) - TIMESTAMP_TO_NS(_prev_system_time);
+       offset_delta = offset - _prev_local_system_offset;
+
+       if (inter_system_time != 0) {
+               ppt_offset =
+                   int (((offset_delta * 1000000000000LL) /
+                         (int64_t) inter_system_time));
+               XPTPD_INFO
+                   ("IEEE1588Port::calcLocalSystemClockRateDifference() offset delta: %Ld",
+                    offset_delta);
+       } else {
+               ppt_offset = 0;
+               offset_delta = 0;
+       }
+
+       if (inter_system_time != 0) {
+               XPTPD_INFO("Calculation Step: %Ld",
+                          ((offset_delta * 1000000000000LL) /
+                           (int64_t) inter_system_time));
+       }
+       XPTPD_INFO
+           ("IEEE1588Port::calcLocalSystemClockRateDifference() offset: %Ld",
+            offset);
+       XPTPD_INFO
+           ("IEEE1588Port::calcLocalSystemClockRateDifference() prev offset: %ld",
+            _prev_local_system_offset);
+       XPTPD_INFO
+           ("IEEE1588Port::calcLocalSystemClockRateDifference() system time: %u,%u",
+            system_time.seconds_ls, system_time.nanoseconds);
+       XPTPD_INFO
+           ("IEEE1588Port::calcLocalSystemClockRateDifference() prev system time: %u,%u",
+            _prev_system_time.seconds_ls, _prev_system_time.nanoseconds);
+       XPTPD_INFO
+           ("IEEE1588Port::calcLocalSystemClockRateDifference() inter-system time: %Lu",
+            inter_system_time);
+       XPTPD_INFO("IEEE1588Port::calcLocalSystemClockRateDifference() PPT: %d",
+                  ppt_offset);
+
+       _prev_system_time = system_time;
+       _prev_local_system_offset = offset;
+
+       return ppt_offset;
+}
+
+void IEEE1588Port::mapSocketAddr(PortIdentity * destIdentity,
+                                LinkLayerAddress * remote)
+{
+       *remote = identity_map[*destIdentity];
+       return;
+}
+
+void IEEE1588Port::addSockAddrMap(PortIdentity * destIdentity,
+                                 LinkLayerAddress * remote)
+{
+       identity_map[*destIdentity] = *remote;
+       return;
+}
+
+int IEEE1588Port::getTxTimestamp(PTPMessageCommon * msg, Timestamp & timestamp,
+                                unsigned &counter_value, bool last)
+{
+       PortIdentity identity;
+       msg->getPortIdentity(&identity);
+       return getTxTimestamp(&identity, msg->getSequenceId(), timestamp,
+                             counter_value, last);
+}
+
+int IEEE1588Port::getRxTimestamp(PTPMessageCommon * msg, Timestamp & timestamp,
+                                unsigned &counter_value, bool last)
+{
+       PortIdentity identity;
+       msg->getPortIdentity(&identity);
+       return getRxTimestamp(&identity, msg->getSequenceId(), timestamp,
+                             counter_value, last);
+}
+
+int IEEE1588Port::getTxTimestamp(PortIdentity * sourcePortIdentity,
+                                uint16_t sequenceId, Timestamp & timestamp,
+                                unsigned &counter_value, bool last)
+{
+       if (_hw_timestamper) {
+               return
+                   _hw_timestamper->HWTimestamper_txtimestamp
+                   (sourcePortIdentity, sequenceId, timestamp, counter_value,
+                    last);
+       }
+       timestamp = clock->getSystemTime();
+       return true;
+}
+
+int IEEE1588Port::getRxTimestamp(PortIdentity * sourcePortIdentity,
+                                uint16_t sequenceId, Timestamp & timestamp,
+                                unsigned &counter_value, bool last)
+{
+       if (_hw_timestamper) {
+               return
+                   _hw_timestamper->HWTimestamper_rxtimestamp
+                   (sourcePortIdentity, sequenceId, timestamp, counter_value,
+                    last);
+       }
+       timestamp = clock->getSystemTime();
+       return true;
+}
diff --git a/daemons/gptp/common/ptp_message.cpp b/daemons/gptp/common/ptp_message.cpp
new file mode 100644 (file)
index 0000000..86ee0ce
--- /dev/null
@@ -0,0 +1,1718 @@
+/******************************************************************************
+
+  Copyright (c) 2009-2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#include <ieee1588.hpp>
+#include <avbts_clock.hpp>
+#include <avbts_message.hpp>
+#include <avbts_port.hpp>
+#include <avbts_ostimer.hpp>
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <time.h>
+
+PTPMessageCommon::PTPMessageCommon(IEEE1588Port * port)
+{
+       // Fill in fields using port/clock dataset as a template
+       versionPTP = GPTP_VERSION;
+       versionNetwork = PTP_NETWORK_VERSION;
+       domainNumber = port->getClock()->getDomain();
+       // Set flags as necessary
+       memset(flags, 0, PTP_FLAGS_LENGTH);
+       correctionField = 0;
+       _gc = false;
+       sourcePortIdentity = new PortIdentity();
+
+       return;
+}
+
+// Determine whether the message was sent by given communication technology, uuid, and port id fields
+bool PTPMessageCommon::isSenderEqual(PortIdentity portIdentity)
+{
+       return portIdentity == *sourcePortIdentity;
+}
+
+PTPMessageCommon *buildPTPMessage(char *buf, int size,
+                                 LinkLayerAddress * remote,
+                                 IEEE1588Port * port)
+{
+       OSTimer *timer = port->getTimerFactory()->createTimer();
+       PTPMessageCommon *msg = NULL;
+       MessageType messageType;
+       unsigned char tspec_msg_t = 0;
+
+       uint16_t sequenceId;
+       PortIdentity *sourcePortIdentity;
+       Timestamp timestamp(0, 0, 0);
+       unsigned counter_value = 0;
+
+#if PTP_DEBUG
+       {
+               int i;
+               XPTPD_INFO("Packet Dump:\n");
+               for (i = 0; i < size; ++i) {
+                       fprintf(stderr, "%hhx\t", buf[i]);
+                       if (i % 8 == 7)
+                               fprintf(stderr, "\n");
+               }
+               if (i % 8 != 0)
+                       fprintf(stderr, "\n");
+       }
+#endif
+
+       memcpy(&tspec_msg_t,
+              buf + PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(PTP_COMMON_HDR_OFFSET),
+              sizeof(tspec_msg_t));
+       messageType = (MessageType) (tspec_msg_t & 0xF);
+
+       sourcePortIdentity = new PortIdentity((uint8_t *) (buf +
+                                     PTP_COMMON_HDR_SOURCE_CLOCK_ID
+                                     (PTP_COMMON_HDR_OFFSET)),
+                        (uint16_t *) (buf +
+                                      PTP_COMMON_HDR_SOURCE_PORT_ID
+                                      (PTP_COMMON_HDR_OFFSET)));
+
+       memcpy(&(sequenceId),
+              buf + PTP_COMMON_HDR_SEQUENCE_ID(PTP_COMMON_HDR_OFFSET),
+              sizeof(sequenceId));
+       sequenceId = PLAT_ntohs(sequenceId);
+
+       //fprintf( stderr, "Captured Sequence Id: %u\n", sequenceId );
+       XPTPD_INFO("Captured Sequence Id: %u", sequenceId);
+
+       if (!(messageType >> 3)) {
+               int iter = 2;
+               long req = 1000;        // = 1 ms
+               int ts_good =
+                   port->getRxTimestamp(sourcePortIdentity, sequenceId,
+                                        timestamp, counter_value, false);
+               while (ts_good != 0 && iter-- != 0) {
+                       // Waits at least 1 time slice regardless of size of 'req'
+                       timer->sleep(req);
+                       if (ts_good != 72)
+                               fprintf(stderr,
+                                       "Error (RX) timestamping RX event packet (Retrying), error=%d\n",
+                                       ts_good);
+                       ts_good =
+                           port->getRxTimestamp(sourcePortIdentity, sequenceId,
+                                                timestamp, counter_value,
+                                                iter == 0);
+                       req *= 2;
+               }
+               if (ts_good != 0) {
+                       char msg[HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
+                       port->getExtendedError(msg);
+                       XPTPD_ERROR
+                           ("*** Received an event packet but cannot retrieve timestamp, discarding. messageType=%u,error=%d\n%s",
+                            messageType, ts_good, msg);
+                       //_exit(-1);
+                       return NULL;
+               }
+
+               else {
+                       XPTPD_INFO("Timestamping event packet");
+               }
+
+       }
+
+       switch (messageType) {
+       case SYNC_MESSAGE:
+
+               //fprintf( stderr, "*** Received Sync message\n" );
+               //printf( "Sync RX timestamp = %hu,%u,%u\n", timestamp.seconds_ms, timestamp.seconds_ls, timestamp.nanoseconds );
+               XPTPD_INFO("*** Received Sync message");
+
+               // Be sure buffer is the correction size
+               if (size < PTP_COMMON_HDR_LENGTH + PTP_SYNC_LENGTH) {
+                       goto done;
+               }
+               {
+                       PTPMessageSync *sync_msg = new PTPMessageSync();
+                       sync_msg->messageType = messageType;
+                       // Copy in v2 sync specific fields
+                       memcpy(&(sync_msg->originTimestamp.seconds_ms),
+                              buf + PTP_SYNC_SEC_MS(PTP_SYNC_OFFSET),
+                              sizeof(sync_msg->originTimestamp.seconds_ms));
+                       memcpy(&(sync_msg->originTimestamp.seconds_ls),
+                              buf + PTP_SYNC_SEC_LS(PTP_SYNC_OFFSET),
+                              sizeof(sync_msg->originTimestamp.seconds_ls));
+                       memcpy(&(sync_msg->originTimestamp.nanoseconds),
+                              buf + PTP_SYNC_NSEC(PTP_SYNC_OFFSET),
+                              sizeof(sync_msg->originTimestamp.nanoseconds));
+                       msg = sync_msg;
+               }
+               break;
+       case FOLLOWUP_MESSAGE:
+
+               XPTPD_INFO("*** Received Follow Up message");
+
+               // Be sure buffer is the correction size
+               if (size < PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH) {
+                       goto done;
+               }
+               {
+                       PTPMessageFollowUp *followup_msg =
+                           new PTPMessageFollowUp();
+                       followup_msg->messageType = messageType;
+                       // Copy in v2 sync specific fields
+                       memcpy(&
+                              (followup_msg->
+                               preciseOriginTimestamp.seconds_ms),
+                              buf + PTP_FOLLOWUP_SEC_MS(PTP_FOLLOWUP_OFFSET),
+                              sizeof(followup_msg->
+                                     preciseOriginTimestamp.seconds_ms));
+                       memcpy(&
+                              (followup_msg->
+                               preciseOriginTimestamp.seconds_ls),
+                              buf + PTP_FOLLOWUP_SEC_LS(PTP_FOLLOWUP_OFFSET),
+                              sizeof(followup_msg->
+                                     preciseOriginTimestamp.seconds_ls));
+                       memcpy(&
+                              (followup_msg->
+                               preciseOriginTimestamp.nanoseconds),
+                              buf + PTP_FOLLOWUP_NSEC(PTP_FOLLOWUP_OFFSET),
+                              sizeof(followup_msg->
+                                     preciseOriginTimestamp.nanoseconds));
+
+                       followup_msg->preciseOriginTimestamp.seconds_ms =
+                           PLAT_ntohs(followup_msg->
+                                      preciseOriginTimestamp.seconds_ms);
+                       followup_msg->preciseOriginTimestamp.seconds_ls =
+                           PLAT_ntohl(followup_msg->
+                                      preciseOriginTimestamp.seconds_ls);
+                       followup_msg->preciseOriginTimestamp.nanoseconds =
+                           PLAT_ntohl(followup_msg->
+                                      preciseOriginTimestamp.nanoseconds);
+
+                       msg = followup_msg;
+               }
+               break;
+       case PATH_DELAY_REQ_MESSAGE:
+
+               XPTPD_INFO("*** Received PDelay Request message");
+
+               // Be sure buffer is the correction size
+               if (size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_REQ_LENGTH
+                   && /* For Broadcom compatibility */ size != 46) {
+                       goto done;
+               }
+               {
+                       PTPMessagePathDelayReq *pdelay_req_msg =
+                           new PTPMessagePathDelayReq();
+                       pdelay_req_msg->messageType = messageType;
+
+#if 0
+                       // The origin timestamp for PDelay Request packets has been eliminated since it is unused
+                       // Copy in v2 PDelay Request specific fields
+                       memcpy(&(pdelay_req_msg->originTimestamp.seconds_ms),
+                              buf +
+                              PTP_PDELAY_REQ_SEC_MS(PTP_PDELAY_REQ_OFFSET),
+                              sizeof(pdelay_req_msg->
+                                     originTimestamp.seconds_ms));
+                       memcpy(&(pdelay_req_msg->originTimestamp.seconds_ls),
+                              buf +
+                              PTP_PDELAY_REQ_SEC_LS(PTP_PDELAY_REQ_OFFSET),
+                              sizeof(pdelay_req_msg->
+                                     originTimestamp.seconds_ls));
+                       memcpy(&(pdelay_req_msg->originTimestamp.nanoseconds),
+                              buf + PTP_PDELAY_REQ_NSEC(PTP_PDELAY_REQ_OFFSET),
+                              sizeof(pdelay_req_msg->
+                                     originTimestamp.nanoseconds));
+
+                       pdelay_req_msg->originTimestamp.seconds_ms =
+                           PLAT_ntohs(pdelay_req_msg->
+                                      originTimestamp.seconds_ms);
+                       pdelay_req_msg->originTimestamp.seconds_ls =
+                           PLAT_ntohl(pdelay_req_msg->
+                                      originTimestamp.seconds_ls);
+                       pdelay_req_msg->originTimestamp.nanoseconds =
+                           PLAT_ntohl(pdelay_req_msg->
+                                      originTimestamp.nanoseconds);
+#endif
+
+                       msg = pdelay_req_msg;
+               }
+               break;
+       case PATH_DELAY_RESP_MESSAGE:
+
+               XPTPD_INFO("*** Received PDelay Response message, %u, %u, %u",
+                          timestamp.seconds_ls, timestamp.nanoseconds,
+                          sequenceId);
+
+               // Be sure buffer is the correction size
+               if (size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_RESP_LENGTH) {
+                       goto done;
+               }
+               {
+                       PTPMessagePathDelayResp *pdelay_resp_msg =
+                           new PTPMessagePathDelayResp();
+                       pdelay_resp_msg->messageType = messageType;
+                       // Copy in v2 PDelay Response specific fields
+                       pdelay_resp_msg->requestingPortIdentity =
+                           new PortIdentity((uint8_t *) buf +
+                                            PTP_PDELAY_RESP_REQ_CLOCK_ID
+                                            (PTP_PDELAY_RESP_OFFSET),
+                                            (uint16_t *) (buf +
+                                                          PTP_PDELAY_RESP_REQ_PORT_ID
+                                                          (PTP_PDELAY_RESP_OFFSET)));
+
+#ifdef DEBUG
+                       for (int n = 0; n < PTP_CLOCK_IDENTITY_LENGTH; ++n) {   // MMM
+                               fprintf(stderr, "%c",
+                                       pdelay_resp_msg->
+                                       requestingPortIdentity.clockIdentity
+                                       [n]);
+                       }
+#endif
+
+                       memcpy(&
+                              (pdelay_resp_msg->
+                               requestReceiptTimestamp.seconds_ms),
+                              buf +
+                              PTP_PDELAY_RESP_SEC_MS(PTP_PDELAY_RESP_OFFSET),
+                              sizeof(pdelay_resp_msg->
+                                     requestReceiptTimestamp.seconds_ms));
+                       memcpy(&
+                              (pdelay_resp_msg->
+                               requestReceiptTimestamp.seconds_ls),
+                              buf +
+                              PTP_PDELAY_RESP_SEC_LS(PTP_PDELAY_RESP_OFFSET),
+                              sizeof(pdelay_resp_msg->
+                                     requestReceiptTimestamp.seconds_ls));
+                       memcpy(&
+                              (pdelay_resp_msg->
+                               requestReceiptTimestamp.nanoseconds),
+                              buf +
+                              PTP_PDELAY_RESP_NSEC(PTP_PDELAY_RESP_OFFSET),
+                              sizeof(pdelay_resp_msg->
+                                     requestReceiptTimestamp.nanoseconds));
+
+                       pdelay_resp_msg->requestReceiptTimestamp.seconds_ms =
+                           PLAT_ntohs(pdelay_resp_msg->requestReceiptTimestamp.seconds_ms);
+                       pdelay_resp_msg->requestReceiptTimestamp.seconds_ls =
+                           PLAT_ntohl(pdelay_resp_msg->requestReceiptTimestamp.seconds_ls);
+                       pdelay_resp_msg->requestReceiptTimestamp.nanoseconds =
+                           PLAT_ntohl(pdelay_resp_msg->requestReceiptTimestamp.nanoseconds);
+
+                       msg = pdelay_resp_msg;
+               }
+               break;
+       case PATH_DELAY_FOLLOWUP_MESSAGE:
+
+               XPTPD_INFO("*** Received PDelay Response FollowUp message");
+
+               // Be sure buffer is the correction size
+//     if( size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_FOLLOWUP_LENGTH ) {
+//       goto done;
+//     }
+               {
+                       PTPMessagePathDelayRespFollowUp *pdelay_resp_fwup_msg =
+                           new PTPMessagePathDelayRespFollowUp();
+                       pdelay_resp_fwup_msg->messageType = messageType;
+                       // Copy in v2 PDelay Response specific fields
+                       pdelay_resp_fwup_msg->requestingPortIdentity =
+                           new PortIdentity((uint8_t *) buf +
+                                            PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID
+                                            (PTP_PDELAY_RESP_OFFSET),
+                                            (uint16_t *) (buf +
+                                                          PTP_PDELAY_FOLLOWUP_REQ_PORT_ID
+                                                          (PTP_PDELAY_FOLLOWUP_OFFSET)));
+
+                       memcpy(&
+                              (pdelay_resp_fwup_msg->
+                               responseOriginTimestamp.seconds_ms),
+                              buf +
+                              PTP_PDELAY_FOLLOWUP_SEC_MS
+                              (PTP_PDELAY_FOLLOWUP_OFFSET),
+                              sizeof
+                              (pdelay_resp_fwup_msg->responseOriginTimestamp.
+                               seconds_ms));
+                       memcpy(&
+                              (pdelay_resp_fwup_msg->
+                               responseOriginTimestamp.seconds_ls),
+                              buf +
+                              PTP_PDELAY_FOLLOWUP_SEC_LS
+                              (PTP_PDELAY_FOLLOWUP_OFFSET),
+                              sizeof
+                              (pdelay_resp_fwup_msg->responseOriginTimestamp.
+                               seconds_ls));
+                       memcpy(&
+                              (pdelay_resp_fwup_msg->
+                               responseOriginTimestamp.nanoseconds),
+                              buf +
+                              PTP_PDELAY_FOLLOWUP_NSEC
+                              (PTP_PDELAY_FOLLOWUP_OFFSET),
+                              sizeof
+                              (pdelay_resp_fwup_msg->responseOriginTimestamp.
+                               nanoseconds));
+
+                       pdelay_resp_fwup_msg->
+                           responseOriginTimestamp.seconds_ms =
+                           PLAT_ntohs
+                           (pdelay_resp_fwup_msg->responseOriginTimestamp.
+                            seconds_ms);
+                       pdelay_resp_fwup_msg->
+                           responseOriginTimestamp.seconds_ls =
+                           PLAT_ntohl
+                           (pdelay_resp_fwup_msg->responseOriginTimestamp.
+                            seconds_ls);
+                       pdelay_resp_fwup_msg->
+                           responseOriginTimestamp.nanoseconds =
+                           PLAT_ntohl
+                           (pdelay_resp_fwup_msg->responseOriginTimestamp.
+                            nanoseconds);
+
+                       msg = pdelay_resp_fwup_msg;
+               }
+               break;
+       case ANNOUNCE_MESSAGE:
+               {
+                       PTPMessageAnnounce *annc = new PTPMessageAnnounce();
+                       annc->messageType = messageType;
+
+                       memcpy(&(annc->currentUtcOffset),
+                              buf +
+                              PTP_ANNOUNCE_CURRENT_UTC_OFFSET
+                              (PTP_ANNOUNCE_OFFSET),
+                              sizeof(annc->currentUtcOffset));
+                       annc->currentUtcOffset =
+                           PLAT_ntohs(annc->currentUtcOffset);
+                       memcpy(&(annc->grandmasterPriority1),
+                              buf +
+                              PTP_ANNOUNCE_GRANDMASTER_PRIORITY1
+                              (PTP_ANNOUNCE_OFFSET),
+                              sizeof(annc->grandmasterPriority1));
+                       memcpy(annc->clockQuality,
+                              buf +
+                              PTP_ANNOUNCE_GRANDMASTER_CLOCK_QUALITY
+                              (PTP_ANNOUNCE_OFFSET),
+                              sizeof(annc->clockQuality));
+                       annc->clockQuality->offsetScaledLogVariance =
+                           PLAT_ntohs(annc->
+                                      clockQuality->offsetScaledLogVariance);
+                       memcpy(&(annc->grandmasterPriority2),
+                              buf +
+                              PTP_ANNOUNCE_GRANDMASTER_PRIORITY2
+                              (PTP_ANNOUNCE_OFFSET),
+                              sizeof(annc->grandmasterPriority2));
+                       memcpy(&(annc->grandmasterIdentity),
+                              buf +
+                              PTP_ANNOUNCE_GRANDMASTER_IDENTITY
+                              (PTP_ANNOUNCE_OFFSET),
+                              PTP_CLOCK_IDENTITY_LENGTH);
+                       memcpy(&(annc->stepsRemoved),
+                              buf +
+                              PTP_ANNOUNCE_STEPS_REMOVED(PTP_ANNOUNCE_OFFSET),
+                              sizeof(annc->stepsRemoved));
+                       annc->stepsRemoved = PLAT_ntohs(annc->stepsRemoved);
+                       memcpy(&(annc->timeSource),
+                              buf +
+                              PTP_ANNOUNCE_TIME_SOURCE(PTP_ANNOUNCE_OFFSET),
+                              sizeof(annc->timeSource));
+
+                       msg = annc;
+               }
+               break;
+       default:
+
+               XPTPD_ERROR("Received unsupported message type, %d",
+                           (int)messageType);
+
+               goto done;
+       }
+
+       msg->_gc = false;
+
+       // Copy in common header fields
+       memcpy(&(msg->versionPTP),
+              buf + PTP_COMMON_HDR_PTP_VERSION(PTP_COMMON_HDR_OFFSET),
+              sizeof(msg->versionPTP));
+       memcpy(&(msg->messageLength),
+              buf + PTP_COMMON_HDR_MSG_LENGTH(PTP_COMMON_HDR_OFFSET),
+              sizeof(msg->messageLength));
+       msg->messageLength = PLAT_ntohs(msg->messageLength);
+       memcpy(&(msg->domainNumber),
+              buf + PTP_COMMON_HDR_DOMAIN_NUMBER(PTP_COMMON_HDR_OFFSET),
+              sizeof(msg->domainNumber));
+       memcpy(&(msg->flags), buf + PTP_COMMON_HDR_FLAGS(PTP_COMMON_HDR_OFFSET),
+              PTP_FLAGS_LENGTH);
+       memcpy(&(msg->correctionField),
+              buf + PTP_COMMON_HDR_CORRECTION(PTP_COMMON_HDR_OFFSET),
+              sizeof(msg->correctionField));
+       msg->correctionField = bswap_64(msg->correctionField);  // Assume LE machine
+       msg->sourcePortIdentity = sourcePortIdentity;
+       msg->sequenceId = sequenceId;
+       memcpy(&(msg->control),
+              buf + PTP_COMMON_HDR_CONTROL(PTP_COMMON_HDR_OFFSET),
+              sizeof(msg->control));
+       memcpy(&(msg->logMeanMessageInterval),
+              buf + PTP_COMMON_HDR_LOG_MSG_INTRVL(PTP_COMMON_HDR_OFFSET),
+              sizeof(msg->logMeanMessageInterval));
+
+       port->addSockAddrMap(msg->sourcePortIdentity, remote);
+
+       msg->_timestamp = timestamp;
+       msg->_timestamp_counter_value = counter_value;
+
+ done:
+       return msg;
+}
+
+void PTPMessageCommon::processMessage(IEEE1588Port * port)
+{
+       _gc = true;
+       return;
+}
+
+void PTPMessageCommon::buildCommonHeader(uint8_t * buf)
+{
+       unsigned char tspec_msg_t;
+       tspec_msg_t = messageType | 0x10;
+       //tspec_msg_t = messageType;
+       long long correctionField_BE = bswap_64(correctionField);       // Assume LE machine
+       uint16_t messageLength_NO = PLAT_htons(messageLength);
+
+       memcpy(buf + PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(PTP_COMMON_HDR_OFFSET),
+              &tspec_msg_t, sizeof(tspec_msg_t));
+       memcpy(buf + PTP_COMMON_HDR_PTP_VERSION(PTP_COMMON_HDR_OFFSET),
+              &versionPTP, sizeof(versionPTP));
+       memcpy(buf + PTP_COMMON_HDR_MSG_LENGTH(PTP_COMMON_HDR_OFFSET),
+              &messageLength_NO, sizeof(messageLength_NO));
+       memcpy(buf + PTP_COMMON_HDR_DOMAIN_NUMBER(PTP_COMMON_HDR_OFFSET),
+              &domainNumber, sizeof(domainNumber));
+       memcpy(buf + PTP_COMMON_HDR_FLAGS(PTP_COMMON_HDR_OFFSET), &flags,
+              PTP_FLAGS_LENGTH);
+       memcpy(buf + PTP_COMMON_HDR_CORRECTION(PTP_COMMON_HDR_OFFSET),
+              &correctionField_BE, sizeof(correctionField));
+
+       sourcePortIdentity->getClockIdentityString((char *)buf +
+                                                  PTP_COMMON_HDR_SOURCE_CLOCK_ID
+                                                  (PTP_COMMON_HDR_OFFSET));
+       sourcePortIdentity->getPortNumberNO((uint16_t *) (buf +
+                                                         PTP_COMMON_HDR_SOURCE_PORT_ID
+                                                         (PTP_COMMON_HDR_OFFSET)));
+
+       XPTPD_INFO("Sending Sequence Id: %u", sequenceId);
+       sequenceId = PLAT_htons(sequenceId);
+       memcpy(buf + PTP_COMMON_HDR_SEQUENCE_ID(PTP_COMMON_HDR_OFFSET),
+              &sequenceId, sizeof(sequenceId));
+       sequenceId = PLAT_ntohs(sequenceId);
+       memcpy(buf + PTP_COMMON_HDR_CONTROL(PTP_COMMON_HDR_OFFSET), &control,
+              sizeof(control));
+       memcpy(buf + PTP_COMMON_HDR_LOG_MSG_INTRVL(PTP_COMMON_HDR_OFFSET),
+              &logMeanMessageInterval, sizeof(logMeanMessageInterval));
+
+       return;
+}
+
+void PTPMessageCommon::getPortIdentity(PortIdentity * identity)
+{
+       *identity = *sourcePortIdentity;
+}
+
+void PTPMessageCommon::setPortIdentity(PortIdentity * identity)
+{
+       *sourcePortIdentity = *identity;
+}
+
+PTPMessageCommon::~PTPMessageCommon(void)
+{
+       delete sourcePortIdentity;
+       return;
+}
+
+PTPMessageAnnounce::PTPMessageAnnounce(void)
+{
+       clockQuality = new ClockQuality();
+}
+
+PTPMessageAnnounce::~PTPMessageAnnounce(void)
+{
+       delete clockQuality;
+}
+
+bool PTPMessageAnnounce::isBetterThan(PTPMessageAnnounce * msg)
+{
+       unsigned char this1[14];
+       unsigned char that1[14];
+       uint16_t tmp;
+
+       this1[0] = grandmasterPriority1;
+       that1[0] = msg->getGrandmasterPriority1();
+
+       this1[1] = clockQuality->cq_class;
+       that1[1] = msg->getGrandmasterClockQuality()->cq_class;
+
+       this1[2] = clockQuality->clockAccuracy;
+       that1[2] = msg->getGrandmasterClockQuality()->clockAccuracy;
+
+       tmp = clockQuality->offsetScaledLogVariance;
+       tmp = PLAT_htons(tmp);
+       memcpy(this1 + 3, &tmp, sizeof(tmp));
+       tmp = msg->getGrandmasterClockQuality()->offsetScaledLogVariance;
+       tmp = PLAT_htons(tmp);
+       memcpy(that1 + 3, &tmp, sizeof(tmp));
+
+       this1[5] = grandmasterPriority2;
+       that1[5] = msg->getGrandmasterPriority2();
+
+       this->getGrandmasterIdentity((char *)this1 + 6);
+       msg->getGrandmasterIdentity((char *)that1 + 6);
+
+#if 0
+       fprintf(stderr, "Us: ");
+       for (int i = 0; i < 14; ++i)
+               fprintf(stderr, "%hhx", this1[i]);
+       fprintf(stderr, "\n");
+       fprintf(stderr, "Them: ");
+       for (int i = 0; i < 14; ++i)
+               fprintf(stderr, "%hhx", that1[i]);
+       fprintf(stderr, "\n");
+#endif
+
+       return (memcmp(this1, that1, 14) < 0) ? true : false;
+}
+
+ PTPMessageSync::PTPMessageSync(IEEE1588Port * port):PTPMessageCommon(port)
+{
+       messageType = SYNC_MESSAGE;     // This is an event message
+       sequenceId = port->getNextSyncSequenceId();
+       control = SYNC;
+
+       flags[PTP_ASSIST_BYTE] |= (0x1 << PTP_ASSIST_BIT);
+
+       originTimestamp = port->getClock()->getTime();
+
+       logMeanMessageInterval = port->getSyncInterval();
+       return;
+}
+
+void PTPMessageSync::sendPort(IEEE1588Port * port, PortIdentity * destIdentity)
+{
+       uint8_t buf_t[256];
+       uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
+       unsigned char tspec_msg_t = 0x0;
+       Timestamp originTimestamp_BE;
+       memset(buf_t, 0, 256);
+       // Create packet in buf
+       // Copy in common header
+       messageLength = PTP_COMMON_HDR_LENGTH + PTP_SYNC_LENGTH;
+       tspec_msg_t |= messageType & 0xF;
+       buildCommonHeader(buf_ptr);
+       // Get timestamp
+       originTimestamp = port->getClock()->getTime();
+       originTimestamp_BE.seconds_ms = PLAT_htons(originTimestamp.seconds_ms);
+       originTimestamp_BE.seconds_ls = PLAT_htonl(originTimestamp.seconds_ls);
+       originTimestamp_BE.nanoseconds =
+           PLAT_htonl(originTimestamp.nanoseconds);
+       // Copy in v2 sync specific fields
+       memcpy(buf_ptr + PTP_SYNC_SEC_MS(PTP_SYNC_OFFSET),
+              &(originTimestamp_BE.seconds_ms),
+              sizeof(originTimestamp.seconds_ms));
+       memcpy(buf_ptr + PTP_SYNC_SEC_LS(PTP_SYNC_OFFSET),
+              &(originTimestamp_BE.seconds_ls),
+              sizeof(originTimestamp.seconds_ls));
+       memcpy(buf_ptr + PTP_SYNC_NSEC(PTP_SYNC_OFFSET),
+              &(originTimestamp_BE.nanoseconds),
+              sizeof(originTimestamp.nanoseconds));
+
+       port->sendEventPort(buf_t, messageLength, MCAST_OTHER, destIdentity);
+
+       return;
+}
+
+ PTPMessageAnnounce::PTPMessageAnnounce(IEEE1588Port * port):PTPMessageCommon
+    (port)
+{
+       messageType = ANNOUNCE_MESSAGE; // This is an event message
+       sequenceId = port->getNextAnnounceSequenceId();
+       ClockIdentity id;
+       control = MESSAGE_OTHER;
+
+       id = port->getClock()->getClockIdentity();
+       tlv.setClockIdentity(&id);
+
+       currentUtcOffset = port->getClock()->getCurrentUtcOffset();
+       grandmasterPriority1 = port->getClock()->getPriority1();
+       grandmasterPriority2 = port->getClock()->getPriority2();
+       clockQuality = new ClockQuality();
+       *clockQuality = port->getClock()->getClockQuality();
+       stepsRemoved = 0;
+       timeSource = port->getClock()->getTimeSource();
+       ClockIdentity clock_identity;
+       clock_identity = port->getClock()->getClockIdentity();
+       clock_identity.getIdentityString(grandmasterIdentity);
+
+       logMeanMessageInterval = port->getAnnounceInterval();
+       return;
+}
+
+void PTPMessageAnnounce::sendPort(IEEE1588Port * port,
+                                 PortIdentity * destIdentity)
+{
+       uint8_t buf_t[256];
+       uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
+       unsigned char tspec_msg_t = 0x0;
+
+       uint16_t currentUtcOffset_l = PLAT_htons(currentUtcOffset);
+       uint16_t stepsRemoved_l = PLAT_htons(stepsRemoved);
+       ClockQuality clockQuality_l = *clockQuality;
+       clockQuality_l.offsetScaledLogVariance =
+           PLAT_htons(clockQuality_l.offsetScaledLogVariance);
+
+       memset(buf_t, 0, 256);
+       // Create packet in buf
+       // Copy in common header
+       messageLength =
+           PTP_COMMON_HDR_LENGTH + PTP_ANNOUNCE_LENGTH + sizeof(tlv);
+       tspec_msg_t |= messageType & 0xF;
+       buildCommonHeader(buf_ptr);
+       memcpy(buf_ptr + PTP_ANNOUNCE_CURRENT_UTC_OFFSET(PTP_ANNOUNCE_OFFSET),
+              &currentUtcOffset_l, sizeof(currentUtcOffset));
+       memcpy(buf_ptr +
+              PTP_ANNOUNCE_GRANDMASTER_PRIORITY1(PTP_ANNOUNCE_OFFSET),
+              &grandmasterPriority1, sizeof(grandmasterPriority1));
+       memcpy(buf_ptr +
+              PTP_ANNOUNCE_GRANDMASTER_CLOCK_QUALITY(PTP_ANNOUNCE_OFFSET),
+              &clockQuality_l, sizeof(clockQuality));
+       memcpy(buf_ptr +
+              PTP_ANNOUNCE_GRANDMASTER_PRIORITY2(PTP_ANNOUNCE_OFFSET),
+              &grandmasterPriority2, sizeof(grandmasterPriority2));
+       port->getClock()->getGrandmasterIdentity((char *)buf_ptr +
+                                                PTP_ANNOUNCE_GRANDMASTER_IDENTITY
+                                                (PTP_ANNOUNCE_OFFSET));
+       memcpy(buf_ptr + PTP_ANNOUNCE_STEPS_REMOVED(PTP_ANNOUNCE_OFFSET),
+              &stepsRemoved_l, sizeof(stepsRemoved));
+       memcpy(buf_ptr + PTP_ANNOUNCE_TIME_SOURCE(PTP_ANNOUNCE_OFFSET),
+              &timeSource, sizeof(timeSource));
+       tlv.toByteString(buf_ptr + PTP_COMMON_HDR_LENGTH + PTP_ANNOUNCE_LENGTH);
+
+       port->sendGeneralPort(buf_t, messageLength, MCAST_OTHER, destIdentity);
+
+       return;
+}
+
+void PTPMessageAnnounce::processMessage(IEEE1588Port * port)
+{
+       // Delete announce receipt timeout
+       port->getClock()->deleteEventTimer(port,
+                                          ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES);
+
+       // Add message to the list
+       port->addQualifiedAnnounce(this);
+
+       port->getClock()->addEventTimer(port, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
+                                       (unsigned long long)
+                                       (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER *
+                                        (pow
+                                         ((double)2,
+                                          port->getAnnounceInterval()) *
+                                         1000000000.0)));
+       port->getClock()->addEventTimer(port, STATE_CHANGE_EVENT, 16000000);
+}
+
+void PTPMessageSync::processMessage(IEEE1588Port * port)
+{
+       Timestamp system_time;
+       Timestamp device_time;
+       int64_t delay;
+
+       signed long long local_system_offset;
+       signed long long scalar_offset;
+
+       int32_t local_clock_adjustment;
+       int32_t local_system_freq_offset;
+
+       // Expire any SYNC_RECEIPT timers that exist
+       port->getClock()->deleteEventTimer(port, SYNC_RECEIPT_TIMEOUT_EXPIRES);
+       if (port->getPortState() == PTP_INITIALIZING
+           || port->getPortState() == PTP_DISABLED) {
+               // Do nothing Sync messages should be ignored when in this state
+               return;
+       }
+       if (port->getPortState() == PTP_FAULTY) {
+               // According to spec recovery is implementation specific
+               port->recoverPort();
+               return;
+       }
+
+       XPTPD_INFO("PTP assist flag is not set, FLAGS[0,1] = %u,%u", flags[0],
+                  flags[1]);
+
+//   if( flags[PTP_ASSIST_BYTE] & (0x1<<PTP_ASSIST_BIT)) {
+       if (true) {
+               // If PTP_ASSIST flag is set, expect a follow-up message and do nothing
+               PTPMessageSync *old_sync = port->getLastSync();
+               if (old_sync != NULL) {
+                       delete old_sync;
+               }
+               port->setLastSync(this);
+               _gc = false;
+               goto done;
+       } else {
+               _gc = true;
+       }
+
+       // Indicates invalid link delay, wait until link delay had been calculated
+       if ((delay = port->getLinkDelay()) == 3600000000000) {
+               printf
+                   ("Got Sync/Follow-Up but Link Delay has not been computed\n");
+               goto done;
+       }
+#if 0
+       scalar_offset = _timestamp.nanoseconds +
+           (((unsigned long long)_timestamp.seconds_ms <<
+             sizeof(_timestamp.seconds_ls) * 8) +
+            _timestamp.seconds_ls) * 1000000000LL;
+       scalar_offset -=
+           originTimestamp.nanoseconds +
+           (((unsigned long long)originTimestamp.seconds_ms <<
+             sizeof(originTimestamp.seconds_ls) * 8) +
+            originTimestamp.seconds_ls) * 1000000000LL;
+#endif
+       scalar_offset =
+           TIMESTAMP_TO_NS(_timestamp) - TIMESTAMP_TO_NS(originTimestamp);
+       scalar_offset -= delay;
+#if 0
+       scalar_offset -= delay.nanoseconds +
+           (((unsigned long long)delay.seconds_ms << sizeof(delay.seconds_ls) *
+             8) + delay.seconds_ls) * 1000000000LL;
+#endif
+       scalar_offset -= correctionField >> 16; // Fractional nanoseconds are dropped
+
+       // Otherwise synchronize clock with approximate time from Sync message
+       uint32_t local_clock;
+       uint32_t nominal_clock_rate;
+       uint32_t device_sync_time_offset;
+
+#if 0
+       Timestamp crstamp_device_time;
+       int64_t external_local_offset;
+       int32_t external_local_freq_offset;
+#endif
+
+       port->getDeviceTime(system_time, device_time, local_clock,
+                           nominal_clock_rate);
+
+       // Adjust local_clock to correspond to _timestamp
+       device_sync_time_offset =
+           TIMESTAMP_TO_NS(device_time) - TIMESTAMP_TO_NS(_timestamp);
+       local_clock -=
+           device_sync_time_offset / (1000000000 / nominal_clock_rate);
+
+       XPTPD_INFO
+           ("ptp_message::sync::processMessage System time: %u,%u Device Time: %u,%u",
+            system_time.seconds_ls, system_time.nanoseconds,
+            device_time.seconds_ls, device_time.nanoseconds);
+
+       local_clock_adjustment =
+           port->calcMasterLocalClockRateDifference(scalar_offset, _timestamp);
+       port->setMasterRateOffset(local_clock_adjustment);
+
+       local_system_offset =
+           TIMESTAMP_TO_NS(system_time) - TIMESTAMP_TO_NS(device_time);
+#if 0
+       local_system_offset = system_time.nanoseconds +
+           (((unsigned long long)system_time.seconds_ms <<
+             sizeof(system_time.seconds_ls) * 8) +
+            system_time.seconds_ls) * 1000000000LL;
+       local_system_offset -=
+           device_time.nanoseconds +
+           (((unsigned long long)device_time.seconds_ms <<
+             sizeof(device_time.seconds_ls) * 8) +
+            device_time.seconds_ls) * 1000000000LL;
+#endif
+
+       local_system_freq_offset =
+           port->calcLocalSystemClockRateDifference(local_system_offset,
+                                                    system_time);
+
+       TIMESTAMP_SUB_NS(system_time,
+                        (device_sync_time_offset *
+                         (1000000000000ULL +
+                          local_system_freq_offset)) / 1000000000000ULL);
+
+       //port->getExternalClockRate( crstamp_device_time, external_local_offset, external_local_freq_offset );
+
+#if 0
+       port->getClock()->setMasterOffset(scalar_offset, _timestamp,
+                                         local_clock_adjustment,
+                                         local_system_offset, system_time,
+                                         local_system_freq_offset,
+                                         external_local_offset,
+                                         crstamp_device_time,
+                                         external_local_freq_offset);
+#endif
+       port->getClock()->setMasterOffset(scalar_offset, _timestamp,
+                                         local_clock_adjustment,
+                                         local_system_offset, system_time,
+                                         local_system_freq_offset,
+                                         nominal_clock_rate, local_clock);
+       //fprintf( stderr, "Master-Local Offset=%d\n", local_clock_adjustment );
+
+       if (port->doSyntonization()) {
+               port->adjustClockRate(local_clock_adjustment,
+                                     _timestamp_counter_value, originTimestamp,
+                                     scalar_offset, false);
+       }
+
+ done:
+       // Restart the SYNC_RECEIPT timer
+       port->getClock()->addEventTimer(port, SYNC_RECEIPT_TIMEOUT_EXPIRES,
+                                       (unsigned long long)
+                                       (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
+                                        ((double)
+                                         pow((double)2,
+                                             port->getSyncInterval()) *
+                                         1000000000.0)));
+
+       return;
+}
+
+ PTPMessageFollowUp::PTPMessageFollowUp(IEEE1588Port * port):PTPMessageCommon
+    (port)
+{
+       messageType = FOLLOWUP_MESSAGE; // This is an event message
+       control = FOLLOWUP;
+
+       logMeanMessageInterval = port->getSyncInterval();
+
+       return;
+}
+
+void PTPMessageFollowUp::sendPort(IEEE1588Port * port,
+                                 PortIdentity * destIdentity)
+{
+       uint8_t buf_t[256];
+       uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
+       unsigned char tspec_msg_t = 0x0;
+       Timestamp preciseOriginTimestamp_BE;
+       memset(buf_t, 0, 256);
+       // Create packet in buf
+       // Copy in common header
+       messageLength =
+           PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH + sizeof(tlv);
+       tspec_msg_t |= messageType & 0xF;
+       buildCommonHeader(buf_ptr);
+       preciseOriginTimestamp_BE.seconds_ms =
+           PLAT_htons(preciseOriginTimestamp.seconds_ms);
+       preciseOriginTimestamp_BE.seconds_ls =
+           PLAT_htonl(preciseOriginTimestamp.seconds_ls);
+       preciseOriginTimestamp_BE.nanoseconds =
+           PLAT_htonl(preciseOriginTimestamp.nanoseconds);
+       // Copy in v2 sync specific fields
+       memcpy(buf_ptr + PTP_FOLLOWUP_SEC_MS(PTP_FOLLOWUP_OFFSET),
+              &(preciseOriginTimestamp_BE.seconds_ms),
+              sizeof(preciseOriginTimestamp.seconds_ms));
+       memcpy(buf_ptr + PTP_FOLLOWUP_SEC_LS(PTP_FOLLOWUP_OFFSET),
+              &(preciseOriginTimestamp_BE.seconds_ls),
+              sizeof(preciseOriginTimestamp.seconds_ls));
+       memcpy(buf_ptr + PTP_FOLLOWUP_NSEC(PTP_FOLLOWUP_OFFSET),
+              &(preciseOriginTimestamp_BE.nanoseconds),
+              sizeof(preciseOriginTimestamp.nanoseconds));
+       tlv.toByteString(buf_ptr + PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH);
+
+       XPTPD_INFO("Follow-Up Time: %u seconds(hi)",
+                  preciseOriginTimestamp.seconds_ms);
+       XPTPD_INFO("Follow-Up Time: %u seconds",
+                  preciseOriginTimestamp.seconds_ls);
+       XPTPD_INFO("F-UP Time: %u nanoseconds",
+                  preciseOriginTimestamp.nanoseconds);
+       XPTPD_INFO("F-UP Time: %x seconds", preciseOriginTimestamp.seconds_ls);
+       XPTPD_INFO("F-UP Time: %x nanoseconds",
+                  preciseOriginTimestamp.nanoseconds);
+#if 0
+       XPTPD_INFO("Follow-up Dump:\n");
+#ifdef DEBUG
+       for (int i = 0; i < messageLength; ++i) {
+               fprintf(stderr, "%d:%02x ", i, (unsigned char)buf[i]);
+       }
+       fprintf(stderr, "\n");
+#endif
+#endif
+
+       port->sendGeneralPort(buf_t, messageLength, MCAST_OTHER, destIdentity);
+
+       return;
+}
+
+void PTPMessageFollowUp::processMessage(IEEE1588Port * port)
+{
+       int64_t delay;
+       Timestamp sync_arrival;
+       Timestamp system_time(0, 0, 0);
+       Timestamp device_time(0, 0, 0);
+
+       signed long long local_system_offset;
+       signed long long scalar_offset;
+
+       int32_t local_clock_adjustment;
+       int32_t local_system_freq_offset;
+
+       XPTPD_INFO("Processing a follow-up message");
+
+       if (port->getPortState() == PTP_INITIALIZING
+           || port->getPortState() == PTP_DISABLED) {
+               // Do nothing Sync messages should be ignored when in this state
+               return;
+       }
+       if (port->getPortState() == PTP_FAULTY) {
+               // According to spec recovery is implementation specific
+               port->recoverPort();
+               return;
+       }
+
+       PortIdentity sync_id;
+       PTPMessageSync *sync = port->getLastSync();
+       if (sync == NULL) {
+
+               XPTPD_ERROR("Received Follow Up but there is no sync message");
+
+               return;
+       }
+       sync->getPortIdentity(&sync_id);
+
+       if (sync->getSequenceId() != sequenceId
+           || sync_id != *sourcePortIdentity) {
+
+               XPTPD_ERROR
+                   ("Received Follow Up but cannot find corresponding Sync");
+
+               goto done;
+       }
+
+       sync_arrival = sync->getTimestamp();
+
+       XPTPD_INFO("Sync Arrival: %u seconds", sync_arrival.seconds_ls);
+       XPTPD_INFO("Sync Arrival: %u nanoseconds", sync_arrival.nanoseconds);
+       XPTPD_INFO("Sync Depart: %u seconds",
+                  preciseOriginTimestamp.seconds_ls);
+       XPTPD_INFO("Sync Depart: %u nanoseconds",
+                  preciseOriginTimestamp.nanoseconds);
+       XPTPD_INFO("Sync Depart: %x seconds",
+                  preciseOriginTimestamp.seconds_ls);
+       XPTPD_INFO("Sync Depart: %x nanoseconds",
+                  preciseOriginTimestamp.nanoseconds);
+
+       delay = port->getLinkDelay();
+       if ((delay = port->getLinkDelay()) == 3600000000000) {
+               goto done;
+       }
+       //fprintf( stderr, "Local Time = %llu,Master Time = %llu\n", TIMESTAMP_TO_NS(sync_arrival)-delay, TIMESTAMP_TO_NS( preciseOriginTimestamp));
+
+       scalar_offset =
+           TIMESTAMP_TO_NS(sync_arrival) -
+           TIMESTAMP_TO_NS(preciseOriginTimestamp);
+
+       //printf( "Followup timestamp: %u,%u,%u\n", preciseOriginTimestamp.seconds_ms, preciseOriginTimestamp.seconds_ls, preciseOriginTimestamp.nanoseconds );
+       //printf( "Sync Arrival timestamp: %u,%u,%u\n", sync_arrival.seconds_ms, sync_arrival.seconds_ls, sync_arrival.nanoseconds );
+       //printf( "FollowUp Scalar = %Ld\n", scalar_offset );
+
+       scalar_offset -= delay;
+       scalar_offset -= correctionField >> 16; // Fractional nanoseconds are dropped
+       //fprintf( stderr, "Scalar offset = %lld\n", scalar_offset );
+       //scalar_offset -= sync->getCorrectionField() >> 16; // Fractional nanoseconds are dropped
+       //fprintf( stderr, "Correction Field (ns): %lld\n", correctionField >> 16 );
+       //fprintf( stderr, "Link Delay (ns): %lld(%llu,%llu)\n", delay, TIMESTAMP_TO_NS( sync_arrival), TIMESTAMP_TO_NS(preciseOriginTimestamp) );
+
+       XPTPD_INFO("Followup Correction Field: %Ld,%lu", correctionField >> 16,
+                  delay);
+       XPTPD_INFO("FollowUp Scalar = %lld", scalar_offset);
+
+       // Otherwise synchronize clock with approximate time from Sync message
+       uint32_t local_clock, nominal_clock_rate;
+       uint32_t device_sync_time_offset;
+
+#if 0
+       Timestamp crstamp_device_time;
+       int64_t external_local_offset;
+       int32_t external_local_freq_offset;
+#endif
+
+       port->getDeviceTime(system_time, device_time, local_clock,
+                           nominal_clock_rate);
+       //fprintf( stderr, "Device Time = %llu,System Time = %llu\n", TIMESTAMP_TO_NS(device_time), TIMESTAMP_TO_NS(system_time));
+
+       // Adjust local_clock to correspond to sync_arrival
+       device_sync_time_offset =
+           TIMESTAMP_TO_NS(device_time) - TIMESTAMP_TO_NS(sync_arrival);
+       //local_clock -= device_sync_time_offset/(1000000000/nominal_clock_rate);
+
+       XPTPD_INFO
+           ("ptp_message::FollowUp::processMessage System time: %u,%u Device Time: %u,%u",
+            system_time.seconds_ls, system_time.nanoseconds,
+            device_time.seconds_ls, device_time.nanoseconds);
+
+       local_system_offset =
+           TIMESTAMP_TO_NS(system_time) - TIMESTAMP_TO_NS(device_time);
+
+#if 0
+       local_system_offset = system_time.nanoseconds +
+           (((unsigned long long)system_time.seconds_ms <<
+             sizeof(system_time.seconds_ls) * 8) +
+            system_time.seconds_ls) * 1000000000LL;
+       local_system_offset -=
+           device_time.nanoseconds +
+           (((unsigned long long)device_time.seconds_ms <<
+             sizeof(device_time.seconds_ls) * 8) +
+            device_time.seconds_ls) * 1000000000LL;
+#endif
+
+       local_clock_adjustment =
+           port->calcMasterLocalClockRateDifference(scalar_offset,
+                                                    sync_arrival);
+       port->setMasterRateOffset(local_clock_adjustment);
+
+       local_system_freq_offset =
+           port->calcLocalSystemClockRateDifference(local_system_offset,
+                                                    system_time);
+       //fprintf( stderr, "Master-Local Freq Offset = %d\n", local_clock_adjustment );
+       //fprintf( stderr, "Local-System Freq Offset = %d\n", local_system_freq_offset );
+
+       TIMESTAMP_SUB_NS(system_time,
+                        (device_sync_time_offset *
+                         (1000000000000ULL +
+                          local_system_freq_offset)) / 1000000000000ULL);
+
+       //port->getExternalClockRate( crstamp_device_time, external_local_offset, external_local_freq_offset );
+
+#if 0
+       port->getClock()->setMasterOffset(scalar_offset, sync_arrival,
+                                         local_clock_adjustment,
+                                         local_system_offset, system_time,
+                                         local_system_freq_offset,
+                                         external_local_offset,
+                                         crstamp_device_time,
+                                         external_local_freq_offset);
+#endif
+       port->getClock()->setMasterOffset(scalar_offset, sync_arrival,
+                                         local_clock_adjustment,
+                                         local_system_offset, system_time,
+                                         local_system_freq_offset,
+                                         nominal_clock_rate, local_clock);
+       //fprintf( stderr, "Master-Local Offset=%lld,%d,%llu\n", scalar_offset, local_clock_adjustment, TIMESTAMP_TO_NS(sync_arrival) );
+
+       if (port->doSyntonization()) {
+               port->adjustClockRate(local_clock_adjustment,
+                                     sync->getTimestampCounterValue(),
+                                     preciseOriginTimestamp, scalar_offset,
+                                     false);
+       }
+
+ done:
+       _gc = true;
+       delete sync;
+       port->setLastSync(NULL);
+
+       return;
+}
+
+ PTPMessagePathDelayReq::PTPMessagePathDelayReq(IEEE1588Port * port):PTPMessageCommon
+    (port)
+{
+       logMeanMessageInterval = 0;
+       control = MESSAGE_OTHER;
+       messageType = PATH_DELAY_REQ_MESSAGE;
+       sequenceId = port->getNextPDelaySequenceId();
+       return;
+}
+
+void PTPMessagePathDelayReq::processMessage(IEEE1588Port * port)
+{
+       OSTimer *timer = port->getTimerFactory()->createTimer();
+
+       if (port->getPortState() == PTP_INITIALIZING
+           || port->getPortState() == PTP_DISABLED) {
+               // Do nothing all messages should be ignored when in this state
+               return;
+       }
+
+       if (port->getPortState() == PTP_FAULTY) {
+               // According to spec recovery is implementation specific
+               port->recoverPort();
+               return;
+       }
+
+       port->getClock()->deleteEventTimer(port,
+                                          PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES);
+       port->getClock()->addEventTimer(port,
+                                       PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES,
+                                       (unsigned long long)
+                                       (PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER
+                                        *
+                                        (pow
+                                         ((double)2,
+                                          port->getPDelayInterval()) *
+                                         1000000000.0)));
+       // Generate and send message
+       PTPMessagePathDelayResp *resp = new PTPMessagePathDelayResp(port);
+       PortIdentity resp_id;
+       port->getPortIdentity(resp_id);
+       resp->setPortIdentity(&resp_id);
+       resp->setSequenceId(sequenceId);
+
+       XPTPD_INFO("Process PDelay Request SeqId: %u\t", sequenceId);
+       //XPTPD_INFO( "Process PDelay Request Port: %u\t", );
+       //XPTPD_INFO( "Process PDelay Request Identity: \"" );
+
+#ifdef DEBUG
+       for (int n = 0; n < PTP_CLOCK_IDENTITY_LENGTH; ++n) {
+               fprintf(stderr, "%c", resp_id.clockIdentity[n]);
+       }
+       fprintf(stderr, "\"\n");
+#endif
+
+       PortIdentity requestingPortIdentity_p;
+       this->getPortIdentity(&requestingPortIdentity_p);
+       resp->setRequestingPortIdentity(&requestingPortIdentity_p);
+       resp->setRequestReceiptTimestamp(_timestamp);
+       port->getTxLock();
+       resp->sendPort(port, sourcePortIdentity);
+
+       XPTPD_INFO("Sent path delay response");
+
+       int ts_good;
+       int iter = 2;
+       Timestamp resp_timestamp;
+       unsigned resp_timestamp_counter_value;
+       unsigned req = 1000;    // = 1 ms
+
+       XPTPD_INFO("Start TS Read");
+       ts_good =
+           port->getTxTimestamp(resp, resp_timestamp,
+                                resp_timestamp_counter_value, false);
+
+       XPTPD_INFO("Done TS Read");
+
+       while (ts_good != 0 && iter-- != 0) {
+               timer->sleep(req);
+               if (ts_good == -72 && iter < 1)
+                       fprintf(stderr,
+                               "Error (TX) timestamping PDelay Response (Retrying-%d), error=%d\n",
+                               iter, ts_good);
+               ts_good =
+                   port->getTxTimestamp(resp, resp_timestamp,
+                                        resp_timestamp_counter_value,
+                                        iter == 0);
+               req *= 2;
+       }
+       port->putTxLock();
+
+       if (ts_good != 0) {
+               char msg[HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
+               port->getExtendedError(msg);
+               fprintf(stderr,
+                       "Error (TX) timestamping PDelay Response, error=%d\n%s",
+                       ts_good, msg);
+               delete resp;
+               return;
+       }
+
+       PTPMessagePathDelayRespFollowUp *resp_fwup =
+           new PTPMessagePathDelayRespFollowUp(port);
+       PortIdentity resp_fwup_id;
+       port->getPortIdentity(resp_fwup_id);
+       resp_fwup->setPortIdentity(&resp_fwup_id);
+       resp_fwup->setSequenceId(sequenceId);
+       resp_fwup->setRequestingPortIdentity(sourcePortIdentity);
+       resp_fwup->setResponseOriginTimestamp(resp_timestamp);
+       long long turnaround;
+       turnaround =
+           (resp_timestamp.seconds_ls - _timestamp.seconds_ls) * 1000000000LL;
+
+       XPTPD_INFO("Response Depart(sec): %u", resp_timestamp.seconds_ls);
+       XPTPD_INFO("Request Arrival(sec): %u", _timestamp.seconds_ls);
+       XPTPD_INFO("#1 Correction Field: %Ld", turnaround);
+
+       turnaround += resp_timestamp.nanoseconds;
+
+       XPTPD_INFO("#2 Correction Field: %Ld", turnaround);
+
+       turnaround -= _timestamp.nanoseconds;
+
+       XPTPD_INFO("#3 Correction Field: %Ld", turnaround);
+
+       //resp_fwup->setCorrectionField( turnaround << 16 );
+       resp_fwup->setCorrectionField(0);       // MMM
+       resp_fwup->sendPort(port, sourcePortIdentity);
+
+       XPTPD_INFO("Sent path delay response fwup");
+
+       delete resp;
+       delete resp_fwup;
+
+       _gc = true;
+}
+
+void PTPMessagePathDelayReq::sendPort(IEEE1588Port * port,
+                                     PortIdentity * destIdentity)
+{
+       uint8_t buf_t[256];
+       uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
+       unsigned char tspec_msg_t = 0;
+       memset(buf_t, 0, 256);
+       // Create packet in buf
+       // Copy in common header
+       messageLength = PTP_COMMON_HDR_LENGTH + PTP_PDELAY_REQ_LENGTH;
+       tspec_msg_t |= messageType & 0xF;
+       buildCommonHeader(buf_ptr);
+       // Get timestamp
+       //originTimestamp = port->getClock()->getTime();
+       // These fields are not used
+//   memcpy( buf+PTP_PDELAY_REQ_SEC_MS(PTP_PDELAY_REQ_OFFSET), &(originTimestamp.seconds_ms), sizeof(originTimestamp.seconds_ms));
+//   memcpy( buf+PTP_PDELAY_REQ_SEC_LS(PTP_PDELAY_REQ_OFFSET), &(originTimestamp.seconds_ls), sizeof(originTimestamp.seconds_ls));
+//   memcpy( buf+PTP_PDELAY_REQ_NSEC(PTP_PDELAY_REQ_OFFSET), &(originTimestamp.nanoseconds), sizeof(originTimestamp.nanoseconds));
+//   memcpy( buf+PTP_PDELAY_REQ_TS_OFFSET(PTP_PDELAY_REQ_OFFSET), &(originTimestamp.timescaleOffset), sizeof(originTimestamp.timescaleOffset));
+
+       port->sendEventPort(buf_t, messageLength, MCAST_PDELAY, destIdentity);
+       return;
+}
+
+ PTPMessagePathDelayResp::PTPMessagePathDelayResp(IEEE1588Port * port):
+PTPMessageCommon(port)
+{
+       logMeanMessageInterval = 0;
+       control = MESSAGE_OTHER;
+       messageType = PATH_DELAY_RESP_MESSAGE;
+       versionPTP = GPTP_VERSION;
+       requestingPortIdentity = new PortIdentity();
+
+       flags[PTP_ASSIST_BYTE] |= (0x1 << PTP_ASSIST_BIT);
+
+       return;
+}
+
+PTPMessagePathDelayResp::~PTPMessagePathDelayResp()
+{
+       delete requestingPortIdentity;
+}
+
+void PTPMessagePathDelayResp::processMessage(IEEE1588Port * port)
+{
+       if (port->getPortState() == PTP_INITIALIZING
+           || port->getPortState() == PTP_DISABLED) {
+               // Do nothing all messages should be ignored when in this state
+               return;
+       }
+       if (port->getPortState() == PTP_FAULTY) {
+               // According to spec recovery is implementation specific
+               port->recoverPort();
+               return;
+       }
+
+       if (port->tryPDelayRxLock() != true) {
+               fprintf(stderr, "Failed to get PDelay RX Lock\n");
+               return;
+       }
+
+       port->getClock()->deleteEventTimer(port,
+                                          PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES);
+       port->getClock()->addEventTimer(port,
+                                       PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES,
+                                       (unsigned long long)
+                                       (PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER
+                                        *
+                                        (pow
+                                         ((double)2,
+                                          port->getPDelayInterval()) *
+                                         1000000000.0)));
+       PTPMessagePathDelayResp *old_pdelay_resp = port->getLastPDelayResp();
+       if (old_pdelay_resp != NULL) {
+               delete old_pdelay_resp;
+       }
+       port->setLastPDelayResp(this);
+
+       port->putPDelayRxLock();
+       _gc = false;
+
+       return;
+}
+
+void PTPMessagePathDelayResp::sendPort(IEEE1588Port * port,
+                                      PortIdentity * destIdentity)
+{
+       uint8_t buf_t[256];
+       uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
+       unsigned char tspec_msg_t = 0;
+       Timestamp requestReceiptTimestamp_BE;
+       memset(buf_t, 0, 256);
+       // Create packet in buf
+       // Copy in common header
+       messageLength = PTP_COMMON_HDR_LENGTH + PTP_PDELAY_RESP_LENGTH;
+       tspec_msg_t |= messageType & 0xF;
+       buildCommonHeader(buf_ptr);
+       requestReceiptTimestamp_BE.seconds_ms =
+           PLAT_htons(requestReceiptTimestamp.seconds_ms);
+       requestReceiptTimestamp_BE.seconds_ls =
+           PLAT_htonl(requestReceiptTimestamp.seconds_ls);
+       requestReceiptTimestamp_BE.nanoseconds =
+           PLAT_htonl(requestReceiptTimestamp.nanoseconds);
+
+       // Copy in v2 PDelay_Req specific fields
+       requestingPortIdentity->getClockIdentityString((char *)buf_ptr +
+                                                      PTP_PDELAY_RESP_REQ_CLOCK_ID
+                                                      (PTP_PDELAY_RESP_OFFSET));
+       requestingPortIdentity->getPortNumberNO((uint16_t *) (buf_ptr +
+                                                             PTP_PDELAY_RESP_REQ_PORT_ID
+                                                             (PTP_PDELAY_RESP_OFFSET)));
+       memcpy(buf_ptr + PTP_PDELAY_RESP_SEC_MS(PTP_PDELAY_RESP_OFFSET),
+              &(requestReceiptTimestamp_BE.seconds_ms),
+              sizeof(requestReceiptTimestamp.seconds_ms));
+       memcpy(buf_ptr + PTP_PDELAY_RESP_SEC_LS(PTP_PDELAY_RESP_OFFSET),
+              &(requestReceiptTimestamp_BE.seconds_ls),
+              sizeof(requestReceiptTimestamp.seconds_ls));
+       memcpy(buf_ptr + PTP_PDELAY_RESP_NSEC(PTP_PDELAY_RESP_OFFSET),
+              &(requestReceiptTimestamp_BE.nanoseconds),
+              sizeof(requestReceiptTimestamp.nanoseconds));
+
+       XPTPD_INFO("PDelay Resp Timestamp: %u,%u",
+                  requestReceiptTimestamp.seconds_ls,
+                  requestReceiptTimestamp.nanoseconds);
+
+       port->sendEventPort(buf_t, messageLength, MCAST_PDELAY, destIdentity);
+       return;
+}
+
+void PTPMessagePathDelayResp::setRequestingPortIdentity(PortIdentity * identity)
+{
+       *requestingPortIdentity = *identity;
+}
+
+void PTPMessagePathDelayResp::getRequestingPortIdentity(PortIdentity * identity)
+{
+       *identity = *requestingPortIdentity;
+}
+
+ PTPMessagePathDelayRespFollowUp::PTPMessagePathDelayRespFollowUp(IEEE1588Port * port):
+PTPMessageCommon
+    (port)
+{
+       logMeanMessageInterval = 0;
+       control = MESSAGE_OTHER;
+       messageType = PATH_DELAY_FOLLOWUP_MESSAGE;
+       versionPTP = GPTP_VERSION;
+       requestingPortIdentity = new PortIdentity();
+
+       return;
+}
+
+PTPMessagePathDelayRespFollowUp::~PTPMessagePathDelayRespFollowUp()
+{
+       delete requestingPortIdentity;
+}
+
+void PTPMessagePathDelayRespFollowUp::processMessage(IEEE1588Port * port)
+{
+       Timestamp remote_resp_tx_timestamp(0, 0, 0);
+       Timestamp request_tx_timestamp(0, 0, 0);
+       Timestamp remote_req_rx_timestamp(0, 0, 0);
+       Timestamp response_rx_timestamp(0, 0, 0);
+
+       if (port->getPortState() == PTP_INITIALIZING
+           || port->getPortState() == PTP_DISABLED) {
+               // Do nothing all messages should be ignored when in this state
+               return;
+       }
+       if (port->getPortState() == PTP_FAULTY) {
+               // According to spec recovery is implementation specific
+               port->recoverPort();
+               return;
+       }
+
+       if (port->tryPDelayRxLock() != true)
+               return;
+
+       PTPMessagePathDelayReq *req = port->getLastPDelayReq();
+       PTPMessagePathDelayResp *resp = port->getLastPDelayResp();
+
+       PortIdentity req_id;
+       PortIdentity resp_id;
+
+       if (req == NULL) {
+               // Shouldn't happen
+               XPTPD_ERROR
+                   (">>> Received PDelay followup but no REQUEST exists");
+               goto abort;
+       }
+
+       if (resp == NULL) {
+               // Probably shouldn't happen either
+               XPTPD_ERROR
+                   (">>> Received PDelay followup but no RESPONSE exists");
+               goto abort;
+       }
+
+       req->getPortIdentity(&req_id);
+       resp->getRequestingPortIdentity(&resp_id);
+
+       // Check if we have sent a request
+//   if( req->getSequenceId() != sequenceId || req_id.portNumber != requestingPortIdentity.portNumber || 
+//       memcmp( req_id.clockIdentity, requestingPortIdentity.clockIdentity, PTP_CLOCK_IDENTITY_LENGTH ) != 0 ) {
+       if (req->getSequenceId() != sequenceId) {
+
+               XPTPD_ERROR
+                   ("Received PDelay Response Follow Up but cannot find corresponding request");
+               //     XPTPD_INFO( "Requesting SeqId: %u ", req->getSequenceId() );
+               //     XPTPD_INFO( "Requesting SeqId: %u ", sequenceId );
+               XPTPD_ERROR("My SeqId: %u ", req->getSequenceId());
+               XPTPD_ERROR("Their SeqId: %u ", sequenceId);
+               //XPTPD_INFO( "Requesting Port: %u ", requestingPortIdentity.portNumber );
+               XPTPD_INFO("Requesting Identity: \"");
+
+#ifdef DEBUG
+               for (int n = 0; n < PTP_CLOCK_IDENTITY_LENGTH; ++n) {
+                       fprintf(stderr, "%u: %x ", n,
+                               requestingPortIdentity.clockIdentity[n]);
+               }
+               fprintf(stderr, " \"\n");
+#endif
+
+               //XPTPD_INFO( "Requesting SeqId: %u ", req->getSequenceId() );
+               //XPTPD_INFO( "Requesting Port: %u ", req_id.portNumber );
+               XPTPD_INFO("Requesting Identity: \"");
+
+#ifdef DEBUG
+               for (int n = 0; n < PTP_CLOCK_IDENTITY_LENGTH; ++n) {
+                       fprintf(stderr, "%u:%x ", n, req_id.clockIdentity[n]);
+               }
+               fprintf(stderr, " \"\n");
+#endif
+
+               goto abort;
+       }
+       //fprintf( stderr, "PDelay Follow-Up OK\n" );
+
+       // Check if we have received a response
+       if (resp->getSequenceId() != sequenceId
+           || resp_id != *requestingPortIdentity) {
+               uint16_t resp_port_number;
+               uint16_t req_port_number;
+               resp_id.getPortNumber(&resp_port_number);
+               requestingPortIdentity->getPortNumber(&req_port_number);
+               XPTPD_ERROR
+                   ("Received PDelay Response Follow Up but cannot find corresponding response");
+               XPTPD_ERROR("%hu, %hu, %hu, %hu", resp->getSequenceId(),
+                           sequenceId, resp_port_number, req_port_number);
+
+               goto abort;
+       }
+
+       XPTPD_INFO("Request Sequence Id: %u", req->getSequenceId());
+       XPTPD_INFO("Response Sequence Id: %u", resp->getSequenceId());
+       XPTPD_INFO("Follow-Up Sequence Id: %u", req->getSequenceId());
+
+       port->setAsCapable(true);
+
+       int64_t link_delay;
+       unsigned long long turn_around;
+
+       // Assume that we are a two step clock, otherwise originTimestamp may be used
+       request_tx_timestamp = req->getTimestamp();
+       if (request_tx_timestamp.nanoseconds ==
+           PDELAY_PENDING_TIMESTAMP.nanoseconds) {
+               // Defer processing
+               if (port->getLastPDelayRespFollowUp() != NULL) {
+                       delete port->getLastPDelayRespFollowUp();
+               }
+               port->setLastPDelayRespFollowUp(this);
+               port->getClock()->addEventTimer(port,
+                                               PDELAY_DEFERRED_PROCESSING,
+                                               1000000);
+               goto defer;
+       }
+       if (request_tx_timestamp.nanoseconds == INVALID_TIMESTAMP.nanoseconds) {
+               // Stop processing the packet
+               goto abort;
+       }
+       remote_req_rx_timestamp = resp->getRequestReceiptTimestamp();
+       response_rx_timestamp = resp->getTimestamp();
+       remote_resp_tx_timestamp = responseOriginTimestamp;
+
+#if 0
+       fprintf(stderr, "@REQT,%u,%u,%u,%hu\n", request_tx_timestamp.seconds_ms,
+               request_tx_timestamp.seconds_ls,
+               request_tx_timestamp.nanoseconds, req->getSequenceId());
+       fprintf(stderr, "@REQR,%u,%u,%u,%hu\n",
+               remote_req_rx_timestamp.seconds_ms,
+               remote_req_rx_timestamp.seconds_ls,
+               remote_req_rx_timestamp.nanoseconds, resp->getSequenceId());
+       fprintf(stderr, "@RESR,%u,%u,%u,%hu\n",
+               response_rx_timestamp.seconds_ms,
+               response_rx_timestamp.seconds_ls,
+               response_rx_timestamp.nanoseconds, resp->getSequenceId());
+       fprintf(stderr, "@REST,%u,%u,%u,%hu\n",
+               remote_resp_tx_timestamp.seconds_ms,
+               remote_resp_tx_timestamp.seconds_ls,
+               remote_resp_tx_timestamp.nanoseconds, sequenceId);
+#endif
+
+       link_delay =
+           ((response_rx_timestamp.seconds_ms * 1LL -
+             request_tx_timestamp.seconds_ms) << 32) * 1000000000;
+       link_delay +=
+           (response_rx_timestamp.seconds_ls * 1LL -
+            request_tx_timestamp.seconds_ls) * 1000000000;
+       link_delay +=
+           (response_rx_timestamp.nanoseconds * 1LL -
+            request_tx_timestamp.nanoseconds);
+       //fprintf( stderr, "Send/Recv Delay is %lld\n", link_delay );
+
+       turn_around =
+           ((remote_resp_tx_timestamp.seconds_ms * 1LL -
+             remote_req_rx_timestamp.seconds_ms) << 32) * 1000000000;
+       turn_around +=
+           (remote_resp_tx_timestamp.seconds_ls * 1LL -
+            remote_req_rx_timestamp.seconds_ls) * 1000000000;
+       turn_around +=
+           (remote_resp_tx_timestamp.nanoseconds * 1LL -
+            remote_req_rx_timestamp.nanoseconds);
+       //fprintf( stderr, "Unadjusted Turn Around is %llu\n", turn_around );
+       //fprintf( stderr, "Unadjusted Link Delay *2 %lld\n", link_delay - turn_around );
+
+       //fprintf( stderr, "Peer Rate Offset: %d", port->getPeerRateOffset() );
+
+       // Adjust turn-around time for peer to local clock rate difference
+       turn_around +=
+           (((long long)turn_around) * port->getPeerRateOffset()) /
+           1000000000000LL;
+
+       XPTPD_INFO("Turn Around Adjustment %Ld",
+                  ((long long)turn_around * port->getPeerRateOffset()) /
+                  1000000000000LL);
+       XPTPD_INFO("Step #1: Turn Around Adjustment %Ld",
+                  ((long long)turn_around * port->getPeerRateOffset()));
+       XPTPD_INFO("Adjusted Peer turn around is %Lu", turn_around);
+
+       // Subtract turn-around time from link delay after rate adjustment
+       link_delay -= turn_around;
+
+       link_delay /= 2;
+
+       {
+               uint64_t mine_elapsed;
+               uint64_t theirs_elapsed;
+               Timestamp prev_peer_ts_mine;
+               Timestamp prev_peer_ts_theirs;
+               int32_t rate_offset;
+               if (port->getPeerOffset(prev_peer_ts_mine, prev_peer_ts_theirs)) {
+                       mine_elapsed =
+                           TIMESTAMP_TO_NS(request_tx_timestamp) -
+                           TIMESTAMP_TO_NS(prev_peer_ts_mine);
+                       theirs_elapsed =
+                           TIMESTAMP_TO_NS(remote_req_rx_timestamp) -
+                           TIMESTAMP_TO_NS(prev_peer_ts_theirs);
+#if 0
+                       rate_offset =
+                           (int32_t) ((mine_elapsed * 1000000000ULL) /
+                                      theirs_elapsed);
+                       rate_offset -= 1000000000;
+#endif
+                       theirs_elapsed -= port->getLinkDelay() - link_delay;
+                       rate_offset =
+                           (int32_t) ((mine_elapsed * 1000000000ULL) /
+                                      theirs_elapsed);
+                       rate_offset -= 1000000000;
+                       rate_offset *= 1000;
+                       port->setPeerRateOffset(rate_offset);
+                       //fprintf( stderr, "(2)PDelay rate offset: %d\n", rate_offset );
+               }
+       }
+       port->setLinkDelay(link_delay);
+       port->setPeerOffset(request_tx_timestamp, remote_req_rx_timestamp);
+
+ abort:
+       delete req;
+       port->setLastPDelayReq(NULL);
+       delete resp;
+       port->setLastPDelayResp(NULL);
+
+       _gc = true;
+
+ defer:
+       port->putPDelayRxLock();
+
+       return;
+}
+
+void PTPMessagePathDelayRespFollowUp::sendPort(IEEE1588Port * port,
+                                              PortIdentity * destIdentity)
+{
+       uint8_t buf_t[256];
+       uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
+       unsigned char tspec_msg_t = 0;
+       Timestamp responseOriginTimestamp_BE;
+       memset(buf_t, 0, 256);
+       // Create packet in buf
+       // Copy in common header
+       messageLength = PTP_COMMON_HDR_LENGTH + PTP_PDELAY_RESP_LENGTH;
+       tspec_msg_t |= messageType & 0xF;
+       buildCommonHeader(buf_ptr);
+       responseOriginTimestamp_BE.seconds_ms =
+           PLAT_htons(responseOriginTimestamp.seconds_ms);
+       responseOriginTimestamp_BE.seconds_ls =
+           PLAT_htonl(responseOriginTimestamp.seconds_ls);
+       responseOriginTimestamp_BE.nanoseconds =
+           PLAT_htonl(responseOriginTimestamp.nanoseconds);
+
+       // Copy in v2 PDelay_Req specific fields
+       requestingPortIdentity->getClockIdentityString((char *)buf_ptr +
+                                                      PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID
+                                                      (PTP_PDELAY_FOLLOWUP_OFFSET));
+       requestingPortIdentity->getPortNumberNO((uint16_t *) (buf_ptr +
+                                                             PTP_PDELAY_FOLLOWUP_REQ_PORT_ID
+                                                             (PTP_PDELAY_FOLLOWUP_OFFSET)));
+       memcpy(buf_ptr + PTP_PDELAY_FOLLOWUP_SEC_MS(PTP_PDELAY_FOLLOWUP_OFFSET),
+              &(responseOriginTimestamp_BE.seconds_ms),
+              sizeof(responseOriginTimestamp.seconds_ms));
+       memcpy(buf_ptr + PTP_PDELAY_FOLLOWUP_SEC_LS(PTP_PDELAY_FOLLOWUP_OFFSET),
+              &(responseOriginTimestamp_BE.seconds_ls),
+              sizeof(responseOriginTimestamp.seconds_ls));
+       memcpy(buf_ptr + PTP_PDELAY_FOLLOWUP_NSEC(PTP_PDELAY_FOLLOWUP_OFFSET),
+              &(responseOriginTimestamp_BE.nanoseconds),
+              sizeof(responseOriginTimestamp.nanoseconds));
+
+       XPTPD_INFO("PDelay Resp Timestamp: %u,%u",
+                  responseOriginTimestamp.seconds_ls,
+                  responseOriginTimestamp.nanoseconds);
+
+       port->sendGeneralPort(buf_t, messageLength, MCAST_PDELAY, destIdentity);
+       return;
+}
+
+void PTPMessagePathDelayRespFollowUp::setRequestingPortIdentity(PortIdentity *
+                                                               identity)
+{
+       *requestingPortIdentity = *identity;
+}
diff --git a/daemons/gptp/linux/CVS/Entries b/daemons/gptp/linux/CVS/Entries
new file mode 100644 (file)
index 0000000..b44d45c
--- /dev/null
@@ -0,0 +1,2 @@
+D/src////
+D/build////
diff --git a/daemons/gptp/linux/CVS/Repository b/daemons/gptp/linux/CVS/Repository
new file mode 100644 (file)
index 0000000..34ff17b
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/linux
diff --git a/daemons/gptp/linux/CVS/Root b/daemons/gptp/linux/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/linux/build/CVS/Entries b/daemons/gptp/linux/build/CVS/Entries
new file mode 100644 (file)
index 0000000..8933c8a
--- /dev/null
@@ -0,0 +1,2 @@
+D/obj////
+/Makefile/1.1/Fri Sep  7 18:53:45 2012//
diff --git a/daemons/gptp/linux/build/CVS/Repository b/daemons/gptp/linux/build/CVS/Repository
new file mode 100644 (file)
index 0000000..8599377
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/linux/build
diff --git a/daemons/gptp/linux/build/CVS/Root b/daemons/gptp/linux/build/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/linux/build/Makefile b/daemons/gptp/linux/build/Makefile
new file mode 100644 (file)
index 0000000..8d13174
--- /dev/null
@@ -0,0 +1,84 @@
+#
+#  Copyright (c) 2012 Intel Corporation 
+#  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.
+#  
+#   3. Neither the name of the Intel Corporation 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.
+
+CXX = g++
+
+CFLAGS_G = -Wall -g -I. -I../../common -I../src 
+LDFLAGS_G = -lpthread -lrt
+
+CFLAGS = $(CFLAGS_G)
+LDFLAGS = $(LDFLAGS_G)
+
+CXXFLAGS =
+COMMON_DIR = ../../common
+SRC_DIR = ../src
+OBJ_DIR = obj
+
+OBJ_FILES = $(OBJ_DIR)/ptp_message.o\
+                $(OBJ_DIR)/avbts_osnet.o\
+                $(OBJ_DIR)/ieee1588port.o\
+                $(OBJ_DIR)/ieee1588clock.o
+
+HEADER_FILES = $(COMMON_DIR)/avbts_port.hpp\
+               $(COMMON_DIR)/avbts_ostimerq.hpp\
+               $(COMMON_DIR)/avbts_ostimer.hpp\
+               $(COMMON_DIR)/avbts_osthread.hpp\
+               $(COMMON_DIR)/avbts_osnet.hpp\
+               $(COMMON_DIR)/avbts_oslock.hpp\
+               $(COMMON_DIR)/avbts_osipc.hpp\
+               $(COMMON_DIR)/avbts_oscondition.hpp\
+               $(COMMON_DIR)/avbts_message.hpp\
+               $(COMMON_DIR)/avbts_clock.hpp\
+               $(COMMON_DIR)/ieee1588.hpp\
+               $(SRC_DIR)/linux_hal.hpp\
+               $(SRC_DIR)/platform.hpp
+
+all: daemon_cl
+
+rebuild: clean all
+
+daemon_cl: $(SRC_DIR)/daemon_cl.cpp $(OBJ_FILES)
+       $(CXX) $(CFLAGS) $(CXXFLAGS) $(OBJ_FILES) $(SRC_DIR)/daemon_cl.cpp -o $(OBJ_DIR)/daemon_cl $(LDFLAGS)
+
+$(OBJ_DIR)/ieee1588port.o: $(COMMON_DIR)/ieee1588port.cpp $(HEADER_FILES)
+       $(CXX) $(CFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/ieee1588port.cpp -o $(OBJ_DIR)/ieee1588port.o
+
+$(OBJ_DIR)/ieee1588clock.o: $(COMMON_DIR)/ieee1588clock.cpp $(HEADER_FILES)
+       $(CXX) $(CFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/ieee1588clock.cpp -o $(OBJ_DIR)/ieee1588clock.o
+
+$(OBJ_DIR)/ptp_message.o: $(COMMON_DIR)/ptp_message.cpp $(HEADER_FILES)
+       $(CXX) $(CFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/ptp_message.cpp -o $(OBJ_DIR)/ptp_message.o
+
+$(OBJ_DIR)/avbts_osnet.o: $(COMMON_DIR)/avbts_osnet.cpp $(HEADER_FILES)
+       $(CXX) $(CFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/avbts_osnet.cpp -o $(OBJ_DIR)/avbts_osnet.o
+
+clean:
+       /bin/rm -f *~ $(OBJ_DIR)/*.o  $(OBJ_DIR)/daemon_cl 
+
diff --git a/daemons/gptp/linux/build/obj/.dir b/daemons/gptp/linux/build/obj/.dir
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/daemons/gptp/linux/build/obj/CVS/Entries b/daemons/gptp/linux/build/obj/CVS/Entries
new file mode 100644 (file)
index 0000000..508243e
--- /dev/null
@@ -0,0 +1,2 @@
+/.dir/1.1/Fri Sep 21 21:13:03 2012//
+D
diff --git a/daemons/gptp/linux/build/obj/CVS/Repository b/daemons/gptp/linux/build/obj/CVS/Repository
new file mode 100644 (file)
index 0000000..1b22db8
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/linux/build/obj
diff --git a/daemons/gptp/linux/build/obj/CVS/Root b/daemons/gptp/linux/build/obj/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/linux/build/obj/avbts_osnet.o b/daemons/gptp/linux/build/obj/avbts_osnet.o
new file mode 100644 (file)
index 0000000..5aab873
Binary files /dev/null and b/daemons/gptp/linux/build/obj/avbts_osnet.o differ
diff --git a/daemons/gptp/linux/build/obj/daemon_cl b/daemons/gptp/linux/build/obj/daemon_cl
new file mode 100755 (executable)
index 0000000..3bbe40a
Binary files /dev/null and b/daemons/gptp/linux/build/obj/daemon_cl differ
diff --git a/daemons/gptp/linux/build/obj/ieee1588clock.o b/daemons/gptp/linux/build/obj/ieee1588clock.o
new file mode 100644 (file)
index 0000000..e9471a7
Binary files /dev/null and b/daemons/gptp/linux/build/obj/ieee1588clock.o differ
diff --git a/daemons/gptp/linux/build/obj/ieee1588port.o b/daemons/gptp/linux/build/obj/ieee1588port.o
new file mode 100644 (file)
index 0000000..87e0cc3
Binary files /dev/null and b/daemons/gptp/linux/build/obj/ieee1588port.o differ
diff --git a/daemons/gptp/linux/build/obj/ptp_message.o b/daemons/gptp/linux/build/obj/ptp_message.o
new file mode 100644 (file)
index 0000000..203bc8a
Binary files /dev/null and b/daemons/gptp/linux/build/obj/ptp_message.o differ
diff --git a/daemons/gptp/linux/src/CVS/Entries b/daemons/gptp/linux/src/CVS/Entries
new file mode 100644 (file)
index 0000000..1c3e6b1
--- /dev/null
@@ -0,0 +1,4 @@
+/daemon_cl.cpp/1.1/Fri Sep  7 18:52:56 2012//
+/linux_hal.hpp/1.1/Fri Sep 21 17:52:55 2012//
+/platform.hpp/1.1/Fri Sep  7 18:52:41 2012//
+D
diff --git a/daemons/gptp/linux/src/CVS/Repository b/daemons/gptp/linux/src/CVS/Repository
new file mode 100644 (file)
index 0000000..8a8b350
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/linux/src
diff --git a/daemons/gptp/linux/src/CVS/Root b/daemons/gptp/linux/src/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/linux/src/daemon_cl.cpp b/daemons/gptp/linux/src/daemon_cl.cpp
new file mode 100644 (file)
index 0000000..dc3f85a
--- /dev/null
@@ -0,0 +1,89 @@
+/******************************************************************************
+
+  Copyright (c) 2012 Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#include "ieee1588.hpp"
+#include "avbts_clock.hpp"
+#include "avbts_osnet.hpp"
+#include "avbts_oslock.hpp"
+#include "linux_hal.hpp"
+
+int main(int argc, char **argv)
+{
+       sigset_t set;
+       InterfaceName *ifname;
+       int sig;
+
+       LinuxPCAPNetworkInterfaceFactory *default_factory =
+           new LinuxPCAPNetworkInterfaceFactory;
+       OSNetworkInterfaceFactory::registerFactory(factory_name_t("default"),
+                                                  default_factory);
+       LinuxThreadFactory *thread_factory = new LinuxThreadFactory();
+       LinuxTimerQueueFactory *timerq_factory = new LinuxTimerQueueFactory();
+       LinuxLockFactory *lock_factory = new LinuxLockFactory();
+       LinuxTimerFactory *timer_factory = new LinuxTimerFactory();
+       LinuxConditionFactory *condition_factory = new LinuxConditionFactory();
+       LinuxSimpleIPC *ipc = new LinuxSimpleIPC();
+
+       if (argc < 2)
+               return -1;
+       ifname = new InterfaceName(argv[1], strlen(argv[1]));
+
+       IEEE1588Clock *clock = new IEEE1588Clock(false, timerq_factory, ipc);
+       HWTimestamper *timestamper = new LinuxTimestamper();
+       IEEE1588Port *port =
+           new IEEE1588Port(clock, 1, false, timestamper, false, 0, ifname,
+                            condition_factory, thread_factory, timer_factory,
+                            lock_factory);
+
+       if (!port->init_port()) {
+               printf("failed to initialize port \n");
+               return -1;
+       }
+       port->processEvent(POWERUP);
+
+       sigemptyset(&set);
+       sigaddset(&set, SIGINT);
+       if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) {
+               perror("pthread_sigmask()");
+               return -1;
+       }
+
+       if (sigwait(&set, &sig) != 0) {
+               perror("sigwait()");
+               return -1;
+       }
+
+       fprintf(stderr, "Exiting on %d\n", sig);
+
+       return 0;
+}
diff --git a/daemons/gptp/linux/src/linux_hal.hpp b/daemons/gptp/linux/src/linux_hal.hpp
new file mode 100644 (file)
index 0000000..1d3d269
--- /dev/null
@@ -0,0 +1,875 @@
+/******************************************************************************
+
+  Copyright (c) 2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef LINUX_HAL_HPP
+#define LINUX_HAL_HPP
+
+#include "avbts_osnet.hpp"
+#include "avbts_oslock.hpp"
+#include "avbts_oscondition.hpp"
+#include "avbts_ostimerq.hpp"
+#include "avbts_ostimer.hpp"
+#include "ieee1588.hpp"
+
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+#include <time.h>
+
+#include <string.h>
+#include <errno.h>
+
+#include <stdlib.h>
+
+#include <sys/ioctl.h>
+#include <sys/prctl.h>
+#include <netinet/in.h>
+
+#include <sys/socket.h>
+#include <netpacket/packet.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <sys/select.h>
+#include <linux/net_tstamp.h>
+#include <linux/sockios.h>
+
+#define ONE_WAY_PHY_DELAY 400
+#define P8021AS_MULTICAST "\x01\x80\xC2\x00\x00\x0E"
+
+static inline Timestamp tsToTimestamp(struct timespec *ts)
+{
+       Timestamp ret;
+       if (sizeof(ts->tv_sec) > sizeof(ret.seconds_ls)) {
+               ret.seconds_ms = ts->tv_sec >> (sizeof(ret.seconds_ls) * 8);
+               ret.seconds_ls = ts->tv_sec & 0xFFFFFFFF;
+               ret.nanoseconds = ts->tv_nsec;
+       } else {
+               ret.seconds_ms = 0;
+               ret.seconds_ls = ts->tv_sec;
+               ret.nanoseconds = ts->tv_nsec;
+       }
+       return ret;
+}
+
+class LinuxTimestamper:public HWTimestamper {
+ private:
+       int sd;
+       Timestamp crstamp_system;
+       Timestamp crstamp_device;
+       pthread_mutex_t cross_stamp_lock;
+       bool cross_stamp_good;
+        std::list < Timestamp > rxTimestampList;
+ public:
+        virtual bool HWTimestamper_init(InterfaceLabel * iface_label) {
+               pthread_mutex_init(&cross_stamp_lock, NULL);
+               sd = -1;
+               cross_stamp_good = false;
+               return true;
+       } 
+       void setSocketDescriptor(int sd) {
+               this->sd = sd;
+       };
+       void updateCrossStamp(Timestamp * system_time, Timestamp * device_time) {
+               pthread_mutex_lock(&cross_stamp_lock);
+               crstamp_system = *system_time;
+               crstamp_device = *device_time;
+               cross_stamp_good = true;
+               pthread_mutex_unlock(&cross_stamp_lock);
+       }
+       void pushRXTimestamp(Timestamp * tstamp) {
+               rxTimestampList.push_front(*tstamp);
+       }
+       bool post_init(int ifindex) {
+               int timestamp_flags = 0;
+               struct ifreq device;
+               struct hwtstamp_config hwconfig;
+               int err;
+
+               memset(&device, 0, sizeof(device));
+               device.ifr_ifindex = ifindex;
+               err = ioctl(sd, SIOCGIFNAME, &device);
+               if (err == -1) {
+                       XPTPD_ERROR("Failed to get interface name: %s",
+                                   strerror(errno));
+                       return false;
+               }
+
+               device.ifr_data = (char *)&hwconfig;
+               memset(&hwconfig, 0, sizeof(hwconfig));
+               hwconfig.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+               hwconfig.tx_type = HWTSTAMP_TX_ON;
+               printf("TX type = %u\n", hwconfig.tx_type);
+               printf("RX filter = %u\n", hwconfig.rx_filter);
+               err = ioctl(sd, SIOCSHWTSTAMP, &device);
+               if (err == -1) {
+                       XPTPD_ERROR("Failed to configure timestamping: %s",
+                                   strerror(errno));
+                       return false;
+               }
+
+               timestamp_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
+               timestamp_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
+               timestamp_flags |= SOF_TIMESTAMPING_SYS_HARDWARE;
+               timestamp_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
+               err =
+                   setsockopt(sd, SOL_SOCKET, SO_TIMESTAMPING,
+                              &timestamp_flags, sizeof(timestamp_flags));
+               if (err == -1) {
+                       XPTPD_ERROR
+                           ("Failed to configure timestamping on socket: %s",
+                            strerror(errno));
+                       return false;
+               }
+
+               return true;
+       }
+
+       virtual bool HWTimestamper_gettime(Timestamp * system_time,
+                                          Timestamp * device_time,
+                                          uint32_t * local_clock,
+                                          uint32_t * nominal_clock_rate) {
+               bool ret = false;
+               pthread_mutex_lock(&cross_stamp_lock);
+               if (cross_stamp_good) {
+                       *system_time = crstamp_system;
+                       *device_time = crstamp_device;
+                       ret = true;
+               }
+               pthread_mutex_unlock(&cross_stamp_lock);
+               return ret;
+       }
+
+       virtual int HWTimestamper_txtimestamp(PortIdentity * identity,
+                                             uint16_t sequenceId,
+                                             Timestamp & timestamp,
+                                             unsigned &clock_value,
+                                             bool last) {
+               int err;
+               int ret = -72;
+               struct msghdr msg;
+               struct cmsghdr *cmsg;
+               struct sockaddr_ll remote;
+               struct iovec sgentry;
+               struct {
+                       struct cmsghdr cm;
+                       char control[256];
+               } control;
+
+               if (sd == -1)
+                       return -1;
+               memset(&msg, 0, sizeof(msg));
+
+               msg.msg_iov = &sgentry;
+               msg.msg_iovlen = 1;
+
+               sgentry.iov_base = NULL;
+               sgentry.iov_len = 0;
+
+               memset(&remote, 0, sizeof(remote));
+               msg.msg_name = (caddr_t) & remote;
+               msg.msg_namelen = sizeof(remote);
+               msg.msg_control = &control;
+               msg.msg_controllen = sizeof(control);
+
+               err = recvmsg(sd, &msg, MSG_ERRQUEUE);
+               if (err == -1) {
+                       if (errno == EAGAIN)
+                               return -72;
+                       else
+                               return -1;
+               }
+
+               cmsg = CMSG_FIRSTHDR(&msg);
+               while (cmsg != NULL) {
+                       if (cmsg->cmsg_level == SOL_SOCKET
+                           && cmsg->cmsg_type == SO_TIMESTAMPING) {
+                               struct timespec *ts_device, *ts_system;
+                               Timestamp device, system;
+                               ts_system =
+                                   ((struct timespec *)CMSG_DATA(cmsg)) + 1;
+                               system = tsToTimestamp(ts_system);
+                               ts_device = ts_system + 1;
+                               device = tsToTimestamp(ts_device);
+                               updateCrossStamp(&system, &device);
+                               timestamp = device;
+                               ret = 0;
+                               break;
+                       }
+                       cmsg = CMSG_NXTHDR(&msg, cmsg);
+               }
+
+               return ret;
+       }
+
+       virtual int HWTimestamper_rxtimestamp(PortIdentity * identity,
+                                             uint16_t sequenceId,
+                                             Timestamp & timestamp,
+                                             unsigned &clock_value,
+                                             bool last) {
+               if (rxTimestampList.empty())
+                       return -72;
+               timestamp = rxTimestampList.back();
+               rxTimestampList.pop_back();
+
+               return 0;
+       }
+};
+
+class LinuxLock:public OSLock {
+       friend class LinuxLockFactory;
+ private:
+        OSLockType type;
+       pthread_t thread_id;
+       int lock_c;
+       pthread_mutexattr_t mta;
+       pthread_mutex_t mutex;
+       pthread_cond_t port_ready_signal;
+ protected:
+       LinuxLock() {
+               lock_c = NULL;
+       } 
+       bool initialize(OSLockType type) {
+               pthread_mutexattr_init(&mta);
+               if (type == oslock_recursive)
+                       pthread_mutexattr_settype(&mta,
+                                                 PTHREAD_MUTEX_RECURSIVE);
+               lock_c = pthread_mutex_init(&mutex, &mta);
+               if (lock_c != 0) {
+                       XPTPD_ERROR("Mutex initialization faile - %s\n",
+                                   strerror(errno));
+                       return oslock_fail;
+               }
+               return oslock_ok;
+
+       }
+       OSLockResult lock() {
+               lock_c = pthread_mutex_lock(&mutex);
+               if (lock_c != 0)
+                       return oslock_fail;
+               return oslock_ok;
+       }
+       OSLockResult trylock() {
+               lock_c = pthread_mutex_trylock(&mutex);
+               if (lock_c != 0)
+                       return oslock_fail;
+               return oslock_ok;
+       }
+       OSLockResult unlock() {
+               lock_c = pthread_mutex_unlock(&mutex);
+               if (lock_c != 0)
+                       return oslock_fail;
+               return oslock_ok;
+       }
+};
+
+class LinuxLockFactory:public OSLockFactory {
+ public:
+       OSLock * createLock(OSLockType type) {
+               LinuxLock *lock = new LinuxLock();
+               if (lock->initialize(type) != oslock_ok) {
+                       delete lock;
+                        lock = NULL;
+               }
+               return lock;
+       }
+};
+
+class LinuxCondition:public OSCondition {
+       friend class LinuxConditionFactory;
+ private:
+        pthread_cond_t port_ready_signal;
+       pthread_mutex_t port_lock;
+ protected:
+        bool initialize() {
+               int lock_c;
+                pthread_cond_init(&port_ready_signal, NULL);
+                lock_c = pthread_mutex_init(&port_lock, NULL);
+               if (lock_c != 0)
+                        return false;
+                return true;
+ } 
+public:
+        bool wait_prelock() {
+               pthread_mutex_lock(&port_lock);
+               up();
+               return true;
+       }
+       bool wait() {
+               pthread_cond_wait(&port_ready_signal, &port_lock);
+               down();
+               pthread_mutex_unlock(&port_lock);
+               return true;
+       }
+       bool signal() {
+               pthread_mutex_lock(&port_lock);
+               if (waiting())
+                       pthread_cond_broadcast(&port_ready_signal);
+               pthread_mutex_unlock(&port_lock);
+               return true;
+       }
+};
+
+class LinuxConditionFactory:public OSConditionFactory {
+ public:
+       OSCondition * createCondition() {
+               LinuxCondition *result = new LinuxCondition();
+                return result->initialize() ? result : NULL;
+       }
+};
+
+class LinuxTimerQueue;
+
+struct TimerQueue_t;
+
+struct LinuxTimerQueueHandlerArg {
+       timer_t timer_handle;
+       struct sigevent sevp;
+       event_descriptor_t *inner_arg;
+       ostimerq_handler func;
+       int type;
+       bool rm;
+       TimerQueue_t *timer_queue;
+};
+
+typedef std::list < LinuxTimerQueueHandlerArg * >TimerArgList_t;
+
+struct TimerQueue_t {
+       TimerArgList_t arg_list;
+       pthread_mutex_t lock;
+};
+
+typedef std::map < int, TimerQueue_t > TimerQueueMap_t;
+
+void LinuxTimerQueueHandler(union sigval arg_in);
+
+class LinuxTimerQueue:public OSTimerQueue {
+       friend class LinuxTimerQueueFactory;
+       friend void LinuxTimerQueueHandler(union sigval arg_in);
+ private:
+       TimerQueueMap_t timerQueueMap;
+       TimerArgList_t retiredTimers;
+       bool in_callback;
+ protected:
+       LinuxTimerQueue() {
+               int err;
+               pthread_mutex_t retiredTimersLock;
+               pthread_mutexattr_t retiredTimersLockAttr;
+               err = pthread_mutexattr_init(&retiredTimersLockAttr);
+               if (err != 0) {
+                       XPTPD_ERROR("mutexattr_init()");
+                       exit(0);
+               }
+               err =
+                   pthread_mutexattr_settype(&retiredTimersLockAttr,
+                                             PTHREAD_MUTEX_NORMAL);
+               if (err != 0) {
+                       XPTPD_ERROR("mutexattr_settype()");
+                       exit(0);
+               }
+               err =
+                   pthread_mutex_init(&retiredTimersLock,
+                                      &retiredTimersLockAttr);
+               if (err != 0) {
+                       XPTPD_ERROR("mutex_init()");
+                       exit(0);
+               }
+       };
+ public:
+       bool addEvent(unsigned long micros, int type, ostimerq_handler func,
+                     event_descriptor_t * arg, bool rm, unsigned *event) {
+               LinuxTimerQueueHandlerArg *outer_arg =
+                   new LinuxTimerQueueHandlerArg();
+               if (timerQueueMap.find(type) == timerQueueMap.end()) {
+                       pthread_mutex_init(&timerQueueMap[type].lock, NULL);
+               }
+               outer_arg->inner_arg = arg;
+               outer_arg->func = func;
+               outer_arg->type = type;
+               outer_arg->timer_queue = &timerQueueMap[type];
+               sigset_t set;
+               sigset_t oset;
+               int err;
+               timer_t timerhandle;
+               struct sigevent ev;
+
+               sigemptyset(&set);
+               sigaddset(&set, SIGALRM);
+               err = pthread_sigmask(SIG_BLOCK, &set, &oset);
+               if (err != 0) {
+                       XPTPD_ERROR
+                           ("Add timer pthread_sigmask( SIG_BLOCK ... )");
+                       exit(0);
+               }
+               pthread_mutex_lock(&timerQueueMap[type].lock);
+               {
+                       struct itimerspec its;
+                       memset(&ev, 0, sizeof(ev));
+                       ev.sigev_notify = SIGEV_THREAD;
+                       ev.sigev_value.sival_ptr = outer_arg;
+                       ev.sigev_notify_function = LinuxTimerQueueHandler;
+                       ev.sigev_notify_attributes = new pthread_attr_t;
+                       pthread_attr_init((pthread_attr_t *) ev.sigev_notify_attributes);
+                       pthread_attr_setdetachstate((pthread_attr_t *) ev.sigev_notify_attributes,
+                                                   PTHREAD_CREATE_DETACHED);
+                       if (timer_create(CLOCK_MONOTONIC, &ev, &timerhandle) == -1) {
+                               XPTPD_ERROR("timer_create failed - %s\n",
+                                           strerror(errno));
+                               exit(0);
+                       }
+                       outer_arg->timer_handle = timerhandle;
+                       outer_arg->sevp = ev;
+
+                       memset(&its, 0, sizeof(its));
+                       its.it_value.tv_sec = micros / 1000000;
+                       its.it_value.tv_nsec = (micros % 1000000) * 1000;
+                       timer_settime(outer_arg->timer_handle, 0, &its, NULL);
+               }
+               timerQueueMap[type].arg_list.push_front(outer_arg);
+
+               pthread_mutex_unlock(&timerQueueMap[type].lock);
+
+               err = pthread_sigmask(SIG_SETMASK, &oset, NULL);
+               if (err != 0) {
+                       XPTPD_ERROR
+                           ("Add timer pthread_sigmask( SIG_SETMASK ... )");
+                       exit(0);
+               }
+               return true;
+       }
+       bool cancelEvent(int type, unsigned *event) {
+               TimerQueueMap_t::iterator iter = timerQueueMap.find(type);
+               if (iter == timerQueueMap.end())
+                       return false;
+               sigset_t set;
+               sigset_t oset;
+               int err;
+               sigemptyset(&set);
+               sigaddset(&set, SIGALRM);
+               err = pthread_sigmask(SIG_BLOCK, &set, &oset);
+               if (err != 0) {
+                       XPTPD_ERROR
+                           ("Add timer pthread_sigmask( SIG_BLOCK ... )");
+                       exit(0);
+               }
+               pthread_mutex_lock(&timerQueueMap[type].lock);
+               while (!timerQueueMap[type].arg_list.empty()) {
+                       LinuxTimerQueueHandlerArg *del_arg =
+                           timerQueueMap[type].arg_list.front();
+                       timerQueueMap[type].arg_list.pop_front();
+                       timer_delete(del_arg->timer_handle);
+                       delete(pthread_attr_t *) del_arg->sevp.
+                           sigev_notify_attributes;
+                       if (del_arg->rm)
+                               delete del_arg->inner_arg;
+                       delete del_arg;
+               }
+               pthread_mutex_unlock(&timerQueueMap[type].lock);
+               err = pthread_sigmask(SIG_SETMASK, &oset, NULL);
+               if (err != 0) {
+                       XPTPD_ERROR
+                           ("Add timer pthread_sigmask( SIG_SETMASK ... )");
+                       exit(0);
+               }
+               return true;
+       }
+};
+
+void LinuxTimerQueueHandler(union sigval arg_in)
+{
+       LinuxTimerQueueHandlerArg *arg =
+           (LinuxTimerQueueHandlerArg *) arg_in.sival_ptr;
+       bool runnable = false;
+       unsigned size;
+
+       pthread_mutex_lock(&arg->timer_queue->lock);
+       size = arg->timer_queue->arg_list.size();
+       arg->timer_queue->arg_list.remove(arg);
+       if (arg->timer_queue->arg_list.size() < size) {
+               runnable = true;
+       }
+       pthread_mutex_unlock(&arg->timer_queue->lock);
+
+       if (runnable) {
+               arg->func(arg->inner_arg);
+               if (arg->rm)
+                       delete arg->inner_arg;
+               delete(pthread_attr_t *) arg->sevp.sigev_notify_attributes;
+       }
+}
+
+class LinuxTimerQueueFactory:public OSTimerQueueFactory {
+ public:
+       virtual OSTimerQueue * createOSTimerQueue() {
+               LinuxTimerQueue *timerq = new LinuxTimerQueue();
+               return timerq;
+       };
+};
+
+class LinuxTimer:public OSTimer {
+       friend class LinuxTimerFactory;
+ public:
+       virtual unsigned long sleep(unsigned long micros) {
+               struct timespec req = { 0, micros };    /* Should be micros*1000 -Chris */
+               nanosleep(&req, NULL);
+               return micros;
+       }
+ protected:
+       LinuxTimer() {};
+};
+
+class LinuxTimerFactory:public OSTimerFactory {
+ public:
+       virtual OSTimer * createTimer() {
+               return new LinuxTimer();
+       }
+};
+
+struct OSThreadArg {
+       OSThreadFunction func;
+       void *arg;
+       OSThreadExitCode ret;
+};
+
+void *OSThreadCallback(void *input)
+{
+       OSThreadArg *arg = (OSThreadArg *) input;
+       arg->ret = arg->func(arg->arg);
+       return 0;
+}
+
+class LinuxThread:public OSThread {
+       friend class LinuxThreadFactory;
+ private:
+
+       pthread_t thread_id;
+       OSThreadArg *arg_inner;
+ public:
+       virtual bool start(OSThreadFunction function, void *arg) {
+               sigset_t set;
+               sigset_t oset;
+               int err;
+               arg_inner = new OSThreadArg();
+               arg_inner->func = function;
+               arg_inner->arg = arg;
+               sigemptyset(&set);
+               sigaddset(&set, SIGALRM);
+               err = pthread_sigmask(SIG_BLOCK, &set, &oset);
+               if (err != 0) {
+                       XPTPD_ERROR
+                           ("Add timer pthread_sigmask( SIG_BLOCK ... )");
+                       return false;
+               }
+               err = pthread_create(&thread_id, NULL, OSThreadCallback,
+                                  arg_inner);
+               if (err != 0)
+                       return false;
+               sigdelset(&oset, SIGALRM);
+               err = pthread_sigmask(SIG_SETMASK, &oset, NULL);
+               if (err != 0) {
+                       XPTPD_ERROR
+                           ("Add timer pthread_sigmask( SIG_SETMASK ... )");
+                       return false;
+               }
+
+               return true;
+       }
+       virtual bool join(OSThreadExitCode & exit_code) {
+               int err;
+               err = pthread_join(thread_id, NULL);
+               if (err != 0)
+                       return false;
+               exit_code = arg_inner->ret;
+               delete arg_inner;
+               return true;
+       }
+ protected:
+       LinuxThread() {};
+};
+
+class LinuxThreadFactory:public OSThreadFactory {
+ public:
+       OSThread * createThread() {
+               return new LinuxThread();
+       }
+};
+
+class LinuxPCAPNetworkInterface:public OSNetworkInterface {
+       friend class LinuxPCAPNetworkInterfaceFactory;
+ private:
+       LinkLayerAddress local_addr;
+       int sd_event;
+       int sd_general;
+       LinuxTimestamper *timestamper;
+       int ifindex;
+ public:
+       virtual net_result send(LinkLayerAddress * addr, uint8_t * payload,
+                               size_t length, bool timestamp) {
+               sockaddr_ll *remote = NULL;
+               int err;
+               remote = new struct sockaddr_ll;
+               memset(remote, 0, sizeof(*remote));
+               remote->sll_family = AF_PACKET;
+               remote->sll_protocol = htons(PTP_ETHERTYPE);
+               remote->sll_ifindex = ifindex;
+               remote->sll_halen = ETH_ALEN;
+               addr->toOctetArray(remote->sll_addr);
+               if (timestamp) {
+                       err = sendto(sd_event, payload, length, 0,
+                                  (sockaddr *) remote, sizeof(*remote));
+               } else {
+                       err = sendto(sd_general, payload, length, 0,
+                                  (sockaddr *) remote, sizeof(*remote));
+               }
+               delete remote;
+               if (err == -1) {
+                       XPTPD_ERROR("Failed to send: %s(%d)", strerror(errno),
+                                   errno);
+                       return net_fatal;
+               }
+               return net_succeed;
+       }
+
+       virtual net_result recv(LinkLayerAddress * addr, uint8_t * payload,
+                               size_t & length) {
+               fd_set readfds;
+               int err;
+               struct msghdr msg;
+               struct cmsghdr *cmsg;
+               struct {
+                       struct cmsghdr cm;
+                       char control[256];
+               } control;
+               struct sockaddr_ll remote;
+               struct iovec sgentry;
+
+               struct timeval timeout = { 0, 100000 };
+
+               FD_ZERO(&readfds);
+               FD_SET(sd_event, &readfds);
+
+               err = select(sd_event + 1, &readfds, NULL, NULL, &timeout);
+               if (err == 0) {
+                       return net_trfail;
+               } else if (err == -1) {
+                       if (err == EINTR) {
+                               XPTPD_ERROR("select() recv signal");
+                       } else {
+                               XPTPD_ERROR("select() failed");
+                               return net_fatal;
+                       }
+               }
+
+               memset(&msg, 0, sizeof(msg));
+
+               msg.msg_iov = &sgentry;
+               msg.msg_iovlen = 1;
+
+               sgentry.iov_base = payload;
+               sgentry.iov_len = length;
+
+               memset(&remote, 0, sizeof(remote));
+               msg.msg_name = (caddr_t) & remote;
+               msg.msg_namelen = sizeof(remote);
+               msg.msg_control = &control;
+               msg.msg_controllen = sizeof(control);
+
+               err = recvmsg(sd_event, &msg, 0);
+               if (err < 0)
+                       return net_fatal;
+               *addr = LinkLayerAddress(remote.sll_addr);
+
+               if (err > 0 && !(payload[0] & 0x8)) {
+                       cmsg = CMSG_FIRSTHDR(&msg);
+                       while (cmsg != NULL) {
+                               if (cmsg->cmsg_level == SOL_SOCKET
+                                   && cmsg->cmsg_type == SO_TIMESTAMPING) {
+                                       struct timespec *ts_device, *ts_system;
+                                       Timestamp device, system;
+                                       ts_system =
+                                           ((struct timespec *)CMSG_DATA(cmsg))
+                                           + 1;
+                                       system = tsToTimestamp(ts_system);
+                                       ts_device = ts_system + 1;
+                                       device = tsToTimestamp(ts_device);
+                                       timestamper->updateCrossStamp(&system,
+                                                                     &device);
+                                       timestamper->pushRXTimestamp(&device);
+                                       break;
+                               }
+                               cmsg = CMSG_NXTHDR(&msg, cmsg);
+                       }
+               }
+
+               length = err;
+               return net_succeed;
+       }
+
+       virtual void getLinkLayerAddress(LinkLayerAddress * addr) {
+               *addr = local_addr;
+       }
+
+       virtual unsigned getPayloadOffset() {
+               return 0;
+       }
+
+       virtual ~ LinuxPCAPNetworkInterface() {
+               close(sd_event);
+               close(sd_general);
+       }
+
+ protected:
+       LinuxPCAPNetworkInterface() {};
+};
+
+class LinuxPCAPNetworkInterfaceFactory:public OSNetworkInterfaceFactory {
+ public:
+       virtual bool createInterface(OSNetworkInterface ** net_iface,
+                                    InterfaceLabel * label,
+                                    HWTimestamper * timestamper) {
+               struct ifreq device;
+               int err;
+               struct sockaddr_ll ifsock_addr;
+               struct packet_mreq mr_8021as;
+               LinkLayerAddress addr;
+               int ifindex;
+
+               LinuxPCAPNetworkInterface *net_iface_l =
+                   new LinuxPCAPNetworkInterface();
+               InterfaceName *ifname = dynamic_cast < InterfaceName * >(label);
+               if (ifname == NULL) {
+                       XPTPD_ERROR("ifame == NULL \n");
+                       return false;
+               }
+
+               net_iface_l->sd_general =
+                   socket(PF_PACKET, SOCK_DGRAM, htons(PTP_ETHERTYPE));
+               if (net_iface_l->sd_general == -1) {
+                       XPTPD_ERROR("failed to open general socket: %s \n",
+                                   strerror(errno));
+                       return false;
+               }
+               net_iface_l->sd_event =
+                   socket(PF_PACKET, SOCK_DGRAM, htons(PTP_ETHERTYPE));
+               if (net_iface_l->sd_event == -1) {
+                       XPTPD_ERROR("failed to open event socket: %s \n",
+                                   strerror(errno));
+                       return false;
+               }
+
+               memset(&device, 0, sizeof(device));
+               ifname->toString(device.ifr_name, IFNAMSIZ);
+               err = ioctl(net_iface_l->sd_event, SIOCGIFHWADDR, &device);
+               if (err == -1) {
+                       XPTPD_ERROR("Failed to get interface address: %s",
+                                   strerror(errno));
+                       return false;
+               }
+               addr = LinkLayerAddress(((struct sockaddr_ll *)&device.ifr_hwaddr)->sll_addr);
+               net_iface_l->local_addr = addr;
+
+               err = ioctl(net_iface_l->sd_event, SIOCGIFINDEX, &device);
+               if (err == -1) {
+                       XPTPD_ERROR("Failed to get interface index: %s",
+                                   strerror(errno));
+                       return false;
+               }
+               ifindex = device.ifr_ifindex;
+               net_iface_l->ifindex = ifindex;
+               memset(&mr_8021as, 0, sizeof(mr_8021as));
+               mr_8021as.mr_ifindex = ifindex;
+               mr_8021as.mr_type = PACKET_MR_MULTICAST;
+               mr_8021as.mr_alen = 6;
+               memcpy(mr_8021as.mr_address, P8021AS_MULTICAST,
+                      mr_8021as.mr_alen);
+               err = setsockopt(net_iface_l->sd_event, SOL_PACKET,
+                              PACKET_ADD_MEMBERSHIP, &mr_8021as,
+                              sizeof(mr_8021as));
+               if (err == -1) {
+                       XPTPD_ERROR
+                           ("Unable to add PTP multicast addresses to port id: %u",
+                            ifindex);
+                       return false;
+               }
+
+               memset(&ifsock_addr, 0, sizeof(ifsock_addr));
+               ifsock_addr.sll_family = AF_PACKET;
+               ifsock_addr.sll_ifindex = ifindex;
+               ifsock_addr.sll_protocol = htons(PTP_ETHERTYPE);
+               err = bind(net_iface_l->sd_event, (sockaddr *) & ifsock_addr,
+                        sizeof(ifsock_addr));
+               if (err == -1) {
+                       XPTPD_ERROR("Call to bind() failed: %s",
+                                   strerror(errno));
+                       return false;
+               }
+
+               net_iface_l->timestamper = dynamic_cast < LinuxTimestamper * >(timestamper);
+               if (net_iface_l->timestamper == NULL) {
+                       XPTPD_ERROR("timestamper == NULL\n");
+                       return false;
+               }
+               net_iface_l->timestamper->setSocketDescriptor(net_iface_l->sd_event);
+               if (!net_iface_l->timestamper->post_init(ifindex)) {
+                       XPTPD_ERROR("post_init failed\n");
+                       return false;
+               }
+               *net_iface = net_iface_l;
+
+               return true;
+       }
+};
+
+class LinuxSimpleIPC:public OS_IPC {
+ public:
+       LinuxSimpleIPC() {};
+       ~LinuxSimpleIPC() {}
+       virtual bool init() {
+               return true;
+       }
+       virtual bool update(int64_t ml_phoffset, int64_t ls_phoffset,
+                           int32_t ml_freqoffset, int32_t ls_freqoffset,
+                           uint64_t local_time) {
+#ifdef DEBUG
+               fprintf(stderr,
+                       "Master-Local Phase Offset: %ld\n"
+                       "Master-Local Frequency Offset: %d\n"
+                       "Local-System Phase Offset: %ld\n"
+                       "Local-System Frequency Offset: %d\n"
+                       "Local Time: %lu\n", ml_phoffset, ml_freqoffset,
+                       ls_phoffset, ls_freqoffset, local_time);
+#endif
+               return true;
+       }
+};
+
+#endif
diff --git a/daemons/gptp/linux/src/platform.hpp b/daemons/gptp/linux/src/platform.hpp
new file mode 100644 (file)
index 0000000..eaf0654
--- /dev/null
@@ -0,0 +1,46 @@
+/******************************************************************************
+
+  Copyright (c) 2012 Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#ifndef PLATFORM_HPP
+#define PLATFORM_HPP
+
+#include <arpa/inet.h>
+
+#define PLAT_strncpy( dest, src, max ) strncpy( dest, src, max+1 );
+
+#define PLAT_htons( s ) htons( s )
+#define PLAT_htonl( l ) htonl( l )
+#define PLAT_ntohs( s ) ntohs( s )
+#define PLAT_ntohl( l ) ntohl( l )
+
+#endif
diff --git a/daemons/gptp/windows/CVS/Entries b/daemons/gptp/windows/CVS/Entries
new file mode 100644 (file)
index 0000000..68ce4fc
--- /dev/null
@@ -0,0 +1,4 @@
+D/daemon_cl////
+D/x64////
+D/named_pipe_test////
+/gptp.sln/1.1/Fri Sep 21 16:52:20 2012/-kb/
diff --git a/daemons/gptp/windows/CVS/Repository b/daemons/gptp/windows/CVS/Repository
new file mode 100644 (file)
index 0000000..819fa3a
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/windows
diff --git a/daemons/gptp/windows/CVS/Root b/daemons/gptp/windows/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/windows/daemon_cl/CVS/Entries b/daemons/gptp/windows/daemon_cl/CVS/Entries
new file mode 100644 (file)
index 0000000..fb41e46
--- /dev/null
@@ -0,0 +1,15 @@
+D/x64////
+/ReadMe.txt/1.1/Fri Sep 21 20:19:03 2012//
+/daemon_cl.cpp/1.1/Fri Sep  7 19:10:38 2012//
+/daemon_cl.vcxproj/1.1/Fri Sep 21 16:50:01 2012//
+/daemon_cl.vcxproj.filters/1.1/Fri Sep 21 16:50:23 2012//
+/daemon_cl.vcxproj.user/1.1/Fri Sep  7 18:39:51 2012//
+/ipcdef.hpp/1.1/Fri Sep  7 19:11:15 2012//
+/packet.cpp/1.1/Fri Sep  7 19:10:51 2012//
+/packet.hpp/1.1/Fri Sep  7 19:11:26 2012//
+/platform.hpp/1.1/Fri Sep  7 19:11:37 2012//
+/stdafx.cpp/1.1/Fri Sep  7 18:39:51 2012//
+/stdafx.h/1.1/Fri Sep  7 18:39:51 2012//
+/targetver.h/1.1/Fri Sep  7 18:39:51 2012//
+/tsc.hpp/1.1/Fri Sep 21 16:58:33 2012//
+/windows_hal.hpp/1.1/Fri Sep 21 16:53:58 2012//
diff --git a/daemons/gptp/windows/daemon_cl/CVS/Repository b/daemons/gptp/windows/daemon_cl/CVS/Repository
new file mode 100644 (file)
index 0000000..d3b6fa5
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/windows/daemon_cl
diff --git a/daemons/gptp/windows/daemon_cl/CVS/Root b/daemons/gptp/windows/daemon_cl/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/windows/daemon_cl/ReadMe.txt b/daemons/gptp/windows/daemon_cl/ReadMe.txt
new file mode 100644 (file)
index 0000000..ae30f53
--- /dev/null
@@ -0,0 +1,56 @@
+========================================================================\r
+(C) Copyright 2009-2012 Intel Corporation, All Rights Reserved\r
+Author: Christopher Hall <christopher.s.hall@intel.com>\r
+========================================================================\r
+\r
+========================================================================\r
+    CONSOLE APPLICATION : daemon_cl Project Overview\r
+========================================================================\r
+\r
+* Dependencies\r
+\r
+       WinPCAP Developer's Pack is required for linking (WpdPack_*.zip)\r
+       WinPCAP must also be installed on any machine where the daemon runs (WinPcap_*.exe installer for windows)\r
+\r
+To run from the command line:\r
+\r
+daemon_cl.exe xx-xx-xx-xx-xx-xx\r
+\r
+       where xx-xx-xx-xx-xx-xx is the mac address of the local interface\r
+\r
+* Terminology\r
+\r
+       master - 802.1AS Grandmaster Clock\r
+       local  - local network device clock (802.1AS timestamp source)\r
+       system - clock use elsewhere on a PC-like device, e.g. TSC or HPET timer\r
+\r
+* Interprocess Communication:\r
+\r
+The daemon communicates with other user processes through a named pipe.  The pipe name and message format is defined in ipcdef.hpp.\r
+\r
+The pipe name is "gptp-update".  An example is in the project named_pipe_test.\r
+\r
+The message format is:\r
+\r
+    Integer64  <master-local phase offset>\r
+    Integer64  <local-system phase offset>\r
+    Integer32  <master-local frequency offset>\r
+    Integer32  <local-system frequency offset>\r
+    UInteger64 <local time of last update>\r
+\r
+* Meaning of IPC provided values:\r
+\r
+       master  ~= local  - <master-local phase offset>\r
+       local   ~= system - <local-system phase offset>\r
+       Dmaster ~= Dlocal * (1-<master-local phase offset>/1e12)\r
+               (where D denotes a delta rather than a specific value)\r
+       Dlocal ~= Dsystem * (1-<local-system freq offset>/1e12)\r
+               (where D denotes a delta rather than a specific value)\r
+\r
+* Known Limitations:\r
+\r
+       * There are problems with timestamp accuracy create problems using switches that impose limits on the peer rate offset\r
+       * The current driver version does not allow timestamping between the system clock (e.g. TCS) and the network device clock;\r
+               systems offsets are not valid\r
+\r
+\r
diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.cpp b/daemons/gptp/windows/daemon_cl/daemon_cl.cpp
new file mode 100644 (file)
index 0000000..146d0d2
--- /dev/null
@@ -0,0 +1,124 @@
+/******************************************************************************\r
+\r
+  Copyright (c) 2009-2012, Intel Corporation \r
+  All rights reserved.\r
+  \r
+  Redistribution and use in source and binary forms, with or without \r
+  modification, are permitted provided that the following conditions are met:\r
+  \r
+   1. Redistributions of source code must retain the above copyright notice, \r
+      this list of conditions and the following disclaimer.\r
+  \r
+   2. Redistributions in binary form must reproduce the above copyright \r
+      notice, this list of conditions and the following disclaimer in the \r
+      documentation and/or other materials provided with the distribution.\r
+  \r
+   3. Neither the name of the Intel Corporation nor the names of its \r
+      contributors may be used to endorse or promote products derived from \r
+      this software without specific prior written permission.\r
+  \r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+  POSSIBILITY OF SUCH DAMAGE.\r
+\r
+******************************************************************************/\r
+\r
+\r
+#include "ieee1588.hpp"\r
+#include "avbts_clock.hpp"\r
+#include "avbts_osnet.hpp"\r
+#include "avbts_oslock.hpp"\r
+#include "windows_hal.hpp"\r
+#include <tchar.h>\r
+\r
+#define MACSTR_LENGTH 17\r
+\r
+static bool exit_flag;\r
+\r
+BOOL WINAPI ctrl_handler( DWORD ctrl_type ) {\r
+    bool ret;\r
+    if( ctrl_type == CTRL_C_EVENT ) {\r
+        exit_flag = true;\r
+        ret = true;\r
+    } else {\r
+        ret = false;\r
+    }\r
+    return ret;\r
+}\r
+\r
+int parseMacAddr( _TCHAR *macstr, uint8_t *octet_string ) {\r
+    int i;\r
+    _TCHAR *cur = macstr;\r
+\r
+    if( strnlen_s( macstr, MACSTR_LENGTH ) != 17 ) return -1;\r
+\r
+    for( i = 0; i < ETHER_ADDR_OCTETS; ++i ) {\r
+        octet_string[i] = strtol( cur, &cur, 16 ) & 0xFF;\r
+        ++cur;\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+int _tmain(int argc, _TCHAR* argv[])\r
+{\r
+    bool force_slave = false;\r
+    int32_t offset = 0;\r
+    bool syntonize = false;\r
+\r
+    // Register default network interface\r
+    WindowsPCAPNetworkInterfaceFactory *default_factory = new WindowsPCAPNetworkInterfaceFactory();\r
+    OSNetworkInterfaceFactory::registerFactory( factory_name_t( "default" ), default_factory );\r
+\r
+    // Create thread, lock, timer, timerq factories\r
+    WindowsThreadFactory *thread_factory = new WindowsThreadFactory();\r
+    WindowsTimerQueueFactory *timerq_factory = new WindowsTimerQueueFactory();\r
+    WindowsLockFactory *lock_factory = new WindowsLockFactory();\r
+    WindowsTimerFactory *timer_factory = new WindowsTimerFactory();\r
+    WindowsConditionFactory *condition_factory = new WindowsConditionFactory();\r
+    WindowsNamedPipeIPC *ipc = new WindowsNamedPipeIPC();\r
+    if( !ipc->init() ) {\r
+        delete ipc;\r
+        ipc = NULL;\r
+    }\r
+\r
+    // Create Low level network interface object\r
+    uint8_t local_addr_ostr[ETHER_ADDR_OCTETS];\r
+    if( argc < 2 ) return -1;\r
+    parseMacAddr( argv[1], local_addr_ostr );\r
+    LinkLayerAddress local_addr(local_addr_ostr);\r
+    \r
+    // Create Clock object\r
+    IEEE1588Clock *clock = new IEEE1588Clock( false, timerq_factory, ipc );  // Do not force slave\r
+    // Create HWTimestamper object\r
+    HWTimestamper *timestamper = new WindowsTimestamper();\r
+    // Create Port Object linked to clock and low level\r
+    IEEE1588Port *port = new IEEE1588Port( clock, 1, false, timestamper, false, 0, &local_addr,\r
+                                            condition_factory, thread_factory, timer_factory, lock_factory );\r
+    if( !port->init_port() ) {\r
+        printf( "Failed to initialize port\n" );\r
+        return -1;\r
+    }\r
+    port->processEvent( POWERUP );\r
+\r
+    // Wait for Ctrl-C\r
+    if( !SetConsoleCtrlHandler( ctrl_handler, true )) {\r
+        printf( "Unable to register Ctrl-C handler\n" );\r
+        return -1;\r
+    }\r
+\r
+    while( !exit_flag ) Sleep( 1200 );\r
+\r
+    delete( ipc );\r
+\r
+    return 0;\r
+}\r
+\r
diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj b/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj
new file mode 100644 (file)
index 0000000..9473646
--- /dev/null
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{590D3055-A068-4B31-B4F9-B2ACC5F93663}</ProjectGuid>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <RootNamespace>daemon_cl</RootNamespace>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v110</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v110</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v110</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v110</PlatformToolset>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <PrecompiledHeader>Use</PrecompiledHeader>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories>C:\Users\John\src\pcap\Include;C:\Users\John\src\gptp\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalLibraryDirectories>C:\Users\John\src\pcap\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <ClCompile>\r
+      <PrecompiledHeader>Use</PrecompiledHeader>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories>C:\Users\John\src\pcap\Include;C:\Users\John\src\gptp\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <AdditionalLibraryDirectories>C:\Users\John\src\pcap\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories>C:\Users\John\src\pcap\Include;C:\Users\John\src\gptp\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <AdditionalLibraryDirectories>C:\Users\John\src\pcap\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
+      <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories>C:\Users\John\src\pcap\Include;$(SolutionDir)\daemon_cl\;..\..\..\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <AdditionalLibraryDirectories>C:\Users\John\src\pcap\Lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
+      <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <GenerateMapFile>true</GenerateMapFile>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <None Include="ReadMe.txt" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="..\..\..\common\avbts_clock.hpp" />\r
+    <ClInclude Include="..\..\..\common\avbts_message.hpp" />\r
+    <ClInclude Include="..\..\..\common\avbts_oscondition.hpp" />\r
+    <ClInclude Include="..\..\..\common\avbts_osipc.hpp" />\r
+    <ClInclude Include="..\..\..\common\avbts_oslock.hpp" />\r
+    <ClInclude Include="..\..\..\common\avbts_osnet.hpp" />\r
+    <ClInclude Include="..\..\..\common\avbts_osthread.hpp" />\r
+    <ClInclude Include="..\..\..\common\avbts_ostimer.hpp" />\r
+    <ClInclude Include="..\..\..\common\avbts_ostimerq.hpp" />\r
+    <ClInclude Include="..\..\..\common\avbts_port.hpp" />\r
+    <ClInclude Include="..\..\..\common\ieee1588.hpp" />\r
+    <ClInclude Include="ipcdef.hpp" />\r
+    <ClInclude Include="packet.hpp" />\r
+    <ClInclude Include="platform.hpp" />\r
+    <ClInclude Include="stdafx.h" />\r
+    <ClInclude Include="targetver.h" />\r
+    <ClInclude Include="tsc.hpp" />\r
+    <ClInclude Include="windows_hal.hpp" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\..\common\avbts_osnet.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\common\ieee1588clock.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\common\ieee1588port.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\common\ptp_message.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="daemon_cl.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="packet.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+    </ClCompile>\r
+    <ClCompile Include="stdafx.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.filters b/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.filters
new file mode 100644 (file)
index 0000000..09509ef
--- /dev/null
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="ReadMe.txt" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="stdafx.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="targetver.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\ieee1588.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_clock.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_message.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_osnet.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_port.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_oslock.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_ostimer.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="windows_hal.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_osthread.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="packet.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_oscondition.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_ostimerq.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\common\avbts_osipc.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="ipcdef.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="platform.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="tsc.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="stdafx.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="daemon_cl.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\common\ieee1588port.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\common\ieee1588clock.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\common\ptp_message.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\..\..\common\avbts_osnet.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="packet.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.user b/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.user
new file mode 100644 (file)
index 0000000..145a860
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <LocalDebuggerCommandArguments>88-88-88-88-87-88</LocalDebuggerCommandArguments>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <LocalDebuggerCommandArguments>00-13-20-F8-84-41</LocalDebuggerCommandArguments>\r
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>\r
+  </PropertyGroup>\r
+</Project>
\ No newline at end of file
diff --git a/daemons/gptp/windows/daemon_cl/ipcdef.hpp b/daemons/gptp/windows/daemon_cl/ipcdef.hpp
new file mode 100644 (file)
index 0000000..4ac3e32
--- /dev/null
@@ -0,0 +1,88 @@
+/******************************************************************************\r
+\r
+  Copyright (c) 2009-2012, Intel Corporation \r
+  All rights reserved.\r
+  \r
+  Redistribution and use in source and binary forms, with or without \r
+  modification, are permitted provided that the following conditions are met:\r
+  \r
+   1. Redistributions of source code must retain the above copyright notice, \r
+      this list of conditions and the following disclaimer.\r
+  \r
+   2. Redistributions in binary form must reproduce the above copyright \r
+      notice, this list of conditions and the following disclaimer in the \r
+      documentation and/or other materials provided with the distribution.\r
+  \r
+   3. Neither the name of the Intel Corporation nor the names of its \r
+      contributors may be used to endorse or promote products derived from \r
+      this software without specific prior written permission.\r
+  \r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+  POSSIBILITY OF SUCH DAMAGE.\r
+\r
+******************************************************************************/\r
+\r
+\r
+#ifndef IPCDEF_HPP\r
+#define IPCDEF_HPP\r
+\r
+#include <stdint.h>\r
+\r
+#define PIPE_PREFIX "\\\\.\\pipe\\"\r
+#define P802_1AS_PIPENAME "gptp-update"\r
+#define OUTSTANDING_MESSAGES 10\r
+\r
+#pragma pack(push,1)\r
+\r
+class WindowsNPipeMessage {\r
+private:\r
+    int64_t ml_phoffset;\r
+    int64_t ls_phoffset;\r
+    int32_t ml_freqoffset;\r
+    int32_t ls_freq_offset;\r
+    uint64_t local_time;\r
+public:\r
+    WindowsNPipeMessage() {};\r
+    WindowsNPipeMessage( int64_t ml_phoffset, int64_t ls_phoffset, int32_t ml_freqoffset, int32_t ls_freq_offset, uint64_t local_time ) {\r
+        this->ml_phoffset = ml_phoffset;\r
+        this->ls_phoffset = ls_phoffset;\r
+        this->ml_freqoffset = ml_freqoffset;\r
+        this->ls_freq_offset = ls_freq_offset;\r
+        this->local_time = local_time;\r
+\r
+    }\r
+    bool write( HANDLE pipe ) {\r
+        DWORD bytes_written;\r
+        DWORD last_error = ERROR_SUCCESS;\r
+        if( WriteFile( pipe, this, sizeof(*this), &bytes_written, NULL ) == 0 ) {\r
+            last_error = GetLastError();\r
+        }\r
+        if( last_error == ERROR_SUCCESS || last_error == ERROR_PIPE_LISTENING ) {\r
+            return true;\r
+        }\r
+        return false;\r
+    }\r
+    bool read( HANDLE pipe ) {\r
+        DWORD bytes_written;\r
+        if( ReadFile( pipe, this, sizeof(*this), &bytes_written, NULL ) == 0 ) return false;\r
+        return true;\r
+    }\r
+    int64_t getMasterLocalOffset() { return ml_phoffset; }\r
+    int32_t getMasterLocalFreqOffset() { return ml_freqoffset; }\r
+    int64_t getLocalSystemOffset() { return ls_phoffset; }\r
+    int32_t getLocalSystemFreqOffset() { return ls_freq_offset; }\r
+    uint64_t getLocalTime() { return local_time; }\r
+};\r
+\r
+#pragma pack(pop)\r
+\r
+#endif\r
diff --git a/daemons/gptp/windows/daemon_cl/packet.cpp b/daemons/gptp/windows/daemon_cl/packet.cpp
new file mode 100644 (file)
index 0000000..dea9138
--- /dev/null
@@ -0,0 +1,207 @@
+/******************************************************************************\r
+\r
+  Copyright (c) 2009-2012, Intel Corporation \r
+  All rights reserved.\r
+  \r
+  Redistribution and use in source and binary forms, with or without \r
+  modification, are permitted provided that the following conditions are met:\r
+  \r
+   1. Redistributions of source code must retain the above copyright notice, \r
+      this list of conditions and the following disclaimer.\r
+  \r
+   2. Redistributions in binary form must reproduce the above copyright \r
+      notice, this list of conditions and the following disclaimer in the \r
+      documentation and/or other materials provided with the distribution.\r
+  \r
+   3. Neither the name of the Intel Corporation nor the names of its \r
+      contributors may be used to endorse or promote products derived from \r
+      this software without specific prior written permission.\r
+  \r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+  POSSIBILITY OF SUCH DAMAGE.\r
+\r
+******************************************************************************/\r
+\r
+\r
+#include "packet.hpp"\r
+#include "platform.hpp"\r
+\r
+#include <pcap.h>\r
+#include "iphlpapi.h"\r
+\r
+#define MAX_FRAME_SIZE 96\r
+\r
+#define WINPCAP_INTERFACENAMEPREFIX "rpcap://\\Device\\NPF_"\r
+#define WINPCAP_INTERFACENAMEPREFIX_LENGTH 20\r
+#define WINPCAP_INTERFACENAMESUFFIX_LENGTH 38\r
+#define WINPCAP_INTERFACENAME_LENGTH WINPCAP_INTERFACENAMEPREFIX_LENGTH+WINPCAP_INTERFACENAMESUFFIX_LENGTH\r
+\r
+struct packet_handle {\r
+    pcap_t *iface;\r
+    char errbuf[PCAP_ERRBUF_SIZE];\r
+    packet_addr_t iface_addr;\r
+    HANDLE capture_lock;\r
+    uint16_t ethertype;\r
+    struct bpf_program filter;\r
+};\r
+\r
+\r
+packet_error_t mallocPacketHandle( struct packet_handle **phandle ) {\r
+    packet_error_t ret = PACKET_NO_ERROR;\r
+\r
+    packet_handle *handle = (struct packet_handle *) malloc((size_t) sizeof( *handle ));\r
+    if( handle == NULL ) {\r
+        ret = PACKET_NOMEMORY_ERROR;\r
+        goto fnexit;\r
+    }\r
+    *phandle = handle;\r
+\r
+    if(( handle->capture_lock = CreateMutex( NULL, FALSE, NULL )) == NULL ) {\r
+        ret = PACKET_CREATEMUTEX_ERROR;\r
+        goto fnexit;\r
+    }\r
+    handle->iface = NULL;\r
+\r
+fnexit:\r
+    return ret;\r
+}\r
+\r
+void freePacketHandle( struct packet_handle *handle ) {\r
+    CloseHandle( handle->capture_lock );\r
+    free((void *) handle );\r
+}\r
+\r
+packet_error_t openInterfaceByAddr( struct packet_handle *handle, packet_addr_t *addr, int timeout ) {\r
+    packet_error_t ret = PACKET_NO_ERROR;\r
+    char name[WINPCAP_INTERFACENAME_LENGTH+1] = "\0";\r
+\r
+    PIP_ADAPTER_ADDRESSES pAdapterAddress;\r
+    IP_ADAPTER_ADDRESSES AdapterAddress[32];       // Allocate information for up to 32 NICs\r
+    DWORD dwBufLen = sizeof(AdapterAddress);  // Save memory size of buffer\r
+\r
+    DWORD dwStatus = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, AdapterAddress, &dwBufLen);\r
+\r
+    if( dwStatus != ERROR_SUCCESS ) {\r
+        ret = PACKET_IFLOOKUP_ERROR;\r
+        goto fnexit;\r
+    }\r
+\r
+    for( pAdapterAddress = AdapterAddress; pAdapterAddress != NULL; pAdapterAddress = pAdapterAddress->Next ) {\r
+        if( pAdapterAddress->PhysicalAddressLength == ETHER_ADDR_OCTETS &&\r
+            memcmp( pAdapterAddress->PhysicalAddress, addr->addr, ETHER_ADDR_OCTETS ) == 0 ) {\r
+            break;\r
+        }\r
+    }\r
+\r
+    if( pAdapterAddress != NULL ) {\r
+        strcpy_s( name, WINPCAP_INTERFACENAMEPREFIX );\r
+        strncpy_s( name+WINPCAP_INTERFACENAMEPREFIX_LENGTH, WINPCAP_INTERFACENAMESUFFIX_LENGTH+1, pAdapterAddress->AdapterName, WINPCAP_INTERFACENAMESUFFIX_LENGTH );\r
+        printf( "Opening: %s\n", name );\r
+        handle->iface = pcap_open(  name, MAX_FRAME_SIZE, PCAP_OPENFLAG_MAX_RESPONSIVENESS | PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_NOCAPTURE_LOCAL,\r
+                                    timeout, NULL, handle->errbuf );\r
+        if( handle->iface == NULL ) {\r
+            ret = PACKET_IFLOOKUP_ERROR;\r
+            goto fnexit;\r
+        }\r
+        handle->iface_addr = *addr;\r
+    } else {\r
+        ret = PACKET_IFNOTFOUND_ERROR;\r
+        goto fnexit;\r
+    }\r
+\r
+fnexit:\r
+    return ret;\r
+}\r
+\r
+void closeInterface( struct packet_handle *pfhandle ) {\r
+    if( pfhandle->iface != NULL ) pcap_close( pfhandle->iface );\r
+}\r
+\r
+\r
+packet_error_t sendFrame( struct packet_handle *handle, packet_addr_t *addr, uint16_t ethertype, uint8_t *payload, size_t length ) {\r
+    packet_error_t ret = PACKET_NO_ERROR;\r
+    uint16_t ethertype_no = PLAT_htons( ethertype );\r
+    uint8_t *payload_ptr = payload;\r
+\r
+    if( length < PACKET_HDR_LENGTH ) {\r
+        ret = PACKET_BADBUFFER_ERROR;\r
+    }\r
+\r
+    // Build Header\r
+    memcpy( payload_ptr, addr->addr, ETHER_ADDR_OCTETS ); payload_ptr+= ETHER_ADDR_OCTETS;\r
+    memcpy( payload_ptr, handle->iface_addr.addr, ETHER_ADDR_OCTETS ); payload_ptr+= ETHER_ADDR_OCTETS;\r
+    memcpy( payload_ptr, &ethertype_no, sizeof( ethertype_no ));\r
+\r
+    if( pcap_sendpacket( handle->iface, payload, (int) length+PACKET_HDR_LENGTH ) != 0 ) {\r
+        ret = PACKET_XMIT_ERROR;\r
+        goto fnexit;\r
+    }\r
+\r
+fnexit:\r
+    return ret;\r
+}\r
+\r
+packet_error_t packetBind( struct packet_handle *handle, uint16_t ethertype ) {\r
+    packet_error_t ret = PACKET_NO_ERROR;\r
+    char filter_expression[32] = "ether proto 0x";\r
+\r
+    sprintf_s( filter_expression+strlen(filter_expression), 31-strlen(filter_expression), "%hx", ethertype );\r
+    if( pcap_compile( handle->iface, &handle->filter, filter_expression, 1, 0 ) == -1 ) {\r
+        ret = PACKET_BIND_ERROR;\r
+        goto fnexit;\r
+    }\r
+    if( pcap_setfilter( handle->iface, &handle->filter ) == -1 ) {\r
+        ret = PACKET_BIND_ERROR;\r
+        goto fnexit;\r
+    }\r
+\r
+    handle->ethertype = ethertype;\r
+\r
+fnexit:\r
+    return ret;\r
+}\r
+\r
+// Call to recvFrame must be thread-safe.  However call to pcap_next_ex() isn't because of somewhat undefined memory management semantics.\r
+// Wrap call to pcap library with mutex\r
+packet_error_t recvFrame( struct packet_handle *handle, packet_addr_t *addr, uint8_t *payload, size_t &length ) {\r
+    packet_error_t ret = PACKET_NO_ERROR;\r
+    struct pcap_pkthdr *hdr_r;\r
+    u_char *data;\r
+\r
+    int pcap_result;\r
+    DWORD wait_result;\r
+\r
+    wait_result = WaitForSingleObject( handle->capture_lock, 1000 );\r
+    if( wait_result != WAIT_OBJECT_0 ) {\r
+        ret = PACKET_GETMUTEX_ERROR;\r
+        goto fnexit;\r
+    }\r
+\r
+    pcap_result = pcap_next_ex( handle->iface, &hdr_r, (const u_char **) &data );\r
+    if( pcap_result == 0 ) {\r
+        ret = PACKET_RECVTIMEOUT_ERROR;\r
+    } else if( pcap_result < 0 ) {\r
+        ret = PACKET_RECVFAILED_ERROR;\r
+    } else {\r
+        length = hdr_r->len-PACKET_HDR_LENGTH >= length ? length : hdr_r->len-PACKET_HDR_LENGTH;\r
+        memcpy( payload, data+PACKET_HDR_LENGTH, length );\r
+        memcpy( addr->addr, data+ETHER_ADDR_OCTETS, ETHER_ADDR_OCTETS );\r
+    }\r
+    \r
+    if( !ReleaseMutex( handle->capture_lock )) {\r
+        ret = PACKET_RLSMUTEX_ERROR;\r
+        goto fnexit;\r
+    }\r
+\r
+fnexit:\r
+    return ret;\r
+}\r
diff --git a/daemons/gptp/windows/daemon_cl/packet.hpp b/daemons/gptp/windows/daemon_cl/packet.hpp
new file mode 100644 (file)
index 0000000..3e08051
--- /dev/null
@@ -0,0 +1,62 @@
+/******************************************************************************\r
+\r
+  Copyright (c) 2009-2012, Intel Corporation \r
+  All rights reserved.\r
+  \r
+  Redistribution and use in source and binary forms, with or without \r
+  modification, are permitted provided that the following conditions are met:\r
+  \r
+   1. Redistributions of source code must retain the above copyright notice, \r
+      this list of conditions and the following disclaimer.\r
+  \r
+   2. Redistributions in binary form must reproduce the above copyright \r
+      notice, this list of conditions and the following disclaimer in the \r
+      documentation and/or other materials provided with the distribution.\r
+  \r
+   3. Neither the name of the Intel Corporation nor the names of its \r
+      contributors may be used to endorse or promote products derived from \r
+      this software without specific prior written permission.\r
+  \r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+  POSSIBILITY OF SUCH DAMAGE.\r
+\r
+******************************************************************************/\r
+\r
+\r
+#ifndef PACKET_H\r
+#define PACKET_H\r
+\r
+#include "stdint.h"\r
+\r
+#define ETHER_ADDR_OCTETS 6\r
+#define PACKET_HDR_LENGTH 14\r
+\r
+typedef enum {\r
+    PACKET_NO_ERROR = 0, PACKET_NOMEMORY_ERROR, PACKET_BADBUFFER_ERROR, PACKET_XMIT_ERROR, PACKET_IFLOOKUP_ERROR, PACKET_IFNOTFOUND_ERROR,\r
+    PACKET_CREATEMUTEX_ERROR, PACKET_GETMUTEX_ERROR, PACKET_RLSMUTEX_ERROR, PACKET_RECVTIMEOUT_ERROR, PACKET_RECVFAILED_ERROR,\r
+    PACKET_BIND_ERROR\r
+} packet_error_t; \r
+\r
+typedef struct { uint8_t addr[ETHER_ADDR_OCTETS]; } packet_addr_t;\r
+typedef struct packet_handle * pfhandle_t;\r
+\r
+packet_error_t mallocPacketHandle( pfhandle_t *pfhandle_r );\r
+void freePacketHandle( pfhandle_t pfhandle );\r
+\r
+packet_error_t openInterfaceByAddr( pfhandle_t pfhandle, packet_addr_t *addr, int timeout );\r
+void closeInterface( pfhandle_t pfhandle );\r
+packet_error_t sendFrame( pfhandle_t pfhandle, packet_addr_t *addr, uint16_t ethertype, uint8_t *payload, size_t length );\r
+packet_error_t recvFrame( pfhandle_t pfhandle, packet_addr_t *addr,                     uint8_t *payload, size_t &length );\r
+\r
+packet_error_t packetBind( struct packet_handle *handle, uint16_t ethertype );\r
+\r
+#endif /* PACKET_H */\r
diff --git a/daemons/gptp/windows/daemon_cl/platform.hpp b/daemons/gptp/windows/daemon_cl/platform.hpp
new file mode 100644 (file)
index 0000000..bbd0fd0
--- /dev/null
@@ -0,0 +1,46 @@
+/******************************************************************************\r
+\r
+  Copyright (c) 2009-2012, Intel Corporation \r
+  All rights reserved.\r
+  \r
+  Redistribution and use in source and binary forms, with or without \r
+  modification, are permitted provided that the following conditions are met:\r
+  \r
+   1. Redistributions of source code must retain the above copyright notice, \r
+      this list of conditions and the following disclaimer.\r
+  \r
+   2. Redistributions in binary form must reproduce the above copyright \r
+      notice, this list of conditions and the following disclaimer in the \r
+      documentation and/or other materials provided with the distribution.\r
+  \r
+   3. Neither the name of the Intel Corporation nor the names of its \r
+      contributors may be used to endorse or promote products derived from \r
+      this software without specific prior written permission.\r
+  \r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+  POSSIBILITY OF SUCH DAMAGE.\r
+\r
+******************************************************************************/\r
+\r
+#ifndef PLATFORM_HPP\r
+#define PLATFORM_HPP\r
+\r
+#include <Winsock2.h>\r
+\r
+#define PLAT_strncpy( dest, src, max ) strncpy_s( dest, max+1, src, _TRUNCATE );\r
+\r
+#define PLAT_htons( s ) htons( s )\r
+#define PLAT_htonl( l ) htonl( l )\r
+#define PLAT_ntohs( s ) ntohs( s )\r
+#define PLAT_ntohl( l ) ntohl( l )\r
+\r
+#endif\r
diff --git a/daemons/gptp/windows/daemon_cl/stdafx.cpp b/daemons/gptp/windows/daemon_cl/stdafx.cpp
new file mode 100644 (file)
index 0000000..a3275bf
--- /dev/null
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes\r
+// daemon_cl.pch will be the pre-compiled header\r
+// stdafx.obj will contain the pre-compiled type information\r
+\r
+#include "stdafx.h"\r
+\r
+// TODO: reference any additional headers you need in STDAFX.H\r
+// and not in this file\r
diff --git a/daemons/gptp/windows/daemon_cl/stdafx.h b/daemons/gptp/windows/daemon_cl/stdafx.h
new file mode 100644 (file)
index 0000000..47a0d02
--- /dev/null
@@ -0,0 +1,15 @@
+// stdafx.h : include file for standard system include files,\r
+// or project specific include files that are used frequently, but\r
+// are changed infrequently\r
+//\r
+\r
+#pragma once\r
+\r
+#include "targetver.h"\r
+\r
+#include <stdio.h>\r
+#include <tchar.h>\r
+\r
+\r
+\r
+// TODO: reference additional headers your program requires here\r
diff --git a/daemons/gptp/windows/daemon_cl/targetver.h b/daemons/gptp/windows/daemon_cl/targetver.h
new file mode 100644 (file)
index 0000000..90e767b
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once\r
+\r
+// Including SDKDDKVer.h defines the highest available Windows platform.\r
+\r
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and\r
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.\r
+\r
+#include <SDKDDKVer.h>\r
diff --git a/daemons/gptp/windows/daemon_cl/tsc.hpp b/daemons/gptp/windows/daemon_cl/tsc.hpp
new file mode 100644 (file)
index 0000000..9484a09
--- /dev/null
@@ -0,0 +1,65 @@
+/******************************************************************************\r
+\r
+  Copyright (c) 2009-2012, Intel Corporation \r
+  All rights reserved.\r
+  \r
+  Redistribution and use in source and binary forms, with or without \r
+  modification, are permitted provided that the following conditions are met:\r
+  \r
+   1. Redistributions of source code must retain the above copyright notice, \r
+      this list of conditions and the following disclaimer.\r
+  \r
+   2. Redistributions in binary form must reproduce the above copyright \r
+      notice, this list of conditions and the following disclaimer in the \r
+      documentation and/or other materials provided with the distribution.\r
+  \r
+   3. Neither the name of the Intel Corporation nor the names of its \r
+      contributors may be used to endorse or promote products derived from \r
+      this software without specific prior written permission.\r
+  \r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+  POSSIBILITY OF SUCH DAMAGE.\r
+\r
+******************************************************************************/\r
+\r
+#ifndef TSC_HPP\r
+#define TSC_HPP\r
+\r
+#include <intrin.h>\r
+#include <stdint.h>\r
+\r
+#define CPUFREQ_BASE 133\r
+\r
+inline unsigned __int64 PLAT_rdtsc()\r
+{\r
+  return __rdtsc();\r
+}\r
+\r
+// 'millis' argument specifies time to measure TSC over.  A longer time is generally more reliable\r
+// Returns TSC frequency\r
+inline uint64_t getTSCFrequency( unsigned millis ) {\r
+       uint64_t tsc1, tsc2, multiplier;\r
+       unsigned msig, lsig;\r
+\r
+       tsc1 = PLAT_rdtsc();\r
+       Sleep( millis );\r
+       tsc2 = PLAT_rdtsc();\r
+       multiplier = (unsigned) (tsc2 - tsc1)/133;\r
+       lsig = multiplier % 1000000;\r
+       msig = (unsigned) multiplier / 1000000;\r
+       if( lsig >= 750000 ) multiplier = (msig+1)*1000000;\r
+       else if( lsig < 250000 ) multiplier = msig*1000000;\r
+       else multiplier = msig*1000000 + 500000;\r
+       return multiplier*CPUFREQ_BASE;\r
+}\r
+\r
+#endif/*TSC_HPP*/\r
diff --git a/daemons/gptp/windows/daemon_cl/windows_hal.hpp b/daemons/gptp/windows/daemon_cl/windows_hal.hpp
new file mode 100644 (file)
index 0000000..fdb1172
--- /dev/null
@@ -0,0 +1,576 @@
+/******************************************************************************\r
+\r
+  Copyright (c) 2009-2012, Intel Corporation \r
+  All rights reserved.\r
+  \r
+  Redistribution and use in source and binary forms, with or without \r
+  modification, are permitted provided that the following conditions are met:\r
+  \r
+   1. Redistributions of source code must retain the above copyright notice, \r
+      this list of conditions and the following disclaimer.\r
+  \r
+   2. Redistributions in binary form must reproduce the above copyright \r
+      notice, this list of conditions and the following disclaimer in the \r
+      documentation and/or other materials provided with the distribution.\r
+  \r
+   3. Neither the name of the Intel Corporation nor the names of its \r
+      contributors may be used to endorse or promote products derived from \r
+      this software without specific prior written permission.\r
+  \r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+  POSSIBILITY OF SUCH DAMAGE.\r
+\r
+******************************************************************************/\r
+\r
+#ifndef WINDOWS_HAL_HPP\r
+#define WINDOWS_HAL_HPP\r
+\r
+#include "avbts_osnet.hpp"\r
+#include "avbts_oslock.hpp"\r
+#include "avbts_oscondition.hpp"\r
+#include "avbts_ostimerq.hpp"\r
+#include "avbts_ostimer.hpp"\r
+#include "packet.hpp"\r
+#include "ieee1588.hpp"\r
+#include "iphlpapi.h"\r
+#include "ipcdef.hpp"\r
+#include "tsc.hpp"\r
+\r
+#include "avbts_osipc.hpp"\r
+\r
+#include <ntddndis.h>\r
+\r
+#include <map>\r
+\r
+class WindowsPCAPNetworkInterface : public OSNetworkInterface {\r
+    friend class WindowsPCAPNetworkInterfaceFactory;\r
+private:\r
+    pfhandle_t handle;\r
+    LinkLayerAddress local_addr;\r
+public:\r
+    virtual net_result send( LinkLayerAddress *addr, uint8_t *payload, size_t length, bool timestamp ) {\r
+        packet_addr_t dest;\r
+        addr->toOctetArray( dest.addr );\r
+        if( sendFrame( handle, &dest, PTP_ETHERTYPE, payload, length ) != PACKET_NO_ERROR ) return net_fatal;\r
+        return net_succeed;\r
+    }\r
+    virtual net_result recv( LinkLayerAddress *addr, uint8_t *payload, size_t &length ) {\r
+        packet_addr_t dest;\r
+        packet_error_t pferror = recvFrame( handle, &dest, payload, length );\r
+        if( pferror != PACKET_NO_ERROR && pferror != PACKET_RECVTIMEOUT_ERROR ) return net_fatal;\r
+        if( pferror == PACKET_RECVTIMEOUT_ERROR ) return net_trfail;\r
+        *addr = LinkLayerAddress( dest.addr );\r
+        return net_succeed;\r
+    }\r
+    virtual void getLinkLayerAddress( LinkLayerAddress *addr ) {\r
+        *addr = local_addr;\r
+    }\r
+    virtual unsigned getPayloadOffset() {\r
+        return PACKET_HDR_LENGTH;\r
+    }\r
+    virtual ~WindowsPCAPNetworkInterface() {\r
+        closeInterface( handle );\r
+        if( handle != NULL ) freePacketHandle( handle );\r
+    }\r
+protected:\r
+    WindowsPCAPNetworkInterface() { handle = NULL; };\r
+};\r
+\r
+class WindowsPCAPNetworkInterfaceFactory : public OSNetworkInterfaceFactory {\r
+public:\r
+    virtual bool createInterface( OSNetworkInterface **net_iface, InterfaceLabel *label, HWTimestamper *timestamper ) {\r
+        WindowsPCAPNetworkInterface *net_iface_l = new WindowsPCAPNetworkInterface();\r
+        LinkLayerAddress *addr = dynamic_cast<LinkLayerAddress *>(label);\r
+        if( addr == NULL ) goto error_nofree;\r
+        net_iface_l->local_addr = *addr;\r
+        packet_addr_t pfaddr;\r
+        addr->toOctetArray( pfaddr.addr );\r
+        if( mallocPacketHandle( &net_iface_l->handle ) != PACKET_NO_ERROR ) goto error_nofree;\r
+        if( openInterfaceByAddr( net_iface_l->handle, &pfaddr, 1 ) != PACKET_NO_ERROR ) goto error_free_handle;\r
+        if( packetBind( net_iface_l->handle, PTP_ETHERTYPE ) != PACKET_NO_ERROR ) goto error_free_handle;\r
+        *net_iface = net_iface_l;\r
+\r
+        return true;\r
+\r
+error_free_handle:\r
+error_nofree:\r
+        delete net_iface_l;\r
+\r
+        return false;\r
+    }\r
+};\r
+\r
+class WindowsLock : public OSLock {\r
+    friend class WindowsLockFactory;\r
+private:\r
+    OSLockType type;\r
+    DWORD thread_id;\r
+    HANDLE lock_c;\r
+    OSLockResult lock_l( DWORD timeout ) {\r
+        DWORD wait_result = WaitForSingleObject( lock_c, timeout );\r
+        if( wait_result == WAIT_TIMEOUT ) return oslock_held;\r
+        else if( wait_result == WAIT_OBJECT_0 ) return oslock_ok;\r
+        else return oslock_fail;\r
+\r
+    }\r
+    OSLockResult nonreentrant_lock_l( DWORD timeout ) {\r
+        OSLockResult result;\r
+        DWORD wait_result;\r
+        wait_result = WaitForSingleObject( lock_c, timeout );\r
+        if( wait_result == WAIT_OBJECT_0 ) {\r
+            if( thread_id == GetCurrentThreadId() ) {\r
+                result = oslock_self;\r
+                ReleaseMutex( lock_c );\r
+            } else {\r
+                result = oslock_ok;\r
+                thread_id = GetCurrentThreadId();\r
+            }\r
+        } else if( wait_result == WAIT_TIMEOUT ) result = oslock_held;\r
+        else result = oslock_fail;\r
+        \r
+        return result;\r
+    }\r
+protected:\r
+    WindowsLock() {\r
+        lock_c = NULL;\r
+    }\r
+    bool initialize( OSLockType type ) {\r
+        lock_c = CreateMutex( NULL, false, NULL );\r
+        if( lock_c == NULL ) return false;\r
+        this->type = type;\r
+        return true;\r
+    }\r
+    OSLockResult lock() {\r
+        if( type == oslock_recursive ) {\r
+            return lock_l( INFINITE );\r
+        }\r
+        return nonreentrant_lock_l( INFINITE );\r
+    }\r
+    OSLockResult trylock() {\r
+        if( type == oslock_recursive ) {\r
+            return lock_l( 0 );\r
+        }\r
+        return nonreentrant_lock_l( 0 );\r
+    }\r
+    OSLockResult unlock() {\r
+        ReleaseMutex( lock_c );\r
+        return oslock_ok;\r
+    }\r
+};\r
+\r
+class WindowsLockFactory : public OSLockFactory {\r
+public:\r
+    OSLock *createLock( OSLockType type ) {\r
+        WindowsLock *lock = new WindowsLock();\r
+        if( !lock->initialize( type )) {\r
+            delete lock;\r
+            lock = NULL;\r
+        }\r
+        return lock;\r
+    }\r
+};\r
+\r
+class WindowsCondition : public OSCondition {\r
+    friend class WindowsConditionFactory;\r
+private:\r
+    SRWLOCK lock;\r
+    CONDITION_VARIABLE condition;\r
+protected:\r
+    bool initialize() {\r
+        InitializeSRWLock( &lock );\r
+        InitializeConditionVariable( &condition );\r
+        return true;\r
+    }\r
+public:\r
+    bool wait_prelock() {\r
+        AcquireSRWLockExclusive( &lock );\r
+        up();\r
+        return true;\r
+    }\r
+    bool wait() {\r
+        BOOL result = SleepConditionVariableSRW( &condition, &lock, INFINITE, 0 );\r
+        bool ret = false;\r
+        if( result == TRUE ) {\r
+            down();\r
+            ReleaseSRWLockExclusive( &lock );\r
+            ret = true;\r
+        }\r
+        return ret;\r
+    }\r
+    bool signal() {\r
+        AcquireSRWLockExclusive( &lock );\r
+        if( waiting() ) WakeAllConditionVariable( &condition );\r
+        ReleaseSRWLockExclusive( &lock );\r
+        return true;\r
+    }\r
+};\r
+\r
+class WindowsConditionFactory : public OSConditionFactory {\r
+public:\r
+    OSCondition *createCondition() {\r
+        WindowsCondition *result = new WindowsCondition();\r
+        return result->initialize() ? result : NULL;\r
+    }\r
+};\r
+\r
+class WindowsTimerQueue;\r
+\r
+struct TimerQueue_t;\r
+\r
+struct WindowsTimerQueueHandlerArg {\r
+    HANDLE timer_handle;\r
+    HANDLE queue_handle;\r
+    event_descriptor_t *inner_arg;\r
+    ostimerq_handler func;\r
+    int type;\r
+    bool rm;\r
+    WindowsTimerQueue *queue;\r
+    TimerQueue_t *timer_queue;\r
+};\r
+\r
+typedef std::list<WindowsTimerQueueHandlerArg *> TimerArgList_t;\r
+\r
+struct TimerQueue_t {\r
+    TimerArgList_t arg_list;\r
+    HANDLE queue_handle;\r
+    SRWLOCK lock;\r
+};\r
+\r
+\r
+VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore );\r
+\r
+typedef std::map<int,TimerQueue_t> TimerQueueMap_t;\r
+\r
+class WindowsTimerQueue : public OSTimerQueue {\r
+    friend class WindowsTimerQueueFactory;\r
+    friend VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore );\r
+private:\r
+    TimerQueueMap_t timerQueueMap;\r
+    TimerArgList_t retiredTimers;\r
+    SRWLOCK retiredTimersLock;\r
+    void cleanupRetiredTimers() {\r
+        AcquireSRWLockExclusive( &retiredTimersLock );\r
+        while( !retiredTimers.empty() ) {\r
+            WindowsTimerQueueHandlerArg *retired_arg = retiredTimers.front();\r
+            retiredTimers.pop_front();\r
+            ReleaseSRWLockExclusive( &retiredTimersLock );\r
+            DeleteTimerQueueTimer( retired_arg->queue_handle, retired_arg->timer_handle, INVALID_HANDLE_VALUE );\r
+            if( retired_arg->rm ) delete retired_arg->inner_arg;\r
+            delete retired_arg;\r
+            AcquireSRWLockExclusive( &retiredTimersLock );\r
+        }\r
+        ReleaseSRWLockExclusive( &retiredTimersLock );\r
+\r
+    }\r
+protected:\r
+    WindowsTimerQueue() {\r
+        InitializeSRWLock( &retiredTimersLock );\r
+    };\r
+public:\r
+    bool addEvent( unsigned long micros, int type, ostimerq_handler func, event_descriptor_t *arg, bool rm, unsigned *event ) {\r
+        WindowsTimerQueueHandlerArg *outer_arg = new WindowsTimerQueueHandlerArg();\r
+        cleanupRetiredTimers();\r
+        if( timerQueueMap.find(type) == timerQueueMap.end() ) {\r
+            timerQueueMap[type].queue_handle = CreateTimerQueue();\r
+            InitializeSRWLock( &timerQueueMap[type].lock );\r
+        }\r
+        outer_arg->queue_handle = timerQueueMap[type].queue_handle;\r
+        outer_arg->inner_arg = arg;\r
+        outer_arg->func = func;\r
+        outer_arg->queue = this;\r
+        outer_arg->type = type;\r
+        outer_arg->timer_queue = &timerQueueMap[type];\r
+        AcquireSRWLockExclusive( &timerQueueMap[type].lock );\r
+        CreateTimerQueueTimer( &outer_arg->timer_handle, timerQueueMap[type].queue_handle, WindowsTimerQueueHandler, (void *) outer_arg, micros/1000, 0, 0 );\r
+        timerQueueMap[type].arg_list.push_front(outer_arg);\r
+        ReleaseSRWLockExclusive( &timerQueueMap[type].lock );\r
+        return true;\r
+    }\r
+    bool cancelEvent( int type, unsigned *event ) {\r
+        TimerQueueMap_t::iterator iter = timerQueueMap.find( type );\r
+        if( iter == timerQueueMap.end() ) return false;\r
+        AcquireSRWLockExclusive( &timerQueueMap[type].lock );\r
+        while( ! timerQueueMap[type].arg_list.empty() ) {\r
+            WindowsTimerQueueHandlerArg *del_arg = timerQueueMap[type].arg_list.front();\r
+            timerQueueMap[type].arg_list.pop_front();\r
+            ReleaseSRWLockExclusive( &timerQueueMap[type].lock );\r
+            DeleteTimerQueueTimer( del_arg->queue_handle, del_arg->timer_handle, INVALID_HANDLE_VALUE );\r
+            if( del_arg->rm ) delete del_arg->inner_arg;\r
+            delete del_arg;\r
+            AcquireSRWLockExclusive( &timerQueueMap[type].lock );\r
+        }\r
+        ReleaseSRWLockExclusive( &timerQueueMap[type].lock );\r
+\r
+        return true;\r
+    }\r
+};\r
+\r
+VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore ) {\r
+    WindowsTimerQueueHandlerArg *arg = (WindowsTimerQueueHandlerArg *) arg_in;\r
+    arg->func( arg->inner_arg );\r
+\r
+    // Remove myself from unexpired timer queue\r
+    AcquireSRWLockExclusive( &arg->timer_queue->lock );\r
+    arg->timer_queue->arg_list.remove( arg );\r
+    ReleaseSRWLockExclusive( &arg->timer_queue->lock );\r
+\r
+    // Add myself to the expired timer queue\r
+    AcquireSRWLockExclusive( &arg->queue->retiredTimersLock );\r
+    arg->queue->retiredTimers.push_front( arg );\r
+    ReleaseSRWLockExclusive( &arg->queue->retiredTimersLock );\r
+}\r
+\r
+class WindowsTimerQueueFactory : public OSTimerQueueFactory {\r
+public:\r
+    virtual OSTimerQueue *createOSTimerQueue() {\r
+        WindowsTimerQueue *timerq = new WindowsTimerQueue();\r
+        return timerq;\r
+    };\r
+};\r
+\r
+class WindowsTimer : public OSTimer {\r
+    friend class WindowsTimerFactory;\r
+public:\r
+    virtual unsigned long sleep( unsigned long micros ) {\r
+        Sleep( micros/1000 );\r
+        return micros;\r
+    }\r
+protected:\r
+    WindowsTimer() {};\r
+};\r
+\r
+class WindowsTimerFactory : public OSTimerFactory {\r
+public:\r
+    virtual OSTimer *createTimer() {\r
+        return new WindowsTimer();\r
+    }\r
+};\r
+\r
+struct OSThreadArg {\r
+    OSThreadFunction func;\r
+    void *arg;\r
+    OSThreadExitCode ret;\r
+};\r
+\r
+DWORD WINAPI OSThreadCallback( LPVOID input ) {\r
+    OSThreadArg *arg = (OSThreadArg*) input;\r
+    arg->ret = arg->func( arg->arg );\r
+    return 0;\r
+}\r
+\r
+class WindowsThread : public OSThread {\r
+    friend class WindowsThreadFactory;\r
+private:\r
+    HANDLE thread_id;\r
+    OSThreadArg *arg_inner;\r
+public:\r
+    virtual bool start( OSThreadFunction function, void *arg ) {\r
+        arg_inner = new OSThreadArg();\r
+        arg_inner->func = function;\r
+        arg_inner->arg = arg;\r
+        thread_id = CreateThread( NULL, 0, OSThreadCallback, arg_inner, 0, NULL );\r
+        if( thread_id == NULL ) return false;\r
+        else return true;\r
+    }\r
+    virtual bool join( OSThreadExitCode &exit_code ) {\r
+        if( WaitForSingleObject( thread_id, INFINITE ) != WAIT_OBJECT_0 ) return false;\r
+        exit_code = arg_inner->ret;\r
+        delete arg_inner;\r
+        return true;\r
+    }\r
+protected:\r
+    WindowsThread() {};\r
+};\r
+\r
+class WindowsThreadFactory : public OSThreadFactory {\r
+public:\r
+    OSThread *createThread() {\r
+        return new WindowsThread();\r
+    }\r
+};\r
+\r
+#define NETCLOCK_HZ 1056000000\r
+#define ONE_WAY_PHY_DELAY 8000\r
+\r
+#define NETWORK_CARD_ID_PREFIX "\\\\.\\"\r
+#define OID_INTEL_GET_RXSTAMP 0xFF020264\r
+#define OID_INTEL_GET_TXSTAMP 0xFF020263\r
+#define OID_INTEL_GET_SYSTIM  0xFF020262\r
+#define OID_INTEL_SET_SYSTIM  0xFF020261\r
+\r
+class WindowsTimestamper : public HWTimestamper {\r
+private:\r
+    // No idea whether the underlying implementation is thread safe\r
+    HANDLE miniport;\r
+    LARGE_INTEGER tsc_hz;\r
+    DWORD readOID( NDIS_OID oid, void *output_buffer, DWORD size, DWORD *size_returned ) {\r
+        NDIS_OID oid_l = oid;\r
+        DWORD rc = DeviceIoControl(\r
+                       miniport,\r
+                       IOCTL_NDIS_QUERY_GLOBAL_STATS,\r
+                       &oid_l,\r
+                       sizeof(oid_l),\r
+                       output_buffer,\r
+            size,\r
+                       size_returned,\r
+                       NULL );\r
+        if( rc == 0 ) return GetLastError();\r
+        return ERROR_SUCCESS;\r
+    }\r
+    Timestamp nanoseconds64ToTimestamp( uint64_t time ) {\r
+        Timestamp timestamp;\r
+        timestamp.nanoseconds = time % 1000000000;\r
+        timestamp.seconds_ls = (time / 1000000000) & 0xFFFFFFFF;\r
+        timestamp.seconds_ms = (uint16_t)((time / 1000000000) >> 32);\r
+        return timestamp;\r
+    }\r
+    uint64_t scaleNativeClockToNanoseconds( uint64_t time ) {\r
+        long double scaled_output = ((long double)NETCLOCK_HZ)/1000000000;\r
+        scaled_output = ((long double) time)/scaled_output;\r
+        return (uint64_t) scaled_output;\r
+    }\r
+    uint64_t scaleTSCClockToNanoseconds( uint64_t time ) {\r
+        long double scaled_output = ((long double)tsc_hz.QuadPart)/1000000000;\r
+        scaled_output = ((long double) time)/scaled_output;\r
+        return (uint64_t) scaled_output;\r
+    }\r
+public:\r
+    virtual bool HWTimestamper_init( InterfaceLabel *iface_label ) {\r
+        char network_card_id[64];\r
+        LinkLayerAddress *addr = dynamic_cast<LinkLayerAddress *>(iface_label);\r
+        if( addr == NULL ) return false;\r
+        PIP_ADAPTER_ADDRESSES pAdapterAddress;\r
+        IP_ADAPTER_ADDRESSES AdapterAddress[32];       // Allocate information for up to 32 NICs\r
+        DWORD dwBufLen = sizeof(AdapterAddress);  // Save memory size of buffer\r
+\r
+        DWORD dwStatus = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, AdapterAddress, &dwBufLen);\r
+        if( dwStatus != ERROR_SUCCESS ) return false;\r
+\r
+        for( pAdapterAddress = AdapterAddress; pAdapterAddress != NULL; pAdapterAddress = pAdapterAddress->Next ) {\r
+            if( pAdapterAddress->PhysicalAddressLength == ETHER_ADDR_OCTETS && *addr == LinkLayerAddress( pAdapterAddress->PhysicalAddress )) { \r
+                break;\r
+            }\r
+        }\r
+\r
+        if( pAdapterAddress == NULL ) return false;\r
+\r
+        PLAT_strncpy( network_card_id, NETWORK_CARD_ID_PREFIX, 63 );\r
+        PLAT_strncpy( network_card_id+strlen(network_card_id), pAdapterAddress->AdapterName, 63-strlen(network_card_id) );\r
+\r
+        miniport = CreateFile( network_card_id,\r
+            GENERIC_READ | GENERIC_WRITE,\r
+            FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+            NULL, OPEN_EXISTING, 0, NULL );\r
+        if( miniport == INVALID_HANDLE_VALUE ) return false;\r
+\r
+        tsc_hz.QuadPart = getTSCFrequency( 1000 );\r
+\r
+        return true;\r
+    }\r
+    virtual bool HWTimestamper_gettime( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock, uint32_t *nominal_clock_rate )\r
+    {\r
+        DWORD buf[6];\r
+        DWORD returned;\r
+        uint64_t now_net, now_tsc;\r
+        DWORD result;\r
+\r
+        memset( buf, 0xFF, sizeof( buf ));\r
+        if(( result = readOID( OID_INTEL_GET_SYSTIM, buf, sizeof(buf), &returned )) != ERROR_SUCCESS ) return false;\r
+\r
+        now_net = (((uint64_t)buf[1]) << 32) | buf[0];\r
+        now_net = scaleNativeClockToNanoseconds( now_net );\r
+        *device_time = nanoseconds64ToTimestamp( now_net );\r
+\r
+        now_tsc = (((uint64_t)buf[3]) << 32) | buf[2];\r
+        now_tsc = scaleTSCClockToNanoseconds( now_tsc );\r
+        *system_time = nanoseconds64ToTimestamp( now_tsc );\r
+\r
+        return true;\r
+    }\r
+\r
+  virtual int HWTimestamper_txtimestamp( PortIdentity *identity, uint16_t sequenceId, Timestamp &timestamp, unsigned &clock_value, bool last )\r
+  {\r
+        DWORD buf[8], buf_tmp[8];\r
+        DWORD returned = 0;\r
+        uint64_t tx_r,tx_s;\r
+        DWORD result;\r
+        while(( result = readOID( OID_INTEL_GET_TXSTAMP, buf_tmp, sizeof(buf_tmp), &returned )) == ERROR_SUCCESS ) {\r
+            memcpy( buf, buf_tmp, sizeof( buf ));\r
+        }\r
+        if( result != ERROR_GEN_FAILURE ) return -1;\r
+        if( returned == 0 ) return -72;\r
+        tx_r = (((uint64_t)buf[1]) << 32) | buf[0];\r
+        tx_s = scaleNativeClockToNanoseconds( tx_r );\r
+        tx_s += ONE_WAY_PHY_DELAY;\r
+        timestamp = nanoseconds64ToTimestamp( tx_s );\r
+        //fprintf( stderr, "@@@SI,%hu,%u\n", sequenceId, buf[3] );\r
+        //fprintf( stderr, "@@TXR,%u,%u,%u,%hu,%llu,%hu,%hu\n", timestamp.seconds_ms, timestamp.seconds_ls,\r
+        //    timestamp.nanoseconds, 0, tx_r, sequenceId, buf[3] );\r
+\r
+        return 0;\r
+  }\r
+\r
+  virtual int HWTimestamper_rxtimestamp( PortIdentity *identity, uint16_t sequenceId, Timestamp &timestamp, unsigned &clock_value, bool last )\r
+  {\r
+        DWORD buf[4], buf_tmp[4];\r
+        DWORD returned;\r
+        uint64_t rx_r,rx_s;\r
+        DWORD result;\r
+        uint16_t packet_sequence_id;\r
+        while(( result = readOID( OID_INTEL_GET_RXSTAMP, buf_tmp, sizeof(buf_tmp), &returned )) == ERROR_SUCCESS ) {\r
+            memcpy( buf, buf_tmp, sizeof( buf ));\r
+        }\r
+        if( result != ERROR_GEN_FAILURE ) return -1;\r
+        if( returned == 0 ) return -72;\r
+        packet_sequence_id = *((uint32_t *) buf+3) >> 16;\r
+        if( PLAT_ntohs( packet_sequence_id ) != sequenceId ) return -72;\r
+        rx_r = (((uint64_t)buf[1]) << 32) | buf[0];\r
+        rx_s = scaleNativeClockToNanoseconds( rx_r );\r
+        rx_s -= ONE_WAY_PHY_DELAY;\r
+        timestamp = nanoseconds64ToTimestamp( rx_s );\r
+        //fprintf( stderr, "@@RXR,%u,%u,%u,%hu,%llu\n", timestamp.seconds_ms, timestamp.seconds_ls,\r
+        //   timestamp.nanoseconds, PLAT_ntohs(packet_sequence_id), rx_r );\r
+\r
+        return 0;\r
+  }\r
+};\r
+\r
+\r
+\r
+class WindowsNamedPipeIPC : public OS_IPC {\r
+private:\r
+    HANDLE pipe;\r
+public:\r
+    WindowsNamedPipeIPC() { };\r
+    ~WindowsNamedPipeIPC() {\r
+        CloseHandle( pipe );\r
+    }\r
+    virtual bool init() {\r
+        char pipename[64];\r
+        PLAT_strncpy( pipename, PIPE_PREFIX, 63 );\r
+        PLAT_strncpy( pipename+strlen(pipename), P802_1AS_PIPENAME, 63-strlen(pipename) );\r
+        pipe = CreateNamedPipe( pipename, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE, PIPE_UNLIMITED_INSTANCES,\r
+            OUTSTANDING_MESSAGES*sizeof( WindowsNPipeMessage ), 0, 0, NULL );\r
+        if( pipe == INVALID_HANDLE_VALUE ) return false;\r
+        return true;\r
+    }\r
+    virtual bool update( int64_t ml_phoffset, int64_t ls_phoffset, int32_t ml_freqoffset, int32_t ls_freq_offset, uint64_t local_time ) {\r
+        WindowsNPipeMessage msg( ml_phoffset, ls_phoffset, ml_freqoffset, ls_freq_offset, local_time );\r
+        if( !msg.write( pipe )) {\r
+            CloseHandle(pipe);\r
+            return init();\r
+        }\r
+        return true;\r
+    }\r
+};\r
+\r
+#endif\r
diff --git a/daemons/gptp/windows/daemon_cl/x64/CVS/Entries b/daemons/gptp/windows/daemon_cl/x64/CVS/Entries
new file mode 100644 (file)
index 0000000..1784810
--- /dev/null
@@ -0,0 +1 @@
+D
diff --git a/daemons/gptp/windows/daemon_cl/x64/CVS/Repository b/daemons/gptp/windows/daemon_cl/x64/CVS/Repository
new file mode 100644 (file)
index 0000000..0120903
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/windows/daemon_cl/x64
diff --git a/daemons/gptp/windows/daemon_cl/x64/CVS/Root b/daemons/gptp/windows/daemon_cl/x64/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/windows/gptp.sln b/daemons/gptp/windows/gptp.sln
new file mode 100644 (file)
index 0000000..15e2131
--- /dev/null
@@ -0,0 +1,21 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 12.00\r
+# Visual Studio 2012\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "daemon_cl", "daemon_cl\daemon_cl.vcxproj", "{590D3055-A068-4B31-B4F9-B2ACC5F93663}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_pipe_test", "named_pipe_test\named_pipe_test.vcxproj", "{303FACBB-2A44-4511-A855-2B5B2C0E3A89}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Release|x64 = Release|x64\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|x64.ActiveCfg = Release|x64\r
+               {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|x64.Build.0 = Release|x64\r
+               {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|x64.ActiveCfg = Release|x64\r
+               {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|x64.Build.0 = Release|x64\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/daemons/gptp/windows/named_pipe_test/CVS/Entries b/daemons/gptp/windows/named_pipe_test/CVS/Entries
new file mode 100644 (file)
index 0000000..95ee666
--- /dev/null
@@ -0,0 +1,9 @@
+/ReadMe.txt/1.1/Fri Sep 21 20:20:49 2012//
+/named_pipe_test.cpp/1.1/Fri Sep 21 20:21:47 2012//
+/named_pipe_test.vcxproj/1.1/Fri Sep 21 16:52:35 2012//
+/named_pipe_test.vcxproj.filters/1.1/Fri Sep  7 18:39:51 2012//
+/named_pipe_test.vcxproj.user/1.1/Fri Sep  7 18:39:51 2012//
+/stdafx.cpp/1.1/Fri Sep  7 18:39:51 2012//
+/stdafx.h/1.1/Fri Sep  7 18:39:51 2012//
+/targetver.h/1.1/Fri Sep  7 18:39:51 2012//
+D
diff --git a/daemons/gptp/windows/named_pipe_test/CVS/Repository b/daemons/gptp/windows/named_pipe_test/CVS/Repository
new file mode 100644 (file)
index 0000000..2e82842
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/windows/named_pipe_test
diff --git a/daemons/gptp/windows/named_pipe_test/CVS/Root b/daemons/gptp/windows/named_pipe_test/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/windows/named_pipe_test/ReadMe.txt b/daemons/gptp/windows/named_pipe_test/ReadMe.txt
new file mode 100644 (file)
index 0000000..ad4c1ba
--- /dev/null
@@ -0,0 +1,10 @@
+========================================================================\r
+(C) Copyright 2009-2012 Intel Corporation, All Rights Reserved\r
+Author: Christopher Hall <christopher.s.hall@intel.com>\r
+========================================================================\r
+\r
+========================================================================\r
+    CONSOLE APPLICATION : named_pipe_test Project Overview\r
+========================================================================\r
+\r
+An example application to interface with gptp/daemon_cl.  See ipcdef.hpp for message details.\r
diff --git a/daemons/gptp/windows/named_pipe_test/named_pipe_test.cpp b/daemons/gptp/windows/named_pipe_test/named_pipe_test.cpp
new file mode 100644 (file)
index 0000000..2247cba
--- /dev/null
@@ -0,0 +1,114 @@
+/******************************************************************************\r
+\r
+  Copyright (c) 2009-2012, Intel Corporation \r
+  All rights reserved.\r
+  \r
+  Redistribution and use in source and binary forms, with or without \r
+  modification, are permitted provided that the following conditions are met:\r
+  \r
+   1. Redistributions of source code must retain the above copyright notice, \r
+      this list of conditions and the following disclaimer.\r
+  \r
+   2. Redistributions in binary form must reproduce the above copyright \r
+      notice, this list of conditions and the following disclaimer in the \r
+      documentation and/or other materials provided with the distribution.\r
+  \r
+   3. Neither the name of the Intel Corporation nor the names of its \r
+      contributors may be used to endorse or promote products derived from \r
+      this software without specific prior written permission.\r
+  \r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+  POSSIBILITY OF SUCH DAMAGE.\r
+\r
+******************************************************************************/\r
+\r
+#include "stdafx.h"\r
+#include "ipcdef.hpp"\r
+#include "tsc.hpp"\r
+\r
+#define PIPE_PREFIX "\\\\.\\pipe\\"\r
+#define P802_1AS_PIPENAME "gptp-update"\r
+#define OUTSTANDING_MESSAGES 10\r
+\r
+static bool exit_flag;\r
+\r
+BOOL WINAPI ctrl_handler( DWORD ctrl_type ) {\r
+    bool ret;\r
+    if( ctrl_type == CTRL_C_EVENT ) {\r
+        exit_flag = true;\r
+        ret = true;\r
+    } else {\r
+        ret = false;\r
+    }\r
+    return ret;\r
+}\r
+\r
+uint64_t scaleTSCClockToNanoseconds( uint64_t tsc_value, uint64_t tsc_frequency ) {\r
+       long double scaled_output = ((long double)tsc_frequency)/1000000000;\r
+       scaled_output = ((long double) tsc_value)/scaled_output;\r
+       return (uint64_t) scaled_output;\r
+}\r
+int _tmain(int argc, _TCHAR* argv[])\r
+{\r
+    char pipename[64];\r
+    strcpy_s( pipename, 64, PIPE_PREFIX );\r
+    strcat_s( pipename, 64-strlen(pipename), P802_1AS_PIPENAME );\r
+    WindowsNPipeMessage msg;\r
+    HANDLE pipe;\r
+       uint64_t tsc_frequency = getTSCFrequency( 1000 );\r
+\r
+    pipe = CreateFile( pipename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );\r
+    if( pipe == INVALID_HANDLE_VALUE ) {\r
+        printf( "Failed to open gptp handle, %d\n", GetLastError() );\r
+    }\r
+\r
+    \r
+   // Wait for Ctrl-C\r
+    if( !SetConsoleCtrlHandler( ctrl_handler, true )) {\r
+        printf( "Unable to register Ctrl-C handler\n" );\r
+        return -1;\r
+    }\r
+\r
+       printf( "TSC Frequency: %llu\n", tsc_frequency );\r
+    while( msg.read( pipe ) == true && !exit_flag ) {\r
+               uint64_t now_tscns, now_8021as;\r
+               uint64_t update_tscns, update_8021as;\r
+               unsigned delta_tscns, delta_8021as;\r
+               long double ml_ratio, ls_ratio;\r
+#if 0\r
+        printf( "Master-Local Offset = %lld\n", msg.getMasterLocalOffset() );\r
+        printf( "Master-Local Frequency Offset = %d\n", msg.getMasterLocalFreqOffset() );\r
+        printf( "Local-System Offset = %lld\n", msg.getLocalSystemOffset() );\r
+        printf( "Local-System Frequency Offset = %d\n", msg.getLocalSystemFreqOffset() );\r
+        printf( "Local Time = %llu\n", msg.getLocalTime() );\r
+#endif\r
+               now_tscns = scaleTSCClockToNanoseconds( PLAT_rdtsc(), tsc_frequency );\r
+               update_tscns = msg.getLocalTime() + msg.getLocalSystemOffset();\r
+               update_8021as = msg.getLocalTime() - msg.getMasterLocalOffset();\r
+               delta_tscns = (unsigned)(now_tscns - update_tscns);\r
+               ml_ratio = -1*(((long double)msg.getMasterLocalFreqOffset())/1000000000000)+1;\r
+               ls_ratio = -1*(((long double)msg.getLocalSystemFreqOffset())/1000000000000)+1;\r
+               delta_8021as = (unsigned)(ml_ratio*ls_ratio*delta_tscns);\r
+               now_8021as = update_8021as + delta_8021as;\r
+               printf( "Time now in terms of TSC scaled to nanoseconds time: %llu\n", now_tscns );\r
+               printf( "Last update time in terms of 802.1AS time: %llu\n", update_8021as );\r
+               printf( "TSC delta scaled to ns: %u\n", delta_tscns );\r
+               printf( "8021as delta scaled: %u\n", delta_8021as );\r
+               printf( "Time now in terms of 802.1AS time: %llu\n", now_8021as );\r
+    }\r
+\r
+    printf( "Closing pipe\n" );\r
+    CloseHandle( pipe );\r
+\r
+    return 0;\r
+}\r
+\r
diff --git a/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj b/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj
new file mode 100644 (file)
index 0000000..05b568f
--- /dev/null
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{303FACBB-2A44-4511-A855-2B5B2C0E3A89}</ProjectGuid>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <RootNamespace>named_pipe_test</RootNamespace>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v110</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v110</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v110</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>Application</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>Unicode</CharacterSet>\r
+    <PlatformToolset>v110</PlatformToolset>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <LinkIncremental>true</LinkIncremental>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <LinkIncremental>false</LinkIncremental>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <PrecompiledHeader>Use</PrecompiledHeader>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <PreprocessorDefinitions>\r
+      </PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories>C:\Users\John\src\gptp\windows\gptp\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <ClCompile>\r
+      <PrecompiledHeader>Use</PrecompiledHeader>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <PreprocessorDefinitions>\r
+      </PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories>C:\Users\John\src\gptp\windows\gptp\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <PrecompiledHeader>Use</PrecompiledHeader>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories>C:\Users\John\src\gptp\windows\gptp\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <PrecompiledHeader>Use</PrecompiledHeader>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE</PreprocessorDefinitions>\r
+      <AdditionalIncludeDirectories>..\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <SubSystem>Console</SubSystem>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <None Include="ReadMe.txt" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="stdafx.h" />\r
+    <ClInclude Include="targetver.h" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="named_pipe_test.cpp" />\r
+    <ClCompile Include="stdafx.cpp">\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>\r
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ No newline at end of file
diff --git a/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.filters b/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.filters
new file mode 100644 (file)
index 0000000..c03b555
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="ReadMe.txt" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="stdafx.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="targetver.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="stdafx.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="named_pipe_test.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
diff --git a/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.user b/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.user
new file mode 100644 (file)
index 0000000..695b5c7
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
diff --git a/daemons/gptp/windows/named_pipe_test/stdafx.cpp b/daemons/gptp/windows/named_pipe_test/stdafx.cpp
new file mode 100644 (file)
index 0000000..26915d0
--- /dev/null
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes\r
+// named_pipe_test.pch will be the pre-compiled header\r
+// stdafx.obj will contain the pre-compiled type information\r
+\r
+#include "stdafx.h"\r
+\r
+// TODO: reference any additional headers you need in STDAFX.H\r
+// and not in this file\r
diff --git a/daemons/gptp/windows/named_pipe_test/stdafx.h b/daemons/gptp/windows/named_pipe_test/stdafx.h
new file mode 100644 (file)
index 0000000..d2509e4
--- /dev/null
@@ -0,0 +1,16 @@
+// stdafx.h : include file for standard system include files,\r
+// or project specific include files that are used frequently, but\r
+// are changed infrequently\r
+//\r
+\r
+#pragma once\r
+\r
+#include "targetver.h"\r
+\r
+#include <stdio.h>\r
+#include <tchar.h>\r
+#include <Windows.h>\r
+\r
+\r
+\r
+// TODO: reference additional headers your program requires here\r
diff --git a/daemons/gptp/windows/named_pipe_test/targetver.h b/daemons/gptp/windows/named_pipe_test/targetver.h
new file mode 100644 (file)
index 0000000..90e767b
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once\r
+\r
+// Including SDKDDKVer.h defines the highest available Windows platform.\r
+\r
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and\r
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.\r
+\r
+#include <SDKDDKVer.h>\r
diff --git a/daemons/gptp/windows/named_pipe_test/x64/Release/named_pipe_test.Build.CppClean.log b/daemons/gptp/windows/named_pipe_test/x64/Release/named_pipe_test.Build.CppClean.log
new file mode 100644 (file)
index 0000000..b1d446f
--- /dev/null
@@ -0,0 +1,16 @@
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\cl.command.1.tlog\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\CL.read.1.tlog\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\CL.write.1.tlog\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\link.command.1.tlog\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\link.read.1.tlog\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\link.write.1.tlog\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\mt.command.1.tlog\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\mt.read.1.tlog\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\mt.write.1.tlog\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\named_pipe_test.exe.intermediate.manifest\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\named_pipe_test.obj\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\named_pipe_test.pch\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\x64\Release\stdafx.obj\r
+\\DATAGROVEJF\STG\USERS\CHRISH\GPTP_BZR\MAIN\WINDOWS\GPTP\NAMED_PIPE_TEST\X64\RELEASE\VC100.PDB\r
+\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\x64\Release\named_pipe_test.exe\r
+\\DATAGROVEJF\STG\USERS\CHRISH\GPTP_BZR\MAIN\WINDOWS\GPTP\X64\RELEASE\NAMED_PIPE_TEST.PDB\r
diff --git a/daemons/gptp/windows/named_pipe_test/x64/Release/named_pipe_test.log b/daemons/gptp/windows/named_pipe_test/x64/Release/named_pipe_test.log
new file mode 100644 (file)
index 0000000..d644b10
--- /dev/null
@@ -0,0 +1,9 @@
+Build started 9/5/2012 6:17:28 PM.\r
+     1>Project "\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\named_pipe_test.vcxproj" on node 2 (clean target(s)).\r
+     1>_PrepareForClean:\r
+         Deleting file "x64\Release\named_pipe_test.lastbuildstate".\r
+     1>Done Building Project "\\datagrovejf\STG\USERS\Chrish\gptp_bzr\main\windows\gptp\named_pipe_test\named_pipe_test.vcxproj" (clean target(s)).\r
+\r
+Build succeeded.\r
+\r
+Time Elapsed 00:00:00.30\r
diff --git a/daemons/gptp/windows/x64/CVS/Entries b/daemons/gptp/windows/x64/CVS/Entries
new file mode 100644 (file)
index 0000000..1784810
--- /dev/null
@@ -0,0 +1 @@
+D
diff --git a/daemons/gptp/windows/x64/CVS/Repository b/daemons/gptp/windows/x64/CVS/Repository
new file mode 100644 (file)
index 0000000..76c2143
--- /dev/null
@@ -0,0 +1 @@
+linux_igb_avb/daemons/gptp/windows/x64
diff --git a/daemons/gptp/windows/x64/CVS/Root b/daemons/gptp/windows/x64/CVS/Root
new file mode 100644 (file)
index 0000000..beb56f8
--- /dev/null
@@ -0,0 +1 @@
+:pserver:ekmann@azusa.jf.intel.com:/home/cvsroot/ladsw
diff --git a/daemons/gptp/windows/x64/Release/daemon_cl.map b/daemons/gptp/windows/x64/Release/daemon_cl.map
new file mode 100644 (file)
index 0000000..0325541
--- /dev/null
@@ -0,0 +1,732 @@
+ daemon_cl\r
+\r
+ Timestamp is 5047f856 (Wed Sep 05 18:11:50 2012)\r
+\r
+ Preferred load address is 0000000140000000\r
+\r
+ Start         Length     Name                   Class\r
+ 0001:00000000 00009f5eH .text                   CODE\r
+ 0001:00009f60 0000040cH .text$x                 CODE\r
+ 0001:0000a370 000000b2H .text$yc                CODE\r
+ 0001:0000a430 0000005fH .text$yd                CODE\r
+ 0002:00000000 00000328H .idata$5                DATA\r
+ 0002:00000328 00000008H .CRT$XCA                DATA\r
+ 0002:00000330 00000008H .CRT$XCAA               DATA\r
+ 0002:00000338 00000018H .CRT$XCU                DATA\r
+ 0002:00000350 00000008H .CRT$XCZ                DATA\r
+ 0002:00000358 00000008H .CRT$XIA                DATA\r
+ 0002:00000360 00000008H .CRT$XIAA               DATA\r
+ 0002:00000368 00000008H .CRT$XIY                DATA\r
+ 0002:00000370 00000008H .CRT$XIZ                DATA\r
+ 0002:00000380 00001020H .rdata                  DATA\r
+ 0002:000013a0 0000006cH .rdata$debug            DATA\r
+ 0002:00001410 0000113cH .rdata$r                DATA\r
+ 0002:00002550 00000008H .rtc$IAA                DATA\r
+ 0002:00002558 00000008H .rtc$IZZ                DATA\r
+ 0002:00002560 00000008H .rtc$TAA                DATA\r
+ 0002:00002568 00000008H .rtc$TZZ                DATA\r
+ 0002:00002570 000011e0H .xdata                  DATA\r
+ 0002:00003750 00000084H .xdata$x                DATA\r
+ 0002:000037d4 00000078H .idata$2                DATA\r
+ 0002:0000384c 00000014H .idata$3                DATA\r
+ 0002:00003860 00000328H .idata$4                DATA\r
+ 0002:00003b88 000006daH .idata$6                DATA\r
+ 0002:00004262 00000000H .edata                  DATA\r
+ 0003:00000000 00000714H .data                   DATA\r
+ 0003:00000720 00000600H .bss                    DATA\r
+ 0004:00000000 000009e4H .pdata                  DATA\r
+\r
+  Address         Publics by Value              Rva+Base               Lib:Object\r
+\r
+ 0000:00000000       ___safe_se_handler_count   0000000000000000     <absolute>\r
+ 0000:00000000       ___safe_se_handler_table   0000000000000000     <absolute>\r
+ 0000:00000000       __ImageBase                0000000140000000     <linker-defined>\r
+ 0001:00000000       ??1bad_alloc@std@@UEAA@XZ  0000000140001000 f i avbts_osnet.obj\r
+ 0001:00000020       ??_Gbad_alloc@std@@UEAAPEAXI@Z 0000000140001020 f i avbts_osnet.obj\r
+ 0001:00000020       ??_Ebad_alloc@std@@UEAAPEAXI@Z 0000000140001020 f i  CIL library: CIL module\r
+ 0001:00000060       ??0?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAA@AEBU?$less@Vfactory_name_t@@@1@AEBV?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@1@@Z 0000000140001060 f i avbts_osnet.obj\r
+ 0001:00000100       ??1?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAA@XZ 0000000140001100 f i avbts_osnet.obj\r
+ 0001:00000110       ?erase@?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@@2@0@Z 0000000140001110 f i avbts_osnet.obj\r
+ 0001:000001d0       ?erase@?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@@2@@Z 00000001400011d0 f i avbts_osnet.obj\r
+ 0001:00000520       ?clear@?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAAXXZ 0000000140001520 f i avbts_osnet.obj\r
+ 0001:000005a0       ?_Erase@?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@IEAAXPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@2@@Z 00000001400015a0 f i avbts_osnet.obj\r
+ 0001:00000600       ?_Lrotate@?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@IEAAXPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@2@@Z 0000000140001600 f i avbts_osnet.obj\r
+ 0001:00000660       ?_Rrotate@?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@IEAAXPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@2@@Z 0000000140001660 f i avbts_osnet.obj\r
+ 0001:000006c0       ??0bad_alloc@std@@QEAA@AEBV01@@Z 00000001400016c0 f i avbts_osnet.obj\r
+ 0001:000006f0       ?timerq_handler@@YAXPEAX@Z 00000001400016f0 f   ieee1588clock.obj\r
+ 0001:00000700       ?addEventTimer@IEEE1588Clock@@QEAAXPEAVIEEE1588Port@@W4Event@@_K@Z 0000000140001700 f   ieee1588clock.obj\r
+ 0001:000007a0       ?isBetterThan@IEEE1588Clock@@QEAA_NPEAVPTPMessageAnnounce@@@Z 00000001400017a0 f   ieee1588clock.obj\r
+ 0001:00000870       ??_EInterfaceLabel@@UEAAPEAXI@Z 0000000140001870 f i  CIL library: CIL module\r
+ 0001:00000870       ??_GLinkLayerAddress@@UEAAPEAXI@Z 0000000140001870 f i ieee1588port.obj\r
+ 0001:00000870       ??_ELinkLayerAddress@@UEAAPEAXI@Z 0000000140001870 f i  CIL library: CIL module\r
+ 0001:00000870       ??_GInterfaceLabel@@UEAAPEAXI@Z 0000000140001870 f i ieee1588port.obj\r
+ 0001:000008a0       ?pow@@YANNH@Z              00000001400018a0 f i ieee1588port.obj\r
+ 0001:000008e0       ??1LinkLayerAddress@@UEAA@XZ 00000001400018e0 f i ieee1588port.obj\r
+ 0001:000008f0       ?openPortWrapper@@YA?AW4OSThreadExitCode@@PEAX@Z 00000001400018f0 f   ieee1588port.obj\r
+ 0001:00000910       ??1?$map@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@@std@@QEAA@XZ 0000000140001910 f i ieee1588port.obj\r
+ 0001:00000950       ??0IEEE1588Port@@QEAA@PEAVIEEE1588Clock@@G_NPEAVHWTimestamper@@1HPEAVInterfaceLabel@@PEAVOSConditionFactory@@PEAVOSThreadFactory@@PEAVOSTimerFactory@@PEAVOSLockFactory@@@Z 0000000140001950 f   ieee1588port.obj\r
+ 0001:00000b40       ?init_port@IEEE1588Port@@QEAA_NXZ 0000000140001b40 f   ieee1588port.obj\r
+ 0001:00000cc0       ?openPort@IEEE1588Port@@QEAAPEAXXZ 0000000140001cc0 f   ieee1588port.obj\r
+ 0001:00000e20       ?processEvent@IEEE1588Port@@QEAAXW4Event@@@Z 0000000140001e20 f   ieee1588port.obj\r
+ 0001:00001cc0       ?calculateERBest@IEEE1588Port@@QEAAPEAVPTPMessageAnnounce@@XZ 0000000140002cc0 f   ieee1588port.obj\r
+ 0001:00001d90       ?recommendState@IEEE1588Port@@QEAAXW4PortState@@_N@Z 0000000140002d90 f   ieee1588port.obj\r
+ 0001:00001fa0       ?calcMasterLocalClockRateDifference@IEEE1588Port@@QEAAH_JVTimestamp@@@Z 0000000140002fa0 f   ieee1588port.obj\r
+ 0001:000020e0       ?calcLocalSystemClockRateDifference@IEEE1588Port@@QEAAH_JVTimestamp@@@Z 00000001400030e0 f   ieee1588port.obj\r
+ 0001:000021b0       ??A?$map@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@@std@@QEAAAEAPEAVOSNetworkInterfaceFactory@@AEBVfactory_name_t@@@Z 00000001400031b0 f i ieee1588port.obj\r
+ 0001:000022b0       ??A?$map@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@@std@@QEAAAEAVLinkLayerAddress@@AEBVPortIdentity@@@Z 00000001400032b0 f i ieee1588port.obj\r
+ 0001:000023a0       ??1?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@QEAA@XZ 00000001400033a0 f i ieee1588port.obj\r
+ 0001:000023b0       ??0?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAA@AEBU?$less@VPortIdentity@@@1@AEBV?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@1@@Z 00000001400033b0 f i ieee1588port.obj\r
+ 0001:00002440       ??1?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAA@XZ 0000000140003440 f i ieee1588port.obj\r
+ 0001:00002440       ??1?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAA@XZ 0000000140003440 f i daemon_cl.obj\r
+ 0001:00002450       ??R?$less@VPortIdentity@@@std@@QEBA_NAEBVPortIdentity@@0@Z 0000000140003450 f i ieee1588port.obj\r
+ 0001:000024a0       ?erase@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@@2@0@Z 00000001400034a0 f i ieee1588port.obj\r
+ 0001:00002580       ?_Lbound@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@IEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@2@AEBVPortIdentity@@@Z 0000000140003580 f i ieee1588port.obj\r
+ 0001:00002610       ?erase@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@@2@@Z 0000000140003610 f i ieee1588port.obj\r
+ 0001:00002980       ?clear@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAAXXZ 0000000140003980 f i ieee1588port.obj\r
+ 0001:00002a10       ?_Erase@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@IEAAXPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@2@@Z 0000000140003a10 f i ieee1588port.obj\r
+ 0001:00002a80       ?_Lrotate@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@IEAAXPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@2@@Z 0000000140003a80 f i ieee1588port.obj\r
+ 0001:00002ae0       ?_Rrotate@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@IEAAXPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@2@@Z 0000000140003ae0 f i ieee1588port.obj\r
+ 0001:00002b40       ?_Insert@?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@@2@PEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@2@@Z 0000000140003b40 f i ieee1588port.obj\r
+ 0001:00002de0       ?_Insert@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@@2@PEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@2@@Z 0000000140003de0 f i ieee1588port.obj\r
+ 0001:00003050       ?_Linsert@?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAA?AU?$pair@V?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@@std@@_N@2@PEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@2@_N@Z 0000000140004050 f i ieee1588port.obj\r
+ 0001:000031b0       ?_Insert@?$_Tree@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@IEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@@2@_NPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@2@1@Z 00000001400041b0 f i ieee1588port.obj\r
+ 0001:00003460       ?_Linsert@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAA?AU?$pair@V?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@@std@@_N@2@PEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@2@_N@Z 0000000140004460 f i ieee1588port.obj\r
+ 0001:00003610       ?_Insert@?$_Tree@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@IEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@@2@_NPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@2@1@Z 0000000140004610 f i ieee1588port.obj\r
+ 0001:000038c0       ??$_Buynode@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@1@$$QEAU?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@1@@Z 00000001400048c0 f i ieee1588port.obj\r
+ 0001:00003930       ??$_Buynode@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@1@$$QEAU?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@1@@Z 0000000140004930 f i ieee1588port.obj\r
+ 0001:00003990       ?_Buynode@?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@2@XZ 0000000140004990 f i ieee1588port.obj\r
+ 0001:00003a10       ?_Buynode@?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@2@XZ 0000000140004a10 f i ieee1588port.obj\r
+ 0001:00003a90       ??_EPTPMessagePathDelayReq@@UEAAPEAXI@Z 0000000140004a90 f i  CIL library: CIL module\r
+ 0001:00003a90       ??_GPTPMessageCommon@@UEAAPEAXI@Z 0000000140004a90 f i ptp_message.obj\r
+ 0001:00003a90       ??_GPTPMessageSync@@UEAAPEAXI@Z 0000000140004a90 f i ptp_message.obj\r
+ 0001:00003a90       ??_EPTPMessageSync@@UEAAPEAXI@Z 0000000140004a90 f i  CIL library: CIL module\r
+ 0001:00003a90       ??_EPTPMessageFollowUp@@UEAAPEAXI@Z 0000000140004a90 f i  CIL library: CIL module\r
+ 0001:00003a90       ??_GPTPMessagePathDelayReq@@UEAAPEAXI@Z 0000000140004a90 f i ptp_message.obj\r
+ 0001:00003a90       ??_GPTPMessageFollowUp@@UEAAPEAXI@Z 0000000140004a90 f i ptp_message.obj\r
+ 0001:00003a90       ??_EPTPMessageCommon@@UEAAPEAXI@Z 0000000140004a90 f i  CIL library: CIL module\r
+ 0001:00003ad0       ??_GPTPMessagePathDelayResp@@UEAAPEAXI@Z 0000000140004ad0 f i ptp_message.obj\r
+ 0001:00003ad0       ??_EPTPMessagePathDelayResp@@UEAAPEAXI@Z 0000000140004ad0 f i  CIL library: CIL module\r
+ 0001:00003b30       ??_GPTPMessagePathDelayRespFollowUp@@UEAAPEAXI@Z 0000000140004b30 f i ptp_message.obj\r
+ 0001:00003b30       ??_EPTPMessagePathDelayRespFollowUp@@UEAAPEAXI@Z 0000000140004b30 f i  CIL library: CIL module\r
+ 0001:00003b90       ??0PortIdentity@@QEAA@PEAEPEAG@Z 0000000140004b90 f i ptp_message.obj\r
+ 0001:00003bd0       ?addQualifiedAnnounce@IEEE1588Port@@QEAAXPEAVPTPMessageAnnounce@@@Z 0000000140004bd0 f i ptp_message.obj\r
+ 0001:00003c50       ?buildPTPMessage@@YAPEAVPTPMessageCommon@@PEADHPEAVLinkLayerAddress@@PEAVIEEE1588Port@@@Z 0000000140004c50 f   ptp_message.obj\r
+ 0001:00004370       ?processMessage@PTPMessageCommon@@UEAAXPEAVIEEE1588Port@@@Z 0000000140005370 f   ptp_message.obj\r
+ 0001:00004380       ?buildCommonHeader@PTPMessageCommon@@QEAAXPEAE@Z 0000000140005380 f   ptp_message.obj\r
+ 0001:00004460       ??1PTPMessageCommon@@UEAA@XZ 0000000140005460 f   ptp_message.obj\r
+ 0001:00004480       ??_EPTPMessageAnnounce@@UEAAPEAXI@Z 0000000140005480 f i  CIL library: CIL module\r
+ 0001:00004480       ??_GPTPMessageAnnounce@@UEAAPEAXI@Z 0000000140005480 f i ptp_message.obj\r
+ 0001:000044e0       ?isBetterThan@PTPMessageAnnounce@@QEAA_NPEAV1@@Z 00000001400054e0 f   ptp_message.obj\r
+ 0001:000045b0       ??0PTPMessageSync@@QEAA@PEAVIEEE1588Port@@@Z 00000001400055b0 f   ptp_message.obj\r
+ 0001:00004660       ?sendPort@PTPMessageSync@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z 0000000140005660 f   ptp_message.obj\r
+ 0001:000047a0       ??0PTPMessageAnnounce@@QEAA@PEAVIEEE1588Port@@@Z 00000001400057a0 f   ptp_message.obj\r
+ 0001:000048e0       ?sendPort@PTPMessageAnnounce@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z 00000001400058e0 f   ptp_message.obj\r
+ 0001:00004a60       ?processMessage@PTPMessageAnnounce@@UEAAXPEAVIEEE1588Port@@@Z 0000000140005a60 f   ptp_message.obj\r
+ 0001:00004b50       ?processMessage@PTPMessageSync@@UEAAXPEAVIEEE1588Port@@@Z 0000000140005b50 f   ptp_message.obj\r
+ 0001:00004c60       ??0PTPMessageFollowUp@@QEAA@PEAVIEEE1588Port@@@Z 0000000140005c60 f   ptp_message.obj\r
+ 0001:00004d50       ?sendPort@PTPMessageFollowUp@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z 0000000140005d50 f   ptp_message.obj\r
+ 0001:00004ea0       ?processMessage@PTPMessageFollowUp@@UEAAXPEAVIEEE1588Port@@@Z 0000000140005ea0 f   ptp_message.obj\r
+ 0001:00005290       ?processMessage@PTPMessagePathDelayReq@@UEAAXPEAVIEEE1588Port@@@Z 0000000140006290 f   ptp_message.obj\r
+ 0001:000056b0       ?sendPort@PTPMessagePathDelayReq@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z 00000001400066b0 f   ptp_message.obj\r
+ 0001:000057b0       ??0PTPMessagePathDelayResp@@QEAA@PEAVIEEE1588Port@@@Z 00000001400067b0 f   ptp_message.obj\r
+ 0001:00005840       ?processMessage@PTPMessagePathDelayResp@@UEAAXPEAVIEEE1588Port@@@Z 0000000140006840 f   ptp_message.obj\r
+ 0001:00005990       ?sendPort@PTPMessagePathDelayResp@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z 0000000140006990 f   ptp_message.obj\r
+ 0001:00005ae0       ??0PTPMessagePathDelayRespFollowUp@@QEAA@PEAVIEEE1588Port@@@Z 0000000140006ae0 f   ptp_message.obj\r
+ 0001:00005b70       ?processMessage@PTPMessagePathDelayRespFollowUp@@UEAAXPEAVIEEE1588Port@@@Z 0000000140006b70 f   ptp_message.obj\r
+ 0001:00006070       ?sendPort@PTPMessagePathDelayRespFollowUp@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z 0000000140007070 f   ptp_message.obj\r
+ 0001:000061c0       ?_Buynode@?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAAPEAU_Node@?$_List_nod@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@2@PEAU342@0AEBQEAUWindowsTimerQueueHandlerArg@@@Z 00000001400071c0 f i daemon_cl.obj\r
+ 0001:000061c0       ?_Buynode@?$_List_val@PEAVPTPMessageAnnounce@@V?$allocator@PEAVPTPMessageAnnounce@@@std@@@std@@QEAAPEAU_Node@?$_List_nod@PEAVPTPMessageAnnounce@@V?$allocator@PEAVPTPMessageAnnounce@@@std@@@2@PEAU342@0AEBQEAVPTPMessageAnnounce@@@Z 00000001400071c0 f i ptp_message.obj\r
+ 0001:00006260       ?HWTimestamper_init@HWTimestamper@@UEAA_NPEAVInterfaceLabel@@@Z 0000000140007260 f i daemon_cl.obj\r
+ 0001:00006270       ??3@YAXPEAX0@Z             0000000140007270 f i ieee1588port.obj\r
+ 0001:00006270       ?HWTimestamper_final@HWTimestamper@@UEAAXXZ 0000000140007270 f i daemon_cl.obj\r
+ 0001:00006280       ?HWTimestamper_adjclockrate@HWTimestamper@@UEAA_NHIVTimestamp@@_J_N@Z 0000000140007280 f i daemon_cl.obj\r
+ 0001:00006280       ?HWTimestamper_adjclockrate2@HWTimestamper@@UEAA_NH@Z 0000000140007280 f i daemon_cl.obj\r
+ 0001:00006280       ?HWTimestamper_get_extclk_offset@HWTimestamper@@UEAA_NPEAVTimestamp@@PEA_JPEAH@Z 0000000140007280 f i daemon_cl.obj\r
+ 0001:00006290       ?HWTimestamper_get_extderror@HWTimestamper@@UEAAXPEAD@Z 0000000140007290 f i daemon_cl.obj\r
+ 0001:000062a0       ??_GHWTimestamper@@UEAAPEAXI@Z 00000001400072a0 f i daemon_cl.obj\r
+ 0001:000062a0       ??_GWindowsTimestamper@@UEAAPEAXI@Z 00000001400072a0 f i daemon_cl.obj\r
+ 0001:000062a0       ??_EHWTimestamper@@UEAAPEAXI@Z 00000001400072a0 f i  CIL library: CIL module\r
+ 0001:000062a0       ??_EWindowsTimestamper@@UEAAPEAXI@Z 00000001400072a0 f i  CIL library: CIL module\r
+ 0001:000062d0       ?send@WindowsPCAPNetworkInterface@@UEAA?AW4net_result@@PEAVLinkLayerAddress@@PEAE_K_N@Z 00000001400072d0 f i daemon_cl.obj\r
+ 0001:000063a0       ?recv@WindowsPCAPNetworkInterface@@UEAA?AW4net_result@@PEAVLinkLayerAddress@@PEAEAEA_K@Z 00000001400073a0 f i daemon_cl.obj\r
+ 0001:000064d0       ?getLinkLayerAddress@WindowsPCAPNetworkInterface@@UEAAXPEAVLinkLayerAddress@@@Z 00000001400074d0 f i daemon_cl.obj\r
+ 0001:00006500       ?getPayloadOffset@WindowsPCAPNetworkInterface@@UEAAIXZ 0000000140007500 f i daemon_cl.obj\r
+ 0001:00006510       ??_GWindowsPCAPNetworkInterface@@UEAAPEAXI@Z 0000000140007510 f i daemon_cl.obj\r
+ 0001:00006510       ??_EWindowsPCAPNetworkInterface@@UEAAPEAXI@Z 0000000140007510 f i  CIL library: CIL module\r
+ 0001:00006590       ?createInterface@WindowsPCAPNetworkInterfaceFactory@@UEAA_NPEAPEAVOSNetworkInterface@@PEAVInterfaceLabel@@PEAVHWTimestamper@@@Z 0000000140007590 f i daemon_cl.obj\r
+ 0001:000066f0       ?lock@WindowsLock@@MEAA?AW4OSLockResult@@XZ 00000001400076f0 f i daemon_cl.obj\r
+ 0001:000067a0       ?trylock@WindowsLock@@MEAA?AW4OSLockResult@@XZ 00000001400077a0 f i daemon_cl.obj\r
+ 0001:00006850       ?unlock@WindowsLock@@MEAA?AW4OSLockResult@@XZ 0000000140007850 f i daemon_cl.obj\r
+ 0001:00006870       ?createLock@WindowsLockFactory@@UEAAPEAVOSLock@@W4OSLockType@@@Z 0000000140007870 f i daemon_cl.obj\r
+ 0001:000068f0       ?wait_prelock@WindowsCondition@@UEAA_NXZ 00000001400078f0 f i daemon_cl.obj\r
+ 0001:00006910       ?wait@WindowsCondition@@UEAA_NXZ 0000000140007910 f i daemon_cl.obj\r
+ 0001:00006960       ?signal@WindowsCondition@@UEAA_NXZ 0000000140007960 f i daemon_cl.obj\r
+ 0001:000069a0       ?createCondition@WindowsConditionFactory@@UEAAPEAVOSCondition@@XZ 00000001400079a0 f i daemon_cl.obj\r
+ 0001:000069f0       ?cleanupRetiredTimers@WindowsTimerQueue@@AEAAXXZ 00000001400079f0 f i daemon_cl.obj\r
+ 0001:00006ac0       ??0WindowsTimerQueue@@IEAA@XZ 0000000140007ac0 f i daemon_cl.obj\r
+ 0001:00006b60       ?addEvent@WindowsTimerQueue@@UEAA_NKHP6AXPEAX@ZPEAUevent_descriptor_t@@_NPEAI@Z 0000000140007b60 f i daemon_cl.obj\r
+ 0001:00006da0       ?cancelEvent@WindowsTimerQueue@@UEAA_NHPEAI@Z 0000000140007da0 f i daemon_cl.obj\r
+ 0001:00006f40       ??1?$map@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@@std@@QEAA@XZ 0000000140007f40 f i daemon_cl.obj\r
+ 0001:00006f80       ?WindowsTimerQueueHandler@@YAXPEAXE@Z 0000000140007f80 f   daemon_cl.obj\r
+ 0001:00007090       ?createOSTimerQueue@WindowsTimerQueueFactory@@UEAAPEAVOSTimerQueue@@XZ 0000000140008090 f i daemon_cl.obj\r
+ 0001:000070d0       ?sleep@WindowsTimer@@UEAAKK@Z 00000001400080d0 f i daemon_cl.obj\r
+ 0001:00007100       ?createTimer@WindowsTimerFactory@@UEAAPEAVOSTimer@@XZ 0000000140008100 f i daemon_cl.obj\r
+ 0001:00007130       ?OSThreadCallback@@YAKPEAX@Z 0000000140008130 f   daemon_cl.obj\r
+ 0001:00007150       ?start@WindowsThread@@UEAA_NP6A?AW4OSThreadExitCode@@PEAX@Z0@Z 0000000140008150 f i daemon_cl.obj\r
+ 0001:000071e0       ?join@WindowsThread@@UEAA_NAEAW4OSThreadExitCode@@@Z 00000001400081e0 f i daemon_cl.obj\r
+ 0001:00007230       ?createThread@WindowsThreadFactory@@UEAAPEAVOSThread@@XZ 0000000140008230 f i daemon_cl.obj\r
+ 0001:00007260       ?HWTimestamper_init@WindowsTimestamper@@UEAA_NPEAVInterfaceLabel@@@Z 0000000140008260 f i daemon_cl.obj\r
+ 0001:00007550       ?HWTimestamper_gettime@WindowsTimestamper@@UEAA_NPEAVTimestamp@@0PEAI1@Z 0000000140008550 f i daemon_cl.obj\r
+ 0001:00007730       ?HWTimestamper_txtimestamp@WindowsTimestamper@@UEAAHPEAVPortIdentity@@GAEAVTimestamp@@AEAI_N@Z 0000000140008730 f i daemon_cl.obj\r
+ 0001:000078d0       ?HWTimestamper_rxtimestamp@WindowsTimestamper@@UEAAHPEAVPortIdentity@@GAEAVTimestamp@@AEAI_N@Z 00000001400088d0 f i daemon_cl.obj\r
+ 0001:00007a60       ?init@WindowsNamedPipeIPC@@UEAA_NXZ 0000000140008a60 f i daemon_cl.obj\r
+ 0001:00007b40       ?update@WindowsNamedPipeIPC@@UEAA_N_J0HH_K@Z 0000000140008b40 f i daemon_cl.obj\r
+ 0001:00007bd0       ?ctrl_handler@@YAHK@Z      0000000140008bd0 f   daemon_cl.obj\r
+ 0001:00007bf0       main                       0000000140008bf0 f   daemon_cl.obj\r
+ 0001:00008020       ??A?$map@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@@std@@QEAAAEAUTimerQueue_t@@AEBH@Z 0000000140009020 f i daemon_cl.obj\r
+ 0001:000081e0       ??1TimerQueue_t@@QEAA@XZ   00000001400091e0 f i daemon_cl.obj\r
+ 0001:000081e0       ??1?$list@PEAVPTPMessageAnnounce@@V?$allocator@PEAVPTPMessageAnnounce@@@std@@@std@@QEAA@XZ 00000001400091e0 f i ieee1588port.obj\r
+ 0001:00008240       ??1?$pair@$$CBHUTimerQueue_t@@@std@@QEAA@XZ 0000000140009240 f i daemon_cl.obj\r
+ 0001:00008240       ??$_Dest_val@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@std@@U?$pair@$$CBHUTimerQueue_t@@@2@@std@@YAXAEAV?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@0@PEAU?$pair@$$CBHUTimerQueue_t@@@0@@Z 0000000140009240 f i daemon_cl.obj\r
+ 0001:000082a0       ?_Tidy@?$list@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAAXXZ 00000001400092a0 f i daemon_cl.obj\r
+ 0001:000082f0       ??1?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAA@XZ 00000001400092f0 f i daemon_cl.obj\r
+ 0001:00008300       ??0?$_Tree@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAA@AEBU?$less@H@1@AEBV?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@1@@Z 0000000140009300 f i daemon_cl.obj\r
+ 0001:00008390       ?erase@?$_Tree@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@@2@0@Z 0000000140009390 f i daemon_cl.obj\r
+ 0001:00008490       ??0?$list@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAA@AEBV01@@Z 0000000140009490 f i daemon_cl.obj\r
+ 0001:00008540       ?erase@?$_Tree@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@@2@@Z 0000000140009540 f i daemon_cl.obj\r
+ 0001:000088d0       ?_Erase@?$_Tree@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@IEAAXPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@2@@Z 00000001400098d0 f i daemon_cl.obj\r
+ 0001:00008970       ?_Lrotate@?$_Tree@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@IEAAXPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@2@@Z 0000000140009970 f i daemon_cl.obj\r
+ 0001:000089d0       ?_Rrotate@?$_Tree@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@IEAAXPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@2@@Z 00000001400099d0 f i daemon_cl.obj\r
+ 0001:00008a30       ?_Insert@?$_Tree@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@@2@PEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@2@@Z 0000000140009a30 f i daemon_cl.obj\r
+ 0001:00008c40       ?_Linsert@?$_Tree@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAA?AU?$pair@V?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@@std@@_N@2@PEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@2@_N@Z 0000000140009c40 f i daemon_cl.obj\r
+ 0001:00008d70       ?_Insert@?$_Tree@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@IEAA?AV?$_Tree_iterator@V?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@@2@_NPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@2@1@Z 0000000140009d70 f i daemon_cl.obj\r
+ 0001:00009060       ??$_Buynode@U?$pair@$$CBHUTimerQueue_t@@@std@@@?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@1@$$QEAU?$pair@$$CBHUTimerQueue_t@@@1@@Z 000000014000a060 f i daemon_cl.obj\r
+ 0001:000090e0       ??$_Insert@V?$_List_const_iterator@V?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@@std@@@?$list@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAAXV?$_List_const_iterator@V?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@@1@00Uforward_iterator_tag@1@@Z 000000014000a0e0 f i daemon_cl.obj\r
+ 0001:00009190       ?_Buynode@?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@2@XZ 000000014000a190 f i daemon_cl.obj\r
+ 0001:00009210       ?openInterfaceByAddr@@YA?AW4packet_error_t@@PEAUpacket_handle@@PEAUpacket_addr_t@@H@Z 000000014000a210 f   packet.obj\r
+ 0001:000093d0       ?packetBind@@YA?AW4packet_error_t@@PEAUpacket_handle@@G@Z 000000014000a3d0 f   packet.obj\r
+ 0001:000094d0       ??_U@YAPEAX_K@Z            000000014000a4d0 f   msvcprt:newaop_s.obj\r
+ 0001:000094f0       __security_check_cookie    000000014000a4f0 f   MSVCRT:amdsecgs.obj\r
+ 0001:00009510       ?what@exception@std@@UEBAPEBDXZ 000000014000a510 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009516       ??0exception@std@@QEAA@AEBV01@@Z 000000014000a516 f   MSVCRT:MSVCR100.dll\r
+ 0001:0000951c       _onexit                    000000014000a51c f   MSVCRT:atonexit.obj\r
+ 0001:000095cc       atexit                     000000014000a5cc f   MSVCRT:atonexit.obj\r
+ 0001:000095e4       ??3@YAXPEAX@Z              000000014000a5e4 f   MSVCRT:MSVCR100.dll\r
+ 0001:000095ec       ??_Etype_info@@UEAAPEAXI@Z 000000014000a5ec f i MSVCRT:ti_inst.obj\r
+ 0001:00009656       ??2@YAPEAX_K@Z             000000014000a656 f   MSVCRT:MSVCR100.dll\r
+ 0001:0000965c       _purecall                  000000014000a65c f   MSVCRT:MSVCR100.dll\r
+ 0001:0000991c       mainCRTStartup             000000014000a91c f   MSVCRT:crtexe.obj\r
+ 0001:00009930       __report_gsfailure         000000014000a930 f   MSVCRT:gs_report.obj\r
+ 0001:00009a7a       __C_specific_handler       000000014000aa7a f   MSVCRT:MSVCR100.dll\r
+ 0001:00009a80       _unlock                    000000014000aa80 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009a86       __dllonexit                000000014000aa86 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009a8c       _lock                      000000014000aa8c f   MSVCRT:MSVCR100.dll\r
+ 0001:00009a94       ?__ArrayUnwind@@YAXPEAX_KHP6AX0@Z@Z 000000014000aa94 f   MSVCRT:ehvecdtr.obj\r
+ 0001:00009ae0       ??_M@YAXPEAX_KHP6AX0@Z@Z   000000014000aae0 f   MSVCRT:ehvecdtr.obj\r
+ 0001:00009b40       ?__CxxUnhandledExceptionFilter@@YAJPEAU_EXCEPTION_POINTERS@@@Z 000000014000ab40 f   MSVCRT:unhandld.obj\r
+ 0001:00009b84       __CxxSetUnhandledExceptionFilter 000000014000ab84 f   MSVCRT:unhandld.obj\r
+ 0001:00009b9c       _amsg_exit                 000000014000ab9c f   MSVCRT:MSVCR100.dll\r
+ 0001:00009ba4       _RTC_Initialize            000000014000aba4 f   MSVCRT:_initsect_.obj\r
+ 0001:00009bdc       _RTC_Terminate             000000014000abdc f   MSVCRT:_initsect_.obj\r
+ 0001:00009c14       _XcptFilter                000000014000ac14 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009c20       _ValidateImageBase         000000014000ac20 f   MSVCRT:pesect.obj\r
+ 0001:00009c50       _FindPESection             000000014000ac50 f   MSVCRT:pesect.obj\r
+ 0001:00009ca0       _IsNonwritableInCurrentImage 000000014000aca0 f   MSVCRT:pesect.obj\r
+ 0001:00009ce2       _initterm                  000000014000ace2 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009ce8       _initterm_e                000000014000ace8 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009cf0       _matherr                   000000014000acf0 f   MSVCRT:merr.obj\r
+ 0001:00009cf0       _setargv                   000000014000acf0 f   MSVCRT:dllargv.obj\r
+ 0001:00009cf4       __security_init_cookie     000000014000acf4 f   MSVCRT:gs_support.obj\r
+ 0001:00009da8       __crt_debugger_hook        000000014000ada8 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009dae       ?terminate@@YAXXZ          000000014000adae f   MSVCRT:MSVCR100.dll\r
+ 0001:00009db4       ??1type_info@@UEAA@XZ      000000014000adb4 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009db4       ?_type_info_dtor_internal_method@type_info@@QEAAXXZ 000000014000adb4 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009dba       RtlVirtualUnwind           000000014000adba f   kernel32:KERNEL32.dll\r
+ 0001:00009dc0       RtlLookupFunctionEntry     000000014000adc0 f   kernel32:KERNEL32.dll\r
+ 0001:00009dc6       memcpy                     000000014000adc6 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009dcc       __GSHandlerCheckCommon     000000014000adcc f   MSVCRT:gshandler.obj\r
+ 0001:00009e30       __GSHandlerCheck           000000014000ae30 f   MSVCRT:gshandler.obj\r
+ 0001:00009e60       __chkstk                   000000014000ae60 f   MSVCRT:chkstk.obj\r
+ 0001:00009e60       _alloca_probe              000000014000ae60     MSVCRT:chkstk.obj\r
+ 0001:00009eae       memcmp                     000000014000aeae f   MSVCRT:MSVCR100.dll\r
+ 0001:00009eb4       _CxxThrowException         000000014000aeb4 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009eba       __CxxFrameHandler3         000000014000aeba f   MSVCRT:MSVCR100.dll\r
+ 0001:00009ec0       __RTDynamicCast            000000014000aec0 f   MSVCRT:MSVCR100.dll\r
+ 0001:00009ec8       __GSHandlerCheck_EH        000000014000aec8 f   MSVCRT:gshandlereh.obj\r
+ 0001:00009f58       memset                     000000014000af58 f   MSVCRT:MSVCR100.dll\r
+ 0002:00000000       __imp_GetAdaptersAddresses 000000014000c000     Iphlpapi:IPHLPAPI.DLL\r
+ 0002:00000008       \177IPHLPAPI_NULL_THUNK_DATA 000000014000c008     Iphlpapi:IPHLPAPI.DLL\r
+ 0002:00000010       __imp_GetCurrentProcess    000000014000c010     kernel32:KERNEL32.dll\r
+ 0002:00000018       __imp_TerminateProcess     000000014000c018     kernel32:KERNEL32.dll\r
+ 0002:00000020       __imp_DecodePointer        000000014000c020     kernel32:KERNEL32.dll\r
+ 0002:00000028       __imp_GetSystemTimeAsFileTime 000000014000c028     kernel32:KERNEL32.dll\r
+ 0002:00000030       __imp_UnhandledExceptionFilter 000000014000c030     kernel32:KERNEL32.dll\r
+ 0002:00000038       __imp_SetUnhandledExceptionFilter 000000014000c038     kernel32:KERNEL32.dll\r
+ 0002:00000040       __imp_RtlVirtualUnwind     000000014000c040     kernel32:KERNEL32.dll\r
+ 0002:00000048       __imp_GetCurrentProcessId  000000014000c048     kernel32:KERNEL32.dll\r
+ 0002:00000050       __imp_GetTickCount         000000014000c050     kernel32:KERNEL32.dll\r
+ 0002:00000058       __imp_QueryPerformanceCounter 000000014000c058     kernel32:KERNEL32.dll\r
+ 0002:00000060       __imp_RtlCaptureContext    000000014000c060     kernel32:KERNEL32.dll\r
+ 0002:00000068       __imp_RtlLookupFunctionEntry 000000014000c068     kernel32:KERNEL32.dll\r
+ 0002:00000070       __imp_CreateFileA          000000014000c070     kernel32:KERNEL32.dll\r
+ 0002:00000078       __imp_CreateTimerQueue     000000014000c078     kernel32:KERNEL32.dll\r
+ 0002:00000080       __imp_WaitForSingleObject  000000014000c080     kernel32:KERNEL32.dll\r
+ 0002:00000088       __imp_ReleaseSRWLockExclusive 000000014000c088     kernel32:KERNEL32.dll\r
+ 0002:00000090       __imp_WriteFile            000000014000c090     kernel32:KERNEL32.dll\r
+ 0002:00000098       __imp_AcquireSRWLockExclusive 000000014000c098     kernel32:KERNEL32.dll\r
+ 0002:000000a0       __imp_Sleep                000000014000c0a0     kernel32:KERNEL32.dll\r
+ 0002:000000a8       __imp_InitializeConditionVariable 000000014000c0a8     kernel32:KERNEL32.dll\r
+ 0002:000000b0       __imp_GetLastError         000000014000c0b0     kernel32:KERNEL32.dll\r
+ 0002:000000b8       __imp_SleepConditionVariableSRW 000000014000c0b8     kernel32:KERNEL32.dll\r
+ 0002:000000c0       __imp_CreateNamedPipeA     000000014000c0c0     kernel32:KERNEL32.dll\r
+ 0002:000000c8       __imp_CreateTimerQueueTimer 000000014000c0c8     kernel32:KERNEL32.dll\r
+ 0002:000000d0       __imp_InitializeSRWLock    000000014000c0d0     kernel32:KERNEL32.dll\r
+ 0002:000000d8       __imp_SetConsoleCtrlHandler 000000014000c0d8     kernel32:KERNEL32.dll\r
+ 0002:000000e0       __imp_DeviceIoControl      000000014000c0e0     kernel32:KERNEL32.dll\r
+ 0002:000000e8       __imp_WakeAllConditionVariable 000000014000c0e8     kernel32:KERNEL32.dll\r
+ 0002:000000f0       __imp_CreateMutexA         000000014000c0f0     kernel32:KERNEL32.dll\r
+ 0002:000000f8       __imp_GetCurrentThreadId   000000014000c0f8     kernel32:KERNEL32.dll\r
+ 0002:00000100       __imp_ReleaseMutex         000000014000c100     kernel32:KERNEL32.dll\r
+ 0002:00000108       __imp_CloseHandle          000000014000c108     kernel32:KERNEL32.dll\r
+ 0002:00000110       __imp_DeleteTimerQueueTimer 000000014000c110     kernel32:KERNEL32.dll\r
+ 0002:00000118       __imp_CreateThread         000000014000c118     kernel32:KERNEL32.dll\r
+ 0002:00000120       __imp_EncodePointer        000000014000c120     kernel32:KERNEL32.dll\r
+ 0002:00000128       __imp_IsDebuggerPresent    000000014000c128     kernel32:KERNEL32.dll\r
+ 0002:00000130       \177KERNEL32_NULL_THUNK_DATA 000000014000c130     kernel32:KERNEL32.dll\r
+ 0002:00000138       __imp_?_Xout_of_range@std@@YAXPEBD@Z 000000014000c138     msvcprt:MSVCP100.dll\r
+ 0002:00000140       __imp_?_Xlength_error@std@@YAXPEBD@Z 000000014000c140     msvcprt:MSVCP100.dll\r
+ 0002:00000148       \177MSVCP100_NULL_THUNK_DATA 000000014000c148     msvcprt:MSVCP100.dll\r
+ 0002:00000150       __imp_??0exception@std@@QEAA@AEBQEBD@Z 000000014000c150     MSVCRT:MSVCR100.dll\r
+ 0002:00000158       __imp_??0exception@std@@QEAA@AEBV01@@Z 000000014000c158     MSVCRT:MSVCR100.dll\r
+ 0002:00000160       __imp_??1exception@std@@UEAA@XZ 000000014000c160     MSVCRT:MSVCR100.dll\r
+ 0002:00000168       __imp_??2@YAPEAX_K@Z       000000014000c168     MSVCRT:MSVCR100.dll\r
+ 0002:00000170       __imp_abort                000000014000c170     MSVCRT:MSVCR100.dll\r
+ 0002:00000178       __imp___iob_func           000000014000c178     MSVCRT:MSVCR100.dll\r
+ 0002:00000180       __imp_fprintf              000000014000c180     MSVCRT:MSVCR100.dll\r
+ 0002:00000188       __imp_strncpy_s            000000014000c188     MSVCRT:MSVCR100.dll\r
+ 0002:00000190       __imp_memset               000000014000c190     MSVCRT:MSVCR100.dll\r
+ 0002:00000198       __imp_strtol               000000014000c198     MSVCRT:MSVCR100.dll\r
+ 0002:000001a0       __imp_strnlen              000000014000c1a0     MSVCRT:MSVCR100.dll\r
+ 0002:000001a8       __imp__purecall            000000014000c1a8     MSVCRT:MSVCR100.dll\r
+ 0002:000001b0       __imp_sprintf_s            000000014000c1b0     MSVCRT:MSVCR100.dll\r
+ 0002:000001b8       __imp_free                 000000014000c1b8     MSVCRT:MSVCR100.dll\r
+ 0002:000001c0       __imp_malloc               000000014000c1c0     MSVCRT:MSVCR100.dll\r
+ 0002:000001c8       __imp_strcpy_s             000000014000c1c8     MSVCRT:MSVCR100.dll\r
+ 0002:000001d0       __imp___C_specific_handler 000000014000c1d0     MSVCRT:MSVCR100.dll\r
+ 0002:000001d8       __imp__unlock              000000014000c1d8     MSVCRT:MSVCR100.dll\r
+ 0002:000001e0       __imp_?what@exception@std@@UEBAPEBDXZ 000000014000c1e0     MSVCRT:MSVCR100.dll\r
+ 0002:000001e8       __imp__lock                000000014000c1e8     MSVCRT:MSVCR100.dll\r
+ 0002:000001f0       __imp__onexit              000000014000c1f0     MSVCRT:MSVCR100.dll\r
+ 0002:000001f8       __imp__amsg_exit           000000014000c1f8     MSVCRT:MSVCR100.dll\r
+ 0002:00000200       __imp___getmainargs        000000014000c200     MSVCRT:MSVCR100.dll\r
+ 0002:00000208       __imp__XcptFilter          000000014000c208     MSVCRT:MSVCR100.dll\r
+ 0002:00000210       __imp__exit                000000014000c210     MSVCRT:MSVCR100.dll\r
+ 0002:00000218       __imp__cexit               000000014000c218     MSVCRT:MSVCR100.dll\r
+ 0002:00000220       __imp_exit                 000000014000c220     MSVCRT:MSVCR100.dll\r
+ 0002:00000228       __imp___initenv            000000014000c228     MSVCRT:MSVCR100.dll\r
+ 0002:00000230       __imp__initterm            000000014000c230     MSVCRT:MSVCR100.dll\r
+ 0002:00000238       __imp__initterm_e          000000014000c238     MSVCRT:MSVCR100.dll\r
+ 0002:00000240       __imp__configthreadlocale  000000014000c240     MSVCRT:MSVCR100.dll\r
+ 0002:00000248       __imp___setusermatherr     000000014000c248     MSVCRT:MSVCR100.dll\r
+ 0002:00000250       __imp__commode             000000014000c250     MSVCRT:MSVCR100.dll\r
+ 0002:00000258       __imp__fmode               000000014000c258     MSVCRT:MSVCR100.dll\r
+ 0002:00000260       __imp___set_app_type       000000014000c260     MSVCRT:MSVCR100.dll\r
+ 0002:00000268       __imp___crt_debugger_hook  000000014000c268     MSVCRT:MSVCR100.dll\r
+ 0002:00000270       __imp_?terminate@@YAXXZ    000000014000c270     MSVCRT:MSVCR100.dll\r
+ 0002:00000278       __imp_?_type_info_dtor_internal_method@type_info@@QEAAXXZ 000000014000c278     MSVCRT:MSVCR100.dll\r
+ 0002:00000280       __imp___dllonexit          000000014000c280     MSVCRT:MSVCR100.dll\r
+ 0002:00000288       __imp_memcpy               000000014000c288     MSVCRT:MSVCR100.dll\r
+ 0002:00000290       __imp_memcmp               000000014000c290     MSVCRT:MSVCR100.dll\r
+ 0002:00000298       __imp__CxxThrowException   000000014000c298     MSVCRT:MSVCR100.dll\r
+ 0002:000002a0       __imp___CxxFrameHandler3   000000014000c2a0     MSVCRT:MSVCR100.dll\r
+ 0002:000002a8       __imp___RTDynamicCast      000000014000c2a8     MSVCRT:MSVCR100.dll\r
+ 0002:000002b0       __imp_??3@YAXPEAX@Z        000000014000c2b0     MSVCRT:MSVCR100.dll\r
+ 0002:000002b8       __imp_printf               000000014000c2b8     MSVCRT:MSVCR100.dll\r
+ 0002:000002c0       \177MSVCR100_NULL_THUNK_DATA 000000014000c2c0     MSVCRT:MSVCR100.dll\r
+ 0002:000002c8       __imp_ntohl                000000014000c2c8     ws2_32:WS2_32.dll\r
+ 0002:000002d0       __imp_htonl                000000014000c2d0     ws2_32:WS2_32.dll\r
+ 0002:000002d8       __imp_ntohs                000000014000c2d8     ws2_32:WS2_32.dll\r
+ 0002:000002e0       __imp_htons                000000014000c2e0     ws2_32:WS2_32.dll\r
+ 0002:000002e8       \177WS2_32_NULL_THUNK_DATA 000000014000c2e8     ws2_32:WS2_32.dll\r
+ 0002:000002f0       __imp_pcap_close           000000014000c2f0     wpcap:wpcap.dll\r
+ 0002:000002f8       __imp_pcap_setfilter       000000014000c2f8     wpcap:wpcap.dll\r
+ 0002:00000300       __imp_pcap_next_ex         000000014000c300     wpcap:wpcap.dll\r
+ 0002:00000308       __imp_pcap_sendpacket      000000014000c308     wpcap:wpcap.dll\r
+ 0002:00000310       __imp_pcap_compile         000000014000c310     wpcap:wpcap.dll\r
+ 0002:00000318       __imp_pcap_open            000000014000c318     wpcap:wpcap.dll\r
+ 0002:00000320       \177wpcap_NULL_THUNK_DATA  000000014000c320     wpcap:wpcap.dll\r
+ 0002:00000328       __xc_a                     000000014000c328     MSVCRT:cinitexe.obj\r
+ 0002:00000350       __xc_z                     000000014000c350     MSVCRT:cinitexe.obj\r
+ 0002:00000358       __xi_a                     000000014000c358     MSVCRT:cinitexe.obj\r
+ 0002:00000370       __xi_z                     000000014000c370     MSVCRT:cinitexe.obj\r
+ 0002:000003a8       ??_7type_info@@6B@         000000014000c3a8     MSVCRT:ti_inst.obj\r
+ 0002:000003c0       ??_C@_0BM@PAPJHAGI@invalid?5map?1set?$DMT?$DO?5iterator?$AA@ 000000014000c3c0     avbts_osnet.obj\r
+ 0002:000003e8       ??_7bad_alloc@std@@6B@     000000014000c3e8     avbts_osnet.obj\r
+ 0002:000003f8       ??_C@_07DOAOMMKG@Enabled?$AA@ 000000014000c3f8     ieee1588port.obj\r
+ 0002:00000400       ??_C@_08JGILNPHN@Disabled?$AA@ 000000014000c400     ieee1588port.obj\r
+ 0002:00000410       ??_C@_0P@MNFODPHI@AsCapable?3?5?$CFs?6?$AA@ 000000014000c410     ieee1588port.obj\r
+ 0002:00000420       ??_C@_0CB@NKHFMBCL@?4?4?2?4?4?2?4?4?2common?2ieee1588port?4cpp@ 000000014000c420     ieee1588port.obj\r
+ 0002:00000450       ??_C@_0GF@MDOAJEFI@ERROR?5at?5?$CFu?5in?5?$CFs?3?5Failed?5to?5ini@ 000000014000c450     ieee1588port.obj\r
+ 0002:000004b8       ??_C@_07DLHCIBDH@default?$AA@ 000000014000c4b8     ieee1588port.obj\r
+ 0002:000004c0       ??_C@_0BK@DFGFBKIK@openPort?3?5thread?5started?6?$AA@ 000000014000c4c0     ieee1588port.obj\r
+ 0002:000004e0       ??_C@_0CP@OBBALOF@ERROR?5at?5?$CFu?5in?5?$CFs?3?5Discarding?5in@ 000000014000c4e0     ieee1588port.obj\r
+ 0002:00000510       ??_C@_0DH@EKGLNKDB@ERROR?5at?5?$CFu?5in?5?$CFs?3?5read?5from?5net@ 000000014000c510     ieee1588port.obj\r
+ 0002:00000548       ??_C@_0CN@JABMLKGN@ERROR?5at?5?$CFu?5in?5?$CFs?3?5sendEventPort@ 000000014000c548     ieee1588port.obj\r
+ 0002:00000578       ??_C@_0BG@CGMOFACK@Starting?5port?5thread?6?$AA@ 000000014000c578     ieee1588port.obj\r
+ 0002:00000590       ??_C@_0DA@JEOMFCHP@ERROR?5at?5?$CFu?5in?5?$CFs?3?5Error?5creatin@ 000000014000c590     ieee1588port.obj\r
+ 0002:000005c0       ??_C@_01EEMJAFIK@?6?$AA@   000000014000c5c0     ieee1588port.obj\r
+ 0002:000005c8       ??_C@_0CP@NPGACHBF@?$CK?$CK?$CKSync?5Timeout?5Expired?5?9?5Becomi@ 000000014000c5c8     ieee1588port.obj\r
+ 0002:00000600       ??_C@_0EA@FIDILCHK@Error?5?$CITX?$CJ?5timestamping?5PDelay?5r@ 000000014000c600     ieee1588port.obj\r
+ 0002:00000640       ??_C@_0DE@BANOKGOL@Error?5?$CITX?$CJ?5timestamping?5PDelay?5r@ 000000014000c640     ieee1588port.obj\r
+ 0002:00000678       ??_C@_0DD@OGAMEIIA@Error?5?$CITX?$CJ?5timestamping?5Sync?5?$CIRe@ 000000014000c678     ieee1588port.obj\r
+ 0002:000006b0       ??_C@_0CK@JAJCOOCC@Error?5?$CITX?$CJ?5timestamping?5Sync?0?5er@ 000000014000c6b0     ieee1588port.obj\r
+ 0002:000006e0       ??_C@_0CD@KBDOGJHF@PDelay?5Response?5Followup?5is?5NULL@ 000000014000c6e0     ieee1588port.obj\r
+ 0002:00000708       ??_C@_0BF@CMGMJLA@Switching?5to?5Master?6?$AA@ 000000014000c708     ieee1588port.obj\r
+ 0002:00000720       ??_C@_0BE@JHDPFIAH@Switching?5to?5Slave?6?$AA@ 000000014000c720     ieee1588port.obj\r
+ 0002:00000738       ??_C@_0BE@JONHPENG@map?1set?$DMT?$DO?5too?5long?$AA@ 000000014000c738     ieee1588port.obj\r
+ 0002:00000758       ??_7LinkLayerAddress@@6B@  000000014000c758     ieee1588port.obj\r
+ 0002:00000768       ??_7InterfaceLabel@@6B@    000000014000c768     ieee1588port.obj\r
+ 0002:00000770       ??_C@_0DO@EBENJJMN@Error?5?$CIRX?$CJ?5timestamping?5RX?5event@ 000000014000c770     ptp_message.obj\r
+ 0002:000007b0       ??_C@_0CA@LPEMILMO@?4?4?2?4?4?2?4?4?2common?2ptp_message?4cpp?$AA@ 000000014000c7b0     ptp_message.obj\r
+ 0002:000007d0       ??_C@_0HH@MLCBNOMP@ERROR?5at?5?$CFu?5in?5?$CFs?3?5?$CK?$CK?$CK?5Received?5@ 000000014000c7d0     ptp_message.obj\r
+ 0002:00000848       ??_C@_0DK@JNCBBDII@ERROR?5at?5?$CFu?5in?5?$CFs?3?5Received?5unsu@ 000000014000c848     ptp_message.obj\r
+ 0002:00000890       ??_C@_0EE@GKDAOEGN@ERROR?5at?5?$CFu?5in?5?$CFs?3?5Received?5Foll@ 000000014000c890     ptp_message.obj\r
+ 0002:000008e0       ??_C@_0EK@GKBMCKE@ERROR?5at?5?$CFu?5in?5?$CFs?3?5Received?5Foll@ 000000014000c8e0     ptp_message.obj\r
+ 0002:00000930       ??_C@_0EB@NKLDNAPB@Error?5?$CITX?$CJ?5timestamping?5PDelay?5R@ 000000014000c930     ptp_message.obj\r
+ 0002:00000978       ??_C@_0DF@LCPJCKOO@Error?5?$CITX?$CJ?5timestamping?5PDelay?5R@ 000000014000c978     ptp_message.obj\r
+ 0002:000009b0       ??_C@_0BO@DLMECCKO@Failed?5to?5get?5PDelay?5RX?5Lock?6?$AA@ 000000014000c9b0     ptp_message.obj\r
+ 0002:000009d0       ??_C@_0EH@DDBECIOJ@ERROR?5at?5?$CFu?5in?5?$CFs?3?5?$DO?$DO?$DO?5Received?5@ 000000014000c9d0     ptp_message.obj\r
+ 0002:00000a20       ??_C@_0EI@NNLKEKEC@ERROR?5at?5?$CFu?5in?5?$CFs?3?5?$DO?$DO?$DO?5Received?5@ 000000014000ca20     ptp_message.obj\r
+ 0002:00000a70       ??_C@_0FN@HBGJNHBE@ERROR?5at?5?$CFu?5in?5?$CFs?3?5Received?5PDel@ 000000014000ca70     ptp_message.obj\r
+ 0002:00000ad0       ??_C@_0CC@DILPCBD@ERROR?5at?5?$CFu?5in?5?$CFs?3?5My?5SeqId?3?5?$CFu?5@ 000000014000cad0     ptp_message.obj\r
+ 0002:00000af8       ??_C@_0CF@BHKGMNAC@ERROR?5at?5?$CFu?5in?5?$CFs?3?5Their?5SeqId?3?5@ 000000014000caf8     ptp_message.obj\r
+ 0002:00000b20       ??_C@_0FO@BHOOLJAL@ERROR?5at?5?$CFu?5in?5?$CFs?3?5Received?5PDel@ 000000014000cb20     ptp_message.obj\r
+ 0002:00000b80       ??_C@_0CH@FHAMNBPF@ERROR?5at?5?$CFu?5in?5?$CFs?3?5?$CFhu?0?5?$CFhu?0?5?$CFhu@ 000000014000cb80     ptp_message.obj\r
+ 0002:00000ba8       ??_C@_0BB@MOGOBHAF@list?$DMT?$DO?5too?5long?$AA@ 000000014000cba8     ptp_message.obj\r
+ 0002:00000bc8       ??_7PTPMessageCommon@@6B@  000000014000cbc8     ptp_message.obj\r
+ 0002:00000be0       ??_7PTPMessageSync@@6B@    000000014000cbe0     ptp_message.obj\r
+ 0002:00000bf8       ??_7PTPMessageAnnounce@@6B@ 000000014000cbf8     ptp_message.obj\r
+ 0002:00000c10       ??_7PTPMessagePathDelayReq@@6B@ 000000014000cc10     ptp_message.obj\r
+ 0002:00000c28       ??_7PTPMessagePathDelayResp@@6B@ 000000014000cc28     ptp_message.obj\r
+ 0002:00000c40       ??_7PTPMessagePathDelayRespFollowUp@@6B@ 000000014000cc40     ptp_message.obj\r
+ 0002:00000c58       ??_7PTPMessageFollowUp@@6B@ 000000014000cc58     ptp_message.obj\r
+ 0002:00000c68       ??_C@_04GBDIODIA@?2?2?4?2?$AA@ 000000014000cc68     daemon_cl.obj\r
+ 0002:00000c70       ??_C@_09IPJPBDHI@?2?2?4?2pipe?2?$AA@ 000000014000cc70     daemon_cl.obj\r
+ 0002:00000c80       ??_C@_0M@FKJIJDJM@gptp?9update?$AA@ 000000014000cc80     daemon_cl.obj\r
+ 0002:00000c90       ??_C@_0BL@JMMFGJEE@Failed?5to?5initialize?5port?6?$AA@ 000000014000cc90     daemon_cl.obj\r
+ 0002:00000cb0       ??_C@_0CD@KNEPODGG@Unable?5to?5register?5Ctrl?9C?5handle@ 000000014000ccb0     daemon_cl.obj\r
+ 0002:00000ce8       ??_7HWTimestamper@@6B@     000000014000cce8     daemon_cl.obj\r
+ 0002:00000d40       ??_7WindowsPCAPNetworkInterface@@6B@ 000000014000cd40     daemon_cl.obj\r
+ 0002:00000d70       ??_7WindowsPCAPNetworkInterfaceFactory@@6B@ 000000014000cd70     daemon_cl.obj\r
+ 0002:00000d80       ??_7WindowsLock@@6B@       000000014000cd80     daemon_cl.obj\r
+ 0002:00000da0       ??_7WindowsLockFactory@@6B@ 000000014000cda0     daemon_cl.obj\r
+ 0002:00000db0       ??_7WindowsCondition@@6B@  000000014000cdb0     daemon_cl.obj\r
+ 0002:00000dd0       ??_7WindowsConditionFactory@@6B@ 000000014000cdd0     daemon_cl.obj\r
+ 0002:00000de0       ??_7WindowsTimerQueue@@6B@ 000000014000cde0     daemon_cl.obj\r
+ 0002:00000df8       ??_7WindowsTimerQueueFactory@@6B@ 000000014000cdf8     daemon_cl.obj\r
+ 0002:00000e08       ??_7WindowsTimer@@6B@      000000014000ce08     daemon_cl.obj\r
+ 0002:00000e18       ??_7WindowsTimerFactory@@6B@ 000000014000ce18     daemon_cl.obj\r
+ 0002:00000e28       ??_7WindowsThread@@6B@     000000014000ce28     daemon_cl.obj\r
+ 0002:00000e40       ??_7WindowsThreadFactory@@6B@ 000000014000ce40     daemon_cl.obj\r
+ 0002:00000e58       ??_7WindowsTimestamper@@6B@ 000000014000ce58     daemon_cl.obj\r
+ 0002:00000eb0       ??_7WindowsNamedPipeIPC@@6B@ 000000014000ceb0     daemon_cl.obj\r
+ 0002:00000ec0       ??_C@_0BF@EIMMNHOL@rpcap?3?1?1?2Device?2NPF_?$AA@ 000000014000cec0     packet.obj\r
+ 0002:00000ed8       ??_C@_0N@IELFOPPD@Opening?3?5?$CFs?6?$AA@ 000000014000ced8     packet.obj\r
+ 0002:00000ee8       ??_C@_0P@CMACLOMI@ether?5proto?50x?$AA@ 000000014000cee8     packet.obj\r
+ 0002:00000ef8       ??_C@_03OIHFBGIJ@?$CFhx?$AA@ 000000014000cef8     packet.obj\r
+ 0002:00000f00       __real@43e0000000000000    000000014000cf00      CIL library: CIL module\r
+ 0002:00000f08       __real@41cdcd6500000000    000000014000cf08      CIL library: CIL module\r
+ 0002:00000f10       __real@43f0000000000000    000000014000cf10      CIL library: CIL module\r
+ 0002:00000f18       __real@3ff0e5604189374c    000000014000cf18      CIL library: CIL module\r
+ 0002:00000f20       __real@3ff0000000000000    000000014000cf20      CIL library: CIL module\r
+ 0002:00000fc8       __real@4008000000000000    000000014000cfc8      CIL library: CIL module\r
+ 0002:00000fd0       __real@4000000000000000    000000014000cfd0      CIL library: CIL module\r
+ 0002:00001050       __real@4024000000000000    000000014000d050      CIL library: CIL module\r
+ 0002:00001410       ??_R4type_info@@6B@        000000014000d410     MSVCRT:ti_inst.obj\r
+ 0002:00001438       ??_R3type_info@@8          000000014000d438     MSVCRT:ti_inst.obj\r
+ 0002:00001450       ??_R2type_info@@8          000000014000d450     MSVCRT:ti_inst.obj\r
+ 0002:00001460       ??_R1A@?0A@EA@type_info@@8 000000014000d460     MSVCRT:ti_inst.obj\r
+ 0002:00001488       ??_R4bad_alloc@std@@6B@    000000014000d488     avbts_osnet.obj\r
+ 0002:000014b0       ??_R3bad_alloc@std@@8      000000014000d4b0     avbts_osnet.obj\r
+ 0002:000014c8       ??_R2bad_alloc@std@@8      000000014000d4c8     avbts_osnet.obj\r
+ 0002:000014e0       ??_R1A@?0A@EA@exception@std@@8 000000014000d4e0     avbts_osnet.obj\r
+ 0002:00001508       ??_R3exception@std@@8      000000014000d508     avbts_osnet.obj\r
+ 0002:00001520       ??_R2exception@std@@8      000000014000d520     avbts_osnet.obj\r
+ 0002:00001530       ??_R1A@?0A@EA@bad_alloc@std@@8 000000014000d530     avbts_osnet.obj\r
+ 0002:00001558       ??_R4InterfaceLabel@@6B@   000000014000d558     ieee1588port.obj\r
+ 0002:00001580       ??_R4LinkLayerAddress@@6B@ 000000014000d580     ieee1588port.obj\r
+ 0002:000015a8       ??_R3LinkLayerAddress@@8   000000014000d5a8     ieee1588port.obj\r
+ 0002:000015c0       ??_R2LinkLayerAddress@@8   000000014000d5c0     ieee1588port.obj\r
+ 0002:000015d8       ??_R1A@?0A@EA@InterfaceLabel@@8 000000014000d5d8     ieee1588port.obj\r
+ 0002:00001600       ??_R3InterfaceLabel@@8     000000014000d600     ieee1588port.obj\r
+ 0002:00001618       ??_R2InterfaceLabel@@8     000000014000d618     ieee1588port.obj\r
+ 0002:00001628       ??_R1A@?0A@EA@LinkLayerAddress@@8 000000014000d628     ieee1588port.obj\r
+ 0002:00001650       ??_R4PTPMessageFollowUp@@6B@ 000000014000d650     ptp_message.obj\r
+ 0002:00001678       ??_R3PTPMessageFollowUp@@8 000000014000d678     ptp_message.obj\r
+ 0002:00001690       ??_R2PTPMessageFollowUp@@8 000000014000d690     ptp_message.obj\r
+ 0002:000016a8       ??_R1A@?0A@EA@PTPMessageFollowUp@@8 000000014000d6a8     ptp_message.obj\r
+ 0002:000016d0       ??_R4PTPMessagePathDelayRespFollowUp@@6B@ 000000014000d6d0     ptp_message.obj\r
+ 0002:000016f8       ??_R3PTPMessagePathDelayRespFollowUp@@8 000000014000d6f8     ptp_message.obj\r
+ 0002:00001710       ??_R2PTPMessagePathDelayRespFollowUp@@8 000000014000d710     ptp_message.obj\r
+ 0002:00001728       ??_R1A@?0A@EA@PTPMessagePathDelayRespFollowUp@@8 000000014000d728     ptp_message.obj\r
+ 0002:00001750       ??_R4PTPMessagePathDelayResp@@6B@ 000000014000d750     ptp_message.obj\r
+ 0002:00001778       ??_R3PTPMessagePathDelayResp@@8 000000014000d778     ptp_message.obj\r
+ 0002:00001790       ??_R2PTPMessagePathDelayResp@@8 000000014000d790     ptp_message.obj\r
+ 0002:000017a8       ??_R1A@?0A@EA@PTPMessagePathDelayResp@@8 000000014000d7a8     ptp_message.obj\r
+ 0002:000017d0       ??_R4PTPMessagePathDelayReq@@6B@ 000000014000d7d0     ptp_message.obj\r
+ 0002:000017f8       ??_R3PTPMessagePathDelayReq@@8 000000014000d7f8     ptp_message.obj\r
+ 0002:00001810       ??_R2PTPMessagePathDelayReq@@8 000000014000d810     ptp_message.obj\r
+ 0002:00001828       ??_R1A@?0A@EA@PTPMessagePathDelayReq@@8 000000014000d828     ptp_message.obj\r
+ 0002:00001850       ??_R4PTPMessageAnnounce@@6B@ 000000014000d850     ptp_message.obj\r
+ 0002:00001878       ??_R3PTPMessageAnnounce@@8 000000014000d878     ptp_message.obj\r
+ 0002:00001890       ??_R2PTPMessageAnnounce@@8 000000014000d890     ptp_message.obj\r
+ 0002:000018a8       ??_R1A@?0A@EA@PTPMessageAnnounce@@8 000000014000d8a8     ptp_message.obj\r
+ 0002:000018d0       ??_R4PTPMessageSync@@6B@   000000014000d8d0     ptp_message.obj\r
+ 0002:000018f8       ??_R3PTPMessageSync@@8     000000014000d8f8     ptp_message.obj\r
+ 0002:00001910       ??_R2PTPMessageSync@@8     000000014000d910     ptp_message.obj\r
+ 0002:00001928       ??_R1A@?0A@EA@PTPMessageSync@@8 000000014000d928     ptp_message.obj\r
+ 0002:00001950       ??_R4PTPMessageCommon@@6B@ 000000014000d950     ptp_message.obj\r
+ 0002:00001978       ??_R3PTPMessageCommon@@8   000000014000d978     ptp_message.obj\r
+ 0002:00001990       ??_R2PTPMessageCommon@@8   000000014000d990     ptp_message.obj\r
+ 0002:000019a0       ??_R1A@?0A@EA@PTPMessageCommon@@8 000000014000d9a0     ptp_message.obj\r
+ 0002:000019c8       ??_R4WindowsNamedPipeIPC@@6B@ 000000014000d9c8     daemon_cl.obj\r
+ 0002:000019f0       ??_R3WindowsNamedPipeIPC@@8 000000014000d9f0     daemon_cl.obj\r
+ 0002:00001a08       ??_R2WindowsNamedPipeIPC@@8 000000014000da08     daemon_cl.obj\r
+ 0002:00001a20       ??_R1A@?0A@EA@WindowsNamedPipeIPC@@8 000000014000da20     daemon_cl.obj\r
+ 0002:00001a48       ??_R4WindowsTimestamper@@6B@ 000000014000da48     daemon_cl.obj\r
+ 0002:00001a70       ??_R3WindowsTimestamper@@8 000000014000da70     daemon_cl.obj\r
+ 0002:00001a88       ??_R2WindowsTimestamper@@8 000000014000da88     daemon_cl.obj\r
+ 0002:00001aa0       ??_R1A@?0A@EA@WindowsTimestamper@@8 000000014000daa0     daemon_cl.obj\r
+ 0002:00001ac8       ??_R4WindowsThreadFactory@@6B@ 000000014000dac8     daemon_cl.obj\r
+ 0002:00001af0       ??_R3WindowsThreadFactory@@8 000000014000daf0     daemon_cl.obj\r
+ 0002:00001b08       ??_R2WindowsThreadFactory@@8 000000014000db08     daemon_cl.obj\r
+ 0002:00001b20       ??_R1A@?0A@EA@WindowsThreadFactory@@8 000000014000db20     daemon_cl.obj\r
+ 0002:00001b48       ??_R4WindowsThread@@6B@    000000014000db48     daemon_cl.obj\r
+ 0002:00001b70       ??_R3WindowsThread@@8      000000014000db70     daemon_cl.obj\r
+ 0002:00001b88       ??_R2WindowsThread@@8      000000014000db88     daemon_cl.obj\r
+ 0002:00001ba0       ??_R1A@?0A@EA@WindowsThread@@8 000000014000dba0     daemon_cl.obj\r
+ 0002:00001bc8       ??_R4WindowsTimerFactory@@6B@ 000000014000dbc8     daemon_cl.obj\r
+ 0002:00001bf0       ??_R3WindowsTimerFactory@@8 000000014000dbf0     daemon_cl.obj\r
+ 0002:00001c08       ??_R2WindowsTimerFactory@@8 000000014000dc08     daemon_cl.obj\r
+ 0002:00001c20       ??_R1A@?0A@EA@WindowsTimerFactory@@8 000000014000dc20     daemon_cl.obj\r
+ 0002:00001c48       ??_R4WindowsTimer@@6B@     000000014000dc48     daemon_cl.obj\r
+ 0002:00001c70       ??_R3WindowsTimer@@8       000000014000dc70     daemon_cl.obj\r
+ 0002:00001c88       ??_R2WindowsTimer@@8       000000014000dc88     daemon_cl.obj\r
+ 0002:00001ca0       ??_R1A@?0A@EA@WindowsTimer@@8 000000014000dca0     daemon_cl.obj\r
+ 0002:00001cc8       ??_R4WindowsTimerQueueFactory@@6B@ 000000014000dcc8     daemon_cl.obj\r
+ 0002:00001cf0       ??_R3WindowsTimerQueueFactory@@8 000000014000dcf0     daemon_cl.obj\r
+ 0002:00001d08       ??_R2WindowsTimerQueueFactory@@8 000000014000dd08     daemon_cl.obj\r
+ 0002:00001d20       ??_R1A@?0A@EA@WindowsTimerQueueFactory@@8 000000014000dd20     daemon_cl.obj\r
+ 0002:00001d48       ??_R4WindowsTimerQueue@@6B@ 000000014000dd48     daemon_cl.obj\r
+ 0002:00001d70       ??_R3WindowsTimerQueue@@8  000000014000dd70     daemon_cl.obj\r
+ 0002:00001d88       ??_R2WindowsTimerQueue@@8  000000014000dd88     daemon_cl.obj\r
+ 0002:00001da0       ??_R1A@?0A@EA@WindowsTimerQueue@@8 000000014000dda0     daemon_cl.obj\r
+ 0002:00001dc8       ??_R4WindowsConditionFactory@@6B@ 000000014000ddc8     daemon_cl.obj\r
+ 0002:00001df0       ??_R3WindowsConditionFactory@@8 000000014000ddf0     daemon_cl.obj\r
+ 0002:00001e08       ??_R2WindowsConditionFactory@@8 000000014000de08     daemon_cl.obj\r
+ 0002:00001e20       ??_R1A@?0A@EA@WindowsConditionFactory@@8 000000014000de20     daemon_cl.obj\r
+ 0002:00001e48       ??_R4WindowsCondition@@6B@ 000000014000de48     daemon_cl.obj\r
+ 0002:00001e70       ??_R3WindowsCondition@@8   000000014000de70     daemon_cl.obj\r
+ 0002:00001e88       ??_R2WindowsCondition@@8   000000014000de88     daemon_cl.obj\r
+ 0002:00001ea0       ??_R1A@?0A@EA@WindowsCondition@@8 000000014000dea0     daemon_cl.obj\r
+ 0002:00001ec8       ??_R4WindowsLockFactory@@6B@ 000000014000dec8     daemon_cl.obj\r
+ 0002:00001ef0       ??_R3WindowsLockFactory@@8 000000014000def0     daemon_cl.obj\r
+ 0002:00001f08       ??_R2WindowsLockFactory@@8 000000014000df08     daemon_cl.obj\r
+ 0002:00001f20       ??_R1A@?0A@EA@WindowsLockFactory@@8 000000014000df20     daemon_cl.obj\r
+ 0002:00001f48       ??_R4WindowsLock@@6B@      000000014000df48     daemon_cl.obj\r
+ 0002:00001f70       ??_R3WindowsLock@@8        000000014000df70     daemon_cl.obj\r
+ 0002:00001f88       ??_R2WindowsLock@@8        000000014000df88     daemon_cl.obj\r
+ 0002:00001fa0       ??_R1A@?0A@EA@WindowsLock@@8 000000014000dfa0     daemon_cl.obj\r
+ 0002:00001fc8       ??_R4WindowsPCAPNetworkInterfaceFactory@@6B@ 000000014000dfc8     daemon_cl.obj\r
+ 0002:00001ff0       ??_R3WindowsPCAPNetworkInterfaceFactory@@8 000000014000dff0     daemon_cl.obj\r
+ 0002:00002008       ??_R2WindowsPCAPNetworkInterfaceFactory@@8 000000014000e008     daemon_cl.obj\r
+ 0002:00002020       ??_R1A@?0A@EA@WindowsPCAPNetworkInterfaceFactory@@8 000000014000e020     daemon_cl.obj\r
+ 0002:00002048       ??_R4WindowsPCAPNetworkInterface@@6B@ 000000014000e048     daemon_cl.obj\r
+ 0002:00002070       ??_R3WindowsPCAPNetworkInterface@@8 000000014000e070     daemon_cl.obj\r
+ 0002:00002088       ??_R2WindowsPCAPNetworkInterface@@8 000000014000e088     daemon_cl.obj\r
+ 0002:000020a0       ??_R1A@?0A@EA@WindowsPCAPNetworkInterface@@8 000000014000e0a0     daemon_cl.obj\r
+ 0002:000020c8       ??_R3OS_IPC@@8             000000014000e0c8     daemon_cl.obj\r
+ 0002:000020e0       ??_R2OS_IPC@@8             000000014000e0e0     daemon_cl.obj\r
+ 0002:000020f0       ??_R1A@?0A@EA@OS_IPC@@8    000000014000e0f0     daemon_cl.obj\r
+ 0002:00002118       ??_R3OSTimerQueueFactory@@8 000000014000e118     daemon_cl.obj\r
+ 0002:00002130       ??_R2OSTimerQueueFactory@@8 000000014000e130     daemon_cl.obj\r
+ 0002:00002140       ??_R1A@?0A@EA@OSTimerQueueFactory@@8 000000014000e140     daemon_cl.obj\r
+ 0002:00002168       ??_R3OSTimerQueue@@8       000000014000e168     daemon_cl.obj\r
+ 0002:00002180       ??_R2OSTimerQueue@@8       000000014000e180     daemon_cl.obj\r
+ 0002:00002190       ??_R1A@?0A@EA@OSTimerQueue@@8 000000014000e190     daemon_cl.obj\r
+ 0002:000021b8       ??_R3OSConditionFactory@@8 000000014000e1b8     daemon_cl.obj\r
+ 0002:000021d0       ??_R2OSConditionFactory@@8 000000014000e1d0     daemon_cl.obj\r
+ 0002:000021e0       ??_R1A@?0A@EA@OSConditionFactory@@8 000000014000e1e0     daemon_cl.obj\r
+ 0002:00002208       ??_R3OSCondition@@8        000000014000e208     daemon_cl.obj\r
+ 0002:00002220       ??_R2OSCondition@@8        000000014000e220     daemon_cl.obj\r
+ 0002:00002230       ??_R1A@?0A@EA@OSCondition@@8 000000014000e230     daemon_cl.obj\r
+ 0002:00002258       ??_R3OSThreadFactory@@8    000000014000e258     daemon_cl.obj\r
+ 0002:00002270       ??_R2OSThreadFactory@@8    000000014000e270     daemon_cl.obj\r
+ 0002:00002280       ??_R1A@?0A@EA@OSThreadFactory@@8 000000014000e280     daemon_cl.obj\r
+ 0002:000022a8       ??_R3OSThread@@8           000000014000e2a8     daemon_cl.obj\r
+ 0002:000022c0       ??_R2OSThread@@8           000000014000e2c0     daemon_cl.obj\r
+ 0002:000022d0       ??_R1A@?0A@EA@OSThread@@8  000000014000e2d0     daemon_cl.obj\r
+ 0002:000022f8       ??_R3OSLockFactory@@8      000000014000e2f8     daemon_cl.obj\r
+ 0002:00002310       ??_R2OSLockFactory@@8      000000014000e310     daemon_cl.obj\r
+ 0002:00002320       ??_R1A@?0A@EA@OSLockFactory@@8 000000014000e320     daemon_cl.obj\r
+ 0002:00002348       ??_R3OSLock@@8             000000014000e348     daemon_cl.obj\r
+ 0002:00002360       ??_R2OSLock@@8             000000014000e360     daemon_cl.obj\r
+ 0002:00002370       ??_R1A@?0A@EA@OSLock@@8    000000014000e370     daemon_cl.obj\r
+ 0002:00002398       ??_R3OSTimerFactory@@8     000000014000e398     daemon_cl.obj\r
+ 0002:000023b0       ??_R2OSTimerFactory@@8     000000014000e3b0     daemon_cl.obj\r
+ 0002:000023c0       ??_R1A@?0A@EA@OSTimerFactory@@8 000000014000e3c0     daemon_cl.obj\r
+ 0002:000023e8       ??_R3OSTimer@@8            000000014000e3e8     daemon_cl.obj\r
+ 0002:00002400       ??_R2OSTimer@@8            000000014000e400     daemon_cl.obj\r
+ 0002:00002410       ??_R1A@?0A@EA@OSTimer@@8   000000014000e410     daemon_cl.obj\r
+ 0002:00002438       ??_R3OSNetworkInterfaceFactory@@8 000000014000e438     daemon_cl.obj\r
+ 0002:00002450       ??_R2OSNetworkInterfaceFactory@@8 000000014000e450     daemon_cl.obj\r
+ 0002:00002460       ??_R1A@?0A@EA@OSNetworkInterfaceFactory@@8 000000014000e460     daemon_cl.obj\r
+ 0002:00002488       ??_R3OSNetworkInterface@@8 000000014000e488     daemon_cl.obj\r
+ 0002:000024a0       ??_R2OSNetworkInterface@@8 000000014000e4a0     daemon_cl.obj\r
+ 0002:000024b0       ??_R1A@?0A@EA@OSNetworkInterface@@8 000000014000e4b0     daemon_cl.obj\r
+ 0002:000024d8       ??_R4HWTimestamper@@6B@    000000014000e4d8     daemon_cl.obj\r
+ 0002:00002500       ??_R3HWTimestamper@@8      000000014000e500     daemon_cl.obj\r
+ 0002:00002518       ??_R2HWTimestamper@@8      000000014000e518     daemon_cl.obj\r
+ 0002:00002528       ??_R1A@?0A@EA@HWTimestamper@@8 000000014000e528     daemon_cl.obj\r
+ 0002:00002550       __rtc_iaa                  000000014000e550     MSVCRT:_initsect_.obj\r
+ 0002:00002558       __rtc_izz                  000000014000e558     MSVCRT:_initsect_.obj\r
+ 0002:00002560       __rtc_taa                  000000014000e560     MSVCRT:_initsect_.obj\r
+ 0002:00002568       __rtc_tzz                  000000014000e568     MSVCRT:_initsect_.obj\r
+ 0002:00003750       _CT??_R0?AVbad_alloc@std@@@8??0bad_alloc@std@@QEAA@AEBV01@@Z24 000000014000f750     avbts_osnet.obj\r
+ 0002:00003778       _CT??_R0?AVexception@std@@@8??0exception@std@@QEAA@AEBV01@@Z24 000000014000f778     avbts_osnet.obj\r
+ 0002:000037a0       _CTA2?AVbad_alloc@std@@    000000014000f7a0     avbts_osnet.obj\r
+ 0002:000037b8       _TI2?AVbad_alloc@std@@     000000014000f7b8     avbts_osnet.obj\r
+ 0002:000037d4       __IMPORT_DESCRIPTOR_wpcap  000000014000f7d4     wpcap:wpcap.dll\r
+ 0002:000037e8       __IMPORT_DESCRIPTOR_IPHLPAPI 000000014000f7e8     Iphlpapi:IPHLPAPI.DLL\r
+ 0002:000037fc       __IMPORT_DESCRIPTOR_WS2_32 000000014000f7fc     ws2_32:WS2_32.dll\r
+ 0002:00003810       __IMPORT_DESCRIPTOR_KERNEL32 000000014000f810     kernel32:KERNEL32.dll\r
+ 0002:00003824       __IMPORT_DESCRIPTOR_MSVCP100 000000014000f824     msvcprt:MSVCP100.dll\r
+ 0002:00003838       __IMPORT_DESCRIPTOR_MSVCR100 000000014000f838     MSVCRT:MSVCR100.dll\r
+ 0002:0000384c       __NULL_IMPORT_DESCRIPTOR   000000014000f84c     wpcap:wpcap.dll\r
+ 0003:00000000       ??_R0?AVtype_info@@@8      0000000140011000     MSVCRT:ti_inst.obj\r
+ 0003:00000020       __security_cookie          0000000140011020     MSVCRT:gs_cookie.obj\r
+ 0003:00000028       __security_cookie_complement 0000000140011028     MSVCRT:gs_cookie.obj\r
+ 0003:00000030       __native_dllmain_reason    0000000140011030     MSVCRT:natstart.obj\r
+ 0003:00000034       __native_vcclrit_reason    0000000140011034     MSVCRT:natstart.obj\r
+ 0003:00000038       __globallocalestatus       0000000140011038     MSVCRT:xthdloc.obj\r
+ 0003:0000003c       __defaultmatherr           000000014001103c     MSVCRT:merr.obj\r
+ 0003:00000040       ??_R0?AVbad_alloc@std@@@8  0000000140011040     avbts_osnet.obj\r
+ 0003:00000068       ??_R0?AVexception@std@@@8  0000000140011068     avbts_osnet.obj\r
+ 0003:00000090       ??_R0?AVInterfaceLabel@@@8 0000000140011090     ieee1588port.obj\r
+ 0003:000000b8       ??_R0?AVLinkLayerAddress@@@8 00000001400110b8     ieee1588port.obj\r
+ 0003:000000e0       ??_R0?AVPTPMessageFollowUp@@@8 00000001400110e0     ptp_message.obj\r
+ 0003:00000110       ??_R0?AVPTPMessagePathDelayRespFollowUp@@@8 0000000140011110     ptp_message.obj\r
+ 0003:00000148       ??_R0?AVPTPMessagePathDelayResp@@@8 0000000140011148     ptp_message.obj\r
+ 0003:00000178       ??_R0?AVPTPMessagePathDelayReq@@@8 0000000140011178     ptp_message.obj\r
+ 0003:000001a8       ??_R0?AVPTPMessageAnnounce@@@8 00000001400111a8     ptp_message.obj\r
+ 0003:000001d8       ??_R0?AVPTPMessageSync@@@8 00000001400111d8     ptp_message.obj\r
+ 0003:00000200       ??_R0?AVPTPMessageCommon@@@8 0000000140011200     ptp_message.obj\r
+ 0003:00000228       ??_R0?AVWindowsNamedPipeIPC@@@8 0000000140011228     daemon_cl.obj\r
+ 0003:00000258       ??_R0?AVWindowsTimestamper@@@8 0000000140011258     daemon_cl.obj\r
+ 0003:00000288       ??_R0?AVWindowsThreadFactory@@@8 0000000140011288     daemon_cl.obj\r
+ 0003:000002b8       ??_R0?AVWindowsThread@@@8  00000001400112b8     daemon_cl.obj\r
+ 0003:000002e0       ??_R0?AVWindowsTimerFactory@@@8 00000001400112e0     daemon_cl.obj\r
+ 0003:00000310       ??_R0?AVWindowsTimer@@@8   0000000140011310     daemon_cl.obj\r
+ 0003:00000338       ??_R0?AVWindowsTimerQueueFactory@@@8 0000000140011338     daemon_cl.obj\r
+ 0003:00000368       ??_R0?AVWindowsTimerQueue@@@8 0000000140011368     daemon_cl.obj\r
+ 0003:00000390       ??_R0?AVWindowsConditionFactory@@@8 0000000140011390     daemon_cl.obj\r
+ 0003:000003c0       ??_R0?AVWindowsCondition@@@8 00000001400113c0     daemon_cl.obj\r
+ 0003:000003e8       ??_R0?AVWindowsLockFactory@@@8 00000001400113e8     daemon_cl.obj\r
+ 0003:00000418       ??_R0?AVWindowsLock@@@8    0000000140011418     daemon_cl.obj\r
+ 0003:00000440       ??_R0?AVWindowsPCAPNetworkInterfaceFactory@@@8 0000000140011440     daemon_cl.obj\r
+ 0003:00000480       ??_R0?AVWindowsPCAPNetworkInterface@@@8 0000000140011480     daemon_cl.obj\r
+ 0003:000004b8       ??_R0?AVOS_IPC@@@8         00000001400114b8     daemon_cl.obj\r
+ 0003:000004d8       ??_R0?AVOSTimerQueueFactory@@@8 00000001400114d8     daemon_cl.obj\r
+ 0003:00000508       ??_R0?AVOSTimerQueue@@@8   0000000140011508     daemon_cl.obj\r
+ 0003:00000530       ??_R0?AVOSConditionFactory@@@8 0000000140011530     daemon_cl.obj\r
+ 0003:00000560       ??_R0?AVOSCondition@@@8    0000000140011560     daemon_cl.obj\r
+ 0003:00000588       ??_R0?AVOSThreadFactory@@@8 0000000140011588     daemon_cl.obj\r
+ 0003:000005b0       ??_R0?AVOSThread@@@8       00000001400115b0     daemon_cl.obj\r
+ 0003:000005d0       ??_R0?AVOSLockFactory@@@8  00000001400115d0     daemon_cl.obj\r
+ 0003:000005f8       ??_R0?AVOSLock@@@8         00000001400115f8     daemon_cl.obj\r
+ 0003:00000618       ??_R0?AVOSTimerFactory@@@8 0000000140011618     daemon_cl.obj\r
+ 0003:00000640       ??_R0?AVOSTimer@@@8        0000000140011640     daemon_cl.obj\r
+ 0003:00000660       ??_R0?AVOSNetworkInterfaceFactory@@@8 0000000140011660     daemon_cl.obj\r
+ 0003:00000690       ??_R0?AVOSNetworkInterface@@@8 0000000140011690     daemon_cl.obj\r
+ 0003:000006c0       ??_R0?AVHWTimestamper@@@8  00000001400116c0     daemon_cl.obj\r
+ 0003:000006e8       ?other_multicast@IEEE1588Port@@0VLinkLayerAddress@@A 00000001400116e8     ieee1588port.obj\r
+ 0003:000006f8       ?pdelay_multicast@IEEE1588Port@@0VLinkLayerAddress@@A 00000001400116f8     ieee1588port.obj\r
+ 0003:00000710       _fltused                   0000000140011710     MSVCRT:dllsupp.obj\r
+ 0003:00000cc0       _dowildcard                0000000140011cc0     MSVCRT:wildcard.obj\r
+ 0003:00000cc4       _newmode                   0000000140011cc4     MSVCRT:_newmode.obj\r
+ 0003:00000cc8       _commode                   0000000140011cc8     MSVCRT:xncommod.obj\r
+ 0003:00000ccc       _fmode                     0000000140011ccc     MSVCRT:xtxtmode.obj\r
+ 0003:00000cd8       ?factoryMap@OSNetworkInterfaceFactory@@0V?$map@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@@std@@A 0000000140011cd8     avbts_osnet.obj\r
+ 0003:00000cf8       __native_startup_state     0000000140011cf8     <common>\r
+ 0003:00000d00       __native_startup_lock      0000000140011d00     <common>\r
+ 0003:00000d08       __dyn_tls_init_callback    0000000140011d08     <common>\r
+ 0003:00000d10       __onexitend                0000000140011d10     <common>\r
+ 0003:00000d18       __onexitbegin              0000000140011d18     <common>\r
+\r
+ entry point at        0001:0000991c\r
+\r
+ Static symbols\r
+\r
+ 0001:00009664       pre_cpp_init               000000014000a664 f   MSVCRT:crtexe.obj\r
+ 0001:000096cc       __tmainCRTStartup          000000014000a6cc f   MSVCRT:crtexe.obj\r
+ 0001:0000984c       pre_c_init                 000000014000a84c f   MSVCRT:crtexe.obj\r
+ 0001:00009f60       _onexit$fin$0              000000014000af60 f   MSVCRT:atonexit.obj\r
+ 0001:00009f7b       __tmainCRTStartup$filt$0   000000014000af7b f   MSVCRT:crtexe.obj\r
+ 0001:00009f99       ?filt$0@?0??__ArrayUnwind@@YAXPEAX_KHP6AX0@Z@Z@4HA 000000014000af99 f   MSVCRT:ehvecdtr.obj\r
+ 0001:00009fda       ?fin$0@?0???_M@YAXPEAX_KHP6AX0@Z@Z@4HA 000000014000afda f   MSVCRT:ehvecdtr.obj\r
+ 0001:0000a010       _IsNonwritableInCurrentImage$filt$0 000000014000b010 f   MSVCRT:pesect.obj\r
+ 0001:0000a040       ?catch$0@?0???$_Insert@V?$_List_const_iterator@V?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@@std@@@?$list@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAAXV?$_List_const_iterator@V?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@@1@00Uforward_iterator_tag@1@@Z@4HA 000000014000b040 f    CIL library: CIL module\r
+ 0001:0000a04f       __catch$??$_Insert@V?$_List_const_iterator@V?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@@std@@@?$list@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAAXV?$_List_const_iterator@V?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@@1@00Uforward_iterator_tag@1@@Z$0 000000014000b04f f    CIL library: CIL module\r
+ 0001:0000a0b0       ?dtor$0@?0???0?$list@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAA@AEBV01@@Z@4HA 000000014000b0b0 f    CIL library: CIL module\r
+ 0001:0000a0c0       ?catch$0@?0???0?$list@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAA@AEBV01@@Z@4HA 000000014000b0c0 f    CIL library: CIL module\r
+ 0001:0000a0cd       __catch$??0?$list@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAA@AEBV01@@Z$0 000000014000b0cd f    CIL library: CIL module\r
+ 0001:0000a0e0       ?catch$0@?0??_Buynode@?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAAPEAU_Node@?$_List_nod@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@2@PEAU342@0AEBQEAUWindowsTimerQueueHandlerArg@@@Z@4HA 000000014000b0e0 f    CIL library: CIL module\r
+ 0001:0000a0e0       ?catch$0@?0??_Buynode@?$_List_val@PEAVPTPMessageAnnounce@@V?$allocator@PEAVPTPMessageAnnounce@@@std@@@std@@QEAAPEAU_Node@?$_List_nod@PEAVPTPMessageAnnounce@@V?$allocator@PEAVPTPMessageAnnounce@@@std@@@2@PEAU342@0AEBQEAVPTPMessageAnnounce@@@Z@4HA 000000014000b0e0 f    CIL library: CIL module\r
+ 0001:0000a0ed       __catch$?_Buynode@?$_List_val@PEAVPTPMessageAnnounce@@V?$allocator@PEAVPTPMessageAnnounce@@@std@@@std@@QEAAPEAU_Node@?$_List_nod@PEAVPTPMessageAnnounce@@V?$allocator@PEAVPTPMessageAnnounce@@@std@@@2@PEAU342@0AEBQEAVPTPMessageAnnounce@@@Z$0 000000014000b0ed f    CIL library: CIL module\r
+ 0001:0000a0ed       __catch$?_Buynode@?$_List_val@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@std@@QEAAPEAU_Node@?$_List_nod@PEAUWindowsTimerQueueHandlerArg@@V?$allocator@PEAUWindowsTimerQueueHandlerArg@@@std@@@2@PEAU342@0AEBQEAUWindowsTimerQueueHandlerArg@@@Z$0 000000014000b0ed f    CIL library: CIL module\r
+ 0001:0000a110       ?dtor$0@?0???0PTPMessagePathDelayResp@@QEAA@PEAVIEEE1588Port@@@Z@4HA 000000014000b110 f    CIL library: CIL module\r
+ 0001:0000a110       ?dtor$0@?0???0PTPMessageAnnounce@@QEAA@PEAVIEEE1588Port@@@Z@4HA 000000014000b110 f    CIL library: CIL module\r
+ 0001:0000a110       ?dtor$0@?0???0PTPMessagePathDelayRespFollowUp@@QEAA@PEAVIEEE1588Port@@@Z@4HA 000000014000b110 f    CIL library: CIL module\r
+ 0001:0000a120       ?catch$0@?0???$_Buynode@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@1@$$QEAU?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@1@@Z@4HA 000000014000b120 f    CIL library: CIL module\r
+ 0001:0000a12d       __catch$??$_Buynode@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@?$_Tree_val@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@$0A@@std@@@1@$$QEAU?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@1@@Z$0 000000014000b12d f    CIL library: CIL module\r
+ 0001:0000a150       ?catch$0@?0???$_Buynode@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@1@$$QEAU?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@1@@Z@4HA 000000014000b150 f    CIL library: CIL module\r
+ 0001:0000a15d       __catch$??$_Buynode@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@?$_Tree_val@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@$0A@@std@@@1@$$QEAU?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@1@@Z$0 000000014000b15d f    CIL library: CIL module\r
+ 0001:0000a180       ?dtor$0@?0???$_Buynode@U?$pair@$$CBHUTimerQueue_t@@@std@@@?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@1@$$QEAU?$pair@$$CBHUTimerQueue_t@@@1@@Z@4HA 000000014000b180 f    CIL library: CIL module\r
+ 0001:0000a1a0       ?catch$0@?0???$_Buynode@U?$pair@$$CBHUTimerQueue_t@@@std@@@?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@1@$$QEAU?$pair@$$CBHUTimerQueue_t@@@1@@Z@4HA 000000014000b1a0 f    CIL library: CIL module\r
+ 0001:0000a1ad       __catch$??$_Buynode@U?$pair@$$CBHUTimerQueue_t@@@std@@@?$_Tree_val@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@std@@QEAAPEAU_Node@?$_Tree_nod@V?$_Tmap_traits@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@$0A@@std@@@1@$$QEAU?$pair@$$CBHUTimerQueue_t@@@1@@Z$0 000000014000b1ad f    CIL library: CIL module\r
+ 0001:0000a1d0       ?dtor$1@?0???1?$map@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@@std@@QEAA@XZ@4HA 000000014000b1d0 f    CIL library: CIL module\r
+ 0001:0000a1d0       ?dtor$1@?0???1?$map@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@@std@@QEAA@XZ@4HA 000000014000b1d0 f    CIL library: CIL module\r
+ 0001:0000a1e0       ?dtor$0@?0???0WindowsTimerQueue@@IEAA@XZ@4HA 000000014000b1e0 f    CIL library: CIL module\r
+ 0001:0000a1f0       ?dtor$0@?0???A?$map@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@@std@@QEAAAEAVLinkLayerAddress@@AEBVPortIdentity@@@Z@4HA 000000014000b1f0 f    CIL library: CIL module\r
+ 0001:0000a200       ?dtor$1@?0???A?$map@VPortIdentity@@VLinkLayerAddress@@U?$less@VPortIdentity@@@std@@V?$allocator@U?$pair@$$CBVPortIdentity@@VLinkLayerAddress@@@std@@@4@@std@@QEAAAEAVLinkLayerAddress@@AEBVPortIdentity@@@Z@4HA 000000014000b200 f    CIL library: CIL module\r
+ 0001:0000a210       ?dtor$0@?0???0IEEE1588Port@@QEAA@PEAVIEEE1588Clock@@G_NPEAVHWTimestamper@@1HPEAVInterfaceLabel@@PEAVOSConditionFactory@@PEAVOSThreadFactory@@PEAVOSTimerFactory@@PEAVOSLockFactory@@@Z@4HA 000000014000b210 f    CIL library: CIL module\r
+ 0001:0000a220       ?dtor$1@?0???0IEEE1588Port@@QEAA@PEAVIEEE1588Clock@@G_NPEAVHWTimestamper@@1HPEAVInterfaceLabel@@PEAVOSConditionFactory@@PEAVOSThreadFactory@@PEAVOSTimerFactory@@PEAVOSLockFactory@@@Z@4HA 000000014000b220 f    CIL library: CIL module\r
+ 0001:0000a240       ?dtor$2@?0???0IEEE1588Port@@QEAA@PEAVIEEE1588Clock@@G_NPEAVHWTimestamper@@1HPEAVInterfaceLabel@@PEAVOSConditionFactory@@PEAVOSThreadFactory@@PEAVOSTimerFactory@@PEAVOSLockFactory@@@Z@4HA 000000014000b240 f    CIL library: CIL module\r
+ 0001:0000a260       ?dtor$0@?0???A?$map@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@@std@@QEAAAEAUTimerQueue_t@@AEBH@Z@4HA 000000014000b260 f    CIL library: CIL module\r
+ 0001:0000a270       ?dtor$1@?0???A?$map@HUTimerQueue_t@@U?$less@H@std@@V?$allocator@U?$pair@$$CBHUTimerQueue_t@@@std@@@3@@std@@QEAAAEAUTimerQueue_t@@AEBH@Z@4HA 000000014000b270 f    CIL library: CIL module\r
+ 0001:0000a280       ?dtor$0@?0??createOSTimerQueue@WindowsTimerQueueFactory@@UEAAPEAVOSTimerQueue@@XZ@4HA 000000014000b280 f    CIL library: CIL module\r
+ 0001:0000a290       ?dtor$8@?0??buildPTPMessage@@YAPEAVPTPMessageCommon@@PEADHPEAVLinkLayerAddress@@PEAVIEEE1588Port@@@Z@4HA 000000014000b290 f    CIL library: CIL module\r
+ 0001:0000a2a0       ?dtor$10@?0??buildPTPMessage@@YAPEAVPTPMessageCommon@@PEADHPEAVLinkLayerAddress@@PEAVIEEE1588Port@@@Z@4HA 000000014000b2a0 f    CIL library: CIL module\r
+ 0001:0000a2b0       ?dtor$0@?0??openPort@IEEE1588Port@@QEAAPEAXXZ@4HA 000000014000b2b0 f    CIL library: CIL module\r
+ 0001:0000a2c0       ?dtor$0@?0??processMessage@PTPMessagePathDelayReq@@UEAAXPEAVIEEE1588Port@@@Z@4HA 000000014000b2c0 f    CIL library: CIL module\r
+ 0001:0000a2d0       ?dtor$1@?0??processMessage@PTPMessagePathDelayReq@@UEAAXPEAVIEEE1588Port@@@Z@4HA 000000014000b2d0 f    CIL library: CIL module\r
+ 0001:0000a2e0       ?dtor$0@?0??sendPort@PTPMessagePathDelayReq@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z@4HA 000000014000b2e0 f    CIL library: CIL module\r
+ 0001:0000a2e0       ?dtor$0@?0??sendPort@PTPMessagePathDelayResp@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z@4HA 000000014000b2e0 f    CIL library: CIL module\r
+ 0001:0000a2e0       ?dtor$0@?0??sendPort@PTPMessagePathDelayRespFollowUp@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z@4HA 000000014000b2e0 f    CIL library: CIL module\r
+ 0001:0000a2e0       ?dtor$0@?0??sendPort@PTPMessageAnnounce@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z@4HA 000000014000b2e0 f    CIL library: CIL module\r
+ 0001:0000a2e0       ?dtor$0@?0??sendPort@PTPMessageFollowUp@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z@4HA 000000014000b2e0 f    CIL library: CIL module\r
+ 0001:0000a2e0       ?dtor$0@?0??sendPort@PTPMessageSync@@QEAAXPEAVIEEE1588Port@@PEAVPortIdentity@@@Z@4HA 000000014000b2e0 f    CIL library: CIL module\r
+ 0001:0000a2f0       ?dtor$0@?0??processEvent@IEEE1588Port@@QEAAXW4Event@@@Z@4HA 000000014000b2f0 f    CIL library: CIL module\r
+ 0001:0000a300       ?dtor$1@?0??processEvent@IEEE1588Port@@QEAAXW4Event@@@Z@4HA 000000014000b300 f    CIL library: CIL module\r
+ 0001:0000a310       ?dtor$2@?0??processEvent@IEEE1588Port@@QEAAXW4Event@@@Z@4HA 000000014000b310 f    CIL library: CIL module\r
+ 0001:0000a320       ?dtor$3@?0??processEvent@IEEE1588Port@@QEAAXW4Event@@@Z@4HA 000000014000b320 f    CIL library: CIL module\r
+ 0001:0000a330       main$dtor$1                000000014000b330 f    CIL library: CIL module\r
+ 0001:0000a340       main$dtor$2                000000014000b340 f    CIL library: CIL module\r
+ 0001:0000a350       main$dtor$3                000000014000b350 f    CIL library: CIL module\r
+ 0001:0000a360       ?dtor$1@?0???__F?factoryMap@OSNetworkInterfaceFactory@@0V?$map@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@@std@@A@@YAXXZ@4HA 000000014000b360 f    CIL library: CIL module\r
+ 0001:0000a370       ??__E?factoryMap@OSNetworkInterfaceFactory@@0V?$map@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@@std@@A@@YAXXZ 000000014000b370 f    CIL library: CIL module\r
+ 0001:0000a390       ??__E?other_multicast@IEEE1588Port@@0VLinkLayerAddress@@A@@YAXXZ 000000014000b390 f    CIL library: CIL module\r
+ 0001:0000a3e0       ??__E?pdelay_multicast@IEEE1588Port@@0VLinkLayerAddress@@A@@YAXXZ 000000014000b3e0 f    CIL library: CIL module\r
+ 0001:0000a430       ??__F?factoryMap@OSNetworkInterfaceFactory@@0V?$map@Vfactory_name_t@@PEAVOSNetworkInterfaceFactory@@U?$less@Vfactory_name_t@@@std@@V?$allocator@U?$pair@$$CBVfactory_name_t@@PEAVOSNetworkInterfaceFactory@@@std@@@4@@std@@A@@YAXXZ 000000014000b430 f    CIL library: CIL module\r
+ 0001:0000a470       ??__F?other_multicast@IEEE1588Port@@0VLinkLayerAddress@@A@@YAXXZ 000000014000b470 f    CIL library: CIL module\r
+ 0001:0000a480       ??__F?pdelay_multicast@IEEE1588Port@@0VLinkLayerAddress@@A@@YAXXZ 000000014000b480 f    CIL library: CIL module\r
diff --git a/daemons/mrpd/README b/daemons/mrpd/README
new file mode 100644 (file)
index 0000000..e68d938
--- /dev/null
@@ -0,0 +1,11 @@
+INTRODUCTION
+
+The MRP daemon is required to establish stream reservations with compatible AVB
+infrastructure devices. The command line selectively enables MMRP (via the 
+-m option), MVRP (via the -v option), and MSRP (via the -s option). You must 
+also specify the interface on which you want to bind the daemon to 
+(e.g. -i eth2). The full command line typically appears as follows:
+       sudo ./mrpd -mvs -i eth2
+
+Sample client applications - mrpctl, mrpq, mrpl - illustrate how to connect, 
+query and add attributes to the MRP daemon.
diff --git a/examples/Makefile b/examples/Makefile
deleted file mode 100644 (file)
index a25b198..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-OPT=-O2
-#CFLAGS=$(OPT) -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -ggdb
-CFLAGS=$(OPT) -Wall -W -Wno-parentheses -ggdb
-
-CC=gcc
-INCFLAGS=-I../lib
-LDLIBS=-ligb -lpci -lz -pthread
-LDFLAGS=-L../lib
-
-all: test latency_test simple_talker mrpq mrpl
-
-test: test.o
-
-simple_talker: simple_talker.o
-
-mrpl: mrpl.o
-
-mrpq: mrpq.o
-
-latency_test: latency_test.o
-
-latency_test.o: latency_test.c
-       gcc -c $(INCFLAGS) $(CFLAGS) latency_test.c
-
-test.o: test.c
-       gcc -c $(INCFLAGS) $(CFLAGS) test.c
-
-simple_talker.o: simple_talker.c
-       gcc -c $(INCFLAGS) -I../daemons/mrpd $(CFLAGS) simple_talker.c
-
-mrpl.o: mrpl.c
-       gcc -c $(INCFLAGS) -I../daemons/mrpd $(CFLAGS) mrpl.c
-
-mrpq.o: mrpq.c
-       gcc -c $(INCFLAGS) -I../daemons/mrpd $(CFLAGS) mrpq.c
-
-%: %.o
-       $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
-
-clean:
-       rm -f `find . -name "*~" -o -name "*.[oa]" -o -name "\#*\#" -o -name TAGS -o -name core -o -name "*.orig"`
-
diff --git a/examples/latency_test.c b/examples/latency_test.c
deleted file mode 100644 (file)
index 70d0787..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/******************************************************************************
-
-  Copyright (c) 2001-2012, Intel Corporation 
-  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.
-  
-   3. Neither the name of the Intel Corporation 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.
-
-******************************************************************************/
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <signal.h>
-#include <errno.h>
-
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/mman.h>
-#include <sys/user.h>
-
-#include <sys/un.h>
-
-#include <pci/pci.h>
-
-#include "igb.h"
-
-#define IGB_BIND_NAMESZ 24
-
-device_t       igb_dev;
-volatile int   halt_tx;
-
-void
-sigint_handler (int signum)
-{
-       printf("halting ...\n");
-       halt_tx = signum;
-}
-
-int
-connect()
-{
-       struct  pci_access      *pacc;
-       struct  pci_dev *dev;
-       int             err;
-       char    devpath[IGB_BIND_NAMESZ];
-
-       memset(&igb_dev, 0, sizeof(device_t));
-
-       pacc    =       pci_alloc();
-       pci_init(pacc); 
-       pci_scan_bus(pacc);
-       for     (dev=pacc->devices;     dev;    dev=dev->next)
-       {
-               pci_fill_info(dev,      PCI_FILL_IDENT  |       PCI_FILL_BASES  |       PCI_FILL_CLASS);
-
-               igb_dev.pci_vendor_id = dev->vendor_id;
-               igb_dev.pci_device_id = dev->device_id;
-               igb_dev.domain = dev->domain;
-               igb_dev.bus = dev->bus;
-               igb_dev.dev = dev->dev;
-               igb_dev.func = dev->func;
-
-               snprintf(devpath, IGB_BIND_NAMESZ, "%04x:%02x:%02x.%d", \
-                       dev->domain, dev->bus, dev->dev, dev->func );
-               printf("probing %s\n", devpath);
-
-               err = igb_probe(&igb_dev);
-
-               if (err) {
-                       continue;
-               }
-
-               printf ("attaching to %s\n", devpath);
-               err = igb_attach(devpath, &igb_dev);
-
-               if (err) {
-                       printf ("attach failed! (%s)\n", strerror(errno));
-                       continue;
-               }
-               printf("attach successful to %s\n", devpath);
-               goto out;
-       }
-
-       pci_cleanup(pacc);
-       return  ENXIO;
-
-out:
-       pci_cleanup(pacc);
-       return  0;
-
-}
-
-#define VERSION_STR    "1.0"
-
-static const char *version_str =
-"latency test v" VERSION_STR "\n"
-"Copyright (c) 2012, Intel Corporation\n";
-
-
-static void
-usage( void ) {
-       fprintf(stderr, 
-               "\n"
-               "usage: latency_test [-hr] [-d <obs>]"
-               "\n"
-               "options:\n"
-               "    -h  show this message\n"
-               "    -d  observation window (seconds)\n"
-               "    -p  delay from sw schedule to hw transmit in usec (defaults to 20 msec)\n"
-               "\n"
-               "%s"
-               "\n", version_str);
-       exit(1);
-}
-
-#define PACKET_IPG     (20000000) /* 20 msec */
-
-int
-main(int argc, char *argv[]) {
-       int     c;
-       unsigned        i;
-       unsigned        tqavctl;
-       int     err;
-       struct igb_dma_alloc    a_page;
-       struct igb_packet       a_packet;
-       struct igb_packet       *tmp_packet;
-       struct igb_packet       *cleaned_packets;
-       struct igb_packet       *free_packets;
-       u_int64_t       last_time;
-       u_int64_t       rdtsc0;
-       unsigned int    captured_latency;
-       int             obs_window = 1;
-       int             obs_window_count;
-       int             ipg = PACKET_IPG / 1000;
-
-       unsigned int            min = 0xFFFFFFFF;
-       unsigned int            max = 0;
-       float           avg = 0.0;
-
-       for (;;) {
-               c = getopt(argc, argv, "hrp:d:");
-
-               if (c < 0)
-                       break;
-
-               switch (c) {
-               default:
-               case 'h':
-                       usage();
-                       break;
-               case 'p':
-                       sscanf(optarg, "%d", &ipg);
-                       break;
-               case 'd':
-                       sscanf(optarg, "%d", &obs_window);
-                       break;
-               }
-       }
-       if (optind < argc)
-               usage();
-
-       ipg *= 1000; /* scale to nsec */
-
-       if (ipg > 400000000) { printf("specified delay is too large \n"); return(-1); }
-
-       err = connect();
-
-       if (err) { printf("connect failed (%s)\n", strerror(errno)); return(errno); }
-
-       err = igb_init(&igb_dev);
-
-       if (err) { printf("init failed (%s)\n", strerror(errno)); return(errno); }
-
-       err = igb_dma_malloc_page(&igb_dev, &a_page);
-
-       if (err) { printf("malloc failed (%s)\n", strerror(errno)); return(errno); }
-
-#define PKT_SZ 200
-       memset(&a_packet, 0, sizeof(a_packet));
-
-       a_packet.dmatime = a_packet.attime = a_packet.flags = 0;
-       a_packet.map.paddr = a_page.dma_paddr;
-       a_packet.map.mmap_size = a_page.mmap_size;
-
-       a_packet.offset = 0; 
-       a_packet.vaddr = a_page.dma_vaddr + a_packet.offset;
-       a_packet.len = PKT_SZ;
-       
-       free_packets = NULL; 
-       
-       /* divide the dma page into buffers for packets */
-       for (i = 1; i < ((a_page.mmap_size) / PKT_SZ); i++) {
-               tmp_packet = malloc(sizeof(struct igb_packet));
-               if (NULL == tmp_packet) { printf("malloc failed (%s)\n", strerror(errno)); return(errno); }
-               *tmp_packet = a_packet;
-               tmp_packet->offset = (i * PKT_SZ);
-               tmp_packet->vaddr += tmp_packet->offset;
-               tmp_packet->next = free_packets;
-               memset(tmp_packet->vaddr, 0xffffffff, PKT_SZ); /* MAC header at least */
-               free_packets = tmp_packet;
-       }
-
-       igb_set_class_bandwidth(&igb_dev, 0, 0, 0); /* disable Qav */
-       igb_readreg(&igb_dev, 0x3570, &tqavctl);
-       tqavctl &= 0xFFFF; /* zero-out the prefetch delay */
-       igb_writereg(&igb_dev, 0x3570, tqavctl); 
-
-       halt_tx = 0;
-       signal(SIGINT, sigint_handler);
-
-
-       igb_get_wallclock(&igb_dev, &last_time, &rdtsc0);
-
-       obs_window_count = obs_window;
-
-       while (!halt_tx) {
-               tmp_packet = free_packets;
-
-               if (NULL == tmp_packet) goto cleanup;
-
-               free_packets = tmp_packet->next;
-
-               igb_get_wallclock(&igb_dev, &last_time, &rdtsc0);
-
-               tmp_packet->attime = last_time + ipg;
-               *(u_int64_t *)(tmp_packet->vaddr + 32) = tmp_packet->attime;
-
-               err = igb_xmit(&igb_dev, 0, tmp_packet);
-
-               if (ENOSPC == err) {
-                       /* put back for now */
-                       tmp_packet->next = free_packets;
-                       free_packets = tmp_packet;
-               }
-
-               sleep(1); /* sleep 1 sec */
-
-cleanup:
-               igb_clean(&igb_dev, &cleaned_packets);
-               i = 0;
-               while (cleaned_packets) {
-                       i++;
-                       tmp_packet = cleaned_packets;
-                       cleaned_packets = cleaned_packets->next;
-                       /* remap attime to compare to dma time */
-                       while (tmp_packet->attime > 999999999) tmp_packet->attime -= 1000000000;
-                       if ((tmp_packet->attime > 999000000) && (tmp_packet->dmatime < 1000000))
-                               captured_latency = (unsigned int)(1000000000 - tmp_packet->attime + tmp_packet->dmatime);
-                       else
-                               captured_latency = (unsigned int)(tmp_packet->dmatime - tmp_packet->attime);
-
-                       if (captured_latency < min) 
-                               min = captured_latency;
-
-                       if (captured_latency > max)
-                               max = captured_latency;
-
-                       avg += ((float)captured_latency / (float)obs_window);
-
-                       tmp_packet->next = free_packets;
-                       free_packets = tmp_packet;
-               } 
-               obs_window_count--;
-               if (0 == obs_window_count) {
-                       obs_window_count = obs_window;
-                       printf("min = %d max = %d avg = %f\n", min, max, avg);
-                       min = 0xFFFFFFFF;
-                       max = 0;
-                       avg = 0.0;
-               }
-               
-       }
-
-       igb_dma_free_page(&igb_dev, &a_page);
-       err = igb_detach(&igb_dev);
-       return(0);      
-}
-
diff --git a/examples/mrp_client/Makefile b/examples/mrp_client/Makefile
new file mode 100644 (file)
index 0000000..a9d5414
--- /dev/null
@@ -0,0 +1,26 @@
+OPT=-O2
+CFLAGS=$(OPT) -Wall -W -Wno-parentheses -ggdb
+
+CC=gcc
+INCFLAGS=-I../../lib/igb
+LDLIBS=-ligb -lpci -lz -pthread
+LDFLAGS=-L../../lib/igb
+
+all: mrpq mrpl
+
+mrpl: mrpl.o
+
+mrpq: mrpq.o
+
+mrpl.o: mrpl.c
+       gcc -c $(INCFLAGS) -I../../daemons/mrpd $(CFLAGS) mrpl.c
+
+mrpq.o: mrpq.c
+       gcc -c $(INCFLAGS) -I../../daemons/mrpd $(CFLAGS) mrpq.c
+
+%: %.o
+       $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+clean:
+       rm -f `find . -name "*~" -o -name "*.[oa]" -o -name "\#*\#" -o -name TAGS -o -name core -o -name "*.orig"` mrpl mrpq
+
similarity index 100%
rename from examples/mrpl.c
rename to examples/mrp_client/mrpl.c
similarity index 100%
rename from examples/mrpq.c
rename to examples/mrp_client/mrpq.c
diff --git a/examples/simple_talker.c b/examples/simple_talker.c
deleted file mode 100755 (executable)
index 118fd0f..0000000
+++ /dev/null
@@ -1,970 +0,0 @@
-/******************************************************************************
-
-  Copyright (c) 2012, Intel Corporation 
-  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.
-  
-   3. Neither the name of the Intel Corporation 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.
-
-******************************************************************************/
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/mman.h>
-#include <sys/user.h>
-#include <pci/pci.h>
-#include <sys/socket.h>
-#include <linux/if.h>
-#include <netpacket/packet.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/ethernet.h>
-#include <sys/un.h>
-#include <pthread.h>
-#include <poll.h>
-
-#include "igb.h"
-#include "mrpd.h"
-
-#define IGB_BIND_NAMESZ 24
-
-/* global variables */
-int control_socket = -1;
-device_t       igb_dev;
-volatile int halt_tx = 0;
-volatile int listeners = 0;
-volatile int mrp_okay;
-volatile int mrp_error = 0;;
-volatile int domain_a_valid = 0;
-int domain_class_a_id;
-int domain_class_a_priority;
-int domain_class_a_vid;
-volatile int domain_b_valid = 0;
-int domain_class_b_id;
-int domain_class_b_priority;
-int domain_class_b_vid;
-
-#define VERSION_STR    "1.0"
-
-static const char *version_str =
-"simple_talker v" VERSION_STR "\n"
-"Copyright (c) 2012, Intel Corporation\n";
-
-#define MRPD_PORT_DEFAULT 7500
-
-int mrp_join_listener(uint8_t *streamid);
-
-int
-send_mrp_msg( char *notify_data, int notify_len) {
-       struct sockaddr_in      addr;
-       socklen_t addr_len;
-
-       memset(&addr, 0, sizeof(addr));
-       addr.sin_family = AF_INET;
-       addr.sin_port = htons(MRPD_PORT_DEFAULT);
-       inet_aton("127.0.0.1", &addr.sin_addr);
-       addr_len = sizeof(addr);
-
-       if (control_socket != -1)
-               return(sendto(control_socket, notify_data, notify_len, 0, (struct sockaddr *)&addr, addr_len));
-       else
-               return(0);
-}
-
-int
-mrp_connect() {
-       struct sockaddr_in      addr;
-       int sock_fd = -1;
-
-       sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-       if (sock_fd < 0) 
-               goto out;
-
-       memset(&addr, 0, sizeof(addr));
-       addr.sin_family = AF_INET;
-       addr.sin_port = htons(MRPD_PORT_DEFAULT);
-       inet_aton("127.0.0.1", &addr.sin_addr);
-
-       memset(&addr, 0, sizeof(addr));
-
-       control_socket = sock_fd;
-
-       return(0);
-out:
-       if (sock_fd != -1) close(sock_fd);
-       sock_fd = -1;
-       return(-1);
-}
-
-int
-mrp_disconnect() {
-       char    *msgbuf;
-       int     rc;
-
-       msgbuf = malloc(64);
-       if (NULL == msgbuf)
-               return -1;
-
-       memset(msgbuf,0,64);
-       sprintf(msgbuf,"BYE");
-       mrp_okay = 0;
-       rc = send_mrp_msg(msgbuf, 1500);
-       /* rc = recv_mrp_okay(); */
-       free(msgbuf);
-       return rc;
-}
-
-
-int
-recv_mrp_okay() {
-       while ((mrp_okay == 0) && (mrp_error == 0))
-               usleep(20000);
-       return 0;
-}
-
-int mrp_register_domain(int *class_id, int *priority, u_int16_t *vid) {
-       char    *msgbuf;
-       int     rc;
-       msgbuf = malloc(64);
-       if (NULL == msgbuf)
-               return -1;
-
-       memset(msgbuf,0,64);
-       sprintf(msgbuf,"S+D:C:%d:P:%d:V:%04x",
-                       *class_id,
-                       *priority,
-                       *vid);
-
-       mrp_okay = 0;
-       rc = send_mrp_msg(msgbuf, 1500);
-       /* rc = recv_mrp_okay(); */
-       free(msgbuf);
-       return rc;
-
-}
-
-int mrp_get_domain(int *class_a_id, int *a_priority, u_int16_t *a_vid,  \
-       int *class_b_id, int *b_priority, u_int16_t *b_vid ) {
-       char    *msgbuf;
-
-       /* we may not get a notification if we are joining late,
-        * so query for what is already there ...
-        */
-       msgbuf = malloc(64);
-       if (NULL == msgbuf)
-               return -1;
-
-       memset(msgbuf,0,64);
-       sprintf(msgbuf,"S??");
-       send_mrp_msg(msgbuf, 64);
-       free(msgbuf);
-
-       while (!halt_tx && (domain_a_valid == 0) && (domain_b_valid == 0))
-               usleep(20000);
-
-       *class_a_id = 0;
-       *a_priority = 0;
-       *a_vid = 0;
-       *class_b_id = 0;
-       *b_priority = 0;
-       *b_vid = 0;
-
-       if (domain_a_valid) {
-               *class_a_id = domain_class_a_id;
-               *a_priority = domain_class_a_priority;
-               *a_vid = domain_class_a_vid;
-       }
-       if (domain_b_valid) {
-               *class_b_id = domain_class_b_id;
-               *b_priority = domain_class_b_priority;
-               *b_vid = domain_class_b_vid;
-       }
-
-       return(0);
-}
-
-unsigned char monitor_stream_id[] = {0,0,0,0,0,0,0,0};
-
-int
-mrp_await_listener(unsigned char *streamid) {
-       char    *msgbuf;
-
-       memcpy(monitor_stream_id, streamid, sizeof(monitor_stream_id));
-
-       msgbuf = malloc(64);
-       if (NULL == msgbuf)
-               return -1;
-
-       memset(msgbuf,0,64);
-       sprintf(msgbuf,"S??");
-       send_mrp_msg(msgbuf, 64);
-       free(msgbuf);
-
-       /* either already there ... or need to wait ... */
-       while (!halt_tx && (listeners == 0))
-               usleep(20000);
-
-       return(0);
-}
-
-int
-process_mrp_msg(char *buf, int buflen) {
-
-       /*
-        * 1st character indicates application
-        * [MVS] - MAC, VLAN or STREAM
-        */
-       unsigned int id;
-       unsigned int priority;
-       unsigned int vid;
-       int i,j,k;
-       unsigned int substate;
-       unsigned char recovered_streamid[8];
-       k = 0;
-
-next_line:
-       if (k >= buflen)
-               return(0);
-
-       switch (buf[k]) {
-       case 'E':
-               printf("%s from mrpd\n", buf);
-               fflush(stdout);
-               mrp_error = 1;
-               break;
-       case 'O':
-               mrp_okay = 1;
-               break;
-       case 'M':
-       case 'V':
-               printf("%s unhandled from mrpd\n", buf);
-               fflush(stdout);
-               /* unhandled for now */
-               break;
-       case 'L':
-               /* parse a listener attribute - see if it matches our monitor_stream_id */
-               i = k;
-               while (buf[i] != 'D') 
-                       i++;
-               i+=2; /* skip the ':' */
-               sscanf(&(buf[i]),"%d",&substate);
-
-               while (buf[i] != 'S') 
-                       i++;
-               i+=2; /* skip the ':' */
-
-               for (j = 0; j < 8; j++) {
-                       sscanf(&(buf[i+2*j]),"%02x",&id);
-                       recovered_streamid[j] = (unsigned char)id;
-               }
-
-               printf("FOUND STREAM ID=%02x%02x%02x%02x%02x%02x%02x%02x ", 
-                       recovered_streamid[0],
-                       recovered_streamid[1],
-                       recovered_streamid[2],
-                       recovered_streamid[3],
-                       recovered_streamid[4],
-                       recovered_streamid[5],
-                       recovered_streamid[6],
-                       recovered_streamid[7]);
-               
-               switch (substate) {
-               case 0: 
-                       printf("with state ignore\n");
-                       break;
-               case 1: 
-                       printf("with state askfailed\n");
-                       break;
-               case 2: 
-                       printf("with state ready\n");
-                       break;
-               case 3: 
-                       printf("with state readyfail\n");
-                       break;
-               default:
-                       printf("with state UNKNOWN (%d)\n", substate);
-                       break;
-               }
-
-               if (substate > MSRP_LISTENER_ASKFAILED) {
-                       if (memcmp(recovered_streamid, monitor_stream_id, sizeof(recovered_streamid)) == 0) {
-                               mrp_join_listener(recovered_streamid);
-                               listeners = 1;
-                               printf("added listener\n");
-                       }
-               }
-               fflush(stdout);
-
-               /* try to find a newline ... */
-               while ((i < buflen) && (buf[i] != '\n') && (buf[i] != '\0'))
-                       i++;
-
-               if (i == buflen)
-                       return(0);
-               if (buf[i] == '\0')
-                       return(0);
-
-               i++;
-               k = i;
-               goto next_line;
-               break;
-       case 'D':
-               i = k+4;
-               /* save the domain attribute */
-               sscanf(&(buf[i]),"%d",&id);
-               while (buf[i] != 'P') 
-                       i++;
-               i+=2; /* skip the ':' */
-               sscanf(&(buf[i]),"%d",&priority);
-               while (buf[i] != 'V') 
-                       i++;
-               i+=2; /* skip the ':' */
-               sscanf(&(buf[i]),"%x",&vid);
-               if (id == 6) {
-                       domain_class_a_id = id;
-                       domain_class_a_priority = priority;
-                       domain_class_a_vid = vid;
-                       domain_a_valid = 1;
-               } else {
-                       domain_class_b_id = id;
-                       domain_class_b_priority = priority;
-                       domain_class_b_vid = vid;
-                       domain_b_valid = 1;
-               }
-               while ((i < buflen) && (buf[i] != '\n') && (buf[i] != '\0'))
-                       i++;
-
-               if ((i == buflen) || (buf[i] == '\0'))
-                       return(0);
-               i++;
-               k = i;
-               goto next_line;
-               break;
-       case 'T':
-               /* as simple_talker we don't care about other talkers */
-               i = k;
-               while ((i < buflen) && (buf[i] != '\n') && (buf[i] != '\0'))
-                       i++;
-               if (i == buflen)
-                       return(0);
-               if (buf[i] == '\0')
-                       return(0);
-
-               i++;
-               k = i;
-               goto next_line;
-               break;
-       case 'S':
-               /* handle the leave/join events */
-               switch (buf[k+4]) {
-               case 'L':
-                       i = k+5;
-                       while (buf[i] != 'D') 
-                               i++;
-                       i+=2; /* skip the ':' */
-                       sscanf(&(buf[i]),"%d",&substate);
-       
-                       while (buf[i] != 'S') 
-                               i++;
-                       i+=2; /* skip the ':' */
-       
-                       for (j = 0; j < 8; j++) {
-                               sscanf(&(buf[i+2*j]),"%02x",&id);
-                               recovered_streamid[j] = (unsigned char)id;
-                       }
-       
-                       printf("EVENT on STREAM ID=%02x%02x%02x%02x%02x%02x%02x%02x ", 
-                               recovered_streamid[0],
-                               recovered_streamid[1],
-                               recovered_streamid[2],
-                               recovered_streamid[3],
-                               recovered_streamid[4],
-                               recovered_streamid[5],
-                               recovered_streamid[6],
-                               recovered_streamid[7]);
-                       
-                       switch (substate) {
-                       case 0: 
-                               printf("with state ignore\n");
-                               break;
-                       case 1: 
-                               printf("with state askfailed\n");
-                               break;
-                       case 2: 
-                               printf("with state ready\n");
-                               break;
-                       case 3: 
-                               printf("with state readyfail\n");
-                               break;
-                       default:
-                               printf("with state UNKNOWN (%d)\n", substate);
-                               break;
-                       }
-       
-
-                       switch (buf[k+1]) {
-                       case 'L':
-                               printf("got a leave indication\n");
-                               if (memcmp(recovered_streamid, monitor_stream_id, sizeof(recovered_streamid)) == 0) {
-                                       listeners = 0;
-                                       printf("listener left\n");
-                               }
-                               break;  
-                       case 'J':
-                       case 'N':
-                               printf("got a new/join indication\n");
-                               if (substate > MSRP_LISTENER_ASKFAILED) {
-                                       if (memcmp(recovered_streamid, monitor_stream_id, sizeof(recovered_streamid)) == 0)
-                                       mrp_join_listener(recovered_streamid);
-                                       listeners = 1;
-                               }
-                               break;  
-                       }
-                       /* only care about listeners ... */
-               default:
-                       return(0);
-                       break;
-               }
-               break;
-       case '\0':
-               break;
-       }
-       return(0);
-}
-
-
-void *
-mrp_monitor_thread(void *arg) {
-       char                    *msgbuf;
-       struct sockaddr_in      client_addr;
-       struct msghdr           msg;
-       struct iovec            iov;
-       int                     bytes = 0;
-       struct pollfd           fds;
-       int                     rc;
-
-       if (NULL == arg)
-               rc = 0;
-       else
-               rc = 1;
-
-       msgbuf = (char *)malloc (MAX_MRPD_CMDSZ);
-       if (NULL == msgbuf) 
-               return NULL;
-       while (!halt_tx) {
-               fds.fd = control_socket;
-               fds.events = POLLIN;
-               fds.revents = 0;
-               rc = poll(&fds, 1, 100);
-               if (rc < 0) {
-                       free (msgbuf);
-                       pthread_exit(NULL);
-               }
-               if (rc == 0)
-                       continue;
-               if ((fds.revents & POLLIN) == 0) {
-                       free (msgbuf);
-                       pthread_exit(NULL);
-               }
-
-               memset(&msg, 0, sizeof(msg));
-               memset(&client_addr, 0, sizeof(client_addr));
-               memset(msgbuf, 0, MAX_MRPD_CMDSZ);
-       
-               iov.iov_len = MAX_MRPD_CMDSZ;
-               iov.iov_base = msgbuf;
-               msg.msg_name = &client_addr;
-               msg.msg_namelen = sizeof(client_addr);
-               msg.msg_iov = &iov;
-               msg.msg_iovlen = 1;
-               bytes = recvmsg(control_socket, &msg, 0);       
-               if (bytes < 0) 
-                       continue;
-       
-               process_mrp_msg(msgbuf, bytes);
-       }
-       free (msgbuf);
-       
-       pthread_exit(NULL);
-}
-
-pthread_t      monitor_thread;
-pthread_attr_t monitor_attr;
-
-int
-mrp_monitor() {
-       pthread_attr_init(&monitor_attr);
-       pthread_create(&monitor_thread, NULL, mrp_monitor_thread, NULL);
-
-       return(0);
-}
-
-int
-mrp_join_listener(uint8_t *streamid) {
-       char    *msgbuf;
-       int     rc;
-
-       msgbuf = malloc(1500);
-       if (NULL == msgbuf)
-               return -1;
-
-       memset(msgbuf,0,1500);
-       sprintf(msgbuf,"S+L:%02X%02X%02X%02X%02X%02X%02X%02X"
-                       ":D:2",
-                       streamid[0],
-                       streamid[1],
-                       streamid[2],
-                       streamid[3],
-                       streamid[4],
-                       streamid[5],
-                       streamid[6],
-                       streamid[7]);
-
-       mrp_okay = 0;
-       rc = send_mrp_msg(msgbuf, 1500);
-       /* rc = recv_mrp_okay(); */
-       free(msgbuf);
-       return rc;
-}
-
-int
-mrp_advertise_stream( 
-               uint8_t *streamid, 
-               uint8_t *destaddr, 
-               u_int16_t vlan,
-               int pktsz,
-               int interval,
-               int priority,
-               int latency) {
-       char    *msgbuf;
-       int     rc;
-
-       msgbuf = malloc(1500);
-       if (NULL == msgbuf)
-               return -1;
-
-       memset(msgbuf,0,1500);
-       sprintf(msgbuf,"S++S:%02X%02X%02X%02X%02X%02X%02X%02X"
-                       ":A:%02X%02X%02X%02X%02X%02X"
-                       ":V:%04X"
-                       ":Z:%d"
-                       ":I:%d"
-                       ":P:%d"
-                       ":L:%d",
-                       streamid[0],
-                       streamid[1],
-                       streamid[2],
-                       streamid[3],
-                       streamid[4],
-                       streamid[5],
-                       streamid[6],
-                       streamid[7],
-                       destaddr[0],
-                       destaddr[1],
-                       destaddr[2],
-                       destaddr[3],
-                       destaddr[4],
-                       destaddr[5],
-                       vlan,
-                       pktsz,
-                       interval,
-                       priority << 5,
-                       latency);
-
-       mrp_okay = 0;
-       rc = send_mrp_msg(msgbuf, 1500);
-       /* rc = recv_mrp_okay(); */
-       free(msgbuf);
-       return rc;
-}
-
-int
-mrp_unadvertise_stream( 
-               uint8_t *streamid, 
-               uint8_t *destaddr, 
-               u_int16_t vlan,
-               int pktsz,
-               int interval,
-               int priority,
-               int latency) {
-       char    *msgbuf;
-       int     rc;
-
-       msgbuf = malloc(1500);
-       if (NULL == msgbuf)
-               return -1;
-
-       memset(msgbuf,0,1500);
-       sprintf(msgbuf,"S--S:%02X%02X%02X%02X%02X%02X%02X%02X"
-                       ":A:%02X%02X%02X%02X%02X%02X"
-                       ":V:%04X"
-                       ":Z:%d"
-                       ":I:%d"
-                       ":P:%d"
-                       ":L:%d",
-                       streamid[0],
-                       streamid[1],
-                       streamid[2],
-                       streamid[3],
-                       streamid[4],
-                       streamid[5],
-                       streamid[6],
-                       streamid[7],
-                       destaddr[0],
-                       destaddr[1],
-                       destaddr[2],
-                       destaddr[3],
-                       destaddr[4],
-                       destaddr[5],
-                       vlan,
-                       pktsz,
-                       interval,
-                       priority << 5,
-                       latency);
-
-       mrp_okay = 0;
-       rc = send_mrp_msg(msgbuf, 1500);
-       /* rc = recv_mrp_okay(); */
-       free(msgbuf);
-       return rc;
-}
-
-void
-sigint_handler (int signum)
-{
-       printf("got SIGINT\n");
-       halt_tx = signum;
-}
-
-int
-pci_connect()
-{
-       struct  pci_access      *pacc;
-       struct  pci_dev *dev;
-       int             err;
-       char    devpath[IGB_BIND_NAMESZ];
-
-       memset(&igb_dev, 0, sizeof(device_t));
-
-       pacc    =       pci_alloc();
-       pci_init(pacc); 
-       pci_scan_bus(pacc);
-       for     (dev=pacc->devices;     dev;    dev=dev->next)
-       {
-               pci_fill_info(dev,      PCI_FILL_IDENT  |       PCI_FILL_BASES  |       PCI_FILL_CLASS);
-
-               igb_dev.pci_vendor_id = dev->vendor_id;
-               igb_dev.pci_device_id = dev->device_id;
-               igb_dev.domain = dev->domain;
-               igb_dev.bus = dev->bus;
-               igb_dev.dev = dev->dev;
-               igb_dev.func = dev->func;
-
-               snprintf(devpath, IGB_BIND_NAMESZ, "%04x:%02x:%02x.%d", \
-                       dev->domain, dev->bus, dev->dev, dev->func );
-
-               err = igb_probe(&igb_dev);
-
-               if (err) {
-                       continue;
-               }
-
-               printf ("attaching to %s\n", devpath);
-               err = igb_attach(devpath, &igb_dev);
-
-               if (err) {
-                       printf ("attach failed! (%s)\n", strerror(errno));
-                       continue;
-               }
-               goto out;
-       }
-
-       pci_cleanup(pacc);
-       return  ENXIO;
-
-out:
-       pci_cleanup(pacc);
-       return  0;
-
-}
-
-unsigned char STATION_ADDR[] = {0,0,0,0,0,0};
-unsigned char STREAM_ID[]    = {0,0,0,0,0,0,0,0};
-unsigned char DEST_ADDR[]    = {0x91, 0xE0, 0xF0, 0x00, 0x00, 0x00}; /* IEEE 1722 reserved address */
-
-int
-get_mac_address(char *interface) {
-        struct ifreq if_request;
-        int lsock;
-        int rc;
-
-        lsock = socket(PF_PACKET, SOCK_RAW, htons(0x800));
-        if (lsock < 0)
-                return -1;
-
-        memset(&if_request, 0, sizeof(if_request));
-
-        strncpy(if_request.ifr_name, interface, sizeof(if_request.ifr_name));
-
-        rc = ioctl(lsock, SIOCGIFHWADDR, &if_request);
-        if (rc < 0) {
-                close(lsock);
-                return -1;
-        }
-
-        memcpy(STATION_ADDR, if_request.ifr_hwaddr.sa_data, sizeof(STATION_ADDR));
-       close(lsock);   
-       return 0;
-}
-
-static void
-usage( void ) {
-       fprintf(stderr, 
-               "\n"
-               "usage: simple_talker [-h] -i interface-name"
-               "\n"
-               "options:\n"
-               "    -h  show this message\n"
-               "    -i  specify interface for AVB connection\n"
-               "\n"
-               "%s"
-               "\n", version_str);
-       exit(1);
-}
-
-#define PACKET_IPG     (125000) /* (1) packet every 125 msec */
-
-int
-main(int argc, char *argv[]) {
-       unsigned        i;
-       int     err;
-       struct igb_dma_alloc    a_page;
-       struct igb_packet       a_packet;
-       struct igb_packet       *tmp_packet;
-       struct igb_packet       *cleaned_packets;
-       struct igb_packet       *free_packets;
-       int     c;
-       u_int64_t               last_time;
-       u_int64_t               rdtsc0;
-       int     rc = 0;
-       char    *interface = NULL;
-       int     class_a_id = 0;
-       int     a_priority = 0;
-       u_int16_t a_vid = 0;
-       int     class_b_id = 0;
-       int     b_priority = 0;
-       u_int16_t b_vid = 0;
-
-       for (;;) {
-               c = getopt(argc, argv, "hi:");
-
-               if (c < 0)
-                       break;
-
-               switch (c) {
-               case 'h':
-                       usage();
-                       break;
-               case 'i':
-                       if (interface) {
-                               printf("only one interface per daemon is supported\n");
-                               usage();
-                       }
-                       interface = strdup(optarg);
-                       break;
-               }
-       }
-       if (optind < argc)
-               usage();
-
-       if (NULL == interface) {
-               usage();
-       }
-
-       rc = mrp_connect(); 
-       if (rc) {
-               printf("socket creation failed\n");
-               return(errno);
-       }
-
-       err = pci_connect();
-
-       if (err) { 
-               printf("connect failed (%s) - are you running as root?\n", strerror(errno)); 
-               return(errno); 
-       }
-
-       err = igb_init(&igb_dev);
-
-       if (err) { 
-               printf("init failed (%s) - is the driver really loaded?\n", strerror(errno));
-               return(errno); 
-       }
-
-       err = igb_dma_malloc_page(&igb_dev, &a_page);
-
-       if (err) { 
-               printf("malloc failed (%s) - out of memory?\n", strerror(errno)); 
-               return(errno); 
-       }
-
-       signal(SIGINT, sigint_handler);
-
-       rc = get_mac_address(interface);
-       if (rc) {
-               printf("failed to open interface\n");
-               usage();
-       }
-
-       mrp_monitor();
-       mrp_get_domain(&class_a_id, &a_priority, &a_vid, &class_b_id, &b_priority, &b_vid);
-
-       printf("detected domain Class A PRIO=%d VID=%04x...\n", a_priority, a_vid);
-
-       mrp_register_domain(&class_a_id, &a_priority, &a_vid);
-       igb_set_class_bandwidth(&igb_dev, 0, 0, 0); /* xxx Qav */
-
-       memset(STREAM_ID, 0, sizeof(STREAM_ID));
-
-       memcpy(STREAM_ID, STATION_ADDR, sizeof(STATION_ADDR));
-
-#define PKT_SZ 200
-       a_packet.dmatime = a_packet.attime = a_packet.flags = 0;
-       a_packet.map.paddr = a_page.dma_paddr;
-       a_packet.map.mmap_size = a_page.mmap_size;
-
-       a_packet.offset = 0; 
-       a_packet.vaddr = a_page.dma_vaddr + a_packet.offset;
-       a_packet.len = PKT_SZ;
-       
-       free_packets = NULL; 
-       
-       /* divide the dma page into buffers for packets */
-       for (i = 1; i < ((a_page.mmap_size) / PKT_SZ); i++) {
-               tmp_packet = malloc(sizeof(struct igb_packet));
-               if (NULL == tmp_packet) { printf("failed to allocate igb_packet memory!\n"); return(errno); }
-
-               *tmp_packet = a_packet;
-               tmp_packet->offset = (i * PKT_SZ);
-               tmp_packet->vaddr += tmp_packet->offset;
-               tmp_packet->next = free_packets;
-               memset(tmp_packet->vaddr, 0, PKT_SZ); /* MAC header at least */
-               memcpy(tmp_packet->vaddr, DEST_ADDR, sizeof(DEST_ADDR));
-               memcpy(tmp_packet->vaddr+6, STATION_ADDR, sizeof(STATION_ADDR));
-               /* Q-tag */
-               ((char *)tmp_packet->vaddr)[12] = 0x81;
-               ((char *)tmp_packet->vaddr)[13] = 0x00;
-               ((char *)tmp_packet->vaddr)[14] = ((a_priority << 13 | a_vid) ) >> 8;
-               ((char *)tmp_packet->vaddr)[15] = ((a_priority << 13 | a_vid) ) & 0xFF;
-               ((char *)tmp_packet->vaddr)[16] = 0x88; /* experimental etype */
-               ((char *)tmp_packet->vaddr)[17] = 0xB5;
-               free_packets = tmp_packet;
-       }
-
-
-       /* 
-        * subtract 16 bytes for the MAC header/Q-tag - pktsz is limited to the 
-        * data payload of the ethernet frame .
-        *
-        * IPG is scaled to the Class (A) observation interval of packets per 125 usec
-        */
-       printf("advertising stream ...\n");
-       mrp_advertise_stream( STREAM_ID, DEST_ADDR, a_vid, PKT_SZ - 16, PACKET_IPG / 125000, a_priority, 3900);
-
-       printf("awaiting a listener ...\n");
-
-       mrp_await_listener(STREAM_ID);
-
-       printf("got a listener ...\n");
-
-       halt_tx = 0;
-
-       rc = nice(-20);
-
-       igb_get_wallclock(&igb_dev, &last_time, &rdtsc0);
-
-       while (listeners && !halt_tx) {
-               tmp_packet = free_packets;
-
-               if (NULL == tmp_packet) 
-                       goto cleanup;
-
-               free_packets = tmp_packet->next;
-
-               /* unfortuntely unless this thread is at rtprio
-                * you get pre-empted between fetching the time
-                * and programming the packet and get a late packet
-                */
-               tmp_packet->attime = last_time + PACKET_IPG;
-               *(u_int64_t *)(tmp_packet->vaddr + 32) = tmp_packet->attime;
-               err = igb_xmit(&igb_dev, 0, tmp_packet);
-
-               if (!err) { 
-                       continue;
-               }
-
-               if (ENOSPC == err) {
-                       /* put back for now */
-                       tmp_packet->next = free_packets;
-                       free_packets = tmp_packet;
-               }
-cleanup:
-               igb_clean(&igb_dev, &cleaned_packets);
-               i = 0;
-               while (cleaned_packets) {
-                       i++;
-                       tmp_packet = cleaned_packets;
-                       cleaned_packets = cleaned_packets->next;
-                       tmp_packet->next = free_packets;
-                       free_packets = tmp_packet;
-               } 
-       }
-
-       rc = nice(0);
-
-       if (halt_tx == 0)
-               printf("listener left ...\n");
-
-       halt_tx = 1;
-       mrp_unadvertise_stream( STREAM_ID, DEST_ADDR, a_vid, PKT_SZ - 16, PACKET_IPG / 125000, a_priority, 3900);
-
-       igb_set_class_bandwidth(&igb_dev, 0, 0, 0); /* disable Qav */
-       
-       rc = mrp_disconnect(); 
-       igb_dma_free_page(&igb_dev, &a_page);
-       err = igb_detach(&igb_dev);
-       pthread_exit(NULL);
-       return(0);      
-}
-
diff --git a/examples/simple_talker/Makefile b/examples/simple_talker/Makefile
new file mode 100644 (file)
index 0000000..6e3984c
--- /dev/null
@@ -0,0 +1,21 @@
+OPT=-O2
+CFLAGS=$(OPT) -Wall -W -Wno-parentheses
+
+CC=gcc
+INCFLAGS=-I../../lib/igb
+LDLIBS=-ligb -lpci -lz -lrt -lm -pthread
+LDFLAGS=-L../../lib/igb
+
+all: simple_talker
+
+simple_talker: simple_talker.o
+
+simple_talker.o: simple_talker.c
+       gcc -c $(INCFLAGS) -I../../daemons/mrpd $(CFLAGS) simple_talker.c
+
+%: %.o
+       $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+clean:
+       rm -f `find . -name "*~" -o -name "*.[oa]" -o -name "\#*\#" -o -name TAGS -o -name core -o -name "*.orig"` simple_talker
+
diff --git a/examples/simple_talker/README b/examples/simple_talker/README
new file mode 100644 (file)
index 0000000..79e0db1
--- /dev/null
@@ -0,0 +1,22 @@
+EXAMPLE APPLICATIONS
+
+The 'simple_talker' application illustrates the various steps to publish a stream
+and streaming 1722/61883 audio frames after a listener connects. The audio
+itself is a simple sine wave. It has been tested with other vendors listeners
+at AVNu plug-fests.
+
+The simple talker application requires root permissions to execute and 
+attach to the driver.
+       sudo ./simple_talker
+
+To exit the app, hit Ctrl-C. The application gracefully tears down
+the connection to the driver. If the application unexpectedly aborts the
+kernel-mode driver also reclaims the various buffers and attempts to clean up.
+The application should be able to re-initialize and use the transmit queues
+without restarting the driver.
+
+Note this application requires using the provided gptp timesync daemon to
+provide the 802.1AS presentation times included in the 1722 frames. This 
+application also requires the mrpd daemon to be running to detect and 
+establish various stream reservation parameters.
+
diff --git a/examples/simple_talker/simple_talker.c b/examples/simple_talker/simple_talker.c
new file mode 100755 (executable)
index 0000000..f7178c4
--- /dev/null
@@ -0,0 +1,1155 @@
+/******************************************************************************
+
+  Copyright (c) 2012, Intel Corporation 
+  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.
+  
+   3. Neither the name of the Intel Corporation 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.
+
+******************************************************************************/
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/mman.h>
+#include <sys/user.h>
+#include <pci/pci.h>
+#include <sys/socket.h>
+#include <linux/if.h>
+#include <netpacket/packet.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/ethernet.h>
+#include <sys/un.h>
+#include <pthread.h>
+#include <poll.h>
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "igb.h"
+#include "mrpd.h"
+#include <math.h>
+#include <endian.h>
+#include <stdint.h>
+
+typedef struct { 
+  int64_t ml_phoffset;
+  int64_t ls_phoffset;
+  int32_t ml_freqoffset;
+  int32_t ls_freqoffset;
+  int64_t local_time;
+} gPtpTimeData;
+
+
+#define SHM_SIZE 4*8 + sizeof(pthread_mutex_t) /* 3 - 64 bit and 2 - 32 bits */
+#define SHM_NAME  "/ptp"
+
+#define MAX_SAMPLE_VALUE ((1U << ((sizeof(int32_t)*8)-1))-1)
+
+#define SRC_CHANNELS (2)
+#define SAMPLES_PER_SECOND (48000)
+#define FREQUENCY (480)
+#define SAMPLES_PER_CYCLE (SAMPLES_PER_SECOND/FREQUENCY)
+#define GAIN (.5)
+
+#define SYSTEM_FREQ_FILENAME "/sys/module/igb_avb/parameters/TEN_USEC_COUNT"
+
+//1722 header
+#define ETH_TYPE 0x22F0
+
+#define CD_SUBTYPE 0x02                /* for simple audio format */
+#define SV_VER_MR_RS_GV_TV 0x81
+#define RS_TU  0x00
+#define SAMPLE_FORMAT_NON_INTR_FLOAT 0x02
+#define NOMINAL_SAMPLE_RATE 0x09
+#define LINEAR_SAMPLE_MSB 0x20
+unsigned char GATEWAY_INFO[] =
+    { SAMPLE_FORMAT_NON_INTR_FLOAT, 0, NOMINAL_SAMPLE_RATE, LINEAR_SAMPLE_MSB };
+
+#define SAMPLE_SIZE 4          /* 4 bytes */
+#define SAMPLES_PER_FRAME 6
+#define CHANNELS 2
+#define PAYLOAD_SIZE SAMPLE_SIZE*SAMPLES_PER_FRAME*CHANNELS    /* 6*4 * 2 channels  = 48 bytes */
+
+#define IGB_BIND_NAMESZ 24
+
+#define XMIT_DELAY (200000000) /* us */
+#define RENDER_DELAY (XMIT_DELAY+2000000)      /* us */
+typedef enum { false = 0, true = 1 } bool;
+typedef struct __attribute__ ((packed)) {
+       uint64_t subtype:7;
+       uint64_t cd_indicator:1;
+       uint64_t timestamp_valid:1;
+       uint64_t gateway_valid:1;
+       uint64_t reserved0:1;
+       uint64_t reset:1;
+       uint64_t version:3;
+       uint64_t sid_valid:1;
+       uint64_t seq_number:8;
+       uint64_t timestamp_uncertain:1;
+       uint64_t reserved1:7;
+       uint64_t stream_id;
+       uint64_t timestamp:32;
+       uint64_t gateway_info:32;
+       uint64_t length:16;
+} seventeen22_header;
+
+/* 61883 CIP with SYT Field */
+typedef struct {
+       uint16_t packet_channel:6;
+       uint16_t format_tag:2;
+       uint16_t app_control:4;
+       uint16_t packet_tcode:4;
+       uint16_t source_id:6;
+       uint16_t reserved0:2;
+       uint16_t data_block_size:8;
+       uint16_t reserved1:2;
+       uint16_t source_packet_header:1;
+       uint16_t quadlet_padding_count:3;
+       uint16_t fraction_number:2;
+       uint16_t data_block_continuity:8;
+       uint16_t format_id:6;
+       uint16_t eoh:2;
+       uint16_t format_dependent_field:8;
+       uint16_t syt;
+} six1883_header;
+
+typedef struct {
+       uint8_t label;
+       uint8_t value[3];
+} six1883_sample;
+
+/* global variables */
+int control_socket = -1;
+device_t igb_dev;
+volatile int halt_tx = 0;
+volatile int listeners = 0;
+volatile int mrp_okay;
+volatile int mrp_error = 0;;
+volatile int domain_a_valid = 0;
+int domain_class_a_id;
+int domain_class_a_priority;
+int domain_class_a_vid;
+volatile int domain_b_valid = 0;
+int domain_class_b_id;
+int domain_class_b_priority;
+int domain_class_b_vid;
+
+#define VERSION_STR    "1.0"
+static const char *version_str = "simple_talker v" VERSION_STR "\n"
+    "Copyright (c) 2012, Intel Corporation\n";
+
+#define MRPD_PORT_DEFAULT 7500
+static inline uint64_t ST_rdtsc(void)
+{
+       uint64_t ret;
+       unsigned c, d;
+       asm volatile ("rdtsc":"=a" (c), "=d"(d));
+       ret = d;
+       ret <<= 32;
+       ret |= c;
+       return ret;
+}
+
+static int shm_fd = -1;
+static char *memory_offset_buffer = NULL;
+int gptpinit(void)
+{
+       shm_fd = shm_open(SHM_NAME, O_RDWR, 0);
+       if (shm_fd == -1) {
+               perror("shm_open()");
+               return false;
+       }
+       memory_offset_buffer =
+           (char *)mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
+                        shm_fd, 0);
+       if (memory_offset_buffer == (char *)-1) {
+               perror("mmap()");
+               memory_offset_buffer = NULL;
+               shm_unlink(SHM_NAME);
+               return false;
+       }
+       return true;
+}
+
+void gptpdeinit(void)
+{
+       if (memory_offset_buffer != NULL) {
+               munmap(memory_offset_buffer, SHM_SIZE);
+       }
+       if (shm_fd != -1) {
+               close(shm_fd);
+       }
+}
+
+int gptpscaling(gPtpTimeData * td)
+{
+       pthread_mutex_lock((pthread_mutex_t *) memory_offset_buffer);
+       memcpy(td, memory_offset_buffer + sizeof(pthread_mutex_t), sizeof(*td));
+       pthread_mutex_unlock((pthread_mutex_t *) memory_offset_buffer);
+
+       fprintf(stderr, "ml_phoffset = %lld, ls_phoffset = %lld\n",
+               td->ml_phoffset, td->ls_phoffset);
+       fprintf(stderr, "ml_freqffset = %d, ls_freqoffset = %d\n",
+               td->ml_freqoffset, td->ls_freqoffset);
+
+       return true;
+}
+
+void gensine32(int32_t * buf, unsigned count)
+{
+       long double interval = (2 * ((long double)M_PI)) / count;
+       unsigned i;
+       for (i = 0; i < count; ++i) {
+               buf[i] =
+                   (int32_t) (MAX_SAMPLE_VALUE * sinl(i * interval) * GAIN);
+       }
+}
+
+int get_samples(unsigned count, int32_t * buffer)
+{
+       static int init = 0;
+       static int32_t samples_onechannel[100];
+       static unsigned index = 0;
+
+       if (init == 0) {
+               gensine32(samples_onechannel, 100);
+               init = 1;
+       }
+
+       while (count > 0) {
+               int i;
+               for (i = 0; i < SRC_CHANNELS; ++i) {
+                       *(buffer++) = samples_onechannel[index];
+               }
+               index = (index + 1) % 100;
+               --count;
+       }
+
+       return 0;
+}
+
+int mrp_join_listener(uint8_t * streamid);
+int send_mrp_msg(char *notify_data, int notify_len)
+{
+       struct sockaddr_in addr;
+       socklen_t addr_len;
+       memset(&addr, 0, sizeof(addr));
+       addr.sin_family = AF_INET;
+       addr.sin_port = htons(MRPD_PORT_DEFAULT);
+       inet_aton("127.0.0.1", &addr.sin_addr);
+       addr_len = sizeof(addr);
+       if (control_socket != -1)
+               return (sendto
+                       (control_socket, notify_data, notify_len, 0,
+                        (struct sockaddr *)&addr, addr_len));
+
+       else
+               return (0);
+}
+
+int mrp_connect()
+{
+       struct sockaddr_in addr;
+       int sock_fd = -1;
+       sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       if (sock_fd < 0)
+               goto out;
+       memset(&addr, 0, sizeof(addr));
+       addr.sin_family = AF_INET;
+       addr.sin_port = htons(MRPD_PORT_DEFAULT);
+       inet_aton("127.0.0.1", &addr.sin_addr);
+       memset(&addr, 0, sizeof(addr));
+       control_socket = sock_fd;
+       return (0);
+ out:  if (sock_fd != -1)
+               close(sock_fd);
+       sock_fd = -1;
+       return (-1);
+}
+
+int mrp_disconnect()
+{
+       char *msgbuf;
+       int rc;
+       msgbuf = malloc(64);
+       if (NULL == msgbuf)
+               return -1;
+       memset(msgbuf, 0, 64);
+       sprintf(msgbuf, "BYE");
+       mrp_okay = 0;
+       rc = send_mrp_msg(msgbuf, 1500);
+
+       /* rc = recv_mrp_okay(); */
+       free(msgbuf);
+       return rc;
+}
+
+int recv_mrp_okay()
+{
+       while ((mrp_okay == 0) && (mrp_error == 0))
+               usleep(20000);
+       return 0;
+}
+
+int mrp_register_domain(int *class_id, int *priority, u_int16_t * vid)
+{
+       char *msgbuf;
+       int rc;
+       msgbuf = malloc(64);
+       if (NULL == msgbuf)
+               return -1;
+       memset(msgbuf, 0, 64);
+       sprintf(msgbuf, "S+D:C:%d:P:%d:V:%04x", *class_id, *priority, *vid);
+       mrp_okay = 0;
+       rc = send_mrp_msg(msgbuf, 1500);
+
+       /* rc = recv_mrp_okay(); */
+       free(msgbuf);
+       return rc;
+}
+
+int mrp_get_domain(int *class_a_id, int *a_priority, u_int16_t * a_vid,
+                  int *class_b_id, int *b_priority, u_int16_t * b_vid)
+{
+       char *msgbuf;
+
+       /* we may not get a notification if we are joining late,
+        * so query for what is already there ...
+        */
+       msgbuf = malloc(64);
+       if (NULL == msgbuf)
+               return -1;
+       memset(msgbuf, 0, 64);
+       sprintf(msgbuf, "S??");
+       send_mrp_msg(msgbuf, 64);
+       free(msgbuf);
+       while (!halt_tx && (domain_a_valid == 0) && (domain_b_valid == 0))
+               usleep(20000);
+       *class_a_id = 0;
+       *a_priority = 0;
+       *a_vid = 0;
+       *class_b_id = 0;
+       *b_priority = 0;
+       *b_vid = 0;
+       if (domain_a_valid) {
+               *class_a_id = domain_class_a_id;
+               *a_priority = domain_class_a_priority;
+               *a_vid = domain_class_a_vid;
+       }
+       if (domain_b_valid) {
+               *class_b_id = domain_class_b_id;
+               *b_priority = domain_class_b_priority;
+               *b_vid = domain_class_b_vid;
+       }
+       return (0);
+}
+unsigned char monitor_stream_id[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+int mrp_await_listener(unsigned char *streamid)
+{
+       char *msgbuf;
+       memcpy(monitor_stream_id, streamid, sizeof(monitor_stream_id));
+       msgbuf = malloc(64);
+       if (NULL == msgbuf)
+               return -1;
+       memset(msgbuf, 0, 64);
+       sprintf(msgbuf, "S??");
+       send_mrp_msg(msgbuf, 64);
+       free(msgbuf);
+
+       /* either already there ... or need to wait ... */
+       while (!halt_tx && (listeners == 0))
+               usleep(20000);
+       return (0);
+}
+
+int process_mrp_msg(char *buf, int buflen)
+{
+
+       /*
+        * 1st character indicates application
+        * [MVS] - MAC, VLAN or STREAM
+        */
+       unsigned int id;
+       unsigned int priority;
+       unsigned int vid;
+       int i, j, k;
+       unsigned int substate;
+       unsigned char recovered_streamid[8];
+       k = 0;
+ next_line:if (k >= buflen)
+               return (0);
+       switch (buf[k]) {
+       case 'E':
+               printf("%s from mrpd\n", buf);
+               fflush(stdout);
+               mrp_error = 1;
+               break;
+       case 'O':
+               mrp_okay = 1;
+               break;
+       case 'M':
+       case 'V':
+               printf("%s unhandled from mrpd\n", buf);
+               fflush(stdout);
+
+               /* unhandled for now */
+               break;
+       case 'L':
+
+               /* parse a listener attribute - see if it matches our monitor_stream_id */
+               i = k;
+               while (buf[i] != 'D')
+                       i++;
+               i += 2;         /* skip the ':' */
+               sscanf(&(buf[i]), "%d", &substate);
+               while (buf[i] != 'S')
+                       i++;
+               i += 2;         /* skip the ':' */
+               for (j = 0; j < 8; j++) {
+                       sscanf(&(buf[i + 2 * j]), "%02x", &id);
+                       recovered_streamid[j] = (unsigned char)id;
+               } printf
+                   ("FOUND STREAM ID=%02x%02x%02x%02x%02x%02x%02x%02x ",
+                    recovered_streamid[0], recovered_streamid[1],
+                    recovered_streamid[2], recovered_streamid[3],
+                    recovered_streamid[4], recovered_streamid[5],
+                    recovered_streamid[6], recovered_streamid[7]);
+               switch (substate) {
+               case 0:
+                       printf("with state ignore\n");
+                       break;
+               case 1:
+                       printf("with state askfailed\n");
+                       break;
+               case 2:
+                       printf("with state ready\n");
+                       break;
+               case 3:
+                       printf("with state readyfail\n");
+                       break;
+               default:
+                       printf("with state UNKNOWN (%d)\n", substate);
+                       break;
+               }
+               if (substate > MSRP_LISTENER_ASKFAILED) {
+                       if (memcmp
+                           (recovered_streamid, monitor_stream_id,
+                            sizeof(recovered_streamid)) == 0) {
+                               mrp_join_listener(recovered_streamid);
+                               listeners = 1;
+                               printf("added listener\n");
+                       }
+               }
+               fflush(stdout);
+
+               /* try to find a newline ... */
+               while ((i < buflen) && (buf[i] != '\n') && (buf[i] != '\0'))
+                       i++;
+               if (i == buflen)
+                       return (0);
+               if (buf[i] == '\0')
+                       return (0);
+               i++;
+               k = i;
+               goto next_line;
+               break;
+       case 'D':
+               i = k + 4;
+
+               /* save the domain attribute */
+               sscanf(&(buf[i]), "%d", &id);
+               while (buf[i] != 'P')
+                       i++;
+               i += 2;         /* skip the ':' */
+               sscanf(&(buf[i]), "%d", &priority);
+               while (buf[i] != 'V')
+                       i++;
+               i += 2;         /* skip the ':' */
+               sscanf(&(buf[i]), "%x", &vid);
+               if (id == 6) {
+                       domain_class_a_id = id;
+                       domain_class_a_priority = priority;
+                       domain_class_a_vid = vid;
+                       domain_a_valid = 1;
+               } else {
+                       domain_class_b_id = id;
+                       domain_class_b_priority = priority;
+                       domain_class_b_vid = vid;
+                       domain_b_valid = 1;
+               }
+               while ((i < buflen) && (buf[i] != '\n') && (buf[i] != '\0'))
+                       i++;
+               if ((i == buflen) || (buf[i] == '\0'))
+                       return (0);
+               i++;
+               k = i;
+               goto next_line;
+               break;
+       case 'T':
+
+               /* as simple_talker we don't care about other talkers */
+               i = k;
+               while ((i < buflen) && (buf[i] != '\n') && (buf[i] != '\0'))
+                       i++;
+               if (i == buflen)
+                       return (0);
+               if (buf[i] == '\0')
+                       return (0);
+               i++;
+               k = i;
+               goto next_line;
+               break;
+       case 'S':
+
+               /* handle the leave/join events */
+               switch (buf[k + 4]) {
+               case 'L':
+                       i = k + 5;
+                       while (buf[i] != 'D')
+                               i++;
+                       i += 2; /* skip the ':' */
+                       sscanf(&(buf[i]), "%d", &substate);
+                       while (buf[i] != 'S')
+                               i++;
+                       i += 2; /* skip the ':' */
+                       for (j = 0; j < 8; j++) {
+                               sscanf(&(buf[i + 2 * j]), "%02x", &id);
+                               recovered_streamid[j] = (unsigned char)id;
+                       } printf
+                           ("EVENT on STREAM ID=%02x%02x%02x%02x%02x%02x%02x%02x ",
+                            recovered_streamid[0], recovered_streamid[1],
+                            recovered_streamid[2], recovered_streamid[3],
+                            recovered_streamid[4], recovered_streamid[5],
+                            recovered_streamid[6], recovered_streamid[7]);
+                       switch (substate) {
+                       case 0:
+                               printf("with state ignore\n");
+                               break;
+                       case 1:
+                               printf("with state askfailed\n");
+                               break;
+                       case 2:
+                               printf("with state ready\n");
+                               break;
+                       case 3:
+                               printf("with state readyfail\n");
+                               break;
+                       default:
+                               printf("with state UNKNOWN (%d)\n", substate);
+                               break;
+                       }
+                       switch (buf[k + 1]) {
+                       case 'L':
+                               printf("got a leave indication\n");
+                               if (memcmp
+                                   (recovered_streamid, monitor_stream_id,
+                                    sizeof(recovered_streamid)) == 0) {
+                                       listeners = 0;
+                                       printf("listener left\n");
+                               }
+                               break;
+                       case 'J':
+                       case 'N':
+                               printf("got a new/join indication\n");
+                               if (substate > MSRP_LISTENER_ASKFAILED) {
+                                       if (memcmp
+                                           (recovered_streamid,
+                                            monitor_stream_id,
+                                            sizeof(recovered_streamid)) == 0)
+                                               mrp_join_listener
+                                                   (recovered_streamid);
+                                       listeners = 1;
+                               }
+                               break;
+                       }
+
+                       /* only care about listeners ... */
+               default:
+                       return (0);
+                       break;
+               }
+               break;
+       case '\0':
+               break;
+       }
+       return (0);
+}
+
+void *mrp_monitor_thread(void *arg)
+{
+       char *msgbuf;
+       struct sockaddr_in client_addr;
+       struct msghdr msg;
+       struct iovec iov;
+       int bytes = 0;
+       struct pollfd fds;
+       int rc;
+       if (NULL == arg)
+               rc = 0;
+
+       else
+               rc = 1;
+       msgbuf = (char *)malloc(MAX_MRPD_CMDSZ);
+       if (NULL == msgbuf)
+               return NULL;
+       while (!halt_tx) {
+               fds.fd = control_socket;
+               fds.events = POLLIN;
+               fds.revents = 0;
+               rc = poll(&fds, 1, 100);
+               if (rc < 0) {
+                       free(msgbuf);
+                       pthread_exit(NULL);
+               }
+               if (rc == 0)
+                       continue;
+               if ((fds.revents & POLLIN) == 0) {
+                       free(msgbuf);
+                       pthread_exit(NULL);
+               }
+               memset(&msg, 0, sizeof(msg));
+               memset(&client_addr, 0, sizeof(client_addr));
+               memset(msgbuf, 0, MAX_MRPD_CMDSZ);
+               iov.iov_len = MAX_MRPD_CMDSZ;
+               iov.iov_base = msgbuf;
+               msg.msg_name = &client_addr;
+               msg.msg_namelen = sizeof(client_addr);
+               msg.msg_iov = &iov;
+               msg.msg_iovlen = 1;
+               bytes = recvmsg(control_socket, &msg, 0);
+               if (bytes < 0)
+                       continue;
+               process_mrp_msg(msgbuf, bytes);
+       }
+       free(msgbuf);
+       pthread_exit(NULL);
+}
+
+pthread_t monitor_thread;
+pthread_attr_t monitor_attr;
+int mrp_monitor()
+{
+       pthread_attr_init(&monitor_attr);
+       pthread_create(&monitor_thread, NULL, mrp_monitor_thread, NULL);
+       return (0);
+}
+
+int mrp_join_listener(uint8_t * streamid)
+{
+       char *msgbuf;
+       int rc;
+       msgbuf = malloc(1500);
+       if (NULL == msgbuf)
+               return -1;
+       memset(msgbuf, 0, 1500);
+       sprintf(msgbuf, "S+L:%02X%02X%02X%02X%02X%02X%02X%02X"
+               ":D:2", streamid[0], streamid[1], streamid[2], streamid[3],
+               streamid[4], streamid[5], streamid[6], streamid[7]);
+       mrp_okay = 0;
+       rc = send_mrp_msg(msgbuf, 1500);
+
+       /* rc = recv_mrp_okay(); */
+       free(msgbuf);
+       return rc;
+}
+
+int
+mrp_advertise_stream(uint8_t * streamid,
+                    uint8_t * destaddr,
+                    u_int16_t vlan,
+                    int pktsz, int interval, int priority, int latency)
+{
+       char *msgbuf;
+       int rc;
+       msgbuf = malloc(1500);
+       if (NULL == msgbuf)
+               return -1;
+       memset(msgbuf, 0, 1500);
+       sprintf(msgbuf, "S++S:%02X%02X%02X%02X%02X%02X%02X%02X"
+               ":A:%02X%02X%02X%02X%02X%02X"
+               ":V:%04X"
+               ":Z:%d"
+               ":I:%d"
+               ":P:%d"
+               ":L:%d", streamid[0], streamid[1], streamid[2],
+               streamid[3], streamid[4], streamid[5], streamid[6],
+               streamid[7], destaddr[0], destaddr[1], destaddr[2],
+               destaddr[3], destaddr[4], destaddr[5], vlan, pktsz,
+               interval, priority << 5, latency);
+       mrp_okay = 0;
+       rc = send_mrp_msg(msgbuf, 1500);
+
+       /* rc = recv_mrp_okay(); */
+       free(msgbuf);
+       return rc;
+}
+
+int
+mrp_unadvertise_stream(uint8_t * streamid,
+                      uint8_t * destaddr,
+                      u_int16_t vlan,
+                      int pktsz, int interval, int priority, int latency)
+{
+       char *msgbuf;
+       int rc;
+       msgbuf = malloc(1500);
+       if (NULL == msgbuf)
+               return -1;
+       memset(msgbuf, 0, 1500);
+       sprintf(msgbuf, "S--S:%02X%02X%02X%02X%02X%02X%02X%02X"
+               ":A:%02X%02X%02X%02X%02X%02X"
+               ":V:%04X"
+               ":Z:%d"
+               ":I:%d"
+               ":P:%d"
+               ":L:%d", streamid[0], streamid[1], streamid[2],
+               streamid[3], streamid[4], streamid[5], streamid[6],
+               streamid[7], destaddr[0], destaddr[1], destaddr[2],
+               destaddr[3], destaddr[4], destaddr[5], vlan, pktsz,
+               interval, priority << 5, latency);
+       mrp_okay = 0;
+       rc = send_mrp_msg(msgbuf, 1500);
+
+       /* rc = recv_mrp_okay(); */
+       free(msgbuf);
+       return rc;
+}
+
+void sigint_handler(int signum)
+{
+       printf("got SIGINT\n");
+       halt_tx = signum;
+}
+
+int pci_connect()
+{
+       struct pci_access *pacc;
+       struct pci_dev *dev;
+       int err;
+       char devpath[IGB_BIND_NAMESZ];
+       memset(&igb_dev, 0, sizeof(device_t));
+       pacc = pci_alloc();
+       pci_init(pacc);
+       pci_scan_bus(pacc);
+       for (dev = pacc->devices; dev; dev = dev->next) {
+               pci_fill_info(dev,
+                             PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS);
+               igb_dev.pci_vendor_id = dev->vendor_id;
+               igb_dev.pci_device_id = dev->device_id;
+               igb_dev.domain = dev->domain;
+               igb_dev.bus = dev->bus;
+               igb_dev.dev = dev->dev;
+               igb_dev.func = dev->func;
+               snprintf(devpath, IGB_BIND_NAMESZ, "%04x:%02x:%02x.%d",
+                        dev->domain, dev->bus, dev->dev, dev->func);
+               err = igb_probe(&igb_dev);
+               if (err) {
+                       continue;
+               }
+               printf("attaching to %s\n", devpath);
+               err = igb_attach(devpath, &igb_dev);
+               if (err) {
+                       printf("attach failed! (%s)\n", strerror(errno));
+                       continue;
+               }
+               goto out;
+       }
+       pci_cleanup(pacc);
+       return ENXIO;
+ out:  pci_cleanup(pacc);
+       return 0;
+}
+
+unsigned char STATION_ADDR[] = { 0, 0, 0, 0, 0, 0 };
+unsigned char STREAM_ID[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+/* IEEE 1722 reserved address */
+unsigned char DEST_ADDR[] = { 0x91, 0xE0, 0xF0, 0x00, 0x0e, 0x80 };
+
+int get_mac_address(char *interface)
+{
+       struct ifreq if_request;
+       int lsock;
+       int rc;
+       lsock = socket(PF_PACKET, SOCK_RAW, htons(0x800));
+       if (lsock < 0)
+               return -1;
+       memset(&if_request, 0, sizeof(if_request));
+       strncpy(if_request.ifr_name, interface, sizeof(if_request.ifr_name));
+       rc = ioctl(lsock, SIOCGIFHWADDR, &if_request);
+       if (rc < 0) {
+               close(lsock);
+               return -1;
+       }
+       memcpy(STATION_ADDR, if_request.ifr_hwaddr.sa_data,
+              sizeof(STATION_ADDR));
+       close(lsock);
+       return 0;
+}
+
+static void usage(void)
+{
+       fprintf(stderr, "\n"
+               "usage: simple_talker [-h] -i interface-name"
+               "\n"
+               "options:\n"
+               "    -h  show this message\n"
+               "    -i  specify interface for AVB connection\n"
+               "\n" "%s" "\n", version_str);
+       exit(1);
+}
+
+#define PACKET_IPG     (125000)        /* (1) packet every 125 usec */
+
+int main(int argc, char *argv[])
+{
+       unsigned i;
+       int err;
+       struct igb_dma_alloc a_page;
+       struct igb_packet a_packet;
+       struct igb_packet *tmp_packet;
+       struct igb_packet *cleaned_packets;
+       struct igb_packet *free_packets;
+       int c;
+       u_int64_t last_time;
+       int rc = 0;
+       char *interface = NULL;
+       int class_a_id = 0;
+       int a_priority = 0;
+       u_int16_t a_vid = 0;
+       int class_b_id = 0;
+       int b_priority = 0;
+       u_int16_t b_vid = 0;
+       int seqnum;
+       int time_stamp;
+       int16_t data_length;
+       unsigned total_samples = 0;
+       int TEN_USEC_COUNT;
+       gPtpTimeData td;
+       int32_t sample_buffer[SAMPLES_PER_FRAME * SRC_CHANNELS];
+       seventeen22_header *header0;
+       six1883_header *header1;
+       six1883_sample *sample;
+       FILE *freqfile;
+       char freqstring[8];
+       uint64_t now_tscns, now_8021as;
+       uint64_t update_tscns, update_8021as;
+       unsigned delta_tscns, delta_8021as, delta_local;
+       long double ml_ratio, ls_ratio;
+
+       for (;;) {
+               c = getopt(argc, argv, "hi:");
+               if (c < 0)
+                       break;
+               switch (c) {
+               case 'h':
+                       usage();
+                       break;
+               case 'i':
+                       if (interface) {
+                               printf
+                                   ("only one interface per daemon is supported\n");
+                               usage();
+                       }
+                       interface = strdup(optarg);
+                       break;
+               }
+       }
+       if (optind < argc)
+               usage();
+       if (NULL == interface) {
+               usage();
+       }
+       rc = mrp_connect();
+       if (rc) {
+               printf("socket creation failed\n");
+               return (errno);
+       }
+       err = pci_connect();
+       if (err) {
+               printf("connect failed (%s) - are you running as root?\n",
+                      strerror(errno));
+               return (errno);
+       }
+       err = igb_init(&igb_dev);
+       if (err) {
+               printf("init failed (%s) - is the driver really loaded?\n",
+                      strerror(errno));
+               return (errno);
+       }
+       err = igb_dma_malloc_page(&igb_dev, &a_page);
+       if (err) {
+               printf("malloc failed (%s) - out of memory?\n",
+                      strerror(errno));
+               return (errno);
+       }
+       signal(SIGINT, sigint_handler);
+       rc = get_mac_address(interface);
+       if (rc) {
+               printf("failed to open interface\n");
+               usage();
+       }
+
+       freqfile = fopen(SYSTEM_FREQ_FILENAME, "r");
+       if (freqfile == NULL) {
+               printf("Failed to open kernel module parameter: %s\n",
+                      strerror(errno));
+               return errno;
+       }
+
+       if (fscanf(freqfile, "%7s", freqstring) != 1) {
+               printf("Failed to read kernel module parameter: %s\n",
+                      strerror(errno));
+               return errno;
+       }
+
+       TEN_USEC_COUNT = atoi(freqstring);
+       /* fprintf(stderr, "TEN_USEC_COUNT = %d\n", TEN_USEC_COUNT); */
+
+       mrp_monitor();
+
+       /* 
+        * should use mrp_get_domain() above but this is a simplification 
+        */
+       domain_a_valid = 1;
+       class_a_id = MSRP_SR_CLASS_A;
+       a_priority = MSRP_SR_CLASS_A_PRIO;
+       a_vid = 2;
+       printf("detected domain Class A PRIO=%d VID=%04x...\n", a_priority,
+              a_vid);
+
+#define PKT_SZ 100
+
+       mrp_register_domain(&class_a_id, &a_priority, &a_vid);
+       igb_set_class_bandwidth(&igb_dev, PACKET_IPG / 125000, 0, PKT_SZ - 22,
+                               0);
+
+       memset(STREAM_ID, 0, sizeof(STREAM_ID));
+       memcpy(STREAM_ID, STATION_ADDR, sizeof(STATION_ADDR));
+
+       a_packet.dmatime = a_packet.attime = a_packet.flags = 0;
+       a_packet.map.paddr = a_page.dma_paddr;
+       a_packet.map.mmap_size = a_page.mmap_size;
+       a_packet.offset = 0;
+       a_packet.vaddr = a_page.dma_vaddr + a_packet.offset;
+       a_packet.len = PKT_SZ;
+       free_packets = NULL;
+       seqnum = 0;
+
+       /* divide the dma page into buffers for packets */
+       for (i = 1; i < ((a_page.mmap_size) / PKT_SZ); i++) {
+               tmp_packet = malloc(sizeof(struct igb_packet));
+               if (NULL == tmp_packet) {
+                       printf("failed to allocate igb_packet memory!\n");
+                       return (errno);
+               }
+               *tmp_packet = a_packet;
+               tmp_packet->offset = (i * PKT_SZ);
+               tmp_packet->vaddr += tmp_packet->offset;
+               tmp_packet->next = free_packets;
+               memset(tmp_packet->vaddr, 0, PKT_SZ);   /* MAC header at least */
+               memcpy(tmp_packet->vaddr, DEST_ADDR, sizeof(DEST_ADDR));
+               memcpy(tmp_packet->vaddr + 6, STATION_ADDR,
+                      sizeof(STATION_ADDR));
+
+               /* Q-tag */
+               ((char *)tmp_packet->vaddr)[12] = 0x81;
+               ((char *)tmp_packet->vaddr)[13] = 0x00;
+               ((char *)tmp_packet->vaddr)[14] =
+                   ((a_priority << 13 | a_vid)) >> 8;
+               ((char *)tmp_packet->vaddr)[15] =
+                   ((a_priority << 13 | a_vid)) & 0xFF;
+               ((char *)tmp_packet->vaddr)[16] = 0x22; /* 1722 eth type */
+               ((char *)tmp_packet->vaddr)[17] = 0xF0;
+
+               /* 1722 header update + payload */
+               header0 =
+                   (seventeen22_header *) (((char *)tmp_packet->vaddr) + 18);
+               header0->cd_indicator = 0;
+               header0->subtype = 0;
+               header0->sid_valid = 1;
+               header0->version = 0;
+               header0->reset = 0;
+               header0->reserved0 = 0;
+               header0->gateway_valid = 0;
+               header0->reserved1 = 0;
+               header0->timestamp_uncertain = 0;
+               memset(&(header0->stream_id), 0, sizeof(header0->stream_id));
+               memcpy(&(header0->stream_id), STATION_ADDR,
+                      sizeof(STATION_ADDR));
+               header0->length = htons(32);
+               header1 = (six1883_header *) (header0 + 1);
+               header1->format_tag = 1;
+               header1->packet_channel = 0x1F;
+               header1->packet_tcode = 0xA;
+               header1->app_control = 0x0;
+               header1->reserved0 = 0;
+               header1->source_id = 0x3F;
+               header1->data_block_size = CHANNELS;
+               header1->fraction_number = 0;
+               header1->quadlet_padding_count = 0;
+               header1->source_packet_header = 0;
+               header1->reserved1 = 0;
+               header1->eoh = 0x2;
+               header1->format_id = 0x10;
+               header1->format_dependent_field = 0x02;
+               header1->syt = 0xFFFF;
+               tmp_packet->len =
+                   18 + sizeof(seventeen22_header) + sizeof(six1883_header) +
+                   (SAMPLES_PER_FRAME * CHANNELS * sizeof(six1883_sample));
+               free_packets = tmp_packet;
+       }
+
+       /* 
+        * subtract 16 bytes for the MAC header/Q-tag - pktsz is limited to the 
+        * data payload of the ethernet frame .
+        *
+        * IPG is scaled to the Class (A) observation interval of packets per 125 usec
+        */
+       fprintf(stderr, "advertising stream ...\n");
+       mrp_advertise_stream(STREAM_ID, DEST_ADDR, a_vid, PKT_SZ - 16,
+                            PACKET_IPG / 125000, a_priority, 3900);
+       fprintf(stderr, "awaiting a listener ...\n");
+       mrp_await_listener(STREAM_ID);
+       printf("got a listener ...\n");
+       halt_tx = 0;
+
+       gptpinit();
+       gptpscaling(&td);
+
+       now_tscns = ST_rdtsc() * 10000 / TEN_USEC_COUNT;
+       update_tscns = td.local_time + td.ls_phoffset;
+       update_8021as = td.local_time - td.ml_phoffset;
+       delta_tscns = (unsigned)(now_tscns - update_tscns);
+       ml_ratio = -1 * (((long double)td.ml_freqoffset) / 1000000000000) + 1;
+       ls_ratio = -1 * (((long double)td.ls_freqoffset) / 1000000000000) + 1;
+       delta_local = (unsigned)(ls_ratio * delta_tscns);
+       delta_8021as = (unsigned)(ml_ratio * ls_ratio * delta_tscns);
+       now_8021as = update_8021as + delta_8021as;
+       last_time = td.local_time + delta_local + XMIT_DELAY;
+
+       time_stamp = now_8021as + RENDER_DELAY;
+
+       rc = nice(-20);
+
+       while (listeners && !halt_tx) {
+               tmp_packet = free_packets;
+               if (NULL == tmp_packet)
+                       goto cleanup;
+               header0 =
+                   (seventeen22_header *) (((char *)tmp_packet->vaddr) + 18);
+               header1 = (six1883_header *) (header0 + 1);
+               free_packets = tmp_packet->next;
+
+               /* unfortuntely unless this thread is at rtprio
+                * you get pre-empted between fetching the time
+                * and programming the packet and get a late packet
+                */
+               tmp_packet->attime = last_time + PACKET_IPG;
+               last_time += PACKET_IPG;
+
+               get_samples(SAMPLES_PER_FRAME, sample_buffer);
+               header0->seq_number = seqnum++;
+               if (seqnum % 4 == 0)
+                       header0->timestamp_valid = 0;
+
+               else
+                       header0->timestamp_valid = 1;
+
+               time_stamp = htonl(time_stamp);
+               header0->timestamp = time_stamp;
+               time_stamp = ntohl(time_stamp);
+               time_stamp += PACKET_IPG;
+               header1->data_block_continuity = total_samples;
+               total_samples += SAMPLES_PER_FRAME;
+               sample =
+                   (six1883_sample *) (((char *)tmp_packet->vaddr) +
+                                       (18 + sizeof(seventeen22_header) +
+                                        sizeof(six1883_header)));
+
+               for (i = 0; i < SAMPLES_PER_FRAME * CHANNELS; ++i) {
+                       uint32_t tmp = htonl(sample_buffer[i]);
+                       sample[i].label = 0x40;
+                       memcpy(&(sample[i].value), &(tmp),
+                              sizeof(sample[i].value));
+               }
+
+               err = igb_xmit(&igb_dev, 0, tmp_packet);
+
+               if (!err) {
+                       continue;
+               }
+
+               if (ENOSPC == err) {
+
+                       /* put back for now */
+                       tmp_packet->next = free_packets;
+                       free_packets = tmp_packet;
+               }
+
+ cleanup:      igb_clean(&igb_dev, &cleaned_packets);
+               i = 0;
+               while (cleaned_packets) {
+                       i++;
+                       tmp_packet = cleaned_packets;
+                       cleaned_packets = cleaned_packets->next;
+                       tmp_packet->next = free_packets;
+                       free_packets = tmp_packet;
+               }
+       }
+       rc = nice(0);
+
+       if (halt_tx == 0)
+               printf("listener left ...\n");
+       halt_tx = 1;
+
+       mrp_unadvertise_stream(STREAM_ID, DEST_ADDR, a_vid, PKT_SZ - 16,
+                              PACKET_IPG / 125000, a_priority, 3900);
+
+       igb_set_class_bandwidth(&igb_dev, 0, 0, 0, 0);  /* disable Qav */
+
+       rc = mrp_disconnect();
+
+       igb_dma_free_page(&igb_dev, &a_page);
+
+       err = igb_detach(&igb_dev);
+
+       pthread_exit(NULL);
+
+       return (0);
+}
diff --git a/examples/test.c b/examples/test.c
deleted file mode 100644 (file)
index 524aa24..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/******************************************************************************
-
-  Copyright (c) 2001-2012, Intel Corporation 
-  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.
-  
-   3. Neither the name of the Intel Corporation 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.
-
-******************************************************************************/
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <signal.h>
-#include <errno.h>
-
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/mman.h>
-#include <sys/user.h>
-
-#include <stdio.h>
-
-#include <pci/pci.h>
-
-#include "igb.h"
-
-#define IGB_BIND_NAMESZ 24
-
-device_t       igb_dev;
-volatile int   halt_tx;
-
-void
-sigint_handler (int signum)
-{
-       printf("got SIGINT\n");
-       halt_tx = signum;
-}
-
-int
-connect()
-{
-       struct  pci_access      *pacc;
-       struct  pci_dev *dev;
-       int             err;
-       char    devpath[IGB_BIND_NAMESZ];
-
-       memset(&igb_dev, 0, sizeof(device_t));
-
-       pacc    =       pci_alloc();
-       pci_init(pacc); 
-       pci_scan_bus(pacc);
-       for     (dev=pacc->devices;     dev;    dev=dev->next)
-       {
-               pci_fill_info(dev,      PCI_FILL_IDENT  |       PCI_FILL_BASES  |       PCI_FILL_CLASS);
-
-               igb_dev.pci_vendor_id = dev->vendor_id;
-               igb_dev.pci_device_id = dev->device_id;
-               igb_dev.domain = dev->domain;
-               igb_dev.bus = dev->bus;
-               igb_dev.dev = dev->dev;
-               igb_dev.func = dev->func;
-
-               snprintf(devpath, IGB_BIND_NAMESZ, "%04x:%02x:%02x.%d", \
-                       dev->domain, dev->bus, dev->dev, dev->func );
-               printf("probing %s\n", devpath);
-
-               err = igb_probe(&igb_dev);
-
-               if (err) {
-                       continue;
-               }
-
-               printf ("attaching to %s\n", devpath);
-               err = igb_attach(devpath, &igb_dev);
-
-               if (err) {
-                       printf ("attach failed! (%s)\n", strerror(errno));
-                       continue;
-               }
-               printf("attach successful to %s\n", devpath);
-               goto out;
-       }
-
-       pci_cleanup(pacc);
-       return  ENXIO;
-
-out:
-       pci_cleanup(pacc);
-       return  0;
-
-}
-
-#define PACKET_IPG     (20000000) /* 20 msec */
-
-int
-main() 
-{
-       unsigned        i;
-       int     err;
-       struct igb_dma_alloc    a_page;
-       struct igb_packet       a_packet;
-       struct igb_packet       *tmp_packet;
-       struct igb_packet       *cleaned_packets;
-       struct igb_packet       *free_packets;
-       u_int64_t       last_time;
-       u_int64_t       rdtsc0;
-
-       err = connect();
-
-       if (err) { printf("connect failed (%s)\n", strerror(errno)); return(errno); }
-
-       err = igb_init(&igb_dev);
-
-       if (err) { printf("init failed (%s)\n", strerror(errno)); return(errno); }
-
-       err = igb_dma_malloc_page(&igb_dev, &a_page);
-
-       if (err) { printf("malloc failed (%s)\n", strerror(errno)); return(errno); }
-
-#define PKT_SZ 200
-       a_packet.dmatime = a_packet.attime = a_packet.flags = 0;
-       a_packet.map.paddr = a_page.dma_paddr;
-       a_packet.map.mmap_size = a_page.mmap_size;
-
-       a_packet.offset = 0; 
-       a_packet.vaddr = a_page.dma_vaddr + a_packet.offset;
-       a_packet.len = PKT_SZ;
-       
-       free_packets = NULL; 
-       
-       /* divide the dma page into buffers for packets */
-       for (i = 1; i < ((a_page.mmap_size) / PKT_SZ); i++) {
-               tmp_packet = malloc(sizeof(struct igb_packet));
-               if (NULL == tmp_packet) { printf("failed to allocate igb_packet memory!\n"); return(errno); }
-
-               *tmp_packet = a_packet;
-               tmp_packet->offset = (i * PKT_SZ);
-               tmp_packet->vaddr += tmp_packet->offset;
-               tmp_packet->next = free_packets;
-               memset(tmp_packet->vaddr, 0xffffffff, PKT_SZ); /* MAC header at least */
-               free_packets = tmp_packet;
-       }
-
-       igb_set_class_bandwidth(&igb_dev, 0, 0, 0); /* disable Qav */
-
-       halt_tx = 0;
-       signal(SIGINT, sigint_handler);
-
-
-       igb_get_wallclock(&igb_dev, &last_time, &rdtsc0);
-
-       while (!halt_tx) {
-               tmp_packet = free_packets;
-
-               if (NULL == tmp_packet) goto cleanup;
-
-               free_packets = tmp_packet->next;
-
-               tmp_packet->attime = last_time + PACKET_IPG;
-               *(u_int64_t *)(tmp_packet->vaddr + 32) = tmp_packet->attime;
-
-               err = igb_xmit(&igb_dev, 0, tmp_packet);
-
-               if (!err) { last_time += PACKET_IPG; continue; }
-
-               if (ENOSPC == err) {
-                       /* put back for now */
-                       tmp_packet->next = free_packets;
-                       free_packets = tmp_packet;
-               }
-cleanup:
-               igb_clean(&igb_dev, &cleaned_packets);
-               i = 0;
-               while (cleaned_packets) {
-                       i++;
-                       tmp_packet = cleaned_packets;
-                       cleaned_packets = cleaned_packets->next;
-                       /* remap attime to compare to dma time */
-                       while (tmp_packet->attime > 999999999) tmp_packet->attime -= 1000000000;
-                       /* doesn't handle wrap-around ! */
-                       printf("delta(attime-dmatime)=%d\n", (unsigned int)(tmp_packet->attime - tmp_packet->dmatime));
-                       tmp_packet->next = free_packets;
-                       free_packets = tmp_packet;
-               } 
-               
-       }
-
-       igb_dma_free_page(&igb_dev, &a_page);
-       err = igb_detach(&igb_dev);
-       return(0);      
-}
-
similarity index 100%
rename from kmod/LICENSE
rename to kmod/igb/LICENSE
similarity index 100%
rename from kmod/Makefile
rename to kmod/igb/Makefile
diff --git a/kmod/igb/README b/kmod/igb/README
new file mode 100644 (file)
index 0000000..08f9a5c
--- /dev/null
@@ -0,0 +1,31 @@
+INTRODUCTION
+
+This component demonstrates various features of the Intel I210 Ethernet 
+controller. These features can be used for developing Audio/Video Bridging 
+applications, Industrial Ethernet applications which require precise timing 
+control over frame transmission, or test harnesses for measuring system 
+latencies and sampling events.
+
+This component - igb_avb - is limited to the Intel I210 Ethernet controller.  
+The kernel module can be loaded in parallel to existing in-kernel igb modules 
+which may be used on other supported Intel LAN controllers. Modifications are 
+required to the in-kernel drivers if the existing in-kernel igb driver has 
+support for the Intel I210.
+
+BUILDING
+
+The kernel igb module can be built which supports the latest Linux kernel
+3.x PTP clock support - to enable, modify kmod/Makefile and enable -DCONFIG_PTP
+as a build option (e.g. EXTRA_CFLAGS += -DCONFIG_PTP).
+
+RUNNING
+
+To install the kernel mode driver, you must have root permissions. Typically,
+the driver is loaded by:
+       <optional> sudo modprobe dca
+       <optional> sudo modprobe ptp
+       sudo insmod ./igb_avb.ko
+
+As 3.4 and later kernels include support for the I210, you may need to 'rmmod 
+igb' before loading the igb_avb module.
+
similarity index 100%
rename from kmod/e1000_82575.c
rename to kmod/igb/e1000_82575.c
similarity index 100%
rename from kmod/e1000_82575.h
rename to kmod/igb/e1000_82575.h
similarity index 100%
rename from kmod/e1000_api.c
rename to kmod/igb/e1000_api.c
similarity index 100%
rename from kmod/e1000_api.h
rename to kmod/igb/e1000_api.h
similarity index 100%
rename from kmod/e1000_hw.h
rename to kmod/igb/e1000_hw.h
similarity index 100%
rename from kmod/e1000_i210.c
rename to kmod/igb/e1000_i210.c
similarity index 100%
rename from kmod/e1000_i210.h
rename to kmod/igb/e1000_i210.h
similarity index 100%
rename from kmod/e1000_mac.c
rename to kmod/igb/e1000_mac.c
similarity index 100%
rename from kmod/e1000_mac.h
rename to kmod/igb/e1000_mac.h
similarity index 100%
rename from kmod/e1000_manage.c
rename to kmod/igb/e1000_manage.c
similarity index 100%
rename from kmod/e1000_manage.h
rename to kmod/igb/e1000_manage.h
similarity index 100%
rename from kmod/e1000_mbx.c
rename to kmod/igb/e1000_mbx.c
similarity index 100%
rename from kmod/e1000_mbx.h
rename to kmod/igb/e1000_mbx.h
similarity index 100%
rename from kmod/e1000_nvm.c
rename to kmod/igb/e1000_nvm.c
similarity index 100%
rename from kmod/e1000_nvm.h
rename to kmod/igb/e1000_nvm.h
similarity index 100%
rename from kmod/e1000_osdep.h
rename to kmod/igb/e1000_osdep.h
similarity index 100%
rename from kmod/e1000_phy.c
rename to kmod/igb/e1000_phy.c
similarity index 100%
rename from kmod/e1000_phy.h
rename to kmod/igb/e1000_phy.h
similarity index 100%
rename from kmod/e1000_regs.h
rename to kmod/igb/e1000_regs.h
similarity index 100%
rename from kmod/igb.h
rename to kmod/igb/igb.h
similarity index 100%
rename from kmod/igb_ethtool.c
rename to kmod/igb/igb_ethtool.c
similarity index 100%
rename from kmod/igb_main.c
rename to kmod/igb/igb_main.c
similarity index 100%
rename from kmod/igb_param.c
rename to kmod/igb/igb_param.c
similarity index 100%
rename from kmod/igb_procfs.c
rename to kmod/igb/igb_procfs.c
similarity index 100%
rename from kmod/igb_ptp.c
rename to kmod/igb/igb_ptp.c
similarity index 100%
rename from kmod/igb_regtest.h
rename to kmod/igb/igb_regtest.h
similarity index 100%
rename from kmod/igb_sysfs.c
rename to kmod/igb/igb_sysfs.c
similarity index 100%
rename from kmod/igb_vmdq.c
rename to kmod/igb/igb_vmdq.c
similarity index 100%
rename from kmod/igb_vmdq.h
rename to kmod/igb/igb_vmdq.h
similarity index 100%
rename from kmod/kcompat.c
rename to kmod/igb/kcompat.c
similarity index 100%
rename from kmod/kcompat.h
rename to kmod/igb/kcompat.h
similarity index 100%
rename from lib/LICENSE
rename to lib/igb/LICENSE
similarity index 100%
rename from lib/Makefile
rename to lib/igb/Makefile
similarity index 100%
rename from lib/e1000_82575.h
rename to lib/igb/e1000_82575.h
similarity index 100%
rename from lib/e1000_defines.h
rename to lib/igb/e1000_defines.h
similarity index 100%
rename from lib/e1000_hw.h
rename to lib/igb/e1000_hw.h
similarity index 100%
rename from lib/e1000_osdep.h
rename to lib/igb/e1000_osdep.h
similarity index 100%
rename from lib/e1000_regs.h
rename to lib/igb/e1000_regs.h
similarity index 91%
rename from lib/igb.c
rename to lib/igb/igb.c
index c149e99..4c814fa 100644 (file)
--- a/lib/igb.c
@@ -981,7 +981,11 @@ igb_get_wallclock(device_t *dev, u_int64_t *curtime, u_int64_t *rdtsc)
        return(0);
 } 
 int    
-igb_set_class_bandwidth(device_t *dev, u_int32_t class_a, u_int32_t class_b, u_int32_t tpktsz) 
+igb_set_class_bandwidth(device_t *dev, 
+       u_int32_t class_a,
+       u_int32_t class_b,
+       u_int32_t tpktsz_a,
+       u_int32_t tpktsz_b) 
 {
        u_int32_t       tqavctrl;
        u_int32_t       tqavcc0, tqavcc1;
@@ -992,6 +996,7 @@ igb_set_class_bandwidth(device_t *dev, u_int32_t class_a, u_int32_t class_b, u_i
        struct e1000_hw *hw;
        struct igb_link_cmd     link;
        int     err;
+       float           class_a_percent, class_b_percent;
 
        if (NULL == dev) return EINVAL;
        adapter = (struct adapter *)dev->private_data;
@@ -1011,9 +1016,17 @@ igb_set_class_bandwidth(device_t *dev, u_int32_t class_a, u_int32_t class_b, u_i
 
        if (link.duplex != FULL_DUPLEX ) return EINVAL;
 
-       if ((class_a + class_b) > 75 ) return EINVAL;
+       if (tpktsz_a < 64) 
+               tpktsz_a = 64; /* minimum ethernet frame size */
 
-       if ((tpktsz < 64) || (tpktsz > 2000)) return EINVAL;
+       if (tpktsz_a > 1500)
+               return EINVAL;
+
+       if (tpktsz_b < 64) 
+               tpktsz_b = 64; /* minimum ethernet frame size */
+
+       if (tpktsz_b > 1500)
+               return EINVAL;
 
        tqavctrl = E1000_READ_REG(hw, E1000_TQAVCTRL);
 
@@ -1032,24 +1045,59 @@ igb_set_class_bandwidth(device_t *dev, u_int32_t class_a, u_int32_t class_b, u_i
        else
            linkrate = E1000_TQAVCC_LINKRATE;
 
-       /* XXX convert to fixed point or floating point percents */
-       class_a_idle = (class_a * 2 * linkrate / 100); /* 'class_a' is a percent */
-       class_b_idle = (class_b * 2  * linkrate / 100);
+       /* 
+        * class_a and class_b are the packets-per-(respective)observation
+        * interval (125 usec for class A, 250 usec for class B)
+        * these parameters are also used when establishing the MSRP
+        * talker advertise attribute (as well as the tpktsize)
+        *
+        * note that class_a and class_b are independent of the media
+        * rate. For our idle slope calculation, we need to scale the
+        * (tpktsz + (media overhead)) * rate -> percentage of media rate.
+        */
+
+       /* 12=Ethernet IPG, 8=Preamble+Start of Frame, 18=Mac Header with VLAN+Etype, 4=CRC */
+       class_a_percent = (float)((tpktsz_a + (12 + 8 + 18 + 4)) * class_a) ;
+       class_b_percent = (float)((tpktsz_b + (12 + 8 + 18 + 4)) * class_b) ;
+
+       class_a_percent /= 0.000125; /* class A observation window */
+       class_b_percent /= 0.000250; /* class B observation window */
+
+       if (link.speed == 100) {
+               class_a_percent /= (100000000.0 / 8); /* bytes-per-sec @ 100Mbps */
+               class_b_percent /= (100000000.0 / 8); 
+               class_a_idle = (u_int32_t)(class_a_percent * 0.2 * (float)linkrate + 0.5);
+               class_b_idle = (u_int32_t)(class_b_percent * 0.2 * (float)linkrate + 0.5);
+       } else {
+               class_a_percent /= (1000000000.0 / 8); /* bytes-per-sec @ 1Gbps */
+               class_b_percent /= (1000000000.0 / 8); 
+               class_a_idle = (u_int32_t)(class_a_percent * 2.0 * (float)linkrate + 0.5);
+               class_b_idle = (u_int32_t)(class_b_percent * 2.0 * (float)linkrate + 0.5);
+       }
+
+       if ((class_a_percent + class_b_percent) > 0.75)
+               return EINVAL;
        tqavcc0 |= class_a_idle;
        tqavcc1 |= class_b_idle;
 
        /* 
-        * The datasheet lists a formula for configuring the high credit threshold,
-        * however it is only relevant in the conditions the high priority SR queues
-        * are internally pre-empted by manageability traffic or low power proxy modes -
-        * and if the SR queues are pre-empted, they would burst more packets than expected.
-        * So - if you enable manageability or proxy modes while running AVB traffic, you
-        * should program the high credit thresholds to prevent non-compliant packet bursts. 
-        * But be aware the stream didn't stream as much bandwidth as it reserved,
-        * and you may have had an underrun on the listener.
+        * hiCredit is the number of idleslope credits accumulated due to delay T
+        *
+        * we assume the maxInterferenceSize is 18 + 4 + 1500 (1522).
+        * Note: if EEE is enabled, we should use for maxInterferenceSize
+        * the overhead of link recovery (a media-specific quantity).
+        */
+       tqavhc0 = 0x80000000 + (class_a_idle * 1522 / linkrate ); /* L.10 */
+
+       /* 
+        * Class B high credit is is the same, except the delay
+        * is the MaxBurstSize of Class A + maxInterferenceSize of non-SR traffic
+        *
+        * L.41
+        * max Class B delay = (1522 + tpktsz_a) / (linkrate - class_a_idle)
         */
-       tqavhc0 = 0xFFFFFFFF;
-       tqavhc1 = 0xFFFFFFFF;
+
+       tqavhc1 = 0x80000000 + (class_b_idle * ((1522 + tpktsz_a)/ (linkrate - class_a_idle)));
 
        /* implicitly enable the Qav shaper */
        tqavctrl |= E1000_TQAVCTRL_TX_ARB;
similarity index 98%
rename from lib/igb.h
rename to lib/igb/igb.h
index 4e8239c..5eba112 100644 (file)
--- a/lib/igb.h
@@ -86,7 +86,7 @@ void  igb_dma_free_page(device_t *dev, struct igb_dma_alloc *page);
 int    igb_xmit(device_t *dev, unsigned int queue_index, struct igb_packet *packet);
 void   igb_clean(device_t *dev, struct igb_packet **cleaned_packets);
 int    igb_get_wallclock(device_t *dev, u_int64_t      *curtime, u_int64_t *rdtsc);
-int    igb_set_class_bandwidth(device_t *dev, u_int32_t class_a, u_int32_t class_b, u_int32_t tpktsz);
+int    igb_set_class_bandwidth(device_t *dev, u_int32_t class_a, u_int32_t class_b, u_int32_t tpktsz_a, u_int32_t tpktsz_b);
 
 void   igb_trigger(device_t *dev, u_int32_t data);
 void   igb_readreg(device_t *dev, u_int32_t reg, u_int32_t *data);
similarity index 100%
rename from lib/igb_internal.h
rename to lib/igb/igb_internal.h