RFC 1647

TN3270 Enhancements

πŸ“… published July 1994, from ietf

RFC 1647: TN3270 Enhancements πŸŽ€

Okay bestie, this is RFC 1647, and it's called TN3270 Enhancements πŸ¦‹. It's from July 1994 and it's by B. Kelly at Auburn University πŸŽ“, in the Network Working Group. It's a Standards Track doc, so it's aiming to become a real Internet standard πŸ’…. The title block doesn't list anything it obsoletes or updates, so it isn't replacing or patching any earlier RFC 🧚

Status of this Memo ✨

So this doc specifies an Internet standards track protocol for the Internet community, and it's literally asking for discussion and suggestions for improvements 🫢 If you want the current standardization state and status of this protocol, check the current edition of "Internet Official Protocol Standards" (STD 1). And distribution of this memo is unlimited, so share away πŸ’–

Abstract 🌸

This doc describes a protocol that supports 3270 devices way more fully than the existing tn3270 practices do πŸ”₯ It defines how to emulate both the terminal and printer members of the 3270 family over Telnet πŸ–¨οΈ It also lets a Telnet client ask to be assigned a specific device-name (also called the "LU name" or "network name") 🎯 And it adds support for a bunch of functions, like the ATTN key, the SYSREQ key, and SNA response handling. Iconic πŸ‘‘

This protocol would be negotiated and implemented under a new Telnet Option, and it would be totally unrelated to the Telnet 3270 Regime Option defined in RFC 1041 [1] πŸ¦‹

Table of Contents πŸ’œ

   1.  Introduction ...............................................  2
   2.  TN3270E OVERVIEW ...........................................  3
   3.  COMMAND NAMES AND CODES ....................................  4
   4.  COMMAND MEANINGS ...........................................  5
   5.  DEFAULT SPECIFICATION ......................................  6
   6.  MOTIVATION .................................................  7
   7.  TN3270E SUB-NEGOTIATION RULES ..............................  7
      7.1  DEVICE-TYPE Negotiation ................................  7
          7.1.1 Device Pools ......................................  8
          7.1.2 CONNECT Command ...................................  9
          7.1.3 ASSOCIATE Command ................................. 10
          7.1.4 Device Selection Rules ............................ 10
          7.1.5 Accepting a Request ............................... 11
          7.1.6 REJECT Command .................................... 12
      7.2  FUNCTIONS Negotiation .................................. 13
          7.2.1 Commands .......................................... 13
          7.2.2 List of TN3270E Functions ......................... 14
   8.  TN3270E DATA MESSAGES ...................................... 15
      8.1  The TN3270E Message Header ............................. 16
          8.1.1 DATA-TYPE Field ................................... 16
          8.1.2 REQUEST-FLAG Field ................................ 17
          8.1.3 RESPONSE-FLAG Field ............................... 17
          8.1.4 SEQ-NUMBER Field .................................. 18
   9.  BASIC TN3270E .............................................. 18
      9.1  3270 Mode and NVT Mode ................................. 19
   10. DETAILS OF PROCESSING TN3270E FUNCTIONS .................... 20
      10.1 The SCS-CTL-CODES Function ............................. 20
      10.2 The DATA-STREAM-CTL Function ........................... 20
      10.3 The BIND-IMAGE Function ................................ 21
      10.4 The RESPONSES Function ................................. 22
         10.4.1 Response Messages ................................. 23
      10.5 The SYSREQ Function .................................... 26
         10.5.1 Background ........................................ 26
         10.5.2 TN3270E Implementation of SYSREQ .................. 27
   11. THE 3270 ATTN KEY .......................................... 28
   12. 3270 STRUCTURED FIELDS ..................................... 29
   13. IMPLEMENTATION GUIDELINES .................................. 29
      13.1 3270 Data Stream Notes ................................. 29
      13.2 Negotiation of the TN3270E Telnet Option ............... 30
      13.3 A "Keep-alive" Mechanism ............................... 30
      13.4 Examples ............................................... 31
   14. SECURITY CONSIDERATIONS .................................... 33
   15. REFERENCES ................................................. 33
   16. AUTHOR'S NOTE .............................................. 34
   17. AUTHOR'S ADDRESS ........................................... 34

1. Introduction 🧚

Right now, 3270 terminal emulation over Telnet works through a de facto standard, which is just negotiating three separate Telnet Options: Terminal-Type [2], Binary Transmission [3], and End of Record [4]. Here's the tea β˜• There's no RFC that actually specifies this negotiation as a standard. RFC 1041 tried to standardize it by defining the 3270 Regime Telnet Option, but very few developers and vendors ever implemented RFC 1041 😭

This doc is going to call the existing practice of negotiating those three Telnet Options before exchanging the 3270 data stream "traditional tn3270" πŸ’…

NOTE: Except where otherwise stated, this document does not distinguish between Telnet servers that represent SNA devices and those that represent non-SNA 3270 devices.

Anything in this document about the 3270 data stream, 3270 data stream commands, orders, structured fields, and the like relies on [5]. References to SNA Request and Response Units rely on [6]. And references to SNA versus non-SNA operation rely on [7] πŸ“š

Traditional tn3270 has some real shortcomings, though, and here they are 😀

  • It gives Telnet clients no way to emulate the 328x class of printers. πŸ–¨οΈ
  • There's no mechanism for a Telnet client to ask that its connection be associated with a given 3270 device-name. This matters when a terminal session is being set up, because lots of host applications act differently depending on the network name of the terminal πŸ‘€ For printer emulation it's an absolute necessity, since a ton of host applications pre-define printer destinations.
  • The 3270 ATTN and SYSREQ keys aren't universally supported. πŸ™ˆ
  • There's no support for the SNA positive/negative response process. This is a big deal if printer emulation is going to work properly, but it's also useful for some terminal applications. A positive response says the previously received data was successfully processed. A negative response says some kind of error happened while processing it. That error could come from the host application building a 3270 data stream with an invalid command, or from a mechanical error on the client side, among other things πŸ’€
  • There's no mechanism for the client to access the SNA Bind information. The Bind image has a detailed description of the session between the Telnet server and the host application 🧠
  • There's no mechanism for the server to figure out whether a client supports 3270 structured fields, or for a client to ask to receive them 🫠

2. TN3270E Overview πŸ¦‹

To fix all of this, the doc proposes a brand new Telnet Option called TN3270E πŸŽ€ Telnet clients and servers are free to negotiate support for TN3270E or not. If either side doesn't support TN3270E, they can just use traditional tn3270. Otherwise, a sub-negotiation happens to figure out which subset of TN3270E will be used on the session. The expectation is that a client or server that can do both types of 3270 emulation will try TN3270E first, and only fall back to traditional tn3270 if the other side refuses TN3270E 🌈

Once a client and server have agreed to use TN3270E, they can start negotiating the TN3270E suboptions. The two main pieces of TN3270E sub-negotiation are:

  • a device-type negotiation, which is similar to the existing Telnet Terminal-Type Option but a bit more complicated 🧩
  • negotiating a set of supported 3270 functions, like the printer data stream type (3270 data stream or SNA Character Stream), positive/negative response exchanges, device status information, and passing BIND information from server to client πŸ”₯

When those two suboptions are successfully negotiated, 3270 data stream transmission officially begins ✨ To support several of the new TN3270E functions, every data message has to be prefixed by a header. That header holds flags and indicators that convey things like positive and negative responses, and what type of data follows the header (for example, 3270 data stream, SNA Character Stream, or device status information) πŸ“

3. Command Names and Codes πŸ’…

