<bodytext>

# Network Time Software Functional Specification

        Distribution: COMPANY CONFIDENTIAL

        Number:       2103,723/FS
        Issue:        5
        Author(s):    Jonathan Harris
                      Kevin Bracey
                      Mark Robertshaw
        Date:         29-Jan-12
        Last Issue:   4 (0.04)
        Change:       ECO 4379

## Contents

- History
- Outstanding issues
- Overview
- Technical background
- User interface
- Programmer interface
- Standards
- External dependencies

## History

        0.01 JRH 01-Apr-96 First created.
        0.02 JRH 27-Aug-96 Gets timeserver's IP address from registry.
        (1)                Connection attempts are initiated on
                           receipt of Dialler and Registry services.
                           Removed NetTime_SetTime SWI.
         2   KJB 15-Mar-00 Updated to cover developments in manual
                           configuration, DHCP, NTP, DST and clock slewing.

         3   MJR 08-Sep-00 Added SWI interface for NetTime_Status
         4   RPS 29-Jan-12 Added more useful SWI NetTime_States

## Outstanding issues

Parts of this specification which are emphasised like this are either undecided issues or are liable to change.

- It may be worthwhile supporting anycast and multicast modes of client operation to support autoconfiguration.
- For more precise timekeeping, some of the full NTP algorithms could be employed, including variable poll intervals, multiple servers and an improved Kernel clock discipline.

## Overview

Network Computers and Set-Top Boxes generally do not contain a real-time clock. It is considered desirable (for cookie-expiry among other reasons) that the NC should know the time-of-day to a reasonable accuracy. It is presumed that for security reasons any time-stamping required for file stamps, transaction logging or billing will take place at the server end and will use the server's conception of the time-of-day, so the NC's time-of-day value will be only used locally.

This documents specifies the software that provides network time synchronisation for a Network Computer (or any other RISC OS system).

## Technical background

#### Internet time protocols

Time Protocol

  This simple protocol returns the server's current time relative to 00:00 1st January 1900 UTC. Its use dates back to the beginnings of the ARPA Internet and so it is widely implemented. The protocol's resolution is 1 second. It can be used with either UDP or TCP.

Network Time Protocol (NTP)

  This protocol also returns the server's current time relative to 00:00 1st January 1900 UTC. It is accurate to between 1 and 50ms depending on the characteristics of the server and network paths and is designed to cope with "multiple gateways, highly disruptive delays and unreliable nets" between the client and server. Since the NC would be a leaf on the network it is only be necessary to implement the subset of NTP known as SNTP on the NC.

#### Time in RISC OS

The various system times are derived from a centi-second interrupt from the Timer0 hardware timer. The oscillator that supplies Timer0 is normally specified as being accurate to 100ppm; approximately 1 second every 3 hours. However in some designs, such as the DSL-4000, the timer is driven by a PLL-derived clock that is 400ppm slow; uncorrected this would lose 34 seconds a day.

Time-dependent system events (ie OS_CallEvery, OS_CallAfter) are relative to one particular system timer called the 'monotonic timer' which is incremented on every Timer0 interrupt.

RISC OS also independently maintains a 'real-time' clock for application use which holds the time-of-day. This is initialised on reset to the value held in the RTC chip (if present) combined with the configured year held in NVRAM. It is incremented on every Timer0 interrupt. The RTCAdjust module compares the soft time-of-day value with that held in the RTC chip every hour and re-programs Timer0 to compensate for any inaccuracy in its driving oscillator. This process results in the soft time-of-day being closely synchronised with the RTC chip after two hours.

The kernel has two basic subroutines for reading/writing its time-of-day from/to the RTC:

`SetTime:`
  Sets RISC OS time-of-day, the contents of the RTC and the configured year in NVRAM.
  Called by SWI OS_Word 15,xx (write time and/or date).
`RTCToRealTime:`
  Sets the soft time-of-day to the value held in the RTC combined with the value for the year held in NVRAM.
  Called on kernel initialisation. Also called by `SetTime` to reset the soft time-of-day to the RTC's new contents.

#### NC operation

