User Programs and Functions

This chapter describes how to create user programs using X25 gateway and related APIs.

1. Overview

X25GW must be configured in the Tmax environment configuration. To use the X25GW, custom.h and custom.c must be modified properly. X25GW is created by linking and compiling custom.h, custom.c, X25GW library and register.c files. The file names must be the same as those specified in the SERVER section of the Tmax environment file. Custom.c includes various user defined functions which are described later in this chapter.

2. custom.h

This file includes the msg_info_t struct used in X25GW. The message structure or header of this file can be modified to implement the communication between the remote node and X25GW. However, since the msg_info_t struct is used in the X25GW library and user functions, the member variables, type, length, etc. must not be modified. The msg_info_t struct is used in the X25GW library and the user-defined functions in the custom.c file. In the custom.c file, the struct value must be set in the get_msg_info() function which is called immediately after the message is received from the remote node. The data sent to the remote node must be set to the struct value in the put_msg_info() function which is called immediately before the message is sent to the remote node.

The msg_info_t structure used in X25GW is as follows:

typedef struct msg_info {
    char svc[20];
    int err;
    int len;
    int uid;
    int flags; /* configure flags. (such as TPNOREPLY) */
    int msgtype;
    int channel_id;
    char sys_id[20];  /* Channel group name  */
} msg_info_t;

The following describes the members of the msg_info struct.

Member Description

char svc[20]

Service name that X25GW uses to call the service when it is requested from the remote service.

int err

Error in the response message.

int len

Length of the sent/received data.

int uid

UID generated by X25GW during synchronous communication.

int flags

Used when a service is requested from the remote node to Tmax.

  • NOFLAGS: When receiving reply for the service requested from the remote node.

  • TPNOREPLY: When only requesting the service without receiving the reply. (same as TPNOREPLY for Tmax tpacall).

int msgtype

Currently not used.

char sys_id[20]

Sending/receiving channel number.

3. custom.c

The custom.c file must be implemented to allow communication between the remote node and X25GW. It must be compiled with the X25GW library (libx25gw.a, libx25gw.so). The usage of the functions will be explained in Examples.

The following describes the functions that must be implemented in custom.c.

Function Description

init_remote_info

This function is called before connecting to the remote node.

remote_connected

This function is called after connecting to the remote node.

remote_closed

This function is called after disconnecting from the remote node.

get_msg_info

This function references or processes the info used as an interface between the X25GW library and custom.c after reading request/reply data from the remote node.

get_channel_num

This function allows the user to select the channel when sending data from a Tmax service or client to the remote node.

put_msg_info

This function is called when a message is sent to the remote node.

get_service_name3

This function is configured according to the error code of the service name to tpreply() or tpacall() to.

prepare_shutdown

This function is called immediately before X25GW shuts down.

inmsg_recovery

This function is called when an error occurs while processing the remote node’s request through tpacall (…​, TPBLOCK).

outmsg_recovery

This function is called when an error occurs while sending a request to the remote node.

3.1. init_remote_info

The init_remote_info function is called before connecting to the remote node. It is called only once, immediately after X25GW is initialized. If the shared memory key is configured using the [-k ] option of CLOPT in the Tmax environment file, the logic that creates shared memory to save connection information can be implemented. The implementation can be omitted in some cases.

  • Prototype

    int init_remote_info (char *myname, int mynumber, int num_channel, int key)
  • Parameter

    Parameter Description

    myname

    X25GW server name.

    mynumber

    X25GW process number used to identify each process when multiple X25GW processes are running simultaneously. The number starts from 0.

    num_channel

    Max number of channels connected to X25GW. This is the sum of the values set using the [-n], and [-N] options in the Tmax environment file.

    key

    Shared memory key value set using the [-k] option in the Tmax environment file.

3.2. remote_connected

The remote_connected function is called after connecting to the remote node, and it implements post connection processing. The function is called as many times as the channel count, and it is also called when the channel is reconnected after being disconnected.

  • Prototype

    int remote_connected(int index, int linkno, int lcnno, int type)
  • Parameter

    Parameter Description

    index

    Index value of each channel that X25GW is connected to.

    linkno

    Link number of the connected channel.

    lcnno

    Number of connected channels. A single link has multiple lCNs. This number usually represents a logical number.

    type

    Channel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.

3.3. remote_closed

The remote_closed function is called after disconnecting from the remote node, and it implements post disconnection processing. When the logic that creates the shared memory is implemented in the init_remote_info function, the logic that releases the shared memory is implemented in this function. The function is called as many times as the channel count.

  • Prototype

    int remote_closed(int index, int type)
  • Parameter

    Parameter Description

    index

    Index value of each channel that X25GW is connected to.

    type

    Channel type connected to the remote node. Either IN_CHANNEL or OUT_CHANNEL.

3.4. get_msg_info

The get_msg_info function processes the data received from the remote node before forwarding the request or reply to the Tmax service program. This function can also reference or process the information (uid, len, flags, service name, etc.) required to interface between the X25GW library and custom.c.

  • Prototype

    int get_msg_info(char *data,msg_info_t *info)
  • Parameter

    Parameter Description

    data

    Data part read from the remote node.

    info

    Struct that interfaces between the X25GW library (libx25gw.a, libx25gw.so) and custom.c. Sets various information to the info struct using the received data.

  • Return Value

    Message type to send to Tmax service. X25GW uses this value to determine what needs to be processed.

    For example, REMOTE_REQUEST indicates that there is a request from the remote node, and REMOTE_REPLY is a value that is returned when the remote node sends a response for the request from the Tmax service. When a response is received from the remote node, the UID value must be set to the uid in the info struct. Other values must also be set appropriately.