Here's the full list of command names, reason codes, and function names, straight from the spec. Keep these exact, bestie 🫢

       TN3270E            40
         ASSOCIATE          00
         CONNECT            01
         DEVICE-TYPE        02
         FUNCTIONS          03
         IS                 04
         REASON             05
         REJECT             06
         REQUEST            07
         SEND               08

       Reason-codes
         CONN-PARTNER       00
         DEVICE-IN-USE      01
         INV-ASSOCIATE      02
         INV-DEVICE-NAME    03
         INV-DEVICE-TYPE    04
         TYPE-NAME-ERROR    05
         UNKNOWN-ERROR      06
         UNSUPPORTED-REQ    07

       Function Names
         BIND-IMAGE         00
         DATA-STREAM-CTL    01
         RESPONSES          02
         SCS-CTL-CODES      03
         SYSREQ             04

4. Command Meanings πŸ’–

okay so this is where we get into what each command actually says 🫢 Here are the four basic option commands:

IAC WILL TN3270E

πŸ¦‹ The sender is willing to send TN3270E information in later sub-negotiations.

IAC WON'T TN3270E

πŸ™ˆ The sender refuses to send TN3270E information. Not me saying no πŸ’…

IAC DO TN3270E

✨ The sender is willing to receive TN3270E information in later sub-negotiations.

IAC DON'T TN3270E

πŸ’€ The sender refuses to receive TN3270E information. Bestie, the energy is so clear 😭

Quick tea β˜•: these four aren't explicitly negotiated, but the Telnet Binary Transmission Option [3] and the Telnet End of Record Option [4] are implied by TN3270E. So if a party agrees to support TN3270E, it's automatically on the hook for bi-directional binary and EOR transmissions. No opting out, periodt 🌸

Now the sub-negotiation commands, the real main character stuff πŸ‘‘

IAC SB TN3270E SEND DEVICE-TYPE IAC SE

🧚 Only the server can send this one. It asks the client to send over a device-type and, optionally, a device-name.

IAC SB TN3270E DEVICE-TYPE REQUEST <device-type>
          [CONNECT | ASSOCIATE <device-name>] IAC SE

πŸŽ€ Only the client can send this. It's the reply to the server's SEND DEVICE-TYPE, and it's also how the client suggests a different device-type after the server has sent a DEVICE-TYPE REJECT. It asks to emulate a specific 3270 device type and model. The REQUEST can optionally carry either CONNECT or ASSOCIATE, but not both. If either one shows up, it has to be followed by a <device-name>. (Check the section called "DEVICE-TYPE Negotiation" for the full tea β˜•)

IAC SB TN3270E DEVICE-TYPE IS <device-type> CONNECT
          <device-name> IAC SE

🌈 Only the server sends this. It accepts the client's DEVICE-TYPE REQUEST and hands back the server-defined device-name.

IAC SB TN3270E DEVICE-TYPE REJECT REASON <reason-code> IAC SE

πŸ₯€ Only the server sends this. It rejects the client's DEVICE-TYPE REQUEST. Ouch, but it happens 😭

IAC SB TN3270E FUNCTIONS REQUEST <function-list> IAC SE

πŸ“ Either side can send this one. It suggests a set of 3270 functions for this session. It also doubles as an implicit rejection of a FUNCTIONS REQUEST the other side sent earlier (see the section called "FUNCTIONS Negotiation" for more). Important bit πŸ”₯: when it's being used to reject, the function-list must not be identical to the one in the previous REQUEST.

IAC SB TN3270E FUNCTIONS IS <function-list> IAC SE

πŸ’œ Either side can send this too. It's the response to a FUNCTIONS REQUEST and means "yep, I accept everything you sent." The list in FUNCTIONS IS has to match the list from the previous FUNCTIONS REQUEST. Matching is everything, bestie 🫢


5. Default Specification 🌸

If nobody negotiates anything, the defaults are basically a big no-thank-you πŸ™…β€β™€οΈ

WON'T TN3270E
DON'T TN3270E

Translation: TN3270E will not be used. Bye bye, TN3270E πŸ‘‹

6. Motivation πŸ¦‹

See the section called "Introduction" πŸ’…

7. TN3270E Sub-negotiation Rules πŸŽ€

okay now the rules for how the sub-negotiations go down ✨ All TN3270E commands and parameters are NVT ASCII strings, and upper and lower case count as the same thing. So no drama about capitalization πŸ™ˆ

Once both sides agree TN3270E is happening, the very first sub-negotiation has to be about DEVICE-TYPE (and maybe DEVICE-NAME). Only after that's successfully sorted can the client and server swap FUNCTIONS info. And only after both DEVICE-TYPE and FUNCTIONS are settled can the 3270 data stream start flowing 🌊 It's giving strict order, and I'm here for it πŸ’–

7.1 DEVICE-TYPE Negotiation 🧚

Device-type (and device-name) negotiation kicks off when the server sends the DEVICE-TYPE SEND command. The client replies with DEVICE-TYPE REQUEST, which must include a device-type and may include a device-name request.

Here are the valid device-types πŸ‘‘

 terminals: IBM-3278-2  IBM-3278-2-E  (24 row x 80 col display)
            IBM-3278-3  IBM-3278-3-E  (32 row x 80 col display)
            IBM-3278-4  IBM-3278-4-E  (43 row x 80 col display)
            IBM-3278-5  IBM-3278-5-E  (27 row x 132 col display)
            IBM-DYNAMIC            (no pre-defined display size)

  printers: IBM-3287-1

Now, the tea about the '3278' and '3287' names 🍡: they are NOT meant to exclude any device capabilities πŸ™…β€β™€οΈ They're just commonly known labels for a terminal and a printer in the 3270 family. The whole point is to make negotiation simpler than traditional tn3270 by keeping the number of device-types small, and to break the link between a specific IBM machine and a fixed set of data stream capabilities. For example, negotiating IBM-3278-2-E does NOT, all by itself, rule out any functions from a physical 3279 model S2B. Honestly the mood is "don't judge a device by its label." A client's advanced 3270 data stream abilities are shown not by picking an IBM device type and model number, but by the combo of Read Partition Query and Query Reply ✨

Every terminal device-type supports a "primary" display size of 24 rows by 80 columns πŸ’… The "-3", "-4" and "-5" types also each support an "alternate" display size, as listed above. IBM-DYNAMIC means no pre-defined alternate size. Instead, that size gets passed from the client to host applications inside the Query Reply structured field, and it can be any size the client and host application can both handle 🌈

Terminal device-types with the "-E" suffix should only be negotiated by clients willing to support some part of the 3270 "extended data stream." That usually means at least extended colors and highlighting, but it can also include other stuff like graphics, alternate character sets, and partitions. Iconic range πŸ”₯

Clients that negotiate an "-E" terminal type, or the DYNAMIC type, plus any printer device-type, must be able to accept and respond to a Read Partition Query command (see the section called "3270 Structured Fields"). This is how the client tells host applications which parts of the 3270 extended data stream it's willing to support 🫢

