HP 3000 Manuals

Sample Program in Non-Transparent Mode [ SNA IMF Programmer's Reference Manual ] MPE/iX 5.0 Documentation


SNA IMF Programmer's Reference Manual

Sample Program in Non-Transparent Mode 

When this program is given aninput parm value of zero, it emulates a
display station (LU Type 2) powering on, logging onto the host, logging
off, and powering off.  When it is given a  parm value greater than zero,
it starts a Pass Thru session with a spooler file (LU Type 3).

     program imf3270 (input, output, parm);

     const
        SCREENSIZE    = 1920;
        LINESIZE      = 80;

     { constant for OPEN3270 }
        TERMINAL      = -2;

     { constants for action code of PRINT3270 }
        OPEN_FILE     = 0;
        PRINT_SCREEN  = 2;
        PRINT_BANNER  = 3;
        CLOSE_FILE    = 4;

     { constants for AID of TRAN3270 }
        SYS_REQ_KEY   = 48;
        ENTER_KEY     = 39;

     { constants for ACQUIRE3270 }
        LU_T3         = -3;
        SPOOLER_FILE  = 6;

     type
        shortint      = -32768..32767;     { 16 bits = 2 bytes }
        string        = packed array[1..LINESIZE] of char;
        screen        = packed array[1..SCREENSIZE] of char;

     { type for OPEN3270: }
     { This type takes up 2 bytes.  It can be replaced by the shortint type. }
     { This type is defined for ease of assigning values to each }
     { of the different bit groups }
        flags_type = packed record
           filler     : 0..1023;  { ten bits }
           dbcs       : 0..1;     { one bit }
           unbind     : 0..1;     { one bit }
           LUT1_LUT3  : 0..1;     { one bit }
           int_trace  : 0..1;     { one bit }
           trans_mode : 0..1;     { one bit }
           IO_mode    : 0..1;     { one bit }
        end;                      { total of 16 bits = 2 bytes }

     { type for ACQUIRE3270: }
     { This type takes up two bytes.  It can be replaced by the shortint type. }
     { This type is defined for ease of assigning values to each }
     { of the different bit groups }
     { Note that the readTO field takes up nine bits, but the legal }
     { range of values is 10-255, which only takes up 8 bits. }
     { So, the range is set at 10-256 to take up nine bits, }
     { but a value of 256 or higher is not allowed. }

        options_type = packed record
           filler     : 0..1;     { one bit }
           int_trace  : 0..1;     { one bit }
           sPriority  : 1..13;    { four bits }
           readTO     : 10..256;  { nine bits.  256 is illegal value. }
           LJ2        : 0..1;     { one bit }
        end;                      { total of 16 bits = 2 bytes }

     { Global variables: }
     { These variables are global because they must be used in a number of }
     { procedures.  Some of them are used to actually pass parameters }
     { to other procedures.  Making them global simplifies the code }
     { and makes intuitive sense. }

     var
        terminalid     : shortint;  { terminalid used for intrinsics }
        result         : shortint;  { result code of intrinsic calls }
        fileid         : shortint;  { ID of file printed to }
        action         : shortint;  { action code for PRINT3270 }
        priority       : shortint;  { priority given to spooler file }
        cursorrow      : shortint;  { current cursor row position }
        cursorcolumn   : shortint;  { current cursor column position }
        numfields      : shortint;  { number of fields in the current screen }
        error          : boolean;   { global error flag }
        location       : string;    { location string used by PRINT3270 }
        parm           : shortint;  { parameter specified in command line }

     procedure VERS3270;     intrinsic;
     procedure ERR3270;      intrinsic;
     procedure ACQUIRE3270;  intrinsic;
     procedure ATTRLIST;     intrinsic;
     procedure CLOSE3270;    intrinsic;
     procedure FIELDATTR;    intrinsic;
     procedure OPEN3270;     intrinsic;
     procedure PRINT3270;    intrinsic;
     procedure READSCREEN;   intrinsic;
     procedure RECV3270;     intrinsic;
     procedure SCREENATTR;   intrinsic;
     procedure TRAN3270;     intrinsic;
     procedure WRITEFIELD;   intrinsic;
     procedure READFIELD;    intrinsic;

     {
      * The following procedure takes an errorcode, which is usually a result code
      * from another intrinsic call, and prints out the corresponding message.
      * The conversion is done by ERR3270.  ERR3270 takes an errorcode, fills msgbuf
      * with the corresponding message, assigns msglen to the message length,
      * and sets result to the result code.
     }

     procedure print_message (errorcode: shortint);
     var
        msgbuf  : packed array[1..144] of char;
        msglen  : shortint;

     begin

     { Set flag if any fatal errors have occurred. }
     { errorcode=0 (and errorcode=9 on MPE V) are not errors. }

        if errorcode <> 0 then
           error := TRUE;
        msgbuf := ' '
        ERR3270 (errorcode, msgbuf, msglen, result);

     { Check whether the ERR3270 intrinsic generated any errors. }
        if result = 0 then
           writeln (msgbuf:msglen)
        else begin
           writeln ('INTERNAL ERROR in program:  ERR3270 result = ', result:2);
           error := TRUE;
        end  { if - else }
     end;

     {
      * The following procedure calls RECV3270 to receive and print a screen.
      * The variables terminalid, fileid, action, location, and priority are
      * global.  terminalid is set by OPEN3270.  fileid is set by the first
      * PRINT3270 call, which is the call that opens the print file.  The variables
      * action, location, and priority are set in procedure initialize.
      * Note that the priority variable isn't checked after the first call
      * to PRINT3270, which opened the print file.
     }
     procedure call_recv3270;
     begin
        write (' RECV3270.........');
        RECV3270 (terminalid, result);
        print_message (result);
        write (' PRINT3270 print to file.....')
        PRINT3270 (terminalid, fileid, action, location, priority, result);
        print_message (result);
     end;
     {
      * The following procedure prints the internal screen image to the spooler
      * file before it calls TRAN3270.  The variables terminalid, fileid, action,
      * location, priority, cursorrow, and cursorcolumn are global.
      * terminalid is set by OPEN3270.  fileid is set by the first PRINT3270 call,
      * which is the call that opens the print file.  The variables
      * action, location, and priority are set in procedure initialize.
      * Note that priority is not checked after the first call to PRINT3270,
      * the call that opened the print file.
      * cursorrow and cursorcolumn are set by the previous call to SCREENATTR.
      * Usually, call_recv3270 follows shortly after a call to this procedure,
      * because RECV3270 is usually the first intrinsic called after TRAN3270.
     }
     procedure call_tran3270 (aid:shortint);
     begin
        write (' PRINT3270 print to file.....');
        PRINT3270 (terminalid, fileid, action, location, priority, result);
        print_message (result);
        write (' TRAN3270...................');
        TRAN3270 (terminalid, aid, cursorrow, cursorcolumn, result);
        print_message (result);
     end;

     {
      * The following procedure writes a string to the specified field
      * in the internal screen.  The variable terminalid is global and
      * is set by OPEN3270.
     }
     procedure call_writefield (outbuf:string; outbuflen, fieldnum:shortint);
     var
        offset : shortint;

     begin
        offset := 0;
        write (' WRITEFIELD..............');
        WRITEFIELD (terminalid, fieldnum, offset, outbuf, outbuflen, result);
        print_message (result);
     end;

     {
      * The following procedure calls READSCREEN to read the internal screen
      * image and output it to standard output.  The variable terminalid
      * is global and is set by OPEN3270.
     }
     procedure call_readscreen;
     var
        offset       : shortint;
        maxinbuflen  : shortint;
        actinbuflen  : shortint;
        inbuf        : screen;

     begin
        offset := 0;
        maxinbuflen := SCREENSIZE;
        inbuf := ' ';
        write (' READSCREEN.............');
        READSCREEN (terminalid, offset, maxinbuflen, inbuf, actinbuflen, result);
        print_message (result);
        writeln ('                          the screen read is shown below:')
        writeln (inbuf:actinbuflen);
     end;

     {
      * The following procedure calls ATTRLIST to find all the attribute characters
      * in the internal screen and their positions (thereby locating all the fields).
      * ATTRLIST sets the variable actlistlen, which then indicates the number of
      * fields in the screen.  The procedure then calls SCREENATTR to find the
      * number of fields, the print format, the current cursor position, and other
      * screen information.  SCREENATTR returns the number of fields through
      * the numfields parameter, which is global and is used outside of
      * this procedure after SCREENATTR sets it.  SCREENATTR's numfields parameter
      * and ATTRLIST's actlistlen parameter should contain the same value,
      * since they both represent the number of fields in the screen.
      * This procedure also calls FIELDATTR once for each field, to get
      * information about each of the fields.  Finally, it calls the call_readscreen
      * procedure to output the screen image.  The variable terminalid
      * is global and is set by OPEN3270.
     }
     procedure check_screen;
     var
     { ATTRLIST parameters }
        offset        : shortint;
        subscreensize : shortint;
        maxlistlen    : shortint;
        offsetlist    : array[1..20] of shortint;
        actlistlen    : shortint;
        fieldnum      : shortint;

     { SCREENATTR parameters }
        printformat   : shortint;
        startprint    : shortint;
        soundalarm    : shortint;
        keyboardlock  : shortint;
        screenstatus  : shortint;

     { FIELDATTR parameters }
        protectedattr   : shortint;
        currentfieldlen : shortint;
        fieldrow        : shortint;
        fieldcolumn     : shortint;
        numericattr     : shortint;
        displayattr     : shortint;
        mdt             : shortint;
        maxfieldlen     : shortint;

     begin
        writeln;
        writeln ('Checking screen.....');
        offset := 0;
        subscreensize := SCREENSIZE;
        maxlistlen := 20;

        write (' ATTRLIST.............');
        ATTRLIST (terminalid, offset, subscreensize, maxlistlen, fieldnum,
                    offsetlist, actlistlen, result);
        print_message (result);

        if actlistlen = 0 then
           writeln ('                  no attribute characters');
        else
           for fieldnum := 1 to actlistlen do
           writeln ('               attribute character #', fieldnum:1,
                    ' position = ', offsetlist[fieldnum]:2);

        write (' SCREENATTR.............');
        SCREENATTR (terminalid, printformat, startprint, soundalarm,
                    keyboardlock, numfields, screenstatus, cursorrow,
                    cursorcolumn, result);
        print_message (result);
        writeln ('              printformat = ', printformat:2,
                 '                numfields = ', numfields:2);
        writeln ('                cursorrow = ', cursorrow:2,
                 '             cursorcolumn = ', cursorcolumn:2);

        for fieldnum := 1 to numfields do
        begin
           write (' FIELDATTR ', fieldnum:1, '.............');
           FIELDATTR (terminalid, fieldnum, fieldrow, fieldcolumn,
                      protectedattr, numericattr, displayattr, mdt,
                      currentfieldlen, maxfieldlen, result);
                      print_message (result);
           writeln ('        protectedattr = ', protectedattr:2,
                    '             fieldlen = ', currentfieldlen:2);
        end;

        call_readscreen;
     end;

     {
      * The following function uses READFIELD to check all the fields of
      * the current screen for the string "READY".  This function is used
      * to tell when the host is finished sending screens.  It calls SCREENATTR
      * to get the number of fields in the screen.  SCREENATTR returns this
      * value through the parameter numfields.  The variable terminalid is
      * global and is set by OPEN3270.
     }
     function ready : boolean;
     var
        returnval      : boolean;

     { SCREENATTR parameters }
     printformat    : shortint;
        startprint     : shortint;
        soundalarm     : shortint;
        keyboardlock   : shortint;
        screenstatus   : shortint;

     { READFIELD parameters }
        fieldnum       : shortint;
        maxinbuflen    : shortint;
        actinbuflen    : shortint;
        inbuf          : string;
        offset         : shortint;

     begin
        returnval := FALSE;

        write (' SCREENATTR..............');
        SCREENATTR (terminalid, printformat, startprint, soundalarm,
                    keyboardlock, numfields, screenstatus, cursorrow,
                    cursorcolumn, result);
        print_message (result);
        writeln ('               printformat = ', printformat:2,
                 '                 numfields = ', numfields:2);
        writeln ('                 cursorrow = ', cursorrow:2,
                 '              cursorcolumn = ', cursorcolumn:2);

        offset := 0;
        maxinbuflen := LINESIZE;

        for fieldnum := 1 to numfields do
        begin
           inbuf := ' ';
           write (' READFIELD ', fieldnum:1, '................');
           READFIELD (terminalid, fieldnum, offset, maxinbuflen, inbuf,
                      actinbuflen, result);
           print_message (result);
           writeln ('        inbuf = "', inbuf:actinbuflen, '"');

           if inbuf = 'READY' then
              returnval := TRUE
        end;

        ready := returnval;
     end;

     {
      * The following procedure calls OPEN3270, simulating powering on an
      * IBM display station.  OPEN3270 assigns a value to the global variable
      * terminalid.  This value is used to reference the device in all subsequent
      * SNA IMF intrinsic calls.  This procedure also uses PRINT3270 to
      * open a spooler file, and it prints the attribute characteristic banner
      * to the file.  Note that RECV3270 must be called after a call to OPEN3270
      * to receive the unowned screen.
     }
     procedure initialize;
     var

     { VERS3270 parameter}
        version         : string;

     { OPEN3270 parameters }
        devicenum    : shortint;
        snalnkinfo   : string;
        flags        : flags_type;
        devtype      : shortint;
        ffindex      : shortint;   { not used by SNA IMF. Included }

     { for backwards compatibility. }
        screensize   : shortint;
        timeout      : packed array[1..2] of shortint;

     begin
        writeln (' VERS3270..............');
        VERS3270 (version);
        writeln ('                       version = ', version:14);
        devicenum := TERMINAL;
        snalnkinfo := 'IBMNODE#IMFCLASS ';  { non-alphanumeric character }
                                            { marks end of string }

        with flags do
        begin
           filler := 0;
           dbcs := 0;       { disable double byte character set option }
           unbind := 0;     { disable unbind option }
           LU1_LU3 := 0;    { not applicable to terminal emulation. Set to 0. }
           int_trace := 0;  { internal tracing off }
           trans_mode := 0; { transparent mode off }
           IO_mode := 0;    { standard I/O mode }
        end;

        ffindex := 0;
        timeout[1] := 30;
        timeout[2] := 30;

        writeln ('Now opening LU.T2 session.....');
        write (' OPEN3270.....................');
        OPEN3270 (devicenum, snalnkinfo, flags, terminalid, devtype,
                  ffindex, screensize, timeout, result);
        print_message (result);

        action := OPEN_FILE;   { set action to open spooler file }
        location := ' ';
        priority := 6;
        write (' PRINT3270 open...............');
        PRINT3270 (terminalid, fileid, action, location, priority, result);
        print_message (result);

        action := PRINT_BANNER;  { set action to print attribute character
        banner }
        write (' PRINT3270 print banner.......');
        PRINT3270 (terminalid, fileid, action, location, priority, result);
        print_message (result);

        action := PRINT_SCREEN;  { set action to print internal screen image }
                                 { for the rest of the PRINT3270s }
        writeln;
        writeln ('Receiving unowned screen.....');
        call_recv3270;
        check_screen;

        error := FALSE;
     end;

     {
      * The following procedure makes the major procedure calls.
      * It does the following:
      *    1. Sends a system request to the host and receives the LU-SSCP screen.
      *    2. Logs onto the host (starting an LU-LU session).  Note that
      *       after receiving the logon message, the host may send more than one
      *       screen before it is ready to receive again.
      *    3. Logs off the host.
      * Note that a call_recv3270 follows shortly after each call_tran3270.
     }
     procedure process;
     var
        outbuf     : string;
        outbuflen  : shortint;
        fieldnum   : shortint;

     begin
     { Transmit System Request Key and receive LU-SSCP screen. }
        writeln;
        writeln ('Transmitting System Request Key and receiving LU-SSCP screen');
        call_tran3270 (SYS_REQ_KEY);
        call_recv3270;
        check_screen;

     { Write logon message to LU-SSCP screen. }
        writeln;
        writeln ('Writing "logon applid...." to field 0');
        outbuf := 'logon applid(tso) data(sales/sales) logmode(imf2k)';
        outbuflen := 50;
        fieldnum := 0;
        call_writefield (outbuf, outbuflen, fieldnum);
        call_readscreen;

     { Transmit ENTER key to send logon message to host. }
        writeln;
        writeln ('Transmitting ENTER key.....');
        call_tran3270 (ENTER_KEY);

     { The host may send more than one screen here, so we have to make sure }
     { the host is finished sending before we try to send.  Function ready }
     { checks to see if the host is finished by searching for the string "READY" }
     { in the screens received from the host.  We could just as easily have }
     { waited for a RECV3270 to time out to tell us when the host was finished }
     { sending and ready to receive, but searching for "READY" is more efficient. }

        repeat
           writeln;
           writeln ('Receiving screen and checking for READY or error.....');
           call_recv3270;
        until error or ready;

        check_screen;

     { Write logoff to unprotected field. }
        outbuf := 'logoff';
        outbuflen := 6;
        fieldnum := numfields - 1;  { Write to second-to-last field }
                                    { because it's the unprotected field.    }
        if fieldnum < 0 then fieldnum := 0;
        writeln;
        writeln ('Writing "logoff" to field ', fieldnum:2, '.....');
        call_writefield (outbuf, outbuflen, fieldnum);

     { Transmit ENTER key to send logoff message to host. }
        writeln;
        writeln ('Transmitting ENTER key.....');
        call_tran3270 (ENTER_KEY);
        call_recv3270;
     end;

     {
      * The following procedure does some cleanup.  It closes the spooler file,
      * and it calls CLOSE3270, which simulates powering off the device.
     }
     procedure terminate;
     begin
        action := CLOSE_FILE;
        write (' PRINT3270 close.........');
        PRINT3270 (terminalid, fileid, action, location, priority, result);
        print_message (result);

        write (' CLOSE3270............');
        CLOSE3270 (terminalid, result);
        print_message (result);
     end;

     {
      * The following procedure calls ACQUIRE3270, starting a Pass Thru session
      * on an LU.T3 printer.  The printer must be free from MPE control    when
      * ACQUIRE3270 is called, or an error will occur.
     }
     procedure call_acquire;
     var
        snalnkinfo  : string;
        devicenum   : shortint;
        ldev        : shortint;
        enhance     : shortint;
        priority    : shortint;
        blanks      : shortint;
        format      : shortint;
        flags       : shortint;
        options     : options_type;
        pfn         : string;
     begin
        snalnkinfo := 'IBMNODE#IMFCLASS ';  { non-alphanumeric character }
                                            { marks end of string }
        devicenum := LU_T3;
        ldev := SPOOLER_FILE;
        enhance := 0;
        priority := 6;
        blanks := 0;    { convert leading blanks to nulls }
        format := 2;    { print screen as it appears on terminal }
        flags := 2;     { continue execution after Pass Thru is activated }

        with options do
        begin
           filler := 0;
           int_trace := 1;   { internal trace on }
           sPriority := 7;   { spooler file priority = 7 }
           readTO := 15;     { terminal timeout, not used in this case }
           LJ2 := 1;         { LaserJet II option is on }
        end;

        pfn := 'example ';   { non-alphanumeric character marks end of string }

        writeln ('Now starting Pass Thru session with spooler file.....');
        write (' ACQUIRE3270........');
        ACQUIRE3270 (snalnkinfo, devicenum, ldev, enhance, priority,
                     blanks, format, flags, options, pfn, result);
        print_message (result);

     end;

     begin  { main }
        if parm > 0 then
           call_acquire
        else begin
           initialize;
           process;
           terminate;
        end;
     end.



MPE/iX 5.0 Documentation