3.5. get_channel_num

The get_channel_num function allows the user to select a channel when the data requested from the Tmax service or client is sent to the remote node. The sending channel can be specified according to the characteristics of the data, and it is simply the channel number not the socket number connected to the remote node. X25GW returns an error if the channel specified by the user cannot be used.

  • Prototype

    int get_channel_num(char *data)
  • Parameter

    Parameter Description

    data

    Data to send to the remote node.

  • Return Value

    Channel number.

3.6. put_msg_info

The put_msg_info function is called when sending a message to the remote node. For synchronous communication, the user must save the UID in the message. The UID can be set to the value of the uid in the info struct, or the user can create a UID and then set it to the uid in the info struct.

  • Prototype

    int put_msg_info(char *data, msg_info_t *info)
  • Parameter

    Parameter Description

    data

    Data to send to the remote node.

    info

    Data information to send to the remote node.

  • Return Value

    Total length of the data to send to the remote node, which includes the lengths of the message header and the actual data.

3.7. get_service_name3

When configuring a non-blocking or asynchronous X25GW that uses separate servers for sending and receiving a request/request to/from the remote node, this function configures the name of the service to tpreply() or tpacall() according to the error code.

  • Prototype

    int get_service_name(char *header, int err, char *svc)
  • Parameter

    Parameter Description

    header

    Pointer to the user header stored in X25GW configured using the [-H] or [-h] option.

    err

    Error code.

    svc

    Name of the service that receives tpreply() or tpacall().

3.8. prepare_shutdown

The prepare_shutdown function is called before X25GW shuts down and it generally releases the shared memory created in the init_remote_info() function.

  • Prototype

    int prepare_shutdown(int code)
  • Parameter

    Parameter Description

    code

    Termination code. Currently not in use.

3.9. inmsg_recovery

This function is called when an error is returned because the server is not running when a request from the remote node is processed via tpacall (…​, TPBLOCK). The user can create a new data inside this function and return the data size.

  • Prototype

    int inmsg_recovery(char *data, msg_info_t *info)
  • Parameter

    Parameter Description

    data

    Data part read from the remote node.

    info

    Data information read from the remote node. Meaningful values are as follows.

    • info→svc: Service name that initiated tpacall().

    • info→len: Length of the data for the tpacall().

    • info→err: tperrno when there is an error.

    • info→uid: UID value created during the previous get_msg_info() call.

  • Return Value

    Length of the newly created data (required).

    If the length of the data is greater than 0 and the data contains a value in info→svc, the data is sent to the service through tpacall(…​, TPNOREPLY). Otherwise, the response is sent to the remote node. When the length of the data is negative, the data is discarded.

3.10. outmsg_recovery

The outmsg_recovery function is called when there is an error while sending a request to the remote node. The user can create a new data inside the function, set the desired service name and UID, and return the data size.

  • Prototype

    int outmsg_recovery(char *data, msg_info_t *info)
  • Parameter

    Parameter Description

    data

    Data part read from the remote node.

    info

    Data information read from the remote node. Meaningful values are as follows.

    • info→len: Data length

    • info→uid: UID value that is temporarily created by X25GW

    • info→msgtype: Value greater than 1000 indicates an error has occurred while sending a response to the remote node. The value less than 1000 indicates an error has occurred while sending a request to the remote node.

    • info→err: TPECLOSE indicates that a channel was disconnected while waiting for a response. Other values indicate an error occurred while sending a request.

  • Return Value

    Length of the newly created data (required).

    If the data length is greater than 0 and the data contains a value in info→svc, the data is sent to the service through tpacall(…​, TPNOREPLY). If info→msgtype is greater than 1000, the data is discarded and if info→msgtype is less than 1000, the data is returned to the service that sent the request.

4. register.c

This is the user function registration file. Only registered functions can be called from the gateway library. When the gateway is compiled, register.c must be included. Unused functions can be registered as NULL.

The following is an example of a register.c file.

#include <stdio.h>
#include "custom.h"

extern int init_remote_info(char *name, int index, int n, int key);
extern int prepare_shutdown();
#ifdef _NCR_X25
extern int remote_connected(int index, int pcid, char *lname, char *rname, int type);
#else
extern int remote_connected(int index, int linkno, int lcnno, int type);
#endif
extern int remote_closed(int index, int type);
extern int get_msg_info(char *data, msg_info_t *info);
extern int put_msg_info(char *data, msg_info_t *info);
extern int get_service_name(char *header, int err, char *svc);
extern int get_channel_num(char *data);
extern int inmsg_recovery(char *data, msg_info_t *info);
extern int outmsg_recovery(char *data, msg_info_t *info);

/***************************************************************
 *  int
 *  _register_custom()
 *
 *      returns no used
 *      [function number]
 *        1.  init_remote_info
 *        2.  prepare_shutdown
 *        3.  remote_connected
 *        4.  remote_closed
 *        5.  get_msg_info
 *        6.  put_msg_info
 *        7.  get_service_name
 *        8.  get_channel_num
 *        9.  inmsg_recovery
 *        10. outmsg_recovery
 ***************************************************************/
int
_register_custom()
{
        _x25gw_regfn(1,  init_remote_info);
        _x25gw_regfn(2,  prepare_shutdown);
        _x25gw_regfn(3,  remote_connected);
        _x25gw_regfn(4,  remote_closed);
        _x25gw_regfn(5,  get_msg_info);
        _x25gw_regfn(6,  put_msg_info);
        _x25gw_regfn(7,  get_service_name);
        _x25gw_regfn(8,  get_channel_num);
        _x25gw_regfn(9,  NULL);
        _x25gw_regfn(10, NULL);

        return 1;
}