In a VTAM/SNA environment, negotiating IBM-DYNAMIC as the device-type should result in a Bind where the Presentation Services Usage screen field (the eleventh byte in the logmode's PSERVIC field) is set to 0x03. That tells you the alternate screen size will be figured out by the Query Reply (Usable Area) 🧠

7.1.1 Device Pools πŸŠβ€β™€οΈ

Okay so before we can get into CONNECT and ASSOCIATE, we need the tea on how the server organizes its terminal and printer device pools β˜• It's the stuff the server picks device-names from when it's assigning session requests. (Quick note: "device-name," "LU name," and "network name" are all interchangeable in this doc πŸ’–) Also, for this part of the convo, a "generic session request" is a request for a session from a Telnet client (traditional or TN3270E) that does not ask for a specific device-name. A "specific session request" is a TN3270E client asking for a particular device-name, either with CONNECT or ASSOCIATE πŸŽ€

Same as traditional tn3270, the TN3270E server has to maintain a set of terminal device-names. A generic terminal request gets any available name from this pool. The server can also keep a separate pool of terminal device-names that are only used for specific terminal requests. Why? So a terminal that matters to host applications (and so is likely to be asked for by name) doesn't get "accidentally" handed to a generic request and end up with a client that has no use for it πŸ™ˆ Note that the reverse is allowed too: a specific terminal request can ask for a name that happens to be in the "generic terminal pool." Pool life, no rules broken 🌸

For each terminal device (in both the "generic" and "specific" pools), the TN3270E server could also define a "partner" or "paired" printer device. There should be a unique, one-to-one mapping between a terminal and its printer πŸ¦‹ The reason for this setup is so host applications that print can send output to a printer whose name is determined by the terminal that started the print job. These printers can only be assigned to specific printer requests that use ASSOCIATE (see below) 🧚

The server may also keep a pool of printer device-names that aren't tied to any terminal. These can only be assigned to specific printer requests that use CONNECT (see below). This helps host applications whose print destination is set by something other than the terminal, for example when the userid of the person signed on to a terminal decides where the printing goes πŸ’œ

Finally, a pool of printer device-names could be kept and used only for generic printer requests. That's the last option, and it's giving flexibility 🌈

7.1.2 CONNECT Command πŸ”Œ

CONNECT is how the client asks the server to give this Telnet session a specific device-name. It can be used when requesting either a terminal or a printer session. The device-name has to match the device-type. Like, if the client requests DEVICE-TYPE IBM-3287-1 (a printer) and asks for CONNECT T1000001, but T1000001 is defined at the host as a terminal, then the server should deny the request πŸ™…β€β™€οΈ Also, if the requested device-name is already tied to some other Telnet session, or if it isn't defined to the server at all, the server should deny the request too πŸ’€ Not the vibe.

7.1.3 ASSOCIATE Command ✨

okay bestie, so ASSOCIATE can only be used by the client when it's requesting a DEVICE-TYPE that represents a printer πŸ–¨οΈ no wait, I mean a printer, period πŸ’… The ASSOCIATE command asks for this session to get the device-name of the printer that's paired with the terminal named in the request ✨ If the device-type isn't a printer, or the device-name isn't a terminal, the server SHOULD deny the request πŸ™ˆ The device-name in this request is expected to be one the server handed back earlier when it accepted a terminal session request (see the IS command below) πŸ¦‹ There's no authentication mechanism defined, so the printer paired with that terminal might already be assigned to some other Telnet session πŸ’€ If that's the case, the server SHOULD deny the request too 😭

7.1.4 Device Selection Rules

okay so let's recap with a little pool picture, because this part is lowkey the most confusing bit πŸŽ€ Say a TN3270E server has these device pools defined to it. Device-names starting with a "T" are terminals, and ones starting with a "P" are printers 🌸

  Generic Terminal Pool              Specific Terminal Pool
  ---------------------              ----------------------
  TG000001 <--> PTG00001             TS000001 <--> PTS00001
  TG000002 <--> PTG00002             TS000002 <--> PTS00002
  TG000003 <--> PTG00003             TS000003 <--> PTS00003

  Generic Printer Pool               Specific Printer Pool
  --------------------               ----------------------
       PG000001                            PS000001
       PG000002                            PS000002
       PG000003                            PS000003

Here's the big thing πŸ‘‘ The ONLY pool that absolutely MUST be defined to the server is the generic terminal pool 🧚 If the other pools (or the partner printers for a terminal pool) are missing, the server just can't handle as wide a range of requests as it could if everything were set up πŸ’œ

Given that setup, these rules apply:

  • A generic terminal request can ONLY be satisfied from the generic terminal pool (device-names TG000001 - TG000003) πŸ“
  • A specific terminal request (only allowed via the CONNECT command) can be satisfied from either the generic or the specific terminal pool 🌈 Realistically, most of these requests will ask for terminals in the specific terminal pool (TS000001 - TS000003) ✨
  • A generic printer request can ONLY be satisfied from the generic printer pool (device-names PG000001 - PG000003) 🩷
  • A specific printer request can come in two flavours πŸ¦‹
    • via ASSOCIATE: the request can only be satisfied using the partner of the specified terminal, and that terminal can be in the generic or the specific terminal pool. So devices in the ranges PTG00001 - PTG00003 and PTS00001 - PTS00003 can satisfy it 🫢
    • via CONNECT: the request can be satisfied from either the generic or the specific printer pools (though, like specific terminal requests, most will probably name printers in the specific printer pool πŸ’…). This request can NOT be satisfied by the partner printer of a terminal in either the specific or the generic terminal pools πŸ’€

7.1.5 Accepting a Request

The server MUST accept the client's request or deny it as a whole πŸ”₯ It can't, for example, accept the DEVICE-TYPE request and then deny the CONNECT part πŸ™…β€β™€οΈ

If the server wants to accept, it sends back the DEVICE-TYPE IS command confirming the requested device-type, plus the CONNECT command with the device-name of the terminal or printer assigned to this Telnet session πŸŽ€ That device-name might be the one the client asked for directly (via CONNECT), the one it asked for indirectly (via ASSOCIATE), or one the server picks itself if the client specified neither 🧚

7.1.6 REJECT Command

If the server wants to deny the request, it sends back the DEVICE-TYPE REJECT command with one of these reason-codes πŸ’–

Reason code name         Explanation
----------------         -----------------------------------
INV-DEVICE-TYPE          The server does not support the
                         requested device-type.

INV-DEVICE-NAME          The device-name specified in the
                         CONNECT or ASSOCIATE command is
                         not known to the server.

DEVICE-IN-USE            The requested device-name is
                         already associated with another
                         Telnet session.

TYPE-NAME-ERROR          The requested device-name is
                         incompatible with the requested
                         device-type (such as terminal/
                         printer mismatch).

UNSUPPORTED-REQ          The server is unable to satisfy
                         the type of request sent by the
                         client; e.g., a specific terminal
                         or printer was requested but the
                         server does not have such a pool of
                         device-names defined to it, or the
                         ASSOCIATE command was used but no
                         partner printers are defined to the
                         server.

INV-ASSOCIATE           The client used the ASSOCIATE
                         command and either the device-type
                         is not a printer or the device-name
                         is not a terminal.

CONN-PARTNER             The client used the CONNECT command
                         to request a specific printer but
                         the device-name requested is the
                         partner to some terminal.

UNKNOWN-ERROR            Any other error in device type or
                         name processing has occurred.

Negotiating a device-type and device-name that both sides are happy with can take a few rounds of DEVICE-TYPE REQUEST and DEVICE-TYPE REJECT 🌸 The client SHOULD use the reason-code the server sends back in any DEVICE-TYPE REJECT to cut down on how much negotiating it has to do 🧠 For example, if the client first asks for a specific terminal device-name via CONNECT and the server rejects it with UNSUPPORTED-REQ, the client SHOULD make no more specific terminal requests during the negotiation 😭 And if either side wants to "bail out" at any point, it can just send a WON'T (or DON'T) TN3270E command to the other side πŸ¦‹ After that, both sides are free to negotiate other Telnet options (including traditional tn3270) 🌈

7.2 FUNCTIONS Negotiation

Once DEVICE-TYPE negotiation has successfully finished (that is, when the client receives the DEVICE-TYPE IS command), the client SHOULD start FUNCTIONS negotiation by sending a FUNCTIONS REQUEST command to the server ✨ After that first REQUEST, both sides are free to send FUNCTIONS REQUEST and FUNCTIONS IS commands whenever they need to πŸ’…