Having no RTC, the NC sets the time-of-day to a default value at boot-time - either 02-Jan-1970.00:00:00, or a time stored in NVRAM by NetTime in a previous session.

The NetTime module will attempt to contact a server on boot-up, module initialisation, on receiving service Service_DiallerStatus with states 2 or 5 (ie link going up) or Service_NCRegistry with BB_STATUS_BB_VALID delta set in either boot-block, or on the command *NetTime_Kick.

The server to contact, and which protocol to use, depends on system variables and registry settings:

- If Inet$NTPServer is set, then NetTime will contact that server using NTP
- else if Inet$TimeServer is set, then NetTime will contact that server using UDP Time Protocol
- else if NetTime$Server is set, then NetTime will contact that server using NTP or UDP Time Protocol
- else if NetTime can read the tag TIME_PRIMARY from the registry, it will contact that server using NTP or UDP Time Protocol.

Inet$NTPServer and Inet$TimeServer can be set by the Internet module when DHCP booting. Variables can contain either DNS names or numeric IP addresses.

If the time server address was obtained from NetTime$Server or the registry, NetTime will first try to contact the server using NTP - if an ICMP Destination Unreachable message is returned it will try Time/UDP instead.

On receipt of a reply, NetTime will either set the system clock immediately (if the system clock is significantly different), or will accelerate or decelerate the clock by adjusting the interrupt rate from Timer0 by up to 1% to bring the clock back into line, using the same algorithm as RTCAdjust. (RTCAdjust will be disabled if present, to prevent conflict). The time received is also stored in NVRAM so a rough idea of the time is available after reboot.

It will re-contact the time server 30 minutes after a successful connection and 5 minutes after an an unsuccessful connection unless it receives service Service_DiallerStatus with states other than 2 or 5 (ie link going/gone down).

If the system time is set manually, NetTime will cease operation, until the next *NetTime_Kick or link up.

On an Ethernet LAN, using NTP, NetTime has been found to consistently keep the time accurately to within 0.06 seconds using the default 30 minute poll interval.

#### Daylight Saving Time

NetTime can set the system DST flag according to the time received from the server. Behaviour is determined by the system variable NetTime$DST, as shown below. If the current territory on module initialisation is Australia, then the NetTime$DST flag is set to "Australian".

European
  If set to "European" (the default, unless the locale is set to Australia), the European Union rule is used; DST is in force from 01:00 UTC on the last Sunday in March until 01:00 UTC on the last Sunday in October.
Australian
  If set to "Australian", then Australian DST rules are used; for more details of the rules, see the files in the "Australia" directory in the Docs.
dd-mmm-yyyy:hh:mm:ss; dd-mmm-yyyy:hh:mm:ss
  If a pair of semicolon-separated dates is supplied, DST is enabled if the time received from the server is between the two dates, otherwise it is disabled. The dates must be specified in UTC.
No
  If the system variable is set to "No" (or anything else at present), the DST flag is left untouched.

#### Time zone

NetTime can set the system timezone from DHCP. If a DHCP response is received while NetTime is active (a DHCPACK response to either a DHCPOFFER or DHCPINFORM), and it contains a Time Offset option, the RISC OS time zone will be set to the closest multiple of 15 minutes. The assumption is that the Time Offset does not include a Daylight Saving Time adjustment.

## User interface

### *Commands

### *NetTime_Kick

Initiates time server contact

#### Syntax

`*NetTime_Kick`

#### Parameters

None

#### Use

*NetTime_Kick starts NetTime operation. If NetTime is already running, then the server is polled immediately, rather than waiting for the next scheduled poll. If NetTime is not active, then it starts up - this may be necessary after setting the time server variables manually.

#### Related commands

None

#### Related SWIs

None

#### Related vectors

None

### *NetTime_Status

Displays NetTime information

#### Syntax

`*NetTime_Status`

#### Parameters

None

#### Use

*NetTime_Status shows some information about NetTime's operation, including its current state, when a time server was last contacted, and the current Timer0 rate.

#### Related commands

None

#### Related SWIs

None

#### Related vectors

None

### *NetTime_PollInterval

Change the server poll interval

#### Syntax

`*NetTime_PollInterval time`

#### Parameters

`time` | interval in seconds

