diff options
Diffstat (limited to 'daemons/gptp/windows/daemon_cl/windows_hal.hpp')
-rw-r--r-- | daemons/gptp/windows/daemon_cl/windows_hal.hpp | 974 |
1 files changed, 0 insertions, 974 deletions
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 |