Contents
PHD Script Engine

This is the help file for the PHD Script Engine 1.1.2 for PC Windows 3.1+ and NT 3.51+

Introduction

The PHD Script Engine provides a C/C++ script language to make serial interactions with other computers easier.  It builds upon the standard Windows serial communications API.

The Win16 16 bit Script Engine is supplied as a DLL called SCRENG.DLL.  The Win32 32 bit Script Engine is called ScrEng32.DLL. The Win32 DLL has one extra function: SetTxTimeout(), and has a default timeout of 30 seconds on transmits.

Win16:	Currently only one program can call SCRENG.DLL at a time.
Win32:  Separate programs can call ScrEng32.DLL.

Function List

Initialisation Functions	Starting and stopping scripts
Comms Option Functions	Comms option functions
Error Functions	Error functions and codes
Delay Function	Delay function
Transmit Functions	Transmit functions
Watch Functions	Watch functions
Log File Functions	Log file functions
Raw I/O Functions	Raw read and send functions
Programming Guide

Programming	How to use the script routines
Receiving Characters	Notes on how to cope with receiving characters
Blocking Hook	How the script routines block
Error Codes	List of all error codes
Basic Comms	How the basic comms is implemented
Implementation	Implementation notes
Wish List	Desirable features for future versions
Copyright

13 May 1996, Version 1.05 for Script Engine DLL V1.1.2.

Help text, software design and programming:

(c)  1995 PHD Computer Consultants Ltd, Manchester, UK,  0161 445 1650.

Chris Cant and John Cant.  good-tech@mcr1.poptel.org.uk


Programming
Script Engine Programming

See also Receiving Characters, Blocking Hook, and the list of Error Codes.

Overview

The script engine simplifies communications over a single serial port (COM1 to COM9).  An application can either talk to another computer or device directly, or using a modem link in between.  If you use high baud rates to an external modem then make sure that the PC has 16550A UART chip for the serial port.

Strings may be sent using Transmit().  You can wait for input using WaitFor().

If you need to cope with more than one possible return then you can set up various watch strings using WatchFor(); Received() tells you whether the watch string has been received.  Alternatively WatchEvent() waits for one or more watches to arrive within a timeout.

Example

Here is some example code:

BOOL script()

{

Transmit( "ATDT1234\r");

int sehConnect = WatchFor( "CONNECT");

int sehBusy = WatchFor( "BUSY");

int rv = WatchEvent( 20, sehConnect, sehBusy, -1)

if( rv==sehConnect)

Report( "You're connected");

else if( rv==sehBusy)

Report( "Sorry, the line's busy");

else if( rv==SE_TIMEDOUT)

Report( "Sorry, there's no answer");

return TRUE;

}

if( SEInit( COM2, 19200, BITS8N1, FLOW_RTS_CTS) != SE_SUCCESS)

{

Report( "Could not initialise script engine");

return FALSE;

}

BOOL rv = RunScript( script);

SEExit();

Note that this example ignores most of the error returns from the script engine routines.

Starting and Stopping

Start each comms session to a port with SEInit() and complete it with SEExit().  You can set a new Blocking Hook function to process Windows messages while waiting for serial I/O using SESetBlockingHook().

You can set various communications parameters using SEInit().  Other options can changed with the SESet family of routines: SESetCRLFTranslation(), SESetStripTopBit().

Within a comms session you can run one or more scripts one after the other.
Win16:  Start a script with StartScript() and end it with EndScript().

Win32:  Run a script with RunScript().

Use HangUpLine() to hand up the phone line.  This is done automatically when you SEExit().

Transmitting Characters

Transmit a null-terminated string using Transmit() or several concatenated together with TransmitCat().

You can transmit a string and then wait for the arrival of a response string within a timeout using TNW4().

In the Win32 version, there is a default timeout of 30 seconds.  This can be changed using SetTxTimeout(); a timeout of zero means that there is no timeout, ie the transmit functions may block forever.

Delays

You can delay for a number of seconds using Delay().

Watches

You can wait for the arrival of a string within a timeout using WaitFor().

Alternatively you can set a "watch" for a particular string using WatchFor().  You can determine if the watch string has arrived or not using Received().

You can set up many watch strings at once.  If you want to wait for one of a series of watch strings to arrive within a timeout then use WatchEvent().

You can re-enable a watch with WatchAgain(); this makes Received() return not found (until the original watch string arrives again).

Use ClrWatch() when you have finished with a watch, or ClrAllWatches() to clear them all.

The maximum number of characters in a watched for string is 80.