7.2.1 Commands

The FUNCTIONS REQUEST command has a list of the 3270 functions the sender would like supported on this session πŸŽ€ Any function NOT in the list is considered unsupported πŸ’€ The function-list is a string of 2-byte entries, each separated from the next by a single space character πŸ¦‹ The list ends with the IAC code that comes right before the SE command 🌸 Functions can show up in any order 🫢

When a recipient gets a FUNCTIONS REQUEST command, it has two options πŸ”₯

  • It can agree πŸ₯° by sending back FUNCTIONS IS with the function-list exactly as it was received. It's agreeing to support every function in the list and not to send any data related to functions outside it. Once that happens, FUNCTIONS negotiation has successfully completed ✨
  • It can disagree πŸ™ƒ by sending a FUNCTIONS REQUEST command where the function-list is different from the one it received. The difference has to be more than just the order of the functions, so at least one function must have been added to or removed from the list πŸ’œ

To avoid endless looping, neither party SHOULD add to the function-list it receives any function that it previously added and the other side removed πŸŒ€

Back and forth FUNCTIONS REQUEST commands keep going until one side gets a function-list it can live with πŸ’– That side uses FUNCTIONS IS to accept the list, and once the other side receives that command, all the necessary negotiation is done πŸŽ‰ Only then can 3270 data stream transmission begin πŸš€

It's possible the function-list agreed on ends up null, and that's called "basic TN3270E" 🧚 Check the section called "Basic TN3270E" for more details 🌷

7.2.2 List of TN3270E Functions

Here's a quick rundown of the 3270 functions that can be negotiated in the function-list πŸ‘‘

Function Name       Description
-------------       -----------
SCS-CTL-CODES       (Printer sessions only).  Allows the use
                    of the SNA Character Stream (SCS) and SCS
                    control codes on the session.  SCS is
                    used with LU type 1 SNA sessions.

DATA-STREAM-CTL     (Printer sessions only).  Allows the use
                    of the standard 3270 data stream.  This
                    corresponds to LU type 3 SNA sessions.

RESPONSES           Provides support for positive and
                    negative response handling.  Allows the
                    server to reflect to the client any and
                    all definite, exception, and no response
                    requests sent by the host application.

BIND-IMAGE          Allows the server to send the SNA Bind
                    image and Unbind notification to the
                    client.

SYSREQ              Allows the client and server to emulate
                    some (or all, depending on the server) of
                    the functions of the SYSREQ key in an SNA
                    environment.

8. TN3270E Data Messages ✨

Okay so the big question is how 3270 devices even talk to each other, and bestie, it's giving "wait for the whole outfit before you show up" energy πŸ’…. Each side collects data in a buffer until an entire "message" is built, and only then does it get sent. The "outbound message" (host to device) is a 3270 command plus a bunch of buffer orders, buffer addresses, and data. The "inbound message" is just the buffer orders, addresses, and data, no command at the front πŸŽ€. A message ends at the last byte that gets transmitted (fyi, this discussion ignores SNA chaining, so we're not going there πŸ™ˆ). The Telnet EOR command is what marks off these natural chunks of 3270 data inside the Telnet data stream πŸ¦‹.

In TN3270E, every 3270 message MUST be prefixed with a TN3270E header. The header is five bytes, and the format is spelled out below (look at the section called "The TN3270E Message Header") 🌸.

So a "data message" in TN3270E looks like this:

<TN3270E Header><data><IAC EOR>

Heads up, though: for certain message types there might not be any data portion at all. When that happens, the TN3270E data message is just:

<TN3270E Header><IAC EOR>

If either side wants the decimal value 255 to be treated as data, it MUST "double" that byte. Basically, one 255 gets read by the other side as an IAC, but two 255s in a row get read as one data byte with the value 255 🧚.

Telnet commands (other than IAC IAC) SHOULD be sent between TN3270E data messages, with no header and no trailing IAC EOR. If a TN3270E data message contains IAC IP (which gets read as 3270 Attention) or IAC AO (which gets read as SYSREQ), the receiver SHOULD defer processing that command until the 3270 data has been processed. (Check the sections on 3270 Attention and SYSREQ for the juicy details πŸ‘‘.) If a TN3270E data message contains any other IAC-command sequence (other than IAC IAC), it's implementation dependent when that sequence gets processed, but it MUST be processed. The receiver MAY process it right away, which basically means it gets handled as if it arrived before the current TN3270E data message. Or the processing can wait until after the current TN3270E data message is done. This is exactly why having Telnet commands sitting inside a TN3270E data message (that is, between the header and the trailing IAC EOR) is NOT RECOMMENDED. Neither clients nor servers SHOULD send such data πŸ™ˆπŸ’€.

8.1 The TN3270E Message Header

As we said earlier, every data message in TN3270E MUST be prefixed by a header. The header is five bytes and looks like this πŸ’–:

-----------------------------------------------------------
| DATA-TYPE | REQUEST-FLAG | RESPONSE-FLAG |  SEQ-NUMBER  |
-----------------------------------------------------------
   1 byte        1 byte         1 byte         2 bytes

8.1.1 DATA-TYPE Field

The DATA-TYPE field tells the receiver how to read the data portion of the message. These are the possible values 🌈:

Data-type Name   Code                Meaning
--------------   ----   ---------------------------------
3270-DATA        0x00   The data portion of the message
                        contains only the 3270 data stream.

SCS-DATA         0x01   The data portion of the message
                        contains SNA Character Stream data.

RESPONSE         0x02   The data portion of the message
                        constitutes device-status information
                        and the RESPONSE-FLAG field indicates
                        whether this is a positive or negative
                        response (see below).

BIND-IMAGE       0x03   The data portion of the message is
                        the SNA bind image from the session
                        established between the server and the
                        host application.

UNBIND           0x04   The data portion of the message is
                        an Unbind reason code.

NVT-DATA         0x05   The data portion of the message is to
                        be interpreted as NVT data.

REQUEST          0x06   There is no data portion present in
                        the message.  Only the REQUEST-FLAG
                        field has any meaning.

SSCP-LU-DATA     0x07   The data portion of the message is
                        data from the SSCP-LU session.

8.1.2 REQUEST-FLAG Field

The REQUEST-FLAG field only means something when DATA-TYPE is REQUEST. Otherwise the receiver MUST ignore it, and the sender SHOULD set it to 0x00 ✨. These are the possible values:

Request-Flag Name   Code                Meaning
-----------------   ----   ---------------------------------
ERR-COND-CLEARED    0x00   The client sends this to the server
                           when some previously encountered
                           printer error condition has been
                           cleared.  (See the section entitled
                           "The RESPONSES Function" below.)

8.1.3 RESPONSE-FLAG Field

The RESPONSE-FLAG field only means something for certain DATA-TYPE values. For 3270-DATA and SCS-DATA, the RESPONSE-FLAG tells you whether the sender expects a response. These are the possible values in that case πŸŽ€:

Response-Flag Name  Code                Meaning
------------------  ----   ---------------------------------
NO-RESPONSE         0x00   The sender does not expect the
                           receiver to respond either
                           positively or negatively to this
                           message.  The receiver MUST
                           therefore NOT send any response
                           to this data-message.

ERROR-RESPONSE      0x01   The sender only expects the
                           receiver to respond to this message
                           if some type of error occurred, in
                           which case a negative response MUST
                           be sent by the receiver.

ALWAYS-RESPONSE     0x02   The sender expects the receiver to
                           respond negatively if an error
                           occurs, or positively if no errors
                           occur.  One or the other MUST
                           always be sent by the receiver.

