gPTP Documentation
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ieee1588.hpp
Go to the documentation of this file.
1 /******************************************************************************
2 
3  Copyright (c) 2009-2012, Intel Corporation
4  All rights reserved.
5 
6  Redistribution and use in source and binary forms, with or without
7  modification, are permitted provided that the following conditions are met:
8 
9  1. Redistributions of source code must retain the above copyright notice,
10  this list of conditions and the following disclaimer.
11 
12  2. Redistributions in binary form must reproduce the above copyright
13  notice, this list of conditions and the following disclaimer in the
14  documentation and/or other materials provided with the distribution.
15 
16  3. Neither the name of the Intel Corporation nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  POSSIBILITY OF SUCH DAMAGE.
31 
32 ******************************************************************************/
33 
34 #ifndef IEEE1588_HPP
35 #define IEEE1588_HPP
36 
39 #include <string>
40 
41 #include <stdint.h>
42 
43 #include <string.h>
44 
45 #include <stdio.h>
46 
47 #include <platform.hpp>
48 #include <ptptypes.hpp>
49 
50 #include <debugout.hpp>
51 
52 #define MAX_PORTS 32
54 #define PTP_CLOCK_IDENTITY_LENGTH 8
56 class LinkLayerAddress;
57 struct ClockQuality;
58 class PortIdentity;
59 class PTPMessageCommon;
60 class PTPMessageSync;
61 class PTPMessageAnnounce;
65 class IEEE1588Port;
66 class IEEE1588Clock;
67 class OSNetworkInterface;
68 
74 typedef enum {
75  NULL_EVENT = 0,
76  POWERUP = 5,
88 } Event;
89 
93 typedef struct {
97 
102  public:
103  virtual ~ InterfaceLabel() {
104  };
105 };
106 
112  private:
113  uint8_t id[PTP_CLOCK_IDENTITY_LENGTH];
114  public:
119  memset( id, 0, PTP_CLOCK_IDENTITY_LENGTH );
120  }
121 
126  ClockIdentity( uint8_t *id ) {
127  set(id);
128  }
129 
135  bool operator==(const ClockIdentity & cmp) const {
136  return memcmp(this->id, cmp.id,
137  PTP_CLOCK_IDENTITY_LENGTH) == 0 ? true : false;
138  }
139 
145  bool operator!=( const ClockIdentity &cmp ) const {
146  return memcmp( this->id, cmp.id, PTP_CLOCK_IDENTITY_LENGTH ) != 0 ? true : false;
147  }
148 
154  bool operator<(const ClockIdentity & cmp)const {
155  return memcmp(this->id, cmp.id,
156  PTP_CLOCK_IDENTITY_LENGTH) < 0 ? true : false;
157  }
158 
164  bool operator>(const ClockIdentity & cmp)const {
165  return memcmp(this->id, cmp.id,
166  PTP_CLOCK_IDENTITY_LENGTH) > 0 ? true : false;
167  }
168 
173  std::string getIdentityString();
174 
180  void getIdentityString(uint8_t *id) {
181  memcpy(id, this->id, PTP_CLOCK_IDENTITY_LENGTH);
182  }
183 
189  void set(uint8_t * id) {
190  memcpy(this->id, id, PTP_CLOCK_IDENTITY_LENGTH);
191  }
192 
200  void set(LinkLayerAddress * address);
201 
208  void print(const char *str) {
209  XPTPD_INFO
210  ( "Clock Identity(%s): %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx\n",
211  str, id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7] );
212  }
213 };
214 
215 #define INVALID_TIMESTAMP_VERSION 0xFF
216 #define MAX_NANOSECONDS 1000000000
217 #define MAX_TIMESTAMP_STRLEN 28
222 class Timestamp {
223 private:
224  char output_string[MAX_TIMESTAMP_STRLEN];
225 public:
233  Timestamp
234  (uint32_t ns, uint32_t s_l, uint16_t s_m,
235  uint8_t ver = INVALID_TIMESTAMP_VERSION) {
236  nanoseconds = ns;
237  seconds_ls = s_l;
238  seconds_ms = s_m;
239  _version = ver;
240  }
241  /*
242  * Default constructor. Initializes
243  * the private parameters
244  */
245  Timestamp() {
246  output_string[0] = '\0';
247  }
248  uint32_t nanoseconds;
249  uint32_t seconds_ls;
250  uint16_t seconds_ms;
251  uint8_t _version;
252 
258  char *toString() {
260  ( output_string, 28, "%hu %u %u", seconds_ms, seconds_ls
261  ,
262  nanoseconds );
263  return output_string;
264  }
265 
272  uint32_t nanoseconds;
273  uint32_t seconds_ls;
274  uint16_t seconds_ms;
275  uint8_t version;
276  bool carry;
277 
278  nanoseconds = this->nanoseconds;
279  nanoseconds += o.nanoseconds;
280  carry =
281  nanoseconds < this->nanoseconds ||
282  nanoseconds >= MAX_NANOSECONDS ? true : false;
283  nanoseconds -= carry ? MAX_NANOSECONDS : 0;
284 
285  seconds_ls = this->seconds_ls;
286  seconds_ls += o.seconds_ls;
287  seconds_ls += carry ? 1 : 0;
288  carry = seconds_ls < this->seconds_ls ? true : false;
289 
290  seconds_ms = this->seconds_ms;
291  seconds_ms += o.seconds_ms;
292  seconds_ms += carry ? 1 : 0;
293  carry = seconds_ms < this->seconds_ms ? true : false;
294 
295  version = this->_version == o._version ? this->_version :
297  return Timestamp( nanoseconds, seconds_ls, seconds_ms, version );
298  }
299 
306  uint32_t nanoseconds;
307  uint32_t seconds_ls;
308  uint16_t seconds_ms;
309  uint8_t version;
310  bool carry, borrow_this;
311  unsigned borrow_total = 0;
312 
313  borrow_this = this->nanoseconds < o.nanoseconds;
314  nanoseconds =
315  ((borrow_this ? MAX_NANOSECONDS : 0) + this->nanoseconds) -
316  o.nanoseconds;
317  carry = nanoseconds > MAX_NANOSECONDS;
318  nanoseconds -= carry ? MAX_NANOSECONDS : 0;
319  borrow_total += borrow_this ? 1 : 0;
320 
321  seconds_ls = carry ? 1 : 0;
322  seconds_ls += this->seconds_ls;
323  borrow_this =
324  borrow_total > seconds_ls ||
325  seconds_ls - borrow_total < o.seconds_ls;
326  seconds_ls =
327  borrow_this ? seconds_ls - o.seconds_ls + (uint32_t)-1 :
328  (seconds_ls - borrow_total) - o.seconds_ls;
329  borrow_total = borrow_this ? borrow_total + 1 : 0;
330 
331  seconds_ms = carry ? 1 : 0;
332  seconds_ms += this->seconds_ms;
333  borrow_this =
334  borrow_total > seconds_ms ||
335  seconds_ms - borrow_total < o.seconds_ms;
336  seconds_ms =
337  borrow_this ? seconds_ms - o.seconds_ms + (uint32_t)-1 :
338  (seconds_ms - borrow_total) - o.seconds_ms;
339  borrow_total = borrow_this ? borrow_total + 1 : 0;
340 
341  version = this->_version == o._version ? this->_version :
343  return Timestamp( nanoseconds, seconds_ls, seconds_ms, version );
344  }
345 
351  void set64( uint64_t value ) {
352  nanoseconds = value % 1000000000;
353  seconds_ls = (uint32_t) (value / 1000000000);
354  seconds_ms = (uint16_t)((value / 1000000000) >> 32);
355  }
356 };
357 
358 #define INVALID_TIMESTAMP (Timestamp( 0xC0000000, 0, 0 ))
359 #define PDELAY_PENDING_TIMESTAMP (Timestamp( 0xC0000001, 0, 0 ))
361 #define TIMESTAMP_TO_NS(ts) (((static_cast<long long int>((ts).seconds_ms) \
362  << sizeof((ts).seconds_ls)*8) + \
363  (ts).seconds_ls)*1000000000LL + (ts).nanoseconds)
370 static inline uint64_t byte_swap64(uint64_t in)
371 {
372  uint8_t *s = (uint8_t *) & in;
373  uint8_t *e = s + 7;
374  while (e > s) {
375  uint8_t t;
376  t = *s;
377  *s = *e;
378  *e = t;
379  ++s;
380  --e;
381  }
382  return in;
383 }
384 
385 #define NS_PER_SECOND 1000000000
386 #define LS_SEC_MAX 0xFFFFFFFFull
394 static inline void TIMESTAMP_SUB_NS( Timestamp &ts, uint64_t ns ) {
395  uint64_t secs = (uint64_t)ts.seconds_ls | ((uint64_t)ts.seconds_ms) << 32;
396  uint64_t nanos = (uint64_t)ts.nanoseconds;
397 
398  secs -= ns / NS_PER_SECOND;
399  ns = ns % NS_PER_SECOND;
400 
401  if(ns > nanos)
402  { //borrow
403  nanos += NS_PER_SECOND;
404  --secs;
405  }
406 
407  nanos -= ns;
408 
409  ts.seconds_ms = (uint16_t)(secs >> 32);
410  ts.seconds_ls = (uint32_t)(secs & LS_SEC_MAX);
411  ts.nanoseconds = (uint32_t)nanos;
412 }
413 
420 static inline void TIMESTAMP_ADD_NS( Timestamp &ts, uint64_t ns ) {
421  uint64_t secs = (uint64_t)ts.seconds_ls | ((uint64_t)ts.seconds_ms) << 32;
422  uint64_t nanos = (uint64_t)ts.nanoseconds;
423 
424  secs += ns / NS_PER_SECOND;
425  nanos += ns % NS_PER_SECOND;
426 
427  if(nanos > NS_PER_SECOND)
428  { //carry
429  nanos -= NS_PER_SECOND;
430  ++secs;
431  }
432 
433  ts.seconds_ms = (uint16_t)(secs >> 32);
434  ts.seconds_ls = (uint32_t)(secs & LS_SEC_MAX);
435  ts.nanoseconds = (uint32_t)nanos;
436 }
437 
438 #define HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE 4096
443 class HWTimestamper {
444 protected:
445  uint8_t version;
446 public:
453  virtual bool HWTimestamper_init
454  ( InterfaceLabel *iface_label, OSNetworkInterface *iface )
455  { return true; }
461  virtual void HWTimestamper_final(void) {
462  }
469  virtual bool HWTimestamper_adjclockrate( float frequency_offset )
470  { return false; }
477  virtual bool HWTimestamper_adjclockphase( int64_t phase_adjust )
478  { return false; }
493  virtual bool HWTimestamper_gettime(Timestamp * system_time,
494  Timestamp * device_time,
495  uint32_t * local_clock,
496  uint32_t * nominal_clock_rate) = 0;
497 
507  virtual int HWTimestamper_txtimestamp(PortIdentity * identity,
508  uint16_t sequenceId,
509  Timestamp & timestamp,
510  unsigned &clock_value,
511  bool last) = 0;
512 
522  virtual int HWTimestamper_rxtimestamp(PortIdentity * identity,
523  uint16_t sequenceId,
524  Timestamp & timestamp,
525  unsigned &clock_value,
526  bool last) = 0;
527 
537  virtual bool HWTimestamper_get_extclk_offset(Timestamp * local_time,
538  int64_t * clk_offset,
539  int32_t *
540  ppt_freq_offset) {
541  return false;
542  }
543 
550  virtual void HWTimestamper_get_extderror(char *msg) {
551  *msg = '\0';
552  }
553 
558  virtual bool HWTimestamper_PPS_start() { return false; };
559 
564  virtual bool HWTimestamper_PPS_stop() { return true; };
565 
570  int getVersion() {
571  return version;
572  }
573 
577  HWTimestamper() { version = 0; }
578 
579  /*Deletes HWtimestamper object
580  */
581  virtual ~HWTimestamper() { }
582 };
583 
592 PTPMessageCommon *buildPTPMessage(char *buf, int size,
593  LinkLayerAddress * remote,
594  IEEE1588Port * port);
595 
596 #endif
Power Up. Initialize state machines.
Definition: ieee1588.hpp:76
Pdelay response message timeout.
Definition: ieee1588.hpp:87
Definition: avbts_message.hpp:542
void set64(uint64_t value)
Sets a 64bit value to the object's timestamp.
Definition: ieee1588.hpp:351
Definition: ieee1588.hpp:101
Definition: ieee1588.hpp:445
Definition: avbts_message.hpp:434
PDELAY interval expired. Its time to send pdelay_req message.
Definition: ieee1588.hpp:80
void getIdentityString(uint8_t *id)
Gets the identity string from the ClockIdentity object.
Definition: ieee1588.hpp:180
#define PLAT_snprintf(...)
Definition: linux/src/platform.hpp:42
PTPMessageCommon * buildPTPMessage(char *buf, int size, LinkLayerAddress *remote, IEEE1588Port *port)
Builds a PTP message.
Definition: avbts_message.hpp:839
#define MAX_TIMESTAMP_STRLEN
Definition: ieee1588.hpp:217
Announce receipt timeout. Same as SYNC_RECEIPT_TIMEOUT_EXPIRES.
Definition: ieee1588.hpp:83
ClockIdentity()
Definition: ieee1588.hpp:118
Same as POWERUP.
Definition: ieee1588.hpp:77
Definition: avbts_port.hpp:76
#define XPTPD_INFO(fmt,...)
Definition: debugout.hpp:45
#define INVALID_TIMESTAMP_VERSION
Definition: ieee1588.hpp:215
bool operator>(const ClockIdentity &cmp) const
Implements the operator '>' overloading method.
Definition: ieee1588.hpp:164
ClockIdentity(uint8_t *id)
Constructs the object and sets its ID.
Definition: ieee1588.hpp:126
Definition: avbts_clock.hpp:77
Definition: ieee1588.hpp:93
Definition: ieee1588.hpp:111
Event
Definition: ieee1588.hpp:74
A fault was detected.
Definition: ieee1588.hpp:85
#define PTP_CLOCK_IDENTITY_LENGTH
Definition: ieee1588.hpp:54
uint8_t _version
8 bit version value
Definition: ieee1588.hpp:251
#define LS_SEC_MAX
Definition: ieee1588.hpp:388
Timestamp operator-(const Timestamp &o)
Implements the operator '-' overloading method.
Definition: ieee1588.hpp:305
Definition: avbts_message.hpp:770
Null Event. Used to initialize events.
Definition: ieee1588.hpp:75
#define NS_PER_SECOND
Definition: ieee1588.hpp:387
Definition: avbts_message.hpp:167
bool operator<(const ClockIdentity &cmp) const
Implements the operator '<' overloading method.
Definition: ieee1588.hpp:154
Definition: avbts_clock.hpp:58
Sync interval expired. Its time to send a sync message.
Definition: ieee1588.hpp:79
void print(const char *str)
This method is only enabled at compiling time. When enabled, it prints on the stderr output the clock...
Definition: ieee1588.hpp:208
Definition: avbts_osnet.hpp:52
bool operator!=(const ClockIdentity &cmp) const
Implements the operator '!=' overloading method.
Definition: ieee1588.hpp:145
Announce interval timout. Its time to send an announce message if asCapable is true.
Definition: ieee1588.hpp:84
std::string getIdentityString()
Gets the identity string from the ClockIdentity object.
uint16_t seconds_ms
32 bit seconds MSB value
Definition: ieee1588.hpp:250
Definition: avbts_osnet.hpp:277
Definition: avbts_port.hpp:207
bool operator==(const ClockIdentity &cmp) const
Implements the operator '==' overloading method.
Definition: ieee1588.hpp:135
Signalizes that something has changed. Recalculates best master.
Definition: ieee1588.hpp:78
Sync receipt timeout. Restart timers and take actions based on port's state.
Definition: ieee1588.hpp:81
Timestamp operator+(const Timestamp &o)
Implements the operator '+' overloading method.
Definition: ieee1588.hpp:271
Event event
Event enumeration.
Definition: ieee1588.hpp:95
#define MAX_NANOSECONDS
Definition: ieee1588.hpp:216
char * toString()
Copies the timestamp to the internal string in the following format: seconds_ms seconds_ls nanosecond...
Definition: ieee1588.hpp:258
Qualification timeout. Event not currently used.
Definition: ieee1588.hpp:82
Defers pdelay processing.
Definition: ieee1588.hpp:86
Definition: avbts_message.hpp:721
uint32_t seconds_ls
32 bit seconds LSB value
Definition: ieee1588.hpp:249
IEEE1588Port * port
IEEE 1588 Port.
Definition: ieee1588.hpp:94
Definition: ieee1588.hpp:222
void set(uint8_t *id)
Set the clock id to the object.
Definition: ieee1588.hpp:189
uint32_t nanoseconds
32 bit nanoseconds value
Definition: ieee1588.hpp:248