21
Sat, Dec
3 New Articles

The API Corner: Questions Should Have Answers!

APIs
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Send inquiry messages and receive a reply! Use the power of messages for error-handling, user feedback, or user interaction.

 

In previous articles, we have seen how to send a variety of messages to the user of an application. The message types covered include *ESCAPEs in the case of hard errors ("Inform Users of Problems by Sending Error Messages from Application Programs"), *DIAGnostics in order to provide additional information on error conditions  ("More on Sending Messages from an Application Program"), *COMPletion messages to indicate success in our task ("Sending Non-Error-Related Messages from an Application Program"), and *STATUS messages to keep the user informed about the current running of the application (also found in "Sending Non-Error-Related Messages from an Application Program"). Today, we'll look at sending *INQUIRY messages, which can be used for either success or failure, and receiving a response to the inquiry message.

 

We'll start by adding message description APP0005 to the QGPL/APPLMSGF message file used in the earlier articles.

 

ADDMSGD MSGID(APP0005) MSGF(QGPL/APPLMSGF) +

  MSG('Pick a number: 0 - 999, P') +

  SECLVL('Enter a value from 0 to 999, or P for the program to pick.') +

  TYPE(*DEC) LEN(3 0) SPCVAL(('p' -1) (P -1)) RANGE(0 999) DFT(1)

 

The APP0005 message prompts the user to enter either a number from 0 to 999 or the special value P. The type of reply, if not a special value, must be a decimal number with a maximum of three digits. Any decimal positions specified by the user will not be returned in the reply. If the user enters either a lowercase or uppercase letter P, then a reply value of -1 is to be returned to the program. If the user uses Enter without providing any reply, then a default reply value of 1 is to be used.

 

The following program prompts the user with message APP0005, receives the reply entered, calculates a reply value if the user replied with a p or P value, and then displays the reply value.

 

dSndMsg           pr                  extpgm('QSYS/QMHSNDPM')  

d MsgID                          7    const                    

d QualMsgF                      20    const                    

d MsgDta                     65535    const options(*varsize)  

d LenMsgDta                     10i 0 const                    

d MsgType                       10    const                    

d CallStackEntry             65535    const options(*varsize)  

d CallStackCntr                 10i 0 const                    

d MsgKey                         4                             

d QUSEC                               likeds(QUSEC)            

d LenCSE                        10i 0 const options(*nopass)   

d CSEQual                       20    const options(*nopass)   

d DSPWaitTime                   10i 0 const options(*nopass)   

d CSEType                       10    const options(*nopass)   

d CCSID                         10i 0 const options(*nopass)   

                                                               

dRcvMsg           pr                  extpgm('QSYS/QMHRCVPM')    

d MsgDta                         1    options(*varsize)          

d LenMsgDta                     10i 0 const                      

d Format                         8    const                      

d CallStackEntry             65535    const options(*varsize)    

d CallStackCntr                 10i 0 const                      

d MsgType                       10    const                      

d MsgKey                         4    const                      

d RpyWaitTime                   10i 0 const                      

d MsgAcn                        10    const                      

d QUSEC                               likeds(QUSEC)              

d LenCSE                        10i 0 const options(*nopass)     

d CSEQual                       20    const options(*nopass)     

d CSEType                       10    const options(*nopass)     

d CCSID                         10i 0 const options(*nopass)     

d AlwDftRpyRej                  10    const options(*nopass)     

                                                                  

 /copy qsysinc/qrpglesrc,qmhrcvpm                                

 /copy qsysinc/qrpglesrc,qusec                                   

                                                                 

dMsgDta           ds                  qualified                  

d Common                              likeds(QMHM010001)         

d Nbr                            3                               

                                                                 

dMsgFName         ds                                             

d Name                          10    inz('APPLMSGF')            

d Lib                           10    inz('QGPL')                

                                                                 

dResponse         s             10i 0                            

dMsgKey           s              4                               

                                                                 

 /free                                                            

                                                                 

  QUSBPRV = 0;                                                   

                                                                    

  SndMsg( 'APP0005' :MsgFName :' ' :0 :'*INQ'                       

         :'*EXT' :0 :MsgKey :QUSEC);                                

  RcvMsg( MsgDta :%size(MsgDta) :'RCVM0100' :'*' :0                 

         :'*RPY' :MsgKey :-1 :'*OLD' :QUSEC);                       

  if MsgDta.Common.QMHDRTN00 < MsgDta.Common.QMHDAVL00;             

     dsply 'Reply value out of range';                              

  else;                                                             

     Response = %int(%subst(MsgDta.Nbr :1 :MsgDta.Common.QMHDRTN00));

     if Response = -1;                                              

        Response = (%subdt(%timestamp() :*MS) / 1000);              

     endif;                                                         

     dsply Response;                                                 

  endif;                                                            

                                                                    

  *inlr = *on;                                                       

  return;                                                           

                         

 /end-free               

 

Sending the Inquiry Message

 

When initially sending message APP0005 to the user, the program uses the Send Program Message (QMHSNDPM) API that we have previously used for sending escapes, diagnostics, completion, and status messages. When sending the message, the message type is set to *INQ for inquiry and the destination for the message to *EXT for the external message queue.

 

Receiving the Response to the Inquiry Message

 