For DATA-TYPE RESPONSE, the RESPONSE-FLAG is an actual reply to an earlier data message. That earlier message MUST by definition have had a DATA-TYPE of either 3270-DATA or SCS-DATA, and a RESPONSE-FLAG of either ERROR-RESPONSE or ALWAYS-RESPONSE. The possible values here are πŸ’œ:

Response-Flag Name  Code                Meaning
------------------  ----   ---------------------------------
POSITIVE-RESPONSE   0x00   The previous message was received
                           and executed successfully with
                           no errors.

NEGATIVE-RESPONSE   0x01   The previous message was received
                           but an error(s) occurred while
                           processing it.

Any status info that goes with the response shows up in the data portion of the message 🧚.

For any other DATA-TYPE values, the receiver MUST ignore the RESPONSE-FLAG field, and the sender SHOULD set it to 0x00 🌸.

8.1.4 SEQ-NUMBER Field

The SEQ-NUMBER field is only used when the RESPONSES function has been agreed to. It's a 2-byte binary number, and its job is to match up positive and negative responses with the data messages they were meant for. Check the section called "The RESPONSES Function" for more πŸ¦‹. When the RESPONSES function hasn't been agreed to, the sender SHOULD always set this field to 0x0000, and the receiver MUST ignore it 🫢.

9. Basic TN3270E ✨

Okay bestie, remember how we said that whether each TN3270E function is allowed gets negotiated when the connection is set up? πŸ’– Well, it's totally possible that none of the functions get agreed to. Then the function-list in the FUNCTIONS REQUEST and FUNCTIONS IS commands is null 🫠. This setup is called "basic TN3270E," and since neither SCS-CTL-CODES nor DATA-STREAM-CTL got agreed to, basic TN3270E is for terminal sessions only πŸ–₯️. Printers are not invited to this party, bestie.

Basic TN3270E only needs support for these TN3270E header values:

       Header field         Value
       ------------         -----
        DATA-TYPE          3270-DATA
        DATA-TYPE          NVT-DATA

The REQUEST-FLAG, RESPONSE-FLAG and SEQ-NUMBER fields are not used in basic TN3270E πŸ™ˆ so you can just leave them alone, no drama.

9.1 3270 Mode and NVT Mode 🌸

Okay so at any given moment, a TN3270E connection is either in "3270 mode" or "NVT mode" πŸ¦‹. In 3270 mode, each party MAY send data messages with the DATA-TYPE flag set to 3270-DATA. Sending a DATA-TYPE flag set to NVT-DATA is basically asking to switch modes πŸ”€. In NVT mode it's the reverse: each party MAY send data messages with the DATA-TYPE flag set to NVT-DATA, and sending 3270-DATA is the request to switch. The connection starts out in 3270 mode once TN3270E operation is successfully negotiated πŸ’…. When a party gets a message whose DATA-TYPE doesn't match the mode it's currently in, the connection switches modes.

Switching modes makes the client do the equivalent of a 3270 Erase/Reset operation, as described in [5], using the default partition (screen) size ✨. The server cannot assume the client keeps any attributes from the previous environment across a mode switch, so don't get attached to them 😭.

Note that even when sending NVT-DATA, each side SHOULD buffer data until an entire message is built. For the client, that usually means waiting until the user presses Enter ⌨️. At that point, a complete TN3270E data message SHOULD be built to transmit the NVT data.

Typically, NVT data is how a server talks to the user of a client 🫢. It lets the server do this with a simple NVT data stream instead of needing a full 3270 data stream. Picture a server that shows a list of 3270 applications the client can connect to. The server uses NVT data to display that list and read the user's choice. Then the server connects to the application and the exchange of 3270 data begins between the application and the client 🧚.


10. Details of Processing TN3270E Functions πŸ”₯

So agreement by both parties to a specific function in the FUNCTIONS REQUEST function-list also means each party agrees to support a related set of TN3270E header values πŸ‘‘. It also means you're willing to follow the rules for processing data messages around that agreed function. Any party that fails to accept the header values tied to agreed functions or to basic TN3270E, or that tries to use header values for a function that isn't part of basic TN3270E and was never agreed to, is considered non-conforming and in violation of the protocol πŸ’€. Each function gets its own section below, with the header values and processing rules spelled out πŸŽ€.

10.1 The SCS-CTL-CODES Function πŸ–¨οΈ

This function can only be supported on a 3270 printer session πŸ“.

Agreeing to support this function requires that the party support the following TN3270E header values:

       Header field         Value
       ------------         -----
        DATA-TYPE          SCS-DATA

A client representing a printer device uses this function to say it's ready to accept a data stream that includes SCS control codes πŸ’œ. For the purposes of NVT mode versus 3270 mode, SCS-DATA SHOULD be treated exactly like 3270-DATA. That means it can trigger a switch from NVT mode to 3270 mode πŸ”₯.

When a printer device-type has been negotiated, either the SCS-CTL-CODES function or the DATA-STREAM-CTL function, or both, MUST be negotiated. This is how the server knows when it SHOULD and SHOULD NOT accept a session with a host application on behalf of the client 🧐. If only SCS-CTL-CODES is agreed to, the server won't establish sessions with host applications that would send 3270 data stream control. If both SCS-CTL-CODES and DATA-STREAM-CTL are agreed to, the server will establish sessions with host applications that send SCS control codes and with those that send 3270 orders 🌈.

10.2 The DATA-STREAM-CTL Function πŸ–¨οΈ

This function can only be supported on a 3270 printer session 🌸.

Agreeing to support this function requires that the party support the following TN3270E header values:

       Header field         Value
       ------------         -----
        DATA-TYPE          3270-DATA

A client representing a printer device uses this function to say it's ready to accept a data stream that includes 3270 orders and attributes πŸ¦‹.

When a printer device-type has been negotiated, either the SCS-CTL-CODES function or the DATA-STREAM-CTL function, or both, MUST be negotiated. This is how the server knows when it SHOULD and SHOULD NOT accept a session with a host application on behalf of the client 🫠. If only DATA-STREAM-CTL is agreed to, the server won't establish sessions with host applications that would send SCS control codes in a data stream. If both SCS-CTL-CODES and DATA-STREAM-CTL are agreed to, the server will establish sessions with host applications that send SCS control codes and with those that send 3270 orders ✨.

10.3 The BIND-IMAGE Function 🌟

This function can only be supported when the TN3270E server represents SNA terminals and printers πŸ’….

Agreeing to support this function requires that the party support the following TN3270E header values:

       Header field         Value
       ------------         -----
        DATA-TYPE          BIND-IMAGE
        DATA-TYPE          UNBIND
        DATA-TYPE          SSCP-LU-DATA

When BIND-IMAGE is in effect, the server MUST inform the client when an SNA session has been established with a host application, and when that session has been terminated. It uses the DATA-TYPE values BIND-IMAGE and UNBIND to pass this along πŸ“£.

When the server sets up an SNA session on behalf of a client, it receives a Bind RU from the host application. It also receives a Start Data Traffic RU 🎬. Once the server has responded positively to both of these, it MUST then tell the client the session exists by sending it a data message with the DATA-TYPE flag set to BIND-IMAGE. The data portion of that message MUST contain the bind image exactly as it was received in the Bind RU that the server accepted on behalf of the client πŸ”’.

When an SNA session between the server and a host application ends, the server SHOULD send a data message to the client with the DATA-TYPE flag set to UNBIND. If the server was told about the termination through an SNA Unbind RU, it SHOULD include the Unbind reason code in the data portion of the message it sends to the client. If the server requested the termination itself (for example, as part of SYSREQ key processing), it SHOULD set the data portion of the UNBIND message to 0x01, which means "normal end of session" 🏁.

