Dialler Module Functional Specification
***************************************

--------------------------------------------------------------------------------

	Distribution:	Company Confidential.
	Document ref:	2108,805/FS
	Project:	
	Revision:	0.08
	Date:		1998-02-17
	Authors:	Kevin Bracey
			D N Walker
			Ben Laughton

--------------------------------------------------------------------------------

Contents
========

	1.0 	Overview.
	2.0 	Outstanding issues.
	3.0	Technical background.
	4.0	User interface.
	5.0	Programmer interface.
	6.0	External dependencies.
	7.0	Product organisation.
	8.0	History.


--------------------------------------------------------------------------------

1.0 Overview
============

The Dialler module provides a mechanism for establishing, maintaining
and terminating a modem link.  It supports both the old serial interface
(using blockdrivers) and the new DeviceFS serial interface.

--------------------------------------------------------------------------------

2.0 Outstanding issues
======================

None.

--------------------------------------------------------------------------------

3.0 Technical background
========================

The Dialler's script handling is derived from the Unix 'chat' program. 

The Dialler only supports one connection at a time (although this may be on any
serial device for which there is a blockdriver / device driver), and only one
active client on that connection.

The original Dialler's SWI chunk and service call number clashed with
another module, NCDial.  A variant of the Dialler module called DiallerB
was produced for the Daytona project, which has a different SWI chunk
and service call number, and this is now the preferred variant of the
Dialler to use.

--------------------------------------------------------------------------------

4.0 User interface
==================

4.1 Scripts
-----------

4.1.1 The basics
~~~~~~~~~~~~~~~~
The Dialler establishes and drops connections using scripts.  These scripts
comprise  mainly of pairs of strings: one to expect and one to send eg.

"" ATZ
OK ATC1&C1&D1&K3
OK ATDT9258666
ogin: fred
ssword: jim
rotocol: PPP

4.1.2 Special commands
~~~~~~~~~~~~~~~~~~~~~~
There are a number of special commands that can be used in a script:

TIMEOUT <time in seconds>
+++++++++++++++++++++++++
Set the maximum length of time to wait for strings to be sent / received.  If a
string cannot be sent or has not been received within that time then the Dialler
will abort the script and drop the line.  The initial timeout value is 45
seconds.

ABORT <abort string>
++++++++++++++++++++
The Dialler will abort the script and drop the line if the <abort string> is
received. 

REPORT <report string>
++++++++++++++++++++++
If <report string> is received from the modem then the Dialler copies <report
string>, and all characters after <report string> up to the next control
character, into the Dialler's status string.  This status string can be read by
a call to SWI Dialler_Status.  A typical use of this would be to report the
connection speed: eg. REPORT CONNECT if the modem connected to the remote host
at 28800bps the following string would be copied into the status string: CONNECT
28800

STATUS <status string>
++++++++++++++++++++++
<status string> is immediately copied into the Dialler's status string, which
may be read by calling SWI Dialler_Status.  This can be used to monitor the
general progress of a script.

CONNECTION_TIMEOUT <time in seconds>
++++++++++++++++++++++++++++++++++++
Set the maximum time connection can be idle for before Dialler drops the line. 
This timeout takes effect once the script is successfully completed.  Clients
may alter this timeout by calling SWI Dialler_Timeout, and can reset it to
prevent the line being dropped (typically when the send or receive data) by
calling SWI Dialler_ResetCounter.

DEFAULT '<variable> <value>'
++++++++++++++++++++++++++++
If the system variable <variable> does not exist then set it to <value>.

*Commands
+++++++++
If an expect string starts with * then the whole line will be treated as a
*command which will be passed to the CLI for execution.  If the command contains
white space then it must be enclosed in single quotes.  This facility MUST not
be used to invoke other programs eg. *route. eg. '*Unset
Dialler$Dial$UserPassword'

4.1.3 System variables
~~~~~~~~~~~~~~~~~~~~~~
Each line of a script is processed by OS_GSTrans before the Dialler executes it
so that system variables can be used in Dialler scripts.

4.1.4 Escape sequences
~~~~~~~~~~~~~~~~~~~~~~
The expect and reply strings may contain escape sequences.  All of the sequences
are legal in the reply  string.  Many are legal in the expect.  Those which are
not valid in the expect sequence are so indicated.

''	Expects or sends a null string. If you send a null string then it will
	still send the return character.  This sequence may either be a pair of
	apostrophe or quote characters.

\b	represents a backspace character.

\c	Suppresses the newline at the end of the reply string. This is the only
	method to send a string without a trailing return character. It must be
	at the end of the send string. For example, the sequence hello\c will
	simply send the characters h, e, l, l, o. (not valid in expect.)

\d	Delay for one second. The program uses a non-multitasking sleep which
	will delay to a maximum of one second. (not valid in expect.)

\n	Send a newline or linefeed character.

\N	Send a null character. The same sequence may be represented by \0. (not
	valid in expect.)

\p	Pause for a fraction of a second. The delay is 1/10th of a second. (not
	valid in expect.)

\r	Send or expect a carriage return.

\s	Represents a space character in the string. This may be used when it is
	not desirable to quote the strings which contains spaces. The sequence
	'HI TIM' and HI\sTIM are the same.

\t	Send or expect a tab character.

\\	Send or expect a backslash character.

\ddd	Collapse the octal digits (ddd) into a single ASCII character and send
	that character. (some characters are not valid in expect.)

^C	Substitute the sequence with the control character represented by C.
	For example, the character DC1 (17) is shown as ^Q.  (some characters
	are not valid in expect.)

--------------------------------------------------------------------------------



5.0 Programmer interface
========================

5.1 SWIs
--------

5.1.1 Dialler_Register  (SWI &4C6C5)
      DiallerB_Register (SWI &50C85)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On entry
	None

On exit
	R0 = pointer to status word (can be used as poll word by WIMP tasks)
	All other registers preserved

Interrupts
	Interrupt status is unaltered
	Fast interrupt status is unaltered

Processor Mode
	Processor is in SVC mode

Re-entrancy
	Not defined

Use
	Any application or module that uses the Dialler must call this SWI to
	register with the Dialler so that the client can obtain the address of a
	status word (which can be used as a pollword by WIMP tasks) through
	which the Dialler can communicate with it.

	NB. The use of the pointer to the status word as a Wimp pollword is now
	deprecated; any new tasks written to use the Dialler *MUST NOT* use it
	as such.

Related SWIs
	None

Related vectors
	None

5.1.2 Dialler_Arbitrate  (SWI &4C6C6)
      DiallerB_Arbitrate (SWI &50C86)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On entry
	R0 = Reason code

On exit
	R0 = Result code (access granted / denied)
	If access granted
		R1 = serial input stream file handle (0 for blockdriver)
		R2 = serial output stream file handle (0 for blockdriver)
		R3 = pointer to blockdriver used by Dialler (0 for dual serial)
	If access denied
		R1 = undefined
		R2 = undefined
		R3 = undefined
	All other registers preserved

Interrupts
	Interrupt status is unaltered
	Fast interrupt status is unaltered

Processor Mode
	Processor is in SVC mode

Re-entrancy
	Not defined

Use
	This call is used by clients of the Dialler to request or relinquish
	access rights to the serial port, depending on the reason code in R0:

	Value	Meaning
	0	Request access
	1	Relinquish access

	The result returned by this call only have meaning if access was being
	requested. R0 contains a result code indicating whether the request was
	successful or not; this value is different for Blockdriver and Dual
	Serial versions of the module.

	Blockdriver version
	Value	Meaning
	1	Access granted
	64	Access denied (another client is active)
	65	Access denied (not connected)

	Dual Serial version
	Value	Meaning
	0	Access granted
	64	Access denied (another client is active)
	65	Access denied (not connected)

Related SWIs
	None

Related vectors
	None

5.1.3 Dialler_Dial  (SWI &4C6C0)
      DiallerB_Dial (SWI &50C80)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On entry
	Blockdriver version
	+++++++++++++++++++
	R0 = flags word (see below)
	R1 = pointer to blockdriver in RMA or filename of blockdriver
	     (use previous if 0)
	R2 = pointer to dial script or filename of dial script
	     (use previous if 0)
	R3 = pointer to hangup script or filename of hangup script
	     (use previous if 0)
	R4 = serial speed in bps (use previous if 0)
	If bit 4 R0 set
		R5 = port number

	Dual Serial version
	+++++++++++++++++++
	R0 = flags word (see below)
	R1 = pointer to name of serial device (use previous if 0)
	R2 = pointer to dial script or filename of dial script
	     (use previous if 0)
	R3 = pointer to hangup script or filename of hangup script
	     (use previous if 0)
	R4 = serial speed in bps (use previous if 0).
	If bit 0 R0 set
		R5 = serial input file handle
		R6 = serial output file handle

On exit
	All registers preserved
  
Interrupts
	Interrupt status is unaltered
	Fast interrupt status is unaltered

Processor Mode
	Processor is in SVC mode

Re-entrancy
	Not defined

Use
	This call starts a multitasking dial using the serial device pointed to
	by R1 (see below).
	
	The scripts may either be in memory or in a file depending on the flags
	word in R0.  Scripts may either be copied into the Dialler's workspace
	before execution or can be executed 'in-situ' - from a client's
	workspace or from a file.  If a script is in an application's workspace
	then it *must* be copied into the Dialler's workspace; it *cannot* be
	executed in-situ as the application may be paged out while the Dialler
	is trying to read the script.
	
	The speed at which the computer and modem should communicate (in bps) is
	in R4; split baud rate is not supported. The Dialler relies on the
	serial device to check if the speed is valid, so the caller should try
	to ensure that a valid speed is given.
	
	If any of the parameters (except the flags word) are 0 then the previous
	setting for that parameter will be used. If there is no previous setting
	then an error will be returned. Note that the Dialler does not remember
	the settings on a per-client basis, so a particular client should not
	rely on the settings being the same as when it last called the Dialler. 

	Blockdriver version

	The flags word in R0 is:
	Bit	Meaning when set
	0	R1 points to a loaded blockdriver, else to a filename
	1	R2 points to a script, else to the filename of a script
	2	R3 points to a script, else to the filename of a script
	3	scripts pointed to by R2 and R3 can be used in-situ
	4	R5 contains port number
	5 - 30	reserved, must be 0
	31	Do not perform a DTR reset on the modem before executing a
		Dial or Answer script.

	If R1 points to a blockdriver in memory then that blockdriver must be in
	the RMA. The blockdriver cannot be in application space because it could
	be paged out when the Dialler tried to use it. Also it cannot be in a
	dynamic area because it is executable code. If R1 points to the name of
	a blockdriver then the Dialler will try to load that blockdriver from
	!SerialDev.

	If bit 4 of the flags word is set then R5 contains the port number to
	use.  If bit 4 is unset then port 0 is used by default.

	Dual serial version

	Bit	Meaning when set
	0	R5 and R6 contain serial port input and output file handles
		respectively 
	1	R2 points to a script, else to the filename of a script
	2	R3 points to a script, else to the filename of a script
	3	scripts pointed to by R2 and R3 can be used in-situ
	4 - 30	reserved, must be 0
	31	Do not perform a DTR reset on the modem before executing a
		Dial or Answer script.

	R1 points to the full name of the serial device to use.

Related SWIs
	Dialler_Configure

Related vectors
	None

Examples
	Blockdriver version
	SYS"Dialler_Dial",0,"InternalPC","<Dialler$DialScript>","HangUp",115200

	Dual Serial version
	SYS"Dialler_Dial",0,"serial1:","<Dialler$DialScript>","HangUp",115200

5.1.4 Dialler_HangUp  (SWI &4C6C1)
      DiallerB_HangUp (SWI &50C81)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On entry
	R0 = flags word (must be 0)

On exit
	All registers preserved

Interrupts
	Interrupt status is unaltered
	Fast interrupt status is unaltered

Processor Mode
	Processor is in SVC mode

Re-entrancy
	Not defined

Use
	This call attempts to hang up the modem using the last-specified hangup
	script.

Related SWIs
	None

Related vectors
	None

5.1.5 Dialler_Status  (SWI &4C6C2)
      DiallerB_Status (SWI &50C82)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On entry
	R0 = reason code
	If R0 = 2
		R1 = pointer to buffer to hold status string or 0 to read
		     required size
		R2 = length of buffer or unused (if R1 = 0)

On exit
	R0 = current status
	If R0 = 1
		R1 = monotonic connection time in centiseconds
	If R0 = 2
		R2 = length of string written into buffer excluding terminating
		     0 or size of buffer required (if R1 = 0 on entry) 
	All other registers preserved
  
Interrupts
	Interrupt status is unaltered
	Fast interrupt status is unaltered

Processor Mode
	Processor is in SVC mode

Re-entrancy
	Not defined

Use
	This call is used to determine the state of the Dialler and information
	about the connection.  A status word is always returned (see below) and
	further information may be obtained according to a reason code in R0:
	Value	Meaning
	1	Return monotonic time (centiseconds) at which connection was 
		established
	2	Write 'report' string into buffer or find required size of
		buffer to store report string.

	The status word returned in R0 is divided as follows:

	+----------------+--------+--------+
	| 2 bytes        | 1 byte | 1 byte |
	+----------------+--------+--------+
	31                                0

	The two most significant bytes store a reason code in the form of a
	bit-field, to give a broad indication of why the status change has
	occurred.  The current reason codes are:
	Bit	Meaning when set
	16	Dialler's (internal) state has changed
	17	Line has dropped
	18	Status string has changed


	The third byte (bits 8-15) stores a sub-reason code, again in bit-field
	form, to give a more specific indication of the status:
	Bit 8	Bit 9	Connected / disconnected flags
	0	0	Disconnected
	0	1	Connection state changing
	1	0	Connected (outgoing) (ie. dial script has completed)
	1	1	Connected (incoming)

	Bit 10	If set, Dialler wants active client to become inactive

	Bit 11	Line dropped flag
	0	Line dropped by Dialler
	1	Line dropped by 'other end'

	The fourth byte stores a value
	Value	Meaning
	0	Idle 
	1	Executing dial script
	2	Executing hangup script
	3	Executing answer script
	4	Script aborted due to syntax error
	5	Script aborted due to timeout
	6	Script aborted because Dialler received 'NO CARRIER'
	7	Script aborted because Dialler received 'ERROR'
	8	Script aborted because Dialler received 'NO DIALTONE'
	9	Script aborted because Dialler received 'BUSY'
	10	Script aborted because Dialler received 'NO ANSWER'
	11	Script aborted because Dialler received user-defined abort
		string

	No retries are attempted by the Dialler module - this is the job of the
	Dialler module's caller on receipt of the Error status report.
	
	It is often necessary to use combinations of status bits.  eg. SWI
	Dialler_Dial should only be called if the Dialler is not connected AND
	the Dialler is not currently executing the dial script.

Related SWIs
	None

Related vectors
	None

