HPlogo SNA IMF Programmer's Reference Manual: HP 3000 MPE/iX Computer Systems > Appendix F Sample Programs

Sample Program in Transparent Mode

» 

Technical documentation

» Feedback

 » Table of Contents

 » Glossary

 » Index

This program emulates a display station (LU Type 2) powering on, logging onto the host, logging off, and powering off. Note that, in transparent mode, although there is still an internal screen image, intrinsics that access the fields in the internal screen image (such as READFIELD and WRITEFIELD) are not allowed. The internal screen image is used to store the untranslated data stream received from or waiting to be sent to the host.

program imftran (input, output);const   SCREENSIZE    = 2160;  { in transparent mode, a 1920-character }                          { screen has a buffer limit of 2160 bytes. }   LINESIZE       = 80;   EBCDICtoASCII  = 1;   ASCIItoEBCDIC  = 2;{ constant for OPEN3270 }   TERMINAL       = -2;{ constants for AID of TRAN3270 }   SYS_REQ_KEY    = 48;   ENTER_KEY      = 39;   CLEAR_KEY      = 95;type   shortint       = -32768..32767;   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 }{ 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 }   offset         : shortint;  { current offset in data stream }   numfields      : shortint;  { number of fields in the current screen }   error          : boolean;   { global error flag }procedure VERS3270;     intrinsic;procedure ERR3270;      intrinsic;procedure CLOSE3270;    intrinsic;procedure OPEN3270;     intrinsic;procedure READSTREAM;   intrinsic;procedure RECV3270;     intrinsic;procedure TRAN3270;     intrinsic;procedure WRITESTREAM;  intrinsic;procedure CTRANSLATE;   intrinsic;   { MPE intrinsic that provides }                                     { EBCDIC/ASCII conversions }
{ * 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 data * from the host and buffer it in the internal screen image.  The variable * terminalid is global and is set by OPEN3270.}procedure call_recv3270;begin   write (' RECV3270.........');   RECV3270 (terminalid, result);   print_message (result);end;{ * The following procedure calls TRAN3270.  The variable terminalid * is global and is set by OPEN3270.}procedure call_tran3270 (aid : shortint);var   cursorrow    : shortint;   cursorcolumn : shortint;begin   cursorrow := -1;   cursorcolumn := -1;  { suppress sending cursor address in transparent mode }   write (' TRAN3270............');   TRAN3270 (terminalid, aid, cursorrow, cursorcolumn, result);   print_message (result);end;
{ * The following procedure calls READSTREAM to read the data stream * received from the host.  It also calls the MPE V intrinsic CTRANSLATE * to translate the data from EBCDIC to ASCII.  Note that a RECV3270 call * must be made prior to each call to READSTREAM.  RECV3270 stores data * from the host in the internal screen image, while READSTREAM * retrieves the data.  So, a call to RECV3270 and a call to READSTREAM * must be made for each RU received.  This procedure also sets the * offset variable to the length of the data stream.  This value is used as * the offset in the next call to WRITESTREAM.  The variable terminalid * is global and is set by OPEN3270.}procedure call_readstream (var offset: shortint);var   read_offset  : shortint;   maxinbuflen  : shortint;   inbuf        : screen;   actinbuflen  : shortint;begin   read_offset := 0;   maxinbuflen := SCREENSIZE;   write (' READSTREAM.............');   READSTREAM (terminalid, read_offset, maxinbuflen, inbuf,               actinbuflen, result);   print_message (result);   writeln ('                the data sent is shown below:');   CTRANSLATE (EBCDICtoASCII, inbuf, inbuf, actinbuflen, );                 { An optional parameter has been omitted, so the comma }                 { after the actinbuflen parameter is necessary. }                 { The same variable may be used for the input and output }                 { to the CTRANSLATE intrinsic. }   writeln (inbuf:actinbuflen);   offset := actinbuflen;  { set offset for the next call to WRITESTREAM }end;
{ * The following procedure uses CTRANSLATE to * translate the data from ASCII to EBCDIC.  Then, it calls WRITESTREAM * to put the data into the internal screen image.  The data will be sent * when TRAN3270 gets called from procedure call_tran3270. * When data is sent to the SSCP, the internal screen image is searched, * beginning at the initial cursor address (where the cursor was left * after the previous host message).  Therefore, during the LU-SSCP session, * the offset must be set to the length of the previous data stream received. * The offset value is set from the previous call to call_readstream. * The variable terminalid is global and is set by OPEN3270.}procedure call_writestream (outbuf:string; outbuflen, offset: shortint);begin   CTRANSLATE (ASCIItoEBCDIC, outbuf, outbuf, outbuflen,)                 { An optional parameter has been omitted, so the comma }                 { after the outbuflen parameter is necessary. }                 { The same variable may be used for the input and output }                 { to the CTRANSLATE intrinsic. }   write (' WRITESTREAM............');   WRITESTREAM (terminalid, offset, outbuflen, outbuf, result);   print_message (result);end;
{ * The following function calls READSTREAM to get the data received * from the host and CTRANSLATE to translate it.  READSTREAM reads the data * from the internal screen image and writes it to inbuf.  CTRANSLATE * reads data from inbuf, translates it, and writes the translated data * back into inbuf.  The function then searches the translated data for the * string "READY".  The variable terminalid is global and is set by OPEN3270.}function ready : boolean;var   read_offset     : shortint;   maxinbuflen     : shortint;   actinbuflen     : shortint;   inbuf           : screen;   inbuf_offset    : shortint;   word            : packed array[1..5] of char;   i               : shortint;   done            : boolean;begin   read_offset := 0;   maxinbuflen := SCREENSIZE;   inbuf := ' ';   write (' READSTREAM...........');   READSTREAM (terminalid, read_offset, maxinbuflen, inbuf,               actinbuflen, result);   print_message (result);   writeln ('               the data sent is shown below:');   CTRANSLATE (EBCDICtoASCII, inbuf, inbuf, actinbuflen, );                 { An optional parameter has been omitted, so the comma }                 { after the actinbuflen parameter is necessary. }                 { The same variable may be used for the input and output }                 { to the CTRANSLATE intrinsic. }   writeln (inbuf:actinbuflen);   inbuf_offset := 0;   done := FALSE;   ready := FALSE;@COMPUTERTEXTW =    while not done do   begin{ search for 'R' }      while (inbuf_offset << actinbuflen) and (inbuf[inbuf_offset + 1] <<>> 'R') do         inbuf_offset := inbuf_offset + 1;      if inbuf_offset <<= (actinbuflen - 5) then      begin{ copy candidate string into word }         for i := 1 to 5 do            word[i] := inbuf[inbuf_offset + i];{ check whether the string is "READY" }         if word = 'READY' then         begin            ready := TRUE;            done := TRUE;         end;inbuf_offset := inbuf_offset + 1;      end      else done := TRUE;   end;  { while }end;
{ * The following procedure calls OPEN3270, simulating turning 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.  Note that RECV3270 must be called after a call * to OPEN3270 to receive the unowned screen.}procedure initialize;var   version     : string;   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 }      LUT1_LUT3 := 0;  { not applicable to terminal emulation. Set to 0 }      int_trace := 0;  { internal tracing off }      trans_mode := 1; { transparent mode on }      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);   writeln;   writeln ('Receiving unowned screen.....');   call_recv3270;   call_readstream (offset);   error := FALSE;end;@COMPUTERTEXTW = { * 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. Clears the screen and logs off the host. * Note that a call_recv3270 follows shortly after each call_tran3270.}procedure process;var   offset          : shortint;   total_offset    : shortint;   outbuf          : string;   outbuflen       : shortint;begin{ Transmit System Request Key and receive untranslated LU-SSCP screen. }   writeln;   writeln ('Transmitting System Request Key and receiving screen.....');   call_tran3270 (SYS_REQ_KEY);   call recv3270;   call_readstream (offset);{ Write logon data stream to internal screen image. }   writeln;   writeln ('Writing "logon applid....."');   outbuf := 'logon applid(tso) data(sales/sales) logmode(imf2k)';   outbuflen := 50;   call_writestream (outbuf, outbuflen, offset);{ Transmit ENTER key to send logon message to host. }   writeln;   writeln ('Transmitting ENTER key.....');   call_tran3270 (ENTER_KEY);   offset := 0;@COMPUTERTEXTW = { The host may send more than one RU here, so we have to make sure the }{ host is finished sending before we try to send.  The function ready }{ checks whether the host is finished sending by searching for the string }{ "READY" in the data 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;{ Transmit CLEAR key to host and receive cleared screen from host. }   call_tran3270 (CLEAR_KEY);   call_recv3270;   call_readstream (offset);{ Write logoff to internal screen image. }   outbuf := 'logoff';   outbuflen := 6;   writeln;   writeln ('Writing "logoff" to screen.....');   call_writestream (outbuf, outbuflen, offset);{ Transmit ENTER key to send logoff message to host. }   writeln;   writeln ('Transmitting ENTER key.....');   call_tran3270 (ENTER_KEY);end;@COMPUTERTEXTW = { * The following procedure calls CLOSE3270, * which simulates turning off the device.}procedure terminate;begin   write (' CLOSE3270...........');   CLOSE3270 (terminalid, result);   print_message (result);end;begin  { main }   initialize;   process;   terminate;end.
Feedback to webmaster