CSS-WC Message objects

Module: dvbcss.protocol.wc

The WCMessage class represents a CSS-WC protocol message.

The Candidate class represents the measurement resulting from a request-response exchange of messages with a server. This is a “candidate” that could be used to update the client’s estimate of the Wall Clock and is therefore used by a Wall Clock Client algorithm. A candidate is calculated from a WCMessage that represents a Wall Clock protocol response message received from a server.

A candidate can calculate the correlation needed to set a CorrelatedClock to model the server’s Wall Clock.

Example usage

Creating a request message at a Wall Clock Client:

>>> from dvbcss.protocol.wc import WCMessage
>>> import time

>>> t1 = time.time() * 1000000000

>>> msg = WCMessage(msgtype=WCMessage.TYPE_REQUEST, precision=-10, maxFreqError=256*50, originateNanos=t1, receiveNanos=0, transmitNanos=0)
>>> packedMessage = msg.pack()
>>> packedMessage
"\x00\x00\xf6\x00\x00\x002\x00TvH'3\xf5\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

Processing a received response message at a Wall Clock Client:

>>> from dvbcss.protocol.wc import Candidate

>>> t4 = <nanoseconds-at-which-message-was-received>
>>> msg = WCMessage.unpack(receivedData)
>>> msg.msgtype
1
>>> c = Candidate(msg, t4)
>>> c.rtt
459734573