BIND-IMAGE also changes which DATA-TYPE values are allowed, a little bit, compared to what was described in the section entitled "Basic TN3270E" πŸ€“. When BIND-IMAGE is in effect, data messages with DATA-TYPE set to 3270-DATA or SCS-DATA are not allowed before the client receives the first BIND-IMAGE. Only SSCP-LU-DATA or NVT-DATA can carry user-oriented data during that time. The same goes for data messages exchanged after an UNBIND is sent and before the client receives another BIND-IMAGE πŸ™ƒ. Once the client receives a BIND-IMAGE data message, the allowed DATA-TYPE values include 3270-DATA and/or SCS-DATA. Which ones depends on whether a terminal or printer device-type was negotiated, and whether a printer client agreed to DATA-STREAM-CTL or SCS-CTL-CODES, or both 🧩. (See the section entitled "The SYSREQ Function" for more on the SSCP-LU session in an SNA environment πŸ“–.)

10.4 The RESPONSES Function πŸ’Œ

This function can be supported for both terminal and printer sessions, connected to both SNA and non-SNA servers 🌷.

Agreeing to support this function requires that the party support the following TN3270E header values:

       Header field         Value
       ------------         -----
        DATA-TYPE          RESPONSE
        DATA-TYPE          REQUEST
        RESPONSE-FLAG      -all values-
        REQUEST-FLAG       ERR-COND-CLEARED
        SEQ-NUMBER         binary values from 0-32767

Whenever a data message is sent with a DATA-TYPE of either SCS-DATA or 3270-DATA, the sender MUST set the RESPONSE-FLAG field to NO-RESPONSE, ERROR-RESPONSE, or ALWAYS-RESPONSE 🎯. The client side is expected to usually set RESPONSE-FLAG to NO-RESPONSE πŸ’œ. If the server represents an SNA device, it SHOULD set RESPONSE-FLAG to match the response value in the RH of the RU that produced this data message. A Definite Response gives ALWAYS-RESPONSE, an Exception Response gives ERROR-RESPONSE, and No Response gives NO-RESPONSE. A non-SNA server SHOULD set RESPONSE-FLAG to ERROR-RESPONSE πŸ›ŽοΈ.

On top of that, the sender MUST keep a count of the messages with a DATA-TYPE of 3270-DATA or SCS-DATA that it sends on a given session πŸ”’. This counter SHOULD start at zero for the first such message and go up by one for each message after that. If the counter reaches the maximum of 32767, it SHOULD be restarted at zero. The sender SHOULD place this value in the SEQ-NUMBER field of the TN3270E header before it sends the message. The SEQ-NUMBER field MUST be set regardless of the value of the RESPONSE-FLAG field 🫢.

10.4.1 Response Messages πŸ’–

Whenever a data message with a DATA-TYPE of either SCS-DATA or 3270-DATA shows up, the receiver must attempt to process the data in the data portion, then decide whether it should send a data message with a DATA-TYPE of RESPONSE πŸ’Œ If the message it just processed had a RESPONSE-FLAG of NO-RESPONSE, or it had ERROR-RESPONSE and there were no errors while processing the data, then no RESPONSE type message should be sent. πŸ™…β€β™€οΈ Otherwise, a data message should be sent with the header DATA-TYPE field set to RESPONSE, and its SEQ-NUMBER field is a copy of the SEQ-NUMBER from the message this response belongs to πŸŽ€ The RESPONSE-FLAG field in this header must be either POSITIVE-RESPONSE or NEGATIVE-RESPONSE. A POSITIVE-RESPONSE should be sent if the previously processed message's header specified ALWAYS-RESPONSE and no errors came up while processing the data. A NEGATIVE-RESPONSE should be sent when

  1. the previously processed message specified ERROR-RESPONSE or ALWAYS-RESPONSE and
  2. some kind of error occurred while processing the data.

Normally only the client builds and sends these RESPONSE messages 🧚 A negative response sent by the client to the server is the equivalent of a Unit Check Status [7]. All references to device status and sense codes in this section rely on [7] πŸ’…

The data portion of a RESPONSE message must consist of one byte of binary data. The value of that byte gives a more detailed account of how the previously received data message turned out ✨ The possible values are:

For a RESPONSE-FLAG value of POSITIVE-RESPONSE -

  Value            Meaning
  -----            -------
  0x00      Successful completion (when sent by the client,
            this is equivalent to "Device End").
For a RESPONSE-FLAG value of NEGATIVE-RESPONSE -

  Value            Meaning
  -----            -------
  0x00      An invalid 3270 command was received
            (equivalent to "Command Reject").

  0x01      Printer is not ready (equivalent to
            "Intervention Required").

  0x02      An illegal 3270 buffer address or order
            sequence was received (equivalent to
            "Operation Check").

  0x03      Printer is powered off or not connected
            (equivalent to "Component Disconnected").

When the server gets any of the above responses, it should pass the appropriate information along to the host application πŸ¦‹ Which information is appropriate depends on whether the server represents an SNA or a non-SNA device.

An SNA server should pass a POSITIVE-RESPONSE from the client along to the host application as an SNA positive Response Unit. It should translate a NEGATIVE-RESPONSE from the client into an SNA negative Response Unit in which the Sense Data Indicator bit is on and which contains one of the following sense codes:

RESPONSE-FLAG        Equivalent        SNA Sense Code
-------------        ----------        --------------
    0x00           Command Reject        0x10030000

    0x01        Intervention Required    0x08020000

    0x02           Operation Check       0x10050000

    0x03        Component Disconnected   0x08310000

A non-SNA server should pass a POSITIVE-RESPONSE from the client along by setting the Device End Status bit on. It should reflect a NEGATIVE-RESPONSE from the client by setting the Unit Check Status bit on, and setting either the Command Reject, Intervention Required, or Operation Check Sense bit on when responding to the Sense command 🌈

In the case of Intervention Required or Component Disconnected being passed by the server to the host application, the host would normally hold off on sending any more data to the printer πŸ™ˆ If and when the error condition at the client has been resolved, the client must send the server a data message whose header DATA-TYPE field is set to REQUEST, and whose REQUEST-FLAG is set to ERR-COND-CLEARED. Note that this message has no data portion. When the server receives this message, it should pass the appropriate information along to the host application so the host can resume sending printer output. Again, the form of that information depends on whether the server represents an SNA or a non-SNA device.

An SNA server should reflect an ERR-COND-CLEARED to the host application by sending an SNA LUSTAT RU with one of the following sense codes:

  • if the previous error condition was an Intervention Required, the server should send sense code 0x00010000
  • if the previous error condition was Component Disconnected, the server should send sense code 0x082B0000

A non-SNA server should set the corresponding bits in the Ending Status and Sense Condition bytes. πŸ“


10.5 The SYSREQ Function ✨

This function can only be supported when the TN3270E server represents SNA devices πŸ’œ

Agreeing to support this function means the party has to support the following TN3270E header values:

Header field         Value
------------         -----
 DATA-TYPE          SSCP-LU-DATA

The 3270 SYSREQ key can be really useful in an SNA environment when the ATTN key isn't enough to terminate a process. (See the section entitled "The 3270 ATTN Key" for more information.) πŸ”₯

10.5.1 Background πŸ“š

In SNA, there is a session between the host application (the PLU, or Primary Logical Unit) and the TN3270E server representing the client (the SLU, or Secondary Logical Unit). This is called the PLU-SLU session, and it's the one where normal communication flows 🌸 There's also a session between the host telecommunications access method (the SSCP, or System Services Control Point) and the SLU, called the SSCP-LU session. This session carries various control information and is normally invisible to the user, since normal 3270 data stream orders aren't allowed in this data. For more info, check out [7] 🫢