Log Files

You can have the Script Engine store all received characters for you in a log file.  Open, create or clear the log file with OpenLog(); you must then activate it using ActivateLog().

Any received characters are now written to the log file, after top bit stripping and CR LF translation is requested.

If you wish to write any additional characters to the log file, use WriteLog().

Finally close the log file with CloseLog(); this is done automatically in SEExit().

Reading and Sending Bytes

If you wish to receive a set number of characters to your own buffer, within a timeout, then call ReadBytes().

Note that characters read with ReadBytes() are not checked for watch strings.

It is often more flexible to use a log file to store incoming characters.

If you wish to send a set number of characters including nulls, then call SendBytes().

Errors

If an error on the serial port is detected then SELastCommsError() can be used to determine the actual serial error, as returned by GetCommError().

If you wish to cancel a routine (which is waiting for a timeout) then call SECancel().  You should read the section on the Blocking Hook before you program this.

Note that the script engine never throws up any dialog boxes, ie any errors are always passed to the calling routine.

Win32: 32 bit version

In general, the Win32 32 bit DLL version has the same programming interface as the Win16 16 bit version.

However note that RunScript() should be used instead of StartScript() and EndScript().

The Win32 DLL has extra functionality to allow for (cope with) timeouts when sending characters.  (Perhaps Win16 ie Windows 3.1 is more tolerant if there is no modem attached).

There is a default timeout on sending characters, eg with Transmit(), etc., of 30 seconds.  This can be changed using SetTxTimeout(); a timeout of zero means that there is no timeout, ie the transmit functions may block forever.

Note that blocking versions of the Win32 I/O functions are used.  However, the communications timeouts are set such that reading characters will never block forever.  If you call SetTxTimeout() with a timeout of zero then transmitting functions may block forever.


SEInit() Communications Parameters

The following parameters must be set when you start a comms session using SEInit().

Port

You must specify the serial port that you want to use for a session when you call SEInit().  Give a number in the range 1 to 9 to indicate COM1 to COM9.

Baud

You must specify the baud rate that you want to use for a session when you call SEInit().  This is the rate at which the PC will communicate with the modem (or directly with the other computer).  A modem link may well use a different speed.  Typically you will want to make the baud rate you specify here greater than the modem link speed; this allows modem data compression to have most effect.

Either specify the baud rate a number (less than or equal to 56000) or as a constant ORed with 0x0000FF00 (eg 0x0000FF00 | CBR_256000).

Flow Control

You must specify the flow control that you want to use for a session when you call SEInit().  You can select from RTS/CTS hardware handshaking (FLOW_RTS_CTS) or software handshaking using XON/XOFF characters (FLOW_XON_XOFF).

Note that the DTR line is used to enable a modem.  So dropping DTR is assumed to hang up the phone line.

Flow control is handled by the Windows serial API.

Data bits, Stop bits and Parity

You must select either 8 data bits, 1 stop bit and no parity (BITS8N1) or 7 data bits, 1 stop bit and even parity (BITS7E1) when you call SEInit().

These parameters are handled by the Windows serial API.


Communications Options

The following parameters may be set by calling one of SESet...() family of functions.

Note that the Strip Bit operation occurs (on receive only) before the CR LF translation.
CR LF translation occurs before any logging and watch checking.

CR-LF Translation

LF is the C character '\n', and is ASCII 10, ie '\x0A'.

CR is the C character '\r', and is ASCII 13, ie '\x0D'.

CR LF translation is set using SESetCRLFTranslation().  The default is no translation.  See the definition of SESetCRLFTranslation() for the precise parameter definitions.

You can set different translation options for transmit and receive.  You can change the CR LF setting during a session.

Translation proceeds in three stages.

1.  Basic translation

Set one or more of the following options:

SE_STRIP_CR	Strip any CR character.
SE_STRIP_LF	Strip any LF character.
SE_CR_TO_LF	Replace a CR character with LF.
SE_LF_TO_CR	Replace a LF character with CR.
SE_CR_TO_CRLF	Replace a CR character with CR LF.
SE_LF_TO_CRLF	Replace a LF character with CR LF.
SE_CRLF_TO_CR	Replace CRLF characters with CR.
SE_CRLF_TO_LF	Replace CRLF characters with LF.

The first "matching condition" from the above list finishes this stage of processing.  So if you have SE_STRIP_CR | SE_CR_TO_CRLF set then a CR character is stripped, thus ignoring the SE_CR_TO_CRLF.

These options only operate on the originally sent/received character, not any translations.  So SE_STRIP_LF|SE_CR_TO_CRLF will result in a CR character being translated into CRLF, while any other sent/received LFs are stripped.

2. Safe CR LF

Select SE_SAFE_CRLF if you want to ensure that CR LF characters only occur as CR LF pairs in that order.

3.  Maximum Line Length

You can specify one of SE_TERM_CR, SE_TERM_LF or SE_TERM_CRLF to ensure that lines are terminated by the appropriate character(s) if more than a specified number of characters are on a line.  In this case, you must specify a Maximum Line Length parameter to SESetCRLFTranslation().

CR LF translation occurs as follows:

1.	Any transmitted character.  This applies to characters sent by SendBytes().

2.	Any received character, prior to logging and watch string comparisons.  This applies to characters received by ReadBytes().

Note that any strings passed to the watch functions are not CR LF translated.

This parameter is implemented by the Script Engine.

Strip Top Bit

Stripping the top bit is set using SESetStripTopBit().  The default is not to strip the top bit.

Stripping the top bit is enabled with STRIP_TOP_BIT and disabled with DONT_STRIP_TOP_BIT.

Example: received hex 0A would be left as 0A, but received hex 8A would be changed to 0A.

This parameter is implemented by the Script Engine.


Receiving Characters

The standard Windows API routines are set up to process any outgoing or incoming characters automatically using a large buffer in each direction.

However incoming characters are only taken from the input buffer in a routine which looks for characters, eg WaitFor().  Note that Delay() also removes characters from the input buffer, checking for any WatchEvent() strings.

This makes the following technique valid:

Transmit( "AT\r");

WaitFor( "OK\r\n", 5)

That is, there is no possibility of incoming characters being lost between the end of the Transmit() and running of WaitFor().

(What happens if Transmit() blocks?)


Blocking functionality
Blocking Operations

The script engine functions are blocking, ie if they have to wait for data or a timeout, then the call simply waits until completion.  There is no asynchronous operation mode.

When a function blocks it calls a standard message loop, which processes the standard Windows message queue.  If there are no messages to be processed then it checks whether the loop should be exited.  First it checks to see if the user has requested that the function be cancelled, using SECancel().  Then it performs the checks that a relevant to the calling functions, eg sees if the appropriate characters have arrived.

During this message loop the dispatched message may be a button press for the user cancelling an operation.  Handle this by issuing a SECancel() call.  The button handler should then return.  The script engine message will then exit.  The originally called script engine routine will exit with your supplied cancel value (eg SE_CANCELLED).  So in a button handler, do not cause an application to exit, as the script engine message loop will still be in operation.

For routines that may block, please ensure that you check for all possible returned results, eg SE_CANCELLED.

You can replace the default message loop that is called, see SESetBlockingHook().


Full Function List

Initialisation Functions

SEInit()	Initialise comms on a port
SEExit()	Finish using comms on a port
RunScript()	Win32: Run a script
StartScript()	Win16: Start a script
EndScript()	Win16: End a script
SESetBlockingHook()	Set Blocking Hook

Comms Option Functions

SESetCRLFTranslation()	Set the CR LF translation.
SESetStripTopBit()	Set strip top bit of incoming characters.
Error Functions

HangUpLine()	Hang up the phone line
SELastCommsError()	Get last comms error number
SECancel()	Cancel Script function
Delay Function

Delay()	Delay n seconds
Transmit Functions

SetTxTimeout()	Set the transmit timeout (Win32 only)
Transmit()	Transmit a null-terminated string
TransmitCat()	Concatenate and transmit a series of null-terminated strings
TNW4()	Transmit a null-terminated string and wait for another string to arrive
Watch Functions

ClrAllWatches()	Clears all watches
ClrWatch()	Clear a watch
Received()	See if a WatchFor() has been received
WaitFor()	Wait for a string or a timeout
WatchAgain()	Look for a watch event again
WatchEvent()	Wait for one of several watch events to arrive or a timeout
WatchFor()	Set a watch for a string

Log File Functions

OpenLog()	Open/Create/Truncate a receive log file
CloseLog()	Close a log file
ActivateLog()	Activate (or not) a log file
WriteLog()	Write to a log file
Raw I/O Functions

ReadBytes()	Read a set number of bytes
SendBytes()	Send a set number of bytes, inc nulls


Error Codes