5.1.6 Dialler_Answering  (SWI &4C6C3)
      DiallerB_Answering (SWI &50C83)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On entry
	Blockdriver version
	+++++++++++++++++++
	R0 = flags word
	R1 = pointer to blockdriver in RMA or filename of blockdriver
	     (0 means use current)
	R2 = pointer to script or filename of script for answering
	     (0 means use current)
	R3 = pointer to script or filename of script for hanging up
	     (0 means use current)
	R4 = serial speed in bps (0 means use current)
	R5 = reason code

	Dual Serial version
	+++++++++++++++++++
	R0 = flags word
	R1 = pointer to name of serial device to use (0 means use current)
	R2 = pointer to script or filename of script for answering
	     (0 means use current)
	R3 = pointer to script or filename of script for hanging up
	     (0 means use current)
	R4 = serial speed in bps (0 means use current)
	R5 = reason code


On exit
	Blockdriver version
	+++++++++++++++++++
	R5 = previous state of answering

	Dual Serial version
	+++++++++++++++++++
	R5 = previous state of answering

Use
	This call enables or disables the dialler's answering facility.  While
	enabled all input from the relevant device will be swallowed except when
	the link is in the connected state.
	
	On entry R0 is a flags word which determines the interpretation of the
	other input registers:
	Blockdriver version

	Bit	Meaning
	0	If set R1 points to a loaded blockdriver, else to a filename
	1	If set R2 points to a script, else to the filename of a script
	2	If set R3 points to a script, else to the filename of a script
	3	If set scripts pointed to by R2 and R3 can be used in-situ
	4-31	Reserved (must be 0)

	Dual Serial version
	0	Reserved (must be 0)
	1	If set R2 points to a script, else to the filename of a script
	2	If set R3 points to a script, else to the filename of a script
	3	If set scripts pointed to by R2 and R3 can be used in-situ
	4-31	Reserved (must be 0)

	If R1 points to a blockdriver in memory then that blockdriver must be in
	the RMA.  The blockdriver cannot be in application space because it
	could be paged out when the Dialler tried to use it.  Also it cannot be
	in a dynamic area because it is executable code.  If R1 points to the
	name of a blockdriver then the Dialler will try to load that blockdriver
	from !SerialDev.

	If R2 or R3 is a pointer to a script in memory then the script must be
	in RMA or in a dynamic area.

	R5 is a reason code with the following possible values:
	Value	Meaning
	 0	disable answering
	 1	enable answering
	-1	don't change

Related SWIs
	Dialler_Configure

Related vectors
	None

5.1.7 Dialler_Configure  (SWI &4C6C4)
      DiallerB_Configure (SWI &50C84)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On entry
	Blockdriver version
	+++++++++++++++++++
	R0 = flags word (see below)
	R1 = pointer to blockdriver in RMA or filename of blockdriver
	     (use previous if 0)
	R2 = pointer to dial script or filename of dial script
	     (use previous if 0)
	R3 = pointer to hangup script or filename of hangup script
	     (use previous if 0)
	R4 = serial speed in bps (use previous if 0)

	Dual Serial version
	+++++++++++++++++++
	R0 = flags word (see below)
	R1 = pointer to name of serial device (use previous if 0)
	R2 = pointer to dial script or filename of dial script
	     (use previous if 0)
	R3 = pointer to hangup script or filename of hangup script
	     (use previous if 0)
	R4 = serial speed in bps (use previous if 0).

On exit
	All registers preserved
  
Interrupts
	Interrupt status is unaltered
	Fast interrupt status is unaltered

Processor Mode
	Processor is in SVC mode

Re-entrancy
	Not defined

Use
	This call is used to configure the Dialler's settings without executing
	any script.  See Dialler_Dial for a description of the parameters.

Related SWIs
	Dialler_Dial
	Dialler_Answering

Related vectors
	None

5.1.9 Dialler_Timeout  (SWI &4C6C7)
      DiallerB_Timeout (SWI &50C87)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On entry
	R1 = length of timeout in seconds (-1 to read, 0 to disable)

On exit
	R0 = length of timeout in seconds

Interrupts
	Interrupts are disabled
	Fast interrupt status is unaltered

Processor Mode
	Processor is in SVC mode

Re-entrancy
	Interrupts are disabled so cannot be reentered

Use
	This call is used to set the time that the connection can be idle for
	before the Dialler will drop the line.  The Dialler does not monitor the
	line itself, but relies on clients periodically calling
	Dialler_ResetCounter to indicate that the line is not idle.  If R1 is -1
	on entry then no timeout will be set; if it is 0 then the timeout
	facility will be disabled.

Related SWIs
	Dialler_ResetCounter

Related vectors
	None

5.1.9 Dialler_ResetCounter  (SWI &4C6C8)
      DiallerB_ResetCounter (SWI &50C88)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On entry
	None

On exit
	All registers preserved

Interrupts
	Interrupts are disabled
	Fast interrupt status is unaltered

Processor Mode
	Processor is in SVC mode

Re-entrancy
	Interrupts are disabled so cannot be reentered

Use
	Clients of the Dialler should call this SWI when they send or receive
	data to indicate that the line is not idle.

Related SWIs
	Dialler_Timeout

Related vectors
	None

5.2 Service Calls
-----------------

5.2.1 Service_DiallerStatus  (Service Call &B4)
      Service_DiallerBStatus (Service Call &C4)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dialler status change

On entry
	R0 = new state word (see SWI Dialler_Status)
	R1 = &B4 (reason code)

On exit
	R1 preserved to pass on (do not claim)

Use
	This call is issued by the Dialler when is status word changes.  It must
	not be claimed.


--------------------------------------------------------------------------------

6.0 External dependencies 
=========================

The blockdriver version of the Dialler requires a suitable blockdriver to be
available and expects to be able to find this in the !SerialDev resource
directory.

The DeviceFS version of the Dialler requires a DeviceFS ('dual serial')
type device driver to be present (typically the dual serial module, but
could alternatively be the ISDN module etc.).  These new device drivers
require the following support modules:

	Module		Description				Version
	DeviceFS	Generic device driver interface		0.35
	BufferManager	Buffer Manager				0.25
	FileSwitch	Filing system support			2.36

At the time of writing the latest known version of the Dual Serial module is
0.20, and no earlier version should be used with the Dialler.

The earliest version of the PPP module to support the Dialler is 1.16.

Wimp applications using the Dialler should monitor the Dialler's status using
the TaskModule module.

--------------------------------------------------------------------------------

7.0 Product Organisation
========================

The Dialler is a RISC OS relocatable module written in C.  It can be
built either stand alone or as part of a RISC OS ROM build.

The different builds of the Dialler are specified at compile time using
flags.  These flags (suitable for specifying in the Components file of a
ROM build) are:

CBLOCKDRIVERS=-DBLOCKDRIVERS
to build a block driver variant.

TYPE=OLD
to build the original, deprecated Dialler.

The binaries for Dialler and DiallerB (and any transitional files) are
maintained separately so that Dialler and DiallerB can be built at the
same time without fear of one overwriting the other.

Separate binaries are not maintained for dual serial and DeviceFS
variants.  ie. a dual serial build cannot coexist in the same build
structure as a DeviceFS build.

A C/C++ header file is exported as Export.C.h.dialler in the build
tree; it contains useful definitions for using the Dialler (SWIs, flags
etc.).

--------------------------------------------------------------------------------

8.0 History
===========

	Revision	Who	Rev Date	Comment
	0.01		DNW			Started.
	                KB
	0.02		BAL			Serial port access control
						Timeouts
	0.03		BAL			Script extensions:
						  *commands
						  system variables
	0.04		BAL	1997-03-13	Extension to SWI Dialler_Status
	0.05		BAL	1997-04-29	Added more script info
	0.06		BAL	1997-05-23	Script extensions:
						  report strings
						  status strings
	0.07		BAL	1997-07-07	Added SWI numbers
	0.08		BAL	1998-02-17	Added information about DiallerB
--------------------------------------------------------------------------------