The terminal display and keyboard are usually "owned" by the PLU-SLU session, meaning anything the user types gets sent to the host application. The SYSREQ key toggles ownership of the keyboard and display between the PLU-SLU session and the SSCP-LU session. In other words, the user can press SYSREQ and then talk directly to the host SSCP πŸ’… The user can then enter any valid Unformatted Systems Services commands, which are defined in the USS table associated with the SLU. The most common USS command is "LOGOFF," which asks the SSCP to immediately terminate the PLU-SLU session. People usually do this when the host application (the PLU) has stopped responding altogether πŸ’€

Whenever the keyboard and display are owned by the SSCP-LU session, no data is allowed to flow in either direction on the PLU-SLU session. Once "in" the SSCP-LU session, the user can switch back to the PLU-SLU session by pressing the SYSREQ key again πŸ¦‹

10.5.2 TN3270E Implementation of SYSREQ πŸŽ€

Some TN3270E servers are designed so they can fully support the SYSREQ key, because they're allowed to send USS commands on the SSCP-LU session. Other TN3270E servers work in an environment that doesn't let them send USS commands to the SSCP, which makes full SYSREQ support impossible 😭 For those servers, TN3270E provides emulation of a minimal subset of functions, namely the sequence of pressing SYSREQ and typing LOGOFF that many users rely on to immediately terminate the PLU-SLU session.

The Telnet Abort Output (AO) command is the mechanism used to implement SYSREQ key support in TN3270E. In a real SNA session, once the user presses SYSREQ, the host application is blocked from sending any more output to the terminal (unless the user presses SYSREQ a second time), but the user's process keeps running 🧚

To implement SYSREQ key support, TN3270E clients that have agreed to the SYSREQ function should provide a key (or key combination) identified as mapping to the 3270 SYSREQ key. When the user presses that key (or combination), the client should transmit a Telnet AO command to the server πŸ“

When the AO command arrives, a TN3270E server that has agreed to the SYSREQ function should enter what we'll loosely call "suspended mode" for the connection. If a server that has not agreed to the SYSREQ function receives an AO command, it should simply ignore it. Any attempt by the host application to send data to the client while the connection is "suspended" should be answered by the server with a negative response, sense code 0x082D, indicating an "LU Busy" condition. The server should not transmit anything to the client on behalf of the host application. While the connection is "suspended," any data messages (except TN3270E responses) exchanged between the client and server should have the DATA-TYPE flag set to SSCP-LU-DATA πŸ‘‘

At this point, what the server does depends on whether it's allowed to send USS commands on the SSCP-LU session. Servers with that ability should simply act as a vehicle for passing USS commands and responses between the client and the SSCP.

Servers that are not allowed to send USS commands on the SSCP-LU session should behave as follows:

  • if the user transmits the string LOGOFF (upper or lower case), the server should send an Unbind SNA RU to the host application. This will result in termination of the PLU-SLU session. If the BIND-IMAGE function was agreed upon, then the server should also send a data message to the client with the DATA-TYPE flag set to UNBIND and the data portion set to 0x01.
  • if the user transmits anything other than LOGOFF, the server should respond to the client with the string "COMMAND UNRECOGNIZED". The server should not send anything to the host application on behalf of the client.

The SYSREQ key stays on the same tragic track πŸ’… Whatever kind of server is on the other end (whether or not it may send USS commands on the SSCP-LU session πŸ¦‹), the user can press "SYSREQ" again while the connection is suspended. That sends another AO to the server. The server SHOULD then send the host application a LUSTAT RU with a value of 0x082B, which means "presentation space integrity lost" 😭 The server then "un-suspends" the Telnet connection to the client, so the host application can send data to the client again ✨

11. The 3270 ATTN Key ✨

Okay so, lots of host applications in an SNA environment read the 3270 ATTN key as "the user wants to interrupt whatever's running right now" πŸ›‘ The Telnet Interrupt Process (IP) command was made for exactly that job, so it's what we use to support the 3270 ATTN key. Two things make it work:

  • TN3270E clients SHOULD provide, as part of their keyboard mapping, a single key or a combination of keys that maps to the 3270 ATTN key. When the user presses that key (or keys), the client SHOULD transmit a Telnet IP command to the server πŸŽ€
  • TN3270E servers SHOULD translate the IP command they get from a TN3270E client into the right form and pass it along to the host application as an ATTN key. In other words, the server representing an SLU in an SNA session SHOULD send a SIGNAL RU to the host application πŸ’–

The ATTN key isn't supported in a non-SNA environment, so a TN3270E server representing non-SNA 3270 devices SHOULD ignore any Telnet IP commands it receives from a client πŸ™ˆ

12. 3270 Structured Fields

3270 structured fields come with a much bigger toolkit than "old-style" 3270 data 🧰 Think graphics, partitions, and IPDS printer data streams. It would be unreasonable to expect every TN3270E client to support every structured field function, but there still has to be a way for clients that can handle some or all of them to say so 🌈

The design of 3270 structured fields already gives us a neat way to share that info, including "I don't support any of this." It's the Read Partition Query command, which the host application sends to the device. The device answers with one or more Query Reply structured fields that list which structured field functions it supports, if any ✨

The Query Reply also covers some device capabilities that don't need structured fields at all, like extended color support and extended highlighting. Most host applications will use Read Partition Query to figure out exactly what a device can do once there's some sign that the device handles the "extended data stream" πŸ”₯

So all TN3270E clients that negotiate a terminal device-type with a "-E" suffix, the DYNAMIC terminal type, or a printer device-type MUST be able to respond to a Read Partition Query command πŸ‘‘ Note that these clients MUST support both the Read Partition Query (Type 02) and all forms of the Read Partition Query List (Type 03) πŸ’…

13. Implementation Guidelines πŸŽ€

13.1 3270 Data Stream Notes

Okay, implementors of TN3270E clients, listen up πŸ‘‚ The command codes for the various 3270 Read and Write commands have different values depending on how the server is connected to the host (local versus remote, SNA versus non-SNA). If you want to work with the widest range of servers, your client SHOULD check for all the possible values. See [7] for the details 🧚

13.2 Negotiation of the TN3270E Telnet Option

TN3270E is a Telnet Option governed by [8], so both client and server are free to start negotiating TN3270E by sending a DO TN3270E command πŸ¦‹ Just like with the Telnet DO TERMINAL-TYPE, the server is usually the one who sends DO TN3270E, and the client replies with a WILL or a WON'T TN3270E πŸ’œ

13.3 A "Keep-alive" Mechanism

In a lot of environments, it's super helpful to have something that tells you quickly when a 3270 session is gone 😭 TN3270E does not require any form of keep-alive mechanism from clients or servers. If you do want one, here are some guidelines πŸ“

There are at least two possible ways to do keep-alives in TN3270E: the Telnet IAC NOP command [8], and the Telnet DO TIMING-MARK option [9]. Both have their pros and cons. It is RECOMMENDED that TN3270E clients and servers that support keep-alives accept both NOPs and TIMING-MARKs, and that both sides SHOULD always respond to TIMING-MARKs 🫢

Both clients and servers could be set up to "actively" run keep-alives. That means both sides could send a TIMING-MARK or a NOP to check whether the partner is still alive ✨ Or, network administrators MAY wish to configure only one side to send TIMING-MARKs or NOPs. In that case, the other side is a "passive" participant that just responds to the keep-alives it gets 🌸

Implementors who want their code to be an "active" keep-alive participant SHOULD make their client or server configurable, so administrators can choose which keep-alive mechanism, if any, SHOULD be employed, and how often the NOP or TIMING-MARK gets sent on each session πŸ’…

