home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-30 | 182.2 KB | 5,412 lines |
-
-
-
-
-
-
-
-
-
-
-
-
- Reference Manual for the
- AutoLibrary(tm) Program-Playback Tool
-
- Version 1.2
- March 1992
-
-
-
-
-
-
-
- Copyright 1991 by
- Wayne E. McDaniel
- All Rights Reserved
-
- AutoLibrary(tm) is a Trademark of
- Avid Software
-
- Avid Software
- P.O. Box 1871
- Beaverton, OR 97075-1871
-
- (503) 626-6652
-
- CompuServe Mail: 70372,2513
- Internet: 70372.2513@compuserve.com
-
-
- _______
- ____|__ | (tm)
- --| | |-------------------
- | ____|__ | Association of
- | | |_| Shareware
- |__| o | Professionals
- -----| | |---------------------
- |___|___| MEMBER
-
-
-
-
- Copyright 1991 Wayne E. McDaniel, All rights reserved. Printed
- in the United States of America.
-
- The AutoLibrary(tm) Program-Playback tool Shareware diskette,
- which contains a copy of this manual, may be freely copied and
- shared.
-
- However, multiple copies of this document may not be printed and
- printed copies of this document may not be copied in any way
- without permission in writing from Avid Software.
-
-
-
-
- Table of Contents
-
- Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
-
- Installation . . . . . . . . . . . . . . . . . . . . . . . . 8
-
- System Requirements . . . . . . . . . . . . . . . . . . . . . 9
-
- Optional Requirements . . . . . . . . . . . . . . . . . . . . 9
-
- Discussion of Requirements . . . . . . . . . . . . . . . . . 9
-
- Compiling Source . . . . . . . . . . . . . . . . . . . . . . 9
-
- Compiling Interface Libraries . . . . . . . . . . . . . . . . 9
-
- Compiling Applications . . . . . . . . . . . . . . . . . . . 10
-
- Getting Started Using Example 1 (ex01.exe) . . . . . . . . . 11
-
- Getting Started Using Example 2 (ex02.exe) . . . . . . . . . 14
-
- A Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . 15
-
- Reference Guide For the AutoLibrary(tm) Program-Playback
- tool . . . . . . . . . . . . . . . . . . . . . . . . . . 33
- AvidClosePort - Close Communication Port . . . . . . . . 34
- AvidConvert - Convert Characters to Strings . . . . . . 36
- AvidDrainPort - Drain Communication Port . . . . . . . . 38
- AvidExitAutoLibrary - Exit AutoLibrary . . . . . . . . . 41
- AvidGetFromHoldArea - Get Characters from Hold Area . . 43
- AvidInitAutoLibrary - Initialize AutoLibrary . . . . . . 45
- AvidLogInfo - Log information to file or screen. . . . . 47
- AvidLogOpen - Open a Log File. . . . . . . . . . . . . . 51
- AvidOpenPort - Open Communication Port . . . . . . . . . 53
- AvidProcessOptions - Parse an Option Parameter List . . 57
- AvidRead - Read a Character . . . . . . . . . . . . . . 60
- AvidRegisterSend - Register a String to Send . . . . . . 63
- AvidRegisterWait - Register a Wait String . . . . . . . 65
- AvidSend - Send a String . . . . . . . . . . . . . . . . 67
- AvidSendSearch - Send Strings then Search . . . . . . . 69
- AvidVersion - Print Version and Copyright Information . 76
- EveryChar - Called with Every Character Received . . . . 77
-
- Reference Guide for Interface Routines . . . . . . . . . . . 79
- CommInterfaceClose - Close port . . . . . . . . . . . . 80
- CommInterfaceOpen - Open Port . . . . . . . . . . . . . 82
- CommInterfaceRead - Read Character . . . . . . . . . . . 94
- CommInterfaceSend - Send Character . . . . . . . . . . . 105
-
-
-
- 4
-
-
- Introduction
-
- The AutoLibrary(tm) Program-Playback tool is a C function library
- for automation. Automation is coded into programs then played
- back when the program executes.
-
- This tool will not replace any of your existing automation tools.
- You will still use your terminal emulator's script language for
- automatic access to bulletin boards and online services and you
- may still want your Capture-Playback tool to create quick and
- convenient regression tests.
-
- Instead of replacing any tool, add this tool to your personal
- tool box and use it when it offers the best solution.
-
- To determine if this tool offers you the best solution, consider
- the following questions.
-
- 1. Is there a serial connection to the system being
- automated? Or can there be by redirecting I/O or
- designing in a serial test port?
-
- 2. Are you automating with ASCII characters?
-
- 3. Do you want C as your programming language, where
- automation is hand coded into subroutines?
-
- If your answers to the previous questions were yes, you will
- need...
-
- 1. A PC with a serial port.
-
- 2. Turbo C version 2.0
-
- Or you will need to do one or more of the following...
-
- 1. Port this to a different operating system.
-
- 2. Port the interface routines to something other than RS-
- 232.
-
- 3. Port the interface routines to a different
- communications package.
-
- 4. Port to a different C compiler.
-
- The features of this tool combined with the C programming
- language, give you the benefit of writing easy and flexible
-
-
-
- 5
-
- automation programs. The following list shows some of the
- features and benefits you will like.
-
- 1. Your automation programs can be distributed without
- script files or interpreters.
-
- 2. Your automation programs will take advantage of the C
- programming language for many things like: file I/O,
- flow control, variable declarations, parameterized
- subroutines, and so on. Also, you can take advantage
- of C debuggers, profilers, linkers, and other add-on
- libraries. You will be able to create generic
- automation libraries using the C librarian for
- distribution to other members of your group.
-
- 3. Your automation programs will not have to depend on
- play back timing or comparisons to previous runs.
- Instead, your automation programs will have the
- expected results coded in.
-
- 4. Your automation programs will take advantage of the way
- this tool handles timeouts.
-
- There are two types of timeouts: Repeating-Timeouts and
- Ending-Timeouts. Repeating timeouts start over after
- each newly received character and ending timeouts
- don't.
-
- 5. Your automation programs will handle variations of
- play-back input by registering multiple strings to wait
- for.
-
- 6. Your automation programs will take advantage of the
- options parameter each routine has. This parameter
- allows customized use of the routines. It will also
- allow me to add functionality without adding new
- interfaces or changes existing ones.
-
- 7. Your automation programs may take advantage of the
- EveryChar routine. This routine is written by you and
- is called with each received character.
-
- 8. Your automation programs may take advantage of your
- ability to vary the send delay between each character
- sent.
-
-
-
- 6
-
-
- The following lists each of the routines in this tool...
-
- The main routines that support automation sequences...
-
- AvidRegisterSend - Register a string to send.
- AvidRegisterWait - Register a wait string.
- AvidSendSearch - Send strings then search.
-
- The others in alphabetical order...
-
- AvidClosePort - Close communication port.
- AvidConvert - Convert characters to strings.
- AvidDrainPort - Drain communications port.
- AvidExitAutoLibrary - Exit AutoLibrary.
- AvidGetFromHoldArea - Get characters from hold area.
- AvidInitAutoLibrary - Initialize AutoLibrary.
- AvidLogInfo - Log information to file or screen.
- AvidLogOpen - Open a log file.
- AvidOpenPort - Open communication port.
- AvidProcessOptions - Parse an option parameter list.
- AvidRead - Read a character.
- AvidSend - Send a string.
- AvidVersion - Print version and copyright information.
- EveryChar - Called with every character received.
-
- Interface routines to your communications library...
-
- CommInterfaceClose - Close port.
- CommInterfaceOpen - Open port.
- CommInterfaceRead - Read Character.
- CommInterfaceSend - Send Character.
-
-
-
- 7
-
-
- The following list shows some of the applications this tool would
- be good for. (The items with an asterisk are projects that I
- have done using this automation technique.)
-
- - Automating CompuServe access.
- - Controlling/testing a modem.
- - Controlling/testing an ASCII Terminal
- - Controlling/testing Unix or a program running on Unix.
- - Controlling/testing other mini or mainframe computer
- systems.
- - Controlling/testing Bulletin Board Systems
- - Controlling/testing Data Switches.
- - * Network monitoring from users perspective.
- - Controlling/testing Special equipment. For example,
- medical instruments. Especially instruments that have
- serial ports designed in to help support automated
- testing.
- - * Controlling/testing Target debug monitors.
- - Controlling/testing Prom programmers.
-
- - Controlling/testing anything that has a serial
- connection or can be redirected through a serial
- connection.
-
-
-
- 8
-
-
- Installation
-
- For installation instructions see the readme file for installing
- this software.
-
- Please see the PACKAGE.LST file for a description of CONSULT.DOC,
- SUPPORT.DOC, LICENSE.DOC, and so on. Within these files are
- important information about registering, warranty, support,
- license agreements, vendor/sysop information, hiring me as a
- contractor/consultant, and so on.
-
-
-
- 9
-
-
- System Requirements
-
- a) Turbo C v2.0
- b) COM 1 or COM 2
- c) IBM PC or compatible
-
-
- Optional Requirements
-
- a) A communication package, such as, Greenleaf Comm Library
- v2.21 (Should work with v3.0)
-
-
- Discussion of Requirements
-
- The AutoLibrary Program-Playback Tool communicates via interface
- routines to the communication package. I provide a basic
- asynchronous RS-232 communication package with this tool to get
- you started. However, I recommend using a communication package
- with additional features and a proven track record.
-
- Interface routines are provided for the Greenleaf Comm Library.
- However, you may port the interface routines to any one of the
- many communication packages. This manual contains detailed
- instructions for doing this.
-
- It is possible for both registered and unregistered users to
- write interface routines for a different communication package.
-
- Also, given registered user receive the source, it is possible to
- port this tool to other compilers and operating systems.
-
-
- Compiling Source
-
- The source code is generated by the batch file genauto.bat. Make
- sure Turbo C is located in \tc or edit the batch files with your
- Turbo C path.
-
-
- Compiling Interface Libraries
-
- The interface libraries are generated by the batch file
- genface.bat. Make sure Turbo C is located in \tc and the
- Greenleaf Comm Library is located in \gls or edit the batch files
- with your pathnames.
-
-
-
- 10
-
- Please see the detailed information on how to port the interface
- routines to use other communication packages. The information is
- documented in the reference section for CommInterfaceClose,
- CommInterfaceOpen, CommInterfaceRead, and CommInterfaceSend.
-
-
- Compiling Applications
-
- To compile your application, I recommend starting with example
- one in the self-extracting file ex01.exe. Copy this file to a
- clean directory, then execute ex01. Here you will find a
- template file ready to compile with genex01.bat.
-
-
-
- 11
-
-
- Getting Started Using Example 1 (ex01.exe)
-
- The goal of this section is to provide you with a simple example
- to get you started. Also, to help you get started, read the
- tutorial section. This will give you an overview of how to
- automate using the AutoLibrary(tm) Program-Playback tool. You
- may run the Wyse demo if it is convenient, i.e., if you have a
- Wyse terminal handy. Regardless of whether you are able to run
- the Wyse demo, I recommend doing a quick code review of the demo.
- Start with example 1 and then look at example 2. The examples
- are in self-extracting files ex01.exe and ex02.exe. Execute
- these programs in clean directories to extract the files.
-
- When getting started with something new, it is nice to know the
- minimum that is required. Therefore, I have supplied a template
- file (template.c from ex01.exe) that contains the minimum
- required for the AutoLibrary(tm) Program-Playback tool. The
- following code is a listing of template.c.
-
-
-
- 12
-
-
- /* template.c */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "al.h"
-
- /*****/
- void EveryChar(c)
- int c;
- /*****/
- {
- /* Print each character received. */
- printf("%c", c);
- }
-
- /*****/
- void main(argc, argv)
- /*****/
- int argc;
- char *argv[];
- {
- int com;
- int err, add_info;
-
- argc = argc; /* for compiler. */
- argv = argv; /* for compiler. */
-
- /* Initial AutoLibrary. */
- AvidInitAutoLibrary(AVID, &add_info, "_B'3'");
-
- /* Open the communication port. */
- com = AvidOpenPort(AVID, "com1", &add_info,
- ".b'9600' .1 .8 .n +S -H");
-
- /* Display AutoLibrary version. */
- AvidVersion(AVID, &add_info, "");
-
- /* Ready for automation. */
-
- /* Finished so close the com port. */
- AvidClosePort(AVID, com, &add_info, "");
-
- /* Exit from AutoLibrary. */
- AvidExitAutoLibrary(AVID, &add_info, "");
- }
-
-
-
- 13
-
- The above template program has been supplied with this product
- and can be compiled. If the following automation sequence was
- added to the template file, it would send "Hello World" to
- whatever the PC was connected to. Then it would wait for the
- string "Hello Back".
-
- AvidRegisterSend(AVID, com, "Hello World", &add_info, "");
- AvidRegisterWait(AVID, com, 1, "Hello Back", &add_info, "");
- if ((AvidSendSearch(AVID, com,(long)20, (long)120,
- &add_info, "")) == 1)
- printf("Found Hello Back.\n");
- else
- printf("Timeout occurred.\n");
-
- If you add this code and connect your PC to a terminal or a PC
- running terminal emulation software, you will see the "Hello
- World" string printed. Then, from the terminal or PC running
- terminal emulation software, you can type in the string "Hello
- Back", which would result in a successful automation sequence.
-
- This example is small, but it gives you a feel for how automation
- works. A command string is sent out, then one or more strings
- are scanned for.
-
- Note that this example is a bit odd. Normally, automation
- programs are connected to programs or equipment that can
- communicate on there own. For this example, you simulated
- something being automated when you typed in "Hello Back".
-
-
-
- 14
-
-
- Getting Started Using Example 2 (ex02.exe)
-
- To run the wyse terminal demo you will need to connect
- communication port one (com1) of a PC to a Wyse 30, Wyse 50, or
- Wyse 60. For a Wyse 60 terminal, invoke the setup and select the
- Wyse 50 compatibility mode. When connecting the PC to the
- terminal, a null modem may be required.
-
- The wyse terminal demo is executed from a command line interface
- that works much like a Unix utility. The code in wyse1.c is the
- program control code, where as, the code in wyse.c is the
- automation routines.
-
- By typing in 'wyse' (without options), a help screen is
- displayed. For example...
-
- C:\EX02\>wyse
-
- Usage: wyse <options>
-
- Where: <options> are...
- +a --- Run all tests.
- .A --- Abort program if an error occurs. (Default is continue)
- -L --- Run long version of tests.
- +p --- Run protected mode test.
- -a --- Run screen attributes test.
- +s --- Run screen location test.
- +P --- Run screen print test.
-
- The following will run all of the tests and abort if there is an
- error.
-
- C:\EX02\>wyse +a .A
-
- The following will run the Screen Attributes test and the
- Protected Mode test. The long versions of these tests will be
- run if they exist.
-
- C:\EX02\>wyse -a +p -L
-
- One of the tests has been coded to purposely report errors. This
- will demonstrate what error messages look like.
-
-
-
- 15
-
-
- A Tutorial
-
- The goal of this tutorial is to introduce you to automation using
- the AutoLibrary(tm) Program-Playback tool.
-
- This tutorial uses a PC and a Wyse 50 terminal. The serial
- connection between the PC and the Wyse 50 terminal places the PC
- in the unusual role of "host computer." On the other hand,
- everything seems normal to the terminal, which displays
- characters when received and sends characters when typed in. The
- Wyse 50 does not know it is connected to a PC.
-
- Once the PC and Wyse 50 are connected, we can write automation
- routines that send and receive from the terminal. This tutorial
- focuses on a Wyse 50 command that allows host computers to
- identify the terminal. The command has the format "ESC<space>",
- and is one of many Wyse 50 escape codes. When the Wyse 50
- receives this command, it returns the string "50\r". The '\r'
- character is the C notation for a return character. The
- following code segment is the first of many that will use the
- "ESC<space>" escape command to illustrate automation techniques
- using the AutoLibrary(tm) Program-Playback tool.
-
- sprintf(temp_s, "%s ", ESC_CODE);
- AvidRegisterSend(AVID, com, temp_s, &add_info, "");
- AvidRegisterWait(AVID, com, 1, "50", &add_info, "");
-
- register_value = AvidSendSearch(AVID,
- com,(long)5, (long)10, &add_info, "");
-
- The calls to AvidRegisterSend and AvidRegisterWait result in two
- linked lists being built for AvidSendSearch: the send-list and
- the wait-list. The call to AvidRegisterSend does not actually
- send the string. Instead, AvidSendSearch sends all of the
- strings in the send-list and then begins a search for the strings
- in the wait-list.
-
- In this example, AvidSendSearch sends the command "ESC<space>" to
- the Wyse 50 terminal, then begins a search for the string "50".
- The value returned depends on the outcome of the search. If the
- string "50" is found, the return value will be 1. If the string
- "50" is not found, the value 0 will be returned. Zero is always
- returned when none of the strings in the wait-list are found.
- Notice, when the string is found, the returned value depends on
- what was registered. In this example, the string "50" was
- registered with 1. It could have been registered with the value
- 527, which would cause AvidSendSearch to return 527 when the
- string was found.
-
-
-
- 16
-
-
- It is possible to register more than one string in the send-
- list. However, this is not done very often, since complicated
- send strings can be built using 'sprintf'. It is different for
- the wait-list. Your programs will have multiple wait strings
- many times. Since the Wyse 30, Wyse 50, and Wyse 60 have
- compatibility modes, it makes sense to write the above sample
- code segment as follows.
-
- sprintf(temp_s, "%s ", ESC_CODE);
- AvidRegisterSend(AVID, com, temp_s, &add_info, "");
-
- AvidRegisterWait(AVID, com, 1, "30", &add_info, "");
- AvidRegisterWait(AVID, com, 2, "50", &add_info, "");
- AvidRegisterWait(AVID, com, 3, "60", &add_info, "");
-
- register_value = AvidSendSearch(AVID, com,
- (long)5, (long)10, &add_info, "");
-
- Nothing is different except for the two additional calls to
- AvidRegisterWait. These calls allow AvidSendSearch to search for
- the strings "30", "50", and "60" at the same time.
- AvidSendSearch will return 1 if connected to a Wyse 30, 2 if
- connected to a Wyse 50, and 3 for a Wyse 60. ERR_SNF (Zero) is
- returned if none of these terminals are connected.
-
- Now, suppose the PC's serial port is disconnected. Given the
- above code segment, AvidSendSearch will timeout and return
- ERR_SNF (String-Not-Found).
-
- The AutoLibrary(tm) Program-Playback tool supports two types of
- timeouts: A Repeating Timeout and an Ending Timeout. Before
- defining repeating and ending timeouts, notice that the basic
- model of automation requires timeouts. Automation is
- programmatically sending a keystroke sequence, then scanning the
- output for a list of expected responses. When none of the
- expected responses are found, a timeout must occur. The program
- will enter an endless loop without a timeout feature.
-
- A repeating timeout starts over after each received character.
- Therefore, if a repeating timeout of 10 seconds is specified, the
- timeout will not occur unless there is communication silents for
- 10 seconds. A timeout will never occur if characters are
- continuously received. An ending timeout, on the other hand, is
- not reset with each newly received character. If an ending
- timeout of 20 seconds is specified, a timeout will occur in 20
- seconds regardless, assuming none of the expected responses are
- received.
-
-
-
- 17
-
- These two types of timeouts can play an important role in writing
- correct automation "scripts." The repeating timeout can be given
- a reasonable timeout value and still be able to handle many
- variations in input. The ending timeout can be given a large
- value, which could indicate an error condition. When
- AvidSendSearch returns ERR_SNF due to a timeout, the return
- parameter 'add_info' will be set to ERR_ENDING_TIMEOUT or
- ERR_REPEAT_TIMEOUT.
-
- A topic that is related to timeouts is draining communication
- ports. Draining a communication port is simply reading in
- characters while ignoring them for a specified amount of time.
- The time period to drain a communication port can be a Repeating
- Drain and an Ending Drain. A repeating drain starts over with
- each newly received character. There needs to be communication
- silents for repeating drains to stop. An ending drain will stop
- after the specified amount of time regardless of communication
- activity.
-
- The following is the same sample code segment with the additional
- call to AvidDrainPort.
-
- sprintf(temp_s, "%s ", ESC_CODE);
- AvidRegisterSend(AVID, com, temp_s, &add_info, "");
-
- AvidRegisterWait(AVID, com, 1, "30", &add_info, "");
- AvidRegisterWait(AVID, com, 2, "50", &add_info, "");
- AvidRegisterWait(AVID, com, 3, "60", &add_info, "");
-
- register_value = AvidSendSearch(AVID, com,
- (long)5, (long)10, &add_info, "");
-
- AvidDrainPort(AVID, com, (long)1, (long)3, &add_info, "");
-
- This drains the communication port of the <cr> character.
- Remember that when a Wyse 50 terminal receives the "ESC<space>"
- command, it returns "50<cr>". However, the wait-list contains
- only the string "50", which causes the <cr> character not to be
- read in. To guard against the <cr> character effecting the next
- automation sequence, it is drained.
-
- Another way to make sure the <cr> is read in, is to include it in
- the wait string. The following example demonstrates this.
-
- sprintf(temp_s, "%s ", ESC_CODE);
- AvidRegisterSend(AVID, com, temp_s, &add_info, "");
-
- AvidRegisterWait(AVID, com, 1, "30\r", &add_info, "");
- AvidRegisterWait(AVID, com, 2, "50\r", &add_info, "");
-
-
-
- 18
-
- AvidRegisterWait(AVID, com, 3, "60\r", &add_info, "");
-
- register_value = AvidSendSearch(AVID, com,
- (long)5, (long)10, &add_info, "");
-
- You will notice the call to AvidDrainPort is gone and the '\r'
- character has been added to the wait strings. For this example,
- adding the '\r' character is better than calling AvidDrainPort,
- only because the one second delay in AvidDrainPort is avoided.
- The two methods, otherwise, result in the same thing.
-
- In general, draining is needed when there are leftover characters
- after an automation sequence has finished. In the above example,
- the '\r' was a leftover character. You will find draining
- communication ports very useful when the leftover characters of
- an automation sequence varies.
-
- The following code segment will be familiar by now. It sends the
- "ESC<space>" command to the Wyse 50 terminal then scans for the
- string "50". When finished, the '\r' character is drained.
-
- sprintf(temp_s, "%s ", ESC_CODE);
- AvidRegisterSend(AVID, com, temp_s, &add_info, "");
-
- AvidRegisterWait(AVID, com, 1, "50", &add_info, "");
-
- register_value = AvidSendSearch(AVID, com,
- (long)5, (long)10, &add_info, "");
-
- AvidDrainPort(AVID, com, (long)1, (long)3, &add_info, "");
-
- The following code segment works the same way as above, but uses
- switches instead.
-
- sprintf(temp_s, ".s'%s ' 1w'50' .d'1'", ESC_CODE);
- value = AvidSendSearch(AVID, com, (long)5, (long)10,
- &add_info, temp_s);
-
- With switches, the same automation sequence can be accomplished
- with one call to AvidSendSearch. The .s'%s ' switch adds the
- "ESC<space>" string to the send-list, the 1w'50' switch adds the
- string "50" to the wait-list, and the switch .d'1' indicates
- there is to be a drain after the automation sequence has
- finished. These switches replace the need to call
- AvidRegisterSend, AvidRegisterWait, and AvidDrainPort explicitly.
- Here is the same call again with two additional wait strings.
-
-
-
- 19
-
-
- sprintf(temp_s, ".s'%s ' 7w'30' 6w'50' 9w'60' .d'1'", ESC_CODE);
- value = AvidSendSearch(AVID, com, (long)5, (long)10,
- &add_info, temp_s);
-
- In this example, AvidSendSearch will send the "ESC<space>"
- command then search for the strings "30", "50", and "60". If the
- string "30" is found, AvidSendSearch returns 7, if "50" is found,
- 6 is returned and if "60" is found, 9 will be returned.
-
- Notice that the switch .D'3' would also be required to make the
- switched version match the unswitched version exactly. The .d'1'
- switch causes a Repeating Drain for one second and the .D'3'
- would cause a 3 second Ending Drain.
-
- The "ESC<space>" command would make a nice general purpose
- routine that other parts of the automation program could call.
- Here is a boolean function that returns TRUE if a Wyse 30, 50, or
- 60 is connected and FALSE if not.
-
- /****************/
- int wyse_terminal(com)
- int com;
- /****************/
- {
- char temp_s[85];
- int err;
- int add_info;
-
- /*
- Test to see if connected to a Wyse terminal.
- Use the command ESC<space>
- Where:
- <space> is a blank space.
-
- The Wyse terminal will return 30\r, 50\r, or 60\r
- */
-
- sprintf(temp_s, ".s'%s ' 1w'30' 2w'50' 3w'60' .d'1'",
- ESC_CODE);
- if ((err = AvidSendSearch(AVID, com, (long)1, (long)3,
- &add_info, temp_s)) <= ERR_SNF)
- return(FALSE);
- else
- return(TRUE);
- }
-
- Since all error codes are returned as negative numbers, the test
- for less than or equal to ERR_SNF will work fine. This just
-
-
-
- 20
-
- means that FALSE will be returned if none of the strings in the
- wait-list are found or an error is returned by AvidSendSearch.
- TRUE will be returned if AvidSendSearch returns 1, 2, or 3.
- Other parts of the program would then be able to make calls like
- the following.
-
- /* Before testing begins, make sure we are cable correctly. */
- if ( !wyse_terminal(com)) {
- AvidLogInfo(AVID, com, "Bad connection to Wyse terminal",
- BAD_CONNECTION, &add_info, "");
- }
-
- Since the automation routine 'wyse_terminal' is of general use,
- it could be put in a function library with other automation
- routines written for wyse terminals. The library could then be
- distributed to other members of the programming staff. Creating
- general use automation routines allows automation programs to be
- written like regular programs using a modular design.
-
- The following routine is an improvement on the 'wyse_terminal'
- routine. It will return a constant that specifies the type of
- wyse that is connected.
-
-
-
- 21
-
- /****************/
- int terminal_type(com)
- int com;
- /****************/
- {
- char temp_s[85];
- int err;
- int add_info;
-
- /*
- Test to see if connected to a Wyse terminal.
- Use the command ESC<space>
- Where:
- <space> is a blank space.
-
- The Wyse terminal will return 30\r, 50\r, or 60\r
- */
-
- sprintf(temp_s, "%s ", ESC_CODE);
- AvidRegisterSend(AVID, com, temp_s, &add_info, "");
-
- AvidRegisterWait(AVID, com, WYSE_30, "30", &add_info, "");
- AvidRegisterWait(AVID, com, WYSE_50, "50", &add_info, "");
- AvidRegisterWait(AVID, com, WYSE_60, "60", &add_info, "");
-
- return(AvidSendSearch(AVID, com, (long)2, (long)5,
- &add_info, ".d'1'.D'3'"));
- }
-
- Other parts of the program would then be able to make calls like
- the following.
-
- /* Before testing Wyse 50 features, make sure this is a Wyse 50.
- */
- if ( terminal_type(com) != WYSE_50)
- return;
-
- Notice that the 'terminal_type' routine uses AvidRegisterSend and
- AvidRegisterWait to build the send-list and wait-list. This is a
- nice way to code this routine because of the constants WYSE_30,
- WYSE_50, and WYSE_60. These constants would be defined in a
- global header file and can be given any valid values. If
- switches were used like in previous examples, WYSE_30 would have
- to be defined as 1, WYSE_50 as 2, and WYSE_60 as 3. It is best
- that the 'terminal_type' routine not be required to match the
- constant definitions.
-
-
-
- 22
-
- The call to AvidSendSearch uses the .d'1' and .D'3' switches to
- drain the communication port. An explicit call to AvidDrainPort
- would have yielded the same result.
-
- The above implementation of 'terminal_type' is a very good way to
- code this automation routine. However, I would like to code it a
- different way to demonstrate AvidSendSearch's ability to capture
- strings. By adding the switch -c'2' and the parameters 'actual'
- and 'captured' to AvidSendSearch, a string capture is possible,
- as the following code segment will show.
-
- /****************/
- int terminal_type(com)
- int com;
- /****************/
- {
- char temp_s[85];
- int err, add_info;
- char captured[50];
- long actual;
-
- /*
- Test to see if connected to a Wyse terminal.
- Use the command ESC<space>
- Where:
- <space> is a blank space.
-
- The Wyse terminal will return 30\r, 50\r, or 60\r
- */
-
- sprintf(temp_s, ".s'%s ' 1w'\r' .d'1' .D'3' -c'2'",
- ESC_CODE);
- if ((err = AvidSendSearch(AVID, com,
- (long)2, (long)5, &add_info, temp_s,
- (long *)&actual, captured)) <= ERR_SNF)
- return(err);
-
- return(atoi(captured));
- }
-
- The -c'2' switch causes two characters to be captured. After the
- Wyse 50 receives the "ESC<space>" command, it returns 3
- characters. First, the character is '5', then '0', and then the
- return character '\r'. The capture string starts out empty, then
- fills up during the automation sequence. The following list
- shows how the capture string fills.
-
-
-
- 23
-
- "" - String empty.
- "5" - First character received.
- "50" - Next character received.
- "50" - The return character received.
-
- When the return character is received, the automation sequence
- stops. Notice that the wait string ("\r" here) is not part of
- the captured string.
-
- Suppose the Wyse 50 responds to the "ESC<space>" command
- differently. Instead of "50\r", say the Wyse 50 terminal
- returned "Wyse50\r". The code above will still work by capturing
- only the string "50". However, the capture string will fill up
- differently as shown below.
-
- "" - String empty.
- "W" - First character received.
- "Wy" - Next character received.
- "ys" - Next one.
- "se" - Next one.
- "e5" - Next one.
- "50" - Next one.
- "50" - The return character received.
-
- This illustrates how the capture will start ignoring characters
- by letting them drop off of the end.
-
- The actual number of characters in the capture string may be less
- than the amount specified in the switch. This happens when the
- automation sequence ends before the capture string is filled.
- Also, since NULL characters can be part of the input stream, the
- actual number of characters in the captured string is passed back
- to you in the parameter 'actual'. Strlen(captured) may not equal
- the actual number of characters in the captured string due the
- NULL characters.
-
- There are actually two types of string captures possible from
- AvidSendSearch. The above sample code demonstrated the first
- type, which is initiated with the switch -c'x', where x is the
- maximum number of characters to capture. The second type of
- capture is invoked with the +c'x' switch, where x, again, is the
- number of characters to capture. However, there is a big
- difference between these two types of captures. The first type
- (-c'x') starts pushing the oldest characters out of the capture
- string after x characters have been received. The second type of
- capture (+c'x'), on the other hand, stops the automation sequence
- when the capture string is full.
-
-
-
- 24
-
- Before demonstrating the +c'x' capture, a little history. When I
- first wrote the AutoLibrary(tm) Program-Playback tool,
- AvidSendSearch did not support capturing strings. Instead, the
- only way to get captured strings were to extract them from a hold
- area with the routine AvidGetFromHoldArea. Using
- AvidGetFromHoldArea is still a valid way to get capture strings,
- which the following code segment will show. You will notice this
- code segment gives the same results as the code segment above
- that uses the -c'2' switch.
-
- /****************/
- int terminal_type(com)
- int com;
- /****************/
- {
- char temp_s[85];
- int err, add_info;
- char captured[50];
- long actual;
-
- /*
- Test to see if connected to a Wyse terminal.
- Use the command ESC<space>
- Where:
- <space> is a blank space.
-
- The Wyse terminal will return 30\r, 50\r, or 60\r
- */
-
- sprintf(temp_s, ".s'%s ' 1w'\r' .d'1' .D'3'", ESC_CODE);
- if ((err = AvidSendSearch(AVID, com, (long)2, (long)5,
- &add_info, temp_s)) <= ERR_SNF)
- return(err);
-
- actual = AvidGetFromHoldArea(AVID, com, 1, 2,
- captured, &add_info, "");
-
- return(atoi(captured));
- }
-
- You will find AvidGetFromHoldArea useful in your automation
- routines because of its ability to extract from anywhere in the
- hold area and be able to span across data that was received from
- multiple automation sequences. AvidGetFromHoldArea is a general
- utility for extracting capture strings. However, I found that
- for the vast majority of strings that I wanted to capture,
- convenience was more important. Therefore, I added the capture
- switch to AvidSendSearch. Internally, AvidSendSearch calls
- AvidGetFromHoldArea with the correct parameters. This process of
-
-
-
- 25
-
- capturing strings seemed very natural to me. The process where
- AvidSendSearch does not worry about the capture string until the
- automation sequence is over. Then it looks backwards into the
- hold area to extract out the capture string. This method of
- looking backwards into the hold area led naturally to the second
- type of capture. Namely, a forward looking capture. One that
- would start putting characters into the capture string as they
- were received from the communication port. One where
- AvidSendSearch worries about the capture string before the
- automation sequence starts.
-
- The forward looking capture is invoked with the switch +c'x'.
- This type of capture will be referred to as a Positive Capture.
- The backward looking capture is invoked with the switch -c'x' and
- is referred to as a Negative Capture. Just remember the minus
- sign '-' as the Negative Capture and the plus character '+' as
- the Positive Capture. Also, remember that the Negative Capture
- looks backwards into the hold area after the automation sequence
- has finished. Where as, the Positive Capture looks forward and
- builds the capture string as the automation sequence is
- occurring. The Positive Capture will terminate the automation
- sequence if the capture string is full. The Negative Capture
- will never end the automation sequence.
-
- It is useful to again code the Wyse 50's host identification
- command "ESC<space>" using a Positive Capture.
-
-
-
- 26
-
- /****************/
- int terminal_type(com)
- int com;
- /****************/
- {
- char temp_s[85];
- int err, add_info;
- char captured[50];
- long actual;
-
- /*
- Test to see if connected to a Wyse terminal.
- Use the command ESC<space>
- Where:
- <space> is a blank space.
-
- The Wyse terminal will return 30\r, 50\r, or 60\r
- */
-
- sprintf(temp_s, ".s'%s ' .d'1' .D'3' +c'2'", ESC_CODE);
- if ((err = AvidSendSearch(AVID, com,
- (long)2, (long)5, &add_info, temp_s,
- (long *)&actual, captured)) <= ERR_SNF)
- return(err);
-
- return(atoi(captured));
- }
-
- The +c'2' switch specifies a Positive Capture of two characters.
- The following list shows how the capture string is filled.
-
- "" - String empty.
- "5" - First character received.
- "50" - Next one.
- "50" - The automation sequence ends because the
- capture string is full.
- - The drain switches .d'1' and .D'3' will
- drain the '\r' character.
-
- Suppose, as we did with the Negative Capture, that the Wyse 50
- returned "Wyse50\r" instead of "50\r". Remember the examples
- showed the resulting capture string was "50" regardless of
- whether the Wyse 50 returned "Wyse50\r" or "50\r". The result is
- different, however, for Positive Captures, as the following list
- will show.
-
-
-
- 27
-
- "" - String empty.
- "W" - First character received.
- "Wy" - Next character received.
- "Wy" - The automation sequence ends with this as
- the capture string. - The drain switches then
- drain the characters "se50\r" (Not what is
- desired).
-
- As you can see the result is not what was desired. However,
- since we know the Wyse 50 really will return "50\r", both capture
- methods work fine.
-
- Again, suppose the Wyse 50 worked yet another way, where say, all
- terminal made before 1983 returned "Wyse50\r" and all terminals
- made after 1983 returned "50\r". To make our automation routine
- work with both types of Wyse 50 terminals, the routine that uses
- the Negative Capture would be the only correct solution.
-
- I would like to describe the Positive Capture again with a better
- suited example. The previous examples were good, however, they
- compared the Positive Capture with the Negative Capture in a
- situation where the Negative Capture was the best choice. Now I
- would like to describe an example that is better suited for a
- Positive Capture.
-
- One place where the Positive Capture is best suited, is when the
- string to key off of is before the information to be captured.
- Before describing a new example, the Reference Manual does have a
- good example for Positive Captures, which captures information
- about the current whether conditions. In this example, the
- string "Temperature" is always displayed before the current
- temperature. First, a call is made to AvidSendSearch that waits
- for the string "Temperature", then another AvidSendSearch call is
- made to actually capture the temperature. A complete description
- of this example can be found in the reference guide in the
- section that describes AvidSendSearch.
-
- Another place where the Positive Capture is best suited is when
- the number of characters to capture needs to have an upper limit.
- The following code captures the next 80 characters of an input
- stream.
-
- AvidSendSearch(AVID, com,
- (long)10, (long)60, &add_info,
- "+c'80' 1w'\r' 2w'\n'", (long *)&actual, captured);
-
- This piece of code would be used for reading in a "line" of data
- much like a line of data would be read from a file. When 80
- characters have been received, AvidSendSearch will return with
-
-
-
- 28
-
- the 80 characters in the capture string and the automation
- sequence would be finished. If, however, a newline character
- ('\n') or a return character ('\r') is received, AvidSendSearch
- would return with less than 80 characters in the capture string.
-
- Notice there were no send strings. It is ok (and common) for
- AvidSendSearch to be called without a send string. For
- instances, a previous call to AvidSendSearch may have already
- started an input stream. It is also possible, depending on the
- type of application or device that is being automated, that an
- input stream does not need initiated, i.e., characters will be
- coming in as soon as the port is opened.
-
- The following code segment adds to the previous one. Here,
- AvidSendSearch is put in a while loop. AvidSend is used to send
- the command that starts the data flowing.
-
- AvidSend(AVID, com, "facts\r", &add_info, "");
-
- while (( err = AvidSendSearch(AVID, com,
- (long)10, (long)60, &add_info,
- "+c'80' 1w'\r' 2w'\n'",
- (long *)&actual, captured)) >= ERR_SNF) {
-
- /* It is ok for err to equal ERR_SNF if caused by capture
- string filling up. */
- if ((err == ERR_SNF) && (add_info != ERR_CAPTURE_FULL))
- break;
-
- /* Write captured string to a file. */
- fprintf(cap_file, "%s\n", captured);
- }
-
- Notice that AvidSend was used to send the command 'facts' to the
- host computer. AvidSendSearch could have been used, with
- "facts\r" registered in the send-list and nothing registered in
- the wait-list. However, AvidSend is a better choice here.
- AvidSendSearch would have been a better choice if any of the
- other AvidSendSearch features were needed, such as, draining the
- communication port.
-
- This is the first example that uses 'add_info'. 'Add_info' is a
- return parameter that allows your automation programs to get more
- information on why an error occurred. This example needs to know
- why the ERR_SNF was returned. If ERR_SNF was returned due to a
- timeout, 'add_info' will return with ERR_REPEAT_TIMEOUT or
- ERR_ENDING_TIMEOUT.
-
-
-
- 29
-
- Notice the above example compares 'add_info' to ERR_CAPTURE_FULL.
- This is the best way to find out if the automation sequence
- should continue. When ERR_SNF is returned due to the capture
- string being full, more characters are out there to capture.
-
- Now to summarize what we have looked at so far. This tutorial
- has introduced you to the following routines.
-
- AvidDrainPort --- Drains a communication port.
-
- AvidGetFromHoldArea --- Gets a string from the hold area.
-
- AvidLogInfo --- Log messages to a log file.
-
- AvidRegisterSend --- Registers a string in the send-list.
-
- AvidRegisterWait --- Registers a string in the wait-list.
-
- AvidSend --- Sends a string.
-
- Here is a list of the routines that I would like to introduce
- now.
-
- AvidClosePort --- Closes an AutoLibrary port.
-
- AvidExitAutoLibrary --- Exit from AutoLibrary.
-
- AvidInitAutoLibrary --- Initializes AutoLibrary.
-
- AvidOpenPort --- Opens an AutoLibrary port.
-
- AvidVersion --- Displays the AutoLibrary version.
-
- The following example uses these routines to put it all together.
- The example will call the routine 'terminal_type' to determine
- the type of terminal connected. It will then print the answer to
- the screen.
-
-
-
- 30
-
-
- #include <stdio.h>
- #include <stdlib.h>
-
- #include "al.h"
-
- /******/
- void main(argc, argv)
- /******/
- int argc;
- char *argv[];
- {
- int com;
- int add_info;
-
- /* Initial AutoLibrary. */
- AvidInitAutoLibrary(AVID, &add_info, "_B'3'");
-
- /* Open the communication port. */
- com = AvidOpenPort(AVID, "com1", &add_info,
- ".b'9600' .1 .8 .n +S -H");
-
- /* Display AutoLibrary version. */
- AvidVersion(AVID, &add_info, "");
-
- /* Display the type of Wyse Terminal that is out there. */
- if ((term_type = terminal_type(com)) = 0)
- printf("Not connected to a Wyse 30, 50, or 60\n");
- else
- printf("Connected to a Wyse %i terminal\n", term_type);
-
- /* Finished so close the com port. */
- AvidClosePort(AVID, com, &add_info, "");
-
- /* Finished so exit from AutoLibrary. */
- AvidExitAutoLibrary(AVID, &add_info, "");
- }
-
-
-
- 31
-
- /****************/
- int terminal_type(com)
- int com;
- /****************/
- {
- char temp_s[85];
- int err, add_info;
- char captured[50];
- long actual;
-
- /*
- Test to see if connected to a Wyse terminal.
- Use the command ESC<space>
- Where:
- <space> is a blank space.
-
- The Wyse terminal will return 30\r, 50\r, or 60\r
- */
-
- sprintf(temp_s, ".s'%s ' 1w'\r' .d'1' .D'3' -c'2'",
- ESC_CODE);
- if ((err = AvidSendSearch(AVID, com,
- (long)2, (long)5, &add_info, temp_s,
- (long *)&actual, captured)) <= ERR_SNF)
- return(err);
-
- return(atoi(captured));
- }
-
- Now all of the routines in the AutoLibrary(tm) Program-Playback
- tool have been introduced in this tutorial except for the
- following.
-
- AvidConvert --- Utility routine that converts characters to
- strings.
-
- AvidLogOpen --- Open a log file for AvidLogInfo to use.
-
- AvidProcessOptions --- Used to process the options
- parameter.
-
- AvidRead --- Reads one character.
-
- AvidConvert and AvidProcessOptions are utility routines that your
- automation programs may use. AvidConvert converts characters
- into strings. When a character is not printable, AvidConvert
- will change it to a printable string. AvidProcessOptions is the
- routine that is used internally to process the option parameter.
- Your programs can use this routine if you also want to support an
-
-
-
- 32
-
- options parameter. AvidLogOpen opens a log file for AvidLogInfo
- to use.
-
- AvidRead is used internally by AvidDrainPort and AvidSendSearch.
- Your automation programs should not require this routine. It was
- included only for completeness. The Reference Guide has a more
- information on these routines.
-
- This concludes the tutorial of the AutoLibrary(tm) Program-
- Playback tool. I hope this section has given you a feel for how
- automation is done using this tool.
-
-
-
- 33
-
-
- Reference Guide For the AutoLibrary(tm) Program-Playback tool
-
- The following is the reference guide for the AutoLibrary(tm)
- Program-Playback tool. Each routine is described along with its
- parameters and options. Examples are supplied for each routine.
-
-
-
- 34
-
-
- AvidClosePort - Close Communication Port
-
- err = AvidClosePort(AVID, com, (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- AVID -- System parameter that must always be specified.
-
- int com; -- The communications port to close.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- NONE
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
- ERR_COMM_PACKAGE -- This error can occur when the
- communication package cannot close the
- communication port correctly. When this
- error occurs, the parameter 'add_info' will
- contain the actual error returned by the
- communication package.
-
- ERR_INVALID_PORT -- This error can occur when the
- communication port specified in the 'com'
- parameter was not a valid opened port.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_COMM_PACKAGE is returned, 'add_info'
- contains the actual error returned by the
- communication package.
-
-
- AvidClosePort
-
-
-
- 35
-
-
- Description
-
- This routine closes the communication port that was opened by
- AvidOpenPort. All of the memory allocated by AvidOpenPort is
- freed. This routine calls CommInterfaceClose so the
- communication port of the comm package can be closed. This
- routine will close the log if one was opened by AvidLogOpen.
-
- Examples
-
- The following example assumes there will not be any problems
- closing the port.
-
- AvidClosePort(AVID, com, &add_info, "");
-
- The following example checks for problems when closing the port.
-
- if ((err = AvidClosePort(AVID, com, &add_info, "")) != ERR_OK)
- printf("Error = %d, Additional Info = %d\n", err, add_info);
-
- See Also
-
- AvidOpenPort, CommInterfaceClose
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidClosePort
-
-
-
- 36
-
-
- AvidConvert - Convert Characters to Strings
-
- err = AvidConvert(c, s, (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- int c; -- Character to be converted.
-
- char *s; -- Returned string.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- NONE
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- Description
-
- This routine converts characters into strings. Each of the non-
- printable characters are converted into a coded string. For
- example, the character '\0' would return as "[NUL]". This
- routine is useful in EveryChar, which was the main reason this
- routine was written. The following lists how each of the non-
- printable characters are returned.
-
- 0 - [NUL]
- 1 - [SOH]
- 2 - [STX]
- 3 - [ETX]
- 4 - [EOT]
- 5 - [ENQ]
- 6 - [ACK]
- 7 - [BEL]
- 8 - [BS]
-
-
- AvidConvert
-
-
-
- 37
-
- 9 - [HT]
- 10 - [LF]
- 11 - [VT]
- 12 - [FF]
- 13 - [CR]
- 14 - [SO]
- 15 - [SI]
- 16 - [DLE]
- 17 - [DC1]
- 18 - [DC2]
- 19 - [DC3]
- 20 - [DC4]
- 21 - [NAK]
- 22 - [SYN]
- 23 - [ETB]
- 24 - [CAN]
- 25 - [EM]
- 26 - [SUB]
- 27 - [ESC]
- 28 - [FS]
- 29 - [GS]
- 30 - [RS]
- 31 - [US]
-
- 127 - [DEL]
-
- Examples
-
- The following code will print all characters received from the
- communication port in a tty like mode.
-
- /*****/
- void EveryChar(c)
- int c;
- /*****/
- {
- char s[20];
- int add_info;
-
- AvidConvert(c, s, &add_info, "");
- printf("%s", s);
- }
-
- See Also
-
- EveryChar
-
-
-
- AvidConvert
-
-
-
- 38
-
-
- AvidDrainPort - Drain Communication Port
-
- err = AvidDrainPort(AVID, com, (long)r_drain, (long)e_drain,
- (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- AVID -- System parameter that must always be specified.
-
- int com; -- The communications port to drain.
-
- long r_drain; -- The number of seconds to drain the
- communication port. The drain time will start
- over after each character received. (A repeating
- drain)
-
- The parameter constant AVID_NO_TIMEOUT will cause
- AvidDrainPort to never stop draining due to a
- repeating drain value.
-
- NOTE: AvidDrainPort will drain forever if
- AVID_NO_TIMEOUT is used for both 'r_drain' and
- 'e_drain'.
-
- long e_drain; -- The number of seconds to drain the
- communication port. The drain time will NOT start
- over after each character received. (An ending
- drain)
-
- The parameter constant AVID_NO_TIMEOUT will cause
- AvidDrainPort to never stop draining due to an
- ending drain value.
-
- NOTE: AvidDrainPort will drain forever if
- AVID_NO_TIMEOUT is used for both 'r_drain' and
- 'e_drain'.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- NONE
-
-
- AvidDrainPort
-
-
-
- 39
-
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
- ERR_COMM_PACKAGE -- This error can occur when AvidDrainPort
- reads from the communication port. When this
- error occurs, the parameter 'add_info' will
- contain the actual error returned by the
- communication package.
-
- ERR_INVALID_PORT -- This error can occur when the
- communication port specified in the 'com'
- parameter was not a valid opened port.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_COMM_PACKAGE is returned,
- 'add_info' contains the actual error returned
- by the communication package.
-
- Description
-
- This routine drains a communication port. The drain time can be
- specified as a repeating timeout or as an ending timeout. This
- routine can be called out explicitly or it is possible to drain a
- communication line directly from AvidSendSearch by using
- switches.
-
- Examples
-
- The following example will drain the communication port until
- there is 2 seconds of communications silents. If there is not
- communications silents for 2 seconds, the drain will stop after
- 20 seconds.
-
- err = AvidDrainPort(AVID, com, (long)2, (long)20, &add_info, "");
-
- The following example will drain the communication port until
- there is 4 seconds of communications silents. If there is never
- communications silents this call will never return.
-
-
- AvidDrainPort
-
-
-
- 40
-
-
- err = AvidDrainPort(AVID, com, (long)4, AVID_NO_TIMEOUT,
- &add_info, "");
-
- The following example will drain for 5 seconds paying no
- attention to the communication activity.
-
- err = AvidDrainPort(AVID, com, AVID_NO_TIMEOUT, (long)5,
- &add_info, "");
-
- See Also
-
- AvidSendSearch (Especially .D and .d switches)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidDrainPort
-
-
-
- 41
-
-
- AvidExitAutoLibrary - Exit AutoLibrary
-
- err = AvidExitAutoLibrary(AVID, (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- AVID -- System parameter that must always be specified.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- NONE
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
- ERR_CANNOT_EXIT -- All of the AutoLibrary ports need to be
- closed first with AvidClosePort.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- Description
-
- This routine exits from the AutoLibrary(tm) Program-Playback
- tool. All memory and resources used by this tool are returned.
- Once AvidExitAutoLibrary is called, it is possible to call
- AvidInitAutoLibrary to again initialize the AutoLibrary(tm)
- Program-Playback tool.
-
- Examples
-
- The following call is made after the last opened port is closed
- by AvidClosePort.
-
-
-
- AvidExitAutoLibrary
-
-
-
- 42
-
- err = AvidExitAutoLibrary(AVID, &add_info, "");
-
- See Also
-
- AvidInitAutoLibrary
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidExitAutoLibrary
-
-
-
- 43
-
-
- AvidGetFromHoldArea - Get Characters from Hold Area
-
- actual = AvidGetFromHoldArea(AVID, com, (long)pos, (long)size,
- s, (int *)&add_info, opts)
-
- Parameter Description
-
- long actual; -- This is the actual number of characters in s.
- This may not match strlen(s) if null characters
- were received from the hold area.
-
- AVID -- System parameter that must always be specified.
-
- int com; -- The AutoLibrary communications port.
-
- long pos; -- This is the position in the hold area to start
- getting characters that will make up the string
- returned.
-
- long size; -- This is the size of the string to get.
-
- char *s; -- This is the string that was built by
- AvidGetFromHoldArea.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- NONE
-
- Return Codes
-
- <actual> -- Returns the number of characters in the string.
- Zero is returned when there is no characters in the
- hold area or if erroneous values where passed to it.
- For example, negative seven for the position or a
- position that is specified outside the hold area
- boundaries.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- Description
-
-
- AvidGetFromHoldArea
-
-
-
- 44
-
-
- This routine will get characters from the hold area. It is also
- possible to capture characters directly from the AvidSendSearch
- routine by specifying switches.
-
- Examples
-
- The following example will get 5 characters from the hold area
- starting at position 3. If the hold area had the characters
- "0123456789", 'capture' would have the string "34567".
-
- actual = AvidGetFromHoldArea(AVID, com, (long)3, (long)5,
- capture, &add_info, "");
-
- After the following example executed 'capture' would have the
- string "12" given the same hold area as above.
-
- actual = AvidGetFromHoldArea(AVID, com, (long)8, (long)2,
- capture, &add_info, "");
-
- See Also
-
- AvidSendSearch (Especially +c and -c switches)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidGetFromHoldArea
-
-
-
- 45
-
-
- AvidInitAutoLibrary - Initialize AutoLibrary
-
- err = AvidInitAutoLibrary(AVID, (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- AVID -- System parameter that must always be specified.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- _b'num' -- This changes the number of milliseconds to delay
- before sending the first character of the string. The
- specified value will replace the default permanently.
- (Default is 0).
-
- _B'num' -- This changes the number of milliseconds to delay
- between each character sent. The specified value will
- replace the default permanently. (Default is 0).
-
- +h'num' -- This option changes the size of the hold area. This
- value will automatically be increased if the chosen
- value is less than AvidSendSearch's capture size
- (SEND_SEARCH_CAPTURE_MAX). (Default is 512).
-
- +R -- This switch is used after your copy of AutoLibrary
- is registered. This will initialize AutoLibrary
- without printing "Unregistered Evaluation Copy" to the
- screen.
-
- Unregistered users are not allowed to use this switch.
- However, if the actual printing of "Unregistered
- Evaluation Copy" interferes with your ability to
- evaluate AutoLibrary, you may temporarily use this
- switch.
-
- Note: The +R switch does not change the functionality
- of AutoLibrary. Both the registered and unregistered
- initialization methods result in fully functional
- software.
-
-
-
- AvidInitAutoLibrary
-
-
-
- 46
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_ALREADY_INITIALIZED -- This routine cannot be called more
- than once without first call
- AvidExitAutoLibrary.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- Description
-
- This routine is used to initialize the AutoLibrary(tm) Program-
- Playback tool. This routine must be the first routine called.
- Use AvidExitAutoLibrary to uninitialize.
-
- Examples
-
- The following example initializes AutoLibrary for the
- unregistered libraries. (The unregistered libraries will print
- the message "Unregistered Evaluation Copy".
-
- err = AvidInitAutoLibrary(AVID, &add_info, "");
-
- The following example initialize AutoLibrary for the registered
- libraries. The +R switch causes the printf to not occur.
-
- err = AvidInitAutoLibrary(AVID, &add_info,"+R");
-
- See Also
-
- AvidExitAutoLibrary
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidInitAutoLibrary
-
-
-
- 47
-
-
- AvidLogInfo - Log information to file or screen.
-
- val = AvidLogInfo(AVID, com, title, user_code,
- (int *)&add_info, opts)
-
- Parameter Description
-
- int val; -- Return code or if *E switch is specified, the
- number of logged errors is returned.
-
- AVID -- System parameter that must always be specified.
-
- int com; -- The AutoLibrary communication port.
-
- char *title; -- A one line string to log.
-
- int user_code; -- An integer value that can be used in any way to
- add information to the log entry.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- +p -- Print the log message to the screen using printf. This
- switch guarantees the message will be printed, regardless of
- the current default. The default is to print, but this can
- be changed by AvidLogOpen.
-
- -p -- Do not print the message to the screen. This switch
- guarantees the message will not be printed, regardless of
- the current default. The default is to print, but this can
- be changed by AvidLogOpen.
-
- +E -- After the error has been logged, 'exit(1)' is called to
- abort further processing. This switch guarantees processing
- will abort, regardless of the current default. The default
- is to continue processing, but this can be changed by
- AvidLogOpen. This switch will only have effect on error
- messages, i.e., messages that use the *E switch.
-
- -E -- After message has been logged, continue processing. This
- switch guarantees processing will continue, regardless of
- the current default. The default is to continue processing,
- but this can be changed by AvidLogOpen.
-
-
- AvidLogInfo
-
-
-
- 48
-
-
- +L -- Log the message to the log file. This switch guarantees
- the message will be logged, regardless of the current
- default. The default is to log all messages, but this can
- be changed by AvidLogOpen. Also, this switch is only valid
- after AvidLogOpen is called to open the log file.
-
- -L -- Do not log message in the log file. This switch
- guarantees the message will not be logged, regardless of the
- current default. The default is to log all messages, but
- this can be changed by AvidLogOpen.
-
- *E -- This option directs AvidLogInfo to print the log entry as
- an error. The string "ERROR(int)," is added to the log
- message. AvidLogInfo returns the number of errors logged
- when this switch is specified. The integer that is printed
- as part of ERROR(int) is the 'user_code' parameter.
-
- *T -- This option directs AvidLogInfo to add a date and time
- stamp to the log entry.
-
- *L -- This option directs AvidLogInfo to print information that
- identifies where AvidLogInfo was called from in your source
- code. The line number and source file name will be added to
- the log message. With this information, errors can be
- traced back to the exact source line they occurred.
-
- Return Codes
-
- <Positive Number> -- The number of logged errors. This is
- possible only when the *E switch is used.
-
- ERR_OK -- No error occurred.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
- ERR_WRITING -- There was a problem writing to the log
- file.
-
- ERR_INVALID_PORT -- This error can occur when the
- communication port specified in the 'com'
- parameter was not a valid opened port.
-
- Additional Information Return Codes
-
-
-
- AvidLogInfo
-
-
-
- 49
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_WRITING is returned, 'add_info'
- will contain the system error that was
- returned by the clib call to 'fprintf'.
-
- Description
-
- This routine makes it possible to log a message to a file, to the
- screen, or to both. Switches are used to customize the format of
- a log message. The examples below will show some of the ways
- this routine can be used.
-
- Examples
-
- The following example will use this routine to log when a test
- has started. The 'user_code' is set to zero and is not used,
- since the *E switch was not specified. The *T switch will add a
- time stamp to the logged message, which will document when the
- test started. The output from this call is also shown.
-
- /* Log the type of test and when it started. */
- AvidLogInfo(AVID, com, "Executing screen location test",
- 0, &add_info, "*T");
-
- OUTPUT:
- Mon Jun 24 17:36:12 1991,Executing screen location test
-
- The following example will log an error. Notice the error
- returned from AvidSendSearch is specified as the 'user_code'
- parameter. This will help determine the cause of the error. The
- switches *E, *T, and *L add more information to the error
- message. The output from this call is also shown.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidLogInfo
-
-
-
- 50
-
- /* Make sure the cursor is where we placed it with ESC b */
- sprintf(temp_buf, ".s'%sb' 1w'C' -c'6'", ESC_CODE);
- if ((err = AvidSendSearch(AVID, com,
- (long)10, (long)30, &add_info, temp_buf,
- (long *)&actual, capture)) <= ERR_SNF) {
- num_logged = AvidLogInfo(AVID, com,
- "Cursor not placed correctly",
- err, &add_info, "*ETL");
- }
-
- OUTPUT:
- ERROR(-1002),Mon Jun 24 17:36:12 1991,(TST.C,74),Cursor not
- placed correctly
-
-
- The following example does not log the entry to the log file.
- Instead, the message is printed to the screen. The output from
- this call is also shown.
-
- /* Print Welcome message. */
- AvidLogInfo(AVID, com, "Welcome", 0, &add_info, "-L");
-
- OUTPUT:
- Welcome
-
- See Also
-
- AvidLogOpen
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidLogInfo
-
-
-
- 51
-
-
- AvidLogOpen - Open a Log File.
-
- err = AvidLogOpen(AVID, com, filename, (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- AVID -- System parameter that must always be
- specified.
-
- int com; -- The AutoLibrary communication port.
-
- char *filename; -- The file to open as a log file.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- -p -- This option changes the default for AvidLogInfo to not
- print the log message to the screen. The normal default
- prints messages to the screen using 'printf'.
-
- +E -- This option changes the default for AvidLogInfo to abort
- processing after the error has been logged. The normal
- default continues processing after logging errors. This
- switch will only have effect on error messages, i.e., those
- messages that use the *E switch.
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
- ERR_OPENING -- There was a problem opening the log file.
-
- ERR_INVALID_PORT -- This error can occur when the
- communication port specified in the 'com'
- parameter was not a valid opened port.
-
- Additional Information Return Codes
-
-
- AvidLogOpen
-
-
-
- 52
-
-
- ERR_OK -- No error occurred.
-
- Description
-
- This routine is used to open a log file that AvidLogInfo will
- use. The switches that this routine supports allows AvidLogInfo
- to have different defaults. AvidLogOpen is needed only to open a
- log file and is not required before AvidLogInfo is called.
- However, if AvidLogOpen is not called, AvidLogInfo is restricted
- to logging messages to the screen.
-
- Examples
-
- The following example will open a log file called "logfile".
-
- err = AvidLogOpen(AVID, com, "logfile", &add_info, "");
-
- The following example will again open a log file called
- "logfile". However, it will also change the defaults for
- AvidLogInfo to not print log entries to the screen and to abort
- processing after logging error messages.
-
- err = AvidLogOpen(AVID, com, "logfile", &add_info, "-p +E");
-
- See Also
-
- AvidLogInfo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidLogOpen
-
-
-
- 53
-
-
- AvidOpenPort - Open Communication Port
-
- com = AvidOpenPort(AVID, device, (int *)&add_info, opts)
-
- Parameter Description
-
- int com; -- This is the AutoLibrary port identification
- number that is used by all of the AutoLibrary
- routines.
-
- AVID -- System parameter that must always be specified.
-
- char *device; -- This is the device name of the communication
- port to open.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- _b'num' -- This changes the number of milliseconds to delay
- before sending the first character of the string. The
- specified value will replace the default permanently
- for this port. (Default is 0).
-
- _B'num' -- This changes the number of milliseconds to delay
- between each character sent. The specified value will
- replace the default permanently for this port. (Default
- is 0).
-
- +h'num' -- This option changes the size of the hold area for
- this port. This value will automatically be increased
- if the chosen value is less than AvidSendSearch's
- capture size (SEND_SEARCH_CAPTURE_MAX). (Default is
- 512).
-
- Options (Depends on implementation of CommInterfaceOpen)
-
- .b'baud' -- This will change the baud rate from the default of
- 9600 to the specified value. Choose from: 50, 75,
- 110, 134.5, 150, 300, 600, 1200, 1800, 2000, 2400,
- 3600, 4800, 7200, 9600, 19200. (Default is 9600).
-
- .1 -- One stop bit will be used. (Default).
-
-
-
- AvidOpenPort
-
-
-
- 54
-
- .2 -- Two stop bits will be used. (Default is 1).
-
- .7 -- Seven bits per word. (Default is 8).
-
- .8 -- Eight bits per word. (Default).
-
- .e -- Even parity will be used. (Default is odd).
-
- .o -- Odd parity will be used. (Default).
-
- .n -- No parity will be used. (Default is odd).
-
- -S -- This will cause the 7th bit to NOT be stripped.
- (Default is to strip).
-
- +S -- This will cause the 7th bit to be stripped.
- (Default).
-
- +X -- This will cause software (xon-xoff) flow control to
- be used. (Default).
-
- -X -- This will cause software (xon-xoff) flow control to
- not be used. (Default is on).
-
- .T -- This will cause dtr to be asserted. (Default is not
- to).
-
- rx'num' -- Changes the default receive buffer size. (Default is
- 8192).
-
- tx'num' -- Changes the default transmit buffer size. (Default
- is 512).
-
- The Greenleaf Comm Library
-
- This is a commerical communication package provided by Greenleaf
- Software, Inc. 16479 Dallas Parkway, Bent Tree Tower Two, Suite
- 570, Dallas, TX 75248, (214)248-2561.
-
- (Note: This is just one of many good communication packages. It
- is easy to write interface routines for the AutoLibrary Program-
- Playback Tool, so don't feel you are tied to any one
- communication package.)
-
- Options Supported
-
-
-
-
- AvidOpenPort
-
-
-
- 55
-
- .b'num' .1 .2 .7 .8 .e .o .n -S +S +X -X .T rx'num'
- tx'num'
-
- Baud rates supported are: 50, 75, 110, 134.5, 150, 300, 600,
- 1200, 1800, 2000, 2400, 3600, 4800, 7200, 9600, 19200. (Default
- is 9600).
-
- The ifsrtcl.lib Comm Library
-
- This is a basic communication package supplied with this product
- that combines the interface routines with asynchronous
- communication software. It is intended to allow you to evaluate
- AutoLibrary and make it easy to get started.
-
- ERR_QUEUE_FULL is returned if the send queue is full.
- ERR_INVALID_PORT is returned if something other than com1 or com2
- is specified.
-
- Options Supported
-
- .b'num' .1 .2 .7 .8 .e .o .n
-
- Baud rates supported are: 110, 150, 300, 600, 1200, 2400, 4800,
- 9600. (Default is 9600).
-
- Also, the default is to use receive Xon/Xoff, and cannot be
- changed. Transmit Xon/Xoff is not supported, i.e., this package
- will ignore Xoff characters. However, the Xon/Xoff the protocol
- will be used if characters are received faster than they are
- processed. The restriction works out ok because you can control
- how many characters you send but cannot control how many and how
- fast characters are received.
-
- Return Codes
-
- <Positive number> -- No error occurred. The positive number is
- the AutoLibrary port number.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
- ERR_COMM_PACKAGE -- This error can occur when the
- communication package cannot open the
- communication port correctly. When this
- error occurs, the parameter 'add_info' will
-
-
-
- AvidOpenPort
-
-
-
- 56
-
- contain the actual error returned by the
- communication package.
-
- ERR_EXCEEDED_COMLIST_SIZE -- This will occur when an attempt
- is made to open more than
- COMLIST_SIZE. The default for this
- value is 30, which can be changed
- by re-compiling AutoLibrary.
-
- ERR_NO_MEMORY -- This will occur when there is no more
- memory to allocate required data structures.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_COMM_PACKAGE is returned,
- 'add_info' contains the actual error returned
- by the communication package.
-
- Description
-
- This routine opens an AutoLibrary communication port. This
- routine creates the required data structures to support
- automation and calls CommInterfaceOpen to open the hardware port
- of the communication package supplied.
-
- IMPORTANT: Note: the list of options for this routine are
- dependent on how the interface library routine CommInterfaceOpen
- was implemented.
-
- Examples
-
- The following example opens the communication port at 9600 baud,
- one stop bit, eight bits per word, no parity, strip 7th bit, and
- do not use hardware flow control.
-
- com = AvidOpenPort(AVID, "com1", &add_info,
- ".b'9600' .1 .8 .n +S -H");
-
- See Also
-
- AvidClosePort, CommInterfaceOpen
-
-
-
-
-
-
- AvidOpenPort
-
-
-
- 57
-
-
- AvidProcessOptions - Parse an Option Parameter List
-
- o_char = AvidProcessOptions(AVID, o_list, target,
- (char *)&control, arg_s, (int *)&start)
-
- Parameter Description
-
- char o_char; -- This is the character part of the option. This
- will have a '\0' (null) value when there are no
- more options to process. If the switch was -
- X'good', for example, 'o_char' would return 'X'.
-
- AVID -- System parameter that must always be specified.
-
- char *o_list; -- This is the list of options.
-
- char *target; -- Look only for the option specified as the
- target. This makes it possible to scan for the
- target option without using a while loop.
-
- char *control; -- This is the option control character of the
- parsed option. If the switch was -X'good', for
- example, 'control' would return '-'.
-
- char *arg_s; -- This is where the options argument is written.
- If the switch does not have an argument, a null
- string is returned. If the switch was -X'good',
- for example, 'arg_s' would return "good".
-
- int *start; -- The location to start parsing in the option
- list. This parameter must be initialized to zero,
- then left alone. It is used internally by
- AvidProcessOptions to track which switch to return
- next.
-
- Options
-
- NONE
-
- Return Codes
-
- Not applicable.
-
- Description
-
-
-
-
- AvidProcessOptions
-
-
-
- 58
-
- This is the routine that parses the option parameters that every
- AutoLibrary routine has. AvidProcessOptions is not needed to
- support automation, however, it has been documented and made
- public because it is a nice routine of general utility.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidProcessOptions
-
-
-
- 59
-
- Examples
-
- AvidProcessOptions can be used two ways. This example shows the
- first way, where the 'target' parameter is given a specific
- switch to look for, namely, "-L". AvidProcessOptions won't
- return until it finds this specific switch or it returns NULL.
- This method eliminates the need to call AvidProcessOptions in a
- loop.
-
- /* Find out if over night tests should be done. */
- if (AvidProcessOptions(AVID, arg_str, "-L",
- &control, arg, &start) != '\0')
- long_version = TRUE;
- else
- long_version = FALSE;
-
- The second way to use AvidProcessOptions is to call it in a while
- loop. The 'target' parameter is left empty, which tells
- AvidProcessOptions to return the next switch. The 'sc' variable
- returns with the switch character and the 'control' variable
- returns with the control character. It is important to
- initialize the 'start' parameter to zero, because this variable
- is used to determine which switch to return. If, for example,
- the 'start' parameter was set to zero inside the while loop,
- AvidProcessOptions would always return the first switch.
-
- /* Find out what kind of batch mode testing to do. */
- start=0; /* Required by AvidProcessOptions. */
- while ((sc=AvidProcessOptions(AVID, arg_str, "",
- &control, arg, &start)) != '\0') {
-
- /* Execute print test if "+P" switch was specified. */
- if ((control == '+') && (sc == 'P')) {
- initialize_testing(com);
- test_scr_print(com, 20, 80);
- }
-
- /* Execute screen attributes test if "-a" switch was
- specified. */
- if ((control == '-') && (sc == 'a')) {
- initialize_testing(com);
- test_scr_attribs(com);
- }
- }
-
-
-
-
-
- AvidProcessOptions
-
-
-
- 60
-
-
- AvidRead - Read a Character
-
- c = AvidRead(AVID, com, (long)r_timeout, (long)e_timeout,
- (int *)&add_info, opts)
-
- Parameter Description
-
- int c; -- The character received is returned.
-
- AVID -- System parameter that must always be
- specified.
-
- int com; -- The AutoLibrary port number.
-
- long r_timeout; -- The number of seconds to wait for a
- character. The timeout value starts over
- after each character received.
-
- long e_timeout; -- The total number of seconds wait for a
- character plus the current number of seconds.
- The timeout value does NOT start over after
- each character received.
-
- AvidRead is different from the other
- AutoLibrary routines that use an ending
- timeout. For AvidRead the current number of
- seconds since Jan 1, 1970 must be added to
- the delay before making the call. Use the
- following code segment.
-
- time(seconds);
- if (e_timeout != AVID_NO_TIMEOUT)
- e_timeout = e_timeout + seconds;
-
- ( make call to AvidRead here )
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- NONE
-
- Return Codes
-
-
-
- AvidRead
-
-
-
- 61
-
- <character> -- No error occurred.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
- ERR_COMM_PACKAGE -- This error can occur when the
- communication package cannot read the
- communication port correctly. When this
- error occurs, the parameter 'add_info' will
- contain the actual error returned by the
- communication package.
-
- ERR_EOF -- There were no more characters to read or a
- timeout occurred. If a timeout occurred,
- 'add_info' will have the values
- ERR_REPEAT_TIMEOUT or ERR_ENDING_TIMEOUT.
-
- ERR_INVALID_PORT -- This error can occur when the
- communication port specified in the 'com'
- parameter was not a valid opened port.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_COMM_PACKAGE is returned,
- 'add_info' will contain the actual error
- returned by the communication package.
-
- ERR_REPEAT_TIMEOUT -- When ERR_EOF is returned and the cause for
- the timeout is a Repeating Timeout, this is
- the value returned.
-
- ERR_ENDING_TIMEOUT -- When ERR_EOF is returned and the cause is
- an Ending Timeout, this is the value
- returned.
-
- Description
-
- This routine will read one character at a time from the
- communication port. This routine is supplied only for
- completeness and is not required for automation. Internally
- AvidSendSearch and AvidDrainPort call this routine to read
- characters. The ending timeout must be fixed up as described
- above in the parameter definition of 'e_timeout'.
-
-
-
- AvidRead
-
-
-
- 62
-
- AvidSendSearch should be used to read characters into a buffer,
- instead of AvidRead.
-
- Examples
-
- See the source code for AvidSendSearch or AvidDrainPort.
-
- See Also
-
- CommInterfaceRead
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidRead
-
-
-
- 63
-
-
- AvidRegisterSend - Register a String to Send
-
- err = AvidRegisterSend(AVID, com, s_string,
- (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- AVID -- System parameter that must always be
- specified.
-
- int com; -- The AutoLibrary port number.
-
- char *s_string; -- This is the string to be sent by
- AvidSendSearch.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- _b'num' -- This changes the number of milliseconds to delay
- before sending the first character of the string. The
- specified value will replace the default only for this
- invocation. Use AvidInitAutoLibrary or AvidOpenPort to
- change the defaults permanently. (Default is 0).
-
- _B'num' -- This changes the number of milliseconds to delay
- between each character sent. The specified value will
- replace the default only for this invocation. Use
- AvidInitAutoLibrary or AvidOpenPort to change the
- defaults permanently. (Default is 0).
-
- .N'num' -- This is the number of null characters in the string.
- For example, .N'3' would be specified for the string
- "\n\r\0\0abc\0".
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
-
- AvidRegisterSend
-
-
-
- 64
-
-
- ERR_NO_MEMORY -- This error will occur when there is not
- enough memory to allocate the required data
- structures.
-
- ERR_INVALID_PORT -- This error can occur when the
- communication port specified in the 'com'
- parameter was not a valid opened port.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- Description
-
- This routine will register a string to be sent when
- AvidSendSearch is called. AvidRegisterSend does not send the
- string, it puts it into a linked list.
-
- Note that calling AvidRegisterSend is optional since send strings
- can be registered directly from AvidSendSearch by using switches.
-
- Examples
-
- The following example registers the specified string for
- AvidSendSearch to send.
-
- err = AvidRegisterSend(AVID, com, "hi there\r", &add_info, "");
-
- See Also
-
- AvidRegisterWait, AvidSendSearch (Especially the .s switch)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidRegisterSend
-
-
-
- 65
-
-
- AvidRegisterWait - Register a Wait String
-
- err = AvidRegisterWait(AVID, com, r_num, w_string,
- (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- AVID -- System parameter that must always be
- specified.
-
- int com; -- The AutoLibrary port number.
-
- int r_num; -- This is the registered number to be
- returned by AvidSendSearch if the string is
- found.
-
- Numbers from 20,000 to max integer are
- reserved by Avid Software for future use and
- internal implementations.
-
- char *w_string; -- This is the string to add to the wait-
- list. If this string is found by
- AvidSendSearch, the registered value will be
- returned.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- .N'num' -- This is the number of null characters in the string.
- For example, .N'3' would be specified for the string
- "\n\r\0\0abc\0".
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
-
-
-
- AvidRegisterWait
-
-
-
- 66
-
- ERR_NO_MEMORY -- This error will occur when there is not
- enough memory to allocate the required data
- structures.
-
- ERR_INVALID_PORT -- This error can occur when the
- communication port specified in the 'com'
- parameter was not a valid opened port.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- Description
-
- This routine is used to register a string for AvidSendSearch to
- scan for. This routine puts the wait string in a linked list.
- This routine can be called as many times as required. Each time
- it is called another wait string gets added to the linked list.
- The value that is registered with AvidRegisterWait is the same
- value that AvidSendSearch will return if the wait string is
- found. Wait strings can also be specified as a switch to
- AvidSendSearch. This way calling AvidRegisterWait directly is
- not required.
-
- Examples
-
- The following example registers the specified string for
- AvidSendSearch to wait for. If the string is found,
- AvidSendSearch will return 100.
-
- err = AvidRegisterWait(AVID, com, 100,
- "This is a string", &add_info, "");
-
- See Also
-
- AvidRegisterSend, AvidSendSearch (Especially the 1w switch)
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidRegisterWait
-
-
-
- 67
-
-
- AvidSend - Send a String
-
- err = AvidSend(AVID, com, s, (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- AVID -- System parameter that must always be specified.
-
- int com; -- The AutoLibrary port number.
-
- char *s; -- This is the string to send.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- _b'num' -- This changes the number of milliseconds to delay
- before sending the first character of the string. The
- specified value will replace the default only for this
- invocation. Use AvidInitAutoLibrary or AvidOpenPort to
- change the defaults permanently. (Default is 0).
-
- _B'num' -- This changes the number of milliseconds to delay
- between each character sent. The specified value will
- replace the default only for this invocation. Use
- AvidInitAutoLibrary or AvidOpenPort to change the
- defaults permanently. (Default is 0).
-
- .N'num' -- This is the number of null characters in the string.
- For example, .N'3' would be specified for the string
- "\n\r\0\0abc\0".
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
- ERR_COMM_PACKAGE -- This error can occur when the
- communication package cannot send through the
-
-
- AvidSend
-
-
-
- 68
-
- communication port correctly. When this
- error occurs, the parameter 'add_info' will
- contain the actual error returned by the
- communication package.
-
- ERR_NO_STRING_SPECIFIED -- This error occurs when there was no
- string specified.
-
- ERR_INVALID_PORT -- This error can occur when the
- communication port specified in the 'com'
- parameter was not a valid opened port.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_COMM_PACKAGE is returned, 'add_info'
- contains the actual error returned by the
- communication package.
-
- Description
-
- This routine sends the specified string.
-
- Examples
-
- The following example sends the specified string.
-
- err = AvidSend(AVID, com, "Hello\r", &add_info, "");
-
- See Also
-
- AvidRegisterSend, CommInterfaceSend, AvidSendSearch
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidSend
-
-
-
- 69
-
-
- AvidSendSearch - Send Strings then Search
-
- s_found = AvidSendSearch(AVID, com,
- (long)r_timeout, (long)e_timeout, (int *)&add_info,
- opts, (long *)&actual, cap)
-
- Parameter Description
-
- int s_found; -- The registered value of the string that
- was found. ERR_SNF, which is equal to zero,
- is returned if none of the registered strings
- were found.
-
- AVID -- System parameter that must always be
- specified.
-
- int com; -- The opened communication port.
-
- long r_timeout; -- The number of seconds to scan for the
- strings in the wait-list. The timeout value
- starts over after each character received.
- (A repeating timeout)
-
- The parameter constant AVID_NO_TIMEOUT will
- cause AvidSendSearch to never timeout due to
- a repeating timeout.
-
- long e_timeout; -- The number of seconds to scan for the
- strings in the wait-list. The timeout value
- does NOT start over after each character
- received. (An ending timeout)
-
- The parameter constant AVID_NO_TIMEOUT will
- cause AvidSendSearch to never timeout due to
- an ending timeout.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- <long *actual;> -- This is the actual number of characters
- captured. May not equal strlen(cap) if cap
- received null characters as part of the data.
- (This parameter is optional see the +c and
- -c options below.)
-
-
-
- AvidSendSearch
-
-
-
- 70
-
- <char *cap;> -- This is the capture string. (This
- parameter is optional, see the +c and -c
- options below.)
-
- Options
-
- +c'size' -- This will cause AvidSendSearch to capture each
- received character until 'size' number of
- characters have been received. The captured
- string will be smaller that 'size' if a timeout
- occurs or one of the strings in the wait-list was
- found.
-
- -c'size' -- This will cause AvidSendSearch to capture
- received characters until one of the strings in
- the wait-list was found or a timeout occurred.
- Truncation will occur if more than 'size' number
- of characters are received before AvidSendSearch
- is finished.
-
- .d'drain_time' -- This is the drain time in seconds. The drain
- time will start over with each new received
- character. (Repeating drain)
-
- .D'drain_time' -- This is the drain time in seconds. The drain
- time will NOT start over with each new received
- character. (Ending drain)
-
- 1w'string' -- This is a wait string. AvidSendSearch will
- return 1 if the string is found. Numbers 1
- through 9 are valid for this option. For example,
- 2w'string' will register 'string' with 2 and
- 9w'string' will register it with 9.
-
- .s'string' -- This is a send string.
-
- Return Codes
-
- <registered value> -- When one of the wait strings is found, the
- registered value is returned.
-
- ERR_SNF -- SNF (String Not Found). This is returned
- when none of the wait strings were found.
- The variable 'add_info' can be tested to find
- out additional information about why ERR_SNF
- was returned. The possible values for
-
-
-
- AvidSendSearch
-
-
-
- 71
-
- 'add_info' are ERR_ENDING_TIMEOUT,
- ERR_REPEAT_TIMEOUT, and ERR_CAPTURE_FULL.
-
- ERR_NOT_INITIALIZED -- This error is returned when
- AvidInitAutoLibrary is not called before this
- routine is called.
-
- ERR_NO_MEMORY -- This error can be returned if the .s or 1w
- switch is used. It is possible for
- AvidRegisterSend and AvidRegisterWait to not
- have the required memory to allocate data
- structures.
-
- ERR_COMM_PACKAGE -- This error can occur when the strings in
- the send-list are being sent or when
- characters are being read looking for the
- strings in the wait-list. When this error
- occurs, the parameter 'add_info' will contain
- the actual error returned by the
- communication package.
-
- ERR_INVALID_PORT -- This error can occur when the
- communication port specified in the 'com'
- parameter was not a valid opened port.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_COMM_PACKAGE is returned,
- 'add_info' contains the actual error returned
- by the communication package.
-
- ERR_REPEAT_TIMEOUT -- When ERR_SNF is returned and the cause for
- the timeout is a Repeating Timeout, this is
- the value returned.
-
- ERR_ENDING_TIMEOUT -- When ERR_SNF is returned and the cause is
- an Ending Timeout, this is the value
- returned.
-
- ERR_CAPTURE_FULL -- When ERR_SNF is returned and the cause is
- due to a full capture string, this is the
- value returned.
-
- Description
-
-
-
- AvidSendSearch
-
-
-
- 72
-
- This routine is the main routine used for automation.
- AvidSendSearch sends all of the strings in the send-list, then
- scans for the strings in the wait-list. If one of the strings in
- the wait-list is found, AvidSendSearch returns with that wait
- string's registered value. If none of the wait strings are found
- within the specified timeout period, AvidSendSearch returns with
- ERR_SNF. (SNF is String Not Found).
-
- It is possible to capture characters while AvidSendSearch is
- scanning for the strings in the wait-list using the switches +c
- or -c. It is also possible to specify drain times with switches.
- If specified, draining will occur after one of the strings in the
- wait-list is found.
-
- The send-list and wait-list can be built by calling
- AvidRegisterSend and AvidRegisterWait, respectively. The send-
- list and wait-list can also be built in AvidSendSearch by using
- switches. Using switches eliminates the need to call
- AvidRegisterSend and AvidRegisterWait.
-
- Examples
-
- The following example sends the string "exit\r" then waits for
- the string "login:". Calls to AvidRegisterSend and
- AvidRegisterWait are used to add the strings to the linked list
- for AvidSendSearch.
-
- /* Register the send string. */
- AvidRegisterSend(AVID, com, "exit\r", &add_info, "");
-
- /* Register the wait string. */
- AvidRegisterWait(AVID, com, 1, "login:", &add_info, "");
-
- /* Send the exit command, then wait for the login: prompt. */
- if (AvidSendSearch(AVID, com, (long)5, (long)45,
- &add_info, "") <= ERR_SNF)
- printf("Exit failed\n");
-
- The following example is the same as the one above, except the
- send string and wait string are registered by using
- AvidSendSearch switches.
-
- /* Send the exit command, then wait for the login: prompt. */
- if (AvidSendSearch(AVID, com, (long)5, (long)45,
- &add_info, ".s'exit\r' 1w'login:'") <= ERR_SNF)
- printf("Exit failed\n");
-
-
-
- AvidSendSearch
-
-
-
- 73
-
- Notice in the following example that it is possible to add more
- than one wait string using AvidRegisterWait. AvidSendSearch will
- return the registered string value of the string it finds. In
- this example, either 1 or 2.
-
- /* Register the send string. */
- AvidRegisterSend(AVID, com, "exit\r", &add_info, "");
-
- /* Register the wait string. */
- AvidRegisterWait(AVID, com, 1, "login:", &add_info, "");
-
- /* Register the wait string. */
- AvidRegisterWait(AVID, com, 2, "Enter Data Switch Number:",
- &add_info, "");
-
- /* Send the exit command, then wait for the login: prompt. */
- if (AvidSendSearch(AVID, com, (long)5, (long)45,
- &add_info, "") <= ERR_SNF)
- printf("Exit failed\n");
-
- The following is the same as the example above except
- AvidSendSearch is used to register the wait strings.
-
- /* Register the send string. */
- AvidRegisterSend(AVID, com, "exit\r", &add_info, "");
-
- /* Send the exit command, then wait for the login: prompt. */
- if (AvidSendSearch(AVID, com, (long)5, (long)45, &add_info,
- "1w'login:' 2w'Enter Data Switch Number:'") <= ERR_SNF)
- printf("Exit failed\n");
-
- The following example shows how to capture information using the
- negative capture switch. The negative capture is used when the
- wait string follows the information that needs to be captured.
- Suppose, for example, sending the command 'weather\r' is a host
- command that displays todays weather forecast. A segment of what
- this command returns might be...
-
- November 17, 1990
- Sunny
- Wind gusts to 30 mph
- Temperature 43 F
- No Rain
-
- or the following segment is also possible...
-
- November 18, 1990
-
-
- AvidSendSearch
-
-
-
- 74
-
- Partly cloudy
- Mild wind of 2 mph
- Temperature 35 F
- No Rain
-
- The wind speed needs to be captured. However, the text before
- the wind speed is never consistent. Therefore, it is impossible
- to key off of a string before the value to be captured. The
- string "mph", however, is always displayed after the wind speed.
- With this consistency, it is possible to capture the wind speed
- with a negative capture string. The following example will do
- it.
-
- if (AvidSendSearch(AVID, com, (long)5, (long)45, &add_info,
- ".s'weather\r' 1w'mph' -c'3'",
- (long *)&actual, captured) <= ERR_SNF)
- printf("Failed\n");
-
- The capture string for the first sample segment would have the
- string "30 " and for the second sample segment would have the
- string " 2 ". In each case, the capture string is the last 3
- characters before the string 'mph'.
-
- A positive capture is used when the string to key off of is
- before the information to be captured. Using the sample segments
- from the weather example, notice that the string "Temperature" is
- always displayed before the temperature. Therefore, a positive
- capture can be done. The following code segment will do it.
-
- if (AvidSendSearch(AVID, com, (long)5, (long)45, &add_info,
- "1w'Temperature'") <= ERR_SNF)
- printf("Failed\n");
-
- if (AvidSendSearch(AVID, com, (long)5, (long)45, &add_info,
- "+c'4' 1w'F' .d'1' .D'10'",
- (long *)&actual, captured) < ERR_SNF)
- printf("Failed\n");
-
- The first call to AvidSendSearch continues from where the wind
- speed was captured to the string "Temperature". The second call
- to AvidSendSearch captures the next 4 characters. In case the
- temperature is in the 100's, 4 characters are captured. The C
- function sscanf can be used to filter out the trailing character
- if it is not valid.
-
- Notice that the wait switch 1w'F' was also specified. This will
- cause AvidSendSearch to return if the string "F" is found. Also,
-
-
- AvidSendSearch
-
-
-
- 75
-
- notice that the drain switches .d'1' and .D'10' were specified.
- These switches will cause the rest of the 'weather' command to be
- read in and ignored. In this example, the drain switches would
- cause 'No Rain' to be ignored.
-
- See Also
-
- AvidRegisterSend, AvidRegisterWait, AvidDrainPort
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvidSendSearch
-
-
-
- 76
-
-
- AvidVersion - Print Version and Copyright Information
-
- err = AvidVersion(AVID, (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Return code.
-
- AVID -- System parameter that must always be specified.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- This is the input parameter for options.
-
- Options
-
- NONE
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- Description
-
- This routine prints the version and copyright information.
-
- Examples
-
- The following example will display the version and copyright
- information.
-
- err = AvidVersion(AVID, &add_info, "");
-
-
-
-
-
-
-
-
-
-
-
-
- AvidVersion
-
-
-
- 77
-
-
- EveryChar - Called with Every Character Received
-
- (void) EveryChar(c)
-
- Parameter Description
-
- int c; -- The character that was received.
-
- Options
-
- Not Applicable
-
- Return Codes
-
- Not Applicable
-
- Description
-
- This routine is different from the other routines: the
- AutoLibrary(tm) Program-Playback tool calls this routine with
- each received character. You must supply this routine in your
- code. This will give your applications the opportunity to print
- each received character. If your application does not need this
- feature and you do not want the overhead of this routine, simply
- remove the call from CommInterfaceRead.
-
- Examples
-
- This example prints each received character to the screen. By
- putting this implementation of EveryChar in your application,
- each received character will be printed to the screen. EveryChar
- could also be used to log every character to a file. Also, see
- the example in AvidConvert.
-
- /*****/
- void EveryChar(c)
- int c;
- /*****/
- {
- printf("%c", c);
- }
-
- This example does nothing with each received character, which is
- completely valid. Also, it is possible to remove the call to
- EveryChar in CommInterfaceRead, which is only important if you do
- not want to overhead of calling EveryChar.
-
-
- EveryChar
-
-
-
- 78
-
-
- /*****/
- void EveryChar(c)
- int c;
- /*****/
- {
- c = c; /* for compiler. */
- }
-
- See Also
-
- AvidConvert, CommInterfaceRead
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- EveryChar
-
-
-
- 79
-
-
- Reference Guide for Interface Routines
-
- This section describes the routines that interface to your
- communication package and describes how to create interface
- routines for other communication packages.
-
- Note: The source code discussed in this section can be found in
- intface.c.
-
-
-
- 80
-
-
- CommInterfaceClose - Close port
-
- err = CommInterfaceClose(com, (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- The returned status.
-
- int com; -- The AutoLibrary communication port.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- Options.
-
- Options
-
- See AvidClose
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_COMM_PACKAGE -- This error can occur when the
- communication package cannot correctly close
- the communication port. The parameter
- 'add_info' will contain the actual
- communication packages error code.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_COMM_PACKAGE is returned, this
- variable contains the actual error returned by the
- communication package.
-
- Description
-
- This routine is used to close the communication port. Your code
- must not call this routine directly. This routine will need to
- be modified to support your communication package. See the
- System Requirements section for a list of supported communication
- packages.
-
- Porting to other communication packages
-
-
-
- CommInterfaceClose
-
-
-
- 81
-
- The following sample source code is written to interface with the
- Greenleaf CommLib. To support a different communication package,
- use this code as a template, then code according to the
- specifications of the communication package.
-
- The call to 'asiquit' and the literal ASSUCCESS are unique to the
- Greenleaf CommLib and would need to change to support a different
- communication package.
-
- When this routine works correctly, ERR_OK must be returned in
- 'add_info' and as the return status. When this routine fails for
- any reason, the return status must be ERR_COMM_PACKAGE. When
- ERR_COMM_PACKAGE is returned, 'add_info' should be set to the
- actual error from the communication package.
-
- /********************************************************/
- int /* The return status. */
- CommInterfaceClose (com, info, opts)
- int com; /* The AutoLibrary communication port. */
- int *info;
- char *opts; /* Options. */
- /********************************************************/
- {
- int err;
-
- opts = opts; /* for compiler */
-
- /* Start out with no errors. */
- *info = ERR_OK;
-
- err = asiquit (comlist[com]->hw_port);
- if (err != ASSUCCESS) {
- *info = err;
- return(ERR_COMM_PACKAGE);
- }
-
- return(ERR_OK);
- }
-
- See Also
-
- AvidClosePort, Actual source code.
-
-
-
-
-
-
-
- CommInterfaceClose
-
-
-
- 82
-
-
- CommInterfaceOpen - Open Port
-
- err = CommInterfaceOpen(com, device, (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- The return status.
-
- int com; -- The AutoLibrary port number.
-
- char *device; -- The device name. (For example, "com1" or
- "com2".)
-
- int *add_info; -- Additional return information.
-
- char *opts; -- Options.
-
- Options
-
- See AvidOpenPort
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_COMM_PACKAGE -- This error occurs when the communication
- package cannot open the communication port
- correctly. When this error occurs, the
- parameter 'add_info' will contain the actual
- error returned by the communication package.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_COMM_PACKAGE is returned, 'add_info'
- contains the actual error returned by the
- communication package.
-
- Description
-
- This routine is used to open the communication port. Your code
- must not call this routine directly. This routine will need to
- be modified to support your communication package. See the
- System Requirements section for a list of supported communication
- packages.
-
-
- CommInterfaceOpen
-
-
-
- 83
-
-
- Porting to other communication packages
-
- The best way to describe how to port CommInterfaceOpen is a piece
- at a time. You will want to refer to the final version of
- CommInterfaceOpen at the end of this section as you read about
- this routine. By referring to the final version you will be able
- to see where the many code fragments fit in. The following line
- of code saves the information required to interface with the
- Greenleaf CommLib.
-
- /* Save the Greenleaf port number. */
- comlist[com]->hw_port = port_num;
-
- The Greenleaf port number 'port_num' must be saved for later use
- in the routines CommInterfaceClose, CommInterfaceRead, and
- CommInterfaceSend, since each of these routines make calls to
- Greenleaf routines. Note that the Greenleaf port number
- 'port_num' will not always be equal to the AutoLibrary port
- number 'com', i.e., com != comlist[com]->hw_port. The
- AutoLibrary port number is used by AutoLibrary routines to get
- information from the 'comlist' data structure. Where as, the
- Greenleaf port number is used to identify a port number to
- communicate with.
-
- The following code segment shows a call that opens a Greenleaf
- communication port.
-
- err=asiopen(comlist[com]->hw_port, mode, 8192,
- 512, 9600, P_ODD, 1, 8, 0, 0);
- if (err != ASSUCCESS) {
- *info = err;
- return(ERR_COMM_PACKAGE);
- }
-
- This call opens a communication port with a receive buffer of
- 8192 bytes, transmit buffer of 512 bytes, baud rate of 9600, odd
- parity, one stop bit, and 8 bits per word. This hard coded call
- to 'asiopen' is valid, since the AutoLibrary(tm) Program-Playback
- tool will work as long as a port gets opened. However, since
- hard coded opens are restrictive, switches have been defined to
- support opening a communication port in different ways. For
- example, the switch -b'4800' requests that the port be opened at
- 4800 baud. The switch .2 specifies 2 stop bits and rx'1024'
- requests a receive buffer of 1K.
-
-
-
-
- CommInterfaceOpen
-
-
-
- 84
-
- It is the responsibility of CommInterfaceOpen to support these
- switches. (It is ok to add switches that are unique to your
- communication package.)
-
- Before describing switches, I would like to show the following
- implementation of CommInterfaceOpen, which is instructive because
- it only shows the required code. Additional code is recommended,
- which will be shown later.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CommInterfaceOpen
-
-
-
- 85
-
-
- /********************************************************/
- int
- CommInterfaceOpen (com, device, info, opts)
- int com; /* The AutoLibrary communication port. */
- char *device; /* The device name. */
- int *info;
- char *opts; /* Options. */
- /********************************************************/
- {
- int mode, err;
-
- /* Start out with no errors. */
- *info = ERR_OK;
-
- /* For Greenleaf COM1 is defined as 0. */
- port_num--;
-
- /* Save the port number for closing. */
- comlist[com]->hw_port = port_num;
-
- /* No ASCII device names in this comm package. */
- comlist[com]->hw_port_name = (char *)NULL;
-
- mode = ASCII | ASINOUT | NORMALRX;
-
- err = asiopen (comlist[com]->hw_port, mode, 8192,
- 512, 9600, P_ODD, 1, 8, 0, 0);
- if (err != ASSUCCESS) {
- *info = err;
- return(ERR_COMM_PACKAGE);
- }
-
- err = asixon(comlist[com]->hw_port, 30, 70, XON, XOFF);
- if (err != ASSUCCESS) {
- *info = err;
- return(ERR_COMM_PACKAGE);
- }
-
- return(ERR_OK);
- }
-
- The second line of code decrements 'port_num'. This is required
- because the Greenleaf CommLib defines 0 for com1, 1 for com2, and
- so on. Your communication package may or may not have to
- decrement 'port_num'.
-
-
-
- CommInterfaceOpen
-
-
-
- 86
-
- We have already looked at the third line of code. The Greenleaf
- port number ('port_num') is saved in the 'comlist' data structure
- for later use by the other interface routines.
-
- The forth line of code saves a pointer to the device name in the
- 'comlist' data structure for later use for the same reasons the
- port number is saved. This example sets this value to NULL
- because the Greenleaf CommLib does not use device names. If your
- communication package uses device names, this field would be used
- to save a pointer to the name for the interface routines
- CommInterfaceClose, CommInterfaceRead, and CommInterfaceSend.
- The device name field 'hw_port_name' is important only if your
- communication package refers to ports with text strings instead
- of numbers. Just remember that 'comlist[com]->hw_port_name' is a
- pointer. Use 'malloc' to dynamically allocate the memory needed
- to store the device name, then in CommInterfaceClose free the
- memory.
-
- The remaining code in the above example opens a Greenleaf
- communication port with hard coded parameters. This
- implementation of CommInterfaceOpen contains the bare minimum for
- the AutoLibrary(tm) Program-Playback tool to work correctly. If
- your application is always to be opened with the same parameters,
- an implementation like this may be enough. However, more code is
- required if CommInterfaceOpen is to be flexible. When opening a
- communication port there are many options to choose from, like
- baud rate, number of stop bits, parity, and so on. To support
- these different options, we need to add switch processing to
- CommInterfaceOpen. For example, the following call to
- AvidOpenPort opens communication port one (com1) at 4800 baud and
- even parity. The defaults are used for the other parameters.
-
- AvidOpenPort(AVID, "1", &info, ".b'4800' .e");
-
- AvidOpenPort does not process open switches, instead, the
- switches are passed directly to CommInterfaceOpen. If we stayed
- with the previous implementation of CommInterfaceOpen, the open
- switches ".b'4800' .e" would be ignored. To support open
- switches, the option parameter needs to be parsed using
- AvidProcessOptions. Here is an example of how CommInterfaceOpen
- would process the baud rate switch.
-
-
-
-
-
-
-
-
- CommInterfaceOpen
-
-
-
- 87
-
- baud = 9600; /* default */
-
- s_num = 0; /* Required for AvidProcessOptions. */
- while ((sc = AvidProcessOptions(AVID, opts, "", &control,
- temp_buf, &s_num)) != '\0') {
- if ((control == '.') && (sc == 'b'))
- baud = atoi(temp_buf);
- }
-
- First, the variable 'baud' is set to the default of 9600, which
- is used if the baud rate switch ( .b'baud' ) is not specified.
- The while loop will return each of the switches specified in the
- 'opts' parameter. The 'if' statement inside the while loop tests
- for the baud rate switch. When specified, the new baud rate is
- set. The following if statements, when placed inside the while
- loop, will set the parity to the desired value.
-
- if ((o_odd[0] == control) && (o_odd[1] == sc))
- parity = P_ODD;
-
- if ((o_even[0] == control) && (o_even[1] == sc))
- parity = P_EVEN;
-
- The string 'o_odd' is initialized to ".o" and the string 'o_even'
- is initialized to ".e". This way the actual switch definition is
- done in one spot. The previous example hard coded the baud rate
- switch, which has the option string 'o_baud'. The string
- 'o_baud' will be used in the final version of CommInterfaceOpen.
-
- The constants P_ODD and P_EVEN are defined in the Greenleaf
- CommLib. Since your communication package will be different,
- these constants will be different.
-
- The following while loop shows how the other open options are
- parsed by AvidProcessOptions.
-
- mode = 0;
- baud = 9600;
- parity = P_ODD;
- stop_bits = 1;
- word_len = 8;
- dtr = 0;
- rts = 0;
- rx_length = 8192;
- tx_length = 512;
- strip = ASCII;
- xon = TRUE;
-
-
- CommInterfaceOpen
-
-
-
- 88
-
-
- s_num = 0; /* Required for AvidProcessOptions. */
- while ((sc = AvidProcessOptions (AVID, opts, "", &control,
- temp_buf, &s_num)) != '\0') {
- if ((o_strip_yes[0] == control) && (o_strip_yes[1] == sc))
- strip = ASCII;
-
- if ((o_strip_no[0] == control) && (o_strip_no[1] == sc))
- strip = BINARY;
-
- if ((o_even[0] == control) && (o_even[1] == sc))
- parity = P_EVEN;
-
- if ((o_odd[0] == control) && (o_odd[1] == sc))
- parity = P_ODD;
-
- if ((o_none[0] == control) && (o_none[1] == sc))
- parity = P_NONE;
-
- if ((o_baud[0] == control) && (o_baud[1] == sc))
- baud = atoi (temp_buf);
-
- if ((o_stop_bits_1[0] == control) &&
- (o_stop_bits_2[1] == sc))
- stop_bits = 1;
-
- if ((o_stop_bits_2[0] == control) &&
- (o_stop_bits_2[1] == sc))
- stop_bits = 2;
-
- if ((o_word_len_7[0] == control) && (o_word_len_7[1] == sc))
- word_len = 7;
-
- if ((o_word_len_8[0] == control) && (o_word_len_8[1] == sc))
- word_len = 8;
-
- if ((o_dtr[0] == control) && (o_dtr[1] == sc))
- dtr = 1;
-
- if ((o_xon_yes[0] == control) && (o_xon_yes[1] == sc))
- xon = TRUE;
-
- if ((o_xon_no[0] == control) && (o_xon_no[1] == sc))
- xon = FALSE;
-
- if ((o_rx_len[0] == control) && (o_rx_len[1] == sc)) {
- temp_long = atol (temp_buf);
-
-
- CommInterfaceOpen
-
-
-
- 89
-
- rx_length = temp_long;
- }
-
- if ((o_tx_len[0] == control) && (o_tx_len[1] == sc)) {
- temp_long = atol (temp_buf);
- tx_length = temp_long;
- }
- }
-
- Your implementation of this while loop may be very different.
- Some switches may not apply, like the receive buffer length
- switch (rx) and the send buffer length switch (tx). These
- options were added to CommInterfaceOpen because the Greenleaf
- CommLib supports changing these buffer sizes at run time. Your
- communication package may support other unique features. If so,
- make up a switch that can be used to invoke the feature. Include
- the new switch in intface.c. Try to make the new switch unique
- by checking the other switches in al_sys.h.
-
- Once you have chosen a switch, it is possible to reserve it by
- contacting Avid Software. Also, I am interested in supporting as
- many communications packages as possible, so send in your ported
- code for possible inclusion in the core product.
-
- The 3 major pieces of CommInterfaceOpen have been described.
- First, the port number or device name is saved for later use.
- Next, the switches are parsed, and finally the call is made to
- the communication package to open the port. However, before
- showing a complete listing of CommInterfaceOpen, it is important
- to understand what the first part of CommInterfaceOpen does. The
- following 'if' statements allow communication ports to be
- specified in 2 different ways.
-
- /* Let valid input for device be com1 or 1, for example. */
- if (sscanf (device, "com%d", &port_num) == 0) {
-
- if (sscanf (device, "%d", &port_num) == 0) {
- *info = ASINVPORT;
- return(ERR_COMM_PACKAGE);
- }
- }
-
- This makes it possible, for instance, to accept communication
- port 1 as "com1" or as "1".
-
-
-
-
-
- CommInterfaceOpen
-
-
-
- 90
-
- The following 'if' statement returns an error if the
- communication port number is outside the range possible for the
- Greenleaf CommLib.
-
- /* Make sure wild number did not make it through. */
- if ((port_num < 1) || (port_num > 17)) {
- *info = ASINVPORT;
- return(ERR_COMM_PACKAGE);
- }
-
- Now that everything in CommInterfaceOpen has been described, the
- following listing shows a complete version.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CommInterfaceOpen
-
-
-
- 91
-
-
- /********************************************************/
- int
- CommInterfaceOpen (com, device, info, opts)
- int com; /* The AutoLibrary communication port. */
- char *device; /* The device name. */
- int *info;
- char *opts; /* Options. */
- /********************************************************/
- {
- int mode, word_len, baud, stop_bits, parity, port_num, strip,
- dtr, rts;
- unsigned int rx_length, tx_length;
- char sc, control;
- char temp_buf[85];
- int s_num, err;
- long temp_long;
-
- /* Start out with no errors. */
- *info = ERR_OK;
-
- /* Let valid input for device be com1 or 1 (for example) */
- if (sscanf (device, "com%d", &port_num) == 0) {
-
- if (sscanf (device, "%d", &port_num) == 0) {
- *info = ASINVPORT;
- return (ERR_COMM_PACKAGE);
- }
- }
-
- /* Make sure wild number did not make it through. */
- if ((port_num < 1) || (port_num > 17)) {
- *info = ASINVPORT;
- return (ERR_COMM_PACKAGE);
- }
-
- /* For Greenleaf COM1 is defined as 0. */
- port_num--;
-
- /* Save the port number for closing. */
- comlist[com]->hw_port = port_num;
-
- /* No ASCII device names in this comm package. */
- comlist[com]->hw_port_name = (char *)NULL;
-
- mode = 0;
- baud = 9600;
-
-
- CommInterfaceOpen
-
-
-
- 92
-
- parity = P_ODD;
- stop_bits = 1;
- word_len = 8;
- dtr = 0;
- rts = 0;
- rx_length = 8192;
- tx_length = 512;
- strip = ASCII;
- xon = TRUE;
-
- s_num = 0; /* Required for AvidProcessOptions. */
- while ((sc = AvidProcessOptions (AVID, opts, "", &control,
- temp_buf, &s_num)) != '\0') {
-
- if ((o_strip_yes[0] == control) &&
- (o_strip_yes[1] == sc))
- strip = ASCII;
-
- if ((o_strip_no[0] == control) && (o_strip_no[1] == sc))
- strip = BINARY;
-
- if ((o_even[0] == control) && (o_even[1] == sc))
- parity = P_EVEN;
-
- if ((o_odd[0] == control) && (o_odd[1] == sc))
- parity = P_ODD;
-
- if ((o_none[0] == control) && (o_none[1] == sc))
- parity = P_NONE;
-
- if ((o_baud[0] == control) && (o_baud[1] == sc))
- baud = atoi (temp_buf);
-
- if ((o_stop_bits_1[0] == control) &&
- (o_stop_bits_2[1] == sc))
- stop_bits = 1;
-
- if ((o_stop_bits_2[0] == control) &&
- (o_stop_bits_2[1] == sc))
- stop_bits = 2;
-
- if ((o_word_len_7[0] == control) &&
- (o_word_len_7[1] == sc))
- word_len = 7;
-
- if ((o_word_len_8[0] == control) &&
- (o_word_len_8[1] == sc))
-
-
- CommInterfaceOpen
-
-
-
- 93
-
- word_len = 8;
-
- if ((o_dtr[0] == control) && (o_dtr[1] == sc))
- dtr = 1;
-
- if ((o_xon_yes[0] == control) && (o_xon_yes[1] == sc))
- xon = TRUE;
-
- if ((o_xon_no[0] == control) && (o_xon_no[1] == sc))
- xon = FALSE;
-
- if ((o_rx_len[0] == control) && (o_rx_len[1] == sc)) {
- temp_long = atol (temp_buf);
- rx_length = temp_long;
- }
-
- if ((o_tx_len[0] == control) && (o_tx_len[1] == sc)) {
- temp_long = atol (temp_buf);
- tx_length = temp_long;
- }
- }
-
- mode = strip | ASINOUT | NORMALRX;
-
- err = asiopen (comlist[com]->hw_port, mode,
- rx_length, tx_length, baud, parity, stop_bits,
- word_len, dtr, rts);
- if (err != ASSUCCESS) {
- *info = err;
- return(ERR_COMM_PACKAGE);
- }
-
- if (xon) {
- err = asixon(comlist[com]->hw_port, 30, 70, XON, XOFF);
- if (err != ASSUCCESS) {
- *info = err;
- return(ERR_COMM_PACKAGE);
- }
- }
-
- return(ERR_OK);
- }
-
- See Also
-
- AvidOpenPort, Actual source code.
-
-
-
- CommInterfaceOpen
-
-
-
- 94
-
-
- CommInterfaceRead - Read Character
-
- c = CommInterfaceRead(com, (long)r_timeout, (long)e_timeout,
- (int *)&add_info, opts)
-
- Parameter Description
-
- int c; -- The character that was read.
-
- int com; -- The AutoLibrary communication port.
-
- long r_timeout; -- The repeating timeout.
-
- long e_timeout; -- The ending timeout.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- Options.
-
- Options
-
- See AvidRead
-
- Return Codes
-
- <Received character> -- No error occurred. The character is
- returned.
-
- ERR_COMM_PACKAGE -- This error occurs when the
- communication package cannot read the
- communication port correctly. When this
- error occurs, the parameter 'add_info'
- will contain the actual error returned
- by the communication package.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
- <system err> -- When ERR_COMM_PACKAGE is returned, 'add_info'
- contains the actual error returned by the
- communication package.
-
- Description
-
-
-
-
- CommInterfaceRead
-
-
-
- 95
-
- This routine is used to read from the communication port. Your
- code must not call this routine directly. This routine will need
- to be modified to support your communication package. See the
- System Requirements section for a list of supported communication
- packages.
-
- Porting to other communication packages
-
- You will want to refer to the final version of CommInterfaceRead
- at the end of this section as you read about this routine. By
- referring to the final version you will be able to see where the
- many code fragments fit in.
-
- If timeouts were not required, CommInterfaceRead would be easy.
- This routine would simply return the received character, or
- ERR_EOF when no character was available. The following code
- shows this simple implementation.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CommInterfaceRead
-
-
-
- 96
-
- /********************************************************/
- int
- CommInterfaceRead (com, r_timeout, e_timeout, info, opts)
- int com; /* The AutoLibrary communication port. */
- long r_timeout; /* The repeating timeout. */
- long e_timeout; /* The ending timeout. */
- int *info;
- char *opts; /* Options. */
- /********************************************************/
- {
- int c;
-
- /* Start out with no errors. */
- *info = ERR_OK;
-
- c = asigetc (comlist[com]->hw_port);
- if ((c >=0) && (c <= 0xFF)) {
- EveryChar(c);
- return(c);
- }
-
- if (c == ASINVPORT) {
- *info = ASINVPORT;
- return(ERR_COMM_PACKAGE);
- }
-
- if (c == ASNOTSETUP) {
- *info = ASNOTSETUP;
- return(ERR_COMM_PACKAGE);
- }
-
- return(ERR_EOF);
- }
-
- The above implementation would work. However, since timeouts are
- required to successfully automate communications, the
- AutoLibrary(tm) Program-Playback tool supports 2 types of
- timeouts: Repeating Timeouts and Ending Timeouts. Let's
- implement Repeating Timeouts first. It is possible to implement
- Repeating Timeouts completely from within CommInterfaceRead. We
- will find out later this is not possible with Ending Timeouts.
-
- To implement Repeating Timeouts, a while loop needs to be added.
- The while loop will make repeated calls to the communication
- package asking for a character until a character is received or
- until a timeout occurs. The following implementation supports
- Repeating Timeouts.
-
-
- CommInterfaceRead
-
-
-
- 97
-
-
-
- /********************************************************/
- int
- CommInterfaceRead (com, r_timeout, e_timeout, info, opts)
- int com; /* The AutoLibrary communication port. */
- long r_timeout; /* The repeating timeout. */
- long e_timeout; /* The ending timeout. */
- int *info;
- char *opts; /* Options. */
- /********************************************************/
- {
- int c;
- long seconds;
-
- /* Start out with no errors. */
- *info = ERR_OK;
-
- /* Set up for Repeating Timeout. */
- time(&seconds);
- r_timeout = r_timeout + seconds;
-
- while (1 > 0) {
-
- c = asigetc (comlist[com]->hw_port);
- if ((c >=0) && (c <= 0xFF)) {
- EveryChar(c);
- return(c);
- }
-
- if (c == ASBUFREMPTY) {
-
- /* if still no character, check for timeout. */
- time(&seconds);
- if (seconds >= r_timeout) {
- *info = ERR_REPEAT_TIMEOUT;
- return(ERR_EOF);
- }
- }
- }
-
- return(ERR_EOF);
- }
-
- The call to 'time(&seconds)' gets the total number of seconds
- since Jan 1, 1970. This number is added to the desired timeout
- value. Say, for instance, a Repeating Timeout of 10 seconds was
-
-
- CommInterfaceRead
-
-
-
- 98
-
- specified and the current date and time is June 30, 1991 at
- 18:37:40. The variable 'r_timeout' would then contain
- 678,321,470 which is 678,321,460 plus 10, where 678,321,460 is
- the number of seconds from Jan 1, 1970 to Jun 30, 1991. Once
- 'r_timeout' is initialized this way, it is possible to determine
- when a timeout should happen. Each time 'asigetc' is called,
- which results in no received character, the current system time
- is compared with 'r_timeout'. If the system time is greater than
- or equal to 'r_timeout', a timeout is returned.
-
- The above implementation needs some minor but important changes.
- The first change is in setting up for the Repeating Timeout.
- Instead of...
-
- time(&seconds);
- r_timeout = r_timeout + seconds;
-
- the following code is correct.
-
- time(&seconds);
- if (r_timeout < seconds)
- r_timeout = r_timeout + seconds;
-
- The 'if' test is required to support AVID_NO_TIMEOUT, which
- indicates that a timeout is to never happen. AVID_NO_TIMEOUT is
- defined as 2,147,483,600, which is the system time 68 years from
- now. Therefore, when 'r_timeout' has this value, incrementing
- 'r_timeout' by 'seconds' is not needed.
-
- The next change the above implementation needs is to return an
- error if 'asigetc' returns with an error. Therefore, instead
- of...
-
- if (c == ASBUFREMPTY) {
-
- /* if still no character, check for timeout. */
- time(&seconds);
- if (seconds >= r_timeout) {
- *info = ERR_REPEAT_TIMEOUT;
- return(ERR_EOF);
- }
- }
-
- the following code is correct.
-
-
-
-
-
- CommInterfaceRead
-
-
-
- 99
-
-
- if (c == ASBUFREMPTY) {
-
- /* if still no character, check for timeout. */
- time(&seconds);
- if (seconds >= r_timeout) {
- *info = ERR_REPEAT_TIMEOUT;
- return(ERR_EOF);
- }
-
- } else {
- /* Error ASINVPORT or ASNOTSETUP occurred. */
- *info = c;
- return(ERR_COMM_PACKAGE);
- }
-
- This way if an error besides ASBUFREMPTY is returned,
- ERR_COMM_PACKAGE is returned by CommInterfaceRead.
-
- Finally, the last change is done for speed. A call is made to
- 'asigetc' before setting up for a timeout. If there is a
- character, it is returned without the overhead of setting up for
- a repeating timeout. If there is not a character, the time
- required to set up for a timeout is ok since the code will enter
- a polling loop anyway. At this point I would like to show the
- complete implementation that supports Repeating Timeouts.
- (Remember this implementation doesn't support Ending Timeouts).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CommInterfaceRead
-
-
-
- 100
-
- /********************************************************/
- int
- CommInterfaceRead (com, r_timeout, e_timeout, info, opts)
- int com; /* The AutoLibrary communication port. */
- long r_timeout; /* The repeating timeout. */
- long e_timeout; /* The ending timeout. */
- int *info;
- char *opts; /* Options. */
- /********************************************************/
- {
- int c;
- long seconds;
-
- /* Start out with no errors. */
- *info = ERR_OK;
-
- /* Try to get a character without setting up
- for a timeout. */
- c = asigetc (comlist[com]->hw_port);
- if ((c >=0) && (c <= 0xFF)) {
- EveryChar(c);
- return(c);
- }
-
- if (c == ASINVPORT) {
- *info = ASINVPORT;
- return(ERR_COMM_PACKAGE);
- }
-
- if (c == ASNOTSETUP) {
- *info = ASNOTSETUP;
- return(ERR_COMM_PACKAGE);
- }
-
- /* A timeout is required so set up for it. */
- time(&seconds);
- if (r_timeout < seconds)
- r_timeout = r_timeout + seconds;
-
- while (1 > 0) {
-
- /* Try to get a character. */
- c = asigetc (comlist[com]->hw_port);
- if ((c >=0) && (c <= 0xFF)) {
- EveryChar(c);
- return(c);
- }
-
-
- CommInterfaceRead
-
-
-
- 101
-
-
- if (c == ASBUFREMPTY) {
-
- time (&seconds);
- if (seconds >= r_timeout) {
- *info = ERR_REPEAT_TIMEOUT;
- return(ERR_EOF);
- }
-
- } else {
- /* Error ASINVPORT or ASNOTSETUP occurred. */
- *info = c;
- return(ERR_COMM_PACKAGE);
- }
- }
-
- opts = opts; /* for compiler */
-
- /* Nothing should reach here but if it does... */
- *info = c;
- return(ERR_COMM_PACKAGE);
- }
-
- Now, Ending Timeout support needs to be added to
- CommInterfaceRead. This is simple. The following test needs to
- be added just inside the while loop.
-
- /* Do not try to get a character if an ending timeout has
- occurred. */
- time(&seconds);
- if (seconds >= e_timeout) {
- *info = ERR_ENDING_TIMEOUT;
- return(ERR_EOF);
- }
-
- This test also needs to occur before the first call to 'asigetc'
- in case characters are continously received when an ending
- timeout should occur.
-
- Now the complete and final implementation of CommInterfaceRead
- looks like the following.
-
-
-
-
-
-
-
-
- CommInterfaceRead
-
-
-
- 102
-
-
- /********************************************************/
- int
- CommInterfaceRead (com, r_timeout, e_timeout, info, opts)
- int com; /* The AutoLibrary communication port. */
- long r_timeout; /* The repeating timeout. */
- long e_timeout; /* The ending timeout. */
- int *info;
- char *opts; /* Options. */
- /********************************************************/
- {
- int c;
- long seconds;
-
- /* Start out with no errors. */
- *info = ERR_OK;
-
- /* Have to check for an ending timeout. */
- time(&seconds);
- if (seconds >= e_timeout) {
- *info = ERR_ENDING_TIMEOUT;
- return(ERR_EOF);
- }
-
- /* Try to get a character without setting up
- for a timeout. */
- c = asigetc (comlist[com]->hw_port);
- if ((c >=0) && (c <= 0xFF)) {
- EveryChar(c);
- return(c);
- }
-
- if (c == ASINVPORT) {
- *info = ASINVPORT;
- return(ERR_COMM_PACKAGE);
- }
-
- if (c == ASNOTSETUP) {
- *info = ASNOTSETUP;
- return(ERR_COMM_PACKAGE);
- }
-
- /* A timeout is required so set up for it. */
- time(&seconds);
- if (r_timeout < seconds)
- r_timeout = r_timeout + seconds;
-
-
-
- CommInterfaceRead
-
-
-
- 103
-
- while (1 > 0) {
-
- /*Do not try to get a character if an ending
- timeout has occurred.*/
- time (&seconds);
- if (seconds >= e_timeout) {
- *info = ERR_ENDING_TIMEOUT;
- return(ERR_EOF);
- }
-
- /* Try to get a character. */
- c = asigetc (comlist[com]->hw_port);
- if ((c >=0) && (c <= 0xFF)) {
- EveryChar(c);
- return(c);
- }
-
- if (c == ASBUFREMPTY) {
-
- time (&seconds);
- if (seconds >= r_timeout) {
- *info = ERR_REPEAT_TIMEOUT;
- return(ERR_EOF);
- }
-
- } else {
- /* Error ASINVPORT or ASNOTSETUP occurred. */
- *info = c;
- return(ERR_COMM_PACKAGE);
- }
- }
-
- opts = opts; /* for compiler */
-
- /* Nothing should reach here but if it does... */
- *info = c;
- return(ERR_COMM_PACKAGE);
- }
-
- It was easy for CommInterfaceRead to support Ending Timeouts
- because it is the responsibility of the calling routine to set up
- for it. CommInterfaceRead simply gets (in the 'e_timeout'
- parameter) a system time value in total seconds from Jan 1, 1970.
- An Ending Timeout occurs when the current system time is greater
- than or equal to 'e_timeout'.
-
-
-
-
- CommInterfaceRead
-
-
-
- 104
-
- If you would like to know more about the callers responsibility
- for Ending Timeouts, take a look at the source code for
- AvidSendSearch. AvidSendSearch makes calls to AvidRead from
- inside a while loop. (AvidRead passes the 'r_timeout' and
- 'e_timeout' values directly to CommInterfaceRead). Before the
- while loop, the current system time is added to the 'e_timeout'
- parameter. The 'e_timeout' parameter is then constant for each
- call to AvidRead, which makes it possible to support Ending
- Timeouts.
-
- See Also
-
- AvidRead, Actual source code.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CommInterfaceRead
-
-
-
- 105
-
-
- CommInterfaceSend - Send Character
-
- err = CommInterfaceSend(com, bef, bet, s, len,
- (int *)&add_info, opts)
-
- Parameter Description
-
- int err; -- Error code.
-
- int com; -- The AutoLibrary communication port.
-
- int bef; -- The number of milliseconds to delay before
- sending the first character.
-
- int bet; -- The number of milliseconds to delay between
- each character.
-
- char *s; -- The string to send.
-
- int len; -- The length of the string to send. This value
- may not equal strlen(s) because of null characters
- in the string.
-
- int *add_info; -- Additional return information.
-
- char *opts; -- Options.
-
- Options
-
- See AvidSend
-
- Return Codes
-
- ERR_OK -- No error occurred.
-
- ERR_COMM_PACKAGE -- This error occurs when the communication
- package cannot send to the communication port
- correctly. When this error occurs, the
- parameter 'add_info' will contain the actual
- error returned by the communication package.
-
- Additional Information Return Codes
-
- ERR_OK -- No error occurred.
-
-
-
-
- CommInterfaceSend
-
-
-
- 106
-
- <system err> -- When ERR_COMM_PACKAGE is returned, 'add_info'
- contains the actual error returned by the
- communication package.
-
- Description
-
- This routine is used to send characters out the communication
- port. Your code must not call this routine directly. This
- routine will need to be modified to support your communication
- package. See the System Requirements section for a list of
- supported communication packages.
-
- Porting to other communication packages
-
- The following sample source code is written to interface with the
- Greenleaf CommLib. To support a different communication package,
- use this code as a template, then code according to the
- specifications of the communication package.
-
- This routine is easy to port. A call is made to 'asiputc' inside
- a 'for' loop for each character to be sent. The delay before
- value is done outside of the loop, and the delay between is done
- inside the 'for' loop.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CommInterfaceSend
-
-
-
- 107
-
- /********************************************************/
- int
- CommInterfaceSend (com, bef, bet, s, len, info, opts)
- int com; /* The AutoLibrary communication port. */
- int bef; /* The number of milliseconds to delay before
- sending first character. */
- int bet; /* The number of milliseconds to delay between each
- character. */
- char *s; /* The string to send. */
- int len; /* The length of the string. May not equal
- strlen(s) because of null characters in the
- string. */
- int *info;
- char *opts; /* Options. */
- /********************************************************/
- {
- int i, status;
-
- opts = opts; /* for compiler */
-
- /* Start out with no errors. */
- *info = ERR_OK;
-
- /* The delay before the first character sent. */
- delay (bef);
-
- for (i=0; i<len; i++) {
-
- /* The delay before the first character sent. */
- delay (bet);
-
- status = asiputc (comlist[com]->hw_port, s[i]);
- if (status != ASSUCCESS) {
- *info = status;
- return(ERR_COMM_PACKAGE);
- }
- }
-
- return(ERR_OK);
- }
-
- See Also
-
- AvidSend, Actual source code.
-
-
-
-
-
- CommInterfaceSend
-