diff options
author | Avinash Reddy Palleti <avinash.reddy.palleti@intel.com> | 2018-08-06 09:11:19 +0530 |
---|---|---|
committer | Avinash Reddy Palleti <avinash.reddy.palleti@intel.com> | 2018-08-06 09:11:19 +0530 |
commit | 1829e095d339dbcbb33ec7d4531d8d1a9b1dce69 (patch) | |
tree | 92465da04c1c044d051cab976e972b912970b585 | |
parent | c69fa5a444d50789252bcaf3887a3047bee65f57 (diff) | |
download | Open-AVB-1829e095d339dbcbb33ec7d4531d8d1a9b1dce69.tar.gz |
Move daemons/gptp as separate repo under AVnu
Removing daemons/gptp folder from OpenAVnu and updated all build files and
travis-ci files.
99 files changed, 3 insertions, 24546 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index eccb62eb..88de84bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,6 @@ add_subdirectory("thirdparty/cpputest") add_subdirectory("daemons/common/tests") add_subdirectory("daemons/mrpd") add_subdirectory("daemons/maap") -add_subdirectory("daemons/gptp") message(" ------------------------------------------------------- @@ -7,9 +7,8 @@ help: @echo '' @echo ' lib - igb library' @echo '' - @echo ' daemons_all - build all daemons (mrpd gptp maap shaper)' + @echo ' daemons_all - build all daemons (mrpd maap shaper)' @echo ' mrpd - mrpd daemon' - @echo ' gptp - gptp daemon for linux' @echo ' maap - maap daemon' @echo ' shaper - shaper daemon for linux' @echo '' @@ -47,12 +46,6 @@ mrpd: mrpd_clean: $(call descend,daemons/mrpd/,clean) -gptp: - $(call descend,daemons/$@/linux/build/) - -gptp_clean: - $(call descend,daemons/gptp/linux/build/,clean) - maap: $(call descend,daemons/$@/linux/build/) @@ -65,9 +58,9 @@ shaper: shaper_clean: $(call descend,daemons/shaper/,clean) -daemons_all: mrpd maap gptp shaper +daemons_all: mrpd maap shaper -daemons_all_clean: mrpd_clean gptp_clean maap_clean shaper_clean +daemons_all_clean: mrpd_clean maap_clean shaper_clean examples_common: $(call descend,examples/common) diff --git a/daemons/gptp/.gitignore b/daemons/gptp/.gitignore deleted file mode 100644 index 995d6374..00000000 --- a/daemons/gptp/.gitignore +++ /dev/null @@ -1 +0,0 @@ -doc/build diff --git a/daemons/gptp/CMakeLists.txt b/daemons/gptp/CMakeLists.txt deleted file mode 100644 index fb7d19b3..00000000 --- a/daemons/gptp/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required (VERSION 3.4) -project (gptp) - -include_directories( "./common" ) -file(GLOB GPTP_COMMON "./common/*.cpp" "./common/*.c") - -if(UNIX) - include_directories( include "./linux/src" ) - file(GLOB GPTP_OS - "./linux/src/daemon_cl.cpp" - "./linux/src/linux_ipc.cpp" - "./linux/src/platform.cpp" - "./linux/src/linux_hal_persist_file.cpp" - "./linux/src/linux_hal_generic.cpp" - "./linux/src/linux_hal_generic_adj.cpp" - "./linux/src/linux_hal_common.cpp") - add_executable (gptp ${GPTP_COMMON} ${GPTP_OS}) - target_link_libraries(gptp pthread rt) -elseif(WIN32) - if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - link_directories($ENV{WPCAP_DIR}/Lib/x64) - elseif( CMAKE_SIZEOF_VOID_P EQUAL 4 ) - link_directories($ENV{WPCAP_DIR}/Lib) - endif() - - # HAVE_REMOTE change pcap include options - add_definitions(-D_CRT_SECURE_NO_WARNINGS -DHAVE_REMOTE) - include_directories( include "./windows/daemon_cl" $ENV{WPCAP_DIR}/Include ) - file(GLOB GPTP_OS "./windows/daemon_cl/*.cpp" "./windows/daemon_cl/gptp.manifest") - add_executable (gptp ${GPTP_COMMON} ${GPTP_OS}) - target_link_libraries(gptp wpcap Iphlpapi Ws2_32) - - add_subdirectory("windows/named_pipe_test") - -endif() - diff --git a/daemons/gptp/README.rst b/daemons/gptp/README.rst deleted file mode 100644 index 1e26543d..00000000 --- a/daemons/gptp/README.rst +++ /dev/null @@ -1,145 +0,0 @@ -Introduction ------------- -This is an example Intel provided gptp daemon which can be used on Linux -and Windows platforms. There are a number of other ptp daemons available -for Linux which can be used to establish clock synchronization, although -not all may export the required APIs needed for an AVB system. - -The daemon communicates with other processes through a named pipe. -The pipe name and message format is defined in ipcdef.hpp. The pipe name -is "gptp-update". A Windows example is in the project named_pipe_test. - -The message format is: - - Integer64 <master-local phase offset> - - Integer64 <local-system phase offset> - - Float <master-local frequency offset> - - Float <local-system frequency offset> - - UInteger64 <local time of last update> - -Meaning of IPC provided values -++++++++++++++++++++++++++++++ -- master ~= local - <master-local phase offset> -- local ~= system - <local-system phase offset> -- Dmaster ~= Dlocal * (1-<master-local phase offset>/1e12) (where D denotes a delta rather than a specific value) -- Dlocal ~= Dsystem * (1-<local-system freq offset>/1e12) (where D denotes a delta rather than a specific value) - -Linux Specific -++++++++++++++ - -Requirements for documentation on a ubuntu based system: - - cmake: sudo apt-get install cmake - - doxygen: sudo apt-get install doxygen - - graphviz: sudo apt-get install graphviz - -To build, execute the linux/build makefile. - -To build for I210: - -ARCH=I210 make clean all - -To build for 'generic' Linux: - -make clean all - -To build for Intel CE 5100 Platforms: - -ARCH=IntelCE make clean all - -To execute, run - ./daemon_cl <interface-name> -such as - ./daemon_cl eth0 - -The daemon creates a shared memory segment with the 'ptp' group. Some distributions may not have this group installed. The IPC interface will not available unless the 'ptp' group is available. - - -Windows Specific -++++++++++++++++ - -Registry Changes - -* Find the driver key: - Go to device manager, device properties, details, and select driver key. - For instance, the registry could be: {4d36e972-e325-11ce-bfc1-08002be10318}\0000. - -* Search the registry for the subkey found on the driver key above: - Following the example above, search for 4d36e972-e325-11ce-bfc1-08002be10318 where there is a subkey 0000. - For instance, it could be located at HKLM/System/ControlSet001/Control/Class. - -* Add a DWORD value called TimeSync with a value of 1 to the subkey (0000 in the example above). - -* Reset the driver by disabling and re-enabling (or reboot). - -Build Dependencies - -* WinPCAP Developer's Pack (WpdPack) is required for linking - downloadable from http://www.winpcap.org/devel.htm. - -* CMAKE 3.2.2 or later - -* Microsoft Visual Studio 2013 or later - -The following environment variables must be defined: -* WPCAP_DIR the directory where WinPcap is installed - -* WinPCAP must also be installed on any machine where the daemon runs. - -To run from the command line: - - daemon_cl.exe xx-xx-xx-xx-xx-xx - -where xx-xx-xx-xx-xx-xx is the mac address of the local interface - -Windows Wireless Specific -+++++++++++++++++++++++++ - -Additional Driver/Hardware Requirements: - -* Intel(R) 8260 Adapter - -* Intel(R) PROSet/Wireless Software - - -The wireless software can be downloaded from: - -https://downloadcenter.intel.com/ (Search) - -Running the daemon: - -Currently, the driver only works with peer-to-peer wireless connections. -The connection must be established prior to running the daemon. - -./gptp.exe -w <local hw device MAC> <local P2P MAC> <remove P2P MAC> - -Other limitations: - -Some versions of Windows(R) 10 do not allow WinPcap(R) to inject frames and -the BMCA algorithm can't complete. The result is both peers assume the master -role. To fix this, force one peer to be slave with the following command line: - -./gptp.exe -w -R 255 <local hw device MAC> <local P2P MAC> <remove P2P MAC> - -Other Available PTP Daemons ---------------------------- -There are a number of existing ptp daemon projects. Some of the other known -ptp daemons are listed below. Intel has not tested Open AVB with the following -ptp daemons. - -* Richard Cochran's ptp4l daemon - https://sourceforge.net/p/linuxptp/ - - Note with this version to use gPTP specific settings, which differ - slightly from IEEE 1588. - -* http://ptpd.sourceforge.net/ - -* http://ptpd2.sourceforge.net/ - -* http://code.google.com/p/ptpv2d - -* http://home.mit.bme.hu/~khazy/ptpd/ - - diff --git a/daemons/gptp/README_AVNU_AP.txt b/daemons/gptp/README_AVNU_AP.txt deleted file mode 100644 index 5a88c927..00000000 --- a/daemons/gptp/README_AVNU_AP.txt +++ /dev/null @@ -1,91 +0,0 @@ -## Introduction -This readme covers only the additional features added to the gPTP daemon -to support the AVnu Automotive Profile (AP). - -## Automotive Profile Features Implemented -- In general all features of the AP support for a Slave device have been -implemented with the following exceptions. - - Windows OS platform code has not been implemented. -- Detailed list of the AP implementation includes - - Configuration - - Static gPTP values (AutoCDS 6.2.1) - - Persistent gPTP values (AutoCDS 6.2.2) - - Management Updated Values (AutoCDS 6.2.3) - - Signalling Message Configuration (AutoCDS 6.2.4) - - Followup TLV (AutoCDS 6.2.5) - - Required Values for gPTP (AutoCDS 6.2.6) - - Operation - - Disable BMCA (AutoCDS 6.3) - - No verification of sourcePortIdentity (AutoCDS 6.3) - - Sync Holdover (AutoCDS 6.3) - - Sync Recovery (AutoCDS 6.3) - - Implement Signalling Message (802.1AS 2011 10.5.4) - - Implement Test Mode (AutoCDS 5.3) - - Exception Handling - - Link State Change (AutoCDS 9.2.1) - - Loss of Sync Messages (AutoCDS 9.3.1) - - Non-Continuous Sync Values (AutoCDS 9.3.2) - - Pdelay Response Timeout (AutoCDS 9.3.3) (Not implemented) - - neighborPropDelay value (AutoCDS 9.3.4) - - Diagnostic counters (AutoCDS 13) - - Abstracted with only simple dump to log upon SIGUSR2 signal. - -## Non-Automotive Profile Changes -- Added fuller feature logging within gPTP -- Updated the various logging macros and direct usage of printfs to use the new -logging -- IEEE1588Port class initialization changed to reduced the 14+ constructor -parameters to a single init parameter. -- Link up and Link down detection added. -- Abstracted the state save functionality to allow for easier integration to -other platforms. - -## New Command Line Options -- E enable test mode (as defined in AVnu automotive profile) -- V enable AVnu Automotive Profile -- GM set grandmaster for Automotive Profile -- INITSYNC <value> initial sync interval (Log base 2. 0 = 1 sec) -- OPERSYNC <value> operational sync interval (Log base 2. 0 = 1 sec) -- INITPDELAY <value> initial pdelay interval (Log base 2. 0 = 1 sec) -- OPERPDELAY <value> operational pdelay interval (Log base 2. 0 = 1 sec) - -## Build Related -- There are no changes to the standard build for gPTP - -## Execution Related -- Other than the new command line options there are no changes to starting gPTP -- Example - - ./run_gptp.sh eth1 -M statefile -V - - Start with AP and a specific file name for saving state information. - -## Run Time Related -- Signals - - SIGHUP: writes the current gPTP state information to file. - - SIGUSR2: Dumps the diagnostic counters to the log - -## Known Issues -- When running as slave (none -GM) there may be a SYNC rx timeout exception reported when signalling to a different SYNC rate. -- Link down or link up may be incorrectly detected at times. - -## Windows Functionality That is Missing -- The initial implementation of the Automotive Profile for gPTP was done for Linux only. -- To locate the functionality that must be implemented for windows one approach is to look at the pull request -at https://github.com/AVnu/Open-AVB/pull/355 and review all the differences in the Linux folder. -- Brief summary to give a sense of scope of updates needed for Windows - - MakeFile - - Updates for new files - - daemon_cl.cpp - - New command line options - - Changed state save and restore (persistence) - - Automotive profile configuration setup - - Updates to signal handling - - Other updates as well - - linux_hal_common.cpp - - Link Up and Down functionality - - linux_hal_common.hpp - - Function prototypes updated - - linux_hal_persist_file.cpp - - New functionality - - linux_hal_persist_file.hpp - - New functionality - diff --git a/daemons/gptp/README_GENIVI_DLT.txt b/daemons/gptp/README_GENIVI_DLT.txt deleted file mode 100644 index 8c40354d..00000000 --- a/daemons/gptp/README_GENIVI_DLT.txt +++ /dev/null @@ -1,48 +0,0 @@ -## Introduction -This readme covers the **optional** feature to use GENIVI DLT (Diagnostic Log and Trace) -for logging withiin gPTP. General information about GENIVI DLT can be found at: - -Primary DLT site: -https://at.projects.genivi.org/wiki/display/PROJ/Diagnostic+Log+and+Trace - -DLT on GitHub: -https://github.com/GENIVI/dlt-daemon - - -## Build Related - -DLT support in gPTP is a build time option. - -### DLT must be built separately first before it can be used within gPTP. -- Get the latest DLT from github - - https://github.com/GENIVI/dlt-daemon.git -- Follow instructions in INSTALL file. -- For example (Building with Shared libraries off) - - mkdir build - - cd build - - cmake -DBUILD_SHARED_LIBS=OFF .. - - make - - sudo make install - - Install places static lib in: /usr/local/lib/x86_64-linux-gnu/static/libdlt.a - - Install places header files in: /usr/local/include/dlt/dlt.h - -### Building gPTP with DLT loggging enabled. -- May need to update the gptp Makefile to specify location of DLT headers and lib -- GENIVI_DLT=1 make gptp - - -## Running -### DLT -- See the DLT documentaion about how to run the dlt-daemon. -- For example - - dlt-daemon -d - - Runs the daemon - - dlt-receive -a localhost - - Simple test client included in DLT to recieve DLT messages. - - dlt-user-example "Test message" - - Test the DLT client and daemon. - -### gPTP -- Run as normal. - - diff --git a/daemons/gptp/README_SYSTEMD_WATCHDOG.txt b/daemons/gptp/README_SYSTEMD_WATCHDOG.txt deleted file mode 100644 index 7cf002b8..00000000 --- a/daemons/gptp/README_SYSTEMD_WATCHDOG.txt +++ /dev/null @@ -1,28 +0,0 @@ -## Introduction -This readme covers the **optional** feature to update systemd watchdog during gPTP daemon operation. -System on which the feature will be used must support systemd. - -The solution reads WatchdogSec parameter from service configuration file and notifies watchdog -every 0.5*WatchdogSec that gPTP daemon is alive. -If there is no watchdog configuration available or WatchdogSec == 0, watchdog notification won't run. - -Watchdog configuration is read once during gPTP daemon startup. - - -## Build Related - -Systemd watchdog support in gPTP is a build time option. - -### Systemd headers and library must be present in the system while building gPTP with this feature enabled. - - -### Building gPTP with Systemd watchdog handling enabled. -- SYSTEMD_WATCHDOG=1 make gptp - - -## Running - -### gPTP -- Run as normal. - - diff --git a/daemons/gptp/common/ap_message.cpp b/daemons/gptp/common/ap_message.cpp deleted file mode 100644 index df121838..00000000 --- a/daemons/gptp/common/ap_message.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************************************************* -Copyright (c) 2012-2016, Harman International Industries, Incorporated -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "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 LISTED 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 <avbap_message.hpp> -#include <ether_port.hpp> -#include <avbts_ostimer.hpp> -#include <gptp_log.hpp> - -#include <stdio.h> -#include <string.h> -#include <math.h> - -// Octet based data 2 buffer macros -#define OCT_D2BMEMCP(d, s) memcpy(d, s, sizeof(s)); d += sizeof(s); -#define OCT_D2BBUFCP(d, s, len) memcpy(d, s, len); d += len; -#define OCT_D2BHTONB(d, s) *(U8 *)(d) = s; d += sizeof(s); -#define OCT_D2BHTONS(d, s) *(U16 *)(d) = PLAT_htons(s); d += sizeof(s); -#define OCT_D2BHTONL(d, s) *(U32 *)(d) = PLAT_htonl(s); d += sizeof(s); - -// Bit based data 2 buffer macros -#define BIT_D2BHTONB(d, s, shf) *(uint8_t *)(d) |= s << shf; -#define BIT_D2BHTONS(d, s, shf) *(uint16_t *)(d) |= PLAT_htons((uint16_t)(s << shf)); -#define BIT_D2BHTONL(d, s, shf) *(uint32_t *)(d) |= PLAT_htonl((uint32_t)(s << shf)); - - -APMessageTestStatus::APMessageTestStatus() -{ -} - -APMessageTestStatus::~APMessageTestStatus() -{ -} - -APMessageTestStatus::APMessageTestStatus( EtherPort *port ) -{ -} - -void APMessageTestStatus::sendPort( EtherPort * port ) -{ - static uint16_t sequenceId = 0; - - uint8_t buf_t[256]; - uint8_t *buf_ptr = buf_t + port->getPayloadOffset(); - uint16_t tmp16; - uint32_t tmp32; - uint64_t tmp64; - - memset(buf_t, 0, 256); - - // Create packet in buf - messageLength = AP_TEST_STATUS_LENGTH; - - BIT_D2BHTONB(buf_ptr + AP_TEST_STATUS_AVTP_SUBTYPE(AP_TEST_STATUS_OFFSET), 0xfb, 0); - BIT_D2BHTONB(buf_ptr + AP_TEST_STATUS_AVTP_VERSION_CONTROL(AP_TEST_STATUS_OFFSET), 0x1, 0); - BIT_D2BHTONS(buf_ptr + AP_TEST_STATUS_AVTP_STATUS_LENGTH(AP_TEST_STATUS_OFFSET), 148, 0); - - port->getLocalAddr()->toOctetArray(buf_ptr + AP_TEST_STATUS_TARGET_ENTITY_ID(AP_TEST_STATUS_OFFSET)); - - tmp16 = PLAT_htons(sequenceId++); - memcpy(buf_ptr + AP_TEST_STATUS_SEQUENCE_ID(AP_TEST_STATUS_OFFSET), &tmp16, sizeof(tmp16)); - - BIT_D2BHTONS(buf_ptr + AP_TEST_STATUS_COMMAND_TYPE(AP_TEST_STATUS_OFFSET), 1, 15); - BIT_D2BHTONS(buf_ptr + AP_TEST_STATUS_COMMAND_TYPE(AP_TEST_STATUS_OFFSET), 0x29, 0); - - tmp16 = PLAT_htons(0x09); - memcpy(buf_ptr + AP_TEST_STATUS_DESCRIPTOR_TYPE(AP_TEST_STATUS_OFFSET), &tmp16, sizeof(tmp16)); - tmp16 = PLAT_htons(0x00); - memcpy(buf_ptr + AP_TEST_STATUS_DESCRIPTOR_INDEX(AP_TEST_STATUS_OFFSET), &tmp16, sizeof(tmp16)); - - tmp32 = PLAT_htonl(0x07000023); - memcpy(buf_ptr + AP_TEST_STATUS_COUNTERS_VALID(AP_TEST_STATUS_OFFSET), &tmp32, sizeof(tmp32)); - - tmp32 = PLAT_htonl(port->getLinkUpCount()); - memcpy(buf_ptr + AP_TEST_STATUS_COUNTER_LINKUP(AP_TEST_STATUS_OFFSET), &tmp32, sizeof(tmp32)); - - tmp32 = PLAT_htonl(port->getLinkDownCount()); - memcpy(buf_ptr + AP_TEST_STATUS_COUNTER_LINKDOWN(AP_TEST_STATUS_OFFSET), &tmp32, sizeof(tmp32)); - - Timestamp system_time; - Timestamp device_time; - uint32_t local_clock, nominal_clock_rate; - port->getDeviceTime(system_time, device_time, local_clock, nominal_clock_rate); - tmp64 = PLAT_htonll(TIMESTAMP_TO_NS(system_time)); - memcpy(buf_ptr + AP_TEST_STATUS_MESSAGE_TIMESTAMP(AP_TEST_STATUS_OFFSET), &tmp64, sizeof(tmp64)); - - BIT_D2BHTONB(buf_ptr + AP_TEST_STATUS_STATION_STATE(AP_TEST_STATUS_OFFSET), (uint8_t)port->getStationState(), 0); - - port->sendGeneralPort(AVTP_ETHERTYPE, buf_t, messageLength, MCAST_TEST_STATUS, NULL); - - return; -} - diff --git a/daemons/gptp/common/avbap_message.hpp b/daemons/gptp/common/avbap_message.hpp deleted file mode 100644 index 4c66f758..00000000 --- a/daemons/gptp/common/avbap_message.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/************************************************************************************************************* -Copyright (c) 2012-2016, Harman International Industries, Incorporated -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "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 LISTED 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 AVBAP_MESSAGE_HPP -#define AVBAP_MESSAGE_HPP - -#include <stdint.h> -#include <avbts_osnet.hpp> -#include <ieee1588.hpp> - -#include <list> -#include <algorithm> -#include <avbts_message.hpp> - -/** @file **/ - -#define AP_TEST_STATUS_OFFSET 0 /*!< AP Test Status offset */ -#define AP_TEST_STATUS_LENGTH 160 /*!< AP Test Status length in byte */ -#define AP_TEST_STATUS_AVTP_SUBTYPE(x) x /*!< AVTP Subtype */ -#define AP_TEST_STATUS_AVTP_VERSION_CONTROL(x) x + 1 /*!< Version and control fields */ -#define AP_TEST_STATUS_AVTP_STATUS_LENGTH(x) x + 2 /*!< Status and content length */ -#define AP_TEST_STATUS_TARGET_ENTITY_ID(x) x + 4 /*!< Target entity ID */ -#define AP_TEST_STATUS_CONTROLLER_ENTITY_ID(x) x + 12 /*!< Controller entity ID */ -#define AP_TEST_STATUS_SEQUENCE_ID(x) x + 20 /*!< Sequence ID */ -#define AP_TEST_STATUS_COMMAND_TYPE(x) x + 22 /*!< Command type */ -#define AP_TEST_STATUS_DESCRIPTOR_TYPE(x) x + 24 /*!< Descriptor Type */ -#define AP_TEST_STATUS_DESCRIPTOR_INDEX(x) x + 26 /*!< Descriptor Index */ -#define AP_TEST_STATUS_COUNTERS_VALID(x) x + 28 /*!< Counters valid */ -#define AP_TEST_STATUS_COUNTER_LINKUP(x) x + 32 /*!< Counter Link Up */ -#define AP_TEST_STATUS_COUNTER_LINKDOWN(x) x + 36 /*!< Counter Link Down */ -#define AP_TEST_STATUS_COUNTER_FRAMES_TX(x) x + 40 /*!< Counter Frames TX */ -#define AP_TEST_STATUS_COUNTER_FRAMES_RX(x) x + 44 /*!< Counter Frames RX */ -#define AP_TEST_STATUS_COUNTER_FRAMES_RX_CRC_ERROR(x) x + 48 /*!< Counter Frames RX CRC Error */ -#define AP_TEST_STATUS_COUNTER_GM_CHANGED(x) x + 52 /*!< Counter GM Changed */ -#define AP_TEST_STATUS_COUNTER_RESERVED(x) x + 56 /*!< Reserved counters */ -#define AP_TEST_STATUS_MESSAGE_TIMESTAMP(x) x + 128 /*!< Message timestamp */ -#define AP_TEST_STATUS_STATION_STATE(x) x + 136 /*!< Station state */ -#define AP_TEST_STATUS_STATION_STATE_SPECIFIC_DATA(x) x + 137 /*!< Station state specific data */ -#define AP_TEST_STATUS_COUNTER_27(x) x + 140 /*!< Counter 27 */ -#define AP_TEST_STATUS_COUNTER_28(x) x + 144 /*!< Counter 28 */ -#define AP_TEST_STATUS_COUNTER_29(x) x + 148 /*!< Counter 29 */ -#define AP_TEST_STATUS_COUNTER_30(x) x + 152 /*!< Counter 30 */ -#define AP_TEST_STATUS_COUNTER_31(x) x + 156 /*!< Counter 31 */ - - -/** - * @brief Automotive Profile Test Status Station State - */ -typedef enum { - STATION_STATE_RESERVED, - STATION_STATE_ETHERNET_READY, - STATION_STATE_AVB_SYNC, - STATION_STATE_AVB_MEDIA_READY, -} StationState_t; - - -/** - * @brief Provides a class for building the ANvu Automotive - * Profile Test Status message - */ -class APMessageTestStatus { - private: - uint16_t messageLength; /*!< message length */ - - APMessageTestStatus(); - public: - /** - * @brief Default constructor. Creates APMessageTestStatus - * @param port EtherPort - */ - APMessageTestStatus( EtherPort *port ); - - /** - * @brief Destroys APMessageTestStatus interface - */ - ~APMessageTestStatus(); - - /** - * @brief Assembles APMessageTestStatus message on the - * EtherPort payload - * @param port EtherPort where the message will be assembled - * @return void - */ - void sendPort( EtherPort *port ); -}; - - -#endif diff --git a/daemons/gptp/common/avbts_clock.hpp b/daemons/gptp/common/avbts_clock.hpp deleted file mode 100644 index 22a72464..00000000 --- a/daemons/gptp/common/avbts_clock.hpp +++ /dev/null @@ -1,671 +0,0 @@ -/****************************************************************************** - - 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 <common_port.hpp> -#include <avbts_ostimerq.hpp> -#include <avbts_osipc.hpp> - -/**@file*/ - -#define EVENT_TIMER_GRANULARITY 5000000 /*!< Event timer granularity*/ - -/* These 4 macros are used only when Syntonize mode is enabled */ -#define INTEGRAL 0.0003 /*!< PI controller integral factor*/ -#define PROPORTIONAL 1.0 /*!< PI controller proportional factor*/ -#define UPPER_FREQ_LIMIT 250.0 /*!< Upper frequency limit */ -#define LOWER_FREQ_LIMIT -250.0 /*!< Lower frequency limit */ - -#define UPPER_LIMIT_PPM 250 -#define LOWER_LIMIT_PPM -250 -#define PPM_OFFSET_TO_RATIO(ppm) ((ppm) / ((FrequencyRatio)US_PER_SEC) + 1) - -/* This is the threshold in ns for which frequency adjustments will be made */ -#define PHASE_ERROR_THRESHOLD (1000000000) - -/* This is the maximum count of phase error, outside of the threshold before - adjustment is performed */ -#define PHASE_ERROR_MAX_COUNT (6) - -/* Value returned by calcMasterLocalClockRateDifference() to indicate - detection of negative time jump in follow_up message */ -#define NEGATIVE_TIME_JUMP 0.0 - -/** - * @brief Provides the clock quality abstraction. - * Represents the quality of the clock - * Defined at IEEE 802.1AS-2011 - * Clause 6.3.3.8 - */ -struct ClockQuality { - unsigned char cq_class; /*!< Clock Class - Clause 8.6.2.2 - Denotes the tracebility of the synchronized time - distributed by a clock master when it is grandmaster. */ - unsigned char clockAccuracy; /*!< Clock Accuracy - clause 8.6.2.3. - Indicates the expected time accuracy of - a clock master.*/ - int16_t offsetScaledLogVariance; /*!< ::Offset Scaled log variance - Clause 8.6.2.4. - Is the scaled, offset representation - of an estimate of the PTP variance. The - PTP variance characterizes the - precision and frequency stability of the clock - master. The PTP variance is the square of - PTPDEV (See B.1.3.2). */ -}; - -/** - * @brief Provides the 1588 clock interface - */ -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; - ClockIdentity grandmaster_clock_identity; - ClockQuality grandmaster_clock_quality; - unsigned char grandmaster_priority1; - unsigned char grandmaster_priority2; - bool grandmaster_is_boundary_clock; - uint8_t time_source; - - ClockIdentity LastEBestIdentity; - bool _syntonize; - bool _new_syntonization_set_point; - float _ppm; - int _phase_error_violation; - - CommonPort *port_list[MAX_PORTS]; - - static Timestamp start_time; - Timestamp last_sync_time; - - bool _master_local_freq_offset_init; - Timestamp _prev_master_time; - Timestamp _prev_sync_time; - - bool _local_system_freq_offset_init; - Timestamp _prev_local_time; - Timestamp _prev_system_time; - - OS_IPC *ipc; - - OSTimerQueue *timerq; - - bool forceOrdinarySlave; - FrequencyRatio _master_local_freq_offset; - FrequencyRatio _local_system_freq_offset; - - /** - * @brief fup info stores information of the last time - * the base time has changed. When that happens - * the information from fup_status is copied over - * fup_info. The follow-up sendPort method is - * supposed to get the information from fup_info - * prior to sending a message out. - */ - FollowUpTLV *fup_info; - - /** - * @brief fup status has the instantaneous info - */ - FollowUpTLV *fup_status; - - OSLock *timerq_lock; - -public: - - /** - * @brief Add a new event to the timer queue - * @param target EtherPort target - * @param e Event to be added - * @param time_ns Time in nanoseconds - */ - void addEventTimer - ( CommonPort *target, Event e, - unsigned long long time_ns ); - - /** - * @brief Deletes an event from the timer queue - * @param target Target port to remove the event from - * @param e Event to be removed - * @return void - */ - void deleteEventTimer( CommonPort *target, Event e ); - - /** - * @brief Instantiates a IEEE 1588 Clock - * @param forceOrdinarySlave Forces it to be an ordinary slave - * @param syntonize if TRUE, clock will syntonize to the master clock - * @param priority1 It is used in the execution of BCMA. See IEEE 802.1AS-2011 Clause 10.3 - * @param timerq_factory [in] Provides a factory object for creating timer queues (managing events) - * @param ipc [in] Inter process communication object - * @param lock_factory [in] Provides a factory object for creating locking a locking mechanism - */ - IEEE1588Clock - (bool forceOrdinarySlave, bool syntonize, uint8_t priority1, - OSTimerQueueFactory * timerq_factory, OS_IPC * ipc, - OSLockFactory *lock_factory ); - - /* - * Destroys the IEEE 1588 clock entity - */ - ~IEEE1588Clock(void); - - /** - * @brief Updates the frequencyRatio information - * @param buf [out] Stores the serialized clock quality state - * @param count [inout] Provides the size of buffer. Its decremented internally - * @return TRUE in case of success, FALSE when the count should be updated with the right size. - */ - bool serializeState( void *buf, long *count ); - - /** - * @brief Restores the frequencyRatio with the serialized input buffer data - * @param buf [in] serialized frequencyRatio information - * @param count [inout] Size of buffer. It is incremented internally - * @return TRUE in case of success, FALSE otherwise. - */ - bool restoreSerializedState( void *buf, long *count ); - - /** - * @brief Gets the current time from system clock - * @return System time - */ - Timestamp getTime(void); - - /** - * @brief Gets the timestamp from hardware (Deprecated) - * @return Hardware timestamp - */ - Timestamp getPreciseTime(void); - - /** - * @brief Compares the 1588 Clock to the grandmaster clock - * @param msg [in] PTP announce message - * @return TRUE if the 1588 clock - */ - bool isBetterThan(PTPMessageAnnounce * msg); - - /** - * @brief Gets the Last Best clock identity - * @return clock identity - */ - ClockIdentity getLastEBestIdentity( void ) { - return LastEBestIdentity; - } - - /** - * @brief Sets the last Best clock identity - * @param id ClockIdentity object to be set - * @return void - */ - void setLastEBestIdentity( ClockIdentity id ) { - LastEBestIdentity = id; - return; - } - - /** - * @brief Sets clock identity by id - * @param id [id] Clock identity (as an octet array) - * @return void - */ - void setClockIdentity(char *id) { - clock_identity.set((uint8_t *) id); - } - - /** - * @brief Set clock id based on the link layer address. Clock id is 8 octets - * long whereas link layer address is 6 octets long and it is turned into a - * clock identity as per the 802.1AS standard described in clause 8.5.2.2 - * @param addr Link layer address - * @return void - */ - void setClockIdentity(LinkLayerAddress * addr) { - clock_identity.set(addr); - } - - /** - * @brief Gets the domain number - * @return domain number - */ - unsigned char getDomain(void) { - return domain_number; - } - - /** - * @brief Gets grandmaster clock ID - * @return GM clock ID - */ - ClockIdentity getGrandmasterClockIdentity(void) { - return grandmaster_clock_identity; - } - - /** - * @brief Sets a new GM clock ID - * @param id New id - * @return void - */ - void setGrandmasterClockIdentity(ClockIdentity id) { - if (id != grandmaster_clock_identity) { - GPTP_LOG_STATUS("New Grandmaster \"%s\" (previous \"%s\")", id.getIdentityString().c_str(), grandmaster_clock_identity.getIdentityString().c_str()); - grandmaster_clock_identity = id; - } - } - - /** - * @brief Gets grandmaster clock quality object - * @return Clock quality - */ - ClockQuality getGrandmasterClockQuality(void) { - return grandmaster_clock_quality; - } - - /** - * @brief Sets grandmaster clock quality - * @param clock_quality ClockQuality object to be set - * @return void - */ - void setGrandmasterClockQuality( ClockQuality clock_quality ) { - grandmaster_clock_quality = clock_quality; - } - - /** - * @brief Gets the IEEE 1588 Clock quality - * @return ClockQuality - */ - ClockQuality getClockQuality(void) { - return clock_quality; - } - - /** - * @brief Gets grandmaster priority1 attribute (IEEE 802.1AS-2011 Clause 10.5.3.2.2) - * @return Grandmaster priority1 - */ - unsigned char getGrandmasterPriority1(void) { - return grandmaster_priority1; - } - - /** - * @brief Gets grandmaster priotity2 attribute (IEEE 802.1AS-2011 Clause 10.5.3.2.4) - * @return Grandmaster priority2 - */ - unsigned char getGrandmasterPriority2(void) { - return grandmaster_priority2; - } - - /** - * @brief Sets grandmaster's priority1 attribute (IEEE 802.1AS-2011 Clause 10.5.3.2.2) - * @param priority1 value to be set - * @return void - */ - void setGrandmasterPriority1( unsigned char priority1 ) { - grandmaster_priority1 = priority1; - } - - /** - * @brief Sets grandmaster's priority2 attribute (IEEE 802.1AS-2011 Clause 10.5.3.2.4) - * @param priority2 Value to be set - * @return void - */ - void setGrandmasterPriority2( unsigned char priority2 ) { - grandmaster_priority2 = priority2; - } - - /** - * @brief Gets master steps removed (IEEE 802.1AS-2011 Clause 10.3.3) - * @return steps removed value - */ - uint16_t getMasterStepsRemoved(void) { - return steps_removed; - } - - /** - * @brief Gets the currentUtcOffset attribute (IEEE 802.1AS-2011 Clause 10.3.8.9) - * @return currentUtcOffset - */ - uint16_t getCurrentUtcOffset(void) { - return current_utc_offset; - } - - /** - * @brief Gets the TimeSource attribute (IEEE 802.1AS-2011 clause 10.3.8.10) - * @return TimeSource - */ - uint8_t getTimeSource(void) { - return time_source; - } - - /** - * @brief Gets IEEE1588Clock priority1 value (IEEE 802.1AS-2011 Clause 8.6.2.1) - * @return Priority1 value - */ - unsigned char getPriority1(void) { - return priority1; - } - - /** - * @brief Gets IEEE1588Clock priority2 attribute (IEEE 802.1AS-2011 Clause 8.6.2.5) - * @return Priority2 value - */ - unsigned char getPriority2(void) { - return priority2; - } - - /** - * @brief Gets nextPortId value - * @return The remaining value from the division of current number of ports by - * (maximum number of ports + 1) + 1 - */ - uint16_t getNextPortId(void) { - return (number_ports++ % (MAX_PORTS + 1)) + 1; - } - - /** - * @brief Sets the follow up info internal object. The fup_info object contains - * the last updated information when the frequency or phase have changed - * @param fup Pointer to the FolloUpTLV object. - * @return void - */ - void setFUPInfo(FollowUpTLV *fup) - { - fup_info = fup; - } - - /** - * @brief Gets the fup_info pointer - * @return fup_info pointer - */ - FollowUpTLV *getFUPInfo(void) - { - return fup_info; - } - - /** - * @brief Sets the follow up status internal object. The fup_status object contains - * information about the current frequency/phase aqcuired through the received - * follow up messages - * @param fup Pointer to the FollowUpTLV object - * @return void - */ - void setFUPStatus(FollowUpTLV *fup) - { - fup_status = fup; - } - - /** - * @brief Gets the fup_status pointer - * @return fup_status pointer - */ - FollowUpTLV *getFUPStatus(void) - { - return fup_status; - } - - /** - * @brief Updates the follow up info internal object with the current clock source time - * status values. This method should be called whenever the clockSource entity time - * base changes (IEEE 802.1AS-2011 Clause 9.2) - * @return void - */ - void updateFUPInfo(void) - { - fup_info->incrementGMTimeBaseIndicator(); - fup_info->setScaledLastGmFreqChange(fup_status->getScaledLastGmFreqChange()); - fup_info->setScaledLastGmPhaseChange(fup_status->getScaledLastGmPhaseChange()); - } - - /** - * @brief Registers a new IEEE1588 port - * @param port [in] IEEE1588port instance - * @param index Port's index - * @return void - */ - void registerPort( CommonPort *port, uint16_t index ) - { - if (index < MAX_PORTS) { - port_list[index - 1] = port; - } - ++number_ports; - } - - /** - * @brief Gets the current port list instance - * @param count [out] Number of ports - * @param ports [out] Pointer to the port list - * @return - */ - void getPortList(int &count, CommonPort ** &ports) { - ports = this->port_list; - count = number_ports; - return; - } - - /** - * @brief Gets current system time - * @return Instance of a Timestamp object - */ - static Timestamp getSystemTime(void); - - /** - * @brief Adds an event to the timer queue using a lock - * @param target EtherPort target - * @param e Event to be added - * @param time_ns event time in nanoseconds - * @return void - */ - void addEventTimerLocked - ( CommonPort *target, Event e, unsigned long long time_ns ); - - /** - * @brief Deletes and event from the timer queue using a lock - * @param target Target port to remove the event from - * @param e Event to be deleted - * @return - */ - void deleteEventTimerLocked( CommonPort *target, Event e ); - - /** - * @brief Calculates the master to local clock rate difference - * @param master_time Master time - * @param sync_time Local time - * @return The offset in ppt (parts per trillion) - */ - FrequencyRatio calcMasterLocalClockRateDifference - ( Timestamp master_time, Timestamp sync_time ); - - /** - * @brief Calculates the local to system clock rate difference - * @param local_time Local time - * @param system_time System time - * @return The offset in ppt (parts per trillion) - */ - FrequencyRatio calcLocalSystemClockRateDifference - ( Timestamp local_time, Timestamp system_time ); - - /** - * @brief Sets the master offset, sintonyze and adjusts the frequency offset - * @param master_local_offset Master to local phase offset - * @param local_time Local time - * @param master_local_freq_offset Master to local frequency offset - * @param local_system_offset Local time to system time phase offset - * @param system_time System time - * @param local_system_freq_offset Local to system frequency offset - * @param sync_count Sync messages count - * @param pdelay_count PDelay messages count - * @param port_state PortState instance - * @param asCapable asCapable flag - */ - void setMasterOffset - ( CommonPort *port, int64_t master_local_offset, - Timestamp local_time, FrequencyRatio master_local_freq_offset, - int64_t local_system_offset, Timestamp system_time, - FrequencyRatio local_system_freq_offset, unsigned sync_count, - unsigned pdelay_count, PortState port_state, bool asCapable ); - - /** - * @brief Get local:system frequency ratio - * @return clock ratio - */ - FrequencyRatio getLocalSystemFreqOffset() - { - return _local_system_freq_offset; - } - - /** - * @brief Get the IEEE1588Clock identity value - * @return clock identity - */ - ClockIdentity getClockIdentity() { - return clock_identity; - } - - /** - * @brief Sets a flag that will allow syntonization during setMasterOffset calls - * @return void - */ - void newSyntonizationSetPoint() { - _new_syntonization_set_point = true; - } - - /** - * @brief Restart PDelays on all ports - * @return void - */ - void restartPDelayAll() { - int number_ports, i, j = 0; - CommonPort **ports; - - getPortList( number_ports, ports ); - - for( i = 0; i < number_ports; ++i ) { - while( ports[j] == NULL ) ++j; - ports[j]->restartPDelay(); - } - } - - /** - * @brief Gets all TX locks - * @return void - */ - int getTxLockAll() { - int number_ports, i, j = 0; - CommonPort **ports; - - getPortList( number_ports, ports ); - - for( i = 0; i < number_ports; ++i ) { - while( ports[j] == NULL ) ++j; - if( ports[j]->getTxLock() == false ) { - return false; - } - } - - return true; - } - - /** - * @brief Release all TX locks - * @return void - */ - int putTxLockAll() { - int number_ports, i, j = 0; - CommonPort **ports; - - getPortList( number_ports, ports ); - - for( i = 0; i < number_ports; ++i ) { - while( ports[j] == NULL ) ++j; - if( ports[j]->putTxLock() == false ) { - return false; - } - } - - return true; - } - - - /** - * @brief Declares a friend instance of tick_handler method - * @param sig Signal - * @return void - */ - friend void tick_handler(int sig); - - /** - * @brief Gets the timer queue lock - * @return OSLockResult structure - */ - OSLockResult getTimerQLock() { - return timerq_lock->lock(); - } - - /** - * @brief Releases the timer queue lock - * @return OSLockResult structure - */ - OSLockResult putTimerQLock() { - return timerq_lock->unlock(); - } - - /** - * @brief Gets a pointer to the timer queue lock object - * @return OSLock instance - */ - OSLock *timerQLock() { - return timerq_lock; - } -}; - -void tick_handler(int sig); - -#endif diff --git a/daemons/gptp/common/avbts_message.hpp b/daemons/gptp/common/avbts_message.hpp deleted file mode 100644 index f5ccd9a1..00000000 --- a/daemons/gptp/common/avbts_message.hpp +++ /dev/null @@ -1,1267 +0,0 @@ -/****************************************************************************** - - 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> - -#include <list> -#include <algorithm> - -/** @file **/ - -#define PTP_CODE_STRING_LENGTH 4 /*!< PTP code string length in bytes */ -#define PTP_SUBDOMAIN_NAME_LENGTH 16 /*!< PTP subdomain name lenght in bytes */ -#define PTP_FLAGS_LENGTH 2 /*!< PTP flags length in bytes */ - -#define GPTP_VERSION 2 /*!< GPTP version */ -#define PTP_NETWORK_VERSION 1 /*!< PTP Network version */ - -#define PTP_ETHER 1 /*!< @todo Not used */ -#define PTP_DEFAULT 255 /*!< @todo Not used */ - -#define PTP_COMMON_HDR_OFFSET 0 /*!< PTP common header offset */ -#define PTP_COMMON_HDR_LENGTH 34 /*!< PTP common header length in bytes */ -#define PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(x) x /*!< Gets the message type offset on PTP header */ -#define PTP_COMMON_HDR_PTP_VERSION(x) x+1 /*!< Gets the ptp version offset on PTP header */ -#define PTP_COMMON_HDR_MSG_LENGTH(x) x+2 /*!< Gets the message length offset on PTP header */ -#define PTP_COMMON_HDR_DOMAIN_NUMBER(x) x+4 /*!< Gets the domain number offset on PTP header */ -#define PTP_COMMON_HDR_FLAGS(x) x+6 /*!< Gets the flags offset on PTP header */ -#define PTP_COMMON_HDR_CORRECTION(x) x+8 /*!< Gets the correction field offset on PTP header */ -#define PTP_COMMON_HDR_SOURCE_CLOCK_ID(x) x+20 /*!< Gets the source clock id offset on PTP header */ -#define PTP_COMMON_HDR_SOURCE_PORT_ID(x) x+28 /*!< Gets the source port id offset on PTP header */ -#define PTP_COMMON_HDR_SEQUENCE_ID(x) x+30 /*!< Gets the sequence id offset on PTP header */ -#define PTP_COMMON_HDR_CONTROL(x) x+32 /*!< Gets the control offset on PTP header */ -#define PTP_COMMON_HDR_LOG_MSG_INTRVL(x) x+33 /*!< Gets the log message interval offset on PTP header */ - -#define PTP_ANNOUNCE_OFFSET 34 /*!< PTP announce offset */ -#define PTP_ANNOUNCE_LENGTH 30 /*!< PTP announce length in bytes */ -#define PTP_ANNOUNCE_CURRENT_UTC_OFFSET(x) x+10 /*!< Gets PTP announce current UTC offset */ -#define PTP_ANNOUNCE_GRANDMASTER_PRIORITY1(x) x+13 /*!< Gets Grandmaster priority1 offset on announce fields */ -#define PTP_ANNOUNCE_GRANDMASTER_CLOCK_QUALITY(x) x+14 /*!< Gets Grandmaster clock quality offset on announce fields */ -#define PTP_ANNOUNCE_GRANDMASTER_PRIORITY2(x) x+18 /*!< Gets Grandmasdter priority2 offset on announce fields*/ -#define PTP_ANNOUNCE_GRANDMASTER_IDENTITY(x) x+19 /*!< Gets Grandmaster identity offset on announce fields*/ -#define PTP_ANNOUNCE_STEPS_REMOVED(x) x+27 /*!< Gets steps removed offset on announce fields*/ -#define PTP_ANNOUNCE_TIME_SOURCE(x) x+29 /*!< Gets time source offset on announce fields*/ - -#define PTP_SYNC_OFFSET 34 /*!< PTP SYNC base offset */ -#define PTP_SYNC_LENGTH 10 /*!< PTP SYNC length in bytes */ -#define PTP_SYNC_SEC_MS(x) x /*!< PTP SYNC seconds MSB offset */ -#define PTP_SYNC_SEC_LS(x) x+2 /*!< PTP SYNC seconds LSB offset */ -#define PTP_SYNC_NSEC(x) x+6 /*!< PTP SYNC nanoseconds offset */ - -#define PTP_FOLLOWUP_OFFSET 34 /*!< PTP FOLLOWUP base offset */ -#define PTP_FOLLOWUP_LENGTH 10 /*!< PTP FOLLOWUP length in bytes */ -#define PTP_FOLLOWUP_SEC_MS(x) x /*!< Gets the followup seconds MSB offset */ -#define PTP_FOLLOWUP_SEC_LS(x) x+2 /*!< Gets the followup seconds LSB offset */ -#define PTP_FOLLOWUP_NSEC(x) x+6 /*!< Gets tne followup nanoseconds offset */ - -#define PTP_PDELAY_REQ_OFFSET 34 /*!< PTP PDELAY REQUEST base offset */ -#define PTP_PDELAY_REQ_LENGTH 20 /*!< PTP PDELAY REQUEST length in bytes */ -#define PTP_PDELAY_REQ_SEC_MS(x) x /*!< Gets the pdelay request seconds MSB offset */ -#define PTP_PDELAY_REQ_SEC_LS(x) x+2 /*!< Gets the pdelay request seconds LSB offset */ -#define PTP_PDELAY_REQ_NSEC(x) x+6 /*!< Gets the pdelay request nanoseconds offset */ - -#define PTP_PDELAY_RESP_OFFSET 34 /*!< PDELAY RESPONSE base offset */ -#define PTP_PDELAY_RESP_LENGTH 20 /*!< PDELAY RESPONSE length in bytes */ -#define PTP_PDELAY_RESP_SEC_MS(x) x /*!< Gets the pdelay response seconds MSB offset */ -#define PTP_PDELAY_RESP_SEC_LS(x) x+2 /*!< Gets the pdelay response seconds LSB offset */ -#define PTP_PDELAY_RESP_NSEC(x) x+6 /*!< Gets the pdelay nanoseconds offset */ -#define PTP_PDELAY_RESP_REQ_CLOCK_ID(x) x+10 /*!< Gets the pdelay response request clock id offset */ -#define PTP_PDELAY_RESP_REQ_PORT_ID(x) x+18 /*!< Gets the pdelay response request port id offset */ - -#define PTP_PDELAY_FOLLOWUP_OFFSET 34 /*!< PTP PDELAY FOLLOWUP base offset*/ -#define PTP_PDELAY_FOLLOWUP_LENGTH 20 /*!< PTP PDELAY FOLLOWUP length in bytes */ -#define PTP_PDELAY_FOLLOWUP_SEC_MS(x) x /*!< Gets the pdelay followup seconds MSB offset*/ -#define PTP_PDELAY_FOLLOWUP_SEC_LS(x) x+2 /*!< Gets the pdelay followup seconds LSB offset*/ -#define PTP_PDELAY_FOLLOWUP_NSEC(x) x+6 /*!< Gets the pdelay followup nanoseconds offset*/ -#define PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID(x) x+10 /*!< Gets the pdelay followup request clock id offset*/ -#define PTP_PDELAY_FOLLOWUP_REQ_PORT_ID(x) x+18 /*!< Gets the pdelay followup request port id offset*/ - -#define PTP_SIGNALLING_OFFSET 34 /*!< PTP signalling offset */ -#define PTP_SIGNALLING_LENGTH 10 /*!< PTP signalling length in bytes */ -#define PTP_SIGNALLING_TARGET_PORT_IDENTITY(x) x /*!< PTP signalling Tareget Port Identity */ - -#define PTP_LI_61_BYTE 1 /*!< PTP_LI_61(leap61) byte offset on flags field */ -#define PTP_LI_61_BIT 0 /*!< PTP_LI_61(leap61) bit offset on PTP_LI_61 byte*/ -#define PTP_LI_59_BYTE 1 /*!< PTP_LI_59(leap59) byte offset on flags field*/ -#define PTP_LI_59_BIT 1 /*!< PTP_LI_59(leap59) bit offset on PTP_LI_59 byte*/ -#define PTP_ASSIST_BYTE 0 /*!< PTP_ASSIST(two step flag) byte offset on flags field*/ -#define PTP_ASSIST_BIT 1 /*!< PTP_ASSIST(two step flag) bit on PTP_ASSIST byte*/ -#define PTP_PTPTIMESCALE_BYTE 1 /*!< PTPTIMESCALE byte offset on flags field*/ -#define PTP_PTPTIMESCALE_BIT 3 /*!< PTPTIMESCAPE bit offset on PTPTIMESCALE byte*/ - -#define TX_TIMEOUT_BASE 1000 /*!< Timeout base in microseconds */ -#define TX_TIMEOUT_ITER 6 /*!< Number of timeout iteractions for sending/receiving messages*/ - -/** - * @brief Enumeration message type. IEEE 1588-2008 Clause 13.3.2.2 - */ -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, -}; - -/** - * @brief Enumeration legacy message type - */ -enum LegacyMessageType { - SYNC, - DELAY_REQ, - FOLLOWUP, - DELAY_RESP, - MANAGEMENT, - MESSAGE_OTHER -}; - -/** - * @brief Enumeration multicast type. - */ -enum MulticastType { - MCAST_NONE, - MCAST_PDELAY, - MCAST_TEST_STATUS, - MCAST_OTHER -}; - -class PTPMessageId { - MessageType _messageType; - uint16_t _sequenceId; -public: - PTPMessageId() { }; - PTPMessageId(MessageType messageType, uint16_t sequenceId) : - _messageType(messageType),_sequenceId(sequenceId) { } - PTPMessageId(const PTPMessageId& a) { - _messageType = a._messageType; - _sequenceId = a._sequenceId; - } - - MessageType getMessageType(void) { - return _messageType; - } - void setMessageType(MessageType messageType) { - _messageType = messageType; - } - - uint16_t getSequenceId(void) { - return _sequenceId; - } - void setSequenceId(uint16_t sequenceId) { - _sequenceId = sequenceId; - } - - bool operator!=(const PTPMessageId & cmp) const { - return - this->_sequenceId != cmp._sequenceId || - this->_messageType != cmp._messageType ? true : false; - } - bool operator==(const PTPMessageId & cmp)const { - return - this->_sequenceId == cmp._sequenceId && - this->_messageType == cmp._messageType ? true : false; - } -}; - -/** - * @brief Builds PTP message from buffer - * @param buf [in] byte buffer containing PTP message - * @param size [in] length of buffer in bytes - * @param remote [in] address from where message was received - * @param port [in] port object that message was recieved on - * @return PTP message object - */ -PTPMessageCommon *buildPTPMessage -( char *buf, int size, LinkLayerAddress *remote, CommonPort *port ); - -/** - * @brief Provides the PTPMessage common interface used during building of - * PTP messages. - */ -class PTPMessageCommon { -protected: - unsigned char versionPTP; /*!< PTP version */ - uint16_t versionNetwork; /*!< Network version */ - MessageType messageType; /*!< MessageType to be built */ - - PortIdentity *sourcePortIdentity; /*!< PortIdentity from source*/ - - uint16_t sequenceId; /*!< PTP message sequence ID*/ - LegacyMessageType control; /*!< Control message type of LegacyMessageType */ - unsigned char flags[2]; /*!< PTP flags field */ - - uint16_t messageLength; /*!< PTP message length */ - char logMeanMessageInterval; /*!< LogMessageInterval (IEEE 1588-2008 table 24)*/ - long long correctionField; /*!< Correction Field (IEEE 1588-2008 table 21) */ - unsigned char domainNumber; /*!< PTP domain number */ - - Timestamp _timestamp; /*!< PTP message timestamp */ - unsigned _timestamp_counter_value; /*!< PTP timestamp counter value */ - bool _gc; /*!< Garbage collection flag */ - - /** - * @brief Default constructor - */ - PTPMessageCommon(void) { }; - public: - /** - * @brief Creates the PTPMessageCommon interface - * @param port EtherPort where the message interface is - * connected to. - */ - PTPMessageCommon( CommonPort *port ); - /** - * @brief Destroys PTPMessageCommon interface - */ - virtual ~PTPMessageCommon(void); - - /** - * @brief Gets a pointer to the flags field within the PTP message. - * @return Pointer to the flags field - */ - unsigned char *getFlags(void) { - return flags; - } - - /** - * @brief Gets the sequenceId value within a ptp message - * @return Sequence ID value - */ - uint16_t getSequenceId(void) { - return sequenceId; - } - /** - * @brief Sets the sequence ID value to the PTP message. - * @param seq Sequence id value to be set. - * @return void - */ - void setSequenceId(uint16_t seq) { - sequenceId = seq; - } - - /** - * @brief Gets the MessageType field within the PTP message. - * @return MessageType - */ - MessageType getMessageType(void) { - return messageType; - } - - /** - * @brief Check if message type is event - * @return true if an event message - */ - bool isEvent( void ) - { - return (( messageType >> 3) & 0x1 ) == 0; - } - - /** - * @brief Get TX timestamp - * @param port used to send message - * @param link_speed link speed of message - */ - bool getTxTimestamp( EtherPort *port, uint32_t link_speed ); - - /** - * @brief Gets the MessageID of the PTP message. - * @return MessageId - */ - PTPMessageId getMessageId(void) { - return PTPMessageId(messageType, sequenceId); - } - /** - * @brief Gets the correctionField value in a Little-Endian format. - * @return correctionField - * @todo Little endian format could be removed by adding endianess discovery on - * compile/run time. - */ - long long getCorrectionField(void) { - return correctionField; - } - /** - * @brief Sets the correction field. It expects the host format. - * @param correctionAmount - * @return void - * @todo Little endian format could be removed by adding endianess discovery on - * compile/run time. - */ - void setCorrectionField(long long correctionAmount) { - correctionField = correctionAmount; - } - - /** - * @brief Gets PortIdentity field - * @param identity [out] Source port identity - * @return void - */ - void getPortIdentity(PortIdentity * identity); - /** - * @brief Sets PortIdentity value - * @param identity [in] Source port identity value to be set. - * @return void - */ - void setPortIdentity(PortIdentity * identity); - - /** - * @brief Gets the current Timestamp value from the PTP message - * @return Current Timestamp value - */ - Timestamp getTimestamp(void) { - return _timestamp; - } - /** - * @brief Gets the timestamp counter value set during the RX timestamp method. - * @return timestamp counter value - */ - uint32_t getTimestampCounterValue(void) { - return _timestamp_counter_value;; - } - /** - * @brief Sets the timestamp value - * @param timestamp [in] Reference to Timestamp value - * @return void - */ - void setTimestamp(Timestamp & timestamp) { - _timestamp = timestamp; - } - - /** - * @brief Gets the garbage collection status - * @return TRUE when it needs to be clean. FALSE otherwise. - */ - bool garbage() { - return _gc; - } - - /** - * @brief Determine whether the message was sent by given communication technology, uuid, and - * port id fields - * @param portIdentity PortIdentity value - * @return TRUE if sender equals to internal PTPCommon values, FALSE otherwise. - */ - bool isSenderEqual(PortIdentity portIdentity); - - /** - * @brief Generic interface for processing PTP message - * @param port CommonPort object - * @return void - */ - virtual void processMessage( CommonPort *port ); - - /** - * @brief Builds PTP common header - * @param buf [out] PTP message - * @return void - */ - void buildCommonHeader(uint8_t * buf); - - friend PTPMessageCommon *buildPTPMessage - ( char *buf, int size, LinkLayerAddress *remote, CommonPort *port ); -}; - -/*Exact fit. No padding*/ -#pragma pack(push,1) - -#define PATH_TRACE_TLV_TYPE 0x8 /*!< This is the value that indicates the - TLV is a path trace TLV, as specified in - 16.2.7.1 and Table 34 of IEEE Std - 1588-2008. The value is specified there - as PATH_TRACE, whose value is 0x8. */ - -/** - * @brief Provides the PathTraceTLV interface - * The fields of the path TLV shall be as specified in Table 10-8 and in - * 10.5.4.3.2 through 10.5.4.3.9 from IEEE 802.1AS. This TLV, - * and its use, are defined in IEEE Std 1588-2008 (see 16.2 and Table 34 of IEEE Std 1588-2008). - */ -class PathTraceTLV { - private: - uint16_t tlvType; - typedef std::list<ClockIdentity> IdentityList; - IdentityList identityList; - public: - /** - * @brief Creates the PathTraceTLV interface. - * Sets tlvType to PATH_TRACE_TLV_TYPE using network byte order - */ - PathTraceTLV() { - tlvType = PLAT_htons(PATH_TRACE_TLV_TYPE); - } - /** - * @brief Parses ClockIdentity from message buffer - * @param buffer [in] Message buffer. It should be at least ::PTP_CLOCK_IDENTITY_LENGTH bytes long. - * @param size [in] Buffer size. Should be the length of the data pointed to by the buffer argument. - * @return void - */ - void parseClockIdentity(uint8_t *buffer, int size) { - int length = PLAT_ntohs(*(uint16_t*)buffer); - - buffer += sizeof(uint16_t); - size -= sizeof(uint16_t); - - if((unsigned)size < (unsigned)length) { - length = size; - } - length /= PTP_CLOCK_IDENTITY_LENGTH; - - for(; length > 0; --length) { - ClockIdentity add; - add.set(buffer); - identityList.push_back(add); - buffer += PTP_CLOCK_IDENTITY_LENGTH; - } - } - - /** - * @brief Appends new ClockIdentity to internal ClockIdentity list - * @param id ClockIdentity to be appended - * @return void - */ - void appendClockIdentity(ClockIdentity * id) { - identityList.push_back(*id); - } - - /** - * @brief Gets TLV value in a byte string format - * @param byte_str [out] Output byte string - * @return void - */ - void toByteString(uint8_t * byte_str) { - IdentityList::iterator iter; - *((uint16_t *)byte_str) = tlvType; // tlvType already in network byte order - byte_str += sizeof(tlvType); - *((uint16_t *)byte_str) = PLAT_htons - ((uint16_t)identityList.size()*PTP_CLOCK_IDENTITY_LENGTH); - byte_str += sizeof(uint16_t); - for - (iter = identityList.begin(); - iter != identityList.end(); ++iter) { - iter->getIdentityString(byte_str); - byte_str += PTP_CLOCK_IDENTITY_LENGTH; - } - } - - /** - * @brief Looks for a specific ClockIdentity on the current TLV - * @param id [in] Desired ClockIdentity - * @return TRUE if it has found it, FALSE otherwise. - */ - bool has(ClockIdentity *id) { - return std::find - (identityList.begin(), identityList.end(), *id) != - identityList.end(); - } - - /** - * @brief Gets the total length of TLV. - * Total length of TLV is length of type field (UINT16) + length of 'length' - * field (UINT16) + length of - * identities (each PTP_CLOCK_IDENTITY_LENGTH) in the path - * @return Total length - */ - int length() { - return (int)(2*sizeof(uint16_t) + PTP_CLOCK_IDENTITY_LENGTH*identityList.size()); - } -}; - -/* back to whatever the previous packing mode was */ -#pragma pack(pop) - -/** - * @brief Provides the PTPMessageAnnounce interface - * The PTPMessageAnnounce class is used to create - * announce messages on the 802.1AS format when building - * the ptp messages. - */ -class PTPMessageAnnounce:public PTPMessageCommon { - private: - uint8_t grandmasterIdentity[PTP_CLOCK_IDENTITY_LENGTH]; - ClockQuality *grandmasterClockQuality; - - PathTraceTLV tlv; - - uint16_t currentUtcOffset; - unsigned char grandmasterPriority1; - unsigned char grandmasterPriority2; - ClockQuality *clockQuality; - uint16_t stepsRemoved; - unsigned char timeSource; - - PTPMessageAnnounce(void); - public: - /** - * @brief Creates the PTPMessageAnnounce interface - */ - PTPMessageAnnounce( CommonPort * port ); - - /** - * @brief Destroys the PTPMessageAnnounce interface - */ - ~PTPMessageAnnounce(); - - /** - * @brief Compare gramdmaster's capabilities comming on the - * announce messages against the current grandmaster capabilities. - * @param msg [in] PTPMessageAnnounce to be compared - * @return TRUE if it is better. FALSE otherwise. - */ - bool isBetterThan(PTPMessageAnnounce * msg); - - /** - * @brief Gets grandmaster's priority1 value - * @return Grandmaster priority1 - */ - unsigned char getGrandmasterPriority1(void) { - return grandmasterPriority1; - } - - /** - * @brief Gets grandmaster's priority2 value - * @return Grandmaster priority2 - */ - unsigned char getGrandmasterPriority2(void) { - return grandmasterPriority2; - } - - /** - * @brief Gets grandmaster clock quality - * @return Pointer to a ClockQuality object. - */ - ClockQuality *getGrandmasterClockQuality(void) { - return grandmasterClockQuality; - } - - /** - * @brief Gets the steps removed value. See IEEE 802.1AS-2011 Clause 10.3.3 - * @return steps removed value - */ - uint16_t getStepsRemoved(void) { - return stepsRemoved; - } - - /** - * @brief Gets grandmaster identity value - * @param identity [out] Grandmaster identity - * @return void - */ - void getGrandmasterIdentity(char *identity) { - memcpy(identity, grandmasterIdentity, PTP_CLOCK_IDENTITY_LENGTH); - } - - /** - * @brief Gets grandmaster's clockIdentity value - * @return Grandmaster ClockIdentity - */ - ClockIdentity getGrandmasterClockIdentity() { - ClockIdentity ret; - ret.set( grandmasterIdentity ); - return ret; - } - - void processMessage( CommonPort *port ); - - /** - * @brief Assembles PTPMessageAnnounce message on the - * EtherPort payload - * @param port EtherPort where the message will be - * assembled - * @param destIdentity [in] Destination PortIdentity - * @return true on success - */ - bool sendPort - ( CommonPort *port, PortIdentity *destIdentity); - - friend PTPMessageCommon *buildPTPMessage - ( char *buf, int size, LinkLayerAddress *remote, CommonPort *port ); -}; - -/** - * @brief Provides a class for building the PTP Sync message - */ -class PTPMessageSync : public PTPMessageCommon { - private: - Timestamp originTimestamp; - - PTPMessageSync(); - public: - /** - * @brief Default constructor. Creates PTPMessageSync - * @param port EtherPort - */ - PTPMessageSync( EtherPort *port ); - - /** - * @brief Destroys PTPMessageSync interface - */ - ~PTPMessageSync(); - - void processMessage( CommonPort *port ); - - /** - * @brief Gets origin timestamp value - * @return Origin Timestamp - */ - Timestamp getOriginTimestamp(void) { - return originTimestamp; - } - - /** - * @brief Assembles PTPMessageSync message on the - * EtherPort payload - * @param port EtherPort where the message will be - * assembled - * @param destIdentity [in] Destination PortIdentity - * @return true on success - */ - bool sendPort - (EtherPort *port, PortIdentity *destIdentity ); - - friend PTPMessageCommon *buildPTPMessage - ( char *buf, int size, LinkLayerAddress *remote, CommonPort *port ); -}; - -/* Exact fit. No padding*/ -#pragma pack(push,1) - -/** - * @brief Provides a scaledNs interface - * The scaledNs type represents signed values of time and time interval in units of 2e-16 ns. - */ -class scaledNs { - private: - int32_t ms; - uint64_t ls; - public: - /** - * @brief Builds scaledNs interface - */ - scaledNs() { - ms = 0; - ls = 0; - } - - /** - * @brief Gets scaledNs in a byte string format - * @param byte_str [out] scaledNs value - * @return void - */ - void toByteString(uint8_t * byte_str) { - memcpy(byte_str, this, sizeof(*this)); - } - - /** - * @brief Overloads the operator = for this class - * @param other Value to be attributed to this object's instance. - * @return Reference to scaledNs object - */ - scaledNs& operator=(const scaledNs& other) - { - this->ms = other.ms; - this->ls = other.ls; - - return *this; - } - - /** - * @brief Set the lowest 64bits from the scaledNs object - * @param lsb Value to be set - * @return void - */ - void setLSB(uint64_t lsb) - { - this->ls = lsb; - } - - /** - * @brief Set the highest 32bits of the scaledNs object - * @param msb 32-bit signed integer to be set - * @return void - */ - void setMSB(int32_t msb) - { - this->ms = msb; - } -}; - -/** - * @brief Provides a follow-up TLV interface back to the previous packing mode - */ -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: - /** - * @brief Builds the FollowUpTLV interface - */ - 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 = 0; - scaledLastGmFreqChange = PLAT_htonl(0); - } - - /** - * @brief Gets FollowUpTLV information in a byte string format - * @param byte_str [out] FollowUpTLV values - */ - void toByteString(uint8_t * byte_str) { - memcpy(byte_str, this, sizeof(*this)); - } - - /** - * @brief Gets the cummulative scaledRateOffset - * @return 32 bit signed value with the rate offset information. - */ - int32_t getRateOffset() { - return cumulativeScaledRateOffset; - } - - /** - * @brief Gets the gmTimeBaseIndicator - * @return 16 bit unsigned value of the gmTimeBaseIndicator - * information - */ - uint16_t getGmTimeBaseIndicator() { - return gmTimeBaseIndicator; - } - - /** - * @brief Updates the scaledLastGmFreqChanged private member - * @param val Value to be set - * @return void - */ - void setScaledLastGmFreqChange(int32_t val) - { - scaledLastGmFreqChange = PLAT_htonl(val); - } - - /** - * @brief Gets the current scaledLastGmFreqChanged value - * @return scaledLastGmFreqChange - */ - int32_t getScaledLastGmFreqChange(void) - { - return scaledLastGmFreqChange; - } - - /** - * @brief Sets the gmTimeBaseIndicator private member - * @param tbi Value to be set - * @return void - */ - void setGMTimeBaseIndicator(uint16_t tbi) - { - gmTimeBaseIndicator = tbi; - } - - /** - * @brief Incremets the Time Base Indicator member - * @return void - */ - void incrementGMTimeBaseIndicator(void) - { - ++gmTimeBaseIndicator; - } - - /** - * @brief Gets the current gmTimeBaseIndicator value - * @return gmTimeBaseIndicator - */ - uint16_t getGMTimeBaseIndicator(void) - { - return gmTimeBaseIndicator; - } - - /** - * @brief Sets the scaledLastGmPhaseChange private member - * @param pc Value to be set - * @return void - */ - void setScaledLastGmPhaseChange(scaledNs pc) - { - scaledLastGmPhaseChange = pc; - } - - /** - * @brief Gets the scaledLastGmPhaseChange private member value - * @return scaledLastGmPhaseChange value - */ - scaledNs getScaledLastGmPhaseChange(void) - { - return scaledLastGmPhaseChange; - } -}; - -/* back to whatever the previous packing mode was */ -#pragma pack(pop) - -/** - * @brief Provides a class for a class for building a PTP follow up message - */ -class PTPMessageFollowUp:public PTPMessageCommon { -private: - Timestamp preciseOriginTimestamp; - - FollowUpTLV tlv; - - PTPMessageFollowUp(void) { } -public: - /** - * @brief Builds the PTPMessageFollowUP object - */ - PTPMessageFollowUp( CommonPort *port ); - - /** - * @brief write followup message into buffer - * @param port [in] associated CommonPort object - * @param buf_ptr [out] buffer to write data to - * @return number of bytes written to buffer - */ - size_t buildMessage(CommonPort *port, uint8_t *buf_ptr); - - /** - * @brief Assembles PTPMessageFollowUp message on the - * EtherPort payload - * @param port EtherPort where the message will be - * assembled - * @param destIdentity [in] Destination PortIdentity - * @return true on success - */ - bool sendPort - ( EtherPort *port, PortIdentity *destIdentity ); - - void processMessage( CommonPort *port ); - - /** - * @brief Processes PTP messages - * @param port [in] CommonPort - * @param receipt [in] local time message was received - * @param delay - * @return void - */ - void processMessage( CommonPort *port, Timestamp receipt ); - - /** - * @brief Gets the precise origin timestamp value - * @return preciseOriginTimestamp value - */ - Timestamp getPreciseOriginTimestamp(void) { - return preciseOriginTimestamp; - } - - /** - * @brief Sets the precis origin timestamp value - * @param timestamp Timestamp to be set - * @return void - */ - void setPreciseOriginTimestamp(Timestamp & timestamp) { - preciseOriginTimestamp = timestamp; - } - - /** - * @brief Sets the clock source time interface (802.1AS 9.2) - * @param fup Follow up message - * @return void - */ - void setClockSourceTime(FollowUpTLV *fup) - { - tlv.setGMTimeBaseIndicator(fup->getGMTimeBaseIndicator()); - tlv.setScaledLastGmFreqChange(fup->getScaledLastGmFreqChange()); - tlv.setScaledLastGmPhaseChange(fup->getScaledLastGmPhaseChange()); - } - - friend PTPMessageCommon *buildPTPMessage - ( char *buf, int size, LinkLayerAddress *remote, CommonPort *port ); -}; - -/** - * @brief Provides a class for building the PTP Path Delay Request message - */ -class PTPMessagePathDelayReq : public PTPMessageCommon { - private: - Timestamp originTimestamp; - - PTPMessagePathDelayReq() { - return; - } - public: - /** - * @brief Destroys the PTPMessagePathDelayReq object - */ - ~PTPMessagePathDelayReq() { - } - - /** - * @brief Builds the PTPMessagePathDelayReq message - */ - PTPMessagePathDelayReq( EtherPort *port ); - - /** - * @brief Assembles PTPMessagePathDelayReq message on the - * EtherPort payload - * @param port EtherPort where the message will be - * assembled - * @param destIdentity [in] Destination PortIdentity - * @return true on success - */ - bool sendPort - ( EtherPort *port, PortIdentity *destIdentity ); - - void processMessage( CommonPort *port ); - - /** - * @brief Gets origin timestamp value - * @return Origin Timestamp - */ - Timestamp getOriginTimestamp(void) { - return originTimestamp; - } - - friend PTPMessageCommon *buildPTPMessage - ( char *buf, int size, LinkLayerAddress *remote, CommonPort *port ); -}; - -/** - * @brief Provides a class for building the PTP Path Delay Response message. - */ -class PTPMessagePathDelayResp:public PTPMessageCommon { -private: - PortIdentity * requestingPortIdentity; - Timestamp requestReceiptTimestamp; - - PTPMessagePathDelayResp(void) { - } -public: - /** - * @brief Destroys the PTPMessagePathDelayResp object - */ - ~PTPMessagePathDelayResp(); - /** - * @brief Builds the PTPMessagePathDelayResp object - */ - PTPMessagePathDelayResp( EtherPort *port ); - - /** - * @brief Assembles PTPMessagePathDelayResp message on the - * EtherPort payload - * @param port EtherPort where the message will be - * assembled - * @param destIdentity [in] Destination PortIdentity - * @return true on success - */ - bool sendPort - ( EtherPort *port, PortIdentity *destIdentity ); - - void processMessage( CommonPort *port ); - - /** - * @brief Sets the request receipt timestamp - * @param timestamp Timestamp to be set - * @return void - */ - void setRequestReceiptTimestamp(Timestamp timestamp) { - requestReceiptTimestamp = timestamp; - } - - /** - * @brief Sets requesting port identity - * @param identity [in] PortIdentity to be set - * @return void - */ - void setRequestingPortIdentity(PortIdentity * identity); - /** - * @brief Gets requesting port identity - * @param identity [out] Requested PortIdentity - * @return void - */ - void getRequestingPortIdentity(PortIdentity * identity); - - /** - * @brief Gets the request receipt timestamp - * @return requestReceiptTimestamp - */ - Timestamp getRequestReceiptTimestamp(void) { - return requestReceiptTimestamp; - } - - friend PTPMessageCommon *buildPTPMessage - ( char *buf, int size, LinkLayerAddress *remote, CommonPort *port ); -}; - -/** - * @brief Provides a class for building the PTP Path Delay Response follow up message. - */ -class PTPMessagePathDelayRespFollowUp:public PTPMessageCommon { - private: - Timestamp responseOriginTimestamp; - PortIdentity *requestingPortIdentity; - - PTPMessagePathDelayRespFollowUp(void) { } - -public: - /** - * @brief Builds the PTPMessagePathDelayRespFollowUp object - */ - PTPMessagePathDelayRespFollowUp( EtherPort *port ); - - /** - * @brief Destroys the PTPMessagePathDelayRespFollowUp object - */ - ~PTPMessagePathDelayRespFollowUp(); - - /** - * @brief Assembles PTPMessageRespFollowUp message on the - * EtherPort payload - * @param port EtherPort where the message will be - * assembled - * @param destIdentity [in] Destination PortIdentity - * @return true on success - */ - bool sendPort - ( EtherPort *port, PortIdentity *destIdentity ); - - void processMessage( CommonPort *port ); - - /** - * @brief Sets the response origin timestamp - * @param timestamp Timestamp to be set - * @return void - */ - void setResponseOriginTimestamp(Timestamp timestamp) { - responseOriginTimestamp = timestamp; - } - /** - * @brief Sets the requesting port identity - * @param identity [in] PortIdentity to be set - * @return void - */ - void setRequestingPortIdentity(PortIdentity * identity); - - /** - * @brief Gets the response origin timestamp - * @return responseOriginTimestamp - */ - Timestamp getResponseOriginTimestamp(void) { - return responseOriginTimestamp; - } - /** - * @brief Gets the requesting port identity - * @return Pointer to requesting PortIdentity object - */ - PortIdentity *getRequestingPortIdentity(void) { - return requestingPortIdentity; - } - - friend PTPMessageCommon *buildPTPMessage - ( char *buf, int size, LinkLayerAddress *remote, CommonPort *port ); -}; - -/*Exact fit. No padding*/ -#pragma pack(push,1) - - -/** - * @brief Provides a Signalling Msg Interval Request TLV interface back to the previous - * packing mode - */ -class SignallingTLV { - private: - uint16_t tlvType; - uint16_t lengthField; - uint8_t organizationId[3]; - uint8_t organizationSubType_ms; - uint16_t organizationSubType_ls; - uint8_t linkDelayInterval; - uint8_t timeSyncInterval; - uint8_t announceInterval; - uint8_t flags; - uint16_t reserved; - public: - /** - * @brief Builds the Signalling Msg Interval Request TLV interface - */ - SignallingTLV() { - tlvType = PLAT_htons(0x3); - lengthField = PLAT_htons(12); - organizationId[0] = '\x00'; - organizationId[1] = '\x80'; - organizationId[2] = '\xC2'; - organizationSubType_ms = 0; - organizationSubType_ls = PLAT_htons(2); - linkDelayInterval = 0; - timeSyncInterval = 0; - announceInterval = 0; - flags = 3; - reserved = PLAT_htons(0); - } - - /** - * @brief Gets Msg Interval Request TLV information in a byte - * string format - * @param byte_str [out] Msg Interval Request TLV values - */ - void toByteString(uint8_t * byte_str) { - memcpy(byte_str, this, sizeof(*this)); - } - - /** - * @brief Gets the link delay interval. - * @return 8 bit signed value of the link delay interval. - */ - int8_t getLinkDelayInterval() { - return linkDelayInterval; - } - - /** - * @brief Sets the link delay interval. - * @param 8 bit signed value of the link delay interval. - * @return void - */ - void setLinkDelayInterval(int8_t linkDelayInterval) { - this->linkDelayInterval = linkDelayInterval; - } - - /** - * @brief Gets the time sync interval. - * @return 8 bit signed value of the time sync interval. - */ - int8_t getTimeSyncInterval() { - return timeSyncInterval; - } - - /** - * @brief Sets the time sync interval. - * #param 8 bit signed value of the time sync interval. - * @return void - */ - void setTimeSyncInterval(int8_t timeSyncInterval) { - this->timeSyncInterval = timeSyncInterval; - } - - /** - * @brief Gets the announce interval. - * @return 8 bit signed value of the announce interval. - */ - int8_t getAnnounceInterval() { - return announceInterval; - } - - /** - * @brief Sets the announce interval. - * @param 8 bit signed value of the announce interval. - * @return void - */ - void setAnnounceInterval(int8_t announceInterval) { - this->announceInterval = announceInterval; - } -}; - -/* back to whatever the previous packing mode was */ -#pragma pack(pop) - -/** - * @brief Provides a class for building a PTP signalling message - */ -class PTPMessageSignalling:public PTPMessageCommon { -private: - int8_t targetPortIdentify; - SignallingTLV tlv; - - PTPMessageSignalling(void); -public: - static const int8_t sigMsgInterval_Initial = 126; - static const int8_t sigMsgInterval_NoSend = 127; - static const int8_t sigMsgInterval_NoChange = -128; - - /** - * @brief Builds the PTPMessageSignalling object - */ - PTPMessageSignalling( EtherPort *port ); - - /** - * @brief Destroys the PTPMessageSignalling object - */ - ~PTPMessageSignalling(); - - /** - * @brief Sets the signalling intervals - * @param linkDelayInterval link delay interval - * @param timeSyncInterval Sync interval - * @param announceInterval Announce interval - * @return void - */ - void setintervals(int8_t linkDelayInterval, int8_t timeSyncInterval, int8_t announceInterval); - - /** - * @brief Assembles PTPMessageSignalling message on the - * EtherPort payload - * @param port EtherPort where the message will be - * assembled - * @param destIdentity [in] Destination PortIdentity - * @return true on success - */ - bool sendPort - ( EtherPort *port, PortIdentity *destIdentity ); - - void processMessage( CommonPort *port ); - - friend PTPMessageCommon *buildPTPMessage - ( char *buf, int size, LinkLayerAddress *remote, CommonPort *port ); -}; - -#endif diff --git a/daemons/gptp/common/avbts_oscondition.hpp b/daemons/gptp/common/avbts_oscondition.hpp deleted file mode 100644 index 93511391..00000000 --- a/daemons/gptp/common/avbts_oscondition.hpp +++ /dev/null @@ -1,123 +0,0 @@ -/****************************************************************************** - - 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 - -/**@file*/ - -/** - * @brief Provides a generic interface for OS's locking condition - */ -class OSCondition { -private: - int wait_count; -public: - /** - * @brief Waits until a condition is met - * @return TRUE after waiting - */ - virtual bool wait() = 0; - - /** - * @brief Waits for lock - * @return TRUE after waiting - */ - virtual bool wait_prelock() = 0; - - /** - * @brief Sends a signal to unblock other threads - * @return TRUE - */ - virtual bool signal() = 0; - - /** - * @brief Deletes previously declared flags - */ - virtual ~OSCondition() = 0; -protected: - /** - * @brief Default constructor. Initializes internal variables - */ - OSCondition() { - wait_count = 0; - }; - - /** - * @brief Counts up waiting condition - * @return void - */ - void up() { - ++wait_count; - } - - /** - * @brief Conds down waiting condition - * @return void - */ - void down() { - --wait_count; - } - - /** - * @brief Checks if OS is waiting - * @return TRUE if up counter is greater than zero. FALSE otherwise. - */ - bool waiting() { - return wait_count > 0; - } -}; - -inline OSCondition::~OSCondition() { } - -/** - * @brief Provides factory design patter for OS Condition class - */ -class OSConditionFactory { -public: - /** - * @brief Creates OSCondition class - * @return Pointer to OSCondition object - */ - virtual OSCondition *createCondition() const = 0; - - /** - * @brief Destroys OSCondition objects - */ - virtual ~OSConditionFactory() = 0; -}; - -inline OSConditionFactory::~OSConditionFactory() {} - - -#endif diff --git a/daemons/gptp/common/avbts_osipc.hpp b/daemons/gptp/common/avbts_osipc.hpp deleted file mode 100644 index 2adb3dbd..00000000 --- a/daemons/gptp/common/avbts_osipc.hpp +++ /dev/null @@ -1,140 +0,0 @@ -/****************************************************************************** - - 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 - -#include <stdint.h> -#include <ptptypes.hpp> - -/**@file*/ - -/** - * @brief Generic interface for Inter Process Communication arguments - */ -class OS_IPC_ARG { -public: - virtual ~OS_IPC_ARG() = 0; -}; - -inline OS_IPC_ARG::~OS_IPC_ARG () { } - -/** - * @brief Generic interface for Inter Process Communication - */ -class OS_IPC { -public: - /** - * @brief Initializes the IPC - * @return Implementation dependent - */ - virtual bool init( OS_IPC_ARG *arg = NULL ) = 0; - - /** - * @brief Updates IPC values - * - * @param ml_phoffset Master to local phase offset - * @param ls_phoffset Local to system phase offset - * @param ml_freqoffset Master to local frequency offset - * @param ls_freq_offset Local to system frequency offset - * @param local_time Local time - * @param sync_count Count of syncs - * @param pdelay_count Count of pdelays - * @param port_state Port's state - * @param asCapable asCapable flag - * - * @return Implementation dependent. - */ - virtual bool update( - int64_t ml_phoffset, - int64_t ls_phoffset, - FrequencyRatio ml_freqoffset, - FrequencyRatio ls_freq_offset, - uint64_t local_time, - uint32_t sync_count, - uint32_t pdelay_count, - PortState port_state, - bool asCapable ) = 0; - - /** - * @brief Updates grandmaster IPC values - * - * @param gptp_grandmaster_id Current grandmaster id (all 0's if no grandmaster selected) - * @param gptp_domain_number gPTP domain number - * - * @return Implementation dependent. - */ - virtual bool update_grandmaster( - uint8_t gptp_grandmaster_id[], - uint8_t gptp_domain_number ) = 0; - - /** - * @brief Updates network interface IPC values - * - * @param clock_identity The clock identity of the interface - * @param priority1 The priority1 field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param clock_class The clockClass field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param offset_scaled_log_variance The offsetScaledLogVariance field of the grandmaster functionality of the interface, or 0x0000 if not supported - * @param clock_accuracy The clockAccuracy field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param priority2 The priority2 field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param domain_number The domainNumber field of the grandmaster functionality of the interface, or 0 if not supported - * @param log_sync_interval The currentLogSyncInterval field of the grandmaster functionality of the interface, or 0 if not supported - * @param log_announce_interval The currentLogAnnounceInterval field of the grandmaster functionality of the interface, or 0 if not supported - * @param log_pdelay_interval The currentLogPDelayReqInterval field of the grandmaster functionality of the interface, or 0 if not supported - * @param port_number The portNumber field of the interface, or 0x0000 if not supported - * - * @return Implementation dependent. - */ - virtual bool update_network_interface( - uint8_t clock_identity[], - uint8_t priority1, - uint8_t clock_class, - int16_t offset_scaled_log_variance, - uint8_t clock_accuracy, - uint8_t priority2, - uint8_t domain_number, - int8_t log_sync_interval, - int8_t log_announce_interval, - int8_t log_pdelay_interval, - uint16_t port_number ) = 0; - - /* - * Destroys IPC - */ - virtual ~OS_IPC() = 0; -}; - -inline OS_IPC::~OS_IPC() {} - -#endif - diff --git a/daemons/gptp/common/avbts_oslock.hpp b/daemons/gptp/common/avbts_oslock.hpp deleted file mode 100644 index c53b904b..00000000 --- a/daemons/gptp/common/avbts_oslock.hpp +++ /dev/null @@ -1,112 +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. - -******************************************************************************/ - -#ifndef AVBTS_OSLOCK_HPP -#define AVBTS_OSLOCK_HPP - -/**@file*/ - -/** - * @brief Lock type enumeration. The possible values are: - * - oslock_recursive; - * - oslock_nonrecursive; - */ -typedef enum { oslock_recursive, oslock_nonrecursive } OSLockType; -/** - * @brief Lock result enumeration. The possible values are: - * - oslock_ok; - * - oslock_self; - * - oslock_held; - * - oslock_fail; - */ -typedef enum { oslock_ok, oslock_self, oslock_held, oslock_fail } OSLockResult; - -/** - * @brief Provides a generic mechanism for locking critical sections. - */ -class OSLock { - public: - /** - * @brief Locks a critical section - * @return OSLockResult enumeration - */ - virtual OSLockResult lock() = 0; - - /** - * @brief Unlocks a critical section - * @return OSLockResult enumeration - */ - virtual OSLockResult unlock() = 0; - - /** - * @brief Tries locking a critical section - * @return OSLockResult enumeration - */ - virtual OSLockResult trylock() = 0; - protected: - /** - * @brief Default constructor - */ - OSLock() { } - - /** - * @brief Initializes locking mechanism - * @param type Enumeration OSLockType - * @return FALSE - */ - bool initialize(OSLockType type) { - return false; - } - virtual ~OSLock() = 0; -}; - -inline OSLock::~OSLock() {} - -/** - * @brief Provides a factory pattern for OSLock - */ -class OSLockFactory { - public: - - /** - * @brief Creates locking mechanism - * @param type Enumeration OSLockType - * @return Pointer to an enumeration of type OSLock - */ - virtual OSLock *createLock(OSLockType type) const = 0; - virtual ~OSLockFactory() = 0; -}; - -inline OSLockFactory::~OSLockFactory () {} - -#endif diff --git a/daemons/gptp/common/avbts_osnet.cpp b/daemons/gptp/common/avbts_osnet.cpp deleted file mode 100644 index 6c930d70..00000000 --- a/daemons/gptp/common/avbts_osnet.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/****************************************************************************** - - 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 deleted file mode 100644 index eb3194cb..00000000 --- a/daemons/gptp/common/avbts_osnet.hpp +++ /dev/null @@ -1,396 +0,0 @@ -/****************************************************************************** - - 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> -#include <ptptypes.hpp> - -/**@file*/ - -class CommonTimestamper; - -#define FACTORY_NAME_LENGTH 48 /*!< Factory name maximum length */ -#define DEFAULT_TIMEOUT 1 /*!< Default timeout in milliseconds*/ - -/** - * @brief LinkLayerAddress Class - * Provides methods for initializing and comparing ethernet addresses. - */ -class LinkLayerAddress:public InterfaceLabel { - private: - //!< Ethernet address - uint8_t addr[ETHER_ADDR_OCTETS]; - public: - /** - * @brief Default constructor - */ - LinkLayerAddress() { - }; - - /** - * @brief Receives a 64bit scalar address and initializes its internal octet - * array with the first 48 bits. - * @param address_scalar 64 bit address - */ - LinkLayerAddress(uint64_t address_scalar) { - uint8_t *ptr; - address_scalar <<= 16; - if(addr == NULL) - return; - - for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS; ++ptr) { - *ptr = (address_scalar & 0xFF00000000000000ULL) >> 56; - address_scalar <<= 8; - } - } - - /** - * @brief Receives an address as an array of octets - * and copies the first 6 over the internal ethernet address. - * @param address_octet_array Array of octets containing the address - */ - LinkLayerAddress(uint8_t * address_octet_array) { - uint8_t *ptr; - if( addr == NULL || address_octet_array == NULL) - return; - - for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS; - ++ptr, ++address_octet_array) - { - *ptr = *address_octet_array; - } - } - - /** - * @brief Operator '==' overloading method. - * It provides a comparison between cmp and the class ethernet address defined - * at its constructor. - * @param cmp Value to be compared against. - * @return TRUE if they are equal; FALSE otherwise. - */ - bool operator==(const LinkLayerAddress & cmp) const { - return memcmp - (this->addr, cmp.addr, ETHER_ADDR_OCTETS) == 0 ? true : false; - } - - /** - * @brief Operator '<' overloading method. - ** It provides a comparison between cmp and the class ethernet address defined - * at its constructor. - * @param cmp Value to be compared against. - * @return TRUE if cmp is lower than addr, FALSE otherwise. - */ - bool operator<(const LinkLayerAddress & cmp)const { - return memcmp - (this->addr, cmp.addr, ETHER_ADDR_OCTETS) < 0 ? true : false; - } - - /** - * @brief Operator '>' overloading method. - ** It provides a comparison between cmp and the class ethernet address defined - * at its constructor. - * @param cmp Value to be compared against. - * @return TRUE if cmp is bigger than addr, FALSE otherwise. - */ - bool operator>(const LinkLayerAddress & cmp)const { - return memcmp - (this->addr, cmp.addr, ETHER_ADDR_OCTETS) > 0 ? true : false; - } - - /** - * @brief Gets first 6 bytes from ethernet address of - * object LinkLayerAddress. - * @param address_octet_array [out] Pointer to store the - * ethernet address information. - * @return void - */ - void toOctetArray(uint8_t * address_octet_array) { - uint8_t *ptr; - if(addr == NULL || address_octet_array == NULL) - return; - for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS; - ++ptr, ++address_octet_array) - { - *address_octet_array = *ptr; - } - } -}; - -/** - * @brief Provides methods for dealing with the network interface name - * @todo: Destructor doesnt delete this->name. - */ -class InterfaceName: public InterfaceLabel { - private: - //!< Interface name - char *name; - public: - /** - * @brief Default constructor - */ - InterfaceName() { } - /** - * @brief Initializes Interface name with name and size lenght+1 - * @param name [in] String with the interface name - * @param length Size of name - */ - InterfaceName(char *name, int length) { - this->name = new char[length + 1]; - PLAT_strncpy(this->name, name, length); - } - ~InterfaceName() { - delete(this->name); - } - - /** - * @brief Operator '==' overloading method. - * Compares parameter cmp to the interface name - * @param cmp String to be compared - * @return TRUE if they are equal, FALSE otherwise - */ - bool operator==(const InterfaceName & cmp) const { - return strcmp(name, cmp.name) == 0 ? true : false; - } - - /** - * @brief Operator '<' overloading method. - * Compares cmp to the interface name - * @param cmp String to be compared - * @return TRUE if interface name is found to be less than cmd. FALSE otherwise - */ - bool operator<(const InterfaceName & cmp)const { - return strcmp(name, cmp.name) < 0 ? true : false; - } - - /** - * @brief Operator '>' overloading method. - * Compares cmp to the interface name - * @param cmp String to be compared - * @return TRUE if the interface name is found to be greater than cmd. FALSE otherwise - */ - bool operator>(const InterfaceName & cmp)const { - return strcmp(name, cmp.name) > 0 ? true : false; - } - - /** - * @brief Gets interface name from the class' internal variable - * @param string [out] String to store interface's name - * @param length Length of string - * @return TRUE if length is greater than size of interface name plus one. FALSE otherwise. - */ - bool toString(char *string, size_t length) { - if(string == NULL) - return false; - - if (length >= strlen(name) + 1) { - PLAT_strncpy(string, name, length); - return true; - } - return false; - } -}; - -/** - * @brief Provides a generic class to be used as a key to create factory maps. - */ -class factory_name_t { - private: - /*<! Factory name*/ - char name[FACTORY_NAME_LENGTH]; - factory_name_t(); - public: - /** - * @brief Assign a name to the factory_name - * @param name_a [in] Name to be assigned to the object - */ - factory_name_t(const char *name_a) { - PLAT_strncpy(name, name_a, FACTORY_NAME_LENGTH - 1); - } - - /** - * @brief Operator '==' overloading method - * Compares cmp to the factory name - * @param cmp String to be compared - * @return TRUE if they are equal, FALSE otherwise - */ - bool operator==(const factory_name_t & cmp) { - return strcmp(cmp.name, this->name) == 0 ? true : false; - } - - /** - * @brief Operator '<' overloading method - * Compares cmp to the factory name - * @param cmp String to be compared - * @return TRUE if the factory_name is to be found less than cmp, FALSE otherwise - */ - bool operator<(const factory_name_t & cmp)const { - return strcmp(cmp.name, this->name) < 0 ? true : false; - } - - /** - * @brief Operator '>' overloading method - * Compares cmp to the factory name - * @param cmp String to be compared - * @return TRUE if the factory_name is to be found greater than cmp, FALSE otherwise - */ - bool operator>(const factory_name_t & cmp)const { - return strcmp(cmp.name, this->name) > 0 ? true : false; - } -}; - -/** - * @brief Enumeration net_result: - * - net_trfail - * - net_fatal - * - net_succeed - */ -typedef enum { net_trfail, net_fatal, net_succeed } net_result; - - -/** - * @brief Enumeration net_link_event: - * - net_linkup - * - net_linkdown - */ -typedef enum { NET_LINK_EVENT_DOWN, NET_LINK_EVENT_UP, NET_LINK_EVENT_FAIL } net_link_event; - -/** - * @brief Provides a generic network interface - */ -class OSNetworkInterface { - public: - /** - * @brief Sends a packet to a remote address - * @param addr [in] Remote link layer address - * @param etherType [in] The EtherType of the message - * @param payload [in] Data buffer - * @param length Size of data buffer - * @param timestamp TRUE if to use the event socket with the PTP multicast address. FALSE if to use - * a general socket. - */ - virtual net_result send - (LinkLayerAddress * addr, uint16_t etherType, uint8_t * payload, size_t length, - bool timestamp) = 0; - - /** - * @brief Receives data - * @param addr [out] Destination Mac Address - * @param payload [out] Payload received - * @param length [out] Received length - * @return net_result enumeration - */ - virtual net_result nrecv - ( LinkLayerAddress *addr, uint8_t *payload, size_t &length ) = 0; - - /** - * @brief Get Link Layer address (mac address) - * @param addr [out] Link Layer address - * @return void - */ - virtual void getLinkLayerAddress(LinkLayerAddress * addr) = 0; - - /** - * @brief Watch for netlink changes. - */ - virtual void watchNetLink( CommonPort *pPort ) = 0; - - /** - * @brief Provides generic method for getting the payload offset - */ - virtual unsigned getPayloadOffset() = 0; - - /** - * @brief Native support for polimorphic destruction - */ - virtual ~OSNetworkInterface() = 0; -}; - -inline OSNetworkInterface::~OSNetworkInterface() {} - -class OSNetworkInterfaceFactory; - -/** - * @brief Provides a map for the OSNetworkInterfaceFactory::registerFactory method - */ -typedef std::map < factory_name_t, OSNetworkInterfaceFactory * >FactoryMap_t; - -/** - * @brief Builds and registers a network interface - */ -class OSNetworkInterfaceFactory { - public: - /** - * @brief Registers network factory - * @param id - * @param factory Factory name - * @return TRUE success, FALSE when could not register it. - */ - 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; - } - - /** - * @brief Builds the network interface - * @param iface [out] Pointer to interface name - * @param id Factory name index - * @param iflabel Interface label - * @param timestamper CommonTimestamper class pointer - * @return TRUE ok, FALSE error. - */ - static bool buildInterface - (OSNetworkInterface ** iface, factory_name_t id, InterfaceLabel * iflabel, - CommonTimestamper * timestamper) { - return factoryMap[id]->createInterface - (iface, iflabel, timestamper); - } - virtual ~OSNetworkInterfaceFactory() = 0; -private: - virtual bool createInterface - (OSNetworkInterface ** iface, InterfaceLabel * iflabel, - CommonTimestamper * timestamper) = 0; - static FactoryMap_t factoryMap; -}; - -inline OSNetworkInterfaceFactory::~OSNetworkInterfaceFactory() { } - -#endif diff --git a/daemons/gptp/common/avbts_osthread.hpp b/daemons/gptp/common/avbts_osthread.hpp deleted file mode 100644 index 9464512f..00000000 --- a/daemons/gptp/common/avbts_osthread.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/****************************************************************************** - - 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 - -/**@file*/ - -/** - * @brief thread exit codes. Possible values are: - * - osthread_ok; - * - osthread_error; - */ -typedef enum { osthread_ok, osthread_error } OSThreadExitCode; - -/** - * @brief Provides the OSThreadExitCode callback format - */ -typedef OSThreadExitCode(*OSThreadFunction) (void *); -typedef void *OSThreadFunctionArg; - -/** - * @brief Provides a generic interface for threads - */ -class OSThread { -public: - /** - * @brief Starts a new thread - * @param function Callback to be started on the thread - * @param arg Function arguments - * @return Implementation dependent - */ - virtual bool start(OSThreadFunction function, void *arg) = 0; - - /** - * @brief Joins the thread - * @param exit_code OSThreadExitCode enumeration - * @return Implementation specific - */ - virtual bool join(OSThreadExitCode & exit_code) = 0; - virtual ~OSThread() = 0; -}; - -inline OSThread::~OSThread() {} - -/** - * @brief Provides factory design pattern for OSThread class - */ -class OSThreadFactory { -public: - /** - * @brief Creates a new thread - * @return Pointer to OSThread object - */ - virtual OSThread * createThread() const = 0; - - /** - * @brief Destroys the new thread - */ - virtual ~OSThreadFactory() = 0; -}; - -inline OSThreadFactory::~OSThreadFactory() {} - - -#endif diff --git a/daemons/gptp/common/avbts_ostimer.hpp b/daemons/gptp/common/avbts_ostimer.hpp deleted file mode 100644 index cacdfc95..00000000 --- a/daemons/gptp/common/avbts_ostimer.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************** - - 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 - -/**@file*/ - -/** - * @brief OSTimer generic interface - */ -class OSTimer { -public: - /** - * @brief Sleep for a given amount of time - * @param micro Time in micro-seconds - * @return Implmentation specific - */ - virtual unsigned long sleep(unsigned long micro) = 0; - - /* - * Virtual destructor - */ - virtual ~OSTimer() = 0; -}; - -inline OSTimer::~OSTimer() {} - -/** - * @brief Provides factory design patter for OSTimer class - */ -class OSTimerFactory { -public: - /** - * @brief Creates the OSTimer - * @return Pointer to OSTimer object - */ - virtual OSTimer *createTimer() const = 0; - - /* - * Destroys the OSTimer previsouly created - */ - virtual ~OSTimerFactory() = 0; -}; - -inline OSTimerFactory::~OSTimerFactory() {} - -#endif diff --git a/daemons/gptp/common/avbts_ostimerq.hpp b/daemons/gptp/common/avbts_ostimerq.hpp deleted file mode 100644 index fc60671f..00000000 --- a/daemons/gptp/common/avbts_ostimerq.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/****************************************************************************** - - 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 - -/**@file*/ - -/** - * @brief ostimerq callback definition - */ -typedef void (*ostimerq_handler) (void *); - -class IEEE1588Clock; - -/** - * @brief OSTimerQueue generic interface - */ -class OSTimerQueue { -protected: - /** - * @brief Initializes timer queue - * @return TRUE - */ - virtual bool init() { return true; } - - /** - * @brief Default constructor - */ - OSTimerQueue() {} -public: - /** - * @brief Add an event to the timer queue - * @param micros Time in microsseconds - * @param type Event type - * @param func Callback - * @param arg inner argument of type event_descriptor_t - * @param dynamic when true, allows elements to be deleted from the queue - * @param event [inout] Pointer to the event - * @return TRUE success, FALSE fail - */ - virtual bool addEvent - (unsigned long micros, int type, ostimerq_handler func, - event_descriptor_t * arg, bool dynamic, unsigned *event) = 0; - - /** - * @brief Removes an event from the timer queue - * @param type Event type - * @param event [inout] Pointer to the event - * @return TRUE success, FALSE fail - */ - virtual bool cancelEvent(int type, unsigned *event) = 0; - virtual ~OSTimerQueue() = 0; -}; - -inline OSTimerQueue::~OSTimerQueue() {} - -/** - * @brief Implements factory design patter for OSTimerQueue class - */ -class OSTimerQueueFactory { -public: - /** - * @brief Creates the OSTimerQueue object - * @param clock [in] Pointer to the IEEE1555Clock object - * @return Pointer to OSTimerQueue - */ - virtual OSTimerQueue *createOSTimerQueue( IEEE1588Clock *clock ) = 0; - virtual ~OSTimerQueueFactory() = 0; -}; - -inline OSTimerQueueFactory::~OSTimerQueueFactory() {} - -#endif diff --git a/daemons/gptp/common/avbts_persist.hpp b/daemons/gptp/common/avbts_persist.hpp deleted file mode 100644 index 1c8a3aa0..00000000 --- a/daemons/gptp/common/avbts_persist.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************************************************************* -Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "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 LISTED 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. - -Attributions: The inih library portion of the source code is licensed from -Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt. -Complete license and copyright information can be found at -https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175. -*************************************************************************************************************/ - -#ifndef AVBTS_PERSIST_HPP -#define AVBTS_PERSIST_HPP - -#include <stdint.h> -#include <ptptypes.hpp> - -/**@file*/ - - -/** - * @brief Callback function to write persistent data. - * @param bufPtr Buffer pointer where the restored persistent data shall be stored. - * @param bufSize The size of the buffer. - * @return True on success otherwise False - */ -typedef void (*gPTPPersistWriteCB_t)(char *bufPtr, uint32_t bufSize); - - - -/** - * @brief Generic interface for Simple Persistence for gPTP values - */ -class GPTPPersist { -public: - /** - * @brief Initializes the GPTP_PERSIST - * @param persistID string identifer of the persistence storage. For example a file name - * @return True on success otherwise False - */ - virtual bool initStorage(const char *persistID) = 0; - - /** - * @brief Closes the GPTP_PERSIST instance - * @return True on success otherwise False - */ - virtual bool closeStorage(void) = 0; - - /** - * @brief Read the persistent data - * @param bufPtr Buffer pointer where the restored persistent data is held. - * @param bufSize The size of the restored data. - * @return True on success otherwise False - */ - virtual bool readStorage(char **bufPtr, uint32_t *bufSize) = 0; - - /** - * @brief Register the write call back - * @param writeCB Write callback from - * @return none - */ - virtual void registerWriteCB(gPTPPersistWriteCB_t writeCB) = 0; - - /** - * @brief Set write data size - * @param dataSiuze The size of data that will be written - * @return none - */ - virtual void setWriteSize(uint32_t dataSize) = 0; - - /** - * @brief Trigger the write callback. - * @return True on success otherwise False - */ - virtual bool triggerWriteStorage(void) = 0; - - /* - * Destroys the GPTP_PERSIST instance - */ - virtual ~GPTPPersist() = 0; -}; - -inline GPTPPersist::~GPTPPersist() {} - -#endif // AVBTS_PERSIST_HPP - diff --git a/daemons/gptp/common/common_port.cpp b/daemons/gptp/common/common_port.cpp deleted file mode 100644 index dc47d9d2..00000000 --- a/daemons/gptp/common/common_port.cpp +++ /dev/null @@ -1,762 +0,0 @@ -/****************************************************************************** - - 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 <common_port.hpp> -#include <avbts_clock.hpp> -#include <common_tstamper.hpp> -#include <gptp_cfg.hpp> - -CommonPort::CommonPort( PortInit_t *portInit ) : - thread_factory( portInit->thread_factory ), - timer_factory( portInit->timer_factory ), - lock_factory( portInit->lock_factory ), - condition_factory( portInit->condition_factory ), - _hw_timestamper( portInit->timestamper ), - clock( portInit->clock ), - isGM( portInit->isGM ), - phy_delay( portInit->phy_delay ) -{ - one_way_delay = ONE_WAY_DELAY_DEFAULT; - neighbor_prop_delay_thresh = portInit->neighborPropDelayThreshold; - net_label = portInit->net_label; - link_thread = thread_factory->createThread(); - listening_thread = thread_factory->createThread(); - sync_receipt_thresh = portInit->syncReceiptThreshold; - wrongSeqIDCounter = 0; - _peer_rate_offset = 1.0; - _peer_offset_init = false; - ifindex = portInit->index; - testMode = false; - port_state = PTP_INITIALIZING; - clock->registerPort(this, ifindex); - qualified_announce = NULL; - automotive_profile = portInit->automotive_profile; - announce_sequence_id = 0; - signal_sequence_id = 0; - sync_sequence_id = 0; - initialLogPdelayReqInterval = portInit->initialLogPdelayReqInterval; - initialLogSyncInterval = portInit->initialLogSyncInterval; - log_mean_announce_interval = 0; - pdelay_count = 0; - asCapable = false; - link_speed = INVALID_LINKSPEED; -} - -CommonPort::~CommonPort() -{ - delete qualified_announce; -} - -bool CommonPort::init_port( void ) -{ - log_mean_sync_interval = initialLogSyncInterval; - - if (!OSNetworkInterfaceFactory::buildInterface - ( &net_iface, factory_name_t("default"), net_label, - _hw_timestamper)) - return false; - - this->net_iface->getLinkLayerAddress(&local_addr); - clock->setClockIdentity(&local_addr); - - this->timestamper_init(); - - port_identity.setClockIdentity(clock->getClockIdentity()); - port_identity.setPortNumber(&ifindex); - - syncReceiptTimerLock = lock_factory->createLock(oslock_recursive); - syncIntervalTimerLock = lock_factory->createLock(oslock_recursive); - announceIntervalTimerLock = lock_factory->createLock(oslock_recursive); - - return _init_port(); -} - -void CommonPort::timestamper_init( void ) -{ - if( _hw_timestamper != NULL ) - { - if( !_hw_timestamper->HWTimestamper_init - ( net_label, net_iface )) - { - GPTP_LOG_ERROR - ( "Failed to initialize hardware timestamper, " - "falling back to software timestamping" ); - return; - } - } -} - -void CommonPort::timestamper_reset( void ) -{ - if( _hw_timestamper != NULL ) - { - _hw_timestamper->HWTimestamper_reset(); - } -} - -PTPMessageAnnounce *CommonPort::calculateERBest( void ) -{ - return qualified_announce; -} - -void CommonPort::recommendState -( PortState state, bool changed_external_master ) -{ - bool reset_sync = false; - switch (state) { - case PTP_MASTER: - if ( getPortState() != PTP_MASTER ) - { - setPortState( PTP_MASTER ); - // Start announce receipt timeout timer - // Start sync receipt timeout timer - becomeMaster( true ); - reset_sync = true; - } - break; - case PTP_SLAVE: - if ( getPortState() != PTP_SLAVE ) - { - becomeSlave( true ); - reset_sync = true; - } else { - if( changed_external_master ) { - GPTP_LOG_STATUS("Changed master!" ); - clock->newSyntonizationSetPoint(); - clock->updateFUPInfo(); - reset_sync = true; - } - } - break; - default: - GPTP_LOG_ERROR - ("Invalid state change requested by call to " - "1588Port::recommendState()"); - break; - } - if( reset_sync ) sync_count = 0; - return; -} - -bool CommonPort::serializeState( void *buf, off_t *count ) -{ - bool ret = true; - - if( buf == NULL ) { - *count = sizeof(port_state)+sizeof(_peer_rate_offset)+ - sizeof(asCapable)+sizeof(one_way_delay); - return true; - } - - if( port_state != PTP_MASTER && port_state != PTP_SLAVE ) { - *count = 0; - ret = false; - goto bail; - } - - /* asCapable */ - if( ret && *count >= (off_t) sizeof( asCapable )) { - memcpy( buf, &asCapable, sizeof( asCapable )); - *count -= sizeof( asCapable ); - buf = ((char *)buf) + sizeof( asCapable ); - } else if( ret == false ) { - *count += sizeof( asCapable ); - } else { - *count = sizeof( asCapable )-*count; - ret = false; - } - - /* Port State */ - if( ret && *count >= (off_t) sizeof( port_state )) { - memcpy( buf, &port_state, sizeof( port_state )); - *count -= sizeof( port_state ); - buf = ((char *)buf) + sizeof( port_state ); - } else if( ret == false ) { - *count += sizeof( port_state ); - } else { - *count = sizeof( port_state )-*count; - ret = false; - } - - /* Link Delay */ - if( ret && *count >= (off_t) sizeof( one_way_delay )) { - memcpy( buf, &one_way_delay, sizeof( one_way_delay )); - *count -= sizeof( one_way_delay ); - buf = ((char *)buf) + sizeof( one_way_delay ); - } else if( ret == false ) { - *count += sizeof( one_way_delay ); - } else { - *count = sizeof( one_way_delay )-*count; - ret = false; - } - - /* Neighbor Rate Ratio */ - if( ret && *count >= (off_t) sizeof( _peer_rate_offset )) { - memcpy( buf, &_peer_rate_offset, sizeof( _peer_rate_offset )); - *count -= sizeof( _peer_rate_offset ); - buf = ((char *)buf) + sizeof( _peer_rate_offset ); - } else if( ret == false ) { - *count += sizeof( _peer_rate_offset ); - } else { - *count = sizeof( _peer_rate_offset )-*count; - ret = false; - } - - bail: - return ret; -} - -bool CommonPort::restoreSerializedState -( void *buf, off_t *count ) -{ - bool ret = true; - - /* asCapable */ - if( ret && *count >= (off_t) sizeof( asCapable )) { - memcpy( &asCapable, buf, sizeof( asCapable )); - *count -= sizeof( asCapable ); - buf = ((char *)buf) + sizeof( asCapable ); - } else if( ret == false ) { - *count += sizeof( asCapable ); - } else { - *count = sizeof( asCapable )-*count; - ret = false; - } - - /* Port State */ - if( ret && *count >= (off_t) sizeof( port_state )) { - memcpy( &port_state, buf, sizeof( port_state )); - *count -= sizeof( port_state ); - buf = ((char *)buf) + sizeof( port_state ); - } else if( ret == false ) { - *count += sizeof( port_state ); - } else { - *count = sizeof( port_state )-*count; - ret = false; - } - - /* Link Delay */ - if( ret && *count >= (off_t) sizeof( one_way_delay )) { - memcpy( &one_way_delay, buf, sizeof( one_way_delay )); - *count -= sizeof( one_way_delay ); - buf = ((char *)buf) + sizeof( one_way_delay ); - } else if( ret == false ) { - *count += sizeof( one_way_delay ); - } else { - *count = sizeof( one_way_delay )-*count; - ret = false; - } - - /* Neighbor Rate Ratio */ - if( ret && *count >= (off_t) sizeof( _peer_rate_offset )) { - memcpy( &_peer_rate_offset, buf, sizeof( _peer_rate_offset )); - *count -= sizeof( _peer_rate_offset ); - buf = ((char *)buf) + sizeof( _peer_rate_offset ); - } else if( ret == false ) { - *count += sizeof( _peer_rate_offset ); - } else { - *count = sizeof( _peer_rate_offset )-*count; - ret = false; - } - - return ret; -} - -void CommonPort::startSyncReceiptTimer -( long long unsigned int waitTime ) -{ - clock->getTimerQLock(); - syncReceiptTimerLock->lock(); - clock->deleteEventTimer( this, SYNC_RECEIPT_TIMEOUT_EXPIRES ); - clock->addEventTimer - ( this, SYNC_RECEIPT_TIMEOUT_EXPIRES, waitTime ); - syncReceiptTimerLock->unlock(); - clock->putTimerQLock(); -} - -void CommonPort::stopSyncReceiptTimer( void ) -{ - clock->getTimerQLock(); - syncReceiptTimerLock->lock(); - clock->deleteEventTimer( this, SYNC_RECEIPT_TIMEOUT_EXPIRES ); - syncReceiptTimerLock->unlock(); - clock->putTimerQLock(); -} - -void CommonPort::startSyncIntervalTimer -( long long unsigned int waitTime ) -{ - if( syncIntervalTimerLock->trylock() == oslock_fail ) return; - clock->deleteEventTimerLocked(this, SYNC_INTERVAL_TIMEOUT_EXPIRES); - clock->addEventTimerLocked - (this, SYNC_INTERVAL_TIMEOUT_EXPIRES, waitTime); - syncIntervalTimerLock->unlock(); -} - -void CommonPort::startAnnounceIntervalTimer -( long long unsigned int waitTime ) -{ - announceIntervalTimerLock->lock(); - clock->deleteEventTimerLocked - ( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES ); - clock->addEventTimerLocked - ( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES, waitTime ); - announceIntervalTimerLock->unlock(); -} - -bool CommonPort::processStateChange( Event e ) -{ - bool changed_external_master; - uint8_t LastEBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH]; - int number_ports, j; - PTPMessageAnnounce *EBest = NULL; - char EBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH]; - CommonPort **ports; - - // Nothing to do if we are slave only - if ( clock->getPriority1() == 255 ) - return true; - - clock->getPortList(number_ports, ports); - - /* Find EBest for all ports */ - j = 0; - for (int i = 0; i < number_ports; ++i) { - while (ports[j] == NULL) - ++j; - if ( ports[j]->getPortState() == PTP_DISABLED || - ports[j]->getPortState() == PTP_FAULTY ) - { - continue; - } - if( EBest == NULL ) - { - EBest = ports[j]->calculateERBest(); - } - else if( ports[j]->calculateERBest() ) - { - if( ports[j]-> - calculateERBest()->isBetterThan(EBest)) - { - EBest = ports[j]->calculateERBest(); - } - } - } - - if (EBest == NULL) - { - return true; - } - - /* Check if we've changed */ - clock->getLastEBestIdentity(). - getIdentityString( LastEBestClockIdentity ); - EBest->getGrandmasterIdentity( EBestClockIdentity ); - if( memcmp( EBestClockIdentity, LastEBestClockIdentity, - PTP_CLOCK_IDENTITY_LENGTH ) != 0 ) - { - ClockIdentity newGM; - changed_external_master = true; - newGM.set((uint8_t *) EBestClockIdentity ); - clock->setLastEBestIdentity( newGM ); - } - else - { - changed_external_master = false; - } - - if( clock->isBetterThan( EBest )) - { - // We're Grandmaster, set grandmaster info to me - ClockIdentity clock_identity; - unsigned char priority1; - unsigned char priority2; - ClockQuality clock_quality; - - clock_identity = getClock()->getClockIdentity(); - getClock()->setGrandmasterClockIdentity( clock_identity ); - priority1 = getClock()->getPriority1(); - getClock()->setGrandmasterPriority1( priority1 ); - priority2 = getClock()->getPriority2(); - getClock()->setGrandmasterPriority2( priority2 ); - clock_quality = getClock()->getClockQuality(); - getClock()->setGrandmasterClockQuality( clock_quality ); - } - - j = 0; - for( int i = 0; i < number_ports; ++i ) - { - while (ports[j] == NULL) - ++j; - if ( ports[j]->getPortState() == - PTP_DISABLED || - ports[j]->getPortState() == - PTP_FAULTY) - { - continue; - } - if (clock->isBetterThan(EBest)) - { - // We are the GrandMaster, all ports are master - EBest = NULL; // EBest == NULL : we were grandmaster - ports[j]->recommendState( PTP_MASTER, - changed_external_master ); - } else { - if( EBest == ports[j]->calculateERBest() ) { - // The "best" Announce was received on this - // port - ClockIdentity clock_identity; - unsigned char priority1; - unsigned char priority2; - ClockQuality *clock_quality; - - ports[j]->recommendState - ( PTP_SLAVE, changed_external_master ); - clock_identity = - EBest->getGrandmasterClockIdentity(); - getClock()->setGrandmasterClockIdentity - ( clock_identity ); - priority1 = EBest->getGrandmasterPriority1(); - getClock()->setGrandmasterPriority1 - ( priority1 ); - priority2 = - EBest->getGrandmasterPriority2(); - getClock()->setGrandmasterPriority2 - ( priority2 ); - clock_quality = - EBest->getGrandmasterClockQuality(); - getClock()->setGrandmasterClockQuality - (*clock_quality); - } else { - /* Otherwise we are the master because we have - sync'd to a better clock */ - ports[j]->recommendState - (PTP_MASTER, changed_external_master); - } - } - } - - return true; -} - - -bool CommonPort::processSyncAnnounceTimeout( Event e ) -{ - // We're Grandmaster, set grandmaster info to me - ClockIdentity clock_identity; - unsigned char priority1; - unsigned char priority2; - ClockQuality clock_quality; - - Timestamp system_time; - Timestamp device_time; - uint32_t local_clock, nominal_clock_rate; - - // Nothing to do - if( clock->getPriority1() == 255 ) - return true; - - // Restart timer - if( e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ) { - clock->addEventTimerLocked - (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES, - (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER* - (unsigned long long) - (pow((double)2,getAnnounceInterval())* - 1000000000.0))); - } else { - startSyncReceiptTimer - ((unsigned long long) - (SYNC_RECEIPT_TIMEOUT_MULTIPLIER * - ((double) pow((double)2, getSyncInterval()) * - 1000000000.0))); - } - - if( getPortState() == PTP_MASTER ) - return true; - - GPTP_LOG_STATUS( - "*** %s Timeout Expired - Becoming Master", - e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ? "Announce" : - "Sync" ); - - clock_identity = getClock()->getClockIdentity(); - getClock()->setGrandmasterClockIdentity( clock_identity ); - priority1 = getClock()->getPriority1(); - getClock()->setGrandmasterPriority1( priority1 ); - priority2 = getClock()->getPriority2(); - getClock()->setGrandmasterPriority2( priority2 ); - clock_quality = getClock()->getClockQuality(); - getClock()->setGrandmasterClockQuality( clock_quality ); - - setPortState( PTP_MASTER ); - - getDeviceTime( system_time, device_time, - local_clock, nominal_clock_rate ); - - (void) clock->calcLocalSystemClockRateDifference - ( device_time, system_time ); - - setQualifiedAnnounce( NULL ); - - clock->addEventTimerLocked - ( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, - 16000000 ); - - startAnnounce(); - - return true; -} - -bool CommonPort::processEvent( Event e ) -{ - bool ret; - - switch( e ) - { - default: - // Unhandled event - ret = _processEvent( e ); - break; - - case POWERUP: - case INITIALIZE: - GPTP_LOG_DEBUG("Received POWERUP/INITIALIZE event"); - - // If port has been configured as master or slave, run media - // specific configuration. If it hasn't been configured - // start listening for announce messages - if( clock->getPriority1() == 255 || - port_state == PTP_SLAVE ) - { - becomeSlave( true ); - } - else if( port_state == PTP_MASTER ) - { - becomeMaster( true ); - } - else - { - clock->addEventTimerLocked(this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES, - (uint64_t) ( ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER * pow(2.0, getAnnounceInterval()) * 1000000000.0 )); - } - - // Do any media specific initialization - ret = _processEvent( e ); - break; - - case STATE_CHANGE_EVENT: - ret = _processEvent( e ); - - // If this event wasn't handled in a media specific way, call - // the default action - if( !ret ) - ret = processStateChange( e ); - break; - - case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES: - case SYNC_RECEIPT_TIMEOUT_EXPIRES: - if (e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES) { - incCounter_ieee8021AsPortStatAnnounceReceiptTimeouts(); - } - else if (e == SYNC_RECEIPT_TIMEOUT_EXPIRES) { - incCounter_ieee8021AsPortStatRxSyncReceiptTimeouts(); - } - - ret = _processEvent( e ); - - // If this event wasn't handled in a media specific way, call - // the default action - if( !ret ) - ret = processSyncAnnounceTimeout( e ); - break; - - case ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES: - GPTP_LOG_DEBUG("ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES occured"); - - // Send an announce message - if ( asCapable) - { - PTPMessageAnnounce *annc = - new PTPMessageAnnounce(this); - PortIdentity dest_id; - PortIdentity gmId; - ClockIdentity clock_id = clock->getClockIdentity(); - gmId.setClockIdentity(clock_id); - getPortIdentity( dest_id ); - annc->setPortIdentity( &dest_id ); - annc->sendPort( this, NULL ); - delete annc; - } - - startAnnounceIntervalTimer - ((uint64_t)( pow((double)2, getAnnounceInterval()) * - 1000000000.0 )); - ret = true; - break; - - case SYNC_INTERVAL_TIMEOUT_EXPIRES: - GPTP_LOG_DEBUG("SYNC_INTERVAL_TIMEOUT_EXPIRES occured"); - // If asCapable is true attempt some media specific action - ret = true; - if( asCapable ) - ret = _processEvent( e ); - - /* Do getDeviceTime() after transmitting sync frame - causing an update to local/system timestamp */ - { - Timestamp system_time; - Timestamp device_time; - uint32_t local_clock, nominal_clock_rate; - FrequencyRatio local_system_freq_offset; - int64_t local_system_offset; - - getDeviceTime - ( system_time, device_time, - local_clock, nominal_clock_rate ); - - GPTP_LOG_VERBOSE - ( "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); - local_system_freq_offset = - clock->calcLocalSystemClockRateDifference - ( device_time, system_time ); - clock->setMasterOffset - ( this, 0, device_time, 1.0, - local_system_offset, system_time, - local_system_freq_offset, getSyncCount(), - pdelay_count, port_state, asCapable ); - } - - // Call media specific action for completed sync - syncDone(); - - // Restart the timer - startSyncIntervalTimer - ((uint64_t)( pow((double)2, getSyncInterval()) * - 1000000000.0 )); - - break; - } - - return ret; -} - -void CommonPort::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 CommonPort::startAnnounce() -{ - startAnnounceIntervalTimer(16000000); -} - -int CommonPort::getTimestampVersion() -{ - return _hw_timestamper->getVersion(); -} - -bool CommonPort::_adjustClockRate( FrequencyRatio freq_offset ) -{ - if( _hw_timestamper ) - { - return _hw_timestamper->HWTimestamper_adjclockrate - ((float) freq_offset ); - } - - return false; -} - -void CommonPort::getExtendedError( char *msg ) -{ - if (_hw_timestamper) - { - _hw_timestamper->HWTimestamper_get_extderror(msg); - return; - } - - *msg = '\0'; -} - -bool CommonPort::adjustClockPhase( int64_t phase_adjust ) -{ - if( _hw_timestamper ) - return _hw_timestamper-> - HWTimestamper_adjclockphase( phase_adjust ); - - return false; -} - -FrequencyRatio CommonPort::getLocalSystemFreqOffset() -{ - return clock->getLocalSystemFreqOffset(); -} - -Timestamp CommonPort::getTxPhyDelay( uint32_t link_speed ) const -{ - if( phy_delay->count( link_speed ) != 0 ) - return Timestamp - ( phy_delay->at(link_speed).get_tx_delay(), 0, 0 ); - - return Timestamp(0, 0, 0); -} - -Timestamp CommonPort::getRxPhyDelay( uint32_t link_speed ) const -{ - if( phy_delay->count( link_speed ) != 0 ) - return Timestamp - ( phy_delay->at(link_speed).get_rx_delay(), 0, 0 ); - - return Timestamp(0, 0, 0); -} diff --git a/daemons/gptp/common/common_port.hpp b/daemons/gptp/common/common_port.hpp deleted file mode 100644 index 4f195836..00000000 --- a/daemons/gptp/common/common_port.hpp +++ /dev/null @@ -1,1534 +0,0 @@ -/****************************************************************************** - - 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 COMMON_PORT_HPP -#define COMMON_PORT_HPP - -#include <avbts_message.hpp> -#include <avbts_osthread.hpp> -#include <avbts_oscondition.hpp> -#include <avbts_ostimer.hpp> -#include <avbts_oslock.hpp> -#include <avbts_osnet.hpp> -#include <unordered_map> - -#include <math.h> - -#define SYNC_RECEIPT_TIMEOUT_MULTIPLIER 3 /*!< Sync rcpt timeout multiplier */ -#define ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER 3 /*!< Annc rcpt timeout mult */ -#define LOG2_INTERVAL_INVALID -127 /* Invalid Log base 2 interval value */ - -class IEEE1588Clock; - -/** - * @brief PortIdentity interface - * Defined at IEEE 802.1AS Clause 8.5.2 - */ -class PortIdentity { -private: - ClockIdentity clock_id; - uint16_t portNumber; -public: - /** - * @brief Default Constructor - */ - PortIdentity() { }; - - /** - * @brief Constructs PortIdentity interface. - * @param clock_id Clock ID value as defined at IEEE 802.1AS Clause - * 8.5.2.2 - * @param portNumber Port Number - */ - PortIdentity(uint8_t * clock_id, uint16_t * portNumber) - { - this->portNumber = *portNumber; - this->portNumber = PLAT_ntohs(this->portNumber); - this->clock_id.set(clock_id); - } - - /** - * @brief Implements the operator '!=' overloading method. Compares - * clock_id and portNumber. - * @param cmp Constant PortIdentity value to be compared against. - * @return TRUE if the comparison value differs from the object's - * PortIdentity value. FALSE otherwise. - */ - bool operator!=(const PortIdentity & cmp) const - { - return - !(this->clock_id == cmp.clock_id) || - this->portNumber != cmp.portNumber ? true : false; - } - - /** - * @brief Implements the operator '==' overloading method. Compares - * clock_id and portNumber. - * @param cmp Constant PortIdentity value to be compared against. - * @return TRUE if the comparison value equals to the object's - * PortIdentity value. FALSE otherwise. - */ - bool operator==(const PortIdentity & cmp)const - { - return - this->clock_id == cmp.clock_id && - this->portNumber == cmp.portNumber ? true : false; - } - - /** - * @brief Implements the operator '<' overloading method. Compares - * clock_id and portNumber. - * @param cmp Constant PortIdentity value to be compared against. - * @return TRUE if the comparison value is lower than the object's - * PortIdentity value. FALSE otherwise. - */ - 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; - } - - /** - * @brief Implements the operator '>' overloading method. Compares - * clock_id and portNumber. - * @param cmp Constant PortIdentity value to be compared against. - * @return TRUE if the comparison value is greater than the object's - * PortIdentity value. FALSE otherwise. - */ - 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; - } - - /** - * @brief Gets the ClockIdentity string - * @param id [out] Pointer to an array of octets. - * @return void - */ - void getClockIdentityString(uint8_t *id) - { - clock_id.getIdentityString(id); - } - - /** - * @brief Sets the ClockIdentity. - * @param clock_id Clock Identity to be set. - * @return void - */ - void setClockIdentity(ClockIdentity clock_id) - { - this->clock_id = clock_id; - } - - /** - * @brief Gets the clockIdentity value - * @return A copy of Clock identity value. - */ - ClockIdentity getClockIdentity( void ) { - return this->clock_id; - } - - /** - * @brief Gets the port number following the network byte order, i.e. - * Big-Endian. - * @param id [out] Port number - * @return void - */ - void getPortNumberNO(uint16_t * id) // Network byte order - { - uint16_t portNumberNO = PLAT_htons(portNumber); - *id = portNumberNO; - } - - /** - * @brief Gets the port number in the host byte order, which can be - * either Big-Endian - * or Little-Endian, depending on the processor where it is running. - * @param id Port number - * @return void - */ - void getPortNumber(uint16_t * id) // Host byte order - { - *id = portNumber; - } - - /** - * @brief Sets the Port number - * @param id [in] Port number - * @return void - */ - void setPortNumber(uint16_t * id) - { - portNumber = *id; - } -}; - -class phy_delay_spec_t; -typedef std::unordered_map<uint32_t, phy_delay_spec_t> phy_delay_map_t; - -/** - * @brief Structure for initializing the port class - */ -typedef struct { - /* clock IEEE1588Clock instance */ - IEEE1588Clock * clock; - - /* index Interface index */ - uint16_t index; - - /* timestamper Hardware timestamper instance */ - CommonTimestamper * timestamper; - - /* net_label Network label */ - InterfaceLabel *net_label; - - /* Virtual Network label (e.g. WiFi Direct network MAC) */ - InterfaceLabel *virtual_label; - - /* automotive_profile set the AVnu automotive profile */ - bool automotive_profile; - - /* Set to true if the port is the grandmaster. Used for fixed GM in - * the the AVnu automotive profile */ - bool isGM; - - /* Set to true if the port is the grandmaster. Used for fixed GM in - * the the AVnu automotive profile */ - bool testMode; - - /* Set to true if the port's network interface is up. Used to filter - * false LINKUP/LINKDOWN events */ - bool linkUp; - - /* gPTP 10.2.4.4 */ - signed char initialLogSyncInterval; - - /* gPTP 11.5.2.2 */ - signed char initialLogPdelayReqInterval; - - /* CDS 6.2.1.5 */ - signed char operLogPdelayReqInterval; - - /* CDS 6.2.1.6 */ - signed char operLogSyncInterval; - - /* condition_factory OSConditionFactory instance */ - OSConditionFactory * condition_factory; - - /* thread_factory OSThreadFactory instance */ - OSThreadFactory * thread_factory; - - /* timer_factory OSTimerFactory instance */ - OSTimerFactory * timer_factory; - - /* lock_factory OSLockFactory instance */ - OSLockFactory * lock_factory; - - /* phy delay */ - phy_delay_map_t const *phy_delay; - - /* sync receipt threshold */ - unsigned int syncReceiptThreshold; - - /* neighbor delay threshold */ - int64_t neighborPropDelayThreshold; -} PortInit_t; - - -/** - * @brief Structure for Port Counters - */ -typedef struct { - int32_t ieee8021AsPortStatRxSyncCount; - int32_t ieee8021AsPortStatRxFollowUpCount; - int32_t ieee8021AsPortStatRxPdelayRequest; - int32_t ieee8021AsPortStatRxPdelayResponse; - int32_t ieee8021AsPortStatRxPdelayResponseFollowUp; - int32_t ieee8021AsPortStatRxAnnounce; - int32_t ieee8021AsPortStatRxPTPPacketDiscard; - int32_t ieee8021AsPortStatRxSyncReceiptTimeouts; - int32_t ieee8021AsPortStatAnnounceReceiptTimeouts; - int32_t ieee8021AsPortStatPdelayAllowedLostResponsesExceeded; - int32_t ieee8021AsPortStatTxSyncCount; - int32_t ieee8021AsPortStatTxFollowUpCount; - int32_t ieee8021AsPortStatTxPdelayRequest; - int32_t ieee8021AsPortStatTxPdelayResponse; - int32_t ieee8021AsPortStatTxPdelayResponseFollowUp; - int32_t ieee8021AsPortStatTxAnnounce; -} PortCounters_t; - -/** - * @brief Port functionality common to all network media - */ -class CommonPort -{ -private: - LinkLayerAddress local_addr; - PortIdentity port_identity; - - /* Network socket description - physical interface number that object represents */ - uint16_t ifindex; - - /* Link speed in kb/sec */ - uint32_t link_speed; - - /* Signed value allows this to be negative result because of inaccurate - timestamp */ - int64_t one_way_delay; - int64_t neighbor_prop_delay_thresh; - - InterfaceLabel *net_label; - - OSNetworkInterface *net_iface; - - PortState port_state; - bool testMode; - bool automotive_profile; - - signed char log_mean_sync_interval; - signed char log_mean_announce_interval; - signed char initialLogSyncInterval; - - /*Sync threshold*/ - unsigned int sync_receipt_thresh; - unsigned int wrongSeqIDCounter; - - PortCounters_t counters; - - OSThread *listening_thread; - OSThread *link_thread; - - FrequencyRatio _peer_rate_offset; - Timestamp _peer_offset_ts_theirs; - Timestamp _peer_offset_ts_mine; - bool _peer_offset_init; - bool asCapable; - unsigned sync_count; /* 0 for master, increment for each sync - * received as slave */ - unsigned pdelay_count; - - signed char initialLogPdelayReqInterval; - signed char log_min_mean_pdelay_req_interval; - - PTPMessageAnnounce *qualified_announce; - - uint16_t announce_sequence_id; - uint16_t signal_sequence_id; - uint16_t sync_sequence_id; - - uint16_t lastGmTimeBaseIndicator; - - OSLock *syncReceiptTimerLock; - OSLock *syncIntervalTimerLock; - OSLock *announceIntervalTimerLock; - -protected: - static const int64_t INVALID_LINKDELAY = 3600000000000; - static const int64_t ONE_WAY_DELAY_DEFAULT = INVALID_LINKDELAY; - - OSThreadFactory const * const thread_factory; - OSTimerFactory const * const timer_factory; - OSLockFactory const * const lock_factory; - OSConditionFactory const * const condition_factory; - CommonTimestamper * const _hw_timestamper; - IEEE1588Clock * const clock; - const bool isGM; - - phy_delay_map_t const * const phy_delay; - -public: - static const int64_t NEIGHBOR_PROP_DELAY_THRESH = 800; - static const unsigned int DEFAULT_SYNC_RECEIPT_THRESH = 5; - - CommonPort( PortInit_t *portInit ); - virtual ~CommonPort(); - - /** - * @brief Global media dependent port initialization - * @return true on success - */ - bool init_port( void ); - - /** - * @brief Media specific port initialization - * @return true on success - */ - virtual bool _init_port( void ) = 0; - - /** - * @brief Initializes the hwtimestamper - */ - void timestamper_init( void ); - - /** - * @brief Resets the hwtimestamper - */ - void timestamper_reset( void ); - - /** - * @brief Gets the link delay information. - * @return one way delay if delay > 0, or zero otherwise. - */ - uint64_t getLinkDelay( void ) - { - return one_way_delay > 0LL ? one_way_delay : 0LL; - } - - /** - * @brief Gets the link delay information. - * @param [in] delay Pointer to the delay information - * @return True if valid, false if invalid - */ - bool getLinkDelay( uint64_t *delay ) - { - if(delay == NULL) { - return false; - } - *delay = getLinkDelay(); - return *delay < INVALID_LINKDELAY; - } - - /** - * @brief Sets link delay information. - * Signed value allows this to be negative result because - * of inaccurate timestamps. - * @param delay Link delay - * @return True if one_way_delay is lower or equal than neighbor - * propagation delay threshold False otherwise - */ - bool setLinkDelay( int64_t delay ) - { - one_way_delay = delay; - int64_t abs_delay = (one_way_delay < 0 ? - -one_way_delay : one_way_delay); - - if (testMode) { - GPTP_LOG_STATUS("Link delay: %d", delay); - } - - return (abs_delay <= neighbor_prop_delay_thresh); - } - - /** - * @brief Return frequency offset between local timestamp clock - * system clock - * @return local:system ratio - */ - FrequencyRatio getLocalSystemFreqOffset(); - - /** - * @brief Gets a pointer to IEEE1588Clock - * @return Pointer to clock - */ - IEEE1588Clock *getClock( void ) - { - return clock; - } - - /** - * @brief Gets the local_addr - * @return LinkLayerAddress - */ - LinkLayerAddress *getLocalAddr( void ) - { - return &local_addr; - } - - /** - * @brief Gets the testMode - * @return bool of the test mode value - */ - bool getTestMode( void ) - { - return testMode; - } - - /** - * @brief Sets the testMode - * @param testMode changes testMode to this value - */ - void setTestMode( bool testMode ) - { - this->testMode = testMode; - } - - /** - * @brief Serializes (i.e. copy over buf pointer) the information from - * the variables (in that order): - * - asCapable; - * - Port Sate; - * - Link Delay; - * - Neighbor Rate Ratio - * @param buf [out] Buffer where to put the results. - * @param count [inout] Length of buffer. It contains maximum length - * to be written - * when the function is called, and the value is decremented by the - * same amount the - * buf size increases. - * @return TRUE if it has successfully written to buf all the values - * or if buf is NULL. - * FALSE if count should be updated with the right size. - */ - bool serializeState( void *buf, long *count ); - - /** - * @brief Restores the serialized state from the buffer. Copies the - * information from buffer - * to the variables (in that order): - * - asCapable; - * - Port State; - * - Link Delay; - * - Neighbor Rate Ratio - * @param buf Buffer containing the serialized state. - * @param count Buffer lenght. It is decremented by the same size of - * the variables that are - * being copied. - * @return TRUE if everything was copied successfully, FALSE otherwise. - */ - bool restoreSerializedState( void *buf, long *count ); - - /** - * @brief Sets the internal variabl sync_receipt_thresh, which is the - * flag that monitors the amount of wrong syncs enabled before - * switching - * the ptp to master. - * @param th Threshold to be set - * @return void - */ - void setSyncReceiptThresh(unsigned int th) - { - sync_receipt_thresh = th; - } - - /** - * @brief Gets the internal variabl sync_receipt_thresh, which is the - * flag that monitors the amount of wrong syncs enabled before - * switching - * the ptp to master. - * @return sync_receipt_thresh value - */ - unsigned int getSyncReceiptThresh( void ) - { - return sync_receipt_thresh; - } - - /** - * @brief Sets the wrongSeqIDCounter variable - * @param cnt Value to be set - * @return void - */ - void setWrongSeqIDCounter(unsigned int cnt) - { - wrongSeqIDCounter = cnt; - } - - /** - * @brief Gets the wrongSeqIDCounter value - * @param [out] cnt Pointer to the counter value. It must be valid - * @return TRUE if ok and lower than the syncReceiptThreshold value. - * FALSE otherwise - */ - bool getWrongSeqIDCounter(unsigned int *cnt) - { - if( cnt == NULL ) - { - return false; - } - *cnt = wrongSeqIDCounter; - - return( *cnt < getSyncReceiptThresh() ); - } - - /** - * @brief Increments the wrongSeqIDCounter value - * @param [out] cnt Pointer to the counter value. Must be valid - * @return TRUE if incremented value is lower than the - * syncReceiptThreshold. FALSE otherwise. - */ - bool incWrongSeqIDCounter(unsigned int *cnt) - { - if( getAsCapable() ) - { - wrongSeqIDCounter++; - } - bool ret = wrongSeqIDCounter < getSyncReceiptThresh(); - - if( cnt != NULL) - { - *cnt = wrongSeqIDCounter; - } - - return ret; - } - - /** - * @brief Gets the hardware timestamper version - * @return HW timestamper version - */ - int getTimestampVersion(); - - /** - * @brief Adjusts the clock frequency. - * @param freq_offset Frequency offset - * @return TRUE if adjusted. FALSE otherwise. - */ - bool _adjustClockRate( FrequencyRatio freq_offset ); - - /** - * @brief Adjusts the clock frequency. - * @param freq_offset Frequency offset - * @return TRUE if adjusted. FALSE otherwise. - */ - bool adjustClockRate( FrequencyRatio freq_offset ) { - return _adjustClockRate( freq_offset ); - } - - /** - * @brief Adjusts the clock phase. - * @param phase_adjust phase offset in ns - * @return TRUE if adjusted. FALSE otherwise. - */ - bool adjustClockPhase( int64_t phase_adjust ); - - /** - * @brief Gets extended error message from hardware timestamper - * @param msg [out] Extended error message - * @return void - */ - void getExtendedError(char *msg); - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatRxSyncCount - * @return void - */ - void incCounter_ieee8021AsPortStatRxSyncCount( void ) - { - counters.ieee8021AsPortStatRxSyncCount++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatRxFollowUpCount - * @return void - */ - void incCounter_ieee8021AsPortStatRxFollowUpCount( void ) - { - counters.ieee8021AsPortStatRxFollowUpCount++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatRxPdelayRequest - * @return void - */ - void incCounter_ieee8021AsPortStatRxPdelayRequest( void ) - { - counters.ieee8021AsPortStatRxPdelayRequest++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatRxPdelayResponse - * @return void - */ - void incCounter_ieee8021AsPortStatRxPdelayResponse( void ) - { - counters.ieee8021AsPortStatRxPdelayResponse++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatRxPdelayResponseFollowUp - * @return void - */ - void incCounter_ieee8021AsPortStatRxPdelayResponseFollowUp( void ) - { - counters.ieee8021AsPortStatRxPdelayResponseFollowUp++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatRxAnnounce - * @return void - */ - void incCounter_ieee8021AsPortStatRxAnnounce( void ) - { - counters.ieee8021AsPortStatRxAnnounce++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatRxPTPPacketDiscard - * @return void - */ - void incCounter_ieee8021AsPortStatRxPTPPacketDiscard( void ) - { - counters.ieee8021AsPortStatRxPTPPacketDiscard++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatRxSyncReceiptTimeouts - * @return void - */ - void incCounter_ieee8021AsPortStatRxSyncReceiptTimeouts( void ) - { - counters.ieee8021AsPortStatRxSyncReceiptTimeouts++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatAnnounceReceiptTimeouts - * @return void - */ - void incCounter_ieee8021AsPortStatAnnounceReceiptTimeouts( void ) - { - counters.ieee8021AsPortStatAnnounceReceiptTimeouts++; - } - - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatPdelayAllowedLostResponsesExceeded - * @return void - */ - // TODO: Not called - void incCounter_ieee8021AsPortStatPdelayAllowedLostResponsesExceeded - ( void ) - { - counters. - ieee8021AsPortStatPdelayAllowedLostResponsesExceeded++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatTxSyncCount - * @return void - */ - void incCounter_ieee8021AsPortStatTxSyncCount( void ) - { - counters.ieee8021AsPortStatTxSyncCount++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatTxFollowUpCount - * @return void - */ - void incCounter_ieee8021AsPortStatTxFollowUpCount( void ) - { - counters.ieee8021AsPortStatTxFollowUpCount++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatTxPdelayRequest - * @return void - */ - void incCounter_ieee8021AsPortStatTxPdelayRequest( void ) - { - counters.ieee8021AsPortStatTxPdelayRequest++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatTxPdelayResponse - * @return void - */ - void incCounter_ieee8021AsPortStatTxPdelayResponse( void ) - { - counters.ieee8021AsPortStatTxPdelayResponse++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatTxPdelayResponseFollowUp - * @return void - */ - void incCounter_ieee8021AsPortStatTxPdelayResponseFollowUp( void ) - { - counters.ieee8021AsPortStatTxPdelayResponseFollowUp++; - } - - /** - * @brief Increment IEEE Port counter: - * ieee8021AsPortStatTxAnnounce - * @return void - */ - void incCounter_ieee8021AsPortStatTxAnnounce( void ) - { - counters.ieee8021AsPortStatTxAnnounce++; - } - - /** - * @brief Logs port counters - * @return void - */ - void logIEEEPortCounters( void ) - { - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatRxSyncCount : %u", - counters.ieee8021AsPortStatRxSyncCount ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatRxFollowUpCount : %u", - counters.ieee8021AsPortStatRxFollowUpCount ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatRxPdelayRequest : %u", - counters.ieee8021AsPortStatRxPdelayRequest ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatRxPdelayResponse : %u", - counters.ieee8021AsPortStatRxPdelayResponse ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatRxPdelayResponseFollowUp " - ": %u", counters. - ieee8021AsPortStatRxPdelayResponseFollowUp ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatRxAnnounce : %u", - counters.ieee8021AsPortStatRxAnnounce ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatRxPTPPacketDiscard : %u", - counters. - ieee8021AsPortStatRxPTPPacketDiscard ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatRxSyncReceiptTimeouts " - ": %u", counters. - ieee8021AsPortStatRxSyncReceiptTimeouts ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatAnnounceReceiptTimeouts " - ": %u", counters. - ieee8021AsPortStatAnnounceReceiptTimeouts ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatPdelayAllowed" - "LostResponsesExceeded : %u", counters. - ieee8021AsPortStatPdelayAllowedLostResponsesExceeded - ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatTxSyncCount : %u", - counters.ieee8021AsPortStatTxSyncCount ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatTxFollowUpCount : %u", counters. - ieee8021AsPortStatTxFollowUpCount); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatTxPdelayRequest : %u", - counters.ieee8021AsPortStatTxPdelayRequest); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatTxPdelayResponse : %u", counters. - ieee8021AsPortStatTxPdelayResponse); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatTxPdelayResponseFollowUp : %u", - counters.ieee8021AsPortStatTxPdelayResponseFollowUp - ); - GPTP_LOG_STATUS - ( "IEEE Port Counter " - "ieee8021AsPortStatTxAnnounce : %u", - counters.ieee8021AsPortStatTxAnnounce); - } - - /** - * @brief Get the cross timestamping information. - * The gPTP subsystem uses these samples to calculate - * ratios which can be used to translate or extrapolate - * one clock into another clock reference. The gPTP service - * uses these supplied cross timestamps to perform internal - * rate estimation and conversion functions. - * @param system_time [out] System time - * @param device_time [out] Device time - * @param local_clock [out] Local clock - * @param nominal_clock_rate [out] Nominal clock rate - * @return True in case of success. FALSE in case of error - */ - void getDeviceTime - ( Timestamp &system_time, Timestamp &device_time, - uint32_t &local_clock, uint32_t & nominal_clock_rate ); - - /** - * @brief Sets asCapable flag - * @param ascap flag to be set. If FALSE, marks peer_offset_init as - * false. - * @return void - */ - void setAsCapable(bool ascap) - { - if ( ascap != asCapable ) { - GPTP_LOG_STATUS - ("AsCapable: %s", ascap == true - ? "Enabled" : "Disabled"); - } - if( !ascap ) - { - _peer_offset_init = false; - } - asCapable = ascap; - } - - /** - * @brief Gets the asCapable flag - * @return asCapable flag. - */ - bool getAsCapable() - { - return( asCapable ); - } - - /** - * @brief Gets the Peer rate offset. Used to calculate neighbor - * rate ratio. - * @return FrequencyRatio peer rate offset - */ - FrequencyRatio getPeerRateOffset( void ) - { - return _peer_rate_offset; - } - - /** - * @brief Sets the peer rate offset. Used to calculate neighbor rate - * ratio. - * @param offset Offset to be set - * @return void - */ - void setPeerRateOffset( FrequencyRatio offset ) { - _peer_rate_offset = offset; - } - - /** - * @brief Sets peer offset timestamps - * @param mine Local timestamps - * @param theirs Remote timestamps - * @return void - */ - void setPeerOffset(Timestamp mine, Timestamp theirs) { - _peer_offset_ts_mine = mine; - _peer_offset_ts_theirs = theirs; - _peer_offset_init = true; - } - - /** - * @brief Gets peer offset timestamps - * @param mine [out] Reference to local timestamps - * @param theirs [out] Reference to remote timestamps - * @return TRUE if peer offset has already been initialized. FALSE - * otherwise. - */ - bool getPeerOffset(Timestamp & mine, Timestamp & theirs) { - mine = _peer_offset_ts_mine; - theirs = _peer_offset_ts_theirs; - return _peer_offset_init; - } - - /** - * @brief Sets the neighbor propagation delay threshold - * @param delay Delay in nanoseconds - * @return void - */ - void setNeighPropDelayThresh(int64_t delay) { - neighbor_prop_delay_thresh = delay; - } - - /** - * @brief Restart PDelay - * @return void - */ - void restartPDelay() { - _peer_offset_init = false; - } - - /** - * @brief Gets a pointer to timer_factory object - * @return timer_factory pointer - */ - const OSTimerFactory *getTimerFactory() { - return timer_factory; - } - - /** - * @brief Watch for link up and down events. - * @return Its an infinite loop. Returns NULL in case of error. - */ - void *watchNetLink( void ) - { - // Should never return - net_iface->watchNetLink(this); - - return NULL; - } - - /** - * @brief Receive frame - */ - net_result recv - ( LinkLayerAddress *addr, uint8_t *payload, size_t &length, - uint32_t &link_speed ) - { - net_result result = net_iface->nrecv( addr, payload, length ); - link_speed = this->link_speed; - return result; - } - - /** - * @brief Send frame - */ - net_result send - ( LinkLayerAddress *addr, uint16_t etherType, uint8_t *payload, - size_t length, bool timestamp ) - { - return net_iface->send - ( addr, etherType, payload, length, timestamp ); - } - - /** - * @brief Get the payload offset inside a packet - * @return 0 - */ - unsigned getPayloadOffset() - { - return net_iface->getPayloadOffset(); - } - - bool linkWatch( OSThreadFunction func, OSThreadFunctionArg arg ) - { - return link_thread->start( func, arg ); - } - - bool linkOpen( OSThreadFunction func, OSThreadFunctionArg arg ) - { - return listening_thread->start( func, arg ); - } - - /** - * @brief Gets the portState information - * @return PortState - */ - PortState getPortState( void ) { - return port_state; - } - - /** - * @brief Sets the PortState - * @param state value to be set - * @return void - */ - void setPortState( PortState state ) { - port_state = state; - } - - /** - * @brief Gets port identity - * @param identity [out] Reference to PortIdentity - * @return void - */ - void getPortIdentity(PortIdentity & identity) { - identity = this->port_identity; - } - - /** - * @brief Gets the "best" announce - * @return Pointer to PTPMessageAnnounce - */ - PTPMessageAnnounce *calculateERBest( void ); - - /** - * @brief Changes the port state - * @param state Current state - * @param changed_external_master TRUE if external master has - * changed, FALSE otherwise - * @return void - */ - void recommendState(PortState state, bool changed_external_master); - - /** - * @brief Locks the TX port - * @return TRUE if success. FALSE otherwise. - */ - virtual bool getTxLock() - { - return true; - } - - /** - * @brief Unlocks the port TX. - * @return TRUE if success. FALSE otherwise. - */ - virtual bool putTxLock() - { - return false; - } - - /** - * @brief Adds a new qualified announce the port. IEEE 802.1AS - * Clause 10.3.10.2 - * @param annc PTP announce message - * @return void - */ - void setQualifiedAnnounce( PTPMessageAnnounce *annc ) - { - delete qualified_announce; - qualified_announce = annc; - } - - /** - * @brief Switches port to a gPTP master - * @param annc If TRUE, starts announce event timer. - * @return void - */ - virtual void becomeMaster( bool annc ) = 0; - - /** - * @brief Switches port to a gPTP slave. - * @param restart_syntonization if TRUE, restarts the syntonization - * @return void - */ - virtual void becomeSlave( bool restart_syntonization ) = 0; - - /** - * @brief Gets the AVnu automotive profile flag - * @return automotive_profile flag - */ - bool getAutomotiveProfile() { return(automotive_profile); } - - /** - * @brief Sets the pDelay minimum interval - * @param val time interval - * @return none - */ - void setPDelayInterval(signed char val) { - log_min_mean_pdelay_req_interval = val; - } - - /** - * @brief Gets the pDelay minimum interval - * @return PDelay interval - */ - signed char getPDelayInterval(void) { - return log_min_mean_pdelay_req_interval; - } - - /** - * @brief Sets the pDelay minimum interval back to initial - * value - * @return none - */ - void resetInitPDelayInterval(void) { - log_min_mean_pdelay_req_interval = initialLogPdelayReqInterval; - } - - /** - * @brief set initial pdelay interval - * @param interval [in] log base 2 pdelay rate - */ - void setInitPDelayInterval( int8_t interval ) - { - initialLogPdelayReqInterval = interval; - } - - /** - * @brief get initial pdelay interval - * @return log base 2 pdelay rate - */ - int8_t getInitPDelayInterval(void) - { - return initialLogPdelayReqInterval; - } - - /** - * @brief Start pDelay interval timer - * @param waitTime time interval - * @return none - */ - virtual void startPDelayIntervalTimer( unsigned long long waitTime ) {} - - /** - * @brief Sets current sync count value. - * @param cnt [in] sync count value - * @return void - */ - void setSyncCount(unsigned int cnt) - { - sync_count = cnt; - } - - /** - * @brief Increments sync count - * @return void - */ - void incSyncCount() { - ++sync_count; - } - - /** - * @brief Gets current sync count value. It is set to zero - * when master and incremented at each sync received for slave. - * @return sync count - */ - unsigned getSyncCount() - { - return sync_count; - } - - /** - * @brief Sets current pdelay count value. - * @param cnt [in] pdelay count value - * @return void - */ - void setPdelayCount(unsigned int cnt) { - pdelay_count = cnt; - } - - /** - * @brief Increments Pdelay count - * @return void - */ - void incPdelayCount() - { - ++pdelay_count; - } - - /** - * @brief Gets current pdelay count value. It is set to zero - * when asCapable is false. - * @return pdelay count - */ - unsigned getPdelayCount() - { - return pdelay_count; - } - - /** - * @brief Increments announce sequence id and returns - * @return Next announce sequence id. - */ - uint16_t getNextAnnounceSequenceId( void ) - { - return announce_sequence_id++; - } - - /** - * @brief Increments signal sequence id and returns - * @return Next signal sequence id. - */ - uint16_t getNextSignalSequenceId( void ) - { - return signal_sequence_id++; - } - - /** - * @brief Increments sync sequence ID and returns - * @return Next synce sequence id. - */ - uint16_t getNextSyncSequenceId( void ) - { - return sync_sequence_id++; - } - - /** - * @brief Gets the lastGmTimeBaseIndicator - * @return uint16 of the lastGmTimeBaseIndicator - */ - uint16_t getLastGmTimeBaseIndicator( void ) { - return lastGmTimeBaseIndicator; - } - - /** - * @brief Sets the lastGmTimeBaseIndicator - * @param gmTimeBaseIndicator from last Follow up message - * @return void - */ - void setLastGmTimeBaseIndicator(uint16_t gmTimeBaseIndicator) - { - lastGmTimeBaseIndicator = gmTimeBaseIndicator; - } - - /** - * @brief Gets the sync interval value - * @return Sync Interval - */ - signed char getSyncInterval( void ) - { - return log_mean_sync_interval; - } - - /** - * @brief Sets the sync interval value - * @param val time interval - * @return none - */ - void setSyncInterval( signed char val ) - { - log_mean_sync_interval = val; - } - - /** - * @brief Sets the sync interval back to initial value - * @return none - */ - void resetInitSyncInterval( void ) - { - log_mean_sync_interval = initialLogSyncInterval;; - } - - /** - * @brief Sets the sync interval - * @return none - */ - void setInitSyncInterval( signed char interval ) - { - initialLogSyncInterval = interval; - } - - /** - * @brief Gets the sync interval - * @return sync interval - */ - signed char getInitSyncInterval( void ) - { - return initialLogSyncInterval; - } - - /** - * @brief Gets the announce interval - * @return Announce interval - */ - signed char getAnnounceInterval( void ) { - return log_mean_announce_interval; - } - - /** - * @brief Sets the announce interval - * @param val time interval - * @return none - */ - void setAnnounceInterval(signed char val) { - log_mean_announce_interval = val; - } - /** - * @brief Start sync receipt timer - * @param waitTime time interval - * @return none - */ - void startSyncReceiptTimer(long long unsigned int waitTime); - - /** - * @brief Stop sync receipt timer - * @return none - */ - void stopSyncReceiptTimer( void ); - - /** - * @brief Start sync interval timer - * @param waitTime time interval in nanoseconds - * @return none - */ - void startSyncIntervalTimer(long long unsigned int waitTime); - - /** - * @brief Start announce interval timer - * @param waitTime time interval - * @return none - */ - void startAnnounceIntervalTimer(long long unsigned int waitTime); - - /** - * @brief Starts announce event timer - * @return void - */ - void startAnnounce(); - - /** - * @brief Process default state change event - * @return true if event is handled without errors - */ - bool processStateChange( Event e ); - - /** - * @brief Default sync/announce timeout handler - * @return true if event is handled without errors - */ - bool processSyncAnnounceTimeout( Event e ); - - - /** - * @brief Perform default event action, can be overridden by media - * specific actions in _processEvent - * @return true if event is handled without errors - */ - bool processEvent( Event e ); - - /** - * @brief Perform media specific event handling action - * @return true if event is handled without errors - */ - virtual bool _processEvent( Event e ) = 0; - - /** - * @brief Performs media specific setup after start sync is completed - * @return void - */ - virtual void syncDone() = 0; - - /** - * @brief Sends a general message to a port. No timestamps - * @param buf [in] Pointer to the data buffer - * @param len Size of the message - * @param mcast_type Enumeration - * MulticastType (pdelay, none or other). Depracated. - * @param destIdentity Destination port identity - * @return void - */ - virtual void sendGeneralPort - (uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type, - PortIdentity * destIdentity) = 0; - - /** - * @brief Sets link speed - */ - void setLinkSpeed( uint32_t link_speed ) - { - this->link_speed = link_speed; - } - - /** - * @brief Returns link speed - */ - uint32_t getLinkSpeed( void ) - { - return link_speed; - } - - /** - * @brief Returns TX PHY delay - */ - Timestamp getTxPhyDelay( uint32_t link_speed ) const; - - /** - * @brief Returns RX PHY delay - */ - Timestamp getRxPhyDelay( uint32_t link_speed ) const; -}; - -/** - * @brief Specifies a RX/TX PHY compensation pair - */ -class phy_delay_spec_t -{ -private: - uint16_t tx_delay; - uint16_t rx_delay; -public: - /** - * Constructor setting PHY compensation - */ - phy_delay_spec_t( - uint16_t tx_delay, - uint16_t rx_delay ) - { - this->tx_delay = tx_delay; - this->rx_delay = rx_delay; - } - - /** - * Default constructor sets 0 PHY compensation - */ - phy_delay_spec_t() - { - phy_delay_spec_t( 0, 0 ); - } - - /** - * @brief sets PHY compensation - */ - void set_delay( - uint16_t tx_delay, - uint16_t rx_delay ) - { - this->tx_delay = tx_delay; - this->rx_delay = rx_delay; - } - - /** - * @brief sets RX PHY compensation - */ - void set_tx_delay( - uint16_t tx_delay ) - { - this->tx_delay = tx_delay; - } - - /** - * @brief sets TX PHY compensation - */ - void set_rx_delay( - uint16_t rx_delay ) - { - this->rx_delay = rx_delay; - } - - /** - * @brief gets TX PHY compensation - */ - uint16_t get_tx_delay() const - { - return tx_delay; - } - - /** - * @brief gets RX PHY compensation - */ - uint16_t get_rx_delay() const - { - return rx_delay; - } -}; - -#endif/*COMMON_PORT_HPP*/ diff --git a/daemons/gptp/common/common_tstamper.hpp b/daemons/gptp/common/common_tstamper.hpp deleted file mode 100644 index 557ac184..00000000 --- a/daemons/gptp/common/common_tstamper.hpp +++ /dev/null @@ -1,162 +0,0 @@ -/****************************************************************************** - - 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 COMMON_TSTAMPER_HPP -#define COMMON_TSTAMPER_HPP - -#include <unordered_map> -#include <stdint.h> -#include <avbts_message.hpp> - -#define HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE 4096 /*!< Maximum size of HWTimestamper extended message */ - -/** - * @brief Provides a generic interface for hardware timestamping - */ -class CommonTimestamper { -protected: - uint8_t version; //!< HWTimestamper version - -public: - /** - * @brief Initializes the hardware timestamp unit - * @param iface_label [in] Interface label - * @param iface [in] Network interface - * @return true - */ - virtual bool HWTimestamper_init - ( InterfaceLabel *iface_label, OSNetworkInterface *iface ) - { return true; } - - /** - * @brief Reset the hardware timestamp unit - * @return void - */ - virtual void HWTimestamper_reset(void) { - } - - /** - * @brief This method is called before the object is de-allocated. - * @return void - */ - virtual void HWTimestamper_final(void) { - } - - /** - * @brief Sets system clock descriptor - * @param system_clock_desc name of local clock - * @return false if unimplemented - */ - virtual bool HWTimestamper_setsystemclock - ( const char *system_clock_desc ) - { return false; } - - /** - * @brief Adjusts the hardware clock frequency - * @param frequency_offset Frequency offset - * @return false - */ - virtual bool HWTimestamper_adjclockrate - ( float frequency_offset ) const - { return false; } - - /** - * @brief Adjusts the hardware clock phase - * @param phase_adjust Phase offset - * @return false - */ - virtual bool HWTimestamper_adjclockphase( int64_t phase_adjust ) - { return false; } - - /** - * @brief Get the cross timestamping information. - * The gPTP subsystem uses these samples to calculate - * ratios which can be used to translate or extrapolate - * one clock into another clock reference. The gPTP service - * uses these supplied cross timestamps to perform internal - * rate estimation and conversion functions. - * @param system_time [out] System time - * @param device_time [out] Device time - * @param local_clock [out] Local clock - * @param nominal_clock_rate [out] Nominal clock rate - * @return True in case of success. FALSE in case of error - */ - virtual bool HWTimestamper_gettime(Timestamp * system_time, - Timestamp * device_time, - uint32_t * local_clock, - uint32_t * nominal_clock_rate) const = 0; - - /** - * @brief Gets a string with the error from the hardware timestamp block - * @param msg [out] String error - * @return void - * @todo There is no current implementation for this method. - */ - virtual void HWTimestamper_get_extderror(char *msg) const - { - *msg = '\0'; - } - - /** - * @brief Starts the PPS (pulse per second) interface - * @return false - */ - virtual bool HWTimestamper_PPS_start() { return false; }; - - /** - * @brief Stops the PPS (pulse per second) interface - * @return true - */ - virtual bool HWTimestamper_PPS_stop() { return true; }; - - /** - * @brief Gets the HWTimestamper version - * @return version (signed integer) - */ - int getVersion() const - { - return version; - } - - /** - * @brief Default constructor. Sets version to zero. - */ - CommonTimestamper() { version = 0; } - - /** - * @brief Deletes HWtimestamper object - */ - virtual ~CommonTimestamper() { } -}; - -#endif/*COMMON_TSTAMPER_HPP*/ diff --git a/daemons/gptp/common/ether_port.cpp b/daemons/gptp/common/ether_port.cpp deleted file mode 100644 index 56db3d22..00000000 --- a/daemons/gptp/common/ether_port.cpp +++ /dev/null @@ -1,881 +0,0 @@ -/****************************************************************************** - - 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 <ether_port.hpp> -#include <avbts_message.hpp> -#include <avbts_clock.hpp> - -#include <avbts_oslock.hpp> -#include <avbts_osnet.hpp> -#include <avbts_oscondition.hpp> -#include <ether_tstamper.hpp> - -#include <gptp_log.hpp> - -#include <stdio.h> - -#include <math.h> - -#include <stdlib.h> - -LinkLayerAddress EtherPort::other_multicast(OTHER_MULTICAST); -LinkLayerAddress EtherPort::pdelay_multicast(PDELAY_MULTICAST); -LinkLayerAddress EtherPort::test_status_multicast -( TEST_STATUS_MULTICAST ); - -OSThreadExitCode watchNetLinkWrapper(void *arg) -{ - EtherPort *port; - - port = (EtherPort *) arg; - if (port->watchNetLink() == NULL) - return osthread_ok; - else - return osthread_error; -} - -OSThreadExitCode openPortWrapper(void *arg) -{ - EtherPort *port; - - port = (EtherPort *) arg; - if (port->openPort(port) == NULL) - return osthread_ok; - else - return osthread_error; -} - -EtherPort::~EtherPort() -{ - delete port_ready_condition; -} - -EtherPort::EtherPort( PortInit_t *portInit ) : - CommonPort( portInit ) -{ - linkUp = portInit->linkUp; - setTestMode( portInit->testMode ); - - pdelay_sequence_id = 0; - - pdelay_started = false; - pdelay_halted = false; - sync_rate_interval_timer_started = false; - - duplicate_resp_counter = 0; - last_invalid_seqid = 0; - - operLogPdelayReqInterval = portInit->operLogPdelayReqInterval; - operLogSyncInterval = portInit->operLogSyncInterval; - - if (getAutomotiveProfile()) - { - setAsCapable( true ); - - if (getInitSyncInterval() == LOG2_INTERVAL_INVALID) - setInitSyncInterval( -5 ); // 31.25 ms - if (getInitPDelayInterval() == LOG2_INTERVAL_INVALID) - setInitPDelayInterval( 0 ); // 1 second - if (operLogPdelayReqInterval == LOG2_INTERVAL_INVALID) - operLogPdelayReqInterval = 0; // 1 second - if (operLogSyncInterval == LOG2_INTERVAL_INVALID) - operLogSyncInterval = 0; // 1 second - } else - { - setAsCapable( false ); - - if ( getInitSyncInterval() == LOG2_INTERVAL_INVALID ) - setInitSyncInterval( -3 ); // 125 ms - if (getInitPDelayInterval() == LOG2_INTERVAL_INVALID) - setInitPDelayInterval( 0 ); // 1 second - if (operLogPdelayReqInterval == LOG2_INTERVAL_INVALID) - operLogPdelayReqInterval = 0; // 1 second - if (operLogSyncInterval == LOG2_INTERVAL_INVALID) - operLogSyncInterval = 0; // 1 second - } - - /*TODO: Add intervals below to a config interface*/ - resetInitPDelayInterval(); - - last_sync = NULL; - last_pdelay_req = NULL; - last_pdelay_resp = NULL; - last_pdelay_resp_fwup = NULL; - - setPdelayCount(0); - setSyncCount(0); - - if( getAutomotiveProfile( )) - { - if (isGM) { - avbSyncState = 1; - } - else { - avbSyncState = 2; - } - if (getTestMode()) - { - linkUpCount = 1; // TODO : really should check the current linkup status http://stackoverflow.com/questions/15723061/how-to-check-if-interface-is-up - linkDownCount = 0; - } - setStationState(STATION_STATE_RESERVED); - } -} - -bool EtherPort::_init_port( void ) -{ - pdelay_rx_lock = lock_factory->createLock(oslock_recursive); - port_tx_lock = lock_factory->createLock(oslock_recursive); - - pDelayIntervalTimerLock = lock_factory->createLock(oslock_recursive); - - port_ready_condition = condition_factory->createCondition(); - - return true; -} - -void EtherPort::startPDelay() -{ - if(!pdelayHalted()) { - if( getAutomotiveProfile( )) - { - if( getPDelayInterval() != - PTPMessageSignalling::sigMsgInterval_NoSend) - { - pdelay_started = true; - startPDelayIntervalTimer(EVENT_TIMER_GRANULARITY); - } - } - else { - pdelay_started = true; - startPDelayIntervalTimer(32000000); - } - } -} - -void EtherPort::stopPDelay() -{ - haltPdelay(true); - pdelay_started = false; - clock->deleteEventTimerLocked( this, PDELAY_INTERVAL_TIMEOUT_EXPIRES); -} - -void EtherPort::startSyncRateIntervalTimer() -{ - if( getAutomotiveProfile( )) - { - sync_rate_interval_timer_started = true; - if (isGM) { - // GM will wait up to 8 seconds for signaling rate - // TODO: This isn't according to spec but set because it is believed that some slave devices aren't signalling - // to reduce the rate - clock->addEventTimerLocked( this, SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED, 8000000000 ); - } - else { - // Slave will time out after 4 seconds - clock->addEventTimerLocked( this, SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED, 4000000000 ); - } - } -} - -void EtherPort::processMessage -( char *buf, int length, LinkLayerAddress *remote, uint32_t link_speed ) -{ - GPTP_LOG_VERBOSE("Processing network buffer"); - - PTPMessageCommon *msg = - buildPTPMessage( buf, (int)length, remote, this ); - - if (msg == NULL) - { - GPTP_LOG_ERROR("Discarding invalid message"); - return; - } - GPTP_LOG_VERBOSE("Processing message"); - - if( msg->isEvent() ) - { - Timestamp rx_timestamp = msg->getTimestamp(); - Timestamp phy_compensation = getRxPhyDelay( link_speed ); - GPTP_LOG_DEBUG( "RX PHY compensation: %s sec", - phy_compensation.toString().c_str() ); - phy_compensation._version = rx_timestamp._version; - rx_timestamp = rx_timestamp - phy_compensation; - msg->setTimestamp( rx_timestamp ); - } - - msg->processMessage(this); - if (msg->garbage()) - delete msg; -} - -void *EtherPort::openPort( EtherPort *port ) -{ - port_ready_condition->signal(); - - while (1) { - uint8_t buf[128]; - LinkLayerAddress remote; - net_result rrecv; - size_t length = sizeof(buf); - uint32_t link_speed; - - if ( ( rrecv = recv( &remote, buf, length, link_speed )) - == net_succeed ) - { - processMessage - ((char *)buf, (int)length, &remote, link_speed ); - } else if (rrecv == net_fatal) { - GPTP_LOG_ERROR("read from network interface failed"); - this->processEvent(FAULT_DETECTED); - break; - } - } - - return NULL; -} - -net_result EtherPort::port_send -( uint16_t etherType, 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 if (mcast_type == MCAST_TEST_STATUS) { - dest = test_status_multicast; - } - else { - dest = other_multicast; - } - } else { - mapSocketAddr(destIdentity, &dest); - } - - return send(&dest, etherType, (uint8_t *) buf, size, timestamp); -} - -void EtherPort::sendEventPort -( uint16_t etherType, uint8_t *buf, int size, MulticastType mcast_type, - PortIdentity *destIdentity, uint32_t *link_speed ) -{ - net_result rtx = port_send - ( etherType, buf, size, mcast_type, destIdentity, true ); - if( rtx != net_succeed ) - { - GPTP_LOG_ERROR("sendEventPort(): failure"); - return; - } - - *link_speed = this->getLinkSpeed(); - - return; -} - -void EtherPort::sendGeneralPort -( uint16_t etherType, uint8_t *buf, int size, MulticastType mcast_type, - PortIdentity * destIdentity ) -{ - net_result rtx = port_send(etherType, buf, size, mcast_type, destIdentity, false); - if (rtx != net_succeed) { - GPTP_LOG_ERROR("sendGeneralPort(): failure"); - } - - return; -} - -bool EtherPort::_processEvent( Event e ) -{ - bool ret; - - switch (e) { - case POWERUP: - case INITIALIZE: - if( !getAutomotiveProfile( )) - { - if ( getPortState() != PTP_SLAVE && - getPortState() != PTP_MASTER ) - { - GPTP_LOG_STATUS("Starting PDelay"); - startPDelay(); - } - } - else { - startPDelay(); - } - - port_ready_condition->wait_prelock(); - - if( !linkWatch(watchNetLinkWrapper, (void *)this) ) - { - GPTP_LOG_ERROR("Error creating port link thread"); - ret = false; - break; - } - - if( !linkOpen(openPortWrapper, (void *)this) ) - { - GPTP_LOG_ERROR("Error creating port thread"); - ret = false; - break; - } - - port_ready_condition->wait(); - - if( getAutomotiveProfile( )) - { - setStationState(STATION_STATE_ETHERNET_READY); - if (getTestMode()) - { - APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this); - if (testStatusMsg) { - testStatusMsg->sendPort(this); - delete testStatusMsg; - } - } - if (!isGM) { - // Send an initial signalling message - PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this); - if (sigMsg) { - sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoSend); - sigMsg->sendPort(this, NULL); - delete sigMsg; - } - - startSyncReceiptTimer((unsigned long long) - (SYNC_RECEIPT_TIMEOUT_MULTIPLIER * - ((double) pow((double)2, getSyncInterval()) * - 1000000000.0))); - } - } - - ret = true; - break; - case STATE_CHANGE_EVENT: - // If the automotive profile is enabled, handle the event by - // doing nothing and returning true, preventing the default - // action from executing - if( getAutomotiveProfile( )) - ret = true; - else - ret = false; - - break; - case LINKUP: - haltPdelay(false); - startPDelay(); - if( getAutomotiveProfile( )) - { - GPTP_LOG_EXCEPTION("LINKUP"); - } - else { - GPTP_LOG_STATUS("LINKUP"); - } - - if( clock->getPriority1() == 255 || getPortState() == PTP_SLAVE ) { - becomeSlave( true ); - } else if( getPortState() == PTP_MASTER ) { - becomeMaster( true ); - } else { - clock->addEventTimerLocked - ( this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES, - (uint64_t) - ( ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER * - pow( 2.0, getAnnounceInterval( )) * - 1000000000.0 )); - } - - if( getAutomotiveProfile( )) - { - setAsCapable( true ); - - setStationState(STATION_STATE_ETHERNET_READY); - if (getTestMode()) - { - APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this); - if (testStatusMsg) { - testStatusMsg->sendPort(this); - delete testStatusMsg; - } - } - - resetInitSyncInterval(); - setAnnounceInterval( 0 ); - resetInitPDelayInterval(); - - if (!isGM) { - // Send an initial signaling message - PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this); - if (sigMsg) { - sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoSend, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoSend); - sigMsg->sendPort(this, NULL); - delete sigMsg; - } - - startSyncReceiptTimer((unsigned long long) - (SYNC_RECEIPT_TIMEOUT_MULTIPLIER * - ((double) pow((double)2, getSyncInterval()) * - 1000000000.0))); - } - - // Reset Sync count and pdelay count - setPdelayCount(0); - setSyncCount(0); - - // Start AVB SYNC at 2. It will decrement after each sync. When it reaches 0 the Test Status message - // can be sent - if (isGM) { - avbSyncState = 1; - } - else { - avbSyncState = 2; - } - - if (getTestMode()) - { - linkUpCount++; - } - } - this->timestamper_reset(); - - ret = true; - break; - case LINKDOWN: - stopPDelay(); - if( getAutomotiveProfile( )) - { - GPTP_LOG_EXCEPTION("LINK DOWN"); - } - else { - setAsCapable(false); - GPTP_LOG_STATUS("LINK DOWN"); - } - if (getTestMode()) - { - linkDownCount++; - } - - ret = true; - break; - case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES: - case SYNC_RECEIPT_TIMEOUT_EXPIRES: - if( !getAutomotiveProfile( )) - { - ret = false; - break; - } - - // Automotive Profile specific action - if (e == SYNC_RECEIPT_TIMEOUT_EXPIRES) { - GPTP_LOG_EXCEPTION("SYNC receipt timeout"); - - startSyncReceiptTimer((unsigned long long) - (SYNC_RECEIPT_TIMEOUT_MULTIPLIER * - ((double) pow((double)2, getSyncInterval()) * - 1000000000.0))); - } - ret = true; - break; - case PDELAY_INTERVAL_TIMEOUT_EXPIRES: - GPTP_LOG_DEBUG("PDELAY_INTERVAL_TIMEOUT_EXPIRES occured"); - { - Timestamp req_timestamp; - - 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); - - getTxLock(); - pdelay_req->sendPort(this, NULL); - GPTP_LOG_DEBUG("*** Sent PDelay Request message"); - putTxLock(); - - { - long long timeout; - long long interval; - - timeout = PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER * - ((long long) - (pow((double)2,getPDelayInterval())*1000000000.0)); - - timeout = timeout > EVENT_TIMER_GRANULARITY ? - timeout : EVENT_TIMER_GRANULARITY; - clock->addEventTimerLocked - (this, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, timeout ); - GPTP_LOG_DEBUG("Schedule PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, " - "PDelay interval %d, timeout %lld", - getPDelayInterval(), timeout); - - interval = - ((long long) - (pow((double)2,getPDelayInterval())*1000000000.0)); - interval = interval > EVENT_TIMER_GRANULARITY ? - interval : EVENT_TIMER_GRANULARITY; - startPDelayIntervalTimer(interval); - } - } - break; - case SYNC_INTERVAL_TIMEOUT_EXPIRES: - { - /* Set offset from master to zero, update device vs - system time offset */ - - // Send a sync message and then a followup to broadcast - PTPMessageSync *sync = new PTPMessageSync(this); - PortIdentity dest_id; - bool tx_succeed; - getPortIdentity(dest_id); - sync->setPortIdentity(&dest_id); - getTxLock(); - tx_succeed = sync->sendPort(this, NULL); - GPTP_LOG_DEBUG("Sent SYNC message"); - - if( getAutomotiveProfile() && - getPortState() == PTP_MASTER ) - { - if (avbSyncState > 0) { - avbSyncState--; - if (avbSyncState == 0) { - // Send Avnu Automotive Profile status message - setStationState(STATION_STATE_AVB_SYNC); - if (getTestMode()) { - APMessageTestStatus *testStatusMsg = new APMessageTestStatus(this); - if (testStatusMsg) { - testStatusMsg->sendPort(this); - delete testStatusMsg; - } - } - } - } - } - putTxLock(); - - if ( tx_succeed ) - { - Timestamp sync_timestamp = sync->getTimestamp(); - - GPTP_LOG_VERBOSE("Successful Sync timestamp"); - GPTP_LOG_VERBOSE("Seconds: %u", - sync_timestamp.seconds_ls); - GPTP_LOG_VERBOSE("Nanoseconds: %u", - sync_timestamp.nanoseconds); - - PTPMessageFollowUp *follow_up = new PTPMessageFollowUp(this); - PortIdentity dest_id; - getPortIdentity(dest_id); - - follow_up->setClockSourceTime(getClock()->getFUPInfo()); - follow_up->setPortIdentity(&dest_id); - follow_up->setSequenceId(sync->getSequenceId()); - follow_up->setPreciseOriginTimestamp - (sync_timestamp); - follow_up->sendPort(this, NULL); - delete follow_up; - } else { - GPTP_LOG_ERROR - ("*** Unsuccessful Sync timestamp"); - } - delete sync; - } - break; - case FAULT_DETECTED: - GPTP_LOG_ERROR("Received FAULT_DETECTED event"); - if( !getAutomotiveProfile( )) - { - setAsCapable(false); - } - break; - case PDELAY_DEFERRED_PROCESSING: - GPTP_LOG_DEBUG("PDELAY_DEFERRED_PROCESSING occured"); - pdelay_rx_lock->lock(); - if (last_pdelay_resp_fwup == NULL) { - GPTP_LOG_ERROR("PDelay Response Followup is NULL!"); - 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: - if( !getAutomotiveProfile( )) - { - GPTP_LOG_EXCEPTION("PDelay Response Receipt Timeout"); - setAsCapable(false); - } - setPdelayCount( 0 ); - break; - - case PDELAY_RESP_PEER_MISBEHAVING_TIMEOUT_EXPIRES: - GPTP_LOG_EXCEPTION("PDelay Resp Peer Misbehaving timeout expired! Restarting PDelay"); - - haltPdelay(false); - if( getPortState() != PTP_SLAVE && - getPortState() != PTP_MASTER ) - { - GPTP_LOG_STATUS("Starting PDelay" ); - startPDelay(); - } - break; - case SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED: - { - GPTP_LOG_INFO("SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED occured"); - - sync_rate_interval_timer_started = false; - - bool sendSignalMessage = false; - if ( getSyncInterval() != operLogSyncInterval ) - { - setSyncInterval( operLogSyncInterval ); - sendSignalMessage = true; - } - - if( getPDelayInterval() != operLogPdelayReqInterval) - { - setPDelayInterval( operLogPdelayReqInterval ); - sendSignalMessage = true; - } - - if (sendSignalMessage) { - if (!isGM) { - // Send operational signalling message - PTPMessageSignalling *sigMsg = new PTPMessageSignalling(this); - if (sigMsg) { - if( getAutomotiveProfile( )) - sigMsg->setintervals(PTPMessageSignalling::sigMsgInterval_NoChange, getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoChange); - else - sigMsg->setintervals(getPDelayInterval(), getSyncInterval(), PTPMessageSignalling::sigMsgInterval_NoChange); - sigMsg->sendPort(this, NULL); - delete sigMsg; - } - - startSyncReceiptTimer((unsigned long long) - (SYNC_RECEIPT_TIMEOUT_MULTIPLIER * - ((double) pow((double)2, getSyncInterval()) * - 1000000000.0))); - } - } - } - - break; - default: - GPTP_LOG_ERROR - ( "Unhandled event type in " - "EtherPort::processEvent(), %d", e ); - ret = false; - break; - } - - return ret; -} - -void EtherPort::recoverPort( void ) -{ - return; -} - -void EtherPort::becomeMaster( bool annc ) { - setPortState( PTP_MASTER ); - // Stop announce receipt timeout timer - clock->deleteEventTimerLocked( this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ); - - // Stop sync receipt timeout timer - stopSyncReceiptTimer(); - - if( annc ) { - if( !getAutomotiveProfile( )) - { - startAnnounce(); - } - } - startSyncIntervalTimer(16000000); - GPTP_LOG_STATUS("Switching to Master" ); - - clock->updateFUPInfo(); - - return; -} - -void EtherPort::becomeSlave( bool restart_syntonization ) { - clock->deleteEventTimerLocked( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES ); - clock->deleteEventTimerLocked( this, SYNC_INTERVAL_TIMEOUT_EXPIRES ); - - setPortState( PTP_SLAVE ); - - if( !getAutomotiveProfile( )) - { - clock->addEventTimerLocked - (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES, - (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER* - (unsigned long long) - (pow((double)2,getAnnounceInterval())*1000000000.0))); - } - - GPTP_LOG_STATUS("Switching to Slave" ); - if( restart_syntonization ) clock->newSyntonizationSetPoint(); - - getClock()->updateFUPInfo(); - - return; -} - -void EtherPort::mapSocketAddr -( PortIdentity *destIdentity, LinkLayerAddress *remote ) -{ - *remote = identity_map[*destIdentity]; - return; -} - -void EtherPort::addSockAddrMap -( PortIdentity *destIdentity, LinkLayerAddress *remote ) -{ - identity_map[*destIdentity] = *remote; - return; -} - -int EtherPort::getTxTimestamp -( PTPMessageCommon *msg, Timestamp ×tamp, unsigned &counter_value, - bool last ) -{ - PortIdentity identity; - msg->getPortIdentity(&identity); - return getTxTimestamp - (&identity, msg->getMessageId(), timestamp, counter_value, last); -} - -int EtherPort::getRxTimestamp -( PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value, - bool last ) -{ - PortIdentity identity; - msg->getPortIdentity(&identity); - return getRxTimestamp - (&identity, msg->getMessageId(), timestamp, counter_value, last); -} - -int EtherPort::getTxTimestamp -(PortIdentity *sourcePortIdentity, PTPMessageId messageId, - Timestamp ×tamp, unsigned &counter_value, bool last ) -{ - EtherTimestamper *timestamper = - dynamic_cast<EtherTimestamper *>(_hw_timestamper); - if (timestamper) - { - return timestamper->HWTimestamper_txtimestamp - ( sourcePortIdentity, messageId, timestamp, - counter_value, last ); - } - timestamp = clock->getSystemTime(); - return 0; -} - -int EtherPort::getRxTimestamp -( PortIdentity * sourcePortIdentity, PTPMessageId messageId, - Timestamp ×tamp, unsigned &counter_value, bool last ) -{ - EtherTimestamper *timestamper = - dynamic_cast<EtherTimestamper *>(_hw_timestamper); - if (timestamper) - { - return timestamper->HWTimestamper_rxtimestamp - (sourcePortIdentity, messageId, timestamp, counter_value, - last); - } - timestamp = clock->getSystemTime(); - return 0; -} - -void EtherPort::startPDelayIntervalTimer -( long long unsigned int waitTime ) -{ - pDelayIntervalTimerLock->lock(); - clock->deleteEventTimerLocked(this, PDELAY_INTERVAL_TIMEOUT_EXPIRES); - clock->addEventTimerLocked(this, PDELAY_INTERVAL_TIMEOUT_EXPIRES, waitTime); - pDelayIntervalTimerLock->unlock(); -} - -void EtherPort::syncDone() { - GPTP_LOG_VERBOSE("Sync complete"); - - if( getAutomotiveProfile() && getPortState() == PTP_SLAVE ) - { - if (avbSyncState > 0) { - avbSyncState--; - if (avbSyncState == 0) { - setStationState(STATION_STATE_AVB_SYNC); - if (getTestMode()) { - APMessageTestStatus *testStatusMsg = - new APMessageTestStatus(this); - if (testStatusMsg) { - testStatusMsg->sendPort(this); - delete testStatusMsg; - } - } - } - } - } - - if( getAutomotiveProfile( )) - { - if (!sync_rate_interval_timer_started) { - if ( getSyncInterval() != operLogSyncInterval ) - { - startSyncRateIntervalTimer(); - } - } - } - - if( !pdelay_started ) { - startPDelay(); - } -} diff --git a/daemons/gptp/common/ether_port.hpp b/daemons/gptp/common/ether_port.hpp deleted file mode 100644 index 4c878951..00000000 --- a/daemons/gptp/common/ether_port.hpp +++ /dev/null @@ -1,598 +0,0 @@ -/****************************************************************************** - - 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 ETHER_PORT_HPP -#define ETHER_PORT_HPP - -#include <ieee1588.hpp> -#include <avbap_message.hpp> - -#include <avbts_ostimer.hpp> -#include <avbts_oslock.hpp> -#include <avbts_osnet.hpp> -#include <avbts_osthread.hpp> -#include <avbts_oscondition.hpp> -#include <ipcdef.hpp> -#include <gptp_log.hpp> - -#include <stdint.h> - -#include <map> -#include <list> - -#include <common_port.hpp> - -/**@file*/ - -#define GPTP_MULTICAST 0x0180C200000EULL /*!< GPTP multicast adddress */ -#define PDELAY_MULTICAST GPTP_MULTICAST /*!< PDELAY Multicast value */ -#define OTHER_MULTICAST GPTP_MULTICAST /*!< OTHER multicast value */ -#define TEST_STATUS_MULTICAST 0x011BC50AC000ULL /*!< AVnu Automotive profile test status msg Multicast value */ - -#define PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER 3 /*!< PDelay timeout multiplier*/ - -/** - * @brief PortType enumeration. Selects between delay request-response (E2E) mechanism - * or PTPV1 or PTPV2 P2P (peer delay) mechanism. - */ -typedef enum { - V1, - V2_E2E, - V2_P2P -} PortType; - -/** - * @brief Provides a map for the identityMap member of EtherPort - * class - */ -typedef std::map < PortIdentity, LinkLayerAddress > IdentityMap_t; - - -/** - * @brief Ethernet specific port functions - */ -class EtherPort : public CommonPort -{ - static LinkLayerAddress other_multicast; - static LinkLayerAddress pdelay_multicast; - static LinkLayerAddress test_status_multicast; - - /* Port Status */ - // set to 0 when asCapable is false, increment for each pdelay recvd - bool linkUp; - - /* Port Configuration */ - signed char log_mean_unicast_sync_interval; - signed char log_min_mean_delay_req_interval; - - unsigned int duplicate_resp_counter; - uint16_t last_invalid_seqid; - - /* Automotive Profile : Static variables */ - // port_state : already defined as port_state - bool isGM; - // asCapable : already defined as asCapable - signed char operLogPdelayReqInterval; - signed char operLogSyncInterval; - - // Test Status variables - uint32_t linkUpCount; - uint32_t linkDownCount; - StationState_t stationState; - - - /* Automotive Profile : Persistant variables */ - // neighborPropDelay : defined as one_way_delay ?? - // rateRatio : Optional and didn't fine this variable. Will proceed without writing it. - // neighborRateRatio : defined as _peer_rate_offset ?? - - // Automotive Profile AVB SYNC state indicator. > 0 will inditate valid AVB SYNC state - uint32_t avbSyncState; - - uint16_t pdelay_sequence_id; - PTPMessagePathDelayReq *last_pdelay_req; - PTPMessagePathDelayResp *last_pdelay_resp; - PTPMessagePathDelayRespFollowUp *last_pdelay_resp_fwup; - - IdentityMap_t identity_map; - - PTPMessageSync *last_sync; - - OSCondition *port_ready_condition; - - OSLock *pdelay_rx_lock; - OSLock *port_tx_lock; - - OSLock *pDelayIntervalTimerLock; - - net_result port_send - (uint16_t etherType, uint8_t * buf, int size, MulticastType mcast_type, - PortIdentity * destIdentity, bool timestamp); - - bool pdelay_started; - bool pdelay_halted; - bool sync_rate_interval_timer_started; - -protected: - static const unsigned int DUPLICATE_RESP_THRESH = 3; - - public: - void becomeMaster( bool annc ); - void becomeSlave( bool restart_syntonization ); - - /** - * @brief Starts pDelay event timer. - * @return void - */ - void startPDelay(); - - /** - * @brief Stops PDelay event timer - * @return void - */ - void stopPDelay(); - - /** - * @brief Enable/Disable PDelay Request messages - * @param hlt True to HALT (stop sending), False to resume (start sending). - */ - void haltPdelay(bool hlt) - { - pdelay_halted = hlt; - } - - /** - * @brief Get the status of pdelayHalted condition. - * @return True PdelayRequest halted. False when PDelay Request is running - */ - bool pdelayHalted(void) - { - return pdelay_halted; - } - - /** - * @brief Starts Sync Rate Interval event timer. Used for the - * Automotive Profile. - * @return void - */ - void startSyncRateIntervalTimer(); - - /** - * @brief Starts pDelay event timer if not yet started. - * @return void - */ - void syncDone(); - - /** - * @brief Destroys a EtherPort - */ - ~EtherPort(); - - /** - * @brief Creates the EtherPort interface. - * @param init PortInit initialization parameters - */ - EtherPort( PortInit_t *portInit ); - - /** - * @brief Initializes the port. Creates network interface, initializes - * hardware timestamper and create OS locks conditions - * @return FALSE if error during building the interface. TRUE if success - */ - bool _init_port( void ); - - /** - * @brief Currently doesnt do anything. Just returns. - * @return void - */ - void recoverPort(void); - - /** - * @brief Message processing logic on receipt - * @param [in] buf buffer containing message - * @param [in] length buffer length - * @param [in] remote address of sender - * @param [in] link_speed of the receiving device - */ - void processMessage - ( char *buf, int length, LinkLayerAddress *remote, - uint32_t link_speed ); - - /** - * @brief Receives messages from the network interface - * @return Its an infinite loop. Returns NULL in case of error. - */ - void *openPort( EtherPort *port ); - - /** - * @brief Sends and event to a IEEE1588 port. It includes timestamp - * @param buf [in] Pointer to the data buffer - * @param len Size of the message - * @param mcast_type Enumeration MulticastType (pdlay, none or other). Depracated. - * @param destIdentity Destination port identity - * @param [out] link_speed indicates link speed - * @return void - */ - void sendEventPort - (uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type, - PortIdentity * destIdentity, uint32_t *link_speed ); - - /** - * @brief Sends a general message to a port. No timestamps - * @param buf [in] Pointer to the data buffer - * @param len Size of the message - * @param mcast_type Enumeration MulticastType (pdelay, none or other). Depracated. - * @param destIdentity Destination port identity - * @return void - */ - void sendGeneralPort - (uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type, - PortIdentity * destIdentity); - - /** - * @brief Process all events for a EtherPort - * @param e Event to be processed - * @return true if event is handled, false otherwise - */ - bool _processEvent(Event e); - - /** - * @brief Adds a foreign master. - * @param msg [in] PTP announce message - * @return void - * @todo Currently not implemented - */ - void addForeignMaster(PTPMessageAnnounce * msg); - - /** - * @brief Remove a foreign master. - * @param msg [in] PTP announce message - * @return void - * @todo Currently not implemented - */ - void removeForeignMaster(PTPMessageAnnounce * msg); - - /** - * @brief Remove all foreign masters. - * @return void - * @todo Currently not implemented - */ - void removeForeignMasterAll(void); - - /** - * @brief Start pDelay interval timer - * @param waitTime time interval - * @return none - */ - void startPDelayIntervalTimer(long long unsigned int waitTime); - - /** - * @brief Increments PDelay sequence ID and returns. - * @return Next PDelay sequence id. - */ - uint16_t getNextPDelaySequenceId(void) { - return pdelay_sequence_id++; - } - - /** - * @brief Gets last sync sequence number from parent - * @return Parent last sync sequence number - * @todo Not currently implemented. - */ - uint16_t getParentLastSyncSequenceNumber(void); - - /** - * @brief Sets last sync sequence number from parent - * @param num Sequence number - * @return void - * @todo Currently not implemented. - */ - void setParentLastSyncSequenceNumber(uint16_t num); - - /** - * @brief Sets last sync ptp message - * @param msg [in] PTP sync message - * @return void - */ - void setLastSync(PTPMessageSync * msg) { - last_sync = msg; - } - - /** - * @brief Gets last sync message - * @return PTPMessageSync last sync - */ - PTPMessageSync *getLastSync(void) { - return last_sync; - } - - /** - * @brief Locks PDelay RX - * @return TRUE if acquired the lock. FALSE otherwise - */ - bool getPDelayRxLock() { - return pdelay_rx_lock->lock() == oslock_ok ? true : false; - } - - /** - * @brief Do a trylock on the PDelay RX - * @return TRUE if acquired the lock. FALSE otherwise. - */ - bool tryPDelayRxLock() { - return pdelay_rx_lock->trylock() == oslock_ok ? true : false; - } - - /** - * @brief Unlocks PDelay RX. - * @return TRUE if success. FALSE otherwise - */ - bool putPDelayRxLock() { - return pdelay_rx_lock->unlock() == oslock_ok ? true : false; - } - - bool getTxLock() { - return port_tx_lock->lock() == oslock_ok ? true : false; - } - - bool putTxLock() { - return port_tx_lock->unlock() == oslock_ok ? true : false; - } - - /** - * @brief Sets the last_pdelay_req message - * @param msg [in] PTPMessagePathDelayReq message to set - * @return void - */ - void setLastPDelayReq(PTPMessagePathDelayReq * msg) { - last_pdelay_req = msg; - } - - /** - * @brief Gets the last PTPMessagePathDelayReq message - * @return Last pdelay request - */ - PTPMessagePathDelayReq *getLastPDelayReq(void) { - return last_pdelay_req; - } - - /** - * @brief Sets the last PTPMessagePathDelayResp message - * @param msg [in] Last pdelay response - * @return void - */ - void setLastPDelayResp(PTPMessagePathDelayResp * msg) { - last_pdelay_resp = msg; - } - - /** - * @brief Gets the last PTPMessagePathDelayResp message - * @return Last pdelay response - */ - PTPMessagePathDelayResp *getLastPDelayResp(void) { - return last_pdelay_resp; - } - - /** - * @brief Sets the last PTPMessagePathDelayRespFollowUp message - * @param msg [in] last pdelay response follow up - * @return void - */ - void setLastPDelayRespFollowUp(PTPMessagePathDelayRespFollowUp * msg) { - last_pdelay_resp_fwup = msg; - } - - /** - * @brief Gets the last PTPMessagePathDelayRespFollowUp message - * @return last pdelay response follow up - */ - PTPMessagePathDelayRespFollowUp *getLastPDelayRespFollowUp(void) { - return last_pdelay_resp_fwup; - } - - /** - * @brief Gets RX timestamp based on port identity - * @param sourcePortIdentity [in] Source port identity - * @param sequenceId Sequence ID - * @param timestamp [out] RX timestamp - * @param counter_value [out] timestamp count value - * @param last If true, removes the rx lock. - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - int getRxTimestamp - (PortIdentity * sourcePortIdentity, PTPMessageId messageId, - Timestamp & timestamp, unsigned &counter_value, bool last); - - /** - * @brief Gets TX timestamp based on port identity - * @param sourcePortIdentity [in] Source port identity - * @param sequenceId Sequence ID - * @param timestamp [out] TX timestamp - * @param counter_value [out] timestamp count value - * @param last If true, removes the TX lock - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - int getTxTimestamp - (PortIdentity * sourcePortIdentity, PTPMessageId messageId, - Timestamp & timestamp, unsigned &counter_value, bool last); - - /** - * @brief Gets TX timestamp based on PTP message - * @param msg PTPMessageCommon message - * @param timestamp [out] TX timestamp - * @param counter_value [out] timestamp count value - * @param last If true, removes the TX lock - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - int getTxTimestamp - (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value, - bool last); - - /** - * @brief Gets RX timestamp based on PTP message - * @param msg PTPMessageCommon message - * @param timestamp [out] RX timestamp - * @param counter_value [out] timestamp count value - * @param last If true, removes the RX lock - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - int getRxTimestamp - (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value, - bool last); - - /** - * @brief Sets the value of last duplicated SeqID - * @param seqid Value to set - * @return void - */ - void setLastInvalidSeqID(uint16_t seqid) - { - last_invalid_seqid = seqid; - } - - /** - * @brief Get the value of last invalid seqID - * @return Last invalid seq id - */ - uint16_t getLastInvalidSeqID(void) - { - return last_invalid_seqid; - } - - /** - * @brief Sets the duplicate pdelay_resp counter. - * @param cnt Value to be set - */ - void setDuplicateRespCounter(unsigned int cnt) - { - duplicate_resp_counter = cnt; - } - - /** - * @brief Gets the current value of pdelay_resp duplicate messages counter - * @return Counter value - */ - unsigned int getDuplicateRespCounter(void) - { - return duplicate_resp_counter; - } - - /** - * @brief Increment the duplicate PDelayResp message counter - * @return True if it equals the threshold, False otherwise - */ - bool incrementDuplicateRespCounter(void) - { - return ++duplicate_resp_counter == DUPLICATE_RESP_THRESH; - } - - /** - * @brief Maps socket addr to the remote link layer address - * @param destIdentity [in] PortIdentity remote - * @param remote [in] remote link layer address - * @return void - */ - void mapSocketAddr - (PortIdentity * destIdentity, LinkLayerAddress * remote); - - /** - * @brief Adds New sock addr map - * @param destIdentity [in] PortIdentity remote - * @param remote [in] remote link layer address - * @return void - */ - void addSockAddrMap - (PortIdentity * destIdentity, LinkLayerAddress * remote); - - /** - * @brief Gets link up count - * @return Link up count - */ - uint32_t getLinkUpCount() { - return linkUpCount; - } - - /** - * @brief Gets link down count - * @return Link down count - */ - uint32_t getLinkDownCount() { - return linkDownCount; - } - - /** - * @brief Sets the Station State for the Test Status message - * @param StationState_t [in] The station state - * @return none - */ - void setStationState(StationState_t _stationState) { - stationState = _stationState; - if (stationState == STATION_STATE_ETHERNET_READY) { - GPTP_LOG_STATUS("AVnu AP Status : STATION_STATE_ETHERNET_READY"); - } - else if (stationState == STATION_STATE_AVB_SYNC) { - GPTP_LOG_STATUS("AVnu AP Status : STATION_STATE_AVB_SYNC"); - } - else if (stationState == STATION_STATE_AVB_MEDIA_READY) { - GPTP_LOG_STATUS("AVnu AP Status : STATION_STATE_AVB_MEDIA_READY"); - } - } - - /** - * @brief Gets the Station State for the Test Status - * message - * @return station state - */ - StationState_t getStationState() { - return stationState; - } - - - /** - * @brief Sets the linkUp status - * @param bool of the linkUp status - * @return void - */ - void setLinkUpState(bool state) { - linkUp = state; - } - - /** - * @brief Gets the linkUp status - * @return bool of the linkUp status - */ - bool getLinkUpState(void) { - return linkUp; - } -}; - -#endif/*ETHER_PORT_HPP*/ diff --git a/daemons/gptp/common/ether_tstamper.hpp b/daemons/gptp/common/ether_tstamper.hpp deleted file mode 100644 index bc590cbc..00000000 --- a/daemons/gptp/common/ether_tstamper.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/****************************************************************************** - - 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 ETHER_TSTAMPER_HPP -#define ETHER_TSTAMPER_HPP - -#include <common_tstamper.hpp> - -class EtherTimestamper : public CommonTimestamper -{ -public: - /** - * @brief Gets the tx timestamp from hardware - * @param identity PTP port identity - * @param PTPMessageId Message ID - * @param timestamp [out] Timestamp value - * @param clock_value [out] Clock value - * @param last Signalizes that it is the last timestamp to get. When TRUE, releases the lock when its done. - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - virtual int HWTimestamper_txtimestamp - ( PortIdentity * identity, PTPMessageId messageId, - Timestamp ×tamp, unsigned &clock_value, bool last ) = 0; - - /** - * @brief Get rx timestamp - * @param identity PTP port identity - * @param messageId Message ID - * @param timestamp [out] Timestamp value - * @param clock_value [out] Clock value - * @param last Signalizes that it is the last timestamp to get. When TRUE, releases the lock when its done. - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - virtual int HWTimestamper_rxtimestamp(PortIdentity * identity, - PTPMessageId messageId, - Timestamp & timestamp, - unsigned &clock_value, - bool last) = 0; - - virtual ~EtherTimestamper() {} -}; - -#endif/*ETHER_TSTAMPER_HPP*/ diff --git a/daemons/gptp/common/gptp_cfg.cpp b/daemons/gptp/common/gptp_cfg.cpp deleted file mode 100644 index 943c639a..00000000 --- a/daemons/gptp/common/gptp_cfg.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/************************************************************************************************************* -Copyright (c) 2015, Coveloz Consulting Ltda -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "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 LISTED 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. - -Attributions: The inih library portion of the source code is licensed from -Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt. -Complete license and copyright information can be found at -https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175. -*************************************************************************************************************/ - -/** - * @file - * MODULE SUMMARY : Reads the .ini file and parses it into information - * to be used on daemon_cl - */ - -#include <iostream> - -/* need Microsoft version for strcasecmp() from GCC strings.h */ -#ifdef _MSC_VER -#define strcasecmp _stricmp -#else -#include <strings.h> -#endif - -#include <errno.h> -#include <stdlib.h> - -#include "gptp_cfg.hpp" - -uint32_t findSpeedByName( const char *name, const char **end ); - -GptpIniParser::GptpIniParser(std::string filename) -{ - _config.systemClockDesc[0] = '\0'; - _error = ini_parse(filename.c_str(), iniCallBack, this); -} - -GptpIniParser::~GptpIniParser() -{ -} - -/****************************************************************************/ - -int GptpIniParser::parserError(void) -{ - return _error; -} - -/****************************************************************************/ - -int GptpIniParser::iniCallBack(void *user, const char *section, const char *name, const char *value) -{ - GptpIniParser *parser = (GptpIniParser*)user; - bool valOK = false; - - if( parseMatch(section, "ptp") ) - { - if( parseMatch(name, "priority1") ) - { - errno = 0; - char *pEnd; - unsigned char p1 = (unsigned char) strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.priority1 = p1; - } - } - } - else if( parseMatch(section, "clock") ) - { - if( parseMatch(name, "SystemClock") ) - { - valOK = true; - strncpy( parser->_config.systemClockDesc, value, - MAX_CLOCK_DESC_LEN ); - parser->_config.systemClockDesc[MAX_CLOCK_DESC_LEN] = '\0'; - } - } - else if( parseMatch(section, "port") ) - { - if( parseMatch(name, "announceReceiptTimeout") ) - { - errno = 0; - char *pEnd; - unsigned int art = strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.announceReceiptTimeout = art; - } - } - else if( parseMatch(name, "syncReceiptTimeout") ) - { - errno = 0; - char *pEnd; - unsigned int srt = strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.syncReceiptTimeout = srt; - } - } - else if( parseMatch(name, "neighborPropDelayThresh") ) - { - errno = 0; - char *pEnd; - int64_t nt = strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.neighborPropDelayThresh = nt; - } - } - else if( parseMatch(name, "syncReceiptThresh") ) - { - errno = 0; - char *pEnd; - unsigned int st = strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.syncReceiptThresh = st; - } - } - else if( parseMatch(name, "seqIdAsCapableThresh") ) - { - errno = 0; - char *pEnd; - unsigned int sidt = strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.seqIdAsCapableThresh = sidt; - } - } - else if( parseMatch( name, "lostPdelayRespThresh") ) - { - errno = 0; - char *pEnd; - uint16_t lostpdelayth = (uint16_t) strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0 ) { - valOK = true; - parser->_config.lostPdelayRespThresh = lostpdelayth; - } - } - } - else if( parseMatch(section, "eth") ) - { - if( parseMatch(name, "phy_delay_gb_tx") ) - { - errno = 0; - char *pEnd; - int phdly = strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.phy_delay[LINKSPEED_1G].set_tx_delay( phdly ); - } - } - - else if( parseMatch(name, "phy_delay_gb_rx") ) - { - errno = 0; - char *pEnd; - int phdly = strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.phy_delay[LINKSPEED_1G].set_rx_delay( phdly ); - } - } - - else if( parseMatch(name, "phy_delay_mb_tx") ) - { - errno = 0; - char *pEnd; - int phdly = strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.phy_delay[LINKSPEED_100MB]. - set_tx_delay( phdly ); - } - } - - else if( parseMatch(name, "phy_delay_mb_rx") ) - { - errno = 0; - char *pEnd; - int phdly = strtoul(value, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.phy_delay[LINKSPEED_100MB]. - set_rx_delay( phdly ); - } - } - - else if( parseMatch(name, "phy_delay") ) - { - errno = 0; - char *pEnd; - const char *c_pEnd; - uint32_t speed = findSpeedByName( value, &c_pEnd ); - if( speed == INVALID_LINKSPEED ) - { - speed = strtoul( value, &pEnd, 10 ); - c_pEnd = pEnd; - } - int ph_tx_dly = strtoul(c_pEnd, &pEnd, 10); - int ph_rx_dly = strtoul(pEnd, &pEnd, 10); - if( *pEnd == '\0' && errno == 0) { - valOK = true; - parser->_config.phy_delay[speed]. - set_delay( ph_tx_dly, ph_rx_dly ); - } - } - } - - if(!valOK) - { - std::cerr << "Unrecognized configuration item: section=" << section << ", name=" << name << std::endl; - return 0; - } - - return 1; -} - - -/****************************************************************************/ - -bool GptpIniParser::parseMatch(const char *s1, const char *s2) -{ - return strcasecmp(s1, s2) == 0; -} - -#define PHY_DELAY_DESC_LEN 21 - -void GptpIniParser::print_phy_delay( void ) -{ - - phy_delay_map_t map = this->getPhyDelay(); - for( phy_delay_map_t::const_iterator i = map.cbegin(); - i != map.cend(); ++i ) - { - uint32_t speed; - uint16_t tx, rx; - const char *speed_name; - char phy_delay_desc[PHY_DELAY_DESC_LEN+1]; - - speed = (*i).first; - tx = i->second.get_tx_delay(); - rx = i->second.get_rx_delay(); - - PLAT_snprintf( phy_delay_desc, PHY_DELAY_DESC_LEN+1, - "TX: %hu | RX: %hu", tx, rx ); - - speed_name = findNameBySpeed( speed ); - if( speed_name != NULL ) - GPTP_LOG_INFO( "%s - PHY delay\n\t\t\t%s", - speed_name, phy_delay_desc ); - else - GPTP_LOG_INFO( "link speed %u - PHY delay\n\t\t\t%s", - speed, phy_delay_desc ); - } -} - - -#define DECLARE_SPEED_NAME_MAP( name ) \ - { name, #name } - -typedef struct -{ - const uint32_t speed; - const char *name; -} speed_name_map_t; - -speed_name_map_t speed_name_map[] = -{ - DECLARE_SPEED_NAME_MAP( LINKSPEED_10G ), - DECLARE_SPEED_NAME_MAP( LINKSPEED_2_5G ), - DECLARE_SPEED_NAME_MAP( LINKSPEED_1G ), - DECLARE_SPEED_NAME_MAP( LINKSPEED_100MB ), - DECLARE_SPEED_NAME_MAP( INVALID_LINKSPEED ) -}; - -const char *findNameBySpeed( uint32_t speed ) -{ - speed_name_map_t *iter = speed_name_map; - - while( iter->speed != INVALID_LINKSPEED ) - { - if( iter->speed == speed ) - { - break; - } - ++iter; - } - - if( iter->speed != INVALID_LINKSPEED ) - return iter->name; - - return NULL; -} - -uint32_t findSpeedByName( const char *name, const char **end ) -{ - speed_name_map_t *iter = speed_name_map; - *end = name; - - while( iter->speed != INVALID_LINKSPEED ) - { - if( strncmp( name, iter->name, strlen( iter->name )) == 0 ) - { - *end = name + strlen( iter->name ); - break; - } - ++iter; - } - - return iter->speed; -} - diff --git a/daemons/gptp/common/gptp_cfg.hpp b/daemons/gptp/common/gptp_cfg.hpp deleted file mode 100644 index 4b172b4c..00000000 --- a/daemons/gptp/common/gptp_cfg.hpp +++ /dev/null @@ -1,180 +0,0 @@ -/************************************************************************************************************* -Copyright (c) 2015, Coveloz Consulting Ltda -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "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 LISTED 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. - -Attributions: The inih library portion of the source code is licensed from -Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt. -Complete license and copyright information can be found at -https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175. -*************************************************************************************************************/ - -/** - * @file - * MODULE SUMMARY : Reads the .ini file and parses it into information - * to be used on daemon_cl - */ - -#include <string> - -#include "ini.h" -#include <limits.h> -#include <common_port.hpp> - -const uint32_t LINKSPEED_10G = 10000000; -const uint32_t LINKSPEED_2_5G = 2500000; -const uint32_t LINKSPEED_1G = 1000000; -const uint32_t LINKSPEED_100MB = 100000; -const uint32_t INVALID_LINKSPEED = UINT_MAX; -const uint8_t MAX_CLOCK_DESC_LEN = 64; - -/** - * @brief Returns name given numeric link speed - * @return NULL if speed/name isn't found - */ -const char *findNameBySpeed( uint32_t speed ); - -/** - * @brief Provides the gptp interface for - * the iniParser external module - */ -class GptpIniParser -{ - public: - - /** - * @brief Container with the information to get from the .ini file - */ - typedef struct - { - /*ptp data set*/ - unsigned char priority1; - - /* Clock data set */ - char systemClockDesc[MAX_CLOCK_DESC_LEN+1]; - - /*port data set*/ - unsigned int announceReceiptTimeout; - unsigned int syncReceiptTimeout; - unsigned int syncReceiptThresh; //!< Number of wrong sync messages that will trigger a switch to master - int64_t neighborPropDelayThresh; - unsigned int seqIdAsCapableThresh; - uint16_t lostPdelayRespThresh; - PortState port_state; - - /*ethernet adapter data set*/ - std::string ifname; - phy_delay_map_t phy_delay; - } gptp_cfg_t; - - /*public methods*/ - GptpIniParser(std::string ini_path); - ~GptpIniParser(); - - /** - * @brief Reads the parser Error value - * @param void - * @return Parser Error - */ - int parserError(void); - - /** - * @brief Read SystemClock description - * @return pointer to c-string representing system clock - */ - const char *getSystemClockDesc(void) - { - return _config.systemClockDesc; - } - - /** - * @brief Reads priority1 config value - * @param void - * @return priority1 - */ - unsigned char getPriority1(void) - { - return _config.priority1; - } - - /** - * @brief Reads the announceReceiptTimeout configuration value - * @param void - * @return announceRecepitTimeout value from .ini file - */ - unsigned int getAnnounceReceiptTimeout(void) - { - return _config.announceReceiptTimeout; - } - - /** - * @brief Reads the syncRecepitTimeout configuration value - * @param void - * @return syncRecepitTimeout value from the .ini file - */ - unsigned int getSyncReceiptTimeout(void) - { - return _config.syncReceiptTimeout; - } - - /** - * @brief Reads the PHY DELAY values from the configuration file - * @param void - * @return PHY delay map structure - */ - const phy_delay_map_t getPhyDelay(void) - { - return _config.phy_delay; - } - - /** - * @brief Reads the neighbohr propagation delay threshold from the configuration file - * @param void - * @return neighborPropDelayThresh value from the .ini file - */ - int64_t getNeighborPropDelayThresh(void) - { - return _config.neighborPropDelayThresh; - } - - /** - * @brief Reads the sync receipt threshold from the configuration file - * @return syncRecepitThresh value from the .ini file - */ - unsigned int getSyncReceiptThresh(void) - { - return _config.syncReceiptThresh; - } - - /** - * @brief Dump PHY delays to screen - */ - void print_phy_delay( void ); - - private: - int _error; - gptp_cfg_t _config; - - static int iniCallBack(void *user, const char *section, const char *name, const char *value); - static bool parseMatch(const char *s1, const char *s2); -}; - diff --git a/daemons/gptp/common/gptp_log.cpp b/daemons/gptp/common/gptp_log.cpp deleted file mode 100644 index a1a5809f..00000000 --- a/daemons/gptp/common/gptp_log.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************************************************* -Copyright (c) 2012-2016, Harman International Industries, Incorporated -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "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 LISTED 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 <gptp_log.hpp> - -#include <stdio.h> -#include <stdarg.h> -#include <stdint.h> -#include <platform.hpp> - -// MS VC++ 2013 has C++11 but not C11 support, use this to get millisecond resolution -#include <chrono> - -#ifdef GENIVI_DLT -DLT_DECLARE_CONTEXT(dlt_con_gptp); -#endif - -void gptplogRegister(void) -{ -#ifdef GENIVI_DLT - DLT_REGISTER_APP("GPTP","OpenAVB gPTP"); - DLT_REGISTER_CONTEXT(dlt_con_gptp, "GNRL", "General Context"); -#endif -} - -void gptplogUnregister(void) -{ -#ifdef GENIVI_DLT - DLT_UNREGISTER_CONTEXT(dlt_con_gptp); - DLT_UNREGISTER_APP(); -#endif -} - -void gptpLog(GPTP_LOG_LEVEL level, const char *tag, const char *path, int line, const char *fmt, ...) -{ - char msg[1024]; - - va_list args; - va_start(args, fmt); - vsprintf(msg, fmt, args); - -#ifndef GENIVI_DLT - std::chrono::system_clock::time_point cNow = std::chrono::system_clock::now(); - time_t tNow = std::chrono::system_clock::to_time_t(cNow); - struct tm tmNow; - PLAT_localtime(&tNow, &tmNow); - std::chrono::system_clock::duration roundNow = cNow - std::chrono::system_clock::from_time_t(tNow); - long int millis = (long int) std::chrono::duration_cast<std::chrono::milliseconds>(roundNow).count(); - - if (path) { - fprintf(stderr, "%s: GPTP [%2.2d:%2.2d:%2.2d:%3.3ld] [%s:%u] %s\n", - tag, tmNow.tm_hour, tmNow.tm_min, tmNow.tm_sec, millis, path, line, msg); - } - else { - fprintf(stderr, "%s: GPTP [%2.2d:%2.2d:%2.2d:%3.3ld] %s\n", - tag, tmNow.tm_hour, tmNow.tm_min, tmNow.tm_sec, millis, msg); - } -#else - DltLogLevelType dlt_level; - - switch (level) { - case GPTP_LOG_LVL_CRITICAL: - dlt_level = DLT_LOG_FATAL; - break; - case GPTP_LOG_LVL_ERROR: - dlt_level = DLT_LOG_ERROR; - break; - case GPTP_LOG_LVL_EXCEPTION: - case GPTP_LOG_LVL_WARNING: - dlt_level = DLT_LOG_WARN; - break; - case GPTP_LOG_LVL_INFO: - case GPTP_LOG_LVL_STATUS: - dlt_level = DLT_LOG_INFO; - break; - case GPTP_LOG_LVL_DEBUG: - dlt_level = DLT_LOG_DEBUG; - break; - case GPTP_LOG_LVL_VERBOSE: - dlt_level = DLT_LOG_VERBOSE; - break; - default: - dlt_level = DLT_LOG_INFO; - break; - } - - DLT_LOG(dlt_con_gptp, dlt_level, DLT_STRING(msg)); -#endif - -} - diff --git a/daemons/gptp/common/gptp_log.hpp b/daemons/gptp/common/gptp_log.hpp deleted file mode 100644 index 272d8cd8..00000000 --- a/daemons/gptp/common/gptp_log.hpp +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************************************************* -Copyright (c) 2012-2016, Harman International Industries, Incorporated -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "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 LISTED 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 GPTP_LOG_HPP -#define GPTP_LOG_HPP - -/**@file*/ - -#include <stdio.h> -#include <stdarg.h> -#include <time.h> - -#ifdef GENIVI_DLT -#include "dlt.h" -#endif - -#define GPTP_LOG_CRITICAL_ON 1 -#define GPTP_LOG_ERROR_ON 1 -#define GPTP_LOG_EXCEPTION_ON 1 -#define GPTP_LOG_WARNING_ON 1 -#define GPTP_LOG_INFO_ON 1 -#define GPTP_LOG_STATUS_ON 1 -//#define GPTP_LOG_DEBUG_ON 1 -//#define GPTP_LOG_VERBOSE_ON 1 - -typedef enum { - GPTP_LOG_LVL_CRITICAL, - GPTP_LOG_LVL_ERROR, - GPTP_LOG_LVL_EXCEPTION, - GPTP_LOG_LVL_WARNING, - GPTP_LOG_LVL_INFO, - GPTP_LOG_LVL_STATUS, - GPTP_LOG_LVL_DEBUG, - GPTP_LOG_LVL_VERBOSE, -} GPTP_LOG_LEVEL; - - -void gptplogRegister(void); -void gptplogUnregister(void); -void gptpLog(GPTP_LOG_LEVEL level, const char *tag, const char *path, int line, const char *fmt, ...); - - -#define GPTP_LOG_REGISTER() gptplogRegister() - -#define GPTP_LOG_UNREGISTER() gptplogUnregister() - -#ifdef GPTP_LOG_CRITICAL_ON -#define GPTP_LOG_CRITICAL(fmt,...) gptpLog(GPTP_LOG_LVL_CRITICAL, "CRITICAL ", NULL, 0, fmt, ## __VA_ARGS__) -#else -#define GPTP_LOG_CRITICAL(fmt,...) -#endif - -#ifdef GPTP_LOG_ERROR_ON -#define GPTP_LOG_ERROR(fmt,...) gptpLog(GPTP_LOG_LVL_ERROR, "ERROR ", NULL, 0, fmt, ## __VA_ARGS__) -#else -#define GPTP_LOG_ERROR(fmt,...) -#endif - -#ifdef GPTP_LOG_EXCEPTION_ON -#define GPTP_LOG_EXCEPTION(fmt,...) gptpLog(GPTP_LOG_LVL_EXCEPTION, "EXCEPTION", NULL, 0, fmt, ## __VA_ARGS__) -#else -#define GPTP_LOG_EXCEPTION(fmt,...) -#endif - -#ifdef GPTP_LOG_WARNING_ON -#define GPTP_LOG_WARNING(fmt,...) gptpLog(GPTP_LOG_LVL_WARNING, "WARNING ", NULL, 0, fmt, ## __VA_ARGS__) -#else -#define GPTP_LOG_WARNING(fmt,...) -#endif - -#ifdef GPTP_LOG_INFO_ON -#define GPTP_LOG_INFO(fmt,...) gptpLog(GPTP_LOG_LVL_INFO, "INFO ", NULL, 0, fmt, ## __VA_ARGS__) -#else -#define GPTP_LOG_INFO(fmt,...) -#endif - -#ifdef GPTP_LOG_STATUS_ON -#define GPTP_LOG_STATUS(fmt,...) gptpLog(GPTP_LOG_LVL_STATUS, "STATUS ", NULL, 0, fmt, ## __VA_ARGS__) -#else -#define GPTP_LOG_STATUS(fmt,...) -#endif - -#ifdef GPTP_LOG_DEBUG_ON -#define GPTP_LOG_DEBUG(fmt,...) gptpLog(GPTP_LOG_LVL_DEBUG, "DEBUG ", __FILE__, __LINE__, fmt, ## __VA_ARGS__) -#else -#define GPTP_LOG_DEBUG(fmt,...) -#endif - -#ifdef GPTP_LOG_VERBOSE_ON -#define GPTP_LOG_VERBOSE(fmt,...) gptpLog(GPTP_LOG_LVL_VERBOSE, "VERBOSE ", __FILE__, __LINE__, fmt, ## __VA_ARGS__) -#else -#define GPTP_LOG_VERBOSE(fmt,...) -#endif - -#endif diff --git a/daemons/gptp/common/ieee1588.hpp b/daemons/gptp/common/ieee1588.hpp deleted file mode 100644 index cf3d59e4..00000000 --- a/daemons/gptp/common/ieee1588.hpp +++ /dev/null @@ -1,455 +0,0 @@ -/****************************************************************************** - - 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 - -/** @file */ - -#include <string> - -#include <stdint.h> - -#include <string.h> - -#include <stdio.h> - -#include <platform.hpp> -#include <ptptypes.hpp> - -#include <gptp_log.hpp> -#include <limits.h> - -#define MAX_PORTS 32 /*!< Maximum number of EtherPort instances */ - - -/** - * @brief Return codes for gPTP -*/ -#define GPTP_EC_SUCCESS 0 /*!< No errors.*/ -#define GPTP_EC_FAILURE -1 /*!< Generic error */ -#define GPTP_EC_EAGAIN -72 /*!< Error: Try again */ - - -class LinkLayerAddress; -struct ClockQuality; -class PortIdentity; -class PTPMessageId; -class PTPMessageCommon; -class PTPMessageSync; -class PTPMessageAnnounce; -class PTPMessagePathDelayReq; -class PTPMessagePathDelayResp; -class PTPMessagePathDelayRespFollowUp; -class EtherPort; -class CommonPort; -class IEEE1588Clock; -class OSNetworkInterface; - -/** - * @enum Event - * IEEE 1588 event enumeration type - * Defined at: IEEE 1588-2008 Clause 9.2.6 - */ -typedef enum { - NULL_EVENT = 0, //!< Null Event. Used to initialize events. - POWERUP = 5, //!< Power Up. Initialize state machines. - INITIALIZE, //!< Same as POWERUP. - LINKUP, //!< Triggered when link comes up. - LINKDOWN, //!< Triggered when link goes down. - STATE_CHANGE_EVENT, //!< Signalizes that something has changed. Recalculates best master. - SYNC_INTERVAL_TIMEOUT_EXPIRES, //!< Sync interval expired. Its time to send a sync message. - PDELAY_INTERVAL_TIMEOUT_EXPIRES, //!< PDELAY interval expired. Its time to send pdelay_req message - SYNC_RECEIPT_TIMEOUT_EXPIRES, //!< Sync receipt timeout. Restart timers and take actions based on port's state. - QUALIFICATION_TIMEOUT_EXPIRES, //!< Qualification timeout. Event not currently used - ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES, //!< Announce receipt timeout. Same as SYNC_RECEIPT_TIMEOUT_EXPIRES - ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES, //!< Announce interval timout. Its time to send an announce message if asCapable is true - FAULT_DETECTED, //!< A fault was detected. - PDELAY_DEFERRED_PROCESSING, //!< Defers pdelay processing - PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, //!< Pdelay response message timeout - PDELAY_RESP_PEER_MISBEHAVING_TIMEOUT_EXPIRES, //!< Timeout for peer misbehaving. This even will re-enable the PDelay Requests - SYNC_RATE_INTERVAL_TIMEOUT_EXPIRED, //!< Sync rate signal timeout for the Automotive Profile -} Event; - -/** - * @brief Defines an event descriptor type - */ -typedef struct { - CommonPort *port; //!< Media Dependent Ether Port - Event event; //!< Event enumeration -} event_descriptor_t; - -/** - * @brief Provides a generic InterfaceLabel class - */ -class InterfaceLabel { - public: - virtual ~ InterfaceLabel() { - }; -}; - -/** - * @brief Provides a ClockIdentity abstraction - * See IEEE 802.1AS-2011 Clause 8.5.2.2 - */ -class ClockIdentity { - private: - uint8_t id[PTP_CLOCK_IDENTITY_LENGTH]; - public: - /** - * @brief Default constructor. Sets ID to zero - */ - ClockIdentity() { - memset( id, 0, PTP_CLOCK_IDENTITY_LENGTH ); - } - - /** - * @brief Constructs the object and sets its ID - * @param id [in] clock id as an octet array - */ - ClockIdentity( uint8_t *id ) { - set(id); - } - - /** - * @brief Implements the operator '==' overloading method. - * @param cmp Reference to the ClockIdentity comparing value - * @return TRUE if cmp equals to the object's clock identity. FALSE otherwise - */ - bool operator==(const ClockIdentity & cmp) const { - return memcmp(this->id, cmp.id, - PTP_CLOCK_IDENTITY_LENGTH) == 0 ? true : false; - } - - /** - * @brief Implements the operator '!=' overloading method. - * @param cmp Reference to the ClockIdentity comparing value - * @return TRUE if cmp differs from the object's clock identity. FALSE otherwise. - */ - bool operator!=( const ClockIdentity &cmp ) const { - return memcmp( this->id, cmp.id, PTP_CLOCK_IDENTITY_LENGTH ) != 0 ? true : false; - } - - /** - * @brief Implements the operator '<' overloading method. - * @param cmp Reference to the ClockIdentity comparing value - * @return TRUE if cmp value is lower than the object's clock identity value. FALSE otherwise. - */ - bool operator<(const ClockIdentity & cmp)const { - return memcmp(this->id, cmp.id, - PTP_CLOCK_IDENTITY_LENGTH) < 0 ? true : false; - } - - /** - * @brief Implements the operator '>' overloading method. - * @param cmp Reference to the ClockIdentity comparing value - * @return TRUE if cmp value is greater than the object's clock identity value. FALSE otherwise - */ - bool operator>(const ClockIdentity & cmp)const { - return memcmp(this->id, cmp.id, - PTP_CLOCK_IDENTITY_LENGTH) > 0 ? true : false; - } - - /** - * @brief Gets the identity string from the ClockIdentity object - * @return String containing the clock identity - */ - std::string getIdentityString(); - - /** - * @brief Gets the identity string from the ClockIdentity object - * @param id [out] Value copied from the object ClockIdentity. Needs to be at least ::PTP_CLOCK_IDENTITY_LENGTH long. - * @return void - */ - void getIdentityString(uint8_t *id) { - memcpy(id, this->id, PTP_CLOCK_IDENTITY_LENGTH); - } - - /** - * @brief Set the clock id to the object - * @param id [in] Value to be set - * @return void - */ - void set(uint8_t * id) { - memcpy(this->id, id, PTP_CLOCK_IDENTITY_LENGTH); - } - - /** - * @brief Set clock id based on the link layer address. Clock id is 8 octets - * long whereas link layer address is 6 octets long and it is turned into a - * clock identity as per the 802.1AS standard described in clause 8.5.2.2 - * @param address Link layer address - * @return void - */ - void set(LinkLayerAddress * address); - - /** - * @brief This method is only enabled at compiling time. When enabled, it prints on the - * stderr output the clock identity information - * @param str [in] String to be print out before the clock identity value - * @return void - */ - void print(const char *str) { - GPTP_LOG_VERBOSE - ( "Clock Identity(%s): %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx", - str, id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7] ); - } -}; - -#define INVALID_TIMESTAMP_VERSION 0xFF /*!< Value defining invalid timestamp version*/ -#define MAX_NANOSECONDS 1000000000 /*!< Maximum value of nanoseconds (1 second)*/ -#define MAX_TSTAMP_STRLEN 25 /*!< Maximum size of timestamp strlen*/ - -/** - * @brief Provides a Timestamp interface - */ -class Timestamp { -public: - /** - * @brief Creates a Timestamp instance - * @param ns 32 bit nano-seconds value - * @param s_l 32 bit seconds field LSB - * @param s_m 32 bit seconds field MSB - * @param ver 8 bit version field - */ - Timestamp - (uint32_t ns, uint32_t s_l, uint16_t s_m, - uint8_t ver = INVALID_TIMESTAMP_VERSION) { - nanoseconds = ns; - seconds_ls = s_l; - seconds_ms = s_m; - _version = ver; - } - /* - * Default constructor. Initializes - * the private parameters - */ - Timestamp() { - Timestamp( 0, 0, 0 ); - } - uint32_t nanoseconds; //!< 32 bit nanoseconds value - uint32_t seconds_ls; //!< 32 bit seconds LSB value - uint16_t seconds_ms; //!< 32 bit seconds MSB value - uint8_t _version; //!< 8 bit version value - - /** - * @brief Copies the timestamp to the internal string in the following format: - * seconds_ms seconds_ls nanoseconds - * @return STL string containing timestamp - */ - std::string toString() const - { - char output_string[MAX_TSTAMP_STRLEN+1]; - - PLAT_snprintf - ( output_string, MAX_TSTAMP_STRLEN+1, "%hu %u.%09u", - seconds_ms, seconds_ls, nanoseconds ); - - return std::string( output_string ); - } - - /** - * @brief Implements the operator '+' overloading method. - * @param o Constant reference to the timestamp to be added - * @return Object's timestamp + o. - */ - Timestamp operator+( const Timestamp& o ) { - uint32_t nanoseconds; - uint32_t seconds_ls; - uint16_t seconds_ms; - uint8_t version; - bool carry; - - nanoseconds = this->nanoseconds; - nanoseconds += o.nanoseconds; - carry = - nanoseconds < this->nanoseconds || - nanoseconds >= MAX_NANOSECONDS ? true : false; - nanoseconds -= carry ? MAX_NANOSECONDS : 0; - - seconds_ls = this->seconds_ls; - seconds_ls += o.seconds_ls; - seconds_ls += carry ? 1 : 0; - carry = seconds_ls < this->seconds_ls ? true : false; - - seconds_ms = this->seconds_ms; - seconds_ms += o.seconds_ms; - seconds_ms += carry ? 1 : 0; - carry = seconds_ms < this->seconds_ms ? true : false; - - version = this->_version == o._version ? this->_version : - INVALID_TIMESTAMP_VERSION; - return Timestamp( nanoseconds, seconds_ls, seconds_ms, version ); - } - - /** - * @brief Implements the operator '-' overloading method. - * @param o Constant reference to the timestamp to be subtracted - * @return Object's timestamp - o. - */ - Timestamp operator-( const Timestamp& o ) { - uint32_t nanoseconds; - uint32_t seconds_ls; - uint16_t seconds_ms; - uint8_t version; - bool carry, borrow_this; - unsigned borrow_total = 0; - - borrow_this = this->nanoseconds < o.nanoseconds; - nanoseconds = - ((borrow_this ? MAX_NANOSECONDS : 0) + this->nanoseconds) - - o.nanoseconds; - carry = nanoseconds > MAX_NANOSECONDS; - nanoseconds -= carry ? MAX_NANOSECONDS : 0; - borrow_total += borrow_this ? 1 : 0; - - seconds_ls = carry ? 1 : 0; - seconds_ls += this->seconds_ls; - borrow_this = - borrow_total > seconds_ls || - seconds_ls - borrow_total < o.seconds_ls; - seconds_ls = - borrow_this ? seconds_ls - o.seconds_ls + (uint32_t)-1 : - (seconds_ls - borrow_total) - o.seconds_ls; - borrow_total = borrow_this ? borrow_total + 1 : 0; - - seconds_ms = carry ? 1 : 0; - seconds_ms += this->seconds_ms; - borrow_this = - borrow_total > seconds_ms || - seconds_ms - borrow_total < o.seconds_ms; - seconds_ms = - borrow_this ? seconds_ms - o.seconds_ms + (uint32_t)-1 : - (seconds_ms - borrow_total) - o.seconds_ms; - borrow_total = borrow_this ? borrow_total + 1 : 0; - - version = this->_version == o._version ? this->_version : - INVALID_TIMESTAMP_VERSION; - return Timestamp( nanoseconds, seconds_ls, seconds_ms, version ); - } - - /** - * @brief Sets a 64bit value to the object's timestamp - * @param value Value to be set - * @return void - */ - void set64( uint64_t value ) { - nanoseconds = value % 1000000000; - seconds_ls = (uint32_t) (value / 1000000000); - seconds_ms = (uint16_t)((value / 1000000000) >> 32); - } -}; - -#define INVALID_TIMESTAMP (Timestamp( 0xC0000000, 0, 0 )) /*!< Defines an invalid timestamp using a Timestamp instance and a fixed value*/ -#define PDELAY_PENDING_TIMESTAMP (Timestamp( 0xC0000001, 0, 0 )) /*!< PDelay is pending timestamp */ - -static inline uint64_t TIMESTAMP_TO_NS(Timestamp &ts) -{ - return (((static_cast<long long int>(ts.seconds_ms) << sizeof(ts.seconds_ls)*8) + - ts.seconds_ls)*1000000000LL + ts.nanoseconds) ; /*!< Converts timestamp value into nanoseconds value*/ -} - -/** - * @brief Swaps out byte-a-byte a 64 bit value - * @param in Value to be swapped - * @return Swapped value - */ -static inline uint64_t byte_swap64(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; -} - -#define NS_PER_SECOND 1000000000 /*!< Amount of nanoseconds in a second*/ -#define LS_SEC_MAX 0xFFFFFFFFull /*!< Maximum value of seconds LSB field */ - -/** - * @brief Subtracts a nanosecond value from the timestamp - * @param ts [inout] Timestamp value - * @param ns Nanoseconds value to subtract from ts - * @return void - */ -static inline void TIMESTAMP_SUB_NS( Timestamp &ts, uint64_t ns ) { - uint64_t secs = (uint64_t)ts.seconds_ls | ((uint64_t)ts.seconds_ms) << 32; - uint64_t nanos = (uint64_t)ts.nanoseconds; - - secs -= ns / NS_PER_SECOND; - ns = ns % NS_PER_SECOND; - - if(ns > nanos) - { //borrow - nanos += NS_PER_SECOND; - --secs; - } - - nanos -= ns; - - ts.seconds_ms = (uint16_t)(secs >> 32); - ts.seconds_ls = (uint32_t)(secs & LS_SEC_MAX); - ts.nanoseconds = (uint32_t)nanos; -} - -/** - * @brief Adds a nanosecond value to the timestamp - * @param ts [inout] Timestamp value - * @param ns Nanoseconds value to add to ts - * @return void - */ -static inline void TIMESTAMP_ADD_NS( Timestamp &ts, uint64_t ns ) { - uint64_t secs = (uint64_t)ts.seconds_ls | ((uint64_t)ts.seconds_ms) << 32; - uint64_t nanos = (uint64_t)ts.nanoseconds; - - secs += ns / NS_PER_SECOND; - nanos += ns % NS_PER_SECOND; - - if(nanos > NS_PER_SECOND) - { //carry - nanos -= NS_PER_SECOND; - ++secs; - } - - ts.seconds_ms = (uint16_t)(secs >> 32); - ts.seconds_ls = (uint32_t)(secs & LS_SEC_MAX); - ts.nanoseconds = (uint32_t)nanos; -} - -#endif diff --git a/daemons/gptp/common/ieee1588clock.cpp b/daemons/gptp/common/ieee1588clock.cpp deleted file mode 100644 index 3cb7ad8e..00000000 --- a/daemons/gptp/common/ieee1588clock.cpp +++ /dev/null @@ -1,500 +0,0 @@ -/****************************************************************************** - - 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> - -#include <math.h> - -std::string ClockIdentity::getIdentityString() -{ - uint8_t cid[PTP_CLOCK_IDENTITY_LENGTH]; - getIdentityString(cid); - char scid[PTP_CLOCK_IDENTITY_LENGTH * 3 + 1]; - char* pscid = scid; - for (unsigned i = 0; i < PTP_CLOCK_IDENTITY_LENGTH; ++i) { - unsigned byte = cid[i]; - PLAT_snprintf(pscid, 4, "%2.2X:", byte); - pscid += 3; - } - scid[PTP_CLOCK_IDENTITY_LENGTH * 3 - 1] = '\0'; - - return std::string(scid); -} - -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, bool syntonize, uint8_t priority1, - OSTimerQueueFactory *timerq_factory, OS_IPC *ipc, - OSLockFactory *lock_factory ) -{ - this->priority1 = priority1; - priority2 = 248; - - number_ports = 0; - - this->forceOrdinarySlave = forceOrdinarySlave; - - /*TODO: Make the values below configurable*/ - clock_quality.clockAccuracy = 0x22; - clock_quality.cq_class = 248; - clock_quality.offsetScaledLogVariance = 0x436A; - - time_source = 160; - - domain_number = 0; - - _syntonize = syntonize; - _new_syntonization_set_point = false; - _ppm = 0; - - _phase_error_violation = 0; - - _master_local_freq_offset_init = false; - _local_system_freq_offset_init = false; - - this->ipc = ipc; - - memset( &LastEBestIdentity, 0xFF, sizeof( LastEBestIdentity )); - - timerq_lock = lock_factory->createLock( oslock_recursive ); - - // This should be done LAST!! to pass fully initialized clock object - timerq = timerq_factory->createOSTimerQueue( this ); - - fup_info = new FollowUpTLV(); - fup_status = new FollowUpTLV(); - - return; -} - -bool IEEE1588Clock::serializeState( void *buf, off_t *count ) { - bool ret = true; - - if( buf == NULL ) { - *count = sizeof( _master_local_freq_offset ) + sizeof( _local_system_freq_offset ) + sizeof( LastEBestIdentity ); - return true; - } - - // Master-Local Frequency Offset - if( ret && *count >= (off_t) sizeof( _master_local_freq_offset )) { - memcpy - ( buf, &_master_local_freq_offset, - sizeof( _master_local_freq_offset )); - *count -= sizeof( _master_local_freq_offset ); - buf = ((char *)buf) + sizeof( _master_local_freq_offset ); - } else if( ret == false ) { - *count += sizeof( _master_local_freq_offset ); - } else { - *count = sizeof( _master_local_freq_offset )-*count; - ret = false; - } - - // Local-System Frequency Offset - if( ret && *count >= (off_t) sizeof( _local_system_freq_offset )) { - memcpy - ( buf, &_local_system_freq_offset,(off_t) - sizeof( _local_system_freq_offset )); - *count -= sizeof( _local_system_freq_offset ); - buf = ((char *)buf) + sizeof( _local_system_freq_offset ); - } else if( ret == false ) { - *count += sizeof( _local_system_freq_offset ); - } else { - *count = sizeof( _local_system_freq_offset )-*count; - ret = false; - } - - // LastEBestIdentity - if( ret && *count >= (off_t) sizeof( LastEBestIdentity )) { - memcpy( buf, &LastEBestIdentity, (off_t) sizeof( LastEBestIdentity )); - *count -= sizeof( LastEBestIdentity ); - buf = ((char *)buf) + sizeof( LastEBestIdentity ); - } else if( ret == false ) { - *count += sizeof( LastEBestIdentity ); - } else { - *count = sizeof( LastEBestIdentity )-*count; - ret = false; - } - - return ret; -} - -bool IEEE1588Clock::restoreSerializedState( void *buf, off_t *count ) { - bool ret = true; - - /* Master-Local Frequency Offset */ - if( ret && *count >= (off_t) sizeof( _master_local_freq_offset )) { - memcpy - ( &_master_local_freq_offset, buf, - sizeof( _master_local_freq_offset )); - *count -= sizeof( _master_local_freq_offset ); - buf = ((char *)buf) + sizeof( _master_local_freq_offset ); - } else if( ret == false ) { - *count += sizeof( _master_local_freq_offset ); - } else { - *count = sizeof( _master_local_freq_offset )-*count; - ret = false; - } - - /* Local-System Frequency Offset */ - if( ret && *count >= (off_t) sizeof( _local_system_freq_offset )) { - memcpy - ( &_local_system_freq_offset, buf, - sizeof( _local_system_freq_offset )); - *count -= sizeof( _local_system_freq_offset ); - buf = ((char *)buf) + sizeof( _local_system_freq_offset ); - } else if( ret == false ) { - *count += sizeof( _local_system_freq_offset ); - } else { - *count = sizeof( _local_system_freq_offset )-*count; - ret = false; - } - - /* LastEBestIdentity */ - if( ret && *count >= (off_t) sizeof( LastEBestIdentity )) { - memcpy( &LastEBestIdentity, buf, sizeof( LastEBestIdentity )); - *count -= sizeof( LastEBestIdentity ); - buf = ((char *)buf) + sizeof( LastEBestIdentity ); - } else if( ret == false ) { - *count += sizeof( LastEBestIdentity ); - } else { - *count = sizeof( LastEBestIdentity )-*count; - ret = false; - } - - return ret; -} - -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 -( CommonPort *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::addEventTimerLocked -( CommonPort *target, Event e, unsigned long long time_ns ) -{ - if( getTimerQLock() == oslock_fail ) return; - addEventTimer( target, e, time_ns ); - if( putTimerQLock() == oslock_fail ) return; -} - - - -void IEEE1588Clock::deleteEventTimer -( CommonPort *target, Event event ) -{ - timerq->cancelEvent((int)event, NULL); -} - -void IEEE1588Clock::deleteEventTimerLocked -( CommonPort *target, Event event ) -{ - if( getTimerQLock() == oslock_fail ) return; - - timerq->cancelEvent((int)event, NULL); - - if( putTimerQLock() == oslock_fail ) return; -} - -FrequencyRatio IEEE1588Clock::calcLocalSystemClockRateDifference( Timestamp local_time, Timestamp system_time ) { - unsigned long long inter_system_time; - unsigned long long inter_local_time; - FrequencyRatio ppt_offset; - - GPTP_LOG_DEBUG( "Calculated local to system clock rate difference" ); - - if( !_local_system_freq_offset_init ) { - _prev_system_time = system_time; - _prev_local_time = local_time; - - _local_system_freq_offset_init = true; - - return 1.0; - } - - inter_system_time = - TIMESTAMP_TO_NS(system_time) - TIMESTAMP_TO_NS(_prev_system_time); - inter_local_time = - TIMESTAMP_TO_NS(local_time) - TIMESTAMP_TO_NS(_prev_local_time); - - if( inter_system_time != 0 ) { - ppt_offset = ((FrequencyRatio)inter_local_time)/inter_system_time; - } else { - ppt_offset = 1.0; - } - - _prev_system_time = system_time; - _prev_local_time = local_time; - - return ppt_offset; -} - - - -FrequencyRatio IEEE1588Clock::calcMasterLocalClockRateDifference( Timestamp master_time, Timestamp sync_time ) { - unsigned long long inter_sync_time; - unsigned long long inter_master_time; - FrequencyRatio ppt_offset; - - GPTP_LOG_DEBUG( "Calculated master to local clock rate difference" ); - - if( !_master_local_freq_offset_init ) { - _prev_sync_time = sync_time; - _prev_master_time = master_time; - - _master_local_freq_offset_init = true; - - return 1.0; - } - - inter_sync_time = - TIMESTAMP_TO_NS(sync_time) - TIMESTAMP_TO_NS(_prev_sync_time); - - uint64_t master_time_ns = TIMESTAMP_TO_NS(master_time); - uint64_t prev_master_time_ns = TIMESTAMP_TO_NS(_prev_master_time); - - inter_master_time = master_time_ns - prev_master_time_ns; - - if( inter_sync_time != 0 ) { - ppt_offset = ((FrequencyRatio)inter_master_time)/inter_sync_time; - } else { - ppt_offset = 1.0; - } - - if( master_time_ns < prev_master_time_ns ) { - GPTP_LOG_ERROR("Negative time jump detected - inter_master_time: %lld, inter_sync_time: %lld, incorrect ppt_offset: %Lf", - inter_master_time, inter_sync_time, ppt_offset); - _master_local_freq_offset_init = false; - - return NEGATIVE_TIME_JUMP; - } - - _prev_sync_time = sync_time; - _prev_master_time = master_time; - - return ppt_offset; -} - -void IEEE1588Clock::setMasterOffset -( CommonPort *port, int64_t master_local_offset, - Timestamp local_time, FrequencyRatio master_local_freq_offset, - int64_t local_system_offset, Timestamp system_time, - FrequencyRatio local_system_freq_offset, unsigned sync_count, - unsigned pdelay_count, PortState port_state, bool asCapable ) -{ - _master_local_freq_offset = master_local_freq_offset; - _local_system_freq_offset = local_system_freq_offset; - - if (port->getTestMode()) { - GPTP_LOG_STATUS("Clock offset:%lld Clock rate ratio:%Lf Sync Count:%u PDelay Count:%u", - master_local_offset, master_local_freq_offset, sync_count, pdelay_count); - } - - if( ipc != NULL ) { - uint8_t grandmaster_id[PTP_CLOCK_IDENTITY_LENGTH]; - uint8_t clock_id[PTP_CLOCK_IDENTITY_LENGTH]; - PortIdentity port_identity; - uint16_t port_number; - - grandmaster_clock_identity.getIdentityString(grandmaster_id); - clock_identity.getIdentityString(clock_id); - port->getPortIdentity(port_identity); - port_identity.getPortNumber(&port_number); - - ipc->update( - master_local_offset, local_system_offset, master_local_freq_offset, - local_system_freq_offset, TIMESTAMP_TO_NS(local_time), - sync_count, pdelay_count, port_state, asCapable); - - ipc->update_grandmaster( - grandmaster_id, domain_number); - - ipc->update_network_interface( - clock_id, priority1, - clock_quality.cq_class, clock_quality.offsetScaledLogVariance, - clock_quality.clockAccuracy, - priority2, domain_number, - port->getSyncInterval(), - port->getAnnounceInterval(), - 0, // TODO: Was port->getPDelayInterval() before refactoring. What do we do now? - port_number); - } - - if( master_local_offset == 0 && master_local_freq_offset == 1.0 ) { - return; - } - - if( _syntonize ) { - if( _new_syntonization_set_point || _phase_error_violation > PHASE_ERROR_MAX_COUNT ) { - _new_syntonization_set_point = false; - _phase_error_violation = 0; - /* Make sure that there are no transmit operations - in progress */ - getTxLockAll(); - if (port->getTestMode()) { - GPTP_LOG_STATUS("Adjust clock phase offset:%lld", -master_local_offset); - } - port->adjustClockPhase( -master_local_offset ); - _master_local_freq_offset_init = false; - restartPDelayAll(); - putTxLockAll(); - master_local_offset = 0; - } - - // Adjust for frequency offset - long double phase_error = (long double) -master_local_offset; - if( fabsl(phase_error) > PHASE_ERROR_THRESHOLD ) { - ++_phase_error_violation; - } else { - _phase_error_violation = 0; - - float syncPerSec = (float)(1.0 / pow((float)2, port->getSyncInterval())); - _ppm += (float) ((INTEGRAL * syncPerSec * phase_error) + PROPORTIONAL*((master_local_freq_offset-1.0)*1000000)); - - GPTP_LOG_DEBUG("phase_error = %Lf, ppm = %f", phase_error, _ppm ); - } - - if( _ppm < LOWER_FREQ_LIMIT ) _ppm = LOWER_FREQ_LIMIT; - if( _ppm > UPPER_FREQ_LIMIT ) _ppm = UPPER_FREQ_LIMIT; - if ( port->getTestMode() ) { - GPTP_LOG_STATUS("Adjust clock rate ppm:%f", _ppm); - } - if( !port->adjustClockRate( _ppm ) ) { - GPTP_LOG_ERROR( "Failed to adjust clock rate" ); - } - } - - return; -} - -/* 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; - - if (msg == NULL) - return true; - - 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(this1 + 6); - msg->getGrandmasterIdentity((char *)that1 + 6); - -#if 0 - GPTP_LOG_DEBUG("(Clk)Us: "); - for (int i = 0; i < 14; ++i) - GPTP_LOG_DEBUG("%hhx ", this1[i]); - GPTP_LOG_DEBUG("(Clk)Them: "); - for (int i = 0; i < 14; ++i) - GPTP_LOG_DEBUG("%hhx ", that1[i]); -#endif - - return (memcmp(this1, that1, 14) < 0) ? true : false; -} - -IEEE1588Clock::~IEEE1588Clock(void) -{ - // Do nothing -} diff --git a/daemons/gptp/common/ini.c b/daemons/gptp/common/ini.c deleted file mode 100644 index 42da8066..00000000 --- a/daemons/gptp/common/ini.c +++ /dev/null @@ -1,176 +0,0 @@ -/* inih -- simple .INI file parser
-
-inih is released under the New BSD license (see LICENSE.txt). Go to the project
-home page for more info:
-
-http://code.google.com/p/inih/
-
-*/
-
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "ini.h"
-
-#if !INI_USE_STACK
-#include <stdlib.h>
-#endif
-
-#define MAX_SECTION 50
-#define MAX_NAME 50
-
-/* Strip whitespace chars off end of given string, in place. Return s. */
-static char* rstrip(char* s)
-{
- char* p = s + strlen(s);
- while (p > s && isspace(*--p))
- *p = '\0';
- return s;
-}
-
-/* Return pointer to first non-whitespace char in given string. */
-static char* lskip(const char* s)
-{
- while (*s && isspace(*s))
- s++;
- return (char*)s;
-}
-
-/* Return pointer to first char c or ';' comment in given string, or pointer to
- null at end of string if neither found. ';' must be prefixed by a whitespace
- character to register as a comment. */
-static char* find_char_or_comment(const char* s, char c)
-{
- int was_whitespace = 0;
- while (*s && *s != c && !(was_whitespace && *s == ';')) {
- was_whitespace = isspace(*s);
- s++;
- }
- return (char*)s;
-}
-
-/* Version of strncpy that ensures dest (size bytes) is null-terminated. */
-static char* strncpy0(char* dest, const char* src, size_t size)
-{
- strncpy(dest, src, size);
- dest[size - 1] = '\0';
- return dest;
-}
-
-/* See documentation in header file. */
-int ini_parse_file(FILE* file,
- int (*handler)(void*, const char*, const char*,
- const char*),
- void* user)
-{
- /* Uses a fair bit of stack (use heap instead if you need to) */
-#if INI_USE_STACK
- char line[INI_MAX_LINE];
-#else
- char* line;
-#endif
- char section[MAX_SECTION] = "";
- char prev_name[MAX_NAME] = "";
-
- char* start;
- char* end;
- char* name;
- char* value;
- int lineno = 0;
- int error = 0;
-
-#if !INI_USE_STACK
- line = (char*)malloc(INI_MAX_LINE);
- if (!line) {
- return -2;
- }
-#endif
-
- /* Scan through file line by line */
- while (fgets(line, INI_MAX_LINE, file) != NULL) {
- lineno++;
-
- start = line;
-#if INI_ALLOW_BOM
- if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
- (unsigned char)start[1] == 0xBB &&
- (unsigned char)start[2] == 0xBF) {
- start += 3;
- }
-#endif
- start = lskip(rstrip(start));
-
- if (*start == ';' || *start == '#') {
- /* Per Python ConfigParser, allow '#' comments at start of line */
- }
-#if INI_ALLOW_MULTILINE
- else if (*prev_name && *start && start > line) {
- /* Non-black line with leading whitespace, treat as continuation
- of previous name's value (as per Python ConfigParser). */
- if (!handler(user, section, prev_name, start) && !error)
- error = lineno;
- }
-#endif
- else if (*start == '[') {
- /* A "[section]" line */
- end = find_char_or_comment(start + 1, ']');
- if (*end == ']') {
- *end = '\0';
- strncpy0(section, start + 1, sizeof(section));
- *prev_name = '\0';
- }
- else if (!error) {
- /* No ']' found on section line */
- error = lineno;
- }
- }
- else if (*start && *start != ';') {
- /* Not a comment, must be a name[=:]value pair */
- end = find_char_or_comment(start, '=');
- if (*end != '=') {
- end = find_char_or_comment(start, ':');
- }
- if (*end == '=' || *end == ':') {
- *end = '\0';
- name = rstrip(start);
- value = lskip(end + 1);
- end = find_char_or_comment(value, '\0');
- if (*end == ';')
- *end = '\0';
- rstrip(value);
-
- /* Valid name[=:]value pair found, call handler */
- strncpy0(prev_name, name, sizeof(prev_name));
- if (!handler(user, section, name, value) && !error)
- error = lineno;
- }
- else if (!error) {
- /* No '=' or ':' found on name[=:]value line */
- error = lineno;
- }
- }
- }
-
-#if !INI_USE_STACK
- free(line);
-#endif
-
- return error;
-}
-
-/* See documentation in header file. */
-int ini_parse(const char* filename,
- int (*handler)(void*, const char*, const char*, const char*),
- void* user)
-{
- FILE* file;
- int error;
-
- file = fopen(filename, "r");
- if (!file)
- return -1;
- error = ini_parse_file(file, handler, user);
- fclose(file);
- return error;
-}
diff --git a/daemons/gptp/common/ini.h b/daemons/gptp/common/ini.h deleted file mode 100644 index b3a494a2..00000000 --- a/daemons/gptp/common/ini.h +++ /dev/null @@ -1,72 +0,0 @@ -/* inih -- simple .INI file parser
-
-inih is released under the New BSD license (see LICENSE.txt). Go to the project
-home page for more info:
-
-http://code.google.com/p/inih/
-
-*/
-
-#ifndef __INI_H__
-#define __INI_H__
-
-/* Make this header file easier to include in C++ code */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-
-/* Parse given INI-style file. May have [section]s, name=value pairs
- (whitespace stripped), and comments starting with ';' (semicolon). Section
- is "" if name=value pair parsed before any section heading. name:value
- pairs are also supported as a concession to Python's ConfigParser.
-
- For each name=value pair parsed, call handler function with given user
- pointer as well as section, name, and value (data only valid for duration
- of handler call). Handler should return nonzero on success, zero on error.
-
- Returns 0 on success, line number of first error on parse error (doesn't
- stop on first error), -1 on file open error, or -2 on memory allocation
- error (only when INI_USE_STACK is zero).
-*/
-int ini_parse(const char* filename,
- int (*handler)(void* user, const char* section,
- const char* name, const char* value),
- void* user);
-
-/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
- close the file when it's finished -- the caller must do that. */
-int ini_parse_file(FILE* file,
- int (*handler)(void* user, const char* section,
- const char* name, const char* value),
- void* user);
-
-/* Nonzero to allow multi-line value parsing, in the style of Python's
- ConfigParser. If allowed, ini_parse() will call the handler with the same
- name for each subsequent line parsed. */
-#ifndef INI_ALLOW_MULTILINE
-#define INI_ALLOW_MULTILINE 1
-#endif
-
-/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
- the file. See http://code.google.com/p/inih/issues/detail?id=21 */
-#ifndef INI_ALLOW_BOM
-#define INI_ALLOW_BOM 1
-#endif
-
-/* Nonzero to use stack, zero to use heap (malloc/free). */
-#ifndef INI_USE_STACK
-#define INI_USE_STACK 1
-#endif
-
-/* Maximum line length for any line in INI file. */
-#ifndef INI_MAX_LINE
-#define INI_MAX_LINE 200
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INI_H__ */
diff --git a/daemons/gptp/common/ipcdef.hpp b/daemons/gptp/common/ipcdef.hpp deleted file mode 100644 index 670aeeed..00000000 --- a/daemons/gptp/common/ipcdef.hpp +++ /dev/null @@ -1,120 +0,0 @@ -/****************************************************************************** - - 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 IPCDEF_HPP -#define IPCDEF_HPP - -/**@file - * This is a common header file. OS-specific implementations should use - * this file as base. Currently we have two IPC implementations: - * Linux: Located at linux/src/linux_ipc.hpp (among other files that include this) - * Windows: Located at windows/daemon_cl/windows_ipc.hpp -*/ - -#if defined (__unix__) || defined(__linux__) -#include <sys/types.h> - -/*Type for process id*/ -#define PID_TYPE pid_t - -#elif defined(_WIN32) || defined(_WIN64) - -/*Definition of DWORD*/ -#include <IntSafe.h> - -/*Type for process ID*/ -#define PID_TYPE DWORD - -#else -/*Create new ifdefs for different OSs and/or add to the existing ones*/ -#error "ERROR. OS not supported" -#endif /*__unix__ / _WIN*/ - -#include <ptptypes.hpp> - -/** - * @brief Provides a data structure for gPTP time - */ -typedef struct { - int64_t ml_phoffset; //!< Master to local phase offset - int64_t ls_phoffset; //!< Local to system phase offset - FrequencyRatio ml_freqoffset; //!< Master to local frequency offset - FrequencyRatio ls_freqoffset; //!< Local to system frequency offset - uint64_t local_time; //!< Local time of last update - - /* Current grandmaster information */ - /* Referenced by the IEEE Std 1722.1-2013 AVDECC Discovery Protocol Data Unit (ADPDU) */ - uint8_t gptp_grandmaster_id[PTP_CLOCK_IDENTITY_LENGTH]; //!< Current grandmaster id (all 0's if no grandmaster selected) - uint8_t gptp_domain_number; //!< gPTP domain number - - /* Grandmaster support for the network interface */ - /* Referenced by the IEEE Std 1722.1-2013 AVDECC AVB_INTERFACE descriptor */ - uint8_t clock_identity[PTP_CLOCK_IDENTITY_LENGTH]; //!< The clock identity of the interface - uint8_t priority1; //!< The priority1 field of the grandmaster functionality of the interface, or 0xFF if not supported - uint8_t clock_class; //!< The clockClass field of the grandmaster functionality of the interface, or 0xFF if not supported - int16_t offset_scaled_log_variance; //!< The offsetScaledLogVariance field of the grandmaster functionality of the interface, or 0x0000 if not supported - uint8_t clock_accuracy; //!< The clockAccuracy field of the grandmaster functionality of the interface, or 0xFF if not supported - uint8_t priority2; //!< The priority2 field of the grandmaster functionality of the interface, or 0xFF if not supported - uint8_t domain_number; //!< The domainNumber field of the grandmaster functionality of the interface, or 0 if not supported - int8_t log_sync_interval; //!< The currentLogSyncInterval field of the grandmaster functionality of the interface, or 0 if not supported - int8_t log_announce_interval; //!< The currentLogAnnounceInterval field of the grandmaster functionality of the interface, or 0 if not supported - int8_t log_pdelay_interval; //!< The currentLogPDelayReqInterval field of the grandmaster functionality of the interface, or 0 if not supported - uint16_t port_number; //!< The portNumber field of the interface, or 0x0000 if not supported - - /* Linux-specific */ - uint32_t sync_count; //!< Sync messages count - uint32_t pdelay_count; //!< pdelay messages count - bool asCapable; //!< asCapable flag: true = device is AS Capable; false otherwise - PortState port_state; //!< gPTP port state. It can assume values defined at ::PortState - PID_TYPE process_id; //!< Process id number -} gPtpTimeData; - -/* - - Integer64 <master-local phase offset> - Integer64 <local-system phase offset> - LongDouble <master-local frequency offset> - LongDouble <local-system frequency offset> - UInteger64 <local time of last update> - - * Meaning of IPC provided values: - - master ~= local - <master-local phase offset> - local ~= system - <local-system phase offset> - Dmaster ~= Dlocal * <master-local frequency offset> - Dlocal ~= Dsystem * <local-system freq offset> (where D denotes a delta) - -*/ - -#endif/*IPCDEF_HPP*/ - diff --git a/daemons/gptp/common/ptp_message.cpp b/daemons/gptp/common/ptp_message.cpp deleted file mode 100644 index 8dc6775c..00000000 --- a/daemons/gptp/common/ptp_message.cpp +++ /dev/null @@ -1,2018 +0,0 @@ -/****************************************************************************** - - 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 <ether_port.hpp> -#include <avbts_ostimer.hpp> -#include <ether_tstamper.hpp> - -#include <stdio.h> -#include <string.h> -#include <math.h> - -PTPMessageCommon::PTPMessageCommon( CommonPort *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); - flags[PTP_PTPTIMESCALE_BYTE] |= (0x1 << PTP_PTPTIMESCALE_BIT); - 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, - CommonPort *port ) -{ - OSTimer *timer = port->getTimerFactory()->createTimer(); - PTPMessageCommon *msg = NULL; - PTPMessageId messageId; - MessageType messageType; - unsigned char tspec_msg_t = 0; - unsigned char transportSpecific = 0; - - uint16_t sequenceId; - PortIdentity *sourcePortIdentity; - Timestamp timestamp(0, 0, 0); - unsigned counter_value = 0; - EtherPort *eport = NULL; - -#if PTP_DEBUG - { - int i; - GPTP_LOG_VERBOSE("Packet Dump:\n"); - for (i = 0; i < size; ++i) { - GPTP_LOG_VERBOSE("%hhx\t", buf[i]); - if (i % 8 == 7) - GPTP_LOG_VERBOSE("\n"); - } - if (i % 8 != 0) - GPTP_LOG_VERBOSE("\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); - transportSpecific = (tspec_msg_t >> 4) & 0x0F; - - 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); - - GPTP_LOG_VERBOSE("Captured Sequence Id: %u", sequenceId); - messageId.setMessageType(messageType); - messageId.setSequenceId(sequenceId); - - - if (!(messageType >> 3)) { - int iter = 5; - long req = 4000; // = 1 ms - - eport = dynamic_cast <EtherPort *> ( port ); - if (eport == NULL) - { - GPTP_LOG_ERROR - ( "Received Event Message, but port type " - "doesn't support timestamping\n" ); - goto abort; - } - - int ts_good = - eport->getRxTimestamp - (sourcePortIdentity, messageId, timestamp, counter_value, false); - while (ts_good != GPTP_EC_SUCCESS && iter-- != 0) { - // Waits at least 1 time slice regardless of size of 'req' - timer->sleep(req); - if (ts_good != GPTP_EC_EAGAIN) - GPTP_LOG_ERROR( - "Error (RX) timestamping RX event packet (Retrying), error=%d", - ts_good ); - ts_good = - eport->getRxTimestamp(sourcePortIdentity, messageId, - timestamp, counter_value, - iter == 0); - req *= 2; - } - if (ts_good != GPTP_EC_SUCCESS) { - char err_msg[HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE]; - port->getExtendedError(err_msg); - GPTP_LOG_ERROR - ("*** Received an event packet but cannot retrieve timestamp, discarding. messageType=%u,error=%d\n%s", - messageType, ts_good, msg); - //_exit(-1); - goto abort; - } - - else { - GPTP_LOG_VERBOSE("Timestamping event packet"); - } - - } - - if (1 != transportSpecific) { - GPTP_LOG_EXCEPTION("*** Received message with unsupported transportSpecific type=%d", transportSpecific); - goto abort; - } - - switch (messageType) { - case SYNC_MESSAGE: - - GPTP_LOG_DEBUG("*** Received Sync message" ); - GPTP_LOG_VERBOSE("Sync RX timestamp = %hu,%u,%u", timestamp.seconds_ms, timestamp.seconds_ls, timestamp.nanoseconds ); - - // Be sure buffer is the correction size - if (size < PTP_COMMON_HDR_LENGTH + PTP_SYNC_LENGTH) { - goto abort; - } - { - 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: - - GPTP_LOG_DEBUG("*** Received Follow Up message"); - - // Be sure buffer is the correction size - if (size < (int)(PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH + sizeof(FollowUpTLV))) { - goto abort; - } - { - 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); - - memcpy( &(followup_msg->tlv), - buf+PTP_FOLLOWUP_OFFSET+PTP_FOLLOWUP_LENGTH, - sizeof(followup_msg->tlv) ); - - msg = followup_msg; - } - - break; - case PATH_DELAY_REQ_MESSAGE: - - GPTP_LOG_DEBUG("*** 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 abort; - } - { - PTPMessagePathDelayReq *pdelay_req_msg = - new PTPMessagePathDelayReq(); - pdelay_req_msg->messageType = messageType; - -#if 0 - /*TODO: Do we need the code below? Can we remove it?*/ - // 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: - - GPTP_LOG_DEBUG("*** Received PDelay Response message, Timestamp %u (sec) %u (ns), seqID %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 abort; - } - { - 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 - GPTP_LOG_VERBOSE("%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: - - GPTP_LOG_DEBUG("*** Received PDelay Response FollowUp message"); - - // Be sure buffer is the correction size -// if( size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_FOLLOWUP_LENGTH ) { -// goto abort; -// } - { - 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: - - GPTP_LOG_VERBOSE("*** Received Announce message"); - - { - PTPMessageAnnounce *annc = new PTPMessageAnnounce(); - annc->messageType = messageType; - int tlv_length = size - PTP_COMMON_HDR_LENGTH + PTP_ANNOUNCE_LENGTH; - - 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->grandmasterClockQuality, - buf+ - PTP_ANNOUNCE_GRANDMASTER_CLOCK_QUALITY - (PTP_ANNOUNCE_OFFSET), - sizeof( *annc->grandmasterClockQuality )); - annc-> - grandmasterClockQuality->offsetScaledLogVariance = - PLAT_ntohs - ( annc->grandmasterClockQuality-> - 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)); - - // Parse TLV if it exists - buf += PTP_COMMON_HDR_LENGTH + PTP_ANNOUNCE_LENGTH; - if( tlv_length > (int) (2*sizeof(uint16_t)) && PLAT_ntohs(*((uint16_t *)buf)) == PATH_TRACE_TLV_TYPE) { - buf += sizeof(uint16_t); - tlv_length -= sizeof(uint16_t); - annc->tlv.parseClockIdentity((uint8_t *)buf, tlv_length); - } - - msg = annc; - } - break; - - case SIGNALLING_MESSAGE: - { - PTPMessageSignalling *signallingMsg = new PTPMessageSignalling(); - signallingMsg->messageType = messageType; - - memcpy(&(signallingMsg->targetPortIdentify), - buf + PTP_SIGNALLING_TARGET_PORT_IDENTITY(PTP_SIGNALLING_OFFSET), - sizeof(signallingMsg->targetPortIdentify)); - - memcpy( &(signallingMsg->tlv), buf + PTP_SIGNALLING_OFFSET + PTP_SIGNALLING_LENGTH, sizeof(signallingMsg->tlv) ); - - msg = signallingMsg; - } - break; - - default: - - GPTP_LOG_EXCEPTION("Received unsupported message type, %d", - (int)messageType); - port->incCounter_ieee8021AsPortStatRxPTPPacketDiscard(); - - goto abort; - } - - 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 = PLAT_ntohll(msg->correctionField); - 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)); - - if( eport != NULL ) - eport->addSockAddrMap( msg->sourcePortIdentity, remote ); - - msg->_timestamp = timestamp; - msg->_timestamp_counter_value = counter_value; - - delete timer; - - return msg; - -abort: - delete sourcePortIdentity; - delete timer; - - return NULL; -} - -bool PTPMessageCommon::getTxTimestamp( EtherPort *port, uint32_t link_speed ) -{ - OSTimer *timer = port->getTimerFactory()->createTimer(); - int ts_good; - Timestamp tx_timestamp; - uint32_t unused; - unsigned req = TX_TIMEOUT_BASE; - int iter = TX_TIMEOUT_ITER; - - ts_good = port->getTxTimestamp - ( this, tx_timestamp, unused, false ); - while( ts_good != GPTP_EC_SUCCESS && iter-- != 0 ) - { - timer->sleep(req); - if (ts_good != GPTP_EC_EAGAIN && iter < 1) - GPTP_LOG_ERROR( - "Error (TX) timestamping PDelay request " - "(Retrying-%d), error=%d", iter, ts_good); - ts_good = port->getTxTimestamp - ( this, tx_timestamp, unused , iter == 0 ); - req *= 2; - } - - if( ts_good == GPTP_EC_SUCCESS ) - { - Timestamp phy_compensation = port->getTxPhyDelay( link_speed ); - GPTP_LOG_DEBUG( "TX PHY compensation: %s sec", - phy_compensation.toString().c_str() ); - phy_compensation._version = tx_timestamp._version; - _timestamp = tx_timestamp + phy_compensation; - } else - { - char msg[HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE]; - port->getExtendedError(msg); - GPTP_LOG_ERROR( - "Error (TX) timestamping PDelay request, error=%d\t%s", - ts_good, msg); - _timestamp = INVALID_TIMESTAMP; - } - - delete timer; - return ts_good == GPTP_EC_SUCCESS; -} - -void PTPMessageCommon::processMessage( CommonPort *port ) -{ - _gc = true; - return; -} - -void PTPMessageCommon::buildCommonHeader(uint8_t * buf) -{ - unsigned char tspec_msg_t; - /*TODO: Message type assumes value sbetween 0x0 and 0xD (its an enumeration). - * So I am not sure why we are adding 0x10 to it - */ - tspec_msg_t = messageType | 0x10; - long long correctionField_BE = PLAT_htonll(correctionField); - 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 - ((uint8_t *) 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))); - - GPTP_LOG_VERBOSE("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) -{ - grandmasterClockQuality = new ClockQuality(); -} - -PTPMessageAnnounce::~PTPMessageAnnounce(void) -{ - delete grandmasterClockQuality; -} - -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] = grandmasterClockQuality->cq_class; - that1[1] = msg->getGrandmasterClockQuality()->cq_class; - - this1[2] = grandmasterClockQuality->clockAccuracy; - that1[2] = msg->getGrandmasterClockQuality()->clockAccuracy; - - tmp = grandmasterClockQuality->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 - GPTP_LOG_VERBOSE("Us: "); - for (int i = 0; i < 14; ++i) - GPTP_LOG_VERBOSE("%hhx", this1[i]); - GPTP_LOG_VERBOSE("\n"); - GPTP_LOG_VERBOSE("Them: "); - for (int i = 0; i < 14; ++i) - GPTP_LOG_VERBOSE("%hhx", that1[i]); - GPTP_LOG_VERBOSE("\n"); -#endif - - return (memcmp(this1, that1, 14) < 0) ? true : false; -} - - -PTPMessageSync::PTPMessageSync() { -} - -PTPMessageSync::~PTPMessageSync() { -} - -PTPMessageSync::PTPMessageSync( EtherPort *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; -} - -bool PTPMessageSync::sendPort -( EtherPort *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; - uint32_t link_speed; - - 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 - ( PTP_ETHERTYPE, buf_t, messageLength, MCAST_OTHER, - destIdentity, &link_speed ); - port->incCounter_ieee8021AsPortStatTxSyncCount(); - - return getTxTimestamp( port, link_speed ); -} - -PTPMessageAnnounce::PTPMessageAnnounce( CommonPort *port ) : - PTPMessageCommon( port ) -{ - messageType = ANNOUNCE_MESSAGE; // This is an event message - sequenceId = port->getNextAnnounceSequenceId(); - ClockIdentity id; - control = MESSAGE_OTHER; - ClockIdentity clock_identity; - - id = port->getClock()->getClockIdentity(); - tlv.appendClockIdentity(&id); - - currentUtcOffset = port->getClock()->getCurrentUtcOffset(); - grandmasterPriority1 = port->getClock()->getPriority1(); - grandmasterPriority2 = port->getClock()->getPriority2(); - grandmasterClockQuality = new ClockQuality(); - *grandmasterClockQuality = port->getClock()->getClockQuality(); - stepsRemoved = 0; - timeSource = port->getClock()->getTimeSource(); - clock_identity = port->getClock()->getGrandmasterClockIdentity(); - clock_identity.getIdentityString(grandmasterIdentity); - - logMeanMessageInterval = port->getAnnounceInterval(); - return; -} - -bool PTPMessageAnnounce::sendPort -( CommonPort *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 = *grandmasterClockQuality; - 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 + tlv.length(); - tspec_msg_t |= messageType & 0xF; - buildCommonHeader(buf_ptr); - memcpy(buf_ptr + PTP_ANNOUNCE_CURRENT_UTC_OFFSET(PTP_ANNOUNCE_OFFSET), - ¤tUtcOffset_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_l)); - memcpy(buf_ptr + - PTP_ANNOUNCE_GRANDMASTER_PRIORITY2(PTP_ANNOUNCE_OFFSET), - &grandmasterPriority2, sizeof(grandmasterPriority2)); - memcpy( buf_ptr+ - PTP_ANNOUNCE_GRANDMASTER_IDENTITY(PTP_ANNOUNCE_OFFSET), - grandmasterIdentity, PTP_CLOCK_IDENTITY_LENGTH ); - 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(PTP_ETHERTYPE, buf_t, messageLength, MCAST_OTHER, destIdentity); - port->incCounter_ieee8021AsPortStatTxAnnounce(); - - return true; -} - -void PTPMessageAnnounce::processMessage( CommonPort *port ) -{ - ClockIdentity my_clock_identity; - - port->incCounter_ieee8021AsPortStatRxAnnounce(); - - // Delete announce receipt timeout - port->getClock()->deleteEventTimerLocked - (port, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES); - - if( stepsRemoved >= 255 ) goto bail; - - // Reject Announce message from myself - my_clock_identity = port->getClock()->getClockIdentity(); - if( sourcePortIdentity->getClockIdentity() == my_clock_identity ) { - goto bail; - } - - if(tlv.has(&my_clock_identity)) { - goto bail; - } - - // Add message to the list - port->setQualifiedAnnounce( this ); - - port->getClock()->addEventTimerLocked(port, STATE_CHANGE_EVENT, 16000000); - bail: - port->getClock()->addEventTimerLocked - (port, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES, - (unsigned long long) - (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER * - (pow - ((double)2, - port->getAnnounceInterval()) * - 1000000000.0))); -} - -void PTPMessageSync::processMessage( CommonPort *port ) -{ - EtherPort *eport = dynamic_cast <EtherPort *> (port); - PTPMessageSync *old_sync; - - if (eport == NULL) - { - GPTP_LOG_ERROR( "Discarding sync message on wrong port type" ); - _gc = true; - goto done; - } - - if (port->getPortState() == PTP_DISABLED ) { - // Do nothing Sync messages should be ignored in this state - return; - } - if (port->getPortState() == PTP_FAULTY) { - // According to spec recovery is implementation specific - eport->recoverPort(); - return; - } - - port->incCounter_ieee8021AsPortStatRxSyncCount(); - -#if CHECK_ASSIST_BIT - if( flags[PTP_ASSIST_BYTE] & (0x1<<PTP_ASSIST_BIT)) { -#endif - old_sync = eport->getLastSync(); - - if (old_sync != NULL) { - delete old_sync; - } - eport->setLastSync(this); - _gc = false; - goto done; -#if CHECK_ASSIST_BIT - } else { - GPTP_LOG_ERROR("PTP assist flag is not set, discarding invalid sync"); - _gc = true; - goto done; - } -#endif - - done: - return; -} - -PTPMessageFollowUp::PTPMessageFollowUp( CommonPort *port ) : - PTPMessageCommon( port ) -{ - messageType = FOLLOWUP_MESSAGE; /* This is an event message */ - control = FOLLOWUP; - - logMeanMessageInterval = port->getSyncInterval(); - - return; -} - -size_t PTPMessageFollowUp::buildMessage( CommonPort *port, uint8_t *buf_ptr ) -{ - /* Create packet in buf - Copy in common header */ - messageLength = - PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH + sizeof(tlv); - unsigned char tspec_msg_t = 0; - Timestamp preciseOriginTimestamp_BE; - - 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)); - - /*Change time base indicator to Network Order before sending it*/ - uint16_t tbi_NO = PLAT_htonl(tlv.getGMTimeBaseIndicator()); - tlv.setGMTimeBaseIndicator(tbi_NO); - tlv.toByteString(buf_ptr + PTP_COMMON_HDR_LENGTH + - PTP_FOLLOWUP_LENGTH); - - port->incCounter_ieee8021AsPortStatTxFollowUpCount(); - - return PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH + sizeof(tlv); -} - -bool PTPMessageFollowUp::sendPort -( EtherPort *port, PortIdentity *destIdentity ) -{ - uint8_t buf_t[256]; - uint8_t *buf_ptr = buf_t + port->getPayloadOffset(); - memset(buf_t, 0, 256); - /* Create packet in buf - Copy in common header */ - buildMessage(port, buf_ptr); - - GPTP_LOG_VERBOSE( "Follow-Up Time: %u seconds(hi)", - preciseOriginTimestamp.seconds_ms); - GPTP_LOG_VERBOSE( "Follow-Up Time: %u seconds", - preciseOriginTimestamp.seconds_ls); - GPTP_LOG_VERBOSE( "FW-UP Time: %u nanoseconds", - preciseOriginTimestamp.nanoseconds); - GPTP_LOG_VERBOSE( "FW-UP Time: %x seconds", - preciseOriginTimestamp.seconds_ls); - GPTP_LOG_VERBOSE( "FW-UP Time: %x nanoseconds", - preciseOriginTimestamp.nanoseconds); -#ifdef DEBUG - GPTP_LOG_VERBOSE("Follow-up Dump:"); - for (int i = 0; i < messageLength; ++i) { - GPTP_LOG_VERBOSE("%d:%02x ", i, (unsigned char)buf_t[i]); - } -#endif - - port->sendGeneralPort( PTP_ETHERTYPE, buf_t, messageLength, - MCAST_OTHER, destIdentity ); - - return true; -} - -void PTPMessageFollowUp::processMessage -( CommonPort *port, Timestamp sync_arrival ) -{ - uint64_t delay; - Timestamp system_time(0, 0, 0); - Timestamp device_time(0, 0, 0); - - signed long long local_system_offset; - signed long long scalar_offset; - - FrequencyRatio local_clock_adjustment; - FrequencyRatio local_system_freq_offset; - FrequencyRatio master_local_freq_offset; - int64_t correction; - int32_t scaledLastGmFreqChange = 0; - scaledNs scaledLastGmPhaseChange; - - port->incCounter_ieee8021AsPortStatRxFollowUpCount(); - - if (!port->getLinkDelay(&delay)) - { - GPTP_LOG_ERROR( "Received Follow up but " - "there is no valid link delay" ); - goto done; - } - - master_local_freq_offset = tlv.getRateOffset(); - master_local_freq_offset /= 1ULL << 41; - master_local_freq_offset += 1.0; - master_local_freq_offset /= port->getPeerRateOffset(); - - correctionField /= 1 << 16; - correction = (int64_t) - ((delay * master_local_freq_offset) + correctionField); - - if (correction > 0) - TIMESTAMP_ADD_NS(preciseOriginTimestamp, correction); - else TIMESTAMP_SUB_NS(preciseOriginTimestamp, -correction); - - local_clock_adjustment = - port->getClock()-> - calcMasterLocalClockRateDifference - (preciseOriginTimestamp, sync_arrival); - - if( local_clock_adjustment == NEGATIVE_TIME_JUMP ) - { - GPTP_LOG_VERBOSE - ( "Received Follow Up but preciseOrigintimestamp " - "indicates negative time jump" ); - goto done; - } - - scalar_offset = TIMESTAMP_TO_NS( sync_arrival ); - scalar_offset -= TIMESTAMP_TO_NS( preciseOriginTimestamp ); - - GPTP_LOG_VERBOSE( "Followup Correction Field: %lld, Link Delay: %lu", - correctionField, delay ); - GPTP_LOG_VERBOSE( "FollowUp Scalar = %lld", - scalar_offset ); - - - /* Otherwise synchronize clock with approximate Sync time */ - uint32_t local_clock, nominal_clock_rate; - uint32_t device_sync_time_offset; - - port->getDeviceTime(system_time, device_time, local_clock, - nominal_clock_rate); - GPTP_LOG_VERBOSE( "Device Time = %llu,System Time = %llu", - TIMESTAMP_TO_NS( device_time ), - TIMESTAMP_TO_NS( system_time )); - - /* Adjust local_clock to correspond to sync_arrival */ - device_sync_time_offset = (uint32_t) - ( TIMESTAMP_TO_NS( device_time ) - - TIMESTAMP_TO_NS( sync_arrival )); - - GPTP_LOG_VERBOSE - ( "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); - - /*Update information on local status structure.*/ - scaledLastGmFreqChange = (int32_t) - ((1.0 / local_clock_adjustment - 1.0) * (1ULL << 41)); - scaledLastGmPhaseChange.setLSB(tlv.getRateOffset( )); - port->getClock()->getFUPStatus()->setScaledLastGmFreqChange - ( scaledLastGmFreqChange ); - port->getClock()->getFUPStatus()->setScaledLastGmPhaseChange - ( scaledLastGmPhaseChange ); - - if( port->getPortState() == PTP_SLAVE ) - { - /* - * The sync_count counts the number of sync messages received - * that influence the time on the device. Since adjustments are - * only made in the PTP_SLAVE state, increment it here - */ - port->incSyncCount(); - - /* - * Do not call calcLocalSystemClockRateDifference it updates - * state global to the clock object and if we are master then - * the network is transitioning to us not being master but - * the master process is still running locally - */ - local_system_freq_offset = port->getClock() - ->calcLocalSystemClockRateDifference - ( device_time, system_time ); - TIMESTAMP_SUB_NS - (system_time, (uint64_t) - (((FrequencyRatio)device_sync_time_offset) / - local_system_freq_offset)); - local_system_offset = - TIMESTAMP_TO_NS( system_time ) - - TIMESTAMP_TO_NS( sync_arrival ); - - port->getClock()->setMasterOffset - ( port, scalar_offset, sync_arrival, local_clock_adjustment, - local_system_offset, system_time, local_system_freq_offset, - port->getSyncCount(), port->getPdelayCount(), - port->getPortState(), port->getAsCapable( )); - - port->syncDone(); - // Restart the SYNC_RECEIPT timer - port->startSyncReceiptTimer((unsigned long long) - (SYNC_RECEIPT_TIMEOUT_MULTIPLIER * - ((double)pow((double)2, port->getSyncInterval()) * - 1000000000.0))); - } - - uint16_t lastGmTimeBaseIndicator; - lastGmTimeBaseIndicator = port->getLastGmTimeBaseIndicator(); - if (( lastGmTimeBaseIndicator > 0 ) && - ( tlv.getGmTimeBaseIndicator( ) != lastGmTimeBaseIndicator )) - { - GPTP_LOG_EXCEPTION( "Sync discontinuity" ); - } - port->setLastGmTimeBaseIndicator( tlv.getGmTimeBaseIndicator( )); - -done: - _gc = true; - - return; -} - -void PTPMessageFollowUp::processMessage( CommonPort *port ) -{ - Timestamp sync_arrival; - EtherPort *eport = dynamic_cast <EtherPort *> (port); - if (eport == NULL) - { - GPTP_LOG_ERROR - ( "Discarding followup message on wrong port type" ); - return; - } - - GPTP_LOG_DEBUG("Processing a follow-up message"); - - // Expire any SYNC_RECEIPT timers that exist - port->stopSyncReceiptTimer(); - - if (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 - eport->recoverPort(); - return; - } - - PTPMessageSync *sync = eport->getLastSync(); - { - PortIdentity sync_id; - if( sync == NULL ) - { - GPTP_LOG_ERROR("Received Follow Up but there is no " - "sync message"); - return; - } - sync->getPortIdentity(&sync_id); - - if( sync->getSequenceId() != sequenceId || - sync_id != *sourcePortIdentity ) - { - unsigned int cnt = 0; - - if( !port->incWrongSeqIDCounter( &cnt )) - { - port->becomeMaster( true ); - port->setWrongSeqIDCounter(0); - } - GPTP_LOG_ERROR - ( "Received Follow Up %d times but cannot " - "find corresponding Sync", cnt ); - goto done; - } - } - - if( sync->getTimestamp()._version != port->getTimestampVersion( )) - { - GPTP_LOG_ERROR( "Received Follow Up but timestamp version " - "indicates Sync is out of date" ); - goto done; - } - - sync_arrival = sync->getTimestamp(); - - processMessage(port, sync_arrival); - -done: - eport->setLastSync(NULL); - delete sync; -} - -PTPMessagePathDelayReq::PTPMessagePathDelayReq -( EtherPort *port ) : PTPMessageCommon( port ) -{ - logMeanMessageInterval = 0; - control = MESSAGE_OTHER; - messageType = PATH_DELAY_REQ_MESSAGE; - sequenceId = port->getNextPDelaySequenceId(); - return; -} - -void PTPMessagePathDelayReq::processMessage( CommonPort *port ) -{ - OSTimer *timer = port->getTimerFactory()->createTimer(); - PortIdentity resp_fwup_id; - PortIdentity requestingPortIdentity_p; - PTPMessagePathDelayResp *resp; - PortIdentity resp_id; - PTPMessagePathDelayRespFollowUp *resp_fwup; - - EtherPort *eport = dynamic_cast <EtherPort *> (port); - if (eport == NULL) - { - GPTP_LOG_ERROR( "Received Pdelay Request on wrong port type" ); - goto done; - } - - if (port->getPortState() == PTP_DISABLED) { - // Do nothing all messages should be ignored when in this state - goto done; - } - - if (port->getPortState() == PTP_FAULTY) { - // According to spec recovery is implementation specific - eport->recoverPort(); - goto done; - } - - port->incCounter_ieee8021AsPortStatRxPdelayRequest(); - - /* Generate and send message */ - resp = new PTPMessagePathDelayResp(eport); - port->getPortIdentity(resp_id); - resp->setPortIdentity(&resp_id); - resp->setSequenceId(sequenceId); - - GPTP_LOG_DEBUG("Process PDelay Request SeqId: %u\t", sequenceId); - -#ifdef DEBUG - for (int n = 0; n < PTP_CLOCK_IDENTITY_LENGTH; ++n) { - GPTP_LOG_VERBOSE("%c", resp_id.clockIdentity[n]); - } -#endif - - this->getPortIdentity(&requestingPortIdentity_p); - resp->setRequestingPortIdentity(&requestingPortIdentity_p); - resp->setRequestReceiptTimestamp(_timestamp); - - port->getTxLock(); - resp->sendPort(eport, sourcePortIdentity); - GPTP_LOG_DEBUG("*** Sent PDelay Response message"); - port->putTxLock(); - - if( resp->getTimestamp()._version != _timestamp._version ) { - GPTP_LOG_ERROR("TX timestamp version mismatch: %u/%u", - resp->getTimestamp()._version, _timestamp._version); -#if 0 // discarding the request could lead to the peer setting the link to non-asCapable - delete resp; - goto done; -#endif - } - - resp_fwup = new PTPMessagePathDelayRespFollowUp(eport); - port->getPortIdentity(resp_fwup_id); - resp_fwup->setPortIdentity(&resp_fwup_id); - resp_fwup->setSequenceId(sequenceId); - resp_fwup->setRequestingPortIdentity(sourcePortIdentity); - resp_fwup->setResponseOriginTimestamp(resp->getTimestamp()); - long long turnaround; - turnaround = (resp->getTimestamp().seconds_ls - _timestamp.seconds_ls) - * 1000000000LL; - - GPTP_LOG_VERBOSE("Response Depart(sec): %u", - resp->getTimestamp().seconds_ls); - GPTP_LOG_VERBOSE("Request Arrival(sec): %u", _timestamp.seconds_ls); - GPTP_LOG_VERBOSE("#1 Correction Field: %Ld", turnaround); - - turnaround += resp->getTimestamp().nanoseconds; - - GPTP_LOG_VERBOSE("#2 Correction Field: %Ld", turnaround); - - turnaround -= _timestamp.nanoseconds; - - GPTP_LOG_VERBOSE("#3 Correction Field: %Ld", turnaround); - - resp_fwup->setCorrectionField(0); - resp_fwup->sendPort(eport, sourcePortIdentity); - - GPTP_LOG_DEBUG("*** Sent PDelay Response FollowUp message"); - - delete resp; - delete resp_fwup; - -done: - delete timer; - _gc = true; - return; -} - -bool PTPMessagePathDelayReq::sendPort -( EtherPort *port, PortIdentity *destIdentity ) -{ - uint32_t link_speed; - - if(port->pdelayHalted()) - return false; - - 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); - port->sendEventPort - ( PTP_ETHERTYPE, buf_t, messageLength, MCAST_PDELAY, - destIdentity, &link_speed ); - port->incCounter_ieee8021AsPortStatTxPdelayRequest(); - - return getTxTimestamp( port, link_speed ); -} - -PTPMessagePathDelayResp::PTPMessagePathDelayResp -( EtherPort *port ) : PTPMessageCommon( port ) -{ - /*TODO: Why 0x7F?*/ - logMeanMessageInterval = 0x7F; - 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( CommonPort *port ) -{ - EtherPort *eport = dynamic_cast <EtherPort *> (port); - if (eport == NULL) - { - GPTP_LOG_ERROR( "Received Pdelay Resp on wrong port type" ); - _gc = true; - return; - } - - if (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 - eport->recoverPort(); - return; - } - - port->incCounter_ieee8021AsPortStatRxPdelayResponse(); - - if (eport->tryPDelayRxLock() != true) { - GPTP_LOG_ERROR("Failed to get PDelay RX Lock"); - return; - } - - PortIdentity resp_id; - PortIdentity oldresp_id; - uint16_t resp_port_number; - uint16_t oldresp_port_number; - - PTPMessagePathDelayResp *old_pdelay_resp = eport->getLastPDelayResp(); - if( old_pdelay_resp == NULL ) { - goto bypass_verify_duplicate; - } - - old_pdelay_resp->getPortIdentity(&oldresp_id); - oldresp_id.getPortNumber(&oldresp_port_number); - getPortIdentity(&resp_id); - resp_id.getPortNumber(&resp_port_number); - - /* In the case where we have multiple PDelay responses for the same - * PDelay request, and they come from different sources, it is necessary - * to verify if this happens 3 times (sequentially). If it does, PDelayRequests - * are halted for 5 minutes - */ - if( getSequenceId() == old_pdelay_resp->getSequenceId() ) - { - /*If the duplicates are in sequence and from different sources*/ - if( (resp_port_number != oldresp_port_number ) && ( - (eport->getLastInvalidSeqID() + 1 ) == getSequenceId() || - eport->getDuplicateRespCounter() == 0 ) ){ - GPTP_LOG_ERROR("Two responses for same Request. seqID %d. First Response Port# %hu. Second Port# %hu. Counter %d", - getSequenceId(), oldresp_port_number, resp_port_number, eport->getDuplicateRespCounter()); - - if( eport->incrementDuplicateRespCounter() ) { - GPTP_LOG_ERROR("Remote misbehaving. Stopping PDelay Requests for 5 minutes."); - eport->stopPDelay(); - eport->getClock()->addEventTimerLocked - (port, PDELAY_RESP_PEER_MISBEHAVING_TIMEOUT_EXPIRES, (int64_t)(300 * 1000000000.0)); - } - } - else { - eport->setDuplicateRespCounter(0); - } - eport->setLastInvalidSeqID(getSequenceId()); - } - else - { - eport->setDuplicateRespCounter(0); - } - -bypass_verify_duplicate: - eport->setLastPDelayResp(this); - - if (old_pdelay_resp != NULL) { - delete old_pdelay_resp; - } - - eport->putPDelayRxLock(); - _gc = false; - - return; -} - -bool PTPMessagePathDelayResp::sendPort -( EtherPort *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; - uint32_t link_speed; - - 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 - (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)); - - GPTP_LOG_VERBOSE("PDelay Resp Timestamp: %u,%u", - requestReceiptTimestamp.seconds_ls, - requestReceiptTimestamp.nanoseconds); - - port->sendEventPort - ( PTP_ETHERTYPE, buf_t, messageLength, MCAST_PDELAY, - destIdentity, &link_speed ); - port->incCounter_ieee8021AsPortStatTxPdelayResponse(); - - return getTxTimestamp( port, link_speed ); -} - -void PTPMessagePathDelayResp::setRequestingPortIdentity -(PortIdentity * identity) -{ - *requestingPortIdentity = *identity; -} - -void PTPMessagePathDelayResp::getRequestingPortIdentity -(PortIdentity * identity) -{ - *identity = *requestingPortIdentity; -} - -PTPMessagePathDelayRespFollowUp::PTPMessagePathDelayRespFollowUp -( EtherPort *port ) : PTPMessageCommon( port ) -{ - logMeanMessageInterval = 0x7F; - control = MESSAGE_OTHER; - messageType = PATH_DELAY_FOLLOWUP_MESSAGE; - versionPTP = GPTP_VERSION; - requestingPortIdentity = new PortIdentity(); - - return; -} - -PTPMessagePathDelayRespFollowUp::~PTPMessagePathDelayRespFollowUp() -{ - delete requestingPortIdentity; -} - -#define US_PER_SEC 1000000 -void PTPMessagePathDelayRespFollowUp::processMessage -( CommonPort *port ) -{ - PTPMessagePathDelayReq *req; - PTPMessagePathDelayResp *resp; - - 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); - - EtherPort *eport = dynamic_cast <EtherPort *> (port); - if (eport == NULL) - { - GPTP_LOG_ERROR( "Received Pdelay Response FollowUp on wrong " - "port type" ); - goto abort; - } - - if (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 - eport->recoverPort(); - return; - } - - port->incCounter_ieee8021AsPortStatRxPdelayResponseFollowUp(); - - if (eport->tryPDelayRxLock() != true) - return; - - req = eport->getLastPDelayReq(); - resp = eport->getLastPDelayResp(); - - if (req == NULL) { - /* Shouldn't happen */ - GPTP_LOG_ERROR - (">>> Received PDelay followup but no REQUEST exists"); - goto abort; - } - - if (resp == NULL) { - /* Probably shouldn't happen either */ - GPTP_LOG_ERROR - (">>> Received PDelay followup but no RESPONSE exists"); - - goto abort; - } - - if( req->getSequenceId() != sequenceId ) { - GPTP_LOG_ERROR - ( "Received PDelay FUP has different seqID than the " - "PDelay request (%d/%d)", - sequenceId, req->getSequenceId() ); - goto abort; - } - - { - PortIdentity req_id; - PortIdentity resp_id; - uint16_t resp_port_number; - uint16_t req_port_number; - - ClockIdentity resp_clkId = resp_id.getClockIdentity(); - ClockIdentity req_clkId = req_id.getClockIdentity(); - PortIdentity fup_sourcePortIdentity; - PortIdentity resp_sourcePortIdentity; - - req->getPortIdentity(&req_id); - resp->getRequestingPortIdentity(&resp_id); - - resp_id.getPortNumber(&resp_port_number); - requestingPortIdentity->getPortNumber(&req_port_number); - - resp->getPortIdentity(&resp_sourcePortIdentity); - getPortIdentity(&fup_sourcePortIdentity); - - /* - * IEEE 802.1AS, Figure 11-8, subclause 11.2.15.3 - */ - if (resp->getSequenceId() != sequenceId) { - GPTP_LOG_ERROR - ("Received PDelay Response Follow Up but cannot find " - "corresponding response"); - GPTP_LOG_ERROR( "%hu, %hu, %hu, %hu", - resp->getSequenceId(), sequenceId, - resp_port_number, req_port_number ); - - goto abort; - } - - /* - * IEEE 802.1AS, Figure 11-8, subclause 11.2.15.3 - */ - if (req_clkId != resp_clkId) { - GPTP_LOG_ERROR - ( "ClockID Resp/Req differs. PDelay Response ClockID: " - "%s PDelay Request ClockID: %s", - req_clkId.getIdentityString().c_str(), - resp_clkId.getIdentityString().c_str( )); - goto abort; - } - - /* - * IEEE 802.1AS, Figure 11-8, subclause 11.2.15.3 - */ - if (resp_port_number != req_port_number) { - GPTP_LOG_ERROR - ( "Request port number (%hu) is different from " - "Response port number (%hu)", - req_port_number, resp_port_number ); - - goto abort; - } - - /* - * IEEE 802.1AS, Figure 11-8, subclause 11.2.15.3 - */ - if (fup_sourcePortIdentity != resp_sourcePortIdentity) { - GPTP_LOG_ERROR( "Source port identity from " - "PDelay Response/FUP differ" ); - - goto abort; - } - } - - port->getClock()->deleteEventTimerLocked - (port, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES); - - GPTP_LOG_VERBOSE("Request Sequence Id: %u", req->getSequenceId()); - GPTP_LOG_VERBOSE("Response Sequence Id: %u", resp->getSequenceId()); - GPTP_LOG_VERBOSE("Follow-Up Sequence Id: %u", sequenceId); - - 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 == INVALID_TIMESTAMP.nanoseconds ) - { - /* Stop processing the packet */ - goto abort; - } - - if (request_tx_timestamp.nanoseconds == - PDELAY_PENDING_TIMESTAMP.nanoseconds) { - // Defer processing - if( - eport->getLastPDelayRespFollowUp() != NULL && - eport->getLastPDelayRespFollowUp() != this ) - { - delete eport->getLastPDelayRespFollowUp(); - } - eport->setLastPDelayRespFollowUp(this); - port->getClock()->addEventTimerLocked - (port, PDELAY_DEFERRED_PROCESSING, 1000000); - goto defer; - } - remote_req_rx_timestamp = resp->getRequestReceiptTimestamp(); - response_rx_timestamp = resp->getTimestamp(); - remote_resp_tx_timestamp = responseOriginTimestamp; - - if( request_tx_timestamp._version != response_rx_timestamp._version ) { - GPTP_LOG_ERROR("RX timestamp version mismatch %d/%d", - request_tx_timestamp._version, response_rx_timestamp._version ); - goto abort; - } - - port->incPdelayCount(); - - - 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); - - 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); - - // Adjust turn-around time for peer to local clock rate difference - // TODO: Are these .998 and 1.002 specifically defined in the standard? - // Should we create a define for them ? - if - ( port->getPeerRateOffset() > .998 && - port->getPeerRateOffset() < 1.002 ) { - turn_around = (int64_t) - (turn_around * port->getPeerRateOffset()); - } - - GPTP_LOG_VERBOSE - ("Turn Around Adjustment %Lf", - ((long long)turn_around * port->getPeerRateOffset()) / - 1000000000000LL); - GPTP_LOG_VERBOSE - ("Step #1: Turn Around Adjustment %Lf", - ((long long)turn_around * port->getPeerRateOffset())); - GPTP_LOG_VERBOSE("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; - GPTP_LOG_DEBUG( "Link delay: %ld ns", link_delay ); - - { - uint64_t mine_elapsed; - uint64_t theirs_elapsed; - Timestamp prev_peer_ts_mine; - Timestamp prev_peer_ts_theirs; - FrequencyRatio rate_offset; - if( port->getPeerOffset( prev_peer_ts_mine, prev_peer_ts_theirs )) { - FrequencyRatio upper_ratio_limit, lower_ratio_limit; - upper_ratio_limit = - PPM_OFFSET_TO_RATIO(UPPER_LIMIT_PPM); - lower_ratio_limit = - PPM_OFFSET_TO_RATIO(LOWER_LIMIT_PPM); - - 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); - theirs_elapsed -= port->getLinkDelay(); - theirs_elapsed += link_delay < 0 ? 0 : link_delay; - rate_offset = ((FrequencyRatio) mine_elapsed) - / theirs_elapsed; - - if( rate_offset < upper_ratio_limit && - rate_offset > lower_ratio_limit ) - port->setPeerRateOffset(rate_offset); - } - } - if( !port->setLinkDelay( link_delay )) - { - if( !eport->getAutomotiveProfile( )) - { - GPTP_LOG_ERROR( "Link delay %ld beyond " - "neighborPropDelayThresh; " - "not AsCapable", link_delay ); - port->setAsCapable( false ); - } - } else - { - if( !eport->getAutomotiveProfile( )) - port->setAsCapable( true ); - } - port->setPeerOffset( request_tx_timestamp, remote_req_rx_timestamp ); - - abort: - delete resp; - eport->setLastPDelayResp(NULL); - - _gc = true; - - defer: - eport->putPDelayRxLock(); - - return; -} - -bool PTPMessagePathDelayRespFollowUp::sendPort -( EtherPort *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 - (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)); - - GPTP_LOG_VERBOSE("PDelay Resp Timestamp: %u,%u", - responseOriginTimestamp.seconds_ls, - responseOriginTimestamp.nanoseconds); - - port->sendGeneralPort(PTP_ETHERTYPE, buf_t, messageLength, MCAST_PDELAY, destIdentity); - port->incCounter_ieee8021AsPortStatTxPdelayResponseFollowUp(); - - return true; -} - -void PTPMessagePathDelayRespFollowUp::setRequestingPortIdentity -(PortIdentity * identity) -{ - *requestingPortIdentity = *identity; -} - - - PTPMessageSignalling::PTPMessageSignalling(void) -{ -} - -PTPMessageSignalling::PTPMessageSignalling -( EtherPort *port ) : PTPMessageCommon( port ) -{ - messageType = SIGNALLING_MESSAGE; - sequenceId = port->getNextSignalSequenceId(); - - targetPortIdentify = (int8_t)0xff; - - control = MESSAGE_OTHER; - - logMeanMessageInterval = 0x7F; // 802.1AS 2011 10.5.2.2.11 logMessageInterval (Integer8) -} - - PTPMessageSignalling::~PTPMessageSignalling(void) -{ -} - -void PTPMessageSignalling::setintervals(int8_t linkDelayInterval, int8_t timeSyncInterval, int8_t announceInterval) -{ - tlv.setLinkDelayInterval(linkDelayInterval); - tlv.setTimeSyncInterval(timeSyncInterval); - tlv.setAnnounceInterval(announceInterval); -} - -bool PTPMessageSignalling::sendPort -( EtherPort *port, PortIdentity *destIdentity ) -{ - uint8_t buf_t[256]; - uint8_t *buf_ptr = buf_t + port->getPayloadOffset(); - unsigned char tspec_msg_t = 0x0; - - memset(buf_t, 0, 256); - // Create packet in buf - // Copy in common header - messageLength = PTP_COMMON_HDR_LENGTH + PTP_SIGNALLING_LENGTH + sizeof(tlv); - tspec_msg_t |= messageType & 0xF; - buildCommonHeader(buf_ptr); - - memcpy(buf_ptr + PTP_SIGNALLING_TARGET_PORT_IDENTITY(PTP_SIGNALLING_OFFSET), - &targetPortIdentify, sizeof(targetPortIdentify)); - - tlv.toByteString(buf_ptr + PTP_COMMON_HDR_LENGTH + PTP_SIGNALLING_LENGTH); - - port->sendGeneralPort(PTP_ETHERTYPE, buf_t, messageLength, MCAST_OTHER, destIdentity); - - return true; -} - -void PTPMessageSignalling::processMessage( CommonPort *port ) -{ - long long unsigned int waitTime; - - GPTP_LOG_STATUS("Signalling Link Delay Interval: %d", tlv.getLinkDelayInterval()); - GPTP_LOG_STATUS("Signalling Sync Interval: %d", tlv.getTimeSyncInterval()); - GPTP_LOG_STATUS("Signalling Announce Interval: %d", tlv.getAnnounceInterval()); - - char linkDelayInterval = tlv.getLinkDelayInterval(); - char timeSyncInterval = tlv.getTimeSyncInterval(); - char announceInterval = tlv.getAnnounceInterval(); - - if (linkDelayInterval == PTPMessageSignalling::sigMsgInterval_Initial) { - port->resetInitPDelayInterval(); - - waitTime = ((long long) (pow((double)2, port->getPDelayInterval()) * 1000000000.0)); - waitTime = waitTime > EVENT_TIMER_GRANULARITY ? waitTime : EVENT_TIMER_GRANULARITY; - port->startPDelayIntervalTimer(waitTime); - } - else if (linkDelayInterval == PTPMessageSignalling::sigMsgInterval_NoSend) { - // TODO: No send functionality needs to be implemented. - GPTP_LOG_WARNING("Signal received to stop sending pDelay messages: Not implemented"); - } - else if (linkDelayInterval == PTPMessageSignalling::sigMsgInterval_NoChange) { - // Nothing to do - } - else { - port->setPDelayInterval(linkDelayInterval); - - waitTime = ((long long) (pow((double)2, port->getPDelayInterval()) * 1000000000.0)); - waitTime = waitTime > EVENT_TIMER_GRANULARITY ? waitTime : EVENT_TIMER_GRANULARITY; - port->startPDelayIntervalTimer(waitTime); - } - - if (timeSyncInterval == PTPMessageSignalling::sigMsgInterval_Initial) { - port->resetInitSyncInterval(); - - waitTime = ((long long) (pow((double)2, port->getSyncInterval()) * 1000000000.0)); - waitTime = waitTime > EVENT_TIMER_GRANULARITY ? waitTime : EVENT_TIMER_GRANULARITY; - port->startSyncIntervalTimer(waitTime); - } - else if (timeSyncInterval == PTPMessageSignalling::sigMsgInterval_NoSend) { - // TODO: No send functionality needs to be implemented. - GPTP_LOG_WARNING("Signal received to stop sending Sync messages: Not implemented"); - } - else if (timeSyncInterval == PTPMessageSignalling::sigMsgInterval_NoChange) { - // Nothing to do - } - else { - port->setSyncInterval(timeSyncInterval); - - waitTime = ((long long) (pow((double)2, port->getSyncInterval()) * 1000000000.0)); - waitTime = waitTime > EVENT_TIMER_GRANULARITY ? waitTime : EVENT_TIMER_GRANULARITY; - port->startSyncIntervalTimer(waitTime); - } - - if (!port->getAutomotiveProfile()) { - if (announceInterval == PTPMessageSignalling::sigMsgInterval_Initial) { - // TODO: Needs implementation - GPTP_LOG_WARNING("Signal received to set Announce message to initial interval: Not implemented"); - } - else if (announceInterval == PTPMessageSignalling::sigMsgInterval_NoSend) { - // TODO: No send functionality needs to be implemented. - GPTP_LOG_WARNING("Signal received to stop sending Announce messages: Not implemented"); - } - else if (announceInterval == PTPMessageSignalling::sigMsgInterval_NoChange) { - // Nothing to do - } - else { - port->setAnnounceInterval(announceInterval); - - waitTime = ((long long) (pow((double)2, port->getAnnounceInterval()) * 1000000000.0)); - waitTime = waitTime > EVENT_TIMER_GRANULARITY ? waitTime : EVENT_TIMER_GRANULARITY; - port->startAnnounceIntervalTimer(waitTime); - } - } -} diff --git a/daemons/gptp/common/ptptypes.hpp b/daemons/gptp/common/ptptypes.hpp deleted file mode 100644 index f73c8f92..00000000 --- a/daemons/gptp/common/ptptypes.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/****************************************************************************** - - 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 PTP_TYPES_HPP -#define PTP_TYPES_HPP - -/**@file*/ - -#if defined(__clang__) && defined(__x86_64__) -// Clang/llvm has incompatible long double (fp128) for x86_64. -typedef double FrequencyRatio; /*!< Frequency Ratio */ -#else -typedef long double FrequencyRatio; /*!< Frequency Ratio */ -#endif - -#define ETHER_HDR_LEN (14) -#define ETHER_ADDR_OCTETS 6 /*!< Number of octets in a link layer address*/ -#define IP_ADDR_OCTETS 4 /*!< Number of octets in a ip address*/ -#define PTP_ETHERTYPE 0x88F7 /*!< PTP ethertype */ -#define AVTP_ETHERTYPE 0x22F0 /*!< AVTP ethertype used for Test Status Message */ - -#define PTP_CLOCK_IDENTITY_LENGTH 8 /*!< Size of a clock identifier stored in the ClockIndentity class, described at IEEE 802.1AS-2011 Clause 8.5.2.4*/ - -/** - * @brief PortState enumeration - */ -typedef enum { - PTP_MASTER = 7, //!< Port is PTP Master - PTP_PRE_MASTER, //!< Port is not PTP Master yet. - PTP_SLAVE, //!< Port is PTP Slave - PTP_UNCALIBRATED, //!< Port is uncalibrated. - PTP_DISABLED, //!< Port is not PTP enabled. All messages are ignored when in this state. - PTP_FAULTY, //!< Port is in a faulty state. Recovery is implementation specific. - PTP_INITIALIZING, //!< Port's initial state. - PTP_LISTENING //!< Port is in a PTP listening state. Currently not in use. -} PortState; - -#endif/*PTP_TYPES_HPP*/ diff --git a/daemons/gptp/common/wireless_port.cpp b/daemons/gptp/common/wireless_port.cpp deleted file mode 100644 index 40db5015..00000000 --- a/daemons/gptp/common/wireless_port.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2015, 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 <wireless_port.hpp> -#include <wireless_tstamper.hpp> -#include <avbts_clock.hpp> - -WirelessPort::~WirelessPort() -{ - // Intentionally left blank -} - -WirelessPort::WirelessPort( PortInit_t *portInit, LinkLayerAddress peer_addr ) -: CommonPort( portInit ) -{ - this->peer_addr = peer_addr; - - setAsCapable( true ); - if ( getInitSyncInterval() == LOG2_INTERVAL_INVALID ) - setInitSyncInterval (-3 ); // 125 ms - if ( getInitPDelayInterval() == LOG2_INTERVAL_INVALID ) - setInitPDelayInterval( 127 ); // 1 second - - prev_dialog.dialog_token = 0; -} - -bool WirelessPort::_init_port(void) -{ - port_ready_condition = condition_factory->createCondition(); - - return true; -} - -bool WirelessPort::_processEvent( Event e ) -{ - bool ret; - - switch (e) - { - default: - GPTP_LOG_ERROR - ("Unhandled event type in " - "WirelessPort::processEvent(), %d", e); - ret = false; - break; - - case POWERUP: - case INITIALIZE: - { - port_ready_condition->wait_prelock(); - - if ( !linkOpen(_openPort, (void *)this )) - { - GPTP_LOG_ERROR( "Error creating port thread" ); - ret = false; - break; - } - - port_ready_condition->wait(); - - ret = true; - break; - } - - case SYNC_INTERVAL_TIMEOUT_EXPIRES: - { - WirelessTimestamper *timestamper = - dynamic_cast<WirelessTimestamper *>( _hw_timestamper ); - PTPMessageFollowUp *follow_up; - PortIdentity dest_id; - uint16_t seq; - uint8_t buffer[128]; - size_t length; - - memset(buffer, 0, sizeof( buffer )); - - if( prev_dialog.dialog_token != 0 ) - { - follow_up = new PTPMessageFollowUp( this ); - - getPortIdentity(dest_id); - follow_up->setPortIdentity(&dest_id); - follow_up->setSequenceId(prev_dialog.fwup_seq); - follow_up->setPreciseOriginTimestamp - ( prev_dialog.action ); - length = follow_up->buildMessage - (this, buffer + timestamper->getFwUpOffset()); - - delete follow_up; - } - - seq = getNextSyncSequenceId(); - ret = timestamper->requestTimingMeasurement - ( &peer_addr, seq, &prev_dialog, buffer, (int)length ) - == net_succeed; - - ret = true; - break; - } - - case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES: - case SYNC_RECEIPT_TIMEOUT_EXPIRES: - ret = false; - break; - - case STATE_CHANGE_EVENT: - ret = false; - break; - } - - return ret; -} - -bool WirelessPort::openPort() -{ - port_ready_condition->signal(); - - while (true) - { - uint8_t buf[128]; - LinkLayerAddress remote; - net_result rrecv; - size_t length = sizeof(buf); - uint32_t link_speed; - - if(( rrecv = recv( &remote, buf, length, link_speed )) - == net_succeed ) - { - processMessage - ((char *)buf, (int)length, &remote, link_speed ); - } - else if( rrecv == net_fatal ) - { - GPTP_LOG_ERROR( "read from network interface failed" ); - this->processEvent( FAULT_DETECTED ); - break; - } - } - - return false; -} - -void WirelessPort::sendGeneralPort -(uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type, - PortIdentity * destIdentity) -{ - net_result rtx = send( &peer_addr, etherType, buf, len, false); - if( rtx != net_succeed ) - GPTP_LOG_ERROR( "sendGeneralPort(): failure" ); - - return; -} - -void WirelessPort::processMessage -(char *buf, int length, LinkLayerAddress *remote, uint32_t link_speed) -{ - GPTP_LOG_VERBOSE( "Processing network buffer" ); - - PTPMessageCommon *msg = - buildPTPMessage( buf, (int)length, remote, this ); - - if( msg == NULL ) - { - GPTP_LOG_ERROR( "Discarding invalid message" ); - return; - } - GPTP_LOG_VERBOSE( "Processing message" ); - - if( !msg->isEvent( )) - { - msg->processMessage( this ); - } else - { - GPTP_LOG_ERROR( "Received event message on port " - "incapable of processing" ); - msg->PTPMessageCommon::processMessage( this ); - } - - if (msg->garbage()) - delete msg; -} - -void WirelessPort::becomeSlave(bool restart_syntonization) -{ - clock->deleteEventTimerLocked(this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES); - clock->deleteEventTimerLocked( this, SYNC_INTERVAL_TIMEOUT_EXPIRES ); - - setPortState( PTP_SLAVE ); - - GPTP_LOG_STATUS("Switching to Slave"); - if( restart_syntonization ) clock->newSyntonizationSetPoint(); - - getClock()->updateFUPInfo(); -} - -void WirelessPort::becomeMaster(bool annc) -{ - setPortState( PTP_MASTER ); - // Stop announce receipt timeout timer - clock->deleteEventTimerLocked( this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES); - - // Stop sync receipt timeout timer - stopSyncReceiptTimer(); - - if (annc) - startAnnounce(); - - startSyncIntervalTimer( 16000000 ); - GPTP_LOG_STATUS( "Switching to Master" ); - - clock->updateFUPInfo(); -} diff --git a/daemons/gptp/common/wireless_port.hpp b/daemons/gptp/common/wireless_port.hpp deleted file mode 100644 index bfffbd47..00000000 --- a/daemons/gptp/common/wireless_port.hpp +++ /dev/null @@ -1,179 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2015, 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 WIRELESS_PORT_HPP -#define WIRELESS_PORT_HPP - -#include <common_port.hpp> -#include <avbts_oscondition.hpp> - -class WirelessDialog -{ -public: - Timestamp action; - uint64_t action_devclk; - Timestamp ack; - uint64_t ack_devclk; - uint8_t dialog_token; - uint16_t fwup_seq; - - WirelessDialog( uint32_t action, uint32_t ack, uint8_t dialog_token ) - { - this->action_devclk = action; this->ack_devclk = ack; - this->dialog_token = dialog_token; - } - - WirelessDialog() { dialog_token = 0; } - - WirelessDialog & operator=( const WirelessDialog & a ) - { - if (this != &a) - { - this->ack = a.ack; - this->ack_devclk = a.ack_devclk; - this->action = a.action; - this->action_devclk = a.action_devclk; - this->dialog_token = a.dialog_token; - this->fwup_seq = a.fwup_seq; - } - return *this; - } -}; - -class WirelessPort : public CommonPort -{ -private: - OSCondition *port_ready_condition; - LinkLayerAddress peer_addr; - WirelessDialog prev_dialog; - -public: - WirelessPort( PortInit_t *portInit, LinkLayerAddress peer_addr ); - virtual ~WirelessPort(); - - /** - * @brief Media specific port initialization - * @return true on success - */ - bool _init_port( void ); - - /** - * @brief Perform media specific event handling action - * @return true if event is handled without errors - */ - bool _processEvent( Event e ); - - /** - * @brief Process message - * @param buf [in] Pointer to the data buffer - * @param length Size of the message - * @param remote [in] source address of message - * @param link_speed [in] for receive operation - * @return void - */ - void processMessage - (char *buf, int length, LinkLayerAddress *remote, uint32_t link_speed); - - /** - * @brief Sends a general message to a port. No timestamps - * @param buf [in] Pointer to the data buffer - * @param len Size of the message - * @param mcast_type Enumeration - * MulticastType (pdelay, none or other). Depracated. - * @param destIdentity Destination port identity - * @return void - */ - void sendGeneralPort - ( uint16_t etherType, uint8_t * buf, int len, MulticastType mcast_type, - PortIdentity * destIdentity ); - - /** - * @brief Nothing required for wireless port - */ - void syncDone() {} - - /** - * @brief Switches port to a gPTP master - * @param annc If TRUE, starts announce event timer. - * @return void - */ - void becomeMaster( bool annc ); - - /** - * @brief Switches port to a gPTP slave. - * @param restart_syntonization if TRUE, restarts the syntonization - * @return void - */ - void becomeSlave( bool restart_syntonization ); - - /** - * @brief Receives messages from the network interface - * @return Its an infinite loop. Returns false in case of error. - */ - bool openPort(); - - /** - * @brief Wraps open port method for argument to thread - * @param larg pointer to WirelessPort object - * @return thread exit code - */ - static OSThreadExitCode _openPort( void *larg ) - { - WirelessPort *port = (decltype(port))larg; - - if (!port->openPort()) - return osthread_error; - - return osthread_ok; - } - - /** - * @brief Sets previous dialog - * @param dialog new value of prev_dialog - */ - void setPrevDialog( WirelessDialog *dialog ) - { - prev_dialog = *dialog; - } - - /** - * @brief Sets previous dialog - * @return reference to prev_dialog - */ - WirelessDialog *getPrevDialog( void ) - { - return &prev_dialog; - } -}; - -#endif/*WIRELESS_PORT_HPP*/ diff --git a/daemons/gptp/common/wireless_tstamper.cpp b/daemons/gptp/common/wireless_tstamper.cpp deleted file mode 100644 index 10c3be06..00000000 --- a/daemons/gptp/common/wireless_tstamper.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2015, 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 <wireless_tstamper.hpp> -#include <wireless_port.hpp> - -net_result WirelessTimestamper::requestTimingMeasurement -( LinkLayerAddress *dest, uint16_t seq, WirelessDialog *prev_dialog, - uint8_t *follow_up, int followup_length ) -{ - WirelessDialog next_dialog; - net_result retval; - TIMINGMSMT_REQUEST *req; - - // Valid dialog token > 0 && < 256 - next_dialog.dialog_token = (seq % MAX_DIALOG_TOKEN) + 1; - next_dialog.fwup_seq = seq; - next_dialog.action_devclk = 0; - req = (TIMINGMSMT_REQUEST *)follow_up; - - // File in request - req->DialogToken = next_dialog.dialog_token; - req->FollowUpDialogToken = prev_dialog->dialog_token; - req->Category = 0x0; - req->Action = 0x0; - req->WiFiVSpecHdr.ElementId = FWUP_VDEF_TAG; - req->WiFiVSpecHdr.Length = 0; - if( req->FollowUpDialogToken != 0 && prev_dialog->action_devclk != 0 ) - { - req->T1 = (uint32_t)prev_dialog->action_devclk; - req->T4 = (uint32_t)prev_dialog->ack_devclk; - req->WiFiVSpecHdr.Length = followup_length + - (uint8_t)sizeof(FwUpLabel); // 1 byte type - req->PtpSpec.FwUpLabel = FwUpLabel; - } - dest->toOctetArray(req->PeerMACAddress); - - retval = _requestTimingMeasurement( req ); - port->setPrevDialog(&next_dialog); - - return retval; -} - -void WirelessTimestamper::timingMeasurementConfirmCB -( LinkLayerAddress addr, WirelessDialog *dialog ) -{ - WirelessDialog *prev_dialog = port->getPrevDialog(); - - // Translate action dev clock to Timestamp - // ACK timestamp isn't needed - dialog->action.set64(dialog->action_devclk*10); - - if (dialog->dialog_token == prev_dialog->dialog_token) - { - dialog->fwup_seq = prev_dialog->fwup_seq; - port->setPrevDialog(dialog); - } -} - -void WirelessTimestamper::timeMeasurementIndicationCB -( LinkLayerAddress addr, WirelessDialog *current, WirelessDialog *previous, - uint8_t *buf, size_t buflen ) -{ - uint64_t link_delay; - WirelessDialog *prev_local; - PTPMessageCommon *msg; - PTPMessageFollowUp *fwup; - // Translate devclk scalar to Timestamp - - msg = buildPTPMessage((char *)buf, (int)buflen, &addr, port); - fwup = dynamic_cast<PTPMessageFollowUp *> (msg); - current->action_devclk *= 10; - current->ack_devclk *= 10; - current->action.set64(current->action_devclk); - prev_local = port->getPrevDialog(); - if ( previous->dialog_token == prev_local->dialog_token && - fwup != NULL && previous->action_devclk != 0) - { - previous->action_devclk *= 10; - previous->ack_devclk *= 10; - unsigned round_trip = (unsigned) - (previous->ack_devclk - previous->action_devclk); - unsigned turn_around = (unsigned) - (prev_local->ack_devclk - prev_local->action_devclk); - link_delay = (round_trip - turn_around) / 2; - port->setLinkDelay(link_delay); - GPTP_LOG_VERBOSE( "Link Delay = %llu(RT=%u,TA=%u," - "T4=%llu,T1=%llu,DT=%hhu)", - link_delay, round_trip, turn_around, - previous->ack_devclk, - previous->action_devclk, - previous->dialog_token); - fwup->processMessage(port, prev_local->action); - } - - port->setPrevDialog(current); -} diff --git a/daemons/gptp/common/wireless_tstamper.hpp b/daemons/gptp/common/wireless_tstamper.hpp deleted file mode 100644 index 79413d0d..00000000 --- a/daemons/gptp/common/wireless_tstamper.hpp +++ /dev/null @@ -1,221 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2015, 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 WIRELESS_TSTAMPER_HPP -#define WIRELESS_TSTAMPER_HPP - -#include <common_tstamper.hpp> -#include <wireless_port.hpp> - -#define MAX_DIALOG_TOKEN 255 -#define OUI_8021AS_OCTETS { 0x00, 0x80, 0xC2 } -static const uint8_t OUI_8021AS[] = OUI_8021AS_OCTETS; -#define FWUP_TYPE 0 -#define FWUP_VDEF_TAG 0xDD /* Vendor Defined Tag */ - -typedef enum _WIRELESS_EVENT_TYPE -{ - TIMINGMSMT_EVENT = 0, - TIMINGMSMT_CONFIRM_EVENT, - TIMINGMSMT_CORRELATEDTIME_EVENT, -} WIRELESS_EVENT_TYPE; - -#pragma pack(push, 1) -typedef struct -{ - uint8_t oui[sizeof(OUI_8021AS)]; - uint8_t type; -} FwUpLabel_t; - -typedef struct _PTP_SPEC -{ - FwUpLabel_t FwUpLabel; - uint8_t fwup_data[1]; -} PTP_SPEC; - -static const FwUpLabel_t FwUpLabel = { OUI_8021AS_OCTETS, FWUP_TYPE }; - -typedef struct _WIFI_VENDOR_SPEC_HDR -{ - uint8_t ElementId; - uint8_t Length; -} WIFI_VENDOR_SPEC_HDR; -#pragma pack(pop) - -typedef struct _TIMINGMSMT_REQUEST -{ - uint8_t PeerMACAddress[ETHER_ADDR_OCTETS]; - uint8_t Category; - uint8_t Action; - uint8_t DialogToken; - uint8_t FollowUpDialogToken; - uint32_t T1; - uint32_t T4; - uint8_t MaxT1Error; - uint8_t MaxT4Error; - - WIFI_VENDOR_SPEC_HDR WiFiVSpecHdr; - PTP_SPEC PtpSpec; -} TIMINGMSMT_REQUEST; - -typedef struct _TIMINGMSMT_EVENT_DATA -{ - uint8_t PeerMACAddress[ETHER_ADDR_OCTETS]; - uint32_t DialogToken; - uint32_t FollowUpDialogToken; - uint64_t T1; - uint32_t MaxT1Error; - uint64_t T4; - uint32_t MaxT4Error; - uint64_t T2; - uint32_t MaxT2Error; - uint64_t T3; - uint32_t MaxT3Error; - - WIFI_VENDOR_SPEC_HDR WiFiVSpecHdr; - PTP_SPEC PtpSpec; -} TIMINGMSMT_EVENT_DATA; - -typedef struct _TIMINGMSMT_CONFIRM_EVENT_DATA -{ - uint8_t PeerMACAddress[ETHER_ADDR_OCTETS]; - uint32_t DialogToken; - uint64_t T1; - uint32_t MaxT1Error; - uint64_t T4; - uint32_t MaxT4Error; -} TIMINGMSMT_CONFIRM_EVENT_DATA; - -typedef struct _WIRELESS_CORRELATEDTIME -{ - uint64_t TSC; - uint64_t LocalClk; -} WIRELESS_CORRELATEDTIME; - -struct S8021AS_Indication { - TIMINGMSMT_EVENT_DATA indication; - uint8_t followup[75]; // (34 header + 10 followup + 32 TLV) - 1 byte contained in indication struct = 75 -}; - -union TimeSyncEventData -{ - TIMINGMSMT_CONFIRM_EVENT_DATA confirm; - S8021AS_Indication indication; - WIRELESS_CORRELATEDTIME ptm_wa; -}; - -class WirelessTimestamper : public CommonTimestamper -{ -private: - WirelessPort *port; -public: - virtual ~WirelessTimestamper() {} - - /** - * @brief attach timestamper to port - * @param port port to attach - */ - void setPort( WirelessPort *port ) - { - this->port = port; - } - - /** - * @brief return reference to attached port - * @return reference to attached port - */ - WirelessPort *getPort(void) const - { - return port; - } - - /** - * @brief Return buffer offset where followup message should be placed - * @return byte offset - */ - uint8_t getFwUpOffset(void) - { - // Subtract 1 to compensate for 'bogus' vendor specific buffer - // length - return (uint8_t)((size_t) &((TIMINGMSMT_REQUEST *) 0)-> - PtpSpec.fwup_data ); - } - - /** - * @brief Request transmission of TM frame - * @param dest [in] MAC destination the frame should be sent to - * @param seq [in] 802.1AS sequence number - * @param prev_dialog [in] last dialog message - * @param follow_up [in] buffer containing followup message - * @param followup_length [in] fw-up message length in bytes - */ - virtual net_result requestTimingMeasurement - ( LinkLayerAddress *dest, uint16_t seq, WirelessDialog *prev_dialog, - uint8_t *follow_up, int followup_length ); - - /** - * @brief abstract method for driver/os specific TM transmit code - * @param timingmsmt_req fully formed TM message - */ - virtual net_result _requestTimingMeasurement - ( TIMINGMSMT_REQUEST *timingmsmt_req ) = 0; - - /** - * @brief Asynchronous completion of TM transmit - * @param addr [in] MAC the message was transmitted to - * @param dialog [in] dialog filled with T1, T4 timestamps - */ - void timingMeasurementConfirmCB( LinkLayerAddress addr, - WirelessDialog *dialog ); - - /** - * @brief Reception of TM frame - * @param addr [in] MAC the message was received from - * @param current [in] dialog filled with T2, T3 timestamps - * @param previous [in] dialog filled with T1, T4 timestamps - * @param buf [in] buffer containing followup message - * @param previous [in] length of followup message - */ - void timeMeasurementIndicationCB - ( LinkLayerAddress addr, WirelessDialog *current, - WirelessDialog *previous, uint8_t *buf, size_t buflen ); -}; - -struct WirelessTimestamperCallbackArg -{ - WIRELESS_EVENT_TYPE iEvent_type; - WirelessTimestamper *timestamper; - TimeSyncEventData event_data; -}; - -#endif/*WIRELESS_TSTAMPER_HPP*/ diff --git a/daemons/gptp/doc/CMakeLists.txt b/daemons/gptp/doc/CMakeLists.txt deleted file mode 100644 index c6fc3dcc..00000000 --- a/daemons/gptp/doc/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -# add a target to generate API documentation with Doxygen -find_package(Doxygen) -option(BUILD_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND}) - -if(BUILD_DOCUMENTATION) - if(NOT DOXYGEN_FOUND) - message(FATAL_ERROR "Doxygen is needed to build the documentation.") - endif() - - set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) - set(doxyfile ${CMAKE_CURRENT_SOURCE_DIR}/build/Doxyfile) - - configure_file(${doxyfile_in} ${doxyfile} @ONLY) - - add_custom_target(doc - COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - COMMENT "Generating API documentation with Doxygen" - VERBATIM) - - #install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc) -endif() diff --git a/daemons/gptp/doc/Doxyfile.in b/daemons/gptp/doc/Doxyfile.in deleted file mode 100644 index 7756614f..00000000 --- a/daemons/gptp/doc/Doxyfile.in +++ /dev/null @@ -1,2303 +0,0 @@ -# Doxyfile 1.8.6 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = "gPTP Documentation" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is included in -# the documentation. The maximum height of the logo should not exceed 55 pixels -# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo -# to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = ../doc/build - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = YES - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = NO - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a -# new page for each member. If set to NO, the documentation of a member will be -# part of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. -# -# Note For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by by putting a % sign in front of the word -# or globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO these classes will be included in the various overviews. This option has -# no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO these declarations will be -# included in the documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the -# todo list. This list is created by putting \todo commands in the -# documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the -# test list. This list is created by putting \test commands in the -# documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if <section_label> ... \endif and \cond <section_label> -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES the list -# will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. Do not use file names with spaces, bibtex cannot handle them. See -# also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO doxygen will only warn about wrong or incomplete parameter -# documentation, but not about the absence of documentation. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. -# Note: If this tag is empty the current directory is searched. - -INPUT = ../common ../linux/src ../windows/daemon_cl ../doc/mainpage.dox - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank the -# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, -# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, -# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, -# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, -# *.qsf, *.as and *.js. - -FILE_PATTERNS = *.hpp - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# <filter> <input-file> -# -# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER ) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES, then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = YES - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- -# defined cascading style sheet that is included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefor more robust against future updates. -# Doxygen will copy the style sheet file to the output directory. For an example -# see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the stylesheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler ( hhc.exe). If non-empty -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated ( -# YES) or that it should be included in the master .chm file ( NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated ( -# YES) or a normal table of contents ( NO) in the .chm file. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = YES - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using prerendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use <access key> + S -# (what the <access key> is depends on the OS and browser, but it is typically -# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down -# key> to jump into the search results window, the results can be navigated -# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel -# the search. The filter options can be selected when the cursor is inside the -# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> -# to select a filter and <Enter> or <escape> to activate or cancel the filter -# option. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There -# are two flavours of web server based searching depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. See -# the section "External Indexing and Searching" for details. -# The default value is: NO. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SERVER_BASED_SEARCH = NO - -# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP -# script for searching. Instead the search results are written to an XML file -# which needs to be processed by an external indexer. Doxygen will invoke an -# external search engine pointed to by the SEARCHENGINE_URL option to obtain the -# search results. -# -# Doxygen ships with an example indexer ( doxyindexer) and search engine -# (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). -# -# See the section "External Indexing and Searching" for details. -# The default value is: NO. -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTERNAL_SEARCH = NO - -# The SEARCHENGINE_URL should point to a search engine hosted by a web server -# which will return the search results when EXTERNAL_SEARCH is enabled. -# -# Doxygen ships with an example indexer ( doxyindexer) and search engine -# (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). See the section "External Indexing and -# Searching" for details. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SEARCHENGINE_URL = - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed -# search data is written to a file for indexing by an external tool. With the -# SEARCHDATA_FILE tag the name of this file can be specified. -# The default file is: searchdata.xml. -# This tag requires that the tag SEARCHENGINE is set to YES. - -SEARCHDATA_FILE = searchdata.xml - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the -# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is -# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple -# projects and redirect the results back to the right project. -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTERNAL_SEARCH_ID = - -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen -# projects other than the one defined by this configuration file, but that are -# all added to the same external search index. Each project needs to have a -# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of -# to a relative location where the documentation can be found. The format is: -# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... -# This tag requires that the tag SEARCHENGINE is set to YES. - -EXTRA_SEARCH_MAPPINGS = - -#--------------------------------------------------------------------------- -# Configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. -# The default value is: YES. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: latex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. -# -# Note that when enabling USE_PDFLATEX this option is only used for generating -# bitmaps for formulas in the HTML output, but not in the Makefile that is -# written to the output directory. -# The default file is: latex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate -# index for LaTeX. -# The default file is: makeindex. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX -# documents. This may be useful for small projects and may help to save some -# trees in general. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used by the -# printer. -# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x -# 14 inches) and executive (7.25 x 10.5 inches). -# The default value is: a4. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names -# that should be included in the LaTeX output. To get the times font for -# instance you can specify -# EXTRA_PACKAGES=times -# If left blank no extra packages will be included. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. -# -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will -# replace them by respectively the title of the page, the current date and time, -# only the current date, the version number of doxygen, the project name (see -# PROJECT_NAME), or the project number (see PROJECT_NUMBER). -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. -# -# Note: Only use a user-defined footer if you know what you are doing! -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_FOOTER = - -# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the LATEX_OUTPUT output -# directory. Note that the files will be copied as-is; there are no commands or -# markers available. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_EXTRA_FILES = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is -# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will -# contain links (just like the HTML output) instead of page references. This -# makes the output suitable for online browsing using a PDF viewer. -# The default value is: YES. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -PDF_HYPERLINKS = YES - -# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES to get a -# higher quality PDF documentation. -# The default value is: YES. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_BATCHMODE = NO - -# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the -# index chapters (such as File Index, Compound Index, etc.) in the output. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_HIDE_INDICES = NO - -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. See -# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. -# The default value is: plain. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_BIB_STYLE = plain - -#--------------------------------------------------------------------------- -# Configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The -# RTF output is optimized for Word 97 and may not look too pretty with other RTF -# readers/editors. -# The default value is: NO. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: rtf. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF -# documents. This may be useful for small projects and may help to save some -# trees in general. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will -# contain hyperlink fields. The RTF file will contain links (just like the HTML -# output) instead of page references. This makes the output suitable for online -# browsing using Word or some other Word compatible readers that support those -# fields. -# -# Note: WordPad (write) and others do not support links. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's config -# file, i.e. a series of assignments. You only have to provide replacements, -# missing definitions are set to their default value. -# -# See also section "Doxygen usage" for information on how to generate the -# default style sheet that doxygen normally uses. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's config file. A template extensions file can be generated -# using doxygen -e rtf extensionFile. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for -# classes and files. -# The default value is: NO. - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. A directory man3 will be created inside the directory specified by -# MAN_OUTPUT. -# The default directory is: man. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to the generated -# man pages. In case the manual section does not start with a number, the number -# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is -# optional. -# The default value is: .3. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it -# will generate one additional man file for each entity documented in the real -# man page(s). These additional files only source the real man page, but without -# them the man command would be unable to find the correct page. -# The default value is: NO. -# This tag requires that the tag GENERATE_MAN is set to YES. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that -# captures the structure of the code including all documentation. -# The default value is: NO. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: xml. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify a XML DTD, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program -# listings (including syntax highlighting and cross-referencing information) to -# the XML output. Note that enabling this will significantly increase the size -# of the XML output. -# The default value is: YES. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the DOCBOOK output -#--------------------------------------------------------------------------- - -# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files -# that can be used to generate PDF. -# The default value is: NO. - -GENERATE_DOCBOOK = NO - -# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in -# front of it. -# The default directory is: docbook. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_OUTPUT = docbook - -#--------------------------------------------------------------------------- -# Configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen -# Definitions (see http://autogen.sf.net) file that captures the structure of -# the code including all documentation. Note that this feature is still -# experimental and incomplete at the moment. -# The default value is: NO. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module -# file that captures the structure of the code including all documentation. -# -# Note that this feature is still experimental and incomplete at the moment. -# The default value is: NO. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary -# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI -# output from the Perl module output. -# The default value is: NO. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely -# formatted so it can be parsed by a human reader. This is useful if you want to -# understand what is going on. On the other hand, if this tag is set to NO the -# size of the Perl module output will be much smaller and Perl will parse it -# just the same. -# The default value is: YES. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file are -# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful -# so different doxyrules.make files included by the same Makefile don't -# overwrite each other's variables. -# This tag requires that the tag GENERATE_PERLMOD is set to YES. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all -# C-preprocessor directives found in the sources and include files. -# The default value is: YES. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names -# in the source code. If set to NO only conditional compilation will be -# performed. Macro expansion can be done in a controlled way by setting -# EXPAND_ONLY_PREDEF to YES. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then -# the macro expansion is limited to the macros specified with the PREDEFINED and -# EXPAND_AS_DEFINED tags. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES the includes files in the -# INCLUDE_PATH will be searched if a #include is found. -# The default value is: YES. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by the -# preprocessor. -# This tag requires that the tag SEARCH_INCLUDES is set to YES. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will be -# used. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that are -# defined before the preprocessor is started (similar to the -D option of e.g. -# gcc). The argument of the tag is a list of macros of the form: name or -# name=definition (no spaces). If the definition and the "=" are omitted, "=1" -# is assumed. To prevent a macro definition from being undefined via #undef or -# recursively expanded use the := operator instead of the = operator. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this -# tag can be used to specify a list of macro names that should be expanded. The -# macro definition that is found in the sources will be used. Use the PREDEFINED -# tag if you want to use a different macro definition that overrules the -# definition found in the source code. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an -# all uppercase name, and do not end with a semicolon. Such function macros are -# typically used for boiler-plate code, and will confuse the parser if not -# removed. -# The default value is: YES. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES tag can be used to specify one or more tag files. For each tag -# file the location of the external documentation should be added. The format of -# a tag file without this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where loc1 and loc2 can be relative or absolute paths or URLs. See the -# section "Linking to external documentation" for more information about the use -# of tag files. -# Note: Each tag file must have an unique name (where the name does NOT include -# the path). If a tag file is not located in the directory in which doxygen is -# run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create a -# tag file that is based on the input files it reads. See section "Linking to -# external documentation" for more information about the usage of tag files. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external class will be listed in the -# class index. If set to NO only the inherited external classes will be listed. -# The default value is: NO. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in -# the modules index. If set to NO, only the current project's groups will be -# listed. -# The default value is: YES. - -EXTERNAL_GROUPS = YES - -# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in -# the related pages index. If set to NO, only the current project's pages will -# be listed. -# The default value is: YES. - -EXTERNAL_PAGES = NO - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of 'which perl'). -# The default file (with absolute path) is: /usr/bin/perl. - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see: -# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide inheritance -# and usage relations if the target is undocumented or is not a class. -# The default value is: YES. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent -# Bell Labs. The other options in this section have no effect if this option is -# set to NO -# The default value is: NO. - -HAVE_DOT = YES - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed -# to run in parallel. When set to 0 doxygen will base this on the number of -# processors available in the system. You can set it explicitly to a value -# larger than 0 to get control over the balance between CPU load and processing -# speed. -# Minimum value: 0, maximum value: 32, default value: 0. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_NUM_THREADS = 0 - -# When you want a differently looking font n the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_FONTPATH = - -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a -# graph for each documented class showing the direct and indirect implementation -# dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -UML_LOOK = YES - -# If the UML_LOOK tag is enabled, the fields and methods are shown inside the -# class node. If there are many fields or methods and many nodes the graph may -# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the -# number of items for each type to make the size more manageable. Set this to 0 -# for no limit. Note that the threshold may be exceeded by 50% before the limit -# is enforced. So when you set the threshold to 10, up to 15 fields may appear, -# but if the number exceeds 15, the total amount of fields shown is limited to -# 10. -# Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. - -UML_LIMIT_NUM_FIELDS = 10 - -# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and -# collaboration graphs will show the relations between templates and their -# instances. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -TEMPLATE_RELATIONS = NO - -# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to -# YES then doxygen will generate a graph for each documented file showing the -# direct and indirect include dependencies of the file with other documented -# files. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -INCLUDE_GRAPH = YES - -# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are -# set to YES then doxygen will generate a graph for each documented file showing -# the direct and indirect include dependencies of the file with other documented -# files. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH tag is set to YES then doxygen will generate a call -# dependency graph for every global function or class method. -# -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller -# dependency graph for every global function or class method. -# -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical -# hierarchy of all classes instead of a textual one. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the -# dependencies a directory has on other directories in a graphical way. The -# dependency relations are determined by the #include relations between the -# files in the directories. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. -# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order -# to make the SVG files visible in IE 9+ (other browsers do not have this -# requirement). -# Possible values are: png, jpg, gif and svg. -# The default value is: png. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# -# Note that this requires a modern browser other than Internet Explorer. Tested -# and working are Firefox, Chrome, Safari, and Opera. -# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make -# the SVG files visible. Older versions of IE do not have SVG support. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -INTERACTIVE_SVG = NO - -# The DOT_PATH tag can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the \dotfile -# command). -# This tag requires that the tag HAVE_DOT is set to YES. - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). - -MSCFILE_DIRS = - -# The DIAFILE_DIRS tag can be used to specify one or more directories that -# contain dia files that are included in the documentation (see the \diafile -# command). - -DIAFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes -# that will be shown in the graph. If the number of nodes in a graph becomes -# larger than this value, doxygen will truncate the graph, which is visualized -# by representing a node as a red box. Note that doxygen if the number of direct -# children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that -# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. -# Minimum value: 0, maximum value: 10000, default value: 50. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs -# generated by dot. A depth value of 3 means that only nodes reachable from the -# root by following a path via at most 3 edges will be shown. Nodes that lay -# further from the root node will be omitted. Note that setting this option to 1 -# or 2 may greatly reduce the computation time needed for large code bases. Also -# note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. -# Minimum value: 0, maximum value: 1000, default value: 0. -# This tag requires that the tag HAVE_DOT is set to YES. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) support -# this, this feature is disabled by default. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_MULTI_TARGETS = YES - -# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page -# explaining the meaning of the various boxes and arrows in the dot generated -# graphs. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot -# files that are used to generate the various graphs. -# The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_CLEANUP = YES diff --git a/daemons/gptp/doc/mainpage.dox b/daemons/gptp/doc/mainpage.dox deleted file mode 100644 index 30243725..00000000 --- a/daemons/gptp/doc/mainpage.dox +++ /dev/null @@ -1,111 +0,0 @@ -/** - * \mainpage gPTP Documentation - * - * Introduction - * ------------ - * This is an example Intel provided gptp daemon which can be used on Linux - * and Windows platforms. There are a number of other ptp daemons available - * for Linux which can be used to establish clock synchronization, although - * not all may export the required APIs needed for an AVB system. - * - * The daemon communicates with other processes through a named pipe. - * The pipe name and message format is defined in ipcdef.hpp. The pipe name - * is "gptp-update". A Windows example is in the project named_pipe_test. - * - * The message format is: - * - * Integer64 <master-local phase offset> - * - * Integer64 <local-system phase offset> - * - * Float <master-local frequency offset> - * - * Float <local-system frequency offset> - * - * UInteger64 < local time of last update> - * - * Meaning of IPC provided values - * - master ~= local - <master-local phase offset> - * - local ~= system - <local-system phase offset> - * - Dmaster ~= Dlocal * (1-<master-local phase offset>/1e12) (where D denotes a delta rather than a specific value) - * - Dlocal ~= Dsystem * (1-<local-system freq offset>/1e12) (where D denotes a delta rather than a specific value) - * - * Linux Specific - * ------------- - * - * Requirements for documentation on a ubuntu based system: - * - cmake: sudo apt-get install cmake - * - doxygen: sudo apt-get install doxygen - * - graphviz: sudo apt-get install graphviz - * - * To build, execute the linux/build makefile. - * - * To build for I210: - * - * ARCH=I210 make clean all - * - * To build for 'generic' Linux: - * - * make clean all - * - * To build for Intel CE 5100 Platforms: - * - * ARCH=IntelCE make clean all - * - * To execute, run - * ./daemon_cl <interface-name> - * such as - * ./daemon_cl eth0 - * - * The daemon creates a shared memory segment with the 'ptp' group. Some distributions may not have this group installed. The IPC interface will not available unless the 'ptp' group is available. - * - * - * Windows Version - * --------------- - * - * Build Dependencies - * - * * WinPCAP Developer's Pack (WpdPack) is required for linking - downloadable from http://www.winpcap.org/devel.htm. - * - * Extract WpdPack so the Include folder is in one of the below locations - * -* 1- ProgramData -* \\WpdPack -* \\Include -* \\Lib -* \\Lib\\x64 -* -* 2- USERPROFILE -* \\src\\pcap -* \\Include -* \\Lib -* \\Lib\\x64 -* -* * WinPCAP must also be installed on any machine where the daemon runs. -* -* To run from the command line: -* -* daemon_cl.exe xx-xx-xx-xx-xx-xx -* -* where xx-xx-xx-xx-xx-xx is the mac address of the local interface -* -* Other Available PTP Daemons -* --------------------------- -* There are a number of existing ptp daemon projects. Some of the other known -* ptp daemons are listed below. Intel has not tested Open AVB with the following -* ptp daemons. -* -* * Richard Cochran's ptp4l daemon - https://sourceforge.net/p/linuxptp/ -* -* Note with this version to use gPTP specific settings, which differ -* slightly from IEEE 1588. -* -* * http://ptpd.sourceforge.net/ -* -* * http://ptpd2.sourceforge.net/ -* -* * http://code.google.com/p/ptpv2d -* -* * http://home.mit.bme.hu/~khazy/ptpd/ -*/ - diff --git a/daemons/gptp/gptp_cfg.ini b/daemons/gptp/gptp_cfg.ini deleted file mode 100644 index 83387606..00000000 --- a/daemons/gptp/gptp_cfg.ini +++ /dev/null @@ -1,70 +0,0 @@ - -[ptp] - -# Priority1 value -# It can assume values between 0 and 255. -# The lower the number, the higher the priority for the BMCA. -priority1 = 248 - -# Clock option to specify system clock type -# Currently, Linux only. Options are MonotonicRaw and Realtime. -# Realtime works on all network interfaces. MonotonicRaw is available on -# interfaces that support it. - -#[clock] -#SystemClock = MonotonicRaw - -[port] - -# TODO -announceReceiptTimeout = 3 - -# TODO -syncReceiptTimeout = 3 - -# Neighbor propagation delay threshold in nanoseconds -# The default pdelay threshold for various hardware link types is specified in -# IEEE Std 802.1AS-Cor1-2013 Table 11-0 "Value of neighborPropDelayThresh for -# various links, in clause 11.2.2. It needs to be configurable because a -# user may be using a converter to fibre and the software wont know until the -# administrator changes it. -neighborPropDelayThresh = 800 - -# Sync Receipt Threshold -# This value defines the number of syncs with wrong seqID that will trigger -# the ptp slave to become master (it will start announcing) -# Normally sync messages are sent every 125ms, so setting it to 8 will allow -# up to 1 second of wrong messages before switching -syncReceiptThresh = 8 - -[eth] - -# Older deprecated format -# PHY delay GB TX in nanoseconds -# The default for I210 is 184 -#phy_delay_gb_tx = 184 - -# Older deprecated format -# PHY delay GB RX in nanoseconds -# The default for I210 is 184 -#phy_delay_gb_rx = 382 - -# Older deprecated format -# PHY delay 100 MB TX in nanoseconds -# The default for I210 is 1044 -#phy_delay_mb_tx = 1044 - -# Older deprecated format -# PHY delay 100 MB RX in nanoseconds -# The default for I210 is 2133 -#phy_delay_mb_rx = 2133 - -# Newer flexible format -# PHY delay GB RX/TX in nanoseconds -# Link speed may be specified numerically or by name -#phy_delay = 1000000 184 382 -phy_delay = LINKSPEED_1G 184 382 - -# PHY delay 100 MB RX/TX in nanoseconds -phy_delay = LINKSPEED_100MB 1044 2133 - diff --git a/daemons/gptp/linux/build/Makefile b/daemons/gptp/linux/build/Makefile deleted file mode 100644 index fa9441d7..00000000 --- a/daemons/gptp/linux/build/Makefile +++ /dev/null @@ -1,195 +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. - -ALTERNATE_LINUX_INCPATH=$(HOME)/header/include/ - -CFLAGS_G = -Wall -g -I. -I../../common -I../src \ - -I$(ALTERNATE_LINUX_INCPATH) - -# Check to see if PTP cross-timestamping is supported in hardware/driver -# and, if so, add flag to compile in support - -PRECISE_TIME_TEST = "\#include <linux/ptp_clock.h>\\n\ -\#ifdef PTP_SYS_OFFSET_PRECISE\\nint main(){return 0;}\\n\#endif" - -HAS_PRECISE_TIME = $(shell /bin/echo -e $(PRECISE_TIME_TEST) | $(CC) -xc - \ --I$(ALTERNATE_LINUX_INCPATH); echo $$?) - -ifeq ($(HAS_PRECISE_TIME),0) - CFLAGS_G += -DPTP_HW_CROSSTSTAMP -endif - -CPPFLAGS_G = $(CFLAGS_G) -std=c++0x -Wnon-virtual-dtor -LDFLAGS_G = - -COMMON_DIR = ../../common -SRC_DIR = ../src -OBJ_DIR = obj - -OBJ_FILES = $(OBJ_DIR)/ptp_message.o\ - $(OBJ_DIR)/ap_message.o\ - $(OBJ_DIR)/avbts_osnet.o\ - $(OBJ_DIR)/ether_port.o\ - $(OBJ_DIR)/common_port.o\ - $(OBJ_DIR)/ieee1588clock.o \ - $(OBJ_DIR)/linux_hal_common.o\ - $(OBJ_DIR)/linux_hal_persist_file.o\ - $(OBJ_DIR)/gptp_log.o\ - $(OBJ_DIR)/platform.o \ - $(OBJ_DIR)/ini.o \ - $(OBJ_DIR)/gptp_cfg.o - -HEADER_FILES = $(COMMON_DIR)/ether_port.hpp\ - $(COMMON_DIR)/common_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)/avbts_persist.hpp\ - $(COMMON_DIR)/avbap_message.hpp\ - $(COMMON_DIR)/ieee1588.hpp\ - $(COMMON_DIR)/ipcdef.hpp\ - $(COMMON_DIR)/ini.h\ - $(COMMON_DIR)/gptp_cfg.hpp\ - $(COMMON_DIR)/gptp_log.hpp\ - $(SRC_DIR)/linux_ipc.hpp\ - $(SRC_DIR)/linux_hal_common.hpp\ - $(SRC_DIR)/linux_hal_persist_file.hpp\ - $(SRC_DIR)/platform.hpp - -ifeq ($(ARCH),I210) - IGB_LIB_INCPATH=../../../../lib/igb/ - IGB_LIB_PATH=../../../../lib/igb/ - CFLAGS_G += -I$(IGB_LIB_INCPATH) -DWITH_IGBLIB - LDFLAGS_G += -lz -ligb -lpci -L$(IGB_LIB_PATH) - OBJ_FILES += $(OBJ_DIR)/linux_hal_generic.o \ - $(OBJ_DIR)/linux_hal_generic_adj.o - OBJ_FILES += $(OBJ_DIR)/linux_hal_i210.o - HEADER_FILES += $(SRC_DIR)/linux_hal_generic.hpp -else ifeq ($(ARCH),IntelCE) - INTELCE_INCPATH=/home/hitesh/work/smd/Dinerout/i686-linux-elf/include/ - INTELCE_LINUX_INCPATH=/home/hitesh/work/smd/Dinerout/i686-linux-elf/include/linux_user - INTELCE_LIBPATH=/home/hitesh/work/smd/Dinerout/i686-linux-elf/lib/ - CFLAGS_G += -I$(INTELCE_LINUX_INCPATH) -I$(INTELCE_INCPATH) -DARCH_INTELCE - LDFLAGS_G += -L$(INTELCE_LIBPATH) -lismd_clock_ioctl -lismd_core_ioctl - HEADER_FILES += $(SRC_DIR)/linux_hal_intelce.hpp - OBJ_FILES += $(OBJ_DIR)/linux_hal_intelce.o - CXX = $(TARGETCXX) -else - OBJ_FILES += $(OBJ_DIR)/linux_hal_generic.o \ - $(OBJ_DIR)/linux_hal_generic_adj.o - HEADER_FILES += $(SRC_DIR)/linux_hal_generic.hpp -endif - -ifeq ($(GENIVI_DLT),1) - GENIVI_DLT_INCLUDE_PATH=/usr/local/include/dlt/ - GENIVI_DLT_LIB_PATH=/usr/local/lib/x86_64-linux-gnu/static/ - CFLAGS_G += -I$(GENIVI_DLT_INCLUDE_PATH) -DGENIVI_DLT - LDFLAGS_G += -ldlt -L$(GENIVI_DLT_LIB_PATH) -endif - -ifeq ($(SYSTEMD_WATCHDOG),1) - CFLAGS_G += -DSYSTEMD_WATCHDOG - LDFLAGS_G += -lsystemd - OBJ_FILES += $(OBJ_DIR)/watchdog.o - HEADER_FILES += $(SRC_DIR)/watchdog.hpp -endif - -LDFLAGS_G += -lpthread -lrt - -CFLAGS = $(CFLAGS_G) -CPPFLAGS = $(CPPFLAGS_G) -LDFLAGS = $(LDFLAGS_G) - -all: $(OBJ_DIR)/daemon_cl - -rebuild: clean all - -$(OBJ_DIR)/daemon_cl: $(SRC_DIR)/daemon_cl.cpp $(OBJ_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(OBJ_FILES) $(SRC_DIR)/daemon_cl.cpp -o $(OBJ_DIR)/daemon_cl $(LDFLAGS) - -$(OBJ_DIR)/linux_hal_common.o: $(SRC_DIR)/linux_hal_common.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/linux_hal_common.cpp -o $(OBJ_DIR)/linux_hal_common.o - -$(OBJ_DIR)/platform.o: $(SRC_DIR)/platform.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/platform.cpp -o $(OBJ_DIR)/platform.o - -$(OBJ_DIR)/linux_hal_generic.o: $(SRC_DIR)/linux_hal_generic.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/linux_hal_generic.cpp -o $(OBJ_DIR)/linux_hal_generic.o - -$(OBJ_DIR)/linux_hal_generic_adj.o: $(SRC_DIR)/linux_hal_generic_adj.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/linux_hal_generic_adj.cpp -o $(OBJ_DIR)/linux_hal_generic_adj.o - -$(OBJ_DIR)/linux_hal_i210.o: $(SRC_DIR)/linux_hal_i210.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/linux_hal_i210.cpp -o $(OBJ_DIR)/linux_hal_i210.o - -$(OBJ_DIR)/linux_hal_intelce.o: $(SRC_DIR)/linux_hal_intelce.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/linux_hal_intelce.cpp -o $(OBJ_DIR)/linux_hal_intelce.o - -$(OBJ_DIR)/ether_port.o: $(COMMON_DIR)/ether_port.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ - -$(OBJ_DIR)/common_port.o: $(COMMON_DIR)/common_port.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ - -$(OBJ_DIR)/ieee1588clock.o: $(COMMON_DIR)/ieee1588clock.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/ieee1588clock.cpp -o $(OBJ_DIR)/ieee1588clock.o - -$(OBJ_DIR)/ptp_message.o: $(COMMON_DIR)/ptp_message.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/ptp_message.cpp -o $(OBJ_DIR)/ptp_message.o - -$(OBJ_DIR)/ap_message.o: $(COMMON_DIR)/ap_message.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/ap_message.cpp -o $(OBJ_DIR)/ap_message.o - -$(OBJ_DIR)/avbts_osnet.o: $(COMMON_DIR)/avbts_osnet.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/avbts_osnet.cpp -o $(OBJ_DIR)/avbts_osnet.o - -$(OBJ_DIR)/linux_hal_persist_file.o: $(SRC_DIR)/linux_hal_persist_file.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/linux_hal_persist_file.cpp -o $(OBJ_DIR)/linux_hal_persist_file.o - -$(OBJ_DIR)/gptp_log.o: $(COMMON_DIR)/gptp_log.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/gptp_log.cpp -o $(OBJ_DIR)/gptp_log.o - -$(OBJ_DIR)/gptp_cfg.o: $(COMMON_DIR)/gptp_cfg.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(COMMON_DIR)/gptp_cfg.cpp -o $(OBJ_DIR)/gptp_cfg.o - -$(OBJ_DIR)/ini.o: $(COMMON_DIR)/ini.c $(HEADER_FILES) - $(CC) $(CFLAGS) -c $(COMMON_DIR)/ini.c -o $(OBJ_DIR)/ini.o - -$(OBJ_DIR)/watchdog.o: $(SRC_DIR)/watchdog.cpp $(HEADER_FILES) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/watchdog.cpp -o $(OBJ_DIR)/watchdog.o -clean: - $(RM) *~ $(OBJ_DIR)/*.o $(OBJ_DIR)/daemon_cl - diff --git a/daemons/gptp/linux/build/obj/.dir b/daemons/gptp/linux/build/obj/.dir deleted file mode 100644 index e69de29b..00000000 --- a/daemons/gptp/linux/build/obj/.dir +++ /dev/null diff --git a/daemons/gptp/linux/shm_test/.gitignore b/daemons/gptp/linux/shm_test/.gitignore deleted file mode 100644 index f0acd3a8..00000000 --- a/daemons/gptp/linux/shm_test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -shm_test diff --git a/daemons/gptp/linux/shm_test/Makefile b/daemons/gptp/linux/shm_test/Makefile deleted file mode 100644 index 6bc87880..00000000 --- a/daemons/gptp/linux/shm_test/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright (c) 2015 Coveloz Consulting -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 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 Coveloz Consulting nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -COMMON_DIR := ../../common -LINUX_SRC_DIR := ../src -TARGET_NAME := shm_test - -CFLAGS_G = -Wall -g -Wnon-virtual-dtor -I. -I$(COMMON_DIR) -I$(LINUX_SRC_DIR) -LDFLAGS_G = -lpthread -lrt - -OBJ_FILES = -HEADER_FILES := $(COMMON_DIR)/ipcdef.hpp $(LINUX_SRC_DIR)/linux_ipc.hpp - -CFLAGS = $(CFLAGS_G) -LDFLAGS = $(LDFLAGS_G) - -all: $(TARGET_NAME) - -$(TARGET_NAME): shm_test.cpp - # Generating $@ - @ $(CXX) $(CFLAGS) $(CXXFLAGS) $(OBJ_FILES) shm_test.cpp -o $(TARGET_NAME) $(LDFLAGS) - -clean: - # Cleaning up - @ $(RM) *.o $(TARGET_NAME) - diff --git a/daemons/gptp/linux/shm_test/shm_test.cpp b/daemons/gptp/linux/shm_test/shm_test.cpp deleted file mode 100644 index dbe01c5b..00000000 --- a/daemons/gptp/linux/shm_test/shm_test.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/****************************************************************************** - - Copyright (c) 2015, Coveloz Consulting - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 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 Coveloz Consulting nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -******************************************************************************/ - -#include <iostream> -#include <fstream> - -#include <stdio.h> -#include <stdint.h> -#include <sys/mman.h> -#include <sys/stat.h> /* For mode constants */ -#include <fcntl.h> /* For O_* constants */ -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <pthread.h> - -#include "linux_ipc.hpp" - -static inline uint64_t getCpuFrequency(void) -{ - uint64_t freq = 0; - std::string line; - std::ifstream cpuinfo("/proc/cpuinfo"); - if (cpuinfo.is_open()) - { - while ( getline (cpuinfo,line) ) - { - if(line.find("MHz") != line.npos) - break; - } - cpuinfo.close(); - } - else std::cout << "Unable to open file"; - - size_t pos = line.find(":"); - if (pos != line.npos) { - std::string mhz_str = line.substr(pos+2, line.npos - pos); - double freq1 = strtod(mhz_str.c_str(), NULL); - freq = freq1 * 1000000ULL; - } - return freq; -} - -int main(int argc, char *argv[]) -{ - int shm_fd = shm_open(SHM_NAME, O_RDONLY, 0666); - - if( shm_fd < 0) { - fprintf(stderr, "shm_open(). %s\n", strerror(errno)); - return -1; - } - char *addr = (char*)mmap(NULL, SHM_SIZE, PROT_READ, MAP_SHARED, shm_fd, 0); - - if( addr == MAP_FAILED ) { - fprintf(stderr, "Error on mmap. Aborting.\n"); - return -1; - } - fprintf(stdout, "--------------------------------------------\n"); - int buf_offset = 0; - buf_offset += sizeof(pthread_mutex_t); - gPtpTimeData *ptpData = (gPtpTimeData*)(addr+buf_offset); - /*TODO: Scale to ns*/ - uint64_t freq = getCpuFrequency(); - printf("Frequency %lu Hz\n", freq); - - fprintf(stdout, "ml phoffset %ld\n", ptpData->ml_phoffset); - fprintf(stdout, "ml freq offset %Lf\n", ptpData->ml_freqoffset); - fprintf(stdout, "ls phoffset %ld\n", ptpData->ls_phoffset); - fprintf(stdout, "ls freq offset %Lf\n", ptpData->ls_freqoffset); - fprintf(stdout, "local time %llu\n\n", (unsigned long long) ptpData->local_time); - - fprintf(stdout, "gptp grandmaster id %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - (unsigned int) ptpData->gptp_grandmaster_id[0], (unsigned int) ptpData->gptp_grandmaster_id[1], - (unsigned int) ptpData->gptp_grandmaster_id[2], (unsigned int) ptpData->gptp_grandmaster_id[3], - (unsigned int) ptpData->gptp_grandmaster_id[4], (unsigned int) ptpData->gptp_grandmaster_id[5], - (unsigned int) ptpData->gptp_grandmaster_id[6], (unsigned int) ptpData->gptp_grandmaster_id[7]); - fprintf(stdout, "gptp domain number %u\n\n", (unsigned int) ptpData->gptp_domain_number); - - fprintf(stdout, "clock identity %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - (unsigned int) ptpData->clock_identity[0], (unsigned int) ptpData->clock_identity[1], - (unsigned int) ptpData->clock_identity[2], (unsigned int) ptpData->clock_identity[3], - (unsigned int) ptpData->clock_identity[4], (unsigned int) ptpData->clock_identity[5], - (unsigned int) ptpData->clock_identity[6], (unsigned int) ptpData->clock_identity[7]); - fprintf(stdout, "priority1 %u\n", (unsigned int) ptpData->priority1); - fprintf(stdout, "clock_class %u\n", (unsigned int) ptpData->clock_class); - fprintf(stdout, "offset_scaled_log_variance %d\n", (int) ptpData->offset_scaled_log_variance); - fprintf(stdout, "clock_accuracy %u\n", (unsigned int) ptpData->clock_accuracy); - fprintf(stdout, "priority2 %u\n", (unsigned int) ptpData->priority2); - fprintf(stdout, "domain_number %u\n", (unsigned int) ptpData->domain_number); - fprintf(stdout, "log_sync_interval %d\n", (int) ptpData->log_sync_interval); - fprintf(stdout, "log_announce_interval %d\n", (int) ptpData->log_announce_interval); - fprintf(stdout, "log_pdelay_interval %d\n", (int) ptpData->log_pdelay_interval); - fprintf(stdout, "port_number %u\n\n", (unsigned int) ptpData->port_number); - - fprintf(stdout, "sync count %u\n", ptpData->sync_count); - fprintf(stdout, "pdelay count %u\n", ptpData->pdelay_count); - fprintf(stdout, "asCapable %s\n", ptpData->asCapable ? "True" : "False"); - fprintf(stdout, "Port State %d\n", (int)ptpData->port_state); - fprintf(stdout, "process_id %d\n\n", (int)ptpData->process_id); - - return 0; -} - diff --git a/daemons/gptp/linux/src/daemon_cl.cpp b/daemons/gptp/linux/src/daemon_cl.cpp deleted file mode 100644 index 53a8f9a4..00000000 --- a/daemons/gptp/linux/src/daemon_cl.cpp +++ /dev/null @@ -1,557 +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 "ieee1588.hpp" -#include "avbts_clock.hpp" -#include "avbts_osnet.hpp" -#include "avbts_oslock.hpp" -#include "avbts_persist.hpp" -#include "gptp_cfg.hpp" -#include "ether_port.hpp" - -#ifdef ARCH_INTELCE -#include "linux_hal_intelce.hpp" -#else -#include "linux_hal_generic.hpp" -#endif - -#include "linux_hal_persist_file.hpp" -#include <ctype.h> -#include <inttypes.h> -#include <signal.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <stdlib.h> -#include <errno.h> -#include <sys/stat.h> -#include <unistd.h> -#include <string.h> - -#ifdef SYSTEMD_WATCHDOG -#include <watchdog.hpp> -#endif - -#define PHY_DELAY_GB_TX_I20 184 //1G delay -#define PHY_DELAY_GB_RX_I20 382 //1G delay -#define PHY_DELAY_MB_TX_I20 1044//100M delay -#define PHY_DELAY_MB_RX_I20 2133//100M delay - -void gPTPPersistWriteCB(char *bufPtr, uint32_t bufSize); - -void print_usage( char *arg0 ) { - fprintf( stderr, - "%s <network interface> [-S] [-P] [-M <filename>] " - "[-G <group>] [-R <priority 1>] " - "[-D <gb_tx_delay,gb_rx_delay,mb_tx_delay,mb_rx_delay>] " - "[-T] [-L] [-E] [-GM] [-INITSYNC <value>] [-OPERSYNC <value>] " - "[-INITPDELAY <value>] [-OPERPDELAY <value>] " - "[-F <path to gptp_cfg.ini file>] " - "\n", - arg0 ); - fprintf - ( stderr, - "\t-S start syntonization\n" - "\t-P pulse per second\n" - "\t-M <filename> save/restore state\n" - "\t-G <group> group id for shared memory\n" - "\t-R <priority 1> priority 1 value\n" - "\t-D Phy Delay <gb_tx_delay,gb_rx_delay,mb_tx_delay,mb_rx_delay>\n" - "\t-T force master (ignored when Automotive Profile set)\n" - "\t-L force slave (ignored when Automotive Profile set)\n" - "\t-E enable test mode (as defined in AVnu automotive profile)\n" - "\t-V enable AVnu Automotive Profile\n" - "\t-GM set grandmaster for Automotive Profile\n" - "\t-INITSYNC <value> initial sync interval (Log base 2. 0 = 1 second)\n" - "\t-OPERSYNC <value> operational sync interval (Log base 2. 0 = 1 second)\n" - "\t-INITPDELAY <value> initial pdelay interval (Log base 2. 0 = 1 second)\n" - "\t-OPERPDELAY <value> operational pdelay interval (Log base 2. 0 = 1 sec)\n" - "\t-F <path-to-ini-file>\n" - ); -} - -int watchdog_setup(OSThreadFactory *thread_factory) -{ -#ifdef SYSTEMD_WATCHDOG - SystemdWatchdogHandler *watchdog = new SystemdWatchdogHandler(); - OSThread *watchdog_thread = thread_factory->createThread(); - int watchdog_result; - long unsigned int watchdog_interval; - watchdog_interval = watchdog->getSystemdWatchdogInterval(&watchdog_result); - if (watchdog_result) { - GPTP_LOG_INFO("Watchtog interval read from service file: %lu us", watchdog_interval); - watchdog->update_interval = watchdog_interval / 2; - GPTP_LOG_STATUS("Starting watchdog handler (Update every: %lu us)", watchdog->update_interval); - watchdog_thread->start(watchdogUpdateThreadFunction, watchdog); - return 0; - } else if (watchdog_result < 0) { - GPTP_LOG_ERROR("Watchdog settings read error."); - return -1; - } else { - GPTP_LOG_STATUS("Watchdog disabled"); - return 0; - } -#else - return 0; -#endif -} - -static IEEE1588Clock *pClock = NULL; -static EtherPort *pPort = NULL; - -int main(int argc, char **argv) -{ - PortInit_t portInit; - - sigset_t set; - InterfaceName *ifname; - int sig; - - bool syntonize = false; - int i; - bool pps = false; - uint8_t priority1 = 248; - bool override_portstate = false; - PortState port_state = PTP_SLAVE; - char *restoredata = NULL; - char *restoredataptr = NULL; - off_t restoredatalength = 0; - off_t restoredatacount = 0; - bool restorefailed = false; - LinuxIPCArg *ipc_arg = NULL; - bool use_config_file = false; - char config_file_path[512]; - const char *systemClockDesc = NULL; - memset(config_file_path, 0, 512); - - GPTPPersist *pGPTPPersist = NULL; - LinuxThreadFactory *thread_factory = new LinuxThreadFactory(); - - // Block SIGUSR1 - { - sigset_t block; - sigemptyset( &block ); - sigaddset( &block, SIGUSR1 ); - if( pthread_sigmask( SIG_BLOCK, &block, NULL ) != 0 ) { - GPTP_LOG_ERROR("Failed to block SIGUSR1"); - return -1; - } - } - - GPTP_LOG_REGISTER(); - GPTP_LOG_INFO("gPTP starting"); - if (watchdog_setup(thread_factory) != 0) { - GPTP_LOG_ERROR("Watchdog handler setup error"); - return -1; - } - phy_delay_map_t ether_phy_delay; - bool input_delay=false; - - portInit.clock = NULL; - portInit.index = 0; - portInit.timestamper = NULL; - portInit.net_label = NULL; - portInit.automotive_profile = false; - portInit.isGM = false; - portInit.testMode = false; - portInit.linkUp = false; - portInit.initialLogSyncInterval = LOG2_INTERVAL_INVALID; - portInit.initialLogPdelayReqInterval = LOG2_INTERVAL_INVALID; - portInit.operLogPdelayReqInterval = LOG2_INTERVAL_INVALID; - portInit.operLogSyncInterval = LOG2_INTERVAL_INVALID; - portInit.condition_factory = NULL; - portInit.thread_factory = NULL; - portInit.timer_factory = NULL; - portInit.lock_factory = NULL; - portInit.syncReceiptThreshold = - CommonPort::DEFAULT_SYNC_RECEIPT_THRESH; - portInit.neighborPropDelayThreshold = - CommonPort::NEIGHBOR_PROP_DELAY_THRESH; - - LinuxNetworkInterfaceFactory *default_factory = - new LinuxNetworkInterfaceFactory; - OSNetworkInterfaceFactory::registerFactory - (factory_name_t("default"), default_factory); - LinuxTimerQueueFactory *timerq_factory = new LinuxTimerQueueFactory(); - LinuxLockFactory *lock_factory = new LinuxLockFactory(); - LinuxTimerFactory *timer_factory = new LinuxTimerFactory(); - LinuxConditionFactory *condition_factory = new LinuxConditionFactory(); - LinuxSharedMemoryIPC *ipc = new LinuxSharedMemoryIPC(); - /* Create Low level network interface object */ - if( argc < 2 ) { - printf( "Interface name required\n" ); - print_usage( argv[0] ); - return -1; - } - ifname = new InterfaceName( argv[1], strlen(argv[1]) ); - - /* Process optional arguments */ - for( i = 2; i < argc; ++i ) { - - if( argv[i][0] == '-' ) { - if( strcmp(argv[i] + 1, "S") == 0 ) { - // Get syntonize directive from command line - syntonize = true; - } - else if( strcmp(argv[i] + 1, "T" ) == 0 ) { - override_portstate = true; - port_state = PTP_MASTER; - } - else if( strcmp(argv[i] + 1, "L" ) == 0 ) { - override_portstate = true; - port_state = PTP_SLAVE; - } - else if( strcmp(argv[i] + 1, "M" ) == 0 ) { - // Open file - if( i+1 < argc ) { - pGPTPPersist = makeLinuxGPTPPersistFile(); - if (pGPTPPersist) { - pGPTPPersist->initStorage(argv[i + 1]); - } - } - else { - printf( "Restore file must be specified on " - "command line\n" ); - } - } - else if( strcmp(argv[i] + 1, "G") == 0 ) { - if( i+1 < argc ) { - ipc_arg = new LinuxIPCArg(argv[++i]); - } else { - printf( "Must specify group name on the command line\n" ); - } - } - else if( strcmp(argv[i] + 1, "P") == 0 ) { - pps = true; - } - else if( strcmp(argv[i] + 1, "H") == 0 ) { - print_usage( argv[0] ); - GPTP_LOG_UNREGISTER(); - return 0; - } - else if( strcmp(argv[i] + 1, "R") == 0 ) { - if( i+1 >= argc ) { - printf( "Priority 1 value must be specified on " - "command line, using default value\n" ); - } else { - unsigned long tmp = strtoul( argv[i+1], NULL, 0 ); ++i; - if( tmp == 0 ) { - printf( "Invalid priority 1 value, using " - "default value\n" ); - } else { - priority1 = (uint8_t) tmp; - } - } - } - else if (strcmp(argv[i] + 1, "D") == 0) { - int phy_delay[4]; - input_delay=true; - int delay_count=0; - char *cli_inp_delay = strtok(argv[i+1],","); - while (cli_inp_delay != NULL) - { - if(delay_count>3) - { - printf("Too many values\n"); - print_usage( argv[0] ); - GPTP_LOG_UNREGISTER(); - return 0; - } - phy_delay[delay_count]=atoi(cli_inp_delay); - delay_count++; - cli_inp_delay = strtok(NULL,","); - } - if (delay_count != 4) - { - printf("All four delay values must be specified\n"); - print_usage( argv[0] ); - GPTP_LOG_UNREGISTER(); - return 0; - } - ether_phy_delay[LINKSPEED_1G].set_delay - ( phy_delay[0], phy_delay[1] ); - ether_phy_delay[LINKSPEED_100MB].set_delay - ( phy_delay[2], phy_delay[3] ); - } - else if (strcmp(argv[i] + 1, "V") == 0) { - portInit.automotive_profile = true; - } - else if (strcmp(argv[i] + 1, "GM") == 0) { - portInit.isGM = true; - } - else if (strcmp(argv[i] + 1, "E") == 0) { - portInit.testMode = true; - } - else if (strcmp(argv[i] + 1, "INITSYNC") == 0) { - portInit.initialLogSyncInterval = atoi(argv[++i]); - } - else if (strcmp(argv[i] + 1, "OPERSYNC") == 0) { - portInit.operLogSyncInterval = atoi(argv[++i]); - } - else if (strcmp(argv[i] + 1, "INITPDELAY") == 0) { - portInit.initialLogPdelayReqInterval = atoi(argv[++i]); - } - else if (strcmp(argv[i] + 1, "OPERPDELAY") == 0) { - portInit.operLogPdelayReqInterval = atoi(argv[++i]); - } - else if (strcmp(argv[i] + 1, "F") == 0) - { - if( i+1 < argc ) { - use_config_file = true; - strcpy(config_file_path, argv[i+1]); - } else { - fprintf(stderr, "config file must be specified.\n"); - } - } - } - } - - if (!input_delay) - { - ether_phy_delay[LINKSPEED_1G].set_delay - ( PHY_DELAY_GB_TX_I20, PHY_DELAY_GB_RX_I20 ); - ether_phy_delay[LINKSPEED_100MB].set_delay - ( PHY_DELAY_MB_TX_I20, PHY_DELAY_MB_RX_I20 ); - } - portInit.phy_delay = ðer_phy_delay; - - if( !ipc->init( ipc_arg ) ) { - delete ipc; - ipc = NULL; - } - if( ipc_arg != NULL ) delete ipc_arg; - - if( pGPTPPersist ) { - uint32_t bufSize = 0; - if (!pGPTPPersist->readStorage(&restoredata, &bufSize)) - GPTP_LOG_ERROR("Failed to stat restore file"); - restoredatalength = bufSize; - restoredatacount = restoredatalength; - restoredataptr = (char *)restoredata; - } - -#ifdef ARCH_INTELCE - EtherTimestamper *timestamper = new LinuxTimestamperIntelCE(); -#else - EtherTimestamper *timestamper = new LinuxTimestamperGeneric(); -#endif - - sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset( &set, SIGTERM ); - sigaddset(&set, SIGHUP); - sigaddset(&set, SIGUSR2); - if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) { - perror("pthread_sigmask()"); - GPTP_LOG_UNREGISTER(); - return -1; - } - - pClock = new IEEE1588Clock - ( false, syntonize, priority1, timerq_factory, ipc, - lock_factory ); - - if( restoredataptr != NULL ) { - if( !restorefailed ) - restorefailed = - !pClock->restoreSerializedState( restoredataptr, &restoredatacount ); - restoredataptr = ((char *)restoredata) + (restoredatalength - restoredatacount); - } - - // TODO: The setting of values into temporary variables should be changed to - // just set directly into the portInit struct. - portInit.clock = pClock; - portInit.index = 1; - portInit.timestamper = timestamper; - portInit.net_label = ifname; - portInit.condition_factory = condition_factory; - portInit.thread_factory = thread_factory; - portInit.timer_factory = timer_factory; - portInit.lock_factory = lock_factory; - - if(use_config_file) - { - GptpIniParser iniParser(config_file_path); - - if (iniParser.parserError() < 0) { - GPTP_LOG_ERROR("Cant parse ini file. Aborting file reading."); - } - else - { - GPTP_LOG_INFO("priority1 = %d", iniParser.getPriority1()); - GPTP_LOG_INFO("announceReceiptTimeout: %d", iniParser.getAnnounceReceiptTimeout()); - GPTP_LOG_INFO("syncReceiptTimeout: %d", iniParser.getSyncReceiptTimeout()); - iniParser.print_phy_delay(); - GPTP_LOG_INFO("neighborPropDelayThresh: %ld", iniParser.getNeighborPropDelayThresh()); - GPTP_LOG_INFO("syncReceiptThreshold: %d", iniParser.getSyncReceiptThresh()); - - /* If using config file, set the neighborPropDelayThresh. - * Otherwise it will use its default value (800ns) */ - portInit.neighborPropDelayThreshold = - iniParser.getNeighborPropDelayThresh(); - - /* If using config file, set the syncReceiptThreshold, otherwise - * it will use the default value (SYNC_RECEIPT_THRESH) - */ - portInit.syncReceiptThreshold = - iniParser.getSyncReceiptThresh(); - - if( strnlen( iniParser.getSystemClockDesc(), - MAX_CLOCK_DESC_LEN ) != 0 ) - systemClockDesc = - iniParser.getSystemClockDesc(); - - /*Only overwrites phy_delay default values if not input_delay switch enabled*/ - if(!input_delay) - { - ether_phy_delay = iniParser.getPhyDelay(); - } - } - - } - - if( systemClockDesc != NULL ) - { - if( timestamper->HWTimestamper_setsystemclock - ( systemClockDesc )) - GPTP_LOG_INFO - ( "Using system Clock: %s", systemClockDesc ); - } - - pPort = new EtherPort(&portInit); - - if (!pPort->init_port()) { - GPTP_LOG_ERROR("failed to initialize port"); - GPTP_LOG_UNREGISTER(); - return -1; - } - - if( restoredataptr != NULL ) { - if( !restorefailed ) { - restorefailed = !pPort->restoreSerializedState( restoredataptr, &restoredatacount ); - GPTP_LOG_INFO("Persistent port data restored: asCapable:%d, port_state:%d, one_way_delay:%lld", - pPort->getAsCapable(), pPort->getPortState(), pPort->getLinkDelay()); - } - restoredataptr = ((char *)restoredata) + (restoredatalength - restoredatacount); - } - - if (portInit.automotive_profile) { - if (portInit.isGM) { - port_state = PTP_MASTER; - } - else { - port_state = PTP_SLAVE; - } - override_portstate = true; - } - - if( override_portstate ) { - pPort->setPortState( port_state ); - } - - // Start PPS if requested - if( pps ) { - if( !timestamper->HWTimestamper_PPS_start()) { - GPTP_LOG_ERROR("Failed to start pulse per second I/O"); - } - } - - // Configure persistent write - if (pGPTPPersist) { - off_t len = 0; - restoredatacount = 0; - pClock->serializeState(NULL, &len); - restoredatacount += len; - pPort->serializeState(NULL, &len); - restoredatacount += len; - pGPTPPersist->setWriteSize((uint32_t)restoredatacount); - pGPTPPersist->registerWriteCB(gPTPPersistWriteCB); - } - - pPort->processEvent(POWERUP); - - do { - sig = 0; - - if (sigwait(&set, &sig) != 0) { - perror("sigwait()"); - GPTP_LOG_UNREGISTER(); - return -1; - } - - if (sig == SIGHUP) { - if (pGPTPPersist) { - // If port is either master or slave, save clock and then port state - if (pPort->getPortState() == PTP_MASTER || pPort->getPortState() == PTP_SLAVE) { - pGPTPPersist->triggerWriteStorage(); - } - } - } - - if (sig == SIGUSR2) { - pPort->logIEEEPortCounters(); - } - } while (sig == SIGHUP || sig == SIGUSR2); - - GPTP_LOG_ERROR("Exiting on %d", sig); - - if (pGPTPPersist) { - pGPTPPersist->closeStorage(); - } - - // Stop PPS if previously started - if( pps ) { - if( !timestamper->HWTimestamper_PPS_stop()) { - GPTP_LOG_ERROR("Failed to stop pulse per second I/O"); - } - } - - if( ipc ) delete ipc; - - GPTP_LOG_UNREGISTER(); - return 0; -} - -void gPTPPersistWriteCB(char *bufPtr, uint32_t bufSize) -{ - off_t restoredatalength = bufSize; - off_t restoredatacount = restoredatalength; - char *restoredataptr = NULL; - - GPTP_LOG_INFO("Signal received to write restore data"); - - restoredataptr = (char *)bufPtr; - pClock->serializeState(restoredataptr, &restoredatacount); - restoredataptr = ((char *)bufPtr) + (restoredatalength - restoredatacount); - pPort->serializeState(restoredataptr, &restoredatacount); - restoredataptr = ((char *)bufPtr) + (restoredatalength - restoredatacount); -} diff --git a/daemons/gptp/linux/src/linux_hal_common.cpp b/daemons/gptp/linux/src/linux_hal_common.cpp deleted file mode 100644 index ab312c95..00000000 --- a/daemons/gptp/linux/src/linux_hal_common.cpp +++ /dev/null @@ -1,1117 +0,0 @@ -/****************************************************************************** - - 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 <linux_hal_common.hpp> -#include <sys/types.h> -#include <avbts_clock.hpp> -#include <ether_port.hpp> - -#include <pthread.h> -#include <linux_ipc.hpp> - -#include <sys/mman.h> -#include <fcntl.h> -#include <grp.h> -#include <net/if.h> - -#include <unistd.h> -#include <errno.h> - -#include <signal.h> -#include <net/ethernet.h> /* the L2 protocols */ - -#include <netpacket/packet.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <sys/socket.h> -#include <netinet/in.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <linux/sockios.h> -#include <gptp_cfg.hpp> - -Timestamp tsToTimestamp(struct timespec *ts) -{ - Timestamp ret; - int seclen = sizeof(ts->tv_sec) - sizeof(ret.seconds_ls); - if (seclen > 0) { - ret.seconds_ms = - ts->tv_sec >> (sizeof(ts->tv_sec) - seclen) * 8; - ret.seconds_ls = ts->tv_sec & 0xFFFFFFFF; - } else { - ret.seconds_ms = 0; - ret.seconds_ls = ts->tv_sec; - } - ret.nanoseconds = ts->tv_nsec; - return ret; -} - -LinuxNetworkInterface::~LinuxNetworkInterface() { - close( sd_event ); - close( sd_general ); -} - -net_result LinuxNetworkInterface::send -( LinkLayerAddress *addr, uint16_t etherType, 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 = PLAT_htons( etherType ); - remote->sll_ifindex = ifindex; - remote->sll_halen = ETH_ALEN; - addr->toOctetArray( remote->sll_addr ); - - if( timestamp ) { -#ifndef ARCH_INTELCE - net_lock.lock(); -#endif - 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 ) { - GPTP_LOG_ERROR( "Failed to send: %s(%d)", strerror(errno), errno ); - return net_fatal; - } - return net_succeed; -} - - -void LinuxNetworkInterface::disable_rx_queue() { - struct packet_mreq mr_8021as; - int err; - - if( !net_lock.lock() ) { - fprintf( stderr, "D rx lock failed\n" ); - _exit(0); - } - - 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 - ( sd_event, SOL_PACKET, PACKET_DROP_MEMBERSHIP, &mr_8021as, - sizeof( mr_8021as )); - if( err == -1 ) { - GPTP_LOG_ERROR - ( "Unable to add PTP multicast addresses to port id: %u", - ifindex ); - return; - } - - return; -} - -void LinuxNetworkInterface::clear_reenable_rx_queue() { - struct packet_mreq mr_8021as; - char buf[256]; - int err; - - while( recvfrom( sd_event, buf, 256, MSG_DONTWAIT, NULL, 0 ) != -1 ); - - 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 - ( sd_event, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr_8021as, - sizeof( mr_8021as )); - if( err == -1 ) { - GPTP_LOG_ERROR - ( "Unable to add PTP multicast addresses to port id: %u", - ifindex ); - return; - } - - if( !net_lock.unlock() ) { - fprintf( stderr, "D failed unlock rx lock, %d\n", err ); - } -} - -static void x_readEvent -( int sockint, EtherPort *pPort, int ifindex ) -{ - int status; - char buf[4096]; - struct iovec iov = { buf, sizeof buf }; - struct sockaddr_nl snl; - struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 }; - struct nlmsghdr *msgHdr; - struct ifinfomsg *ifi; - - status = recvmsg(sockint, &msg, 0); - - if (status < 0) { - GPTP_LOG_ERROR("read_netlink: Error recvmsg: %d", status); - return; - } - - if (status == 0) { - GPTP_LOG_ERROR("read_netlink: EOF"); - return; - } - - // Process the NETLINK messages - for (msgHdr = (struct nlmsghdr *)buf; NLMSG_OK(msgHdr, (unsigned int)status); msgHdr = NLMSG_NEXT(msgHdr, status)) - { - if (msgHdr->nlmsg_type == NLMSG_DONE) - return; - - if (msgHdr->nlmsg_type == NLMSG_ERROR) { - GPTP_LOG_ERROR("netlink message error"); - return; - } - - if (msgHdr->nlmsg_type == RTM_NEWLINK) { - ifi = (struct ifinfomsg *)NLMSG_DATA(msgHdr); - if (ifi->ifi_index == ifindex) { - bool linkUp = ifi->ifi_flags & IFF_RUNNING; - if (linkUp != pPort->getLinkUpState()) { - pPort->setLinkUpState(linkUp); - if (linkUp) { - pPort->processEvent(LINKUP); - } - else { - pPort->processEvent(LINKDOWN); - } - } - else { - GPTP_LOG_DEBUG("False (repeated) %s event for the interface", linkUp ? "LINKUP" : "LINKDOWN"); - } - } - } - } - return; -} - -static void x_initLinkUpStatus( EtherPort *pPort, int ifindex ) -{ - struct ifreq device; - memset(&device, 0, sizeof(device)); - device.ifr_ifindex = ifindex; - - int inetSocket = socket (AF_INET, SOCK_STREAM, 0); - if (inetSocket < 0) { - GPTP_LOG_ERROR("initLinkUpStatus error opening socket: %s", strerror(errno)); - return; - } - - int r = ioctl(inetSocket, SIOCGIFNAME, &device); - if (r < 0) { - GPTP_LOG_ERROR("initLinkUpStatus error reading interface name: %s", strerror(errno)); - close(inetSocket); - return; - } - r = ioctl(inetSocket, SIOCGIFFLAGS, &device); - if (r < 0) { - GPTP_LOG_ERROR("initLinkUpStatus error reading flags: %s", strerror(errno)); - close(inetSocket); - return; - } - if (device.ifr_flags & IFF_RUNNING) { - GPTP_LOG_DEBUG("Interface %s is up", device.ifr_name); - pPort->setLinkUpState(true); - } //linkUp == false by default - close(inetSocket); -} - - -bool LinuxNetworkInterface::getLinkSpeed( int sd, uint32_t *speed ) -{ - struct ifreq ifr; - struct ethtool_cmd edata; - - ifr.ifr_ifindex = ifindex; - if( ioctl( sd, SIOCGIFNAME, &ifr ) == -1 ) - { - GPTP_LOG_ERROR - ( "%s: SIOCGIFNAME failed: %s", __PRETTY_FUNCTION__, - strerror( errno )); - return false; - } - - ifr.ifr_data = (char *) &edata; - edata.cmd = ETHTOOL_GSET; - if( ioctl( sd, SIOCETHTOOL, &ifr ) == -1 ) - { - GPTP_LOG_ERROR - ( "%s: SIOCETHTOOL failed: %s", __PRETTY_FUNCTION__, - strerror( errno )); - return false; - } - - switch (ethtool_cmd_speed(&edata)) - { - default: - GPTP_LOG_ERROR( "%s: Unknown/Unsupported Speed!", - __PRETTY_FUNCTION__ ); - return false; - case SPEED_100: - *speed = LINKSPEED_100MB; - break; - case SPEED_1000: - *speed = LINKSPEED_1G; - break; - case SPEED_2500: - *speed = LINKSPEED_2_5G; - break; - case SPEED_10000: - *speed = LINKSPEED_10G; - break; - } - GPTP_LOG_STATUS( "Link Speed: %d kb/sec", *speed ); - - return true; -} - -void LinuxNetworkInterface::watchNetLink( CommonPort *iPort ) -{ - fd_set netLinkFD; - int netLinkSocket; - int inetSocket; - struct sockaddr_nl addr; - - EtherPort *pPort = - dynamic_cast<EtherPort *>(iPort); - if( pPort == NULL ) - { - GPTP_LOG_ERROR("NETLINK socket open error"); - return; - } - - netLinkSocket = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (netLinkSocket < 0) { - GPTP_LOG_ERROR("NETLINK socket open error"); - return; - } - - memset((void *) &addr, 0, sizeof (addr)); - - addr.nl_family = AF_NETLINK; - addr.nl_pid = getpid (); - addr.nl_groups = RTMGRP_LINK; - - if (bind (netLinkSocket, (struct sockaddr *) &addr, sizeof (addr)) < 0) { - GPTP_LOG_ERROR("Socket bind failed"); - close (netLinkSocket); - return; - } - - /* - * Open an INET family socket to be passed to getLinkSpeed() which calls - * ioctl() because NETLINK sockets do not support ioctl(). Since we will - * enter an infinite loop, there are no apparent close() calls for the - * open sockets, but they will be closed on process termination. - */ - inetSocket = socket (AF_INET, SOCK_STREAM, 0); - if (inetSocket < 0) { - GPTP_LOG_ERROR("watchNetLink error opening socket: %s", strerror(errno)); - close (netLinkSocket); - return; - } - - x_initLinkUpStatus(pPort, ifindex); - if( pPort->getLinkUpState() ) - { - uint32_t link_speed; - getLinkSpeed( inetSocket, &link_speed ); - pPort->setLinkSpeed((int32_t) link_speed ); - } else - { - pPort->setLinkSpeed( INVALID_LINKSPEED ); - } - - while (1) { - FD_ZERO(&netLinkFD); - FD_CLR(netLinkSocket, &netLinkFD); - FD_SET(netLinkSocket, &netLinkFD); - - // Wait forever for a net link event - int retval = select(FD_SETSIZE, &netLinkFD, NULL, NULL, NULL); - if (retval == -1) - ; // Error on select. We will ignore and keep going - else if (retval) { - bool prev_link_up = pPort->getLinkUpState(); - x_readEvent(netLinkSocket, pPort, ifindex); - - // Don't do anything else if link state is the same - if( prev_link_up == pPort->getLinkUpState() ) - continue; - if( pPort->getLinkUpState() ) - { - uint32_t link_speed; - getLinkSpeed( inetSocket, &link_speed ); - pPort->setLinkSpeed((int32_t) link_speed ); - } else - { - pPort->setLinkSpeed( INVALID_LINKSPEED ); - } - } - else { - ; // Would be timeout but Won't happen because we wait forever - } - } -} - - -struct LinuxTimerQueuePrivate { - pthread_t signal_thread; -}; - -struct LinuxTimerQueueActionArg { - timer_t timer_handle; - struct sigevent sevp; - event_descriptor_t *inner_arg; - ostimerq_handler func; - int type; - bool rm; -}; - -LinuxTimerQueue::~LinuxTimerQueue() { - pthread_join(_private->signal_thread,NULL); - if( _private != NULL ) delete _private; -} - -bool LinuxTimerQueue::init() { - _private = new LinuxTimerQueuePrivate; - if( _private == NULL ) return false; - - return true; -} - -void *LinuxTimerQueueHandler( void *arg ) { - LinuxTimerQueue *timerq = (LinuxTimerQueue *) arg; - sigset_t waitfor; - struct timespec timeout; - timeout.tv_sec = 0; timeout.tv_nsec = 100000000; /* 100 ms */ - - sigemptyset( &waitfor ); - GPTP_LOG_DEBUG("Signal thread started"); - while( !timerq->stop ) { - siginfo_t info; - LinuxTimerQueueMap_t::iterator iter; - sigaddset( &waitfor, SIGUSR1 ); - if( sigtimedwait( &waitfor, &info, &timeout ) == -1 ) { - if( errno == EAGAIN ) { - continue; - } - else { - GPTP_LOG_ERROR("Signal thread sigtimedwait error: %d", errno); - break; - } - } - if( timerq->lock->lock() != oslock_ok ) { - break; - } - - iter = timerq->timerQueueMap.find(info.si_value.sival_int); - if( iter != timerq->timerQueueMap.end() ) { - struct LinuxTimerQueueActionArg *arg = iter->second; - timerq->timerQueueMap.erase(iter); - timerq->LinuxTimerQueueAction( arg ); - if( arg->rm ) { - delete arg->inner_arg; - } - timer_delete(arg->timer_handle); - delete arg; - } - if( timerq->lock->unlock() != oslock_ok ) { - break; - } - } - GPTP_LOG_DEBUG("Signal thread exit"); - return NULL; -} - -void LinuxTimerQueue::LinuxTimerQueueAction( LinuxTimerQueueActionArg *arg ) { - arg->func( arg->inner_arg ); - - return; -} - -OSTimerQueue *LinuxTimerQueueFactory::createOSTimerQueue - ( IEEE1588Clock *clock ) { - LinuxTimerQueue *ret = new LinuxTimerQueue(); - - if( !ret->init() ) { - return NULL; - } - - ret->key = 0; - ret->stop = false; - ret->lock = clock->timerQLock(); - if( pthread_create - ( &(ret->_private->signal_thread), - NULL, LinuxTimerQueueHandler, ret ) != 0 ) { - delete ret; - return NULL; - } - - return ret; -} - - - -bool LinuxTimerQueue::addEvent -( unsigned long micros, int type, ostimerq_handler func, - event_descriptor_t * arg, bool rm, unsigned *event) { - LinuxTimerQueueActionArg *outer_arg; - int err; - LinuxTimerQueueMap_t::iterator iter; - - - outer_arg = new LinuxTimerQueueActionArg; - outer_arg->inner_arg = arg; - outer_arg->rm = rm; - outer_arg->func = func; - outer_arg->type = type; - - // Find key that we can use - while( timerQueueMap.find( key ) != timerQueueMap.end() ) { - ++key; - } - - { - struct itimerspec its; - memset(&(outer_arg->sevp), 0, sizeof(outer_arg->sevp)); - outer_arg->sevp.sigev_notify = SIGEV_SIGNAL; - outer_arg->sevp.sigev_signo = SIGUSR1; - outer_arg->sevp.sigev_value.sival_int = key; - if ( timer_create - (CLOCK_MONOTONIC, &outer_arg->sevp, &outer_arg->timer_handle) - == -1) { - GPTP_LOG_ERROR("timer_create failed - %s", strerror(errno)); - return false; - } - timerQueueMap[key] = outer_arg; - - memset(&its, 0, sizeof(its)); - its.it_value.tv_sec = micros / 1000000; - its.it_value.tv_nsec = (micros % 1000000) * 1000; - err = timer_settime( outer_arg->timer_handle, 0, &its, NULL ); - if( err < 0 ) { - GPTP_LOG_ERROR("Failed to arm timer: %s", strerror(errno)); - return false; - } - } - - return true; -} - - -bool LinuxTimerQueue::cancelEvent( int type, unsigned *event ) { - LinuxTimerQueueMap_t::iterator iter; - for( iter = timerQueueMap.begin(); iter != timerQueueMap.end();) { - if( (iter->second)->type == type ) { - // Delete element - if( (iter->second)->rm ) { - delete (iter->second)->inner_arg; - } - timer_delete(iter->second->timer_handle); - delete iter->second; - timerQueueMap.erase(iter++); - } else { - ++iter; - } - } - - return true; -} - - -void* OSThreadCallback( void* input ) { - OSThreadArg *arg = (OSThreadArg*) input; - - arg->ret = arg->func( arg->arg ); - return 0; -} - -bool LinuxTimestamper::post_init( int ifindex, int sd, TicketingLock *lock ) { - return true; -} - -LinuxTimestamper::~LinuxTimestamper() {} - -unsigned long LinuxTimer::sleep(unsigned long micros) { - struct timespec req; - struct timespec rem; - req.tv_sec = micros / 1000000; - req.tv_nsec = micros % 1000000 * 1000; - int ret = nanosleep( &req, &rem ); - while( ret == -1 && errno == EINTR ) { - req = rem; - ret = nanosleep( &req, &rem ); - } - if( ret == -1 ) { - fprintf - ( stderr, "Error calling nanosleep: %s\n", strerror( errno )); - _exit(-1); - } - return micros; -} - -struct TicketingLockPrivate { - pthread_cond_t condition; - pthread_mutex_t cond_lock; -}; - -bool TicketingLock::lock( bool *got ) { - uint8_t ticket; - bool yield = false; - bool ret = true; - if( !init_flag ) return false; - - if( pthread_mutex_lock( &_private->cond_lock ) != 0 ) { - ret = false; - goto done; - } - // Take a ticket - ticket = cond_ticket_issue++; - while( ticket != cond_ticket_serving ) { - if( got != NULL ) { - *got = false; - --cond_ticket_issue; - yield = true; - goto unlock; - } - if( pthread_cond_wait( &_private->condition, &_private->cond_lock ) != 0 ) { - ret = false; - goto unlock; - } - } - - if( got != NULL ) *got = true; - - unlock: - if( pthread_mutex_unlock( &_private->cond_lock ) != 0 ) { - ret = false; - goto done; - } - - if( yield ) pthread_yield(); - - done: - return ret; -} - -bool TicketingLock::unlock() { - bool ret = true; - if( !init_flag ) return false; - - if( pthread_mutex_lock( &_private->cond_lock ) != 0 ) { - ret = false; - goto done; - } - ++cond_ticket_serving; - if( pthread_cond_broadcast( &_private->condition ) != 0 ) { - ret = false; - goto unlock; - } - - unlock: - if( pthread_mutex_unlock( &_private->cond_lock ) != 0 ) { - ret = false; - goto done; - } - - done: - return ret; -} - -bool TicketingLock::init() { - int err; - if( init_flag ) return false; // Don't do this more than once - _private = new TicketingLockPrivate; - if( _private == NULL ) return false; - - err = pthread_mutex_init( &_private->cond_lock, NULL ); - if( err != 0 ) return false; - err = pthread_cond_init( &_private->condition, NULL ); - if( err != 0 ) return false; - in_use = false; - cond_ticket_issue = 0; - cond_ticket_serving = 0; - init_flag = true; - - return true; -} - -TicketingLock::TicketingLock() { - init_flag = false; - _private = NULL; -} - -TicketingLock::~TicketingLock() { - if( _private != NULL ) delete _private; -} - -struct LinuxLockPrivate { - pthread_t thread_id; - pthread_mutexattr_t mta; - pthread_mutex_t mutex; - pthread_cond_t port_ready_signal; -}; - -bool LinuxLock::initialize( OSLockType type ) { - int lock_c; - - _private = new LinuxLockPrivate; - if( _private == NULL ) return false; - - pthread_mutexattr_init(&_private->mta); - if( type == oslock_recursive ) - pthread_mutexattr_settype(&_private->mta, PTHREAD_MUTEX_RECURSIVE); - lock_c = pthread_mutex_init(&_private->mutex,&_private->mta); - if(lock_c != 0) { - GPTP_LOG_ERROR("Mutex initialization failed - %s",strerror(errno)); - return false; - } - - return true; -} - -LinuxLock::~LinuxLock() { - int lock_c = pthread_mutex_lock(&_private->mutex); - if(lock_c == 0) { - pthread_mutex_destroy( &_private->mutex ); - } -} - -OSLockResult LinuxLock::lock() { - int lock_c; - lock_c = pthread_mutex_lock(&_private->mutex); - if(lock_c != 0) { - fprintf( stderr, "LinuxLock: lock failed %d\n", lock_c ); - return oslock_fail; - } - return oslock_ok; -} - -OSLockResult LinuxLock::trylock() { - int lock_c; - lock_c = pthread_mutex_trylock(&_private->mutex); - if(lock_c != 0) return oslock_fail; - return oslock_ok; -} - -OSLockResult LinuxLock::unlock() { - int lock_c; - lock_c = pthread_mutex_unlock(&_private->mutex); - if(lock_c != 0) { - fprintf( stderr, "LinuxLock: unlock failed %d\n", lock_c ); - return oslock_fail; - } - return oslock_ok; -} - -struct LinuxConditionPrivate { - pthread_cond_t port_ready_signal; - pthread_mutex_t port_lock; -}; - - -LinuxCondition::~LinuxCondition() { - if( _private != NULL ) delete _private; -} - -bool LinuxCondition::initialize() { - int lock_c; - - _private = new LinuxConditionPrivate; - if( _private == NULL ) return false; - - pthread_cond_init(&_private->port_ready_signal, NULL); - lock_c = pthread_mutex_init(&_private->port_lock, NULL); - if (lock_c != 0) - return false; - return true; -} - -bool LinuxCondition::wait_prelock() { - pthread_mutex_lock(&_private->port_lock); - up(); - return true; -} - -bool LinuxCondition::wait() { - pthread_cond_wait(&_private->port_ready_signal, &_private->port_lock); - down(); - pthread_mutex_unlock(&_private->port_lock); - return true; -} - -bool LinuxCondition::signal() { - pthread_mutex_lock(&_private->port_lock); - if (waiting()) - pthread_cond_broadcast(&_private->port_ready_signal); - pthread_mutex_unlock(&_private->port_lock); - return true; -} - -struct LinuxThreadPrivate { - pthread_t thread_id; -}; - -bool LinuxThread::start(OSThreadFunction function, void *arg) { - sigset_t set; - sigset_t oset; - int err; - - _private = new LinuxThreadPrivate; - if( _private == NULL ) return false; - - 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) { - GPTP_LOG_ERROR - ("Add timer pthread_sigmask( SIG_BLOCK ... )"); - return false; - } - err = pthread_create(&_private->thread_id, NULL, OSThreadCallback, - arg_inner); - if (err != 0) - return false; - sigdelset(&oset, SIGALRM); - err = pthread_sigmask(SIG_SETMASK, &oset, NULL); - if (err != 0) { - GPTP_LOG_ERROR - ("Add timer pthread_sigmask( SIG_SETMASK ... )"); - return false; - } - - return true; -} - -bool LinuxThread::join(OSThreadExitCode & exit_code) { - int err; - err = pthread_join(_private->thread_id, NULL); - if (err != 0) - return false; - exit_code = arg_inner->ret; - delete arg_inner; - return true; -} - -LinuxThread::LinuxThread() { - _private = NULL; -}; - -LinuxThread::~LinuxThread() { - if( _private != NULL ) delete _private; -} - -LinuxSharedMemoryIPC::~LinuxSharedMemoryIPC() { - munmap(master_offset_buffer, SHM_SIZE); - shm_unlink(SHM_NAME); -} - -bool LinuxSharedMemoryIPC::init( OS_IPC_ARG *barg ) { - LinuxIPCArg *arg; - struct group *grp; - const char *group_name; - pthread_mutexattr_t shared; - mode_t oldumask = umask(0); - - if( barg == NULL ) { - group_name = DEFAULT_GROUPNAME; - } else { - arg = dynamic_cast<LinuxIPCArg *> (barg); - if( arg == NULL ) { - GPTP_LOG_ERROR( "Wrong IPC init arg type" ); - goto exit_error; - } else { - group_name = arg->group_name; - } - } - grp = getgrnam( group_name ); - if( grp == NULL ) { - GPTP_LOG_ERROR( "Group %s not found, will try root (0) instead", group_name ); - } - - shm_fd = shm_open( SHM_NAME, O_RDWR | O_CREAT, 0660 ); - if( shm_fd == -1 ) { - GPTP_LOG_ERROR( "shm_open(): %s", strerror(errno) ); - goto exit_error; - } - (void) umask(oldumask); - if (fchown(shm_fd, -1, grp != NULL ? grp->gr_gid : 0) < 0) { - GPTP_LOG_ERROR("shm_open(): Failed to set ownership"); - } - if( ftruncate( shm_fd, SHM_SIZE ) == -1 ) { - GPTP_LOG_ERROR( "ftruncate()" ); - goto exit_unlink; - } - master_offset_buffer = (char *) mmap - ( NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_LOCKED | MAP_SHARED, - shm_fd, 0 ); - if( master_offset_buffer == (char *) -1 ) { - GPTP_LOG_ERROR( "mmap()" ); - goto exit_unlink; - } - /*create mutex attr */ - err = pthread_mutexattr_init(&shared); - if(err != 0) { - GPTP_LOG_ERROR - ("mutex attr initialization failed - %s", - strerror(errno)); - goto exit_unlink; - } - pthread_mutexattr_setpshared(&shared,1); - /*create a mutex */ - err = pthread_mutex_init((pthread_mutex_t *) master_offset_buffer, &shared); - if(err != 0) { - GPTP_LOG_ERROR - ("sharedmem - Mutex initialization failed - %s", - strerror(errno)); - goto exit_unlink; - } - return true; - exit_unlink: - shm_unlink( SHM_NAME ); - exit_error: - return false; -} - -bool LinuxSharedMemoryIPC::update( - int64_t ml_phoffset, - int64_t ls_phoffset, - FrequencyRatio ml_freqoffset, - FrequencyRatio ls_freqoffset, - uint64_t local_time, - uint32_t sync_count, - uint32_t pdelay_count, - PortState port_state, - bool asCapable ) -{ - int buf_offset = 0; - pid_t process_id = getpid(); - char *shm_buffer = master_offset_buffer; - gPtpTimeData *ptimedata; - if( shm_buffer != NULL ) { - /* lock */ - pthread_mutex_lock((pthread_mutex_t *) shm_buffer); - buf_offset += sizeof(pthread_mutex_t); - ptimedata = (gPtpTimeData *) (shm_buffer + buf_offset); - ptimedata->ml_phoffset = ml_phoffset; - ptimedata->ls_phoffset = ls_phoffset; - ptimedata->ml_freqoffset = ml_freqoffset; - ptimedata->ls_freqoffset = ls_freqoffset; - ptimedata->local_time = local_time; - ptimedata->sync_count = sync_count; - ptimedata->pdelay_count = pdelay_count; - ptimedata->asCapable = asCapable; - ptimedata->port_state = port_state; - ptimedata->process_id = process_id; - /* unlock */ - pthread_mutex_unlock((pthread_mutex_t *) shm_buffer); - } - return true; -} - -bool LinuxSharedMemoryIPC::update_grandmaster( - uint8_t gptp_grandmaster_id[], - uint8_t gptp_domain_number ) -{ - int buf_offset = 0; - char *shm_buffer = master_offset_buffer; - gPtpTimeData *ptimedata; - if( shm_buffer != NULL ) { - /* lock */ - pthread_mutex_lock((pthread_mutex_t *) shm_buffer); - buf_offset += sizeof(pthread_mutex_t); - ptimedata = (gPtpTimeData *) (shm_buffer + buf_offset); - memcpy(ptimedata->gptp_grandmaster_id, gptp_grandmaster_id, PTP_CLOCK_IDENTITY_LENGTH); - ptimedata->gptp_domain_number = gptp_domain_number; - /* unlock */ - pthread_mutex_unlock((pthread_mutex_t *) shm_buffer); - } - return true; -} - -bool LinuxSharedMemoryIPC::update_network_interface( - uint8_t clock_identity[], - uint8_t priority1, - uint8_t clock_class, - int16_t offset_scaled_log_variance, - uint8_t clock_accuracy, - uint8_t priority2, - uint8_t domain_number, - int8_t log_sync_interval, - int8_t log_announce_interval, - int8_t log_pdelay_interval, - uint16_t port_number ) -{ - int buf_offset = 0; - char *shm_buffer = master_offset_buffer; - gPtpTimeData *ptimedata; - if( shm_buffer != NULL ) { - /* lock */ - pthread_mutex_lock((pthread_mutex_t *) shm_buffer); - buf_offset += sizeof(pthread_mutex_t); - ptimedata = (gPtpTimeData *) (shm_buffer + buf_offset); - memcpy(ptimedata->clock_identity, clock_identity, PTP_CLOCK_IDENTITY_LENGTH); - ptimedata->priority1 = priority1; - ptimedata->clock_class = clock_class; - ptimedata->offset_scaled_log_variance = offset_scaled_log_variance; - ptimedata->clock_accuracy = clock_accuracy; - ptimedata->priority2 = priority2; - ptimedata->domain_number = domain_number; - ptimedata->log_sync_interval = log_sync_interval; - ptimedata->log_announce_interval = log_announce_interval; - ptimedata->log_pdelay_interval = log_pdelay_interval; - ptimedata->port_number = port_number; - /* unlock */ - pthread_mutex_unlock((pthread_mutex_t *) shm_buffer); - } - return true; -} - -void LinuxSharedMemoryIPC::stop() { - if( master_offset_buffer != NULL ) { - munmap( master_offset_buffer, SHM_SIZE ); - shm_unlink( SHM_NAME ); - } -} - -bool LinuxNetworkInterfaceFactory::createInterface -( OSNetworkInterface **net_iface, InterfaceLabel *label, - CommonTimestamper *timestamper ) { - struct ifreq device; - int err; - struct sockaddr_ll ifsock_addr; - struct packet_mreq mr_8021as; - LinkLayerAddress addr; - int ifindex; - - LinuxNetworkInterface *net_iface_l = new LinuxNetworkInterface(); - - if( !net_iface_l->net_lock.init()) { - GPTP_LOG_ERROR( "Failed to initialize network lock"); - return false; - } - - InterfaceName *ifname = dynamic_cast<InterfaceName *>(label); - if( ifname == NULL ){ - GPTP_LOG_ERROR( "ifname == NULL"); - return false; - } - - net_iface_l->sd_general = socket( PF_PACKET, SOCK_DGRAM, 0 ); - if( net_iface_l->sd_general == -1 ) { - GPTP_LOG_ERROR( "failed to open general socket: %s", strerror(errno)); - return false; - } - net_iface_l->sd_event = socket( PF_PACKET, SOCK_DGRAM, 0 ); - if( net_iface_l->sd_event == -1 ) { - GPTP_LOG_ERROR - ( "failed to open event socket: %s ", strerror(errno)); - return false; - } - - memset( &device, 0, sizeof(device)); - ifname->toString( device.ifr_name, IFNAMSIZ - 1 ); - err = ioctl( net_iface_l->sd_event, SIOCGIFHWADDR, &device ); - if( err == -1 ) { - GPTP_LOG_ERROR - ( "Failed to get interface address: %s", strerror( errno )); - return false; - } - - addr = LinkLayerAddress( (uint8_t *)&device.ifr_hwaddr.sa_data ); - net_iface_l->local_addr = addr; - err = ioctl( net_iface_l->sd_event, SIOCGIFINDEX, &device ); - if( err == -1 ) { - GPTP_LOG_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 ) { - GPTP_LOG_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 = PLAT_htons( PTP_ETHERTYPE ); - err = bind - ( net_iface_l->sd_event, (sockaddr *) &ifsock_addr, - sizeof( ifsock_addr )); - if( err == -1 ) { - GPTP_LOG_ERROR( "Call to bind() failed: %s", strerror(errno) ); - return false; - } - - net_iface_l->timestamper = - dynamic_cast <LinuxTimestamper *>(timestamper); - if(net_iface_l->timestamper == NULL) { - GPTP_LOG_ERROR( "timestamper == NULL" ); - return false; - } - if( !net_iface_l->timestamper->post_init - ( ifindex, net_iface_l->sd_event, &net_iface_l->net_lock )) { - GPTP_LOG_ERROR( "post_init failed\n" ); - return false; - } - *net_iface = net_iface_l; - - return true; -} diff --git a/daemons/gptp/linux/src/linux_hal_common.hpp b/daemons/gptp/linux/src/linux_hal_common.hpp deleted file mode 100644 index 9eb3ddc9..00000000 --- a/daemons/gptp/linux/src/linux_hal_common.hpp +++ /dev/null @@ -1,723 +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. - -******************************************************************************/ - -#ifndef LINUX_HAL_COMMON_HPP -#define LINUX_HAL_COMMON_HPP - -/**@file*/ - -#include "avbts_osnet.hpp" -#include "avbts_oslock.hpp" -#include "avbts_oscondition.hpp" -#include "avbts_ostimerq.hpp" -#include "avbts_ostimer.hpp" -#include "avbts_osthread.hpp" -#include "avbts_osipc.hpp" -#include "ieee1588.hpp" -#include <ether_tstamper.hpp> -#include <linux/ethtool.h> - -#include <list> - -#define ONE_WAY_PHY_DELAY 400 /*!< One way phy delay. TX or RX phy delay default value*/ -#define P8021AS_MULTICAST "\x01\x80\xC2\x00\x00\x0E" /*!< Default multicast address*/ -#define PTP_DEVICE "/dev/ptpXX" /*!< Default PTP device */ -#define PTP_DEVICE_IDX_OFFS 8 /*!< PTP device index offset*/ -#define CLOCKFD 3 /*!< Clock file descriptor */ -#define FD_TO_CLOCKID(fd) ((~(clockid_t) (fd) << 3) | CLOCKFD) /*!< Converts an FD to CLOCKID */ -struct timespec; - -/** - * @brief Converts timestamp in the struct timespec format to Timestamp - * @param ts Timestamp on struct timespec format - * @return timestamp on the Timestamp format - */ -extern Timestamp tsToTimestamp(struct timespec *ts); - -struct TicketingLockPrivate; - -/** - * @brief Provides the type for the TicketingLock private structure - */ -typedef struct TicketingLockPrivate * TicketingLockPrivate_t; - -/** - * @brief TicketingLock: Implements the ticket lock algorithm. - * A ticket lock consists of two counters, one containing the - * number of requests to acquire the lock, and the other the - * number of times the lock has been released. A processor acquires the lock - * by performing a fetch and increment operation on the request counter and - * waiting until the result its ticket is equal to the value of the release - * counter. It releases the lock by incrementing the release counter. - */ -class TicketingLock { -public: - /** - * @brief Lock mechanism. - * Gets a ticket and try locking the process. - * @param got [out] If non-null, it is set to TRUE when the lock is acquired. FALSE otherwise. - * @return TRUE when successfully got the lock, FALSE otherwise. - */ - bool lock( bool *got = NULL ); - - /** - * @brief Unlock mechanism. Increments the release counter and unblock other threads - * waiting for a condition flag. - * @return TRUE in case of success, FALSE otherwise. - */ - bool unlock(); - - /** - * @brief Initializes all flags and counters. Create private structures. - * @return TRUE in case of success, FALSE otherwise. - */ - bool init(); - - /** - * @brief Default constructor sets some flags to false that will be initialized on - * the init method. Protects against using lock/unlock without calling init. - */ - TicketingLock(); - - /** - * @brief Deletes the object and private structures. - */ - ~TicketingLock(); -private: - bool init_flag; - TicketingLockPrivate_t _private; - bool in_use; - uint8_t cond_ticket_issue; - uint8_t cond_ticket_serving; -}; - -/** - * @brief LinuxTimestamper: Provides a generic hardware - * timestamp interface for linux based systems. - */ -class LinuxTimestamper : public EtherTimestamper { -public: - /** - * @brief Destructor - */ - virtual ~LinuxTimestamper() = 0; - - /** - * @brief Provides a generic method for initializing timestamp interfaces - * @param ifindex Network device interface index - * @param sd Socket descriptor - * @param lock [in] Pointer to ticketing Lock object - * @return TRUE if success, FALSE in case of error - */ - virtual bool post_init( int ifindex, int sd, TicketingLock *lock ) = 0; -}; - -/** - * @brief Provides a Linux network generic interface - */ -class LinuxNetworkInterface : public OSNetworkInterface { - friend class LinuxNetworkInterfaceFactory; -private: - LinkLayerAddress local_addr; - int sd_event; - int sd_general; - LinuxTimestamper *timestamper; - int ifindex; - - TicketingLock net_lock; -public: - /** - * @brief Sends a packet to a remote address - * @param addr [in] Remote link layer address - * @param etherType [in] The EtherType of the message in host order - * @param payload [in] Data buffer - * @param length Size of data buffer - * @param timestamp TRUE if to use the event socket with the PTP multicast address. FALSE if to use - * a general socket. - * @return net_fatal if error, net_success if success - */ - virtual net_result send - ( LinkLayerAddress *addr, uint16_t etherType, uint8_t *payload, size_t length, - bool timestamp ); - - /** - * @brief Receives a packet from a remote address - * @param addr [in] Remote link layer address - * @param payload [out] Data buffer - * @param length [out] Size of received data buffer - * @return net_succeed in case of successful reception, net_trfail in case there is - * an error on the transmit side, net_fatal if error on reception - */ - virtual net_result nrecv - ( LinkLayerAddress *addr, uint8_t *payload, size_t &length ); - - /** - * @brief Disables rx socket descriptor rx queue - * @return void - */ - void disable_rx_queue();; - - /** - * @brief Clears and enables the rx socket descriptor - * @return void - */ - void clear_reenable_rx_queue(); - - /** - * @brief Gets the local link layer address - * @param addr [out] Pointer to the LinkLayerAddress object - * @return void - */ - virtual void getLinkLayerAddress( LinkLayerAddress *addr ) { - *addr = local_addr; - } - - /** - * @brief Get speed of network link - * - * @param [in] sd Open socket descriptor - * @param [out] speed Link speed in kb/sec - * @return false on error - */ - bool getLinkSpeed( int sd, uint32_t *speed ); - - /** - * @brief Watch for net link changes. - */ - virtual void watchNetLink( CommonPort *pPort ); - - /** - * @brief Gets the payload offset - * @return payload offset - */ - virtual unsigned getPayloadOffset() { - return 0; - } - /** - * @brief Destroys the network interface - */ - ~LinuxNetworkInterface(); -protected: - /** - * @brief Default constructor - */ - LinuxNetworkInterface() {}; -}; - -/** - * @brief Provides a list of LinuxNetworkInterface members - */ -typedef std::list<LinuxNetworkInterface *> LinuxNetworkInterfaceList; - -struct LinuxLockPrivate; -/** - * @brief Provides a type for the LinuxLock class - */ -typedef LinuxLockPrivate * LinuxLockPrivate_t; - -/** - * @brief Extends OSLock generic interface to Linux - */ -class LinuxLock : public OSLock { - friend class LinuxLockFactory; -private: - OSLockType type; - LinuxLockPrivate_t _private; -protected: - /** - * @brief Default constructor. - */ - LinuxLock() { - _private = NULL; - } - - /** - * @brief Initializes all mutexes and locks - * @param type OSLockType enumeration. If oslock_recursive then set pthreads - * attributes to PTHREAD_MUTEX_RECURSIVE - * @return If successful, returns oslock_ok. Returns oslock_fail otherwise - */ - bool initialize( OSLockType type ); - - /** - * @brief Destroys mutexes if lock is still valid - */ - ~LinuxLock(); - - /** - * @brief Provides a simple lock mechanism. - * @return oslock_fail if lock has failed, oslock_ok otherwise. - */ - OSLockResult lock(); - - /** - * @brief Provides a simple trylock mechanism. - * @return oslock_fail if lock has failed, oslock_ok otherwise. - */ - OSLockResult trylock(); - - /** - * @brief Provides a simple unlock mechanism. - * @return oslock_fail if unlock has failed, oslock_ok otherwise. - */ - OSLockResult unlock(); -}; - -/** - * @brief Provides a factory pattern for LinuxLock class - */ -class LinuxLockFactory:public OSLockFactory { -public: - /** - * @brief Creates the locking mechanism - * @param type OSLockType enumeration - * @return Pointer to OSLock object - */ - OSLock * createLock( OSLockType type ) const - { - LinuxLock *lock = new LinuxLock(); - if (!lock->initialize(type)) { - delete lock; - lock = NULL; - } - return lock; - } -}; - -struct LinuxConditionPrivate; -/** - * @brief Provides a private type for the LinuxCondition class - */ -typedef struct LinuxConditionPrivate * LinuxConditionPrivate_t; - -/** - * @brief Extends OSCondition class to Linux - */ -class LinuxCondition : public OSCondition { - friend class LinuxConditionFactory; -private: - LinuxConditionPrivate_t _private; -protected: - - /** - * @brief Initializes locks and mutex conditions - * @return TRUE if it is ok, FALSE in case of error - */ - bool initialize(); -public: - - /** - * @brief Counts up the amount of times we call the locking - * mechanism - * @return TRUE after incrementing the counter. - */ - bool wait_prelock(); - - /** - * @brief Waits until the ready signal condition is met and decrements - * the counter. - */ - bool wait(); - - /** - * @brief Unblock all threads that are busy waiting for a condition - * @return TRUE - */ - bool signal(); - - /* - * Default constructor - */ - ~LinuxCondition(); - - /* - * Destructor: Deletes internal variables - */ - LinuxCondition() { - _private = NULL; - } -}; - -/** - * @brief Implements factory design pattern for LinuxCondition class - */ -class LinuxConditionFactory : public OSConditionFactory { -public: - /** - * @brief Creates LinuxCondition objects - * @return Pointer to the OSCondition object in case of success. NULL otherwise - */ - OSCondition *createCondition() const - { - LinuxCondition *result = new LinuxCondition(); - return result->initialize() ? result : NULL; - } -}; - -struct LinuxTimerQueueActionArg; - -/** - * @brief Provides a map type for the LinuxTimerQueue class - */ -typedef std::map < int, struct LinuxTimerQueueActionArg *> LinuxTimerQueueMap_t; - -/** - * @brief Linux timer queue handler. Deals with linux queues - * @param arg [in] LinuxTimerQueue arguments - * @return void - */ -void *LinuxTimerQueueHandler( void *arg ); - -struct LinuxTimerQueuePrivate; -/** - * @brief Provides a private type for the LinuxTimerQueue class - */ -typedef struct LinuxTimerQueuePrivate * LinuxTimerQueuePrivate_t; - -/** - * @brief Extends OSTimerQueue to Linux - */ -class LinuxTimerQueue : public OSTimerQueue { - friend class LinuxTimerQueueFactory; - friend void *LinuxTimerQueueHandler( void * arg ); -private: - LinuxTimerQueueMap_t timerQueueMap; - int key; - bool stop; - LinuxTimerQueuePrivate_t _private; - OSLock *lock; - void LinuxTimerQueueAction( LinuxTimerQueueActionArg *arg ); -protected: - /** - * @brief Default constructor - */ - LinuxTimerQueue() { - _private = NULL; - } - - /** - * @brief Initializes internal variables - * @return TRUE if success, FALSE otherwise. - */ - virtual bool init(); -public: - /** - * @brief Deletes pre-allocated internal variables. - */ - ~LinuxTimerQueue(); - - /** - * @brief Add an event to the timer queue - * @param micros Time in microsseconds - * @param type Event type - * @param func Callback - * @param arg inner argument of type event_descriptor_t - * @param rm when true, allows elements to be deleted from the queue - * @param event [inout] Pointer to the event - * @return TRUE success, FALSE fail - */ - bool addEvent - ( unsigned long micros, int type, ostimerq_handler func, - event_descriptor_t * arg, bool rm, unsigned *event ); - - /** - * @brief Removes an event from the timer queue - * @param type Event type - * @param event [inout] Pointer to the event - * @return TRUE success, FALSE fail - */ - bool cancelEvent( int type, unsigned *event ); -}; - -/** - * @brief Implements factory design pattern for linux - */ -class LinuxTimerQueueFactory : public OSTimerQueueFactory { -public: - /** - * @brief Creates Linux timer queue - * @param clock [in] Pointer to IEEE15588Clock type - * @return Pointer to OSTimerQueue - */ - virtual OSTimerQueue *createOSTimerQueue( IEEE1588Clock *clock ); -}; - -/** - * @brief Extends the OSTimer generic class to Linux - */ -class LinuxTimer : public OSTimer { - friend class LinuxTimerFactory; - public: - /** - * @brief Sleeps for a given amount of time in microsseconds - * @param micros Time in micro-seconds - * @return -1 if error, micros (input argument) if success - */ - virtual unsigned long sleep(unsigned long micros); - protected: - /** - * @brief Destroys linux timer - */ - LinuxTimer() {}; -}; - -/** - * @brief Provides factory design pattern for LinuxTimer - */ -class LinuxTimerFactory : public OSTimerFactory { - public: - /** - * @brief Creates the linux timer - * @return Pointer to OSTimer object - */ - virtual OSTimer *createTimer() const - { - return new LinuxTimer(); - } -}; - -/** - * @brief Provides the default arguments for the OSThread class - */ -struct OSThreadArg { - OSThreadFunction func; /*!< Callback function */ - void *arg; /*!< Input arguments */ - OSThreadExitCode ret; /*!< Return code */ -}; - -/** - * @brief OSThread callback - * @param input OSThreadArg structure - * @return void - */ -void *OSThreadCallback(void *input); - -struct LinuxThreadPrivate; -/** - * @brief Provides a private type for the LinuxThread class - */ -typedef LinuxThreadPrivate * LinuxThreadPrivate_t; - -/** - * @brief Extends OSThread class to Linux - */ -class LinuxThread : public OSThread { - friend class LinuxThreadFactory; - private: - LinuxThreadPrivate_t _private; - OSThreadArg *arg_inner; - public: - /** - * @brief Starts a new thread - * @param function Callback to the thread to be started - * @param arg Function's parameters - * @return TRUE if no error during init, FALSE otherwise - */ - virtual bool start(OSThreadFunction function, void *arg); - - /** - * @brief Joins a new thread - * @param exit_code Callback's return code - * @return TRUE if ok, FALSE if error. - */ - virtual bool join(OSThreadExitCode & exit_code); - virtual ~LinuxThread(); - protected: - LinuxThread(); -}; - -/** - * @brief Provides factory design pattern for LinuxThread class - */ -class LinuxThreadFactory:public OSThreadFactory { - public: - /** - * @brief Creates a new LinuxThread - * @return Pointer to LinuxThread object - */ - OSThread *createThread() const { - return new LinuxThread(); - } -}; - -/** - * @brief Extends OSNetworkInterfaceFactory for LinuxNetworkInterface - */ -class LinuxNetworkInterfaceFactory : public OSNetworkInterfaceFactory { -public: - /** - * @brief Creates a new interface - * @param net_iface [out] Network interface. Created internally. - * @param label [in] Label to be cast to the interface's name internally - * @param timestamper [in] Pointer to a hardware timestamp object - * @return TRUE if no error during interface creation, FALSE otherwise - */ - virtual bool createInterface - ( OSNetworkInterface **net_iface, InterfaceLabel *label, - CommonTimestamper *timestamper ); -}; - -/** - * @brief Extends IPC ARG generic interface to linux - */ -class LinuxIPCArg : public OS_IPC_ARG { -private: - char *group_name; -public: - /** - * @brief Initializes IPCArg object - * @param group_name [in] Group's name - */ - LinuxIPCArg( char *group_name ) { - int len = strnlen(group_name,16); - this->group_name = new char[len+1]; - strncpy( this->group_name, group_name, len+1 ); - this->group_name[len] = '\0'; - } - /** - * @brief Destroys IPCArg internal variables - */ - virtual ~LinuxIPCArg() { - delete group_name; - } - friend class LinuxSharedMemoryIPC; -}; - -#define DEFAULT_GROUPNAME "ptp" /*!< Default groupname for the shared memory interface*/ - -/** - * @brief Linux shared memory interface - */ -class LinuxSharedMemoryIPC:public OS_IPC { -private: - int shm_fd; - char *master_offset_buffer; - int err; -public: - /** - * @brief Initializes the internal flags - */ - LinuxSharedMemoryIPC() { - shm_fd = 0; - err = 0; - master_offset_buffer = NULL; - }; - /** - * @brief Destroys and unlinks shared memory - */ - ~LinuxSharedMemoryIPC(); - - /** - * @brief Initializes shared memory with DEFAULT_GROUPNAME case arg is null - * @param barg Groupname of the shared memory - * @return TRUE if no error, FALSE otherwise - */ - virtual bool init( OS_IPC_ARG *barg = NULL ); - - /** - * @brief Updates IPC values - * - * @param ml_phoffset Master to local phase offset - * @param ls_phoffset Local to slave phase offset - * @param ml_freqoffset Master to local frequency offset - * @param ls_freqoffset Local to slave frequency offset - * @param local_time Local time - * @param sync_count Count of syncs - * @param pdelay_count Count of pdelays - * @param port_state Port's state - * @param asCapable asCapable flag - * - * @return TRUE - */ - virtual bool update( - int64_t ml_phoffset, - int64_t ls_phoffset, - FrequencyRatio ml_freqoffset, - FrequencyRatio ls_freqoffset, - uint64_t local_time, - uint32_t sync_count, - uint32_t pdelay_count, - PortState port_state, - bool asCapable ); - - /** - * @brief Updates grandmaster IPC values - * - * @param gptp_grandmaster_id Current grandmaster id (all 0's if no grandmaster selected) - * @param gptp_domain_number gPTP domain number - * - * @return TRUE - */ - virtual bool update_grandmaster( - uint8_t gptp_grandmaster_id[], - uint8_t gptp_domain_number ); - - /** - * @brief Updates network interface IPC values - * - * @param clock_identity The clock identity of the interface - * @param priority1 The priority1 field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param clock_class The clockClass field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param offset_scaled_log_variance The offsetScaledLogVariance field of the grandmaster functionality of the interface, or 0x0000 if not supported - * @param clock_accuracy The clockAccuracy field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param priority2 The priority2 field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param domain_number The domainNumber field of the grandmaster functionality of the interface, or 0 if not supported - * @param log_sync_interval The currentLogSyncInterval field of the grandmaster functionality of the interface, or 0 if not supported - * @param log_announce_interval The currentLogAnnounceInterval field of the grandmaster functionality of the interface, or 0 if not supported - * @param log_pdelay_interval The currentLogPDelayReqInterval field of the grandmaster functionality of the interface, or 0 if not supported - * @param port_number The portNumber field of the interface, or 0x0000 if not supported - * - * @return TRUE - */ - virtual bool update_network_interface( - uint8_t clock_identity[], - uint8_t priority1, - uint8_t clock_class, - int16_t offset_scaled_log_variance, - uint8_t clock_accuracy, - uint8_t priority2, - uint8_t domain_number, - int8_t log_sync_interval, - int8_t log_announce_interval, - int8_t log_pdelay_interval, - uint16_t port_number ); - - /** - * @brief unmaps and unlink shared memory - * @return void - */ - void stop(); -}; - - -#endif/*LINUX_HAL_COMMON_HPP*/ diff --git a/daemons/gptp/linux/src/linux_hal_generic.cpp b/daemons/gptp/linux/src/linux_hal_generic.cpp deleted file mode 100644 index 2a462696..00000000 --- a/daemons/gptp/linux/src/linux_hal_generic.cpp +++ /dev/null @@ -1,588 +0,0 @@ -/****************************************************************************** - - 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 <linux_hal_generic.hpp> -#include <linux_hal_generic_tsprivate.hpp> -#include <platform.hpp> -#include <avbts_message.hpp> -#include <gptp_cfg.hpp> - -#include <sys/select.h> -#include <sys/socket.h> -#include <netpacket/packet.h> -#include <errno.h> -#include <linux/ethtool.h> -#include <net/if.h> -#include <linux/sockios.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include <fcntl.h> -#include <linux/net_tstamp.h> -#include <linux/ptp_clock.h> -#include <syscall.h> -#include <limits.h> - -#define TX_PHY_TIME 184 -#define RX_PHY_TIME 382 - -net_result LinuxNetworkInterface::nrecv -( 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; - net_result ret = net_succeed; - bool got_net_lock; - - LinuxTimestamperGeneric *gtimestamper; - - struct timeval timeout = { 0, 16000 }; // 16 ms - - if( !net_lock.lock( &got_net_lock )) { - GPTP_LOG_ERROR("A Failed to lock mutex"); - return net_fatal; - } - if( !got_net_lock ) { - return net_trfail; - } - - FD_ZERO( &readfds ); - FD_SET( sd_event, &readfds ); - - err = select( sd_event+1, &readfds, NULL, NULL, &timeout ); - if( err == 0 ) { - ret = net_trfail; - goto done; - } else if( err == -1 ) { - if( err == EINTR ) { - // Caught signal - GPTP_LOG_ERROR("select() recv signal"); - ret = net_trfail; - goto done; - } else { - GPTP_LOG_ERROR("select() failed"); - ret = net_fatal; - goto done; - } - } else if( !FD_ISSET( sd_event, &readfds )) { - ret = net_trfail; - goto done; - } - - 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 ) { - if( errno == ENOMSG ) { - GPTP_LOG_ERROR("Got ENOMSG: %s:%d", __FILE__, __LINE__); - ret = net_trfail; - goto done; - } - GPTP_LOG_ERROR("recvmsg() failed: %s", strerror(errno)); - ret = net_fatal; - goto done; - } - *addr = LinkLayerAddress( remote.sll_addr ); - - gtimestamper = dynamic_cast<LinuxTimestamperGeneric *>(timestamper); - if( err > 0 && !(payload[0] & 0x8) && gtimestamper != NULL ) { - /* Retrieve the timestamp */ - 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 ); - gtimestamper->pushRXTimestamp( &device ); - break; - } - cmsg = CMSG_NXTHDR(&msg,cmsg); - } - } - - length = err; - - done: - if( !net_lock.unlock()) { - GPTP_LOG_ERROR("A Failed to unlock, %d", err); - return net_fatal; - } - - return ret; -} - -int findPhcIndex( InterfaceLabel *iface_label ) { - int sd; - InterfaceName *ifname; - struct ethtool_ts_info info; - struct ifreq ifr; - - if(( ifname = dynamic_cast<InterfaceName *>(iface_label)) == NULL ) { - GPTP_LOG_ERROR("findPTPIndex requires InterfaceName"); - return -1; - } - - sd = socket( AF_UNIX, SOCK_DGRAM, 0 ); - if( sd < 0 ) { - GPTP_LOG_ERROR("findPTPIndex: failed to open socket"); - return -1; - } - - memset( &ifr, 0, sizeof(ifr)); - memset( &info, 0, sizeof(info)); - info.cmd = ETHTOOL_GET_TS_INFO; - ifname->toString( ifr.ifr_name, IFNAMSIZ-1 ); - ifr.ifr_data = (char *) &info; - - if( ioctl( sd, SIOCETHTOOL, &ifr ) < 0 ) { - GPTP_LOG_ERROR("findPTPIndex: ioctl(SIOETHTOOL) failed"); - return -1; - } - - close(sd); - - return info.phc_index; -} - -LinuxTimestamperGeneric::clock_map_t -LinuxTimestamperGeneric::system_clock_map[] = -{ - { CLOCK_REALTIME, "Realtime" }, - { CLOCK_MONOTONIC_RAW, "MonotonicRaw" } -}; - -LinuxTimestamperGeneric::~LinuxTimestamperGeneric() { - if( _private != NULL ) delete _private; -#ifdef WITH_IGBLIB - if( igb_private != NULL ) delete igb_private; -#endif -} - -LinuxTimestamperGeneric::LinuxTimestamperGeneric() { - _private = NULL; -#ifdef WITH_IGBLIB - igb_private = NULL; -#endif - sd = -1; - system_clockid = CLOCK_REALTIME; -} - -const char *LinuxTimestamperGeneric::getClockNameFromId( clockid_t clockid ) - const -{ - unsigned i; - - for( i = 0; i < sizeof(system_clock_map)/sizeof(system_clock_map[0]); - ++i ) - { - if( system_clock_map[i].clockid == clockid ) - return system_clock_map[i].clock_name; - } - - return NULL; -} - -bool LinuxTimestamperGeneric::Adjust( void *tmx ) const { - if( syscall(__NR_clock_adjtime, _private->clockid, tmx ) != 0 ) { - GPTP_LOG_ERROR("Failed to adjust PTP clock rate"); - return false; - } - return true; -} - -bool LinuxTimestamperGeneric::HWTimestamper_init -( InterfaceLabel *iface_label, OSNetworkInterface *iface ) { - cross_stamp_good = false; - int phc_index; - char ptp_device[] = PTP_DEVICE; -#ifdef PTP_HW_CROSSTSTAMP - struct ptp_clock_caps ptp_capability; -#endif - _private = new LinuxTimestamperGenericPrivate; - - pthread_mutex_init( &_private->cross_stamp_lock, NULL ); - - // Determine the correct PTP clock interface - phc_index = findPhcIndex( iface_label ); - if( phc_index < 0 ) { - GPTP_LOG_ERROR("Failed to find PTP device index"); - return false; - } - - snprintf - ( ptp_device+PTP_DEVICE_IDX_OFFS, - sizeof(ptp_device)-PTP_DEVICE_IDX_OFFS, "%d", phc_index ); - GPTP_LOG_ERROR("Using clock device: %s", ptp_device); - phc_fd = open( ptp_device, O_RDWR ); - if( phc_fd == -1 || (_private->clockid = FD_TO_CLOCKID(phc_fd)) == -1 ) { - GPTP_LOG_ERROR("Failed to open PTP clock device"); - return false; - } - -#ifdef PTP_HW_CROSSTSTAMP - // Query PTP stack for availability of HW cross-timestamp - if( ioctl( phc_fd, PTP_CLOCK_GETCAPS, &ptp_capability ) == -1 ) - { - GPTP_LOG_ERROR("Failed to query PTP clock capabilities"); - return false; - } - precise_timestamp_enabled = ptp_capability.cross_timestamping; -#endif - - if( !resetFrequencyAdjustment() ) { - GPTP_LOG_ERROR("Failed to reset (zero) frequency adjustment"); - return false; - } - - if( dynamic_cast<LinuxNetworkInterface *>(iface) != NULL ) { - iface_list.push_front - ( (dynamic_cast<LinuxNetworkInterface *>(iface)) ); - } - - return true; -} - -void LinuxTimestamperGeneric::HWTimestamper_reset() -{ - if( !resetFrequencyAdjustment() ) { - GPTP_LOG_ERROR("Failed to reset (zero) frequency adjustment"); - } -} - -bool LinuxTimestamperGeneric::HWTimestamper_setsystemclock -( const char *system_clock_desc ) -{ - unsigned i; - - if( system_clock_desc == NULL ) - return false; - - for( i = 0; i < sizeof(system_clock_map)/sizeof(system_clock_map[0]); - ++i ) - { - if( strncmp( system_clock_desc, system_clock_map[i].clock_name, - MAX_CLOCK_DESC_LEN ) == 0 ) - { - system_clockid = system_clock_map[i].clockid; - - return true; - } - } - - GPTP_LOG_ERROR - ( "Requested clock type: '%s' not found", system_clock_desc ); - - return false; -} - -int LinuxTimestamperGeneric::HWTimestamper_txtimestamp -( PortIdentity *identity, PTPMessageId messageId, Timestamp ×tamp, - unsigned &clock_value, bool last ) -{ - int err; - int ret = GPTP_EC_EAGAIN; - struct msghdr msg; - struct cmsghdr *cmsg; - struct sockaddr_ll remote; - struct iovec sgentry; - PTPMessageId reflectedMessageId; - uint8_t reflected_bytes[ETHER_HDR_LEN + PTP_COMMON_HDR_LENGTH]; - uint8_t *gptpCommonHeader; - uint16_t sequenceId; - 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 = reflected_bytes; - sgentry.iov_len = sizeof(reflected_bytes); - - gptpCommonHeader = reflected_bytes + ETHER_HDR_LEN; - - 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 ) { - ret = GPTP_EC_EAGAIN; - goto done; - } - else { - ret = GPTP_EC_FAILURE; - goto done; - } - } - sequenceId = PLAT_ntohs(*((uint16_t*)(PTP_COMMON_HDR_SEQUENCE_ID(gptpCommonHeader)))); - reflectedMessageId.setSequenceId(sequenceId); - reflectedMessageId.setMessageType((MessageType)(*PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(gptpCommonHeader) & 0xF)); - if (messageId != reflectedMessageId) { - GPTP_LOG_WARNING("Timestamp discarded due to wrong message id"); - ret = GPTP_EC_EAGAIN; - goto done; - } - - // Retrieve the timestamp - 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 ); - system._version = version; - device._version = version; - timestamp = device; - ret = 0; - break; - } - cmsg = CMSG_NXTHDR(&msg,cmsg); - } - - if( ret != 0 ) { - GPTP_LOG_ERROR("Received a error message, but didn't find a valid timestamp"); - } - - done: - if( ret == 0 || last ) { - net_lock->unlock(); - } - - return ret; -} - -bool LinuxTimestamperGeneric::post_init( int ifindex, int sd, TicketingLock *lock ) { - int timestamp_flags = 0; - struct ifreq device; - struct hwtstamp_config hwconfig; - int err; - - this->sd = sd; - this->net_lock = lock; - - memset( &device, 0, sizeof(device)); - device.ifr_ifindex = ifindex; - err = ioctl( sd, SIOCGIFNAME, &device ); - if( err == -1 ) { - GPTP_LOG_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_EVENT; - hwconfig.tx_type = HWTSTAMP_TX_ON; - err = ioctl( sd, SIOCSHWTSTAMP, &device ); - if( err == -1 ) { - GPTP_LOG_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, ×tamp_flags, - sizeof(timestamp_flags) ); - if( err == -1 ) { - GPTP_LOG_ERROR - ("Failed to configure timestamping on socket: %s", - strerror(errno)); - return false; - } - - return true; -} - -#define MAX_NSEC 1000000000 - -/* Return *a - *b */ -static inline ptp_clock_time pct_diff -( struct ptp_clock_time *a, struct ptp_clock_time *b ) { - ptp_clock_time result; - if( a->nsec >= b->nsec ) { - result.nsec = a->nsec - b->nsec; - } else { - --a->sec; - result.nsec = (MAX_NSEC - b->nsec) + a->nsec; - } - result.sec = a->sec - b->sec; - - return result; -} - -static inline int64_t pctns(struct ptp_clock_time t) -{ - return t.sec * 1000000000LL + t.nsec; -} - -static inline Timestamp pctTimestamp( struct ptp_clock_time *t ) { - Timestamp result; - - result.seconds_ls = t->sec & 0xFFFFFFFF; - result.seconds_ms = t->sec >> sizeof(result.seconds_ls)*8; - result.nanoseconds = t->nsec; - - return result; -} - -// Use HW cross-timestamp if available -bool LinuxTimestamperGeneric::HWTimestamper_gettime -( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock, - uint32_t *nominal_clock_rate ) const -{ - if( phc_fd == -1 ) - return false; - -#ifdef PTP_HW_CROSSTSTAMP - if( precise_timestamp_enabled ) - { - struct ptp_sys_offset_precise offset; - memset( &offset, 0, sizeof(offset)); - if( ioctl( phc_fd, PTP_SYS_OFFSET_PRECISE, &offset ) != 0 ) - { - GPTP_LOG_ERROR( "Read PHC Crosstime IOCTL failed" ); - - return false; - } - - *device_time = pctTimestamp( &offset.device ); - - if( system_clockid == CLOCK_REALTIME ) - *system_time = pctTimestamp( &offset.sys_realtime ); - else if( system_clockid == CLOCK_MONOTONIC_RAW ) - *system_time = pctTimestamp( &offset.sys_monoraw ); - - else - { - const char * clock_name = - getClockNameFromId( system_clockid ); - GPTP_LOG_ERROR( - "Requested clock type: '%s' not supported", - clock_name != NULL ? clock_name : "Unknown" - ); - - return false; - } - - return true; - } -#endif - - { - unsigned i; - struct ptp_clock_time *pct; - struct ptp_clock_time *system_time_l = NULL, *device_time_l = NULL; - int64_t interval = LLONG_MAX; - struct ptp_sys_offset offset; - - memset( &offset, 0, sizeof(offset)); - offset.n_samples = PTP_MAX_SAMPLES; - if( ioctl( phc_fd, PTP_SYS_OFFSET, &offset ) == -1 ) - { - GPTP_LOG_ERROR( "Read PHC Crosstime IOCTL failed" ); - - return false; - } - - pct = &offset.ts[0]; - for( i = 0; i < offset.n_samples; ++i ) { - int64_t interval_t; - interval_t = pctns(pct_diff( pct+2*i+2, pct+2*i )); - if( interval_t < interval ) { - system_time_l = pct+2*i; - device_time_l = pct+2*i+1; - interval = interval_t; - } - } - - if( !device_time_l || !system_time_l ) - { - GPTP_LOG_ERROR( "PHC Crosstime result is empty" ); - - return false; - } - - *device_time = pctTimestamp( device_time_l ); - - if( system_clockid == CLOCK_REALTIME ) - *system_time = pctTimestamp( system_time_l ); - else - { - const char *clock_name = - getClockNameFromId( system_clockid ); - GPTP_LOG_ERROR( - "Requested clock type: '%s' not supported", - clock_name != NULL ? clock_name : "Unknown" - ); - } - } - - return true; -} diff --git a/daemons/gptp/linux/src/linux_hal_generic.hpp b/daemons/gptp/linux/src/linux_hal_generic.hpp deleted file mode 100644 index 76b09015..00000000 --- a/daemons/gptp/linux/src/linux_hal_generic.hpp +++ /dev/null @@ -1,217 +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. - -******************************************************************************/ - -#ifndef LINUX_HAL_GENERIC_HPP -#define LINUX_HAL_GENERIC_HPP - -#include <linux_hal_common.hpp> - -/**@file*/ - -struct LinuxTimestamperGenericPrivate; -/** - * @brief Provides LinuxTimestamperGeneric a private type - */ -typedef struct LinuxTimestamperGenericPrivate * LinuxTimestamperGenericPrivate_t; - -#ifdef WITH_IGBLIB -struct LinuxTimestamperIGBPrivate; -typedef struct LinuxTimestamperIGBPrivate * LinuxTimestamperIGBPrivate_t; -#endif - -/** - * @brief Linux timestamper generic interface - */ -class LinuxTimestamperGeneric : public LinuxTimestamper { -private: - int sd; - int phc_fd; - Timestamp crstamp_system; - Timestamp crstamp_device; - LinuxTimestamperGenericPrivate_t _private; - bool cross_stamp_good; - std::list<Timestamp> rxTimestampList; - LinuxNetworkInterfaceList iface_list; -#ifdef PTP_HW_CROSSTSTAMP - bool precise_timestamp_enabled; -#endif - - TicketingLock *net_lock; - clockid_t system_clockid; - -#ifdef WITH_IGBLIB - LinuxTimestamperIGBPrivate_t igb_private; -#endif - - struct clock_map_t - { - clockid_t clockid; - const char *clock_name; - }; - - static clock_map_t system_clock_map[]; - - const char *getClockNameFromId( clockid_t clockid ) const; - -public: - /** - * @brief Default constructor. Initializes internal variables - */ - LinuxTimestamperGeneric(); - - /** - * @brief Resets frequency adjustment value to zero and calls - * linux system calls for frequency adjustment. - * @return TRUE if success, FALSE if error. - */ - bool resetFrequencyAdjustment(); - - /** - * @brief Calls linux system call for adjusting frequency or phase. - * @param tmx [in] Void pointer that must be cast (and filled in correctly) to - * the struct timex - * @return TRUE if ok, FALSE if error. - */ - bool Adjust( void *tmx ) const; - - /** - * @brief Initializes the Hardware timestamp interface - * @param iface_label [in] Network interface label (used to find the phc index) - * @param iface [in] Network interface - * @return FALSE in case of error, TRUE if success. - */ - virtual bool HWTimestamper_init - ( InterfaceLabel *iface_label, OSNetworkInterface *iface ); - - /** - * @brief Reset the Hardware timestamp interface - * @return void - */ - virtual void HWTimestamper_reset(); - - virtual bool HWTimestamper_setsystemclock - ( const char *system_clock_desc ); - - /** - * @brief Inserts a new timestamp to the beginning of the - * RX timestamp list. - * @param tstamp [in] RX timestamp - * @return void - */ - void pushRXTimestamp( Timestamp *tstamp ) { - tstamp->_version = version; - rxTimestampList.push_front(*tstamp); - } - - /** - * @brief Post initialization procedure. - * @param ifindex struct ifreq.ifr_ifindex value - * @param sd Socket file descriptor - * @param lock [in] Instance of TicketingLock object - * @return TRUE if ok. FALSE if error. - */ - bool post_init( int ifindex, int sd, TicketingLock *lock ); - - /** - * @brief Gets the ptp clock time information - * @param system_time [out] System time - * @param device_time [out] Device time - * @param local_clock Not Used - * @param nominal_clock_rate Not Used - * @return TRUE if got the time successfully, FALSE otherwise - */ - virtual bool HWTimestamper_gettime - ( Timestamp *system_time, Timestamp *device_time, - uint32_t *local_clock, uint32_t *nominal_clock_rate ) const; - - /** - * @brief Gets the TX timestamp from hardware interface - * @param identity PTP port identity - * @param PTPMessageId Message ID - * @param timestamp [out] Timestamp value - * @param clock_value [out] Clock value - * @param last Signalizes that it is the last timestamp to get. When TRUE, releases the lock when its done. - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - virtual int HWTimestamper_txtimestamp - ( PortIdentity *identity, PTPMessageId messageId, Timestamp ×tamp, - unsigned &clock_value, bool last ); - - /** - * @brief Gets the RX timestamp from the hardware interface. This - * Currently the RX timestamp is retrieved at LinuxNetworkInterface::nrecv method. - * @param identity PTP port identity - * @param PTPMessageId Message ID - * @param timestamp [out] Timestamp value - * @param clock_value [out] Clock value - * @param last Signalizes that it is the last timestamp to get. When TRUE, releases the lock when its done. - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - virtual int HWTimestamper_rxtimestamp - ( PortIdentity *identity, PTPMessageId messageId, Timestamp ×tamp, - unsigned &clock_value, bool last ) { - /* This shouldn't happen. Ever. */ - if( rxTimestampList.empty() ) return GPTP_EC_EAGAIN; - timestamp = rxTimestampList.back(); - rxTimestampList.pop_back(); - - return GPTP_EC_SUCCESS; - } - - /** - * @brief Adjusts the clock phase - * @param phase_adjust Phase adjustment - * @return TRUE if success, FALSE if error. - */ - virtual bool HWTimestamper_adjclockphase( int64_t phase_adjust ); - - /** - * @brief Adjusts the frequency - * @param freq_offset Frequency adjustment - * @return TRUE in case of sucess, FALSE if error. - */ - virtual bool HWTimestamper_adjclockrate( float freq_offset ) const; - -#ifdef WITH_IGBLIB - bool HWTimestamper_PPS_start( ); - bool HWTimestamper_PPS_stop(); -#endif - - /** - * @brief deletes LinuxTimestamperGeneric object - */ - virtual ~LinuxTimestamperGeneric(); -}; - - -#endif/*LINUX_HAL_GENERIC_HPP*/ diff --git a/daemons/gptp/linux/src/linux_hal_generic_adj.cpp b/daemons/gptp/linux/src/linux_hal_generic_adj.cpp deleted file mode 100644 index 7f1d59c8..00000000 --- a/daemons/gptp/linux/src/linux_hal_generic_adj.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************** - - 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 <sys/timex.h> -#define ADJ_SETOFFSET 0x0100 // Missing from older header files -#include <linux_hal_generic.hpp> -#include <syscall.h> -#include <math.h> - -bool LinuxTimestamperGeneric::resetFrequencyAdjustment() { - struct timex tx; - tx.modes = ADJ_FREQUENCY; - tx.freq = 0; - - return Adjust(&tx); -} - -bool LinuxTimestamperGeneric::HWTimestamper_adjclockphase( int64_t phase_adjust ) { - struct timex tx; - LinuxNetworkInterfaceList::iterator iface_iter; - bool ret = true; - LinuxTimerFactory factory; - OSTimer *timer = factory.createTimer(); - - /* Walk list of interfaces disabling them all */ - iface_iter = iface_list.begin(); - for - ( iface_iter = iface_list.begin(); iface_iter != iface_list.end(); - ++iface_iter ) { - (*iface_iter)->disable_rx_queue(); - } - - rxTimestampList.clear(); - - /* Wait 180 ms - This is plenty of time for any time sync frames - to clear the queue */ - timer->sleep(180000); - - ++version; - - tx.modes = ADJ_SETOFFSET | ADJ_NANO; - if( phase_adjust >= 0 ) { - tx.time.tv_sec = phase_adjust / 1000000000LL; - tx.time.tv_usec = phase_adjust % 1000000000LL; - } else { - tx.time.tv_sec = (phase_adjust / 1000000000LL)-1; - tx.time.tv_usec = (phase_adjust % 1000000000LL)+1000000000; - } - - if( !Adjust( &tx )) { - ret = false; - } - - // Walk list of interfaces re-enabling them - iface_iter = iface_list.begin(); - for( iface_iter = iface_list.begin(); iface_iter != iface_list.end(); - ++iface_iter ) { - (*iface_iter)->clear_reenable_rx_queue(); - } - - delete timer; - return ret; -} - -bool LinuxTimestamperGeneric::HWTimestamper_adjclockrate( float freq_offset ) const { - struct timex tx; - tx.modes = ADJ_FREQUENCY; - tx.freq = long(freq_offset) << 16; - tx.freq += long(fmodf( freq_offset, 1.0 )*65536.0); - - return Adjust(&tx); -} diff --git a/daemons/gptp/linux/src/linux_hal_generic_tsprivate.hpp b/daemons/gptp/linux/src/linux_hal_generic_tsprivate.hpp deleted file mode 100644 index a43e1c37..00000000 --- a/daemons/gptp/linux/src/linux_hal_generic_tsprivate.hpp +++ /dev/null @@ -1,61 +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. - -******************************************************************************/ - -#ifndef LINUX_HAL_TSPRIVATE -#define LINUX_HAL_TSPRIVATE - -/**@file*/ - -#include <pthread.h> -#ifdef WITH_IGBLIB -extern "C" { -#include <igb.h> -} -/** - * @brief Private IGB structure. - */ -struct LinuxTimestamperIGBPrivate { - device_t igb_dev; - bool igb_initd; -}; -#endif - -/** - * @brief Provides private members for the LinuxTimestamperGeneric class - */ -struct LinuxTimestamperGenericPrivate { - pthread_mutex_t cross_stamp_lock; /*!< Cross timestamp lock*/ - clockid_t clockid; /*!< Clock ID */ -}; - -#endif/*LINUX_HAL_TSPRIVATE*/ diff --git a/daemons/gptp/linux/src/linux_hal_i210.cpp b/daemons/gptp/linux/src/linux_hal_i210.cpp deleted file mode 100644 index 117a590a..00000000 --- a/daemons/gptp/linux/src/linux_hal_i210.cpp +++ /dev/null @@ -1,162 +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 <linux_hal_generic.hpp> -#include <linux_hal_generic_tsprivate.hpp> -#include <errno.h> - -extern "C" { -#include <pci/pci.h> -#include <igb.h> -} - -#define IGB_BIND_NAMESZ 24 - -#define TSSDP 0x003C // Time Sync SDP Configuration Register -#define FREQOUT0 0xB654 -#define TSAUXC 0xB640 -#define IGB_CTRL 0x0000 -#define SYSTIMH 0xB604 -#define TRGTTIML0 0xB644 -#define TRGTTIMH0 0xB648 - - -static int -pci_connect( device_t *igb_dev ) -{ - char devpath[IGB_BIND_NAMESZ]; - struct pci_access *pacc; - struct pci_dev *dev; - int err; - - 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; - } - GPTP_LOG_INFO("attaching to %s", devpath); - err = igb_attach(devpath, igb_dev); - if (err) { - GPTP_LOG_ERROR("attach failed! (%s)", strerror(err)); - continue; - } - /*igb_attach_tx missing here ???*/ - goto out; - } - pci_cleanup(pacc); - return ENXIO; -out: - pci_cleanup(pacc); - return 0; -} - - -bool LinuxTimestamperGeneric::HWTimestamper_PPS_start( ) { - unsigned tssdp; - unsigned freqout; - unsigned ctrl; - unsigned tsauxc; - unsigned trgttimh; - - if( igb_private == NULL ) { - igb_private = new LinuxTimestamperIGBPrivate; - } - - if( pci_connect( &igb_private->igb_dev ) != 0 ) { - return false; - } - - if( igb_init( &igb_private->igb_dev ) != 0 ) { - return false; - } - - igb_private->igb_initd = true; - - igb_lock( &igb_private->igb_dev ); - - // Edges must be second aligned - igb_readreg( &igb_private->igb_dev, SYSTIMH, &trgttimh ); - trgttimh += 2; // First edge in 1-2 seconds - igb_writereg(&igb_private->igb_dev, TRGTTIMH0, trgttimh ); - igb_writereg(&igb_private->igb_dev, TRGTTIML0, 0 ); - - freqout = 500000000; - igb_writereg(&igb_private->igb_dev, FREQOUT0, freqout ); - - igb_readreg(&igb_private->igb_dev, IGB_CTRL, &ctrl ); - ctrl |= 0x400000; // set bit 22 SDP0 enabling output - igb_writereg(&igb_private->igb_dev, IGB_CTRL, ctrl ); - - igb_readreg(&igb_private->igb_dev, TSSDP, &tssdp); - tssdp &= ~0x40; // Set SDP0 output to freq clock 0 - tssdp |= 0x80; - igb_writereg(&igb_private->igb_dev, TSSDP, tssdp); - - igb_readreg(&igb_private->igb_dev, TSSDP, &tssdp); - tssdp |= 0x100; // set bit 8 -> SDP0 Time Sync Output - igb_writereg(&igb_private->igb_dev, TSSDP, tssdp); - - igb_readreg( &igb_private->igb_dev, TSAUXC, &tsauxc ); - tsauxc |= 0x14; - igb_writereg( &igb_private->igb_dev, TSAUXC, tsauxc ); - - igb_unlock( &igb_private->igb_dev ); - - return true; -} - -bool LinuxTimestamperGeneric::HWTimestamper_PPS_stop() { - unsigned tsauxc; - - if( !igb_private->igb_initd ) return false; - - igb_readreg( &igb_private->igb_dev, TSAUXC, &tsauxc ); - tsauxc &= ~0x14; // set bit 4 and bit 2 -> AUXC ST0 and EN_CLK0 - igb_writereg( &igb_private->igb_dev, TSAUXC, tsauxc ); - - return true; -} diff --git a/daemons/gptp/linux/src/linux_hal_intelce.cpp b/daemons/gptp/linux/src/linux_hal_intelce.cpp deleted file mode 100644 index 99c0fe2a..00000000 --- a/daemons/gptp/linux/src/linux_hal_intelce.cpp +++ /dev/null @@ -1,243 +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 <linux_hal_intelce.hpp> -#include <avbts_message.hpp> -extern "C" { -#include <ismd_sysclk.h> -#include <ismd_core.h> -} -#include <netpacket/packet.h> -#include <errno.h> -#include <sys/socket.h> -#include <sys/types.h> - -#define NOMINAL_NET_CLOCK_RATE (25)/* MHz */ -#define NET_CLOCK_ADJUST (1000/NOMINAL_NET_CLOCK_RATE) - -#define TX_PHY_TIME 8000 -#define RX_PHY_TIME 8000 - -uint64_t scale_clock( uint64_t count ) { - return count*NET_CLOCK_ADJUST; -} - -int LinuxTimestamperIntelCE::ce_timestamp_common -( PortIdentity *identity, uint16_t sequenceId, Timestamp ×tamp, - unsigned &clock_value, bool tx ) { - uint64_t timestamp_s; - uint16_t captured_sequence; - uint16_t port_no; - PortIdentity captured_id; - ismd_sysclk_msg_t message; - ismd_result_t result; - int ret = GPTP_EC_EAGAIN; - - if( tx ) { - result = ismd_sysclk_get_tx_time( ×tamp_s, &message ); - if( timestamp_s == last_tx_time ) { - result = ISMD_ERROR_NO_DATA_AVAILABLE; - } else { - last_tx_time = timestamp_s; - } - } else { - struct timespec ts; - clock_gettime( CLOCK_REALTIME, &ts ); - result = ismd_sysclk_get_rx_time( ×tamp_s, &message ); - if( timestamp_s == last_rx_time ) { - result = ISMD_ERROR_NO_DATA_AVAILABLE; - } else { - last_rx_time = timestamp_s; - } - } - - if( result == ISMD_ERROR_NO_DATA_AVAILABLE ) { - goto fail; - } else if( result != ISMD_SUCCESS ) { - ret = GPTP_EC_FAILURE; - goto fail; - } - - timestamp_s = scale_clock( timestamp_s ); - - captured_id.setClockIdentity( ClockIdentity(message.msgid) ); - port_no = - PLAT_ntohs(*((uint16_t *)(message.msgid+PTP_CLOCK_IDENTITY_LENGTH))); - captured_id.setPortNumber( &port_no ); - captured_sequence = PLAT_ntohs( *((uint16_t *)message.msgseq )); - - if( captured_sequence != sequenceId || captured_id != *identity ) { - uint16_t cap_port_no; - uint16_t id_port_no; - captured_id.getPortNumber(&cap_port_no); - identity->getPortNumber(&id_port_no); - goto fail; - } - - ret = GPTP_EC_SUCCESS; - - if( tx ) { - timestamp_s += TX_PHY_TIME; - } else { - timestamp_s -= RX_PHY_TIME; - } - - timestamp.set64( timestamp_s ); - timestamp._version = version; - clock_value = (unsigned) timestamp_s; - - fail: - return ret; -} - -int LinuxTimestamperIntelCE::HWTimestamper_txtimestamp -( PortIdentity *identity, PTPMessageId messageId, Timestamp ×tamp, - unsigned &clock_value, bool last ) { - return ce_timestamp_common - ( identity, messageId.getSequenceId(), timestamp, clock_value, true ); -} - -int LinuxTimestamperIntelCE::HWTimestamper_rxtimestamp -( PortIdentity *identity, PTPMessageId messageId, Timestamp ×tamp, - unsigned &clock_value, bool last ) { - return ce_timestamp_common - ( identity, messageId.getSequenceId(), timestamp, clock_value, false ); -} - -bool LinuxTimestamperIntelCE::post_init( int ifindex, int sd, TicketingLock *lock ) { - ismd_sysclk_ptp_filter_config_t filter_config; - filter_config.tx_filter_enable = true; - filter_config.rx_filter_enable = true; - filter_config.compare_ptp_ver = true; - filter_config.ip_l2 = false; - filter_config.ptp_version = GPTP_VERSION; - filter_config.ether_type = PTP_ETHERTYPE; - filter_config.da_hash_inclusion = false; - ismd_result_t result; - - result = ismd_sysclk_set_ptp_filter( filter_config ); - if( result != ISMD_SUCCESS ) return false; - - return true; -} -bool LinuxTimestamperIntelCE::HWTimestamper_init -( InterfaceLabel *iface_label, OSNetworkInterface *iface ) { - ismd_result_t result; - - // Allocate clock - result = ismd_clock_alloc_typed - ( ISMD_CLOCK_CLASS_SLAVE, ISMD_CLOCK_DOMAIN_TYPE_AV, &iclock ); - if( result != ISMD_SUCCESS ) return false; - - return true; -} - -bool LinuxTimestamperIntelCE::HWTimestamper_gettime -( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock, - uint32_t *nominal_clock_rate ) { - uint64_t system_time_s; - uint64_t device_time_s; - - if( ismd_clock_trigger_software_event( iclock ) != ISMD_SUCCESS ) - return false; - - if( ismd_clock_get_last_trigger_correlated_time - ( iclock, &system_time_s, &device_time_s ) != ISMD_SUCCESS ) - return false; - - system_time->set64( system_time_s ); - - device_time_s = scale_clock( device_time_s ); - device_time->set64( device_time_s ); - - return true; -} - - - -net_result LinuxNetworkInterface::nrecv -( LinkLayerAddress *addr, uint8_t *payload, size_t &length ) { - fd_set readfds; - int err; - struct sockaddr_ll remote; - net_result ret = net_succeed; - bool got_net_lock; - - struct timeval timeout = { 0, 16000 }; // 16 ms - - if( !net_lock.lock( &got_net_lock ) || !got_net_lock ) { - GPTP_LOG_ERROR( "A Failed to lock mutex" ); - return net_fatal; - } - - FD_ZERO( &readfds ); - FD_SET( sd_event, &readfds ); - - err = select( sd_event+1, &readfds, NULL, NULL, &timeout ); - if( err == 0 ) { - ret = net_trfail; - goto done; - } else if( err == -1 ) { - if( err == EINTR ) { - // Caught signal - GPTP_LOG_ERROR( "select() recv signal" ); - ret = net_trfail; - goto done; - } else { - GPTP_LOG_ERROR( "select() failed" ); - ret = net_fatal; - goto done; - } - } else if( !FD_ISSET( sd_event, &readfds )) { - ret = net_trfail; - goto done; - } - - err = recv( sd_event, payload, length, 0 ); - if( err < 0 ) { - GPTP_LOG_ERROR( "recvmsg() failed: %s", strerror(errno) ); - ret = net_fatal; - goto done; - } - *addr = LinkLayerAddress( remote.sll_addr ); - - length = err; - - done: - if( !net_lock.unlock()) { - GPTP_LOG_ERROR( "A Failed to unlock, %d", err ); - return net_fatal; - } - - return ret; -} diff --git a/daemons/gptp/linux/src/linux_hal_intelce.hpp b/daemons/gptp/linux/src/linux_hal_intelce.hpp deleted file mode 100644 index f0f57814..00000000 --- a/daemons/gptp/linux/src/linux_hal_intelce.hpp +++ /dev/null @@ -1,127 +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. - -******************************************************************************/ - -#ifndef LINUX_HAL_INTELCE_HPP -#define LINUX_HAL_INTELCE_HPP - -#include <linux_hal_common.hpp> -#include <ismd_core.h> - -/**@file*/ - -/** - * @brief Extends the LinuxTimestamper to IntelCE cards - */ -class LinuxTimestamperIntelCE : public LinuxTimestamper { -private: - ismd_clock_t iclock; - uint64_t last_tx_time; - uint64_t last_rx_time; - int ce_timestamp_common - ( PortIdentity *identity, uint16_t sequenceId, Timestamp ×tamp, - unsigned &clock_value, bool tx ); -public: - - /** - * @brief Initializes the hardware timestamp unit. - * @param iface_label [in] Interface label - * @param iface [in] Network interface - * @return TRUE if success, FALSE otherwise - */ - virtual bool HWTimestamper_init - ( InterfaceLabel *iface_label, OSNetworkInterface *iface ); - - /** - * @brief Gets the TX hardware timestamp value - * @param identity Clock Identity - * @param PTPMessageId Message ID - * @param timestamp [out] Reference to the TX timestamps - * @param clock_value [out] 64 bit timestamp value - * @param last Not used - * @return 0 if success. -72 if there is an error in the captured sequence or if there - * is no data available. -1 in case of error when reading data from hardware interface. - */ - virtual int HWTimestamper_txtimestamp - ( PortIdentity *identity, PTPMessageId messageId, Timestamp ×tamp, - unsigned &clock_value, bool last ); - - /** - * @brief Gets the RX hardware timestamp value - * @param identity Clock identity - * @param PTPMessageId Message ID - * @param timestamp [out] Reference to the RX timestamps - * @param clock_value [out] 64 bit timestamp value - * @param last Not used - * @return 0 if success. -72 if there is an error in the captured sequence or if there - * is no data available. -1 in case of error when reading data from hardware interface. - */ - virtual int HWTimestamper_rxtimestamp - ( PortIdentity *identity, PTPMessageId messageId, Timestamp ×tamp, - unsigned &clock_value, bool last ); - - /** - * @brief Post initialization procedure. Configures hardware ptp filter - * @param ifindex Not used - * @param sd Not used - * @param lock Not used - * @return TRUE if success, FALSE otherwise. - */ - bool post_init( int ifindex, int sd, TicketingLock *lock ); - - /** - * @brief Destroys timestamper - */ - virtual ~LinuxTimestamperIntelCE() { - } - - /** - * @brief Default constructor. Initialize some internal variables - */ - LinuxTimestamperIntelCE() { - last_tx_time = 0; - last_rx_time = 0; - } - - /** - * @brief Gets time from hardware interface and stores internally in the object's memory. - * @param system_time Not used - * @param device_time Not used - * @param local_clock Not used - * @param nominal_clock_rate Not used - */ - virtual bool HWTimestamper_gettime - ( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock, - uint32_t *nominal_clock_rate ); -}; - -#endif/*LINUX_HAL_INTELCE_HPP*/ diff --git a/daemons/gptp/linux/src/linux_hal_persist_file.cpp b/daemons/gptp/linux/src/linux_hal_persist_file.cpp deleted file mode 100644 index 335c44c6..00000000 --- a/daemons/gptp/linux/src/linux_hal_persist_file.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/************************************************************************************************************* -Copyright (c) 2012-2016, Harman International Industries, Incorporated -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "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 LISTED 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 <stdio.h> -#include <string> -#include <string.h> -#include <stdlib.h> -#include <stdint.h> -#include <ctype.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <errno.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <gptp_log.hpp> -#include "linux_hal_persist_file.hpp" - -class LinuxGPTPPersistFile : public GPTPPersist { -private: - std::string persistIDStr; - gPTPPersistWriteCB_t writeCB; - - int persistFD; - void *restoredata; - off_t storedDataLength; - off_t memoryDataLength; - -public: - LinuxGPTPPersistFile() { - persistFD = -1; - restoredata = ((void *)-1); - storedDataLength = 0; - memoryDataLength = 0; - } - - ~LinuxGPTPPersistFile() {} ; - - bool initStorage(const char *persistID) { - persistIDStr = persistID; - - persistFD = open(persistID, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (persistFD == -1) { - GPTP_LOG_ERROR("Failed to open restore file"); - return false; - } - return true; - } - - bool closeStorage(void) { - if (persistFD != -1) { - if (restoredata != ((void *) -1)) - munmap(restoredata, storedDataLength); - close(persistFD); - } - return true; - } - - bool readStorage(char **bufPtr, uint32_t *bufSize) { - bool result = false; - if (persistFD != -1) { - // MMAP file - struct stat stat0; - if (fstat(persistFD, &stat0) == -1) { - GPTP_LOG_ERROR("Failed to stat restore file, %s", strerror(errno)); - storedDataLength = 0; - } - else { - storedDataLength = stat0.st_size; - if (storedDataLength != 0) { - if ((restoredata = mmap(NULL, storedDataLength, PROT_READ | PROT_WRITE, MAP_SHARED, persistFD, 0)) == ((void *)-1)) { - GPTP_LOG_ERROR("Failed to mmap restore file, %s", strerror(errno)); - } - else { - *bufSize = storedDataLength; - *bufPtr = (char *)restoredata; - result = true; - } - } - } - } - - return result; - } - - void registerWriteCB(gPTPPersistWriteCB_t writeCB) - { - this->writeCB = writeCB; - } - - void setWriteSize(uint32_t dataSize) - { - memoryDataLength = dataSize; - } - - bool triggerWriteStorage(void) - { - if (!writeCB) { - GPTP_LOG_ERROR("Persistent write callback not registered"); - } - - bool result = false; - if (memoryDataLength > storedDataLength) { - int ret = ftruncate(persistFD, memoryDataLength); - if (ret != 0) { - GPTP_LOG_ERROR("Failed to extend stored data length from %ld to %ld, %s", storedDataLength, memoryDataLength, strerror(errno)); - } - if (restoredata != ((void *)-1)) { - restoredata = mremap(restoredata, storedDataLength, memoryDataLength, MREMAP_MAYMOVE); - } - else { - restoredata = mmap(NULL, memoryDataLength, PROT_READ | PROT_WRITE, MAP_SHARED, persistFD, 0); - } - if (restoredata == ((void *)-1)) { - - } - else { - storedDataLength = memoryDataLength; - result = true; - } - } - - writeCB((char *)restoredata, storedDataLength); - return result; - } -}; - - - -GPTPPersist* makeLinuxGPTPPersistFile() { - return new LinuxGPTPPersistFile(); -} - diff --git a/daemons/gptp/linux/src/linux_hal_persist_file.hpp b/daemons/gptp/linux/src/linux_hal_persist_file.hpp deleted file mode 100644 index 4ff1bbdc..00000000 --- a/daemons/gptp/linux/src/linux_hal_persist_file.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************************************************* -Copyright (c) 2012-2016, Harman International Industries, Incorporated -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "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 LISTED 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_PERSIST_FILE_HPP -#define LINUX_HAL_PERSIST_FILE_HPP - -#include "avbts_persist.hpp" - - -/**@file*/ - -/** - * @brief Creates an instance of a GPTPPersist - * @return Pointer to the GPTPPersist instance or NULL on failure - */ -GPTPPersist *makeLinuxGPTPPersistFile(); - - -#endif /* LINUX_HAL_PERSIST_FILE_HPP */ diff --git a/daemons/gptp/linux/src/linux_ipc.hpp b/daemons/gptp/linux/src/linux_ipc.hpp deleted file mode 100644 index 624e6bff..00000000 --- a/daemons/gptp/linux/src/linux_ipc.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - - 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 LINUXIPC_HPP -#define LINUXIPC_HPP - -#include "ipcdef.hpp" - -#define SHM_SIZE (sizeof(gPtpTimeData) + sizeof(pthread_mutex_t)) /*!< Shared memory size*/ -#define SHM_NAME "/ptp" /*!< Shared memory name*/ - - -#endif /*LINUXPIC_HPP*/ diff --git a/daemons/gptp/linux/src/platform.cpp b/daemons/gptp/linux/src/platform.cpp deleted file mode 100644 index 134ec628..00000000 --- a/daemons/gptp/linux/src/platform.cpp +++ /dev/null @@ -1,65 +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 <platform.hpp> -#include <arpa/inet.h> -#include <time.h> - -uint16_t PLAT_htons( uint16_t s ) { - return htons( s ); -} -uint32_t PLAT_htonl( uint32_t l ) { - return htonl( l ); -} -uint16_t PLAT_ntohs( uint16_t s ) { - return ntohs( s ); -} -uint32_t PLAT_ntohl( uint32_t l ) { - return ntohl( l ); -} -uint64_t PLAT_htonll(uint64_t x) -{ - return ( (htonl(1) == 1) ? x : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32) ); -} -uint64_t PLAT_ntohll(uint64_t x) -{ - return( (ntohl(1) == 1) ? x : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32) ); -} -int PLAT_localtime(const time_t * inTime, struct tm * outTm) -{ - if (localtime_r(inTime, outTm)) { - return 0; - } else { - return -1; - } -} diff --git a/daemons/gptp/linux/src/platform.hpp b/daemons/gptp/linux/src/platform.hpp deleted file mode 100644 index 32ad739e..00000000 --- a/daemons/gptp/linux/src/platform.hpp +++ /dev/null @@ -1,108 +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. - -******************************************************************************/ - -#ifndef PLATFORM_HPP -#define PLATFORM_HPP - -#include <stdint.h> -#include <time.h> - -/**@file*/ - -#define PLAT_strncpy( dest, src, max ) strncpy( dest, src, max+1 ) /*!< Provides strncpy */ -#define PLAT_snprintf(...) snprintf( __VA_ARGS__ ) /*!< Provides snprintf*/ - -/** - * @brief Converts the unsigned short integer hostshort - * from host byte order to network byte order. - * @param s short host byte order - * @return short value in network order - */ -uint16_t PLAT_htons( uint16_t s ); - -/** - * @brief Converts the unsigned integer hostlong - * from host byte order to network byte order. - * @param l Host long byte order - * @return value in network byte order - */ -uint32_t PLAT_htonl( uint32_t l ); - -/** - * @brief Converts the unsigned short integer netshort - * from network byte order to host byte order. - * @param s Network order short integer - * @return host order value - */ -uint16_t PLAT_ntohs( uint16_t s ); - -/** - * @brief Converts the unsigned integer netlong - * from network byte order to host byte order. - * @param l Long value in network order - * @return Long value on host byte order - */ -uint32_t PLAT_ntohl( uint32_t l ); - -/** - * @brief Converts a 64-bit word from host to network order - * @param x Value to be converted - * @return Converted value - */ -uint64_t PLAT_htonll(uint64_t x); - -/** - * @brief Converts a 64 bit word from network to host order - * @param x Value to be converted - * @return Converted value - */ -uint64_t PLAT_ntohll(uint64_t x); - -#ifndef _LINUX_TIMEX_H -/* - * linux_hal_generic_adj.cpp includes linux/timex.h, which precludes definition - * of time_h, so we can't make this function available there or we will get an - * error about time_t not having a type. - */ - -/** - * @brief Converts a time_t structure into a tm structure - * @param[in] inTime The time_t to be converted - * @param[out] outTm The tm to store the converted value in - * @return An error code - */ -int PLAT_localtime(const time_t * inTime, struct tm * outTm); -#endif - - -#endif diff --git a/daemons/gptp/linux/src/watchdog.cpp b/daemons/gptp/linux/src/watchdog.cpp deleted file mode 100644 index 1406fb55..00000000 --- a/daemons/gptp/linux/src/watchdog.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "watchdog.hpp" -#include "avbts_osthread.hpp" -#include "gptp_log.hpp" -#include <systemd/sd-daemon.h> - - -OSThreadExitCode watchdogUpdateThreadFunction(void *arg) -{ - SystemdWatchdogHandler *watchdog = (SystemdWatchdogHandler*) arg; - watchdog->run_update(); - return osthread_ok; -} - - -SystemdWatchdogHandler::SystemdWatchdogHandler() -{ - GPTP_LOG_INFO("Creating Systemd watchdog handler."); - LinuxTimerFactory timer_factory = LinuxTimerFactory(); - timer = timer_factory.createTimer(); -} - -SystemdWatchdogHandler::~SystemdWatchdogHandler() -{ - //Do nothing -} - -long unsigned int -SystemdWatchdogHandler::getSystemdWatchdogInterval(int *result) -{ - long unsigned int watchdog_interval; //in microseconds - *result = sd_watchdog_enabled(0, &watchdog_interval); - return watchdog_interval; -} - -void SystemdWatchdogHandler::run_update() -{ - while(1) - { - GPTP_LOG_DEBUG("NOTIFYING WATCHDOG."); - sd_notify(0, "WATCHDOG=1"); - GPTP_LOG_DEBUG("GOING TO SLEEP %lld", update_interval); - timer->sleep(update_interval); - GPTP_LOG_DEBUG("WATCHDOG WAKE UP"); - } -} - diff --git a/daemons/gptp/linux/src/watchdog.hpp b/daemons/gptp/linux/src/watchdog.hpp deleted file mode 100644 index b2e05ccf..00000000 --- a/daemons/gptp/linux/src/watchdog.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef SYSTEMDWATCHDOGHANDLER_H -#define SYSTEMDWATCHDOGHANDLER_H -#include <linux_hal_common.hpp> -#include <avbts_ostimer.hpp> - - -OSThreadExitCode watchdogUpdateThreadFunction(void *arg); - -class SystemdWatchdogHandler -{ -public: - long unsigned int update_interval; - long unsigned int getSystemdWatchdogInterval(int *result); - void run_update(); - SystemdWatchdogHandler(); - virtual ~SystemdWatchdogHandler(); -private: - OSTimer *timer; -}; - -#endif // SYSTEMDWATCHDOGHANDLER_H diff --git a/daemons/gptp/windows/.gitignore b/daemons/gptp/windows/.gitignore deleted file mode 100644 index 9735ebd8..00000000 --- a/daemons/gptp/windows/.gitignore +++ /dev/null @@ -1,56 +0,0 @@ -#Solution - -#Library objects -*.lo -*.la - -#OS junk files -[Tt]humbs.db -*.DS_Store - -#Visual Studio files -*.[Oo]bj -*.user -*.aps -*.pch -*.vspscc -*.vssscc -*_i.c -*_p.c -*.ncb -*.suo -*.tlb -*.tlh -*.bak -*.[Cc]ache -*.ilk -*.log -*.lib -*.sbr -*.sdf -*.opensdf -*.unsuccessfulbuild -ipch/ -obj/ -[Bb]in -[Bb]uild/ -[Dd]ebug*/ -[Pp]ackages/ -[Rr]elease*/ -/w[78]/ -Ankh.NoLoad - -#Tooling -_ReSharper*/ -*.resharper -[Tt]est[Rr]esult* -StyleCop.Cache - -#Project files -*/[Bb]uild/ - -#Subversion files -.svn - -# Office Temp Files -~$*
\ No newline at end of file diff --git a/daemons/gptp/windows/__build.cmd b/daemons/gptp/windows/__build.cmd deleted file mode 100644 index fa104560..00000000 --- a/daemons/gptp/windows/__build.cmd +++ /dev/null @@ -1,75 +0,0 @@ -@ECHO OFF - -:: -:: Batch for compiling solution via command line using MSBuild -:: -:: Author: Michael Welter <michael@cetoncorp.com> -:: -:: /x64 = 64-bit -:: /Win32 = 32-bit -:: -:: /Release = Release build -:: /Debug = Debug build -:: -:: Defaults to /Release /Win32 /x64 -:: - -SETLOCAL ENABLEDELAYEDEXPANSION - -SET MSBuild=%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe -IF NOT EXIST "%MSBuild%" ( - ECHO Error: MSBuild not found - "%MSBuild%" - GOTO Exit -) - -IF "%1"=="/?" (GOTO Help) -IF "%1"=="-?" (GOTO Help) - -FOR %%* IN (%*) DO ( - SET arg=%%* - IF /I "%%*"=="/x64" (SET Platform=!Platform! !arg:~1!) - IF /I "%%*"=="/Win32" (SET Platform=!Platform! !arg:~1!) - IF /I "%%*"=="/Release" (SET Configuration=!Configuration! !arg:~1!) - IF /I "%%*"=="/Debug" (SET Configuration=!Configuration! !arg:~1!) - IF /I "%%*"=="help" (GOTO Help) -) - -IF "%Platform%"=="" (SET Platform=Win32 x64) -IF "%Configuration%"=="" (SET Configuration=Release) - -FOR %%* IN ("%~dp0*.sln") DO (SET Filename="%%*") -IF NOT EXIST "%Filename%" ( - ECHO Error: Solution "%Filename%" not found - GOTO Exit -) - -FOR %%C IN (%Configuration%) DO FOR %%P IN (%Platform%) DO ( - ECHO %%C^|%%P - %MSBuild% /maxcpucount /nologo "%Filename%" /p:Configuration="%%C" /p:Platform="%%P" /t:Clean;Build -) - -:Exit - -ENDLOCAL - -EXIT /B - -:Help - -ECHO. -ECHO. Batch for compiling solution via command line using MSBuild -ECHO. -ECHO. Author: Michael Welter ^<michael@cetoncorp.com^> -ECHO. -ECHO. Usage: %~nx0 [/x64][/Win32][/Release][/Debug] -ECHO. -ECHO. /x64 = 64-bit -ECHO. /Win32 = 32-bit -ECHO. -ECHO. /Release = Release build -ECHO. /Debug = Debug build -ECHO. -ECHO. Defaults to /Release /Win32 /x64 -ECHO. - -GOTO Exit
\ No newline at end of file diff --git a/daemons/gptp/windows/daemon_cl/IPCListener.cpp b/daemons/gptp/windows/daemon_cl/IPCListener.cpp deleted file mode 100644 index e4d75784..00000000 --- a/daemons/gptp/windows/daemon_cl/IPCListener.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/****************************************************************************** - -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 <windows.h> -#include <PeerList.hpp> -#include <IPCListener.hpp> - -DWORD WINAPI IPCListener::IPCListenerLoop( IPCSharedData *arg ) { - PeerList *list = arg->list; - LockableOffset *loffset = arg->offset; - HANDLE pipe = INVALID_HANDLE_VALUE; - - uint8_t tmp[NPIPE_MAX_MSG_SZ]; - OVERLAPPED pipe_ol; - HANDLE ol_event; - enum { PIPE_CLOSED, PIPE_UNCONNECT, PIPE_CONNECT_PENDING, PIPE_CONNECT, PIPE_READ_PENDING } pipe_state; - - // Open named pipe - char pipename[64]; - strncpy_s( pipename, 64, PIPE_PREFIX, 63 ); - strncpy_s( pipename+strlen(pipename), 64-strlen(pipename), P802_1AS_PIPENAME, 63-strlen(pipename) ); - ol_event = CreateEvent( NULL, true, false, NULL ); - pipe_state = PIPE_CLOSED; - - DWORD retval = -1; - - while( !exit_waiting ) { - int err; - DWORD ret; - if( pipe_state < PIPE_UNCONNECT ) { - if( pipe != INVALID_HANDLE_VALUE ) { - DisconnectNamedPipe( pipe ); - CloseHandle( pipe ); - } - pipe = CreateNamedPipe( pipename, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE , PIPE_UNLIMITED_INSTANCES, - OUTSTANDING_MESSAGES*NPIPE_MAX_SERVER_MSG_SZ, OUTSTANDING_MESSAGES*NPIPE_MAX_MSG_SZ, 0, NULL ); - if( pipe == INVALID_HANDLE_VALUE ) { - GPTP_LOG_ERROR( "Open pipe error (%s): %d", pipename, GetLastError() ); - goto do_error; - } - pipe_state = PIPE_UNCONNECT; - } else if( pipe_state < PIPE_CONNECT ) { - if( pipe_state != PIPE_CONNECT_PENDING ) { - memset( &pipe_ol, 0, sizeof( pipe_ol )); - pipe_ol.hEvent = ol_event; - if( ResetEvent( ol_event ) == 0 ) goto do_error; - if( ConnectNamedPipe( pipe, &pipe_ol ) != 0 ) { - // Successfully connected - pipe_state = PIPE_CONNECT; - continue; - } else { - err = GetLastError(); - switch( err ) { - default: - GPTP_LOG_ERROR( "Attempt to connect on Pipe failed, %d", err ); - goto do_error; - case ERROR_PIPE_CONNECTED: - pipe_state = PIPE_CONNECT; - continue; - case ERROR_IO_PENDING: - pipe_state = PIPE_CONNECT_PENDING; - } - } - } - ret = WaitForSingleObject( ol_event, 200 ); - switch( ret ) { - case WAIT_OBJECT_0: - pipe_state = PIPE_CONNECT; - case WAIT_TIMEOUT: - continue; - default: - goto do_error; - } - } else { - // We're connected - long readlen; - if( pipe_state < PIPE_READ_PENDING ) { - // Wait for message - Read Base Message - ((WindowsNPipeMessage *)tmp)->init(); - if( ResetEvent( ol_event ) == 0 ) goto do_error; - if(( readlen = ((WindowsNPipeMessage *)tmp)->read_ol( pipe, 0, ol_event )) == -1 ) { - err = GetLastError(); - switch( err ) { - default: - GPTP_LOG_ERROR( "Failed to read from pipe @%u,%d", __LINE__, err ); - goto do_error; - case ERROR_BROKEN_PIPE: - pipe_state = PIPE_CLOSED; - continue; - case ERROR_IO_PENDING: - ; - } - } - // Fall through to here whether data is available or not - pipe_state = PIPE_READ_PENDING; - } - ret = WaitForSingleObject( ol_event, 200 ); - switch( ret ) { - default: - goto do_error; - case WAIT_TIMEOUT: - continue; - case WAIT_OBJECT_0: - if(( readlen = ((WinNPipeCtrlMessage *)tmp)->read_ol_complete( pipe )) == -1 ) { - err = GetLastError(); - if( err == ERROR_BROKEN_PIPE ) { - pipe_state = PIPE_CLOSED; - continue; - } - GPTP_LOG_ERROR( "Failed to read from pipe @%u,%d", __LINE__, err ); - goto do_error; - } - switch( ((WindowsNPipeMessage *)tmp)->getType() ) { - case CTRL_MSG: - ((WinNPipeCtrlMessage *)tmp)->init(); - if(( readlen = ((WinNPipeCtrlMessage *)tmp)->read( pipe, readlen )) == -1 ) { - GPTP_LOG_ERROR( "Failed to read from pipe @%u", __LINE__ ); - goto do_error; - } - //readlen may not be set properly ?? - // Attempt to add or remove from the list - switch( ((WinNPipeCtrlMessage *)tmp)->getCtrlWhich() ) { - default: - GPTP_LOG_ERROR( "Recvd CTRL cmd specifying illegal operation @%u", __LINE__ ); - goto do_error; - case ADD_PEER: - if( !list->IsReady() || !list->add( ((WinNPipeCtrlMessage *)tmp)->getPeerAddr() ) ) { - GPTP_LOG_ERROR( "Failed to add peer @%u", __LINE__ ); - } - break; - case REMOVE_PEER: - if( !list->IsReady() || !list->remove( ((WinNPipeCtrlMessage *)tmp)->getPeerAddr() ) ) { - GPTP_LOG_ERROR( "Failed to remove peer @%u", __LINE__ ); - } - break; - } - break; - case OFFSET_MSG: - ((WinNPipeQueryMessage *)tmp)->init(); - if(( readlen = ((WinNPipeQueryMessage *)tmp)->read( pipe, readlen )) == -1 ) { - GPTP_LOG_ERROR( "Failed to read from pipe @%u", __LINE__ ); - goto do_error; - } - // Create an offset message and send it - loffset->get(); - if( loffset->isReady() ) ((WinNPipeOffsetUpdateMessage *)tmp)->init((Offset *)loffset); - else ((WinNPipeOffsetUpdateMessage *)tmp)->init(); - loffset->put(); - ((WinNPipeOffsetUpdateMessage *)tmp)->write(pipe); - break; - default: - GPTP_LOG_ERROR( "Recvd Unknown Message" ); - // Is this recoverable? - goto do_error; - } - pipe_state = PIPE_CONNECT; - } - } - } - - - retval = 0; // Exit normally -do_error: - // Close Named Pipe - if( pipe != INVALID_HANDLE_VALUE ) CloseHandle( pipe ); - - return retval; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/daemons/gptp/windows/daemon_cl/IPCListener.hpp b/daemons/gptp/windows/daemon_cl/IPCListener.hpp deleted file mode 100644 index 1ef521b1..00000000 --- a/daemons/gptp/windows/daemon_cl/IPCListener.hpp +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************************** - -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 IPCLISTENER_HPP -#define IPCLISTENER_HPP - -#include <stdlib.h> -#include <windows_ipc.hpp> -#include <PeerList.hpp> -#include <Stoppable.hpp> - -/**@file */ - -/** - * @brief Provides an interface for offset with lock - */ -class LockableOffset : public Lockable, public Offset { -private: - bool ready; -public: - /** - * @brief Default constructor. Initializes internal variables - */ - LockableOffset() { - ml_phoffset = 0; - ml_freqoffset = 0.0; - ls_phoffset = 0; - ls_freqoffset = 0.0; - local_time = 0; - - memset(gptp_grandmaster_id, 0, sizeof(gptp_grandmaster_id)); - gptp_domain_number = 0; - - memset(clock_identity, 0, sizeof(clock_identity)); - priority1 = 0xFF; - clock_class = 0xFF; - offset_scaled_log_variance = 0x0000; - clock_accuracy = 0xFF; - priority2 = 0xFF; - domain_number = 0; - log_sync_interval = 0; - log_announce_interval = 0; - log_pdelay_interval = 0; - port_number = 0x0000; - } - /** - * @brief Get Internal ready flag - * @return TRUE if is ready. FALSE otherwise. - */ - bool isReady() { return ready; } - /** - * @brief Sets ready flag - * @param ready Value to be set. - */ - void setReady( bool ready ) { this->ready = ready; } -}; - -/** - * @brief Provides an interface for the IPC shared data - */ -class IPCSharedData { -public: - PeerList *list; /*!< List of peers */ - LockableOffset *offset; /*!< Ponter to LockableOffset class */ -}; - -/** - * @brief Provides an interface for the IPC Listener - */ -class IPCListener : public Stoppable { -private: - static DWORD WINAPI IPCListenerLoopWrap( LPVOID arg ) { - DWORD ret; - LPVOID *argl = (LPVOID *) arg; - IPCListener *this0 = (IPCListener *) argl[0]; - ret = this0->IPCListenerLoop((IPCSharedData *) argl[1] ); - delete argl[1]; - delete [] argl; - return ret; - } - DWORD WINAPI IPCListenerLoop( IPCSharedData *arg ); -public: - /** - * @brief Starts the listener loop in a new thread - * @return TRUE in case of success, FALSE in case of error - */ - bool start( IPCSharedData data ) { - LPVOID *arg = new LPVOID[2]; - if( thread != NULL ) { - return false; - } - arg[1] = (void *) malloc((size_t) sizeof(IPCSharedData)); - arg[0] = this; - *((IPCSharedData *) arg[1]) = data; - thread = CreateThread( NULL, 0, &IPCListenerLoopWrap, arg, 0, NULL ); - if( thread != NULL ) return true; - else return false; - } - /** - * @brief Destroys the IPC listener interface - */ - ~IPCListener() {} -}; - - - -#endif/*IPCListener_hpp*/ diff --git a/daemons/gptp/windows/daemon_cl/Lockable.hpp b/daemons/gptp/windows/daemon_cl/Lockable.hpp deleted file mode 100644 index 37759657..00000000 --- a/daemons/gptp/windows/daemon_cl/Lockable.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/****************************************************************************** - -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 LOCKABLE_HPP -#define LOCKABLE_HPP - -#include <Windows.h> - -/**@file*/ - -/** - * @brief Provides a lock abstraction - */ -class Lockable { -private: - SRWLOCK lock; -public: - /** - * @brief Initializes lock interface - */ - Lockable() { InitializeSRWLock( &lock ); } - /** - * @brief Acquires lock - * @return void - */ - void get() { AcquireSRWLockExclusive( &lock ); } - /** - * @brief Releases lock - * @return void - */ - void put() { ReleaseSRWLockExclusive( &lock ); } -}; - -#endif/*LOCKABLE_HPP*/ diff --git a/daemons/gptp/windows/daemon_cl/PeerList.hpp b/daemons/gptp/windows/daemon_cl/PeerList.hpp deleted file mode 100644 index 1d862990..00000000 --- a/daemons/gptp/windows/daemon_cl/PeerList.hpp +++ /dev/null @@ -1,196 +0,0 @@ -/****************************************************************************** - -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 PEERLIST_HPP -#define PEERLIST_HPP - -#include <vector> -#include <windows_ipc.hpp> -#include <Lockable.hpp> - -/**@file*/ - -/** - * @brief Type Peer address with state - */ -typedef struct { - PeerAddr addr; /*!< Peer address */ - void *state; /*!< Used by consumers of */ -} PeerAddrWithState; - -/** - * @brief Peer init handler callback definition - */ -typedef bool (*peer_init_handler)( void **, void *, PeerAddr addr ); -/** - * @brief Peer remove callback definition - */ -typedef bool (*peer_rm_handler)( void *, void * ); - -/** - * @brief Type peer vector - */ -typedef std::vector<PeerAddrWithState> PeerVector; - -/** - * @brief Peer List interface - */ -class PeerList : public Lockable { -private: - peer_init_handler init; - void *handler_arg; - peer_rm_handler rm; - PeerVector internal_vector; - bool ready; -public: - typedef PeerVector::const_iterator const_iterator; /*!< Peer constant iterator*/ - typedef PeerVector::iterator PeerVectorIt; /*!< Peer vector iterator*/ - /** - * @brief Initializes peer list - */ - PeerList() { rm = NULL; init = NULL; } - /** - * @brief Look for a peer address - * @param addr Peer address - * @param found [out] Set to true when address is found - * @return PeerVector internal - */ - PeerVectorIt find( PeerAddr addr, bool *found ) { - PeerVectorIt it = internal_vector.begin(); - *found = false; - if( internal_vector.size() == 0 ) { - goto done; - } - for( ;it < internal_vector.end(); ++it ) { - if( addr == (*it).addr ) { - *found = true; - break; - } - if( addr < (*it).addr ) { - break; - } - } -done: - return it; - } - /** - * @brief Add a new peer address - * @param addr PeerAddr address - * @return TRUE if successfully added. FALSE if it already exists - */ - bool add( PeerAddr addr ) { - bool found; - PeerVectorIt it; - it = find( addr, &found ); - if( found ) { - return false; - } else { - PeerAddrWithState addr_state = { addr, NULL }; - if( init ) { - if( !init( &addr_state.state, handler_arg, addr )) { - //DBGPRINT("Call to initialize peer state failed"); - // return false? - } else { - internal_vector.insert( it, addr_state ); - } - } - } - return true; - } - /** - * @brief Remove a peer address from the internal list - * @param addr Address to remove - * @return FALSE if the address is not found. TRUE if successfully removed. - */ - bool remove( PeerAddr addr ) { - bool found; - PeerVectorIt it; - it = find( addr, &found ); - if( !found ) { - return false; - } else { - if( rm != NULL ) { - if( !rm( it->state, handler_arg ) ) { - fprintf( stderr, "Call to cleanup peer state failed\n" ); - } - } - internal_vector.erase( it ); - } - return true; - } - /** - * @brief Gets the beginning of the sequence container - * @return An iterator to the beginning of the sequence container - */ - const_iterator begin() { - return internal_vector.begin(); - } - /** - * @brief Gets the end of the sequence container - * @return An iterator to the end of the sequence container - */ - const_iterator end() { - return internal_vector.end(); - } - /** - * @brief Sets init handler - * @param init Peer init handler - * @param init_arg [in] Init arguments - * @return void - */ - void setInit( peer_init_handler init, void *init_arg ) { - this->init = init; - this->handler_arg = init_arg; - } - /** - * @brief Sets peer remove callback on the PeerList object - * @param rm rm handler - * @return void - */ - void setRm( peer_rm_handler rm ) { - this->rm = rm; - } - /** - * @brief Gets ready flag - * @return TRUE if ready. FALSE otherwise - */ - bool IsReady() { return ready; } - /** - * @brief Sets ready flag - * @param ready Flag value to be set - * @return void - */ - void setReady( bool ready ) { this->ready = ready; } -}; - -#endif/*PEERLIST_HPP*/ diff --git a/daemons/gptp/windows/daemon_cl/Stoppable.hpp b/daemons/gptp/windows/daemon_cl/Stoppable.hpp deleted file mode 100644 index 0b73d66c..00000000 --- a/daemons/gptp/windows/daemon_cl/Stoppable.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/****************************************************************************** - -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 STOPPABLE_HPP -#define STOPPABLE_HPP - -#include <Windows.h> -#include <gptp_log.hpp> - -/**@file*/ - -/** - * @brief Provides an interface to stop threads - */ -class Stoppable { -protected: - bool exit_waiting; /*!< Waiting to exit */ - HANDLE thread; /*!< Thread handler */ -public: - /** - * @brief Initializes interface - */ - Stoppable() { thread = NULL; exit_waiting = false; } - /** - * @brief Stops thread - * @return TRUE in case of success. FALSE otherwise. - */ - bool stop() { - if( thread == NULL ) return false; - exit_waiting = true; - if( WaitForSingleObject( thread, INFINITE ) == WAIT_FAILED ) { - char *errstr; - GPTP_LOG_ERROR( "Wait for thread exit failed %s", errstr ); - delete errstr; - } - exit_waiting = false; - return true; - } - /** - * @brief destroys the interface - */ - virtual ~Stoppable() = 0 {}; -}; - -#endif/*STOPPABLE_HPP*/ diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.cpp b/daemons/gptp/windows/daemon_cl/daemon_cl.cpp deleted file mode 100644 index 8da3ddfa..00000000 --- a/daemons/gptp/windows/daemon_cl/daemon_cl.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/****************************************************************************** - -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 <winsock2.h> -#include <Windows.h> -#include <winnt.h> -#include "ieee1588.hpp" -#include "avbts_clock.hpp" -#include "avbts_osnet.hpp" -#include "avbts_oslock.hpp" -#include "windows_hal.hpp" -#include "avbts_message.hpp" -#include "gptp_cfg.hpp" -#include <tchar.h> -#include <iphlpapi.h> - -#include <ether_port.hpp> -#include <wireless_port.hpp> -#include <intel_wireless.hpp> - -/* Generic PCH delays */ -#define PHY_DELAY_GB_TX_PCH 7750 //1G delay -#define PHY_DELAY_GB_RX_PCH 7750 //1G delay -#define PHY_DELAY_MB_TX_PCH 27500 //100M delay -#define PHY_DELAY_MB_RX_PCH 27500 //100M delay - -/* I210 delays */ -#define PHY_DELAY_GB_TX_I210 184 //1G delay -#define PHY_DELAY_GB_RX_I210 382 //1G delay -#define PHY_DELAY_MB_TX_I210 1044 //100M delay -#define PHY_DELAY_MB_RX_I210 2133 //100M delay - -#define MACSTR_LENGTH 17 - -uint32_t findLinkSpeed(LinkLayerAddress *local_addr); - -static bool exit_flag; - -void print_usage( char *arg0 ) { - fprintf( stderr, - "%s " - "[-R <priority 1>] <network interface>\n" - "where <network interface> is a MAC address entered as xx-xx-xx-xx-xx-xx\n", - arg0 ); -} - -BOOL WINAPI ctrl_handler( DWORD ctrl_type ) { - bool ret; - if( ctrl_type == CTRL_C_EVENT ) { - exit_flag = true; - ret = true; - } else { - ret = false; - } - return ret; -} - -int parseMacAddr( _TCHAR *macstr, uint8_t *octet_string ) { - int i; - _TCHAR *cur = macstr; - - if( strnlen_s( macstr, MACSTR_LENGTH ) != 17 ) return -1; - - for( i = 0; i < ETHER_ADDR_OCTETS; ++i ) { - octet_string[i] = strtol( cur, &cur, 16 ) & 0xFF; - ++cur; - } - - return 0; -} - -int _tmain(int argc, _TCHAR* argv[]) -{ - PortInit_t portInit; - - phy_delay_map_t ether_phy_delay; - ether_phy_delay[LINKSPEED_1G].set_delay - (PHY_DELAY_GB_TX_PCH, PHY_DELAY_GB_RX_PCH); - ether_phy_delay[LINKSPEED_100MB].set_delay - (PHY_DELAY_MB_TX_PCH, PHY_DELAY_MB_RX_PCH); - - - portInit.clock = NULL; - portInit.index = 1; - portInit.timestamper = NULL; - portInit.net_label = NULL; - portInit.automotive_profile = false; - portInit.isGM = false; - portInit.testMode = false; - portInit.initialLogSyncInterval = LOG2_INTERVAL_INVALID; - portInit.initialLogPdelayReqInterval = LOG2_INTERVAL_INVALID; - portInit.operLogPdelayReqInterval = LOG2_INTERVAL_INVALID; - portInit.operLogSyncInterval = LOG2_INTERVAL_INVALID; - portInit.condition_factory = NULL; - portInit.thread_factory = NULL; - portInit.timer_factory = NULL; - portInit.lock_factory = NULL; - portInit.neighborPropDelayThreshold = - CommonPort::NEIGHBOR_PROP_DELAY_THRESH; - - bool syntonize = false; - bool wireless = false; - uint8_t priority1 = 248; - int i; - int phy_delays[4] = { -1, -1, -1, -1 }; - uint8_t addr_ostr[ETHER_ADDR_OCTETS]; - - // Register default network interface - WindowsPCAPNetworkInterfaceFactory *default_factory = new WindowsPCAPNetworkInterfaceFactory(); - OSNetworkInterfaceFactory::registerFactory( factory_name_t( "default" ), default_factory ); - - // Create thread, lock, timer, timerq factories - portInit.thread_factory = new WindowsThreadFactory(); - portInit.lock_factory = new WindowsLockFactory(); - portInit.timer_factory = new WindowsTimerFactory(); - portInit.condition_factory = new WindowsConditionFactory(); - WindowsNamedPipeIPC *ipc = new WindowsNamedPipeIPC(); - WindowsTimerQueueFactory *timerq_factory = new WindowsTimerQueueFactory(); - CommonPort *port; - WindowsWirelessAdapter *wl_adapter = NULL; - - if( !ipc->init() ) { - delete ipc; - ipc = NULL; - } - - // If there are no arguments, output usage - if (1 == argc) { - print_usage(argv[0]); - return -1; - } - - - /* Process optional arguments */ - for( i = 1; i < argc; ++i ) { - if (ispunct(argv[i][0])) - { - if (toupper(argv[i][1]) == 'H') { - print_usage(argv[0]); - return -1; - } - if (toupper(argv[i][1]) == 'W') - { - wireless = true; - } - else if (toupper(argv[i][1]) == 'R') { - if (i + 1 >= argc) { - printf("Priority 1 value must be specified on " - "command line, using default value\n"); - } - else { - unsigned long tmp = strtoul(argv[i + 1], NULL, 0); ++i; - if (tmp > 255) { - printf("Invalid priority 1 value, using " - "default value\n"); - } - else { - priority1 = (uint8_t)tmp; - } - } - } - } else - { - break; - } - } - - // Parse local HW MAC address - if (i < argc) - { - parseMacAddr(argv[i++], addr_ostr); - portInit.net_label = new LinkLayerAddress(addr_ostr); - } else - { - printf("Local hardware MAC address required"); - return -1; - } - - if( wireless ) - { - if (i < argc) - { - parseMacAddr(argv[i++], addr_ostr); - portInit.virtual_label = new LinkLayerAddress(addr_ostr); - } else - { - printf("Wireless operation requires local virtual MAC address"); - return -1; - } - } - - if (!wireless) - { - // Create HWTimestamper object - portInit.timestamper = new WindowsEtherTimestamper(); - } else - { - portInit.timestamper = new WindowsWirelessTimestamper(); - (static_cast<WindowsWirelessTimestamper *> (portInit.timestamper))->setAdapter(new IntelWirelessAdapter()); - } - - // Create Clock object - portInit.clock = new IEEE1588Clock(false, false, priority1, timerq_factory, ipc, portInit.lock_factory); // Do not force slave - - if (!wireless) - { - // Create Port Object linked to clock and low level - portInit.phy_delay = ðer_phy_delay; - EtherPort *eport = new EtherPort(&portInit); - eport->setLinkSpeed( findLinkSpeed( static_cast <LinkLayerAddress *> ( portInit.net_label ))); - port = eport; - if (!eport->init_port()) { - printf("Failed to initialize port\n"); - return -1; - } - port->processEvent(POWERUP); - } else - { - if (i < argc) - { - parseMacAddr(argv[i++], addr_ostr); - LinkLayerAddress peer_addr(addr_ostr); - port = new WirelessPort(&portInit, peer_addr); - (static_cast <WirelessTimestamper *> (portInit.timestamper))->setPort( static_cast<WirelessPort *> ( port )); - if (!port->init_port()) { - printf("Failed to initialize port\n"); - return -1; - } - port->processEvent(POWERUP); - } else - { - printf("Wireless operation requires remote MAC address"); - return -1; - } - } - - // Wait for Ctrl-C - if( !SetConsoleCtrlHandler( ctrl_handler, true )) { - printf( "Unable to register Ctrl-C handler\n" ); - return -1; - } - - while( !exit_flag ) Sleep( 1200 ); - - delete( ipc ); - - return 0; -} - -#define WIN_LINKSPEED_MULT (1000/*1 Kbit*/) - -uint32_t findLinkSpeed( LinkLayerAddress *local_addr ) -{ - ULONG ret_sz; - char *buffer; - PIP_ADAPTER_ADDRESSES pAddr; - ULONG err; - uint32_t ret; - - buffer = (char *) malloc((size_t)15000); - ret_sz = 15000; - pAddr = (PIP_ADAPTER_ADDRESSES)buffer; - err = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, pAddr, &ret_sz ); - for (; pAddr != NULL; pAddr = pAddr->Next) - { - //fprintf(stderr, "** here : %p\n", pAddr); - if (pAddr->PhysicalAddressLength == ETHER_ADDR_OCTETS && - *local_addr == LinkLayerAddress(pAddr->PhysicalAddress)) - { - break; - } - } - - if (pAddr == NULL) - return INVALID_LINKSPEED; - - switch ( pAddr->ReceiveLinkSpeed / WIN_LINKSPEED_MULT ) - { - default: - GPTP_LOG_ERROR("Can't find link speed, %llu", pAddr->ReceiveLinkSpeed); - ret = INVALID_LINKSPEED; - break; - case LINKSPEED_1G: - ret = LINKSPEED_1G; - break; - case LINKSPEED_100MB: - ret = LINKSPEED_100MB; - break; - } - - delete buffer; - return ret; -}
\ No newline at end of file diff --git a/daemons/gptp/windows/daemon_cl/gptp.manifest b/daemons/gptp/windows/daemon_cl/gptp.manifest deleted file mode 100644 index fde96021..00000000 --- a/daemons/gptp/windows/daemon_cl/gptp.manifest +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> - <security> - <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> - <requestedExecutionLevel level="asInvoker" uiAccess="false" /> - </requestedPrivileges> - </security> - </trustInfo> - - <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> - <application> - <!-- Windows Vista and Windows Server 2008 --> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS> - - <!-- Windows 7 and Windows Server 2008 R2 --> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - - <!-- Windows 8 and Windows Server 2012 --> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS> - - <!-- Windows 8.1 and Windows Server 2012 R2 --> - <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> - - <!-- Windows 10 --> - <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> - - </application> - </compatibility> -</asmv1:assembly> diff --git a/daemons/gptp/windows/daemon_cl/intel_wireless.cpp b/daemons/gptp/windows/daemon_cl/intel_wireless.cpp deleted file mode 100644 index a6f8f99f..00000000 --- a/daemons/gptp/windows/daemon_cl/intel_wireless.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2015, 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 <intel_wireless.hpp> -#include <windows_hal.hpp> -#include <work_queue.hpp> -#include <memory> -#include <map> - -#define INTEL_EVENT_OFFSET 0x1141 -#define GP2_ROLLOVER 4294967296ULL - -GetAdapterList_t GetAdapterList; -WifiCmdTimingMeasurementRequest_t WifiCmdTimingMeasurementRequest; -WifiCmdTimingPtmWa_t WifiCmdTimingPtmWa; -RegisterIntelCallback_t RegisterIntelCallback; -DeregisterIntelCallback_t DeregisterIntelCallback; - -struct TimestamperContext -{ - WindowsWorkQueue work_queue; - WindowsWirelessTimestamper *timestamper; - ~TimestamperContext() - { - work_queue.stop(); - } -}; - -typedef std::map< LinkLayerAddress, TimestamperContext > TimestamperContextMap; - -class LockedTimestamperContextMap -{ -public: - LockedTimestamperContextMap() - { - InitializeSRWLock(&lock); - } - TimestamperContextMap map; - SRWLOCK lock; -}; - -LockedTimestamperContextMap timestamperContextMap; -HANDLE IntelTimestamperThread; -bool IntelTimestamperThreadStop = false; - -void IntelWirelessTimestamperEventHandler( INTEL_EVENT iEvent, void *pContext ) -{ - WindowsWirelessTimestamper *timestamper; - IntelWirelessAdapter *adapter; - LockedTimestamperContextMap *timestamperContextMap = - (LockedTimestamperContextMap *)pContext; - WirelessTimestamperCallbackArg *arg = - new WirelessTimestamperCallbackArg(); - int vendor_extension_copy_length; - bool error = false; - bool submit = false; // If true submit the event for later processing - - // We share driver callback with other events, subtract the offset for - // timing measurement related events and check this is time sync event - iEvent.eType = - (WIRELESS_EVENT_TYPE) (iEvent.eType - INTEL_EVENT_OFFSET); - switch( iEvent.eType ) - { - default: - return; - case TIMINGMSMT_CONFIRM_EVENT: - case TIMINGMSMT_EVENT: - case TIMINGMSMT_CORRELATEDTIME_EVENT: - break; - } - - LinkLayerAddress event_source( iEvent.BtMacAddress ); - arg->iEvent_type = (WIRELESS_EVENT_TYPE) iEvent.eType; - AcquireSRWLockShared( ×tamperContextMap->lock ); - if( timestamperContextMap->map.find( event_source ) - != timestamperContextMap->map.cend()) - { - arg->timestamper = - timestamperContextMap->map[event_source].timestamper; - } else - { - goto bail; - } - - timestamper = dynamic_cast <WindowsWirelessTimestamper *> - (arg->timestamper); - if( timestamper == NULL ) - { - GPTP_LOG_ERROR( "Unexpected timestamper type encountered" ); - goto bail; - } - adapter = dynamic_cast <IntelWirelessAdapter *> - (timestamper->getAdapter( )); - if( adapter == NULL ) - { - GPTP_LOG_ERROR( "Unexpected adapter type encountered" ); - goto bail; - } - - // The driver implementation makes no guarantee of the lifetime of the - // iEvent object we make a copy and delete the copy when processing is - // complete - switch( arg->iEvent_type ) - { - case TIMINGMSMT_CONFIRM_EVENT: - arg->event_data.confirm = - *(TIMINGMSMT_CONFIRM_EVENT_DATA *)iEvent.data; - arg->event_data.confirm.T1 = - adapter->calc_rollover( arg->event_data.confirm.T1 ); - arg->event_data.confirm.T4 = - adapter->calc_rollover( arg->event_data.confirm.T4 ); - submit = true; - - break; - - case TIMINGMSMT_EVENT: - arg->event_data.indication.indication = - *(TIMINGMSMT_EVENT_DATA *)iEvent.data; - arg->event_data.indication.indication.T2 = - adapter->calc_rollover - ( arg->event_data.indication.indication.T2/100 ); - arg->event_data.indication.indication.T3 = - adapter->calc_rollover - ( arg->event_data.indication.indication.T3/100 ); - // Calculate copy length, at most followup message - // (See S8021AS indication) - vendor_extension_copy_length = arg->event_data. - indication.indication.WiFiVSpecHdr.Length - 1; - vendor_extension_copy_length -= vendor_extension_copy_length - - sizeof(arg->event_data.indication.followup) > 0 ? - vendor_extension_copy_length - - sizeof(arg->event_data.indication.followup) : 0; - // Copy the rest of the vendor specific field - memcpy( arg->event_data.indication.followup, - ((BYTE *)iEvent.data) + - sizeof( arg->event_data.indication.indication ), - vendor_extension_copy_length ); - submit = true; - break; - case TIMINGMSMT_CORRELATEDTIME_EVENT: - AcquireSRWLockExclusive(&adapter->ct_lock); - if (adapter->ct_miss > 0) - { - --adapter->ct_miss; - } else - { - arg->event_data.ptm_wa = - *(WIRELESS_CORRELATEDTIME *)iEvent.data; - arg->event_data.ptm_wa.LocalClk = - adapter->calc_rollover - (arg->event_data.ptm_wa.LocalClk); - adapter->ct_done = true; - // No need to schedule this, it returns immediately - WirelessTimestamperCallback(arg); - WakeAllConditionVariable(&adapter->ct_cond); - } - ReleaseSRWLockExclusive(&adapter->ct_lock); - - break; - } - - if (submit && - !timestamperContextMap->map[event_source].work_queue.submit - ( WirelessTimestamperCallback, arg )) - GPTP_LOG_ERROR("Failed to submit WiFi event"); -bail: - ReleaseSRWLockShared(×tamperContextMap->lock); -} - -DWORD WINAPI IntelWirelessLoop(LPVOID arg) -{ - // Register for callback - INTEL_CALLBACK tempCallback; - tempCallback.fnIntelCallback = IntelWirelessTimestamperEventHandler; - tempCallback.pContext = arg; - - if (RegisterIntelCallback(&tempCallback) != S_OK) { - GPTP_LOG_ERROR( "Failed to register WiFi callback" ); - return 0; - } - - while (!IntelTimestamperThreadStop) - { - SleepEx(320, true); - } - - DeregisterIntelCallback(tempCallback.fnIntelCallback); - - return 0; -} - -bool IntelWirelessAdapter::initialize(void) -{ - HMODULE MurocApiDLL = LoadLibrary("MurocApi.dll"); - - GetAdapterList = (GetAdapterList_t) - GetProcAddress(MurocApiDLL, "GetAdapterList"); - if( GetAdapterList == NULL ) - return false; - - RegisterIntelCallback = (RegisterIntelCallback_t) - GetProcAddress(MurocApiDLL, "RegisterIntelCallback"); - if( RegisterIntelCallback == NULL ) - return false; - - DeregisterIntelCallback = (DeregisterIntelCallback_t) - GetProcAddress(MurocApiDLL, "DeregisterIntelCallback"); - if( DeregisterIntelCallback == NULL ) - return false; - - WifiCmdTimingPtmWa = (WifiCmdTimingPtmWa_t) - GetProcAddress(MurocApiDLL, "WifiCmdTimingPtmWa"); - if( WifiCmdTimingPtmWa == NULL ) - return false; - - WifiCmdTimingMeasurementRequest = (WifiCmdTimingMeasurementRequest_t) - GetProcAddress(MurocApiDLL, "WifiCmdTimingMeasurementRequest"); - if (WifiCmdTimingMeasurementRequest == NULL) - return false; - - // Initialize crosstimestamp condition - InitializeConditionVariable(&ct_cond); - InitializeSRWLock(&ct_lock); - ct_miss = 0; - - // Spawn thread - IntelTimestamperThread = CreateThread - ( NULL, 0, IntelWirelessLoop, ×tamperContextMap, 0, NULL); - return true; -} - -void IntelWirelessAdapter::shutdown(void) { - // Signal thread exit - IntelTimestamperThreadStop = true; - // Join thread - WaitForSingleObject(IntelTimestamperThread, INFINITE); -} - -bool IntelWirelessAdapter::refreshCrossTimestamp(void) { - INTEL_WIFI_HEADER header; - WIRELESS_CORRELATEDTIME ptm_wa; - DWORD wait_return = TRUE; - DWORD start = 0; - - AcquireSRWLockExclusive(&ct_lock); - ct_done = false; - header.dwSize = sizeof(ptm_wa); - header.dwStructVersion = INTEL_STRUCT_VER_LATEST; - HRESULT hres = WifiCmdTimingPtmWa(hAdapter, &header, &ptm_wa); - if (hres != S_OK) - return false; - - while (!ct_done && wait_return == TRUE) { - DWORD now = GetTickCount(); - start = start == 0 ? now : start; - DWORD wait = now - start < CORRELATEDTIME_TRANSACTION_TIMEOUT ? - CORRELATEDTIME_TRANSACTION_TIMEOUT - - (now - start) : 0; - wait_return = SleepConditionVariableSRW - ( &ct_cond, &ct_lock, wait, 0 ); - } - ct_miss += wait_return != TRUE ? 1 : 0; - ReleaseSRWLockExclusive(&ct_lock); - - return wait_return == TRUE ? true : false; -} - -bool IntelWirelessAdapter::initiateTimingRequest -( TIMINGMSMT_REQUEST *tm_request ) -{ - INTEL_WIFI_HEADER header; - HRESULT err; - - memset(&header, 0, sizeof(header)); - // Proset wants an equivalent, but slightly different struct definition - header.dwSize = sizeof(*tm_request) - sizeof(PTP_SPEC) + 1; - header.dwStructVersion = INTEL_STRUCT_VER_LATEST; - if(( err = WifiCmdTimingMeasurementRequest - (hAdapter, &header, tm_request)) != S_OK ) - return false; - - return true; -} - -// Find Intel adapter given MAC address and return adapter ID -// -// @adapter(out): Adapter identifier used for all driver interaction -// @mac_addr: HW address of the adapter -// @return: *false* if adapter is not found or driver communication failure -// occurs, otherwise *true* -// -bool IntelWirelessAdapter::attachAdapter(uint8_t *mac_addr) -{ - PINTEL_ADAPTER_LIST adapter_list; - int i; - - if (GetAdapterList(&adapter_list) != S_OK) - return false; - - GPTP_LOG_VERBOSE("Driver query returned %d adapters\n", - adapter_list->count); - for (i = 0; i < adapter_list->count; ++i) { - if( memcmp(adapter_list->adapter[i].btMACAddress, - mac_addr, ETHER_ADDR_OCTETS) == 0 ) - break; - } - - if (i == adapter_list->count) - { - GPTP_LOG_ERROR("Driver failed to find the requested adapter"); - return false; - } - hAdapter = adapter_list->adapter[i].hAdapter; - - return true; -} - -// Register timestamper with Intel wireless subsystem. -// -// @timestamper: timestamper object that should receive events -// @source: MAC address of local interface -// @return: *false* if the MAC address has already been registered, *true* if -// -bool IntelWirelessAdapter::registerTimestamper -(WindowsWirelessTimestamper *timestamper) -{ - bool ret = false; - - AcquireSRWLockExclusive(×tamperContextMap.lock); - // Do not "re-add" the same timestamper - if( timestamperContextMap.map.find - ( *timestamper->getPort()->getLocalAddr() ) - == timestamperContextMap.map.cend()) - { - // Initialize per timestamper context and add - timestamperContextMap.map - [*timestamper->getPort()->getLocalAddr()]. - work_queue.init(0); - timestamperContextMap.map - [*timestamper->getPort()->getLocalAddr()]. - timestamper = timestamper; - ret = true; - } - ReleaseSRWLockExclusive(×tamperContextMap.lock); - - return ret; -} - -bool IntelWirelessAdapter::deregisterTimestamper -( WindowsWirelessTimestamper *timestamper ) -{ - bool ret; - - TimestamperContextMap::iterator iter; - AcquireSRWLockExclusive(×tamperContextMap.lock); - // Find timestamper - iter = timestamperContextMap.map.find - ( *timestamper->getPort()->getLocalAddr( )); - if( iter != timestamperContextMap.map.end( )) - { - // Shutdown work queue - iter->second.work_queue.stop(); - // Remove timestamper from list - timestamperContextMap.map.erase(iter); - ret = true; - } - ReleaseSRWLockExclusive(×tamperContextMap.lock); - - return ret; -} - -uint64_t IntelWirelessAdapter::calc_rollover( uint64_t gp2 ) -{ - gp2 = gp2 & 0xFFFFFFFF; - uint64_t l_gp2_ext; - - if (gp2_last == ULLONG_MAX) - { - gp2_last = gp2; - - return gp2; - } - - if (gp2 < GP2_ROLLOVER/4 && gp2_last > (GP2_ROLLOVER*3)/4) - ++gp2_ext; - - l_gp2_ext = gp2_ext; - if( gp2_last < GP2_ROLLOVER / 4 && gp2 >(GP2_ROLLOVER * 3) / 4 ) - --l_gp2_ext; - else - gp2_last = gp2; - - return gp2 + ( l_gp2_ext * GP2_ROLLOVER ); -} diff --git a/daemons/gptp/windows/daemon_cl/intel_wireless.hpp b/daemons/gptp/windows/daemon_cl/intel_wireless.hpp deleted file mode 100644 index bad97d71..00000000 --- a/daemons/gptp/windows/daemon_cl/intel_wireless.hpp +++ /dev/null @@ -1,187 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2015, 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 INTEL_WIRELESS_HPP -#define INTEL_WIRELESS_HPP - -#include <windows_hal.hpp> -#include <Windows.h> -#include <stdint.h> - -#define INTEL_MAC_ADDR_LENGTH 6 -#define INTEL_MAX_ADAPTERS 20 -#define CORRELATEDTIME_TRANSACTION_TIMEOUT 110/*ms*/ - -enum _WIRELESS_EVENT_TYPE; - -typedef struct INTEL_EVENT -{ - BYTE BtMacAddress[INTEL_MAC_ADDR_LENGTH + 1]; - ///< Source of event (MAC address) - _WIRELESS_EVENT_TYPE eType; ///< Event type - HRESULT hErrCode; ///< Error code - DWORD dwSize; - BYTE* data; -} INTEL_EVENT, *PINTEL_EVENT; - -typedef void(*INTEL_EVENT_CALLBACK) ( INTEL_EVENT iEvent, void *pContext ); - -typedef struct INTEL_CALLBACK -{ - INTEL_EVENT_CALLBACK fnIntelCallback; - void *pContext; - -} INTEL_CALLBACK, *PINTEL_CALLBACK; - -/// Adapter handle -typedef DWORD HADAPTER; - -//intel Header structure -typedef struct _INTEL_WIFI_HEADER -{ - DWORD dwStructVersion; - //Structure version for which this header is created - DWORD dwSize; - //size of the structure for which this header is created - DWORD dwFlags; //For future use - DWORD dwReserved; //For future use -} INTEL_WIFI_HEADER, *PINTEL_WIFI_HEADER; - -typedef enum INTEL_ADAPTER_TYPE -{ - eStone, // Stone Peak - without BT Support - eStoneBT, // Stone Peak - with BT Support - eSnowfield // Snowfield Peak -} INTEL_ADAPTER_TYPE; - -#define INTEL_ADAPTER_NAME_SIZE 64 -#define INTEL_ADAPTER_DESCRIPTION_SIZE 64 -#define INTEL_ADAPTER_CLSGUID_SIZE 64 -#define INTEL_REGPATH_SIZE 512 - -#define INTEL_STRUCT_VER_LATEST 156 - -typedef enum INTEL_ADAPTER_PROTOCOL -{ - eUnknownProtocol, ///< Unknown adapter. - e802_11, ///< WiFi -} INTEL_ADAPTER_PROTOCOL; - -typedef struct INTEL_ADAPTER_LIST_ENTRY -{ - HADAPTER hAdapter; - ///< Adapter handle - UCHAR btMACAddress[INTEL_MAC_ADDR_LENGTH]; - ///< Adapter MAC address - CHAR szAdapterName[INTEL_ADAPTER_NAME_SIZE]; - ///< Adapter OS CLSGUID - CHAR szAdapterDescription[INTEL_ADAPTER_DESCRIPTION_SIZE]; - ///< Display name - CHAR szAdapterClsguid[INTEL_ADAPTER_CLSGUID_SIZE]; - ///< Muroc CLSGUID - CHAR szRegistryPath[INTEL_REGPATH_SIZE]; - ///< Adapter registry root - CHAR szPnPId[INTEL_REGPATH_SIZE]; ///< Plug-and-Play ID - BOOL bEnabled; ///< enabled in driver - INTEL_ADAPTER_TYPE eAdapterType; ///< Adapter type - INTEL_ADAPTER_PROTOCOL eAdapterProtocol; ///< Adapter type -} INTEL_ADAPTER_LIST_ENTRY, *PINTEL_ADAPTER_LIST_ENTRY; - -typedef struct INTEL_ADAPTER_LIST -{ - int count; ///< Number of entries - INTEL_ADAPTER_LIST_ENTRY adapter[INTEL_MAX_ADAPTERS]; - ///< Array of adapter entries -} INTEL_ADAPTER_LIST, *PINTEL_ADAPTER_LIST; - - -typedef HRESULT ( APIENTRY *GetAdapterList_t ) - ( PINTEL_ADAPTER_LIST* ppAdapterList ); -typedef HRESULT ( APIENTRY *WifiCmdTimingMeasurementRequest_t ) - ( HADAPTER, PINTEL_WIFI_HEADER, void * ); -typedef HRESULT ( APIENTRY *WifiCmdTimingPtmWa_t ) - (HADAPTER, PINTEL_WIFI_HEADER, void *); -typedef HRESULT ( APIENTRY *RegisterIntelCallback_t ) ( PINTEL_CALLBACK ); -typedef HRESULT ( APIENTRY *DeregisterIntelCallback_t ) - ( INTEL_EVENT_CALLBACK ); - -extern GetAdapterList_t GetAdapterList; -extern WifiCmdTimingMeasurementRequest_t WifiCmdTimingMeasurementRequest; -extern WifiCmdTimingPtmWa_t WifiCmdTimingPtmWa; -extern RegisterIntelCallback_t RegisterIntelCallback; -extern DeregisterIntelCallback_t DeregisterIntelCallback; - -typedef struct _TIMINGMSMT_REQUEST *tm_request_t; -typedef struct WirelessTimestamperCallbackArg -*WirelessTimestamperCallbackArg_t; -typedef void( *WirelessTimestamperCallback_t ) -( WirelessTimestamperCallbackArg_t arg ); - -class IntelWirelessAdapter : public WindowsWirelessAdapter -{ -private: - HADAPTER hAdapter; - - // Get correlated time operation may timeout - // Use condition wait to manage this - SRWLOCK ct_lock; - CONDITION_VARIABLE ct_cond; - bool ct_done; - int ct_miss; - - uint64_t gp2_last; - unsigned gp2_ext; - -public: - bool initialize( void ); - void shutdown( void ); - bool refreshCrossTimestamp(); - bool initiateTimingRequest( TIMINGMSMT_REQUEST *tm_request ); - bool attachAdapter( uint8_t *mac_addr ); - bool registerTimestamper( WindowsWirelessTimestamper *timestamper ); - bool deregisterTimestamper( WindowsWirelessTimestamper *timestamper ); - IntelWirelessAdapter(); - - uint64_t calc_rollover( uint64_t gp2 ); - - friend void IntelWirelessTimestamperEventHandler - ( INTEL_EVENT iEvent, void *pContext ); -}; - -inline IntelWirelessAdapter::IntelWirelessAdapter() -{ - gp2_ext = 0; - gp2_last = ULLONG_MAX; -} - -#endif diff --git a/daemons/gptp/windows/daemon_cl/packet.cpp b/daemons/gptp/windows/daemon_cl/packet.cpp deleted file mode 100644 index 4158619a..00000000 --- a/daemons/gptp/windows/daemon_cl/packet.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/****************************************************************************** - - 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 "packet.hpp" -#include "platform.hpp" - -#include <pcap.h> -#include "iphlpapi.h" - -#define MAX_FRAME_SIZE 96 - -#define WINPCAP_INTERFACENAMEPREFIX "rpcap://\\Device\\NPF_" -#define WINPCAP_INTERFACENAMEPREFIX_LENGTH 20 -#define WINPCAP_INTERFACENAMESUFFIX_LENGTH 38 -#define WINPCAP_INTERFACENAME_LENGTH WINPCAP_INTERFACENAMEPREFIX_LENGTH+WINPCAP_INTERFACENAMESUFFIX_LENGTH - -struct packet_handle { - pcap_t *iface; - char errbuf[PCAP_ERRBUF_SIZE]; - packet_addr_t iface_addr; - HANDLE capture_lock; - uint16_t ethertype; - struct bpf_program filter; -}; - - -packet_error_t mallocPacketHandle( struct packet_handle **phandle ) { - packet_error_t ret = PACKET_NO_ERROR; - - packet_handle *handle = (struct packet_handle *) malloc((size_t) sizeof( *handle )); - if( handle == NULL ) { - ret = PACKET_NOMEMORY_ERROR; - goto fnexit; - } - *phandle = handle; - - if(( handle->capture_lock = CreateMutex( NULL, FALSE, NULL )) == NULL ) { - ret = PACKET_CREATEMUTEX_ERROR; - goto fnexit; - } - handle->iface = NULL; - -fnexit: - return ret; -} - -void freePacketHandle( struct packet_handle *handle ) { - CloseHandle( handle->capture_lock ); - free((void *) handle ); -} - -packet_error_t openInterfaceByAddr( struct packet_handle *handle, packet_addr_t *addr, int timeout ) { - packet_error_t ret = PACKET_NO_ERROR; - char name[WINPCAP_INTERFACENAME_LENGTH+1] = "\0"; - - PIP_ADAPTER_ADDRESSES pAdapterAddress; - IP_ADAPTER_ADDRESSES AdapterAddress[32]; // Allocate information for up to 32 NICs - DWORD dwBufLen = sizeof(AdapterAddress); // Save memory size of buffer - - DWORD dwStatus = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, AdapterAddress, &dwBufLen); - - if( dwStatus != ERROR_SUCCESS ) { - ret = PACKET_IFLOOKUP_ERROR; - goto fnexit; - } - - for( pAdapterAddress = AdapterAddress; pAdapterAddress != NULL; pAdapterAddress = pAdapterAddress->Next ) { - if( pAdapterAddress->PhysicalAddressLength == ETHER_ADDR_OCTETS && - memcmp( pAdapterAddress->PhysicalAddress, addr->addr, ETHER_ADDR_OCTETS ) == 0 ) { - break; - } - } - - if( pAdapterAddress != NULL ) { - strcpy_s( name, WINPCAP_INTERFACENAMEPREFIX ); - strncpy_s( name+WINPCAP_INTERFACENAMEPREFIX_LENGTH, WINPCAP_INTERFACENAMESUFFIX_LENGTH+1, pAdapterAddress->AdapterName, WINPCAP_INTERFACENAMESUFFIX_LENGTH ); - printf( "Opening: %s\n", name ); - handle->iface = pcap_open( name, MAX_FRAME_SIZE, PCAP_OPENFLAG_MAX_RESPONSIVENESS | PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_NOCAPTURE_LOCAL, - timeout, NULL, handle->errbuf ); - if( handle->iface == NULL ) { - ret = PACKET_IFLOOKUP_ERROR; - goto fnexit; - } - handle->iface_addr = *addr; - } else { - ret = PACKET_IFNOTFOUND_ERROR; - goto fnexit; - } - -fnexit: - return ret; -} - -void closeInterface( struct packet_handle *pfhandle ) { - if( pfhandle->iface != NULL ) pcap_close( pfhandle->iface ); -} - - -packet_error_t sendFrame( struct packet_handle *handle, packet_addr_t *addr, uint16_t ethertype, uint8_t *payload, size_t length ) { - packet_error_t ret = PACKET_NO_ERROR; - uint16_t ethertype_no = PLAT_htons( ethertype ); - uint8_t *payload_ptr = payload; - - if( length < PACKET_HDR_LENGTH ) { - ret = PACKET_BADBUFFER_ERROR; - } - - // Build Header - memcpy( payload_ptr, addr->addr, ETHER_ADDR_OCTETS ); payload_ptr+= ETHER_ADDR_OCTETS; - memcpy( payload_ptr, handle->iface_addr.addr, ETHER_ADDR_OCTETS ); payload_ptr+= ETHER_ADDR_OCTETS; - memcpy( payload_ptr, ðertype_no, sizeof( ethertype_no )); - - if( pcap_sendpacket( handle->iface, payload, (int) length+PACKET_HDR_LENGTH ) != 0 ) { - ret = PACKET_XMIT_ERROR; - goto fnexit; - } - -fnexit: - return ret; -} - -packet_error_t packetBind( struct packet_handle *handle, uint16_t ethertype ) { - packet_error_t ret = PACKET_NO_ERROR; - char filter_expression[32] = "ether proto 0x"; - - sprintf_s( filter_expression+strlen(filter_expression), 31-strlen(filter_expression), "%hx", ethertype ); - if( pcap_compile( handle->iface, &handle->filter, filter_expression, 1, 0 ) == -1 ) { - ret = PACKET_BIND_ERROR; - goto fnexit; - } - if( pcap_setfilter( handle->iface, &handle->filter ) == -1 ) { - ret = PACKET_BIND_ERROR; - goto fnexit; - } - - handle->ethertype = ethertype; - -fnexit: - return ret; -} - -// Call to recvFrame must be thread-safe. However call to pcap_next_ex() isn't because of somewhat undefined memory management semantics. -// Wrap call to pcap library with mutex -packet_error_t recvFrame( struct packet_handle *handle, packet_addr_t *addr, uint8_t *payload, size_t &length ) { - packet_error_t ret = PACKET_NO_ERROR; - struct pcap_pkthdr *hdr_r; - u_char *data; - - int pcap_result; - DWORD wait_result; - - wait_result = WaitForSingleObject( handle->capture_lock, 1000 ); - if( wait_result != WAIT_OBJECT_0 ) { - ret = PACKET_GETMUTEX_ERROR; - goto fnexit; - } - - pcap_result = pcap_next_ex( handle->iface, &hdr_r, (const u_char **) &data ); - if( pcap_result == 0 ) { - ret = PACKET_RECVTIMEOUT_ERROR; - } else if( pcap_result < 0 ) { - ret = PACKET_RECVFAILED_ERROR; - } else { - length = hdr_r->len-PACKET_HDR_LENGTH >= length ? length : hdr_r->len-PACKET_HDR_LENGTH; - memcpy( payload, data+PACKET_HDR_LENGTH, length ); - memcpy( addr->addr, data+ETHER_ADDR_OCTETS, ETHER_ADDR_OCTETS ); - } - - if( !ReleaseMutex( handle->capture_lock )) { - ret = PACKET_RLSMUTEX_ERROR; - goto fnexit; - } - -fnexit: - return ret; -} diff --git a/daemons/gptp/windows/daemon_cl/packet.hpp b/daemons/gptp/windows/daemon_cl/packet.hpp deleted file mode 100644 index bc315d61..00000000 --- a/daemons/gptp/windows/daemon_cl/packet.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/****************************************************************************** - - 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 PACKET_H -#define PACKET_H - -#include "stdint.h" - -/**@file*/ - -#define ETHER_ADDR_OCTETS 6 /*!< Link layer number of octets */ -#define PACKET_HDR_LENGTH 14 /*!< Packet header length in bytes */ - -/** - * @brief Packet error enumeration. Possible values are: - * - PACKET_NO_ERROR; - * - PACKET_NOMEMORY_ERROR; - * - PACKET_BADBUFFER_ERROR; - * - PACKET_XMIT_ERROR; - * - PACKET_IFLOOKUP_ERROR; - * - PACKET_IFNOTFOUND_ERROR; - * - PACKET_CREATEMUTEX_ERROR; - * - PACKET_GETMUTEX_ERROR; - * - PACKET_RLSMUTEX_ERROR; - * - PACKET_RECVTIMEOUT_ERROR; - * - PACKET_RECVFAILED_ERROR; - * - PACKET_BIND_ERROR; - */ -typedef enum { - PACKET_NO_ERROR = 0, PACKET_NOMEMORY_ERROR, PACKET_BADBUFFER_ERROR, PACKET_XMIT_ERROR, PACKET_IFLOOKUP_ERROR, PACKET_IFNOTFOUND_ERROR, - PACKET_CREATEMUTEX_ERROR, PACKET_GETMUTEX_ERROR, PACKET_RLSMUTEX_ERROR, PACKET_RECVTIMEOUT_ERROR, PACKET_RECVFAILED_ERROR, - PACKET_BIND_ERROR -} packet_error_t; - -/** - * @brief type to ethernet address - */ -typedef struct { - uint8_t addr[ETHER_ADDR_OCTETS]; /*!< Link layer address*/ -} packet_addr_t; -/** - * @brief Type to packet handle - */ -typedef struct packet_handle * pfhandle_t; - -/** - * @brief Allocate memory for the packet handle - * @param pfhandle_r [inout] Packet handle type - * @return void - */ -packet_error_t mallocPacketHandle( pfhandle_t *pfhandle_r ); -/** - * @brief Close the packet handle - * @param pfhandle [in] Packet handler - * @return void - */ -void freePacketHandle( pfhandle_t pfhandle ); - -/** - * @brief Opens the interface by link layer address. Uses libpcap. - * @param pfhandle [in] Packet interface handler - * @param addr Link layer address - * @param timeout Timeout - * @return Type packet_error_t with the error code - */ -packet_error_t openInterfaceByAddr( pfhandle_t pfhandle, packet_addr_t *addr, int timeout ); -/** - * @brief Close the interface - * @param pfhandle [in] Packet interface handler - * @return void - */ -void closeInterface( pfhandle_t pfhandle ); -/** - * @brief Sends a frame through an interface using libpcap - * @param pfhandle Packet Inteface handler - * @param addr [in] Link layer address - * @param ethertype Ethertype - * @param payload [in] Data buffer - * @param length Data length - * @return packet_error_t error codes - */ -packet_error_t sendFrame( pfhandle_t pfhandle, packet_addr_t *addr, uint16_t ethertype, uint8_t *payload, size_t length ); -/** - * @brief Receives a frame - * @param pfhandle Packet interface handler - * @param addr Link layer address - * @param payload [out] Data buffer - * @param length [out] Data length - * @return packet_error_t error codes - */ -packet_error_t recvFrame( pfhandle_t pfhandle, packet_addr_t *addr, uint8_t *payload, size_t &length ); - -/** - * @brief Set filters for packet handler - * @param handle [in] packet interface handler - * @param ethertype Ethertype - * @return packet_error_t error codes - */ -packet_error_t packetBind( struct packet_handle *handle, uint16_t ethertype ); - -#endif /* PACKET_H */ diff --git a/daemons/gptp/windows/daemon_cl/platform.cpp b/daemons/gptp/windows/daemon_cl/platform.cpp deleted file mode 100644 index 0187170f..00000000 --- a/daemons/gptp/windows/daemon_cl/platform.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/****************************************************************************** - - 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 <Winsock2.h> -#include <stdint.h> -#include <time.h> - -errno_t PLAT_strncpy( char *dest, const char *src, rsize_t max ) { - return strncpy_s( dest, max+1, src, _TRUNCATE ); -} - -uint16_t PLAT_htons( uint16_t s ) { - return htons( s ); -} - -uint32_t PLAT_htonl( uint32_t l ) { - return htonl( l ); -} - -uint16_t PLAT_ntohs( uint16_t s ) { - return ntohs( s ); -} - -uint32_t PLAT_ntohl( uint32_t l ) { - return ntohl( l ); -} - -uint64_t PLAT_htonll(uint64_t x) -{ - return ( (htonl(1) == 1) ? x : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32) ); -} - -uint64_t PLAT_ntohll(uint64_t x) -{ - return( (ntohl(1) == 1) ? x : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32) ); -} - -errno_t PLAT_localtime(const time_t * inTime, struct tm * outTm) -{ - return localtime_s(outTm, inTime); -} diff --git a/daemons/gptp/windows/daemon_cl/platform.hpp b/daemons/gptp/windows/daemon_cl/platform.hpp deleted file mode 100644 index cdb514d8..00000000 --- a/daemons/gptp/windows/daemon_cl/platform.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/****************************************************************************** - - 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. - -******************************************************************************/ - -/**@file*/ - -#ifndef PLATFORM_HPP -#define PLATFORM_HPP - -#include <stdio.h> - -/** - * @brief Provides strncpy - */ -errno_t PLAT_strncpy( char *dest, const char *src, rsize_t max ); -/** - * @brief provides snprintf - */ -#define PLAT_snprintf(buffer,count,...) _snprintf_s(buffer,count,count,__VA_ARGS__); - -/** - * @brief Converts the unsigned short integer hostshort - * from host byte order to network byte order. - * @param s short host byte order - * @return short value in network order - */ -uint16_t PLAT_htons( uint16_t s ); - -/** - * @brief Converts the unsigned integer hostlong - * from host byte order to network byte order. - * @param l Host long byte order - * @return value in network byte order - */ -uint32_t PLAT_htonl( uint32_t l ); - -/** - * @brief Converts the unsigned short integer netshort - * from network byte order to host byte order. - * @param s Network order short integer - * @return host order value - */ -uint16_t PLAT_ntohs( uint16_t s ); - -/** - * @brief Converts the unsigned integer netlong - * from network byte order to host byte order. - * @param l Long value in network order - * @return Long value on host byte order - */ -uint32_t PLAT_ntohl( uint32_t l ); - -/** - * @brief Converts a 64-bit word from host to network order - * @param x Value to be converted - * @return Converted value - */ -uint64_t PLAT_htonll(uint64_t x); - -/** - * @brief Converts a 64 bit word from network to host order - * @param x Value to be converted - * @return Converted value - */ -uint64_t PLAT_ntohll(uint64_t x); - -/** - * @brief Converts a time_t structure into a tm structure - * @param[in] inTime The time_t to be converted - * @param[out] outTm The tm to store the converted value in - * @return An error code - */ -errno_t PLAT_localtime(const time_t * inTime, struct tm * outTm); - -#endif diff --git a/daemons/gptp/windows/daemon_cl/stdafx.cpp b/daemons/gptp/windows/daemon_cl/stdafx.cpp deleted file mode 100644 index ba468098..00000000 --- a/daemons/gptp/windows/daemon_cl/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// daemon_cl.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/daemons/gptp/windows/daemon_cl/stdafx.h b/daemons/gptp/windows/daemon_cl/stdafx.h deleted file mode 100644 index b005a839..00000000 --- a/daemons/gptp/windows/daemon_cl/stdafx.h +++ /dev/null @@ -1,15 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#include <stdio.h> -#include <tchar.h> - - - -// TODO: reference additional headers your program requires here diff --git a/daemons/gptp/windows/daemon_cl/targetver.h b/daemons/gptp/windows/daemon_cl/targetver.h deleted file mode 100644 index 87c0086d..00000000 --- a/daemons/gptp/windows/daemon_cl/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include <SDKDDKVer.h> diff --git a/daemons/gptp/windows/daemon_cl/tsc.hpp b/daemons/gptp/windows/daemon_cl/tsc.hpp deleted file mode 100644 index 425205d3..00000000 --- a/daemons/gptp/windows/daemon_cl/tsc.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/****************************************************************************** - - 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. - -******************************************************************************/ - -/**@file*/ - -#ifndef TSC_HPP -#define TSC_HPP - -#include <intrin.h> -#include <stdint.h> - -/** - * @brief Gets the processor timestamp - * @return processor timestamp - */ -inline unsigned __int64 PLAT_rdtsc() -{ - return __rdtsc(); -} - -#define CLOCK_INFO_CPUID_LEAF (0x15) -#define SYSTEM_CLOCK_24MHZ (24000000) -#define MAX_MODEL_LIST_LEN (2) - -typedef struct -{ - short model_list[MAX_MODEL_LIST_LEN+1]; // Terminate model list with -1 - uint32_t clock_rate; // clock_rate of 0 is invalid -} -ModelNumberSystemClockRateMapping; - -static ModelNumberSystemClockRateMapping ModelNumberSystemClockRateMap[] = -{ - {{ 0x5E, 0x4E, -1 }, SYSTEM_CLOCK_24MHZ }, - {{ -1 }, 0 }, -}; - -/** -* @brief Gets the system clock frequency using CPU model number -* @param model_query model number to look up -* @return System frequency, or 0 on error -*/ -inline uint32_t FindFrequencyByModel(uint8_t model_query) { - ModelNumberSystemClockRateMapping *map = ModelNumberSystemClockRateMap; - uint32_t ret = 0; - - while (map->clock_rate != 0) - { - short *model = map->model_list; - - while (*model != -1) - { - if (*model == model_query) { - ret = map->clock_rate; - break; - } - ++model; - } - ++map; - } - - return ret; -} - - -/** - * @brief Gets the TSC frequnecy - * @param builtin whether device is connected to the Intel bus (not PCIE) - * @return TSC frequency, or 0 on error - */ -inline uint64_t getTSCFrequency( bool builtin ) { - int max_cpuid_level; - int tmp[4]; - BOOL is_windows_10; - LARGE_INTEGER freq; - - // Find the max cpuid level, and if possible find clock info - __cpuid(tmp, 0); - max_cpuid_level = tmp[0]; - if (max_cpuid_level >= CLOCK_INFO_CPUID_LEAF) - __cpuid(tmp, CLOCK_INFO_CPUID_LEAF); - - // Determine if the OS is Windows 10 or later. - { - OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; - DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); - osvi.dwMajorVersion = 10; - - // NOTE: VerifyVersionInfo returns false when called by applications that do not have a compatibility manifest for Windows 10, - // even when the current operating system version is Windows 10. - is_windows_10 = VerifyVersionInfoW(&osvi, VER_MAJORVERSION, dwlConditionMask) != FALSE; - } - - // For pre-Win10 on 6th Generation or greater Intel CPUs the raw hardware - // clock will be returned, *else* use QPC for everything else - // - // EAX (tmp[0]) must be >= 1, See Intel SDM 17.15.4 "Invariant Time-keeping" - if (!is_windows_10 && - max_cpuid_level >= CLOCK_INFO_CPUID_LEAF && - tmp[0] >= 1 && - builtin ) - { - SYSTEM_INFO info; - - GetSystemInfo(&info); - - // Look at processor model (upper byte of revision) number to determine clock rate - return FindFrequencyByModel(info.wProcessorRevision >> 8); - } - - if (QueryPerformanceFrequency(&freq)) - return freq.QuadPart; - - return 0; -} - -#endif/*TSC_HPP*/ diff --git a/daemons/gptp/windows/daemon_cl/windows_hal.cpp b/daemons/gptp/windows/daemon_cl/windows_hal.cpp deleted file mode 100644 index 3d034e39..00000000 --- a/daemons/gptp/windows/daemon_cl/windows_hal.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/****************************************************************************** - - 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 <WinSock2.h> -#include <iphlpapi.h> -#include <windows_hal.hpp> -#include <IPCListener.hpp> -#include <PeerList.hpp> -#include <gptp_log.hpp> - -DWORD WINAPI OSThreadCallback( LPVOID input ) { - OSThreadArg *arg = (OSThreadArg*) input; - arg->ret = arg->func( arg->arg ); - return 0; -} - -VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore ) { - WindowsTimerQueueHandlerArg *arg = (WindowsTimerQueueHandlerArg *) arg_in; - size_t diff; - - // Remove myself from unexpired timer queue - AcquireSRWLockExclusive( &arg->timer_queue->lock ); - diff = arg->timer_queue->arg_list.size(); - arg->timer_queue->arg_list.remove( arg ); - diff -= arg->timer_queue->arg_list.size(); - ReleaseSRWLockExclusive( &arg->timer_queue->lock ); - - // If the remove was unsuccessful bail because we were - // stepped on by 'cancelEvent' - if( diff == 0 ) return; - - arg->func( arg->inner_arg ); - - // Add myself to the expired timer queue - AcquireSRWLockExclusive( &arg->queue->retiredTimersLock ); - arg->queue->retiredTimers.push_front( arg ); - ReleaseSRWLockExclusive( &arg->queue->retiredTimersLock ); -} - -inline uint64_t scale64(uint64_t i, uint32_t m, uint32_t n) -{ - uint64_t tmp, res, rem; - - rem = i % n; - i /= n; - - res = i * m; - tmp = rem * m; - - tmp /= n; - - return res + tmp; -} - -void WirelessTimestamperCallback( LPVOID arg ) -{ - WirelessTimestamperCallbackArg *larg = - (WirelessTimestamperCallbackArg *)arg; - WindowsWirelessTimestamper *timestamper = - dynamic_cast<WindowsWirelessTimestamper *> (larg->timestamper); - WirelessDialog tmp1, tmp2; - LinkLayerAddress *peer_addr = NULL; - - if (timestamper == NULL) - { - GPTP_LOG_ERROR( "Wrong timestamper type: %p", - larg->timestamper ); - return; - } - - switch( larg->iEvent_type ) - { - default: - case TIMINGMSMT_CONFIRM_EVENT: - tmp1.action_devclk = larg->event_data.confirm.T1; - tmp1.ack_devclk = larg->event_data.confirm.T4; - tmp1.dialog_token = (BYTE)larg->event_data.confirm.DialogToken; - GPTP_LOG_VERBOSE - ( "Got confirm, %hhu(%llu,%llu)", tmp1.dialog_token, - tmp1.action_devclk, tmp1.ack_devclk ); - peer_addr = new LinkLayerAddress - ( larg->event_data.confirm.PeerMACAddress ); - larg->timestamper-> - timingMeasurementConfirmCB( *peer_addr, &tmp1 ); - - break; - - case TIMINGMSMT_EVENT: - tmp1/*prev*/.action_devclk = larg->event_data.indication. - indication.T1; - tmp1/*prev*/.ack_devclk = larg->event_data.indication. - indication.T4; - tmp1/*prev*/.dialog_token = (BYTE)larg->event_data.indication. - indication.FollowUpDialogToken; - tmp2/*curr*/.action_devclk = larg->event_data.indication. - indication.T2; - tmp2/*curr*/.ack_devclk = larg->event_data.indication. - indication.T3; - tmp2/*curr*/.dialog_token = (BYTE)larg->event_data.indication. - indication.DialogToken; - GPTP_LOG_VERBOSE - ("Got indication, %hhu(%llu,%llu) %hhu(%llu,%llu)", - tmp1.dialog_token, tmp1.action_devclk, - tmp1.ack_devclk, tmp2.dialog_token, - tmp2.action_devclk, tmp2.ack_devclk); - peer_addr = new LinkLayerAddress(larg->event_data.indication. - indication.PeerMACAddress); - - larg->timestamper->timeMeasurementIndicationCB - ( *peer_addr, &tmp2, &tmp1, - larg->event_data.indication. - indication.PtpSpec.fwup_data, - larg->event_data.indication. - indication.WiFiVSpecHdr.Length - (sizeof(PTP_SPEC) - - 1)); - - break; - - case TIMINGMSMT_CORRELATEDTIME_EVENT: - timestamper->system_counter = - scale64( larg->event_data.ptm_wa.TSC, NS_PER_SECOND, - (uint32_t)timestamper->tsc_hz.QuadPart ); - timestamper->system_time.set64(timestamper->system_counter); - // Scale from TM timescale to nanoseconds - larg->event_data.ptm_wa.LocalClk *= 10; - timestamper->device_time.set64 - (larg->event_data.ptm_wa.LocalClk*10); - - break; - } - - delete peer_addr; -} - -net_result WindowsWirelessTimestamper::_requestTimingMeasurement -(TIMINGMSMT_REQUEST *timingmsmt_req) -{ - net_result ret = net_succeed; - - if (!adapter->initiateTimingRequest(timingmsmt_req)) { - GPTP_LOG_ERROR("Failed to send timing measurement request\n"); - ret = net_fatal; - } - - return ret; -} - -bool WindowsWirelessTimestamper::HWTimestamper_gettime -( Timestamp *system_time, - Timestamp * device_time, - uint32_t * local_clock, - uint32_t * nominal_clock_rate ) const -{ - bool refreshed = adapter->refreshCrossTimestamp(); - if (refreshed) - { - // We have a fresh cross-timestamp just use it - *system_time = this->system_time; - *device_time = this->device_time; - } else - { - // We weren't able to get a fresh timestamp, - // extrapolate from the last - LARGE_INTEGER tsc_now; - QueryPerformanceCounter(&tsc_now); - unsigned device_delta = (unsigned) - (((long double) (tsc_now.QuadPart - system_counter)) / - (((long double)tsc_hz.QuadPart) / 1000000000)); - device_delta = (unsigned)(device_delta*getPort()-> - getLocalSystemFreqOffset()); - system_time->set64((uint64_t) - (((long double)tsc_now.QuadPart) / - ((long double)tsc_hz.QuadPart / - 1000000000))); - device_time->set64(device_delta); - *device_time = *device_time + this->device_time; - } - - return true; -} - -bool WindowsWirelessTimestamper::HWTimestamper_init -(InterfaceLabel *iface_label, OSNetworkInterface *iface) -{ - uint8_t mac_addr_local[ETHER_ADDR_OCTETS]; - - if (!initialized) { - if (!adapter->initialize()) return false; - if (getPort()->getLocalAddr() == NULL) - return false; - - getPort()->getLocalAddr()->toOctetArray(mac_addr_local); - if (!adapter->attachAdapter(mac_addr_local)) { - return false; - } - - tsc_hz.QuadPart = getTSCFrequency(false); - if (tsc_hz.QuadPart == 0) { - return false; - } - - if (!adapter->registerTimestamper(this)) - return false; - } - - initialized = true; - return true; -} - -WindowsWirelessTimestamper::~WindowsWirelessTimestamper() { - if (adapter->deregisterTimestamper(this)) - adapter->shutdown(); - else - GPTP_LOG_INFO("Failed to shutdown time sync on adapter"); -} - -bool WindowsEtherTimestamper::HWTimestamper_init( InterfaceLabel *iface_label, OSNetworkInterface *net_iface ) { - char network_card_id[64]; - LinkLayerAddress *addr = dynamic_cast<LinkLayerAddress *>(iface_label); - if( addr == NULL ) return false; - PIP_ADAPTER_INFO pAdapterInfo; - IP_ADAPTER_INFO AdapterInfo[32]; // Allocate information for up to 32 NICs - DWORD dwBufLen = sizeof(AdapterInfo); // Save memory size of buffer - - DWORD dwStatus = GetAdaptersInfo( AdapterInfo, &dwBufLen ); - if( dwStatus != ERROR_SUCCESS ) return false; - - for( pAdapterInfo = AdapterInfo; pAdapterInfo != NULL; pAdapterInfo = pAdapterInfo->Next ) { - if( pAdapterInfo->AddressLength == ETHER_ADDR_OCTETS && *addr == LinkLayerAddress( pAdapterInfo->Address )) { - break; - } - } - - if( pAdapterInfo == NULL ) return false; - - DeviceClockRateMapping *rate_map = DeviceClockRateMap; - while (rate_map->device_desc != NULL) - { - if (strstr(pAdapterInfo->Description, rate_map->device_desc) != NULL) - break; - ++rate_map; - } - if (rate_map->device_desc != NULL) { - netclock_hz.QuadPart = rate_map->clock_rate; - } - else { - GPTP_LOG_ERROR("Unable to determine clock rate for interface %s", pAdapterInfo->Description); - return false; - } - - GPTP_LOG_INFO( "Adapter UID: %s\n", pAdapterInfo->AdapterName ); - PLAT_strncpy( network_card_id, NETWORK_CARD_ID_PREFIX, 63 ); - PLAT_strncpy( network_card_id+strlen(network_card_id), pAdapterInfo->AdapterName, 63-strlen(network_card_id) ); - - miniport = CreateFile( network_card_id, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, NULL ); - if( miniport == INVALID_HANDLE_VALUE ) return false; - - tsc_hz.QuadPart = getTSCFrequency( true ); - if( tsc_hz.QuadPart == 0 ) { - return false; - } - - return true; -} - -bool WindowsNamedPipeIPC::init(OS_IPC_ARG *arg) { - IPCListener *ipclistener; - IPCSharedData ipcdata = { &peerList_, &lOffset_ }; - - ipclistener = new IPCListener(); - // Start IPC listen thread - if (!ipclistener->start(ipcdata)) { - GPTP_LOG_ERROR("Starting IPC listener thread failed"); - } - else { - GPTP_LOG_INFO("Starting IPC listener thread succeeded"); - } - - return true; -} - -bool WindowsNamedPipeIPC::update( - int64_t ml_phoffset, - int64_t ls_phoffset, - FrequencyRatio ml_freqoffset, - FrequencyRatio ls_freq_offset, - uint64_t local_time, - uint32_t sync_count, - uint32_t pdelay_count, - PortState port_state, - bool asCapable ) -{ - lOffset_.get(); - lOffset_.local_time = local_time; - lOffset_.ml_freqoffset = ml_freqoffset; - lOffset_.ml_phoffset = ml_phoffset; - lOffset_.ls_freqoffset = ls_freq_offset; - lOffset_.ls_phoffset = ls_phoffset; - - if (!lOffset_.isReady()) lOffset_.setReady(true); - lOffset_.put(); - return true; -} - -bool WindowsNamedPipeIPC::update_grandmaster( - uint8_t gptp_grandmaster_id[], - uint8_t gptp_domain_number ) -{ - lOffset_.get(); - memcpy(lOffset_.gptp_grandmaster_id, gptp_grandmaster_id, PTP_CLOCK_IDENTITY_LENGTH); - lOffset_.gptp_domain_number = gptp_domain_number; - - if (!lOffset_.isReady()) lOffset_.setReady(true); - lOffset_.put(); - return true; -} - -bool WindowsNamedPipeIPC::update_network_interface( - uint8_t clock_identity[], - uint8_t priority1, - uint8_t clock_class, - int16_t offset_scaled_log_variance, - uint8_t clock_accuracy, - uint8_t priority2, - uint8_t domain_number, - int8_t log_sync_interval, - int8_t log_announce_interval, - int8_t log_pdelay_interval, - uint16_t port_number ) -{ - lOffset_.get(); - memcpy(lOffset_.clock_identity, clock_identity, PTP_CLOCK_IDENTITY_LENGTH); - lOffset_.priority1 = priority1; - lOffset_.clock_class = clock_class; - lOffset_.offset_scaled_log_variance = offset_scaled_log_variance; - lOffset_.clock_accuracy = clock_accuracy; - lOffset_.priority2 = priority2; - lOffset_.domain_number = domain_number; - lOffset_.log_sync_interval = log_sync_interval; - lOffset_.log_announce_interval = log_announce_interval; - lOffset_.log_pdelay_interval = log_pdelay_interval; - lOffset_.port_number = port_number; - - if (!lOffset_.isReady()) lOffset_.setReady(true); - lOffset_.put(); - return true; -} - - -void WindowsPCAPNetworkInterface::watchNetLink( CommonPort *pPort) -{ - /* ToDo add link up/down detection, Google MIB_IPADDR_DISCONNECTED */ -} diff --git a/daemons/gptp/windows/daemon_cl/windows_hal.hpp b/daemons/gptp/windows/daemon_cl/windows_hal.hpp deleted file mode 100644 index 5f1a6f61..00000000 --- a/daemons/gptp/windows/daemon_cl/windows_hal.hpp +++ /dev/null @@ -1,974 +0,0 @@ -/****************************************************************************** - - 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 WINDOWS_HAL_HPP -#define WINDOWS_HAL_HPP - -/**@file*/ - -#include <IPCListener.hpp> -#include "avbts_osnet.hpp" -#include "avbts_oslock.hpp" -#include "avbts_oscondition.hpp" -#include "avbts_ostimerq.hpp" -#include "avbts_ostimer.hpp" -#include "avbts_osthread.hpp" -#include "packet.hpp" -#include "ieee1588.hpp" -#include "ether_tstamper.hpp" -#include "wireless_tstamper.hpp" -#include "iphlpapi.h" -#include "windows_ipc.hpp" -#include "tsc.hpp" - -#include "avbts_osipc.hpp" - -#include <ntddndis.h> - -#include <map> -#include <list> - -/** - * @brief WindowsPCAPNetworkInterface implements an interface to the network adapter - * through calls to the publicly available libraries known as PCap. - */ -class WindowsPCAPNetworkInterface : public OSNetworkInterface { - friend class WindowsPCAPNetworkInterfaceFactory; -private: - pfhandle_t handle; - LinkLayerAddress local_addr; -public: - /** - * @brief Sends a packet to a remote address - * @param addr [in] Destination link Layer address - * @param etherType [in] The EtherType of the message in host order - * @param payload [in] Data buffer - * @param length Size of buffer - * @param timestamp TRUE: Use timestamp, FALSE otherwise - * @return net_result structure - */ - virtual net_result send( LinkLayerAddress *addr, uint16_t etherType, uint8_t *payload, size_t length, bool timestamp) { - packet_addr_t dest; - addr->toOctetArray( dest.addr ); - if( sendFrame( handle, &dest, etherType, payload, length ) != PACKET_NO_ERROR ) return net_fatal; - return net_succeed; - } - /** - * @brief Receives a packet from a remote address - * @param addr [out] Remote link layer address - * @param payload [out] Data buffer - * @param length [out] Length of received data - * @param delay [in] Specifications for PHY input and output delays in nanoseconds - * @return net_result structure - */ - virtual net_result nrecv( LinkLayerAddress *addr, uint8_t *payload, size_t &length ) - { - packet_addr_t dest; - packet_error_t pferror = recvFrame( handle, &dest, payload, length ); - if( pferror != PACKET_NO_ERROR && pferror != PACKET_RECVTIMEOUT_ERROR ) return net_fatal; - if( pferror == PACKET_RECVTIMEOUT_ERROR ) return net_trfail; - *addr = LinkLayerAddress( dest.addr ); - return net_succeed; - } - /** - * @brief Gets the link layer address (MAC) of the network adapter - * @param addr [out] Link layer address - * @return void - */ - virtual void getLinkLayerAddress( LinkLayerAddress *addr ) { - *addr = local_addr; - } - - /** - * @brief Watch for netlink changes. - */ - virtual void watchNetLink( CommonPort *pPort ); - - /** - * @brief Gets the offset to the start of data in the Layer 2 Frame - * @return ::PACKET_HDR_LENGTH - */ - virtual unsigned getPayloadOffset() { - return PACKET_HDR_LENGTH; - } - /** - * @brief Destroys the network interface - */ - virtual ~WindowsPCAPNetworkInterface() { - closeInterface( handle ); - if( handle != NULL ) freePacketHandle( handle ); - } -protected: - /** - * @brief Default constructor - */ - WindowsPCAPNetworkInterface() { handle = NULL; }; -}; - -/** - * @brief WindowsPCAPNetworkInterface implements an interface to the network adapter - * through calls to the publicly available libraries known as PCap. - */ -class WindowsPCAPNetworkInterfaceFactory : public OSNetworkInterfaceFactory { -public: - /** - * @brief Create a network interface - * @param net_iface [in] Network interface - * @param label [in] Interface label - * @param timestamper [in] HWTimestamper instance - * @return TRUE success; FALSE error - */ - virtual bool createInterface( OSNetworkInterface **net_iface, InterfaceLabel *label, CommonTimestamper *timestamper ) { - WindowsPCAPNetworkInterface *net_iface_l = new WindowsPCAPNetworkInterface(); - LinkLayerAddress *addr = dynamic_cast<LinkLayerAddress *>(label); - if( addr == NULL ) goto error_nofree; - net_iface_l->local_addr = *addr; - packet_addr_t pfaddr; - addr->toOctetArray( pfaddr.addr ); - if( mallocPacketHandle( &net_iface_l->handle ) != PACKET_NO_ERROR ) goto error_nofree; - if( openInterfaceByAddr( net_iface_l->handle, &pfaddr, 1 ) != PACKET_NO_ERROR ) goto error_free_handle; - if( packetBind( net_iface_l->handle, PTP_ETHERTYPE ) != PACKET_NO_ERROR ) goto error_free_handle; - *net_iface = net_iface_l; - - return true; - -error_free_handle: -error_nofree: - delete net_iface_l; - - return false; - } -}; - -/** - * @brief Provides lock interface for windows - */ -class WindowsLock : public OSLock { - friend class WindowsLockFactory; -private: - OSLockType type; - DWORD thread_id; - HANDLE lock_c; - OSLockResult lock_l( DWORD timeout ) { - DWORD wait_result = WaitForSingleObject( lock_c, timeout ); - if( wait_result == WAIT_TIMEOUT ) return oslock_held; - else if( wait_result == WAIT_OBJECT_0 ) return oslock_ok; - else return oslock_fail; - - } - OSLockResult nonreentrant_lock_l( DWORD timeout ) { - OSLockResult result; - DWORD wait_result; - wait_result = WaitForSingleObject( lock_c, timeout ); - if( wait_result == WAIT_OBJECT_0 ) { - if( thread_id == GetCurrentThreadId() ) { - result = oslock_self; - ReleaseMutex( lock_c ); - } else { - result = oslock_ok; - thread_id = GetCurrentThreadId(); - } - } else if( wait_result == WAIT_TIMEOUT ) result = oslock_held; - else result = oslock_fail; - - return result; - } -protected: - /** - * @brief Default constructor - */ - WindowsLock() { - lock_c = NULL; - } - /** - * @brief Initializes lock interface - * @param type OSLockType - */ - bool initialize( OSLockType type ) { - lock_c = CreateMutex( NULL, false, NULL ); - if( lock_c == NULL ) return false; - this->type = type; - return true; - } - /** - * @brief Acquires lock - * @return OSLockResult type - */ - OSLockResult lock() { - if( type == oslock_recursive ) { - return lock_l( INFINITE ); - } - return nonreentrant_lock_l( INFINITE ); - } - /** - * @brief Tries to acquire lock - * @return OSLockResult type - */ - OSLockResult trylock() { - if( type == oslock_recursive ) { - return lock_l( 0 ); - } - return nonreentrant_lock_l( 0 ); - } - /** - * @brief Releases lock - * @return OSLockResult type - */ - OSLockResult unlock() { - ReleaseMutex( lock_c ); - return oslock_ok; - } -}; - -/** - * @brief Provides the LockFactory abstraction - */ -class WindowsLockFactory : public OSLockFactory { -public: - /** - * @brief Creates a new lock mechanism - * @param type Lock type - OSLockType - * @return New lock on OSLock format - */ - OSLock *createLock( OSLockType type ) const { - WindowsLock *lock = new WindowsLock(); - if( !lock->initialize( type )) { - delete lock; - lock = NULL; - } - return lock; - } -}; - -/** - * @brief Provides a OSCondition interface for windows - */ -class WindowsCondition : public OSCondition { - friend class WindowsConditionFactory; -private: - SRWLOCK lock; - CONDITION_VARIABLE condition; -protected: - /** - * @brief Initializes the locks and condition variables - */ - bool initialize() { - InitializeSRWLock( &lock ); - InitializeConditionVariable( &condition ); - return true; - } -public: - /** - * @brief Acquire a new lock and increment the condition counter - * @return true - */ - bool wait_prelock() { - AcquireSRWLockExclusive( &lock ); - up(); - return true; - } - /** - * @brief Waits for a condition and decrements the condition - * counter when the condition is met. - * @return TRUE if the condition is met and the lock is released. FALSE otherwise. - */ - bool wait() { - BOOL result = SleepConditionVariableSRW( &condition, &lock, INFINITE, 0 ); - bool ret = false; - if( result == TRUE ) { - down(); - ReleaseSRWLockExclusive( &lock ); - ret = true; - } - return ret; - } - /** - * @brief Sends a signal to unblock other threads - * @return true - */ - bool signal() { - AcquireSRWLockExclusive( &lock ); - if( waiting() ) WakeAllConditionVariable( &condition ); - ReleaseSRWLockExclusive( &lock ); - return true; - } -}; - -/** - * @brief Condition factory for windows - */ -class WindowsConditionFactory : public OSConditionFactory { -public: - OSCondition *createCondition() const { - WindowsCondition *result = new WindowsCondition(); - return result->initialize() ? result : NULL; - } -}; - -class WindowsTimerQueue; - -struct TimerQueue_t; - -/** - * @brief Timer queue handler arguments structure - * @todo Needs more details from original developer - */ -struct WindowsTimerQueueHandlerArg { - HANDLE timer_handle; /*!< timer handler */ - HANDLE queue_handle; /*!< queue handler */ - event_descriptor_t *inner_arg; /*!< Event inner arguments */ - ostimerq_handler func; /*!< Timer queue callback*/ - int type; /*!< Type of timer */ - bool rm; /*!< Flag that signalizes the argument deletion*/ - WindowsTimerQueue *queue; /*!< Windows Timer queue */ - TimerQueue_t *timer_queue; /*!< Timer queue*/ -}; - -/** - * @brief Creates a list of type WindowsTimerQueueHandlerArg - */ -typedef std::list<WindowsTimerQueueHandlerArg *> TimerArgList_t; -/** - * @brief Timer queue type - */ -struct TimerQueue_t { - TimerArgList_t arg_list; /*!< Argument list */ - HANDLE queue_handle; /*!< Handle to the timer queue */ - SRWLOCK lock; /*!< Lock type */ -}; - -/** - * @brief Windows Timer queue handler callback definition - */ -VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore ); - -/** - * @brief Creates a map for the timerQueue - */ -typedef std::map<int,TimerQueue_t> TimerQueueMap_t; - -/** - * @brief Windows timer queue interface - */ -class WindowsTimerQueue : public OSTimerQueue { - friend class WindowsTimerQueueFactory; - friend VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore ); -private: - TimerQueueMap_t timerQueueMap; - TimerArgList_t retiredTimers; - SRWLOCK retiredTimersLock; - void cleanupRetiredTimers() { - AcquireSRWLockExclusive( &retiredTimersLock ); - while( !retiredTimers.empty() ) { - WindowsTimerQueueHandlerArg *retired_arg = retiredTimers.front(); - retiredTimers.pop_front(); - ReleaseSRWLockExclusive( &retiredTimersLock ); - DeleteTimerQueueTimer( retired_arg->queue_handle, retired_arg->timer_handle, INVALID_HANDLE_VALUE ); - if( retired_arg->rm ) delete retired_arg->inner_arg; - delete retired_arg; - AcquireSRWLockExclusive( &retiredTimersLock ); - } - ReleaseSRWLockExclusive( &retiredTimersLock ); - - } -protected: - /** - * @brief Default constructor. Initializes timers lock - */ - WindowsTimerQueue() { - InitializeSRWLock( &retiredTimersLock ); - }; -public: - /** - * @brief Create a new event and add it to the timer queue - * @param micros Time in microsseconds - * @param type ::Event type - * @param func Callback function - * @param arg [in] Event arguments - * @param rm when true, allows elements to be deleted from the queue - * @param event [in] Pointer to the event to be created - * @return Always return true - */ - bool addEvent( unsigned long micros, int type, ostimerq_handler func, event_descriptor_t *arg, bool rm, unsigned *event ) { - WindowsTimerQueueHandlerArg *outer_arg = new WindowsTimerQueueHandlerArg(); - cleanupRetiredTimers(); - if( timerQueueMap.find(type) == timerQueueMap.end() ) { - timerQueueMap[type].queue_handle = CreateTimerQueue(); - InitializeSRWLock( &timerQueueMap[type].lock ); - } - outer_arg->queue_handle = timerQueueMap[type].queue_handle; - outer_arg->inner_arg = arg; - outer_arg->func = func; - outer_arg->queue = this; - outer_arg->type = type; - outer_arg->rm = rm; - outer_arg->timer_queue = &timerQueueMap[type]; - AcquireSRWLockExclusive( &timerQueueMap[type].lock ); - CreateTimerQueueTimer( &outer_arg->timer_handle, timerQueueMap[type].queue_handle, WindowsTimerQueueHandler, (void *) outer_arg, micros/1000, 0, 0 ); - timerQueueMap[type].arg_list.push_front(outer_arg); - ReleaseSRWLockExclusive( &timerQueueMap[type].lock ); - return true; - } - /** - * @brief Cancels an event from the queue - * @param type ::Event type - * @param event [in] Pointer to the event to be removed - * @return Always returns true. - */ - bool cancelEvent( int type, unsigned *event ) { - TimerQueueMap_t::iterator iter = timerQueueMap.find( type ); - if( iter == timerQueueMap.end() ) return false; - AcquireSRWLockExclusive( &timerQueueMap[type].lock ); - while( ! timerQueueMap[type].arg_list.empty() ) { - WindowsTimerQueueHandlerArg *del_arg = timerQueueMap[type].arg_list.front(); - timerQueueMap[type].arg_list.pop_front(); - ReleaseSRWLockExclusive( &timerQueueMap[type].lock ); - DeleteTimerQueueTimer( del_arg->queue_handle, del_arg->timer_handle, INVALID_HANDLE_VALUE ); - if( del_arg->rm ) delete del_arg->inner_arg; - delete del_arg; - AcquireSRWLockExclusive( &timerQueueMap[type].lock ); - } - ReleaseSRWLockExclusive( &timerQueueMap[type].lock ); - - return true; - } -}; - -/** - * @brief Windows callback for the timer queue handler - */ -VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore ); - -/** - * @brief Windows implementation of OSTimerQueueFactory - */ -class WindowsTimerQueueFactory : public OSTimerQueueFactory { -public: - /** - * @brief Creates a new timer queue - * @param clock [in] IEEE1588Clock type - * @return new timer queue - */ - virtual OSTimerQueue *createOSTimerQueue( IEEE1588Clock *clock ) { - WindowsTimerQueue *timerq = new WindowsTimerQueue(); - return timerq; - }; -}; - -/** - * @brief Windows implementation of OSTimer - */ -class WindowsTimer : public OSTimer { - friend class WindowsTimerFactory; -public: - /** - * @brief Sleep for an amount of time - * @param micros Time in microsseconds - * @return Time in microsseconds - */ - virtual unsigned long sleep( unsigned long micros ) { - Sleep( micros/1000 ); - return micros; - } -protected: - /** - * @brief Default constructor - */ - WindowsTimer() {}; -}; - -/** - * @brief Windows implementation of OSTimerFactory - */ -class WindowsTimerFactory : public OSTimerFactory { -public: - /** - * @brief Creates a new timer - * @return New windows OSTimer - */ - virtual OSTimer *createTimer() const { - return new WindowsTimer(); - } -}; - -/** - * @brief OSThread argument structure - */ -struct OSThreadArg { - OSThreadFunction func; /*!< Thread callback function */ - void *arg; /*!< Thread arguments */ - OSThreadExitCode ret; /*!< Return value */ -}; - -/** - * @brief Windows OSThread callback - */ -DWORD WINAPI OSThreadCallback( LPVOID input ); - -/** - * @brief Implements OSThread interface for windows - */ -class WindowsThread : public OSThread { - friend class WindowsThreadFactory; -private: - HANDLE thread_id; - OSThreadArg *arg_inner; -public: - /** - * @brief Starts a new thread - * @param function Function to be started as a new thread - * @param arg [in] Function's arguments - * @return TRUE if successfully started, FALSE otherwise. - */ - virtual bool start( OSThreadFunction function, void *arg ) { - arg_inner = new OSThreadArg(); - arg_inner->func = function; - arg_inner->arg = arg; - thread_id = CreateThread( NULL, 0, OSThreadCallback, arg_inner, 0, NULL ); - if( thread_id == NULL ) return false; - else return true; - } - /** - * @brief Joins a terminated thread - * @param exit_code [out] Thread's return code - * @return TRUE in case of success. FALSE otherwise. - */ - virtual bool join( OSThreadExitCode &exit_code ) { - if( WaitForSingleObject( thread_id, INFINITE ) != WAIT_OBJECT_0 ) return false; - exit_code = arg_inner->ret; - delete arg_inner; - return true; - } -protected: - /** - * @brief Default constructor - */ - WindowsThread() {}; -}; - -/** - * @brief Provides a windows implmementation of OSThreadFactory - */ -class WindowsThreadFactory : public OSThreadFactory { -public: - /** - * @brief Creates a new windows thread - * @return New thread of type OSThread - */ - OSThread *createThread() const { - return new WindowsThread(); - } -}; - -void WirelessTimestamperCallback(LPVOID arg); - -class WindowsWirelessAdapter; - -/** -* @brief Windows Wireless (802.11) HWTimestamper implementation -*/ -class WindowsWirelessTimestamper : public WirelessTimestamper -{ -private: - WindowsWirelessAdapter *adapter; - - uint64_t system_counter; - Timestamp system_time; - Timestamp device_time; - LARGE_INTEGER tsc_hz; - bool initialized; - -public: - WindowsWirelessTimestamper() - { - initialized = false; - } - - net_result _requestTimingMeasurement - ( TIMINGMSMT_REQUEST *timingmsmt_req ); - - bool HWTimestamper_gettime - ( Timestamp *system_time, Timestamp * device_time, - uint32_t * local_clock, uint32_t * nominal_clock_rate ) const; - - virtual bool HWTimestamper_init - ( InterfaceLabel *iface_label, OSNetworkInterface *iface ); - - /** - * @brief attach adapter to timestamper - * @param adapter [in] adapter to attach - */ - void setAdapter( WindowsWirelessAdapter *adapter ) - { - this->adapter = adapter; - } - - /** - * @brief get attached adapter - * @return attached adapter - */ - WindowsWirelessAdapter *getAdapter(void) - { - return adapter; - } - - ~WindowsWirelessTimestamper(); - - friend void WirelessTimestamperCallback( LPVOID arg ); -}; - -class WindowsWirelessAdapter -{ -public: - /** - * @brief initiate wireless TM request (completion is asynchronous) - * @param tm_request [in] pointer to TM request object - * @return true on success - */ - virtual bool initiateTimingRequest(TIMINGMSMT_REQUEST *tm_request) = 0; - - /** - * @brief attempt to refresh cross timestamp (extrapolate on failure) - * @return true on success - */ - virtual bool refreshCrossTimestamp() = 0; - - /** - * @brief register timestamper with adapter - * @param timestamper [in] timestamper object - * @return true on success - */ - virtual bool registerTimestamper - ( WindowsWirelessTimestamper *timestamper ) = 0; - - /** - * @brief deregister timestamper - * @param timestamper [in] timestamper object - * @return true on success - */ - virtual bool deregisterTimestamper - ( WindowsWirelessTimestamper *timestamper ) = 0; - - /** - * @brief initialize adapter object - * @return true on success - */ - virtual bool initialize() = 0; - - /** - * @brief shutdown adapter - */ - virtual void shutdown() = 0; - - /** - * @brief attach adapter to MAC address - * @param mac_addr [in] MAC address to attach to - * @return true on success - */ - virtual bool attachAdapter( uint8_t *mac_addr ) = 0; -}; - -#define I217_DESC "I217-LM" -#define I219_DESC "I219-V" - -#define NETWORK_CARD_ID_PREFIX "\\\\.\\" /*!< Network adapter prefix */ -#define OID_INTEL_GET_RXSTAMP 0xFF020264 /*!< Get RX timestamp code*/ -#define OID_INTEL_GET_TXSTAMP 0xFF020263 /*!< Get TX timestamp code*/ -#define OID_INTEL_GET_SYSTIM 0xFF020262 /*!< Get system time code */ -#define OID_INTEL_SET_SYSTIM 0xFF020261 /*!< Set system time code */ - -typedef struct -{ - uint32_t clock_rate; - char *device_desc; -} DeviceClockRateMapping; - -/** -* @brief Maps network device type to device clock rate -*/ -static DeviceClockRateMapping DeviceClockRateMap[] = -{ - { 1000000000, I217_DESC }, - { 1008000000, I219_DESC }, - { 0, NULL }, -}; - -/** - * @brief Windows Ethernet HWTimestamper implementation - */ -class WindowsEtherTimestamper : public EtherTimestamper { -private: - // No idea whether the underlying implementation is thread safe - HANDLE miniport; - LARGE_INTEGER tsc_hz; - LARGE_INTEGER netclock_hz; - DWORD readOID( NDIS_OID oid, void *output_buffer, DWORD size, DWORD *size_returned ) const { - NDIS_OID oid_l = oid; - DWORD rc = DeviceIoControl( - miniport, - IOCTL_NDIS_QUERY_GLOBAL_STATS, - &oid_l, - sizeof(oid_l), - output_buffer, - size, - size_returned, - NULL ); - if( rc == 0 ) return GetLastError(); - return ERROR_SUCCESS; - } - Timestamp nanoseconds64ToTimestamp( uint64_t time ) const { - Timestamp timestamp; - timestamp.nanoseconds = time % 1000000000; - timestamp.seconds_ls = (time / 1000000000) & 0xFFFFFFFF; - timestamp.seconds_ms = (uint16_t)((time / 1000000000) >> 32); - return timestamp; - } - uint64_t scaleNativeClockToNanoseconds( uint64_t time ) const { - long double scaled_output = ((long double)netclock_hz.QuadPart)/1000000000; - scaled_output = ((long double) time)/scaled_output; - return (uint64_t) scaled_output; - } - uint64_t scaleTSCClockToNanoseconds( uint64_t time ) const { - long double scaled_output = ((long double)tsc_hz.QuadPart)/1000000000; - scaled_output = ((long double) time)/scaled_output; - return (uint64_t) scaled_output; - } -public: - /** - * @brief Initializes the network adaptor and the hw timestamper interface - * @param iface_label InterfaceLabel - * @param net_iface Network interface - * @return TRUE if success; FALSE if error - */ - virtual bool HWTimestamper_init( InterfaceLabel *iface_label, OSNetworkInterface *net_iface ); - /** - * @brief Get the cross timestamping information. - * The gPTP subsystem uses these samples to calculate - * ratios which can be used to translate or extrapolate - * one clock into another clock reference. The gPTP service - * uses these supplied cross timestamps to perform internal - * rate estimation and conversion functions. - * @param system_time [out] System time - * @param device_time [out] Device time - * @param local_clock [out] Local clock - * @param nominal_clock_rate [out] Nominal clock rate - * @return True in case of success. FALSE in case of error - */ - virtual bool HWTimestamper_gettime( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock, - uint32_t *nominal_clock_rate ) const { - DWORD buf[6]; - DWORD returned; - uint64_t now_net, now_tsc; - DWORD result; - - memset( buf, 0xFF, sizeof( buf )); - if(( result = readOID( OID_INTEL_GET_SYSTIM, buf, sizeof(buf), &returned )) != ERROR_SUCCESS ) return false; - - now_net = (((uint64_t)buf[1]) << 32) | buf[0]; - now_net = scaleNativeClockToNanoseconds( now_net ); - *device_time = nanoseconds64ToTimestamp( now_net ); - device_time->_version = version; - - now_tsc = (((uint64_t)buf[3]) << 32) | buf[2]; - now_tsc = scaleTSCClockToNanoseconds( now_tsc ); - *system_time = nanoseconds64ToTimestamp( now_tsc ); - system_time->_version = version; - - return true; - } - - /** - * @brief Gets the TX timestamp - * @param identity [in] PortIdentity interface - * @param PTPMessageId Message ID - * @param timestamp [out] TX hardware timestamp - * @param clock_value Not used - * @param last Not used - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - virtual int HWTimestamper_txtimestamp(PortIdentity *identity, PTPMessageId messageId, Timestamp ×tamp, unsigned &clock_value, bool last) - { - DWORD buf[4], buf_tmp[4]; - DWORD returned = 0; - uint64_t tx_r,tx_s; - DWORD result; - - while(( result = readOID( OID_INTEL_GET_TXSTAMP, buf_tmp, sizeof(buf_tmp), &returned )) == ERROR_SUCCESS ) { - memcpy( buf, buf_tmp, sizeof( buf )); - } - if( result != ERROR_GEN_FAILURE ) { - fprintf( stderr, "Error is: %d\n", result ); - return GPTP_EC_FAILURE; - } - if( returned != sizeof(buf_tmp) ) return GPTP_EC_EAGAIN; - tx_r = (((uint64_t)buf[1]) << 32) | buf[0]; - tx_s = scaleNativeClockToNanoseconds( tx_r ); - timestamp = nanoseconds64ToTimestamp( tx_s ); - timestamp._version = version; - - return GPTP_EC_SUCCESS; - } - - /** - * @brief Gets the RX timestamp - * @param identity PortIdentity interface - * @param PTPMessageId Message ID - * @param timestamp [out] RX hardware timestamp - * @param clock_value [out] Not used - * @param last Not used - * @return GPTP_EC_SUCCESS if no error, GPTP_EC_FAILURE if error and GPTP_EC_EAGAIN to try again. - */ - virtual int HWTimestamper_rxtimestamp(PortIdentity *identity, PTPMessageId messageId, Timestamp ×tamp, unsigned &clock_value, bool last) - { - DWORD buf[4], buf_tmp[4]; - DWORD returned; - uint64_t rx_r,rx_s; - DWORD result; - uint16_t packet_sequence_id; - - while(( result = readOID( OID_INTEL_GET_RXSTAMP, buf_tmp, sizeof(buf_tmp), &returned )) == ERROR_SUCCESS ) { - memcpy( buf, buf_tmp, sizeof( buf )); - } - if( result != ERROR_GEN_FAILURE ) return GPTP_EC_FAILURE; - if( returned != sizeof(buf_tmp) ) return GPTP_EC_EAGAIN; - packet_sequence_id = *((uint32_t *) buf+3) >> 16; - if (PLAT_ntohs(packet_sequence_id) != messageId.getSequenceId()) return GPTP_EC_EAGAIN; - rx_r = (((uint64_t)buf[1]) << 32) | buf[0]; - rx_s = scaleNativeClockToNanoseconds( rx_r ); - timestamp = nanoseconds64ToTimestamp( rx_s ); - timestamp._version = version; - - return GPTP_EC_SUCCESS; - } -}; - - -/** - * @brief Named pipe interface - */ -class WindowsNamedPipeIPC : public OS_IPC { -private: - HANDLE pipe_; - LockableOffset lOffset_; - PeerList peerList_; -public: - /** - * @brief Default constructor. Initializes the IPC interface - */ - WindowsNamedPipeIPC() : pipe_(INVALID_HANDLE_VALUE) { }; - - /** - * @brief Destroys the IPC interface - */ - ~WindowsNamedPipeIPC() { - if (pipe_ != 0 && pipe_ != INVALID_HANDLE_VALUE) - ::CloseHandle(pipe_); - } - - /** - * @brief Initializes the IPC arguments - * @param arg [in] IPC arguments. Not in use - * @return Always returns TRUE. - */ - virtual bool init(OS_IPC_ARG *arg = NULL); - - /** - * @brief Updates IPC interface values - * - * @param ml_phoffset Master to local phase offset - * @param ls_phoffset Local to system phase offset - * @param ml_freqoffset Master to local frequency offset - * @param ls_freq_offset Local to system frequency offset - * @param local_time Local time - * @param sync_count Counts of sync messages - * @param pdelay_count Counts of pdelays - * @param port_state PortState information - * @param asCapable asCapable flag - * - * @return TRUE if success; FALSE if error - */ - virtual bool update( - int64_t ml_phoffset, - int64_t ls_phoffset, - FrequencyRatio ml_freqoffset, - FrequencyRatio ls_freq_offset, - uint64_t local_time, - uint32_t sync_count, - uint32_t pdelay_count, - PortState port_state, - bool asCapable ); - - /** - * @brief Updates grandmaster IPC interface values - * - * @param gptp_grandmaster_id Current grandmaster id (all 0's if no grandmaster selected) - * @param gptp_domain_number gPTP domain number - * - * @return TRUE if success; FALSE if error - */ - virtual bool update_grandmaster( - uint8_t gptp_grandmaster_id[], - uint8_t gptp_domain_number ); - - /** - * @brief Updates network interface IPC interface values - * - * @param clock_identity The clock identity of the interface - * @param priority1 The priority1 field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param clock_class The clockClass field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param offset_scaled_log_variance The offsetScaledLogVariance field of the grandmaster functionality of the interface, or 0x0000 if not supported - * @param clock_accuracy The clockAccuracy field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param priority2 The priority2 field of the grandmaster functionality of the interface, or 0xFF if not supported - * @param domain_number The domainNumber field of the grandmaster functionality of the interface, or 0 if not supported - * @param log_sync_interval The currentLogSyncInterval field of the grandmaster functionality of the interface, or 0 if not supported - * @param log_announce_interval The currentLogAnnounceInterval field of the grandmaster functionality of the interface, or 0 if not supported - * @param log_pdelay_interval The currentLogPDelayReqInterval field of the grandmaster functionality of the interface, or 0 if not supported - * @param port_number The portNumber field of the interface, or 0x0000 if not supported - * - * @return TRUE if success; FALSE if error - */ - virtual bool update_network_interface( - uint8_t clock_identity[], - uint8_t priority1, - uint8_t clock_class, - int16_t offset_scaled_log_variance, - uint8_t clock_accuracy, - uint8_t priority2, - uint8_t domain_number, - int8_t log_sync_interval, - int8_t log_announce_interval, - int8_t log_pdelay_interval, - uint16_t port_number ); -}; - -#endif diff --git a/daemons/gptp/windows/daemon_cl/windows_ipc.hpp b/daemons/gptp/windows/daemon_cl/windows_ipc.hpp deleted file mode 100644 index c1628ac4..00000000 --- a/daemons/gptp/windows/daemon_cl/windows_ipc.hpp +++ /dev/null @@ -1,416 +0,0 @@ -/****************************************************************************** - - 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 WINDOWSIPC_HPP -#define WINDOWSIPC_HPP - -#include <windows.h> -#include <stdint.h> -#include <minwinbase.h> -#include <gptp_log.hpp> - -#include "ipcdef.hpp" - -#define OUTSTANDING_MESSAGES 10 /*!< Number of outstanding messages on named pipe declaration*/ - -#define PIPE_PREFIX "\\\\.\\pipe\\" /*!< PIPE name prefix */ -#define P802_1AS_PIPENAME "gptp-ctrl" /*!< PIPE group name */ - -#pragma pack(push,1) - -/** - * @brief Enumeration named pipe message type. Possible values are: - * - BASE_MSG; - * - CTRL_MSG; - * - QUERY_MSG; - * - OFFSET_MSG; - */ -typedef enum { BASE_MSG = 0, CTRL_MSG, QUERY_MSG, OFFSET_MSG } NPIPE_MSG_TYPE; - -/** - * @brief Provides a windows named pipe interface - */ -class WindowsNPipeMessage { - protected: - DWORD sz; /*!< Size */ - NPIPE_MSG_TYPE type; /*!< Message type as NPIPE_MSG_TYPE*/ - - OVERLAPPED ol_read; /*!< Overlapped read*/ - DWORD ol_read_req; /*!< Overlapped read request */ - public: - /** - * @brief Initializes the interface - * @return void - */ - void init() { - sz = sizeof( WindowsNPipeMessage ); - } - /** - * @brief Writes to the named pipe - * @param pipe Pipe handler - * @return TRUE in case of success, FALSE in case of error. - */ - bool write( HANDLE pipe ) { - DWORD bytes_written; - DWORD last_error = ERROR_SUCCESS; - if( sz == 0 ) return false; - if( WriteFile( pipe, this, sz, &bytes_written, NULL ) == 0 ) { - last_error = GetLastError(); - } - if( last_error == ERROR_SUCCESS || last_error == ERROR_PIPE_LISTENING ) { - return true; - } - GPTP_LOG_ERROR( "Failed to write to named pipe: %u", last_error ); - return false; - } - /** - * @brief Reads from the pipe - * @param pipe Pipe handle - * @param offs base offset - * @param event Event handler - * @return -1 if error, 0 if ERROR_IO_PENDING or bytes_read + offs - */ - long read_ol( HANDLE pipe, long offs, HANDLE event ) { - DWORD bytes_read; - long sz_l = (long) sz; - LPOVERLAPPED lol; - if( sz_l - offs < 0 || sz_l == 0 ) return -1; - if( sz_l - offs == 0 ) return offs; - ol_read_req = sz_l-offs; - if( event != NULL ) { - memset( &ol_read, 0, sizeof( ol_read )); - ol_read.hEvent = event; - lol = &ol_read; - } else { - lol = NULL; - } - if( ReadFile( pipe, ((char *)this)+offs, ol_read_req, &bytes_read, lol ) == 0 ) { - int err = GetLastError(); - if( err != ERROR_IO_PENDING ) { - GPTP_LOG_ERROR( "Failed to read %d bytes from named pipe: %u", ol_read_req, err ); - } - return err == ERROR_IO_PENDING ? 0 : -1; - } - return (bytes_read == sz_l-offs) ? offs+bytes_read : -1; - } - /** - * @brief Reads completely the overlapped result - * @param pipe Pipe handler - * @return bytes read in case of success, -1 in case of error - * @todo Its not clear what GetOverlappedResult does - */ - long read_ol_complete( HANDLE pipe ) { - DWORD bytes_read; - if( GetOverlappedResult( pipe, &ol_read, &bytes_read, false ) == 0 ) { - return -1; - } - return bytes_read; - } - /** - * @brief Reads from the pipe - * @param pipe Pipe handler - * @param offs base offset - * @return -1 if error, 0 if ERROR_IO_PENDING or bytes_read + offs - */ - long read( HANDLE pipe, long offs ) { - return read_ol( pipe, offs, NULL ); - } - /** - * @brief Gets pipe message type - * @return ::NPIPE_MSG_TYPE - */ - NPIPE_MSG_TYPE getType() { return type; } -}; - -#ifndef PTP_CLOCK_IDENTITY_LENGTH -#define PTP_CLOCK_IDENTITY_LENGTH 8 /*!< Size of a clock identifier stored in the ClockIndentity class, described at IEEE 802.1AS-2011 Clause 8.5.2.4*/ -#endif - -/** - * @brief Provides an interface for the phase/frequency offsets - */ -class Offset { - public: - int64_t ml_phoffset; //!< Master to local phase offset - FrequencyRatio ml_freqoffset; //!< Master to local frequency offset - int64_t ls_phoffset; //!< Local to system phase offset - FrequencyRatio ls_freqoffset; //!< Local to system frequency offset - uint64_t local_time; //!< Local time - - /* Current grandmaster information */ - /* Referenced by the IEEE Std 1722.1-2013 AVDECC Discovery Protocol Data Unit (ADPDU) */ - uint8_t gptp_grandmaster_id[PTP_CLOCK_IDENTITY_LENGTH]; //!< Current grandmaster id (all 0's if no grandmaster selected) - uint8_t gptp_domain_number; //!< gPTP domain number - - /* Grandmaster support for the network interface */ - /* Referenced by the IEEE Std 1722.1-2013 AVDECC AVB_INTERFACE descriptor */ - uint8_t clock_identity[PTP_CLOCK_IDENTITY_LENGTH]; //!< The clock identity of the interface - uint8_t priority1; //!< The priority1 field of the grandmaster functionality of the interface, or 0xFF if not supported - uint8_t clock_class; //!< The clockClass field of the grandmaster functionality of the interface, or 0xFF if not supported - int16_t offset_scaled_log_variance; //!< The offsetScaledLogVariance field of the grandmaster functionality of the interface, or 0x0000 if not supported - uint8_t clock_accuracy; //!< The clockAccuracy field of the grandmaster functionality of the interface, or 0xFF if not supported - uint8_t priority2; //!< The priority2 field of the grandmaster functionality of the interface, or 0xFF if not supported - uint8_t domain_number; //!< The domainNumber field of the grandmaster functionality of the interface, or 0 if not supported - int8_t log_sync_interval; //!< The currentLogSyncInterval field of the grandmaster functionality of the interface, or 0 if not supported - int8_t log_announce_interval; //!< The currentLogAnnounceInterval field of the grandmaster functionality of the interface, or 0 if not supported - int8_t log_pdelay_interval; //!< The currentLogPDelayReqInterval field of the grandmaster functionality of the interface, or 0 if not supported - uint16_t port_number; //!< The portNumber field of the interface, or 0x0000 if not supported -}; - -/** - * @brief Provides an interface to update the Offset information - */ -class WinNPipeOffsetUpdateMessage : public WindowsNPipeMessage { - private: - Offset offset; - public: - /** - * @brief Initializes interface - * @return void - */ - void _init() { - sz = sizeof(WinNPipeOffsetUpdateMessage); - type = OFFSET_MSG; - } - /** - * @brief Initializes interface and clears the Offset message - * @return void - */ - void init() { - _init(); - memset( &this->offset, 0, sizeof( this->offset )); - } - /** - * @brief Initializes the interface based on the Offset structure - * @param offset [in] Offset structure - * @return void - */ - void init( Offset *offset ) { - _init(); - this->offset = *offset; - } - /** - * @brief Gets master to local phase offset - * @return master to local phase offset - */ - int64_t getMasterLocalOffset() { return offset.ml_phoffset; } - /** - * @brief Gets Master to local frequency offset - * @return Master to local frequency offset - */ - FrequencyRatio getMasterLocalFreqOffset() { return offset.ml_freqoffset; } - /** - * @brief Gets local to system phase offset - * @return local to system phase offset - */ - int64_t getLocalSystemOffset() { return offset.ls_phoffset; } - /** - * @brief Gets Local to system frequency offset - * @return Local to system frequency offset - */ - FrequencyRatio getLocalSystemFreqOffset() { return offset.ls_freqoffset; } - /** - * @brief Gets local time - * @return Local time - */ - uint64_t getLocalTime() { return offset.local_time; } -}; - -/** - * @brief Enumeration CtrlWhich. It can assume the following values: - * - ADD_PEER; - * - REMOVE_PEER; - */ -typedef enum { ADD_PEER, REMOVE_PEER } CtrlWhich; -/** - * @brief Enumeration AddrWhich. It can assume the following values: - * - MAC_ADDR; - * - IP_ADDR; - * - INVALID_ADDR; - */ -typedef enum { MAC_ADDR, IP_ADDR, INVALID_ADDR } AddrWhich; - -/** - * @brief Provides an interface for Peer addresses - */ -class PeerAddr { - public: - AddrWhich which; /*!< Peer address */ - /** - * @brief shared memory between mac and ip addresses - */ - union { - uint8_t mac[ETHER_ADDR_OCTETS]; /*!< Link Layer address */ - uint8_t ip[IP_ADDR_OCTETS]; /*!< IP Address */ - }; - /** - * @brief Implements the operator '==' overloading method. - * @param other [in] Reference to the peer addresses - * @return TRUE if mac or ip are the same. FALSE otherwise. - */ - bool operator==(const PeerAddr &other) const { - int result; - switch( which ) { - case MAC_ADDR: - result = memcmp( &other.mac, &mac, ETHER_ADDR_OCTETS ); - break; - case IP_ADDR: - result = memcmp( &other.ip, &ip, IP_ADDR_OCTETS ); - break; - default: - result = -1; // != 0 - break; - } - return (result == 0) ? true : false; - } - /** - * @brief Implements the operator '<' overloading method. - * @param other Reference to the peer addresses to be compared. - * @return TRUE if mac or ip address from the object is lower than the peer's. - */ - bool operator<(const PeerAddr &other) const { - int result; - switch( which ) { - case MAC_ADDR: - result = memcmp( &other.mac, &mac, ETHER_ADDR_OCTETS ); - break; - case IP_ADDR: - result = memcmp( &other.ip, &ip, IP_ADDR_OCTETS ); - break; - default: - result = 1; // > 0 - break; - } - return (result < 0) ? true : false; - } -}; - -/** - * @brief Provides an interface for named pipe control messages - */ -class WinNPipeCtrlMessage : public WindowsNPipeMessage { - private: - CtrlWhich which; - PeerAddr addr; - uint16_t flags; - public: - /** - * @brief Initializes interface's internal variables. - * @return void - */ - void init() { - sz = sizeof(WinNPipeCtrlMessage); - type = CTRL_MSG; - } - /** - * @brief Initializes Interface's internal variables and sets - * control and addresses values - * @param which ::CtrlWhich enumeration - * @param addr Peer addresses - * @return void - */ - void init( CtrlWhich which, PeerAddr addr ) { - init(); - this->which = which; - this->addr = addr; - flags = 0; - } - /** - * @brief Gets peer addresses - * @return PeerAddr structure - */ - PeerAddr getPeerAddr() { return addr; } - /** - * @brief Sets peer address - * @param addr PeerAddr to set - * @return void - */ - void setPeerAddr( PeerAddr addr ) { this->addr = addr; } - /** - * @brief Gets control type - * @return ::CtrlWhich type - */ - CtrlWhich getCtrlWhich() { return which; } - /** - * @brief Sets control message type - * @param which ::CtrlWhich message - * @return void - */ - void setCtrlWhich( CtrlWhich which ) { this->which = which; } - /** - * @brief Gets internal flags - * @return Internal flags - * @todo What are these flags used for? Apparently its not in use. - */ - uint16_t getFlags() { return flags; } -}; - -/** - * @brief WindowsNPipeQueryMessage is sent from the client to gPTP daemon to query the - * offset of type ::NPIPE_MSG_TYPE. The daemon sends WindowsNPipeMessage in response. - * Currently there is no data associated with this message. - */ -class WinNPipeQueryMessage : public WindowsNPipeMessage { - public: - /** - * @brief Initializes the interface - * @return void - */ - void init() { type = OFFSET_MSG; sz = sizeof(*this); } -}; - -/** - * @brief Provides the client's named pipe interface - * @todo Not in use and should be removed. - */ -typedef union { - WinNPipeCtrlMessage a; /*!< Control message */ - WinNPipeQueryMessage b; /*!< Query message */ -} WindowsNPipeMsgClient; - -/** - * @brief Provides the server's named pipe interface - * @todo Not in use and should be removed. - */ -typedef union { - WinNPipeOffsetUpdateMessage a; /*!< Offset update message */ -} WindowsNPipeMsgServer; - -#define NPIPE_MAX_CLIENT_MSG_SZ (sizeof( WindowsNPipeMsgClient )) /*!< Maximum message size for the client */ -#define NPIPE_MAX_SERVER_MSG_SZ (sizeof( WindowsNPipeMsgServer )) /*!< Maximum message size for the server */ -#define NPIPE_MAX_MSG_SZ (NPIPE_MAX_CLIENT_MSG_SZ > NPIPE_MAX_SERVER_MSG_SZ ? NPIPE_MAX_CLIENT_MSG_SZ : NPIPE_MAX_SERVER_MSG_SZ) /*!< Maximum message size */ - -#pragma pack(pop) - -#endif /*WINDOWSIPC_HPP*/ - diff --git a/daemons/gptp/windows/daemon_cl/work_queue.cpp b/daemons/gptp/windows/daemon_cl/work_queue.cpp deleted file mode 100644 index 461d6923..00000000 --- a/daemons/gptp/windows/daemon_cl/work_queue.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2015, 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 <work_queue.hpp> -#include <stdio.h> - - -struct WWQueueThreadState { - bool running; - bool stop; - WWQueueCallback task; - LPVOID arg; -}; - -DWORD WINAPI WindowsWorkQueueLoop(LPVOID arg) { - WWQueueThreadState *state = (WWQueueThreadState *)arg; - state->running = true; - while (!state->stop) { - if (state->task != NULL) { - state->task(state->arg); - delete state->arg; - state->task = NULL; - } - Sleep(1); - } - state->running = false; - - return 0; -} - -bool WindowsWorkQueue::init(int number_threads) -{ - if (number_threads == 0) number_threads = DEFAULT_THREAD_COUNT; - state = new WWQueueThreadState[number_threads]; - for (int i = 0; i < number_threads; ++i) { - state[i].running = false; - state[i].stop = false; - state[i].task = NULL; - } - workers = new HANDLE[number_threads]; - for (int i = 0; i < number_threads; ++i) { - workers[i] = CreateThread(NULL, 0, WindowsWorkQueueLoop, state + i, 0, NULL); - if (workers[i] == INVALID_HANDLE_VALUE) - return false; - while (!state[i].running) - Sleep(1); - } - this->number_threads = number_threads; - return true; -} - -bool WindowsWorkQueue::submit(WWQueueCallback cb, LPVOID arg) -{ - int i; - - for (i = 0; i < number_threads; ++i) { - if (state[i].task == NULL) { - state[i].arg = arg; - state[i].task = cb; - break; - } - } - if (i == number_threads) - return false; - - return true; -} - -void WindowsWorkQueue::stop() -{ - for (int i = 0; i < number_threads; ++i) { - state[i].stop = true; - while (state[i].running) - Sleep(1); - } -} diff --git a/daemons/gptp/windows/daemon_cl/work_queue.hpp b/daemons/gptp/windows/daemon_cl/work_queue.hpp deleted file mode 100644 index 4ac750c5..00000000 --- a/daemons/gptp/windows/daemon_cl/work_queue.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2015, 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 WORK_QUEUE_HPP -#define WORK_QUEUE_HPP - -#include <WTypesbase.h> - -#define DEFAULT_THREAD_COUNT (5) - -struct WWQueueThreadState; - -typedef void(*WWQueueCallback)(LPVOID arg); - -class WindowsWorkQueue -{ -private: - HANDLE *workers; - WWQueueThreadState *state; - int number_threads; - -public: - /** - * @brief initialize work queue - * @param number_threads [in] number of threads (0 = default) - * @return true on success - */ - bool init( int number_threads ); - - /** - * @brief submit job to work queue - * @param cb [in] function to call - * @param arg [in] parameter provided to callback - * @return true on success - */ - bool submit( WWQueueCallback cb, LPVOID arg ); - - /** - * @brief stop work queue - */ - void stop(); -}; - -#endif/*WORK_QUEUE_HPP*/ diff --git a/daemons/gptp/windows/named_pipe_test/CMakeLists.txt b/daemons/gptp/windows/named_pipe_test/CMakeLists.txt deleted file mode 100644 index e872a4f1..00000000 --- a/daemons/gptp/windows/named_pipe_test/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -#Windows specifc build of named pipe test -cmake_minimum_required (VERSION 2.8) -project (named_pipe_test) - -include_directories( ".." ) -file(GLOB SRC "*.cpp") - -add_definitions(-D_CRT_SECURE_NO_WARNINGS ) -include_directories( include "../../common" ) -add_executable (named_pipe_test ${SRC} "../../common/gptp_log.cpp" "../../windows/daemon_cl/platform.cpp") -target_link_libraries(named_pipe_test Iphlpapi Ws2_32) diff --git a/daemons/gptp/windows/named_pipe_test/ReadMe.txt b/daemons/gptp/windows/named_pipe_test/ReadMe.txt deleted file mode 100644 index 4ba7155b..00000000 --- a/daemons/gptp/windows/named_pipe_test/ReadMe.txt +++ /dev/null @@ -1,10 +0,0 @@ -======================================================================== -(C) Copyright 2009-2012 Intel Corporation, All Rights Reserved -Author: Christopher Hall <christopher.s.hall@intel.com> -======================================================================== - -======================================================================== - CONSOLE APPLICATION : named_pipe_test Project Overview -======================================================================== - -An example application to interface with gptp/daemon_cl. See ipcdef.hpp for message details. diff --git a/daemons/gptp/windows/named_pipe_test/named_pipe_test.cpp b/daemons/gptp/windows/named_pipe_test/named_pipe_test.cpp deleted file mode 100644 index 9a34a4ef..00000000 --- a/daemons/gptp/windows/named_pipe_test/named_pipe_test.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/****************************************************************************** - - 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 "stdafx.h" -#include "windows_ipc.hpp" -#include "tsc.hpp" - -static bool exit_flag; - -BOOL WINAPI ctrl_handler( DWORD ctrl_type ) { - bool ret; - if( ctrl_type == CTRL_C_EVENT ) { - exit_flag = true; - ret = true; - } else { - ret = false; - } - return ret; -} - -uint64_t scaleTSCClockToNanoseconds( uint64_t tsc_value, uint64_t tsc_frequency ) { - long double scaled_output = ((long double)tsc_frequency)/1000000000; - scaled_output = ((long double) tsc_value)/scaled_output; - return (uint64_t) scaled_output; -} - -int _tmain(int argc, _TCHAR* argv[]) -{ - char pipename[64]; - strcpy_s( pipename, 64, PIPE_PREFIX ); - strcat_s( pipename, 64-strlen(pipename), P802_1AS_PIPENAME ); - HANDLE pipe; - uint64_t tsc_frequency = getTSCFrequency( true ); - - // Wait for Ctrl-C - if( !SetConsoleCtrlHandler( ctrl_handler, true )) { - printf( "Unable to register Ctrl-C handler\n" ); - return -1; - } - - pipe = CreateFile( pipename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - if( pipe == INVALID_HANDLE_VALUE ) { - printf( "Failed to open gptp handle, %d\n", GetLastError() ); - } - - printf( "TSC Frequency: %llu\n", tsc_frequency ); - while( !exit_flag ) { - uint64_t now_tscns, now_8021as; - uint64_t update_tscns, update_8021as; - unsigned delta_tscns, delta_8021as; - long double ml_ratio, ls_ratio; - WinNPipeQueryMessage qmsg; - WinNPipeOffsetUpdateMessage omsg; - bool ret; - long offset; - - qmsg.init(); - ret = qmsg.write( pipe ); - if( ret != true ) { - printf( "Failed to send query message\n" ); - break; - } - - omsg.init(); - offset = omsg.read( pipe, 0 ); - - printf( "Master-Local Offset = %lld\n", omsg.getMasterLocalOffset() ); - printf( "Master-Local Frequency Offset = %Lf\n", omsg.getMasterLocalFreqOffset() ); - printf( "Local-System Offset = %lld\n", omsg.getLocalSystemOffset() ); - printf( "Local-System Frequency Offset = %Lf\n", omsg.getLocalSystemFreqOffset() ); - printf( "Local Time = %llu\n\n", omsg.getLocalTime() ); - - now_tscns = scaleTSCClockToNanoseconds( PLAT_rdtsc(), tsc_frequency ); - update_tscns = omsg.getLocalTime() + omsg.getLocalSystemOffset(); - delta_tscns = (unsigned)(now_tscns - update_tscns); - printf( "Time now in terms of TSC scaled to nanoseconds time: %llu\n", now_tscns ); - printf( "TSC delta scaled to ns: %u\n", delta_tscns ); - ml_ratio = omsg.getMasterLocalFreqOffset(); - ls_ratio = omsg.getLocalSystemFreqOffset(); - delta_8021as = (unsigned)(ml_ratio*ls_ratio*delta_tscns); - printf( "8021as delta scaled: %u\n", delta_8021as ); - update_8021as = omsg.getLocalTime() - omsg.getMasterLocalOffset(); - now_8021as = update_8021as + delta_8021as; - printf( "Last update time in terms of 802.1AS time: %llu\n", update_8021as ); - printf( "Time now in terms of 802.1AS time: %llu\n", now_8021as ); - - exit_flag = true; - } - - printf( "Closing pipe\n" ); - CloseHandle( pipe ); - - return 0; -} - diff --git a/daemons/gptp/windows/named_pipe_test/stdafx.cpp b/daemons/gptp/windows/named_pipe_test/stdafx.cpp deleted file mode 100644 index 8f3984c3..00000000 --- a/daemons/gptp/windows/named_pipe_test/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// named_pipe_test.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/daemons/gptp/windows/named_pipe_test/stdafx.h b/daemons/gptp/windows/named_pipe_test/stdafx.h deleted file mode 100644 index 686c8f5b..00000000 --- a/daemons/gptp/windows/named_pipe_test/stdafx.h +++ /dev/null @@ -1,16 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#include <stdio.h> -#include <tchar.h> -#include <Windows.h> - - - -// TODO: reference additional headers your program requires here diff --git a/daemons/gptp/windows/named_pipe_test/targetver.h b/daemons/gptp/windows/named_pipe_test/targetver.h deleted file mode 100644 index 87c0086d..00000000 --- a/daemons/gptp/windows/named_pipe_test/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include <SDKDDKVer.h> @@ -11,8 +11,3 @@ cmake .. -G "Unix Makefiles" make export ARGS=--output-on-failure make test -cd ../daemons/gptp/doc -mkdir build -cd build -cmake .. -make doc |