|
9.1. Overview
9.2. C-Language Interface
9.3. Cobol Interface Parameters
9.4. Cobol Interface Functions
9.1. Overview
This chapter serves as reference to the software developer wanting to utilize the
communication services of UCM.
Section 9.2 shows some examples on how to use the C-Language Interface.
9.2. C-Language Interface
In this section three different server models are shown:
- Standard Server
- Self-Contained Server
- Inetd Server
All of these servers do the same processing, they just write back the messages
received. The purpose of this section is to show how to implement and configure UCM
servers, but not application dependent message processing.
To test all of these examples, a simple C or Visual Basic program can be made:
C Client
| /* UCM Client /
ucmtest.c */ #include "ucm.h"
main(argc, argv)
int argc;
char *argv[];
{
int len;
T_SOCKET sock;
T_UCM_MSGID msgId;
T_UCM_MSG msg;
ucmProgName = "UcmTest";
/* for UCM error messages */
UcmInit();
sock = UcmConnect("128.41.1.1", "7999");
if (sock < 0)
{
fprintf(stderr, "UcmConnect
failed, ucmErrno=%d\n", ucmErrno);
return 1;
}
UcmSendf(sock, "Test", "Hello World!");
if ((len = UcmRecv(sock, msgId, msg, -1, UF_NOFLAGS)) > 0)
printf("From server:
%s\n", msg);
UcmClose(sock);
UcmTerm();
return 0;
} |
Visual Basic Client
Create a project and use the Project | Components... dialog to add the UCM
Active-X Control, Ucm.ocx, located in your Windows system directory, to the
new project.
On Form1 (the main form) place two label controls, two text controls, two button
controls, and an UCM control. Your form should now lock like this:

Set the properties of the new controls as follows:
| Property |
Value |
| Form1.Caption |
UCM Test |
| Label1.Caption |
Output: |
| Label2.Caption |
Input: |
| Text1.Text |
<blank> |
| Text2.Text |
<blank> |
| Command1.Caption |
&Send |
| Command2.Caption |
E&xit |
| Ucm1.AdrMode |
ucmTCP |
| Ucm1.Host |
128.41.1.1 / use correct IP
address of your UCM server system |
| Ucm1.Port |
7999 |
| Ucm1.InputID |
Test |
| Ucm1.OutputID |
Test |
Now your form locks like:

To finish the test program, you have to add event logic:
Command1_Click()
Ucm1.OutputMsg = Text1
Command2_Click()
Unload Me
Form1_Unload(Cancel as Integer)
Ucm1.OutputMsg = "Exit"
Ucm1_DataInput()
Text2 = Ucm1.InputMsg
As a final step, use File | Make EXE File... to create the ucmtest.exe
program. You have just created an UCM client application in less than five minutes!
Configuration is easy as well. Throughout this section we use TCP/IP service ID 7999.
If this number is already in use, select any number greater than 5000. It is however
important, that the same ID is used on both, the server and the client systems.
| Important note: In TCP/IP programming a communication link between a server and a client
is established by the use of a entity called socket, introduced by UCB
University of California at Berkley, also referred to by BSD sockets. A socket is defined
by the IP address of the two participating systems and a so called port number. Port
numbers often have a symbolic service name assigned in a control file named services,
but internally the number is used as is. Many well known port numbers (reserved
services) are defined in the rage from 1 to 1023, but
room should be kept for extension. By convention, user port numbers should have values
> 5000 assigned. Unitec software uses port numbers in
the rage 6800 to 6999, e.g. for a future version of the
license manager the port 6800 has been reserved and the CSS
spooler uses port 6801. To avoid conflicts with standard TCP/IP and
Unitec ports, you should use numbers in the range 5001 to 6799
or >= 7000. |
Your new UCM client application is now ready to run. But wait, before the test
run starts, the server program has to be developed on the host.
A) Standard Server
| /* Standard UCM Server */ #include "ucm.h"
static T_SOCKET sock;
static T_UCM_MSGID msgId;
static T_UCM_MSG msg;
main(argc, argv)
int argc;
char *argv[];
{
int len;
if (argc < 2 || (sock = atoi(argv[1])
< 1))
{
fprintf(stderr, "illegal socket
argument\n");
return 1;
}
ucmProgName = argv[0]; /* for UCM error messages */
UcmInit();
if (UcmOpen(sock))
{
fprintf(stderr, "UcmOpen failed,
ucmErrno=%d\n", ucmErrno);
return 1;
}
while ((len = UcmRecv(sock, msgId, msg, -1, UF_NOFLAGS)) > 0)
{
/* process incoming message */
if (strcmp(msg, "Exit") == 0)
break;
UcmSendf(sock, msgId, "Got: %s",
msg);
}
UcmClose(sock);
UcmTerm();
return 0;
} |
Compile with: cc -o test1 test1.c libucm.a
Start the new server manually with:
UcmServer -s 7999 -e test1
Now you can switch to Windows and run ucmtest.exe. Enter Hello
World! in the Input box and push the Send button. You should now see
Got: Hello World in the Output box. To stop the program, push the Exit
button.
Back to Unix, use the ps(1) command and locate the UcmServer
process. Use the numeric process ID (PID) to stop the server with kill(1)
kill <PID>
B) Self-Contained Server
| /* Self-Contained UCM
Server */ #include "ucm.h"
#if defined(__STDC__)
static int DoService(T_SOCKET sock);
#else
static int DoService();
#endif
main(argc, argv)
int argc;
char *argv[];
{
ucmProgName = "test2"; /* for UCM error
messages */
UcmInit();
UcmServer("7999", DoService);
UcmTerm();
}
static int DoService(sock)
T_SOCKET sock;
{
int len;
T_UCM_MSGID msgId;
T_UCM_MSG msg;
if (UcmOpen(sock))
{
fprintf(stderr, "UcmOpen failed,
ucmErrno=%d\n", ucmErrno);
return 1;
}
while ((len = UcmRecv(sock, msgId, msg, -1, UF_NOFLAGS)) > 0)
{
/* process incoming message */
if (strcmp(msg, "Exit") == 0)
break;
UcmSendf(sock, msgId, "Got: %s",
msg);
}
UcmClose(sock);
return 0;
} |
Compile with: cc -o test2 test2.c libucm.a
Start the new server manually with:
test2
Again, you can use this server with the Windows ucmtest.exe client.
To stop the server, use the ps(1) command and locate the test2 process.
Use the numeric process ID (PID) to stop the server with kill(1).
C) Inetd Server
| /* Inetd UCM Server */ #include "ucm.h"
static T_SOCKET sock;
static T_UCM_MSGID msgId;
static T_UCM_MSG msg;
main(argc, argv)
int argc;
char *argv[];
{
int len;
sock = 0;
/*
stdin, stdout and stderr all point to the
** socket descriptor we may use.
*/
ucmProgName = argv[0]; /* for UCM error messages */
UcmInit();
if (UcmOpen(sock))
return 1;
while ((len = UcmRecv(sock, msgId, msg, -1, UF_NOFLAGS)) > 0)
{
/* process incoming message */
if (strcmp(msg, "Exit") == 0)
break;
UcmSendf(sock, msgId, "Got: %s",
msg);
}
UcmClose(sock);
UcmTerm();
return 0;
} |
Compile with: cc -o test3 test3.c libucm.a
The Internet Superserver inetd(1) requires to use symbolic service
names as defined in the services file.
Edit your /etc/services file and add the same lines as on the client system:
# UCM Services
ucmtest 7999/tcp
Now edit your /etc/inetd.conf file and add the lines:
# UCM Services
ucmtest stream tcp nowait root /usr/ucm/test3
The inetd(1) process reads configuration file /etc/inetd.conf at startup
to initialize itself. This will also make our ucmtest service available for
connections through ucmtest.exe on the Windows client.
As shown in this section, writing UCM server- as well as client applications is
very easy and provides fast development cycles.
9.3. Cobol Interface Parameters
The Unix distribution media of UCM contains a Cobol copy book and an interface
library in source. These files enable programmers to implement Cobol UCM servers.
Since many different Cobol flavors exist, some adaptations may be necessary. The functions
have been tested to work with MF Cobol. Other environments will likely need some changes
in the area of parameter passing to functions (see Calling Conventions in your
Cobol documentation).
The copy book is named uci.cpy:
*-----------------------------------------------------
* Unitec Communication Manager Copy-Book
* **************************************
*
* Parameter:
*
* UCI-PAR:
* - UCI-SOCKET: Socket-No. from 'ucmserver'
* - UCI-ERRNO: Error-No. if return code <> 0
*
* UCI-ADDR:
* - UCI-HOST: Host IP address or host name
* - UCI-SERVICE: TCP/IP service name or port no.
*
* UCI-MSG:
* - UCI-IDSIZE: Length of the message ID buffer
* - UCI-MSGSIZE: Length of the message buffer
* - UCI-MSGLEN: Length of the current input message
* - UCI-IDBUF: Message-ID value
* - UCI-MSGBUF: Message value
*
* UCI-RELEASE:
* - UCI-TIMEOUT: UciClientVersion timeout in ms
* - UCI-VERSION: Version number
*
*----------------------------------------------------- 01
UCI-PAR.
05 UCI-SOCKET PIC 9(5) VALUE 0.
05 UCI-ERRNO PIC 99.
*
01 UCI-ADDR.
05 UCI-HOST PIC X(32).
05 UCI-SERVICE
PIC X(32).
*
01 UCI-MSG.
05 UCI-IDSIZE PIC 9(2) VALUE 32.
05 UCI-MSGSIZE PIC 9(4) VALUE 2000.
05 UCI-MSGLEN PIC 9(4).
05 UCI-IDBUF PIC X(32).
05 UCI-MSGBUF PIC X(2000).
*
01 UCI-RELEASE.
05 UCI-TIMEOUT PIC 9(5) VALUE
10000.
05 UCI-VERSION PIC 9(4).
*
* End 'uci.cpy' |
The values of UCI-IDSIZE and UCI-MSGSIZE must correspond to the size of UCI-IDBUF
and UCI-MSGBUF respectively. The maximum values are described under Configuration
Limits, Chapter 10.
9.4. Cobol Interface Functions
This section contains descriptions of the UCM Cobol Interface function family UCI.
Users of UCM Rel 1.x may also use the compatibility layer grouped in the UDM
function family. For a description of the UDM functions, please refer to
the Rel. 1.x manual. The page headers for each description contain the function name and
title.
The Synopsis section gives a summary of the actual
function declaration.
The Description explains all of the function's operational
details.
In the Diagnostics section, common status and error codes
are listed, often with possible explanation for their occurrences.
Related functions are identified in the See Also section.
An Example section is provided for each function. The
example is intended to illustrate how the function is called, not necessarily how to use
the function. In some cases, the example is very brief. In all cases, it should be
sufficient to show how the call is made.
The following functions are in alphabetical order:
Return- and error codes of all UCI functions are described in ucmErrno.
Although most of the UCM clients make use of the Active-X control Ucm.ocx,
the following table shows the control flow of a typical Cobol only client-server session:
| Server |
Client |
| Start server through UcmServer(U) |
|
| |
Call UciInit
Call UciConnect |
Call UciInit
Accept socket from command line
Call UciOpen |
|
| |
Call UciWrite [1] |
Call UciRead, receive message [1]
Call UciWrite [2] |
|
| |
Call UcmiRead, receive message [2] |
| Repeat read/write as needed |
Repeate write/read as needed |
Call UciClose
Call UciTerm |
Call UciClose
Call UciTerm |
|
|