SE_SUCCESS	Function succeeded: value 0.
SE_COMMS_ERROR	Error on serial line: use SELastCommsError() to get the error code which was returned by the Windows API GetCommError().
SE_NOT_FOUND	Watch event not found.
SE_TIMEDOUT	Function timed out
SE_CANCELLED	Function was cancelled by the user calling SECancel() with the default error return value SE_CANCELLED.
SE_QUITTED	Function aborted as default blocking routine found a WM_QUIT message in the message queue: see Blocking Operations.
SE_BAD_PARAM	Bad parameter passed to function, eg invalid watch handle
SE_IN_USE	SEInit(): Port already allocated by SEInit(), or another app is using the port.
SE_OPENCOMM_ERROR	SEInit(): OpenComm() error;  use SELastCommsError() to get the error code
SE_BAD_SPEED	SEInit(): bad speed: >56000
SE_OUT_OF_MEMORY	SEInit(): out of memory;  use SELastCommsError() to get the error code
SE_SETCOMMSTATE_ERR	SEInit(): SetCommState() error;  use SELastCommsError() to get the error code
SE_NO_WATCHES	No watch handles left.
SE_SYSTEM_ERROR	Internal script engine failure


SEInit()

Description	Initialise the Script Engine for a particular port.
	#include <screng.h> int PASCAL FAR SEInit( int port, long baud, BOOL BitsParity, BOOL FlowControl, BOOL StripTopBit, BOOL CRLFTranslation);
	port The COM port number, ie 1 to 9. baud The baud rate that is used to communicate with the modem.  This may be the actual speed value (up to 56000) or an index ORed with 0x0000FF00, ie CBR_110 | 0x0000FF00 to CBR_256000 | 0x0000FF00. BitsParity The data bits, stop bits and parity setting: either BITS8N1 or BITS7E1. FlowControl The flow control setting: either FLOW_RTS_CTS or FLOW_XON_XOFF. StripTopBit The strip top bit setting: either STRIP_TOP_BIT or DONT_STRIP_TOP_BIT. CRLFTranslation The CR <-> LF Translation setting: either CRLF_TRANS or NO_CRLF_TRANS.
Remarks	You can only initialise the Script Engine for one port at a time.  Trying to initialise another port or reinitialise the same port  Make sure that each call to SEInit() is matched by a terminating call to SEExit() when you have finished using the port.  Make sure that you do this before your program exits.
Return Value	SE_SUCCESS if Script Engine initialised OK on given port. SE_BAD_SPEED:  Speed is greater than 56000. SE_IN_USE:  A port has already been allocated with SEInit() or another application is using the port. SE_OUT_OF_MEMORY:  Cannot allocate enough memory: SELastCommsError() indicates point of error. SE_OPENCOMM_ERROR:  Error returned from OpenComm() result: Use SELastCommsError() to retrieve the returned value. SE_SETCOMMSTATE_ERR:  Error returned from SetCommState() result: Use SELastCommsError() to retrieve the returned value.
See Also	Communications Parameters, SEExit(), SELastCommsError()


SEExit()

Description	Finish using the Script Engine for a particular port.
	#include <screng.h> void PASCAL FAR SEExit();
Remarks	The log file is closed, any transmitted characters are sent and the phone line hung up. SEExit() then frees the resources which were allocated by the matching SEInit().
Return Value	None
See Also	SEInit()


RunScript()

WIN32 only

Description	Runs a script.
	#include <screng.h> int RunScript( BOOL (*fnScript)());
Return Value	Normally has the return value from your function fnScript(). SE_TERMINATED.
See Also	Calls StartScript() and EndScript() internally.


StartScript()

WIN16 only

Description	Start a script.
	#include <screng.h> int PASCAL FAR StartScript();
Remarks	Must be matched by a EndScript() when the script finishes.
Return Value	SE_SUCCESS SE_BAD_PARAM if a script is already running.
See Also	EndScript()


EndScript()

WIN16 only

Description	End a script.
	#include <screng.h> void PASCAL FAR EndScript();
Remarks	Must matched an earlier StartScript().
Return Value	None
See Also	StartScript()


SESetBlockingHook()

Description	Set the Blocking Hook function.
	#include <screng.h> FARPROC PASCAL FAR SESetBlockingHook( BOOL (FAR *NewBlockingHook)(void));
	NewBlockingHook The replacement BlockingHook() routine.
Remarks	When a routine blocks waiting for a time delay or for characters to be processed, the script engine calls a BlockingHook() function.  You can set the routine that is called using SESetBlockingHook().
	You might want to change this function:  (A) if you wish to process modeless dialog box messages correctly, or (B) if you wish to debar command, eg ignore WM_COMMAND messages.
Return Value	The return value points to the previous blocking hook function.
Comments	This is the default BlockingHook() function. BOOL DefaultBlockingHook(void) { MSG msg; BOOL ret; // get the next message if any ret = (BOOL)PeekMessage(&msg,NULL,0,0,PM_REMOVE); // if we got one, process it if (ret) { if( msg.message == WM_QUIT) SECancel( SE_QUITTED); TranslateMessage(&msg); DispatchMessage(&msg); } // TRUE if we got a message return ret; }
See Also	Blocking Operations, SECancel()


SESetCRLFTranslation()

Description	Specify how incoming and outgoing CR and LF characters are handled.
	#include <screng.h> int PASCAL FAR SESetCRLFTranslation( int CRLFTranslation, short MaxLineLength=0);
	CRLFTranslation Bit map of required options - see below.  Set to zero to turn off CR LF translation. MaxLineLength The maximum number of characters in a line.  Only needed if SE_TERM_CR, SE_TERM_LF or SE_TERM_CRLF set.
Remarks	The following bit values may be specified in CRLFTranslation, ORed together. Specify one of the following three values (or miss off to specify SE_CRLF_TXRX).  Note that you can use two calls to set different transmit and receive options. SE_CRLF_RXONLY Settings only apply to receive characters SE_CRLF_TXONLY Settings only apply to transmit characters SE_CRLF_TXRX Settings apply to both transmit and receive characters Select one or more of the following options.  The first "matching condition" from the list below will stop processing of these options.  So SE_STRIP_CR|SE_CR_TO_CRLF is equivalent to SE_STRIP_CR.  Options only operate on the orginally sent/received character, not any translations.  So SE_STRIP_LF|SE_CR_TO_CRLF will result in a CR character being translated into CRLF, while any other sent/received LFs are stripped. SE_STRIP_CR Strip any CR character. SE_STRIP_LF Strip any LF character. SE_CR_TO_LF Replace a CR character with LF. SE_LF_TO_CR Replace a LF character with CR. SE_CR_TO_CRLF Replace a CR character with CR LF. SE_LF_TO_CRLF Replace a LF character with CR LF. SE_CRLF_TO_CR Replace CRLF characters with CR. SE_CRLF_TO_LF Replace CRLF characters with LF. After the above processing, the following option is checked. SE_SAFE_CRLF Strip any CR or LF characters that are not in CRLF pairs. The following further options allow a maximum line length to be specified.  Parameter MaxLineLength must be given.  The specified character is inserted if MaxLineLength characters have been sent/received without an intervening specified character.  Select one of the following three options. SE_TERM_CR Insert a CR line terminator, after MaxLineLength characters. SE_TERM_LF Insert a LF line terminator, after MaxLineLength characters. SE_TERM_CRLF Insert a CRLF line terminator, after MaxLineLength characters. This option is best used with SE_SAFE_CRLF.
Return Value	Returns the previous CR LF translation bit map setting.
Comments	The effects of successive calls are not cumulative, with the exception that you can make two calls to set the transmit and receive settings separately. Note that the strip top bit operation, if selected, is applied before any CR LF translation.  However CR LF translation is done before all other normal activities, ie writing to log file, or processing watches.
See Also	Comms Options


SESetStripTopBit()

Description	Specify whether the top bit is stripped from all incoming character bytes.
	#include <screng.h> BOOL PASCAL FAR SESetStripTopBit( BOOL StripTopBit);
	StripTopBit TRUE if the top bit is to be stripped.
Return Value	Returns the previous strip top bit setting.
See Also	Comms Options


HangUpLine()

Description	Hang up the phone line, by dropping DTR.
	#include <screng.h> void PASCAL FAR HangUpLine();
Return Value	None
See Also


SELastCommsError()

Description	Return the last comms error number.
	#include <screng.h> int FAR PASCAL SELastCommsError();
Remarks
Return Value	Returns the last comms error number, retrieved from GetCommError(), or zero if no error.
See Also


SECancel()

Description	Cancel the script routine function in progress.
	#include <screng.h> int PASCAL FAR SECancel( int rv=SE_CANCELLED);
	rv The value that the BlockingHook() function and the calling script routine will return. rv must be not equal to zero for a cancel to occur.  You may set a value other then SE_CANCELLED if you wish that to be returned.  It is strongly recommended that you use negative values, as positive values may appear to be valid returns from a script routine.
Remarks	A script routine, such as Delay(), will have called the BlockingHook() routine message loop while waiting for a delay timeout.  If a message handler calls SECancel() then the delay is halted prematurely and rv is returned to the script routine.  The script routine always returns this value, eg Delay() will return rv, ie usually SE_CANCELLED.
Return Value	SE_SUCCESS. SE_BAD_PARAM if rv is zero or if there is no message loop in progress
See Also	Blocking Operations


Delay()

Description	Delay for the given number of seconds.
	#include <screng.h> int PASCAL FAR Delay( int timeout);
	timeout The delay timeout in seconds.
Return Value	SE_SUCCESS if delay completed successfully. SE_QUITTED if the default BlockingHook() found a WM_QUIT message SE_CANCELLED if aborted by using SECancel(). SE_QUITTED if the default BlockingHook() found a WM_QUIT message.
See Also	Blocking Operations, SECancel()


SetTxTimeout()

Description	Set the Win32 transmit timeout.
	#include <screng.h> int PASCAL SetTxTimeout( int TxToSecs);
	TxToSecs The transmit timeout in seconds; must be greater than or equal to zero.
Remarks	Sets the timeout to be used for all the transmit functions.  This overrides the default timeout of 30 seconds. If TxToSecs is zero then there is no timeout, and the transmit functions may block forever. This function is only available in the Win32 32 bit version of the script engine:
Return Value	SE_SUCCESS if OK. SE_BAD_PARAM if the Script Engine has not been initialised, or if setting the timeouts failed.
See Also


Transmit()

Description	Transmit a null-terminated string.
	#include <screng.h> int PASCAL FAR Transmit( char FAR* str);
	str The null-terminated string to transmit.
Remarks	If CRLFTranslation is enabled then any \n ('\x0A') in the output string is changed into a \r ('\x0D'). The Script Engine uses its text mode write to send the characters.  Characters with a hex value of '\x20' and above are stored in an output buffer, ie not sent directly.  When the buffer is full, or when a character with a hex value of less than '\x20' is received, then the whole buffer is sent. Note that if the Windows transmission is temporarily disabled then this routine may block.  Use SECancel() to abort  In the event of a SE_COMMS_ERROR error or a cancel then remaining part of the string to send is thrown away;  there is no indication of how many characters were transmitted. Win32:  A timeout operates.  It defaults to 30 seconds, unless overridden by SetTxTimeout()
Return Value	SE_SUCCESS if delay completed successfully. SE_COMMS_ERROR if an error occurred on transmission. SE_CANCELLED if aborted by using SECancel(). SE_QUITTED if the default BlockingHook() found a WM_QUIT message. Win32: SE_TIMEDOUT if transmit timed out.
See Also	Blocking Operations, SECancel(), TransmitCat(), SetTxTimeout()


TransmitCat()

Description	Concatenate and transmit a series of null-terminated strings.
	#include <screng.h> int FAR CDECL TransmitCat( LPCSTR str_A, ...);
	str_A The first null-terminated string to transmit. ... List of strings to transmit, terminated by (LPCSTR)NULL.
Remarks	NOTE:  You MUST cast each string to LPCSTR for the function parameters to be passed correctly. NOTE:  You MUST put a final parameter of (LPCSTR)NULL to terminate the list. If CRLFTranslation is enabled then any \n ('\x0A') in the output string is changed into a \r ('\x0D'). The Script Engine uses its text mode write to send the characters.  Characters with a hex value of '\x20' and above are stored in an output buffer, ie not sent directly.  When the buffer is full, or when a character with a hex value of less than '\x20' is received, then the whole buffer is sent. Note that if the Windows transmission is temporarily disabled then this routine may block.  Use SECancel() to abort  In the event of a SE_COMMS_ERROR error or a cancel then remaining part of the string to send is thrown away;  there is no indication of how many characters were transmitted. Win32:  A timeout operates.  It defaults to 30 seconds, unless overridden by SetTxTimeout()
Return Value	SE_SUCCESS if delay completed successfully. SE_COMMS_ERROR if an error occurred on transmission. SE_CANCELLED if aborted by using SECancel(). SE_QUITTED if the default BlockingHook() found a WM_QUIT message. Win32: SE_TIMEDOUT if transmit timed out.
Example	rv = TransmitCat( (LPCSTR)"AT", (LPCSTR)InitString, (LPCSTR)"\r", (LPCSTR)NULL);
See Also	Blocking Operations, SECancel(), Transmit(), SetTxTimeout()


TNW4()

Description	Transmit a null-terminated string and wait for another string to arrive.
	#include <screng.h> int PASCAL FAR TNW4( char FAR* SendStr, char FAR* Wait4Str, short WaitTime);
	SendStr The null-terminated string to transmit. Wait4Str The null-terminated string to wait for. WaitTime The timeout in seconds.
Remarks	This routine sends SendStr using Transmit() and then waits for Wait4Str with a timeout of WaitTime. The watch is case-insensitive.  CRLF translation applies If CRLFTranslation is enabled then any \n ('\x0A') in the output string is changed into a \r ('\x0D'). The Script Engine uses its text mode write to send the characters.  Characters with a hex value of '\x20' and above are stored in an output buffer, ie not sent directly.  When the buffer is full, or when a character with a hex value of less than '\x20' is received, then the whole buffer is sent. Note that if the Windows transmission is temporarily disabled then this routine may block.  Use SECancel() to abort  In the event of a SE_COMMS_ERROR error or a cancel then remaining part of the string to send is thrown away;  there is no indication of how many characters were transmitted. Win32:  A timeout operates.  It defaults to 30 seconds, unless overridden by SetTxTimeout()
Return Value	SE_SUCCESS if the transmit and waitfor was completed successfully. SE_TIMEDOUT if the Wait4Str was not found within the specified timeout. SE_COMMS_ERROR if an error occurred on transmission. SE_CANCELLED if aborted by using SECancel(). SE_QUITTED if the default BlockingHook() found a WM_QUIT message. Win32: SE_TIMEDOUT if transmit timed out.
See Also	Blocking Operations, SECancel(), Transmit(), SetTxTimeout()


Received()

Description	See if a WatchFor() has been received.
	#include <screng.h> int PASCAL FAR Received( int handle);
	handle The handle of the WatchFor() event.
Return Value	SE_SUCCESS if the watch has been found. SE_NOT_FOUND if the watch has not been found. SE_BAD_PARAM if the handle is invalid or if there is not a watch set.
See Also	WatchFor()


ClrWatch()

Description	Clear a watch
	#include <screng.h> int PASCAL FAR ClrWatch( int handle);
	handle The watch number.
Remarks
Return Value	SE_SUCCESS if watch successfully cleared SE_BAD_PARAM if handle was invalid.
See Also	WatchFor(), ClrAllWatches()


ClrAllWatches()

Description	Clears all watches
	#include <screng.h> void PASCAL FAR ClrAllWatches();
Remarks
Return Value	None
See Also	ClrWatch()


WaitFor()

Description	Wait for a string or a timeout
	#include <screng.h> int PASCAL FAR WaitFor( char FAR* what, int timeout);
	what The string to watch for. timeout The timeout in seconds.
Remarks	The watch is case-insensitive.  CRLF translation applies.  The maximum number of characters in a watched for string is 80.
Return Value	SE_SUCCESS if string found SE_TIMEDOUT if string not found within timeout SE_CANCELLED if aborted by using SECancel(). SE_QUITTED if the default BlockingHook() found a WM_QUIT message.
See Also	SECancel()


WatchAgain()

Description	Look for a watch event again
	#include <screng.h> int PASCAL FAR WatchAgain( int handle);
	handle The watch handle to watch on again, originally allocated by WatchFor().
Remarks	The watch is case-insensitive.  CRLF translation applies. If a WatchFor() event has been Received(), then it is possible to look again for the same string using WatchAgain.  During this routine, Received() is reset to SE_NOT_FOUND.
Return Value	SE_SUCCESS if watch set again. SE_BAD_PARAM if handle is invalid.
See Also	WatchFor(), Received(), ClrWatch()


WatchEvent()

Description	Wait for one of several watch events to arrive or a timeout.
	#include <screng.h> int FAR CDECL WatchEvent( int timeout, int handle_A, ...);
	timeout The timeout in seconds. handle_A The first watch handle to stop on, originally allocated by WatchFor(). ... List of watch handles to stop on, terminated by -1.
Remarks	Note: You MUST terminate the list of watch handles with -1. The watches are case-insensitive.  CRLF translation applies. This routine waits until one of the given watch events occurs, or the timeout occurs.  If a watch event has already occurred then WatchEvent() returns straight away.
Return Value	>= 0  The handle of the event that occurred. SE_TIMEDOUT if the timeout occurred. SE_CANCELLED if aborted by using SECancel(). SE_QUITTED if the default BlockingHook() found a WM_QUIT message. SE_BAD_PARAM if any of the handles are invalid.
See Also	WatchFor(), Received(), ClrWatch()


WatchFor()

Description	Set a watch for a string
	#include <screng.h> int PASCAL FAR WatchFor( char FAR* what);
	what The string to watch for.
Remarks	The watch is case-insensitive.  CRLF translation applies.  The maximum number of characters in a watched for string is 80.
Return Value	>= 0: index of watch handle. SE_NO_WATCHES if no watches are available. SE_BAD_PARAM if what is a NULL pointer.
See Also	Received(), WatchAgain() WatchEvent(), ClrWatch()


OpenLog()

Description	Open/Create/Truncate a receive log file.
	#include <screng.h> BOOL PASCAL FAR OpenLog( char FAR* LogFileName, BOOL ClearOut=FALSE);
	LogFileName The log file name. ClearOut Set TRUE to truncate the file to zero length
Remarks	This function opens a log file, creating it if necessary.  If ClearOut is TRUE then any file contents are cleared, ie the file length is set to zero. Note that ActivateLog() must be called before any received characters are logged. Note that transmitted characters are not sent to the log. Any received characters are sent to the log, after Strip Top Bit and CRLF Translation.  Further if CRLF Translation is enabled then WriteLog() ensures that any '\r', ie '\x0D', is followed by a '\n', ie '\x0A'. You can write additional characters to the log file using WriteLog().
Return Value	TRUE if log file opened FALSE if open failed.
See Also	ActivateLog(), WriteLog(), CloseLog()


ActivateLog()

Description	Activate/Deactivate the log file.
	#include <screng.h> void PASCAL FAR ActivateLog( BOOL flag=TRUE);
	flag TRUE to enable log file writes.
Remarks	You must call ActivateLog() after OpenLog() to enable logging of received characters
Return Value	None
See Also	OpenLog(), WriteLog(), CloseLog()


WriteLog()

Description	Write an additional character to the log file.
	#include <screng.h> void PASCAL FAR WriteLog( BYTE cc);
	cc The byte the write to the log file.
Remarks	The log file must have been opened with OpenLog() and activated with ActivateLog(). If CRLF Translation is enabled then WriteLog() ensures that any '\r', ie '\x0D', is followed by a '\n', ie '\x0A'.
Return Value	None
See Also	OpenLog(), ActivateLog(), CloseLog()


CloseLog()

Description	Close the log file.
	#include <screng.h> void PASCAL FAR CloseLog();
Remarks
Return Value	None
See Also	OpenLog(), ActivateLog(), WriteLog()


ReadBytes()

Description	Read a set number of bytes.
	#include <screng.h> int PASCAL FAR ReadBytes( int timeout, char FAR* where, int ByteCount);
	timeout The timeout in seconds where Where to return any read characters ByteCount The count of bytes to read
Remarks	There is no watch event processing during this routine. However the top bit is stripped and CR LF translation are applied if selected.
Return Value	0 if the required number of bytes were read >0 if not all the bytes were read within the specified timeout <0 for other errors, eg SE_COMMS_ERROR
See Also


SendBytes()

Description	Send a set number of bytes, inc nulls
	#include <screng.h> int PASCAL FAR SendBytes( char FAR* str, int ByteCount);
	str Pointer to the characters to be sent ByteCount The count of bytes to send
Remarks	There is no watch event processing during this routine. However CR LF translation is applied if selected. The Script Engine uses its binary mode write to send the characters, ie all characters are sent individually straight away, and so are not buffered by the Script Engine. Note that if the Windows transmission is temporarily disabled then this routine may block.  Use SECancel() to abort  In the event of a SE_COMMS_ERROR error or a cancel then remaining part of the string to send is thrown away;  there is no indication of how many characters were transmitted. Win32:  A timeout operates.  It defaults to 30 seconds, unless overridden by SetTxTimeout()
Return Value	SE_SUCCESS if delay completed successfully. SE_COMMS_ERROR if an error occurred on transmission. SE_CANCELLED if aborted by using SECancel(). SE_QUITTED if the default BlockingHook() found a WM_QUIT message. Win32: SE_TIMEDOUT if transmit timed out.
See Also	SECancel(), SetTxTimeout()


Implementation Notes

The SetTimer() call in SetScriptTimer() is assumed to work.


Basic Comms

Buffers

ScrEng uses OpenComm() giving it BUF_SIZE as the length Windows is to use for its receive and transmit internal buffers.

ScrEng also allocates its own buffers (on top of the Windows ones), also BUF_SIZE in length.

BUF_SIZE is 2048.

Watches

The default number of watches (NUM_WATCHES) is 16.

The maximum number of characters in a string to watch for (MAX_LOOKFOR) is 80 characters.


Wish List

Desirable features for future versions of the Script Engine

1.	Terminal Window

2.	Resolve whether to keep StartScript() and EndScript().  Make them do something more useful.