..ti set ..tb 9 17 25 33 41 49 57 65 73 <TITLE>RPC User Manual <AUTHOR>T.J. Berners&hyphen.Lee CERN DD/OC <DATE>Version 3.0.0, Last Revised April 1990 <COPYRIGHT>CERN 1986, 87, 88, 89, 90 Now includes: Use of the internet daemon, Use of the WAY name server. <HP1>(Details about how to acquire a copy of this document are given in an appendix). </HP1> </TITLEP> <TOC> </FRONTM> <BODY> <H1>Introduction This manual describes how to build a distributed system using the Remote Procedure Call system developed in the Online Group of the DD Division of CERN, the European Particle Physics Laboratory. <h2> The system The remote procedure call product consists of two essential parts: an RPC compiler which is used during development of an application, and the RPC run time system, which is part of the run time code. Target systems supported are <ul> <li>VAX/VMS, <li>Unix (Berkley 4.3 or Ultrix or equivalent) <li>stand&hyphen.alone M680x0 (MoniCa) systems (Valet&hyphen.Plus, etc) <li>stand&hyphen.alone M6809 systems <li>M680x0 systems running RMS68K <li>M680x0 systems running OS9 <li>The IBM&hyphen.PC running TurboPascal or Turbo-C <li>The Macintosh running TurboPascal or MPW </ul> Application languages catered for explicitly are FORTRAN, C, Pascal and PILS. The RPC system will operate over media including DECNET, ISO Transport protocols, TCP/IP, RS232 lines, raw Ethernet, and "CERN Host Interface" VAX-FASTBUS FASTBUS-VME and VAX-VME links. Support for new target systems is added from time to time. Development on VAX/VMS, BSD 4.2 Unix (or Ultrix), or IBM-PC MSDOS host systems is described. <H2> Using this Manual This manual aims to be a complete reference text, and is not intended to be read from cover to cover at one sitting. <hp2> Most of it will not apply to you </hp2> so just read the first few chapters, and then parts relevant to your chosen operating system and communication medium. Detailed examples of the use of the compiler for different systems are provided. The internals, construction and maintenance of the compiler and run&hyphen.time systems are not covered. These are covered in the Internals Guide <BIBREF REFID=RPCIMP>. For an introduction to Remote Procedure Call, see <BIBREF REFID=VIR88>. For a discussion of design choices made in the design of this particular system, see <BIBREF REFID=RPCIMP> and <BIBREF REFID=RTC87>. For information on how to run an RPC application which has already been written, skip to the chapter "Running an RPC system". That chapter also gives details of supported systems, communications media and interface hardware. The steps involved in making a distributed system are dealt with, in this manual, in roughly chronological order. They are: ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skippic1 <FIG ID=PICT1 PLACE=INLINE FRAME=NONE> <PICTURE NAME=PICT1$$S> <FIGCAP><HP1>The steps in designing a distributed system </HP1> </FIG> ..go donepic1 ...skippic1 <FIG ID=PICT1 PLACE=INLINE FRAME=NONE> <XMP> +-----------------------------------------------------------+ | Design the system (Ch. 2) | +-----------------------------+-----------------------------+ | +-----------------------------+-----------------------------+ | Write a formal description of the | | module interfaces (Ch. 3) | +-----------------------------+-----------------------------+ | +-------------------+--------------+ | | | | +--------------+----------------+ +-----------+-------------------+ | Write the modules just | | Generate "stub" code by | | as though not distributed | | running RPC compiler | | (But see Ch. 6) | | (Ch.4) | +--------------+----------------+ +-----------+-------------------+ | | +-----------------+----------------+ | +---------------------------+-------------------------------+ | Compile and link the program modules with stubs | | and run&hyphen.time library (Ch. 5) | +---------------------------+-------------------------------+ | +---------------------------+-------------------------------+ | Define server addresses on client systems | | and client addresses on server system (Ch. 7) | +---------------------------+-------------------------------+ | +---------------------------+-------------------------------+ | Run the programs | +-----------------------------------------------------------+ </XMP> <FIGCAP><HP1>The steps in designing a distributed system </HP1> </FIG> ...donepic1 Chapter 8 describes special features of the RPC system. The Appendices contain information for reference about the RPC compiler, details of installation of the system, and pointers to more information. <H1>Designing a distributed system <I1 IX=1>System design <I1 IX=1>Designing the system Distributed design using RPC starts with the design of a modular program. It is wise (as in any system) to define the interfaces between the modules before writing each module. <h2> Design Rules <I1 IX=1>Restrictions In order that, in the final version, the modules can run on different machines, various rules must be followed: <OL> <LI> Control is not passed between modules except as a procedure call <LI> No data is to be passed between modules except explicitly <fn> In fact, mechanisms exist to have implicitly passed data (such as FORTRAN COMMON blocks) transferred as well. See the "PRAGMA external_marshalling" </fn> as parameters to procedures. <LI> It is better, for efficency, to make a few calls to a remote module rather than lots of calls transfering a little data each time. <LI> Also for efficiency reasons, it is a bad idea to pass large arrays unnecessarily. </OL> <I1 IX=1>Calling conventions The calling conventions used for remote procedures may be selected to be either FORTRAN, C, Pascal or PILS compatible, when the system is generated. Basically the RPC system can be easily used with most high level languages. There are some limitations imposed on data types: variant records ("unions" in C) are not handled by the compiler, for instance. <fn>You can handle them using the "External Marshalling" (q.v.) feature. </fn> FORTRAN and PILS have their own inherent limitations on data types if used. If pointers are passed from one machine to another, they may either be passed as integers, so that they retain their value but not their usefulness, or data structure to which they point can be transferred automatically, in which case they retain their meaning but not their literal value. Linked lists and trees of linked records may be passed so long as they are not circular. A full list of supported data types is given in an Appendix. <h2> Component parts Some of the code necessary to connect the local and remote parts of the programs are already written, and are contained in a run&hyphen.time library. This includes an interface to the various communications systems used. The remaining parts are the <HP2>"stub"</HP2> <I1 IX=1>Stub, definition of modules. These are generated specially for each application by an RPC compiler (RPCC). On the calling machine, there is a stub module which emulates the called procedure, and on the called machine there is a stub module which emulates the calling program. For ease of handling, related procedures are grouped into units called <I1 IX=1>Package, definition of <HP2>"packages"</HP2>. The package is the unit of compilation of stub modules, and a unit of addressing in the run&hyphen.time system. For example, a graphics package might contain all the procedures for graphics handling. For each package, the designer must write a definition file, described below. For each package, any module which calls the procedures is referred to as a <HP2>"client"</HP2>, <I1 IX=1>Client, definition of and the module which is called is referred to as a <I1 IX=1>Server, definition of <HP2>"server"</HP2>. <FIG ID=nFIG2 PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go sknfig2 <PICTURE NAME=NFIG2$$S> ..go donnfig2 ...sknfig2 (diagram omitted) ...donnfig2 <FIGCAP><HP1> The software components of a remote call. </HP1> </FIG> <H1>Writing the definition file <I1 IX=1>Definition file <I1 IX=1>Interface, definition file The RPC Compiler accepts a formal description of the procedures which are called remotely, and their parameters. It produces as output the necessary software to exchange data between your local application and the remote one. The input language is called RPCL. The <I1 IX=1>RPCL RPCL syntax is a similar to the ADA language; a formal description is contained in an appendix, to which the reader is referred for details. <FIG ID=DEFNF PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk3 <PICTURE NAME=DEFNF$$S> ...timsk3 <FIGCAP><HP1> The definition file defines the interface between two software modules. </HP1> </FIG> An example input file is <xmp> PACKAGE myfacility IS TYPE myarray IS ARRAY(1..20) OF RPC_LONG; PROCEDURE doit( xxx: IN RPC_SHORT; yyy: OUT myarray); END myfacility; </xmp> The package in this example contains a procedure to set the state of, say, a remote valve. The procedure takes three input parameters from the caller: two integers ..bf mono (func, index) ..pf and a real. It does not alter the value of these. It has one output parameter which happens to be the last one, a 32 bit status value ..bf mono (stat). ..pf The procedure does not use the initial value of ..bf mono stat, ..pf but a new value is returned to the caller. (In the examples, the reserved words are given in upper case for clarity, although in an input file upper and lower case are treated the same.) In general, the input file is composed of two parts: type declarations and procedure/function declarations. In a type declaration complicated types may, if necessary, be defined in terms of simpler types. In the second part of the file, the remote procedures and functions are defined by giving, for each one, its name, the number an type of parameters, their direction and, for a function, the type of value returned. This is very <i1>Procedure <i1>Function similar to the declaration of a external procedure in other high level languages. <BOX> <XMP> -- Example: RPCL Definition of a FILE ACCESS PACKAGE -- PACKAGE filer IS -- Type declaration part: TYPE my_int IS RPC_SHORT; TYPE my_long IS RPC_LONG; TYPE my_subs IS SUBSTRING(255); TYPE my_type IS ARRAY(1..4) OF RPC_CHAR; -- Procedure declaration part: PROCEDURE f_init( status: OUT my_long); PROCEDURE f_end( status: OUT my_long); PROCEDURE f_open( unitno: IN my_int; name: IN my_subs; mode: IN my_int; nameuse: IN my_type; status: OUT my_long); PROCEDURE f_close(unitno: IN my_int; status: OUT my_long); PROCEDURE f_getline( unitno: IN my_int; linebuf: OUT my_subs; ch: OUT my_int; status: OUT my_long); PROCEDURE f_putline( unitno: IN my_int; name: IN my_subs; status: OUT my_long); PROCEDURE f_rename(name1, name2: IN my_subs; t1, t2: IN my_type; status: OUT my_long); PROCEDURE f_errmess(messno: IN my_long; name: OUT my_subs; status: OUT my_long); END filer; </XMP> </BOX> .pa Below are the equivalent Pascal declarations for each procedure in the example above. <XMP> PROCEDURE f_init ( PROCEDURE f_putline ( VAR status : my_long); VAR unitno : my_int; EXTERN; VAR a_name : my_subs; VAR s_name : rpc_short; PROCEDURE f_end ( VAR l_name : rpc_short; VAR status : my_long); VAR status : my_long); EXTERN; EXTERN; PROCEDURE f_open ( PROCEDURE f_rename ( VAR unitno : my_int; VAR a_name1 : my_subs; VAR a_name : my_subs; VAR s-name1 : rpc_short; VAR s_name : rpc_short; VAR l_name1 : rpc_short; VAR l_name : rpc_short; VAR a_name2 : my_subs; VAR mode : my_int; VAR s_name2 : rpc_short; VAR nameuse : my_type; VAR l_name2 : rpc_short; VAR status : my_long); VAR t1 : my_type; EXTERN; VAR t2 : my_type; VAR status : my_long); PROCEDURE f_close ( EXTERN; VAR unitno : my_int; VAR status : my_long); PROCEDURE f_errmess ( EXTERN; VAR messno : my_long; VAR a_name : my_subs; PROCEDURE f_getline ( VAR s_name : rpc_short; VAR unitno : my_int; VAR l_name : rpc_short; VAR a_linebuf : my_subs; VAR status : my_long); VAR s_linebuf : rpc_short EXTERN; VAR l_linebuf : rpc_short VAR ch : my_int; VAR status : my_long); EXTERN; </XMP> This list of declarations is automatically generated by the RPC Compiler, as the .ext file described in the next section. <h2> PRAGMAs A PRAGMA is a statement in an RPC definition file which instructs the compiler how to implement something, without fundamentally changing the definition of the interface. A PRAGMA consists of the word PRAGMA followed by the name of the pragma, followed by (in brackets) the name of things to which it applies, and any other parameters. <i1 ix=1>PRAGMA <h3> PRAGMA TIMEOUT Syntax: <xmp> PRAGMA TIMEOUT ( <procedure_name> , <value> ); </xmp> <I1 IX=1>Pragma TIMEOUT <I1 IX=1>Timeout, pragma for each procedure This specifies the absolute maximum time which the procedure could possibly be expected to take, including any network delays. The RPC system will check this time (when the underlying transport service allows it) and if it expires will create and error. This will halt the program unless a user Error Handler (q.v.) or a Call Status parameter (q.v.) is used. If this pragma is not used, the default will be no timeout, or the value specified with the TIMEOUT compiler option, if that has been given. The procedure (or function) name given must already have been declared. The value is given in units of 10ms as a decimal integer value. <h3> PRAGMA CONCURRENT Syntax: <xmp> PRAGMA CONCURRENT ( <procedure_name> , { <procedure_name> }* ); </xmp> <I1 IX=1>Pragma CONCURRENT <I1 IX=1>CONCURRENT pragma <i1 ix=1>Asynchronous execution the {braces}* indicating more than one (previously declared) procedure name may be given. This specifies that, once started, the procedure should continue execution concurrently with the client. The fact that the client continues processing after the procesdure call does not, in this case, signify that the procedure is complete: only, that it has started. <FIG ID=CONCU PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk6 <PICTURE NAME=CONCU$$S> ...timsk6 <FIGCAP><HP1>The flow of control for a normal call and for a concurrent call. </HP1> </FIG> The procedure (<hp2>not</hp2> function) name given must already have been declared. It may not have any return (OUT or INOUT) parameters. This method provides concurrency between the caller and the called routine. There are other methods of achieving concurrency, for example which allow a separate server task to run concurrently with the client processes, and be interrupted to service a remote call. These are described later under "varieties of server". See also PRAGMA CAST below. <h3> PRAGMA CAST ..bx on 81 Syntax: <xmp> PRAGMA CAST ( <procedure_name> , { <procedure_name> }* ); </xmp> <I1 IX=1>Pragma CAST: One way messages <I1 IX=1>CAST pragma <i1 ix=1>One&hyphen.way calls <i1>Streamed RPCs (CASTs) <i1>Broadcast calls <i1>Multicast calls <i1 ix=1>Asynchronous execution the {braces}* indicating more than one (previously declared) procedure name may be given. This specifies that no return message should be sent at all. The call message is sent and return is immediately made to the caller. Over a reliable stream oriented medium (TCP, DECnet, ISO TP4, CHI etc.), this allows information to be streamed between a client producing it and a server receiving it. This may significantly increase the efficiency in some applications. Over a non-reliable medium (raw ethernet, UDP etc.), this option supresses the protocol which ensures reliable transmission of the data.There is no acknowledgement made at all. This can <hp2>speed up</hp2> execution by a factor of two or more. Pragma CAST also allows broadcast and multicast calls to be made where the transport protocol supports it, for example over raw ethernet. <FIG ID=CONCU PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk7 ..fo off Client Server | |------- call message -----> | | | | | - (There is no reply) | V execution continues ..fo on ...timsk7 <FIGCAP><HP1>The flow of control for a cast. </HP1> </FIG> The procedure (<hp2>not</hp2> function) name given must already have been declared. It may not have any return (OUT or INOUT) parameters. ..bx off <h3> PRAGMA CALL_STATUS Syntax: <xmp> PRAGMA CALL_STATUS ( <procedure_name> , <parameter_name> ); </xmp> <I1 IX=1>Call status parameter <I1 IX=1>Status parameter for call status <I1 IX=1>Error, return to user parameter <I1 IX=1>Pragma, CALL_STATUS This informs the compiler that the parameter indicated is a status parameter for the return of any bad call status. In this case, if any error (network failure, timeout, etc.,) occurs during the call, a VMS&hyphen.style error code will be put into this parameter and all the other OUT parameters (and return value of a function) will be undefined. In this case the RPC system will <hp2>not</hp2> take the normal error action (calling user error handlers or aborting the program with an error message). The procedure (or function) name given must already have been declared. The parameter name must be the identifier of one of the parameters of that procedure. The parameter must be OUT or INOUT, and of type RPC_LONG. <h3> PRAGMA EXTERNAL_MARSHALLING Syntax: <xmp> PRAGMA EXTERNAL_MARSHALLING ( <type_id> ); </xmp> The type_id must refer to a previously defined type. This tells the compiler that external procedures ..bf MONO PCK_<type_id> ..pf and ..bf MONO UPK_<type_id> ..pf will be used to marshal and unmarshal (respectively) the given type. Marshalling is the process of taking data from the user space and putting it into a message in the correct format for transmission. <I1 IX=1>Marshalling, external <I1 IX=1>External marshalling <I1 IX=1>User-defined marshalling <I1 IX=1>COMMON blocks, automatic transfer <I1 IX=1>Types, user defined <I1 IX=1>Pragma, EXTERNAL_MARSHALLING This pragma will allow types whose data type is a function of circumstance (unions, private conventions, etc) to be transferred as RPC parameters. It also allows the RPC system to send any related data which may be required, such as to send over parts of a FORTRAN common block. Also, side effects may be put into user marshalling routines, such as parameter value checking, rebinding of the client depending on a particular parameter value, etc. The type must already be declared, and it is this declaration which will decide how much memory is allocated to receive a variable of this type in the server. The marshaling routines must be provided by the user, or may be distributed with a library for certain special types. Their format is as follows: <xmp> -- Marshalling for type <type_id> PROCEDURE PCK_<type_id> ( rpc_p_buf: IN rpc_buffer_pointer; -- by reference variable: IN <type_id>); -- by reference -- Unmarshalling for type <type_id> PROCEDURE UPK_<type_id> ( rpc_p_buf: IN rpc_buffer_pointer; -- by reference variable: OUT <type_id>); -- by reference </xmp> The writer of these routines is recommended to build them in terms of the basic routines such as PCK_INTEGER etc which are defined in the include files RPCSTUB.H (Pascal), rpcheader.h (for C). (Under VMS, these files are under the RPC_INC directory). <H1>Running the RPC Compiler <I1 IX=1>Compiler RPC <I1 IX=1>RPC compiler <I1 IX=1>RPCC command <I1 IX=1>RPC command The syntax to invoke the compiler is: Under VAX/VMS, or MSDOS: <XMP> RPCC <source_file_name> [/option] [/option] ... or RPC <source_file_name> [/option] [/option] ... </XMP> The first form produces stubs in Pascal, FORTRAN, PILS or C, which you then compile. The second form, only available under VMS, is used for Pascal, and also runs the stubs though the preprocessor and (for VMS/Pascal or CERNCROSS pascal) compiles them. <FIG ID=COMPI PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk4 <PICTURE NAME=COMPI$$S> ...timsk4 <FIGCAP><HP1> The RPCC command generates the souces for the stubs. The RPC command under VMS performs all the functions in the dotted circle, for Pascal only). </HP1> </FIG> Under Bsd UNIX, Ultrix: <I1 IX=1>Unix, command format <xmp> rpcc <source_file_name> [-option] [-option] ... </xmp> The source file is the RPCL description file described in the previous section. This file name can have any extension except '.ext'. The compiler options are listed below. The RPCC lists, on the standard output device, the generated version number of the stub, (see the /VERSION option), and a list of errors, if any. If no error has been found, it produces three output files called, by default: <xmp> cli<source_file_name> (The client stub module) ser<source_file_name> (The server stub module) <source_file_name>.ext (A Pascal or C declaration file) </xmp> The '.ext' file contains a Pascal or C declaration of the procedures declared in <I1 IX=1>EXTernal declaration file RPCL. This is a declaration of external procedures <fn> See also the TYPES option, later in this chapter. </fn> that you can use to include in your client program if you are programming in Pascal or C. Note that under VAX/VMS you must run a command file (@DISK$D1:[RPC]RPC on VXCERN, on other machines it is @[...]SETUP in the directory in which the RPC software has been installed) to gain access to RPC commands, while under UNIX BSD the 'rpcc' should be present in any directory of your PATH shell variable. <H2>Target environment options The stub code produced by the RPCC may be in FORTRAN, C, or in Pascal with INCLUDE preprocessor statements. If the RPC command is used, the pascal will be put through the INCLUDE preprocessor automatically, and compiled to object format where a compiler exists on the machine. <I1 IX=1>Target selection <I1 IX=1>Stub, source files The code may be tailored for one of the following compilers: <UL> <LI>A C compiler. <LI>A FORTRAN77 compiler. <li>A PILS compiler or interpreter <LI>Omegasoft Pascal (version 2) for the M6809. <LI>VAX/VMS PASCAL, <LI>CERN Cross Software Pascal 2.5 for the Motorola 68000 family, <LI>UNIX Berkeley (or Ultrix) Pascal compiler <LI>IBM PC Turbo Pascal <LI>A standard Pascal compiler without modular compilation, </UL> <I1 IX=1>C language <I1 IX=1>PILS <I1 IX=1>Omegasoft pascal <I1 IX=1>Pascal Omegasoft <I1 IX=1>Pascal VAX <I1 IX=1>Unix , compiling stubs for <I1 IX=1>Turbo Pascal <I1 IX=1>Pascal, on the IBM PC <I1 IX=1>IBM PC , compiling stubs for In all but the last case, separately compilable modules are produced which can be simply linked to your application. In the last case, standard Pascal <I1 IX=1>monolithic compilation <I1 IX=1>Pascal standard code is provided for those applications that require monolithic compilation. In such a case one must include (by hand using the editor, or using a preprocessor) the code generated by RPCC in the main program before compilation. The target environment is specified separately for client and server using the following options: <xmp> c<environment> [ =<filename> ] </xmp> to specify the client (caller) environment, and the option <xmp> s<environment> [ =<filename> ] </xmp> to specify the server (called) environment. The =<filename> clauses are optional, and allow the name of the output file to be specified explicitly, overriding the default This clause is not available for the RPC form, only for RPCC. The <environment> can be one of the following: <DL TSIZE=15> <DT>genericC <DD> A standard C compiler. The files produced refer to an include file, rpcheader.h, which is supplied with the release. Under VMS, compile the stubs using the <P> $ CC/INCLUDE=RPC_INC/DEFINE=VAXVMS option to have access to this file and select the correct compilation option. <DT>FORTRAN <DD> A FORTRAN77 compiler. If structures are specified in the RPC definition file, the FORTRAN stubs will have structures in VAX/FORTRAN format. <DT>PILS <dd>A PILS (Portable Interactive Language System) compiler or interpreter. <DT>cerncross <DD> Cern Cross Pascal M680x0 compiler; <DT>M6809 <DD> Omegasoft M6809 Pascal Compiler; <I1 IX=1>M6809, selecting target <DT>vaxpascal <DD> VAX/VMS Pascal compiler. Strings are of type VARYING OF CHAR. <DT>vaxvms <DD> VAX/VMS Pascal compiler (strings FORTRAN compatible). This options is included for back-compatibility but is not recommended. <DT>unixbsd <DD> Berkley Unix (or Ultrix) Pascal Compiler; <I1 IX=1>Pascal, Unix Berkley <DT>pcturbo <DD> The Turbo Pascal system on the IBM&hyphen.PC <DT>monolith <DD> A standard pascal compiler without modular compilation; </DL> You should put at most one option for the client environment and one for the server environment. If you want to generate stub code for several environments, you must run the compiler several times giving different options each time. <HP1>Example: The following command under UNIX generates pascal code for UNIX for the client side (into clifiler.rpc) and VAX/VMS for the server side (into the file mysstub.pas). It is supposed that input definition file is in 'filer.rpc'.</HP1> <xmp> rpcc filer.rpc -cunixbsd -svaxvms=mysstub.pas </xmp> <HP1>The following command under VAX/VMS generates object code for VAX/VMS for the client side (CLIFILER.OBJ) and M680X0 for the server side (SERFILER.CUF) . The input definition file is in FILER.RPC.</HP1> <xmp> $ RPC FILER.RPC /CVAXVMS /SCERNCROSS </xmp> <H2>Calling convention, BYVALUE <i1 ix=1>BYVALUE compiler option <I1 IX=1>Calling conventions This section does not apply to PILS or FORTRAN stubs. In Pascal or C, stubs may be generated to respect either the FORTRAN, Pascal or C conventions. Intermediate possibilities exist, or example for C programs which are written to be FORTRAN callable. The conventions used by the client stub should match those of the client program, and the conventions of the server stub must match those of the server routines. By running the compiler twice, it is possible to generate stubs of both types for the same package. These will be able to communicate with each other, so, for instance, a FORTRAN main program will be able to call subroutines written in C, and vice&hyphen.versa. The two chief areas of difference are in the way strings are passed, and the way simple types are passed as IN parameters. <ul> <li> For simple IN parameters, the deault is passing by address, for FORTRAN compatability (whatever language the stubs are generated in). The ..bf MONO ..bd BYVALUE ..pf option allows them so be passed by immediate value. <FN> Not possible with SVAXVMS, CVAXVMS, SVAXPASCAL, CVAXPASCAL options. This is because under VAX/VMS, the Pascal is FORTRAN compatible, so a parameter is <hp1>always</hp1> passed by address, even if it is not "VAR". Therefore, VAX/Pascal stubs will not be compatible with C code. If C compatability is required, the stub should be generated using the genericC opions. </FN> <li> The string passing is determined solely by the language option chosen. In C, the strings are null terminated, in Pascal they are passed by native Pascal string type (where available), by descriptor (VAXVMS option), or otherwise as two arguments, an array and a length. See the appendix on supported data types for details. </ul> <HP1>The following command under VAX/VMS generates C code for both stubs, which will be compatible with C client and server modules. </HP1> <xmp> $ RPCC FILER.RPC /CGENERICC=CLIFILER.C /SGENERICC=SFILER.C /BYVALUE </xmp> To summarise the possible combinations, <dl TSIZE=20> <DT>Pascal <DD>Default, FORTRAN compatible. If the user program is in Pascal, all parameters must be passed "VAR". <DT>Pascal, BYVALUE <DD>Pascal compatible, with IN parameters not passed with pascal "VAR". <DT>GenericC <DD>This combination may be used to make stubs in C to be called from FORTRAN, where a pascal compiler is not avilable (OS9), but beware of the differences in string passing convention. All parameters must be passed by address (with an "&" in C). <DT>GenericC, BYVALUE <DD>C compatible. </dl><H2>Producing Type Declarations - TYPES The option ..bf MONO ..bd TYPES ..pf causes the user's type definitions to be included in the declaration (.ext) file. This is a convenient feature if the .ext file if to be used directly as a basis for the client or server program. If the user's types definitions already exist, or must be defined in terms of other types not in the RPC definition file, then this option will not be useful. <H2>Auto&hyphen.Initialisation: NOAUTOINIT <I1 IX=1>Initialisation automatic This section applies in conjunction with VAXVMS, VAXPASCAL, PILS, PCTUBO or MACTURBO client and server options only. In these cases, normally, the client and server stubs are initialised <fn> Under VMS, the [INITIALIZE] attribute of a procedure is used to cause initialisation code to be put into the LIB$INITIALIZE PSECT so that the procedure will be called on image load. Under PILS or TurboPascal, each module contains a main section which is called initially before the main program. </fn> when a program is loaded, and make contact with each other automatically. Use of the ..bf MONO NOAUTOINIT ..pf <I1 IX=1>AUTOINIT <I1 IX=1>NOAUTOINIT option suppresses this facility. In this case, the user is responsible for calling RPC_Open (on the <I1 IX=1>RPC_Open called automatically <I1 IX=1>RPC_Attach called automatically client) and RPC_Attach (on the server) for each stub. See the section on initialisation procedures. The initialisation makes the RPC system totally invisible to the user code, but you may wish to suppress it for portability, or for introducing your own special initialisation code. <HP1>Example:</HP1> <XMP> $ RPC FILER.RPC /SVAXVMS /CVAXVMS /NOAUTOINIT </XMP> <H2>CONCURRENT Execution option <I1 IX=1>CONCURRENT execution The ..bf MONO concurrent ..pf option modifies the code produced by the compiler, by making the ..bf mono PRAGMA CONCURRENT ..pf implicitly apply to all procedures which return no results, that is, procedures (not functions) which have no OUT or INOUT parameters. For these procedures, the server stub is made to reply immediately to the caller, <HP1>before executing the called routine.</HP1> See under "Pragmas". <HP1>Example:</HP1> <XMP> $ RPCC FILER.RPC /SFORTRAN=S.FOR /CFORTRAN=C.FOR /CONCURRENT </xmp> Users of this facility should bear in mind, however, that the semantics of a <HP1>concurrent</HP1> remote call differ from those of a local call. <h2>LARGE parameter option Under VMS, and using the RPC (not RPCC) command only, stubs may be generated with the parameter size extended to 8kB from 1.5kB. When this is done, <ol> <li>When using the RPC command and Pascal stubs, the ..bf MONO LARGE ..pf option must be specified. (Not required for C or FORTRAN stubs). <li>The resulting stubs must be linked with the RPC_LARGE library rather than the RPC_LIB library. (These are logical names). <li>Communication is not available over raw ethernet. </ol> <H2>Error messages and error recovery <I1 IX=1>Error messages from compiler When the RPCC finds an error it prints on the standard output the line number in which the error occurred, then the offending input line with an arrow below the first character of the word that was wrong and finally, on the third line, the error meassage. Error messages are in English and should be quite self&hyphen.explanatory so no other information is provided. In general the RPCC tries to recover from the error without aborting. If the error is not fatal, a semicolon forgotten for example, the compiler inserts or deletes a word (token) and continues to parse the input. If the error is not simple, a very malformed declaration for example, the compiler skips the input until a meaningful structure is found. Sometimes this attempt at recovery can produce misleading error messages, so be careful, and try to correct the very first error before going on. If any errors at all are encountered, no code generation is performed. <H1>Building An Example RPC Application <I1 IX=1>Building a system <I1 IX=1>Linking a system together <I1 IX=1>Binding, compilation time The following example shows the commands needed to build a RPC application, a rather simple file server called "Filer". VAX/VMS is used here for illustration: There are further examples under the later sections which deal with each environment. Suppose we have a program called MYPROG.FOR written in FORTRAN and running on a VAX under VMS. This needs to call procedures in a module called FILER written in Pascal and running on an M68020 under MoniCa. The interface between the two is described in RPCL in the file FILER.RPC. Because this is an example we have deliberatly chosen Fortran for the main program and Pascal for the server to show a mixed language application: however, the modules could as well both have been written in the same language, and run on the same type of machine. <H2>Under VMS First of all we compile the main program using the native FORTRAN compiler, generating the file MYPROG.OBJ, and we compile the server module using the cross Pascal compiler, generating the file FILER.CUF. We then generate the stub code for each system using the RPC Compiler: <XMP> $ RPC FILER.RPC /SCERNCROSS $ RPCC FILER.RPC /CFORTRAN=CLIFILER.FOR </XMP> These commands will produce (if no errors are found) the files: <XMP> SERFILER.CUF The server stub, in M680x0 object format FILER.EXT The Pascal declaration file CLIFILER.FOR The client stub in FORTRAN </XMP> The client stub is compiled: <xmp> $ FORTRAN CLIFILER </xmp> Next, we link together the VAX image: <XMP> $ LINK MYPROG, CLIFILER, rpc_lib/OPT </XMP> We now have an executable file, MYPROG.EXE, which, when run, will call the remote version of FILER. To link the M68k object modules together, we have to first concatenate <I1 IX=1>UNIPUSH <I1 IX=1>CUFLINK them into one file, then use CUFLINK, then format the result with UNIPUSH: <XMP> $ COPY FILER.CUF, SERFILER.CUF FILER.CCU <P> $ CUFLINK FILER.CCU, rpc_lib68, FILER, - <P> MYLOP, MYOPT, MYLMP <P> $ UNIPUSH FILER </XMP> ..cm @@ Diagram: data flow The result is FILER.ABS, a Motorola "S&hyphen.format" loadable file which, <I1 IX=1>ABSolute format <I1 IX=1>S record format when run, will provide the service required by MYPROG.EXE. (The use of cross software under VAX/VMS, and the significance of the LOP, OPT and LMP files, is described in <BIBREF REFID=XSOFTN3> and its references). The name ..bf MONO rpc_lib68 ..pf is a logical name. <I1 IX=1>rpc_lib68 The actual file used to satisfy entry points into the RPC system will depend on the target M680x0 system being used, typically the MONICA.ROM file. <H2>Stubs in C This example is equivalent to the example above, but we assume that the client and/or server routines will be written in C. (The client stub should be produced in C if the client module is in C, and the server module should be produced in C if the server module is written in C. This does not stop a C client talking to a FORTRAN server, for instance, as the communication format used between the stubs is the same in all cases) The RPCC command is used. To make the VMS client, the commands would be <xmp> ..fo off $ RPCC FILER.RPC /CGENERICC=CLIFILER.C/BYVALUE ! Make CLIFILER.C $ CC/INC=RPC_INC/DEFINE=VAXVMS CLIFILER ! Make CLIFILER.OBJ $ LINK MYPROG, CLIFILER, rpc_lib/OPT ! MAKE MYPROG.EXE </xmp> and to make ther server, <xmp> ..fo off $ RPCC FILER.RPC /SGENERICC=SERFILER.C/BYVALUE ! Make SERFILER.C $ CC/INC=RPC_INC/DEFINE=VAXVMS SERFILER ! Make SERFILER.OBJ $ LINK FILER, SERFILER, rpc_lib/OPT ! Make FILER.EXE </xmp> ..fo on In this case, FILER must contain, apart from the server subroutines, a small main program to attach the server stub to the run-time system, and call the server loop. (See Chapter 6) <H2>Explicit Post Processing of Pascal stubs <I1 IX=1>Explicit post processing <I1 IX=1>Post processing, explicit (This section is only relevant to users making stubs in Pascal, and who wish to modify them by hand). The RPC command used above produces object modules via intermediate files generated in Pascal. In some cases, howver, one may wish to invoke the RPC compiler only to produce source versions of the stub code, which can then be modified before compilation. In this case, the RPCC (two C's) command is used, and the compiler produces the source files: in our example above, these would be, by default, <xmp> CLIFILER.RPC The client stub, in M68020 Pascal SERFILER.RPC The server stub, in VAX/VMS Pascal FILER.EXT The Pascal declaration file (as before). </xmp> The .RPC files must be put through the INCLUDE preprocessor to make pascal files, and these must in turn be compiled using a suitable pascal compiler. In the example above, the operations required are as follows: We compile the client stub using the INCLUDE preprocessor, and the native VAX Pascal compiler. <xmp> $ INCLUDE CLIFILER.RPC CLIFILER.PAS +VAXVMS $ PASCAL CLIFILER </xmp> This generates the object file ..bf MONO CLIFILER.OBJ. ..pf <FN> (Theer is also an optional +ALIGN keyword, (See index "ALIGN") as discussed in a later chapter, but its inclusion is not recommended). </FN> on it. (Note the upper case for all keywords). To make the M68k code, we compile the server stub, SERFILER.RPC, using the Cross PASCAL compiler and the INCLUDE preprocessor: <xmp> $ INCLUDE SERFILER.RPC SERFILER.PAS CERNCROSS $ NEWP68K SERFILER </xmp> generating the object file SERFILER.CUF for the M68k. <I1 IX=1>INCLUDE program The INCLUDE program is part of the CERN cross software suite for the M680x0 processors, and is described in outline in <BIBREF REFID=XSOFTN3>. <H2>Under Unix <I1 IX=1>Unix, development under If the development of the M68k part were to be done under Berkley Unix or Ultrix, the commands would have been similar to those used above, with explicit post processing of the stubs: <xmp> rpcc filer.rpc -ccerncross -svaxvms include CERNCROSS < serfiler.rpc > serfiler.p pasc68k serfiler cat filer.cuf clifiler.cuf > myprog.ccu cuflink myprog <RPC_library_path_name> unipush myprog </xmp> The file CERNCROSS.DFS is not needed in this case, as the keywords are command line parameters. This will similarly produce the file 'myprog.abs'. Note that, whereas on the client side the user program is a main program, on the server side the user code is just a called module. A main program module is, however, necessary on the server side, to call the RPC system and ask it to service future requests. In the example above it is assumed that this is part of FILER.CUF. This module is normally quite simple, and is discussed in the next chapter. <H1>Initialisation procedures On VAX/VMS systems using Pascal, on PILS systems, and on Turbopascal systems, the stub modules are automatically called before the main program is run, and so initialise themselves. The application program need not, therefore, be aware that the modules with which it has been linked are remote. A server loop module which may serve as a main program is available in the run&hyphen.time library. See the example "VAX-VAX over Decnet" later on. Under Turbo Pascal, the user must include a "USES" clause in his program referencing each stub his program uses. On other target systems, the initialisation procedures must be called explicitly from the application program, as follows. <H2>General Initialisation <I1 IX=1>Initialisation, manual Not required for VAX/VMS, TurboPascal, PILS or MoniCa based systems. If the RPC system is not built into the environment you are using (such as MoniCa or a version RMS68K) it must be initialised by calling RPC_Init (no parameters) before any other RPC routines. <xmp> ..tb 9 17 25 33 41 49 57 65 73 CALL RPC_INIT ! in FORTRAN rpc_init(); /* in C */ rpc_init; { in pascal } rpc_init; -- in ADA </xmp> <H2>Client Initialisation In the client, all that is required is that for each server xxx to be used, the procedure OPEN_xxx is called once, before any other calls are made. ..us Example (C) <box><xmp> main() { open_filer; /* Initialise FILER stub */ ... /* rest of program */ } </xmp></box> ..us Example (FORTRAN) <box><xmp> PROGRAM FRED CALL OPEN_FILER C ... the rest of the client program ... END </xmp></box> If you want to explicitly give the rpc address of the server from your program, for instance if you want to handle many servers of the same type, see Section 8.3.2. and the library call RPC_Open. <H2>Server Programs For the server, a simple main program is required which will first attach the stubs which are available to the run&hyphen.time support, and then call the run&hyphen.time support routines to service any incoming requests. <FIG ID=INITI PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk5 <PICTURE NAME=INITI$$S> ...timsk5 <FIGCAP><HP1>The client stub (left) and the server stub (right) both announce themselves to the Run Time Support library. On the server side, a small main program calls a server loop in the RTS. </HP1> </FIG> An example server in C, and the equivalent in Pascal follows: <box> <xmp> #include <rpcheader> main() { int status; rpc_init(); /* (Not for VMS version or MoniCa) */ attach_filer(); /* Declare stub */ rpc_loop_server(&status, /* Loop until fatal error */ "RPC_CLIENT_NAME "); /* Note this name must be 40 characters long */ rpc_report_error(status); /* Report any error */ } /* end of main */ </xmp> </box> The equivalent pascal follows. The *INCLUDE statements are to be processed by the INCLUDE preprocessor. <box> <XMP> PROGRAM SERVERLOOP; { Example server program } CONST *INCLUDE RPC_CONST TYPE *INCLUDE RPC_TYPES { Define RPC types } VAR status: rpc_status; client_name: rpc_name; { Clients for main loop } *INCLUDE RPC_PROC { Declare library procedures } PROCEDURE attach_filer; extern; { Contained in SERFILER stub } BEGIN attach_filer; { Make stub known to run&hyphen.time system } { Not necessary on VAX/VMS } client_name:= 'RPC_CLIENT_NAME '; RPC_Loop_Server(status, client_name); rpc_report_error(status); END. </XMP> The following example is in VAX/FORTRAN. Note the %REF(). For deatails of passing parameters of different types to RPC_XXX routines, see the introduction to appendix B. <XMP> C VAX/FORTRAN example of a simple RPC server program PROGRAM SERVERLOOP INTEGER*4 STATUS CHARACTER*40 CLIENT C Attach the server stub to the RPC system: CALL ATTACH_FILER C Run a server loop indefinitely unless error occurs: CLIENT = 'RPC_CLIENT_NAME' CALL RPC_LOOP_SERVER(STATUS,%REF(CLIENT)) CALL RPC_REPORT_ERROR(STATUS) END </XMP> </box> If more complex configurations are required, they can be built, as decribed later ("varieties of server", in Chapter 8). <H1>Running an RPC system You should read the general section of RPC addressing, then the specific sections both for your communications medium, and for each machine you are running on. <H2>Defining server addresses <I1 IX=1>Address server When an RPC system is made, none of the modules have, built into them, a knowledge of the addresses of other modules required. Therefore, before running a distributed system, this information must be set up, so that the run&hyphen.time support system can make the necessary connections. This is done by associating an address string with the name of each remote package. This address must be known on any machine that will need to access that package. On VAX/VMS, the logical name system is used. Under OS9, MSDOS or Unix, the "shell" evironment is used. Under MoniCa, the <I1 IX=1>DEFINE command <I1 IX=1>Environment variables (OS9, Unix, MSDOS) <I1 IX=1>Configuration file (Mac, M6809) symbol table is used. On the Macintosh and on the M6809 under FLEX, no such device exists, so the definitions are stored in a file. See the section relating to your particular system for details. For VMS or MoniCa, the command to define the server address to be used by the client is the same: <xmp> DEFINE <remote package name> <server address> </xmp> Under Unix or OS9 it is <xmp> setenv <remote package name> <server address> </xmp> Under MSDOS it is <xmp> SET <remote package name>=<server address> </xmp> without any spaces surrounding the '=' sign. <HP1>Example</HP1>: <xmp> VMS: DEFINE filer "FILER@AA_00_04_00_2F_58.ETHERNET" MoniCa: DEFINE filer FILER@AA_00_04_00_2F_58.ETHERNET OS9: SETENV filer FILER@AA_00_04_00_2F_58.ETHERNET MSDOS: SET filer=FILER@AA_00_04_00_2F_58.ETHERNET unix: setenv FILER FILER@AA_00_04_00_2F_58.ETHERNET </xmp> (The "quotation marks" are necessary under VMS only, if the string contains an @ sign.) There is currently a limit of 40 characters on the length of a logical or physical name. The format of the <server address> is defined below. A similar scheme is used to define the client(s) to which a server process requests. This is done (for the standard server) by defining the name RPC_CLIENT_NAME to give the <medium address> of the client. ..cc 3 <HP1>Example</HP1>: DEFINE RPC_CLIENT_NAME *.ETHERNET <H2>RPC address format The rpc address of a <HP1>server</HP1> has two parts. The first is a package name or number, used to distinguish different packages attached to the same <medium address>. <I1 IX=1>Address, medium <xmp> ..tb 9 17 25 33 41 49 57 65 73 <server address> ::= <package name> @ <medium address> or <package number> @ <medium address> or <medium address> or <package name> </xmp> <ol> <li>In the first case, the <package name> must be the name used in the package declaration. At initialisation time, the client machine will interrogate the server machine, to acquire a corresponding number for use during actual remote calls. <li>In the second case, if the package number is known by the client in advance, specifying it explicitly will save a little time and allow back-compatibility with previous systems. Package numbers are allocated by the server run&hyphen.time system, as the packages are attached to the server, starting from zero. <li>In the third case, neither a name or number is given. The RPC system will assume that the logical name given was the package name, and use that. For example, to define <xmp> $ DEFINE FILER MYTASK.DECNET </xmp> is equivalent to defining <xmp> $ DEFINE FILER "FILER@MYTASK.DECNET" </xmp> <li>In the last case, no <medium address> is specified, and so ".LOCAL" is assumed (see below). Therefore, if no address is given, the RPC system system will assume that the server stub (as well as the client stub) is linked locally to the same program. </ol> A <HP1>client</HP1> is identified to a server by the <medium address> alone. The second part, the medium address, is in turn composed of two pieces. The first is a network or similar address, in a format depending on the medium. The second is the name of the medium. <medium address> ::= <net address> . <medium> The format of <net address> depends on <medium>, and is given below, <I1 IX=1>Address network for each communication medium. <H2>LOCAL routing <I1 IX=1>Address LOCAL <I1 IX=1>LOCAL address It is possible, if your are using the advanced client features, (described in next chapter) that one wants a package to be either remote or local, as selected at runtime. In this case, the <medium address> for a local call is simply LOCAL . <HP1>Example</HP1>: <xmp> DEFINE PHI1 PHI1@LOCAL </xmp> <h2>Using the WAY Name Server RPC implementations for Unix, OS9, MSDOS/TurboC, and VMS over TCP allow the WAY ("Where Are You") name server to be used. This allows clients to find servers automatically at run time. To use an existing WAY server, all you have to do is know it's address. To run your own WAY server, see the WAY manual <BIBREF REFID=WAY> There are two environment variables (logical names) which are looked up to control the use of WAY. To allow clients to interrogate WAY, just define <xmp> way_request </xmp> as the RPC address of the name server. To cause servers to automatically register themselves with WAY, just define <xmp> way_register </xmp> as the RPC address of the name server. In the following example script file, both request and registration are enabled, using a name server we imagine is running on port 5678 on node priam. The server is started to use any free TCP port. It registers itself automatically when it runs. The serevr is forked off as a seperate process, then the client is run. The client picks up the actual port number from the name server when it runs. <xmp> setenv way_request 'way@priam:5678.tcp' setenv way_register 'way@priam:5678.tcp' setenv RPC_CLIENT_NAME '*.tcp' my_server & my_client </xmp> WAY provides many other facilities, for example the use of an initial WAY database. these are descibed in <BIBREF REFID=WAY>. ..pa <h2>Using the Internet: TCP and UDP Remote procedure calls can run over TCP/IP and UDP/IP services. This section gives common information about using TCP or UDP, whatetever machine you are on. You should also look up specific information about the machine you are using, later in this chapter. <h3>Introduction: Internet addressing To use TCP or UDP, your RPC addresses must end in the medium names .TCP or .UDP respectively. TCP is a connection&hyphen.oriented protocol, whereas UDP is a datagram protocol. The RPC system uses one or the other as instructed. UDP may be faster but is not available on some machines. TCP is stream-oriented and so, when data flow is mainly in one direction, PRAGMA CAST may used to stream messages for extra speed. <dl tsize=10> <dt>Node <dd>A node on the internet is identified either by a name (e.g ..bf MONO VXCRNA ..pf ), or if the name is not known locally, by a set of four numbers separated by dots (e.g. ..bf MONO 141.4.12.10 ..pf ) Node names are normally in lower case on systems where this is significant. (See file /etc/hosts on unix). <dt>Port <dd> A port is an endpoint of communication within a node. Within a node there are many ports, identified by decimal numbers 0 to 32767. Ports 0 to 1023 are reserved for so called "well known port" numbers. (See file /etc/services on unix). Priviledge (SYSPRV under VMS) is required to use a number below 1024. Port numbers of 1024 and above are free for user applications, although it is not possible to use one already in use. To communicate, one side (normally the server) must either establish a numbered port and the other side (normally a client) must make a connection to it. If a port number is unspecified for a server, the RPC system will dynamically chose the first free port in the range 5000 to 5999 (decimal). <dt>Connection <dd>There may be many connections to a port. A connection is normally established at initialisation time, but is the RPC address is preceded by a "#" hash character, the RPC system will open and close a connection for each call. This will save connections when there are very many machines but take more time. </dl> <h3>Defining the clientele for a server A server may service multiple clients. The address of the client it is to service starts with an asterisk "*" to indicate this. Then follow the node number or name, a colon, and the number of the port at which the server is to listen. The server creates a local port of that number, and waits for connections from the given node. <xmp> *vxcrna:777.tcp Service multiple clients on node vxcrna. Establish a local port number 777. Use TCP </xmp> If the node is omitted, the server will service connections from any node: <xmp> *:777.tcp Service multiple clients on any nodes. Establish a local port number 777. Use TCP </xmp> The colon ":" must always precede the port number. If the colon and port number are omitted, the server will dynamically find a free port number: <xmp> *.tcp Service multiple clients on any nodes. Find a free port starting at 5000. Use TCP </xmp> In this case, a name server is necessary for the client to find the correct port for the given service using a name server, for example. <h3>Staring servers automatically : The Internet Daemon It is possible to arrange for servers to be started automatically (under unix or VMS, at least). This is done by the internet daemon process which normally runs on a machine running TCP/IP. In order to do this, you must arrange that your server program is in the database used by the inet deamon, "inetd". This will require privilege. You should read the documentation for your system <fn> On unix, see /etc/inetd.conf and <hp2>man inetd</hp2>. On VMS, see TWG$TCP:[NETDIST.ETC]SERVERS.DAT and read <BIBREF REFID=WINTCPADM>, around p154. </fn> for details of how to do this, and how to start and stop the daemon if necessary. The program which is started by the daemon should be written as normal RPC server program, with the clientelle <hp1>explicitly</hp1> put in as <xmp> .tcp Use connection handed down from the internet daemon </xmp> In this case, when a connection is made to the server port given in the deamon database, the daemon starts your server and passes it the connection. The server program in this case handles only one client per task. <h3>Defining a server for a client On the client side, to define the address of a remote package, one must quote the server port number and the node name: <xmp> vxcrna:777.TCP Node VXCRNA, port 777. 121.12.2.1:777.TCP Node 121.12.2.1, port 777 #vxcrna:777.TCP Node VXCRNA, port 777 (reconnect for each call) </xmp> The port number quoted by the client must, of course, be the same as the one established by the server. ..pa <H2>Ethernet addressing When using Ethernet in it's raw form, that is, without a standard protocol running over it, the addressing facilities are cruder that those provided by higher level protocols. This section describes what one can do. <h3>Introduction: Ethernet Header fields An ethernet packet has a header which contains three fields <ol> <li> A six byte destination address <li> A six byte source address <li> A two byte "protocol type" field </ol> The source and destination addresses define the physical ethernet interface which recieve or sent the packet, respectively. These addresses are not, in general, modifiable by the user. Therefore, in order to distinguish packets intended for different logical destinations within the same machine, the protocol type field is all that remains. Normally, this field is used to select a higher level protocol, such as UDP, TCP, or TP4, which then interprets part of the rest of the packet as further subaddressing information in some format or other. The user of raw ethernet packets, however, must use different protocol types to distinuguish packets which would otherwise have identical headers. Most drivers which allow access to raw ethernet packets allow one to specify the partner address and/or the protocol type one wishes to use. <h3> Address format In the RPC address format, the peer address and protocol type are specified in hexadecimal, with a medium name of "ETHERNET". <xmp> ..fo off ..tb 9 17 25 33 41 49 57 65 73 <rpc_address> ::= <peer_address> [ <protocol_type> ] .ETHERNET <peer_address> ::= * | <byte><byte><byte><byte><byte><byte> <protocol_type> ::= <byte><byte> <byte> ::= [ _ ] <hex_digit> <hex_digit> </xmp> <box> ..us Example ..bf MONO AA_00_04_00_2F_58_5050.ETHERNET ..pf ..us on This refers to ethernet node AA_00_04_00_2F_58 (which might be a particular VAX, for example) and protocol type 5050. ..us off </box> The default protocol type used by the RPC system is is 5050 hex. This is assumed if none is given. <box> ..us Example ..bf MONO AA_00_04_00_2F_58.ETHERNET ..pf </box> <h3> Wildcard address In all cases, one must specify a protocol type (or the default is assumed). Normally, one also specifies the peer (partner) node address. An exception to this is when a server listens to any other node, in which case the peer address is replaced with a "*" ("$" is used under OS9, to prevent conflict with special meaning of "*") <box> ..us Example ..bf MONO *.ETHERNET ..pf This refers to any ethernet node, protocol type 5050. It is known as a wildcard address. </box> <box> ..us Example ..bf MONO *_5055.ETHERNET ..pf This refers to any ethernet node, protocol type 5055. </box> <H3>Rules The following rules are necessary to prevent conflict: <ul> <li> At CERN, RPC users should not use protocol types outside the range 5000 to 51FF hexadecimal (or a range allocated to their group), as other values may conflict with other traffic on the Ethernet and cause widespread chaos. Type 5052 should also be avoided, as that is used for Valet&hyphen.Plus bootstrap broadcast messages. <li> Two processes in one node which talk to the same partner node must use different protocol types. <li> Under OS9 (with the driver written by Tim Charity), no two tasks may use the same protocol type, even if they are talking to different nodes. <li> No user should use a wildcard ethernet address on a multiuser machine without ensuring that noone else on that node is using the protocol type at all. </ul> It is clear that in a complex system, some thought is necessary for the allocation of protocol types. Two simple ways of allocating types are as follows. <ol> <li> For one&hyphen.to&hyphen.one communication between tasks, specify both the protocol type and the ethernet address of the partner. The protocol type need only be unique within the process (or node, for OS9). <hp1> Example </hp1> <xmp> ..fo off Server refers to client as: AA0004002F58_5050.ETHERNET Client refers to server as: AA0004004558_5050.ETHERNET </xmp> <li>For a server handling many clients, specify only the protocol type, and leave the address wildcard. <hp1> Example </hp1> <xmp> Server refers to client as: *_5050.ETHERNET Client refers to server as: AA0004004558_5050.ETHERNET </xmp> ..fo on In this case, check that the server is the only process using that protocol type on the node in question. </ol> The RPC system runs its own protocol over ethernet in order to ensure reliable transmission. <fn> Note: When ethernet is used, the package number should not be given explicitly in the RPC address: rather, the name should be given. This forces the RPC system to make an initial call to discover the package number. If it is not done, the first call (only) may be executed twice. </fn> <h2>RS232 (V24) Communication RS232 serial lines may be used for point to point communication between two machines. In this case, the RPC system runs a simple protocol over the line. There are various options available to optimise the protocol given the capabilities of the systems in use. The address format is <xmp> < device > : <options> .V24 </xmp> The < device > is, under VAX/VMS a logical device name, but otherwise of the form ..bf MONO TTn ..pf where n is the channel number: <xmp> IBM-PC Macintosh MoniCa __________ __________ ___________ TT1 COM1: sPortA Terminal TT2 COM2: sPortB Hostline </xmp> The options are optional single letters as follows. They are not all supported on all systems. <DL> <DT>B <DD> Binary coding method: use all 8 bits of the communication path. This is the default. This is faster than the alternative "L" option, but is not possible with some systems because of operating system restrictions. If the serial line runs over multiplexers, then they might also restrict the use of the line so that 8 bit communication cannot be used. In this case the alternative option (L) must be used. <DT>L <DD> Printable ASCII coding method: use only the printable ASCII characters (seven bits). This is slower, but does not require the operating system to pass control characters undamaged. <DT>R <DD>A strict handshake is used for flow control, for the benefit of those systems with inadequate input buffering. If both connected systems have sufficient input buffering, the F option may be used to make the protocol run faster. The default varies from system to system. <DT>F <DD>Disables the handshake protocol. Alternative to R. <DT>C n <DD>Selects (for PCs, Monica and Macintosh) the communications channel. "n" is either 1 or 2. <DT>S n <DD>Selects, where this is possible, the baud rate. "n" must be the baud rate required in decimal, e.g. S300 or S9600 </DL> These options are specified in the RPC address string, just before the ".V24" medium specifier. See details in the section about your particular system below. <h2>CERN Host Interface addressing The CERN Host Interface is a system of fast 32 bit wide parallel point&hyphen.to&hyphen.point links between BI based VAXes, FASTBUS and VME systems. On the VAX side, the module needed is a Digital Equipment DRB32 interface. This is 32 bit parallel interface for the VAX BI. It can be connected to another DRB32, or to the "HyperVIOR" VME module, or to the "CHIFC" FASTBUS module. When using the CHI, the same addressing syntax is used on the VAXes as on M680x0 systems. The medium name is "DRB". The communication facility is a standard transport service, so it works by one side declaring itself to be a named access point (TSAP), and then the other side making a connection by quoting that name. Typically (but not necessarily) it will be the RPC server which declares an access point name, and the client which connects to it. In this way, more than one client task (on the VAX) can access the same server. The access point name is an alphanumeric case insensitive string of a maximum of 32 characters. The syntax is similar to that used with DECNET or ISO transport protocol:- The format for declaring a server at access point "FRED" would be <xmp> *FRED.DRB </XMP> The asterisk "*" indicates that an access point should be established with the name "FRED", and any connections to that TSAP accepted. The TSAP name is mandatory, and has a maxuimum length of 32 characters. To refer to a package MYPACK2 on which is provided by that server, the client side would specify <xmp> MYPACK2@FRED.DRB </xmp> Notice there is no asterisk: the network address FRED.DRB means that this side should actively request a connection to an existing TSAP called FRED on the other side. In this case, therefore, the server must be started before the client. The CHI FASTBUS module has an RPC server permanently listening at access point "BOOT", so any server package which has been attached (see the list produced by the "PACKAGES" command) can be accessed from the VAX as <xmp> <packagename> @BOOT.DRB </xmp> The physical DRB device used by the RPC system is defined by the logical name DRB_Device. This may be set up for you by the system manager, or by a setup command file which you run from your login.com file to specify which CHI you are using. Alternatively, on the VAX, you can override the device name by specifying it before the TSAP name: <xmp> $ DEFINE RPC_CLIENT_NAME *UQA0:FRED.DRB </xmp> <h3>16 bit interfaces: DRQ and DRE&hyphen-11 When using a microvax or VAX without a BI (Backplane Interconnect), the same software exists for 16 bit interfaces. The DRE&hyphen-11 is used on UNIBUS, and the DRQ&hyphen.11 on QBUS. In this case, <hp2>the medium name is still .DRB as above</hp2> but the logical name DRB_DEVICE is changed to indicate a UU: device rather than a UQ: device. For example, <xmp> $ DEFINE DRB_DEVICE _UUA0: $ DEFINE RPC_CLIENT_NAME *FRED.DRB or $ DEFINE RPC_CLIENT_NAME *_UUA0:FRED.DRB </xmp> <h3>Run&hyphen.Time Libraries The VAX library to be used should be logical CHI$LIB, (file CHILIB.OLB), and not the usual RPC$LIB. The CHI$LIB library allows the use of DRB and DRQ interfaces, and also RS232, decnet and ethernet. On the CHIFC itself, the entire library is available in ROM, so one need only link to the symbol module CHI$ROM (file CHIMON.ROM). Ensure that you have the version corresponding to the ROMs in your CHI. On the Valet-Plus, the library for communication over the HVIOR is also in ROM, and the usual MONICA.ROM file should be used. For more information onthe CHIFC device, see the CHI User Manual. ..pa <H2>VAX/VMS Run Time Support <H3>Raw Ethernet <I1 IX=1>Ethernet, under VAX/VMS Ethernet 2.0 may be used on VAX/VMS, for communication with other VAXes or microprocessor systems, Personal Computers, etc. The addressing possibilities for ethernet are described in the general section above. Under VMS, the RPC system will attempt to find an ethernet device using the following list of device names in order, until success: <ol> <li> RPC_ETHERNET_DEVICE (A logical name you may define) <LI> XEA0: (For UNIBUS interfaces, DEUNA, DELUA) <LI> XQA0: (For Qbus interfaces, DEQNA) <LI> ESA0: (for Vaxstations) <LI> ETA0: (for BI machines with DEBNT devices) </ol> You can define RPC_ETHERNET_DEVICE at system or process level if you will to force a particular device to be used, or you wish to use one not in the list. <H3>RS232 Serial Line An asynchronous <I1 IX=1>V24, under VAX/VMS <I1 IX=1>RS232, (see V24) <I1 IX=1>Serial links , (see V24) <I1 IX=1>Asynchronous transmission , (see V24) V24 <FN> For readers outside Europe, CCITT recomendation V24 is the European equivalent of the RS232&hyphen.C standard. </FN> (RS232&hyphen.C) line may be used for connecting two devices. The <medium name> is V24. The <net address> is the device name, or a logical name which translates to the device name. A set of options may be specified following a colon terminating the device or logical name specification. The options currently supported are <DL> <DT>B <DD> Binary coding method: use all 8 bits of the communication path. This is the default. <DT>L <DD> Printable ASCII coding method: use only the printable ASCII characters (seven bits). <DT>F <DD> Disables the RTS/CTS protocol. By default (or with R specified), a strict handshake is used for flow control, for the benefit of those systems with inadequate input buffering. If both connected systems have sufficient input buffering, the F option may be used to make the protocol run faster. </DL> <HP1>Examples</HP1>: <P> TT:L.V24 7 bit working on the user's terminal <P> _TTA6:.V24 8 bit working on _TTA6: device <I1 IX=1>XON/XOFF <HP1>Note that data overrun errors can occur when using 8 bit operation, as XON/XOFF control is not used. This can be avoided by increasing the size of the typeahead buffer under VMS, or, better, by using the characteristic TT2$M_ALTYPEAHD on the line involved, which allows the use of a larger typeahead buffer defined at system generation. The non&hyphen.privileged user could avoid the data overrun errors by not using the above mentioned F (Fast) option, and, if the problem persists, by setting the line to a lower baud rate. </HP1> <H3>DECnet <I1 IX=1>DECNET Between VAX machines under VMS, a service may be provided over decnet, the server being automatically loaded by the network server at the remote machine, or run explictly by command. The <medium> is given as DECNET. The <net address> for the server should be either the DECNET address of an object, or an asterisk followed by the decnet object name of an object to be created. In the first case, a connection is requested to the given object. In the second case, the program declares itself as being a given object, and waits for incoming connections. <HP3>Explicit DECNET addresses</HP3> If the DECNET address of the remote server or client is known, that should be <I1 IX=1>Address DECNET given as the network address. This comprises the nodename followed by the object specification: <machine>::"TASK= <object>" or <node>::"0=<object>" (equivalent) <HP1>Example</HP1>: $ DEFINE filer "0@VXCRNA::""0=FILER"".DECNET" <HP1>(Note the double quotes necessary within a quoted string under VMS)</HP1> There is a limit of 40 characters on any RPC address. You can avoid exceeding this by defining a logical name for a long decnet address: <HP1>Example</HP1>: <XMP> $ DEFINE FILER "0@HOST.DECNET" ! 40 char. limit $ DEFINE HOST "VXIMAG""USER PASSWORD""::""TASK=IMAGE3""" </XMP> When such an address is used, a connection will be set up to the named object on the remote node. When this is done, the actions DECNET will take on the remote node as as follows: <ol> <li>If a multiple client server (see below) is already running with that object name, the connection will be made to that process. <li>If not, then DECNET will look for a command file with the same name as the object requested, and extension .COM. The directory searched will be the home directory if access control information is passed (user and password), otherwise the DECNET directory. If it finds that file, it will run it. The file may start a multi-client server, or a single client server using the address "SYS$NET.DECNET". <li>If the .COM file is not found, DECNET will search for an executable file (.EXE) and run that in the same way. <li>If none of the above work, a "No such object at remote node" error is returned to the client. </ol> For instance, in the example above, if a server does not already exist which has network name FILER, VMS will try to run a file FILER.COM or FILER.EXE on the remote machine. <HP3>Single&hyphen.client server</HP3> If a process (a server, for instance), is automatically started by DECNET as descibed above, then within that process, the originating process may be addressed as SYS$NET. This is a logical name set up by VMS to point to the process which made the connection. <I1 IX=1>SYS$NET In this way, the command file run by VMS can set up the RPC name of the partner process: <HP1>Example filer.com</HP1>: $ DEFINE RPC_CLIENT_NAME SYS$NET.DECNET <P> $ RUN FILER.EXE This method is normally used to make a server which will be activated automatically when the client runs. In this case, if a second client tries to contact the same server, a second copy of the server process will be created to service it. It is equally possible to make a client program which is automatically activated when the server runs. This method may be useful which the server is interactive, or when the server is to be debugged interactively. <HP3>Wildcard addressing: Handling multiple connections</HP3> <I1 IX=1>Wildcard Addressing <I1 IX=1>Address wildcard For a server wanting to service a number of clients of unknown address, a wildcard network address may be given. This consists of "*", followed by the network name by which the server is to be known. <HP1>Example filer.com</HP1> $ DEFINE RPC_CLIENT_NAME *FILER.DECNET <P> $ RUN FILER.EXE In this example, when filer.com is run (by hand, or automatically by VMS when the client accesses it) a network object is created which will endure even when the first client has exited. <I1 IX=1>Network object A server set up with a wildcard client address may service requests from many clients, who may be connected at the same time. <I1 IX=1>SYSNAM It is necessary for the process to have SYSNAM privilege under VAX/VMS to use this facility. A fuller example of decnet addressing is given at the end of the chapter. <H3>Internet Protocols (TCP, UDP) To use TCP/IP or UDP/IP <fn> Not available in the first release. </fn> under VMS requires the installation of an internet protocol package such as the WIN/TCP. To use this facility, <ul> <li>Use library RPCLIBC rather than RPCLIB, or RPCLIBC8K instead of RPCLARGE. <li>Produce the stubs with the GeniericC options of the compiler. <li>Compile the stubs <hp2>without the /DEFINE=VAXVMS qualifier.</hp2> </ul> The ability to declare a server using one's own "well known port number" requires SYSPRV privilege. See the section on Internet addressing above. <H3>ISO Transport Protocol <I1 IX=1>ISO protocol, On VAX/VMS <I1 IX=1>TP4, on VAX/VMS <I1 IX=1>VOTS ISO class 4 Transport Protocol ("TP4") may be used. This requires the installation of the VOTS package under VAX/VMS. <I1 IX=1>CATS The <medium name> is IEEE.CATS <FN> CATS is a standard calling sequence for a networking transport service. Implementations under VMS include those for ISO Transport Protocols over IEEE 802.3, DECNET, Mailboxes, and X.25 protocols. The "IEEE" selects the protocol used, from those supported by the CATS library. </FN>. For the client, <net address> is of the form <tsuf>@<ethernet address> where the <tsuf> (transport suffix) identifies the process that will run the server - it should be the same as the tsuf specified by the server; and <ethernet address> gives the physical address of the machine running the server. The maximum length of a <tsuf> on DECnet is 12 characters. The <net address> may optionally be preceded by a "#", which causes the client to make a new transport connection for each RPC call rather than to leave it open after the RPC_Open and only close it when RPC_close is called. The "short&hyphen.connect" client is useful <I1 IX=1>Short connect <i1>Connect on call when either the client or server can only have limited number of connections open. For the server, the address is of the form <xmp> *<tsuf>@IEEE.CATS </xmp> where the <tsuf> identifies the current process to the network system. <HP1>Examples</HP1>: The following examples give two possible addresses for the client and the corresponding address for the server. <xmp> 0@MYSERVER@AA000400DD58.IEEE.CATS Normal client. 0@#MYSERVER@AA-00-04-00-DD-58.IEEE.CATS Short-connect client. *MYSERVER@ieee.cats Server. </xmp> <h3>CERN Host Interface to VME or FASTBUS This is a fast point to point communication link between VAXes, VME and FASTBUS systems. See the section above on CERN Host Interface addressing. <H3>Debugging tools The logical name (VAX/VMS) ..bf mono rpc_trace_flag ..pf controls diagnostic output. To turn it on, this must be defined as the output filename, for instance SYS$OUTPUT: (with the colon). If trace is on, the RPC run&hyphen.time system will produce copious <I1 IX=1>Trace information , under VAX/VMS <I1 IX=1>Diagnostic output , (see Trace) trace information about each transaction, including the contents of each message received or transmitted, and the addresses involved. Two commands are provided to manage this: <DL> <DT>$ TRON <DD> <I1 IX=1>TRON Turn run&hyphen.time trace on <DT>$ TROFF <DD> <I1 IX=1>TROFF Turn run&hyphen.time trace off </DL> If a run time error occurs which you do not understand, running the trace (perhaps to a file) may explain what went wrong more clearly than the single error message. <H3>Example: VAX-VAX over DECNET Suppose, as above, that the program MYPROG uses the module FILER, but let us suppose they are both on a VAX under VMS. The program MYPROG is on decnet node NODEM, and FILER is on NODEF. <I1 IX=1>DECNET example We build the system as described above, but to run under VMS on both sides: The server program is the standard one (SERVERLOOP) provided in the library: $ RPC FILER /SVAXVMS /CVAXVMS $ LINK MYPROG, CLIFILER, rpc_lib/OPT $ LINK FILER, SERFILER, rpc_lib/INCLUDE=SERVERLOOP/LIB - rpc_lib/opt To run MYPROG on NODEM, we make a command file MYPROG.COM: $ DEFINE/USER MYTASK "NODEF""user password""::""0=FILER""" <P> $ DEFINE/USER FILER "0@MYTASK.DECNET" <P> $ RUN MYPROG.EXE (The definition of MYTASK as a logical name allows one to put in a long name without exceeding the limit of 40 characters on the RPC address string, FILER). When this runs, it will attempt, over decnet, to contact the object FILER on NODEF. The DECNET software on NODEF, when it receives the request, will look first for a task which has already declared a network object called FILER. If it can't find that, it will look for a command file (.COM), and run that. It will look for the .COM file in the default directory associated with the "user password" given, or otherwise in the default directory (usually [DECNET]). We therefore put, on NODEF, in the top level directory [user], the command file FILER.COM containing the following commands: <xmp> $ DEFINE/USER RPC_CLIENT_NAME SYS$NET.DECNET $ RUN FILER.EXE </xmp> Note that either the username and password must be specified with the node name, or a "proxy login" must be created for the remote (or even <I1 IX=1>Proxy login local) decnet access, or FILER.COM must be installed in the default network user directory. See the DECNET manual for details. When this file is run by the decnet network server on NODEF, it first <I1 IX=1>SYS$NET declares that FILER should service the client SYS$NET. This is is a logical name set up to allow access to the process which started the job. Then, the FILER program runs, and will service any requests made by MYPROG. The distributed system is then run by typing (on NODEM) <xmp> $ @MYPROG </xmp> In this case, the server serves the one client, and exits when the client process exits. If another identical client asks for a connection to FILER, then a separate server process is started. If the server command file had been <xmp> $ DEFINE/USER RPC_CLIENT_NAME *FILER.DECNET $ RUN FILER.EXE </xmp> then the server would have declared itself as a DECNET object "FILER". It would have then serviced the client, but remained active even after the client had exited, to server any other clients which might run. In this case, if more than one client had requested a connection to FILER, then they would all have been connected to the same initial server, which would have serviced requests from all of them. ..pa <H2>Unix Run Time Support Under Berkley unix, DEC Ultrix or equivalent, the RPC system can communicate over TCP/IP, UDP/IP, raw ethernet <fn> UDP, raw ethernet, RS232 not provided for Ultrix in the first release. </fn> or RS232 links. See the sections above on TCP, etc for details of addressing. The shell environment (see setenv, printenv commands) is used to define rpc addresses. The RPC compiler is available to run in these environments. Support in this environment is currently for C compatible software, FORTRAN can be made be avialble if required. The stubs should be generated using GenericC or FORTRAN options of the compiler, and then compiled using the resident C compiler. They must be linked with the rpclib.o module and rpc_rts_for if in FORTRAN. The stubs must be initialised (See Chapter 6) by calls to open_xxx and attach_xxx in the client and server programs respectively. <h3>Defining addresses See the earlier sections in this chapter for the format of RPC addreses. The setenv command must be used (under csh) or and equate (a=b) syntax under the shell 'sh'. For example, <xmp> setenv TESTPACKAGE CERNVAX:777.TCP setenv RPC_CLIENT_NAME '*:777.TCP' </xmp> Note that in the last example, the single quotes were necessary to stop the shell interpreting the "*" character. <h3>Example Imagine we have written a file server called "FILER". The interface is described by a file "filer.rpc". The simple IN variables are passed by value as in normal in C. The client application program is called myclient.c and the filer server itself is filer.c. First, we generate the server program. Here, filer.c contains a simple main program which calls attach_filer() to initialise the stub, and then rpc_loop_server(..) to run the server. It also, of course, contains the file access routines themselves. <xmp> rpcc -sgenericc=filer_server_stub.c -byvalue filer.rpc cc -o filer filer.c filer_server_stub.c rpcrts.o ts.o chmod +x filer </xmp> Next, we generate the client. The client in this example has a call to open_filer() before it uses any remote routines. <xmp> rpcc -cgenericc=filer_client_stub.c -byvalue filer.rpc cc -o myclient myclient.c filer_client_stub.c rpcrts.o ts.o chmod +x myclient </xmp> Now we run the server, asking it to wait for any connections to TCP port 1789: <xmp> setenv RPC_CLIENT_NAME '*:1789.TCP' filer & </xmp> We can leave that running and go start the client: <xmp> setenv FILER mynode:1789.TCP myclient </xmp> where mynode is the internet name of the node on which the server is running. Here, the port number was chosen to be random but greater than 1024. See the section on TCP addressing. <h3>Diagnostic trace output If there is a problem, the RPC sytem will normally print an error message. If this is insufficient to determine what has gone wrong, then the same program may be run with the runtime trace turned on. This is done by setting the environment variable RPC_TRACE_FLAG to the name of the file to be used. For example, <xmp> setenv RPC_TRACE_FLAG rpc.trace or setenv RPC_TRACE_FLAG /dev/tty </xmp> Trace information will be appended to the given file. To turn the trace back off, the command is <xmp> unsetenv RPC_TRACE_FLAG </xmp> (Don't use ..bf MONO setenv RPC_TRACE_FLAG /dev/null ..pf which will just slow down the RPC system to no purpose) <h3>Installation The files available are <dl tsize=15> <dt>rpcc <dd>The rpc compiler <dt>rpcc.p <dd>The source of rpcc for compilation under different systems. <dt>rpcheader.h <dd>The general include file <dt>rpc_ts.h <dd>An include file for ts.c <dt>rpc_code.h <dd>An include file for rpc code modules <dt>rpcrts.c <dd>The runtime kernel source <dt>ts.c <dd>The transport service interface module <dt>cm_env.c <dd>The configuration manager <dt>rpc_rts_for.c <dd>The fortran runtime interface <dt>system_sepcific.h <dd>An include file which selects a suitable xxx_specific.h file <dt>unix_specific.h <dd>Include file with the characteristics of unix. </dl> The C files must all be compiled and put into library rpclib.o. The separate library, rpclibc8k.o , is made in the same way but using the C compiler switch -DRPC_BUFFER_SIZE=8096. If you ever need to make any modifications to this software to run it on your system, please notify the changes to the address in the appendix "More Information". Thanks. ..pa <H2>M680X0 Run Time Support under MoniCa or RMS68K <I1 IX=1>M680x0, Run Time Support Software exists to support RPC on the M68000/M68020 family, in a single task environment or an RMS68k multitask environment. The runtime library modules to be used will depend on the system. If the RPC library is already burnt into ROM, applications may be linked directly to the stubs and the rom entry point file. Application software may be in C, Pascal, FORTRAN or PILS, with stubs generated in styles GENERICC, CERNCROSS, FORTRAN or PILS. On the Valet&hyphen.Plus <fn>This is a standard test system for High Energy Physics built in VME equipment practice </fn> the RPC syetem and PILS are all available in ROM. The MoniCa (or RMON) debugger is used in two ways, either of which may be suppressed if MoniCa is not available. <I1 IX=1>MoniCa symbols It is used to manage a symbol table used for translation, for which a dummy may be provided if MoniCa is not present. <I1 IX=1>MIOS The MoniCa I/O system (MIOS) is used only for RS232 communication. <H3>Raw Ethernet <I1 IX=1>Ethernet, on M68k Ethernet 2.0 may be used using the AMD "Lance" interface chip. (This is the chip used, for example on the LRT "Filtabyte" 25.1 board). The ethernet address format is described above (Sect 7.4). <H3>RS232 Serial Line An asynchronous <I1 IX=1>V24, on M680x0 V24 <FN> For readers outside Europe, CCITT recomendation V24 is the European equivalent of the RS232&hyphen.C standard. </FN> (RS232&hyphen.C) line may be used for connecting two devices. The <medium name> is V24. Under MoniCa there are two standard serial channels, <I1 IX=1>MoniCa serial channels thus allowing for two possible basic values of <net address>: <DL> <DT>TT1 <DD> The primary V24 line ("Terminal") <DT>TT2 <DD> The auxiliary V24 line ("Hostline") </DL> Inside the <net address> a set of options may be specified after the above mentioned serial channel specifications. The options currently supported are: <DL> <DT>B <DD> Binary coding method: use all 8 bits of the communication path. This is the default. <DT>L <DD> Printable ASCII coding method: use only the printable ASCII characters (seven bits). <DT>F <DD> Disables the RTS/CTS protocol. By default, a strict handshake is used for flow control, the benefit of those systems with inadequate input buffering. If both connected systems have sufficient input buffering, the F option may be used to make the protocol to run faster. </DL> <HP1>Example</HP1>: <P> TT2B.V24 8 bit operation over the auxilliary channel <H3>Under RMS68k The RPC run&hyphen.time system is shareable and reentrant. The following restrictions apply under RMS68k to the use of advanced RPC facilities. <UL> <LI> If a user error handle is declared, it will apply to all tasks, and so must be written to be shareable. <LI> The facilities for finding the name of the last caller (RPC_Caller_Address and the x@CALLER and x@CALLBACK format) <I1 IX=1>CALLBACK addressing, under RMS68k <I1 IX=1>CALLER addressing, under RMS68k cannot be used if there is more than one server task in the system </UL> The following restrictions apply to any RMS68K tasks which use RPC. See the RMS68k manual for explanations of terms, and how to set up tables. <I1 IX=1>ASQ under RMS68k <UL> <LI> The task must have an ASQ (Asynchronous Service Queue). <LI> Register stacking for ASRs must be enabled. <LI> If a default ASQ buffer is used, then it must be permanently enabled and of length at least 24 bytes. </UL> Stub modules are <HP1>NOT</HP1> shareable, and so if two different tasks use the same client stub, each must be prelinked with a separate copy. As there is only one symbol table for all tasks, one may define a task&hyphen.wide symbol by prefixing it with the name of the task. For example define RMON_PHI1 0@AA0004003558_5050.ETHERNET <P> define TSK2_PHI1 0@AA0004003558_5062.ETHERNET specifies that the task RMON will access a PHI1 server AS SERVER 0 at address AA0004003558 using ethernet protocol type 5045, but that task TSK2 will access it using ethernet protcol type 5062. <H3>Debugging tools <I1 IX=1>Trace information , on M680x0 The MoniCa symbol rpc_trace_flag controls diagnosic output. To turn it on, under Monica, this must be defined as "TRUE". If trace is on, the RPC run&hyphen.time system will produce copious trace information about each transaction, including the contents of each message received or transmitted, and the addresses involved. Under MoniCa (but not RMS68k), detailed diagnostics of the ethernet driver are controlled by the global (integer) flag _DEBUG. This may take values from 0 to 5, giving increasing amounts of trace information: <P> 0 Trace only transmit errors, or internal hardware errors. <P> 1 Trace also initialisation. (Still no output at interrupt level) <P> 2 Trace all above plus error conditions at interrupt level <P> 3 Trace all above plus normal Transmit interrupts <P> 4 Trace all above plus normal Receive interrupts The flag is normally 0, or 1 if rpc_trace_flag is defined as TRUE. It may be set to other values by hand. The output is always sent to the local terminal, even if a remote terminal is running over RPC. If a fatal error, or an error when debug output is enabled, then a message may be output to the terminal with two bytes in hexadecimal. <xmp> * LANCE: Transmit error, status = 43, error = 04 </xmp> For a receive error, the status bits are as follows: <dl compact=2> <dt>Bit 0 <dd>ENP: Buffer includes the packet end. <dt>Bit 1 <dd>STP: Buffer includes the packet start. Both bits 0 and 1 indicate a whole packet, which is normal. <dt>Bit 2 <dd>BUFF: (Chained buffer access error. Should never occur, as chaining is not used.) <dt>Bit 3 <dd>CRC: CRC error on incoming packet <dt>Bit 4 <dd>OFLO: Overflow: The interface could not access memory fast enough to empty its FIFO buffer as the packet arrived. <dt>Bit 5 <dd>FRAM: CRC error and non&hyphen.integeral number of bytes in packet. <dt>Bit 6 <dd>ERR: An error has occured, at least one of FRAM, OFLO, CRC, BUFF is set. <dt>Bit 7 <dd>The buffer is in use bythe interface. </dl> For a transmission error, the status bits are: <dl compact=2> <dt>Bit 0 <dd>ENP: Buffer includes the packet end. <dt>Bit 1 <dd>STP: Buffer includes the packet start. Both bits 0 and 1 indicate a whole packet, which is normal. <dt>Bit 2 <dd>DEFF: It was necessary to defer when trying to transmit. <dt>Bit 3 <dd>ONE: Exactly one retry was necessary to transmit the packet. <dt>Bit 4 <dd>MORE: More than one retry was necessary to transmit the packet. <dt>Bit 5 <dd>Always zero. <dt>Bit 6 <dd>An error (LCAR, UFLO or RTRY) condition occured. <dt>Bit 7 <dd>The buffer is in use by the interface. </dl> The interesting bits in the acompanying transmit "error" field are: <dl compact=2> <dt>Bit 2 <dd>RTRY: 16 attempts were made to send the packet, all failing due to collisions on the ethernet. Note that apparent collisions can also be caused by a badly terminated cable, as well as by severe overload of the ethernet. <dt>Bit 3 <dd>LCAR: Loss of carrier during transmission. <dt>Bit 4 <dd>LCOL: Late collision. A collision has occured afterthe slot time of the channel has elapsed. No retry is performed in this case. <dt>Bit 5 <dd>RES: Always zero. <dt>Bit 6 <dd>UFLO: Underflow: data could not be read from memory fast enough to fill the packet. <dt>Bit 7 <dd>BUFF: Buffer chaining error. Should not occur. </dl> <H3>Development Tools Some utility programs which run under VAX/VMS have been developed to aid the development of remote microprocessor systems which include RPC software. These include facilities for interrogation of tasks and memory in the target task, starting and stopping of tasks, and file load and dump. These are described elsewhere. ..pa <H2>M6809 Run Time Support <I1 IX=1>M6809, Run Time Support As operating system and langauge support on the M6809 is not so complete as on 32 bit processors, a little more work has to be done by the user. The code which must be put in the client and server programs is discussed below. The run&hyphen.time system on the M6809 was written for the <I1 IX=1>FLEX FLEX operating system running on the <I1 IX=1>G64 G64 system. Hence the supported transport media are for the G64 system. However, apart from the configuration manager, which uses the file system to read in the configuration file (see below), the system should work under other operating systems. The stubs produced by the RPC compiler (with the /xM6809 option) are for the Omegasoft Pascal compiler, which is available for both the FLEX and <I1 IX=1>OS9, on the M6809 OS9 operating systems. Before the RPC system can be used, the procedure <I1 IX=1>RPC_INIT, on M6809 RPC_Init must be called. Apart from initialising the RPC system, RPC_Init will read in the configuration file from disk ( 2.CM.DAT, or if not found, 0.CM.DAT, otherwise no configuration file is used). The configuration file contains a list of equivalences for RPC addresses and address fields, that is intended as a substitute for the VMS logical name system. It is free&hyphen.format: name followed by equivalence, separated by one or more spaces. Comments are preceded by an exclamation mark (!). If an address or the equivalence of an address (translation is repeated until there is no equivalence available) is of the form ASK"prompt"[default] (eg. ASK"Node"[VXDEOP] ), then the user is prompted for the equivalence. If RETURN is pressed, then the default is used (specifying a default is optional). This mechanism is limited by the 40 character maximium size of the address. <HP1>Example</HP1>: <XMP> ! Example of a configuration file: CM.DAT ! Name Equivalence ! ==== =========== vxdeop AA000400DD58 vxcrna AA0004002F58 filer_client_name *FILER@IEEE.CATS ! The following two names cause the user to be prompted for the remote ! node name, while supplying the rest of the RPC address. filer_server_name 0@FILER@NODE.IEEE.CATS node ASK"Node"[VXDEOP] </XMP> <H3>Client program <I1 IX=1>Initialisation, on M6809 For each package that is to be accessed, an integer (16 bit) variable h_xxx (where xxx is the package name) must be declared in the MAIN program as ENTRY. This is the handle. Before the package can be used, <I1 IX=1>RPC_OPEN, on M6809 RPC_Open (status, h_xxx, name) must be called. Status is of type RPC_status, <I1 IX=1>Handle h_xxx is the handle, and name is of type RPC_name and must be equated to a 40 character long string or character array (padded on the right with spaces) which is the server address. The server address and the fields within it are translated (iteratively) as described above. Before exiting the program a call to <I1 IX=1>RPC_CLOSE, on M6809 RPC_Close(status, handle); must be made. This is particularly important if the connection is to ethernet, since even if the program exits, the ethernet card will keep the connection open. In any program modules that need to call RPC run&hyphen.time routines (such as RPC_Init or RPC_Open), it is necessary to include RPC_const, RPC_types, and RPC_proc in the constant, type, and procedure declaration parts of the program respectively. These files are accessable, either as input (via *INCLUDE) to the INCLUDE preprocessor on the VAX under these logical names (ie. RPC_const, etc.), or as Pacsal include files on the G64. In the latter case (often the more convenient) they have FLEX filenames RPCCONST.INC, RPCTYPES.INC, and RPCPROC.INC respectivly. In addition, unlike on other systems, it is necessary to include the file rpc$var (or, on the G64: RPCVAR.INC ) in the variable declaration section of the <HP1>main</HP1> program. This will declare as ENTRY the global variables required by the RPC run&hyphen.time system (this is necessary because of a bug in the Omegasoft Pascal compiler that fails to allocate space on the stack for global variables in modules that are not also declared in the main program). You must compile and assemble the client stub and include it as one of the <HP1>"Additional files to load"</HP1> when you link. The RPC library (RPCLIB.RO) must be included as one of the <HP1>"Additional library files"</HP1>. <XMP> ..us Example using package name FILER: PROGRAM FILER (input, output); { Example client program on M6809 } CONST {$iRPCconst.inc Include RPC constant definitions} TYPE VAR {$iRPCvar.INC Include RPC global variables} h_filer: integer entry; { Handle onto server } status: RPC_status; address: RPC_name; { Server address } {$iRPCproc.INC Include RPC procedure declarations} BEGIN RPC_Init; { Initialise RPC system } { Open a connection to the server. We use an address that we hope will be translated by the configuration manager. See the example configuration file above for a possible translation for filer_client_name. } address:= 'filer_client_name '; RPC_Open (status, h_filer, address); { open connection to server } RPC_Report_Error (status); {Instead of inserting the main program in here, we put in a call to a procedure MAIN (defined in this file). This allows us to separate the calls to the RPC run-time system from the rest of the program. { main; RPC_Close (status, h_filer); { close connection to server } RPC_Report_Error (status); END. </XMP> <H3>Server program The procedure attach_xxx is not defined on the M6809. Thus you must call RPC_Attach_Stub (status, integer(addr(r_xxx)), service, prog_no) <I1 IX=1>RPC_ATTACH_STUB, on M6809 where r_xxx (with xxx being the package name) is declared INTEGER PCR and service is of type RPC_name and contains the space&hyphen.padded package name, and prog_no is an integer (16&hyphen.bit). As for the client program, the server main program must include the file RPCVAR.INC in the VAR section. Any modules that use RPC run&hyphen.time routines (eg. RPC_Loop_Server) must also include ..bf MONO RPCCONST.INC, RPCTYPES.INC, ..pf and ..bf MONO RPCPROC.INC. ..pf You must compile and assemble your server procedures and the server stub, both of which must be included as <HP1>"Additional files to load"</HP1> when you link. The RPC library (RPCLIB.RO) must be included as one of the <HP1>"Additional library files".</HP1> <HP1>Example using package name FILER</HP1>: <XMP> PROGRAM MAIN (input, output); { Example server program on M6809 } CONST {$iRPCconst.inc Include RPC constant definitions} TYPE {$iRPCtypes.inc Include RPC type declarations} VAR {$iRPCvar.inc Include RPC global variables} r_filer: integer pcr; { Server stub address } status: RPC_status; package: RPC_name; { package name } address: RPC_name; { Address of client } prog_no: integer; { Returned package number } {$iRPCproc.inc Include RPC procedure declarations} BEGIN RPC_Init; { Initialise RPC system } package:= 'filer '; RPC_Attach_Stub (status, integer(addr(r_filer)), package, prog_no); RPC_Report_Error (status); address:= 'filer_server_name '; RPC_Loop_Server (status, address); { Service RPC requests } RPC_Report_Error (status); END. </XMP> <H3>Example: VAX-G64 over ethernet, ISO TP4 protocol <I1 IX=1>FLEX <I1 IX=1>Omegasoft Pascal <I1 IX=1>Building a system , under FLEX on G64 The following example shows the commands needed to build a RPC application. Suppose we have a program called MYPROG.FOR written in FORTRAN and running on a VAX under VMS. This needs to call procedures in a module called FILER.TXT written in Omegasoft Pascal and running on the G64 running the FLEX operating system. The interface between the two is described in RPCL in the file FILER.RPC. First of all we compile the main program using the VAX/FORTRAN compiler, generating the file MYPROG.OBJ: $ FORTRAN MYPROG We then generate the stub code for each system using the RPC Compiler: $ RPC FILER.RPC /CVAXVMS /SM6809 Now the RPCC will produce (if no errors are found) the files: CLIFILER.OBJ The client stub for VAX/VMS <P> SERFILER.PAS The server stub: Omegasoft Pascal We can then link together the VAX image: $ LINK MYPROG, CLIFILER, rpc_lib/opt We now have an executable file, MYPROG.EXE, which, when run, will call the remote version of FILER. To create the executable file on the G64, the file SERFILER.PAS must then be downloaded to the G64. Note that the default filetype for source files under FLEX is .TXT so when the file is downloaded, the output filespec should be specified as SERFILER.TXT (also filename must not be more than 8 characters long). The server stub must then be compiled and assembled: +++PASCAL <SERFILER > O <P> +++RA <SERFILER.CO >SERFILER.RO O The server routines (that we wrote) in FILER.TXT must also be compiled and assembled: +++PASCAL <FILER > O <P> +++RA <FILER.CO >FILER.RO O Finally these must both be linked in with a main program (say, MAIN.TXT ) that will simply initialise the RPC system and call a routine like RPC_Loop_Server (which simply services remote procedure calls forever). An example main server program is given above. The main program can be compiled and linked with the chain file produced by the LC command: <XMP> +++LC "MAIN" F <P> Linkage Creator Version 2.11 <P> Copyright 1982 by Omegasoft <P> Auto setup ? Y Let LC decide where to put the stack <P> System stack size : 400 (in hex) Better to overestimate! <P> Starting load location : 0 The start of the program in hex <P> Library drive number : 0 Drive on which RL.RO can be found <P> Additional files to load : SERFILER Sever stub <P> Additional files to load : FILER Server routines <P> Additional library files : RPCLIB G64 RPC library <P> Load options : Options for the LL command line <P> Map options : Use F for a full map listing <P> Additional command : FLEX command to follow Link step. </XMP> The command CHAIN MAIN will execute the chain file and produce the executable file 2.MAIN.BIN, which may be executed by the command 2.MAIN.BIN . Remember that the file CM.DAT should be present on either disk 2 or 0, so that the definitions for filer_server_name and filer_client_name (used in the client and server main programs respectively) are present. <H3>RS232 serial line <I1 IX=1>V24, on G64 <I1 IX=1>G64 <I1 IX=1>ACIA An asynchronous V24 <FN> For readers outside Europe, CCITT recomendation V24 is the European equivalent of the RS232&hyphen.C standard. </FN> (RS232&hyphen.C) line may be used for connecting two devices. The G64 system has two types of RS232 chip, the SCN2661 (the older type - used on the "asynchrone" board) and the SCN2681 (supplied with the new paged&hyphen.RAM CPU card) which provides two asynchronous channels. The format of <medium address> is similar for the two chips. The <medium name> is V24. The <net address> gives the four&hyphen.digit hexadecimal address of the memory&hyphen.mapped RS232 controller preceded by a "$". For the SCN2681, this is followed by "_A" or "_B" depending which of the two channels of the <I1 IX=1>DUART DUART is to be used. The <net address> may have a suffix giving the baud rate. This defaults to 9600 baud. <HP1>Examples</HP1>: <XMP> $E020_B.4800.V24 Second terminal line on CPU board run at 4800 baud. $E000.V24 First chip on the Dual Asynchrone board. </XMP> The implimentation of V24 communications for other systems allow both 7- and 8-bit communications. Only 8-bit communications is supported on the G64, and consequently those systems that the G64 communicates with via RS232 should also be configured to use 8-bit. <H3>OSI Transport Service over ethernet <I1 IX=1>OSI <I1 IX=1>Cheapernet <I1 IX=1>Ethernet, on M6809 For Ethernet/Cheapernet communication on the G64, the <I1 IX=1>G64, Cheapernet card <I1 IX=1>Cheapernet, card for G64 cheapernet interface card (produced by CERN/DD) is required on the G64 crate. ISO class 4 Transport Protocol ("TP4") <I1 IX=1>TP4, on G64 is used. If communicating with the VAX, the <I1 IX=1>VOTS VOTS package is required on the VAX. <I1 IX=1>CATS (The software uses a CATS <FN> CATS is a standard calling sequence for a transport service. Implementations existing include those running over IEEE 802.3 (Ethernet/Cheapernet) on the VAX/VMS and G64; and DECNET, Mailbox, and X.25 protocols on the VAX, and over the CERN Host Interface. </FN> library to access the communications service). The <medium name> is CATS. The <net address> has a suffix to indicate which medium CATS is to use. Currently only IEEE is supported on the G64 (IEEE, DECNET, X25, and MBX are supported on the VAX). For the client, <net address> is of the form <tsuf>@<ethernet address>.IEEE where the <tsuf> (transport suffix) identifies the process that will run the server - it should be the same as the tsuf specified by the server; and <ethernet address> gives the physical address of the machine running the server. The <net address> may optionally be preceded by a "#", which causes the client to make a new transport connection for each RPC call rather than to leave it open after the RPC_Open and only close it when RPC_close is called. The "short&hyphen.connect" client is useful <I1 IX=1>Short connect when either the client or server can only have limited number of connections open. For the server, <net address> is of the form *<tsuf>@IEEE where the <tsuf> identifies the current process to the network system. On the G64 - not a multi&hyphen.tasking system - only one <tsuf> may be used at a time. <HP1>Examples</HP1>: The following examples give two possible addresses for the client and the corresponding address for the server. <XMP> 0@MYSERVER@AA000400DD58.IEEE.CATS Normal client. 0@#MYSERVER@AA-00-04-00-DD-58 Short-connect client. *MYSERVER@ieee.cats Server. </XMP> On the G64, .IEEE and .CATS are default and may be omitted. <H3>Debugging tools <I1 IX=1>Trace information , on M6809 If the RPCLIB.RO library was compiled with tracing messages included, then rpc_trace_flag is translated using the configuration file by RPC_Init. If it translates to Y, then tracing messages are displayed on each call. If ASK"Enable Tracing?"[Y] is included in the configuration file, then the user will be prompted at run&hyphen.time. Tracing may be turned on or off from within the program by setting rpc_trace_flag (a global variable defined in rpc$var) to false. The tracing output goes to the output stream errlog (a global text file also defined in rpc$var) which is setup by RPC_Init to be routed to the terminal output stream. If the RPC run&hyphen.time system has been generated with tracing disabled, then no tracing output can be obtained. <H3>Further comments <OL> <LI>Since the heap is used by the RPC run&hyphen.time system, it is important that Omegasoft Pascal's mark and release routines do not come on either side of a call to the RPC run&hyphen.time system. ie. mark(i); ... RPC_open(); ... release(i); is a <HP1>bad move</HP1>. <LI> Currently there is no support for asynchronous calls on the M6809. Consequently RPC_Start_Server, RPC_Queue_Server, and RPC_Service are not defined. RPC_Accept with a timeout of zero is a useful mechanism for polling for an RPC request while carrying out other tasks. <LI> In order to save memory space, versions of the M6809 RPC library can be created without support for all the transport media, or for debugging messages. </OL> ..pa <H2>IBM&hyphen.PC Run Time Support <I1 IX=1>Turbo Pascal , Run time support <I1 IX=1>IBM-PC , Run time support <I1 IX=1>PC, IBM , Run time support The RPC compiler and runtime system are both available toi run under MSDOS, using TurboPascal. The RPC compiler command line syntax is the same as for VMS. The stubs should be generted with the /CPCTURBO or /SPCTURBO option, and compiled using TurboPascal. (No INCLUDE preprocessing is required.) The program should declare the name of any stubs which it uses in a "USES" clause. This will cause the stubs to be linked in and automatically initialised <fn> The NOAUTOINIT option of the compiler may be used to inhibit this. See the chapter on "Running the compiler". </fn> at run time. The library files provided in the release must be made available to turbopascal for linking. Communication may be over <dl> <dt>Ethernet <dd>See the section on ethernet addressing for the address format. <dt>RS232 <dd>The addressing format is the same as for the M680x0 under MoniCa. <dt>ISO Tranport protocol class 4, running over ethernet. <dd>The address format is the same as under VMS, but with a medium name of "IEEE" (not IEEE.CATS). </dl> For either raw ethernet or TP4 communication, the BICC "ISOLAN" card is used. <hp1> In the initial release, a separate library must be used for ISO tranport communication, from the one or ethernet and RS232 communication. </hp1> <h3>Hardware required The system runs over RS232 ports (COM1: or CONM2:), or over raw ethernet, or over ISO TP4 protocol. For the latter two options, a BICC ethernet interface card is required. <h3>Defining the RPC addresses <i1>Addresses on the PC Under MSDOS, the RPC address strings are defined using the environment variables. The command is SET: <xmp> > SET <logical>=<physical> </xmp> This takes the place of the DEFINE command, for example, under VMS. Note that there should bve no spaces on either side of the = sign. For example, <xmp> > SET RPC_TRACE_FLAG=TRUE > SET RPC_CLIENT_NAME=*_5150.ETHERNET > SET MYPKG=GRAPHICS@AA0004007758_5150.ETHERNET </xmp> The address syntax for RPC addresses is the same as for other systems. ..pa <h2>Macintosh Run Time Support <I1 IX=1>Turbo Pascal, on Mac <i1>MPW, Macintosh Programmer's Workshop <I1 IX=1>PC, Macintosh , Run time support RPC is available for the Macintosh, using either TurboPascal or MPW Pascal. <h3>Program building. The stubs should be generted with the CMACTURBO or SMACTURBO option, and compiled using TurboPascal or MPW Pascal. (No INCLUDE preprocessing is required.) The program should declare the name of any stubs which it uses in a "USES" clause. The stubs will be automatically initialised under TurboPascal <fn> The NOAUTOINIT option of the compiler may be used to inhibit this. See the chapter on "Running the compiler". </fn> at run time, but not under MPW, when initialisation calls should be inserted in the main program as shown in he examples. The library files provided in the release must be made available to turbopascal or MPW for linking. The dependecies between the modules are as follows: <xmp> Client Server program program | | | _________|__________ | | | CLIENT STUB SERVER STUB Server |________________| routines | RPCRTS ___________|___________ | | RPCSTUB TSTURBO |_______________________| | RPCMACPAS </xmp> Because of the 32kbyte limitation on the size of any one program segment, you will need to put at least one RPC library module into its own segment using the $S directive as shown below. The client program header will be of the form: <box><xmp> ..tb 9 17 25 33 41 49 57 65 73 program Client; {Main client program} {$S+} {Enable segmentation} {$U RPCMacPas} { Mac-specific runtime support } {$U RPCStub} { Run time support for stubs } {$U TSTurbo} { Run time support transport } {$U RPCRTS} { Run time support kernel } {$U clitest} { Client stub in this example } uses MemTypes, QuickDraw, OSIntf, ToolIntf, RPCMacPas, { RPC system starts here } RPCStub, TSTurbo, {$S SEGRTS} RPCRTS, { Put RPC RTS into different segment } clitest; { The client stub } var ... begin RPCMacPas_Init; { MPW only } RPC_Init; { MPW only } Open_test; { MPW only } ... if (rpc_trace) then close(errlog); end. </xmp></box> A typeical server program is: <box><xmp> ..tb 9 17 25 33 41 49 57 65 73 program Server; {Main server program} {$S+} {Enable segmentation} {$U RPCMacPas} {$U RPCStub} {$U TSTurbo} {$U RPCRTS} {$U test} {$U sertest} uses MemTypes, QuickDraw, OSIntf, ToolIntf, RPCMacPas, RPCStub, TSTurbo, {$S SEGRTS} RPCRTS, { RPC runtime system } test, { Server subroutines } {$S testseg} sertest; { Server stub } var status : RPC_status; address : RPC_name; begin RPCMacPas_Init; { MPW only } RPC_Init; { MPW only } Open_test; { MPW only } Attach_test; { MPW only } address := 'test '; RPC_Loop_Server (status,address); RPC_Report_Error (status); close(errlog); end. </xmp></box> <h3> Configuration file <i1 ix=1>Configuation file (Mac) As there is no shell environment on the Mac, RPC addresses must be defined in a file called RPC_Cfg. You can edit this with the turbopascal editor. The format is <xmp> < name > = < address > < name > = < address > . . . </xmp> For example, <xmp> RPC_TRACE_FLAG=rpc_trace_file TEST=0@TT1:F.V24 </xmp> A file in this case is produced for trace information. The user program must close this file, if it is used, before exiting the program (or it will be unreadable). Communication may be over RS232 only at the moment, and the address modifiers for changing baud rate, etc., are not supported. ..pa <H2>OS9 Run Time support for M680x0 <I1 IX=1>OS9, runtime support Under Microware's OS9 operating system, RPC is available to run over TCP/IP, ethernet or RS232 serial links. <fn> RPC running over ISO transport protocol is under development. </fn> Release notes distributed with the files describe how to make smaller libraries which support only a subset of these media. <h3>Running over TCP/IP For this, you will need to link with the socket library as well as the rpc library. The socket library is available from Microware. See the earlier section on TCP addressing. <h3>Running over Ethernet For ethernet, the 'elan' driver <fn>T. Charity, CERN/EP. If you are using the Aleph network disks, you will already have this driver. </fn> is used. See the section above on ethernet addressing for the address format. <h3>Running over RS232 For RS232 (V24) working, the port device descriptors must be in a modifiable address space. This is not the case if they are loaded from EPROM. You can check that it is writable by using the XMODE command to make a change, and then checking that the change has taken effect. Also, all processes must be removed which are in any way connected to the serial port (usually only "tsmon"). See the section above on RS232 addressing. <H3> Langauges and stub generation As C is the dominant language in this environment, stubs in C should be used. Programs written in C to run under OS9 may communicate with server and clients on other systems, no matter what langauge they are written in. The genericC option of the compiler (see chapter 4) should be used to generate stubs. The "byvalue" qualifier should also be used for C compatibility, while omitting it will give stubs more compatible with FORTRAN. If you are using FORTRAN, you should use the RTF compiler by Hans Von der Schmitt. The stubs are compiled without the "byvalue" qualifier. In this case, you should avoid passing strings, as they will be passed using the C convention which is not compatible with FORTRAN. <fn> To mix OS9 and C and FORTRAN, you will need a special module ..bf MONO rtfcstart.a ..pf and a special link command ..bf MONO lnc ..pf developed in OPAL. This allows FORTRAN programs to call C subroutines (including RPC stubs). </fn> Until the RPC compiler has been ported to run under OS9, the stubs must be generated under VAX/VMS or Ultrix and then copied (using FTP, OSWRITE, etc) to OS9 for compilation. This will only have to be repeated if the package definition file is changed, which should happen infrequently. <H3> Linking A client or server must be linked with stubs and with the runtime library files. Examples of the creation of a client and a server for OS9 are given below. <h3>Diagnostics If your have problems, the RPC system will give you an error message or a bad (even) status return. To get more information, turn on tracing with the command <xmp> setenv RPC_TRACE_FLAG <file> </xmp> giving the filename of your choice. Use the <xmp> printenv </xmp> command to see all environment variables. Setting RPC_TARCE_FLAG to the same thing as PORT will give you trace on the terminal screen. The trace shows everything the RPC system does on your behalf. You can see all the messages (in hexadecimal), and all the stages in the setting up of the communications. If you report a problem with which you need help, it is useful if you include in your report a copy of the trace file (from both client and server is possible). The command <xmp> unsetenv RPC_TRACE_FLAG </xmp> turns the tracing off again. <H3> Installation The file are available in a VMS save set, and may be picked up with the command <xmp> $BACKUP VXCERN::DISK$D1:[RPC.DISTRIBUTION_KIT]RPC_OS9vvu.A/SAV [] </XMP> where vvu is 024 for version 2.4 etc. The save set also contains a file of release notes. Read these for further instructions. Files may be copied to OS9 using the OS9PUT utility. The header file ..bf MONO rpcheader.h ..pf should be put into the standard directory which will be searched by the C compiler. The source files are distributed in source (C) form for portability, and must then be compiled as described in the release notes. <H3> Example 1: VMS server for OS9 client This example gives the code used to make a server which would allow an OS9 user to give any VMS DCL command for execution on a host VAX. The code essential to an understanding of the RPC is shown, although other details have been removed for clarity. Copies of the original files are available if required. ..bd The Package definition The package consists, in this case, of only one function. This is the definition file which describes it: <box><xmp> PACKAGE OS9_SERVICE IS TYPE IN_STRING IS STRING(133); FUNCTION OS9_DCL( COMMAND : IN IN_STRING) RETURN RPC_LONG; END OS9_SERVICE; </xmp></box> ..bd The server subroutine The server is based on a FORTRAN subroutine to have the command exectuted by the LIB$SPAWN library call. <box><XMP> INTEGER FUNCTION OS9_DCL(COMMAND) C execute a VAX command from OS9 CHARACTER *(*) COMMAND OS9_DCL = LIB$SPAWN( COMMAND , !command + , !input file + , !output file + ) !many other params C keep a record of action and status OPEN(35,FILE='OS9_DCL.OUT',FORM='FORMATTED', + STATUS='UNKNOWN',ACCESS='APPEND') WRITE(35,10) COMMAND, OS9_DCL 10 FORMAT(//,2X,'Command was: ',A,/,2X,'Status: ',I10,/) CLOSE(35) RETURN END </XMP></box> ..bd The server main program This is a simple server loop, along the lines given in the section on initialisation in this manual. In this example it is written in C for variety. Note the 40 character name which matches data type rpc_name. This is only given as an example: in fact, the predefined serverloop module could have been used (see below). <box><xmp> ..tb 9 17 25 33 41 49 57 65 73 #include <rpcheader.h> #include <stdio.h> extern attach_os9_service(); /* comes from server stub */ main() { /* the name between " " must be EXACTLY 40 char long. It will be translated to the address to be used by the server. */ rpc_status status; attach_os9_service(); /* See chapter 6 */ rpc_loop_server(&status, "RPC_CLIENT_NAME "); rpc_report_error(&status); } </xmp></box> ..bd Commands to make the VMS server <xmp> $! PRODUCE STUBS (SERDCL.OBJ AND CLIDCL.RPC) $ rpc dcl.rpc /svaxvms /cgenericc /noautoinit /byvalue $! LINK THE SERVER ROUTINES ASSUMING THEY HAVE BEEN COMPILED $ link/debug os9_dcl.obj, serdcl.obj, - rpc_lib/include=serverloop, rpc_lib/opt </xmp> Alternatively, the predefined server loop could have been used, with automatic initialisation of the stub: <xmp> $! PRODUCE STUBS (SERDCL.OBJ AND CLIDCL.RPC) $ rpc dcl.rpc /svaxvms /byvalue $! LINK THE SERVER ROUTINES ASSUMING THEY HAVE BEEN COMPILED $ link/debug os9_dcl.obj, serdcl.obj, rpc_lib/inc=serverloop - rpc_lib/lib </xmp> ..bd Client Program This is the program which runs under OS9. It takes one command line parameter, the VMS DCL command to be executed by the VMS server. <box><xmp> #include <strings.h> #include <types.h> #include <rpcheader.h> extern void open_os9_service(); extern void rpc_init(); extern rpc_long os9_dcl(); /* see DCL.EXT file produced by RPCC */ main (argc,argv) int argc; char *argv[]; { int i, j, istat; char command[133], temp[133]; static char *next_call = {"command_is"}; rpc_init(); open_os9_service(); istat = os9_dcl(next_call); /*send the command */ if (istat == 1) printf(" On this end (muVAX and OS9) all is fine\n"); else { printf(" SORRY, there has been a problem! Please, see\n"); printf(" an expert and report ISTAT = %d\n",istat); } } </xmp></box> ..bd Copying the Client Stub to OS9 You must compile and link on OS9 with the following commands <xmp> cc -rs -v=/m17/rpc filename cc -x client.r clientstub.r /m17/rpc/rpclib.l -dOS9 -f=fileout </xmp> <ul> <li>It is useful to set the environment variables CDEFS and CLIB to the directory name for .h files (e.g. /m14/defs) and .l files (e.g. /m14/lib) respectively.) <li>If the include file rpcheader.h is has not been put in a standard directory, the option -v=<directory> (eg -v=/m17/rpc) can be used to tell the compiler where to find it. <li>The -dOS9 defines a preprocessor symbol to select apropriate code from this file, and is not necessary under the latest (v3) release of RPC for OS9 <li>If more stack is needed, the option ..bf mono -m=10 ..pf may be needed. </ul> ..bd Defining addresses on the VAX Define the logical name used by the SERVERLOOP program. The Protocol type here is a number between 5680 and 56FF hex (at CERN, this protocol type is reserved for OPAL RPC). for this example: <xmp> DEFINE RPC_CLIENT_NAME *_5680.ETHERNET </xmp> ..bd Defining addresses on the OS9 system Here, you set the environment variable for the client. By default the varaible name is the PACKAGE name. On OS9 you MUST use UPPERCASE letters. In this example talking with UXOPCJ: <xmp> SETENV OS9_SERVICE 0@AA_00_04_00_15_58_5680.ETHERNET </xmp> Now, Run the SERVER on the VAX, then Run the CLIENT on OS9. <h3> Example 2: Client on VMS, server on OS9. The general procedure is as above <ol> <li>Write the server, client, and variable declaration files <li>RPC the declaration file with correct options <li>Link the client modules on the VAX (for this application) <li>Port the server routines, compile, and link with RPC files <li>Define the logical/environment variables(=addresses) <li>Run the application </ol> .bd CLIENT program The client program is as follows: <xmp> #include <stdio.h> #include <rpcheader.h> extern void open_test_2(); extern rpc_long testfun_2(); main() { int a,b; open_test_2(); /* connect us to the server */ a = 1; b = 9; printf("\n A = %d B = %d", a, b); printf("\n A + B = %d", testfun_2(a,b)); } </xmp> ..bd Package Definition The pacakge definition file is as follows: <xmp> PACKAGE TEST_2 IS FUNCTION TESTFUN_2 ( P1 : IN RPC_LONG; P2 : IN RPC_LONG) RETURN RPC_LONG; END TEST_2; </xmp> ..bd Server routines <xmp> #include <rpcheader.h> #include <stdio.h> #include <types.h> extern void attach_test_2(); extern void rpc_init(); main() { rpc_status status; rpc_init(); attach_test_2(); rpc_loop_server(&status,"RPC_CLIENT_NAME "); rpc_report_error(&status); } testfun_2(p1,p2) int p1,p2; { return(p1 + p2); } </xmp> ..bd To run it Define the addresses, under OS9: <xmp> SETENV RPC_CLIENT_NAME AA_00_04_00_15_58_5680.ETHERNET </xmp> or, to service requests from any address, <xmp> SETENV RPC_CLIENT_NAME $_5680.ETHERNET </xmp> and on the VAX: <xmp> VAX: DEFINE TEST_2 0@02_60_86_00_04_4E_5680.ETHERNET </xmp> Then start the server and run the client. ..pa <H1>Advanced Use of RPC This chapter describes facilities in the RPC kernel which may be called by users wishing to perform more than transparent procedure calls. This chapter need not be read by users who are building straightforward distributed programs. Topics covered are <ul> <li>Task to task communication and object oriented programming <li>Handling of multiple clients <li>Handling of multiple servers <li>User error handling <li>Setting timeouts on RPC calls <li>Controlling stub version number checking </ul> Details of parameters of each library procedure are given in an appendix. <H2>Varieties of server <I1 IX=1>Server, building different types This section describes a method of building servers which look to the client like ordinary procedures, but in fact are something more complicated. It describes how task to task communication may be performed with RPC. <H3>Server loop The simplest server is a program which waits in a loop, servicing each request as it comes in. The procedure <hp2>RPC_Loop_Server</hp2>, in the run&hyphen.time library, <I1 IX=1>Server loop implements such a loop. This takes as a parameter the medium address(es) to which it is to listen. This may be used in a situation where a task can be dedicated to servicing remote calls. <FIG ID=FIG1 PLACE=FLOAT FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig1 <PICTURE NAME=FIG1$$$S> ..go donefig1 ...skipfig1 ..tb 9 17 25 33 41 49 57 65 73 +---------------------->| | | | +-------+-------+ | | wait for a | | | request | | +---------------+ | | | +-------+-------+-------+-------+ | | | | | | | +---+ +---+ +---+ +---+ +---+ service the | | | | | | | | | | | particular | +---+ +---+ +---+ +---+ +---+ request | | | | | | | +-------+-------+-------+-------+ | | ------------<---------- ...donefig1 <FIGCAP><HP1>A simple server loop </HP1> </FIG> The RPC_loop_server procedure is used in the default main program module "SERVERLOOP" provided with the VAX/VMS run time library. <h3> Object Oriented Programming <I1 IX=1>Object oriented programming <I1 IX=1>Task&hyphen.Task communication A powerful and convenient way of designing a multitask system is to use "Object oriented programming". It means that for a data object, or physical object, you write a bunch of procedures for performing operations on that object. In a real&hyphen.time system, as well as a bunch of procedures, you probably want a controlling program which runs as an independent process, with overall responsability for the object. The smart step is to make some of the operations on the object available to other processes by RPC: <FIG ID=FIG2 PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig2 <PICTURE NAME=FIG2$$$S> ..go donefig2 ...skipfig2 ..tb 9 17 25 33 41 49 57 65 73 +---------------+ | Controlling | | program | +---------------+ +---------------+ | remote | | | program | | +---------------+ | / | / | ______________________/ | / (RPC) | / |/ +---------------+ | Access | | procedures | +---------------+ | database &/or physical object ...donefig2 <FIGCAP><HP1>A local controlling program allows a remote program to access some of it's procedures asynchonously. </HP1> </FIG> The access procedures are linked with the main program, and share its data structures. <ul> <li>The remote program uses the access routines like any other routine <li>The control program can enable or disable access from outside for exclusive access to the object at any time. <li>The access routines may affect data structures, and synchronisation primitives, and so modify the way the main program behaves. (For instance, access routine can release the main program from a wait state). </ul> ..cc 20 Task to task communication may be set up between two or more processes, each one providing a set of routines which may be called by the other. <FIG ID=FIG3 PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig3 <PICTURE NAME=FIG3$$$S> ..go donefig3 ...skipfig3 ..tb 9 17 25 33 41 49 57 65 73 +---------------+ +---------------+ | Program 1 | | Program 2 | +---------------+ +---------------+ |\ / | | \ / | | \__________ / | | \ / | | ___________\__________/ | | / rpc \ | | / \_____________ | |/ rpc \| +---------------+ +---------------+ | Access | | Access | | procedures | | procedures | +---------------+ +---------------+ | | | | Object 1 Object 2 ...donefig3 <FIGCAP><HP1>Interprocess communication by RPC between processes responsible for different objects. </HP1> </FIG> In the example program "battleships" (available on demand) two instances of the same program communicate in this way, to implement a simple game of battleships. Each program manages an object which is a fleet of ships. An object manager may be implemented either by polling, or by asynchronous reponse to incoming requests. The next two sections describe these alternatives. <H3>Polling Server <I1 IX=1>Server, with common processing A variation of the simple server loop allows the server program to service one call at a time, and perform processing in between. It allows the object oriented approach in environments where asynchronous servers are not supported. (M6809, IBM PC/MSDOS etc) <FIG ID=FIG4 PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig4 <PICTURE NAME=fig4$$$S> ..go donefig4 ...skipfig4 ..tb 9 17 25 33 41 49 57 65 73 +-------------->| | | | +-------+-------+ | | wait for a |(request) | | request |-----------------> | +---------------+ | | |(timeout) | | | | | +-------+-------+-------+ | | | | | | | | +---+ +---+ +---+ +---+ service the | | | | | | | | | | particular | | +---+ +---+ +---+ +---+ request | | | | | | | | +-------+-------+-------+ | | | | |<------------------------- | | | +-------------------------------+ | | Other activities | | | | | +-------------------------------+ | | ------------<-- ...donefig4 <FIGCAP><HP1>A polling server using RPC_Accept </HP1> </FIG> A call to the run&hyphen.time system <hp2>RPC_Accept</hp2> routine <i1> RPC_Accept causes a wait for the next request, and the servicing of the called procedure. The procedures called in this way may share data with the user program and communicate in other ways. The library procedure <hp2>RPC_Create_Server</hp2> must be used to initialise <i1> RPC_Create_Server the server before RPC_Accept can be called, in order to the open communication channel. It may be that the "other activities" are not related to the service procedures, if there are other things for which the task is responsible, as may be the case, for example, in a microprocessor without a multitasking kernel. It may also be that the "other activities" are very related to the service procedures. They may be fed commands by the service procedures, they may share data areas with the service procedures, and they may even call the same service procedures themselves. This method may also be appropriate if the server is regarded as a state machine, when requests from different clients must interact in some way, as in a resource manager. (This form of server is analoguous to an Ada task with "entries": examples of its use may be found in Ada tutorials.) <H3>Asynchronous Server <I1 IX=1>Server, Asynchronous This method of designing a server allows a user program on the server side to run continuously, at the same time as the client process(es). The user program simply asks the run&hyphen.time system to service any incoming requests asynchronously. The <hp2>RPC_Start_Server</HP2> routine is used once to set this up. <i1> RPC_Start_Server From that time on, whenever a call arrives, the user task will be interrupted, the called procedure will execute as though it had been called from the user program at that point, and then the user program will continue. (Under VMS, the procedure is run at AST level; on the M68k it is run <I1 IX=1>AST level in an equivalent way, not at interrupt level). <FIG ID=FIG5 PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig5 <PICTURE NAME=fig5$$$S> ..go donefig5 ...skipfig5 ..tb 9 17 25 33 41 49 57 65 73 +-------------->| | | | +-------+-------+ | | | | | | | | | | | User | ------------> Interrupted | | program | by request arriving | | loop | | | | | | | | | +-------+-------+-------+ | | | | | | | | | | +---+ +---+ +---+ +---+ service the | | | | | | | | | | | particular | | | +---+ +---+ +---+ +---+ request | | | | | | | | | | +-------+-------+-------+ | | | | | | | <-------------------- reenter loop where it | | | left off | +---------------+ | | | | -----<--------- ...donefig5 <FIGCAP><HP1>An asynchronous server using RPC_Start_Server </HP1> </FIG> This is the most powerful form of server, and may be the easiest to use. It is only available where the environment supports asynchronous response to events. It is useful for object oriented programming, to also allow RPC to control an otherwise autonomous process, or in a single tasking system, to provide a little concurrency. When accessing common data structures, the user program may temparaily disable asynchronous calls be calling the ..bf MONO SETAST ..pf system service provided under VMS and on the Valet&hyphen.Plus, or the equivalent. <H3>Multi&hyphen.threaded server: Identifying the client <I1 IX=1>Multiple clients If there are multiple clients for the same service, we can distinguish three cases: <ol> <li>If each service is a self&hyphen.contained operation, and no state information is held about the client, then one server task may be directly shared by many clients. ("<hp2>Idempotent</hp2>" operations). <I1> Idempotent operations <li>If some calls leave the server state changed, as, for example, when an "open" call to a file server leaves a file open, one solution is to dedicate a separate server task to each client. This is reasonable when a small number of clients will each use the server intensively. <li>If it is not practicable to dedicate a separate process to serving each client, and some state information must be kept by the server on behalf of each client, then the server must be able to determine the identity of the client. </ol> In the last case, the server may find, for his own information, the address of a caller using the <hp2>RPC_caller_address</hp2> procedure. <i1> RPC_Caller_Address <box> <HP1>Example</HP1> (VAX/FORTRAN) <XMP> SUBROUTINE MY_REMOTE_PROCEDURE CHARACTER*40 CALLER_ADR INTEGER STATUS ... CALL RPC_CALLER_ADDRESS(STATUS, %REF(CALLER_ADR)) ... END </XMP> </box> <H3>Making your own service ASTs This section is not intended for the general user. The routines mentioned allow specialised servers to be made, for instance which fork extra processes off for different clients. (This is used in the MODEL TCS system.) The <hp2>RPC_Queue_Server</hp2> procedure allows a user program <I1>RPC_queue_server to queue its own AST procedure to service the next request. <I1 IX=1>RPC_Service <hp2>RPC_service</hp2> is a procedure taking one rpc_message parameter. It will handle one incoming call message, deallocate the message buffer passed to it, and return. It is a suitable AST routine to be passed to RPC_Queue_Server, or may be called from a specially written user routine. See the description of these routines in the appendix. <H3>LOCAL servers <I1 IX=1>LOCAL addressing <I1 IX=1>Address LOCAL It is possible that one wants a package to be either remote or local, as selected at runtime. In this case, one has to link (bind) the server and client into the same program. <FIG ID=FIG6 PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig6 <PICTURE NAME=fig6$$$S> ..go donefig6 ...skipfig6 ..tb 9 17 25 33 41 49 57 65 73 +---------------------------------------+ | Application (client) | +---------------------------------------+ entry points-> | +---------------------------------------+ | Client stub | +---------------------------------------+ | +---------------------------------------+ | RPC Run Time Support | +---------------------------------------+ | +---------------------------------------+ | Server stub | +---------------------------------------+ same entry points-> | +---------------------------------------+ | Server Routines | +---------------------------------------+ ...donefig6 <FIGCAP><HP1>A LOCAL call is made to a procedure which is in fact part of the same process. The Server routines and the client stub provide entry points with the same name. </HP1> </FIG> <I1 IX=1>Binding, local servers This has to be done carefully, as two sets of entry points with the same name will exist. This is because the client stub provides the same routine names as the server module. Logically, what must be done is as follows. The client must call entry points in the client stub, rather than call the server module directly. Therefore, the client and client stub should be linked togther as one part, and the server and server stub must be linked together as another. Then, these two resulting parts are linked together into one whole. The method of performing this logical operation differs from system to system, and is not discussed here in detail. Now, the system may be set up so that the client and server stubs are directly connected. In this case, when the client stub is called, the message it produces is passed straight to the server stub, which calls the procedure in question. The <medium address> used to set this up is LOCAL . If a different RPC address is used, and RPC_Switch called, for example, calls will be redirected to a remote process. <H2>Calls within calls - CALLBACK <I1 IX=1>CALLBACK addressing The RPC system is reentrant, so that one remote procedure may call another remote procedure. A useful special case of this is when a remote procedure calls back routines in the caller. This is known as "CALLBACK". For example, a routine to display the state of a remote moinitoring task might call back a routine in the caller to print out each line. In that way, whoever calls the procedure, the output will arrive in the correct place. <FIG ID=FIG7 PLACE=INLINE FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig7 <PICTURE NAME=fig7$$$S> ..go donefig7 ...skipfig7 ..tb 9 17 25 33 41 49 57 65 73 Machine A Machine B +-------+ | Appl. | | prog. | +-------+ ------- call ------> +-------+ |DISPLAY| |STATE | +-------+ <----- callback ----- +-------+ |PRINT | | LINE | +-------+ ...donefig7 <FIGCAP><HP1>Callback allows the server to call routines in the client's process. Each process is therefor a client (c) of one call and a server (s) of the other. </HP1> </FIG> This takes advantage of the fact that <hp2>any client, while waiting for a reply, automatically behaves as a server.</hp2> The package called back must be defined as a separate package, and separate client stubs (for machine B) and server stubs (machine A) generated and linked in. On machine B, the special syntax for the address of the callback package address is <xmp> <package number> @ CALLBACK </xmp> In this case, <ul> <li>The package number must be explicitly stated (normally 0). (This is because the address is only valid within an RPC. If you don't give the package number explicitly, the RPC system would have to query the other side at initialisation time to determine the package number. It can't do that because at initialisation time, no caller is defined.) <li>The initialisation on machine B (RPC_open or open_xxx) only happens once; <li>Callback calls may ONLY be made from within remote procedures: the address is effectively undefined outside these. <li>The RPC system will use the same connection for the call back as for the original call (over DECNET for example). </ul> This system is not suitable if you want the server process to call the client back outside (some time after) the original call. In this case, a new channel must be opened with the "@CALLER" syntax (q.v.). <H2>Client facilities for selecting servers <FIG ID=FIG8 PLACE=FLOAT FRAME=NONE> ..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig8 <PICTURE NAME=fig8$$$S> ..go donefig8 ...skipfig8 ..tb 9 17 25 33 41 49 57 65 73 +--------+ | | | Client | | | +----|---+ | . . . . . . . . .+--------------+ . . . . . . . . . . | . +-------+ +-------+ +---|---+ +-------+ | | | | | | | | | Server| | Server| | Server| | Server| | A | | B | | C | | D | +-------+ +-------+ +-------+ +-------+ ...donefig8 <FIGCAP><HP1>A client may wish to select one from a set of similar servers dynamically. </HP1> </FIG> This section applies when there may be more than one instance of the same type of server in the system. In this case, the client program may wish to select one particular server at run time. <I1 IX=1>Multiple servers <I1 IX=1>Servers, multiple <I1 IX=1>Binding, run time There are two ways of doing this. The first method (using RPC_Switch) allows communication to be set up with one server at a time. The second method (using RPC_Open and RPC_close) allows communication to be established with more than one server at once, the client being able to switch rapidly between them. The "binding" of the client to the server refers to the resolution of the server address, and the setting up of communication channels to the server. This is normally done by the stub itself when the open_xxxx routine in the stub is called at initialisation time. <fn> Under VMS and TurboPascal, binding is performed automatiaclly by the client stub at initialisation time. If explicit binding is to be done by the user program, the NOAUTOINIT option should be used when the client stub is compiled, to disable automatic binding. </fn> <i1 ix=1> NOAUTOINIT, for explicit binding The result is a reference number called a <hp2>handle</hp2> which refers to the open connection. This is stored in a global variable called h_xxxx where xxxx is the name of the package. <h3> Reconfiguring the system The <hp2>RPC_configure</hp2> <I1 IX=1>RPC_configure <I1 IX=1>Reconfiguration call allows one client to use more than one identical server in turn. The effect is for the connections to all open servers to be closed and reopened with the translation of their logical names being perfomed according to new values which may have been set up. A client process which wishes to use several identical servers may therefore repeatedly redefine the logical names which give the addresses of those servers, and call RPC_configure to cause future calls to be directed to the new servers. <hp1>Note that if RPC_Configure returns a bad status, then one or all of the handles will be invailidated. In this case, as the user has no way of knowing which are valid and which are invalid, all he can do is exit. The use of RPC_Configure is not, therefore, recommended. </hp1> The <hp2>RPC_Switch</hp2> <I1 IX=1>RPC_Switch <I1 IX=1>Binding, run time <I1 IX=1>Handle switching routine performs the reconfiguration function on a single package, referenced by a handle. The package must be already open (for the handle to be valid). The value of the handle is unchanged. <h3> Explicit binding The RPC_Open and RPC_Close routines allow the user to perform the binding himself, and overwrite the handle used by the stub. The <hp2>RPC_Open</hp2> <i1 ix=1>RPC_Open <i1> Binding, explicit routine allows a client to open communication with a specific server. A string parameter describes the remote service required. It may be a formatted physical address (program name or number, network address, etc) or it may be a logical name which is converted by the run&hyphen time system into an appropriate address. The handle value returned is used in all future reference to the service by the client. If this value is put into the handle variable used by the stub, the stub will be directed to refer to the server in question. The handle variable used by the stub should be accessed as an external variable h_xxx where xxx is the package name. The client program may, however, perform RPC_Open serveral times, and keep a record of each of the handle values returned. It may then switch rapidly between servers by overwriting the stub's handle variable with the handle to the server it wants to access. Every server which has been opened must be closed again by calling <hp2>RPC_Close</hp2>. <i1 ix=1>RPC_Close <H2>User Error Handling <I1 IX=1>RPC_Establish <I1 IX=1>Errors, user handler <I1 IX=1>User error handler <I1 IX=1>Handler, user error The <hp2>RPC_Establish</hp2> procedure may be used in a client program to handle errors occuring in remote procedure calls. By default, if an unrecoverable error occurs in the communication with the server, a message is displayed and the client program is stopped. ($EXIT occurs under VAX/VMS, a pascal halt on other systems.) If the user wishes to handle the error himself, he passes the address of his error handler to RPC_Establish. If this has been done, his handler will be called <HP1>instead</HP1> of the default handler. <I1 IX=1>Errors, default handler In order to revert to the default handler, RPC_Establish is called with a value of zero. <box> <HP1>Example</HP1> (VAX FORTRAN): <XMP> EXTERNAL HANDLER ... CALL RPC_ESTABALISH(HANDLER) CALL MY_REMOTE_PROCEDURE CALL RPC_Establish(0) ... </XMP> </box> The user error handler is a routine taking one parameter, which is the rpc_message in question. If the user is programming in pascal, he will find the offending error status in the m_status field of the rpc_message. <box> <HP1>Example</HP1> (VAX Pascal): <XMP> VAR global_status: [VOLATILE] rpc_status; { error flag } ... [UNBOUND, ASYNCHRONOUS] PROCEDURE handler(p: rpc_message_pointer); BEGIN global_status := p^.m_status; {record bad status } END; ... </XMP> <HP1>In main program</HP1>: <XMP> global_status := SS$_NORMAL; { Initialise error flag } RPC_Establish(handler); { Establish my error handler } my_remote_procedure; { Try calling remote module } RPC_Establish(%IMMED 0); { Reselect default handler } IF not odd(global_status) { Check error flag } THEN ... </XMP> Note that [UNBOUND], [ASYNCHRONOUS], [VOLATILE] are all attributes which prevent the VAX Pascal compiler overoptimising the error handler, so that it will still work when called out of context. </box> <H2>Message format control - The ALIGN option. <I1 IX=1>ALIGN This option controls the formatting (invisible to the user) of messages sent by the stubs. /ALIGN selects or deselects word alignment of parameter values which is less space&hyphen.efficient, but Courier compatible. It is not recommended. The ALIGN option MUST be the same for corresponding client and server stubs. For microprocessor stubs, the ALIGN choice is built into the runtime library, and cannot be selected by the stub. The microprocessor libraries provided with the RPC software are generated without ALIGN. For VAX/VMS, the ALIGN option may be selected when building the stub: <OL> <LI> If using the RPC command, NOALIGN is the default, and /ALIGN must be specified as a command line parameter if Courier compatability is required. <LI>If you are using explicit postprocessing of the stubs (discussed below), NOALIGN is the default, unless the keyword ALIGN is included in the <I1 IX=1>INCLUDE INCLUDE keyword list. </OL> <H2>Timeouts on remote calls <I1 IX=1>Timeouts, on RPCs In some cases, where the communication medium and protocol used is unreliable, or where the remote software may be unreliable, one wants to specify the maximum time for execution of a remote routine. The timeout may be specified in two ways. PRAGMA TIMEOUT <hp1>(q.v.)</hp1> may be specified in the RPC definition file, in which case it is given separately for each procedure. Alternatively, the defualt timeout for the package may be specified on the compiler command line when generating the client stubs, using the option <xmp> TIMEOUT=nnnn </xmp> where nnnn is the time limit <hp2>in units of 10ms</hp2>. For example, the option ..bf MONO TIMEOUT=1000 ..pf selects a timeout of ten seconds. Allowance should be made for any delays which could occur in the transmission of messages, or due a machine being heavily loaded. This ensures that timeouts only occur when a real problem has arisen. If a timeout occurs on a remote call, it is treated as an error. That is, the client program will stop with an error message, unless a user error handler (discussed above) is declared, or a call_status (q.v.) parameter is given. <H2>Stub Version Numbers By default, the RPC compiler generates a version number from the RPC interface definition file. This 4 digit number is displayed on the standard output by the compiler, and inserted as a comment into the external definition (.ext) file produced. It is also compiled into the stub code. At run time, the client stub sends a version number to the server stub, which checks it against its own version number. If the version numbers do not match the request is rejected, and the error message "incompatible versions" is produced at the client. This ensures that the two stubs were generated from the same definition file, and will therefore refer to compatible modules. The version number is formed from a checksum of the non&hyphen.comment characters in the definition, and so will change when a material alteration to the package definition is made. In some cases, it is possible to make a small change to a package which will not cause serious compatabilty problems. For instance, the procedure names may be changed, another procedure is added <HP1>to the end</HP1> of the package definition, or a modification is made to a procedure which has in fact never yet been used. In this case it is possible to force the stubs to a have a particular version number, with the version= <number> option. The version number must be an integer between 1 and 32767. Numbers between 1 and 999 will not be generated automatically by the compiler, and so may be used for a private version numbering scheme. <HP1>Example</HP1>: Suppose there is a requirement that the procedure names on the client machine should differ from those on the server. This may be required to prevent a clash, for example, between local and remote versions of the same procedure, so that the same program can access either. In this case, two RPCL files are made, which differ only in the procedure names. The server stub is compiled first, with an automatically generated version number, and then the client stub is compiled with the version number forced to be compatible. <XMP> $ RPC MYSTUB1.RPC /SVAXVMS <P> RPCC: Generated stub version number is 2765 <P> $ RPC MYSTUB2.RPC /CVAXVMS /VERSION=2765 </XMP> <I1 ix=1>Version numbers <HP1>[The option version=0 causes the RPCC to generate "unsafe" stubs with no version number check. If use of this option later allows the inadvertent connection of incompatible stubs, run&hyphen.time errors (access violations etc) may occur without the cause of the problem being obvious. This may lead to wasted debugging time, and so is not recommended.]</HP1> <Appendix> <H1> RPC Compiler command options <i1 ix=1>Compiler, command options <i1 ix=1>command options for compiler The following is a list of command options accepted by the RPC compiler, RPCC. The options must be preceded by "/" under VMS or MSDOS, "-" under Unix or OS9. The option names are not case sensitive. See the chapter "Running the RPC Compiler" for more details and examples, and also the chapter "Advanced use of RPC". <dl TSIZE=20> <DT>NOAUTOINIT <DD>Suppress the automatic initialisation of the stubs (Under VMS, PILS or TurboPascal only) <DT>BYVALUE <dd>Pass simple IN arguments to routines by value, rather than by address. This removes FORTRAN compatibility, but is normally necessary for C compatability. Should not be used with the SFORTRAN or CFORTRAN options. <DT>CONCURRENT <DD>Allow those procedures (not functions) which do not return any results to be executed after the reply message has been sent back, concurrently with the calling program. See also PRAGMA CONCURRENT. <dt>TIMEOUT=<value> <dd>Specify the maximum time to be allowed for the completion (at run time) of any one procedure call in this package. An error "RPC Timeout" occurs if this time is exceeded. The timeout value is decimal, in in units of 10ms. [Default=no timeout] See section 8, and also see PRAGMA TIMEOUT. <DT>TYPES <DD>Causes definitions of the user-defined types (in C or Pascal) to be included in the external declaration (.ext) file generated. See section 8. <DT>ALIGN <dd>Adds an extra alignment byte in the cannonical form after each RPC_BYTE or RPC_CHAR type. RPC command only, not RPCC. Not recommended. <DT>VERSION <I1 ix=1>Version numbers <DD>Force the version number to a specified value. If zero is specified, supresses version number checking. See section 8. <lp> The following options select the generation of client stub files. Each may optionally be followed by an equals sign and a filename e.g. ..bf MONO cgeneric=clixxx.c ..pf <fn>The filename may not be included with the alternative "RPC" command described in chapter 4, only with "RPCC". </fn> <dt>CGENERICC <dd>Produce a client stub file in C langage. Note this is normally used with the BYVALUE option. <dt>CFORTRAN <dd>Produce a client stub in FORTRAN. <dt>CPILS <dd>Produce a client stub in PILS (Portable Interactive Language System) <dt>CCERNCROSS <dd>Produce a client stub file in Pascal suitable for the CERN cross software. <dt>CM6809 <dd>Produce a client stub file suitable for the Omegasoft Pascal compiler for the M6809. <dt>CVAXVMS <dd>Produce a client stub file suitable for the VAX/VMS pascal compiler 'VAX/Pascal'. <dt>CUNIXBSD <dd>Produce a client stub file suitable for the Berkley Unix 4.2, 4.3 pascal compiler 'pc'. <dt>CPCTURBO <dd>Produce a client stub file suitable for a TurboPascal (IBM PC or Macintosh) compiler. <DT>CMONOLITH <dd>Produce a client stub file suitable for a non&hyphen.module monolithic Pascal compilation. <lp> The following options select the generation of server stub files. Each may optionally be followed by an equals sign and a filename eg ..bf MONO sgeneric=serxxx.c ..pf <fn>The filename may not be included with the alternative "RPC" command described in chapter 4, only with "RPCC". </fn> <DT>SGENERICC <dd>Produce a server stub file in C langage. <dt>SFORTRAN <dd>Produce a server stub in FORTRAN. <dt>SPILS <dd>Produce a server stub in PILS (Portable Interactive Language System) <DT>SCERNCROSS <dd>Produce a server stub file in Pascal suitable for the CERN cross software. <DT>SM6809 <dd>Produce a server stub file suitable for the Omegasoft Pascal compiler for the M6809. <DT>SVAXVMS <dd>Produce a server stub file suitable for the VAX/VMS pascal compiler 'VAX/Pascal'. <DT>SUNIXBSD <dd>Produce a server stub file suitable for the Berkley Unix 4.2, 4.3 pascal compiler 'pc'. <DT>SPCTURBO <dd>Produce a server stub file suitable for a TurboPascal (IBM PC or Macintosh) compiler. <DT>SMONOLITH <dd>Produce a server stub file suitable for a non&hyphen.module monolithic Pascal compilation. <lp> The following options are only useful for development and maintenance of the compiler. They show the operation of the compiler at some low level and are of no interest for the normal user. Their setting does not influence the operation of the compiler itself and the output code obtained with these switches set is unaffected. These options can be mixed in any combination. <DT>DTREE <DD>Prints the tree of types and blocks. The compiler generates on the standard output a list of type and procedures definitions after the input parsing. This could be useful if you want to check whether the compiler really understood your definitions. The file '.ext' produced by the compiler is another way to check this consistency. The maximum and minimum estimated sizes of parameters passed to and from each routine are also listed. <DT>DLEX <DD>For debugging lexical analiser. Print each input line and the tokens that are extracted from this line. Only useful for upgrading and maintenance. <DT>DLEXHOT <DD>For debugging the lexical analiser. Print each character read from input. Only useful for upgrading and maintenance. </dl> <H1> RPC Library Routines Reference There follows a list of those library routines which may be called by application code in order to perform functions above those of pure remote procedure call. The methods and reasons for calling these are described in earlier chapters. Many of these routines are documented here only for completeness, and will never be called by the user. Note that although the stubs produced by the RPC compiler are deliberately matched to FORTRAN or C calling conventions, these library routines exist only in one form, and the caller is required to ensure that the calling conventions outlined below are met. <h2> Types The data types refered to in this chapter are as follows. For pascal, a declaration file (logical name rpc_proc) exists. If you use a different language, ensure that the data types and calling conventions match, given the operating system and language you are using. <box> * Under VMS, The simple types which are normally passed by value are in fact always passed by address when using the libraries rpc$lib or rpc$large. (A feature of VMS Pascal, for FORTRAN compatibility). See also notes under rpc_name and entry_point types. </box> <dl> <DT>rpc_status <DD>A 32 bit integer. This is normally passed by address, as it is returned from the procedure. <DT>rpc_name <DD>A 40 character fixed length string, padded with spaces. This is always passed by address. Users of VAX FORTRAN must be sure to include a %REF() around the parameter to prevent it being passed by descriptor. If you are calling these routines from C, and using a library which is not in C (ie RPC$LIB, RPC$LARGE under VMS, and libraries for M6809, MoniCa, RMS68k), you must always provide 40 characters. The RPC library in C (rpc$libc and rpc$libc8k on vms, and libraries on unix, os9 and the PC) will also accept zero-terminated strings up to a maximum of 40 characters plus terminator as IN parameters. Also be aware that the RPC system will not add a '\0' null character on the end of a returned string. <DT>socket <dd>The RPC system uses a 32 bit "socket" <I1 IX=1>Socket, definition of to refer to a communication channel to a remote task. This is just a reference number used by the commmunications code within the RPC system. <DT>handle <I1 IX=1>Handle, definition of <DD>A different reference number, which on a client machine refers to one remote package. There is a handle (32 bit) for each package. It is a global variable, and accessible as h_ followed by the package name. For example, the handle for the FILER package is h_filer. <DT>rpc_message_pointer <DD>The system uses a data structure called an <hp2>"rpc_message"</HP2> <I1 IX=1>rpc_message, definition of to hold all the information about a remote call. This includes its status and pointers to the socket which is being used for communication with the remote party. It is not normally necessary for the user to know the format of this structure, but in some cases he may want to pass a pointer to it from one routine to another. (For the format of an rpc_message, see the rpc_types include file, as this contains several fields used internally by the RPC RTS, which may be changed between versions. It is not recommended that user code uses this buffer directly, but calls RPC_Service to have it serviced.) An rpc_message_pointer is a pointer to an rpc_message. <dt>entry_point <dd>This is the address of a routine. Under VAX/FORTRAN, the parameter must be enclosed in %LOC() in order to simulate its being passed as a VAX11 bound procedure value. </dl> <h2> Library Routines The routines are listed for reference in alphabetical order. For a pascal declaration file for these routines, see the file rpcproc.h (logical name rpc_proc under VMS). <box> ..bf TITLE ..ra RPC_ACCEPT <I1 PG=MAJOR> RPC_accept ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>IN s socket by value* <li>IN timeout integer by value* </ol> <DT>Effect <DD>This routine waits for a single request on the given socket, and services it according to the currently attached stub modules. The socket, s, must be a value returned by a previous call to rpc_create_server. The timeout is specified in units of 10ms. If no request arrives during the timeout period, then a status value of RPC_s_timeout is returned. A timeout value of 0 allows an outstanding request to be serviced without waiting for a new one. A value of -1 may be used to specify an infinite timeout. A maximum of one request is handled per call to RPC_accept. </dl></box> <box> ..bf TITLE ..ra RPC_ATTACH_STUB <I1 PG=MAJOR> RPC_attach_stub ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>IN stub entry_point by value* <li>IN service rpc_name by address <li>OUT pkg_no integer by address </ol> <DT>Effect <DD>The server stub is declared. The 'stub' parameter must be the entry point of the server stub routine. The 'service' parameter must be the name of the service (normally as declared in the package definition file). The returned 'pkg_no' parameter is the package number allocated to the stub (0 for the first one, 1 for the next, etc) which may be used by the client as an explicit address, or may be passed to RPC_DETACH_STUB. <DT>Note <DD>Called by stubs only. Not called by user application code. </dl></box> <box> ..bf TITLE ..ra RPC_CALL <I1 PG=MAJOR> RPC_call ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>IN handle integer by address <li>IN OUT p_buf rpc_message_pointer by address <li>IN timeout integer by value* </ol> <DT>Effect <DD>A remote call is made. The 'handle' parameter must be a value previously returned by a call to RPC_OPEN. The p_buf parameter is a pointer to the buffer. If an error occurs, the program is stopped with a message, or a user error handler is called. In the latter case, the stack is unwound to cause a premature exit from the caller (the stub) as to continue to unpack parameters could cause further errors. <DT>Note <DD>Called by stubs only. Not normally called by user application code. </dl></box> <box> ..bf TITLE ..ra RPC_CALL_STATUS <I1 PG=MAJOR> RPC_call_status ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>IN handle integer by address <li>IN OUT p_buf rpc_message_pointer by address <li>IN timeout integer by value* </ol> <DT>Return value <DD>Call status, type rpc_status, VMS format <DT>Effect <DD>A remote call is made. The 'handle' parameter must be a value previously returned by a call to RPC_OPEN. The p_buf parameter is a pointer to the buffer. If an error occurs, it is reflected in an even return value with the VMS (facility, message, severity) format. If no error occurs, the return value is RPC_S_NORMAL (=1). <DT>Note <DD>Called by stubs only. Not normally called by user application code. </dl></box> <box> ..bf TITLE <I1 PG=MAJOR> RPC_caller_address ..ra RPC_CALLER_ADDRESS ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>OUT name rpc_name by address </ol> <DT>Effect <DD>Returns the RPC address of the process which called the current procedure. The format for an ethernet connection will be in the normal RPC format with an explicit packet type, for example <xmp> AA0004002F58_5050.ETHERNET </xmp> For a DECNET connection to a multiclient server, the address will be the RPC address of the client process, assuming that it has started a server with the name of the process as DECNET object name: <xmp> VXCRNA::"0=FRED".DECNET </xmp> <DT>Note <DD>Called by application code in a server procedure to find out the name of the client who called it. This routine must be called from within a remote procedure, as only then is the "current client" defined. Returns an RPC address blank filled. <DT>Note <DD>Not available on M6809. </dl></box> <box> ..bf TITLE ..ra RPC_CLOSE <I1 PG=MAJOR> RPC_close ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>IN handle handle_type by value* </ol> <DT>Effect <DD>The reverse of RPC_OPEN. The handle specified becomes invalid for use in future calls. </dl></box> <box> ..bf TITLE ..ra RPC_CONFIGURE <I1 PG=MAJOR> RPC_configure ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address </ol> <DT>Effect <DD>Retranslates the logical name of each open package. For each one which has changed, closes the communication channel and reopens it with the new address. See also RPC_switch. <DT>Note <DD>Called by a client program. </dl></box> <box> ..bf TITLE ..ra RPC_CREATE_SERVER <I1 PG=MAJOR> RPC_create_server ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>IN client rpc_name by address <li>OUT s socket by address </ol> <DT>Effect <DD>Initialises a server, opening the communication channel where necessary. The socket returned may be used by future calls to RPC_ACCEPT. Used when writing a "polling server". </dl></box> <box> ..bf TITLE ..ra RPC_DETACH_STUB <I1 PG=MAJOR> RPC_detach_stub ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>IN pkg_no integer by value* </ol> <DT>Effect <DD>Opposite to RPC_ATTACH_STUB. The server stub is disconneted from the RPC system, and can no longer be accessed by a client. <DT>Note <DD>Called by server stubs only. Not called by user application code. </dl></box> <box> ..bf TITLE ..ra RPC_DISPOSE <I1 PG=MAJOR> RPC_dispose ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>IN P rpc_message_pointer by value* </ol> <DT>Effect <DD>Opposite of rpc_new. The message buffer is deallocated (returned to the pool). <DT>Note <DD>Called by client stubs only. Not called by user application code. </dl></box> <box> ..bf TITLE ..ra RPC_EARLY_RETURN <I1 PG=MAJOR> RPC_early_return ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>INOUT P rpc_message_pointer by address </ol> <DT>Effect <DD>The message is returned to the caller. This is normally done automatically by the runtime system, but in some cases (/concurrent option) the stub may wish to force an early return, before futher processing. <DT>Note <DD>Called by server stubs only. Not called by user application code. </dl></box> <box> ..bf TITLE ..ra RPC_ESTABLISH <I1 PG=MAJOR> RPC_establish ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>IN handler entry_point by value* </ol> <DT>Effect <DD>Deletes any previous user error handler. Establishes the specified handler such that whenever a fatal error occurs during an RPC call, the user error handler will be called, and passed the offending message as a parameter. On return from the user error handler (under VMS or on the M680x0), the stack will be unwound to prevent the rest of the stub from executing, and return will be made to directly to the user program after the remote call. </dl></box> <box> ..bf TITLE ..ra RPC_HARDWARE_RESET <I1 PG=MAJOR> RPC_hardware_reset ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>IN handle integer by address </ol> <DT>Effect <DD>Finds the physical address of the hardware of the server in use, and performs (if possible) a physical reset function on it. </dl></box> <box> ..bf TITLE ..ra RPC_INIT <I1 PG=MAJOR> RPC_init ..pf <dl> <DT>Parameters <DD>None <DT>Effect <DD>Initialises the entire RPC run time system. <DT>Note <DD>Need not be called under VAX/VMS or Turbopascal. </dl></box> <box> ..bf TITLE ..ra RPC_LOOP_SERVER <I1 PG=MAJOR> RPC_loop_server ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>IN client rpc_name by address </ol> <DT>Effect <DD>A communication channel is opened, and any requests received serviced. The routine loops until an error occurs, then closes the communication channel. <DT>Note <DD>This is the routine called by the default SERVERLOOP main program. </dl></box> <box> ..bf TITLE ..ra RPC_NEW <I1 PG=MAJOR> RPC_new ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT p rpc_message_pointer by address <li>IN size integer by value* </ol> <DT>Effect <DD>Allocates an rpc buffer for a future call. The size parameter is currently ignored. <DT>Note <DD>Called by stubs only. Not called by user application code. </dl></box> <box> ..bf TITLE ..ra RPC_OPEN <I1 PG=MAJOR> RPC_open ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>OUT handle integer by address <li>IN service rpc_name by address </ol> <DT>Effect <DD>This is the binding routine. It establishes communication with a server for the package specified in the 'service' parameter. This may be a logical name or a physical RPC address. The 'handle' parameter returned is used by the stub in all calls, and in any call to RPC_CLOSE. </dl></box> <box> ..bf TITLE ..ra RPC_QUEUE_SERVER <I1 PG=MAJOR> RPC_queue_server ..pf <dl> <DT>Note <DD>This is only used when one is making a special multitask server. (Eg MODEL TCS Terminal Control System). Not normally called by user code. <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>IN s socket by value* <li>IN action entry_point by value* <li>IN dummy integer by value* </ol> <DT>Effect <DD>An asynchronous receive request is queued for the server socket given, such that the 'action' routine will be called when the next request arrives. (The last parameter is dummy). This routine queues an asynchronous user routine (AST) to be called when the next request arrives on the given socket (see RPC_Create_Server). It allocates space for the incoming message, and passes the address of this to the AST routine. <I1 IX=1>AST user The user AST routine has entry point astadr and is passed by address one parameter (M, of type RPC_message). This parameter is suitable to be passed to RPC_Service (see below). This parameter is all that is required by the service routine below: the user program may, however, want to perform some pre- or post- processing, such as forking off other tasks to handle the requests, or application functions. </dl></box> <box> ..bf TITLE ..ra RPC_REPORT_ERROR <I1 PG=MAJOR> RPC_report_error ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>IN status rpc_status by address </ol> <DT>Effect <DD>Logs an error message corresponding to the given status code. Under VAX/VMS, causes an image EXIT, with the status code as exit status. </dl></box> <box> ..bf TITLE ..ra RPC_SERVICE <I1 PG=MAJOR> RPC_service ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>IN p rpc_message_pointer by address </ol> <DT>Effect <DD>Services the request specified in the message pointer to by 'p'. The return message is sent. Note that on VMS, pointer is passed by address, unlike the parameter to the user AST routine of RPC_Queue_Service. </dl></box> <box> ..bf TITLE ..ra RPC_START_SERVER <I1 PG=MAJOR> RPC_start_server ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>IN client rpc_name by address </ol> <DT>Effect <DD>An asynchronous server is started. That is, a communication channel is opened, and an asynchronous read request is queued on that channel. When the read completes, the RPC system services the request and queues another read, so that the server continues to run. The set of clients to be serviced is identified by the string parameter, which may in some cases include wildcards. The procedure returns immediately, but from then on any requests coming in are serviced asynchronously. The effect is as though RPC_Accept (q.v.) were called automatically whenever a request arrives. </dl></box> <box> ..bf TITLE ..ra RPC_SWITCH <I1 PG=MAJOR> RPC_switch ..pf <dl> <DT>Parameters <DD><OL COMPACT=1> <li>OUT status rpc_status by address <li>IN handle integer by address </ol> <DT>Effect <DD>Retranslates the logical name of the package. If it has changed, closes the communication channel and reopens it. </dl></box> <H1>Supported data types <I1 IX=1>Data types <I1 IX=1>Calling conventions The following types are supported by the RPC Compiler. For each type, the representation in each high level language is given. The principal constraint is that variable length arrays must be passed as two parameters, firstly an array, and secondly the number of elements in that array. This is refered to as a SEQUENCE. <I1 IX=1>SEQUENCE <I1 IX=1>Array, variable length <H2>Simple Types <DL> <DT>RPC_BYTE <DD> An unsigned 8 bit long value. <I1 IX=1>BYTE <DL TSIZE=20> <DT>C <DD> ..bf MONO unsigned char ..pf <DT>Standard Pascal <DD> ..bf MONO 1..255 ..pf <DT>M68k Pascal <DD> ..bf MONO PACKED 1..255 ..pf <DT>Omegasoft Pascal <DD> ..bf MONO BYTE ..pf <DT>TurboPascal <DD> ..bf MONO BYTE ..pf <DT>VAX/FORTRAN <DD> ..bf MONO BYTE or LOGICAL*1 ..pf </DL> <DT>RPC_CHAR <DD> <I1 IX=1>Character single A character in the local coding convention, converted by the RPC system if necessary to/from ASCII. <DL TSIZE=20> <DT>C <DD> ..bf MONO char ..pf <DT>Pascal <DD> ..bf MONO CHAR ..pf <DT>FORTRAN <DD> ..bf MONO CHARACTER*1 ..pf </DL> <DT>RPC_SHORT <DD> A 2's complement 16 bit long value. <DL TSIZE=20> <DT>C <DD> ..bf MONO short int ..pf <DT>Standard Pascal <DD> ..bf MONO -32768..32767 (on 32 bit machine) ..br INTEGER (on 16 bit machine) ..pf <DT>M68k Pascal <DD> ..bf MONO PACKED -32768..32767 ..pf <DT>VAX/FORTRAN <DD> ..bf MONO INTEGER*2 ..pf </DL> <DT>RPC_LONG <DD> <I1 IX=1>long integer <I1 IX=1>integer short A 2's complement 32 bit long value. <DL TSIZE=20> <DT>C <DD> ..bf MONO long int ..pf <DT>Standard Pascal <DD> ..bf MONO INTEGER ..pf (32 bit machine) (normally a record on 16 bit machine). <DT>M68k Pascal <DD> ..bf MONO INTEGER ..pf <DT>Omegasoft Pascal <DD> ..bf MONO LONGINTEGER ..pf <DT>TurboPascal <DD> ..bf MONO LONGINT ..pf <DT>VAX/FORTRAN <DD> ..bf MONO INTEGER*4 ..pf </DL> <DT>RPC_INTEGER <DD> <I1 IX=1>integer generic A 2's complement 16 bit long value which is represented in the machine in the local standard integer length (32 bit for M68k and VAX/VMS). This allows 16 bit and 32 bit systems to exchange data between programs which each use the local INTEGER type. Only 16 bits are actually transferred. If an attempt is made to pass more than 16 bits, the upper 16 bits are simply lost, and no error is generated. <HP1>Experience shows that using RPC INTEGER where appropriate (as opposed to RPC LONG or RPC SHORT) leads to smoother porting of software between systems</HP1>. <DL TSIZE=20> <DT>C <DD> ..bf MONO int ..pf (32 or 16 bit machine) <DT>Any Pascal <DD> ..bf MONO INTEGER (32 or 16 bit machine) ..pf <DT>FORTRAN <DD> ..bf MONO INTEGER ..pf </DL> <DT>RPC_REAL32 <DD> Real numbers, 32 bit. These are passed in the local representation and converted by the RPC system if necessary. In the future, RPC_REAL48, RPC_REAL64 and RPC_REAL128 may be supported too. Consult the documentation for the compiler of your machine about the floating point number format. As format conversion may take place in transferring real numbers, it is possible that small rounding errors occur. As the ranges of real numbers differ, very small numbers may be rounded down to zero, and large ones may cause an "overflow" conversion error. <DL TSIZE=20> <DT>C <DD> ..bf MONO float ..pf <DT>Turbo Pascal <DD> ..bf MONO SINGLE ..pf <DT>Other Pascal <DD> ..bf MONO REAL ..pf <DT>FORTRAN <DD> ..bf MONO REAL ..pf </DL> </DL> <H2>Structured Types <DL> <DT>STRING <DD> <I1 IX=1>String <I1 IX=1>Character, string of A string is a variable length array of characters. Its declaration in RPCL must specify the maximum number of characters which are ever going to be passed, so that the compiler knows how much space to allocate at the receiving end. With the exceptions noted below, a string is passed as two parameters, the first to give the character array, and the second the length. The first parameter is an array of CHAR. The second parameter is of type RPC_INTEGER, and indicates the number of valid characters actually in the string. In C, a string is passed as one paremeter, a pointer to its first character. The string is terminated by a '\0' (null) character. For VAX/FORTRAN (options FORTRAN or VAXVMS), the string is passed as one parameter, a string descriptor. This is the standard for VAX/FORTRAN, but not for the other <FN> In the client, to call a procedure with a string parameter from VAX/Pascal, it is necessary to include the %STDESCR before the parameter to force FORTRAN conventions, but then any Pascal string or varying of char can be passed. In a server, in order to write a Pascal procedure which takes a string parameter, it is necessary to declare the parameter as a RECORD with the string descriptor format, and explicitly access the length and pointer within it. See the VAX/VMS manual for futher details. </FN> VMS languages. The length field of a string descriptor is never changed. If an OUT string has a different length from the receiving descriptor on the client, it is truncated or blank filled. On the server, for an IN parameter, a descriptor is generated the same length as the client's string. The string should be declared in the RPCL with a length greater than or equal to the maximum string size which will ever be used for that parameter, in the client or in the server. On the M6809, and under TurboPascal, the string is passed as a single STRING argument, a byte array with the current length in position 0 and the characters in positions 1 to <length>, with a maximum length of 126. The figure of 80 below is used only as an example: the only upper limit imposed by the RPC system is 32767. <DL> <DT>RPCL <DD> ..bf MONO TYPE mystring IS STRING(80); <P> PROCEDURE proc_name(..; thestring: IN OUT mystring; ...); ..pf <DT>C <DD> ..bf MONO typedef char mystring[81]; <P> proc_name(..., the string, ...); <P> ... <P> mystring thestring; <P> ..pf <DT>Pascal <DD> ..bf MONO TYPE mystring = PACKED ARRAY [1..80] OF CHAR; <P> PROCEDURE proc_name(... <P> VAR s: mystring, <P> VAR l: RPC_SHORT, ..); ..pf <DT>VAX/Pascal <DD> ..bf MONO In client: TYPE mystring = PACKED ARRAY [1..80] OF CHAR; <P> - or VARYING OF CHAR } <P> PROCEDURE proc_name(... VAR s: %STDESCR mystring; ...); EXTERN; In server: <P> TYPE mystring = PACKED ARRAY [1..80] OF CHAR; <P> descriptor = RECORD <P> strlen: [word]0..80; <P> dum1, dum1: [byte] 0..255; <P> stradr: ^mystring <P> END; PROCEDURE proc_name(... VAR d: descriptor; ...); <P> BEGIN <P> ... <P> END; ..pf <DT>FORTRAN <DD> ..bf MONO SUBROUTINE PROC_NAME(..., THESTRING, ...) <P> CHARACTER *(*) THESTRING ..pf <DT>Omegasoft Pascal, TurboPascal <DD> ..bf MONO TYPE mystring = STRING[80]; <P> PROCEDURE proc_name(... VAR s: mystring); ..pf </DL> <DT>SUBSTRING <DD> The substring type has been introduced to allow a more efficient implementation of the PILS remote host interface. A substring is a packed array of char in which the valid characters are between two indices. The first index, START, indicates the first valid element in the array, while the second, LENGTH, indicates the number of valid characters that follow (and including) the START. <DL> <DT>RPCL <DD> ..bf MONO TYPE mysub IS SUBSTRING(80); <P> PROCEDURE proc_name(..; mysubstring : IN OUT mysub; ...); ..pf <DT>C <DD> ..bf MONO typedef char mysubs[80] <P> proce_name(..., a_thesubs, s_thesubs, l_thesubs, ...) <P> ... <P> mysubs a_thesubs; <P> int *s_thesub, *l_thesub; <P> ... ..pf <DT>Pascal <DD> ..bf MONO TYPE mysub = PACKED ARRAY [1..80] OF CHAR; <P> PROCEDURE proc_name(.., VAR thesub: mysub; <P> VAR start, len: RPC_INTEGER, ...); ..pf </DL> <DT>ARRAY <DD> A sequence of SIMPLE type like RPC_CHAR or RPC_LONG. It may be multidimensional and must have a specified size for each dimension. <HP1>(Note that the example below, although illustrating different aspects of array types, would in practice be too big for the limit currently imposed by the runtime support of about 1450 bytes per call</HP1>.) <DL> <DT>RPCL <DD> ..bf MONO TYPE myarray IS array (1..256, -15..23, 10..15) of rpc_long; <p> PROCEDURE proc_name(..; the_array: IN OUT myarray; ..); ..pf <DT>C <DD> ..bf MONO typedef int myarray[256][39][6] ..pf <DT>Pascal <DD> ..bf MONO TYPE myarray = ARRAY [1..256, -15..23, 10..15] OF INTEGER; <P> PROCEDURE proc_name(.. VAR a: myarray; ...); ..pf <DT>FORTRAN <DD> ..bf MONO SUBROUTINE PROC_NAME(..., IARRAY, ..) <P> INTEGER IARRAY(256, 39, 6) ..pf <DD> </DL> Arrays of the same sizes on different machines are compatible, even if the starting index is not the same. For example, a FORTRAN array(1..10) may be passed to a C array(0..9). Arrays are of fixed length: the same amount of data is transferred every time. An array which contains a varying amount of dat should be described as a sequence. (Under VAX/FORTRAN, ARRAY type cannot be used to pass arrays of CHARACTER. Use the STRING type instead). <DT>SEQUENCE <DD> A sequence is a general variable&hyphen.length array. It represents a one&hyphen.dimensional collection of data, whose type and maximum number are specified at compile time but whose actual number and value are specified at run&hyphen.time. A sequence is always passed as two parameters, a length and an array, although it is specified in RPCL as one logical parameter. <DL> <DT>RPCL <DD> ..bf MONO TYPE myseq IS sequence (80) of rpc_long; <P> procedure proc_name(..; theseq: IN OUT myseq; ...); ..pf <DT>C <DD> ..bf MONO typdef int myseq[80]; <P> proc_name(..., a_theseq, l_theseq, ...); <P> ... <P> myseq a_theseq; <P> int * l_theseq; <P> ... ..pf <DT>Pascal <DD> ..bf MONO TYPE myseque = ARRAY [1..80] OF INTEGER; <P> PROCEDURE proc_name(... <P> VAR thearr: myseq; <P> VAR thelen: INTEGER; ...); ..pf <DT>Fortran <DD> ..bf MONO SUBROUTINE PROC_NAME( ..., THESEQ, THELEN, ...) <P> INTEGER THESEQ (80) <P> INTEGER THELEN ..pf <DD> <HP1> Note that under VAX/VMS, for a SEQUENCE(...)OF RPC CHAR, the array must be a pure array: it may not be a FORTRAN string passed by descriptor. If a FORTRAN string is used in the client, it must be passed with a %REF qualifier. A FORTRAN string cannot be used for the array in the called routine. The STRING type (above) is available for passing strings, although with FORTRAN this will result in the entire length of the string being passed every time, as FORTRAN strings are fixed length</HP1>. </DL> <DT>RECORD <DD>A record is a data structure consisting of a set of named fields. <DL> <DT>RPCL <dd> <xmp> TYPE myrec IS RECORD field1: RPC_INTEGER; field2: RPC_INTEGER; END RECORD; </xmp> <DT>Pascal <dd> <xmp> TYPE MYREC = RECORD FIELD1: INTEGER; FIELD2: INTEGER; END; VAR X: MYREC; </xmp> <DT>C <DD> <xmp> struct { int field_1; int field_2; } myrec; struct myrec x; </xmp> <DT>VAX/FORTRAN <dd> <xmp> STRUCTURE /MYREC/ INTEGER FIELD1 INTEGER FIELD2 END STRUCTURE RECORD /MYREC/ X </xmp> <DT>PILS <DD> (There is no concept of records in PILS.) </DL> <DT>Pointers <DD>A pointer type, if explcitly declared as such, is assumed to be NIL (null) or to point to valid data. In the later case, the data is transfered to the other side, and a pointer to it is generated. This will occur recursively, so that linked lists and trees may be passed. Self-referencial data structues (circular lists etc) are not allowed. For an INOUT parameter, the called routine may modify the structure. On the client side, the RPC system completely destroys the structure (returning it to the heap) and rebuilds (from the heap) the structure returned from the server. For IN parameters, the RPC system does not touch the structure or pointer on the client side at all. For OUT parameters, the RPC system allocates a new structure on the client side, and it is the responsability of the caller eventually to return it to the heap. The original value of the pointer is ignored, and simply overwritten with a pointer to the new structure. <dl> <dt>RPCL <DD> ..bf mono TYPE mypo IS ACCESS myrec; ..pf <dt>Pascal <DD> ..bf mono TYPE mypo = ^myrec; ..pf <dt>C <DD> ..bf mono typedef struct myrec *x; ..pf <dt>FORTRAN <DD>There is no concept of pointer in FORTRAN. <dt>PILS <DD>There is no concept of pointer in PILS. </dl> </DL> <H1>RPCL Language Definition <I1 IX=1>RPCL, definition <I1 IX=1>Interface, definition file format There follows a Backus&hyphen.Naur Form (BNF) definition of the RPC language, RPCL Version 1.0. This is a reference definition and should be used to solve any ambiguity or error that could arise when writing in RPCL. Reserved keywords are in upper case. Words inside angle brackets are productions: that is, they may be replaced by the part on the right of the '::=' of their own definition. The sign '|' means 'exclusive or', that is one form or the other may be used. ..bf MONO ..fo off ..tb 9 17 25 33 41 49 57 65 73 <rpcl_program> ::= PACKAGE <ident> IS { <type_dec> ; }* { <other_dec> ; }* END <ident> ; <type_dec> ::= TYPE <ident> IS <type> | <pragma> <other_dec> ::= PROCEDURE <ident> <formal_params> | FUNCTION <ident> <formal_params> RETURN <simple_type> | <pragma> <formal_params> ::= ( <formal_def> { ; <formal_def> }* ) | <void> <formal_def> ::= <identlist> : <direction> <type> <direction> ::= IN | OUT | IN OUT <pragma> | PRAGMA EXTERNAL_MARSHALLING( <identlist> ); | PRAGMA CONCURRENT ( <identlist> ) | PRAGMA CAST ( <identlist> ) | PRAGMA TIMEOUT ( <ident> , <number> ) | PRAGMA CALL_STATUS ( <ident> , <ident> ) <identlist> ::= <ident> {, <ident>}* <type> ::= <simple_type> | <structured_type> | ACCESS <subtype> <subtype> ::= <ident> | <simple type> <simple_type> ::= RPC_CHAR | RPC_BYTE | RPC_SHORT | RPC_INTEGER | RPC_LONG | RPC_REAL32 | RPC_REAL48 | RPC_REAL64 | RPC_REAL128 <structured_type>::= ARRAY (range { , <range> }*) OF <subtype> | RECORD { <identlist> : <subtype> }* END RECORD | SEQUENCE (index) OF <subtype> | STRING ( [index] ) | SUBSTRING ( [index] ) <range> ::= [index] .. [index] <number> ::= < A number in 1 .. 65536> <ident> ::= < A Pascal&hyphen.like identifier> ..us Where ::= means "may be composed of" | means "or" { }* means zero or more times; <void> means no characters at all ..fo on ..pf <hp2>Notes:</hp2> <OL> <LI> Comments in RPCL start with two dashes '--' and end at the end of the line. Comments can be put anywhere except inside keywords or identifiers. <LI> STRING is not equivalent to a type SEQUENCE OF RPC_CHAR, because a special (more efficient) Courier message format is used to represent objects of type STRING and SUBSTRING. <LI> The maximum length of identifier is limited to 25 characters. <LI> RPCL is case independent, meaning that you can write your desciption file in any mixture of upper and lower case. The identifiers 'VAR_ONE' and 'var_one' are, for example, the same, as are the keywords "String" and "STRING". <LI> Identifiers may not be reserved words in any language in which stubs are to be generated. In order to avoid clashes within the stubs, one should also avoid identifiers starting with any of: <XMP> abort_ call_ m_ reject_ return_ rpc_ </xmp> or the identifiers: <xmp> b header procedure_number program_number version_number which why </XMP> The package should not have the same name as any of the procedures within it. </OL> <H1>Installation of the RPC tools <I1 IX=1>Installation This is a list with which the user need not generally concern himself. It details the files which must be available on the machine in order to compile and link distributed programs. Under VAX/VMS, a single command (@DISK$D1:[RPC]RPC on VXCRNA) sets up all the other commands and logical names required, and may be put in <I1 IX=1>login file your login file. Under UNIX BSD the compiler 'rpcc' should be present in any directory of your PATH shell variable. The header file rpcheader.h should be in one of the system (or user) header file areas searched by the compiler. The files forming part of release 2.4 on VAXVMS are as follows <DL TSIZE=13> <DT>include.com <DD>The include preprocessor command file. <DT>include.exe <DD>The include preprocessor, used by the RPC.COM command file for stubs in Pascal. <DD>lnkdef.com <DT>A command file used by setup.com for defining the <dt>rpc.com <dd>The command file used by the RPC command. <DT>rpc.hlb <DD> A VAX/VMS help library <DT>rpc.hlp The RPC help library. If your want the .HLP file, extract it from this with LIB/HELP/EXTRACT. <DT>rpcc.exe <DD> The rpc compiler <DT>rpcc.obj <DD> The rpc compiler in object form, so that you can link it to run on an old version of VMS if necessary. The command is LINK/NOTRACEBACK RPCC <DT>rpcconst.h <DD> A pascal include file. Contains some basic definitions of constants. <DT>rpcheader.h <DD> An include file in C language. Contains all constants, types, and (un)marshaling procedures. <DT>rpclarge.olb <DD> The run&hyphen.time library, version for DECNET, ethernet, V24, ISO TP4, X24 8k byte buffers. Logical name is rpc_large <DT>rpclib.olb <DD> The run&hyphen.time library, version for DECNET, ethernet, V24, ISO TP4, X24 etc. Logical name is rpc_lib <DT>rpclibc.olb <DD> The run&hyphen.time library, version for TCP/IP working. Logical name is rpc_libc <DT>rpclibc8k.olb <DD> The run&hyphen.time library, version for TCP/IP working. 8kB buffer version. Logical name is rpc_libc # <DT>rpclarge.opt <DD> Link options file, version for DECNET, ethernet, V24, ISO TP4, X24 8k byte buffers. Logical name is rpc_large <DT>rpclib.opt <DD> Link options file, version for DECNET, ethernet, V24, ISO TP4, X24 etc. Logical name is rpc_lib <DT>rpclibc.opt <DD> Link options file, version for TCP/IP working. Logical name is rpc_libc <DT>rpclibc8k.opt <DD> Link options file, version for TCP/IP working. 8kB buffer version. Logical name is rpc_libc <dt>rpcmsg.exe <dd>An error file. $SET ERROR RPCMSG will allow VMS to translate RPC error numbers into text strings. Any program linked with RPC can do this anyway, as the same information is in a module RPC_ERRS in the library. <DT>rpcproc.h <DD> A pascal include file. Contains external declaration of routines used to transport messages to the counterpart side. <DT>rpcstub.h <DD> A pascal include file. Contains system dependent library routines to marshal and unmarshal parameters. <DT>rpctypes.h <DD> A pascal include file. contains system dependent type definitions. <dt>rpc_vms024.release_notes <dd>A set of notes describing differences between this and previous releases, and how to install the product. <DT>setup.com <DD> Login command file to set up logical names and symbols. Put a call to this into the login.com for each user wishing to develop programs using RPC. (No changes are required for those users using programs built with RPC.) </DL> <H1>More Information If you would like a copy of this document, mail Anne Perrelle at CERN. <xmp> Internet: PERRELLE@CERNVM.CERN.CH UUCP: cernvax!cernvm!perrelle DECNET: VXCERN::MINT"PERRELLE@CERNVM" BITNET: PERRELLE AT CERNVM </xmp> <HP2>On&hyphen.line help</HP2> Some of the information in this document is available on&hyphen.line under a VMS "HELP" scheme. The help library is released with the VAX/VMS software. <HP2>VAX/NOTES Conference</HP2> For up to date release information, bug reports and user feedback, see the VAX/NOTES conference VXCERN::RPC. If you have NOTES installed but haven't used it, to access the conference first type (under VAX/VMS) <xmp> $ NOTES > ADD ENTRY VXCERN::RPC > OPEN RPC > SET SEEN > DIR *.* > EXIT </xmp> To find out what's new on future occasions, type <xmp> $ NOTES RPC </xmp> <HP2>Electronic Mail</HP2> Please send any suggestions, comments or problems by mail to <xmp> Internet: RPC@VXCERN.CERN.CH UUCP: cernvax!vxcern!rpc DECNET: VXCERN::RPC BITNET: RPC%VXCERN AT CERNVAX </xmp> <H1>Acknowledgements Many people have helped in the construction and support of the RPC system (and this manual), whilst at or passing through CERN. Many brought in specialist knowledge of particular systems, and all have shown the patience and tolerance which is required as part of such a widely distributed and loosely coupled team. Antonio Pastore, a technical student at CERN in 1986, wrote the RPC compiler (in a remarkably short time) and wrote code to test it on the M68000 and the IBM&hyphen.PC. Nici Schraudolph, a summer student at CERN in 1987, enhanced the compiler (also in a very short time) to include several new features, including the production of C code as an alternative to Pascal. Tim Adye from the Rutherford Lab ported the system to the M6809 and wrote the machine&hyphen.dependent run&hyphen.time support for that. He has also been a source of numerous useful suggestions and additions to both the code and the documentation. Bob Jones (CERN/DD) extended the functionality of the DECNET interface to allow a server to handle multiple clients. Ignacio Martinez (Univ of Santander) added ISO TP4 communications under VAX/VMS, and Angel Camacho (Atlas Energias, Santander) has continued that work. Dirk Gosman, visiting CERN/DD from NIKHEF&hyphen.H, has provided communications support in an RMS68K multitasking environment, using Kik Piney's "ET" driver. Johannes Raab, working with the OPAL online group, debugged the C version of the system, and ported it to OS9. Peter Lorenz of the Delphi experiment ported the system to the IBM PC, and interfaced it to the OSI transport software from BICC. Roberto Bagnara, a technical student at CERN in 1988, enhanced the RS232 communication format for speed and reliability, and extended the PC implementation to include RS232 and raw ethernet handling as well as Class 4 transport. Louis Tremblet (CERN/DD) wrote the code generator for stubs in PILS. Anne Perrelle has been invaluable for her help in creating and distrubuting this and other RPC documents. ..ce Trademarks Ada is a trademark of the US Government, Ada Joint Program Office. OmegaSoft is a trademark of Certified Software Corporation. OS&hyphen.9 is a trademark of Microware Systems Corporation. Unix is a trademark of Bell Laboratories. Ultrix, VAX, VMS, UNIBUS and DECnet are trademarks of Digital Equipment Corporation. We apologize for any inadvertent omission to acknowledge any trademarks as such. </BODY> </APPENDIX> <BACKM> <H1>References <BL> <BIB ID=RPCIMP> T.J. Berners&hyphen.Lee CERN/DD, "RPC Internals" version 2.3.1, formerly "RPC Implementation Guide" <BIB ID=VIR88> T.J. Berners&hyphen.Lee, CERN/DD, "Programming Distributed Systems: Remote Procedure Call" <hp1>Proceedings of the conference on VMEbus In Research, Zürich,1988</hp1> An introduction to the basic concepts of RPC. <BIB ID=RTC87> T.J. Berners&hyphen.Lee, CERN/DD, "Experience with Remote Procedure Call in Data Acquisition and Control", <hp1> IEEE Transaction on Nuclear Science,</hp1> Vol NS&hyphen.34, No. 4 August 1987 <BIB ID=NELSON> B.J. Nelson, "Remote Procedure Call", XEROX PARC CSL&hyphen.81&hyphen.9, May 1981 <BIB ID=KOSTR85> K. Kostro, CERN/DD, "Portable Communication with Remote Procedure Call Protocols", private communication, copies from the author. <BIB ID=XSOFTN3> J.D. Blake, "User of Microprocessor Cross Software under VAX VMS", CERN PRIAM Note XSOFT/N3, June 86. Under Wylbur, type HELP PRIAM MICDOC P, then quote reference XSOFT/N3 when asked. <BIB ID=COURIER> "Courier: The Remote Procedure Call Protocol", XEROX Corporation, XSIS 038112, December 1981. <BIB ID=WINTCPADM> <hp1>WIN/TCP Administrator's Guide</hp1> GEC Software Ltd., <BIB ID=WINTCPREF> <hp1>WIN/TCP Reference Manual</hp1> GEC Software Ltd. <BIB ID=WAY> R.Bagnara, University of Pisa, <hp1>WAY User Manual</hp1> (in preparation Sept 89) </BL> <INDEX IX=1>Index </BACKM> </GDOC>