Creating a correlation to configure a :class:``dvbcss.clock.CorrelatedClock` representing the client estimate of the server’s wall clock:

>>> corr = c.calcCorrelationFor(wallClock, localMaxFreqErrorPpm=wallClock.getRootMaxFreqError())
>>> wallClock.correlation = corr

Classes

WCMessage

class dvbcss.protocol.wc.WCMessage(msgtype, precision, maxFreqError, originateNanos, receiveNanos, transmitNanos, originalOriginate=None)[source]

Create object representing a CSS-WC wall clock request or response message.

Initialisation takes the following parameters:

Parameters:
  • msgtype (int) – Type of message. One of: TYPE_REQUEST, TYPE_RESPONSE, TYPE_RESPONSE_WITH_FOLLOWUP and TYPE_FOLLOWUP
  • precision (int) – Precision (of the server’s wall clock) encoded in log base 2 seconds between -128 and +127 inclusive.
  • maxFreqError (int) – Maximum frequency error (of the server’s wall clock) in units of 1/256ths ppm.
  • originateNanos (int) – Originate timevalue in integer number of nanoseconds
  • receiveNanos (int) – Receive timevalue in integer number of nanoseconds
  • transmitNanos (int) – Transmit timevalue in integer number of nanoseconds
  • originalOriginate (None or (int, int)) – Optional original encoding of the originate timevalue as (seconds, nanos). Overrides originateNanos if not None.

The originalOriginate parameter, if not None, overrides the originateNanos parameter.

Convert to and from a string containing the binary encoding of this message using the pack() method and unpack() class method.

msgtype[source]

(read/write int) Type of message. 0=request, 1=response, 2=response-with-followup, 3=followup

precision[source]

(read/write int) Precision encoded in log base 2 seconds between -128 and +127 inclusive. For example: -10 encodes a precision value of roughly 0.001 seconds.

maxFreqError[source]

(read/write int) Maximum frequency error in units of 1/256ths ppm. For example: 12800 encodes a max freq error of 50ppm.

originateNanos[source]

(read/write int) Originate timevalue in integer number of nanoseconds

receiveNanos[source]

(read/write int) Receive timevalue in integer number of nanosecond

transmitNanos[source]

(read/write int) Transmit timevalue in integer number of nanosecond

originalOriginate[source]

(read/write None or (int, int)) Optional original encoding of the originate timevalue as (seconds, nanos). Overrides originateNanos when the message is packed if the value is not None.

TYPE_FOLLOWUP = 3[source]

Constant: Message type 3 “follow-up response”

TYPE_REQUEST = 0[source]

Constant: Message type 0 “request”

TYPE_RESPONSE = 1[source]

Constant: Message type 1 “response with no follow-up”

TYPE_RESPONSE_WITH_FOLLOWUP = 2[source]

Constant: Message type 2 “response to be followed by a follow-up response”

copy()[source]

Duplicate this wallclock message object

classmethod encodePrecision(precisionSecs)[source]

Convert a precision value in seconds to the format used in these messages

getMaxFreqError()[source]

Get frequency error in ppm

getPrecision()[source]

Get precision value in fractions of a second

pack()[source]

Pack wall clock message into binary representation.

Returns:String containing the wall clock message in final bitstream form.
setMaxFreqError(maxFreqErrorPpm)[source]

Set freq error given a freq error represented as ppm

setPrecision(precisionSecs)[source]

Set precision value given a precision represented as factions of a second

classmethod unpack(data)[source]

Class method that takes a string containing a wall clock message and unpacks it to a WCMessage object.

Parameters:data (str) – String containing binary representation of a Wall Clock message as received from a client or server.
Returns:WCMessage object representing the wall clock message.

Candidate

class dvbcss.protocol.wc.Candidate(msg, nanosRx)[source]

This object represents a measurement “candidate” to be fed into a Wall Clock Client’s algorithm. It is calculated from a WCMessage received as a response from a Wall Clock server.

This object requires that response comes from a Wall Clock Client that measured the parent of the clock that will be used to model the wall clock locally.

Initialisation takes the following parameters:

Parameters:
  • msg (WCMessage) – Response message received from server
  • nanosRx (int) – the time, in nanoseconds, at which it was received (from the server)

Pass in a received WallClockMessage that is a response and this will represent the candidate data derived from that request-response interaction.

Populates properties of this objects with the candidate information. t1, t2, t3 and t4 represent the times of message sending and receiving as shown below:

_images/wc-request-response.png

It also calculates and provides, as properties, the round-trip time (rtt) and clock offset estimate (offset) based on this measurement.

All data is in units of nanoseconds, except for precision which is measured in seconds, and maximum frequency error which is measured in ppm.

A helper function calcCorrelationFor() makes it easy to calculate the Correlation needed to take this measurment candidate and use it to control a CorrelatedClock.

t1 = msg.originateNanos[source]

(read only) The time “t1” at which the request was sent in the request-response measurement (nanoseconds)

t2 = msg.receiveNanos[source]

(read only) The time “t2” at which the request was received in the request-response measurement (nanoseconds)

t3 = msg.transmitNanos[source]

(read only) The time “t3” at which the response was sent in the request-response measurement (nanoseconds)

t4 = nanosRx[source]

(read only) The time “t4” at which the response was received in the request-response measurement (nanoseconds)

offset = ((t3+t2)-(t4+t1))/2[source]

(read only) Server<->client clock offset (nanoseconds)

rtt = (t4-t1)-(t3-t2)[source]

(read only) Round trip time (nanoseconds)

isNanos = True[source]
precision = msg.getPrecision()[source]

(read only) The precision reported by the server in its response (units of factions of a second)

maxFreqError = msg.getMaxFreqError()[source]

(read only) The maximum frequency error reported by the server in its response (units of ppm)

msg = WCMessage[source]

(read only WCMessage) The response message from which this candidate was derived

calcCorrelationFor(clock, localMaxFreqErrorPpm=None)[source]

Calculates and returns the Correlation for a CorrelatedClock that is equivalent to this candidate.

The returned correlation can then be applied to the clock to model the time at the server. This includes the error bounds information needed to enable the clock to correctly calculate dispersion.

Parameters:
  • clockCorrelatedClock that will model the server clock. Its parent must be the one that was measured for t1 and t4 this candidate.
  • localMaxFreqErrorPpm – Optional. By defeault the getRootMaxFreqError() of the clock is used. Provide this value to override that.
Returns:

Correlation representing this candidate, and that can be used with the CorrelatedClock.

Note

The parameters of the correlation are calculated by this function as follows:

  • parentTicks = (t1’ + t4’) / 2
  • childTicks = (t2’ + t3’) / 2
  • initialError = precision + ( rtt/2 + mfeC * (t4 - t1) + mfeS * (t3 - t2) ) / 109
  • errorGrowthRate = mfeC + mfeS

Where:

  • t1, t2, t3 and t4 are in units of nanoseconds
  • t1’ and t4’ are the same as t1 and t4 but converted to ticks of the parent of the specified clock
  • t2’ and t3’ are the same as t2 and t3 but converted to ticks of the specified clock
  • mfeC is the clock’s getRootMaxFreqError(), converted from ppm to a fraction by dividing by 106
  • mfeS is the max freq error reported by the server, converted from ppm to a fraction by dividing by 106

New in version 0.4.

toTicks(clock)[source]

Returns a new Candidate object the same as this one but whose measurements have been converted to match the timescale of a clock.

Raises:NotImplementedError – This function has been deprecated.

Warning

Deprecated since version 0.4: This function has been deprecated because of the architectural change to taking taking readings from a different clock to the one that is adjusted.

Use calcCorrelationFor() instead as this will perform the necessary conversion to clock tick rate units as well as creating the correlation needed to configure that clock.