McIDAS Programmer's Manual
Version 2003
[Search Manual] [Table of Contents] [Go to Previous] [Go to Next]
Whether you're creating primary or secondary ADDE servers, they must perform these seven steps:
Steps 1, 2, 3 and 7 are the same for all data types; steps 4, 5 and 6 are different among the data types. All seven steps are described in this section, along with the function calls required to perform them.
This section is organized into these parts:
The McIDAS-X library functions that you will use when creating an ADDE server are listed alphabetically in the table below.
Your server must be able to access McIDAS-X disk files, since most servers are built using disk file utilities. Use the initblok function to initialize the McIDAS-X disk file system so the server can recognize MCPATH and the redirection table, as shown below. Note that the parameter passed into initblok must be a 2-byte integer.
integer*2 init_stat : ok = initblok (init_stat) |
short init_stat; : ok = initblok_ (&init_stat); |
For more information about disk files, see the section titled McIDAS disk files in Chapter 5, Accessing Data. For more information about file redirection and MCPATH, see the section titled McIDAS user applications in Chapter 2, Learning the Basics. |
Each ADDE client request received by the server contains a 160-byte request header, which contains system-level information built for the server.
The table below shows the input components included in the request header. The third column contains the starting word locations if the server is written in Fortran; the fourth column contains the variable names for the C structure, servacct, if the server is written in C.
Request header components | Length, in bytes | Word number in Fortran | servacct structure names in C |
---|---|---|---|
The last 120 characters of the request header is a buffer that may hold the client request string. The request string contains the group and descriptor names, and any selection conditions the server may need to fulfill the client request. If the request string is too long to fit in this buffer, the request string variable will contain a value of zero in bytes 4-7; bytes 0-3 will contain the actual length of the request string, which the server then must read from stdin.
The process for reading the ADDE client request is performed with one of two functions, depending on whether the server reading the request is a primary or secondary server.
Words 41 to 64 are for sending a return packet. The section Ending the transaction in this chapter provides more information.
To read the client request from a primary server, call M0sxGetClientRequest or m0sxgetclientrequest, as shown in the code fragments below.
include 'fileparm.inc' character*(MAXPATHLENGTH) request integer request_block(64) : : ok = m0sxgetclientrequest(request_block, request) |
#include "mcidas.h" : servacct request_block; char *request; int ok; ok = M0sxGetClientRequest (&request_block, &request); |
Upon successful completion, request_block contains the request header information sent to the server, and request contains the request string, including the group and descriptor names and selection conditions specified.
To read the client request from a secondary server, call the function M0InitLocalServer, as shown in the code fragment below.
const char Server[] = {"TESTSERV"}; servacct request_block; char *request; : : ok = M0InitLocalServer (Server, &request_block, &request); |
Upon successful completion, request_block contains the request header information sent to the server, and request contains the request string, including the group and descriptor names and selection conditions specified.
If the dataset requested by the client is stored in a non-standard McIDAS-X format on the server, the primary server starts the secondary server with a call to m0subserv. m0subserv builds an argument list for the secondary server and starts it with a call to execlp. The argument list contains both information from the client request block and the actual client request string. The M0InitLocalServer function extracts values from the secondary server's argument list and puts them in the client request block.
Once the server successfully receives the client's request, it must extract information from the server mapping table, which is a database that provides the server with information needed to fulfill a user request. The server mapping table is manipulated by the DSSERVE command and contains information about the location and format of the data on the server machine. This information is accessed by the server based on the group and descriptor names included in the client request.
The function M0sxdatasetinfo or m0sxdatasetinfo extracts information that the server needs from the server mapping table, including:
The code fragment below demonstrates the use of M0sxdatasetinfo. It assumes that the server administrator entered the following DSSERVE command, which created the ADDE dataset GMS/IR:
Upon successful completion, the output variables will contain the following values:
Variable | Value |
---|---|
After the server reads the client request and extracts the dataset information from the server mapping table, it parses the client request so the data can be located and the request fulfilled.
Since client requests are similar in form to a McIDAS-X command, it is easiest to use the McIDAS-X command line parsing routines to extract information from the request. To use common command line data retrievers, such as Mccmdstr and Mccmdint, you must initialize the command line subsystem. You only need to do this for primary servers. The M0InitLocalServer function automatically performs these steps for secondary servers.
The code fragments below demonstrate how to initialize the command line subsystem in both Fortran and C.
character*256 request integer len_req : c--- request already contains the request string to be parsed call m0cmdput (m0cmdparse (request, len_req)) |
char *request; int len_req; int stat; : /* request already contains the request string to be parsed */ stat = M0cmdput (M0cmdparse (request, &len_req)) ; |
Once the request string is parsed by the command line subsystem, it is your job, as the server developer, to find the data matching the request. The section titled Request syntax and data transmission formats later in this chapter explains the request syntax for each of the McIDAS-X data types.
The method of retrieving data matching the client request will vary from file format to file format.
When determining the location of data files, you should be aware that the server mapping table may not have enough entries available for an individual dataset to fully explain the filing format. If this happens, use a configuration file and store the name of that file in the INFO field of the server mapping table. Then the server can get additional file location information there.
When the request is parsed and the appropriate data is located, it can be sent back to the client. All data transactions are done in pairs (count + data) using the function M0sxsend or m0sxsend. First, a 4-byte value containing the length of the data being sent to the client is transmitted. Then that many bytes of data are transmitted.
To ensure that data sent between the server and the client is in network-byte-order (big-endian), include calls to M0swbyt4 or swbyt4 for all integer values. This function flips 4-byte memory segments on little-endian machines; it has no effect on big-endian machines.
The first value sent from the server to the client is read internally by the client function M0cxreq or m0cxreq before any API-level reading routines are called. For example, when serving image data, this value is the total number of bytes the server will send to completely transmit the data object. Some ADDE clients expect a dummy, nonzero value in this location. If a zero is sent back, M0cxreq or m0cxreq assumes the server was unable to fulfill the request. The complete transmission format for each McIDAS-X data type is described later in this chapter in the section titled Request syntax and data transmission formats.
The code fragment below demonstrates the appropriate way to send data from the server to the client. It assumes the client wants to receive a 4-byte dummy value of one, which will be read by m0cxreq, followed by two 40-byte records. Words 2 through 4 in the record are character values; the remainder of the record contains integer values.
After the data is transmitted to the client, the server ends the transaction by calling M0sxdone or m0sxdone. This function sends a 96-byte trailer, which is filled on the server and sent to the client at the end of the transaction. Its contents are described in the table below.
Trailer description | Length, in bytes | Word number in Fortran | servacct structure names in C |
---|---|---|---|
Before the transaction ends, you must set the return status code and any error messages that may have voided the transaction. The only successful return code is zero, which appears in word 43 of the client request block. If you send a nonzero value to the client, also put an error string in words 44-61 so the client API will print a message telling the user why the request couldn't be fulfilled. If your site uses the ADDE accounting software, also fill word 41 with the total number of bytes transmitted to the client.
The code fragment below shows the calling sequence that a server should include for a request that can't be fulfilled.
Using this example, the message below is printed by the function m0cxreq if the server encounters a syntax error.
COMMAND: Syntax error in the user request -1001 |
[Search Manual] [Table of Contents] [Go to Previous] [Go to Next]