When a session with keep-alives fails, both parties SHOULD make the proper notifications 🚨 A client SHOULD give the user some indication of the failure, like an error code in the Operator Information Area of the screen. A server SHOULD notify the host application that the session has ended, for example by sending an UNBIND with type CLEANUP in an SNA environment πŸ§šβ€β™€οΈ

13.4 Examples

Here's the first one, a TN3270E-capable server and a traditional tn3270 client connecting πŸŽ€

  Server:  IAC DO TN3270E
  Client:  IAC WON'T TN3270E
  Server:  IAC DO TERMINAL-TYPE
  Client:  IAC WILL TERMINAL-TYPE
  Server:  IAC SB TERMINAL-TYPE SEND IAC SE
  Client:  IAC SB TERMINAL-TYPE IS IBM-3278-2 IAC SE
  Server:  IAC DO EOR IAC WILL EOR
  Client:  IAC WILL EOR IAC DO EOR
  Server:  IAC DO BINARY IAC WILL BINARY
  Client:  IAC WILL BINARY IAC DO BINARY
     (3270 data stream is exchanged)

Next up: a TN3270E-capable server and a TN3270E-capable client setting up a generic pool (non-specific) terminal session 🌈

  Server:  IAC DO TN3270E
  Client:  IAC WILL TN3270E
  Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
  Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-2 IAC SE
  Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-2 CONNECT
                  anyterm IAC SE
  Client:  IAC SB TN3270E FUNCTIONS REQUEST RESPONSES IAC SE
  Server:  IAC SB TN3270E FUNCTIONS IS RESPONSES IAC SE
     (3270 data stream is exchanged)

Now the client asks for a specific device-name πŸ“

  Server:  IAC DO TN3270E
  Client:  IAC WILL TN3270E
  Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
  Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-5-E
                  CONNECT myterm IAC SE
  Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-5-E CONNECT
                  myterm IAC SE
  Client:  IAC SB TN3270E FUNCTIONS REQUEST RESPONSES
                  BIND-IMAGE IAC SE
  Server:  IAC SB TN3270E FUNCTIONS IS RESPONSES BIND-IMAGE
                  IAC SE
     (3270 data stream is exchanged)

This one is a little drama πŸ™ˆ The client tries to connect, but the device-name it asked for is already in use, so it has to try again:

  Server:  IAC DO TN3270E
  Client:  IAC WILL TN3270E
  Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
  Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-5
                  CONNECT myterm IAC SE
  Server:  IAC SB TN3270E DEVICE-TYPE REJECT REASON
                  DEVICE-IN-USE IAC SE
  Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-2
                  CONNECT herterm IAC SE
  Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-2 CONNECT
                  herterm IAC SE
  Client:  IAC SB TN3270E FUNCTIONS REQUEST RESPONSES IAC SE
  Server:  IAC SB TN3270E FUNCTIONS IS RESPONSES IAC SE
     (3270 data stream is exchanged)

Here's a printer session where the client asks for a specific device-name, and some 3270 function negotiation has to happen before they agree πŸ–¨οΈβœ¨

  Server:  IAC DO TN3270E
  Client:  IAC WILL TN3270E
  Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
  Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3287-1 CONNECT
                  myprt IAC SE
  Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3287-1 CONNECT
                  myprt IAC SE
  Client:  IAC SB TN3270E FUNCTIONS REQUEST DATA-STREAM-CTL IAC
  Server:  IAC SB TN3270E FUNCTIONS REQUEST DATA-STREAM-CTL
                  RESPONSES IAC SE
  Client:  IAC SB TN3270E FUNCTIONS REQUEST DATA-STREAM-CTL IAC
  Server:  IAC SB TN3270E FUNCTIONS IS DATA-STREAM-CTL IAC SE
     (3270 data stream is exchanged)

And last one in this batch: first a generic terminal session, then a printer session where the "partner" printer for the assigned terminal is requested πŸ§šβ€β™€οΈπŸ’–

  Server:  IAC DO TN3270E
  Client:  IAC WILL TN3270E
  Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
  Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-2 IAC SE
  Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-2 CONNECT
                  termXYZ IAC SE
  Client:  IAC SB TN3270E FUNCTIONS REQUEST RESPONSES IAC SE
  Server:  IAC SB TN3270E FUNCTIONS IS RESPONSES IAC SE
     (3270 data stream is exchanged)
           .            .
           .            .
     (user decides to request a printer session,
      so client again connects to Telnet port on server)
  Server:  IAC DO TN3270E
  Client:  IAC WILL TN3270E
  Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
  Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3287-1
                  ASSOCIATE termXYZ IAC SE
  Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3287-1 CONNECT
                  termXYZ's-prt IAC SE
  Client:  IAC SB TN3270E FUNCTIONS REQUEST SCS-CTL-CODES
                  RESPONSES IAC SE
  Server:  IAC SB TN3270E FUNCTIONS IS SCS-CTL-CODES RESPONSES
                  IAC SE
     (3270 data stream is exchanged)

14. Security Considerations ✨

okay bestie, this section is short but it's a LOT πŸ˜­πŸ”’ Security issues are literally NOT addressed in this document πŸ’€ The vibe is basically "authentication is coming, we'll figure it out later." Once authentication mechanisms are well established, TN3270E might be able to use them πŸ‘€ One of the big reasons you'd want auth is to answer the question of whether a given user should be allowed to "use" a specific terminal or printer device-name. Main character security energy πŸ¦‹πŸ”

15. References πŸ“š

  • [1] Rekhter, J., "Telnet 3270 Regime Option", RFC 1041, IBM Corporation, January 1988. 🌸
  • [2] VanBokkelen, J., "Telnet Terminal-Type Option", RFC 1091, FTP Software, Inc., February 1989. πŸ’…
  • [3] Postel, J., and J. Reynolds, "Telnet Binary Transmission", STD 27, RFC 856, USC/Information Sciences Institute, May 1983. πŸŽ€
  • [4] Postel, J., "Telnet End of Record Option", RFC 885, USC/ Information Sciences Institute, December 1983. ✨
  • [5] "3270 Information Display System - Data Stream Programmer's Reference", publication number GA24-0059, IBM Corporation. πŸ“–
  • [6] "SNA Formats", publication number GA27-3136, IBM Corporation. 🧚
  • [7] "3174 Establishment Controller Functional Description", publication number GA23-0218, IBM Corporation. πŸ¦‹
  • [8] Postel, J., and J. Reynolds, "Telnet Protocol Specification", STD 8, RFC 854, USC/Information Sciences Institute, May 1983. πŸ’–
  • [9] Postel, J., and J. Reynolds, "Telnet Timing Mark Option", STD 31, RFC 860, USC/Information Sciences Institute, May 1983. 🫢

16. Author's Note πŸ“

okay so the author's note is basically the origin story πŸ₯Ή Portions of this document were drawn from:

  • A White Paper written by Owen Reddecliffe, WRQ Corporation, October 1991. πŸ“„
  • Experimental work on the part of Cleve Graves and Michelle Angel, OpenConnect Systems, 1992 - 1993. πŸ”¬
  • Discussions at the 1993 IETF meetings. πŸ—£οΈ
  • Discussions on the "TN3270E" list, 1993-94. πŸ’œ

17. Author's Address πŸŽ€

Bill Kelly Division of University Computing 144 Parker Hall Auburn University, AL 36849

Phone: (205) 844-4512 EMail: kellywh@mail.auburn.edu


And that's the whole RFC, bestie! πŸŒˆπŸ‘‘ We made it through all 8 parts, you're officially a TN3270E expert now πŸ«ΆπŸ’–

πŸ“¦ where this page comes from