#### Use

*NetTime_PollInterval sets the server polling interval, ie the time interval between periodic server contacts. The default is 1800 seconds (30 minutes). The current interval is displayed by NetTime_Status.

If the poll interval is too short, clock stability may be adversely affected, particularly if a Time/UDP server is being used. Generally, the interval should be at least one minute for NTP, 10 minutes for Time/UDP.

#### Example

`*NetTime_PollInterval 15*60`

#### Related commands

*NetTime_Status

#### Related SWIs

None

#### Related vectors

None

## Programmer interface

Related to this work, a new Kernel call to set the time to centisecond precision has been created. Previously, the Kernel real-time clock setting calls only allowed second precision.

### SWI Calls

### NetTime_Status

### (SWI &54AC0)

Displays NetTime information (equivalent to *NetTime_Status)

#### On entry

Takes no parameters

#### On exit

Returns no parameters

#### Interrupts

Interrupts are enabled
Fast interrupts are enabled

#### Processor Mode

Processor is in SVC mode

#### Re-entrancy

SWI is not re-entrant

#### Use

This call displays the current NetTime status information, however as the output text is language dependent and the number of lines varies depending on the mode of operation, this SWI should be considered deprecated - use *NetTime_States instead.

### NetTime_States

### (SWI &54AC1)

Retrieves NetTime state information

#### On entry

Takes no parameters

#### On exit

R0 = bits defining the state
R1 = time since last state, in centiseconds
R2 = time since current state, in centiseconds
R3 = time to next state, in centiseconds

#### Interrupts

Interrupts are enabled
Fast interrupts are enabled

#### Processor Mode

Processor is in SVC mode

#### Re-entrancy

SWI is not re-entrant

#### Use

This call returns the current NetTime state information. The last attempt/current state/next action are encoded with 8 bits per action as follows

  1 = time synchronised via SNTP protocol
  2 = time synchronised via Time protocol
  3 = time not synchronised with the network
  256 = idle
  257 = dormant
  258 = active
  65536 = retry
  65537 = issue new query

### OS_Word 15,5

### (SWI &07)

Writes the real-time in 5-byte format to both the CMOS clock and its soft copy

#### On entry

R0 = 15
R1 = pointer to parameter block

  R1+0 = 5 (reason code)
  R1+1 = LSB of time
  R1+2 = ...
  R1+3 = ...
  R1+4 = ...
  R1+5 = MSB of time

#### On exit

R0, R1 preserved

#### Interrupts

Interrupts are enabled
Fast interrupts are enabled

#### Processor Mode

Processor is in SVC mode

#### Re-entrancy

SWI is not re-entrant

#### Use

This call writes the real-time to both the CMOS clock and its soft copy. On entry, the parameter block contains a 5-byte UTC time.

This call is available in version 4.85 or later of the Kernel. You should not use this call, you should use Territory_SetTime instead, as that call works on all versions of RISC OS since RISC OS 3. There is no error indication from OS_Word 15 if reason code 5 isn't implemented.

Version 0.35 or later of the Territory Manager uses OS_Word 15,5 to implement Territory_SetTime instead of OS_Word 15,24. It also provides OS_Word 15,5 itself (with lower accuracy) if the Kernel doesn't.

#### Related SWIs

OS_Word 15 (page 1-423), Territory_SetTime (page 3-800)

#### Related vectors

WordV

## Standards

[RFC868]
  J.Postel & K.Harrenstein, "Time Protocol", ISI & SRI, May 1983.
[RFC1305]
  D.L.Mills, "Network Time Protocol (Version 3)", U. of Delaware, March 1992.
[RFC2131]
  R.Droms, "Dynamic Host Configuration Protocol", Bucknell University, March 1997.
[RFC2132]
  S.Alexander & R.Droms, "DHCP Options and BOOTP Vendor Extensions", Silicon Graphics, Inc. & Bucknell University, March 1997.
[RFC2030]
  D.Mills, "Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI", U. of Delaware, October 1996.

## External dependencies

NetTime requires a 4-byte NVRAM tag "SystemTime" to store a time value across reboots. This tag should not be present if an RTC is fitted.

</bodytext>