John McKee wrote:
I used the following QSH command:
system 'call pgm(qmhsndpm)
parm(
'CPF9898' 'QCPFMSG *LIBL' 'TEST MESSAGE' '12'
'*ESCAPE' '*SYSOPR' '3' ' ' ' '
')'
CPF24B3: Message type MESSAGE not valid.
CPC2206: Ownership of object QZSHSYSTEM in QTEMP type
*USRSPC changed.
Issues I have: No idea what should be used just after
the *SYSOPR parameter. Coding a 3 is just guesswork.
The Call Stack Entry refers to a program name within the stack.
There is no provision in the API for non-program message queues that
I am aware of. The special value *SYSOPR intends to resolve to the
non-program message queue name QSYSOPR in QSYS; and supported only
where documented.
The Call Stack Entry counter refers to the location of the target
program message queue, relative to the named program [which must be
in the active program stack].
Is the CPF24B3 related to the value of '3'? The command
SNDPGMMSG does not show a MESSAGE parameter.
The error says "message type" is the problem, with its
replacement value suggesting the string 'MESSAGE' was specified for
what is effectively the MSGTYPE() parameter for the API; i.e. the
fifth parameter of the API.
I was wondering if SNDPGMMSG was restricted based on a
parameter, but the API that actually sends the message
did not need that restriction.
Like the KEYVAR() of SNDPGMMSG, the "Message Key" of the QMHSNDPM
is defined as /Output/ only, and theoretically requires a variable
in order to utilize it. However as parameters are passed by
reference, and that the CALL interface generates a 32-byte storage
location for each parameter, a command line invocation of the API
should not be problematic; except that there is no ability to access
the /message key/ return value.
For the given scenario, the expression /wrong tool for the job/
comes to mind. That the attempt is to send a message to the QSYSOPR
message queue, I would expect SNDMSG, Send Nonprogram Message
(QMHSNDM) API, Send Message (QEZSNDMG) API, SNDBRKMSG, or Send Break
Message (QMHSNDBM) API to be used instead. One odd part to me is
the *ESCAPE specification, which implies that the sending of the
message should then also terminate the active processing.? Of
course exiting after sending a message which is not an exception,
accomplishes the same; i.e. a non-program queue gives no option for
a receiving program to react, except as an invocation exit [the
activation of any established termination handlers of each preceding
program in the stack].
As if the QMHSNDPM were acceptable, consider the following
comments about the parameters being passed in the given example:
1 Message identifier Input Char(7)
2 Qualified MSGF name Input Char(20)
3 Message data Input Char(*)
or immediate text
4 Length of MsgDta Input Binary(4)
or Length of immediate text
5 Message type Input Char(10)
6 Call stack entry Input Char(*) or Pointer
7 Call stack counter Input Binary(4)
8 Message key Output Char(4)
9 Error code I/O Char(*)
In review, the parameters passed in the example, to correlate
with the expected parameters from the documentation included just
above. The following #> bullets repeat each of the specified
values, with a short pseudo-parameter-name as description of what
the parameter is; from the SNDPGMMSG command, for those with a like
parameter.
'CPF9898' 'QCPFMSG *LIBL' 'TEST MESSAGE' '12'
'*ESCAPE' '*SYSOPR' '3' ' ' ' '
1> MsgId 'CPF9898'
This indicates that the Message ID is to be used
which implies that parm3 and parm4 will refer to
/message data/ not /immediate text/. FWiW when
using CPF9898 with only &1 replacement var, this
could reasonably be passed as ' '; i.e. is
documented "blanks for an immediate message."
http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/apis/QMHSNDPM.htm
2> MsgF 'QCPFMSG *LIBL'
This should be 'QCPFMSG *LIBL ' instead,
even though in the given example it is unnecessary
because the implementation whereby 32-bytes is
defaulted for input; i.e. the parameter is CHAR(20)
so proper coding dictates passing 20 characters.
3> MsgDta 'TEST MESSAGE'
or Msg
No issue here. If blanks are used for MsgID parm,
then I think adding a period is required to match.
This parameter is variable length CHAR(*) for which
the next parameter describes its length; thus the
32-byte issue is moot, given the length specified
is consistent with the specified character string.
4> MsgDtaLen '12'
'12' is 0xF1F2 [x'F1F2] which as a unsigned BIN(4)
in decimal is 61938, which in two's complement is
a negative number. Specify x'0000000C' as the
string to represent 4-byte binary as decimal 12.
5> MsgTyp '*ESCAPE'
As CHAR(10), /properly/ should be '*ESCAPE '
6> PgmQ E2.1 '*SYSOPR'
There is no documented special value for *SYSOPR
that I could find for this API. This API intends
to use only program message queue rather than a
non-program message queue. There are some special
values allowed: *, *PGMBDY, *CTLBDY, *PGMNAME, *EXT
of which none directs to an external message queue.
At least *PGMNAME request the parameter list to the
API to then include optional parameters. That said,
the /external message queue/ [not to be confused
with the /external object type/ of *MSGQ] probably
is not technically a /program message queue/, and is
called out as "can also be specified" using the *EXT
special value... and is required for MsgType(*INQ).
7> PgmQ E1 '3'
Again a character instead of 4-byte BINARY that
represents an integer. If the relative position
from the Call Stack Entry was three, then the value
x'00000003' would need to be specified.
8> KeyVar ' '
As alluded this parameter is Output only, but AFaIK
is still /functional/ at least for being able to
CALL QMHSNDPM, but really should be a variable versus
a literal.
9> ErrCde ' '
The Error Code parameter expects a 4-byte binary. The
specification as a blank character string is the value
x'40404040' which is horribly wrong; that an error was
issued, I infer that bogus value is being interpreted
by API error processing as zero. The proper coding is
expected to be x'00000000' to indicate that zero bytes
provided to the API for error code return information;
i.e. that the parameter becomes input-only to the API,
such that exceptions are returned versus error codes.
Regards, Chuck
As an Amazon Associate we earn from qualifying purchases.