How to send inquiry messages and get replies

Create impromptu messages with APIs and commands or RPG.

This tip is an excerpt of the article "How to send inquiry messages and get replies" published in the November/December 2002 edition (volume 5, number 6) of the iSeries 400 Experts Journal. Provided courtesy of iSeries 400 Experts.


Ron Turull

Few things are more frustrating than having to code an entire display file just to ask a user a quick question and get a reply. There is a better –- and easier -– way. Using an inquiry message is a quick way to ask the question; using –- or more appropriately receiving –- a reply message is the quick way to get the reply.

Messages come in different flavors

There are many different types of messages on the AS/400. For example, every programmer is familiar with the dreaded escape message. Unless monitored for, escape messages cause programs to crash.

Another type of message is the status message. These show up on the message line while a program is running. They are usually used to inform the user of a possible long-running function. The familiar "query running" message is an example of a status message.

Inquiry messages are used when you want to get a response back from the user. That response is sent back to the program as a reply message. The program can then receive the reply message off its message queue.

How messages work

Messages on the AS/400 are "transported" on objects called message queues. There are two types of message queues: program message queues and non-program message queues.

Program message queues are associated with programs; that is, each program on the call stack has its own program message queue. They are created automatically when the program is called. Programs in the same job can use them to send messages back and forth to each other. Only programs can use program message queues.

Non-program message queues are not associated with any particular program, although programs can use them. Examples of non-program message queues are the QSYSOPR message queue, user message queues, and message queues associated with a display station. For example, non-program message queues can be used to communicate messages between two different jobs or between a program and a user.

A program can send a message by using one of the send message commands or APIs. When a message is sent, it is assigned a unique key and put on the message queu which you specify when you send it (except for status messages). A program can then fetch the message off the message queue by using one of the receive message commands or APIs. You can fetch messages by key (a message’s key uniquely identifies it on the message queue to which it was sent), or you can fetch them in either LIFO or FIFO order. The program usually has the choice of whether or not the message should be deleted from the message queue after it is fetched.

Six common commands and APIs you'll use for messages

The following is a list of the commands and APIs most commonly used for sending and receiving messages. The commands listed can be used only in CL programs. The APIs can be used in any program.

1. SNDPGMMSG. The send program message command is used to send a message to either a program or non- program message queue. When sending an inquiry message, it is vital that you specify a 4-byte character field for the KEYVAR parameter. The SNDPGMMSG command will return the key assigned to the inquiry message, which is needed for retrieving the associated reply message.

2. QMHSNDPM. The send program message API is similar to the SNDPGMMSG command except that it can be used only to send a message to a program message queue (more on this later).

3. QMHSNDM. The send non- program message API is used to send a message to a non- program message queue.

4. RCVMSG. The receive message command is used to receive a message from either a program or a non-program message queue. You can receive messages by key or by LIFO or FIFO order. You can also request only certain types of messages, such as a reply message. Note: When receiving a reply message, you must send the RCVMSG command the key to the associated inquiry message on the MSGKEY parameter.

5. QMHRCVPM. The receive program message API is similar to the RCVMSG command except that it can be used only to receive a message from a program message queue.

6. QMHRCVM. The receive non- program message API is used to receive a message from a non-program message queue.

Caution: Note the inconsistency in the naming and function of the message commands versus the message APIs, particularly the SNDPGMMSG command. From the naming convention of the other message commands and APIs, especially the QMHSNDPM API, it would seem to imply that the send program message command can be used to send a message only to program message queues, not to non-program message queues, as well. However, the "program" in "send program message" does not refer to program message queues as it does in the name of the send program message API (QMHSNDPM). Instead, it means that the SNDPGMMSG can be used only from within a CL program and is meant to differentiate this command from the SNDMSG (send message) command. which can be used from a command line or by a program.

How to put the commands and APIs to work

Figure 1 illustrates the use of the SNDPGMMSG and RCVMSG commands to send an inquiry message and fetch the user's reply. Often, inquiry messages are sent before a program is about to do something "extreme" -- for example, ending the system to the restricted state. The inquiry message usually gives the user a last chance to cancel the action before it is too late. However, this is not the only use for inquiry messages.


/*  You need a variable for the message key and another for   +
    the reply.                                            /*

             DCL        VAR(&KEY) TYPE(*CHAR) LEN(4)
             DCL        VAR(&REPLY) TYPE(*CHAR) LEN(1)
             DCL        VAR(&REPLY_LEN) TYPE(*DEC) LEN(5 0)


/*  Check with user before going further. */

