SNTP

Copyright (C) Simon Wright <simon@pushface.org>

This package is free software; you can redistribute it and/or modify it under terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License distributed with this package; see file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

This notice is placed in a UML model designed to be automatically converted into program source code units. As a special exception, if other files instantiate generics from those units, or you link those units with other files to produce an executable, those units do not by themselves cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU Public License.

This domain represents an SNTP client/server, to RFC 2030 (but only using IPv4, at version 3).

Revision: $Revision: 8a24f41a8d3e $

Contents

All classes

Class diagram for SNTP

Public Classes

Private Classes

Associations

Types

Exceptions


Public Classes

User

Context class diagram for User

Provides the interface to client applications.

The interface is written in terms of an Agent, which represents the domain, and may offer Client or Server features (or both).

Public instance operations

Close

Closes the agent.

Parameters:

The_Agent : in out Agent
Create returns Agent

Creates an agent, which may be tasked to provide Client and/or Server functionality later.

There is an associated task; the parameter 'at priority' specifies the priority at which it runs (relative to the default).

If 'errors to' is not null, error messages will be sent to it; if it is null, to ColdFrame.Project.Log_Error.

Parameters:

Using : in Port_Type
At_Priority : in Integer
Errors_To : in Logger
Obtain_Time_From

The agent is to act as a Client, requesting time from the specified host at the specified interval. When a time is received, it is reported to the specified Receiver callback, if any.

Note that, unless Receive Broadcasts Via or Provide Service has already been called, this call will prevent any later use of those calls (the implementation socket is irrevocably bound to a port assigned by the operating system).

Parameters:

The_Agent : in Agent
Host : in String
At_Interval : in Duration
Reporting_To : in Receiver
Provide_Broadcasts

The agent, which must already have been instructed to "Provide Service", is to send the current time at the specified interval to the (broadcast) address specified in "To".

Parameters:

The_Agent : in Agent
At_Interval : in Duration
To : in String
Provide_Service

The agent is to act as a Server, responding to specific requests ("Obtain Time From"), and obtaining the current time by calling the specified Provider callback (null means "use Ada.Calendar.Clock"), and identifying itself using the Reference Identifier 'with identifier' if provided (if not, a suitable default is constructed from the network address).

Parameters:

The_Agent : in Agent
Obtaining_From : in Provider
With_Identifier : in String
Receive_Broadcasts_Via

The agent is to act as a Client, receiving broadcast times. When a time is received, it is reported to the specified Receiver callback, if any.

Parameters:

The_Agent : in Agent
Reporting_To : in Receiver
Stop_Broadcasts

Stop providing broadcasts.

Parameters:

The_Agent : in Agent
Stop_Providing

Stop Server activities.

Parameters:

The_Agent : in Agent
Stop_Receiving

Stop Client activities (either actively obtaining time from a server, or receiving broadcasts).

Parameters:

The_Agent : in Agent

Private Classes

Client

Context class diagram for Client

A Client uses the Socket to obtain time values from a remote time server.

Identifying attributes

ID : Integer (autonumbering)

Normal attributes

Interval : Duration

The interval between requests.

Next_Time : Timer

Part of the state machine; holds the timeout used to manage regular polling.

Server : Sock_Addr_Type

The IP address of the server to use.

States

Initial

The Client can be started in two ways:

(a) a "start active" event initiates regular requests to the known server for update;

(b) a "start passive" event causes the Client only to wait for broadcasts, not to initiate any requests.

Requesting

This is a transitional state, which is entered for two reasons:

(a) to start cyclic requests for timestamps;

(b) to make the next cyclic request for a timestamp.

Waiting

The Client waits for updates, which can either be as a response to a specific request, or because the Server is generating cyclic broadcasts.

Events

Next_Time
Start_Active
Start_Passive

State-Event Matrix

State Entry Action(s) Event Drop-through
Next_Time Start_Active Start_Passive
Initial none can't happen Requesting Waiting none
Requesting Request
Set_Next_Time_Timeout
can't happen can't happen can't happen Waiting
Waiting none Requesting can't happen can't happen none

State Diagram

State diagram for SNTP.Client

Public class operations

Create_Active

Creates a Client, associated with the given Socket and requesting time updates from the specified host at the specified interval.

When a response is received, it is to be reported to the specified Receiver callback.

Parameters:

For_The_Socket : in Socket
Host : in String
At_Interval : in Duration
Reporting_To : in Receiver
Create_Passive

Creates a Client, associated with the given Socket and waiting passively for broadcast time updates.

When a response is received, it is to be reported to the specified Receiver callback.

Parameters:

For_The_Socket : in Socket
Reporting_To : in Receiver

Private instance operations

Cleanup, instance finalization

Called during instance deletion to disconnect from the Socket (includes unlinking).

Request

A state entry action, called to request a timestamp.

Set_Next_Time_Timeout

A state entry action, called to arrange the next request.

Associations

Server

Context class diagram for Server

A Server uses the Socket to provide time values to remote clients on request. It may optionally broadcast the time at regular intervals.

Identifying attributes

ID : Integer (autonumbering)

Normal attributes

Broadcasting_To : Sock_Addr_Type, initial value GNAT.Sockets.No_Sock_Addr

The address to which broadcasting is required.

Delaying : Timer

Holds "Time To Broadcast" events.

Identifier : Reference_Identifier

The reference identifier to be used.

Interval : Duration, initial value 0.0

The interval between broadcasts (if broadcasting is required).

Source : Provider

Called to provide a timestamp when required.

If null, Ada.Calendar.Clock is used.

States

Initial
Idle

If the Server is required to make regular broadcasts, it must be sent a Start event.

Waiting

On entry to the Waiting state, the Server sends a broadcast update and posts a "time to broadcast" event to fire after the required interval between broadcasts.

Events

Start
Stop
Time_To_Broadcast

State-Event Matrix

State Entry Action(s) Event Drop-through
Start Stop Time_To_Broadcast
Initial none can't happen can't happen can't happen Idle
Idle none Waiting can't happen can't happen none
Waiting Send_Broadcast
Post_Delay
can't happen Idle/
Cancel_Delay
Waiting none

State Diagram

State diagram for SNTP.Server

Public class operations

Create

Creates a Server, associated with the given Socket.

"Obtaining_From" is the callback Provider, to be called to obtain the current Time. If null, Ada.Calendar.Clock is used.

"With_Identifier" is the Reference Identifier to be used.

Parameters:

For_The_Socket : in Socket
Obtaining_From : in Provider
With_Identifier : in Reference_Identifier

Public instance operations

Is_Originator_Of returns Boolean

Returns True if this server was the originator of the packet 'P'.

Parameters:

P : in SNTP_Packet
Receive

Called to process a request packet from the client whose IP address is in "From".

Parameters:

P : in SNTP_Packet
From : in Sock_Addr_Type
Start_Broadcast

Send the current time at the specified interval to the (broadcast) address specified in "To".

Parameters:

To : in String
At_Interval : in Duration
Stop_Broadcast

Stops broadcasting.

Raises Use_Error if the Server wasn't actually broadcasting.

Private instance operations

Cancel_Delay

This entry action cancels the pending "Time To Broadcast" event.

Cleanup, instance finalization

Called during instance deletion to disconnect from the Socket (includes unlinking).

Post_Delay

This entry action posts a "Time To Broadcast" event to run after "Interval".

Send_Broadcast

This entry action sends a broadcast update.

Associations

Socket

Context class diagram for Socket

A Socket represents a UDP socket, which may be used in SNTP Client or Server mode, or both.

The associated task reads UDP packets from the socket, forwarding responses and broadcasts to the associated Client (if any) and requests to the associated Server (if any).

Identifying attributes

Using : Port_Type

The port number of the UDP socket.

Normal attributes

Bound : Boolean, initial value False

Indicates whether the Socket has already been bound (via 'Bind To Port').

Errors_To : Logger

Gives access to a procedure, provided by the user, to log error messages.

Report_To : Receiver, atomic

An array of pointers-to-procedure, used as a 'swing' buffer. The entry indexed by 'current receiver' holds the procedure to be called when a new Time is available.

Sock : Socket_Type

The UDP socket.

Task_Priority : Priority

Public class operations

Create returns Socket

Create a Socket using the specified port number.

Parameters:

Using : in Port_Type
At_Priority : in Priority
Errors_To : in Logger

Public instance operations

Allow_Broadcast

Allow the Socket to broadcast. "Bind To Port" must have been called.

Bind_To_Port

Bind the Socket to the port "using", as its externally-visible address.

This may be to provide service or to receive broadcast updates.

Log

Log an error message.

Parameters:

Error : in String
Post_Broadcast

Called by the associated Server to broadcast the packet "P" to the socket address "To" (the standard port is used).

Parameters:

P : in SNTP_Packet
To : in Sock_Addr_Type
Post_Request

Called by the associated Client to post the packet "P" to the server "To" (the standard port is used).

Parameters:

P : in SNTP_Packet
To : in Sock_Addr_Type
Post_Response

Used by the associated Server to post the reply "p" to the requesting client "to".

Parameters:

P : in SNTP_Packet
To : in Sock_Addr_Type
Set_Receiver

Update the Receiver that will be called when a new Time is received.

Parameters:

To : in Receiver

Private instance operations

Cleanup, instance finalization

Called when the Socket is deleted to close the UDP socket and tidy up any using Clients or Servers.

Start, entry

This entry acts as a barrier to ensure that the instance's associated task doesn't start processing until the instance is fully initialized. This includes binding the socket to a port; this will either be the port designated by 'Using' or, in the case where the first action is a call to Post Request, a port assigned by the operating system.

Teardown

Called during unit test teardown to free the 'sock' resource.

Associations

Associations

A1

The Socket may be being used to handle a single Client.

Roles

Client (0..1) Posts_Requests_Via (1) Socket

Socket (1) Receives_Responses_For (0..1) Client

A2

The Socket may be being used by a single Server.

Roles

Server (0..1) Posts_Responses_Via (1) Socket

Socket (1) Receives_Requests_For (0..1) Server

Types

Agent

The external (client) view of a Socket.

A counterpart for a ColdFrame class in or for another domain.

A counterpart for a ColdFrame class in or for another domain.

High_Res_Time

This is a time with a resolution of at least a microsecond.

Renames ColdFrame.Project.High_Resolution_Time.Time.

High_Res_Time has operations:

High_Res_Clock returns High_Res_Time

Returns the current value of the high resolution clock.

Inet_Addr_Type

Imported from GNAT.Sockets.

Logger

Logger, access-to-operation

Defines a type which gives access to a procedure, to be provided by the user to log error messages.

Parameters:

Error : in String

Port_Type

Imported from GNAT.Sockets.

Priority

Imported from System.

Provider

Supports callback when a time is needed.

Imported from SNTP_Support.

Receiver

Supports callback when a new Time has been received.

Imported from SNTP_Support.

Reference_Identifier

String of up to four characters, null- or space-padded, forming the Reference Identifier of a Server.

Renames SNTP_Support.Four_Character_String.

SNTP_Packet

The contents of an SNTP packet, see RFC 2030.

Imported from SNTP_Support.

Sock_Addr_Type

Imported from GNAT.Sockets.

Socket_Type

Imported from GNAT.Sockets.

Exceptions

Use_Error

Raised when invalid parameters are supplied to an operation, or operations are called inappropriately.