diff options
author | Christopher Hall <christopher.s.hall@intel.com> | 2014-01-08 15:45:53 -0800 |
---|---|---|
committer | Christopher Hall <christopher.s.hall@intel.com> | 2014-01-08 15:45:53 -0800 |
commit | 90e313957a2e2b4d6ea8901c33987f20b1648291 (patch) | |
tree | e8058e8542e5f61644c9cf1c2a5c5d935e699ba8 | |
parent | 8044f3cd824731954db10d3a8f0d3c39e90e70f3 (diff) | |
download | Open-AVB-90e313957a2e2b4d6ea8901c33987f20b1648291.tar.gz |
Fixed line-ending issues
76 files changed, 7261 insertions, 7261 deletions
diff --git a/daemons/gptp/common/avbts_clock.hpp b/daemons/gptp/common/avbts_clock.hpp index f335b494..8e7f6f09 100644 --- a/daemons/gptp/common/avbts_clock.hpp +++ b/daemons/gptp/common/avbts_clock.hpp @@ -1,292 +1,292 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_CLOCK_HPP
-#define AVBTS_CLOCK_HPP
-
-#include <stdint.h>
-#include <ieee1588.hpp>
-#include <avbts_port.hpp>
-#include <avbts_ostimerq.hpp>
-#include <avbts_osipc.hpp>
-
-#define EVENT_TIMER_GRANULARITY 5000000
-
-#define INTEGRAL 0.0024
-#define PROPORTIONAL 1.0
-#define UPPER_FREQ_LIMIT 250.0
-#define LOWER_FREQ_LIMIT -250.0
-
-struct ClockQuality {
- unsigned char cq_class;
- unsigned char clockAccuracy;
- int16_t offsetScaledLogVariance;
-};
-
-class IEEE1588Clock {
-private:
- ClockIdentity clock_identity;
- ClockQuality clock_quality;
- unsigned char priority1;
- unsigned char priority2;
- bool initializable;
- bool is_boundary_clock;
- bool two_step_clock;
- unsigned char domain_number;
- uint16_t number_ports;
- uint16_t number_foreign_records;
- bool slave_only;
- int16_t current_utc_offset;
- bool leap_59;
- bool leap_61;
- uint16_t epoch_number;
- uint16_t steps_removed;
- int64_t offset_from_master;
- Timestamp one_way_delay;
- PortIdentity parent_identity;
- 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;
-
- IEEE1588Port *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;
-
- HWTimestamper *_timestamper;
-
- OS_IPC *ipc;
-
- OSTimerQueue *timerq;
-
- bool forceOrdinarySlave;
- FrequencyRatio _master_local_freq_offset;
- FrequencyRatio _local_system_freq_offset;
-
- OSLock *timerq_lock;
-public:
- IEEE1588Clock
- (bool forceOrdinarySlave, bool syntonize, uint8_t priority1,
- HWTimestamper *timestamper, OSTimerQueueFactory * timerq_factory,
- OS_IPC * ipc, OSLockFactory *lock_factory );
- ~IEEE1588Clock(void);
-
- bool serializeState( void *buf, off_t *count );
- bool restoreSerializedState( void *buf, off_t *count );
-
- Timestamp getTime(void);
- Timestamp getPreciseTime(void);
-
- bool isBetterThan(PTPMessageAnnounce * msg);
-
- ClockIdentity getLastEBestIdentity( void ) {
- return LastEBestIdentity;
- }
- void setLastEBestIdentity( ClockIdentity id ) {
- LastEBestIdentity = id;
- return;
- }
-
- void setClockIdentity(char *id) {
- clock_identity.set((uint8_t *) id);
- }
- void setClockIdentity(LinkLayerAddress * addr) {
- clock_identity.set(addr);
- }
-
- unsigned char getDomain(void) {
- return domain_number;
- }
-
- ClockIdentity getGrandmasterClockIdentity(void) {
- return grandmaster_clock_identity;
- }
- void setGrandmasterClockIdentity(ClockIdentity id) {
- grandmaster_clock_identity = id;
- }
-
- ClockQuality getGrandmasterClockQuality(void) {
- return grandmaster_clock_quality;
- }
- void setGrandmasterClockQuality( ClockQuality clock_quality ) {
- grandmaster_clock_quality = clock_quality;
- }
-
- ClockQuality getClockQuality(void) {
- return clock_quality;
- }
-
- unsigned char getGrandmasterPriority1(void) {
- return grandmaster_priority1;
- }
-
- unsigned char getGrandmasterPriority2(void) {
- return grandmaster_priority2;
- }
- void setGrandmasterPriority1( unsigned char priority1 ) {
- grandmaster_priority1 = priority1;
- }
-
- void setGrandmasterPriority2( unsigned char priority2 ) {
- grandmaster_priority2 = priority2;
- }
-
- uint16_t getMasterStepsRemoved(void) {
- return steps_removed;
- }
-
- uint16_t getCurrentUtcOffset(void) {
- return current_utc_offset;
- }
-
- uint8_t getTimeSource(void) {
- return time_source;
- }
-
- unsigned char getPriority1(void) {
- return priority1;
- }
-
- unsigned char getPriority2(void) {
- return priority2;
- }
- uint16_t getNextPortId(void) {
- return (number_ports++ % (MAX_PORTS + 1)) + 1;
- }
- void registerPort(IEEE1588Port * port, uint16_t index) {
- if (index < MAX_PORTS) {
- port_list[index - 1] = port;
- }
- ++number_ports;
- }
- void getPortList(int &count, IEEE1588Port ** &ports) {
- ports = this->port_list;
- count = number_ports;
- return;
- }
-
- static Timestamp getSystemTime(void);
-
- void addEventTimer
- ( IEEE1588Port * target, Event e, unsigned long long time_ns );
- void deleteEventTimer(IEEE1588Port * target, Event e);
-
- void addEventTimerLocked
- ( IEEE1588Port * target, Event e, unsigned long long time_ns );
- void deleteEventTimerLocked(IEEE1588Port * target, Event e);
-
- FrequencyRatio calcMasterLocalClockRateDifference
- ( Timestamp master_time, Timestamp sync_time );
- FrequencyRatio calcLocalSystemClockRateDifference
- ( Timestamp local_time, Timestamp system_time );
-
- void setMasterOffset
- ( 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 );
-
- ClockIdentity getClockIdentity() {
- return clock_identity;
- }
-
- void newSyntonizationSetPoint() {
- _new_syntonization_set_point = true;
- }
-
- int getTxLockAll() {
- int number_ports, i, j = 0;
- IEEE1588Port **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;
- }
-
- int putTxLockAll() {
- int number_ports, i, j = 0;
- IEEE1588Port **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;
- }
-
- friend void tick_handler(int sig);
-
- OSLockResult getTimerQLock() {
- return timerq_lock->lock();
- }
- OSLockResult putTimerQLock() {
- return timerq_lock->unlock();
- }
- OSLock *timerQLock() {
- return timerq_lock;
- }
-};
-
-void tick_handler(int sig);
-
-#endif
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef AVBTS_CLOCK_HPP +#define AVBTS_CLOCK_HPP + +#include <stdint.h> +#include <ieee1588.hpp> +#include <avbts_port.hpp> +#include <avbts_ostimerq.hpp> +#include <avbts_osipc.hpp> + +#define EVENT_TIMER_GRANULARITY 5000000 + +#define INTEGRAL 0.0024 +#define PROPORTIONAL 1.0 +#define UPPER_FREQ_LIMIT 250.0 +#define LOWER_FREQ_LIMIT -250.0 + +struct ClockQuality { + unsigned char cq_class; + unsigned char clockAccuracy; + int16_t offsetScaledLogVariance; +}; + +class IEEE1588Clock { +private: + ClockIdentity clock_identity; + ClockQuality clock_quality; + unsigned char priority1; + unsigned char priority2; + bool initializable; + bool is_boundary_clock; + bool two_step_clock; + unsigned char domain_number; + uint16_t number_ports; + uint16_t number_foreign_records; + bool slave_only; + int16_t current_utc_offset; + bool leap_59; + bool leap_61; + uint16_t epoch_number; + uint16_t steps_removed; + int64_t offset_from_master; + Timestamp one_way_delay; + PortIdentity parent_identity; + 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; + + IEEE1588Port *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; + + HWTimestamper *_timestamper; + + OS_IPC *ipc; + + OSTimerQueue *timerq; + + bool forceOrdinarySlave; + FrequencyRatio _master_local_freq_offset; + FrequencyRatio _local_system_freq_offset; + + OSLock *timerq_lock; +public: + IEEE1588Clock + (bool forceOrdinarySlave, bool syntonize, uint8_t priority1, + HWTimestamper *timestamper, OSTimerQueueFactory * timerq_factory, + OS_IPC * ipc, OSLockFactory *lock_factory ); + ~IEEE1588Clock(void); + + bool serializeState( void *buf, off_t *count ); + bool restoreSerializedState( void *buf, off_t *count ); + + Timestamp getTime(void); + Timestamp getPreciseTime(void); + + bool isBetterThan(PTPMessageAnnounce * msg); + + ClockIdentity getLastEBestIdentity( void ) { + return LastEBestIdentity; + } + void setLastEBestIdentity( ClockIdentity id ) { + LastEBestIdentity = id; + return; + } + + void setClockIdentity(char *id) { + clock_identity.set((uint8_t *) id); + } + void setClockIdentity(LinkLayerAddress * addr) { + clock_identity.set(addr); + } + + unsigned char getDomain(void) { + return domain_number; + } + + ClockIdentity getGrandmasterClockIdentity(void) { + return grandmaster_clock_identity; + } + void setGrandmasterClockIdentity(ClockIdentity id) { + grandmaster_clock_identity = id; + } + + ClockQuality getGrandmasterClockQuality(void) { + return grandmaster_clock_quality; + } + void setGrandmasterClockQuality( ClockQuality clock_quality ) { + grandmaster_clock_quality = clock_quality; + } + + ClockQuality getClockQuality(void) { + return clock_quality; + } + + unsigned char getGrandmasterPriority1(void) { + return grandmaster_priority1; + } + + unsigned char getGrandmasterPriority2(void) { + return grandmaster_priority2; + } + void setGrandmasterPriority1( unsigned char priority1 ) { + grandmaster_priority1 = priority1; + } + + void setGrandmasterPriority2( unsigned char priority2 ) { + grandmaster_priority2 = priority2; + } + + uint16_t getMasterStepsRemoved(void) { + return steps_removed; + } + + uint16_t getCurrentUtcOffset(void) { + return current_utc_offset; + } + + uint8_t getTimeSource(void) { + return time_source; + } + + unsigned char getPriority1(void) { + return priority1; + } + + unsigned char getPriority2(void) { + return priority2; + } + uint16_t getNextPortId(void) { + return (number_ports++ % (MAX_PORTS + 1)) + 1; + } + void registerPort(IEEE1588Port * port, uint16_t index) { + if (index < MAX_PORTS) { + port_list[index - 1] = port; + } + ++number_ports; + } + void getPortList(int &count, IEEE1588Port ** &ports) { + ports = this->port_list; + count = number_ports; + return; + } + + static Timestamp getSystemTime(void); + + void addEventTimer + ( IEEE1588Port * target, Event e, unsigned long long time_ns ); + void deleteEventTimer(IEEE1588Port * target, Event e); + + void addEventTimerLocked + ( IEEE1588Port * target, Event e, unsigned long long time_ns ); + void deleteEventTimerLocked(IEEE1588Port * target, Event e); + + FrequencyRatio calcMasterLocalClockRateDifference + ( Timestamp master_time, Timestamp sync_time ); + FrequencyRatio calcLocalSystemClockRateDifference + ( Timestamp local_time, Timestamp system_time ); + + void setMasterOffset + ( 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 ); + + ClockIdentity getClockIdentity() { + return clock_identity; + } + + void newSyntonizationSetPoint() { + _new_syntonization_set_point = true; + } + + int getTxLockAll() { + int number_ports, i, j = 0; + IEEE1588Port **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; + } + + int putTxLockAll() { + int number_ports, i, j = 0; + IEEE1588Port **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; + } + + friend void tick_handler(int sig); + + OSLockResult getTimerQLock() { + return timerq_lock->lock(); + } + OSLockResult putTimerQLock() { + return timerq_lock->unlock(); + } + 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 index f54cf42b..df0541ff 100644 --- a/daemons/gptp/common/avbts_message.hpp +++ b/daemons/gptp/common/avbts_message.hpp @@ -1,470 +1,470 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_MESSAGE_HPP
-#define AVBTS_MESSAGE_HPP
-
-#include <stdint.h>
-#include <avbts_osnet.hpp>
-#include <ieee1588.hpp>
-
-#define PTP_CODE_STRING_LENGTH 4
-#define PTP_SUBDOMAIN_NAME_LENGTH 16
-#define PTP_FLAGS_LENGTH 2
-
-#define GPTP_VERSION 2
-#define PTP_NETWORK_VERSION 1
-
-#define PTP_ETHER 1
-#define PTP_DEFAULT 255
-
-#define PTP_COMMON_HDR_OFFSET 0
-#define PTP_COMMON_HDR_LENGTH 34
-#define PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(x) x
-#define PTP_COMMON_HDR_PTP_VERSION(x) x+1
-#define PTP_COMMON_HDR_MSG_LENGTH(x) x+2
-#define PTP_COMMON_HDR_DOMAIN_NUMBER(x) x+4
-#define PTP_COMMON_HDR_FLAGS(x) x+6
-#define PTP_COMMON_HDR_CORRECTION(x) x+8
-#define PTP_COMMON_HDR_SOURCE_CLOCK_ID(x) x+20
-#define PTP_COMMON_HDR_SOURCE_PORT_ID(x) x+28
-#define PTP_COMMON_HDR_SEQUENCE_ID(x) x+30
-#define PTP_COMMON_HDR_CONTROL(x) x+32
-#define PTP_COMMON_HDR_LOG_MSG_INTRVL(x) x+33
-
-#define PTP_ANNOUNCE_OFFSET 34
-#define PTP_ANNOUNCE_LENGTH 30
-#define PTP_ANNOUNCE_CURRENT_UTC_OFFSET(x) x+10
-#define PTP_ANNOUNCE_GRANDMASTER_PRIORITY1(x) x+13
-#define PTP_ANNOUNCE_GRANDMASTER_CLOCK_QUALITY(x) x+14
-#define PTP_ANNOUNCE_GRANDMASTER_PRIORITY2(x) x+18
-#define PTP_ANNOUNCE_GRANDMASTER_IDENTITY(x) x+19
-#define PTP_ANNOUNCE_STEPS_REMOVED(x) x+27
-#define PTP_ANNOUNCE_TIME_SOURCE(x) x+29
-
-#define PTP_SYNC_OFFSET 34
-#define PTP_SYNC_LENGTH 10
-#define PTP_SYNC_SEC_MS(x) x
-#define PTP_SYNC_SEC_LS(x) x+2
-#define PTP_SYNC_NSEC(x) x+6
-
-#define PTP_FOLLOWUP_OFFSET 34
-#define PTP_FOLLOWUP_LENGTH 10
-#define PTP_FOLLOWUP_SEC_MS(x) x
-#define PTP_FOLLOWUP_SEC_LS(x) x+2
-#define PTP_FOLLOWUP_NSEC(x) x+6
-
-#define PTP_PDELAY_REQ_OFFSET 34
-#define PTP_PDELAY_REQ_LENGTH 20
-#define PTP_PDELAY_REQ_SEC_MS(x) x
-#define PTP_PDELAY_REQ_SEC_LS(x) x+2
-#define PTP_PDELAY_REQ_NSEC(x) x+6
-
-#define PTP_PDELAY_RESP_OFFSET 34
-#define PTP_PDELAY_RESP_LENGTH 20
-#define PTP_PDELAY_RESP_SEC_MS(x) x
-#define PTP_PDELAY_RESP_SEC_LS(x) x+2
-#define PTP_PDELAY_RESP_NSEC(x) x+6
-#define PTP_PDELAY_RESP_REQ_CLOCK_ID(x) x+10
-#define PTP_PDELAY_RESP_REQ_PORT_ID(x) x+18
-
-#define PTP_PDELAY_FOLLOWUP_OFFSET 34
-#define PTP_PDELAY_FOLLOWUP_LENGTH 20
-#define PTP_PDELAY_FOLLOWUP_SEC_MS(x) x
-#define PTP_PDELAY_FOLLOWUP_SEC_LS(x) x+2
-#define PTP_PDELAY_FOLLOWUP_NSEC(x) x+6
-#define PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID(x) x+10
-#define PTP_PDELAY_FOLLOWUP_REQ_PORT_ID(x) x+18
-
-#define PTP_LI_61_BYTE 1
-#define PTP_LI_61_BIT 0
-#define PTP_LI_59_BYTE 1
-#define PTP_LI_59_BIT 1
-#define PTP_ASSIST_BYTE 0
-#define PTP_ASSIST_BIT 1
-#define PTP_PTPTIMESCALE_BYTE 1
-#define PTP_PTPTIMESCALE_BIT 3
-
-#define TX_TIMEOUT_BASE 1000 /* microseconds */
-#define TX_TIMEOUT_ITER 6
-
-enum MessageType {
- SYNC_MESSAGE = 0,
- DELAY_REQ_MESSAGE = 1,
- PATH_DELAY_REQ_MESSAGE = 2,
- PATH_DELAY_RESP_MESSAGE = 3,
- FOLLOWUP_MESSAGE = 8,
- DELAY_RESP_MESSAGE = 9,
- PATH_DELAY_FOLLOWUP_MESSAGE = 0xA,
- ANNOUNCE_MESSAGE = 0xB,
- SIGNALLING_MESSAGE = 0xC,
- MANAGEMENT_MESSAGE = 0xD,
-};
-
-enum LegacyMessageType {
- SYNC,
- DELAY_REQ,
- FOLLOWUP,
- DELAY_RESP,
- MANAGEMENT,
- MESSAGE_OTHER
-};
-
-enum MulticastType {
- MCAST_NONE,
- MCAST_PDELAY,
- MCAST_OTHER
-};
-
-class PTPMessageCommon {
-protected:
- unsigned char versionPTP;
- uint16_t versionNetwork;
- MessageType messageType;
-
- PortIdentity *sourcePortIdentity;
-
- uint16_t sequenceId;
- LegacyMessageType control;
- unsigned char flags[2];
-
- uint16_t messageLength;
- char logMeanMessageInterval;
- long long correctionField;
- unsigned char domainNumber;
-
- Timestamp _timestamp;
- unsigned _timestamp_counter_value;
- bool _gc;
-
- PTPMessageCommon(void) { };
- public:
- PTPMessageCommon(IEEE1588Port * port);
- virtual ~PTPMessageCommon(void);
-
- unsigned char *getFlags(void) {
- return flags;
- }
-
- uint16_t getSequenceId(void) {
- return sequenceId;
- }
- void setSequenceId(uint16_t seq) {
- sequenceId = seq;
- }
-
- MessageType getMessageType(void) {
- return messageType;
- }
-
- long long getCorrectionField(void) {
- return correctionField;
- }
- void setCorrectionField(long long correctionAmount) {
- correctionField = correctionAmount;
- }
-
- void getPortIdentity(PortIdentity * identity);
- void setPortIdentity(PortIdentity * identity);
-
- Timestamp getTimestamp(void) {
- return _timestamp;
- }
- uint32_t getTimestampCounterValue(void) {
- return _timestamp_counter_value;;
- }
- void setTimestamp(Timestamp & timestamp) {
- _timestamp = timestamp;
- }
-
- bool garbage() {
- return _gc;
- }
-
- bool isSenderEqual(PortIdentity portIdentity);
-
- virtual void processMessage(IEEE1588Port * port);
-
- void buildCommonHeader(uint8_t * buf);
-
- friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
-};
-
-#pragma pack(push,1)
-
-class PathTraceTLV {
- private:
- uint16_t tlvType;
- uint16_t lengthField;
- ClockIdentity identity;
- public:
- PathTraceTLV() {
- tlvType = PLAT_htons(0x8);
- lengthField = PLAT_htons(sizeof(identity));
- }
- void setClockIdentity(ClockIdentity * id) {
- identity = *id;
- }
- void toByteString(uint8_t * byte_str) {
- memcpy(byte_str, this, sizeof(*this));
- }
-};
-
-#pragma pack(pop)
-
-class PTPMessageAnnounce:public PTPMessageCommon {
- private:
- 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:
- PTPMessageAnnounce(IEEE1588Port * port);
- ~PTPMessageAnnounce();
-
- bool isBetterThan(PTPMessageAnnounce * msg);
-
- unsigned char getGrandmasterPriority1(void) {
- return grandmasterPriority1;
- }
- unsigned char getGrandmasterPriority2(void) {
- return grandmasterPriority2;
- }
-
- ClockQuality *getGrandmasterClockQuality(void) {
- return grandmasterClockQuality;
- }
-
- uint16_t getStepsRemoved(void) {
- return stepsRemoved;
- }
-
- void getGrandmasterIdentity(char *identity) {
- memcpy(identity, grandmasterIdentity, PTP_CLOCK_IDENTITY_LENGTH);
- }
- ClockIdentity getGrandmasterClockIdentity() {
- ClockIdentity ret;
- ret.set( grandmasterIdentity );
- return ret;
- }
-
- void processMessage(IEEE1588Port * port);
-
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
-
- friend PTPMessageCommon *buildPTPMessage(char *buf, int size,
- LinkLayerAddress * remote,
- IEEE1588Port * port);
-};
-
-class PTPMessageSync : public PTPMessageCommon {
- private:
- Timestamp originTimestamp;
-
- PTPMessageSync();
- public:
- PTPMessageSync(IEEE1588Port * port);
- ~PTPMessageSync();
- void processMessage(IEEE1588Port * port);
-
- Timestamp getOriginTimestamp(void) {
- return originTimestamp;
- }
-
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
-
- friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
-};
-
-#pragma pack(push,1)
-
-class scaledNs {
- private:
- int32_t ms;
- uint64_t ls;
- public:
- scaledNs() {
- ms = 0;
- ls = 0;
- } void toByteString(uint8_t * byte_str) {
- memcpy(byte_str, this, sizeof(*this));
- }
-};
-
-class FollowUpTLV {
- private:
- uint16_t tlvType;
- uint16_t lengthField;
- uint8_t organizationId[3];
- uint8_t organizationSubType_ms;
- uint16_t organizationSubType_ls;
- int32_t cumulativeScaledRateOffset;
- uint16_t gmTimeBaseIndicator;
- scaledNs scaledLastGmPhaseChange;
- int32_t scaledLastGmFreqChange;
- public:
- FollowUpTLV() {
- tlvType = PLAT_htons(0x3);
- lengthField = PLAT_htons(28);
- organizationId[0] = '\x00';
- organizationId[1] = '\x80';
- organizationId[2] = '\xC2';
- organizationSubType_ms = 0;
- organizationSubType_ls = PLAT_htons(1);
- cumulativeScaledRateOffset = PLAT_htonl(0);
- gmTimeBaseIndicator = PLAT_htons(0);
- scaledLastGmFreqChange = PLAT_htonl(0);
- }
- void toByteString(uint8_t * byte_str) {
- memcpy(byte_str, this, sizeof(*this));
- }
- int32_t getRateOffset() {
- return cumulativeScaledRateOffset;
- }
-};
-
-#pragma pack(pop)
-
-class PTPMessageFollowUp:public PTPMessageCommon {
-private:
- Timestamp preciseOriginTimestamp;
-
- FollowUpTLV tlv;
-
- PTPMessageFollowUp(void) { }
-public:
- PTPMessageFollowUp(IEEE1588Port * port);
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
- void processMessage(IEEE1588Port * port);
-
- Timestamp getPreciseOriginTimestamp(void) {
- return preciseOriginTimestamp;
- }
- void setPreciseOriginTimestamp(Timestamp & timestamp) {
- preciseOriginTimestamp = timestamp;
- }
-
- friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
-};
-
-class PTPMessagePathDelayReq : public PTPMessageCommon {
- private:
- Timestamp originTimestamp;
-
- PTPMessagePathDelayReq() {
- return;
- }
- public:
- ~PTPMessagePathDelayReq() {
- }
- PTPMessagePathDelayReq(IEEE1588Port * port);
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
- void processMessage(IEEE1588Port * port);
-
- Timestamp getOriginTimestamp(void) {
- return originTimestamp;
- }
-
- friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
-};
-
-class PTPMessagePathDelayResp:public PTPMessageCommon {
-private:
- PortIdentity * requestingPortIdentity;
- Timestamp requestReceiptTimestamp;
-
- PTPMessagePathDelayResp(void) {
- }
-public:
- ~PTPMessagePathDelayResp();
- PTPMessagePathDelayResp(IEEE1588Port * port);
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
- void processMessage(IEEE1588Port * port);
-
- void setRequestReceiptTimestamp(Timestamp timestamp) {
- requestReceiptTimestamp = timestamp;
- }
-
- void setRequestingPortIdentity(PortIdentity * identity);
- void getRequestingPortIdentity(PortIdentity * identity);
-
- Timestamp getRequestReceiptTimestamp(void) {
- return requestReceiptTimestamp;
- }
-
- friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
-};
-
-class PTPMessagePathDelayRespFollowUp:public PTPMessageCommon {
- private:
- Timestamp responseOriginTimestamp;
- PortIdentity *requestingPortIdentity;
-
- PTPMessagePathDelayRespFollowUp(void) { }
-public:
- PTPMessagePathDelayRespFollowUp(IEEE1588Port * port);
- ~PTPMessagePathDelayRespFollowUp();
- void sendPort(IEEE1588Port * port, PortIdentity * destIdentity);
- void processMessage(IEEE1588Port * port);
-
- void setResponseOriginTimestamp(Timestamp timestamp) {
- responseOriginTimestamp = timestamp;
- }
- void setRequestingPortIdentity(PortIdentity * identity);
-
- Timestamp getResponseOriginTimestamp(void) {
- return responseOriginTimestamp;
- }
- PortIdentity *getRequestingPortIdentity(void) {
- return requestingPortIdentity;
- }
-
- friend PTPMessageCommon *buildPTPMessage
- (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port);
-};
-
-#endif
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef AVBTS_MESSAGE_HPP +#define AVBTS_MESSAGE_HPP + +#include <stdint.h> +#include <avbts_osnet.hpp> +#include <ieee1588.hpp> + +#define PTP_CODE_STRING_LENGTH 4 +#define PTP_SUBDOMAIN_NAME_LENGTH 16 +#define PTP_FLAGS_LENGTH 2 + +#define GPTP_VERSION 2 +#define PTP_NETWORK_VERSION 1 + +#define PTP_ETHER 1 +#define PTP_DEFAULT 255 + +#define PTP_COMMON_HDR_OFFSET 0 +#define PTP_COMMON_HDR_LENGTH 34 +#define PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(x) x +#define PTP_COMMON_HDR_PTP_VERSION(x) x+1 +#define PTP_COMMON_HDR_MSG_LENGTH(x) x+2 +#define PTP_COMMON_HDR_DOMAIN_NUMBER(x) x+4 +#define PTP_COMMON_HDR_FLAGS(x) x+6 +#define PTP_COMMON_HDR_CORRECTION(x) x+8 +#define PTP_COMMON_HDR_SOURCE_CLOCK_ID(x) x+20 +#define PTP_COMMON_HDR_SOURCE_PORT_ID(x) x+28 +#define PTP_COMMON_HDR_SEQUENCE_ID(x) x+30 +#define PTP_COMMON_HDR_CONTROL(x) x+32 +#define PTP_COMMON_HDR_LOG_MSG_INTRVL(x) x+33 + +#define PTP_ANNOUNCE_OFFSET 34 +#define PTP_ANNOUNCE_LENGTH 30 +#define PTP_ANNOUNCE_CURRENT_UTC_OFFSET(x) x+10 +#define PTP_ANNOUNCE_GRANDMASTER_PRIORITY1(x) x+13 +#define PTP_ANNOUNCE_GRANDMASTER_CLOCK_QUALITY(x) x+14 +#define PTP_ANNOUNCE_GRANDMASTER_PRIORITY2(x) x+18 +#define PTP_ANNOUNCE_GRANDMASTER_IDENTITY(x) x+19 +#define PTP_ANNOUNCE_STEPS_REMOVED(x) x+27 +#define PTP_ANNOUNCE_TIME_SOURCE(x) x+29 + +#define PTP_SYNC_OFFSET 34 +#define PTP_SYNC_LENGTH 10 +#define PTP_SYNC_SEC_MS(x) x +#define PTP_SYNC_SEC_LS(x) x+2 +#define PTP_SYNC_NSEC(x) x+6 + +#define PTP_FOLLOWUP_OFFSET 34 +#define PTP_FOLLOWUP_LENGTH 10 +#define PTP_FOLLOWUP_SEC_MS(x) x +#define PTP_FOLLOWUP_SEC_LS(x) x+2 +#define PTP_FOLLOWUP_NSEC(x) x+6 + +#define PTP_PDELAY_REQ_OFFSET 34 +#define PTP_PDELAY_REQ_LENGTH 20 +#define PTP_PDELAY_REQ_SEC_MS(x) x +#define PTP_PDELAY_REQ_SEC_LS(x) x+2 +#define PTP_PDELAY_REQ_NSEC(x) x+6 + +#define PTP_PDELAY_RESP_OFFSET 34 +#define PTP_PDELAY_RESP_LENGTH 20 +#define PTP_PDELAY_RESP_SEC_MS(x) x +#define PTP_PDELAY_RESP_SEC_LS(x) x+2 +#define PTP_PDELAY_RESP_NSEC(x) x+6 +#define PTP_PDELAY_RESP_REQ_CLOCK_ID(x) x+10 +#define PTP_PDELAY_RESP_REQ_PORT_ID(x) x+18 + +#define PTP_PDELAY_FOLLOWUP_OFFSET 34 +#define PTP_PDELAY_FOLLOWUP_LENGTH 20 +#define PTP_PDELAY_FOLLOWUP_SEC_MS(x) x +#define PTP_PDELAY_FOLLOWUP_SEC_LS(x) x+2 +#define PTP_PDELAY_FOLLOWUP_NSEC(x) x+6 +#define PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID(x) x+10 +#define PTP_PDELAY_FOLLOWUP_REQ_PORT_ID(x) x+18 + +#define PTP_LI_61_BYTE 1 +#define PTP_LI_61_BIT 0 +#define PTP_LI_59_BYTE 1 +#define PTP_LI_59_BIT 1 +#define PTP_ASSIST_BYTE 0 +#define PTP_ASSIST_BIT 1 +#define PTP_PTPTIMESCALE_BYTE 1 +#define PTP_PTPTIMESCALE_BIT 3 + +#define TX_TIMEOUT_BASE 1000 /* microseconds */ +#define TX_TIMEOUT_ITER 6 + +enum MessageType { + SYNC_MESSAGE = 0, + DELAY_REQ_MESSAGE = 1, + PATH_DELAY_REQ_MESSAGE = 2, + PATH_DELAY_RESP_MESSAGE = 3, + FOLLOWUP_MESSAGE = 8, + DELAY_RESP_MESSAGE = 9, + PATH_DELAY_FOLLOWUP_MESSAGE = 0xA, + ANNOUNCE_MESSAGE = 0xB, + SIGNALLING_MESSAGE = 0xC, + MANAGEMENT_MESSAGE = 0xD, +}; + +enum LegacyMessageType { + SYNC, + DELAY_REQ, + FOLLOWUP, + DELAY_RESP, + MANAGEMENT, + MESSAGE_OTHER +}; + +enum MulticastType { + MCAST_NONE, + MCAST_PDELAY, + MCAST_OTHER +}; + +class PTPMessageCommon { +protected: + unsigned char versionPTP; + uint16_t versionNetwork; + MessageType messageType; + + PortIdentity *sourcePortIdentity; + + uint16_t sequenceId; + LegacyMessageType control; + unsigned char flags[2]; + + uint16_t messageLength; + char logMeanMessageInterval; + long long correctionField; + unsigned char domainNumber; + + Timestamp _timestamp; + unsigned _timestamp_counter_value; + bool _gc; + + PTPMessageCommon(void) { }; + public: + PTPMessageCommon(IEEE1588Port * port); + virtual ~PTPMessageCommon(void); + + unsigned char *getFlags(void) { + return flags; + } + + uint16_t getSequenceId(void) { + return sequenceId; + } + void setSequenceId(uint16_t seq) { + sequenceId = seq; + } + + MessageType getMessageType(void) { + return messageType; + } + + long long getCorrectionField(void) { + return correctionField; + } + void setCorrectionField(long long correctionAmount) { + correctionField = correctionAmount; + } + + void getPortIdentity(PortIdentity * identity); + void setPortIdentity(PortIdentity * identity); + + Timestamp getTimestamp(void) { + return _timestamp; + } + uint32_t getTimestampCounterValue(void) { + return _timestamp_counter_value;; + } + void setTimestamp(Timestamp & timestamp) { + _timestamp = timestamp; + } + + bool garbage() { + return _gc; + } + + bool isSenderEqual(PortIdentity portIdentity); + + virtual void processMessage(IEEE1588Port * port); + + void buildCommonHeader(uint8_t * buf); + + friend PTPMessageCommon *buildPTPMessage + (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port); +}; + +#pragma pack(push,1) + +class PathTraceTLV { + private: + uint16_t tlvType; + uint16_t lengthField; + ClockIdentity identity; + public: + PathTraceTLV() { + tlvType = PLAT_htons(0x8); + lengthField = PLAT_htons(sizeof(identity)); + } + void setClockIdentity(ClockIdentity * id) { + identity = *id; + } + void toByteString(uint8_t * byte_str) { + memcpy(byte_str, this, sizeof(*this)); + } +}; + +#pragma pack(pop) + +class PTPMessageAnnounce:public PTPMessageCommon { + private: + 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: + PTPMessageAnnounce(IEEE1588Port * port); + ~PTPMessageAnnounce(); + + bool isBetterThan(PTPMessageAnnounce * msg); + + unsigned char getGrandmasterPriority1(void) { + return grandmasterPriority1; + } + unsigned char getGrandmasterPriority2(void) { + return grandmasterPriority2; + } + + ClockQuality *getGrandmasterClockQuality(void) { + return grandmasterClockQuality; + } + + uint16_t getStepsRemoved(void) { + return stepsRemoved; + } + + void getGrandmasterIdentity(char *identity) { + memcpy(identity, grandmasterIdentity, PTP_CLOCK_IDENTITY_LENGTH); + } + ClockIdentity getGrandmasterClockIdentity() { + ClockIdentity ret; + ret.set( grandmasterIdentity ); + return ret; + } + + void processMessage(IEEE1588Port * port); + + void sendPort(IEEE1588Port * port, PortIdentity * destIdentity); + + friend PTPMessageCommon *buildPTPMessage(char *buf, int size, + LinkLayerAddress * remote, + IEEE1588Port * port); +}; + +class PTPMessageSync : public PTPMessageCommon { + private: + Timestamp originTimestamp; + + PTPMessageSync(); + public: + PTPMessageSync(IEEE1588Port * port); + ~PTPMessageSync(); + void processMessage(IEEE1588Port * port); + + Timestamp getOriginTimestamp(void) { + return originTimestamp; + } + + void sendPort(IEEE1588Port * port, PortIdentity * destIdentity); + + friend PTPMessageCommon *buildPTPMessage + (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port); +}; + +#pragma pack(push,1) + +class scaledNs { + private: + int32_t ms; + uint64_t ls; + public: + scaledNs() { + ms = 0; + ls = 0; + } void toByteString(uint8_t * byte_str) { + memcpy(byte_str, this, sizeof(*this)); + } +}; + +class FollowUpTLV { + private: + uint16_t tlvType; + uint16_t lengthField; + uint8_t organizationId[3]; + uint8_t organizationSubType_ms; + uint16_t organizationSubType_ls; + int32_t cumulativeScaledRateOffset; + uint16_t gmTimeBaseIndicator; + scaledNs scaledLastGmPhaseChange; + int32_t scaledLastGmFreqChange; + public: + FollowUpTLV() { + tlvType = PLAT_htons(0x3); + lengthField = PLAT_htons(28); + organizationId[0] = '\x00'; + organizationId[1] = '\x80'; + organizationId[2] = '\xC2'; + organizationSubType_ms = 0; + organizationSubType_ls = PLAT_htons(1); + cumulativeScaledRateOffset = PLAT_htonl(0); + gmTimeBaseIndicator = PLAT_htons(0); + scaledLastGmFreqChange = PLAT_htonl(0); + } + void toByteString(uint8_t * byte_str) { + memcpy(byte_str, this, sizeof(*this)); + } + int32_t getRateOffset() { + return cumulativeScaledRateOffset; + } +}; + +#pragma pack(pop) + +class PTPMessageFollowUp:public PTPMessageCommon { +private: + Timestamp preciseOriginTimestamp; + + FollowUpTLV tlv; + + PTPMessageFollowUp(void) { } +public: + PTPMessageFollowUp(IEEE1588Port * port); + void sendPort(IEEE1588Port * port, PortIdentity * destIdentity); + void processMessage(IEEE1588Port * port); + + Timestamp getPreciseOriginTimestamp(void) { + return preciseOriginTimestamp; + } + void setPreciseOriginTimestamp(Timestamp & timestamp) { + preciseOriginTimestamp = timestamp; + } + + friend PTPMessageCommon *buildPTPMessage + (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port); +}; + +class PTPMessagePathDelayReq : public PTPMessageCommon { + private: + Timestamp originTimestamp; + + PTPMessagePathDelayReq() { + return; + } + public: + ~PTPMessagePathDelayReq() { + } + PTPMessagePathDelayReq(IEEE1588Port * port); + void sendPort(IEEE1588Port * port, PortIdentity * destIdentity); + void processMessage(IEEE1588Port * port); + + Timestamp getOriginTimestamp(void) { + return originTimestamp; + } + + friend PTPMessageCommon *buildPTPMessage + (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port); +}; + +class PTPMessagePathDelayResp:public PTPMessageCommon { +private: + PortIdentity * requestingPortIdentity; + Timestamp requestReceiptTimestamp; + + PTPMessagePathDelayResp(void) { + } +public: + ~PTPMessagePathDelayResp(); + PTPMessagePathDelayResp(IEEE1588Port * port); + void sendPort(IEEE1588Port * port, PortIdentity * destIdentity); + void processMessage(IEEE1588Port * port); + + void setRequestReceiptTimestamp(Timestamp timestamp) { + requestReceiptTimestamp = timestamp; + } + + void setRequestingPortIdentity(PortIdentity * identity); + void getRequestingPortIdentity(PortIdentity * identity); + + Timestamp getRequestReceiptTimestamp(void) { + return requestReceiptTimestamp; + } + + friend PTPMessageCommon *buildPTPMessage + (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port); +}; + +class PTPMessagePathDelayRespFollowUp:public PTPMessageCommon { + private: + Timestamp responseOriginTimestamp; + PortIdentity *requestingPortIdentity; + + PTPMessagePathDelayRespFollowUp(void) { } +public: + PTPMessagePathDelayRespFollowUp(IEEE1588Port * port); + ~PTPMessagePathDelayRespFollowUp(); + void sendPort(IEEE1588Port * port, PortIdentity * destIdentity); + void processMessage(IEEE1588Port * port); + + void setResponseOriginTimestamp(Timestamp timestamp) { + responseOriginTimestamp = timestamp; + } + void setRequestingPortIdentity(PortIdentity * identity); + + Timestamp getResponseOriginTimestamp(void) { + return responseOriginTimestamp; + } + PortIdentity *getRequestingPortIdentity(void) { + return requestingPortIdentity; + } + + friend PTPMessageCommon *buildPTPMessage + (char *buf, int size, LinkLayerAddress * remote, IEEE1588Port * port); +}; + +#endif diff --git a/daemons/gptp/common/avbts_oscondition.hpp b/daemons/gptp/common/avbts_oscondition.hpp index 769d8002..56c3fe84 100644 --- a/daemons/gptp/common/avbts_oscondition.hpp +++ b/daemons/gptp/common/avbts_oscondition.hpp @@ -1,71 +1,71 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_OSSIGNAL_HPP
-#define AVBTS_OSSIGNAL_HPP
-
-class OSCondition {
-private:
- int wait_count;
-public:
- virtual bool wait() = 0;
- virtual bool wait_prelock() = 0;
- virtual bool signal() = 0;
- virtual ~OSCondition() = 0;
-protected:
- OSCondition() {
- wait_count = 0;
- };
- void up() {
- ++wait_count;
- }
- void down() {
- --wait_count;
- }
- bool waiting() {
- return wait_count > 0;
- }
-};
-
-inline OSCondition::~OSCondition() { }
-
-class OSConditionFactory {
-public:
- virtual OSCondition * createCondition() = 0;
- virtual ~OSConditionFactory() = 0;
-};
-
-inline OSConditionFactory::~OSConditionFactory() {}
-
-
-#endif
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef AVBTS_OSSIGNAL_HPP +#define AVBTS_OSSIGNAL_HPP + +class OSCondition { +private: + int wait_count; +public: + virtual bool wait() = 0; + virtual bool wait_prelock() = 0; + virtual bool signal() = 0; + virtual ~OSCondition() = 0; +protected: + OSCondition() { + wait_count = 0; + }; + void up() { + ++wait_count; + } + void down() { + --wait_count; + } + bool waiting() { + return wait_count > 0; + } +}; + +inline OSCondition::~OSCondition() { } + +class OSConditionFactory { +public: + virtual OSCondition * createCondition() = 0; + virtual ~OSConditionFactory() = 0; +}; + +inline OSConditionFactory::~OSConditionFactory() {} + + +#endif diff --git a/daemons/gptp/common/avbts_osipc.hpp b/daemons/gptp/common/avbts_osipc.hpp index 8120efaf..c686be11 100644 --- a/daemons/gptp/common/avbts_osipc.hpp +++ b/daemons/gptp/common/avbts_osipc.hpp @@ -1,63 +1,63 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_OSIPC_HPP
-#define AVBTS_OSIPC_HPP
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <ptptypes.hpp>
-#include <avbts_port.hpp>
-
-class OS_IPC_ARG {
-public:
- virtual ~OS_IPC_ARG() = 0;
-};
-
-inline OS_IPC_ARG::~OS_IPC_ARG () { }
-
-class OS_IPC {
-public:
- virtual bool init( OS_IPC_ARG *arg = NULL ) = 0;
- 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 ) = 0;
- virtual ~OS_IPC() = 0;
-};
-
-inline OS_IPC::~OS_IPC() {}
-
-#endif
-
+/****************************************************************************** + + 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 <stdlib.h> +#include <ptptypes.hpp> +#include <avbts_port.hpp> + +class OS_IPC_ARG { +public: + virtual ~OS_IPC_ARG() = 0; +}; + +inline OS_IPC_ARG::~OS_IPC_ARG () { } + +class OS_IPC { +public: + virtual bool init( OS_IPC_ARG *arg = NULL ) = 0; + 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 ) = 0; + 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 index 89262495..bb12c5f2 100644 --- a/daemons/gptp/common/avbts_oslock.hpp +++ b/daemons/gptp/common/avbts_oslock.hpp @@ -1,62 +1,62 @@ -/******************************************************************************
-
- Copyright (c) 2001-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_OSLOCK_HPP
-#define AVBTS_OSLOCK_HPP
-typedef enum { oslock_recursive, oslock_nonrecursive } OSLockType;
-typedef enum { oslock_ok, oslock_self, oslock_held, oslock_fail } OSLockResult;
-
-class OSLock {
- public:
- virtual OSLockResult lock() = 0;
- virtual OSLockResult unlock() = 0;
- virtual OSLockResult trylock() = 0;
- protected:
- OSLock() { }
- bool initialize(OSLockType type) {
- return false;
- }
- virtual ~OSLock() = 0;
-};
-
-inline OSLock::~OSLock() {}
-
-class OSLockFactory {
-public:
- virtual OSLock * createLock(OSLockType type) = 0;
- virtual ~OSLockFactory() = 0;
-};
-
-inline OSLockFactory::~OSLockFactory () {}
-
-#endif
+/****************************************************************************** + + Copyright (c) 2001-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef AVBTS_OSLOCK_HPP +#define AVBTS_OSLOCK_HPP +typedef enum { oslock_recursive, oslock_nonrecursive } OSLockType; +typedef enum { oslock_ok, oslock_self, oslock_held, oslock_fail } OSLockResult; + +class OSLock { + public: + virtual OSLockResult lock() = 0; + virtual OSLockResult unlock() = 0; + virtual OSLockResult trylock() = 0; + protected: + OSLock() { } + bool initialize(OSLockType type) { + return false; + } + virtual ~OSLock() = 0; +}; + +inline OSLock::~OSLock() {} + +class OSLockFactory { +public: + virtual OSLock * createLock(OSLockType type) = 0; + virtual ~OSLockFactory() = 0; +}; + +inline OSLockFactory::~OSLockFactory () {} + +#endif diff --git a/daemons/gptp/common/avbts_osnet.cpp b/daemons/gptp/common/avbts_osnet.cpp index fd93727f..57c751e8 100644 --- a/daemons/gptp/common/avbts_osnet.cpp +++ b/daemons/gptp/common/avbts_osnet.cpp @@ -1,38 +1,38 @@ -/******************************************************************************
-
- 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;
+/****************************************************************************** + + 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 index f3762958..7b2c348f 100644 --- a/daemons/gptp/common/avbts_osnet.hpp +++ b/daemons/gptp/common/avbts_osnet.hpp @@ -1,183 +1,183 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_OSNET_HPP
-#define AVBTS_OSNET_HPP
-
-#include <stdint.h>
-#include <string.h>
-#include <map>
-#include <ieee1588.hpp>
-
-#define FACTORY_NAME_LENGTH 48
-#define ETHER_ADDR_OCTETS 6
-#define PTP_ETHERTYPE 0x88F7
-#define DEFAULT_TIMEOUT 1 // milliseconds
-
-class LinkLayerAddress:public InterfaceLabel {
- private:
- uint8_t addr[ETHER_ADDR_OCTETS];
- public:
- LinkLayerAddress() {
- };
- LinkLayerAddress(uint64_t address_scalar) {
- uint8_t *ptr;
- address_scalar <<= 16;
- for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS; ++ptr) {
- *ptr = (address_scalar & 0xFF00000000000000ULL) >> 56;
- address_scalar <<= 8;
- }
- }
- LinkLayerAddress(uint8_t * address_octet_array) {
- uint8_t *ptr;
- for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS;
- ++ptr, ++address_octet_array)
- {
- *ptr = *address_octet_array;
- }
- }
- bool operator==(const LinkLayerAddress & cmp) const {
- return memcmp
- (this->addr, cmp.addr, ETHER_ADDR_OCTETS) == 0 ? true : false;
- }
- bool operator<(const LinkLayerAddress & cmp)const {
- return memcmp
- (this->addr, cmp.addr, ETHER_ADDR_OCTETS) < 0 ? true : false;
- }
- bool operator>(const LinkLayerAddress & cmp)const {
- return memcmp
- (this->addr, cmp.addr, ETHER_ADDR_OCTETS) < 0 ? true : false;
- }
- void toOctetArray(uint8_t * address_octet_array) {
- uint8_t *ptr;
- for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS;
- ++ptr, ++address_octet_array)
- {
- *address_octet_array = *ptr;
- }
- }
-};
-
-class InterfaceName: public InterfaceLabel {
- private:
- char *name;
- public:
- InterfaceName() { }
- InterfaceName(char *name, int length) {
- this->name = new char[length + 1];
- PLAT_strncpy(this->name, name, length);
- }
- bool operator==(const InterfaceName & cmp) const {
- return strcmp(name, cmp.name) == 0 ? true : false;
- }
- bool operator<(const InterfaceName & cmp)const {
- return strcmp(name, cmp.name) < 0 ? true : false;
- }
- bool operator>(const InterfaceName & cmp)const {
- return strcmp(name, cmp.name) < 0 ? true : false;
- }
- bool toString(char *string, size_t length) {
- if (length >= strlen(name) + 1) {
- PLAT_strncpy(string, name, length);
- return true;
- }
- return false;
- }
-};
-
-class factory_name_t {
- private:
- char name[FACTORY_NAME_LENGTH];
- factory_name_t();
- public:
- factory_name_t(const char *name_a) {
- PLAT_strncpy(name, name_a, FACTORY_NAME_LENGTH - 1);
- }
- bool operator==(const factory_name_t & cmp) {
- return strcmp(cmp.name, this->name) == 0 ? true : false;
- }
- bool operator<(const factory_name_t & cmp)const {
- return strcmp(cmp.name, this->name) < 0 ? true : false;
- }
- bool operator>(const factory_name_t & cmp)const {
- return strcmp(cmp.name, this->name) > 0 ? true : false;
- }
-};
-
-typedef enum { net_trfail, net_fatal, net_succeed } net_result;
-
-class OSNetworkInterface {
- public:
- virtual net_result send
- (LinkLayerAddress * addr, uint8_t * payload, size_t length,
- bool timestamp) = 0;
- virtual net_result recv
- (LinkLayerAddress * addr, uint8_t * payload, size_t & length) = 0;
- virtual void getLinkLayerAddress(LinkLayerAddress * addr) = 0;
- virtual unsigned getPayloadOffset() = 0;
- virtual ~OSNetworkInterface() = 0;
-};
-
-inline OSNetworkInterface::~OSNetworkInterface() {}
-
-class OSNetworkInterfaceFactory;
-
-typedef std::map < factory_name_t, OSNetworkInterfaceFactory * >FactoryMap_t;
-
-class OSNetworkInterfaceFactory {
- public:
- static bool registerFactory
- (factory_name_t id, OSNetworkInterfaceFactory * factory) {
- FactoryMap_t::iterator iter = factoryMap.find(id);
- if (iter != factoryMap.end())
- return false;
- factoryMap[id] = factory;
- return true;
- }
- static bool buildInterface
- (OSNetworkInterface ** iface, factory_name_t id, InterfaceLabel * iflabel,
- HWTimestamper * timestamper) {
- return factoryMap[id]->createInterface
- (iface, iflabel, timestamper);
- }
- virtual ~OSNetworkInterfaceFactory() = 0;
-private:
- virtual bool createInterface
- (OSNetworkInterface ** iface, InterfaceLabel * iflabel,
- HWTimestamper * timestamper) = 0;
- static FactoryMap_t factoryMap;
-};
-
-inline OSNetworkInterfaceFactory::~OSNetworkInterfaceFactory() { }
-
-#endif
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef AVBTS_OSNET_HPP +#define AVBTS_OSNET_HPP + +#include <stdint.h> +#include <string.h> +#include <map> +#include <ieee1588.hpp> + +#define FACTORY_NAME_LENGTH 48 +#define ETHER_ADDR_OCTETS 6 +#define PTP_ETHERTYPE 0x88F7 +#define DEFAULT_TIMEOUT 1 // milliseconds + +class LinkLayerAddress:public InterfaceLabel { + private: + uint8_t addr[ETHER_ADDR_OCTETS]; + public: + LinkLayerAddress() { + }; + LinkLayerAddress(uint64_t address_scalar) { + uint8_t *ptr; + address_scalar <<= 16; + for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS; ++ptr) { + *ptr = (address_scalar & 0xFF00000000000000ULL) >> 56; + address_scalar <<= 8; + } + } + LinkLayerAddress(uint8_t * address_octet_array) { + uint8_t *ptr; + for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS; + ++ptr, ++address_octet_array) + { + *ptr = *address_octet_array; + } + } + bool operator==(const LinkLayerAddress & cmp) const { + return memcmp + (this->addr, cmp.addr, ETHER_ADDR_OCTETS) == 0 ? true : false; + } + bool operator<(const LinkLayerAddress & cmp)const { + return memcmp + (this->addr, cmp.addr, ETHER_ADDR_OCTETS) < 0 ? true : false; + } + bool operator>(const LinkLayerAddress & cmp)const { + return memcmp + (this->addr, cmp.addr, ETHER_ADDR_OCTETS) < 0 ? true : false; + } + void toOctetArray(uint8_t * address_octet_array) { + uint8_t *ptr; + for (ptr = addr; ptr < addr + ETHER_ADDR_OCTETS; + ++ptr, ++address_octet_array) + { + *address_octet_array = *ptr; + } + } +}; + +class InterfaceName: public InterfaceLabel { + private: + char *name; + public: + InterfaceName() { } + InterfaceName(char *name, int length) { + this->name = new char[length + 1]; + PLAT_strncpy(this->name, name, length); + } + bool operator==(const InterfaceName & cmp) const { + return strcmp(name, cmp.name) == 0 ? true : false; + } + bool operator<(const InterfaceName & cmp)const { + return strcmp(name, cmp.name) < 0 ? true : false; + } + bool operator>(const InterfaceName & cmp)const { + return strcmp(name, cmp.name) < 0 ? true : false; + } + bool toString(char *string, size_t length) { + if (length >= strlen(name) + 1) { + PLAT_strncpy(string, name, length); + return true; + } + return false; + } +}; + +class factory_name_t { + private: + char name[FACTORY_NAME_LENGTH]; + factory_name_t(); + public: + factory_name_t(const char *name_a) { + PLAT_strncpy(name, name_a, FACTORY_NAME_LENGTH - 1); + } + bool operator==(const factory_name_t & cmp) { + return strcmp(cmp.name, this->name) == 0 ? true : false; + } + bool operator<(const factory_name_t & cmp)const { + return strcmp(cmp.name, this->name) < 0 ? true : false; + } + bool operator>(const factory_name_t & cmp)const { + return strcmp(cmp.name, this->name) > 0 ? true : false; + } +}; + +typedef enum { net_trfail, net_fatal, net_succeed } net_result; + +class OSNetworkInterface { + public: + virtual net_result send + (LinkLayerAddress * addr, uint8_t * payload, size_t length, + bool timestamp) = 0; + virtual net_result recv + (LinkLayerAddress * addr, uint8_t * payload, size_t & length) = 0; + virtual void getLinkLayerAddress(LinkLayerAddress * addr) = 0; + virtual unsigned getPayloadOffset() = 0; + virtual ~OSNetworkInterface() = 0; +}; + +inline OSNetworkInterface::~OSNetworkInterface() {} + +class OSNetworkInterfaceFactory; + +typedef std::map < factory_name_t, OSNetworkInterfaceFactory * >FactoryMap_t; + +class OSNetworkInterfaceFactory { + public: + static bool registerFactory + (factory_name_t id, OSNetworkInterfaceFactory * factory) { + FactoryMap_t::iterator iter = factoryMap.find(id); + if (iter != factoryMap.end()) + return false; + factoryMap[id] = factory; + return true; + } + static bool buildInterface + (OSNetworkInterface ** iface, factory_name_t id, InterfaceLabel * iflabel, + HWTimestamper * timestamper) { + return factoryMap[id]->createInterface + (iface, iflabel, timestamper); + } + virtual ~OSNetworkInterfaceFactory() = 0; +private: + virtual bool createInterface + (OSNetworkInterface ** iface, InterfaceLabel * iflabel, + HWTimestamper * 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 index d0041031..f87f5107 100644 --- a/daemons/gptp/common/avbts_osthread.hpp +++ b/daemons/gptp/common/avbts_osthread.hpp @@ -1,57 +1,57 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_OSTHREAD_HPP
-#define AVBTS_OSTHREAD_HPP
-typedef enum { osthread_ok, osthread_error } OSThreadExitCode;
-typedef OSThreadExitCode(*OSThreadFunction) (void *);
-
-class OSThread {
-public:
- virtual bool start(OSThreadFunction function, void *arg) = 0;
- virtual bool join(OSThreadExitCode & exit_code) = 0;
- virtual ~OSThread() = 0;
-};
-
-inline OSThread::~OSThread() {}
-
-class OSThreadFactory {
-public:
- virtual OSThread * createThread() = 0;
- virtual ~OSThreadFactory() = 0;
-};
-
-inline OSThreadFactory::~OSThreadFactory() {}
-
-
-#endif
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef AVBTS_OSTHREAD_HPP +#define AVBTS_OSTHREAD_HPP +typedef enum { osthread_ok, osthread_error } OSThreadExitCode; +typedef OSThreadExitCode(*OSThreadFunction) (void *); + +class OSThread { +public: + virtual bool start(OSThreadFunction function, void *arg) = 0; + virtual bool join(OSThreadExitCode & exit_code) = 0; + virtual ~OSThread() = 0; +}; + +inline OSThread::~OSThread() {} + +class OSThreadFactory { +public: + virtual OSThread * createThread() = 0; + virtual ~OSThreadFactory() = 0; +}; + +inline OSThreadFactory::~OSThreadFactory() {} + + +#endif diff --git a/daemons/gptp/common/avbts_ostimer.hpp b/daemons/gptp/common/avbts_ostimer.hpp index 41f3411c..2b17260a 100644 --- a/daemons/gptp/common/avbts_ostimer.hpp +++ b/daemons/gptp/common/avbts_ostimer.hpp @@ -1,53 +1,53 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_OSTIMER_HPP
-#define AVBTS_OSTIMER_HPP
-
-class OSTimer {
-public:
- virtual unsigned long sleep(unsigned long micro) = 0;
- virtual ~OSTimer() = 0;
-};
-
-inline OSTimer::~OSTimer() {}
-
-class OSTimerFactory {
-public:
- virtual OSTimer * createTimer() = 0;
- virtual ~OSTimerFactory() = 0;
-};
-
-inline OSTimerFactory::~OSTimerFactory() {}
-
-#endif
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef AVBTS_OSTIMER_HPP +#define AVBTS_OSTIMER_HPP + +class OSTimer { +public: + virtual unsigned long sleep(unsigned long micro) = 0; + virtual ~OSTimer() = 0; +}; + +inline OSTimer::~OSTimer() {} + +class OSTimerFactory { +public: + virtual OSTimer * createTimer() = 0; + virtual ~OSTimerFactory() = 0; +}; + +inline OSTimerFactory::~OSTimerFactory() {} + +#endif diff --git a/daemons/gptp/common/avbts_ostimerq.hpp b/daemons/gptp/common/avbts_ostimerq.hpp index 578307da..3810fedb 100644 --- a/daemons/gptp/common/avbts_ostimerq.hpp +++ b/daemons/gptp/common/avbts_ostimerq.hpp @@ -1,60 +1,60 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_OSTIMERQ_HPP
-#define AVBTS_OSTIMERQ_HPP
-
-typedef void (*ostimerq_handler) (void *);
-
-class IEEE1588Clock;
-
-class OSTimerQueue {
-public:
- virtual bool addEvent
- (unsigned long micros, int type, ostimerq_handler func,
- event_descriptor_t * arg, bool dynamic, unsigned *event) = 0;
- virtual bool cancelEvent(int type, unsigned *event) = 0;
- virtual ~OSTimerQueue() = 0;
-};
-
-inline OSTimerQueue::~OSTimerQueue() {}
-
-class OSTimerQueueFactory {
-public:
- virtual OSTimerQueue *createOSTimerQueue( IEEE1588Clock *clock ) = 0;
- virtual ~OSTimerQueueFactory() = 0;
-};
-
-inline OSTimerQueueFactory::~OSTimerQueueFactory() {}
-
-#endif
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef AVBTS_OSTIMERQ_HPP +#define AVBTS_OSTIMERQ_HPP + +typedef void (*ostimerq_handler) (void *); + +class IEEE1588Clock; + +class OSTimerQueue { +public: + virtual bool addEvent + (unsigned long micros, int type, ostimerq_handler func, + event_descriptor_t * arg, bool dynamic, unsigned *event) = 0; + virtual bool cancelEvent(int type, unsigned *event) = 0; + virtual ~OSTimerQueue() = 0; +}; + +inline OSTimerQueue::~OSTimerQueue() {} + +class OSTimerQueueFactory { +public: + virtual OSTimerQueue *createOSTimerQueue( IEEE1588Clock *clock ) = 0; + virtual ~OSTimerQueueFactory() = 0; +}; + +inline OSTimerQueueFactory::~OSTimerQueueFactory() {} + +#endif diff --git a/daemons/gptp/common/avbts_port.hpp b/daemons/gptp/common/avbts_port.hpp index bc73d73c..8c78d936 100644 --- a/daemons/gptp/common/avbts_port.hpp +++ b/daemons/gptp/common/avbts_port.hpp @@ -1,454 +1,454 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef AVBTS_PORT_HPP
-#define AVBTS_PORT_HPP
-
-#include <ieee1588.hpp>
-#include <avbts_message.hpp>
-
-#include <avbts_ostimer.hpp>
-#include <avbts_oslock.hpp>
-#include <avbts_osnet.hpp>
-#include <avbts_osthread.hpp>
-#include <avbts_oscondition.hpp>
-
-#include <stdint.h>
-
-#include <map>
-#include <list>
-
-#define GPTP_MULTICAST 0x0180C200000EULL
-#define PDELAY_MULTICAST GPTP_MULTICAST
-#define OTHER_MULTICAST GPTP_MULTICAST
-
-#define PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER 3
-#define SYNC_RECEIPT_TIMEOUT_MULTIPLIER 3
-#define ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER 3
-
-typedef enum {
- PTP_MASTER = 7,
- PTP_PRE_MASTER,
- PTP_SLAVE,
- PTP_UNCALIBRATED,
- PTP_DISABLED,
- PTP_FAULTY,
- PTP_INITIALIZING,
- PTP_LISTENING
-} PortState;
-
-typedef enum {
- V1,
- V2_E2E,
- V2_P2P
-} PortType;
-
-class PortIdentity {
-private:
- ClockIdentity clock_id;
- uint16_t portNumber;
-public:
- PortIdentity() { };
- PortIdentity(uint8_t * clock_id, uint16_t * portNumber) {
- this->portNumber = *portNumber;
- this->portNumber = PLAT_ntohs(this->portNumber);
- this->clock_id.set(clock_id);
- }
- bool operator!=(const PortIdentity & cmp) const {
- return
- !(this->clock_id == cmp.clock_id) ||
- this->portNumber != cmp.portNumber ? true : false;
- }
- bool operator==(const PortIdentity & cmp)const {
- return
- this->clock_id == cmp.clock_id &&
- this->portNumber == cmp.portNumber ? true : false;
- }
- bool operator<(const PortIdentity & cmp)const {
- return
- this->clock_id < cmp.clock_id ?
- true : this->clock_id == cmp.clock_id &&
- this->portNumber < cmp.portNumber ? true : false;
- }
- bool operator>(const PortIdentity & cmp)const {
- return
- this->clock_id > cmp.clock_id ?
- true : this->clock_id == cmp.clock_id &&
- this->portNumber > cmp.portNumber ? true : false;
- }
- void getClockIdentityString(uint8_t *id) {
- clock_id.getIdentityString(id);
- }
- void setClockIdentity(ClockIdentity clock_id) {
- this->clock_id = clock_id;
- }
- ClockIdentity getClockIdentity( void ) {
- return this->clock_id;
- }
- void getPortNumberNO(uint16_t * id) { // Network byte order
- uint16_t portNumberNO = PLAT_htons(portNumber);
- *id = portNumberNO;
- }
- void getPortNumber(uint16_t * id) { // Host byte order
- *id = portNumber;
- }
- void setPortNumber(uint16_t * id) {
- portNumber = *id;
- }
-};
-
-typedef std::map < PortIdentity, LinkLayerAddress > IdentityMap_t;
-
-class IEEE1588Port {
- static LinkLayerAddress other_multicast;
- static LinkLayerAddress pdelay_multicast;
-
- PortIdentity port_identity;
- /* directly connected node */
- PortIdentity peer_identity;
-
- OSNetworkInterface *net_iface;
- LinkLayerAddress local_addr;
-
- /* Port Status */
- unsigned sync_count; // 0 for master, ++ for each sync receive as slave
- // set to 0 when asCapable is false, increment for each pdelay recvd
- unsigned pdelay_count;
-
- /* Port Configuration */
- unsigned char delay_mechanism;
- PortState port_state;
- char log_mean_unicast_sync_interval;
- char log_mean_sync_interval;
- char log_mean_announce_interval;
- char log_min_mean_delay_req_interval;
- char log_min_mean_pdelay_req_interval;
- bool burst_enabled;
- int _accelerated_sync_count;
- /* Signed value allows this to be negative result because of inaccurate
- timestamp */
- int64_t one_way_delay;
- /* Implementation Specific data/methods */
- IEEE1588Clock *clock;
-
- bool _syntonize;
-
- bool asCapable;
-
- int32_t *rate_offset_array;
- uint32_t rate_offset_array_size;
- uint32_t rate_offset_count;
- uint32_t rate_offset_index;
-
- FrequencyRatio _peer_rate_offset;
- Timestamp _peer_offset_ts_theirs;
- Timestamp _peer_offset_ts_mine;
- bool _peer_offset_init;
-
- int32_t _initial_clock_offset;
- int32_t _current_clock_offset;
-
- PTPMessageAnnounce *qualified_announce;
-
- uint16_t announce_sequence_id;
- uint16_t sync_sequence_id;
-
- uint16_t pdelay_sequence_id;
- PTPMessagePathDelayReq *last_pdelay_req;
- PTPMessagePathDelayResp *last_pdelay_resp;
- PTPMessagePathDelayRespFollowUp *last_pdelay_resp_fwup;
-
- /* Network socket description
- physical interface number that object represents */
- uint16_t ifindex;
-
- IdentityMap_t identity_map;
-
- PTPMessageSync *last_sync;
-
- OSThread *listening_thread;
-
- OSCondition *port_ready_condition;
-
- OSLock *pdelay_rx_lock;
- OSLock *port_tx_lock;
-
- OSThreadFactory *thread_factory;
- OSTimerFactory *timer_factory;
-
- HWTimestamper *_hw_timestamper;
-
- net_result port_send
- (uint8_t * buf, int size, MulticastType mcast_type,
- PortIdentity * destIdentity, bool timestamp);
-
- InterfaceLabel *net_label;
-
- OSLockFactory *lock_factory;
- OSConditionFactory *condition_factory;
-
- bool pdelay_started;
- public:
- // Added for testing
- bool forceSlave;
-
- bool serializeState( void *buf, off_t *count );
- bool restoreSerializedState( void *buf, off_t *count );
- void becomeMaster( bool annc );
- void becomeSlave( bool );
-
- void startPDelay();
- void startAnnounce();
-
- void syncDone() {
- if( !pdelay_started ) {
- startPDelay();
- }
- }
-
- OSTimerFactory *getTimerFactory() {
- return timer_factory;
- }
- void setAsCapable(bool ascap) {
- if (ascap != asCapable) {
- fprintf(stderr, "AsCapable: %s\n",
- ascap == true ? "Enabled" : "Disabled");
- }
- if(!ascap){
- _peer_offset_init = false;
- }
- asCapable = ascap;
- }
-
- ~IEEE1588Port();
- IEEE1588Port
- (IEEE1588Clock * clock, uint16_t index,
- bool forceSlave, int accelerated_sync_count,
- HWTimestamper * timestamper,
- int32_t offset, InterfaceLabel * net_label,
- OSConditionFactory * condition_factory,
- OSThreadFactory * thread_factory,
- OSTimerFactory * timer_factory,
- OSLockFactory * lock_factory);
- bool init_port();
-
- void recoverPort(void);
- void *openPort(void);
- unsigned getPayloadOffset();
- void sendEventPort
- (uint8_t * buf, int len, MulticastType mcast_type,
- PortIdentity * destIdentity);
- void sendGeneralPort
- (uint8_t * buf, int len, MulticastType mcast_type,
- PortIdentity * destIdentity);
- void processEvent(Event e);
-
- PTPMessageAnnounce *calculateERBest(void);
-
- void addForeignMaster(PTPMessageAnnounce * msg);
- void removeForeignMaster(PTPMessageAnnounce * msg);
- void removeForeignMasterAll(void);
-
- void addQualifiedAnnounce(PTPMessageAnnounce * msg) {
- if( qualified_announce != NULL ) delete qualified_announce;
- qualified_announce = msg;
- }
-
- char getSyncInterval(void) {
- return log_mean_sync_interval;
- }
- char getAnnounceInterval(void) {
- return log_mean_announce_interval;
- }
- char getPDelayInterval(void) {
- return log_min_mean_pdelay_req_interval;
- }
- PortState getPortState(void) {
- return port_state;
- }
- void setPortState( PortState state ) {
- port_state = state;
- }
- void getPortIdentity(PortIdentity & identity) {
- identity = this->port_identity;
- }
- bool burstEnabled(void) {
- return burst_enabled;
- }
- uint16_t getNextAnnounceSequenceId(void) {
- return announce_sequence_id++;
- }
- uint16_t getNextSyncSequenceId(void) {
- return sync_sequence_id++;
- }
- uint16_t getNextPDelaySequenceId(void) {
- return pdelay_sequence_id++;
- }
-
- uint16_t getParentLastSyncSequenceNumber(void);
- void setParentLastSyncSequenceNumber(uint16_t num);
-
- IEEE1588Clock *getClock(void);
-
- void setLastSync(PTPMessageSync * msg) {
- last_sync = msg;
- }
- PTPMessageSync *getLastSync(void) {
- return last_sync;
- }
-
- bool getPDelayRxLock() {
- return pdelay_rx_lock->lock() == oslock_ok ? true : false;
- }
-
- bool tryPDelayRxLock() {
- return pdelay_rx_lock->trylock() == oslock_ok ? true : false;
- }
-
- bool putPDelayRxLock() {
- return pdelay_rx_lock->unlock() == oslock_ok ? true : false;
- }
-
- bool getTxLock() {
- return port_tx_lock->lock() == oslock_ok ? true : false;
- }
- bool putTxLock() {
- return port_tx_lock->unlock() == oslock_ok ? true : false;
- }
- int getTimestampVersion() {
- return _hw_timestamper->getVersion();
- }
- void setLastPDelayReq(PTPMessagePathDelayReq * msg) {
- last_pdelay_req = msg;
- }
- PTPMessagePathDelayReq *getLastPDelayReq(void) {
- return last_pdelay_req;
- }
-
- void setLastPDelayResp(PTPMessagePathDelayResp * msg) {
- last_pdelay_resp = msg;
- }
- PTPMessagePathDelayResp *getLastPDelayResp(void) {
- return last_pdelay_resp;
- }
-
- void setLastPDelayRespFollowUp(PTPMessagePathDelayRespFollowUp * msg) {
- last_pdelay_resp_fwup = msg;
- }
- PTPMessagePathDelayRespFollowUp *getLastPDelayRespFollowUp(void) {
- return last_pdelay_resp_fwup;
- }
-
- FrequencyRatio getPeerRateOffset(void) {
- return _peer_rate_offset;
- }
- void setPeerRateOffset( FrequencyRatio offset ) {
- _peer_rate_offset = offset;
- }
- void setPeerOffset(Timestamp mine, Timestamp theirs) {
- _peer_offset_ts_mine = mine;
- _peer_offset_ts_theirs = theirs;
- _peer_offset_init = true;
- }
- bool getPeerOffset(Timestamp & mine, Timestamp & theirs) {
- mine = _peer_offset_ts_mine;
- theirs = _peer_offset_ts_theirs;
- return _peer_offset_init;
- }
-
- bool _adjustClockRate( FrequencyRatio freq_offset ) {
- if( _hw_timestamper ) {
- return _hw_timestamper->HWTimestamper_adjclockrate((float) freq_offset );
- }
- return false;
- }
-
- bool adjustClockRate( FrequencyRatio freq_offset ) {
- return _adjustClockRate( freq_offset );
- }
-
- void getExtendedError(char *msg) {
- if (_hw_timestamper) {
- _hw_timestamper->HWTimestamper_get_extderror(msg);
- } else {
- *msg = '\0';
- }
- }
-
- int getRxTimestamp
- (PortIdentity * sourcePortIdentity, uint16_t sequenceId,
- Timestamp & timestamp, unsigned &counter_value, bool last);
- int getTxTimestamp
- (PortIdentity * sourcePortIdentity, uint16_t sequenceId,
- Timestamp & timestamp, unsigned &counter_value, bool last);
-
- int getTxTimestamp
- (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value,
- bool last);
- int getRxTimestamp
- (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value,
- bool last);
-
- void getDeviceTime
- (Timestamp & system_time, Timestamp & device_time, uint32_t & local_clock,
- uint32_t & nominal_clock_rate);
-
- uint64_t getLinkDelay(void) {
- return one_way_delay > 0LL ? one_way_delay : 0LL;
- }
- void setLinkDelay(int64_t delay) {
- one_way_delay = delay;
- }
-
- void recommendState(PortState state, bool changed_external_master);
-
- void mapSocketAddr
- (PortIdentity * destIdentity, LinkLayerAddress * remote);
- void addSockAddrMap
- (PortIdentity * destIdentity, LinkLayerAddress * remote);
-
- void incPdelayCount() {
- ++pdelay_count;
- }
- unsigned getPdelayCount() {
- return pdelay_count;
- }
- void incSyncCount() {
- ++sync_count;
- }
- unsigned getSyncCount() {
- return sync_count;
- }
-};
-
-#endif
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef AVBTS_PORT_HPP +#define AVBTS_PORT_HPP + +#include <ieee1588.hpp> +#include <avbts_message.hpp> + +#include <avbts_ostimer.hpp> +#include <avbts_oslock.hpp> +#include <avbts_osnet.hpp> +#include <avbts_osthread.hpp> +#include <avbts_oscondition.hpp> + +#include <stdint.h> + +#include <map> +#include <list> + +#define GPTP_MULTICAST 0x0180C200000EULL +#define PDELAY_MULTICAST GPTP_MULTICAST +#define OTHER_MULTICAST GPTP_MULTICAST + +#define PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER 3 +#define SYNC_RECEIPT_TIMEOUT_MULTIPLIER 3 +#define ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER 3 + +typedef enum { + PTP_MASTER = 7, + PTP_PRE_MASTER, + PTP_SLAVE, + PTP_UNCALIBRATED, + PTP_DISABLED, + PTP_FAULTY, + PTP_INITIALIZING, + PTP_LISTENING +} PortState; + +typedef enum { + V1, + V2_E2E, + V2_P2P +} PortType; + +class PortIdentity { +private: + ClockIdentity clock_id; + uint16_t portNumber; +public: + PortIdentity() { }; + PortIdentity(uint8_t * clock_id, uint16_t * portNumber) { + this->portNumber = *portNumber; + this->portNumber = PLAT_ntohs(this->portNumber); + this->clock_id.set(clock_id); + } + bool operator!=(const PortIdentity & cmp) const { + return + !(this->clock_id == cmp.clock_id) || + this->portNumber != cmp.portNumber ? true : false; + } + bool operator==(const PortIdentity & cmp)const { + return + this->clock_id == cmp.clock_id && + this->portNumber == cmp.portNumber ? true : false; + } + bool operator<(const PortIdentity & cmp)const { + return + this->clock_id < cmp.clock_id ? + true : this->clock_id == cmp.clock_id && + this->portNumber < cmp.portNumber ? true : false; + } + bool operator>(const PortIdentity & cmp)const { + return + this->clock_id > cmp.clock_id ? + true : this->clock_id == cmp.clock_id && + this->portNumber > cmp.portNumber ? true : false; + } + void getClockIdentityString(uint8_t *id) { + clock_id.getIdentityString(id); + } + void setClockIdentity(ClockIdentity clock_id) { + this->clock_id = clock_id; + } + ClockIdentity getClockIdentity( void ) { + return this->clock_id; + } + void getPortNumberNO(uint16_t * id) { // Network byte order + uint16_t portNumberNO = PLAT_htons(portNumber); + *id = portNumberNO; + } + void getPortNumber(uint16_t * id) { // Host byte order + *id = portNumber; + } + void setPortNumber(uint16_t * id) { + portNumber = *id; + } +}; + +typedef std::map < PortIdentity, LinkLayerAddress > IdentityMap_t; + +class IEEE1588Port { + static LinkLayerAddress other_multicast; + static LinkLayerAddress pdelay_multicast; + + PortIdentity port_identity; + /* directly connected node */ + PortIdentity peer_identity; + + OSNetworkInterface *net_iface; + LinkLayerAddress local_addr; + + /* Port Status */ + unsigned sync_count; // 0 for master, ++ for each sync receive as slave + // set to 0 when asCapable is false, increment for each pdelay recvd + unsigned pdelay_count; + + /* Port Configuration */ + unsigned char delay_mechanism; + PortState port_state; + char log_mean_unicast_sync_interval; + char log_mean_sync_interval; + char log_mean_announce_interval; + char log_min_mean_delay_req_interval; + char log_min_mean_pdelay_req_interval; + bool burst_enabled; + int _accelerated_sync_count; + /* Signed value allows this to be negative result because of inaccurate + timestamp */ + int64_t one_way_delay; + /* Implementation Specific data/methods */ + IEEE1588Clock *clock; + + bool _syntonize; + + bool asCapable; + + int32_t *rate_offset_array; + uint32_t rate_offset_array_size; + uint32_t rate_offset_count; + uint32_t rate_offset_index; + + FrequencyRatio _peer_rate_offset; + Timestamp _peer_offset_ts_theirs; + Timestamp _peer_offset_ts_mine; + bool _peer_offset_init; + + int32_t _initial_clock_offset; + int32_t _current_clock_offset; + + PTPMessageAnnounce *qualified_announce; + + uint16_t announce_sequence_id; + uint16_t sync_sequence_id; + + uint16_t pdelay_sequence_id; + PTPMessagePathDelayReq *last_pdelay_req; + PTPMessagePathDelayResp *last_pdelay_resp; + PTPMessagePathDelayRespFollowUp *last_pdelay_resp_fwup; + + /* Network socket description + physical interface number that object represents */ + uint16_t ifindex; + + IdentityMap_t identity_map; + + PTPMessageSync *last_sync; + + OSThread *listening_thread; + + OSCondition *port_ready_condition; + + OSLock *pdelay_rx_lock; + OSLock *port_tx_lock; + + OSThreadFactory *thread_factory; + OSTimerFactory *timer_factory; + + HWTimestamper *_hw_timestamper; + + net_result port_send + (uint8_t * buf, int size, MulticastType mcast_type, + PortIdentity * destIdentity, bool timestamp); + + InterfaceLabel *net_label; + + OSLockFactory *lock_factory; + OSConditionFactory *condition_factory; + + bool pdelay_started; + public: + // Added for testing + bool forceSlave; + + bool serializeState( void *buf, off_t *count ); + bool restoreSerializedState( void *buf, off_t *count ); + void becomeMaster( bool annc ); + void becomeSlave( bool ); + + void startPDelay(); + void startAnnounce(); + + void syncDone() { + if( !pdelay_started ) { + startPDelay(); + } + } + + OSTimerFactory *getTimerFactory() { + return timer_factory; + } + void setAsCapable(bool ascap) { + if (ascap != asCapable) { + fprintf(stderr, "AsCapable: %s\n", + ascap == true ? "Enabled" : "Disabled"); + } + if(!ascap){ + _peer_offset_init = false; + } + asCapable = ascap; + } + + ~IEEE1588Port(); + IEEE1588Port + (IEEE1588Clock * clock, uint16_t index, + bool forceSlave, int accelerated_sync_count, + HWTimestamper * timestamper, + int32_t offset, InterfaceLabel * net_label, + OSConditionFactory * condition_factory, + OSThreadFactory * thread_factory, + OSTimerFactory * timer_factory, + OSLockFactory * lock_factory); + bool init_port(); + + void recoverPort(void); + void *openPort(void); + unsigned getPayloadOffset(); + void sendEventPort + (uint8_t * buf, int len, MulticastType mcast_type, + PortIdentity * destIdentity); + void sendGeneralPort + (uint8_t * buf, int len, MulticastType mcast_type, + PortIdentity * destIdentity); + void processEvent(Event e); + + PTPMessageAnnounce *calculateERBest(void); + + void addForeignMaster(PTPMessageAnnounce * msg); + void removeForeignMaster(PTPMessageAnnounce * msg); + void removeForeignMasterAll(void); + + void addQualifiedAnnounce(PTPMessageAnnounce * msg) { + if( qualified_announce != NULL ) delete qualified_announce; + qualified_announce = msg; + } + + char getSyncInterval(void) { + return log_mean_sync_interval; + } + char getAnnounceInterval(void) { + return log_mean_announce_interval; + } + char getPDelayInterval(void) { + return log_min_mean_pdelay_req_interval; + } + PortState getPortState(void) { + return port_state; + } + void setPortState( PortState state ) { + port_state = state; + } + void getPortIdentity(PortIdentity & identity) { + identity = this->port_identity; + } + bool burstEnabled(void) { + return burst_enabled; + } + uint16_t getNextAnnounceSequenceId(void) { + return announce_sequence_id++; + } + uint16_t getNextSyncSequenceId(void) { + return sync_sequence_id++; + } + uint16_t getNextPDelaySequenceId(void) { + return pdelay_sequence_id++; + } + + uint16_t getParentLastSyncSequenceNumber(void); + void setParentLastSyncSequenceNumber(uint16_t num); + + IEEE1588Clock *getClock(void); + + void setLastSync(PTPMessageSync * msg) { + last_sync = msg; + } + PTPMessageSync *getLastSync(void) { + return last_sync; + } + + bool getPDelayRxLock() { + return pdelay_rx_lock->lock() == oslock_ok ? true : false; + } + + bool tryPDelayRxLock() { + return pdelay_rx_lock->trylock() == oslock_ok ? true : false; + } + + bool putPDelayRxLock() { + return pdelay_rx_lock->unlock() == oslock_ok ? true : false; + } + + bool getTxLock() { + return port_tx_lock->lock() == oslock_ok ? true : false; + } + bool putTxLock() { + return port_tx_lock->unlock() == oslock_ok ? true : false; + } + int getTimestampVersion() { + return _hw_timestamper->getVersion(); + } + void setLastPDelayReq(PTPMessagePathDelayReq * msg) { + last_pdelay_req = msg; + } + PTPMessagePathDelayReq *getLastPDelayReq(void) { + return last_pdelay_req; + } + + void setLastPDelayResp(PTPMessagePathDelayResp * msg) { + last_pdelay_resp = msg; + } + PTPMessagePathDelayResp *getLastPDelayResp(void) { + return last_pdelay_resp; + } + + void setLastPDelayRespFollowUp(PTPMessagePathDelayRespFollowUp * msg) { + last_pdelay_resp_fwup = msg; + } + PTPMessagePathDelayRespFollowUp *getLastPDelayRespFollowUp(void) { + return last_pdelay_resp_fwup; + } + + FrequencyRatio getPeerRateOffset(void) { + return _peer_rate_offset; + } + void setPeerRateOffset( FrequencyRatio offset ) { + _peer_rate_offset = offset; + } + void setPeerOffset(Timestamp mine, Timestamp theirs) { + _peer_offset_ts_mine = mine; + _peer_offset_ts_theirs = theirs; + _peer_offset_init = true; + } + bool getPeerOffset(Timestamp & mine, Timestamp & theirs) { + mine = _peer_offset_ts_mine; + theirs = _peer_offset_ts_theirs; + return _peer_offset_init; + } + + bool _adjustClockRate( FrequencyRatio freq_offset ) { + if( _hw_timestamper ) { + return _hw_timestamper->HWTimestamper_adjclockrate((float) freq_offset ); + } + return false; + } + + bool adjustClockRate( FrequencyRatio freq_offset ) { + return _adjustClockRate( freq_offset ); + } + + void getExtendedError(char *msg) { + if (_hw_timestamper) { + _hw_timestamper->HWTimestamper_get_extderror(msg); + } else { + *msg = '\0'; + } + } + + int getRxTimestamp + (PortIdentity * sourcePortIdentity, uint16_t sequenceId, + Timestamp & timestamp, unsigned &counter_value, bool last); + int getTxTimestamp + (PortIdentity * sourcePortIdentity, uint16_t sequenceId, + Timestamp & timestamp, unsigned &counter_value, bool last); + + int getTxTimestamp + (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value, + bool last); + int getRxTimestamp + (PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value, + bool last); + + void getDeviceTime + (Timestamp & system_time, Timestamp & device_time, uint32_t & local_clock, + uint32_t & nominal_clock_rate); + + uint64_t getLinkDelay(void) { + return one_way_delay > 0LL ? one_way_delay : 0LL; + } + void setLinkDelay(int64_t delay) { + one_way_delay = delay; + } + + void recommendState(PortState state, bool changed_external_master); + + void mapSocketAddr + (PortIdentity * destIdentity, LinkLayerAddress * remote); + void addSockAddrMap + (PortIdentity * destIdentity, LinkLayerAddress * remote); + + void incPdelayCount() { + ++pdelay_count; + } + unsigned getPdelayCount() { + return pdelay_count; + } + void incSyncCount() { + ++sync_count; + } + unsigned getSyncCount() { + return sync_count; + } +}; + +#endif diff --git a/daemons/gptp/common/ieee1588.hpp b/daemons/gptp/common/ieee1588.hpp index 6ff38f8f..47073d9c 100644 --- a/daemons/gptp/common/ieee1588.hpp +++ b/daemons/gptp/common/ieee1588.hpp @@ -1,265 +1,265 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#ifndef IEEE1588_HPP
-#define IEEE1588_HPP
-
-#include <stdint.h>
-
-#include <string.h>
-
-#include <signal.h>
-
-#include <stdio.h>
-
-#include <platform.hpp>
-#include <ptptypes.hpp>
-
-#define MAX_PORTS 32
-
-#define PTP_CLOCK_IDENTITY_LENGTH 8
-
-class LinkLayerAddress;
-struct ClockQuality;
-class PortIdentity;
-class PTPMessageCommon;
-class PTPMessageSync;
-class PTPMessageAnnounce;
-class PTPMessagePathDelayReq;
-class PTPMessagePathDelayResp;
-class PTPMessagePathDelayRespFollowUp;
-class IEEE1588Port;
-class IEEE1588Clock;
-class OSNetworkInterface;
-
-typedef enum {
- NULL_EVENT = 0,
- POWERUP = 5,
- INITIALIZE,
- STATE_CHANGE_EVENT,
- SYNC_INTERVAL_TIMEOUT_EXPIRES,
- PDELAY_INTERVAL_TIMEOUT_EXPIRES,
- SYNC_RECEIPT_TIMEOUT_EXPIRES,
- QUALIFICATION_TIMEOUT_EXPIRES,
- ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
- ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES,
- FAULT_DETECTED,
- PDELAY_DEFERRED_PROCESSING,
- PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES,
-} Event;
-
-typedef struct {
- IEEE1588Port *port;
- Event event;
-} event_descriptor_t;
-
-class InterfaceLabel {
- public:
- virtual ~ InterfaceLabel() {
- };
-};
-
-class ClockIdentity {
- private:
- uint8_t id[PTP_CLOCK_IDENTITY_LENGTH];
- public:
- bool operator==(const ClockIdentity & cmp) const {
- return memcmp(this->id, cmp.id,
- PTP_CLOCK_IDENTITY_LENGTH) == 0 ? true : false;
- }
- bool operator!=( const ClockIdentity &cmp ) const {
- return memcmp( this->id, cmp.id, PTP_CLOCK_IDENTITY_LENGTH ) != 0 ? true : false;
- }
- bool operator<(const ClockIdentity & cmp)const {
- return memcmp(this->id, cmp.id,
- PTP_CLOCK_IDENTITY_LENGTH) < 0 ? true : false;
- }
- bool operator>(const ClockIdentity & cmp)const {
- return memcmp(this->id, cmp.id,
- PTP_CLOCK_IDENTITY_LENGTH) < 0 ? true : false;
- }
- void getIdentityString(uint8_t *id) {
- memcpy(id, this->id, PTP_CLOCK_IDENTITY_LENGTH);
- }
- void set(uint8_t * id) {
- memcpy(this->id, id, PTP_CLOCK_IDENTITY_LENGTH);
- }
- void set(LinkLayerAddress * address);
-};
-
-class Timestamp {
- public:
- Timestamp(uint32_t ns, uint32_t s_l, uint16_t s_m) {
- nanoseconds = ns;
- seconds_ls = s_l;
- seconds_ms = s_m;
- }
- Timestamp() {
- };
- uint32_t nanoseconds;
- uint32_t seconds_ls;
- uint16_t seconds_ms;
- uint8_t _version;
-};
-
-#define INVALID_TIMESTAMP (Timestamp( 0xC0000000, 0, 0 ))
-#define PDELAY_PENDING_TIMESTAMP (Timestamp( 0xC0000001, 0, 0 ))
-
-#define TIMESTAMP_TO_NS(ts) (((static_cast<long long int>((ts).seconds_ms) \
- << sizeof((ts).seconds_ls)*8) + \
- (ts).seconds_ls)*1000000000LL + (ts).nanoseconds)
-
-static inline uint64_t bswap_64(uint64_t in)
-{
- uint8_t *s = (uint8_t *) & in;
- uint8_t *e = s + 7;
- while (e > s) {
- uint8_t t;
- t = *s;
- *s = *e;
- *e = t;
- ++s;
- --e;
- }
- return in;
-}
-
-#define NS_PER_SECOND 1000000000
-#define LS_SEC_MAX 0xFFFFFFFFull
-
-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;
-}
-
-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;
-}
-
-#define XPTPD_ERROR(fmt,...) fprintf( stderr, "ERROR at %u in %s: " fmt "\n", __LINE__, __FILE__ ,## __VA_ARGS__)
-#ifdef PTP_DEBUG
-#define XPTPD_INFO(fmt,...) fprintf( stderr, "DEBUG at %u in %s: " fmt "\n", __LINE__, __FILE__ ,## __VA_ARGS__)
-#else
-#define XPTPD_INFO(fmt,...)
-#endif
-
-#define HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE 4096
-
-class HWTimestamper {
-protected:
- uint8_t version;
-public:
- virtual bool HWTimestamper_init
- ( InterfaceLabel *iface_label, OSNetworkInterface *iface )
- { return true; }
- virtual void HWTimestamper_final(void) {
- }
-
- virtual bool HWTimestamper_adjclockrate( float frequency_offset )
- { return false; }
- virtual bool HWTimestamper_adjclockphase( int64_t phase_adjust )
- { return false; }
-
- virtual bool HWTimestamper_gettime(Timestamp * system_time,
- Timestamp * device_time,
- uint32_t * local_clock,
- uint32_t * nominal_clock_rate) = 0;
-
- virtual int HWTimestamper_txtimestamp(PortIdentity * identity,
- uint16_t sequenceId,
- Timestamp & timestamp,
- unsigned &clock_value,
- bool last) = 0;
-
- virtual int HWTimestamper_rxtimestamp(PortIdentity * identity,
- uint16_t sequenceId,
- Timestamp & timestamp,
- unsigned &clock_value,
- bool last) = 0;
-
- virtual bool HWTimestamper_get_extclk_offset(Timestamp * local_time,
- int64_t * clk_offset,
- int32_t *
- ppt_freq_offset) {
- return false;
- }
-
- virtual void HWTimestamper_get_extderror(char *msg) {
- *msg = '\0';
- }
-
- virtual bool HWTimestamper_PPS_start() { return false; };
- virtual bool HWTimestamper_PPS_stop() { return true; };
-
- int getVersion() {
- return version;
- }
- HWTimestamper() { version = 0; }
- virtual ~ HWTimestamper() {
- }
-};
-
-PTPMessageCommon *buildPTPMessage(char *buf, int size,
- LinkLayerAddress * remote,
- IEEE1588Port * port);
-
-#endif
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#ifndef IEEE1588_HPP +#define IEEE1588_HPP + +#include <stdint.h> + +#include <string.h> + +#include <signal.h> + +#include <stdio.h> + +#include <platform.hpp> +#include <ptptypes.hpp> + +#define MAX_PORTS 32 + +#define PTP_CLOCK_IDENTITY_LENGTH 8 + +class LinkLayerAddress; +struct ClockQuality; +class PortIdentity; +class PTPMessageCommon; +class PTPMessageSync; +class PTPMessageAnnounce; +class PTPMessagePathDelayReq; +class PTPMessagePathDelayResp; +class PTPMessagePathDelayRespFollowUp; +class IEEE1588Port; +class IEEE1588Clock; +class OSNetworkInterface; + +typedef enum { + NULL_EVENT = 0, + POWERUP = 5, + INITIALIZE, + STATE_CHANGE_EVENT, + SYNC_INTERVAL_TIMEOUT_EXPIRES, + PDELAY_INTERVAL_TIMEOUT_EXPIRES, + SYNC_RECEIPT_TIMEOUT_EXPIRES, + QUALIFICATION_TIMEOUT_EXPIRES, + ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES, + ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES, + FAULT_DETECTED, + PDELAY_DEFERRED_PROCESSING, + PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, +} Event; + +typedef struct { + IEEE1588Port *port; + Event event; +} event_descriptor_t; + +class InterfaceLabel { + public: + virtual ~ InterfaceLabel() { + }; +}; + +class ClockIdentity { + private: + uint8_t id[PTP_CLOCK_IDENTITY_LENGTH]; + public: + bool operator==(const ClockIdentity & cmp) const { + return memcmp(this->id, cmp.id, + PTP_CLOCK_IDENTITY_LENGTH) == 0 ? true : false; + } + bool operator!=( const ClockIdentity &cmp ) const { + return memcmp( this->id, cmp.id, PTP_CLOCK_IDENTITY_LENGTH ) != 0 ? true : false; + } + bool operator<(const ClockIdentity & cmp)const { + return memcmp(this->id, cmp.id, + PTP_CLOCK_IDENTITY_LENGTH) < 0 ? true : false; + } + bool operator>(const ClockIdentity & cmp)const { + return memcmp(this->id, cmp.id, + PTP_CLOCK_IDENTITY_LENGTH) < 0 ? true : false; + } + void getIdentityString(uint8_t *id) { + memcpy(id, this->id, PTP_CLOCK_IDENTITY_LENGTH); + } + void set(uint8_t * id) { + memcpy(this->id, id, PTP_CLOCK_IDENTITY_LENGTH); + } + void set(LinkLayerAddress * address); +}; + +class Timestamp { + public: + Timestamp(uint32_t ns, uint32_t s_l, uint16_t s_m) { + nanoseconds = ns; + seconds_ls = s_l; + seconds_ms = s_m; + } + Timestamp() { + }; + uint32_t nanoseconds; + uint32_t seconds_ls; + uint16_t seconds_ms; + uint8_t _version; +}; + +#define INVALID_TIMESTAMP (Timestamp( 0xC0000000, 0, 0 )) +#define PDELAY_PENDING_TIMESTAMP (Timestamp( 0xC0000001, 0, 0 )) + +#define TIMESTAMP_TO_NS(ts) (((static_cast<long long int>((ts).seconds_ms) \ + << sizeof((ts).seconds_ls)*8) + \ + (ts).seconds_ls)*1000000000LL + (ts).nanoseconds) + +static inline uint64_t bswap_64(uint64_t in) +{ + uint8_t *s = (uint8_t *) & in; + uint8_t *e = s + 7; + while (e > s) { + uint8_t t; + t = *s; + *s = *e; + *e = t; + ++s; + --e; + } + return in; +} + +#define NS_PER_SECOND 1000000000 +#define LS_SEC_MAX 0xFFFFFFFFull + +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; +} + +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; +} + +#define XPTPD_ERROR(fmt,...) fprintf( stderr, "ERROR at %u in %s: " fmt "\n", __LINE__, __FILE__ ,## __VA_ARGS__) +#ifdef PTP_DEBUG +#define XPTPD_INFO(fmt,...) fprintf( stderr, "DEBUG at %u in %s: " fmt "\n", __LINE__, __FILE__ ,## __VA_ARGS__) +#else +#define XPTPD_INFO(fmt,...) +#endif + +#define HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE 4096 + +class HWTimestamper { +protected: + uint8_t version; +public: + virtual bool HWTimestamper_init + ( InterfaceLabel *iface_label, OSNetworkInterface *iface ) + { return true; } + virtual void HWTimestamper_final(void) { + } + + virtual bool HWTimestamper_adjclockrate( float frequency_offset ) + { return false; } + virtual bool HWTimestamper_adjclockphase( int64_t phase_adjust ) + { return false; } + + virtual bool HWTimestamper_gettime(Timestamp * system_time, + Timestamp * device_time, + uint32_t * local_clock, + uint32_t * nominal_clock_rate) = 0; + + virtual int HWTimestamper_txtimestamp(PortIdentity * identity, + uint16_t sequenceId, + Timestamp & timestamp, + unsigned &clock_value, + bool last) = 0; + + virtual int HWTimestamper_rxtimestamp(PortIdentity * identity, + uint16_t sequenceId, + Timestamp & timestamp, + unsigned &clock_value, + bool last) = 0; + + virtual bool HWTimestamper_get_extclk_offset(Timestamp * local_time, + int64_t * clk_offset, + int32_t * + ppt_freq_offset) { + return false; + } + + virtual void HWTimestamper_get_extderror(char *msg) { + *msg = '\0'; + } + + virtual bool HWTimestamper_PPS_start() { return false; }; + virtual bool HWTimestamper_PPS_stop() { return true; }; + + int getVersion() { + return version; + } + HWTimestamper() { version = 0; } + virtual ~ HWTimestamper() { + } +}; + +PTPMessageCommon *buildPTPMessage(char *buf, int size, + LinkLayerAddress * remote, + IEEE1588Port * port); + +#endif diff --git a/daemons/gptp/common/ieee1588clock.cpp b/daemons/gptp/common/ieee1588clock.cpp index 103021df..19424ef2 100644 --- a/daemons/gptp/common/ieee1588clock.cpp +++ b/daemons/gptp/common/ieee1588clock.cpp @@ -1,420 +1,420 @@ -/******************************************************************************
-
- 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 <time.h>
-
-void ClockIdentity::set(LinkLayerAddress * addr)
-{
- uint64_t tmp1 = 0;
- uint32_t tmp2;
- addr->toOctetArray((uint8_t *) & tmp1);
- tmp2 = tmp1 & 0xFFFFFF;
- tmp1 >>= 24;
- tmp1 <<= 16;
- tmp1 |= 0xFEFF;
- tmp1 <<= 24;
- tmp1 |= tmp2;
- memcpy(id, &tmp1, PTP_CLOCK_IDENTITY_LENGTH);
-}
-
-IEEE1588Clock::IEEE1588Clock
-( bool forceOrdinarySlave, bool syntonize, uint8_t priority1,
- HWTimestamper *timestamper, OSTimerQueueFactory *timerq_factory,
- OS_IPC *ipc, OSLockFactory *lock_factory )
-{
- this->priority1 = priority1;
- priority2 = 248;
-
- number_ports = 0;
-
- this->forceOrdinarySlave = forceOrdinarySlave;
-
- clock_quality.clockAccuracy = 0xfe;
- clock_quality.cq_class = 248;
- clock_quality.offsetScaledLogVariance = 16640;
-
- time_source = 160;
-
- domain_number = 0;
-
- _syntonize = syntonize;
- _new_syntonization_set_point = false;
- _ppm = 0;
-
- _master_local_freq_offset_init = false;
- _local_system_freq_offset_init = false;
- _timestamper = timestamper;
-
- this->ipc = ipc;
-
- memset( &LastEBestIdentity, 0xFF, sizeof( LastEBestIdentity ));
-
- timerq_lock = lock_factory->createLock( oslock_nonrecursive );
-
- // This should be done LAST!! to pass fully initialized clock object
- timerq = timerq_factory->createOSTimerQueue( this );
-
- 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
-( IEEE1588Port * target, Event e, unsigned long long time_ns )
-{
- event_descriptor_t *event_descriptor = new event_descriptor_t();
- event_descriptor->event = e;
- event_descriptor->port = target;
- timerq->addEvent
- ((unsigned)(time_ns / 1000), (int)e, timerq_handler, event_descriptor,
- true, NULL);
-}
-
-void IEEE1588Clock::addEventTimerLocked
-( IEEE1588Port * 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(IEEE1588Port * target, Event event)
-{
- timerq->cancelEvent((int)event, NULL);
-}
-
-void IEEE1588Clock::deleteEventTimerLocked(IEEE1588Port * 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;
-
- XPTPD_INFO( "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;
-
- XPTPD_INFO( "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);
- inter_master_time =
- TIMESTAMP_TO_NS(master_time) - TIMESTAMP_TO_NS(_prev_master_time);
-
- if( inter_sync_time != 0 ) {
- ppt_offset = ((FrequencyRatio)inter_master_time)/inter_sync_time;
- } else {
- ppt_offset = 1.0;
- }
-
- _prev_sync_time = sync_time;
- _prev_master_time = master_time;
-
- return ppt_offset;
-}
-
-void IEEE1588Clock::setMasterOffset
-( 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 )
-{
- _master_local_freq_offset = master_local_freq_offset;
- _local_system_freq_offset = local_system_freq_offset;
-
- if( ipc != NULL ) 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 );
-
- if( master_local_offset == 0 && master_local_freq_offset == 1.0 ) {
- return;
- }
-
- if( _syntonize ) {
- if( _new_syntonization_set_point ) {
- _new_syntonization_set_point = false;
- if( _timestamper ) {
- /* Make sure that there are no transmit operations
- in progress */
- getTxLockAll();
- _timestamper->HWTimestamper_adjclockphase
- ( -master_local_offset );
- _master_local_freq_offset_init = false;
- putTxLockAll();
- master_local_offset = 0;
- }
- }
- // Adjust for frequency offset
- long double phase_error = (long double) -master_local_offset;
- _ppm += (float) (INTEGRAL*phase_error +
- PROPORTIONAL*((master_local_freq_offset-1.0)*1000000));
- if( _ppm < LOWER_FREQ_LIMIT ) _ppm = LOWER_FREQ_LIMIT;
- if( _ppm > UPPER_FREQ_LIMIT ) _ppm = UPPER_FREQ_LIMIT;
- if( _timestamper ) {
- if( !_timestamper->HWTimestamper_adjclockrate( _ppm )) {
- XPTPD_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;
-
- 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
- fprintf(stderr, "(Clk)Us: ");
- for (int i = 0; i < 14; ++i)
- fprintf(stderr, "%hhx ", this1[i]);
- fprintf(stderr, "\n");
- fprintf(stderr, "(Clk)Them: ");
- for (int i = 0; i < 14; ++i)
- fprintf(stderr, "%hhx ", that1[i]);
- fprintf(stderr, "\n");
-#endif
-
- return (memcmp(this1, that1, 14) < 0) ? true : false;
-}
-
-IEEE1588Clock::~IEEE1588Clock(void)
-{
- // Do nothing
-}
+/****************************************************************************** + + 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 <time.h> + +void ClockIdentity::set(LinkLayerAddress * addr) +{ + uint64_t tmp1 = 0; + uint32_t tmp2; + addr->toOctetArray((uint8_t *) & tmp1); + tmp2 = tmp1 & 0xFFFFFF; + tmp1 >>= 24; + tmp1 <<= 16; + tmp1 |= 0xFEFF; + tmp1 <<= 24; + tmp1 |= tmp2; + memcpy(id, &tmp1, PTP_CLOCK_IDENTITY_LENGTH); +} + +IEEE1588Clock::IEEE1588Clock +( bool forceOrdinarySlave, bool syntonize, uint8_t priority1, + HWTimestamper *timestamper, OSTimerQueueFactory *timerq_factory, + OS_IPC *ipc, OSLockFactory *lock_factory ) +{ + this->priority1 = priority1; + priority2 = 248; + + number_ports = 0; + + this->forceOrdinarySlave = forceOrdinarySlave; + + clock_quality.clockAccuracy = 0xfe; + clock_quality.cq_class = 248; + clock_quality.offsetScaledLogVariance = 16640; + + time_source = 160; + + domain_number = 0; + + _syntonize = syntonize; + _new_syntonization_set_point = false; + _ppm = 0; + + _master_local_freq_offset_init = false; + _local_system_freq_offset_init = false; + _timestamper = timestamper; + + this->ipc = ipc; + + memset( &LastEBestIdentity, 0xFF, sizeof( LastEBestIdentity )); + + timerq_lock = lock_factory->createLock( oslock_nonrecursive ); + + // This should be done LAST!! to pass fully initialized clock object + timerq = timerq_factory->createOSTimerQueue( this ); + + 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 +( IEEE1588Port * target, Event e, unsigned long long time_ns ) +{ + event_descriptor_t *event_descriptor = new event_descriptor_t(); + event_descriptor->event = e; + event_descriptor->port = target; + timerq->addEvent + ((unsigned)(time_ns / 1000), (int)e, timerq_handler, event_descriptor, + true, NULL); +} + +void IEEE1588Clock::addEventTimerLocked +( IEEE1588Port * 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(IEEE1588Port * target, Event event) +{ + timerq->cancelEvent((int)event, NULL); +} + +void IEEE1588Clock::deleteEventTimerLocked(IEEE1588Port * 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; + + XPTPD_INFO( "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; + + XPTPD_INFO( "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); + inter_master_time = + TIMESTAMP_TO_NS(master_time) - TIMESTAMP_TO_NS(_prev_master_time); + + if( inter_sync_time != 0 ) { + ppt_offset = ((FrequencyRatio)inter_master_time)/inter_sync_time; + } else { + ppt_offset = 1.0; + } + + _prev_sync_time = sync_time; + _prev_master_time = master_time; + + return ppt_offset; +} + +void IEEE1588Clock::setMasterOffset +( 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 ) +{ + _master_local_freq_offset = master_local_freq_offset; + _local_system_freq_offset = local_system_freq_offset; + + if( ipc != NULL ) 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 ); + + if( master_local_offset == 0 && master_local_freq_offset == 1.0 ) { + return; + } + + if( _syntonize ) { + if( _new_syntonization_set_point ) { + _new_syntonization_set_point = false; + if( _timestamper ) { + /* Make sure that there are no transmit operations + in progress */ + getTxLockAll(); + _timestamper->HWTimestamper_adjclockphase + ( -master_local_offset ); + _master_local_freq_offset_init = false; + putTxLockAll(); + master_local_offset = 0; + } + } + // Adjust for frequency offset + long double phase_error = (long double) -master_local_offset; + _ppm += (float) (INTEGRAL*phase_error + + PROPORTIONAL*((master_local_freq_offset-1.0)*1000000)); + if( _ppm < LOWER_FREQ_LIMIT ) _ppm = LOWER_FREQ_LIMIT; + if( _ppm > UPPER_FREQ_LIMIT ) _ppm = UPPER_FREQ_LIMIT; + if( _timestamper ) { + if( !_timestamper->HWTimestamper_adjclockrate( _ppm )) { + XPTPD_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; + + 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 + fprintf(stderr, "(Clk)Us: "); + for (int i = 0; i < 14; ++i) + fprintf(stderr, "%hhx ", this1[i]); + fprintf(stderr, "\n"); + fprintf(stderr, "(Clk)Them: "); + for (int i = 0; i < 14; ++i) + fprintf(stderr, "%hhx ", that1[i]); + fprintf(stderr, "\n"); +#endif + + return (memcmp(this1, that1, 14) < 0) ? true : false; +} + +IEEE1588Clock::~IEEE1588Clock(void) +{ + // Do nothing +} diff --git a/daemons/gptp/common/ieee1588port.cpp b/daemons/gptp/common/ieee1588port.cpp index f8717a1d..76acab9a 100644 --- a/daemons/gptp/common/ieee1588port.cpp +++ b/daemons/gptp/common/ieee1588port.cpp @@ -1,1053 +1,1053 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#include <ieee1588.hpp>
-
-#include <avbts_port.hpp>
-#include <avbts_message.hpp>
-#include <avbts_clock.hpp>
-
-#include <avbts_oslock.hpp>
-#include <avbts_osnet.hpp>
-#include <avbts_oscondition.hpp>
-
-#include <stdio.h>
-
-#include <math.h>
-
-#include <stdlib.h>
-#include <time.h>
-
-LinkLayerAddress IEEE1588Port::other_multicast(OTHER_MULTICAST);
-LinkLayerAddress IEEE1588Port::pdelay_multicast(PDELAY_MULTICAST);
-
-OSThreadExitCode openPortWrapper(void *arg)
-{
- IEEE1588Port *port;
-
- port = (IEEE1588Port *) arg;
- if (port->openPort() == NULL)
- return osthread_ok;
- else
- return osthread_error;
-}
-
-IEEE1588Port::~IEEE1588Port()
-{
- delete port_ready_condition;
- delete [] rate_offset_array;
- if( qualified_announce != NULL ) delete qualified_announce;
-}
-
-IEEE1588Port::IEEE1588Port
-(IEEE1588Clock * clock, uint16_t index, bool forceSlave,
- int accelerated_sync_count, HWTimestamper * timestamper, int32_t offset,
- InterfaceLabel * net_label, OSConditionFactory * condition_factory,
- OSThreadFactory * thread_factory, OSTimerFactory * timer_factory,
- OSLockFactory * lock_factory)
-{
- sync_sequence_id = 0;
-
- clock->registerPort(this, index);
- this->clock = clock;
- ifindex = index;
-
- this->forceSlave = forceSlave;
- port_state = PTP_INITIALIZING;
-
- asCapable = false;
-
- announce_sequence_id = 0;
- sync_sequence_id = 0;
- pdelay_sequence_id = 0;
-
- sync_sequence_id = 0;
-
- pdelay_started = false;
-
- log_mean_sync_interval = -3;
- _accelerated_sync_count = accelerated_sync_count;
- log_mean_announce_interval = 0;
- log_min_mean_pdelay_req_interval = 0;
-
- _current_clock_offset = _initial_clock_offset = offset;
-
- rate_offset_array = NULL;
-
- _hw_timestamper = timestamper;
-
- one_way_delay = 3600000000000;
-
- _peer_rate_offset = 1.0;
-
- last_sync = NULL;
- last_pdelay_req = NULL;
- last_pdelay_resp = NULL;
- last_pdelay_resp_fwup = NULL;
-
- qualified_announce = NULL;
-
- this->net_label = net_label;
-
- this->timer_factory = timer_factory;
- this->thread_factory = thread_factory;
-
- this->condition_factory = condition_factory;
- this->lock_factory = lock_factory;
-
- pdelay_count = 0;
- sync_count = 0;
-}
-
-bool IEEE1588Port::init_port()
-{
- if (!OSNetworkInterfaceFactory::buildInterface
- (&net_iface, factory_name_t("default"), net_label, _hw_timestamper))
- return false;
-
- this->net_iface = net_iface;
- this->net_iface->getLinkLayerAddress(&local_addr);
- clock->setClockIdentity(&local_addr);
-
- if( _hw_timestamper != NULL ) {
- if( !_hw_timestamper->HWTimestamper_init( net_label, net_iface )) {
- XPTPD_ERROR
- ( "Failed to initialize hardware timestamper, "
- "falling back to software timestamping" );
- _hw_timestamper = NULL;
- }
- }
-
- pdelay_rx_lock = lock_factory->createLock(oslock_recursive);
- port_tx_lock = lock_factory->createLock(oslock_recursive);
-
- port_identity.setClockIdentity(clock->getClockIdentity());
- port_identity.setPortNumber(&ifindex);
-
- port_ready_condition = condition_factory->createCondition();
-
- return true;
-}
-
-void IEEE1588Port::startPDelay() {
- pdelay_started = true;
- clock->addEventTimer( this, PDELAY_INTERVAL_TIMEOUT_EXPIRES, 32000000 );
-}
-
-void IEEE1588Port::startAnnounce() {
- clock->addEventTimer( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES, 16000000 );
-}
-
-bool IEEE1588Port::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 IEEE1588Port::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 *IEEE1588Port::openPort(void)
-{
- port_ready_condition->signal();
-
- while (1) {
- PTPMessageCommon *msg;
- uint8_t buf[128];
- LinkLayerAddress remote;
- net_result rrecv;
- size_t length = sizeof(buf);
-
- if ((rrecv = net_iface->recv(&remote, buf, length)) == net_succeed) {
- XPTPD_INFO("Processing network buffer");
- msg = buildPTPMessage((char *)buf, (int)length, &remote,
- this);
- if (msg != NULL) {
- XPTPD_INFO("Processing message");
- msg->processMessage(this);
- if (msg->garbage()) {
- delete msg;
- }
- } else {
- XPTPD_ERROR("Discarding invalid message");
- }
- } else if (rrecv == net_fatal) {
- XPTPD_ERROR("read from network interface failed");
- this->processEvent(FAULT_DETECTED);
- break;
- }
- }
-
- return NULL;
-}
-
-net_result IEEE1588Port::port_send(uint8_t * buf, int size,
- MulticastType mcast_type,
- PortIdentity * destIdentity, bool timestamp)
-{
- LinkLayerAddress dest;
-
- if (mcast_type != MCAST_NONE) {
- if (mcast_type == MCAST_PDELAY) {
- dest = pdelay_multicast;
- } else {
- dest = other_multicast;
- }
- } else {
- mapSocketAddr(destIdentity, &dest);
- }
-
- return net_iface->send(&dest, (uint8_t *) buf, size, timestamp);
-}
-
-unsigned IEEE1588Port::getPayloadOffset()
-{
- return net_iface->getPayloadOffset();
-}
-
-void IEEE1588Port::sendEventPort(uint8_t * buf, int size,
- MulticastType mcast_type,
- PortIdentity * destIdentity)
-{
- net_result rtx = port_send(buf, size, mcast_type, destIdentity, true);
- if (rtx != net_succeed) {
- XPTPD_ERROR("sendEventPort(): failure");
- }
-
- return;
-}
-
-void IEEE1588Port::sendGeneralPort(uint8_t * buf, int size,
- MulticastType mcast_type,
- PortIdentity * destIdentity)
-{
- net_result rtx = port_send(buf, size, mcast_type, destIdentity, false);
- if (rtx != net_succeed) {
- XPTPD_ERROR("sendGeneralPort(): failure");
- }
-
- return;
-}
-
-void IEEE1588Port::processEvent(Event e)
-{
- bool changed_external_master;
- OSTimer *timer = timer_factory->createTimer();
-
- switch (e) {
- case POWERUP:
- case INITIALIZE:
- XPTPD_INFO("Received POWERUP/INITIALIZE event");
- clock->getTimerQLock();
-
- {
- unsigned long long interval3;
- unsigned long long interval4;
- Event e3 = NULL_EVENT;
- Event e4 = NULL_EVENT;
-
- if( port_state != PTP_MASTER ) {
- _accelerated_sync_count = -1;
- }
-
- if( port_state != PTP_SLAVE && port_state != PTP_MASTER ) {
- fprintf( stderr, "Starting PDelay\n" );
- startPDelay();
- }
-
- if( clock->getPriority1() == 255 || port_state == PTP_SLAVE ) {
- becomeSlave( false );
- } else if( port_state == PTP_MASTER ) {
- becomeMaster( true );
- } else {
- //e3 = SYNC_RECEIPT_TIMEOUT_EXPIRES;
- e4 = ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES;
- interval3 = (unsigned long long)
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER*
- pow((double)2,getSyncInterval())*1000000000.0);
- interval4 = (unsigned long long)
- (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER*
- pow((double)2,getAnnounceInterval())*1000000000.0);
- }
-
- port_ready_condition->wait_prelock();
- listening_thread = thread_factory->createThread();
- if (!listening_thread->
- start (openPortWrapper, (void *)this))
- {
- XPTPD_ERROR("Error creating port thread");
- return;
- }
- port_ready_condition->wait();
-
- if (e3 != NULL_EVENT)
- clock->addEventTimer(this, e3, interval3);
- if (e4 != NULL_EVENT)
- clock->addEventTimer(this, e4, interval4);
- }
-
- clock->putTimerQLock();
-
- break;
- case STATE_CHANGE_EVENT:
- if ( clock->getPriority1() != 255 ) {
- int number_ports, j;
- PTPMessageAnnounce *EBest = NULL;
- char EBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH];
-
- IEEE1588Port **ports;
- 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]->port_state == PTP_DISABLED
- || ports[j]->port_state == PTP_FAULTY) {
- continue;
- }
- if (EBest == NULL) {
- EBest = ports[j]->calculateERBest();
- } else {
- if (ports[j]->calculateERBest()->isBetterThan(EBest)) {
- EBest = ports[j]->calculateERBest();
- }
- }
- }
-
- /* Check if we've changed */
- {
-
- uint8_t LastEBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH];
- 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]->port_state == PTP_DISABLED
- || ports[j]->port_state == 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 recieved 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);
- }
- }
- }
- }
- break;
- case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
- case SYNC_RECEIPT_TIMEOUT_EXPIRES:
- {
- if( clock->getPriority1() == 255 ) {
- // Restart timer
- if( e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ) {
- clock->addEventTimer
- (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
- (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER*
- (unsigned long long)
- (pow((double)2,getAnnounceInterval())*
- 1000000000.0)));
- } else {
- clock->addEventTimer
- (this, SYNC_RECEIPT_TIMEOUT_EXPIRES,
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER*
- (unsigned long long)
- (pow((double)2,getSyncInterval())*
- 1000000000.0)));
- }
- return;
- }
- if (port_state == PTP_INITIALIZING
- || port_state == PTP_UNCALIBRATED
- || port_state == PTP_SLAVE
- || port_state == PTP_PRE_MASTER) {
- fprintf
- (stderr,
- "*** %s Timeout Expired - Becoming Master\n",
- e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ? "Announce" :
- "Sync" );
- {
- // 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 );
- }
- port_state = PTP_MASTER;
- Timestamp system_time;
- Timestamp device_time;
-
- uint32_t local_clock, nominal_clock_rate;
-
- getDeviceTime(system_time, device_time,
- local_clock, nominal_clock_rate);
-
- (void) clock->calcLocalSystemClockRateDifference
- ( device_time, system_time );
-
- delete qualified_announce;
- qualified_announce = NULL;
-
- // Add timers for Announce and Sync, this is as close to immediately as we get
- clock->addEventTimer
- ( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, 16000000 );
- startAnnounce();
- //
- }
- }
-
- break;
- case PDELAY_INTERVAL_TIMEOUT_EXPIRES:
- XPTPD_INFO("PDELAY_INTERVAL_TIMEOUT_EXPIRES occured");
- {
- int ts_good;
- Timestamp req_timestamp;
- int iter = TX_TIMEOUT_ITER;
- long req = TX_TIMEOUT_BASE;
- unsigned req_timestamp_counter_value;
- long long wait_time = 0;
-
- 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);
- XPTPD_INFO("Sent PDelay Request");
-
- ts_good =
- getTxTimestamp
- (pdelay_req, req_timestamp, req_timestamp_counter_value,
- false);
- while (ts_good != 0 && iter-- != 0) {
- timer->sleep(req);
- wait_time += req;
- if (ts_good != -72 && iter < 1)
- fprintf
- (stderr,
- "Error (TX) timestamping PDelay request "
- "(Retrying-%d), error=%d\n", iter, ts_good);
- ts_good =
- getTxTimestamp
- (pdelay_req, req_timestamp,
- req_timestamp_counter_value, iter == 0);
- req *= 2;
- }
- putTxLock();
-
- if (ts_good == 0) {
- pdelay_req->setTimestamp(req_timestamp);
- } else {
- Timestamp failed = INVALID_TIMESTAMP;
- pdelay_req->setTimestamp(failed);
- fprintf( stderr, "Invalid TX\n" );
- }
-
- if (ts_good != 0) {
- char msg
- [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
- getExtendedError(msg);
- XPTPD_ERROR(
- "Error (TX) timestamping PDelay request, error=%d\t%s",
- ts_good, msg);
- }
-#ifdef DEBUG
- if (ts_good == 0) {
- XPTPD_INFO
- ("Successful PDelay Req timestamp, %u,%u",
- req_timestamp.seconds_ls,
- req_timestamp.nanoseconds);
- } else {
- XPTPD_INFO
- ("*** Unsuccessful PDelay Req timestamp");
- }
-#endif
-
- {
- long long timeout;
- long long interval;
-
- timeout = PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER *
- ((long long)
- (pow((double)2,getPDelayInterval())*1000000000.0)) -
- wait_time*1000;
- timeout = timeout > EVENT_TIMER_GRANULARITY ?
- timeout : EVENT_TIMER_GRANULARITY;
- clock->addEventTimer
- (this, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, timeout );
-
- interval =
- ((long long)
- (pow((double)2,getPDelayInterval())*1000000000.0)) -
- wait_time*1000;
- interval = interval > EVENT_TIMER_GRANULARITY ?
- interval : EVENT_TIMER_GRANULARITY;
- clock->addEventTimer
- (this, PDELAY_INTERVAL_TIMEOUT_EXPIRES, interval );
- }
- }
- break;
- case SYNC_INTERVAL_TIMEOUT_EXPIRES:
- XPTPD_INFO("SYNC_INTERVAL_TIMEOUT_EXPIRES occured");
- {
- /* Set offset from master to zero, update device vs
- system time offset */
- Timestamp system_time;
- Timestamp device_time;
- FrequencyRatio local_system_freq_offset;
- int64_t local_system_offset;
- long long wait_time = 0;
-
- uint32_t local_clock, nominal_clock_rate;
-
- // Send a sync message and then a followup to broadcast
- if (asCapable) {
- PTPMessageSync *sync = new PTPMessageSync(this);
- PortIdentity dest_id;
- getPortIdentity(dest_id);
- sync->setPortIdentity(&dest_id);
- getTxLock();
- sync->sendPort(this, NULL);
- XPTPD_INFO("Sent SYNC message");
-
- int ts_good;
- Timestamp sync_timestamp;
- unsigned sync_timestamp_counter_value;
- int iter = TX_TIMEOUT_ITER;
- long req = TX_TIMEOUT_BASE;
- ts_good =
- getTxTimestamp(sync, sync_timestamp,
- sync_timestamp_counter_value,
- false);
- while (ts_good != 0 && iter-- != 0) {
- timer->sleep(req);
- wait_time += req;
-
- if (ts_good != -72 && iter < 1)
- XPTPD_ERROR(
- "Error (TX) timestamping Sync (Retrying), "
- "error=%d", ts_good);
- ts_good =
- getTxTimestamp
- (sync, sync_timestamp,
- sync_timestamp_counter_value, iter == 0);
- req *= 2;
- }
- putTxLock();
-
- if (ts_good != 0) {
- char msg
- [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
- getExtendedError(msg);
- fprintf
- (stderr,
- "Error (TX) timestamping Sync, error="
- "%d\n%s",
- ts_good, msg );
- }
-
- if (ts_good == 0) {
- XPTPD_INFO("Successful Sync timestamp");
- XPTPD_INFO("Seconds: %u",
- sync_timestamp.seconds_ls);
- XPTPD_INFO("Nanoseconds: %u",
- sync_timestamp.nanoseconds);
- } else {
- XPTPD_INFO
- ("*** Unsuccessful Sync timestamp");
- }
-
- PTPMessageFollowUp *follow_up;
- if (ts_good == 0) {
- follow_up =
- new PTPMessageFollowUp(this);
- PortIdentity dest_id;
- getPortIdentity(dest_id);
- follow_up->setPortIdentity(&dest_id);
- follow_up->setSequenceId(sync->getSequenceId());
- follow_up->setPreciseOriginTimestamp(sync_timestamp);
- follow_up->sendPort(this, NULL);
- delete follow_up;
- } else {
- }
- delete sync;
- }
- /* Do getDeviceTime() after transmitting sync frame
- causing an update to local/system timestamp */
- getDeviceTime
- (system_time, device_time, local_clock, nominal_clock_rate);
-
- XPTPD_INFO
- ("port::processEvent(): System time: %u,%u Device Time: %u,%u",
- system_time.seconds_ls, system_time.nanoseconds,
- device_time.seconds_ls, device_time.nanoseconds);
-
- local_system_offset =
- TIMESTAMP_TO_NS(system_time) -
- TIMESTAMP_TO_NS(device_time);
- local_system_freq_offset =
- clock->calcLocalSystemClockRateDifference
- ( device_time, system_time );
- clock->setMasterOffset
- (0, device_time, 1.0, local_system_offset,
- system_time, local_system_freq_offset, sync_count,
- pdelay_count, port_state );
-
- /* If accelerated_sync is non-zero then start 16 ms sync
- timer, subtract 1, for last one start PDelay also */
- if( _accelerated_sync_count > 0 ) {
- clock->addEventTimer
- ( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, 8000000 );
- --_accelerated_sync_count;
- } else {
- syncDone();
- if( _accelerated_sync_count == 0 ) {
- --_accelerated_sync_count;
- }
- wait_time *= 1000; // to ns
- wait_time =
- ((long long)
- (pow((double)2,getSyncInterval())*1000000000.0)) -
- wait_time;
- wait_time = wait_time > EVENT_TIMER_GRANULARITY ? wait_time :
- EVENT_TIMER_GRANULARITY;
- clock->addEventTimer
- ( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, wait_time );
- }
-
- }
- break;
- case ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES:
- if (asCapable) {
- // Send an announce message
- PTPMessageAnnounce *annc = new PTPMessageAnnounce(this);
- PortIdentity dest_id;
- PortIdentity gmId;
- ClockIdentity clock_id = clock->getClockIdentity();
- gmId.setClockIdentity(clock_id);
- getPortIdentity(dest_id);
- annc->setPortIdentity(&dest_id);
- annc->sendPort(this, NULL);
- delete annc;
- }
- clock->addEventTimer
- (this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES,
- (unsigned)
- (pow ((double)2, getAnnounceInterval()) * 1000000000.0));
- break;
- case FAULT_DETECTED:
- XPTPD_INFO("Received FAULT_DETECTED event");
- break;
- case PDELAY_DEFERRED_PROCESSING:
- pdelay_rx_lock->lock();
- if (last_pdelay_resp_fwup == NULL) {
- fprintf(stderr, "PDelay Response Followup is NULL!\n");
- abort();
- }
- last_pdelay_resp_fwup->processMessage(this);
- if (last_pdelay_resp_fwup->garbage()) {
- delete last_pdelay_resp_fwup;
- this->setLastPDelayRespFollowUp(NULL);
- }
- pdelay_rx_lock->unlock();
- break;
- case PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES:
- setAsCapable(false);
- pdelay_count = 0;
- break;
- default:
- XPTPD_INFO
- ("Unhandled event type in IEEE1588Port::processEvent(), %d",
- e);
- break;
- }
-
- delete timer;
- return;
-}
-
-PTPMessageAnnounce *IEEE1588Port::calculateERBest(void)
-{
- return qualified_announce;
-}
-
-void IEEE1588Port::recoverPort(void)
-{
- return;
-}
-
-IEEE1588Clock *IEEE1588Port::getClock(void)
-{
- return clock;
-}
-
-void IEEE1588Port::getDeviceTime
-(Timestamp & system_time, Timestamp & device_time,
- uint32_t & local_clock, uint32_t & nominal_clock_rate)
-{
- if (_hw_timestamper) {
- _hw_timestamper->HWTimestamper_gettime
- (&system_time, &device_time, &local_clock, &nominal_clock_rate);
- } else {
- device_time = system_time = clock->getSystemTime();
- local_clock = nominal_clock_rate = 0;
- }
- return;
-}
-
-void IEEE1588Port::becomeMaster( bool annc ) {
- port_state = PTP_MASTER;
- // Start announce receipt timeout timer
- // Start sync receipt timeout timer
- clock->deleteEventTimer( this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES );
- clock->deleteEventTimer( this, SYNC_RECEIPT_TIMEOUT_EXPIRES );
- if( annc ) {
- startAnnounce();
- }
- clock->addEventTimer( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, 16000000 );
- fprintf( stderr, "Switching to Master\n" );
-
- return;
-}
-
-void IEEE1588Port::becomeSlave( bool restart_syntonization ) {
- clock->deleteEventTimer( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES );
- clock->deleteEventTimer( this, SYNC_INTERVAL_TIMEOUT_EXPIRES );
-
- port_state = PTP_SLAVE;
-
- /*clock->addEventTimer
- ( this, SYNC_RECEIPT_TIMEOUT_EXPIRES,
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER*
- (unsigned long long)(pow((double)2,getSyncInterval())*1000000000.0)));*/
- clock->addEventTimer
- (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
- (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER*
- (unsigned long long)
- (pow((double)2,getAnnounceInterval())*1000000000.0)));
- fprintf( stderr, "Switching to Slave\n" );
- if( restart_syntonization ) clock->newSyntonizationSetPoint();
-
- return;
-}
-
-void IEEE1588Port::recommendState
-( PortState state, bool changed_external_master )
-{
- bool reset_sync = false;
- switch (state) {
- case PTP_MASTER:
- if (port_state != PTP_MASTER) {
- port_state = PTP_MASTER;
- // Start announce receipt timeout timer
- // Start sync receipt timeout timer
- becomeMaster( true );
- reset_sync = true;
- }
- break;
- case PTP_SLAVE:
- if (port_state != PTP_SLAVE) {
- becomeSlave( true );
- reset_sync = true;
- } else {
- if( changed_external_master ) {
- fprintf( stderr, "Changed master!\n" );
- clock->newSyntonizationSetPoint();
- reset_sync = true;
- }
- }
- break;
- default:
- XPTPD_INFO
- ("Invalid state change requested by call to "
- "1588Port::recommendState()");
- break;
- }
- if( reset_sync ) sync_count = 0;
- return;
- }
-
-void IEEE1588Port::mapSocketAddr
-(PortIdentity * destIdentity, LinkLayerAddress * remote)
-{
- *remote = identity_map[*destIdentity];
- return;
-}
-
-void IEEE1588Port::addSockAddrMap
-(PortIdentity * destIdentity, LinkLayerAddress * remote)
-{
- identity_map[*destIdentity] = *remote;
- return;
-}
-
-int IEEE1588Port::getTxTimestamp
-(PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value,
- bool last)
-{
- PortIdentity identity;
- msg->getPortIdentity(&identity);
- return getTxTimestamp
- (&identity, msg->getSequenceId(), timestamp, counter_value, last);
-}
-
-int IEEE1588Port::getRxTimestamp(PTPMessageCommon * msg, Timestamp & timestamp,
- unsigned &counter_value, bool last)
-{
- PortIdentity identity;
- msg->getPortIdentity(&identity);
- return getRxTimestamp
- (&identity, msg->getSequenceId(), timestamp, counter_value, last);
-}
-
-int IEEE1588Port::getTxTimestamp(PortIdentity * sourcePortIdentity,
- uint16_t sequenceId, Timestamp & timestamp,
- unsigned &counter_value, bool last)
-{
- if (_hw_timestamper) {
- return _hw_timestamper->HWTimestamper_txtimestamp
- (sourcePortIdentity, sequenceId, timestamp, counter_value,
- last);
- }
- timestamp = clock->getSystemTime();
- return 0;
-}
-
-int IEEE1588Port::getRxTimestamp(PortIdentity * sourcePortIdentity,
- uint16_t sequenceId, Timestamp & timestamp,
- unsigned &counter_value, bool last)
-{
- if (_hw_timestamper) {
- return _hw_timestamper->HWTimestamper_rxtimestamp
- (sourcePortIdentity, sequenceId, timestamp, counter_value,
- last);
- }
- timestamp = clock->getSystemTime();
- return 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_port.hpp> +#include <avbts_message.hpp> +#include <avbts_clock.hpp> + +#include <avbts_oslock.hpp> +#include <avbts_osnet.hpp> +#include <avbts_oscondition.hpp> + +#include <stdio.h> + +#include <math.h> + +#include <stdlib.h> +#include <time.h> + +LinkLayerAddress IEEE1588Port::other_multicast(OTHER_MULTICAST); +LinkLayerAddress IEEE1588Port::pdelay_multicast(PDELAY_MULTICAST); + +OSThreadExitCode openPortWrapper(void *arg) +{ + IEEE1588Port *port; + + port = (IEEE1588Port *) arg; + if (port->openPort() == NULL) + return osthread_ok; + else + return osthread_error; +} + +IEEE1588Port::~IEEE1588Port() +{ + delete port_ready_condition; + delete [] rate_offset_array; + if( qualified_announce != NULL ) delete qualified_announce; +} + +IEEE1588Port::IEEE1588Port +(IEEE1588Clock * clock, uint16_t index, bool forceSlave, + int accelerated_sync_count, HWTimestamper * timestamper, int32_t offset, + InterfaceLabel * net_label, OSConditionFactory * condition_factory, + OSThreadFactory * thread_factory, OSTimerFactory * timer_factory, + OSLockFactory * lock_factory) +{ + sync_sequence_id = 0; + + clock->registerPort(this, index); + this->clock = clock; + ifindex = index; + + this->forceSlave = forceSlave; + port_state = PTP_INITIALIZING; + + asCapable = false; + + announce_sequence_id = 0; + sync_sequence_id = 0; + pdelay_sequence_id = 0; + + sync_sequence_id = 0; + + pdelay_started = false; + + log_mean_sync_interval = -3; + _accelerated_sync_count = accelerated_sync_count; + log_mean_announce_interval = 0; + log_min_mean_pdelay_req_interval = 0; + + _current_clock_offset = _initial_clock_offset = offset; + + rate_offset_array = NULL; + + _hw_timestamper = timestamper; + + one_way_delay = 3600000000000; + + _peer_rate_offset = 1.0; + + last_sync = NULL; + last_pdelay_req = NULL; + last_pdelay_resp = NULL; + last_pdelay_resp_fwup = NULL; + + qualified_announce = NULL; + + this->net_label = net_label; + + this->timer_factory = timer_factory; + this->thread_factory = thread_factory; + + this->condition_factory = condition_factory; + this->lock_factory = lock_factory; + + pdelay_count = 0; + sync_count = 0; +} + +bool IEEE1588Port::init_port() +{ + if (!OSNetworkInterfaceFactory::buildInterface + (&net_iface, factory_name_t("default"), net_label, _hw_timestamper)) + return false; + + this->net_iface = net_iface; + this->net_iface->getLinkLayerAddress(&local_addr); + clock->setClockIdentity(&local_addr); + + if( _hw_timestamper != NULL ) { + if( !_hw_timestamper->HWTimestamper_init( net_label, net_iface )) { + XPTPD_ERROR + ( "Failed to initialize hardware timestamper, " + "falling back to software timestamping" ); + _hw_timestamper = NULL; + } + } + + pdelay_rx_lock = lock_factory->createLock(oslock_recursive); + port_tx_lock = lock_factory->createLock(oslock_recursive); + + port_identity.setClockIdentity(clock->getClockIdentity()); + port_identity.setPortNumber(&ifindex); + + port_ready_condition = condition_factory->createCondition(); + + return true; +} + +void IEEE1588Port::startPDelay() { + pdelay_started = true; + clock->addEventTimer( this, PDELAY_INTERVAL_TIMEOUT_EXPIRES, 32000000 ); +} + +void IEEE1588Port::startAnnounce() { + clock->addEventTimer( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES, 16000000 ); +} + +bool IEEE1588Port::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 IEEE1588Port::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 *IEEE1588Port::openPort(void) +{ + port_ready_condition->signal(); + + while (1) { + PTPMessageCommon *msg; + uint8_t buf[128]; + LinkLayerAddress remote; + net_result rrecv; + size_t length = sizeof(buf); + + if ((rrecv = net_iface->recv(&remote, buf, length)) == net_succeed) { + XPTPD_INFO("Processing network buffer"); + msg = buildPTPMessage((char *)buf, (int)length, &remote, + this); + if (msg != NULL) { + XPTPD_INFO("Processing message"); + msg->processMessage(this); + if (msg->garbage()) { + delete msg; + } + } else { + XPTPD_ERROR("Discarding invalid message"); + } + } else if (rrecv == net_fatal) { + XPTPD_ERROR("read from network interface failed"); + this->processEvent(FAULT_DETECTED); + break; + } + } + + return NULL; +} + +net_result IEEE1588Port::port_send(uint8_t * buf, int size, + MulticastType mcast_type, + PortIdentity * destIdentity, bool timestamp) +{ + LinkLayerAddress dest; + + if (mcast_type != MCAST_NONE) { + if (mcast_type == MCAST_PDELAY) { + dest = pdelay_multicast; + } else { + dest = other_multicast; + } + } else { + mapSocketAddr(destIdentity, &dest); + } + + return net_iface->send(&dest, (uint8_t *) buf, size, timestamp); +} + +unsigned IEEE1588Port::getPayloadOffset() +{ + return net_iface->getPayloadOffset(); +} + +void IEEE1588Port::sendEventPort(uint8_t * buf, int size, + MulticastType mcast_type, + PortIdentity * destIdentity) +{ + net_result rtx = port_send(buf, size, mcast_type, destIdentity, true); + if (rtx != net_succeed) { + XPTPD_ERROR("sendEventPort(): failure"); + } + + return; +} + +void IEEE1588Port::sendGeneralPort(uint8_t * buf, int size, + MulticastType mcast_type, + PortIdentity * destIdentity) +{ + net_result rtx = port_send(buf, size, mcast_type, destIdentity, false); + if (rtx != net_succeed) { + XPTPD_ERROR("sendGeneralPort(): failure"); + } + + return; +} + +void IEEE1588Port::processEvent(Event e) +{ + bool changed_external_master; + OSTimer *timer = timer_factory->createTimer(); + + switch (e) { + case POWERUP: + case INITIALIZE: + XPTPD_INFO("Received POWERUP/INITIALIZE event"); + clock->getTimerQLock(); + + { + unsigned long long interval3; + unsigned long long interval4; + Event e3 = NULL_EVENT; + Event e4 = NULL_EVENT; + + if( port_state != PTP_MASTER ) { + _accelerated_sync_count = -1; + } + + if( port_state != PTP_SLAVE && port_state != PTP_MASTER ) { + fprintf( stderr, "Starting PDelay\n" ); + startPDelay(); + } + + if( clock->getPriority1() == 255 || port_state == PTP_SLAVE ) { + becomeSlave( false ); + } else if( port_state == PTP_MASTER ) { + becomeMaster( true ); + } else { + //e3 = SYNC_RECEIPT_TIMEOUT_EXPIRES; + e4 = ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES; + interval3 = (unsigned long long) + (SYNC_RECEIPT_TIMEOUT_MULTIPLIER* + pow((double)2,getSyncInterval())*1000000000.0); + interval4 = (unsigned long long) + (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER* + pow((double)2,getAnnounceInterval())*1000000000.0); + } + + port_ready_condition->wait_prelock(); + listening_thread = thread_factory->createThread(); + if (!listening_thread-> + start (openPortWrapper, (void *)this)) + { + XPTPD_ERROR("Error creating port thread"); + return; + } + port_ready_condition->wait(); + + if (e3 != NULL_EVENT) + clock->addEventTimer(this, e3, interval3); + if (e4 != NULL_EVENT) + clock->addEventTimer(this, e4, interval4); + } + + clock->putTimerQLock(); + + break; + case STATE_CHANGE_EVENT: + if ( clock->getPriority1() != 255 ) { + int number_ports, j; + PTPMessageAnnounce *EBest = NULL; + char EBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH]; + + IEEE1588Port **ports; + 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]->port_state == PTP_DISABLED + || ports[j]->port_state == PTP_FAULTY) { + continue; + } + if (EBest == NULL) { + EBest = ports[j]->calculateERBest(); + } else { + if (ports[j]->calculateERBest()->isBetterThan(EBest)) { + EBest = ports[j]->calculateERBest(); + } + } + } + + /* Check if we've changed */ + { + + uint8_t LastEBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH]; + 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]->port_state == PTP_DISABLED + || ports[j]->port_state == 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 recieved 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); + } + } + } + } + break; + case ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES: + case SYNC_RECEIPT_TIMEOUT_EXPIRES: + { + if( clock->getPriority1() == 255 ) { + // Restart timer + if( e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ) { + clock->addEventTimer + (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES, + (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER* + (unsigned long long) + (pow((double)2,getAnnounceInterval())* + 1000000000.0))); + } else { + clock->addEventTimer + (this, SYNC_RECEIPT_TIMEOUT_EXPIRES, + (SYNC_RECEIPT_TIMEOUT_MULTIPLIER* + (unsigned long long) + (pow((double)2,getSyncInterval())* + 1000000000.0))); + } + return; + } + if (port_state == PTP_INITIALIZING + || port_state == PTP_UNCALIBRATED + || port_state == PTP_SLAVE + || port_state == PTP_PRE_MASTER) { + fprintf + (stderr, + "*** %s Timeout Expired - Becoming Master\n", + e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ? "Announce" : + "Sync" ); + { + // 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 ); + } + port_state = PTP_MASTER; + Timestamp system_time; + Timestamp device_time; + + uint32_t local_clock, nominal_clock_rate; + + getDeviceTime(system_time, device_time, + local_clock, nominal_clock_rate); + + (void) clock->calcLocalSystemClockRateDifference + ( device_time, system_time ); + + delete qualified_announce; + qualified_announce = NULL; + + // Add timers for Announce and Sync, this is as close to immediately as we get + clock->addEventTimer + ( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, 16000000 ); + startAnnounce(); + // + } + } + + break; + case PDELAY_INTERVAL_TIMEOUT_EXPIRES: + XPTPD_INFO("PDELAY_INTERVAL_TIMEOUT_EXPIRES occured"); + { + int ts_good; + Timestamp req_timestamp; + int iter = TX_TIMEOUT_ITER; + long req = TX_TIMEOUT_BASE; + unsigned req_timestamp_counter_value; + long long wait_time = 0; + + 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); + XPTPD_INFO("Sent PDelay Request"); + + ts_good = + getTxTimestamp + (pdelay_req, req_timestamp, req_timestamp_counter_value, + false); + while (ts_good != 0 && iter-- != 0) { + timer->sleep(req); + wait_time += req; + if (ts_good != -72 && iter < 1) + fprintf + (stderr, + "Error (TX) timestamping PDelay request " + "(Retrying-%d), error=%d\n", iter, ts_good); + ts_good = + getTxTimestamp + (pdelay_req, req_timestamp, + req_timestamp_counter_value, iter == 0); + req *= 2; + } + putTxLock(); + + if (ts_good == 0) { + pdelay_req->setTimestamp(req_timestamp); + } else { + Timestamp failed = INVALID_TIMESTAMP; + pdelay_req->setTimestamp(failed); + fprintf( stderr, "Invalid TX\n" ); + } + + if (ts_good != 0) { + char msg + [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE]; + getExtendedError(msg); + XPTPD_ERROR( + "Error (TX) timestamping PDelay request, error=%d\t%s", + ts_good, msg); + } +#ifdef DEBUG + if (ts_good == 0) { + XPTPD_INFO + ("Successful PDelay Req timestamp, %u,%u", + req_timestamp.seconds_ls, + req_timestamp.nanoseconds); + } else { + XPTPD_INFO + ("*** Unsuccessful PDelay Req timestamp"); + } +#endif + + { + long long timeout; + long long interval; + + timeout = PDELAY_RESP_RECEIPT_TIMEOUT_MULTIPLIER * + ((long long) + (pow((double)2,getPDelayInterval())*1000000000.0)) - + wait_time*1000; + timeout = timeout > EVENT_TIMER_GRANULARITY ? + timeout : EVENT_TIMER_GRANULARITY; + clock->addEventTimer + (this, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, timeout ); + + interval = + ((long long) + (pow((double)2,getPDelayInterval())*1000000000.0)) - + wait_time*1000; + interval = interval > EVENT_TIMER_GRANULARITY ? + interval : EVENT_TIMER_GRANULARITY; + clock->addEventTimer + (this, PDELAY_INTERVAL_TIMEOUT_EXPIRES, interval ); + } + } + break; + case SYNC_INTERVAL_TIMEOUT_EXPIRES: + XPTPD_INFO("SYNC_INTERVAL_TIMEOUT_EXPIRES occured"); + { + /* Set offset from master to zero, update device vs + system time offset */ + Timestamp system_time; + Timestamp device_time; + FrequencyRatio local_system_freq_offset; + int64_t local_system_offset; + long long wait_time = 0; + + uint32_t local_clock, nominal_clock_rate; + + // Send a sync message and then a followup to broadcast + if (asCapable) { + PTPMessageSync *sync = new PTPMessageSync(this); + PortIdentity dest_id; + getPortIdentity(dest_id); + sync->setPortIdentity(&dest_id); + getTxLock(); + sync->sendPort(this, NULL); + XPTPD_INFO("Sent SYNC message"); + + int ts_good; + Timestamp sync_timestamp; + unsigned sync_timestamp_counter_value; + int iter = TX_TIMEOUT_ITER; + long req = TX_TIMEOUT_BASE; + ts_good = + getTxTimestamp(sync, sync_timestamp, + sync_timestamp_counter_value, + false); + while (ts_good != 0 && iter-- != 0) { + timer->sleep(req); + wait_time += req; + + if (ts_good != -72 && iter < 1) + XPTPD_ERROR( + "Error (TX) timestamping Sync (Retrying), " + "error=%d", ts_good); + ts_good = + getTxTimestamp + (sync, sync_timestamp, + sync_timestamp_counter_value, iter == 0); + req *= 2; + } + putTxLock(); + + if (ts_good != 0) { + char msg + [HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE]; + getExtendedError(msg); + fprintf + (stderr, + "Error (TX) timestamping Sync, error=" + "%d\n%s", + ts_good, msg ); + } + + if (ts_good == 0) { + XPTPD_INFO("Successful Sync timestamp"); + XPTPD_INFO("Seconds: %u", + sync_timestamp.seconds_ls); + XPTPD_INFO("Nanoseconds: %u", + sync_timestamp.nanoseconds); + } else { + XPTPD_INFO + ("*** Unsuccessful Sync timestamp"); + } + + PTPMessageFollowUp *follow_up; + if (ts_good == 0) { + follow_up = + new PTPMessageFollowUp(this); + PortIdentity dest_id; + getPortIdentity(dest_id); + follow_up->setPortIdentity(&dest_id); + follow_up->setSequenceId(sync->getSequenceId()); + follow_up->setPreciseOriginTimestamp(sync_timestamp); + follow_up->sendPort(this, NULL); + delete follow_up; + } else { + } + delete sync; + } + /* Do getDeviceTime() after transmitting sync frame + causing an update to local/system timestamp */ + getDeviceTime + (system_time, device_time, local_clock, nominal_clock_rate); + + XPTPD_INFO + ("port::processEvent(): System time: %u,%u Device Time: %u,%u", + system_time.seconds_ls, system_time.nanoseconds, + device_time.seconds_ls, device_time.nanoseconds); + + local_system_offset = + TIMESTAMP_TO_NS(system_time) - + TIMESTAMP_TO_NS(device_time); + local_system_freq_offset = + clock->calcLocalSystemClockRateDifference + ( device_time, system_time ); + clock->setMasterOffset + (0, device_time, 1.0, local_system_offset, + system_time, local_system_freq_offset, sync_count, + pdelay_count, port_state ); + + /* If accelerated_sync is non-zero then start 16 ms sync + timer, subtract 1, for last one start PDelay also */ + if( _accelerated_sync_count > 0 ) { + clock->addEventTimer + ( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, 8000000 ); + --_accelerated_sync_count; + } else { + syncDone(); + if( _accelerated_sync_count == 0 ) { + --_accelerated_sync_count; + } + wait_time *= 1000; // to ns + wait_time = + ((long long) + (pow((double)2,getSyncInterval())*1000000000.0)) - + wait_time; + wait_time = wait_time > EVENT_TIMER_GRANULARITY ? wait_time : + EVENT_TIMER_GRANULARITY; + clock->addEventTimer + ( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, wait_time ); + } + + } + break; + case ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES: + if (asCapable) { + // Send an announce message + PTPMessageAnnounce *annc = new PTPMessageAnnounce(this); + PortIdentity dest_id; + PortIdentity gmId; + ClockIdentity clock_id = clock->getClockIdentity(); + gmId.setClockIdentity(clock_id); + getPortIdentity(dest_id); + annc->setPortIdentity(&dest_id); + annc->sendPort(this, NULL); + delete annc; + } + clock->addEventTimer + (this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES, + (unsigned) + (pow ((double)2, getAnnounceInterval()) * 1000000000.0)); + break; + case FAULT_DETECTED: + XPTPD_INFO("Received FAULT_DETECTED event"); + break; + case PDELAY_DEFERRED_PROCESSING: + pdelay_rx_lock->lock(); + if (last_pdelay_resp_fwup == NULL) { + fprintf(stderr, "PDelay Response Followup is NULL!\n"); + abort(); + } + last_pdelay_resp_fwup->processMessage(this); + if (last_pdelay_resp_fwup->garbage()) { + delete last_pdelay_resp_fwup; + this->setLastPDelayRespFollowUp(NULL); + } + pdelay_rx_lock->unlock(); + break; + case PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES: + setAsCapable(false); + pdelay_count = 0; + break; + default: + XPTPD_INFO + ("Unhandled event type in IEEE1588Port::processEvent(), %d", + e); + break; + } + + delete timer; + return; +} + +PTPMessageAnnounce *IEEE1588Port::calculateERBest(void) +{ + return qualified_announce; +} + +void IEEE1588Port::recoverPort(void) +{ + return; +} + +IEEE1588Clock *IEEE1588Port::getClock(void) +{ + return clock; +} + +void IEEE1588Port::getDeviceTime +(Timestamp & system_time, Timestamp & device_time, + uint32_t & local_clock, uint32_t & nominal_clock_rate) +{ + if (_hw_timestamper) { + _hw_timestamper->HWTimestamper_gettime + (&system_time, &device_time, &local_clock, &nominal_clock_rate); + } else { + device_time = system_time = clock->getSystemTime(); + local_clock = nominal_clock_rate = 0; + } + return; +} + +void IEEE1588Port::becomeMaster( bool annc ) { + port_state = PTP_MASTER; + // Start announce receipt timeout timer + // Start sync receipt timeout timer + clock->deleteEventTimer( this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ); + clock->deleteEventTimer( this, SYNC_RECEIPT_TIMEOUT_EXPIRES ); + if( annc ) { + startAnnounce(); + } + clock->addEventTimer( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, 16000000 ); + fprintf( stderr, "Switching to Master\n" ); + + return; +} + +void IEEE1588Port::becomeSlave( bool restart_syntonization ) { + clock->deleteEventTimer( this, ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES ); + clock->deleteEventTimer( this, SYNC_INTERVAL_TIMEOUT_EXPIRES ); + + port_state = PTP_SLAVE; + + /*clock->addEventTimer + ( this, SYNC_RECEIPT_TIMEOUT_EXPIRES, + (SYNC_RECEIPT_TIMEOUT_MULTIPLIER* + (unsigned long long)(pow((double)2,getSyncInterval())*1000000000.0)));*/ + clock->addEventTimer + (this, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES, + (ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER* + (unsigned long long) + (pow((double)2,getAnnounceInterval())*1000000000.0))); + fprintf( stderr, "Switching to Slave\n" ); + if( restart_syntonization ) clock->newSyntonizationSetPoint(); + + return; +} + +void IEEE1588Port::recommendState +( PortState state, bool changed_external_master ) +{ + bool reset_sync = false; + switch (state) { + case PTP_MASTER: + if (port_state != PTP_MASTER) { + port_state = PTP_MASTER; + // Start announce receipt timeout timer + // Start sync receipt timeout timer + becomeMaster( true ); + reset_sync = true; + } + break; + case PTP_SLAVE: + if (port_state != PTP_SLAVE) { + becomeSlave( true ); + reset_sync = true; + } else { + if( changed_external_master ) { + fprintf( stderr, "Changed master!\n" ); + clock->newSyntonizationSetPoint(); + reset_sync = true; + } + } + break; + default: + XPTPD_INFO + ("Invalid state change requested by call to " + "1588Port::recommendState()"); + break; + } + if( reset_sync ) sync_count = 0; + return; + } + +void IEEE1588Port::mapSocketAddr +(PortIdentity * destIdentity, LinkLayerAddress * remote) +{ + *remote = identity_map[*destIdentity]; + return; +} + +void IEEE1588Port::addSockAddrMap +(PortIdentity * destIdentity, LinkLayerAddress * remote) +{ + identity_map[*destIdentity] = *remote; + return; +} + +int IEEE1588Port::getTxTimestamp +(PTPMessageCommon * msg, Timestamp & timestamp, unsigned &counter_value, + bool last) +{ + PortIdentity identity; + msg->getPortIdentity(&identity); + return getTxTimestamp + (&identity, msg->getSequenceId(), timestamp, counter_value, last); +} + +int IEEE1588Port::getRxTimestamp(PTPMessageCommon * msg, Timestamp & timestamp, + unsigned &counter_value, bool last) +{ + PortIdentity identity; + msg->getPortIdentity(&identity); + return getRxTimestamp + (&identity, msg->getSequenceId(), timestamp, counter_value, last); +} + +int IEEE1588Port::getTxTimestamp(PortIdentity * sourcePortIdentity, + uint16_t sequenceId, Timestamp & timestamp, + unsigned &counter_value, bool last) +{ + if (_hw_timestamper) { + return _hw_timestamper->HWTimestamper_txtimestamp + (sourcePortIdentity, sequenceId, timestamp, counter_value, + last); + } + timestamp = clock->getSystemTime(); + return 0; +} + +int IEEE1588Port::getRxTimestamp(PortIdentity * sourcePortIdentity, + uint16_t sequenceId, Timestamp & timestamp, + unsigned &counter_value, bool last) +{ + if (_hw_timestamper) { + return _hw_timestamper->HWTimestamper_rxtimestamp + (sourcePortIdentity, sequenceId, timestamp, counter_value, + last); + } + timestamp = clock->getSystemTime(); + return 0; +} diff --git a/daemons/gptp/common/ptp_message.cpp b/daemons/gptp/common/ptp_message.cpp index e713f57b..532dfed7 100644 --- a/daemons/gptp/common/ptp_message.cpp +++ b/daemons/gptp/common/ptp_message.cpp @@ -1,1583 +1,1583 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-#include <ieee1588.hpp>
-#include <avbts_clock.hpp>
-#include <avbts_message.hpp>
-#include <avbts_port.hpp>
-#include <avbts_ostimer.hpp>
-
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-#include <time.h>
-
-PTPMessageCommon::PTPMessageCommon(IEEE1588Port * port)
-{
- // Fill in fields using port/clock dataset as a template
- versionPTP = GPTP_VERSION;
- versionNetwork = PTP_NETWORK_VERSION;
- domainNumber = port->getClock()->getDomain();
- // Set flags as necessary
- memset(flags, 0, PTP_FLAGS_LENGTH);
- 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, IEEE1588Port * port)
-{
- OSTimer *timer = port->getTimerFactory()->createTimer();
- PTPMessageCommon *msg = NULL;
- 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;
-
-#if PTP_DEBUG
- {
- int i;
- XPTPD_INFO("Packet Dump:\n");
- for (i = 0; i < size; ++i) {
- fprintf(stderr, "%hhx\t", buf[i]);
- if (i % 8 == 7)
- fprintf(stderr, "\n");
- }
- if (i % 8 != 0)
- fprintf(stderr, "\n");
- }
-#endif
-
- memcpy(&tspec_msg_t,
- buf + PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(PTP_COMMON_HDR_OFFSET),
- sizeof(tspec_msg_t));
- messageType = (MessageType) (tspec_msg_t & 0xF);
- 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);
-
- XPTPD_INFO("Captured Sequence Id: %u", sequenceId);
-
- if (!(messageType >> 3)) {
- int iter = 2;
- long req = 1000; // = 1 ms
- int ts_good =
- port->getRxTimestamp
- (sourcePortIdentity, sequenceId, timestamp, counter_value, false);
- while (ts_good != 0 && iter-- != 0) {
- // Waits at least 1 time slice regardless of size of 'req'
- timer->sleep(req);
- if (ts_good != -72)
- fprintf
- ( stderr, "Error (RX) timestamping RX event packet (Retrying), error=%d\n",
- ts_good );
- ts_good =
- port->getRxTimestamp(sourcePortIdentity, sequenceId,
- timestamp, counter_value,
- iter == 0);
- req *= 2;
- }
- if (ts_good != 0) {
- char msg[HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
- port->getExtendedError(msg);
- XPTPD_ERROR
- ("*** Received an event packet but cannot retrieve timestamp, discarding. messageType=%u,error=%d\n%s",
- messageType, ts_good, msg);
- //_exit(-1);
- return NULL;
- }
-
- else {
- XPTPD_INFO("Timestamping event packet");
- }
-
- }
-
- if (transportSpecific!=1) {
- XPTPD_INFO("*** Received message with unsupported transportSpecific type=%d",transportSpecific);
- return NULL;
- }
-
- switch (messageType) {
- case SYNC_MESSAGE:
-
- //fprintf( stderr, "*** Received Sync message\n" );
- //printf( "Sync RX timestamp = %hu,%u,%u\n", timestamp.seconds_ms, timestamp.seconds_ls, timestamp.nanoseconds );
- XPTPD_INFO("*** Received Sync message");
-
- // Be sure buffer is the correction size
- if (size < PTP_COMMON_HDR_LENGTH + PTP_SYNC_LENGTH) {
- goto done;
- }
- {
- PTPMessageSync *sync_msg = new PTPMessageSync();
- sync_msg->messageType = messageType;
- // Copy in v2 sync specific fields
- memcpy(&(sync_msg->originTimestamp.seconds_ms),
- buf + PTP_SYNC_SEC_MS(PTP_SYNC_OFFSET),
- sizeof(sync_msg->originTimestamp.seconds_ms));
- memcpy(&(sync_msg->originTimestamp.seconds_ls),
- buf + PTP_SYNC_SEC_LS(PTP_SYNC_OFFSET),
- sizeof(sync_msg->originTimestamp.seconds_ls));
- memcpy(&(sync_msg->originTimestamp.nanoseconds),
- buf + PTP_SYNC_NSEC(PTP_SYNC_OFFSET),
- sizeof(sync_msg->originTimestamp.nanoseconds));
- msg = sync_msg;
- }
- break;
- case FOLLOWUP_MESSAGE:
-
- XPTPD_INFO("*** Received Follow Up message");
-
- // Be sure buffer is the correction size
- if (size < (int)(PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH + sizeof(FollowUpTLV))) {
- goto done;
- }
- {
- PTPMessageFollowUp *followup_msg =
- new PTPMessageFollowUp();
- followup_msg->messageType = messageType;
- // Copy in v2 sync specific fields
- memcpy(&
- (followup_msg->
- preciseOriginTimestamp.seconds_ms),
- buf + PTP_FOLLOWUP_SEC_MS(PTP_FOLLOWUP_OFFSET),
- sizeof(followup_msg->
- preciseOriginTimestamp.seconds_ms));
- memcpy(&
- (followup_msg->
- preciseOriginTimestamp.seconds_ls),
- buf + PTP_FOLLOWUP_SEC_LS(PTP_FOLLOWUP_OFFSET),
- sizeof(followup_msg->
- preciseOriginTimestamp.seconds_ls));
- memcpy(&
- (followup_msg->
- preciseOriginTimestamp.nanoseconds),
- buf + PTP_FOLLOWUP_NSEC(PTP_FOLLOWUP_OFFSET),
- sizeof(followup_msg->
- preciseOriginTimestamp.nanoseconds));
-
- followup_msg->preciseOriginTimestamp.seconds_ms =
- PLAT_ntohs(followup_msg->
- preciseOriginTimestamp.seconds_ms);
- followup_msg->preciseOriginTimestamp.seconds_ls =
- PLAT_ntohl(followup_msg->
- preciseOriginTimestamp.seconds_ls);
- followup_msg->preciseOriginTimestamp.nanoseconds =
- PLAT_ntohl(followup_msg->
- preciseOriginTimestamp.nanoseconds);
-
- memcpy( &(followup_msg->tlv), buf+PTP_FOLLOWUP_LENGTH, sizeof(followup_msg->tlv) );
-
- msg = followup_msg;
- }
- break;
- case PATH_DELAY_REQ_MESSAGE:
-
- XPTPD_INFO("*** Received PDelay Request message");
-
- // Be sure buffer is the correction size
- if (size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_REQ_LENGTH
- && /* For Broadcom compatibility */ size != 46) {
- goto done;
- }
- {
- PTPMessagePathDelayReq *pdelay_req_msg =
- new PTPMessagePathDelayReq();
- pdelay_req_msg->messageType = messageType;
-
-#if 0
- // The origin timestamp for PDelay Request packets has been eliminated since it is unused
- // Copy in v2 PDelay Request specific fields
- memcpy(&(pdelay_req_msg->originTimestamp.seconds_ms),
- buf +
- PTP_PDELAY_REQ_SEC_MS(PTP_PDELAY_REQ_OFFSET),
- sizeof(pdelay_req_msg->
- originTimestamp.seconds_ms));
- memcpy(&(pdelay_req_msg->originTimestamp.seconds_ls),
- buf +
- PTP_PDELAY_REQ_SEC_LS(PTP_PDELAY_REQ_OFFSET),
- sizeof(pdelay_req_msg->
- originTimestamp.seconds_ls));
- memcpy(&(pdelay_req_msg->originTimestamp.nanoseconds),
- buf + PTP_PDELAY_REQ_NSEC(PTP_PDELAY_REQ_OFFSET),
- sizeof(pdelay_req_msg->
- originTimestamp.nanoseconds));
-
- pdelay_req_msg->originTimestamp.seconds_ms =
- PLAT_ntohs(pdelay_req_msg->
- originTimestamp.seconds_ms);
- pdelay_req_msg->originTimestamp.seconds_ls =
- PLAT_ntohl(pdelay_req_msg->
- originTimestamp.seconds_ls);
- pdelay_req_msg->originTimestamp.nanoseconds =
- PLAT_ntohl(pdelay_req_msg->
- originTimestamp.nanoseconds);
-#endif
-
- msg = pdelay_req_msg;
- }
- break;
- case PATH_DELAY_RESP_MESSAGE:
-
- XPTPD_INFO("*** Received PDelay Response message, %u, %u, %u",
- timestamp.seconds_ls, timestamp.nanoseconds,
- sequenceId);
-
- // Be sure buffer is the correction size
- if (size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_RESP_LENGTH) {
- goto done;
- }
- {
- PTPMessagePathDelayResp *pdelay_resp_msg =
- new PTPMessagePathDelayResp();
- pdelay_resp_msg->messageType = messageType;
- // Copy in v2 PDelay Response specific fields
- pdelay_resp_msg->requestingPortIdentity =
- new PortIdentity((uint8_t *) buf +
- PTP_PDELAY_RESP_REQ_CLOCK_ID
- (PTP_PDELAY_RESP_OFFSET),
- (uint16_t *) (buf +
- PTP_PDELAY_RESP_REQ_PORT_ID
- (PTP_PDELAY_RESP_OFFSET)));
-
-#ifdef DEBUG
- for (int n = 0; n < PTP_CLOCK_IDENTITY_LENGTH; ++n) { // MMM
- fprintf(stderr, "%c",
- pdelay_resp_msg->
- requestingPortIdentity.clockIdentity
- [n]);
- }
-#endif
-
- memcpy(& (pdelay_resp_msg->requestReceiptTimestamp.seconds_ms),
- buf + PTP_PDELAY_RESP_SEC_MS(PTP_PDELAY_RESP_OFFSET),
- sizeof
- (pdelay_resp_msg->requestReceiptTimestamp.seconds_ms));
- memcpy(&
- (pdelay_resp_msg->
- requestReceiptTimestamp.seconds_ls),
- buf +
- PTP_PDELAY_RESP_SEC_LS(PTP_PDELAY_RESP_OFFSET),
- sizeof(pdelay_resp_msg->
- requestReceiptTimestamp.seconds_ls));
- memcpy(&
- (pdelay_resp_msg->
- requestReceiptTimestamp.nanoseconds),
- buf +
- PTP_PDELAY_RESP_NSEC(PTP_PDELAY_RESP_OFFSET),
- sizeof(pdelay_resp_msg->
- requestReceiptTimestamp.nanoseconds));
-
- pdelay_resp_msg->requestReceiptTimestamp.seconds_ms =
- PLAT_ntohs(pdelay_resp_msg->requestReceiptTimestamp.seconds_ms);
- pdelay_resp_msg->requestReceiptTimestamp.seconds_ls =
- PLAT_ntohl(pdelay_resp_msg->requestReceiptTimestamp.seconds_ls);
- pdelay_resp_msg->requestReceiptTimestamp.nanoseconds =
- PLAT_ntohl(pdelay_resp_msg->requestReceiptTimestamp.nanoseconds);
-
- msg = pdelay_resp_msg;
- }
- break;
- case PATH_DELAY_FOLLOWUP_MESSAGE:
-
- XPTPD_INFO("*** Received PDelay Response FollowUp message");
-
- // Be sure buffer is the correction size
-// if( size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_FOLLOWUP_LENGTH ) {
-// goto done;
-// }
- {
- PTPMessagePathDelayRespFollowUp *pdelay_resp_fwup_msg =
- new PTPMessagePathDelayRespFollowUp();
- pdelay_resp_fwup_msg->messageType = messageType;
- // Copy in v2 PDelay Response specific fields
- pdelay_resp_fwup_msg->requestingPortIdentity =
- new PortIdentity((uint8_t *) buf +
- PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID
- (PTP_PDELAY_RESP_OFFSET),
- (uint16_t *) (buf +
- PTP_PDELAY_FOLLOWUP_REQ_PORT_ID
- (PTP_PDELAY_FOLLOWUP_OFFSET)));
-
- memcpy(&
- (pdelay_resp_fwup_msg->
- responseOriginTimestamp.seconds_ms),
- buf +
- PTP_PDELAY_FOLLOWUP_SEC_MS
- (PTP_PDELAY_FOLLOWUP_OFFSET),
- sizeof
- (pdelay_resp_fwup_msg->responseOriginTimestamp.
- seconds_ms));
- memcpy(&
- (pdelay_resp_fwup_msg->
- responseOriginTimestamp.seconds_ls),
- buf +
- PTP_PDELAY_FOLLOWUP_SEC_LS
- (PTP_PDELAY_FOLLOWUP_OFFSET),
- sizeof
- (pdelay_resp_fwup_msg->responseOriginTimestamp.
- seconds_ls));
- memcpy(&
- (pdelay_resp_fwup_msg->
- responseOriginTimestamp.nanoseconds),
- buf +
- PTP_PDELAY_FOLLOWUP_NSEC
- (PTP_PDELAY_FOLLOWUP_OFFSET),
- sizeof
- (pdelay_resp_fwup_msg->responseOriginTimestamp.
- nanoseconds));
-
- pdelay_resp_fwup_msg->
- responseOriginTimestamp.seconds_ms =
- PLAT_ntohs
- (pdelay_resp_fwup_msg->responseOriginTimestamp.
- seconds_ms);
- pdelay_resp_fwup_msg->
- responseOriginTimestamp.seconds_ls =
- PLAT_ntohl
- (pdelay_resp_fwup_msg->responseOriginTimestamp.
- seconds_ls);
- pdelay_resp_fwup_msg->
- responseOriginTimestamp.nanoseconds =
- PLAT_ntohl
- (pdelay_resp_fwup_msg->responseOriginTimestamp.
- nanoseconds);
-
- msg = pdelay_resp_fwup_msg;
- }
- break;
- case ANNOUNCE_MESSAGE:
- {
- PTPMessageAnnounce *annc = new PTPMessageAnnounce();
- annc->messageType = messageType;
-
- memcpy(&(annc->currentUtcOffset),
- buf +
- PTP_ANNOUNCE_CURRENT_UTC_OFFSET
- (PTP_ANNOUNCE_OFFSET),
- sizeof(annc->currentUtcOffset));
- annc->currentUtcOffset =
- PLAT_ntohs(annc->currentUtcOffset);
- memcpy(&(annc->grandmasterPriority1),
- buf +
- PTP_ANNOUNCE_GRANDMASTER_PRIORITY1
- (PTP_ANNOUNCE_OFFSET),
- sizeof(annc->grandmasterPriority1));
- memcpy( annc->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));
-
- msg = annc;
- }
- break;
- default:
-
- XPTPD_ERROR("Received unsupported message type, %d",
- (int)messageType);
-
- goto done;
- }
-
- msg->_gc = false;
-
- // Copy in common header fields
- memcpy(&(msg->versionPTP),
- buf + PTP_COMMON_HDR_PTP_VERSION(PTP_COMMON_HDR_OFFSET),
- sizeof(msg->versionPTP));
- memcpy(&(msg->messageLength),
- buf + PTP_COMMON_HDR_MSG_LENGTH(PTP_COMMON_HDR_OFFSET),
- sizeof(msg->messageLength));
- msg->messageLength = PLAT_ntohs(msg->messageLength);
- memcpy(&(msg->domainNumber),
- buf + PTP_COMMON_HDR_DOMAIN_NUMBER(PTP_COMMON_HDR_OFFSET),
- sizeof(msg->domainNumber));
- memcpy(&(msg->flags), buf + PTP_COMMON_HDR_FLAGS(PTP_COMMON_HDR_OFFSET),
- PTP_FLAGS_LENGTH);
- memcpy(&(msg->correctionField),
- buf + PTP_COMMON_HDR_CORRECTION(PTP_COMMON_HDR_OFFSET),
- sizeof(msg->correctionField));
- msg->correctionField = bswap_64(msg->correctionField); // Assume LE machine
- msg->sourcePortIdentity = sourcePortIdentity;
- msg->sequenceId = sequenceId;
- memcpy(&(msg->control),
- buf + PTP_COMMON_HDR_CONTROL(PTP_COMMON_HDR_OFFSET),
- sizeof(msg->control));
- memcpy(&(msg->logMeanMessageInterval),
- buf + PTP_COMMON_HDR_LOG_MSG_INTRVL(PTP_COMMON_HDR_OFFSET),
- sizeof(msg->logMeanMessageInterval));
-
- port->addSockAddrMap(msg->sourcePortIdentity, remote);
-
- msg->_timestamp = timestamp;
- msg->_timestamp_counter_value = counter_value;
-
- done:
- delete timer;
-
- return msg;
-}
-
-void PTPMessageCommon::processMessage(IEEE1588Port * port)
-{
- _gc = true;
- return;
-}
-
-void PTPMessageCommon::buildCommonHeader(uint8_t * buf)
-{
- unsigned char tspec_msg_t;
- tspec_msg_t = messageType | 0x10;
- //tspec_msg_t = messageType;
- long long correctionField_BE = bswap_64(correctionField); // Assume LE machine
- uint16_t messageLength_NO = PLAT_htons(messageLength);
-
- memcpy(buf + PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(PTP_COMMON_HDR_OFFSET),
- &tspec_msg_t, sizeof(tspec_msg_t));
- memcpy(buf + PTP_COMMON_HDR_PTP_VERSION(PTP_COMMON_HDR_OFFSET),
- &versionPTP, sizeof(versionPTP));
- memcpy(buf + PTP_COMMON_HDR_MSG_LENGTH(PTP_COMMON_HDR_OFFSET),
- &messageLength_NO, sizeof(messageLength_NO));
- memcpy(buf + PTP_COMMON_HDR_DOMAIN_NUMBER(PTP_COMMON_HDR_OFFSET),
- &domainNumber, sizeof(domainNumber));
- memcpy(buf + PTP_COMMON_HDR_FLAGS(PTP_COMMON_HDR_OFFSET), &flags,
- PTP_FLAGS_LENGTH);
- memcpy(buf + PTP_COMMON_HDR_CORRECTION(PTP_COMMON_HDR_OFFSET),
- &correctionField_BE, sizeof(correctionField));
-
- sourcePortIdentity->getClockIdentityString
- ((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)));
-
- XPTPD_INFO("Sending Sequence Id: %u", sequenceId);
- sequenceId = PLAT_htons(sequenceId);
- memcpy(buf + PTP_COMMON_HDR_SEQUENCE_ID(PTP_COMMON_HDR_OFFSET),
- &sequenceId, sizeof(sequenceId));
- sequenceId = PLAT_ntohs(sequenceId);
- memcpy(buf + PTP_COMMON_HDR_CONTROL(PTP_COMMON_HDR_OFFSET), &control,
- sizeof(control));
- memcpy(buf + PTP_COMMON_HDR_LOG_MSG_INTRVL(PTP_COMMON_HDR_OFFSET),
- &logMeanMessageInterval, sizeof(logMeanMessageInterval));
-
- return;
-}
-
-void PTPMessageCommon::getPortIdentity(PortIdentity * identity)
-{
- *identity = *sourcePortIdentity;
-}
-
-void PTPMessageCommon::setPortIdentity(PortIdentity * identity)
-{
- *sourcePortIdentity = *identity;
-}
-
-PTPMessageCommon::~PTPMessageCommon(void)
-{
- delete sourcePortIdentity;
- return;
-}
-
-PTPMessageAnnounce::PTPMessageAnnounce(void)
-{
- 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
- fprintf(stderr, "Us: ");
- for (int i = 0; i < 14; ++i)
- fprintf(stderr, "%hhx", this1[i]);
- fprintf(stderr, "\n");
- fprintf(stderr, "Them: ");
- for (int i = 0; i < 14; ++i)
- fprintf(stderr, "%hhx", that1[i]);
- fprintf(stderr, "\n");
-#endif
-
- return (memcmp(this1, that1, 14) < 0) ? true : false;
-}
-
-
-PTPMessageSync::PTPMessageSync() {
-}
-
-PTPMessageSync::~PTPMessageSync() {
-}
-
-PTPMessageSync::PTPMessageSync(IEEE1588Port * port) : PTPMessageCommon(port)
-{
- messageType = SYNC_MESSAGE; // This is an event message
- sequenceId = port->getNextSyncSequenceId();
- control = SYNC;
-
- flags[PTP_ASSIST_BYTE] |= (0x1 << PTP_ASSIST_BIT);
-
- originTimestamp = port->getClock()->getTime();
-
- logMeanMessageInterval = port->getSyncInterval();
- return;
-}
-
-void PTPMessageSync::sendPort(IEEE1588Port * port, PortIdentity * destIdentity)
-{
- uint8_t buf_t[256];
- uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
- unsigned char tspec_msg_t = 0x0;
- Timestamp originTimestamp_BE;
- memset(buf_t, 0, 256);
- // Create packet in buf
- // Copy in common header
- messageLength = PTP_COMMON_HDR_LENGTH + PTP_SYNC_LENGTH;
- tspec_msg_t |= messageType & 0xF;
- buildCommonHeader(buf_ptr);
- // Get timestamp
- originTimestamp = port->getClock()->getTime();
- originTimestamp_BE.seconds_ms = PLAT_htons(originTimestamp.seconds_ms);
- originTimestamp_BE.seconds_ls = PLAT_htonl(originTimestamp.seconds_ls);
- originTimestamp_BE.nanoseconds =
- PLAT_htonl(originTimestamp.nanoseconds);
- // Copy in v2 sync specific fields
- memcpy(buf_ptr + PTP_SYNC_SEC_MS(PTP_SYNC_OFFSET),
- &(originTimestamp_BE.seconds_ms),
- sizeof(originTimestamp.seconds_ms));
- memcpy(buf_ptr + PTP_SYNC_SEC_LS(PTP_SYNC_OFFSET),
- &(originTimestamp_BE.seconds_ls),
- sizeof(originTimestamp.seconds_ls));
- memcpy(buf_ptr + PTP_SYNC_NSEC(PTP_SYNC_OFFSET),
- &(originTimestamp_BE.nanoseconds),
- sizeof(originTimestamp.nanoseconds));
-
- port->sendEventPort(buf_t, messageLength, MCAST_OTHER, destIdentity);
-
- return;
-}
-
- PTPMessageAnnounce::PTPMessageAnnounce(IEEE1588Port * port) : PTPMessageCommon
- (port)
-{
- messageType = ANNOUNCE_MESSAGE; // This is an event message
- sequenceId = port->getNextAnnounceSequenceId();
- ClockIdentity id;
- control = MESSAGE_OTHER;
- ClockIdentity clock_identity;
-
- id = port->getClock()->getClockIdentity();
- tlv.setClockIdentity(&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;
-}
-
-void PTPMessageAnnounce::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
-{
- uint8_t buf_t[256];
- uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
- unsigned char tspec_msg_t = 0x0;
-
- uint16_t currentUtcOffset_l = PLAT_htons(currentUtcOffset);
- uint16_t stepsRemoved_l = PLAT_htons(stepsRemoved);
- ClockQuality clockQuality_l = *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 + sizeof(tlv);
- 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(buf_t, messageLength, MCAST_OTHER, destIdentity);
-
- return;
-}
-
-void PTPMessageAnnounce::processMessage(IEEE1588Port * port)
-{
- // Delete announce receipt timeout
- port->getClock()->deleteEventTimerLocked
- (port, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES);
-
- if( stepsRemoved >= 255 ) goto bail;
- // Add message to the list
- port->addQualifiedAnnounce(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(IEEE1588Port * port)
-{
- Timestamp system_time;
- Timestamp device_time;
- Timestamp corrected_sync_time;
-
- uint64_t delay;
-
- signed long long local_system_offset;
- signed long long scalar_offset;
- int correction;
-
- FrequencyRatio local_clock_adjustment;
- FrequencyRatio local_system_freq_offset;
-
- 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
- port->recoverPort();
- return;
- }
-
- XPTPD_INFO("PTP assist flag is not set, FLAGS[0,1] = %u,%u", flags[0],
- flags[1]);
-
-// if( flags[PTP_ASSIST_BYTE] & (0x1<<PTP_ASSIST_BIT)) {
- if (true) {
- // If PTP_ASSIST flag is set, expect a follow-up message and do nothing
- PTPMessageSync *old_sync = port->getLastSync();
- if (old_sync != NULL) {
- delete old_sync;
- }
- port->setLastSync(this);
- _gc = false;
- goto done;
- } else {
- _gc = true;
- }
-
- // Indicates invalid link delay, wait until link delay had been calculated
- if ((delay = port->getLinkDelay()) == 3600000000000) {
- printf
- ("Got Sync/Follow-Up but Link Delay has not been computed\n");
- goto done;
- }
-
- correction = (int) (delay + (correctionField >> 16));
- corrected_sync_time = _timestamp;
- TIMESTAMP_SUB_NS( corrected_sync_time, correction );
- scalar_offset = TIMESTAMP_TO_NS( corrected_sync_time );
- scalar_offset -= TIMESTAMP_TO_NS( originTimestamp );
-
- // Otherwise synchronize clock with approximate time from Sync message
- uint32_t local_clock;
- uint32_t nominal_clock_rate;
- uint32_t device_sync_time_offset;
-
- port->getDeviceTime
- (system_time, device_time, local_clock, nominal_clock_rate);
-
- // Adjust local_clock to correspond to _timestamp
- device_sync_time_offset =
- TIMESTAMP_TO_NS(device_time) - TIMESTAMP_TO_NS(_timestamp);
- local_clock -=
- device_sync_time_offset / (1000000000 / nominal_clock_rate);
-
- XPTPD_INFO
- ("ptp_message::sync::processMessage System time: %u,%u "
- "Device Time: %u,%u",
- system_time.seconds_ls, system_time.nanoseconds,
- device_time.seconds_ls, device_time.nanoseconds);
-
- local_clock_adjustment = port->getClock()->
- calcMasterLocalClockRateDifference
- ( originTimestamp, corrected_sync_time );
-
- local_system_offset =
- TIMESTAMP_TO_NS(system_time) - TIMESTAMP_TO_NS(device_time);
-
- if( port->getPortState() != PTP_MASTER ) {
- /* 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)
- (device_sync_time_offset/local_system_freq_offset) );
- port->getClock()->setMasterOffset
- ( scalar_offset, _timestamp, local_clock_adjustment,
- local_system_offset, system_time, local_system_freq_offset,
- port->getSyncCount(), port->getPdelayCount(), port->getPortState() );
- port->syncDone();
- }
-
-
- done:
- return;
-}
-
- PTPMessageFollowUp::PTPMessageFollowUp(IEEE1588Port * port):PTPMessageCommon
- (port)
-{
- messageType = FOLLOWUP_MESSAGE; /* This is an event message */
- control = FOLLOWUP;
-
- logMeanMessageInterval = port->getSyncInterval();
-
- return;
-}
-
-void PTPMessageFollowUp::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
-{
- uint8_t buf_t[256];
- uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
- unsigned char tspec_msg_t = 0x0;
- Timestamp preciseOriginTimestamp_BE;
- memset(buf_t, 0, 256);
- /* Create packet in buf
- Copy in common header */
- messageLength =
- PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH + sizeof(tlv);
- tspec_msg_t |= messageType & 0xF;
- buildCommonHeader(buf_ptr);
- preciseOriginTimestamp_BE.seconds_ms =
- PLAT_htons(preciseOriginTimestamp.seconds_ms);
- preciseOriginTimestamp_BE.seconds_ls =
- PLAT_htonl(preciseOriginTimestamp.seconds_ls);
- preciseOriginTimestamp_BE.nanoseconds =
- PLAT_htonl(preciseOriginTimestamp.nanoseconds);
- /* Copy in v2 sync specific fields */
- memcpy(buf_ptr + PTP_FOLLOWUP_SEC_MS(PTP_FOLLOWUP_OFFSET),
- &(preciseOriginTimestamp_BE.seconds_ms),
- sizeof(preciseOriginTimestamp.seconds_ms));
- memcpy(buf_ptr + PTP_FOLLOWUP_SEC_LS(PTP_FOLLOWUP_OFFSET),
- &(preciseOriginTimestamp_BE.seconds_ls),
- sizeof(preciseOriginTimestamp.seconds_ls));
- memcpy(buf_ptr + PTP_FOLLOWUP_NSEC(PTP_FOLLOWUP_OFFSET),
- &(preciseOriginTimestamp_BE.nanoseconds),
- sizeof(preciseOriginTimestamp.nanoseconds));
- tlv.toByteString(buf_ptr + PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH);
-
- XPTPD_INFO
- ("Follow-Up Time: %u seconds(hi)", preciseOriginTimestamp.seconds_ms);
- XPTPD_INFO
- ("Follow-Up Time: %u seconds", preciseOriginTimestamp.seconds_ls);
- XPTPD_INFO
- ("FW-UP Time: %u nanoseconds", preciseOriginTimestamp.nanoseconds);
- XPTPD_INFO
- ("FW-UP Time: %x seconds", preciseOriginTimestamp.seconds_ls);
- XPTPD_INFO
- ("FW-UP Time: %x nanoseconds", preciseOriginTimestamp.nanoseconds);
-#if 0
- XPTPD_INFO("Follow-up Dump:\n");
-#ifdef DEBUG
- for (int i = 0; i < messageLength; ++i) {
- fprintf(stderr, "%d:%02x ", i, (unsigned char)buf[i]);
- }
- fprintf(stderr, "\n");
-#endif
-#endif
-
- port->sendGeneralPort(buf_t, messageLength, MCAST_OTHER, destIdentity);
-
- return;
-}
-
-void PTPMessageFollowUp::processMessage(IEEE1588Port * port)
-{
- uint64_t delay;
- Timestamp sync_arrival;
- Timestamp system_time(0, 0, 0);
- Timestamp device_time(0, 0, 0);
- Timestamp corrected_sync_time;
-
- 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;
- int correction;
-
- XPTPD_INFO("Processing a follow-up message");
-
- // Expire any SYNC_RECEIPT timers that exist
- port->getClock()->deleteEventTimerLocked
- (port, SYNC_RECEIPT_TIMEOUT_EXPIRES);
-
- 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
- port->recoverPort();
- return;
- }
-
- PortIdentity sync_id;
- PTPMessageSync *sync = port->getLastSync();
- if (sync == NULL) {
- XPTPD_ERROR("Received Follow Up but there is no sync message");
- return;
- }
- sync->getPortIdentity(&sync_id);
-
- if (sync->getSequenceId() != sequenceId || sync_id != *sourcePortIdentity)
- {
- XPTPD_ERROR
- ("Received Follow Up but cannot find corresponding Sync");
- goto done;
- }
-
- sync_arrival = sync->getTimestamp();
-
- delay = port->getLinkDelay();
- if ((delay = port->getLinkDelay()) == 3600000000000) {
- goto done;
- }
-
- master_local_freq_offset = tlv.getRateOffset();
- master_local_freq_offset /= 2ULL << 41;
- master_local_freq_offset += 1.0;
- master_local_freq_offset /= port->getPeerRateOffset();
-
- correctionField = (uint64_t)
- ((correctionField >> 16)/master_local_freq_offset);
- correction = (int) (delay + (correctionField >> 16));
- corrected_sync_time = sync_arrival;
-
- if( correction > 0 )
- TIMESTAMP_SUB_NS( corrected_sync_time, correction );
- else TIMESTAMP_ADD_NS( corrected_sync_time, -correction );
- scalar_offset = TIMESTAMP_TO_NS( corrected_sync_time );
- scalar_offset -= TIMESTAMP_TO_NS( preciseOriginTimestamp );
-
- XPTPD_INFO
- ("Followup Correction Field: %Ld,%lu", correctionField >> 16,
- delay);
- XPTPD_INFO
- ("FollowUp Scalar = %lld", scalar_offset);
-
- /* Otherwise synchronize clock with approximate time from Sync message */
- uint32_t local_clock, nominal_clock_rate;
- uint32_t device_sync_time_offset;
-
- port->getDeviceTime(system_time, device_time, local_clock,
- nominal_clock_rate);
- XPTPD_INFO
- ( "Device Time = %llu,System Time = %llu\n",
- TIMESTAMP_TO_NS(device_time), TIMESTAMP_TO_NS(system_time));
-
- /* Adjust local_clock to correspond to sync_arrival */
- device_sync_time_offset =
- TIMESTAMP_TO_NS(device_time) - TIMESTAMP_TO_NS(sync_arrival);
-
- XPTPD_INFO
- ("ptp_message::FollowUp::processMessage System time: %u,%u "
- "Device Time: %u,%u",
- system_time.seconds_ls, system_time.nanoseconds,
- device_time.seconds_ls, device_time.nanoseconds);
-
- local_system_offset =
- TIMESTAMP_TO_NS(system_time) - TIMESTAMP_TO_NS(device_time);
-
- local_clock_adjustment =
- port->getClock()->
- calcMasterLocalClockRateDifference
- ( preciseOriginTimestamp, corrected_sync_time );
-
- if( port->getPortState() != PTP_MASTER ) {
- 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) );
- port->getClock()->setMasterOffset
- ( scalar_offset, sync_arrival, local_clock_adjustment,
- local_system_offset, system_time, local_system_freq_offset,
- port->getSyncCount(), port->getPdelayCount(),
- port->getPortState() );
- port->syncDone();
- // Restart the SYNC_RECEIPT timer
- port->getClock()->addEventTimerLocked
- (port, SYNC_RECEIPT_TIMEOUT_EXPIRES, (unsigned long long)
- (SYNC_RECEIPT_TIMEOUT_MULTIPLIER *
- ((double) pow((double)2, port->getSyncInterval()) *
- 1000000000.0)));
- }
-
-done:
- _gc = true;
- port->setLastSync(NULL);
- delete sync;
-
- return;
-}
-
- PTPMessagePathDelayReq::PTPMessagePathDelayReq(IEEE1588Port * port):
- PTPMessageCommon (port)
-{
- logMeanMessageInterval = 0;
- control = MESSAGE_OTHER;
- messageType = PATH_DELAY_REQ_MESSAGE;
- sequenceId = port->getNextPDelaySequenceId();
- return;
-}
-
-void PTPMessagePathDelayReq::processMessage(IEEE1588Port * port)
-{
- OSTimer *timer = port->getTimerFactory()->createTimer();
- PortIdentity resp_fwup_id;
- PortIdentity requestingPortIdentity_p;
- PTPMessagePathDelayResp *resp;
- PortIdentity resp_id;
- PTPMessagePathDelayRespFollowUp *resp_fwup;
-
- int ts_good;
- Timestamp resp_timestamp;
- unsigned resp_timestamp_counter_value;
- unsigned req = TX_TIMEOUT_BASE;
- int iter = TX_TIMEOUT_ITER;
-
- 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
- port->recoverPort();
- goto done;
- }
-
- /* Generate and send message */
- resp = new PTPMessagePathDelayResp(port);
- port->getPortIdentity(resp_id);
- resp->setPortIdentity(&resp_id);
- resp->setSequenceId(sequenceId);
-
- XPTPD_INFO("Process PDelay Request SeqId: %u\t", sequenceId);
-
-#ifdef DEBUG
- for (int n = 0; n < PTP_CLOCK_IDENTITY_LENGTH; ++n) {
- fprintf(stderr, "%c", resp_id.clockIdentity[n]);
- }
- fprintf(stderr, "\"\n");
-#endif
-
- this->getPortIdentity(&requestingPortIdentity_p);
- resp->setRequestingPortIdentity(&requestingPortIdentity_p);
- resp->setRequestReceiptTimestamp(_timestamp);
- if( port->getTimestampVersion() != _timestamp._version ) {
- delete resp;
- goto done;
- }
- port->getTxLock();
- resp->sendPort(port, sourcePortIdentity);
-
- XPTPD_INFO("Sent path delay response");
-
- XPTPD_INFO("Start TS Read");
- ts_good = port->getTxTimestamp
- (resp, resp_timestamp, resp_timestamp_counter_value, false);
-
- XPTPD_INFO("Done TS Read");
-
- while (ts_good != 0 && iter-- != 0) {
- timer->sleep(req);
- if (ts_good == -72 && iter < 1)
- XPTPD_ERROR( "Error (TX) timestamping PDelay Response "
- "(Retrying-%d), error=%d", iter, ts_good);
- ts_good = port->getTxTimestamp
- (resp, resp_timestamp, resp_timestamp_counter_value, iter == 0);
- req *= 2;
- }
- port->putTxLock();
-
- if (ts_good != 0) {
- char msg[HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
- port->getExtendedError(msg);
- XPTPD_ERROR
- ( "Error (TX) timestamping PDelay Response, error=%d\t%s",
- ts_good, msg);
- delete resp;
- goto done;
- }
-
- resp_fwup = new PTPMessagePathDelayRespFollowUp(port);
- port->getPortIdentity(resp_fwup_id);
- resp_fwup->setPortIdentity(&resp_fwup_id);
- resp_fwup->setSequenceId(sequenceId);
- resp_fwup->setRequestingPortIdentity(sourcePortIdentity);
- resp_fwup->setResponseOriginTimestamp(resp_timestamp);
- long long turnaround;
- turnaround =
- (resp_timestamp.seconds_ls - _timestamp.seconds_ls) * 1000000000LL;
-
- XPTPD_INFO("Response Depart(sec): %u", resp_timestamp.seconds_ls);
- XPTPD_INFO("Request Arrival(sec): %u", _timestamp.seconds_ls);
- XPTPD_INFO("#1 Correction Field: %Ld", turnaround);
-
- turnaround += resp_timestamp.nanoseconds;
-
- XPTPD_INFO("#2 Correction Field: %Ld", turnaround);
-
- turnaround -= _timestamp.nanoseconds;
-
- XPTPD_INFO("#3 Correction Field: %Ld", turnaround);
-
- resp_fwup->setCorrectionField(0);
- resp_fwup->sendPort(port, sourcePortIdentity);
-
- XPTPD_INFO("Sent path delay response fwup");
-
- delete resp;
- delete resp_fwup;
-
-done:
- delete timer;
- _gc = true;
- return;
-}
-
-void PTPMessagePathDelayReq::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
-{
- uint8_t buf_t[256];
- uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
- unsigned char tspec_msg_t = 0;
- memset(buf_t, 0, 256);
- /* Create packet in buf */
- /* Copy in common header */
- messageLength = PTP_COMMON_HDR_LENGTH + PTP_PDELAY_REQ_LENGTH;
- tspec_msg_t |= messageType & 0xF;
- buildCommonHeader(buf_ptr);
-
- port->sendEventPort(buf_t, messageLength, MCAST_PDELAY, destIdentity);
- return;
-}
-
- PTPMessagePathDelayResp::PTPMessagePathDelayResp(IEEE1588Port * port) :
- PTPMessageCommon(port)
-{
- 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(IEEE1588Port * port)
-{
- 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
- port->recoverPort();
- return;
- }
-
- if (port->tryPDelayRxLock() != true) {
- fprintf(stderr, "Failed to get PDelay RX Lock\n");
- return;
- }
-
- port->getClock()->deleteEventTimerLocked
- (port, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES);
- PTPMessagePathDelayResp *old_pdelay_resp = port->getLastPDelayResp();
- if (old_pdelay_resp != NULL) {
- delete old_pdelay_resp;
- }
- port->setLastPDelayResp(this);
-
- port->putPDelayRxLock();
- _gc = false;
-
- return;
-}
-
-void PTPMessagePathDelayResp::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
-{
- uint8_t buf_t[256];
- uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
- unsigned char tspec_msg_t = 0;
- Timestamp requestReceiptTimestamp_BE;
- memset(buf_t, 0, 256);
- // Create packet in buf
- // Copy in common header
- messageLength = PTP_COMMON_HDR_LENGTH + PTP_PDELAY_RESP_LENGTH;
- tspec_msg_t |= messageType & 0xF;
- buildCommonHeader(buf_ptr);
- requestReceiptTimestamp_BE.seconds_ms =
- PLAT_htons(requestReceiptTimestamp.seconds_ms);
- requestReceiptTimestamp_BE.seconds_ls =
- PLAT_htonl(requestReceiptTimestamp.seconds_ls);
- requestReceiptTimestamp_BE.nanoseconds =
- PLAT_htonl(requestReceiptTimestamp.nanoseconds);
-
- // Copy in v2 PDelay_Req specific fields
- requestingPortIdentity->getClockIdentityString
- (buf_ptr + PTP_PDELAY_RESP_REQ_CLOCK_ID
- (PTP_PDELAY_RESP_OFFSET));
- requestingPortIdentity->getPortNumberNO
- ((uint16_t *)
- (buf_ptr + PTP_PDELAY_RESP_REQ_PORT_ID
- (PTP_PDELAY_RESP_OFFSET)));
- memcpy(buf_ptr + PTP_PDELAY_RESP_SEC_MS(PTP_PDELAY_RESP_OFFSET),
- &(requestReceiptTimestamp_BE.seconds_ms),
- sizeof(requestReceiptTimestamp.seconds_ms));
- memcpy(buf_ptr + PTP_PDELAY_RESP_SEC_LS(PTP_PDELAY_RESP_OFFSET),
- &(requestReceiptTimestamp_BE.seconds_ls),
- sizeof(requestReceiptTimestamp.seconds_ls));
- memcpy(buf_ptr + PTP_PDELAY_RESP_NSEC(PTP_PDELAY_RESP_OFFSET),
- &(requestReceiptTimestamp_BE.nanoseconds),
- sizeof(requestReceiptTimestamp.nanoseconds));
-
- XPTPD_INFO("PDelay Resp Timestamp: %u,%u",
- requestReceiptTimestamp.seconds_ls,
- requestReceiptTimestamp.nanoseconds);
-
- port->sendEventPort(buf_t, messageLength, MCAST_PDELAY, destIdentity);
- return;
-}
-
-void PTPMessagePathDelayResp::setRequestingPortIdentity
-(PortIdentity * identity)
-{
- *requestingPortIdentity = *identity;
-}
-
-void PTPMessagePathDelayResp::getRequestingPortIdentity
-(PortIdentity * identity)
-{
- *identity = *requestingPortIdentity;
-}
-
-PTPMessagePathDelayRespFollowUp::PTPMessagePathDelayRespFollowUp
-(IEEE1588Port * port) : PTPMessageCommon (port)
-{
- logMeanMessageInterval = 0x7F;
- control = MESSAGE_OTHER;
- messageType = PATH_DELAY_FOLLOWUP_MESSAGE;
- versionPTP = GPTP_VERSION;
- requestingPortIdentity = new PortIdentity();
-
- return;
-}
-
-PTPMessagePathDelayRespFollowUp::~PTPMessagePathDelayRespFollowUp()
-{
- delete requestingPortIdentity;
-}
-
-void PTPMessagePathDelayRespFollowUp::processMessage(IEEE1588Port * port)
-{
- Timestamp remote_resp_tx_timestamp(0, 0, 0);
- Timestamp request_tx_timestamp(0, 0, 0);
- Timestamp remote_req_rx_timestamp(0, 0, 0);
- Timestamp response_rx_timestamp(0, 0, 0);
-
- if (port->getPortState() == PTP_DISABLED) {
- // Do nothing all messages should be ignored when in this state
- return;
- }
- if (port->getPortState() == PTP_FAULTY) {
- // According to spec recovery is implementation specific
- port->recoverPort();
- return;
- }
-
- if (port->tryPDelayRxLock() != true)
- return;
-
- PTPMessagePathDelayReq *req = port->getLastPDelayReq();
- PTPMessagePathDelayResp *resp = port->getLastPDelayResp();
-
- PortIdentity req_id;
- PortIdentity resp_id;
-
- if (req == NULL) {
- /* Shouldn't happen */
- XPTPD_ERROR
- (">>> Received PDelay followup but no REQUEST exists");
- goto abort;
- }
-
- if (resp == NULL) {
- /* Probably shouldn't happen either */
- XPTPD_ERROR
- (">>> Received PDelay followup but no RESPONSE exists");
- goto abort;
- }
-
- req->getPortIdentity(&req_id);
- resp->getRequestingPortIdentity(&resp_id);
-
- if (req->getSequenceId() != sequenceId) {
-
- XPTPD_ERROR
- ("Received PDelay Response Follow Up but cannot find "
- "corresponding request");
- XPTPD_ERROR("My SeqId: %u ", req->getSequenceId());
- XPTPD_ERROR("Their SeqId: %u ", sequenceId);
-
- goto abort;
- }
-
- // Check if we have received a response
- if (resp->getSequenceId() != sequenceId
- || resp_id != *requestingPortIdentity) {
- uint16_t resp_port_number;
- uint16_t req_port_number;
- resp_id.getPortNumber(&resp_port_number);
- requestingPortIdentity->getPortNumber(&req_port_number);
- XPTPD_ERROR
- ("Received PDelay Response Follow Up but cannot find "
- "corresponding response");
- XPTPD_ERROR("%hu, %hu, %hu, %hu", resp->getSequenceId(),
- sequenceId, resp_port_number, req_port_number);
-
- goto abort;
- }
-
- XPTPD_INFO("Request Sequence Id: %u", req->getSequenceId());
- XPTPD_INFO("Response Sequence Id: %u", resp->getSequenceId());
- XPTPD_INFO("Follow-Up Sequence Id: %u", req->getSequenceId());
-
- 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(
- port->getLastPDelayRespFollowUp() != NULL &&
- port->getLastPDelayRespFollowUp() != this )
- {
- delete port->getLastPDelayRespFollowUp();
- }
- port->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 ) {
- 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
- if
- ( port->getPeerRateOffset() > .998 &&
- port->getPeerRateOffset() < 1.002 ) {
- turn_around = (int64_t) (turn_around * port->getPeerRateOffset());
- }
-
- XPTPD_INFO
- ("Turn Around Adjustment %Ld",
- ((long long)turn_around * port->getPeerRateOffset()) /
- 1000000000000LL);
- XPTPD_INFO
- ("Step #1: Turn Around Adjustment %Ld",
- ((long long)turn_around * port->getPeerRateOffset()));
- XPTPD_INFO("Adjusted Peer turn around is %Lu", turn_around);
-
- /* Subtract turn-around time from link delay after rate adjustment */
- link_delay -= turn_around;
- link_delay /= 2;
-
- {
- uint64_t mine_elapsed;
- uint64_t theirs_elapsed;
- Timestamp prev_peer_ts_mine;
- Timestamp prev_peer_ts_theirs;
- FrequencyRatio rate_offset;
- if( port->getPeerOffset( prev_peer_ts_mine, prev_peer_ts_theirs )) {
- mine_elapsed = TIMESTAMP_TO_NS(request_tx_timestamp)-TIMESTAMP_TO_NS(prev_peer_ts_mine);
- theirs_elapsed = TIMESTAMP_TO_NS(remote_req_rx_timestamp)-TIMESTAMP_TO_NS(prev_peer_ts_theirs);
- theirs_elapsed -= port->getLinkDelay();
- theirs_elapsed += link_delay;
- rate_offset = ((FrequencyRatio) mine_elapsed)/theirs_elapsed;
- port->setPeerRateOffset(rate_offset);
- port->setAsCapable( true );
- }
- }
- port->setLinkDelay( link_delay );
- port->setPeerOffset( request_tx_timestamp, remote_req_rx_timestamp );
-
- abort:
- delete req;
- port->setLastPDelayReq(NULL);
- delete resp;
- port->setLastPDelayResp(NULL);
-
- _gc = true;
-
- defer:
- port->putPDelayRxLock();
-
- return;
-}
-
-void PTPMessagePathDelayRespFollowUp::sendPort(IEEE1588Port * port,
- PortIdentity * destIdentity)
-{
- uint8_t buf_t[256];
- uint8_t *buf_ptr = buf_t + port->getPayloadOffset();
- unsigned char tspec_msg_t = 0;
- Timestamp responseOriginTimestamp_BE;
- memset(buf_t, 0, 256);
- /* Create packet in buf
- Copy in common header */
- messageLength = PTP_COMMON_HDR_LENGTH + PTP_PDELAY_RESP_LENGTH;
- tspec_msg_t |= messageType & 0xF;
- buildCommonHeader(buf_ptr);
- responseOriginTimestamp_BE.seconds_ms =
- PLAT_htons(responseOriginTimestamp.seconds_ms);
- responseOriginTimestamp_BE.seconds_ls =
- PLAT_htonl(responseOriginTimestamp.seconds_ls);
- responseOriginTimestamp_BE.nanoseconds =
- PLAT_htonl(responseOriginTimestamp.nanoseconds);
-
- // Copy in v2 PDelay_Req specific fields
- requestingPortIdentity->getClockIdentityString
- (buf_ptr + PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID
- (PTP_PDELAY_FOLLOWUP_OFFSET));
- requestingPortIdentity->getPortNumberNO
- ((uint16_t *)
- (buf_ptr + PTP_PDELAY_FOLLOWUP_REQ_PORT_ID
- (PTP_PDELAY_FOLLOWUP_OFFSET)));
- memcpy
- (buf_ptr + PTP_PDELAY_FOLLOWUP_SEC_MS(PTP_PDELAY_FOLLOWUP_OFFSET),
- &(responseOriginTimestamp_BE.seconds_ms),
- sizeof(responseOriginTimestamp.seconds_ms));
- memcpy
- (buf_ptr + PTP_PDELAY_FOLLOWUP_SEC_LS(PTP_PDELAY_FOLLOWUP_OFFSET),
- &(responseOriginTimestamp_BE.seconds_ls),
- sizeof(responseOriginTimestamp.seconds_ls));
- memcpy
- (buf_ptr + PTP_PDELAY_FOLLOWUP_NSEC(PTP_PDELAY_FOLLOWUP_OFFSET),
- &(responseOriginTimestamp_BE.nanoseconds),
- sizeof(responseOriginTimestamp.nanoseconds));
-
- XPTPD_INFO("PDelay Resp Timestamp: %u,%u",
- responseOriginTimestamp.seconds_ls,
- responseOriginTimestamp.nanoseconds);
-
- port->sendGeneralPort(buf_t, messageLength, MCAST_PDELAY, destIdentity);
- return;
-}
-
-void PTPMessagePathDelayRespFollowUp::setRequestingPortIdentity
-(PortIdentity * identity)
-{
- *requestingPortIdentity = *identity;
-}
+/****************************************************************************** + + Copyright (c) 2009-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ + +#include <ieee1588.hpp> +#include <avbts_clock.hpp> +#include <avbts_message.hpp> +#include <avbts_port.hpp> +#include <avbts_ostimer.hpp> + +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include <time.h> + +PTPMessageCommon::PTPMessageCommon(IEEE1588Port * port) +{ + // Fill in fields using port/clock dataset as a template + versionPTP = GPTP_VERSION; + versionNetwork = PTP_NETWORK_VERSION; + domainNumber = port->getClock()->getDomain(); + // Set flags as necessary + memset(flags, 0, PTP_FLAGS_LENGTH); + 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, IEEE1588Port * port) +{ + OSTimer *timer = port->getTimerFactory()->createTimer(); + PTPMessageCommon *msg = NULL; + 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; + +#if PTP_DEBUG + { + int i; + XPTPD_INFO("Packet Dump:\n"); + for (i = 0; i < size; ++i) { + fprintf(stderr, "%hhx\t", buf[i]); + if (i % 8 == 7) + fprintf(stderr, "\n"); + } + if (i % 8 != 0) + fprintf(stderr, "\n"); + } +#endif + + memcpy(&tspec_msg_t, + buf + PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(PTP_COMMON_HDR_OFFSET), + sizeof(tspec_msg_t)); + messageType = (MessageType) (tspec_msg_t & 0xF); + 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); + + XPTPD_INFO("Captured Sequence Id: %u", sequenceId); + + if (!(messageType >> 3)) { + int iter = 2; + long req = 1000; // = 1 ms + int ts_good = + port->getRxTimestamp + (sourcePortIdentity, sequenceId, timestamp, counter_value, false); + while (ts_good != 0 && iter-- != 0) { + // Waits at least 1 time slice regardless of size of 'req' + timer->sleep(req); + if (ts_good != -72) + fprintf + ( stderr, "Error (RX) timestamping RX event packet (Retrying), error=%d\n", + ts_good ); + ts_good = + port->getRxTimestamp(sourcePortIdentity, sequenceId, + timestamp, counter_value, + iter == 0); + req *= 2; + } + if (ts_good != 0) { + char msg[HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE]; + port->getExtendedError(msg); + XPTPD_ERROR + ("*** Received an event packet but cannot retrieve timestamp, discarding. messageType=%u,error=%d\n%s", + messageType, ts_good, msg); + //_exit(-1); + return NULL; + } + + else { + XPTPD_INFO("Timestamping event packet"); + } + + } + + if (transportSpecific!=1) { + XPTPD_INFO("*** Received message with unsupported transportSpecific type=%d",transportSpecific); + return NULL; + } + + switch (messageType) { + case SYNC_MESSAGE: + + //fprintf( stderr, "*** Received Sync message\n" ); + //printf( "Sync RX timestamp = %hu,%u,%u\n", timestamp.seconds_ms, timestamp.seconds_ls, timestamp.nanoseconds ); + XPTPD_INFO("*** Received Sync message"); + + // Be sure buffer is the correction size + if (size < PTP_COMMON_HDR_LENGTH + PTP_SYNC_LENGTH) { + goto done; + } + { + PTPMessageSync *sync_msg = new PTPMessageSync(); + sync_msg->messageType = messageType; + // Copy in v2 sync specific fields + memcpy(&(sync_msg->originTimestamp.seconds_ms), + buf + PTP_SYNC_SEC_MS(PTP_SYNC_OFFSET), + sizeof(sync_msg->originTimestamp.seconds_ms)); + memcpy(&(sync_msg->originTimestamp.seconds_ls), + buf + PTP_SYNC_SEC_LS(PTP_SYNC_OFFSET), + sizeof(sync_msg->originTimestamp.seconds_ls)); + memcpy(&(sync_msg->originTimestamp.nanoseconds), + buf + PTP_SYNC_NSEC(PTP_SYNC_OFFSET), + sizeof(sync_msg->originTimestamp.nanoseconds)); + msg = sync_msg; + } + break; + case FOLLOWUP_MESSAGE: + + XPTPD_INFO("*** Received Follow Up message"); + + // Be sure buffer is the correction size + if (size < (int)(PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH + sizeof(FollowUpTLV))) { + goto done; + } + { + PTPMessageFollowUp *followup_msg = + new PTPMessageFollowUp(); + followup_msg->messageType = messageType; + // Copy in v2 sync specific fields + memcpy(& + (followup_msg-> + preciseOriginTimestamp.seconds_ms), + buf + PTP_FOLLOWUP_SEC_MS(PTP_FOLLOWUP_OFFSET), + sizeof(followup_msg-> + preciseOriginTimestamp.seconds_ms)); + memcpy(& + (followup_msg-> + preciseOriginTimestamp.seconds_ls), + buf + PTP_FOLLOWUP_SEC_LS(PTP_FOLLOWUP_OFFSET), + sizeof(followup_msg-> + preciseOriginTimestamp.seconds_ls)); + memcpy(& + (followup_msg-> + preciseOriginTimestamp.nanoseconds), + buf + PTP_FOLLOWUP_NSEC(PTP_FOLLOWUP_OFFSET), + sizeof(followup_msg-> + preciseOriginTimestamp.nanoseconds)); + + followup_msg->preciseOriginTimestamp.seconds_ms = + PLAT_ntohs(followup_msg-> + preciseOriginTimestamp.seconds_ms); + followup_msg->preciseOriginTimestamp.seconds_ls = + PLAT_ntohl(followup_msg-> + preciseOriginTimestamp.seconds_ls); + followup_msg->preciseOriginTimestamp.nanoseconds = + PLAT_ntohl(followup_msg-> + preciseOriginTimestamp.nanoseconds); + + memcpy( &(followup_msg->tlv), buf+PTP_FOLLOWUP_LENGTH, sizeof(followup_msg->tlv) ); + + msg = followup_msg; + } + break; + case PATH_DELAY_REQ_MESSAGE: + + XPTPD_INFO("*** Received PDelay Request message"); + + // Be sure buffer is the correction size + if (size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_REQ_LENGTH + && /* For Broadcom compatibility */ size != 46) { + goto done; + } + { + PTPMessagePathDelayReq *pdelay_req_msg = + new PTPMessagePathDelayReq(); + pdelay_req_msg->messageType = messageType; + +#if 0 + // The origin timestamp for PDelay Request packets has been eliminated since it is unused + // Copy in v2 PDelay Request specific fields + memcpy(&(pdelay_req_msg->originTimestamp.seconds_ms), + buf + + PTP_PDELAY_REQ_SEC_MS(PTP_PDELAY_REQ_OFFSET), + sizeof(pdelay_req_msg-> + originTimestamp.seconds_ms)); + memcpy(&(pdelay_req_msg->originTimestamp.seconds_ls), + buf + + PTP_PDELAY_REQ_SEC_LS(PTP_PDELAY_REQ_OFFSET), + sizeof(pdelay_req_msg-> + originTimestamp.seconds_ls)); + memcpy(&(pdelay_req_msg->originTimestamp.nanoseconds), + buf + PTP_PDELAY_REQ_NSEC(PTP_PDELAY_REQ_OFFSET), + sizeof(pdelay_req_msg-> + originTimestamp.nanoseconds)); + + pdelay_req_msg->originTimestamp.seconds_ms = + PLAT_ntohs(pdelay_req_msg-> + originTimestamp.seconds_ms); + pdelay_req_msg->originTimestamp.seconds_ls = + PLAT_ntohl(pdelay_req_msg-> + originTimestamp.seconds_ls); + pdelay_req_msg->originTimestamp.nanoseconds = + PLAT_ntohl(pdelay_req_msg-> + originTimestamp.nanoseconds); +#endif + + msg = pdelay_req_msg; + } + break; + case PATH_DELAY_RESP_MESSAGE: + + XPTPD_INFO("*** Received PDelay Response message, %u, %u, %u", + timestamp.seconds_ls, timestamp.nanoseconds, + sequenceId); + + // Be sure buffer is the correction size + if (size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_RESP_LENGTH) { + goto done; + } + { + PTPMessagePathDelayResp *pdelay_resp_msg = + new PTPMessagePathDelayResp(); + pdelay_resp_msg->messageType = messageType; + // Copy in v2 PDelay Response specific fields + pdelay_resp_msg->requestingPortIdentity = + new PortIdentity((uint8_t *) buf + + PTP_PDELAY_RESP_REQ_CLOCK_ID + (PTP_PDELAY_RESP_OFFSET), + (uint16_t *) (buf + + PTP_PDELAY_RESP_REQ_PORT_ID + (PTP_PDELAY_RESP_OFFSET))); + +#ifdef DEBUG + for (int n = 0; n < PTP_CLOCK_IDENTITY_LENGTH; ++n) { // MMM + fprintf(stderr, "%c", + pdelay_resp_msg-> + requestingPortIdentity.clockIdentity + [n]); + } +#endif + + memcpy(& (pdelay_resp_msg->requestReceiptTimestamp.seconds_ms), + buf + PTP_PDELAY_RESP_SEC_MS(PTP_PDELAY_RESP_OFFSET), + sizeof + (pdelay_resp_msg->requestReceiptTimestamp.seconds_ms)); + memcpy(& + (pdelay_resp_msg-> + requestReceiptTimestamp.seconds_ls), + buf + + PTP_PDELAY_RESP_SEC_LS(PTP_PDELAY_RESP_OFFSET), + sizeof(pdelay_resp_msg-> + requestReceiptTimestamp.seconds_ls)); + memcpy(& + (pdelay_resp_msg-> + requestReceiptTimestamp.nanoseconds), + buf + + PTP_PDELAY_RESP_NSEC(PTP_PDELAY_RESP_OFFSET), + sizeof(pdelay_resp_msg-> + requestReceiptTimestamp.nanoseconds)); + + pdelay_resp_msg->requestReceiptTimestamp.seconds_ms = + PLAT_ntohs(pdelay_resp_msg->requestReceiptTimestamp.seconds_ms); + pdelay_resp_msg->requestReceiptTimestamp.seconds_ls = + PLAT_ntohl(pdelay_resp_msg->requestReceiptTimestamp.seconds_ls); + pdelay_resp_msg->requestReceiptTimestamp.nanoseconds = + PLAT_ntohl(pdelay_resp_msg->requestReceiptTimestamp.nanoseconds); + + msg = pdelay_resp_msg; + } + break; + case PATH_DELAY_FOLLOWUP_MESSAGE: + + XPTPD_INFO("*** Received PDelay Response FollowUp message"); + + // Be sure buffer is the correction size +// if( size < PTP_COMMON_HDR_LENGTH + PTP_PDELAY_FOLLOWUP_LENGTH ) { +// goto done; +// } + { + PTPMessagePathDelayRespFollowUp *pdelay_resp_fwup_msg = + new PTPMessagePathDelayRespFollowUp(); + pdelay_resp_fwup_msg->messageType = messageType; + // Copy in v2 PDelay Response specific fields + pdelay_resp_fwup_msg->requestingPortIdentity = + new PortIdentity((uint8_t *) buf + + PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID + (PTP_PDELAY_RESP_OFFSET), + (uint16_t *) (buf + + PTP_PDELAY_FOLLOWUP_REQ_PORT_ID + (PTP_PDELAY_FOLLOWUP_OFFSET))); + + memcpy(& + (pdelay_resp_fwup_msg-> + responseOriginTimestamp.seconds_ms), + buf + + PTP_PDELAY_FOLLOWUP_SEC_MS + (PTP_PDELAY_FOLLOWUP_OFFSET), + sizeof + (pdelay_resp_fwup_msg->responseOriginTimestamp. + seconds_ms)); + memcpy(& + (pdelay_resp_fwup_msg-> + responseOriginTimestamp.seconds_ls), + buf + + PTP_PDELAY_FOLLOWUP_SEC_LS + (PTP_PDELAY_FOLLOWUP_OFFSET), + sizeof + (pdelay_resp_fwup_msg->responseOriginTimestamp. + seconds_ls)); + memcpy(& + (pdelay_resp_fwup_msg-> + responseOriginTimestamp.nanoseconds), + buf + + PTP_PDELAY_FOLLOWUP_NSEC + (PTP_PDELAY_FOLLOWUP_OFFSET), + sizeof + (pdelay_resp_fwup_msg->responseOriginTimestamp. + nanoseconds)); + + pdelay_resp_fwup_msg-> + responseOriginTimestamp.seconds_ms = + PLAT_ntohs + (pdelay_resp_fwup_msg->responseOriginTimestamp. + seconds_ms); + pdelay_resp_fwup_msg-> + responseOriginTimestamp.seconds_ls = + PLAT_ntohl + (pdelay_resp_fwup_msg->responseOriginTimestamp. + seconds_ls); + pdelay_resp_fwup_msg-> + responseOriginTimestamp.nanoseconds = + PLAT_ntohl + (pdelay_resp_fwup_msg->responseOriginTimestamp. + nanoseconds); + + msg = pdelay_resp_fwup_msg; + } + break; + case ANNOUNCE_MESSAGE: + { + PTPMessageAnnounce *annc = new PTPMessageAnnounce(); + annc->messageType = messageType; + + memcpy(&(annc->currentUtcOffset), + buf + + PTP_ANNOUNCE_CURRENT_UTC_OFFSET + (PTP_ANNOUNCE_OFFSET), + sizeof(annc->currentUtcOffset)); + annc->currentUtcOffset = + PLAT_ntohs(annc->currentUtcOffset); + memcpy(&(annc->grandmasterPriority1), + buf + + PTP_ANNOUNCE_GRANDMASTER_PRIORITY1 + (PTP_ANNOUNCE_OFFSET), + sizeof(annc->grandmasterPriority1)); + memcpy( annc->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)); + + msg = annc; + } + break; + default: + + XPTPD_ERROR("Received unsupported message type, %d", + (int)messageType); + + goto done; + } + + msg->_gc = false; + + // Copy in common header fields + memcpy(&(msg->versionPTP), + buf + PTP_COMMON_HDR_PTP_VERSION(PTP_COMMON_HDR_OFFSET), + sizeof(msg->versionPTP)); + memcpy(&(msg->messageLength), + buf + PTP_COMMON_HDR_MSG_LENGTH(PTP_COMMON_HDR_OFFSET), + sizeof(msg->messageLength)); + msg->messageLength = PLAT_ntohs(msg->messageLength); + memcpy(&(msg->domainNumber), + buf + PTP_COMMON_HDR_DOMAIN_NUMBER(PTP_COMMON_HDR_OFFSET), + sizeof(msg->domainNumber)); + memcpy(&(msg->flags), buf + PTP_COMMON_HDR_FLAGS(PTP_COMMON_HDR_OFFSET), + PTP_FLAGS_LENGTH); + memcpy(&(msg->correctionField), + buf + PTP_COMMON_HDR_CORRECTION(PTP_COMMON_HDR_OFFSET), + sizeof(msg->correctionField)); + msg->correctionField = bswap_64(msg->correctionField); // Assume LE machine + msg->sourcePortIdentity = sourcePortIdentity; + msg->sequenceId = sequenceId; + memcpy(&(msg->control), + buf + PTP_COMMON_HDR_CONTROL(PTP_COMMON_HDR_OFFSET), + sizeof(msg->control)); + memcpy(&(msg->logMeanMessageInterval), + buf + PTP_COMMON_HDR_LOG_MSG_INTRVL(PTP_COMMON_HDR_OFFSET), + sizeof(msg->logMeanMessageInterval)); + + port->addSockAddrMap(msg->sourcePortIdentity, remote); + + msg->_timestamp = timestamp; + msg->_timestamp_counter_value = counter_value; + + done: + delete timer; + + return msg; +} + +void PTPMessageCommon::processMessage(IEEE1588Port * port) +{ + _gc = true; + return; +} + +void PTPMessageCommon::buildCommonHeader(uint8_t * buf) +{ + unsigned char tspec_msg_t; + tspec_msg_t = messageType | 0x10; + //tspec_msg_t = messageType; + long long correctionField_BE = bswap_64(correctionField); // Assume LE machine + uint16_t messageLength_NO = PLAT_htons(messageLength); + + memcpy(buf + PTP_COMMON_HDR_TRANSSPEC_MSGTYPE(PTP_COMMON_HDR_OFFSET), + &tspec_msg_t, sizeof(tspec_msg_t)); + memcpy(buf + PTP_COMMON_HDR_PTP_VERSION(PTP_COMMON_HDR_OFFSET), + &versionPTP, sizeof(versionPTP)); + memcpy(buf + PTP_COMMON_HDR_MSG_LENGTH(PTP_COMMON_HDR_OFFSET), + &messageLength_NO, sizeof(messageLength_NO)); + memcpy(buf + PTP_COMMON_HDR_DOMAIN_NUMBER(PTP_COMMON_HDR_OFFSET), + &domainNumber, sizeof(domainNumber)); + memcpy(buf + PTP_COMMON_HDR_FLAGS(PTP_COMMON_HDR_OFFSET), &flags, + PTP_FLAGS_LENGTH); + memcpy(buf + PTP_COMMON_HDR_CORRECTION(PTP_COMMON_HDR_OFFSET), + &correctionField_BE, sizeof(correctionField)); + + sourcePortIdentity->getClockIdentityString + ((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))); + + XPTPD_INFO("Sending Sequence Id: %u", sequenceId); + sequenceId = PLAT_htons(sequenceId); + memcpy(buf + PTP_COMMON_HDR_SEQUENCE_ID(PTP_COMMON_HDR_OFFSET), + &sequenceId, sizeof(sequenceId)); + sequenceId = PLAT_ntohs(sequenceId); + memcpy(buf + PTP_COMMON_HDR_CONTROL(PTP_COMMON_HDR_OFFSET), &control, + sizeof(control)); + memcpy(buf + PTP_COMMON_HDR_LOG_MSG_INTRVL(PTP_COMMON_HDR_OFFSET), + &logMeanMessageInterval, sizeof(logMeanMessageInterval)); + + return; +} + +void PTPMessageCommon::getPortIdentity(PortIdentity * identity) +{ + *identity = *sourcePortIdentity; +} + +void PTPMessageCommon::setPortIdentity(PortIdentity * identity) +{ + *sourcePortIdentity = *identity; +} + +PTPMessageCommon::~PTPMessageCommon(void) +{ + delete sourcePortIdentity; + return; +} + +PTPMessageAnnounce::PTPMessageAnnounce(void) +{ + 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 + fprintf(stderr, "Us: "); + for (int i = 0; i < 14; ++i) + fprintf(stderr, "%hhx", this1[i]); + fprintf(stderr, "\n"); + fprintf(stderr, "Them: "); + for (int i = 0; i < 14; ++i) + fprintf(stderr, "%hhx", that1[i]); + fprintf(stderr, "\n"); +#endif + + return (memcmp(this1, that1, 14) < 0) ? true : false; +} + + +PTPMessageSync::PTPMessageSync() { +} + +PTPMessageSync::~PTPMessageSync() { +} + +PTPMessageSync::PTPMessageSync(IEEE1588Port * port) : PTPMessageCommon(port) +{ + messageType = SYNC_MESSAGE; // This is an event message + sequenceId = port->getNextSyncSequenceId(); + control = SYNC; + + flags[PTP_ASSIST_BYTE] |= (0x1 << PTP_ASSIST_BIT); + + originTimestamp = port->getClock()->getTime(); + + logMeanMessageInterval = port->getSyncInterval(); + return; +} + +void PTPMessageSync::sendPort(IEEE1588Port * port, PortIdentity * destIdentity) +{ + uint8_t buf_t[256]; + uint8_t *buf_ptr = buf_t + port->getPayloadOffset(); + unsigned char tspec_msg_t = 0x0; + Timestamp originTimestamp_BE; + memset(buf_t, 0, 256); + // Create packet in buf + // Copy in common header + messageLength = PTP_COMMON_HDR_LENGTH + PTP_SYNC_LENGTH; + tspec_msg_t |= messageType & 0xF; + buildCommonHeader(buf_ptr); + // Get timestamp + originTimestamp = port->getClock()->getTime(); + originTimestamp_BE.seconds_ms = PLAT_htons(originTimestamp.seconds_ms); + originTimestamp_BE.seconds_ls = PLAT_htonl(originTimestamp.seconds_ls); + originTimestamp_BE.nanoseconds = + PLAT_htonl(originTimestamp.nanoseconds); + // Copy in v2 sync specific fields + memcpy(buf_ptr + PTP_SYNC_SEC_MS(PTP_SYNC_OFFSET), + &(originTimestamp_BE.seconds_ms), + sizeof(originTimestamp.seconds_ms)); + memcpy(buf_ptr + PTP_SYNC_SEC_LS(PTP_SYNC_OFFSET), + &(originTimestamp_BE.seconds_ls), + sizeof(originTimestamp.seconds_ls)); + memcpy(buf_ptr + PTP_SYNC_NSEC(PTP_SYNC_OFFSET), + &(originTimestamp_BE.nanoseconds), + sizeof(originTimestamp.nanoseconds)); + + port->sendEventPort(buf_t, messageLength, MCAST_OTHER, destIdentity); + + return; +} + + PTPMessageAnnounce::PTPMessageAnnounce(IEEE1588Port * port) : PTPMessageCommon + (port) +{ + messageType = ANNOUNCE_MESSAGE; // This is an event message + sequenceId = port->getNextAnnounceSequenceId(); + ClockIdentity id; + control = MESSAGE_OTHER; + ClockIdentity clock_identity; + + id = port->getClock()->getClockIdentity(); + tlv.setClockIdentity(&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; +} + +void PTPMessageAnnounce::sendPort(IEEE1588Port * port, + PortIdentity * destIdentity) +{ + uint8_t buf_t[256]; + uint8_t *buf_ptr = buf_t + port->getPayloadOffset(); + unsigned char tspec_msg_t = 0x0; + + uint16_t currentUtcOffset_l = PLAT_htons(currentUtcOffset); + uint16_t stepsRemoved_l = PLAT_htons(stepsRemoved); + ClockQuality clockQuality_l = *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 + sizeof(tlv); + 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(buf_t, messageLength, MCAST_OTHER, destIdentity); + + return; +} + +void PTPMessageAnnounce::processMessage(IEEE1588Port * port) +{ + // Delete announce receipt timeout + port->getClock()->deleteEventTimerLocked + (port, ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES); + + if( stepsRemoved >= 255 ) goto bail; + // Add message to the list + port->addQualifiedAnnounce(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(IEEE1588Port * port) +{ + Timestamp system_time; + Timestamp device_time; + Timestamp corrected_sync_time; + + uint64_t delay; + + signed long long local_system_offset; + signed long long scalar_offset; + int correction; + + FrequencyRatio local_clock_adjustment; + FrequencyRatio local_system_freq_offset; + + 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 + port->recoverPort(); + return; + } + + XPTPD_INFO("PTP assist flag is not set, FLAGS[0,1] = %u,%u", flags[0], + flags[1]); + +// if( flags[PTP_ASSIST_BYTE] & (0x1<<PTP_ASSIST_BIT)) { + if (true) { + // If PTP_ASSIST flag is set, expect a follow-up message and do nothing + PTPMessageSync *old_sync = port->getLastSync(); + if (old_sync != NULL) { + delete old_sync; + } + port->setLastSync(this); + _gc = false; + goto done; + } else { + _gc = true; + } + + // Indicates invalid link delay, wait until link delay had been calculated + if ((delay = port->getLinkDelay()) == 3600000000000) { + printf + ("Got Sync/Follow-Up but Link Delay has not been computed\n"); + goto done; + } + + correction = (int) (delay + (correctionField >> 16)); + corrected_sync_time = _timestamp; + TIMESTAMP_SUB_NS( corrected_sync_time, correction ); + scalar_offset = TIMESTAMP_TO_NS( corrected_sync_time ); + scalar_offset -= TIMESTAMP_TO_NS( originTimestamp ); + + // Otherwise synchronize clock with approximate time from Sync message + uint32_t local_clock; + uint32_t nominal_clock_rate; + uint32_t device_sync_time_offset; + + port->getDeviceTime + (system_time, device_time, local_clock, nominal_clock_rate); + + // Adjust local_clock to correspond to _timestamp + device_sync_time_offset = + TIMESTAMP_TO_NS(device_time) - TIMESTAMP_TO_NS(_timestamp); + local_clock -= + device_sync_time_offset / (1000000000 / nominal_clock_rate); + + XPTPD_INFO + ("ptp_message::sync::processMessage System time: %u,%u " + "Device Time: %u,%u", + system_time.seconds_ls, system_time.nanoseconds, + device_time.seconds_ls, device_time.nanoseconds); + + local_clock_adjustment = port->getClock()-> + calcMasterLocalClockRateDifference + ( originTimestamp, corrected_sync_time ); + + local_system_offset = + TIMESTAMP_TO_NS(system_time) - TIMESTAMP_TO_NS(device_time); + + if( port->getPortState() != PTP_MASTER ) { + /* 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) + (device_sync_time_offset/local_system_freq_offset) ); + port->getClock()->setMasterOffset + ( scalar_offset, _timestamp, local_clock_adjustment, + local_system_offset, system_time, local_system_freq_offset, + port->getSyncCount(), port->getPdelayCount(), port->getPortState() ); + port->syncDone(); + } + + + done: + return; +} + + PTPMessageFollowUp::PTPMessageFollowUp(IEEE1588Port * port):PTPMessageCommon + (port) +{ + messageType = FOLLOWUP_MESSAGE; /* This is an event message */ + control = FOLLOWUP; + + logMeanMessageInterval = port->getSyncInterval(); + + return; +} + +void PTPMessageFollowUp::sendPort(IEEE1588Port * port, + PortIdentity * destIdentity) +{ + uint8_t buf_t[256]; + uint8_t *buf_ptr = buf_t + port->getPayloadOffset(); + unsigned char tspec_msg_t = 0x0; + Timestamp preciseOriginTimestamp_BE; + memset(buf_t, 0, 256); + /* Create packet in buf + Copy in common header */ + messageLength = + PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH + sizeof(tlv); + tspec_msg_t |= messageType & 0xF; + buildCommonHeader(buf_ptr); + preciseOriginTimestamp_BE.seconds_ms = + PLAT_htons(preciseOriginTimestamp.seconds_ms); + preciseOriginTimestamp_BE.seconds_ls = + PLAT_htonl(preciseOriginTimestamp.seconds_ls); + preciseOriginTimestamp_BE.nanoseconds = + PLAT_htonl(preciseOriginTimestamp.nanoseconds); + /* Copy in v2 sync specific fields */ + memcpy(buf_ptr + PTP_FOLLOWUP_SEC_MS(PTP_FOLLOWUP_OFFSET), + &(preciseOriginTimestamp_BE.seconds_ms), + sizeof(preciseOriginTimestamp.seconds_ms)); + memcpy(buf_ptr + PTP_FOLLOWUP_SEC_LS(PTP_FOLLOWUP_OFFSET), + &(preciseOriginTimestamp_BE.seconds_ls), + sizeof(preciseOriginTimestamp.seconds_ls)); + memcpy(buf_ptr + PTP_FOLLOWUP_NSEC(PTP_FOLLOWUP_OFFSET), + &(preciseOriginTimestamp_BE.nanoseconds), + sizeof(preciseOriginTimestamp.nanoseconds)); + tlv.toByteString(buf_ptr + PTP_COMMON_HDR_LENGTH + PTP_FOLLOWUP_LENGTH); + + XPTPD_INFO + ("Follow-Up Time: %u seconds(hi)", preciseOriginTimestamp.seconds_ms); + XPTPD_INFO + ("Follow-Up Time: %u seconds", preciseOriginTimestamp.seconds_ls); + XPTPD_INFO + ("FW-UP Time: %u nanoseconds", preciseOriginTimestamp.nanoseconds); + XPTPD_INFO + ("FW-UP Time: %x seconds", preciseOriginTimestamp.seconds_ls); + XPTPD_INFO + ("FW-UP Time: %x nanoseconds", preciseOriginTimestamp.nanoseconds); +#if 0 + XPTPD_INFO("Follow-up Dump:\n"); +#ifdef DEBUG + for (int i = 0; i < messageLength; ++i) { + fprintf(stderr, "%d:%02x ", i, (unsigned char)buf[i]); + } + fprintf(stderr, "\n"); +#endif +#endif + + port->sendGeneralPort(buf_t, messageLength, MCAST_OTHER, destIdentity); + + return; +} + +void PTPMessageFollowUp::processMessage(IEEE1588Port * port) +{ + uint64_t delay; + Timestamp sync_arrival; + Timestamp system_time(0, 0, 0); + Timestamp device_time(0, 0, 0); + Timestamp corrected_sync_time; + + 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; + int correction; + + XPTPD_INFO("Processing a follow-up message"); + + // Expire any SYNC_RECEIPT timers that exist + port->getClock()->deleteEventTimerLocked + (port, SYNC_RECEIPT_TIMEOUT_EXPIRES); + + 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 + port->recoverPort(); + return; + } + + PortIdentity sync_id; + PTPMessageSync *sync = port->getLastSync(); + if (sync == NULL) { + XPTPD_ERROR("Received Follow Up but there is no sync message"); + return; + } + sync->getPortIdentity(&sync_id); + + if (sync->getSequenceId() != sequenceId || sync_id != *sourcePortIdentity) + { + XPTPD_ERROR + ("Received Follow Up but cannot find corresponding Sync"); + goto done; + } + + sync_arrival = sync->getTimestamp(); + + delay = port->getLinkDelay(); + if ((delay = port->getLinkDelay()) == 3600000000000) { + goto done; + } + + master_local_freq_offset = tlv.getRateOffset(); + master_local_freq_offset /= 2ULL << 41; + master_local_freq_offset += 1.0; + master_local_freq_offset /= port->getPeerRateOffset(); + + correctionField = (uint64_t) + ((correctionField >> 16)/master_local_freq_offset); + correction = (int) (delay + (correctionField >> 16)); + corrected_sync_time = sync_arrival; + + if( correction > 0 ) + TIMESTAMP_SUB_NS( corrected_sync_time, correction ); + else TIMESTAMP_ADD_NS( corrected_sync_time, -correction ); + scalar_offset = TIMESTAMP_TO_NS( corrected_sync_time ); + scalar_offset -= TIMESTAMP_TO_NS( preciseOriginTimestamp ); + + XPTPD_INFO + ("Followup Correction Field: %Ld,%lu", correctionField >> 16, + delay); + XPTPD_INFO + ("FollowUp Scalar = %lld", scalar_offset); + + /* Otherwise synchronize clock with approximate time from Sync message */ + uint32_t local_clock, nominal_clock_rate; + uint32_t device_sync_time_offset; + + port->getDeviceTime(system_time, device_time, local_clock, + nominal_clock_rate); + XPTPD_INFO + ( "Device Time = %llu,System Time = %llu\n", + TIMESTAMP_TO_NS(device_time), TIMESTAMP_TO_NS(system_time)); + + /* Adjust local_clock to correspond to sync_arrival */ + device_sync_time_offset = + TIMESTAMP_TO_NS(device_time) - TIMESTAMP_TO_NS(sync_arrival); + + XPTPD_INFO + ("ptp_message::FollowUp::processMessage System time: %u,%u " + "Device Time: %u,%u", + system_time.seconds_ls, system_time.nanoseconds, + device_time.seconds_ls, device_time.nanoseconds); + + local_system_offset = + TIMESTAMP_TO_NS(system_time) - TIMESTAMP_TO_NS(device_time); + + local_clock_adjustment = + port->getClock()-> + calcMasterLocalClockRateDifference + ( preciseOriginTimestamp, corrected_sync_time ); + + if( port->getPortState() != PTP_MASTER ) { + 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) ); + port->getClock()->setMasterOffset + ( scalar_offset, sync_arrival, local_clock_adjustment, + local_system_offset, system_time, local_system_freq_offset, + port->getSyncCount(), port->getPdelayCount(), + port->getPortState() ); + port->syncDone(); + // Restart the SYNC_RECEIPT timer + port->getClock()->addEventTimerLocked + (port, SYNC_RECEIPT_TIMEOUT_EXPIRES, (unsigned long long) + (SYNC_RECEIPT_TIMEOUT_MULTIPLIER * + ((double) pow((double)2, port->getSyncInterval()) * + 1000000000.0))); + } + +done: + _gc = true; + port->setLastSync(NULL); + delete sync; + + return; +} + + PTPMessagePathDelayReq::PTPMessagePathDelayReq(IEEE1588Port * port): + PTPMessageCommon (port) +{ + logMeanMessageInterval = 0; + control = MESSAGE_OTHER; + messageType = PATH_DELAY_REQ_MESSAGE; + sequenceId = port->getNextPDelaySequenceId(); + return; +} + +void PTPMessagePathDelayReq::processMessage(IEEE1588Port * port) +{ + OSTimer *timer = port->getTimerFactory()->createTimer(); + PortIdentity resp_fwup_id; + PortIdentity requestingPortIdentity_p; + PTPMessagePathDelayResp *resp; + PortIdentity resp_id; + PTPMessagePathDelayRespFollowUp *resp_fwup; + + int ts_good; + Timestamp resp_timestamp; + unsigned resp_timestamp_counter_value; + unsigned req = TX_TIMEOUT_BASE; + int iter = TX_TIMEOUT_ITER; + + 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 + port->recoverPort(); + goto done; + } + + /* Generate and send message */ + resp = new PTPMessagePathDelayResp(port); + port->getPortIdentity(resp_id); + resp->setPortIdentity(&resp_id); + resp->setSequenceId(sequenceId); + + XPTPD_INFO("Process PDelay Request SeqId: %u\t", sequenceId); + +#ifdef DEBUG + for (int n = 0; n < PTP_CLOCK_IDENTITY_LENGTH; ++n) { + fprintf(stderr, "%c", resp_id.clockIdentity[n]); + } + fprintf(stderr, "\"\n"); +#endif + + this->getPortIdentity(&requestingPortIdentity_p); + resp->setRequestingPortIdentity(&requestingPortIdentity_p); + resp->setRequestReceiptTimestamp(_timestamp); + if( port->getTimestampVersion() != _timestamp._version ) { + delete resp; + goto done; + } + port->getTxLock(); + resp->sendPort(port, sourcePortIdentity); + + XPTPD_INFO("Sent path delay response"); + + XPTPD_INFO("Start TS Read"); + ts_good = port->getTxTimestamp + (resp, resp_timestamp, resp_timestamp_counter_value, false); + + XPTPD_INFO("Done TS Read"); + + while (ts_good != 0 && iter-- != 0) { + timer->sleep(req); + if (ts_good == -72 && iter < 1) + XPTPD_ERROR( "Error (TX) timestamping PDelay Response " + "(Retrying-%d), error=%d", iter, ts_good); + ts_good = port->getTxTimestamp + (resp, resp_timestamp, resp_timestamp_counter_value, iter == 0); + req *= 2; + } + port->putTxLock(); + + if (ts_good != 0) { + char msg[HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE]; + port->getExtendedError(msg); + XPTPD_ERROR + ( "Error (TX) timestamping PDelay Response, error=%d\t%s", + ts_good, msg); + delete resp; + goto done; + } + + resp_fwup = new PTPMessagePathDelayRespFollowUp(port); + port->getPortIdentity(resp_fwup_id); + resp_fwup->setPortIdentity(&resp_fwup_id); + resp_fwup->setSequenceId(sequenceId); + resp_fwup->setRequestingPortIdentity(sourcePortIdentity); + resp_fwup->setResponseOriginTimestamp(resp_timestamp); + long long turnaround; + turnaround = + (resp_timestamp.seconds_ls - _timestamp.seconds_ls) * 1000000000LL; + + XPTPD_INFO("Response Depart(sec): %u", resp_timestamp.seconds_ls); + XPTPD_INFO("Request Arrival(sec): %u", _timestamp.seconds_ls); + XPTPD_INFO("#1 Correction Field: %Ld", turnaround); + + turnaround += resp_timestamp.nanoseconds; + + XPTPD_INFO("#2 Correction Field: %Ld", turnaround); + + turnaround -= _timestamp.nanoseconds; + + XPTPD_INFO("#3 Correction Field: %Ld", turnaround); + + resp_fwup->setCorrectionField(0); + resp_fwup->sendPort(port, sourcePortIdentity); + + XPTPD_INFO("Sent path delay response fwup"); + + delete resp; + delete resp_fwup; + +done: + delete timer; + _gc = true; + return; +} + +void PTPMessagePathDelayReq::sendPort(IEEE1588Port * port, + PortIdentity * destIdentity) +{ + uint8_t buf_t[256]; + uint8_t *buf_ptr = buf_t + port->getPayloadOffset(); + unsigned char tspec_msg_t = 0; + memset(buf_t, 0, 256); + /* Create packet in buf */ + /* Copy in common header */ + messageLength = PTP_COMMON_HDR_LENGTH + PTP_PDELAY_REQ_LENGTH; + tspec_msg_t |= messageType & 0xF; + buildCommonHeader(buf_ptr); + + port->sendEventPort(buf_t, messageLength, MCAST_PDELAY, destIdentity); + return; +} + + PTPMessagePathDelayResp::PTPMessagePathDelayResp(IEEE1588Port * port) : + PTPMessageCommon(port) +{ + 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(IEEE1588Port * port) +{ + 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 + port->recoverPort(); + return; + } + + if (port->tryPDelayRxLock() != true) { + fprintf(stderr, "Failed to get PDelay RX Lock\n"); + return; + } + + port->getClock()->deleteEventTimerLocked + (port, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES); + PTPMessagePathDelayResp *old_pdelay_resp = port->getLastPDelayResp(); + if (old_pdelay_resp != NULL) { + delete old_pdelay_resp; + } + port->setLastPDelayResp(this); + + port->putPDelayRxLock(); + _gc = false; + + return; +} + +void PTPMessagePathDelayResp::sendPort(IEEE1588Port * port, + PortIdentity * destIdentity) +{ + uint8_t buf_t[256]; + uint8_t *buf_ptr = buf_t + port->getPayloadOffset(); + unsigned char tspec_msg_t = 0; + Timestamp requestReceiptTimestamp_BE; + memset(buf_t, 0, 256); + // Create packet in buf + // Copy in common header + messageLength = PTP_COMMON_HDR_LENGTH + PTP_PDELAY_RESP_LENGTH; + tspec_msg_t |= messageType & 0xF; + buildCommonHeader(buf_ptr); + requestReceiptTimestamp_BE.seconds_ms = + PLAT_htons(requestReceiptTimestamp.seconds_ms); + requestReceiptTimestamp_BE.seconds_ls = + PLAT_htonl(requestReceiptTimestamp.seconds_ls); + requestReceiptTimestamp_BE.nanoseconds = + PLAT_htonl(requestReceiptTimestamp.nanoseconds); + + // Copy in v2 PDelay_Req specific fields + requestingPortIdentity->getClockIdentityString + (buf_ptr + PTP_PDELAY_RESP_REQ_CLOCK_ID + (PTP_PDELAY_RESP_OFFSET)); + requestingPortIdentity->getPortNumberNO + ((uint16_t *) + (buf_ptr + PTP_PDELAY_RESP_REQ_PORT_ID + (PTP_PDELAY_RESP_OFFSET))); + memcpy(buf_ptr + PTP_PDELAY_RESP_SEC_MS(PTP_PDELAY_RESP_OFFSET), + &(requestReceiptTimestamp_BE.seconds_ms), + sizeof(requestReceiptTimestamp.seconds_ms)); + memcpy(buf_ptr + PTP_PDELAY_RESP_SEC_LS(PTP_PDELAY_RESP_OFFSET), + &(requestReceiptTimestamp_BE.seconds_ls), + sizeof(requestReceiptTimestamp.seconds_ls)); + memcpy(buf_ptr + PTP_PDELAY_RESP_NSEC(PTP_PDELAY_RESP_OFFSET), + &(requestReceiptTimestamp_BE.nanoseconds), + sizeof(requestReceiptTimestamp.nanoseconds)); + + XPTPD_INFO("PDelay Resp Timestamp: %u,%u", + requestReceiptTimestamp.seconds_ls, + requestReceiptTimestamp.nanoseconds); + + port->sendEventPort(buf_t, messageLength, MCAST_PDELAY, destIdentity); + return; +} + +void PTPMessagePathDelayResp::setRequestingPortIdentity +(PortIdentity * identity) +{ + *requestingPortIdentity = *identity; +} + +void PTPMessagePathDelayResp::getRequestingPortIdentity +(PortIdentity * identity) +{ + *identity = *requestingPortIdentity; +} + +PTPMessagePathDelayRespFollowUp::PTPMessagePathDelayRespFollowUp +(IEEE1588Port * port) : PTPMessageCommon (port) +{ + logMeanMessageInterval = 0x7F; + control = MESSAGE_OTHER; + messageType = PATH_DELAY_FOLLOWUP_MESSAGE; + versionPTP = GPTP_VERSION; + requestingPortIdentity = new PortIdentity(); + + return; +} + +PTPMessagePathDelayRespFollowUp::~PTPMessagePathDelayRespFollowUp() +{ + delete requestingPortIdentity; +} + +void PTPMessagePathDelayRespFollowUp::processMessage(IEEE1588Port * port) +{ + Timestamp remote_resp_tx_timestamp(0, 0, 0); + Timestamp request_tx_timestamp(0, 0, 0); + Timestamp remote_req_rx_timestamp(0, 0, 0); + Timestamp response_rx_timestamp(0, 0, 0); + + if (port->getPortState() == PTP_DISABLED) { + // Do nothing all messages should be ignored when in this state + return; + } + if (port->getPortState() == PTP_FAULTY) { + // According to spec recovery is implementation specific + port->recoverPort(); + return; + } + + if (port->tryPDelayRxLock() != true) + return; + + PTPMessagePathDelayReq *req = port->getLastPDelayReq(); + PTPMessagePathDelayResp *resp = port->getLastPDelayResp(); + + PortIdentity req_id; + PortIdentity resp_id; + + if (req == NULL) { + /* Shouldn't happen */ + XPTPD_ERROR + (">>> Received PDelay followup but no REQUEST exists"); + goto abort; + } + + if (resp == NULL) { + /* Probably shouldn't happen either */ + XPTPD_ERROR + (">>> Received PDelay followup but no RESPONSE exists"); + goto abort; + } + + req->getPortIdentity(&req_id); + resp->getRequestingPortIdentity(&resp_id); + + if (req->getSequenceId() != sequenceId) { + + XPTPD_ERROR + ("Received PDelay Response Follow Up but cannot find " + "corresponding request"); + XPTPD_ERROR("My SeqId: %u ", req->getSequenceId()); + XPTPD_ERROR("Their SeqId: %u ", sequenceId); + + goto abort; + } + + // Check if we have received a response + if (resp->getSequenceId() != sequenceId + || resp_id != *requestingPortIdentity) { + uint16_t resp_port_number; + uint16_t req_port_number; + resp_id.getPortNumber(&resp_port_number); + requestingPortIdentity->getPortNumber(&req_port_number); + XPTPD_ERROR + ("Received PDelay Response Follow Up but cannot find " + "corresponding response"); + XPTPD_ERROR("%hu, %hu, %hu, %hu", resp->getSequenceId(), + sequenceId, resp_port_number, req_port_number); + + goto abort; + } + + XPTPD_INFO("Request Sequence Id: %u", req->getSequenceId()); + XPTPD_INFO("Response Sequence Id: %u", resp->getSequenceId()); + XPTPD_INFO("Follow-Up Sequence Id: %u", req->getSequenceId()); + + 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( + port->getLastPDelayRespFollowUp() != NULL && + port->getLastPDelayRespFollowUp() != this ) + { + delete port->getLastPDelayRespFollowUp(); + } + port->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 ) { + 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 + if + ( port->getPeerRateOffset() > .998 && + port->getPeerRateOffset() < 1.002 ) { + turn_around = (int64_t) (turn_around * port->getPeerRateOffset()); + } + + XPTPD_INFO + ("Turn Around Adjustment %Ld", + ((long long)turn_around * port->getPeerRateOffset()) / + 1000000000000LL); + XPTPD_INFO + ("Step #1: Turn Around Adjustment %Ld", + ((long long)turn_around * port->getPeerRateOffset())); + XPTPD_INFO("Adjusted Peer turn around is %Lu", turn_around); + + /* Subtract turn-around time from link delay after rate adjustment */ + link_delay -= turn_around; + link_delay /= 2; + + { + uint64_t mine_elapsed; + uint64_t theirs_elapsed; + Timestamp prev_peer_ts_mine; + Timestamp prev_peer_ts_theirs; + FrequencyRatio rate_offset; + if( port->getPeerOffset( prev_peer_ts_mine, prev_peer_ts_theirs )) { + mine_elapsed = TIMESTAMP_TO_NS(request_tx_timestamp)-TIMESTAMP_TO_NS(prev_peer_ts_mine); + theirs_elapsed = TIMESTAMP_TO_NS(remote_req_rx_timestamp)-TIMESTAMP_TO_NS(prev_peer_ts_theirs); + theirs_elapsed -= port->getLinkDelay(); + theirs_elapsed += link_delay; + rate_offset = ((FrequencyRatio) mine_elapsed)/theirs_elapsed; + port->setPeerRateOffset(rate_offset); + port->setAsCapable( true ); + } + } + port->setLinkDelay( link_delay ); + port->setPeerOffset( request_tx_timestamp, remote_req_rx_timestamp ); + + abort: + delete req; + port->setLastPDelayReq(NULL); + delete resp; + port->setLastPDelayResp(NULL); + + _gc = true; + + defer: + port->putPDelayRxLock(); + + return; +} + +void PTPMessagePathDelayRespFollowUp::sendPort(IEEE1588Port * port, + PortIdentity * destIdentity) +{ + uint8_t buf_t[256]; + uint8_t *buf_ptr = buf_t + port->getPayloadOffset(); + unsigned char tspec_msg_t = 0; + Timestamp responseOriginTimestamp_BE; + memset(buf_t, 0, 256); + /* Create packet in buf + Copy in common header */ + messageLength = PTP_COMMON_HDR_LENGTH + PTP_PDELAY_RESP_LENGTH; + tspec_msg_t |= messageType & 0xF; + buildCommonHeader(buf_ptr); + responseOriginTimestamp_BE.seconds_ms = + PLAT_htons(responseOriginTimestamp.seconds_ms); + responseOriginTimestamp_BE.seconds_ls = + PLAT_htonl(responseOriginTimestamp.seconds_ls); + responseOriginTimestamp_BE.nanoseconds = + PLAT_htonl(responseOriginTimestamp.nanoseconds); + + // Copy in v2 PDelay_Req specific fields + requestingPortIdentity->getClockIdentityString + (buf_ptr + PTP_PDELAY_FOLLOWUP_REQ_CLOCK_ID + (PTP_PDELAY_FOLLOWUP_OFFSET)); + requestingPortIdentity->getPortNumberNO + ((uint16_t *) + (buf_ptr + PTP_PDELAY_FOLLOWUP_REQ_PORT_ID + (PTP_PDELAY_FOLLOWUP_OFFSET))); + memcpy + (buf_ptr + PTP_PDELAY_FOLLOWUP_SEC_MS(PTP_PDELAY_FOLLOWUP_OFFSET), + &(responseOriginTimestamp_BE.seconds_ms), + sizeof(responseOriginTimestamp.seconds_ms)); + memcpy + (buf_ptr + PTP_PDELAY_FOLLOWUP_SEC_LS(PTP_PDELAY_FOLLOWUP_OFFSET), + &(responseOriginTimestamp_BE.seconds_ls), + sizeof(responseOriginTimestamp.seconds_ls)); + memcpy + (buf_ptr + PTP_PDELAY_FOLLOWUP_NSEC(PTP_PDELAY_FOLLOWUP_OFFSET), + &(responseOriginTimestamp_BE.nanoseconds), + sizeof(responseOriginTimestamp.nanoseconds)); + + XPTPD_INFO("PDelay Resp Timestamp: %u,%u", + responseOriginTimestamp.seconds_ls, + responseOriginTimestamp.nanoseconds); + + port->sendGeneralPort(buf_t, messageLength, MCAST_PDELAY, destIdentity); + return; +} + +void PTPMessagePathDelayRespFollowUp::setRequestingPortIdentity +(PortIdentity * identity) +{ + *requestingPortIdentity = *identity; +} diff --git a/daemons/gptp/common/ptptypes.hpp b/daemons/gptp/common/ptptypes.hpp index cd50e580..9cadae1e 100644 --- a/daemons/gptp/common/ptptypes.hpp +++ b/daemons/gptp/common/ptptypes.hpp @@ -1,39 +1,39 @@ -/******************************************************************************
-
- 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 WINPTP_TYPES_HPP
-#define WINPTP_TYPES_HPP
-
-typedef long double FrequencyRatio;
-
-#endif/*WINPTP_TYPES_HPP*/
+/****************************************************************************** + + 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 WINPTP_TYPES_HPP +#define WINPTP_TYPES_HPP + +typedef long double FrequencyRatio; + +#endif/*WINPTP_TYPES_HPP*/ diff --git a/daemons/gptp/linux/src/linux_hal.hpp b/daemons/gptp/linux/src/linux_hal.hpp index 90321200..0ccfa6a7 100644 --- a/daemons/gptp/linux/src/linux_hal.hpp +++ b/daemons/gptp/linux/src/linux_hal.hpp @@ -638,8 +638,8 @@ protected: if (lock_c != 0) return false; return true; - }
-public:
+ } +public: bool wait_prelock() { pthread_mutex_lock(&port_lock); up(); @@ -791,7 +791,7 @@ class LinuxThread:public OSThread { return true; } protected: - LinuxThread() {};
+ LinuxThread() {}; }; class LinuxThreadFactory:public OSThreadFactory { diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.cpp b/daemons/gptp/windows/daemon_cl/daemon_cl.cpp index e1d1bda7..a60a43b0 100644 --- a/daemons/gptp/windows/daemon_cl/daemon_cl.cpp +++ b/daemons/gptp/windows/daemon_cl/daemon_cl.cpp @@ -1,161 +1,161 @@ -/******************************************************************************
-
-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 <winnt.h>
-#include "ieee1588.hpp"
-#include "avbts_clock.hpp"
-#include "avbts_osnet.hpp"
-#include "avbts_oslock.hpp"
-#include "windows_hal.hpp"
-#include <tchar.h>
-
-#define MACSTR_LENGTH 17
-
-static bool exit_flag;
-
-void print_usage( char *arg0 ) {
- fprintf( stderr,
- "%s "
- "[-R <priority 1>] <network interface>\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[])
-{
- bool force_slave = false;
- int32_t offset = 0;
- bool syntonize = false;
- uint8_t priority1 = 248;
- int i;
-
- // Register default network interface
- WindowsPCAPNetworkInterfaceFactory *default_factory = new WindowsPCAPNetworkInterfaceFactory();
- OSNetworkInterfaceFactory::registerFactory( factory_name_t( "default" ), default_factory );
-
- // Create thread, lock, timer, timerq factories
- WindowsThreadFactory *thread_factory = new WindowsThreadFactory();
- WindowsTimerQueueFactory *timerq_factory = new WindowsTimerQueueFactory();
- WindowsLockFactory *lock_factory = new WindowsLockFactory();
- WindowsTimerFactory *timer_factory = new WindowsTimerFactory();
- WindowsConditionFactory *condition_factory = new WindowsConditionFactory();
- WindowsNamedPipeIPC *ipc = new WindowsNamedPipeIPC();
- if( !ipc->init() ) {
- delete ipc;
- ipc = NULL;
- }
-
- /* Process optional arguments */
- for( i = 1; i < argc-1; ++i ) {
- if( ispunct(argv[i][0]) ) {
- if( toupper( argv[i][1] ) == 'H' ) {
- print_usage( argv[0] );
- return -1;
- }
- 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], NULL, 0 ); ++i;
- if( tmp > 254 ) {
- printf( "Invalid priority 1 value, using "
- "default value\n" );
- } else {
- priority1 = (uint8_t) tmp;
- }
- }
- }
- }
- }
-
- // Create Low level network interface object
- uint8_t local_addr_ostr[ETHER_ADDR_OCTETS];
- if( i >= argc ) {
- print_usage( argv[0] );
- return -1;
- }
- parseMacAddr( argv[i], local_addr_ostr );
- LinkLayerAddress local_addr(local_addr_ostr);
-
- // Create HWTimestamper object
- HWTimestamper *timestamper = new WindowsTimestamper();
- // Create Clock object
- IEEE1588Clock *clock = new IEEE1588Clock( false, false, priority1, timestamper, timerq_factory, ipc, lock_factory ); // Do not force slave
- // Create Port Object linked to clock and low level
- IEEE1588Port *port = new IEEE1588Port( clock, 1, false, 0, timestamper, 0, &local_addr,
- condition_factory, thread_factory, timer_factory, lock_factory );
- if( !port->init_port() ) {
- printf( "Failed to initialize port\n" );
- return -1;
- }
- port->processEvent( POWERUP );
-
- // 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;
-}
-
+/****************************************************************************** + +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 <winnt.h> +#include "ieee1588.hpp" +#include "avbts_clock.hpp" +#include "avbts_osnet.hpp" +#include "avbts_oslock.hpp" +#include "windows_hal.hpp" +#include <tchar.h> + +#define MACSTR_LENGTH 17 + +static bool exit_flag; + +void print_usage( char *arg0 ) { + fprintf( stderr, + "%s " + "[-R <priority 1>] <network interface>\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[]) +{ + bool force_slave = false; + int32_t offset = 0; + bool syntonize = false; + uint8_t priority1 = 248; + int i; + + // Register default network interface + WindowsPCAPNetworkInterfaceFactory *default_factory = new WindowsPCAPNetworkInterfaceFactory(); + OSNetworkInterfaceFactory::registerFactory( factory_name_t( "default" ), default_factory ); + + // Create thread, lock, timer, timerq factories + WindowsThreadFactory *thread_factory = new WindowsThreadFactory(); + WindowsTimerQueueFactory *timerq_factory = new WindowsTimerQueueFactory(); + WindowsLockFactory *lock_factory = new WindowsLockFactory(); + WindowsTimerFactory *timer_factory = new WindowsTimerFactory(); + WindowsConditionFactory *condition_factory = new WindowsConditionFactory(); + WindowsNamedPipeIPC *ipc = new WindowsNamedPipeIPC(); + if( !ipc->init() ) { + delete ipc; + ipc = NULL; + } + + /* Process optional arguments */ + for( i = 1; i < argc-1; ++i ) { + if( ispunct(argv[i][0]) ) { + if( toupper( argv[i][1] ) == 'H' ) { + print_usage( argv[0] ); + return -1; + } + 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], NULL, 0 ); ++i; + if( tmp > 254 ) { + printf( "Invalid priority 1 value, using " + "default value\n" ); + } else { + priority1 = (uint8_t) tmp; + } + } + } + } + } + + // Create Low level network interface object + uint8_t local_addr_ostr[ETHER_ADDR_OCTETS]; + if( i >= argc ) { + print_usage( argv[0] ); + return -1; + } + parseMacAddr( argv[i], local_addr_ostr ); + LinkLayerAddress local_addr(local_addr_ostr); + + // Create HWTimestamper object + HWTimestamper *timestamper = new WindowsTimestamper(); + // Create Clock object + IEEE1588Clock *clock = new IEEE1588Clock( false, false, priority1, timestamper, timerq_factory, ipc, lock_factory ); // Do not force slave + // Create Port Object linked to clock and low level + IEEE1588Port *port = new IEEE1588Port( clock, 1, false, 0, timestamper, 0, &local_addr, + condition_factory, thread_factory, timer_factory, lock_factory ); + if( !port->init_port() ) { + printf( "Failed to initialize port\n" ); + return -1; + } + port->processEvent( POWERUP ); + + // 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; +} + diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj b/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj index 79b5844e..7fb0dfea 100644 --- a/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj +++ b/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj @@ -1,212 +1,212 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{590D3055-A068-4B31-B4F9-B2ACC5F93663}</ProjectGuid>
- <Keyword>Win32Proj</Keyword>
- <RootNamespace>daemon_cl</RootNamespace>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- <IncludePath>$(IncludePath)</IncludePath>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- <IncludePath>$(ALLUSERSPROFILE)\WpdPack\Include;$(IncludePath)</IncludePath>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- <IncludePath>$(IncludePath)</IncludePath>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- <IncludePath>$(ALLUSERSPROFILE)\WpdPack\Include;$(IncludePath)</IncludePath>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(ALLUSERSPROFILE)\WpdPack\Include;$(USERPROFILE)\src\pcap\Include;$(SolutionDir)\..\common;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(ALLUSERSPROFILE)\WpdPack\Lib;$(USERPROFILE)\src\pcap\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(ALLUSERSPROFILE)\WpdPack\Include;$(USERPROFILE)\src\pcap\Include;$(SolutionDir)\..\common;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(ALLUSERSPROFILE)\WpdPack\Lib\x64;$(USERPROFILE)\src\pcap\Lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(ALLUSERSPROFILE)\WpdPack\Include;$(USERPROFILE)\src\pcap\Include;$(SolutionDir)\..\common;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <AdditionalLibraryDirectories>$(ALLUSERSPROFILE)\WpdPack\Lib;$(USERPROFILE)\src\pcap\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <GenerateMapFile>true</GenerateMapFile>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(ALLUSERSPROFILE)\WpdPack\Include;$(USERPROFILE)\src\pcap\Include;$(SolutionDir)\..\common;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <AdditionalLibraryDirectories>$(ALLUSERSPROFILE)\WpdPack\Lib\x64;$(USERPROFILE)\src\pcap\Lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <GenerateMapFile>true</GenerateMapFile>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <None Include="ReadMe.txt" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\common\avbts_clock.hpp" />
- <ClInclude Include="..\..\common\avbts_message.hpp" />
- <ClInclude Include="..\..\common\avbts_oscondition.hpp" />
- <ClInclude Include="..\..\common\avbts_osipc.hpp" />
- <ClInclude Include="..\..\common\avbts_oslock.hpp" />
- <ClInclude Include="..\..\common\avbts_osnet.hpp" />
- <ClInclude Include="..\..\common\avbts_osthread.hpp" />
- <ClInclude Include="..\..\common\avbts_ostimer.hpp" />
- <ClInclude Include="..\..\common\avbts_ostimerq.hpp" />
- <ClInclude Include="..\..\common\avbts_port.hpp" />
- <ClInclude Include="..\..\common\ieee1588.hpp" />
- <ClInclude Include="..\..\common\ptptypes.hpp" />
- <ClInclude Include="ipcdef.hpp" />
- <ClInclude Include="packet.hpp" />
- <ClInclude Include="platform.hpp" />
- <ClInclude Include="stdafx.h" />
- <ClInclude Include="targetver.h" />
- <ClInclude Include="tsc.hpp" />
- <ClInclude Include="windows_hal.hpp" />
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\..\common\avbts_osnet.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="..\..\common\ieee1588clock.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="..\..\common\ieee1588port.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="..\..\common\ptp_message.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="daemon_cl.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="packet.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="platform.cpp" />
- <ClCompile Include="stdafx.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="windows_hal.cpp" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
+<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{590D3055-A068-4B31-B4F9-B2ACC5F93663}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>daemon_cl</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <IncludePath>$(IncludePath)</IncludePath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <IncludePath>$(ALLUSERSPROFILE)\WpdPack\Include;$(IncludePath)</IncludePath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <IncludePath>$(IncludePath)</IncludePath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <IncludePath>$(ALLUSERSPROFILE)\WpdPack\Include;$(IncludePath)</IncludePath> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(ALLUSERSPROFILE)\WpdPack\Include;$(USERPROFILE)\src\pcap\Include;$(SolutionDir)\..\common;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(ALLUSERSPROFILE)\WpdPack\Lib;$(USERPROFILE)\src\pcap\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(ALLUSERSPROFILE)\WpdPack\Include;$(USERPROFILE)\src\pcap\Include;$(SolutionDir)\..\common;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(ALLUSERSPROFILE)\WpdPack\Lib\x64;$(USERPROFILE)\src\pcap\Lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(ALLUSERSPROFILE)\WpdPack\Include;$(USERPROFILE)\src\pcap\Include;$(SolutionDir)\..\common;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>$(ALLUSERSPROFILE)\WpdPack\Lib;$(USERPROFILE)\src\pcap\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <GenerateMapFile>true</GenerateMapFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WPCAP;HAVE_REMOTE</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(ALLUSERSPROFILE)\WpdPack\Include;$(USERPROFILE)\src\pcap\Include;$(SolutionDir)\..\common;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>$(ALLUSERSPROFILE)\WpdPack\Lib\x64;$(USERPROFILE)\src\pcap\Lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>wpcap.lib;Iphlpapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <GenerateMapFile>true</GenerateMapFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\common\avbts_clock.hpp" /> + <ClInclude Include="..\..\common\avbts_message.hpp" /> + <ClInclude Include="..\..\common\avbts_oscondition.hpp" /> + <ClInclude Include="..\..\common\avbts_osipc.hpp" /> + <ClInclude Include="..\..\common\avbts_oslock.hpp" /> + <ClInclude Include="..\..\common\avbts_osnet.hpp" /> + <ClInclude Include="..\..\common\avbts_osthread.hpp" /> + <ClInclude Include="..\..\common\avbts_ostimer.hpp" /> + <ClInclude Include="..\..\common\avbts_ostimerq.hpp" /> + <ClInclude Include="..\..\common\avbts_port.hpp" /> + <ClInclude Include="..\..\common\ieee1588.hpp" /> + <ClInclude Include="..\..\common\ptptypes.hpp" /> + <ClInclude Include="ipcdef.hpp" /> + <ClInclude Include="packet.hpp" /> + <ClInclude Include="platform.hpp" /> + <ClInclude Include="stdafx.h" /> + <ClInclude Include="targetver.h" /> + <ClInclude Include="tsc.hpp" /> + <ClInclude Include="windows_hal.hpp" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\common\avbts_osnet.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="..\..\common\ieee1588clock.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="..\..\common\ieee1588port.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="..\..\common\ptp_message.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="daemon_cl.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="packet.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="platform.cpp" /> + <ClCompile Include="stdafx.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> + </ClCompile> + <ClCompile Include="windows_hal.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project>
\ No newline at end of file diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.filters b/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.filters index fdf39bd4..70fc13af 100644 --- a/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.filters +++ b/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.filters @@ -1,108 +1,108 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
- </Filter>
- <Filter Include="Header Files">
- <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
- <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- </Filter>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
- <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <None Include="ReadMe.txt" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="stdafx.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="targetver.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="windows_hal.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="packet.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="ipcdef.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="platform.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="tsc.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_clock.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_message.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_oscondition.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_osipc.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_oslock.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_osnet.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_osthread.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_ostimer.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_ostimerq.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\avbts_port.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\ieee1588.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\common\ptptypes.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="stdafx.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="daemon_cl.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="packet.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\common\avbts_osnet.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\common\ieee1588clock.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\common\ieee1588port.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\common\ptp_message.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="platform.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="windows_hal.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="stdafx.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="targetver.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="windows_hal.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="packet.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="ipcdef.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="platform.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="tsc.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_clock.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_message.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_oscondition.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_osipc.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_oslock.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_osnet.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_osthread.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_ostimer.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_ostimerq.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\avbts_port.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\ieee1588.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\common\ptptypes.hpp"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="stdafx.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="daemon_cl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="packet.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\common\avbts_osnet.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\common\ieee1588clock.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\common\ieee1588port.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\common\ptp_message.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="platform.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="windows_hal.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.user b/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.user index 26a0af46..de099045 100644 --- a/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.user +++ b/daemons/gptp/windows/daemon_cl/daemon_cl.vcxproj.user @@ -1,15 +1,15 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerCommandArguments>88-88-88-88-87-88</LocalDebuggerCommandArguments>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LocalDebuggerCommandArguments>00-13-20-F8-84-41</LocalDebuggerCommandArguments>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LocalDebuggerCommandArguments>/r 200 88-88-88-88-87-88</LocalDebuggerCommandArguments>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LocalDebuggerCommandArguments>88-88-88-88-87-88</LocalDebuggerCommandArguments> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LocalDebuggerCommandArguments>00-13-20-F8-84-41</LocalDebuggerCommandArguments> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LocalDebuggerCommandArguments>/r 200 88-88-88-88-87-88</LocalDebuggerCommandArguments> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> </Project>
\ No newline at end of file diff --git a/daemons/gptp/windows/daemon_cl/ipcdef.hpp b/daemons/gptp/windows/daemon_cl/ipcdef.hpp index 9813fb24..f31cb5a4 100644 --- a/daemons/gptp/windows/daemon_cl/ipcdef.hpp +++ b/daemons/gptp/windows/daemon_cl/ipcdef.hpp @@ -1,89 +1,89 @@ -/******************************************************************************
-
-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
-
-#include <stdint.h>
-#include <ptptypes.hpp>
-
-#define PIPE_PREFIX "\\\\.\\pipe\\"
-#define P802_1AS_PIPENAME "gptp-update"
-#define OUTSTANDING_MESSAGES 10
-
-#pragma pack(push,1)
-
-class WindowsNPipeMessage {
-private:
- int64_t ml_phoffset;
- int64_t ls_phoffset;
- FrequencyRatio ml_freqoffset;
- FrequencyRatio ls_freq_offset;
- uint64_t local_time;
-public:
- WindowsNPipeMessage() {};
- WindowsNPipeMessage( int64_t ml_phoffset, int64_t ls_phoffset, FrequencyRatio ml_freqoffset, FrequencyRatio ls_freq_offset, uint64_t local_time ) {
- this->ml_phoffset = ml_phoffset;
- this->ls_phoffset = ls_phoffset;
- this->ml_freqoffset = ml_freqoffset;
- this->ls_freq_offset = ls_freq_offset;
- this->local_time = local_time;
-
- }
- bool write( HANDLE pipe ) {
- DWORD bytes_written;
- DWORD last_error = ERROR_SUCCESS;
- if( WriteFile( pipe, this, sizeof(*this), &bytes_written, NULL ) == 0 ) {
- last_error = GetLastError();
- }
- if( last_error == ERROR_SUCCESS || last_error == ERROR_PIPE_LISTENING ) {
- return true;
- }
- return false;
- }
- bool read( HANDLE pipe ) {
- DWORD bytes_written;
- if( ReadFile( pipe, this, sizeof(*this), &bytes_written, NULL ) == 0 ) return false;
- return true;
- }
- int64_t getMasterLocalOffset() { return ml_phoffset; }
- FrequencyRatio getMasterLocalFreqOffset() { return ml_freqoffset; }
- int64_t getLocalSystemOffset() { return ls_phoffset; }
- FrequencyRatio getLocalSystemFreqOffset() { return ls_freq_offset; }
- uint64_t getLocalTime() { return local_time; }
-};
-
-#pragma pack(pop)
-
-#endif
+/****************************************************************************** + +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 + +#include <stdint.h> +#include <ptptypes.hpp> + +#define PIPE_PREFIX "\\\\.\\pipe\\" +#define P802_1AS_PIPENAME "gptp-update" +#define OUTSTANDING_MESSAGES 10 + +#pragma pack(push,1) + +class WindowsNPipeMessage { +private: + int64_t ml_phoffset; + int64_t ls_phoffset; + FrequencyRatio ml_freqoffset; + FrequencyRatio ls_freq_offset; + uint64_t local_time; +public: + WindowsNPipeMessage() {}; + WindowsNPipeMessage( int64_t ml_phoffset, int64_t ls_phoffset, FrequencyRatio ml_freqoffset, FrequencyRatio ls_freq_offset, uint64_t local_time ) { + this->ml_phoffset = ml_phoffset; + this->ls_phoffset = ls_phoffset; + this->ml_freqoffset = ml_freqoffset; + this->ls_freq_offset = ls_freq_offset; + this->local_time = local_time; + + } + bool write( HANDLE pipe ) { + DWORD bytes_written; + DWORD last_error = ERROR_SUCCESS; + if( WriteFile( pipe, this, sizeof(*this), &bytes_written, NULL ) == 0 ) { + last_error = GetLastError(); + } + if( last_error == ERROR_SUCCESS || last_error == ERROR_PIPE_LISTENING ) { + return true; + } + return false; + } + bool read( HANDLE pipe ) { + DWORD bytes_written; + if( ReadFile( pipe, this, sizeof(*this), &bytes_written, NULL ) == 0 ) return false; + return true; + } + int64_t getMasterLocalOffset() { return ml_phoffset; } + FrequencyRatio getMasterLocalFreqOffset() { return ml_freqoffset; } + int64_t getLocalSystemOffset() { return ls_phoffset; } + FrequencyRatio getLocalSystemFreqOffset() { return ls_freq_offset; } + uint64_t getLocalTime() { return local_time; } +}; + +#pragma pack(pop) + +#endif diff --git a/daemons/gptp/windows/daemon_cl/packet.cpp b/daemons/gptp/windows/daemon_cl/packet.cpp index dea91385..4158619a 100644 --- a/daemons/gptp/windows/daemon_cl/packet.cpp +++ b/daemons/gptp/windows/daemon_cl/packet.cpp @@ -1,207 +1,207 @@ -/******************************************************************************
-
- 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;
-}
+/****************************************************************************** + + 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 index 3e080510..0ccbf3fb 100644 --- a/daemons/gptp/windows/daemon_cl/packet.hpp +++ b/daemons/gptp/windows/daemon_cl/packet.hpp @@ -1,62 +1,62 @@ -/******************************************************************************
-
- 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"
-
-#define ETHER_ADDR_OCTETS 6
-#define PACKET_HDR_LENGTH 14
-
-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;
-
-typedef struct { uint8_t addr[ETHER_ADDR_OCTETS]; } packet_addr_t;
-typedef struct packet_handle * pfhandle_t;
-
-packet_error_t mallocPacketHandle( pfhandle_t *pfhandle_r );
-void freePacketHandle( pfhandle_t pfhandle );
-
-packet_error_t openInterfaceByAddr( pfhandle_t pfhandle, packet_addr_t *addr, int timeout );
-void closeInterface( pfhandle_t pfhandle );
-packet_error_t sendFrame( pfhandle_t pfhandle, packet_addr_t *addr, uint16_t ethertype, uint8_t *payload, size_t length );
-packet_error_t recvFrame( pfhandle_t pfhandle, packet_addr_t *addr, uint8_t *payload, size_t &length );
-
-packet_error_t packetBind( struct packet_handle *handle, uint16_t ethertype );
-
-#endif /* PACKET_H */
+/****************************************************************************** + + 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" + +#define ETHER_ADDR_OCTETS 6 +#define PACKET_HDR_LENGTH 14 + +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; + +typedef struct { uint8_t addr[ETHER_ADDR_OCTETS]; } packet_addr_t; +typedef struct packet_handle * pfhandle_t; + +packet_error_t mallocPacketHandle( pfhandle_t *pfhandle_r ); +void freePacketHandle( pfhandle_t pfhandle ); + +packet_error_t openInterfaceByAddr( pfhandle_t pfhandle, packet_addr_t *addr, int timeout ); +void closeInterface( pfhandle_t pfhandle ); +packet_error_t sendFrame( pfhandle_t pfhandle, packet_addr_t *addr, uint16_t ethertype, uint8_t *payload, size_t length ); +packet_error_t recvFrame( pfhandle_t pfhandle, packet_addr_t *addr, uint8_t *payload, size_t &length ); + +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 index 1a564e0a..12f9aa56 100644 --- a/daemons/gptp/windows/daemon_cl/platform.cpp +++ b/daemons/gptp/windows/daemon_cl/platform.cpp @@ -1,55 +1,55 @@ -/******************************************************************************
-
- 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>
-
-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 );
-}
+/****************************************************************************** + + 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> + +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 ); +} diff --git a/daemons/gptp/windows/daemon_cl/platform.hpp b/daemons/gptp/windows/daemon_cl/platform.hpp index 37c9b603..38c773b1 100644 --- a/daemons/gptp/windows/daemon_cl/platform.hpp +++ b/daemons/gptp/windows/daemon_cl/platform.hpp @@ -1,44 +1,44 @@ -/******************************************************************************
-
- Copyright (c) 2009-2012, Intel Corporation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-
-#ifndef PLATFORM_HPP
-#define PLATFORM_HPP
-
-errno_t PLAT_strncpy( char *dest, const char *src, rsize_t max );
-uint16_t PLAT_htons( uint16_t s );
-uint32_t PLAT_htonl( uint32_t l );
-uint16_t PLAT_ntohs( uint16_t s );
-uint32_t PLAT_ntohl( uint32_t l );
-
-#endif
+/****************************************************************************** + + 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 PLATFORM_HPP +#define PLATFORM_HPP + +errno_t PLAT_strncpy( char *dest, const char *src, rsize_t max ); +uint16_t PLAT_htons( uint16_t s ); +uint32_t PLAT_htonl( uint32_t l ); +uint16_t PLAT_ntohs( uint16_t s ); +uint32_t PLAT_ntohl( uint32_t l ); + +#endif diff --git a/daemons/gptp/windows/daemon_cl/stdafx.cpp b/daemons/gptp/windows/daemon_cl/stdafx.cpp index a3275bfa..ba468098 100644 --- a/daemons/gptp/windows/daemon_cl/stdafx.cpp +++ b/daemons/gptp/windows/daemon_cl/stdafx.cpp @@ -1,8 +1,8 @@ -// 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
+// 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 index 47a0d025..b005a839 100644 --- a/daemons/gptp/windows/daemon_cl/stdafx.h +++ b/daemons/gptp/windows/daemon_cl/stdafx.h @@ -1,15 +1,15 @@ -// 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
+// 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 index 90e767bf..87c0086d 100644 --- a/daemons/gptp/windows/daemon_cl/targetver.h +++ b/daemons/gptp/windows/daemon_cl/targetver.h @@ -1,8 +1,8 @@ -#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>
+#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 index f5adb200..41281171 100644 --- a/daemons/gptp/windows/daemon_cl/tsc.hpp +++ b/daemons/gptp/windows/daemon_cl/tsc.hpp @@ -1,68 +1,68 @@ -/******************************************************************************
-
- 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 TSC_HPP
-#define TSC_HPP
-
-#include <intrin.h>
-#include <stdint.h>
-
-#define BASE_FREQUENCY 100000000
-
-inline unsigned __int64 PLAT_rdtsc()
-{
- return __rdtsc();
-}
-
-inline uint64_t getTSCFrequency( unsigned millis ) {
- UINT16 multiplierx2;
- uint64_t frequency = 0;
- DWORD mhz;
- DWORD mhz_sz = sizeof(mhz);
-
- if( RegGetValue( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "~MHz", RRF_RT_REG_DWORD, NULL, &mhz, &mhz_sz ) != ERROR_SUCCESS ) {
- goto done;
- }
- fprintf( stderr, "mhz: %u\n", mhz );
- multiplierx2 = (UINT16)((2*mhz*1000000ULL)/BASE_FREQUENCY);
- if( multiplierx2 % 2 == 1 ) ++multiplierx2;
- fprintf( stderr, "Multiplier: %hhu\n", multiplierx2/2 );
-
- frequency = (((uint64_t)multiplierx2)*BASE_FREQUENCY)/2;
- fprintf( stderr, "Frequency: %llu\n", frequency );
-
-done:
- return frequency;
-}
-
-#endif/*TSC_HPP*/
+/****************************************************************************** + + 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 TSC_HPP +#define TSC_HPP + +#include <intrin.h> +#include <stdint.h> + +#define BASE_FREQUENCY 100000000 + +inline unsigned __int64 PLAT_rdtsc() +{ + return __rdtsc(); +} + +inline uint64_t getTSCFrequency( unsigned millis ) { + UINT16 multiplierx2; + uint64_t frequency = 0; + DWORD mhz; + DWORD mhz_sz = sizeof(mhz); + + if( RegGetValue( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "~MHz", RRF_RT_REG_DWORD, NULL, &mhz, &mhz_sz ) != ERROR_SUCCESS ) { + goto done; + } + fprintf( stderr, "mhz: %u\n", mhz ); + multiplierx2 = (UINT16)((2*mhz*1000000ULL)/BASE_FREQUENCY); + if( multiplierx2 % 2 == 1 ) ++multiplierx2; + fprintf( stderr, "Multiplier: %hhu\n", multiplierx2/2 ); + + frequency = (((uint64_t)multiplierx2)*BASE_FREQUENCY)/2; + fprintf( stderr, "Frequency: %llu\n", frequency ); + +done: + return frequency; +} + +#endif/*TSC_HPP*/ diff --git a/daemons/gptp/windows/daemon_cl/windows_hal.cpp b/daemons/gptp/windows/daemon_cl/windows_hal.cpp index a57e6da1..217607fb 100644 --- a/daemons/gptp/windows/daemon_cl/windows_hal.cpp +++ b/daemons/gptp/windows/daemon_cl/windows_hal.cpp @@ -1,108 +1,108 @@ -/******************************************************************************
-
- 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>
-
-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 );
-}
-
-
-bool WindowsTimestamper::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;
-
- if( strstr( pAdapterInfo->Description, NANOSECOND_CLOCK_PART_DESCRIPTION ) != NULL ) {
- netclock_hz.QuadPart = NETCLOCK_HZ_NANO;
- } else {
- netclock_hz.QuadPart = NETCLOCK_HZ_OTHER;
- }
- fprintf( stderr, "Adapter UID: %s(%s)\n", pAdapterInfo->AdapterName, pAdapterInfo->Description+(strlen(pAdapterInfo->Description)-7));
- 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( 1000 );
- if( tsc_hz.QuadPart == 0 ) {
- return false;
- }
-
- return true;
-}
+/****************************************************************************** + + 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> + +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 ); +} + + +bool WindowsTimestamper::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; + + if( strstr( pAdapterInfo->Description, NANOSECOND_CLOCK_PART_DESCRIPTION ) != NULL ) { + netclock_hz.QuadPart = NETCLOCK_HZ_NANO; + } else { + netclock_hz.QuadPart = NETCLOCK_HZ_OTHER; + } + fprintf( stderr, "Adapter UID: %s(%s)\n", pAdapterInfo->AdapterName, pAdapterInfo->Description+(strlen(pAdapterInfo->Description)-7)); + 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( 1000 ); + if( tsc_hz.QuadPart == 0 ) { + return false; + } + + return true; +} diff --git a/daemons/gptp/windows/daemon_cl/windows_hal.hpp b/daemons/gptp/windows/daemon_cl/windows_hal.hpp index 3343f660..39daf344 100644 --- a/daemons/gptp/windows/daemon_cl/windows_hal.hpp +++ b/daemons/gptp/windows/daemon_cl/windows_hal.hpp @@ -1,533 +1,533 @@ -/******************************************************************************
-
- 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
-
-#include <minwindef.h>
-#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 "iphlpapi.h"
-#include "ipcdef.hpp"
-#include "tsc.hpp"
-
-#include "avbts_osipc.hpp"
-
-#include <ntddndis.h>
-
-#include <map>
-#include <list>
-
-class WindowsPCAPNetworkInterface : public OSNetworkInterface {
- friend class WindowsPCAPNetworkInterfaceFactory;
-private:
- pfhandle_t handle;
- LinkLayerAddress local_addr;
-public:
- virtual net_result send( LinkLayerAddress *addr, uint8_t *payload, size_t length, bool timestamp ) {
- packet_addr_t dest;
- addr->toOctetArray( dest.addr );
- if( sendFrame( handle, &dest, PTP_ETHERTYPE, payload, length ) != PACKET_NO_ERROR ) return net_fatal;
- return net_succeed;
- }
- virtual net_result recv( 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;
- }
- virtual void getLinkLayerAddress( LinkLayerAddress *addr ) {
- *addr = local_addr;
- }
- virtual unsigned getPayloadOffset() {
- return PACKET_HDR_LENGTH;
- }
- virtual ~WindowsPCAPNetworkInterface() {
- closeInterface( handle );
- if( handle != NULL ) freePacketHandle( handle );
- }
-protected:
- WindowsPCAPNetworkInterface() { handle = NULL; };
-};
-
-class WindowsPCAPNetworkInterfaceFactory : public OSNetworkInterfaceFactory {
-public:
- virtual bool createInterface( OSNetworkInterface **net_iface, InterfaceLabel *label, HWTimestamper *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;
- }
-};
-
-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:
- WindowsLock() {
- lock_c = NULL;
- }
- bool initialize( OSLockType type ) {
- lock_c = CreateMutex( NULL, false, NULL );
- if( lock_c == NULL ) return false;
- this->type = type;
- return true;
- }
- OSLockResult lock() {
- if( type == oslock_recursive ) {
- return lock_l( INFINITE );
- }
- return nonreentrant_lock_l( INFINITE );
- }
- OSLockResult trylock() {
- if( type == oslock_recursive ) {
- return lock_l( 0 );
- }
- return nonreentrant_lock_l( 0 );
- }
- OSLockResult unlock() {
- ReleaseMutex( lock_c );
- return oslock_ok;
- }
-};
-
-class WindowsLockFactory : public OSLockFactory {
-public:
- OSLock *createLock( OSLockType type ) {
- WindowsLock *lock = new WindowsLock();
- if( !lock->initialize( type )) {
- delete lock;
- lock = NULL;
- }
- return lock;
- }
-};
-
-class WindowsCondition : public OSCondition {
- friend class WindowsConditionFactory;
-private:
- SRWLOCK lock;
- CONDITION_VARIABLE condition;
-protected:
- bool initialize() {
- InitializeSRWLock( &lock );
- InitializeConditionVariable( &condition );
- return true;
- }
-public:
- bool wait_prelock() {
- AcquireSRWLockExclusive( &lock );
- up();
- return true;
- }
- bool wait() {
- BOOL result = SleepConditionVariableSRW( &condition, &lock, INFINITE, 0 );
- bool ret = false;
- if( result == TRUE ) {
- down();
- ReleaseSRWLockExclusive( &lock );
- ret = true;
- }
- return ret;
- }
- bool signal() {
- AcquireSRWLockExclusive( &lock );
- if( waiting() ) WakeAllConditionVariable( &condition );
- ReleaseSRWLockExclusive( &lock );
- return true;
- }
-};
-
-class WindowsConditionFactory : public OSConditionFactory {
-public:
- OSCondition *createCondition() {
- WindowsCondition *result = new WindowsCondition();
- return result->initialize() ? result : NULL;
- }
-};
-
-class WindowsTimerQueue;
-
-struct TimerQueue_t;
-
-struct WindowsTimerQueueHandlerArg {
- HANDLE timer_handle;
- HANDLE queue_handle;
- event_descriptor_t *inner_arg;
- ostimerq_handler func;
- int type;
- bool rm;
- WindowsTimerQueue *queue;
- TimerQueue_t *timer_queue;
-};
-
-typedef std::list<WindowsTimerQueueHandlerArg *> TimerArgList_t;
-struct TimerQueue_t {
- TimerArgList_t arg_list;
- HANDLE queue_handle;
- SRWLOCK lock;
-};
-
-
-VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore );
-
-typedef std::map<int,TimerQueue_t> TimerQueueMap_t;
-
-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:
- WindowsTimerQueue() {
- InitializeSRWLock( &retiredTimersLock );
- };
-public:
- 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;
- }
- 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;
- }
-};
-
-VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore );
-
-class WindowsTimerQueueFactory : public OSTimerQueueFactory {
-public:
- virtual OSTimerQueue *createOSTimerQueue( IEEE1588Clock *clock ) {
- WindowsTimerQueue *timerq = new WindowsTimerQueue();
- return timerq;
- };
-};
-
-class WindowsTimer : public OSTimer {
- friend class WindowsTimerFactory;
-public:
- virtual unsigned long sleep( unsigned long micros ) {
- Sleep( micros/1000 );
- return micros;
- }
-protected:
- WindowsTimer() {};
-};
-
-class WindowsTimerFactory : public OSTimerFactory {
-public:
- virtual OSTimer *createTimer() {
- return new WindowsTimer();
- }
-};
-
-struct OSThreadArg {
- OSThreadFunction func;
- void *arg;
- OSThreadExitCode ret;
-};
-
-DWORD WINAPI OSThreadCallback( LPVOID input );
-
-class WindowsThread : public OSThread {
- friend class WindowsThreadFactory;
-private:
- HANDLE thread_id;
- OSThreadArg *arg_inner;
-public:
- 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;
- }
- 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:
- WindowsThread() {};
-};
-
-class WindowsThreadFactory : public OSThreadFactory {
-public:
- OSThread *createThread() {
- return new WindowsThread();
- }
-};
-
-#define NETCLOCK_HZ_OTHER 1056000000
-#define NETCLOCK_HZ_NANO 1000000000
-#define ONE_WAY_PHY_DELAY 8000
-#define NANOSECOND_CLOCK_PART_DESCRIPTION "I217-LM"
-#define NETWORK_CARD_ID_PREFIX "\\\\.\\"
-#define OID_INTEL_GET_RXSTAMP 0xFF020264
-#define OID_INTEL_GET_TXSTAMP 0xFF020263
-#define OID_INTEL_GET_SYSTIM 0xFF020262
-#define OID_INTEL_SET_SYSTIM 0xFF020261
-
-class WindowsTimestamper : public HWTimestamper {
-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 ) {
- 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 ) {
- 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 ) {
- 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 ) {
- long double scaled_output = ((long double)tsc_hz.QuadPart)/1000000000;
- scaled_output = ((long double) time)/scaled_output;
- return (uint64_t) scaled_output;
- }
-public:
- virtual bool HWTimestamper_init( InterfaceLabel *iface_label, OSNetworkInterface *net_iface );
- virtual bool HWTimestamper_gettime( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock, uint32_t *nominal_clock_rate )
- {
- 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;
- }
-
- virtual int HWTimestamper_txtimestamp( PortIdentity *identity, uint16_t sequenceId, 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 ) return -1;
- if( returned != sizeof(buf_tmp) ) return -72;
- tx_r = (((uint64_t)buf[1]) << 32) | buf[0];
- tx_s = scaleNativeClockToNanoseconds( tx_r );
- tx_s += ONE_WAY_PHY_DELAY;
- timestamp = nanoseconds64ToTimestamp( tx_s );
- timestamp._version = version;
-
- return 0;
- }
-
- virtual int HWTimestamper_rxtimestamp( PortIdentity *identity, uint16_t sequenceId, 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 -1;
- if( returned != sizeof(buf_tmp) ) return -72;
- packet_sequence_id = *((uint32_t *) buf+3) >> 16;
- if( PLAT_ntohs( packet_sequence_id ) != sequenceId ) return -72;
- rx_r = (((uint64_t)buf[1]) << 32) | buf[0];
- rx_s = scaleNativeClockToNanoseconds( rx_r );
- rx_s -= ONE_WAY_PHY_DELAY;
- timestamp = nanoseconds64ToTimestamp( rx_s );
- timestamp._version = version;
-
- return 0;
- }
-};
-
-
-
-class WindowsNamedPipeIPC : public OS_IPC {
-private:
- HANDLE pipe;
-public:
- WindowsNamedPipeIPC() { };
- ~WindowsNamedPipeIPC() {
- CloseHandle( pipe );
- }
- virtual bool init( OS_IPC_ARG *arg = NULL ) {
- char pipename[64];
- PLAT_strncpy( pipename, PIPE_PREFIX, 63 );
- PLAT_strncpy( pipename+strlen(pipename), P802_1AS_PIPENAME, 63-strlen(pipename) );
- pipe = CreateNamedPipe( pipename, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE, PIPE_UNLIMITED_INSTANCES,
- OUTSTANDING_MESSAGES*sizeof( WindowsNPipeMessage ), 0, 0, NULL );
- if( pipe == INVALID_HANDLE_VALUE ) return false;
- return true;
- }
- 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 ) {
- WindowsNPipeMessage msg( ml_phoffset, ls_phoffset, ml_freqoffset, ls_freq_offset, local_time );
- if( !msg.write( pipe )) {
- CloseHandle(pipe);
- return init();
- }
- return true;
- }
-};
-
-#endif
+/****************************************************************************** + + 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 + +#include <minwindef.h> +#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 "iphlpapi.h" +#include "ipcdef.hpp" +#include "tsc.hpp" + +#include "avbts_osipc.hpp" + +#include <ntddndis.h> + +#include <map> +#include <list> + +class WindowsPCAPNetworkInterface : public OSNetworkInterface { + friend class WindowsPCAPNetworkInterfaceFactory; +private: + pfhandle_t handle; + LinkLayerAddress local_addr; +public: + virtual net_result send( LinkLayerAddress *addr, uint8_t *payload, size_t length, bool timestamp ) { + packet_addr_t dest; + addr->toOctetArray( dest.addr ); + if( sendFrame( handle, &dest, PTP_ETHERTYPE, payload, length ) != PACKET_NO_ERROR ) return net_fatal; + return net_succeed; + } + virtual net_result recv( 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; + } + virtual void getLinkLayerAddress( LinkLayerAddress *addr ) { + *addr = local_addr; + } + virtual unsigned getPayloadOffset() { + return PACKET_HDR_LENGTH; + } + virtual ~WindowsPCAPNetworkInterface() { + closeInterface( handle ); + if( handle != NULL ) freePacketHandle( handle ); + } +protected: + WindowsPCAPNetworkInterface() { handle = NULL; }; +}; + +class WindowsPCAPNetworkInterfaceFactory : public OSNetworkInterfaceFactory { +public: + virtual bool createInterface( OSNetworkInterface **net_iface, InterfaceLabel *label, HWTimestamper *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; + } +}; + +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: + WindowsLock() { + lock_c = NULL; + } + bool initialize( OSLockType type ) { + lock_c = CreateMutex( NULL, false, NULL ); + if( lock_c == NULL ) return false; + this->type = type; + return true; + } + OSLockResult lock() { + if( type == oslock_recursive ) { + return lock_l( INFINITE ); + } + return nonreentrant_lock_l( INFINITE ); + } + OSLockResult trylock() { + if( type == oslock_recursive ) { + return lock_l( 0 ); + } + return nonreentrant_lock_l( 0 ); + } + OSLockResult unlock() { + ReleaseMutex( lock_c ); + return oslock_ok; + } +}; + +class WindowsLockFactory : public OSLockFactory { +public: + OSLock *createLock( OSLockType type ) { + WindowsLock *lock = new WindowsLock(); + if( !lock->initialize( type )) { + delete lock; + lock = NULL; + } + return lock; + } +}; + +class WindowsCondition : public OSCondition { + friend class WindowsConditionFactory; +private: + SRWLOCK lock; + CONDITION_VARIABLE condition; +protected: + bool initialize() { + InitializeSRWLock( &lock ); + InitializeConditionVariable( &condition ); + return true; + } +public: + bool wait_prelock() { + AcquireSRWLockExclusive( &lock ); + up(); + return true; + } + bool wait() { + BOOL result = SleepConditionVariableSRW( &condition, &lock, INFINITE, 0 ); + bool ret = false; + if( result == TRUE ) { + down(); + ReleaseSRWLockExclusive( &lock ); + ret = true; + } + return ret; + } + bool signal() { + AcquireSRWLockExclusive( &lock ); + if( waiting() ) WakeAllConditionVariable( &condition ); + ReleaseSRWLockExclusive( &lock ); + return true; + } +}; + +class WindowsConditionFactory : public OSConditionFactory { +public: + OSCondition *createCondition() { + WindowsCondition *result = new WindowsCondition(); + return result->initialize() ? result : NULL; + } +}; + +class WindowsTimerQueue; + +struct TimerQueue_t; + +struct WindowsTimerQueueHandlerArg { + HANDLE timer_handle; + HANDLE queue_handle; + event_descriptor_t *inner_arg; + ostimerq_handler func; + int type; + bool rm; + WindowsTimerQueue *queue; + TimerQueue_t *timer_queue; +}; + +typedef std::list<WindowsTimerQueueHandlerArg *> TimerArgList_t; +struct TimerQueue_t { + TimerArgList_t arg_list; + HANDLE queue_handle; + SRWLOCK lock; +}; + + +VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore ); + +typedef std::map<int,TimerQueue_t> TimerQueueMap_t; + +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: + WindowsTimerQueue() { + InitializeSRWLock( &retiredTimersLock ); + }; +public: + 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; + } + 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; + } +}; + +VOID CALLBACK WindowsTimerQueueHandler( PVOID arg_in, BOOLEAN ignore ); + +class WindowsTimerQueueFactory : public OSTimerQueueFactory { +public: + virtual OSTimerQueue *createOSTimerQueue( IEEE1588Clock *clock ) { + WindowsTimerQueue *timerq = new WindowsTimerQueue(); + return timerq; + }; +}; + +class WindowsTimer : public OSTimer { + friend class WindowsTimerFactory; +public: + virtual unsigned long sleep( unsigned long micros ) { + Sleep( micros/1000 ); + return micros; + } +protected: + WindowsTimer() {}; +}; + +class WindowsTimerFactory : public OSTimerFactory { +public: + virtual OSTimer *createTimer() { + return new WindowsTimer(); + } +}; + +struct OSThreadArg { + OSThreadFunction func; + void *arg; + OSThreadExitCode ret; +}; + +DWORD WINAPI OSThreadCallback( LPVOID input ); + +class WindowsThread : public OSThread { + friend class WindowsThreadFactory; +private: + HANDLE thread_id; + OSThreadArg *arg_inner; +public: + 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; + } + 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: + WindowsThread() {}; +}; + +class WindowsThreadFactory : public OSThreadFactory { +public: + OSThread *createThread() { + return new WindowsThread(); + } +}; + +#define NETCLOCK_HZ_OTHER 1056000000 +#define NETCLOCK_HZ_NANO 1000000000 +#define ONE_WAY_PHY_DELAY 8000 +#define NANOSECOND_CLOCK_PART_DESCRIPTION "I217-LM" +#define NETWORK_CARD_ID_PREFIX "\\\\.\\" +#define OID_INTEL_GET_RXSTAMP 0xFF020264 +#define OID_INTEL_GET_TXSTAMP 0xFF020263 +#define OID_INTEL_GET_SYSTIM 0xFF020262 +#define OID_INTEL_SET_SYSTIM 0xFF020261 + +class WindowsTimestamper : public HWTimestamper { +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 ) { + 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 ) { + 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 ) { + 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 ) { + long double scaled_output = ((long double)tsc_hz.QuadPart)/1000000000; + scaled_output = ((long double) time)/scaled_output; + return (uint64_t) scaled_output; + } +public: + virtual bool HWTimestamper_init( InterfaceLabel *iface_label, OSNetworkInterface *net_iface ); + virtual bool HWTimestamper_gettime( Timestamp *system_time, Timestamp *device_time, uint32_t *local_clock, uint32_t *nominal_clock_rate ) + { + 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; + } + + virtual int HWTimestamper_txtimestamp( PortIdentity *identity, uint16_t sequenceId, 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 ) return -1; + if( returned != sizeof(buf_tmp) ) return -72; + tx_r = (((uint64_t)buf[1]) << 32) | buf[0]; + tx_s = scaleNativeClockToNanoseconds( tx_r ); + tx_s += ONE_WAY_PHY_DELAY; + timestamp = nanoseconds64ToTimestamp( tx_s ); + timestamp._version = version; + + return 0; + } + + virtual int HWTimestamper_rxtimestamp( PortIdentity *identity, uint16_t sequenceId, 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 -1; + if( returned != sizeof(buf_tmp) ) return -72; + packet_sequence_id = *((uint32_t *) buf+3) >> 16; + if( PLAT_ntohs( packet_sequence_id ) != sequenceId ) return -72; + rx_r = (((uint64_t)buf[1]) << 32) | buf[0]; + rx_s = scaleNativeClockToNanoseconds( rx_r ); + rx_s -= ONE_WAY_PHY_DELAY; + timestamp = nanoseconds64ToTimestamp( rx_s ); + timestamp._version = version; + + return 0; + } +}; + + + +class WindowsNamedPipeIPC : public OS_IPC { +private: + HANDLE pipe; +public: + WindowsNamedPipeIPC() { }; + ~WindowsNamedPipeIPC() { + CloseHandle( pipe ); + } + virtual bool init( OS_IPC_ARG *arg = NULL ) { + char pipename[64]; + PLAT_strncpy( pipename, PIPE_PREFIX, 63 ); + PLAT_strncpy( pipename+strlen(pipename), P802_1AS_PIPENAME, 63-strlen(pipename) ); + pipe = CreateNamedPipe( pipename, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE, PIPE_UNLIMITED_INSTANCES, + OUTSTANDING_MESSAGES*sizeof( WindowsNPipeMessage ), 0, 0, NULL ); + if( pipe == INVALID_HANDLE_VALUE ) return false; + return true; + } + 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 ) { + WindowsNPipeMessage msg( ml_phoffset, ls_phoffset, ml_freqoffset, ls_freq_offset, local_time ); + if( !msg.write( pipe )) { + CloseHandle(pipe); + return init(); + } + return true; + } +}; + +#endif diff --git a/daemons/gptp/windows/gptp.sln b/daemons/gptp/windows/gptp.sln index 267b5225..2d939e5d 100644 --- a/daemons/gptp/windows/gptp.sln +++ b/daemons/gptp/windows/gptp.sln @@ -1,36 +1,36 @@ -
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "daemon_cl", "daemon_cl\daemon_cl.vcxproj", "{590D3055-A068-4B31-B4F9-B2ACC5F93663}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_pipe_test", "named_pipe_test\named_pipe_test.vcxproj", "{303FACBB-2A44-4511-A855-2B5B2C0E3A89}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Debug|x64 = Debug|x64
- Release|Win32 = Release|Win32
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Debug|Win32.ActiveCfg = Debug|Win32
- {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Debug|Win32.Build.0 = Debug|Win32
- {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Debug|x64.ActiveCfg = Debug|x64
- {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Debug|x64.Build.0 = Debug|x64
- {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|Win32.ActiveCfg = Release|Win32
- {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|Win32.Build.0 = Release|Win32
- {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|x64.ActiveCfg = Release|x64
- {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|x64.Build.0 = Release|x64
- {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Debug|Win32.ActiveCfg = Debug|Win32
- {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Debug|Win32.Build.0 = Debug|Win32
- {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Debug|x64.ActiveCfg = Debug|x64
- {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Debug|x64.Build.0 = Debug|x64
- {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|Win32.ActiveCfg = Release|Win32
- {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|Win32.Build.0 = Release|Win32
- {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|x64.ActiveCfg = Release|x64
- {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "daemon_cl", "daemon_cl\daemon_cl.vcxproj", "{590D3055-A068-4B31-B4F9-B2ACC5F93663}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_pipe_test", "named_pipe_test\named_pipe_test.vcxproj", "{303FACBB-2A44-4511-A855-2B5B2C0E3A89}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Debug|Win32.ActiveCfg = Debug|Win32 + {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Debug|Win32.Build.0 = Debug|Win32 + {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Debug|x64.ActiveCfg = Debug|x64 + {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Debug|x64.Build.0 = Debug|x64 + {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|Win32.ActiveCfg = Release|Win32 + {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|Win32.Build.0 = Release|Win32 + {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|x64.ActiveCfg = Release|x64 + {590D3055-A068-4B31-B4F9-B2ACC5F93663}.Release|x64.Build.0 = Release|x64 + {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Debug|Win32.ActiveCfg = Debug|Win32 + {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Debug|Win32.Build.0 = Debug|Win32 + {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Debug|x64.ActiveCfg = Debug|x64 + {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Debug|x64.Build.0 = Debug|x64 + {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|Win32.ActiveCfg = Release|Win32 + {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|Win32.Build.0 = Release|Win32 + {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|x64.ActiveCfg = Release|x64 + {303FACBB-2A44-4511-A855-2B5B2C0E3A89}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/daemons/gptp/windows/named_pipe_test/ReadMe.txt b/daemons/gptp/windows/named_pipe_test/ReadMe.txt index ad4c1ba2..4ba7155b 100644 --- a/daemons/gptp/windows/named_pipe_test/ReadMe.txt +++ b/daemons/gptp/windows/named_pipe_test/ReadMe.txt @@ -1,10 +1,10 @@ -========================================================================
-(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.
+======================================================================== +(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 index 2247cba7..758a414c 100644 --- a/daemons/gptp/windows/named_pipe_test/named_pipe_test.cpp +++ b/daemons/gptp/windows/named_pipe_test/named_pipe_test.cpp @@ -1,114 +1,114 @@ -/******************************************************************************
-
- 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 "ipcdef.hpp"
-#include "tsc.hpp"
-
-#define PIPE_PREFIX "\\\\.\\pipe\\"
-#define P802_1AS_PIPENAME "gptp-update"
-#define OUTSTANDING_MESSAGES 10
-
-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 );
- WindowsNPipeMessage msg;
- HANDLE pipe;
- uint64_t tsc_frequency = getTSCFrequency( 1000 );
-
- pipe = CreateFile( pipename, GENERIC_READ, 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() );
- }
-
-
- // Wait for Ctrl-C
- if( !SetConsoleCtrlHandler( ctrl_handler, true )) {
- printf( "Unable to register Ctrl-C handler\n" );
- return -1;
- }
-
- printf( "TSC Frequency: %llu\n", tsc_frequency );
- while( msg.read( pipe ) == true && !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;
-#if 0
- printf( "Master-Local Offset = %lld\n", msg.getMasterLocalOffset() );
- printf( "Master-Local Frequency Offset = %d\n", msg.getMasterLocalFreqOffset() );
- printf( "Local-System Offset = %lld\n", msg.getLocalSystemOffset() );
- printf( "Local-System Frequency Offset = %d\n", msg.getLocalSystemFreqOffset() );
- printf( "Local Time = %llu\n", msg.getLocalTime() );
-#endif
- now_tscns = scaleTSCClockToNanoseconds( PLAT_rdtsc(), tsc_frequency );
- update_tscns = msg.getLocalTime() + msg.getLocalSystemOffset();
- update_8021as = msg.getLocalTime() - msg.getMasterLocalOffset();
- delta_tscns = (unsigned)(now_tscns - update_tscns);
- ml_ratio = -1*(((long double)msg.getMasterLocalFreqOffset())/1000000000000)+1;
- ls_ratio = -1*(((long double)msg.getLocalSystemFreqOffset())/1000000000000)+1;
- delta_8021as = (unsigned)(ml_ratio*ls_ratio*delta_tscns);
- now_8021as = update_8021as + delta_8021as;
- printf( "Time now in terms of TSC scaled to nanoseconds time: %llu\n", now_tscns );
- printf( "Last update time in terms of 802.1AS time: %llu\n", update_8021as );
- printf( "TSC delta scaled to ns: %u\n", delta_tscns );
- printf( "8021as delta scaled: %u\n", delta_8021as );
- printf( "Time now in terms of 802.1AS time: %llu\n", now_8021as );
- }
-
- printf( "Closing pipe\n" );
- CloseHandle( pipe );
-
- return 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 "ipcdef.hpp" +#include "tsc.hpp" + +#define PIPE_PREFIX "\\\\.\\pipe\\" +#define P802_1AS_PIPENAME "gptp-update" +#define OUTSTANDING_MESSAGES 10 + +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 ); + WindowsNPipeMessage msg; + HANDLE pipe; + uint64_t tsc_frequency = getTSCFrequency( 1000 ); + + pipe = CreateFile( pipename, GENERIC_READ, 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() ); + } + + + // Wait for Ctrl-C + if( !SetConsoleCtrlHandler( ctrl_handler, true )) { + printf( "Unable to register Ctrl-C handler\n" ); + return -1; + } + + printf( "TSC Frequency: %llu\n", tsc_frequency ); + while( msg.read( pipe ) == true && !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; +#if 0 + printf( "Master-Local Offset = %lld\n", msg.getMasterLocalOffset() ); + printf( "Master-Local Frequency Offset = %d\n", msg.getMasterLocalFreqOffset() ); + printf( "Local-System Offset = %lld\n", msg.getLocalSystemOffset() ); + printf( "Local-System Frequency Offset = %d\n", msg.getLocalSystemFreqOffset() ); + printf( "Local Time = %llu\n", msg.getLocalTime() ); +#endif + now_tscns = scaleTSCClockToNanoseconds( PLAT_rdtsc(), tsc_frequency ); + update_tscns = msg.getLocalTime() + msg.getLocalSystemOffset(); + update_8021as = msg.getLocalTime() - msg.getMasterLocalOffset(); + delta_tscns = (unsigned)(now_tscns - update_tscns); + ml_ratio = -1*(((long double)msg.getMasterLocalFreqOffset())/1000000000000)+1; + ls_ratio = -1*(((long double)msg.getLocalSystemFreqOffset())/1000000000000)+1; + delta_8021as = (unsigned)(ml_ratio*ls_ratio*delta_tscns); + now_8021as = update_8021as + delta_8021as; + printf( "Time now in terms of TSC scaled to nanoseconds time: %llu\n", now_tscns ); + printf( "Last update time in terms of 802.1AS time: %llu\n", update_8021as ); + printf( "TSC delta scaled to ns: %u\n", delta_tscns ); + printf( "8021as delta scaled: %u\n", delta_8021as ); + printf( "Time now in terms of 802.1AS time: %llu\n", now_8021as ); + } + + printf( "Closing pipe\n" ); + CloseHandle( pipe ); + + return 0; +} + diff --git a/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj b/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj index ca3b5ec3..59148716 100644 --- a/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj +++ b/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj @@ -1,162 +1,162 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{303FACBB-2A44-4511-A855-2B5B2C0E3A89}</ProjectGuid>
- <Keyword>Win32Proj</Keyword>
- <RootNamespace>named_pipe_test</RootNamespace>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v110</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>
- </PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(SolutionDir)\..\common;$(SolutionDir)\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>
- </PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(SolutionDir)\..\common;$(SolutionDir)\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(SolutionDir)\..\common;$(SolutionDir)\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(SolutionDir)\..\common;$(SolutionDir)\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <SubSystem>Console</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <None Include="ReadMe.txt" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="stdafx.h" />
- <ClInclude Include="targetver.h" />
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="named_pipe_test.cpp" />
- <ClCompile Include="stdafx.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
- </ClCompile>
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
+<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{303FACBB-2A44-4511-A855-2B5B2C0E3A89}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>named_pipe_test</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions> + </PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)\..\common;$(SolutionDir)\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions> + </PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)\..\common;$(SolutionDir)\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>Use</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)\..\common;$(SolutionDir)\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>Use</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)\..\common;$(SolutionDir)\daemon_cl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="stdafx.h" /> + <ClInclude Include="targetver.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="named_pipe_test.cpp" /> + <ClCompile Include="stdafx.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> + </ClCompile> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project>
\ No newline at end of file diff --git a/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.filters b/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.filters index c03b555f..6d9eabf2 100644 --- a/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.filters +++ b/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.filters @@ -1,36 +1,36 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
- </Filter>
- <Filter Include="Header Files">
- <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
- <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- </Filter>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
- <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <None Include="ReadMe.txt" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="stdafx.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="targetver.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="stdafx.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="named_pipe_test.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <None Include="ReadMe.txt" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="stdafx.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="targetver.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="stdafx.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="named_pipe_test.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.user b/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.user index 695b5c78..ace9a86a 100644 --- a/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.user +++ b/daemons/gptp/windows/named_pipe_test/named_pipe_test.vcxproj.user @@ -1,3 +1,3 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> </Project>
\ No newline at end of file diff --git a/daemons/gptp/windows/named_pipe_test/stdafx.cpp b/daemons/gptp/windows/named_pipe_test/stdafx.cpp index 26915d09..8f3984c3 100644 --- a/daemons/gptp/windows/named_pipe_test/stdafx.cpp +++ b/daemons/gptp/windows/named_pipe_test/stdafx.cpp @@ -1,8 +1,8 @@ -// 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
+// 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 index d2509e41..686c8f5b 100644 --- a/daemons/gptp/windows/named_pipe_test/stdafx.h +++ b/daemons/gptp/windows/named_pipe_test/stdafx.h @@ -1,16 +1,16 @@ -// 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
+// 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 index 90e767bf..87c0086d 100644 --- a/daemons/gptp/windows/named_pipe_test/targetver.h +++ b/daemons/gptp/windows/named_pipe_test/targetver.h @@ -1,8 +1,8 @@ -#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>
+#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/documents/Linux_Plumbers2012.pdf b/documents/Linux_Plumbers2012.pdf Binary files differindex e5c81eea..8aa5228c 100644 --- a/documents/Linux_Plumbers2012.pdf +++ b/documents/Linux_Plumbers2012.pdf diff --git a/examples/jackd-listener/Makefile b/examples/jackd-listener/Makefile index 9ca00c40..cfd29550 100644 --- a/examples/jackd-listener/Makefile +++ b/examples/jackd-listener/Makefile @@ -1,5 +1,5 @@ -CC = gcc
-LDLIBS = -std=gnu99 -lpcap -lsndfile -pthread -ljack
-
-all: jack_listener.c
- $(CC) -o jack_listener jack_listener.c $(LDLIBS) $(LDFLAGS)
+CC = gcc +LDLIBS = -std=gnu99 -lpcap -lsndfile -pthread -ljack + +all: jack_listener.c + $(CC) -o jack_listener jack_listener.c $(LDLIBS) $(LDFLAGS) diff --git a/examples/osx/avb_viewer/AVB Viewer/Brick-Icons.icns b/examples/osx/avb_viewer/AVB Viewer/Brick-Icons.icns Binary files differindex 7e866914..2c0f617f 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Brick-Icons.icns +++ b/examples/osx/avb_viewer/AVB Viewer/Brick-Icons.icns diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons128x128.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons128x128.png Binary files differindex ecd88642..7f95dbfe 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons128x128.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons128x128.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons128x128@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons128x128@2x.png Binary files differindex 24c7d49f..d1237f46 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons128x128@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons128x128@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons16x16.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons16x16.png Binary files differindex 11339d8d..a027fcd5 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons16x16.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons16x16.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons16x16@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons16x16@2x.png Binary files differindex 1c60ac82..a47600a2 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons16x16@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons16x16@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons256x256.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons256x256.png Binary files differindex 1875e51c..0354b8a6 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons256x256.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons256x256.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons256x256@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons256x256@2x.png Binary files differindex d2ec36ed..b48f1e2e 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons256x256@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons256x256@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons32x32.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons32x32.png Binary files differindex 1174f0fc..39cd1af7 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons32x32.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons32x32.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons32x32@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons32x32@2x.png Binary files differindex 87760cd9..c6f7727a 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons32x32@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons32x32@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons512x512.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons512x512.png Binary files differindex 07b94157..44f1be3f 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons512x512.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons512x512.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons512x512@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons512x512@2x.png Binary files differindex 79fa77bb..f305ef1f 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons512x512@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon-1.appiconset/Brick-Icons512x512@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons128x128.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons128x128.png Binary files differindex ecd88642..7f95dbfe 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons128x128.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons128x128.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons128x128@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons128x128@2x.png Binary files differindex 24c7d49f..d1237f46 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons128x128@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons128x128@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons16x16.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons16x16.png Binary files differindex 11339d8d..a027fcd5 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons16x16.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons16x16.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons16x16@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons16x16@2x.png Binary files differindex 1c60ac82..a47600a2 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons16x16@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons16x16@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons256x256.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons256x256.png Binary files differindex 1875e51c..0354b8a6 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons256x256.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons256x256.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons256x256@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons256x256@2x.png Binary files differindex d2ec36ed..b48f1e2e 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons256x256@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons256x256@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons32x32.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons32x32.png Binary files differindex 1174f0fc..39cd1af7 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons32x32.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons32x32.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons32x32@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons32x32@2x.png Binary files differindex 87760cd9..c6f7727a 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons32x32@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons32x32@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons512x512.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons512x512.png Binary files differindex 07b94157..44f1be3f 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons512x512.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons512x512.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons512x512@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons512x512@2x.png Binary files differindex 79fa77bb..f305ef1f 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons512x512@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/AppIcon.appiconset/Brick-Icons512x512@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_128x128.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_128x128.png Binary files differindex 52abfab7..d77229eb 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_128x128.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_128x128.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_128x128@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_128x128@2x.png Binary files differindex 085c7a25..9cea5cbd 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_128x128@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_128x128@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_16x16.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_16x16.png Binary files differindex 96326bab..d2388afa 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_16x16.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_16x16.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_16x16@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_16x16@2x.png Binary files differindex 28a7b0a0..24e92e8f 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_16x16@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_16x16@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_256x256.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_256x256.png Binary files differindex 085c7a25..9cea5cbd 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_256x256.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_256x256.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_256x256@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_256x256@2x.png Binary files differindex 71e7dd8d..c17b2622 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_256x256@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_256x256@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_32x32.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_32x32.png Binary files differindex 28a7b0a0..24e92e8f 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_32x32.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_32x32.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_32x32@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_32x32@2x.png Binary files differindex 673702d8..c925f9ff 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_32x32@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_32x32@2x.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_512x512.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_512x512.png Binary files differindex 71e7dd8d..c17b2622 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_512x512.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_512x512.png diff --git a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_512x512@2x.png b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_512x512@2x.png Binary files differindex 7c506d87..cd0a4c17 100644 --- a/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_512x512@2x.png +++ b/examples/osx/avb_viewer/AVB Viewer/Images.xcassets/xmos.iconset/icon_512x512@2x.png diff --git a/examples/osx/avb_viewer/Brick-Icons.icns b/examples/osx/avb_viewer/Brick-Icons.icns Binary files differindex 7e866914..2c0f617f 100644 --- a/examples/osx/avb_viewer/Brick-Icons.icns +++ b/examples/osx/avb_viewer/Brick-Icons.icns diff --git a/examples/simple_listener/Makefile b/examples/simple_listener/Makefile index 77378e4f..3ef67a81 100644 --- a/examples/simple_listener/Makefile +++ b/examples/simple_listener/Makefile @@ -1,10 +1,10 @@ -CC = gcc
-LDLIBS = -std=gnu99 -lpcap -lsndfile
-
-simple_listener: simple_listener.c
- $(CC) -o $@ $< $(LDLIBS) $(LDFLAGS)
-
-all: simple_listener
-
-clean:
- rm -f `find . -name "*~" -o -name "*.[oa]" -o -name "\#*\#" -o -name TAGS -o -name core -o -name "*.orig"` simple_listener
+CC = gcc +LDLIBS = -std=gnu99 -lpcap -lsndfile + +simple_listener: simple_listener.c + $(CC) -o $@ $< $(LDLIBS) $(LDFLAGS) + +all: simple_listener + +clean: + rm -f `find . -name "*~" -o -name "*.[oa]" -o -name "\#*\#" -o -name TAGS -o -name core -o -name "*.orig"` simple_listener |