LOOP:
/*  Use the SNDPGMMSG command to send the inquiry message. */

             SNDPGMMSG MSG('This program is about to do something +
                          drastic. Continue (Y or N)?') +
                          TOPGMQ(*EXT) MSGTYPE(*INQ) RPYMSGQ(*PGMQ) +
                          KEYVAR(&KEY)

/*  Use the RCVMSG command along with the message key    +
           returned by the SNDPGMMSG command to wait for and   +
           receive the user's reply. */

             RCVMSG     PGMQ(*SAME) MSGTYPE(*RPY) MSGKEY(&KEY) +
  WAIT(*MAX) RMV(*NO) MSG(&REPLY) +
  MSGLEN(&REPLY_LEN)

/*  Check message length. */

             IF         COND(&REPLY_LEN > 1) THEN(GOTO CMDLBL(LOOP))



/*  For test purposes, display the user's reply.  Note: Replies   +
      are NOT converted to upper case. */

             SNDPGMMSG MSG('The reply was ' *CAT &REPLY *CAT '.')


  Return
    
    
Figure 1. Basic use of the SNDPGMMSG and RCVMSG commands

The SNDPGMMSG command sends the impromptu message to the external message queue (TOPGMQ(*EXT)). The external message queue is a special type of program message queue that is tied to the job; every job has one. Other notable parameters on the SNDPGMMSG command are RPY-MSGQ and KEYVAR. RPYMSGQ tells the system which message queue you want the reply message to go to; the value *PGMQ tells the system to put the reply on the program's messagequeue. KEYVAR is how you receive the message key assigned to the inquiry message. This key is vital in retrieving the associated reply message. Note its use on the RCVMSG command. At this point, the familiar Display Program Messages screen appears , shows you the inquiry message, and waits for the reply.

When the user types their reply and presses Enter, the system will send the reply and a reply message to the program's message queue. The RCVMSG command is then used to receive the reply message.

Doing it in RPG

To do this same thing in RPG, we use the QMHSNDPM and the QMHRCVPM APIs. The parameter list of these two APIs is very similar to the parameters on the SNDPGMMSG and the RCVMSG commands, respectively. The code in Figure 2 shows the identical program in RPG.

The biggest differences are:

  • Replies to inquiry messages are, by default, sent to the program's message queue.
  • The STKENT and STKCTR parameters are the equivalent of the TOPGMQ parameter on the SNDPGMMSG command (or the PGMQ parameter on the RCVMSG command).
  • A -1 for the WAIT parameter is equivalent to WAIT(*MAX) on the RCVMSG command.
  • Messages are returned from the QMHRCVPM API in a data structure, the layout of which is determined by the value you specify for the FORMAT parameter.

*
I   'This program will - C          #MSG
I   'end this job! -
I   'Continue? (Y or N)'
*
I   X'00000000'   C          #RESND
 *
 * UNNAMED DS FOR BINARY VARIABLES.
I  DS
I   B   1   40MSGLEN
I   B   5   80STKCTR
I   B   9  120RCVLEN
I   B  13  160WAIT
 *
IMSGINF DS
I   B   1   40BYTESR
I   B   5   80BYTESA
I   B   9  120MSGSEV
I   13  19 MSGID
I   20  21 MTYP1
I   22  25 RPYKEY
I   B  41  440MSGLNR
I         B  45  480MSGLNA
I   49  49 REPLY
 *
 *
C  MSGLNA DOUEQ1
 *
 *  SEND INQUIRY MESSAGE.
 *
C  CALL 'QMHSNDPM'
C  PARM *BLANKS MSGID   7
C  PARM *BLANKS MSGFIL 20
C  PARM #MSG MSG   256
C  PARM 50  MSGLEN
C  PARM '*INQ' MSGTYP 10
C  PARM '*EXT' TOQ    10
C  PARM 0  STKCTR
C  PARM  MSGKEY  4
C  PARM #RESND ERROR   4
 *
 *
 *  WAIT FOR AND GET REPLY.
 *
C  CALL 'QMHRCVPM'
C  PARM  MSGINF
C  PARM 49  RCVLEN
C  PARM 'RCVM0100' FORMAT 10
C  PARM '*'  STKENT 10
C  PARM 0  STKCTR
C  PARM '*RPY' MSGTYP 10
C  PARM  MSGKEY  4
C  PARM -1  WAIT
C  PARM '*OLD' MSGACT 10
C  PARM #RESND ERROR   4
 *
C  ENDDO
 *
 *
C  REPLY DSPLY  REPLY
 *
 *
C  RETRN
 *
    
Figure 2. RPG version of the CL program shown in Figure 1

-----------------------------------
About the author: Ron Turull is editor of Inside Version 5. He has more than 20 years experience programming for and managing AS/400-iSeries systems.

==================================
MORE INFORMATION
==================================

  • Message break-handling program helps you monitor inquiry messages
    Search400.com member Bill Greenlee says it's tedious to enter DSPMSG repeatedly to check messages, and it's inconvenient to have work interrupted in *BREAK mode for every 'Job completed...' message. But you don't want inquiry messages sitting without response for long periods. What can you do? Try this break-handling program that manages incoming messages according to the kind of message that's received.
  • Issue interactive status messages in a CL program
    Although the Send Program Message (SNDPGMMSG) command serves many useful purposes, one you may not have considered is using SNDPGMMSG to send a status message for update purposes from an interactive CL program to the bottom (line 24) of an interactive green-screen display. This technique is particularly valuable when you're calling a long-running job -- such as a customized CL backup program -- that must be run interactively from the system console.
  • Problem when using SNDPGMMSG
    One user says for no apparent reason, the status messages that usually appear in the bottom of the screen have stopped displaying. Site expert John Brandt has in idea what might be going on.
  • Sending a message to a user profile
    This user can send a reversed image error message to line 24 using SNDPGMMSG, but what he wants to do is send the message to a user profile. How can he do that? Site expert John Brandt has some advice.


This was first published in January 2004

Dig deeper on Performance

0 comments

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

-ADS BY GOOGLE

SearchEnterpriseLinux

SearchDataCenter

Close