After sending the message, the program calls the Receive Program Message (QMHRCVPM) API documented here. The first parameter, MsgDta, is a receiver variable where the API will return information related to the message being received. As with most receive type APIs, the next two parameters further define the receiver variable. The second parameter specifies the allocated size of the receiver variable MsgDta; the third parameter specifies the format of the information to be returned in MsgDta. The QMHSNDPM API supports several formats, with the program requesting format RCVM0100.

 

Format RCVM0100 contains both fixed-length and variable-length fields. The fixed-length fields are defined in member QMHRCVPM of QSYSINC/QRPGLESRC and are copied into the program using the /copy compiler directive. The receiver variable MsgDta is defined as a qualified data structure using the base definition of format RCVM0100, named QMHM010001 within the QSYSINC copy member, followed by a character field, Nbr, of length 3.

 

It is worth pointing out that while the APP0005 message description calls for TYPE(*DEC), this only defines the type of value the user can enter when replying to the message. It does not define the data type to be used in returning the reply value to the program. Inquiry message replies are always returned in character form. That is, a user reply value of 1 is returned to the program as the character value 1, not a packed decimal (3 0) value of 1 (x'001F').

 

The fourth parameter when calling QMHSNDPM specifies where the message reply will be found. While it may seem reasonable for this parameter to be set to the *EXT special value used when sending the inquiry message, this is not the correct value for receiving the reply. When an inquiry message is sent, the system creates a sender copy message that is logically tied to the original inquiry message. This sender copy message is where you will find the reply and is accessed using the special value of an asterisk (*) in addition to the value of the seventh parameter passed when calling the QMHRCVPM API, which will be discussed shortly.

 

The fifth and sixth parameters do not require much explanation. The value of 0 for Call stack counter indicates that the message to be received is associated with the call stack identified by the fourth parameter (which is the special value *), and the Message type value of '*RPY' indicates that we want to receive a reply message.

 

The seventh parameter is used to identify the specific message to be received. In previous articles demonstrating how to send messages using QMHSNDPM, we provided the MsgKey parameter, which the API dutifully returned, and which we then never used. It's now time to find out what this parameter is for! When sending a message, the system assigns a message key for all message types except *STATUS. This message key uniquely identifies the message within the context of the sender of the message. By specifying the MsgKey value returned by QMHSNDPM when we call QMHRCVPM, we are explicitly asking for the reply to that specific instance of the inquiry message.

 

For information on the remaining parameters, refer to the Information Center documentation for the QMHRCVPM API.

 

Processing the User Response to the Inquiry Message

 

Upon successful completion of the QMHRCVPM API call, the MsgDta data structure now contains information related to the reply message. Though not strictly necessary, the program, prior to processing the reply value, now performs a sanity check on the returned value. Just in case "someone" changed the APP0005 message description to allow a larger range of values (for instance,  LEN(5 0) and RANGE(0 99999)) and forgot to update the program, the program checks to see if the length of the returned reply data (QMHDRTN00) is less than the length of all available reply data (QMHDAVL00). This would be the case if the user typed in a reply value of 9999—which will not fit into the three bytes we allocated for MsgDta.Nbr— as there would be four bytes available but only the first three bytes returned. If this situation is detected, then the message "Reply value out of range" is displayed using the DSPLY operation code.

 

As an exercise, you might change the program from using DSPLY to sending an escape message to the program's caller. If you need a refresher on sending escape messages, see the article "Inform Users of Problems by Sending Error Messages from Application Programs." Of course "someone" may have also changed the message definition in other ways, such as the TYPE from *DEC to *CHAR, and again forgotten to update the program (which would most likely result in a decimal data error when later processing the reply value). For this situation (along with for any API call failures as the program is using an API error code Bytes Provided value of 0), a global MONITOR group would be appropriate. In this article, I have elected to omit this additional error handling as the topic is sending and receiving inquiry messages, not how to handle errors (a topic that has been covered in previous articles, such as "What to Do with Messages in the Application Program").

 

Having done some rudimentary validation, the program converts the character value of MsgDta.Nbr (the reply the user provided) to the numeric variable Response. To do this, the program substrings the returned number of reply characters (MsgDta.Common.QMHDRTN00) within MsgDta.Nbr, converting this substring value to integer form. The substring operation is used as a reply value, such as 1 would only update the first byte of variable MsgDta.Nbr (which is defined as being three bytes in length), leaving the remaining two bytes unchanged from their initial value.

 

The program then checks to see if the value of Response is -1. This would be the case if the user replied to message APP0005 with the special value p or P. If so, the program then picks a number in the range of 0 to 999 by extracting the milliseconds component of the current system time. The actual process of picking a number is not of much interest; the intent here is to demonstrate how reply message special values might be supported within an application program.

 

Whether the program calculated a value, or the value was provided by the user, the program now displays the numeric value. Again, as an exercise, you might want to display this value using a predefined message of your own, utilizing replacement data for the Response value.

 

In this article, we have reviewed how to send inquiry messages, receive a reply to an inquiry message, and then process the reply. When combined with previous articles related to message-handling on the system, you should be in a good position to use the power of messages within your IBM i applications, whether it be for error-handling, user feedback, or user interaction.

 

If you have any API questions, send them to me at This email address is being protected from spambots. You need JavaScript enabled to view it.. I'll see what I can do about answering your burning questions in future columns.

 

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: