McIDAS Programmer's Manual
Chapter 7 -
Writing ADDE Servers
This chapter describes the procedures that you will use to build data servers for McIDAS-X ADDE applications. You'll learn:
- information about McIDAS-X servers that you should know before you begin writing a server
- the steps for creating a server and the McIDAS-X library functions that you will use
- how to debug your server
- the request syntax and transmission format for each McIDAS-X data type
This chapter is organized into the following sections:
Overview
ADDE (Abstract Data Distribution Environment) is the client/server mechanism for distributing data in McIDAS-X. In ADDE, an application sends a request for data through an API routine to a server. The server is the software running on a machine in a distributed system that stores data and supplies it to the client upon request.
What does a server do?
The server's job is to:
- interpret the data request from the client
- retrieve the requested data from disk
- arrange the data into the proper format for the client
- send the data back to the application
When the application reads the data sent from the server, the physical location of the original data and its stored format are transparent.
How many server categories does McIDAS-X have?
McIDAS-X has two server categories: primary and secondary.
- Primary servers are started directly by the ADDE communications module, mcserv . They read the client request from stdin (standard input).
- Secondary servers are started by primary servers. They don't read the client request from stdin , but rather from the server's argument list.
In short, a user enters a data request based on the ADDE group and descriptor name. mcserv starts the appropriate primary server based on the request type. The primary server extracts information about the requested dataset from the server mapping table, including the stored format of the data. If the stored data format is different from the standard McIDAS-X stored formats, the primary server starts a secondary server to convert the data to the format the client expects.
Getting started
Before writing an ADDE server, you should understand some basic concepts about servers in McIDAS-X. This section describes the following:
Client and server communication
The ADDE design is stream-oriented, so both the client and server can work simultaneously. An ADDE server reads a data request sent from the client via stdin (standard input) and sends data back to the client using stdout (standard output) through a pipe.
Although the size of the data sent from the server may be many megabytes, intermediate data storage on the server or client is not needed. Since the pipe is a finite size, the server will wait to write if the pipe is full. The client will wait for up to two minutes if the pipe is empty. If no activity takes place on the pipe after two minutes, the process stops. This is important for requests that take a long time to fulfill due to extensive searching. An environment variable, ADDETIMEOUT, can be set on the server to change this timeout length.
Rules for transmitting data
The rules below apply to all data transmissions between the server and client.
- All transactions from the server to the client are performed in pairs. A 4-byte value containing the total number of bytes to be sent is transmitted first, followed by the data.
- All numeric values are sent in network-byte-order, or big-endian. All client APIs for ADDE expect data to be transmitted in big-endian format and perform the necessary byte swapping where appropriate. Byte swapping is only performed on integer values; character strings are not flipped.
- If you transmit floating point values via ADDE, send the data as scaled integers. The platforms supported by McIDAS-X are not guaranteed to use the same bit representation for floating point values.
Primary servers
Primary servers, along with the client APIs, define the client selection syntax and the transmission format between the server and the client. The selection syntax and transmission format are different for the various data types in McIDAS-X. The table below lists the current primary servers provided in McIDAS-X.
|
|
|
|
|
|
|
|
mcadel
|
ADEL
|
image
|
adelserv
|
deletes images from a dataset
|
|
|
mcadir
mcadrd
|
ADIR
|
image
|
adirserv
|
retrieves image header information
|
ADIR
|
|
mcaget
mcalin
mcapfx
mcanav
mcacal
mcacrd
|
AGET
|
image
|
agetserv
|
retrieves the image header, navigation, calibration and data; data is returned line by line
|
AGET
|
|
mcaput
mcaout
mcacou
|
APUT
|
image
|
aputserv
|
writes an image object to a dataset
|
|
|
mcaput
|
ATOK
|
image
|
atokserv
|
checks file permissions for writing image objects
|
|
|
mcgdir
mcgfdrd
mcgdrd
|
GDIR
|
grid
|
gdirserv
|
retrieves grid header information
|
GDIR
|
|
mcgget
mcgridf
mcgridc
|
GGET
|
grid
|
ggetserv
|
retrieves the grid header and entire grid
|
GGET
|
|
mcgput
mcgoutf
mcgoutc
|
GPUT
|
grid
|
gputserv
|
writes a grid object to a dataset
|
|
|
mcgput
|
GTOK
|
grid
|
gtokserv
|
checks file permissions for writing grid objects
|
|
|
m0pthdr
m0ptrdhdr
m0pthdrd
|
MDFH
|
point
|
mdfhserv
|
retrieves point file header information
|
|
|
ptcopy command
|
MDHD
|
point
|
mdhdserv
|
retrieves point header information
|
|
|
m0ptget
m0ptrd
|
MDKS
|
point
|
mdksserv
|
retrieves the point header and data
|
KS
|
|
m0navget
M0ReadNavBlock
|
NAVG
|
nav
|
navgserv
|
retrieves satellite navigation
|
|
|
M0obtxget
M0obtxread
|
OBTG
|
text
|
obtgserv
|
retrieves observational weather text
|
OBTG
|
|
M0textget
M0txtread
|
TXTG
|
text
|
txtgserv
|
retrieves an ASCII text file
|
|
|
M0wtxget
M0wtxread
|
WTXG
|
text
|
wtxgserv
|
retrieves textual weather information
|
WTXG
|
The ADDE communications module, mcserv , starts the primary servers based on the server's IP address, which tells mcserv if the request will be fulfilled locally or remotely. If the request is handled locally, mcserv finds the ADDE request type and runs the appropriate server process. The server process reads the body of the client request, acquires the data requested and sends the data back to the client.
If the request is handled remotely, mcserv opens a connection to the remote server and acts as a TCP-to-pipe bridge, sending out the request. On the server machine, inetd receives the connection and creates a child process running the same mcserv module with slightly different command arguments. Like local requests, this version reads the beginning of the client request, determines which server process is needed and runs it. The server processes the request and sends the data requested back to the client.
Secondary servers
In ADDE, the client requesting data doesn't care about the file format of the stored data. It only cares that the data is delivered in a well-known, predefined format. For example, if you have gridded data stored in a flat ASCII file, the McIDAS-X GRDDISP command can contour that data as long as the server delivers the gridded data to the client in the appropriate format. To accomplish this, you need a secondary server.
The secondary server's job is to:
- interpret the client request
- read the data from disk in its native format
- convert the data to the format the client expects
- send the data to the client
Sample data request
The example below shows the steps that a primary and secondary server will use to fulfill a data request. You should assume that the server administrator inserted the two commands below into the server mapping table:
DSSERVE ADD ETA/00 GRID 101 110 TYPE=GRID "00Z ETA Model Run
DSSERVE ADD LOCAL/MODEL FLAT TYPE=GRID "Local Model Grids
|
The first entry created the grid dataset ETA/00, which is stored in the standard McIDAS-X grid format in grid file numbers 101 to 110. The second entry created the grid dataset LOCAL/MODEL. The grids for this dataset aren't stored in the McIDAS-X grid format, but in a format called FLAT. If a user enters a GRDDISP command to display a grid from each of these datasets, the steps taken by the server to fulfill these requests are different.
Using a primary server
If the user enters the GRDDISP command below, the steps that follow are performed once the appropriate machine is identified.
- mcserv starts the primary server ggetserv .
- ggetserv reads the server mapping table entry for the dataset ETA/00.
- Because the grids from ETA/00 are in the standard McIDAS-X format, ggetserv processes the data request and sends the data to the client.
Using a secondary server
If the user enters the command below, the steps that follow are performed.
Type: GRDDISP LOCAL/MODEL
- mcserv starts the primary server ggetserv .
- ggetserv reads the server mapping table entry for the dataset LOCAL/MODEL.
- Because the grids are stored in a non-standard McIDAS-X format called FLAT, ggetserv starts the secondary server flatgget .
- flatgget processes the data request and sends the data to the client.
Building your ADDE server
Whether you're creating primary or secondary ADDE servers, they must perform these seven steps:
- Initialize the McIDAS-X file system to recognize MCPATH and file redirection.
- Read the ADDE client request.
- Read the server mapping table.
- Interpret the client request.
- Retrieve the requested data from disk.
- Send the data to the client.
- End the transaction.
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:
McIDAS library functions
The McIDAS-X library functions that you will use when creating an ADDE server are listed alphabetically in the table below.
|
|
|
|
|
|
initblok
|
initializes the McIDAS-X environment for the server
|
|
M0isrtdataset
|
m0isrtdataset
|
determines if the dataset requested was flagged as a real-time dataset
|
|
M0IsTraceSet
|
m0istraceset
|
given a client request, activates tracing if TRACE=nonzero value
|
|
M0swbyt4
|
swbyt4
|
conditionally flips 4-byte data buffers
|
|
|
swbyt2
|
conditionally flips 2-byte data buffers
|
|
M0sxdatasetinfo
|
m0sxdatasetinfo
|
extracts the server mapping table information
|
|
M0sxdone
|
m0sxdone
|
ends the ADDE transaction
|
|
M0sxGetClientRequest
|
m0sxgetclientrequest
|
reads the request header and request string sent from the client
|
|
M0sxread
|
m0sxread
|
reads data sent from the client to the server
|
|
|
m0sxresolv
|
appends information from the server mapping table to the client request
|
|
M0sxsend
|
m0sxsend
|
sends data from the server to the client
|
|
M0sxSetTraceOff
|
m0sxsettraceoff
|
turns tracing off
|
|
M0sxSetTraceOn
|
m0sxsettraceon
|
turns tracing on
|
|
M0sxtrce
|
m0sxtrce
|
writes tracing information to a trace file
|
|
M0InitLocalServer
|
|
initializes the environment for secondary servers
|
|
Mctrace
|
mctrace
|
writes tracing information to a trace file
|
Initializing the McIDAS-X file system
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.
In Fortran:
integer*2 init_stat
:
ok = initblok (init_stat)
|
In C:
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 .
|
Reading the ADDE client request
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
|
|
|
servacct structure names in C
|
|
server IP address
|
4
|
1
|
server_address
|
|
server port
|
4
|
2
|
server_port
|
|
client IP address
|
4
|
3
|
client_address
|
|
user initials
|
4 (ASCII)
|
4
|
user
|
|
project number
|
4
|
5
|
project
|
|
password
|
12 (ASCII)
|
6 - 8
|
password
|
|
service name
|
4 (ASCII)
|
9
|
transaction
|
|
input data length
|
4
|
10
|
input_length in excess of 160 bytes
|
|
request string
|
120 (ASCII)
|
11 - 40
|
text
|
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.
Using a primary server
To read the client request from a primary server, call M0sxGetClientRequest or m0sxgetclientrequest , as shown in the code fragments below.
In Fortran:
include 'fileparm.inc'
character*(MAXPATHLENGTH) request
integer request_block(64)
:
:
ok = m0sxgetclientrequest(request_block, request)
|
In C:
#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.
Using a secondary server
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.
Reading the server mapping table
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 ADDE group and descriptor names
- the stored data type and its format
- the minimum and maximum file numbers in the dataset
- any additional information needed to fulfill the request
- the dataset comment section
- a flag indicating if the dataset is a real-time dataset
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:
Type: DSSERVE ADD GMS /IR AUST 3 8 TYPE =IMAGE INFO=east_ir.cfg "GMS Infrared Imagery
char *request;
char *group;
char *dataset;
char *type;
char *format;
char *info;
char *comment;
int min_range;
int max_range;
int real_time;
...
...
...
ok = M0sxdatasetinfo (request, &group, &dataset, &type, &format,
&info, &comment, &min_range, &max_range, &real_time);
|
Upon successful completion, the output variables will contain the following values:
|
|
|
|
group
|
GMS
|
|
dataset
|
IR
|
|
type
|
IMAGE
|
|
format
|
AUST
|
|
info
|
east_ir.cfg
|
|
comment
|
GMS Infrared Imagery
|
|
min_range
|
3
|
|
max_range
|
8
|
|
real_time
|
0 (default)
|
Interpreting the client request
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.
In Fortran:
character*256 request
integer len_req
:
c--- request already contains the request string to be parsed
call m0cmdput (m0cmdparse (request, len_req))
|
In C:
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.
Retrieving the requested data from disk
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.
Sending the data to the client
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.
integer n_bytes ! number of bytes to send
integer n_bytes_nbo ! number of bytes in network byte order
integer dum_val
integer buffer(10)
c--- send the value 4 to the client indicating that it is to read an
c--- additional 4 bytes; the additional 4 bytes will contain the
c--- value 1; this pair is read on the client in m0cxreq.
n_bytes = 4
n_bytes_nbo = n_bytes
call swbyt4(n_bytes_nbo, 1)
call m0sxsend (4, n_bytes_nbo)
dum_val = 1
call swbyt4(dum_val, 1)
call m0sxsend (n_bytes, dum_val)
c--- now we will loop 2 times, getting new data and sending it
c--- back to the client; remember that words 2 through 4 are
c--- character strings.
do 10 I = 1 , 2
c--- get the data
ok = datareader (buffer) ! fictitious function
c--- send the record length back
n_bytes = 40
n_bytes_nbo = n_bytes
call swbyt4(n_bytes_nbo, 1)
call m0sxsend (4, n_bytes_nbo)
c--- convert the appropriate locations in the buffer to
c--- network byte order
call swbyt4(buffer(1), 1)
call swbyt4(buffer(5), 6)
c--- send the data back to the client
call m0sxsend (n_bytes, buffer)
10 continue
|
Ending the transaction
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.
|
|
|
|
servacct structure names in C
|
|
total reply length
|
4
|
41
|
reply_length
|
|
cpu used
|
4
|
42
|
cpu
|
|
return status code
|
4
|
43
|
returncode
|
|
error messages
|
72
|
44 - 61
|
errormsg
|
|
date
|
4
|
62
|
date
|
|
start time
|
4
|
63
|
start_time
|
|
end time
|
4
|
64
|
end_time
|
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.
integer request_block(64)
logical syntax_error
:
:
c---there is a syntax error in the client request
if (syntax_error)then
comm_block(43) = -1001
call movcw (request_block(44),'Syntax error in the user
request')
endif
call m0sxdone (request_block)
|
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
|
Debugging servers
Because ADDE servers read from stdin and write to stdout , you can't call the sdest or Mcprintf function to trace the progress of a server for two reasons:
- First, sdest and Mcprintf statements are sent via stdout . If you send debug messages through stdout , they will corrupt the data stream and cause catastrophic errors on the application side.
- Second, since you don't directly call the server, you won't be able to see the output and, thus, can't print the server progress. This is done from a mother task that may not even be running on your machine.
The solution is to dump messages needed for tracing errors to a file. If errors are reported and tracing is activated, the function M0sxtrce or m0sxtrce will write trace messages to a file named trce . If tracing is not activated, M0sxtrce or m0sxtrce does nothing.
The keyword TRACE is appended to each client request. If TRACE=0, which is the default, tracing is not performed. If TRACE=nonzero value, tracing is activated. The function M0IsTraceSet or m0istraceset automatically activates tracing on the server if the value for TRACE in the client request string is a nonzero number. If you write secondary servers, a call to M0IsTraceSet is made within the function M0InitLocalServer . To activate tracing within a server on your own, call M0sxSetTraceOn or m0sxsettraceon . To turn it off, call M0sxSetTraceOff or m0sxsettraceoff .
Since each account has only one trace file, prefix each line of your tracing strings with the name of the server generating that string. When you look through the contents of the trace file, you can easily find the trace information generated by the problem server.
You can also use the Mctrace or mctrace function to automatically append the server name to the trace message and set a flag for each message. The flag restricts tracing to only selected values of the keyword TRACE.
The sample code fragment below is from the server TOMGSERV.
const char Server[] = {"TOMGSERV"};
char *request;
servacct request_block;
char trace_string[500];
short init_stat;
initblok_ (&init_stat);
/* get the client request and set tracing */
ok = M0sxGetClientRequest (&request_block, &request);
ok = M0IsTraceSet (request);
/* print a trace message containing the entire user request */
sprintf (trace_string, "%s: %s", Server, request);
M0sxtrce (trace_string)
;
/* continue processing */
|
If the user enters the following client request:
Type: GMS AUST TIME=12 DAY=1996352 ID=YSSY TRACE=1
Upon completion, the file trace will contain this line:
TOMGSERV: GMS AUST TIME=12 DAY=1996352 ID=YSSY TRACE=1
|
Request syntax and data transmission formats
This section is organized into the following topics:
In ADDE, the client will manipulate data regardless of the format in which it is stored on the server. For this to happen, however, you must follow a specified set of rules for processing data and delivering it to the client. This section describes the client request syntax and data transmission formats for each data type supported in McIDAS-X. The table below provides a summary of the necessary components for each request type, in alphabetical order.
|
|
|
|
|
|
|
|
ADIR
|
image
|
image header information
|
mcadir
|
mcadrd
|
|
|
AGET
|
image
|
image header, navigation, calibration and data; data is returned line by line; comments
|
mcaget
|
mcalin
mcapfx
mcacrd
mcacal
mcanav
|
|
|
GDIR
|
grid
|
grid header information
|
mcgdir
|
mcgfdrd
mcgdrd
|
|
|
GGET
|
grid
|
grid header and entire grid
|
mcgget
|
mcgridf
|
|
|
MDFH
|
point
|
point file header information
|
m0pthdr
|
m0ptrdhdr
|
FORM=FILE
|
|
MDHD
|
point
|
point header information
|
|
|
PTLIST FORM=PARAM
|
|
MDKS
|
point
|
point header and data
|
m0ptget
|
m0ptrd
|
PTLIST
|
|
NAVG
|
nav
|
satellite navigation
|
m0navget
|
m0snlist
m0nvblk
|
|
|
OBTG
|
text
|
observational weather text
|
M0obtxget
|
M0obtxread
|
|
|
TXTG
|
text
|
ASCII text file
|
M0textgt
|
M0txtread
|
|
|
WTXG
|
text
|
textual weather information
|
M0wtxget
|
M0wtxread
|
|
All secondary servers must perform the four basic tasks below to deliver the appropriate data to the client.
- Read the client request based on the syntax described for the data type.
- Verify that the client request adheres to any special rules which apply to that data type.
- Convert the data to the format the client expects.
- Transmit the data to the client in the appropriate format.
Since ADDE client requests are sent as character strings with a format similar to McIDAS-X commands, it is easiest to use the McIDAS-X command line retrieving routines to extract information from the client request. The request syntax description for each data type described in this section uses the McIDAS-X command line notation.
Additionally, remember that transactions of integer values between the client and the server are performed in network-byte-order (big-endian). Unless otherwise noted, assume that all strings sent back to the client are blank padded.
Serving image data
The ADDE server, agetserv , processes a client request and returns a complete image object to the client. An image object includes an image header and the image lines, and may also contain a line prefix for each line, calibration, navigation and comment cards. Due to the volume of data associated with image objects, the server delivers the data portion of the object to the client one line at a time. The McIDAS-X command IMGDISP accesses image objects.
Image object request syntax
The table below lists the client request syntax options for an image object. Note that keywords 1 through 9 are placed in the request block as positional parameters.
|
|
|
|
|
' ' 1
|
group name
|
|
|
' ' 2
|
dataset name
|
|
|
' ' 3
|
position in the dataset
|
relative position in the dataset; negative means Nth most recent
|
|
' ' 4
|
coordinate type and position
|
(E)arth, (I)mage, (A)rea; (C)entered or (U)pper; no default; this field is used with the next two parameters; for example, to return an image centered at latitude 43.5 and longitude 90.0, the client request will contain EC 43.5 90.0
|
|
' ' 5
|
latitude or line number
|
latitude of the Earth (dd:mm:ss) or line number
|
|
' ' 6
|
longitude or element number
|
longitude of the Earth (dd:mm:ss) or element number
|
|
' ' 7
|
image resolution
|
default=1
|
|
' ' 8
|
number of lines to transmit
|
default=480
|
|
' ' 9
|
number of elements to transmit
|
default=640
|
|
VERSION=
|
transmission version number
|
value as of 11/96 is 1
|
|
TIME=btime etime
|
time of day selection range
|
the format is hh:mm:ss (no default)
|
|
DAY=
|
the day that data is valid
|
not a range of days; format must be yyddd or ccyyddd (no default)
|
|
UNITS=
|
calibration type requested
|
not all calibration types are valid for a data type (default=stored units)
|
|
SPAC=
|
number of bytes per data point
|
be careful when reducing data point resolution, if the data can be sent back in lower resolution (default=stored format)
|
|
CAL=
|
set to QTIR to return TIROS in quick calibration
|
|
|
STYPE=VISR
|
sets calibration to UNITS of BRIT and type of VISR
|
converts data type to 1-byte data
|
|
BAND=band
BAND=ALL
|
specific band number to send or ALL bands
|
|
|
LMAG=
|
line magnification factor
|
blow ups are done on the client to conserve transmission bandwidth (default=1); values must be integers; negative numbers mean a blowdown must be performed
|
|
EMAG=
|
element magnification factor
|
blow ups are done on the client to conserve transmission bandwidth (default=1) values must be integers; negative numbers mean a blowdown must be performed
|
|
DOC=
|
if YES, include the line documentation block
|
default=NO
|
|
AUX=
|
if YES, additional calibration information is sent
|
|
|
Server-specific keywords
|
Description
|
|
ID=
|
NEXRAD station ID (NEXRAD server)
|
|
TIME=btime etime C
|
Coverage; accesses data for specified time range (realtime POES server)
|
|
WL=
|
wavelength (AIRS server)
|
|
WN=
|
wavenumber (AIRS server)
|
Special rules for transmitting an image object
You must adhere to the rules below when transmitting an image object. The first five are specific to the client request; the last three are specific to the transmission format sent back to the client.
- If the position in the dataset is greater than zero, the client is expecting an absolute position number within the dataset.
- If the position in the dataset is less than zero or equal to zero, it is a time relative offset, with 0 being the most recent, -1 being the second most recent, etc.
- If the number of elements is 99999, assume the entire image object will be transmitted.
- If STYPE=VISR, then SPAC=1 and UNITS=BRIT. The prefix is not sent back unless DOC=Y.
- If the UNITS requested is BRIT, SPAC=1. If UNITS is TEMP/ALB, SPAC=2. If UNITS is RAD, SPAC=4.
- If the user asks for data in 2-byte format, but it can be sent back as 1-byte, send it as 1-byte and let the client handle the data expansion. This reduces the data volume sent across the network by half.
- If the request is larger than the source image file, pad the return image with zeros. Padding zeros is only required at the top or to the left of the image being transferred. If zeros are also needed to the right or the bottom of the image, they can be sent as zeros, or words 9 or 10 of the directory can be modified to indicate a smaller image than requested is being sent back (see table below). The client interface will then pad to the right and/or to the bottom of the image.
- If the request is larger than the source image file, pad the return image with zeros. If the server has problems fulfilling the request, use the standard error values and messages found in ~mcidas/src/adderror.doc . The range -11000 to -11999 lists error codes specific to image objects. Use enumerated error codes and messages when applicable and create new error codes and messages for error conditions that are unique to your site.
Converting the image object's format
The image object contains the image header and the image lines. It may also contain line prefixes, navigation, calibration and comment cards. Each of these components is created by the server. Their formats are described in Chapter 6 of this manual in the AREAnnnn data file documentation. Below are the common modifications needed for the image header.
|
|
|
|
|
1
|
ADDE dataset relative position number
|
always modified
|
|
6
|
upper-left image line number
|
1) if client does not specify SIZE=ALL
2) if client requests coordinate base transfer
|
|
7
|
upper-left image element number
|
1) if client does not specify SIZE=ALL
2) if client requests coordinate base transfer
|
|
9
|
number of lines in the image
|
1) if client does not specify SIZE=ALL
2) instead of sending lines containing all zeros at the bottom of the image
|
|
10
|
number of elements in the image; must be divisible by 4
|
1) if client does not specify SIZE=ALL
2) instead of sending lines containing all zeros at the bottom of the image
|
|
11
|
number of bytes per band
|
1) if SPAC≠source value
2) if client requests STYPE=VISR
|
|
12
|
line resolution
|
if LMAG≠1
|
|
13
|
element resolution
|
if EMAG≠1
|
|
14
|
number of spectral bands
|
if BAND≠ALL
|
|
15
|
length of line prefix
|
1) if BAND=ALL is not specified
2) if SIZE=ALL is not specified
3) if DOC=YES is specified
4) if STYPE=VISR
|
|
19
|
spectral band map
|
if BAND=ALL is not specified
|
|
34
|
byte offset to the start of the data block
|
always modified (256+navlength+callength)
|
|
35
|
byte offset to the start of the navigation block
|
always modified (usually 256)
|
|
36
|
validity code
|
1) if request contains DOC=NO, set to 0
2) if SIZE=ALL is not specified, set to 0
3) if DOC=YES, must be set
|
|
49
|
length of the prefix documentation
|
1) if DOC=NO is specified, set to 0
2) if SIZE=ALL is not specified, set to 0
|
|
50
|
length of prefix calibration
|
if STYPE=VISR, set to 0
|
|
51
|
length of prefix band length
|
1) if STYPE=VISR, set to 0
2) if BAND≠ ALL
|
|
52
|
source type; satellite-specific (ASCII)
|
if STYPE=VISR, set to VISR
|
|
53
|
calibration type; satellite-specific (ASCII)
|
if STYPE=VISR, set to BRIT
|
|
54
|
sampling/averaging flag
|
set to 1 if blow down is performed by sampling
|
|
57
|
source's original satellite type (ASCII)
|
if STYPE=VISR, set to original satellite type
|
|
58
|
units of values returned
|
if AUX=YES and UNIT is specified
|
|
59
|
scaling of values returned
|
1) if UNIT is specified
2) if AUX=YES, set to 1
|
|
63
|
byte offset to the start of the calibration block
|
if calibration is sent
(usually 256+navlength)
|
|
64
|
number of comment cards
|
if comment cards exist
|
Transmitting the image object to the client
Once the data is formatted correctly, the image object can be sent to the client. Because the transmission protocol is count+data, the server will send the following information to the client:
- 4-byte value containing the total number of bytes to be sent
- 256-byte image header
- navigation (variable length)
- calibration, if requested (variable length)
- image data lines, one at a time:
line prefix (if requested)
line of data
- 80-byte comment cards
The sample code below shows you how to set up your server to transmit image objects.
integer image_header(64)
integer nav_block(1024)
integer cal_block(1024)
integer line(2000)
integer prefix(100)
integer comment(20)
integer total_bytes
integer nav_size
integer cal_size
integer pre_size
integer n_comments
integer n_lines
integer n_elements
integer data_size
integer n_send
integer n_send_nbo
c--- assume the image_header, nav_block, cal_block have already been loaded
n_lines = image_header(9)
n_elements = image_header(10)
data_size = image_header(11)
nav_size = image_header(63) - image_header(35)
cal_size = image_header(34) - image_header(63)
pre_size = image_header(15)
n_comments = image_header(64)
total_bytes= (n_lines * n_elements * data_size) +
& (n_rows * pre_size) +
& (n_comments * 80)
& (nav_size + cal_size)
c--- send the total number of bytes in the image object
n_send_nbo = total_bytes
call swbyt4(n_send_nbo, 1)
call m0sxsend(4, n_send_nbo)
c--- send the image header; assume imageheadernbo converts the header
c--- to network-byte-order
call imageheadernbo(image_header)
call m0sxsend(256, image_header)
c--- send the nav block; assume navnbo converts the nav block to
c--- network-byte order
if (nav_size .gt. 0)then
call navnbo(nav_block)
call m0sxsend(nav_size, nav_block)
endif
c--- send the cal block; assume calnbo converts the cal block to
c--- network-byte order
if (cal_size .gt. 0)then
call calnbo(cal_block)
call m0sxsend(cal_size, cal_block)
endif
c--- now we will send the image data lines, one line at a time;
c--- assume getoneline retrieves one line of data as packed bytes
do 10 i = 1 , n_lines
ok = getoneline(i, line, prefix)
if (pre_size .gt. 0)then
call m0sxsend(pre_size, prefix)
endif
call m0sxsend(n_elements, line)
10 continue
c--- send the comments; assume readcomment reads one comment card
if (n_comment .gt. 0)then
do 20 i = 1 , n_comments
call readcomment(i, comment)
call m0sxsend(80, comment)
20 continue
endif
Serving image directory data
The ADDE server, adirserv , processes a client request and returns image directories and comment cards to the client. The McIDAS-X command IMGLIST accesses image directories.
Image directory request syntax
The table below lists the client request syntax options for image directories. Note that keywords 1 through 4 are placed in the request block as positional parameters
|
|
|
|
|
' ' 1
|
group name
|
|
|
' ' 2
|
descriptor name
|
|
|
' ' 3
|
beginning file position number
|
can be the value ALL; positive numbers represent absolute locations; negative numbers are time-relative offsets (no default)
|
|
' ' 4
|
ending file position number
|
default=beginning file number
|
|
AUX=
|
when YES, sends the center lat/lon, latitude resolution in km, longitude resolution in km, and valid calibration types as comment cards
|
default=NO
|
|
BAND=
|
spectral band, if the image has multiple bands
|
|
|
DAY=bday eday
|
day range to search
|
ccyyddd or yyddd format (no default)
|
|
ID=
|
NEXRAD station ID
|
NEXRAD server only
|
|
SS=ss1 ss2
|
satellite sensor number
|
no default
|
|
TIME=btime etime
|
time range to search
|
hh:mm:ss format (no default)
|
|
WL=
|
wavelength
|
AIRS server only
|
|
WN=
|
wavenumber
|
AIRS server only
|
Special rules for transmitting the image directory
If the server has problems fulfilling the request, use the following standard error values and messages found in ~mcidas/src/adderror.doc . The range -12000 to -12999 lists error codes specific to image directories. Use enumerated error codes and messages when applicable and create new error codes and messages for error conditions that are unique to your site.
Converting the image directory's format
The image directory sent to the client is a 65-word directory. Word 1 contains the AREA number from the server. Words 2 through 65 are the same as words 1 through 64 in the image directory described in the AREAnnnn data file documentation in Chapter 6.
Transmitting image directory objects to the client
Once the data is formatted correctly, the image directory can be transmitted. Because the transmission protocol is count+data, the server will send the following information to the client:
- 4-byte value containing the total number of bytes of data for the directory being sent (260 + (80 * NumberOfComments ))
- 4-byte value containing the file number for this image directory
- the 256-byte image directory
- the comment cards, blank padded to 80 characters
The information is repeated until there are no new image directories to send. The sample code on the facing page shows you how to set up your server to transmit an image directory.
integer image_header(64)
integer n_comments
integer comment(20)
integer n_send_nbo
integer total_bytes
c--- loop through all image objects matching selection conditions
c--- assume readimagedirectory reads a 64-word image in area format
do 10 i = 1 , n_files
ok = readimagedirectory (i, image_header)
n_comments = image_header(64)
c--- calculate the number of bytes to be sent for this directory
total_bytes = 260 + (n_comments * 80)
n_send_nbo = total_bytes
call swbyt4(n_send_nbo, 1)
call m0sxsend(4, total_bytes)
c--- send the file number
file = i
call swbyt4(file, 1)
call m0sxsend(4, file)
c--- send the image directory; assume imageheadernbo converts
c--- the header to network-byte-order
call imageheadernbo(image_header)
call m0sxsend(256, image_header)
c--- send comment cards backlashes readcomment reads once
c--- comment card
if (n_comments .gt. 0)then
do 20 j = 1 , n_comments
call readcomment(i,j,comment)
call m0sxsend(80,comment)
20 continue
endif
10 continue
|
Serving grid data
The ADDE server, ggetserv , processes a client request and returns complete grid objects to the client. The grid object contains the grid header and the data. Unlike the image server, which can only send one image object to the client, grid requests may include as many grid objects as desired. The McIDAS-X GRDDISP command accesses grid objects.
Grid object request syntax
The table below lists the client request syntax options for grid objects. The table below lists the client request syntax options for image directories. Note that keywords 1 through 3 are placed in the request block as positional parameters
|
|
|
|
|
' ' 1
|
group name
|
|
|
' ' 2
|
descriptor name
|
|
|
' ' 3
|
maximum number of bytes that can be stored in the destination grid buffer on the client
|
|
|
DAY=day1 .. dayn
|
list of model-run days
|
ccyyddd format (no default)
|
|
DERIVE=
|
derived parameters
|
|
|
DRANGE=bday eday dinc
|
range of model-run Julian days
|
ccyyddd format
|
|
FDAY=
|
model-forecast valid day
|
ccyyddd format
|
|
FRANGE=fhr1 .. fhrn
|
range of model-forecast hours
|
|
|
FTIME=
|
model-forecast valid time
|
hhmmss format
|
|
GRIB=sgrib egrib
|
range of grib numbers to get from a McIDAS-X grid file
|
|
|
GRID=sgrid egrid
|
range of grid numbers to get from a McIDAS-X grid file
|
|
|
LEV=lev1 .. levn
|
list of data levels to retrieve
|
can be a number, SFC, MSL or TRO
|
|
NUM=
|
number of grids to retrieve
|
can be a number or ALL
|
|
PARM=p1 .. pn
|
list of parameters to retrieve
|
|
|
PARSE=select1 .. selectn
|
list of grid selection conditions for multiple grid parsing
|
format is a subset of other selection conditions specified; each selection is isolated by single quotes
|
|
PNUM=
|
number of parseable grids specified in the selection
|
|
|
POS=
|
relative file position number in the dataset
|
|
|
PRO=
|
model-projection type
|
|
|
SRC=src1 .. srcn
|
list of model grid sources
|
|
|
TIME=time1 .. timen
|
model run times to retrieve
|
hhmmss format
|
|
TRANGE=btime etime tinc
|
range of model-run times
|
hhmmss format for time
|
|
VERSION=
|
grid transmission version
|
value is A as of 11/96
|
|
VT=vt1 .. vt2
|
valid hour offsets
|
hhmmss format
|
Special rules for transmitting a grid object
You must adhere to the rules below when transmitting a grid object. The first two are specific to the client request. The last three are specific to the transmission format sent back to the client.
- If PAR=STREAML, WINDB or WINDV, you must send the
u- and v- component wind.
- If DERIVE=TTIN, VOR, DVG, SPD, DIR, ABV, DSH, DST, TD, KINX, COR, BETA or ADV, you must calculate the appropriate grid before sending the results back to the client.
- If portions of the grid contain missing values, fill those locations with the value 0x80808080.
- Data must be delivered to the client in column-major format with the first data point in the upper-left corner of the grid.
- If the server has problems fulfilling the request, use the standard error values and messages found in ~mcidas/src/adderror.doc . The range -2100 to -21999 lists error codes specific to grid objects. Use enumerated error codes and messages when applicable and create new error codes and messages for error conditions that are unique to your site.
Converting the grid object's format
The grid object contains a grid header and gridded data. The grid header format is described in Chapter 6 of this manual in the GRIDnnnn data file documentation.
Transmitting grid objects to the client
As the server sends data to the client, TCP may timeout during periods of no data transmission. To avoid timeouts, the server can send a heartbeat value (11223344) periodically to the client to keep the connection active. The heartbeat values are sent at the beginning of the transmission only. Once all the data is found and formatted, the grid object can be sent to the client.
The server sends the client the following information:
- Multiple cycles of size 4, each followed by a heart beat; the cycles of size 4 and the heartbeat are optional
- 4-byte value containing the total number of bytes in the grid objects; the number of bytes transmitted is calculated as follows: (numgrids *260 + (total number of data points * 4)) + 8;
the data size must be sent twice
- 4-byte value containing the number of grids to send to the client
- 256-byte grid header
- grid data object, which has a variable length, (number of rows *number of coulmns )*4
- 4-byte value containing zero
The grid header, grid object, and 4-byte value containing zero are repeated until all the grid objects are sent.
The sample code below shows you how to set up your server to transmit a grid object.
include 'gridparm.inc'
integer grid_header(64)
integer grid(MAXGRIDPT)
integer total_bytes
integer grid_size
c--- read the grid; assume readgrid reads a grid header's grid
c--- into McIDAS format
ok = readgrid(grid_header, grid)
grid_size = grid_header(1)
c--- send the total number of bytes
total_bytes = 256 + (grid_size * 4) + 8
temp_int = total_bytes
call swbyt4(temp_int, 1)
call m0sxsend(4, temp_int)
call M0sxsend (4 temp_int)
c--- send the number of grids
temp_int = 1
call swbyt4(temp_int, 1)
call m0sxsend(4, temp_int)
c--- send the grid header; assume gridheadernbo switches integer
c--- values in the header to network byte order
call gridheadernbo(grid_header)
call m0sxsend(256, grid_header)
c--- send the data
call swbyt4(grid_data,grid_size)
call m0sxsend(grid_size*4, grid)
c---send 0 separate
temp = 0
call swbyt4(temp_int, 1)
call M0sxsend (4,temp_int)
|
Serving grid directories
The ADDE server, gdirserv , processes a client request and returns grid directories to the client. The grid directory contains information about the contents of the grid. The McIDAS-X command GRDLIST is one that accesses grid directories.
Grid directory request syntax
The table below lists the client request syntax options for grid directories. Keywords 1 and 2 are placed in the request block as positional parameters.
|
|
|
|
|
' ' 1
|
group name
|
|
|
' ' 2
|
descriptor name
|
|
|
DAY=day1 .. dayn
|
list of model-run days
|
ccyyddd format
|
|
DERIVE=
|
derived parameters
|
|
|
DRANGE=bday eday dinc
|
range of model-run Julian days
|
ccyyddd format
|
|
FDAY=
|
model forecast valid day
|
ccyyddd format
|
|
FRANGE=fhr1 .. fhrn
|
range of model-forecast hours
|
|
|
FTIME=
|
model-forecast valid time
|
hhmmss format
|
|
GRIB=sgrib egrib
|
range of grib numbers to get from a McIDAS-X grid file
|
|
|
GRID=sgrid egrid
|
range of grid numbers to get from a McIDAS-X grid file
|
|
|
LEV=lev1 .. levn
|
list of data levels to retrieve
|
can be a number, SFC, MSL or TRO
|
|
NUM=
|
number of grids to retrieve
|
can be a number or ALL
|
|
OUT=
|
output format
|
default=ALL
|
|
PARM=p1 .. pn
|
list of parameters to retrieve
|
|
|
PARSE=select1 .. selectn
|
list of grid selection conditions for multiple grid parsing
|
format will be a subset of other selection conditions specified; each selection is isolated by single quotes
|
|
PNUM=
|
number of parseable grids specified in the selection
|
|
|
POS=
|
relative file position number in the dataset
|
|
|
PRO=
|
model-projection type to retrieve
|
|
|
SRC=src1 .. srcn
|
list of model grid sources
|
|
|
TIME=time1 .. timen
|
list of model-run times to retrieve
|
hhmmss format
|
|
TRANGE=btime etime tinc
|
range of model-run times
|
hhmmss format for time
|
|
VERSION=
|
ADDE grid transmission version
|
value is 1 as of 11/96
|
|
VT=vt1 .. vt2
|
list of valid hour offsets
|
hhmmss format
|
Special rules for transmitting the grid directory
If PAR=STREAML, WINDB or WINDV, you must send the u- and v- component wind.
If DERIVE=TTIN, VOR, DVG, SPD, DIR, ABV, DSH, DST, TD, KINX, COR, BETA or ADV, you must calculate the appropriate grid before sending the results back to the client.
Converting the grid directory's format
The grid directory's format is defined in Chapter 6 of this manual in the GRIDnnnn data file documentation.
Transmitting the grid directory to the client
As the server sends data to the client, TCP may timeout during periods of no data transmission. To avoid timeouts, the server can send a heartbeat value (11223344) to the client periodically to maintain an active connection. The heartbeat values are sent at the beginning of the transmission only. Once all the data is found and formatted, the grid directory can be sent to the client.
The server sends the client the following information. Except the first item, all the items listed below are repeated for each grid file. Within each grid file, the grid file header and the two 4-byte values are repeated for each grid in the grid file.
- 4-byte value containing the total number of bytes to transmit
- 4-byte value of zero indicating a new file header is being sent; this information is repeated for each new file header to transfer and is sent after all grids from the previous file are transmitted
- 256-byte grid file header; this information is repeated for each new grid file header to transmit and is sent after the grids from the previous file are transmitted
- 4-byte value of zero indicating a new grid directory is being sent; this information is repeated before each grid directory in the file is sent
- 256-byte grid header; this information is repeated for each grid in the file being sent
- 4-byte value of 1 indicating no more grid directories in the file
A 4-byte value of 2, indicating no more grid files, is sent to end the transaction.
If the server has problems fulfilling the request, use the standard error values/messages found in ~mcidas/src/adderror.doc . The range -22001 to
-22999 lists error codes specific to grid directories. Use enumerated error codes and messages when applicable and create new error codes and messages for error conditions that are unique to your site.
The sample code below shows you how to set up your server to transmit a grid directory.
integer grid_header(64)
integer grid_file_header(64)
c--- send total byte count
temp_int = (260* n_grids) + (n_files * 260)
call m0sxsend(4, temp_int)
c--- loop through the grid file headers
do 10 file = 1 , n_files
c--- read the grid file header; assume readfileheader reads
c--- a grid file header in McIDAS grid file format
call readfileheader(file, grid_file_header, n_grids)
c--- send the value 0 indicating that a grid file was found
temp_int = 0
call m0sxsend (4, temp_int)
c--- send the grid file header; assume gridfileheadernbo
c--- switches integer words to network byte order
nbytes = 256
call gridfileheadernbo(grid_file_header)
call m0sxsend(nbytes, grid_file_header)
do 20 i = 1 , n_grids
c--- read the grid header; assume readgridheader reads a
c--- grid in McIDAS grid format
call readgridheader(file,i,grid_header)
c--- send the value 0 indicating that a grid file was found
temp_int = 0
call m0sxsend (4, temp_int)
c--- send the grid header; assume gridheadernbo switches
c--- integer words to network byte order
nbytes = 256
call gridheadernbo (grid_header)
call m0sxsend(nbytes, grid_header)
20 continue
c--- no more data from this grid file
temp_int = 1
call swbyt4(temp_int, 1)
call m0sxsend (4, temp_int)
10 continue
c--- no more data
temp_int = 2
call swbyt4(temp_int, 1)
call m0sxsend (4, temp_int)
|
Serving point data
The ADDE server, mdksserv , processes a request and returns point data to the client. In addition to the data values, the server also sends information about the units, scaling factor, and name of each parameter returned to the client. The McIDAS-X command PTLIST accesses point data.
Point data request syntax
The table below lists the client request syntax options for point data. The table below lists the client request syntax options for image directories. Note that keywords 1 through 2 are placed in the request block as positional parameters
|
|
|
|
|
' ' 1
|
group name
|
|
|
' ' 2
|
descriptor name
|
|
|
MAX=
|
maximum number of matches to find given the selection conditions
|
|
|
POS=
|
file position number in a dataset
|
|
|
SELECT=
|
data selection clause
|
see comments below
|
|
TRACE=
|
trace file activation
|
set to 1 to activate tracing
|
|
VERSION=
|
transmission version number
|
value is 1 as of 11/96
|
Special rules for transmitting point data
The client can request point data either by specifying no specific parameter names, which sends all the parameters to the client, or by specifying only the parameter names of interest. Because the user may ask for an unlimited number of individual parameters, the parameter list is sent after the client request string. Thus, a server must make additional calls to M0sxread to get the list of 4-byte, blank-padded parameter names. You can also call the McExtractPointRequest function to extract the client request and put it in the C structure PTREQUEST.
The SELECT clause contains the entire data selection clause format. You can use as many selection clauses as needed for each request. The selection clause format is described in the section titled Reading point objects: Defining selection conditions in Chapter 5, Accessing Data.
Transmitting point data to the client
When the point data is formatted correctly, it can be sent to the client. The server sends the following information:
- 4-byte value containing the number of bytes of parameter names
to be sent
- character string of NULL-separated parameter names
- 4-byte value containing the number of unit-string bytes to be sent
- character string of NULL-separated units
- 4-byte value containing the number of bytes of scaling factors
to be sent
- array of integer scaling factors for each parameter
- 4-byte value containing the number of bytes of data to be sent
- n bytes of data
The last two pieces of information are repeated until there is no more data to be transmitted. Then the 4-byte value containing the number of bytes of data to be sent will be zero.
If the server has problems fulfilling the request, use the standard error values and messages found in ~mcidas/src/adderror.doc . The range
-31000 to -31999 lists error codes specific to point data. Use enumerated error codes and messages when applicable and create new error codes and messages for error conditions that are unique to your site.
The sample below shows how to set up your server to transmit point data.
parameter (N_KEYS = 4)
integer buffer(N_KEYS)
character*256 keys
character*256 keys
integer scales(N_KEYS)
integer length
character*1 NULL
data NULL=/'0'/
integer temp
c--- send four parameters to the client: station ID, temperature
c--- in Celsius, dew point in Kelvin and wind direction
keys='ID'//NULL//'T'//NULL//'TD'//NULL//'DIR'
units='CHAR'//NULL//'C'//NULL//'K'//NULL//'DEG'
scales(1) = 0
scales(2) = 2
scales(3) = 2
scales(4) = 0
c--- send the key names
length = lentrim(keys)
temp=length
call swbyt4(length, 1)
call m0sxsend(4, length)
call m0sxsend(temp * 4, keys)
c--- send the units
length = lentrim(units)
temp=length
call m0sxsend(4, length)
call m0sxsend(temp * 4, units)
c--- send the scalings
call swbyt4(n_vals, 1)
call m0sxsend(4, n_vals)
call m0sxsend(N_KEYS, scales)
10 continue
c--- read the new data; assume readnewdata reads a record of
c--- data values
ok = readnewdata(buffer)
if (ok .eq. 0)then
c--- flip the temp, dewpt and direction
call swbyt4(buffer(2), 3)
call m0sxsend(4, n_vals)
call m0sxsend(N_KEYS * 4, buffer)
goto 10
endif
|
Serving weather text data
The ADDE server, wtxgserv , processes a client request and sends back the text header containing information about the data and the actual weather text data. The McIDAS-X command WXTLIST is one command that accesses weather text data.
This server is delivered with the McIDAS-XCD package.
Weather text request syntax
The table below lists the client request syntax options for weather text data.
|
|
|
|
|
APRO=
|
AFOS/AWIPS product headers to match
|
three characters; don't use APRO with the WMO keyword
|
|
ASTN=
|
AFOS/AWIPS stations to match
|
two or three characters
|
|
DAY=
|
most recent day to begin the search
|
ccyyddd format (default=current day)
|
|
DTIME=
|
maximum number of hours back in time to search
|
no default
|
|
MATCH=
|
list of character match strings to find from the text
|
|
|
NUM=
|
number of matches to find
|
default=1
|
|
PROD=
|
predefined product name
|
|
|
SOURCE=
|
circuit source
|
default=ALL
|
|
WMO=
|
WMO product headers to match
|
at least two characters; wildcard characters are allowed; don't use WMO with the APRO keyword
|
|
WSTN=
|
WMO stations to match
|
four characters
|
Special rules for transmitting weather text
If the day specified does not equal the current day, the search begins from the end of the day instead of the current time.
Text data is sent to the client as a blank-padded buffer.
The valid standard error values and messages for weather text are located in the range -45000 to -46999. See the wtxgserv source code for error message descriptions.
Converting the text header's format
The information in the table below must be included with each text header sent to the client.
|
|
|
|
|
0 - 3
|
circuit source
|
blank-padded character string
|
|
4 - 7
|
number of bytes in the data section
|
|
|
8 - 11
|
file address where the data is located
|
usually not important to the client
|
|
12 - 15
|
time the data was ingested
|
hhmmss format
|
|
16 - 19
|
four-character WMO header
|
product code and country code
|
|
20 - 23
|
WMO product number
|
integer value
|
|
24 - 27
|
WMO station origin
|
four-character ICAO ID
|
|
28 - 31
|
AFOS product header
|
three characters
|
|
32 - 35
|
AFOS product location
|
two or three characters
|
|
36 - 39
|
AFOS product issuing station
|
three characters
|
|
40 - 43
|
Julian day of the data
|
ccyyddd format
|
|
44 - 47
|
number of bytes per line
|
usually 80
|
|
60 - 63
|
FAA catalog number
|
|
Transmitting weather text data to the client
Once all the data is found and formatted, the weather text can be sent to the client. Because TCP may timeout during periods of no data transmission, a heartbeat value (11223344) can be sent to the client periodically client maintain an active connection.
The server sends the client the following information:
- 4-byte value containing the length of the client request string; this lets users know how their request was expanded when the PROD keyword is specified
- the expanded client request string
- heartbeat value if needed
- 4-byte value containing the total number of bytes of data for this text block, including the 64-byte header and the text
- 64-byte text header
- n bytes of 80-character text, blank padded
The last three pieces of information are repeated until no more data is found.
The sample code below shows you how to set up your server to transmit weather text data.
char *actual_request;
int text_header[16];
char *text;
int req_length;
int temp_int;
/* send back the client request */
req_length = strlen (actual_request);
temp_int = req_length;
M0swbyt4 (&temp_int, 1);
M0sxsend (4, &temp_int);
length = 1;
while (length > 0)
{
int total_bytes;
/* read the length of the next text block */
length = ReadNewTextBlock (text_header, &text);
if (length > 0)
{
total_bytes = sizeof (text_header) + length;
/* send the total data block length */
M0swbyt4 (&total_bytes, 1);
M0sxsend (4, &total_bytes);
/* send the text header */
M0sxsend (sizeof (text_header), text_header);
/* send the text */
M0sxsend (length, text);
free (text);
}
else
{
temp_int=length;
M0swbyt4 (&temp_int,1);
M0sxsend (4, &temp_int);
}
}
|
Serving observational weather-text data
The ADDE server, obtgserv , processes a client request and returns the text header containing information about the retrieved data, along with the observational weather-text data. The McIDAS-X command OBSRPT is one that accesses observational weather-text data.
This server is delivered with the McIDAS-XCD package.
Observational weather-text request syntax
The table below lists the client request syntax options for observational weather-text data.
|
|
|
|
|
CO=co1 .. con
|
list of countries
|
2- character country IDs are read from COUNTRY.DAT, which is provided with McIDAS-XCD
|
|
ID=id1 .. idn
|
list of stations
|
|
|
IDREQ=
|
ID request type
|
must be set to LIST if CO, REG, or ID is specified; if a LATLON option is added to this server, specify GEO
|
|
NEWEST=day hour
|
most recent observation time to allow in the request
|
default=most recent observation filed
|
|
NHOURS=
|
maximum number of hours back in time to search from the value in NEWEST
|
no default
|
|
NPERIOD=
|
number of time periods to list
|
varies among data types
|
|
NUM=
|
number of matches to find for each station
|
default=1
|
|
OLDEST=day hour
|
oldest observation time to allow in the request
|
|
|
REG=reg1 .. regn
|
list of station regions
|
the regions list is stored in GROUPS.DAT, which contains the stations for a particular state/province
|
|
TYPE=
|
numeric value for the type of observation
|
varies among data types
|
Special rules for transmitting observational weather text
Don't specify both NUM and NPERIOD, or NPERIOD and NHOURS in the same request. If you specify NHOURS, you must specify NEWEST.
The valid standard error values and messages for observational weather text are located in the range -48000 to -48999. See the obgtserv source code for error message descriptions.
Converting the text header's format
The information in the table below must be included with each text header sent to the client.
|
|
|
|
|
0 - 3
|
version number
|
currently zero
|
|
4 - 7
|
observation type number
|
varies among data types
|
|
8 - 11
|
active observation flag
|
0=inactive, 1=active
|
|
12 - 15
|
starting observation day
|
ccyyddd format
|
|
16 - 19
|
starting observation time
|
hhmmss format
|
|
20 - 23
|
starting observation hour
|
hhmmss format
|
|
24 - 27
|
ending observation day
|
ccyyddd format
|
|
28 - 31
|
ending observation time
|
hhmmss format
|
|
32 - 35
|
ending observation hour
|
hhmmss format
|
|
36 - 39
|
ID type flag
|
1 if ICAO ID
|
|
40 - 47
|
station ID
|
ccyyddd format
|
|
48 - 51
|
number of bytes of data
|
|
|
52 - 55
|
number of lines of data
|
|
|
56 - 95
|
reserved for future use
|
|
Transmitting observational weather-text data
to the client
Once the data is formatted, the text data can be sent to the client. The server sends the client the following information:
- 4-byte value containing the length of the text header, which is currently 96; when all the data is sent, this value is reset to zero
- 96-byte text header
- 4-byte value containing the number of bytes of text to be sent
- n bytes of text; 80 characters per line, blank padded
This information should be repeated until no more data is found.
The sample code below shows you how to set up your server to transmit observational weather text data to the client.
integer header(24)
integer n_bytes
integer n_bytes_nbo
character*80 line(1000)
100 continue
ok = readnewdata(header, line)
if (ok .eq. 0)then
n_bytes = 96
n_bytes_nbo = n_bytes
call swbyt4(nbyte_nbo, 1)
call m0sxsend(4, n_bytes_nbo)
call m0sxsend(n_bytes, header)
n_bytes = header(13)
n_bytes_nbo = n_bytes
call swbyt4(n_bytes_nbo, 1)
call m0sxsend(4, n_bytes_nbo)
call m0sxsend(n_bytes, line)
goto 100
else
n_bytes = 4
n_bytes_nbo = n_bytes
call swbyt4(n_bytes_nbo, 1)
call m0sxsend(4, n_bytes_nbo)
call m0sxsend(4,0)
endif
|
Appendices
The Programmer's Manual contains the following appendices: