RFC 2204
ODETTE File Transfer Protocol
ODETTE File Transfer Protocol ๐ฌโจ
Okay bestie, so this is RFC 2204, titled "ODETTE File Transfer Protocol" ๐. It was written by D. Nash from ODETTE and dated September 1997. Its category is Informational ๐. The header doesn't mention it obsoleting or updating any other RFC.
Status of This Memo ๐ธ
okay so this memo is just giving info to the Internet community ๐ซถ. It doesn't specify an Internet standard of any kind, and distribution of it is unlimited ๐ฆ.
Abstract โจ
This one is about a file transfer protocol for swapping electronic data between trading partners ๐ .
The protocol is called the ODETTE File Transfer Protocol ๐ฅ. It supports direct communication between installations and indirect communication through a third party clearing centre. ODETTE (the Organisation for Data Exchange by Tele Transmission in Europe) made it for the European motor industry, and it's being shared here so the wider Internet community can use it ๐๐.
Network Working Group D. Nash
Request for Comments: 2204 ODETTE
Category: Informational September 1997
Table of Contents ๐
1. Introduction 3
1.1 - Background 3
1.2 - Relationship to the original ODETTE Standard 3
1.3 - General Principles 3
1.4 - Structure 4
1.5 - Virtual Files 4
1.6 - Service Description 7
2. Network Service (TCP Transport Service) 7
2.1 - Introduction 7
2.2 - Service Primitives 7
2.3 - Port Assignment 9
3. File Transfer Service 9
3.1 - Model 10
3.2 - Session Setup 11
3.3 - File Transfer 13
3.4 - Session Take Down 16
3.5 - Service State Automata 19
4. Protocol Specification 22
4.1 - Overview 22
4.2 - Start Session Phase 22
4.3 - Start File Phase 23
4.4 - Data Transfer Phase 26
4.5 - End File Phase 27
4.6 - End Session Phase 27
4.7 - Problem Handling 28
5. Commands and Formats 28
5.1 - Conventions 28
5.2 - Commands 29
5.3 - Command Formats 29
5.4 - Identification Code 45
6. ODETTE-FTP Data Exchange Buffer 46
6.1 - Overview 46
6.2 - Data Exchange Buffer Format 46
6.3 - Buffer Filling Rules 47
7. Stream Transmission Buffer (TCP only) 47
7.1 - Introduction 47
7.2 - Stream Transmission Header Format 49
8. Protocol State Machine 50
8.1 - ODETTE-FTP State Machine 50
8.2 - Error Handling 50
8.3 - States 51
8.4 - Input Events 53
8.5 - Output Events 54
8.6 - Local Variables 55
8.7 - Local Constants 55
8.8 - Session Connection State Table 56
8.9 - Error and Abort State Table 58
8.10 - Speaker State Table 1 59
8.11 - Speaker State Table 2 63
8.12 - Listener State Table 65
8.13 - Example 68
9. Security Considerations 68
Appendix A Virtual File Mapping Example 69
Appendix B ISO 646 Character Subset 72
Acknowledgements 73
References 73
ODETTE Address 74
Author's Address 74
1. Introduction ๐
1.1. Background ๐ฐ๏ธ
So the ODETTE File Transfer Protocol (ODETTE-FTP) was defined back in 1986 by working group four of ODETTE ๐ . They made it to handle the electronic data interchange (EDI) needs of the European automotive industry ๐. It was built in the spirit of the Open System Interconnection (OSI) model and used the Network Service from the CCITT X25 recommendation ๐ง.
Over the last ten years it got super widely deployed on everything from personal computers to big mainframes ๐ปโจ. Then internet tech started spreading everywhere and businesses went global, so ODETTE decided to extend the protocol to use TCP/IP and make it available to the Internet community ๐ธ๐. Literally iconic glow-up ๐.
This memo describes ODETTE-FTP using the Transmission Control Protocol for its network service ๐ฆ.
1.2. Relationship to the original ODETTE Standard ๐
This memo is an interpretation of version 1.3 of the ODETTE File Transfer Protocol [OFTP]. If there's any ambiguity between this document and the original ODETTE-FTP, the original shall take precedence ๐ซถ.
For ODETTE-FTP on TCP/IP, these sections were added compared to the original document:
- Section 2 - Network Service
- Section 7 - Stream Transmission Buffer
- Appendix A - Virtual File mapping example
1.3. General Principles ๐ฏ
The whole point of ODETTE-FTP is to move a file between one or more locations in a way that doesn't depend on the data communication network, the system hardware, or the software environment ๐.
When they designed and specified it, they thought about these factors:
- The possible differences of size and sophistication (file storage, small and large systems).
- The necessity to work with existing systems (reduce changes to existing products and allow easy implementation).
- Systems of different ages.
- Systems of different manufactures.
- The potential for growth in sophistication (limit impact and avoid changes at other locations).
1.4. Structure ๐งฉ
ODETTE-FTP is modelled on the OSI reference model ๐ง . It uses the Network Service from level 3 of the model and gives users a File Service, so the protocol spans levels 4 to 7 of the model ๐ฅ.
This memo is closely related to the original 'X.25' specification of the protocol. In the spirit of the OSI model, it describes:
- A File Service provided to a user monitor.
- A protocol for the exchange of information between peer ODETTE-FTP entities.
Adapting the protocol to TCP was a big deal, and the main goal was to change nothing about the existing protocol ๐. Implementers should be able to support internet communication with only minor changes to their existing ODETTE-FTP engines. So they added an extra header to the start of each exchange buffer, which lets the TCP byte stream get broken up into the discrete exchange buffers ODETTE-FTP expects ๐ โจ.
1.5. Virtual Files ๐ฆ
Information is always exchanged between ODETTE-FTP entities in a standard representation called a Virtual File ๐. This means data can move around without caring what kind of systems are talking to each other ๐.
How a file gets mapped between its local form and its virtual form depends on the system, and this memo doesn't define it ๐คทโโ๏ธ.
o---------o
Site | Local |
A | File A |
o---------o
|
o----------------------- Mapping A ------------------------o
| | |
| o---------o |
| | Virtual | |
| | File | |
| o---------o |
| o------------------------------------------------o |
| | | |
| | ODETTE-FTP | |
| | | |
| o------------------------------------------------o |
| o---------o o---------o |
| | Virtual | | Virtual | |
| | File | | File | |
| o---------o o----+----o |
| | | |
o------ Mapping B ------------------------ Mapping C ------o
| |
o---------o o----+----o
| Local | Site Site | Local |
| File B | B C | File C |
o---------o o---------o
A Virtual File is described by a set of attributes that identify and define the data being transferred ๐. The main attributes are:
1.5.1. Organisation: ๐๏ธ
Sequential ๐งพ
Logical records are presented one after another. The ODETTE-FTP must be aware of the record boundaries ๐.
1.5.2. Identification ๐ชช
Dataset Name ๐ท๏ธ
Dataset name of the Virtual File being transfered, assigned by bilateral agreement.
Time stamp (HHMMSS) โฐ
A file qualifier indicating the time the Virtual File was made available for transmission.
Date stamp (YYMMDD) ๐
A file qualifier indicating the date the Virtual File was made available for transmission.
The Dataset Name, Date and Time attributes are assigned by a Virtual File's Originator and are used to uniquely identify the file. They must not be changed by intermediate locations ๐.
The Date attribute stores the decade and year in a two digit field. Since ODETTE-FTP only uses this to identify a particular Virtual File, it keeps working correctly in the year 2000 and beyond ๐ฅณ.
The User Monitor may use the Virtual File Date attribute in local processes involving date comparisons and calculations. Any such use is outside the scope of this protocol, and year 2000 handling is a local implementation issue ๐ .
1.5.3 Record Format ๐
Okay bestie, there are four record formats, and they each have their own vibe ๐
- Fixed (F): every record in the file is the same length. Very neat, very symmetrical ๐ง
- Variable (V): the records can be different lengths. Chaotic but make it work ๐
- Unstructured (U): the file is just a stream of data. No structure is defined here, so it's giving free spirit ๐ฆ
- Text File (T): a Text File is a sequence of ASCII characters with no control characters, except CR/LF, which is what separates lines. A line will not have more than 2048 characters ๐
1.5.4 Restart โจ
ODETTE-FTP can negotiate restarting a Virtual File transmission that got interrupted, which is so iconic ๐ Fixed and Variable format files restart on record boundaries. For Unstructured and Text files, the restart position is written as a file offset in 1K (1024 octet) blocks. The restart position is always calculated relative to the Virtual File ๐ธ
1.6 Service Description ๐ซถ
ODETTE-FTP gives a file transfer service to a user monitor, and then it uses the Internet transport layer stream service to talk to its peers. Ngl, that's a lot of layers, but it's organised ๐
These services are described in this memo with service primitives, which fall into four classes:
- Request (RQ): an entity asks the service to do some work.
- Indication (IND): a service tells an entity that something happened.
- Response (RS): an entity answers an event.
- Confirm (CF): a service tells an entity what the response was.
Services may be confirmed, using the request, indication, response and confirm primitives, or unconfirmed, using just the request and indication primitives ๐ฆ
2. Network Service (TCP Transport Service) ๐
2.1 Introduction ๐ธ
ODETTE-FTP peers talk to each other through either the OSI Network Service or the Transmission Control Protocol Transport Service [TCP]. Both are described with service primitives for request, indication, response and confirmation actions ๐
For the internet environment, the Network Service primitives below need to be mapped to the matching Transport Service primitives. This section covers the network service primitives ODETTE-FTP uses and how they line up with the TCP interface. In practice, the local transport service application programming interface is what gets used to reach the TCP service โจ
2.2 Service Primitives ๐
All Network primitives can be mapped directly to the matching Transport primitives when using TCP. Slay, simple ๐ญ
2.2.1 Network Connection ๐
N_CON_RQ ------> N_CON_IND
N_CON_CF <------ N_CON_RS
This is how a connection gets set up. The requesting ODETTE-FTP peer uses the N_CON_RQ primitive to ask for an active OPEN of a connection to a peer ODETTE-FTP, which is the Responder. The Responder has already asked for a passive OPEN. The Responder is told about the incoming connection through N_CON_IND, and it accepts with N_CON_RS. The requester finds out its OPEN request has completed when _CON_CF comes in ๐ง
Parameters
Request Indication Response Confirmation
---------------------------------------------------------------------
Dest addr ------> same same same
2.2.2 Network Data ๐ฆ
N_DATA_RQ ------> N_DATA_IND
Data exchange is an unconfirmed service. The Requester hands data over for transmission to the network service with the N_DATA_RQ primitive. The Responder is told that data is available through N_DATA_IND. In practice, the notification and the receipt of data can be combined, for example when a blocking read from the network socket returns ๐
Parameters
Request Indication
---------------------------------------------------------------------
Data ------------------> same
2.2.3 Network Disconnection ๐
N_DISC_RQ ------> N_DISC_IND
An ODETTE-FTP requests the end of a connection with the N_DISC_RQ service primitive. Its peer gets notified of the CLOSE through an N_DISC_IND event. It's recognised that each peer must issue an N_DISC_RQ primitive to complete the TCP symmetric close procedure. So it's a two-way thing, no cap ๐
2.2.4 Network Reset ๐
------> N_RST_IND
An ODETTE-FTP entity is told about a network error through an N_RST_IND event. Worth noting that N_RST_IND would also be generated if a peer RESETS the connection. That's ignored here, though, because ODETTE-FTP never sends N_RST_RQ to the Network Service ๐
2.3 Port Assignment ๐
An ODETTE-FTP requester picks a suitable local port of its own ๐
The responding ODETTE-FTP listens for connections on Registered Port 3305, and the service name is 'odette-ftp' โจ
3. File Transfer Service ๐ธ
The File Transfer Service describes what an ODETTE-FTP Entity offers to its User Monitor. How the service primitives are implemented is a local matter, so it's up to each implementation ๐ง
3.1 Model ๐ฆ
o-------------------o o-------------------o
| | | |
| USER MONITOR | | USER MONITOR |
| | | |
o-------------------o o-------------------o
| A | A
...............|...|... FILE TRANSFER SERVICE ...|...|...............
| | | |
F_XXX_RQ/RS | | F_XXX_IND/CF F_XXX_RQ/RS | | F_XXX_IND/CF
V | V |
o-------------------o o-------------------o
| |- - - - - - >| |
| ODETTE-FTP Entity | E-Buffer | ODETTE-FTP Entity |
| |< - - - - - -| |
o-------------------o o-------------------o
| A | A
N_XXX_RQ/RS | | N_XXX_IND/CF N_XXX_RQ/RS | | N_XXX_IND/CF
| | | |
...............|...|...... NETWORK SERVICE ......|...|...............
V | V |
o---------------------------------------------------------o
| |
| N E T W O R K |
| |
o---------------------------------------------------------o
Key: E-Buffer - Exchange Buffer
F_ - File Transfer Service Primitive
N_ - Network Service Primitive
3.2 Session Setup ๐
3.2.1 Session Connection Service ๐
| |
F_CONNECT_RQ ---->|------------|----> F_CONNECT_IND
| |
F_CONNECT_CF <----|------------|<---- F_CONNECT_RS
| |
Parameters
Request Indication Response Confirm
---------------------------------------------------------------------
called-address -> same --- ----
calling-address-> same --- ----
ID1 ------------> same ID2 ------------> same
PSW1------------> same PSW2 -----------> same
mode1 ----------> mode2 ----------> mode3 ----------> same
restart1 -------> same -----------> restart2 -------> same
---------------------------------------------------------------------
Mode
This tells you the file transfer capabilities of the entity sending or receiving an F_CONNECT primitive, and it holds for the whole session ๐
Value:
- Sender-Only: the entity can only send files.
- Receiver-Only: the entity can only receive files.
- Both: the entity can both send and receive files.
Negotiation:
- Sender-Only: not negotiable.
- Receiver-Only: not negotiable.
- Both: can be negotiated down to Sender-Only or Receiver-Only, by the User Monitor or the ODETTE-FTP entity ๐ฅ
Request Indication Response Confirm
---------------------------------------------------------------------
Sender-only ----> Receiver-only --> Receiver-only --> Sender-only
Receiver-only --> Sender-only ----> Sender-only ----> Receiver-only
Both -----+-----> Both ----+------> Both -----------> Both
| or +------> Receiver-only --> Sender-only
| or +------> Sender-only ----> Receiver-only
|
or +-----> Receiver-only --> Receiver-only --> Sender-only
or +-----> Sender-only ----> Sender-only ----> Receiver-only
---------------------------------------------------------------------
Restart
This tells you the file transfer restart capabilities of the User Monitor โจ
Value:
Negotiation:
Request Indication Response Confirm
---------------------------------------------------------------------
restart = Y ----> restart = Y --+-> restart = Y ----> restart = Y
or +-> restart = N ----> restart = N
restart = N ----> restart = N ----> restart = N ----> restart = N
---------------------------------------------------------------------
3.3 File Transfer ๐ท
3.3.1 File Opening ๐ฆ
| |
F_START_FILE_RQ ---->|------------|----> F_START_FILE_IND
| |
F_START_FILE_CF(+|-) <----|------------|<---- F_START_FILE_RS(+|-)
| |
Parameters:
Request Ind. RS(+) CF(+) RS(-) CF(-)
--------------------------------------------------------------------
file-name ----> same ---- ---- ---- ----
date-time ----> same ---- ---- ---- ----
destination---> same ---- ---- ---- ----
originator----> same ---- ---- ---- ----
rec-format----> same ---- ---- ---- ----
rec-size -----> same ---- ---- ---- ----
file-size-----> same ---- ---- ---- ----
restart-pos1--> same-> restart-pos2-> same ---- ----
---- ---- ---- ---- cause ------> same
---- ---- ---- ---- retry-later-> same
--------------------------------------------------------------------
Notes:
- Retry-later has the values "Y" or "N".
- Cause is the reason for refusing the transfer (1,..,13,99).
- Restart-pos1 not equal to 0 is only valid if restart has been agreed during initial negotiation.
- Restart-pos2 is less than or equal to restart-pos1 ๐
3.3.2 Data Regime ๐
| |
F_DATA_RQ ---->|------------|----> F_DATA_IND
| |
Notes:
- The data format within a F_DATA primitive is locally defined.
- The File Transfer service may have to provide a flow control mechanism to regulate the flow of F_DATA primitives. This is the bit where traffic control matters, so keep an eye on it ๐ซถ
3.3.3 File Closing ๐
Okay bestie, time to wrap up a file! ๐ Here's how the close works, with the request and indication on the left and the confirm and response on the right:
| |
F_CLOSE_FILE_RQ --->|------------|----> F_CLOSE_FILE_IND
| |
F_CLOSE_FILE_CF(+|-) <---|------------|<---- F_CLOSE_FILE_RS(+|-)
| |
Here's the parameter table, which is the part that makes it click for me ๐ฆ
Parameters
Request Ind RS(+) CF(+) RS(-) CF(-)
---------------------------------------------------------------------
rec-count ---> same ---- ---- ---- ----
unit-count --> same ---- ---- ---- ----
---- ---- Speaker=Y ---> Speaker=N ---- ----
---- ---- Speaker=N ---> Speaker=Y ---- ----
---- ---- ---- ---- cause ---> same
---------------------------------------------------------------------
So in a positive Close File response (F_CLOSE_FILE_RS(+)), the current Speaker gets two choices ๐:
- Set Speaker to "Yes" and become the Speaker.
- Set Speaker to "No" and remain the Listener.
The File Transfer service makes sure the speaker setting matches what the peer user is actually capable of. Smart, right? ๐ง
The turn is never exchanged when the response or confirmation is negative. No turn swap on a failure, periodt ๐ โโ๏ธ
Last but not least: only the Speaker is allowed to send F_XXX_FILE_RQ primitives. Listeners just have to sit there and be cute ๐ธ
3.3.4 Exchanging the Turn ๐
3.3.4.1 Initial Turn (First Speaker)
The Initiator becomes the first Speaker at the end of the Session Setup, which is when it has received F_CONNECT_CF and the Responder has sent F_CONNECT_RS. The very first Speaker is locked in, no drama โจ
3.3.4.2 Following Turns
Here are the rules for passing the mic around ๐ค
- At each unsuccessful End of File, the turn is not exchanged.
- At each successful End of File, the turn is exchanged if the Listener asks for it:
- The current Listener receives
F_CLOSE_FILE_IND(Speaker = choice). - If the Listener answers
F_CLOSE_FILE_RS(Speaker = YES), it becomes Speaker. The old Speaker receivesF_CLOSE_FILE_CF (Speaker = NO)and becomes Listener. ๐ฆ - If the Listener answers
F_CLOSE_FILE_RS(Speaker = NO), it remains Listener. The Speaker receivesF_CLOSE_FILE_CF (Speaker = YES)and stays Speaker.
- The current Listener receives
- The Speaker can send a Change Direction request (
F_CD_RQ) to become the Listener. The Listener receives a Change Direction indication (F_CD_IND) and becomes the Speaker. - To stop
F_CD_RQ/INDfrom looping forever, it is an error to sendF_CD_RQright after receiving anF_CD_IND. Don't be that person ๐
3.3.5 End to End Response ๐
This service is started by the current Speaker, but only if no file transfer is in progress. Its job is to send an End-to-End response from the final destination back to whoever originated the file.
| |
F_EERP_RQ ---->|------------|----> F_EERP_IND
| |
Parameters
Request Indication
------------------------------------
filename -------> same
date -----------> same
time -----------> same
destination ----> same
originator -----> same
------------------------------------
Here's how it plays with the turn ๐
- Only the Speaker may send an End to End Response request.
- Invoking the EERP service does not change the turn.
- If an
F_CD_INDwas just received beforeF_EERP_RQis issued, that gets you out of the special condition theF_CD_INDcreated. Before this, you could issueF_RELEASE_RQbut notF_CD_RQright after gettingF_CD_IND. Once you've sentF_EERP_RQ, you're back to normal Speaker status, whereF_CD_RQis valid butF_RELEASE_RQisn't. ๐
3.4 Session Take Down ๐
3.4.1 Normal Close ๐ค
| |
F_RELEASE_RQ ---->|------------|----> F_RELEASE_IND
| |
Parameters
Request Indication
---------------------------------------------------------------------
reason = normal -------> ----
---------------------------------------------------------------------
Only the Speaker can start a Release. The Speaker can only send a Release request (F_RELEASE_RQ) right after receiving an unsolicited Change Direction indication (F_CD_IND). That's how the other partner gets the message that no more files are coming in this session ๐ญ
Peer ODETTE-FTP entities do a normal session release by putting Reason = Normal into an End Session (ESID) command.
3.4.2 Abnormal close โ ๏ธ
| |
F_RELEASE_RQ ---->|------------|----> F_ABORT_IND
| |
Parameters
Request Indication
---------------------------------------------------------------------
reason = error value --> same (or equivalent)
AO (Abort Origin) = (L)ocal or (D)istant
---------------------------------------------------------------------
An abnormal session release can be started by either the Speaker or the Listener, and by either the user or the provider. It can happen at any point in the session ๐ฌ
Peer ODETTE-FTP entities do an abnormal session release by putting Reason = Error-value into an End Session (ESID) command.
The abnormal release covers these types of error:
- The service provider starts an abnormal release in these cases:
- Protocol error
- Failure of the Start Session (SSID) negotiation
- Command not recognised
- Exchange buffer size error
- Resources not available
- Other unspecified abort code (with "REASON" = unspecified)
- The User Monitor starts an abnormal release in these cases:
- Local site emergency close down
- Resources not available
- Other unspecified abort code (with "REASON" = unspecified)
Other error types may be handled by aborting the connection. ๐จ
3.4.3 Abort ๐
| |
F_ABORT_RQ ---->|------------|----> F_ABORT_IND
| |
User Initiated Abort
| |
F_ABORT_IND <----|------------|----> F_ABORT_IND
| |
Provider Initiated Abort
Parameters
Request Indication
---------------------------------------------------------------------
-- R (Reason): specified or unspecified
-- AO (Abort Origin): (L)ocal or (D)istant
---------------------------------------------------------------------
Either entity can invoke Abort at any time. The service provider can also start an abort if it detects an error ๐ซ
3.4.4 Explanation of Session Take Down Services ๐
User | OFTP | Network | OFTP | User
---------------|------|----------------------|------|---------------
| | | |
1. Normal Release
F_RELEASE_RQ | | ESID(R=normal) | | F_RELEASE_IND
*--------------|-> ==|======================|=> --|-------------->
(R=normal) | | | |
2. User Initiated Abnormal Release
F_RELEASE_RQ | | ESID(R=error) | | F_ABORT_IND
*--------------|-> ==|======================|=> -|-------------->
(R=error value)| | | | (R=error,AO=D)
User | OFTP | Network | OFTP | User
---------------|------|----------------------|------|---------------
| | | |
3. Provider Initiated Abnormal Release
F_ABORT_IND | | ESID(R=error) | | F_ABORT_IND
<--------------|-* *=|======================|=> --|-------------->
| | | |
4. User Initiated Connection Abort
F_ABORT_RQ | | N_DISC_RQ | | F_ABORT_IND
*--------------|-> --|--------->..----------|-> --|-------------->
| | N_DISC_IND | | (R=unsp.,AO=D)
5. Provider Initiated Connection Abort
F_ABORT_IND | | N_DISC_RQ | | F_ABORT_IND
<--------------|-* *-|--------->..----------|-> --|-------------->
(R=error,AO=L) | | N_DISC_IND | | (R=unsp.,AO=D)
Key: * Origin of command flow
F_ ---> File Transfer Service primitive
N_ ---> Network Service primitive
===> ODETTE-FTP (OFTP) protocol message
3.5 Service State Automata ๐ค
This state automaton describes the service the way the User Monitor sees it. Events that cause a state transition are in lower case, and the resulting action is in upper case where it makes sense.
3.5.1 Idle State Diagram ๐
o------------o
decision | | f_connect_ind
+-----------------| IDLE |-----------------+
| F_CONNECT_RQ | (0) | F_CONNECT_RS |
| o------------o |
V |
o-----------------o |
| | |
| I_WF_FCONNECTCF | |
| | |
o--------+--------o |
| |
| F_CONNECT_CF |
V V
o-----------------o o-----------------o
| | | |
| IDLE SPEAKER | | IDLE LISTENER |
| (1) | | (2) |
| See Speaker | | See Listener |
| State Diagram | | State Diagram |
| | | |
o-----------------o o-----------------o
3.5.2 Speaker State Diagram โจ
okay so this one is the speaker's side of the state machine, and it's giving main character energy ๐ the IDLE SPEAKER state is where all the drama starts ๐
o-----------------o o-----------------o
| IDLE LISTENER | | IDLE |
| CD_RQ just sent | | see (0) |
| see (3), Listen | | Idle |
| State Diagram | | State Diagram |
o-----------------o o-----------------o
A A
| |
decision decision decision
F_CD_RQ +----------------+ F_RELEASE_RQ
| | F_EERP_RQ | |
o=================o | o-----------------o
| |<-------------+ | IDLE SPEAKER |
| IDLE SPEAKER | | (4) |
| (1) | decision | CD_IND |
| |<-----------------------------| just received |
o=================o F_EERP_RQ o-----------------o
A A | |
| | | decision and P1 decision and P1 |
| | +-----------------+ +---------------------+
| | F_START_FILE_RQ | | F_START_FILE_RQ
| | V V
| | o---------------o
| | f_file_start_cf(-) | |
| +----------------------| OPENING |
| | |
| o---------------o
| |
f_file_close_cf(-) f_start_file_cf(+)
and not P2 |
| V
o---------------o o---------------o
| | | |------------------+
| CLOSING | | DATA TRANSFER | record to send |
| | | |<-----------------+
o---------------o o---------------o F_DATA_RQ
| A |
| | end of file |
| +-------------------+
| F_CLOSE_FILE_RQ
| o-----------------o
| f_close_file(+) and P2 | IDLE LISTENER |
+--------------------------------------------->| see (2), Listen |
| State Diagram |
Predicates: o-----------------o
P1: Mode = Both or (Mode = Sender-Only)
P2: Negative confirmation or (positive confirmation, Speaker = YES)
3.5.3 Listener State Diagram ๐ง
and now the listener's side, which is basically the speaker's mirror image ๐ช the vibes are very "I heard you, I'm answering" ๐ซถ
o-----------------o o-----------------o
| IDLE SPEAKER | | IDLE |
| CD_IND just | | |
| received see(4) | | see (0) |
| Speaker State | | Idle |
| Diagram | | State Diagram |
o-----------------o o-----------------o
A A
| |
decision f_eerp_ind decision
F_CD_IND +--------------+ F_RELEASE_IND
| | | |
o=================o | o-----------------o
| |<-----------+ f_eerp_ind | |
| |<-----------------------------| IDLE LISTENER |
| IDLE LISTENER | | (3) |
| | f_start_file_ind | CD_RQ |
| (2) | and not p2 | just sent |
| |---------------------+ | |
o=================o F_START_FILE_RS(-) | o-----------------o
A | A A | | |
| | | +-----------------------+ | |
| | | | |
| | | f_start_file_ind and not p2 | |
| | +--------------------------------------+ |
| | F_START_FILE_RS(-) |
| | |
| | f_start_file_ind f_start_file_ind |
| | and p2 and p2 |
| +-------------------------------+ +------------------+
| F_START_FILE_RS(+) | | F_START_FILE_RS(+)
| V V
| o---------------o
| f_close_file_ind and not p1 | DATA |-------------+
+------------------------------| TRANSFER | |
F_CLOSE_FILE_RS(-) | |<------------+
o---------------o F_DATA_IND
o---------------o |
| IDLE SPEAKER | f_close_file_ind and p1 |
| see (1), Spkr |<--------------------------+
| State Diagram | F_CLOSE_FILE_RS(+)
o---------------o
Predicates:
P1: (decision to send F_CLOSE_FILE_RS(+)) and
(decision to set Speaker = yes in F_CLOSE_FILE_RS(+))
P2: (decision to send F_START_FILE_RS(+))
4. Protocol Specification โจ
4.1 Overview ๐ธ
okay so ODETTE-FTP is split into five operating phases, and they go in this order ๐
Start Session
Start File
Data Transfer
End File
End Session
after End File, an ODETTE-FTP entity may start a brand new Start File phase, or it can end the whole session in the End Session phase ๐ฆ
peers chat by sending and receiving messages inside Exchange Buffers over the Network Service ๐ every Exchange Buffer carries exactly one of these commands ๐
SSRM Start Session Ready Message
SSID Start Session
SFID Start File
SFPA Start File Positive Answer
SFNA Start File Negative Answer
DATA Data
CDT Set Credit
EFID End File
EFPA End File Positive Answer
EFNA End File Negative Answer
ESID End Session
CD Change Direction
EERP End to End Response
RTR Ready To Receive
the rest of this section walks through the protocol flows, and Section five has the full command formats ๐ง
4.2 Start Session Phase ๐
the Start Session phase kicks off right after the network connection is established ๐
4.2.1 Entity Definition
the ODETTE-FTP entity that started the network connection becomes the Initiator ๐ซถ its peer becomes the Responder ๐
4.2.2 Protocol Sequence
the first message must be sent by the Responder ๐ here's how the handshake goes โจ
1. Initiator <-------------SSRM -- Responder Ready Message
-- SSID ------------> Identification
<------------ SSID -- Identification
4.3 Start File Phase ๐
4.3.1 Entity Definition
the Initiator from the Start Session phase becomes the Speaker, and the Responder becomes the Listener ๐ค the roles can flip when the Speaker sends a Change Direction command to the Listener ๐
4.3.2 Protocol Sequence
here are the sequences, and yes, one of them loops back to step 1 ๐
1. Speaker -- SFID ------------> Listener Start File
<------------ SFPA -- Answer YES
2. Speaker -- SFID ------------> Listener Start File
<------------ SFNA -- Answer NO
Go To 1
2. Speaker -- CD --------------> Listener Change Direction
Listener <------------ EERP -- Speaker End to End Response
-- RTR -------------> Ready to Receive
<------------ SFID -- Start File
Note: The User Monitor should take steps to prevent a loop situation occurring. ๐
4.3.3 Restart Facilities ๐
the Start File command has a count in it, so an interrupted transfer can be restarted by negotiating from that point ๐ if restart isn't available, the restart count must be set to zero ๐ the sender then starts with the lowest record count + 1 โจ
4.3.4 Broadcast Facilities ๐ก
the destination in a Start File command can be set in one of two ways ๐
- An explicitly defined destination.
- A group destination that allows an intermediate location to broadcast the Virtual File to multiple destinations.
if the destination isn't known, the Listener will send a negative answer to the Speaker ๐ฅบ
4.3.5 Priority ๐
how files get prioritised for transmission is left up to the local implementation, so each host decides for itself ๐ง for a bit of flexibility, there's a change direction mechanism in the End File phase ๐ฆ
4.3.6 End To End Response (EERP) ๐
Okay bestie, the End to End Response (EERP) command is how the originator of a Virtual File finds out it was successfully delivered to its final destination โจ. Once it knows that, it can do little housekeeping tasks, like deleting its copies of the delivered data ๐งน๐ .
A Response Command MUST be sent from the location doing the final processing or distribution of the data back to the originator. The Response is mandatory and MAY be sent in the same session or in any later one ๐ซถ.
When an intermediate location broadcasts or distributes a Virtual File, it MUST receive a Response command from every location it forwarded the data to before it sends its own Response ๐ฅ. That way the Response the originator gets accounts for all the destination locations, no one left out ๐ญ. So an intermediate location has to keep track of the status of the files it processes over time ๐๏ธ.
Example: Point to Point
Location A sends file Ba to Location B, which sends an EERP back to location A after it successfully receives the file ๐ฆ.
o----------o o-----------o
| Loc. A |----------- S1 ---------->| Loc. B |
| | | |
| [Ba] |<---------- R2 -----------| [Ba] |
+----------o o-----------o
Key: S - File Transfer R - Response EERP [Ba] - File for B from A
Example: Data distribution
Location A sends a Virtual File with data for distribution to locations B and C, going through clearing centres E1 and E2 ๐ธ. Clearing centre E1 has to wait for a response from E2 (for file Ba) and from location C before it sends its response, R8, to location A ๐. Clearing centre E2 can only send response R7 to E1 once location B acknowledges file Ba with response R6 โจ.
o---------o o---------o o---------o o---------o
| Loc. A |-- S1 ->| Loc. E1 |-- S2 ->| Loc. E2 |-- S5 ->| Loc. B |
| | | | | | | |
| [Ba,Ca] |<- R8 --| [Ba,Ca] |<- R7 --| [Ba] |<- R6 --| [Ba] |
o---------o o---------o o---------o o---------o
A |
| | o---------o
| +----- S3 ->| Loc. C |
| | |
+--------- R4 --| [Ca] |
o---------o
Example: Data collection
Locations A and B send files Ca and Cb to clearing centre E1, which forwards both files to location C in one single Virtual File ๐. When E1 gets response R4 from C, it sends response R5 to location A and R6 to location B ๐.
o---------o o---------o o---------o
| Loc. A |-- S1 ->| Loc. E1 |-- S3 ->| Loc. C |
| | | | | |
| [Ca] |<- R5 --| [Ca,Cb] |<- R4 --| [Ca,Cb] |
o---------o o---------o o---------o
A |
o---------o | |
| Loc. B |-- S2 -----+ |
| | |
| [Cb] |<- R6 ---------+
o---------o
4.3.7 Ready To Receive Command (RTR) ๐ง
So an EERP doesn't flood the link and jam up two neighbouring nodes ๐ง, we have the Ready To Receive (RTR) command ๐. The RTR acts like an EERP acknowledgement for flow control, but it has no end-to-end meaning ๐.
Speaker -- EERP ------------> Listener End to End Response
<------------- RTR -- Ready to Receive
-- EERP ------------> End to End Response
<------------- RTR -- Ready to Receive
-- SFID ------------> Start File
or
-- CD --------------> Exchange the turn
After sending an EERP, the Speaker MUST wait for an RTR before sending any other commands โณ.
4.4 Data Transfer Phase ๐
Virtual File data flows from the Speaker to the Listener during the Data Transfer phase, which starts once the Start File phase is done ๐.
4.4.1 Protocol Sequence ๐
To stop congestion at the protocol level, there's a flow control mechanism called the Credit (CDT) command ๐ก๏ธ.
A Credit limit gets negotiated in the Start Session phase. It represents how many Data Exchange Buffers the Speaker is allowed to send before it has to wait for a Credit command from the Listener ๐งฎ.
The available credit starts out set to the negotiated value by the Start File positive answer, which works as an implicit Credit command โจ. The Speaker takes one off the available credit count for every data buffer it sends to the Listener ๐.
When the available credit runs out, the Speaker MUST wait for a Credit command from the Listener, or else a protocol error will happen and the session gets aborted ๐จ.
The Listener SHOULD try its best to send the Credit command without delay, so the Speaker doesn't get stuck blocking ๐.
1. Speaker -- SFID ------------> Listener Start File
<------------ SFPA -- Answer YES
2. If the Credit Value is set to 2
Speaker -- Data ------------> Listener Start File
-- Data ------------>
<------------- CDT -- Set Credit
-- Data ------------>
-- EFID ------------> End File
4.5 End File Phase ๐
4.5.1 Protocol Sequence ๐
The Speaker tells the Listener it's done sending a Virtual File by sending an End File (EFID) command ๐ฉ. The Listener replies with a positive or negative End File command, and it has the option to ask for a Change Direction command from the Speaker ๐.
1. Speaker -- EFID ------------> Listener End File
<------------ EFPA -- Answer YES
2. Speaker -- EFID ------------> Listener End File
<------------ EFPA -- Answer YES + CD
-- CD --------------> Change Direction
Listener <------------ EERP -- Speaker End to End Response
-------------- RTR -> Ready to Receive
Go to Start File Phase
3. Speaker -- EFID ------------> Listener End File
<------------ EFNA -- Answer NO
4.6 End Session Phase ๐
4.6.1 Protocol Sequence ๐
The Speaker ends the session by sending an End Session (ESID) command ๐ซถ.
1. Speaker -- EFID ------------> Listener End File
<------------ EFPA -- Answer YES
-- CD --------------> Change Direction
Listener <------------ ESID -- Speaker End Session
4.7 Problem Handling ๐ ๏ธ
Error detection and handling SHOULD be done as close to the problem as possible ๐. That makes it way easier to figure out what went wrong and fix it ๐ก. Each layer of the reference model is responsible for its own error handling ๐งฑ.
ODETTE-FTP can spot protocol errors through how its state machine is built, and it uses activity timers to catch session hang conditions โฑ๏ธ. These mechanisms are separate from the End to End controls ๐ โโ๏ธ.
4.7.1 Protocol Errors ๐
If a protocol error happens, the session gets terminated and application activity is aborted. Both locations go back to the IDLE state ๐ต.
4.7.2 Timers โฐ
To protect against application and network hang conditions, ODETTE-FTP uses activity timers for every situation where a response is required โณ. The timers, and what to do when they expire, are described in section 8, the Protocol State Machine ๐.
4.7.3 Clearing Centres ๐ฌ
Using clearing centres opens the door to errors from the data processing that happens inside the centre ๐. Those errors aren't directly related to ODETTE-FTP or the communication network, so they're outside the scope of this specification ๐ซ.
5. Commands and Formats ๐ฆ
ODETTE-FTP entities talk to each other through Exchange Buffers ๐ฌ. The Command Exchange Buffers are described below โฌ๏ธ. Virtual File data gets carried in Data Exchange Buffers, which are described in Section 6 ๐ง.
5.1 Conventions ๐
5.1.1 Representation unit:
The basic unit of information is an octet, which is eight bits ๐ข.
5.1.2 Values and Characters:
The ISO 646 IRV 7-bit coded character set [ISO-646] is used to encode constants and strings inside command exchange buffers ๐ค.
5.2 Commands ๐ฏ
A Command Exchange Buffer holds a single command, starting right at the beginning of the buffer. Commands and data are never mixed inside one Exchange Buffer ๐ โโ๏ธ. Each command has a fixed length and can not be compressed ๐.
Components:
- Command identifier:
The first octet of an Exchange Buffer is the Command Identifier, and it defines the format of the buffer ๐ชช.
- Parameter(s):
Command parameters are stored in fixed fields inside a Command Exchange Buffer. All values are REQUIRED ๐.
5.3 Command Formats ๐งพ
The ODETTE-FTP commands are described below, using the following definitions ๐.
- Position (Pos.): the field offset within the command exchange buffer, counted from a zero origin ๐.
- Field: the name of the field ๐ท๏ธ.
- Description: a description of the field ๐.
- Format:
F- A field containing fixed values. All allowable values for the field are listed in the command definition.V- A field with variable values within a defined range. For example, the SFIDFSIZ field may contain any integer value between 0000000 and 9999999.X(n)- An alphanumeric field of length n octets.9(n)- A numeric field of length n octets.
All attributes are in character format ๐ก.
A String contains alphanumeric characters from the following set ๐ :
The numerals: 0 to 9
The upper case letters: A to Z
The following special set: / - . & ( ) space.
Space is not allowed as an embedded character ๐ซ. Numeric fields are always right justified, and left padding with zeros MUST be done when needed ๐ช.
5.3.1 SSRM - Start Session Ready Message ๐
o-------------------------------------------------------------------o
| SSRM Start Session Ready Message |
| |
| Start Session Phase Initiator <---- Responder |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | SSRMCMD | SSRM Command, 'I' | F X(1) |
| 1 | SSRMMSG | Ready Message, 'ODETTE FTP READY ' | F X(17) |
| 18 | SSRMCR | Carriage Return | F X(1) |
o-------------------------------------------------------------------o
SSRMCMD ๐ Command Code, character. Value: 'I', the SSRM Command identifier.
SSRMMSG ๐ฌ Ready Message, String(17). Value: 'ODETTE FTP READY '.
SSRMCR โฉ๏ธ Carriage Return, character. Value: a character with hex value '0D' or '8D'.
5.3.2. SSID - Start Session ๐
okay bestie, SSID is the big intro card the Initiator sends at the start of a session ๐ It's a fixed-layout message, so here's the full picture first:
o-------------------------------------------------------------------o
| SSID Start Session |
| |
| Start Session Phase Initiator <---> Responder |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | SSIDCMD | SSID Command 'X' | F X(1) |
| 1 | SSIDLEV | Protocol Release Level | F 9(1) |
| 2 | SSIDCODE | Initiator's Identification Code | V X(25) |
| 27 | SSIDPSWD | Initiator's Password | V X(8) |
| 35 | SSIDSDEB | Exchange Buffer Size | V 9(5) |
| 40 | SSIDSR | Send / Receive Capabilities (S/R/B) | F X(1) |
| 41 | SSIDCMPR | Compression Indicator (Y/N) | F X(1) |
| 42 | SSIDREST | Restart Indicator (Y/N) | F X(1) |
| 43 | SSIDSPEC | Special Logic Indicator (N) | F X(1) |
| 44 | SSIDCRED | Credit | V 9(3) |
| 47 | SSIDRSV1 | Reserved | F X(5) |
| 52 | SSIDUSER | User Data | V X(8) |
| 60 | SSIDCR | Carriage Return | F X(1) |
o-------------------------------------------------------------------o
Now let's go field by field ๐
SSIDCMD (Command Code, Character) โจ This is the command identifier. The value is 'X', the SSID Command identifier.
SSIDLEV (Protocol Release Level, Numeric(1)) ๐ธ The value '1' means ODETTE-FTP protocol release level 1. Future release levels will get higher numbers. The protocol release level is negotiable, and the lowest level gets selected.
SSIDCODE (Initiator's Identification Code, String(25)) ๐ซถ Format: See Identification Code (Section 5.4). This uniquely identifies the Initiator (sender) taking part in the ODETTE-FTP session.
SSIDPSWD (Password, String(8)) ๐ This is the key used to authenticate the sender. It's assigned by bilateral agreement.
SSIDSDEB (Exchange Buffer Size, Numeric(5)) ๐ Minimum: 128 and Maximum: 99999. This is the length, in octets, of the largest Exchange Buffer the location can accept. The length includes the command octet but does not include the Stream Transmission Header. After negotiation, the smallest size will be selected.
SSIDSR (Send / Receive Capabilities, Character) ๐ฆ The value 'S' means the location can only send files. 'R' means it can only receive files. 'B' means it can do both. Sending and receiving get serialised during the session, so parallel sessions will not take place. An error occurs if adjacent locations both specify the send or receive capability.
SSIDCMPR (Compression Indication, Character) ๐ The value 'Y' means the location can handle compressed data. 'N' means it can not. Compression is only used if both locations support it. The compression mechanism is described in Section 6.2.
SSIDREST (Restart Indication, Character) ๐ The value 'Y' means the location can handle restarting a partially transmitted file. 'N' means it can not restart a file.
SSIDSPEC (Special Logic Indication, Character) ๐ง The only valid value is 'N', and that's only for TCP. The Special Logic extensions are only useful in an X.25 environment and are not supported for TCP/IP.
SSIDCRED (Credit, Numeric(3)) ๐ Maximum: 999. This is the number of consecutive Data Exchange Buffers the Speaker sends before it MUST wait for a Credit (CDT) command from the Listener. The credit value only applies to Data flow in the Data Transfer phase.
The Speaker's available credit gets set to SSIDCRED when it receives a Start File Positive Answer (SFPA) command from the Listener. It gets zeroed by the End File (EFID) command.
After negotiation, the smallest size MUST be selected in the Responder's answer, or a protocol error will abort the session. This is the negotiation of the "credit-window-size" parameter:
Window Size m -- SSID ------------>
<------------ SSID -- Window Size n
(n less or equal m)
Note: negotiated value will be "n".
SSIDRSV1 (Reserved, String(5)) ๐ This field is reserved for future use.
SSIDUSER (User Data, String(8)) ๐ธ The ODETTE-FTP is allowed to use this in any way it likes. If it goes unused, it SHOULD be initialised to spaces. A bilateral agreement is expected to exist about what the data means.
SSIDCR (Carriage Return, Character) ๐
The value is the character with hex value '0D' or '8D'.
5.3.3. SFID - Start File ๐ฆ
SFID is the message that kicks off a Virtual File transfer, so this one carries all the file details ๐
o-------------------------------------------------------------------o
| SFID Start File |
| |
| Start File Phase Speaker ----> Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | SFIDCMD | SFID Command, 'H' | F X(1) |
| 1 | SFIDDSN | Virtual File Dataset Name | V X(26) |
| 27 | SFIDRSV1 | Reserved | F X(9) |
| 36 | SFIDDATE | Virtual File Date stamp, (YYMMDD) | V X(6) |
| 42 | SFIDTIME | Virtual File Time stamp, (HHMMSS) | V X(6) |
| 48 | SFIDUSER | User Data | V X(8) |
| 56 | SFIDDEST | Destination | V X(25) |
| 81 | SFIDORIG | Originator | V X(25) |
| 106 | SFIDFMT | File Format, (F/V/U/T) | F X(1) |
| 107 | SFIDLRECL | Maximum Record Size | V 9(5) |
| 112 | SFIDFSIZ | File Size, 1K blocks | V 9(7) |
| 119 | SFIDREST | Restart Position | V 9(9) |
o-------------------------------------------------------------------o
Here's the breakdown ๐ท
SFIDCMD (Command Code, Character) โจ The value is 'H', the SFID Command identifier.
SFIDDSN (Virtual File Dataset Name, String(26)) ๐ This is the dataset name of the Virtual File being transferred, assigned by bilateral agreement. No general structure is defined for this attribute. Check out Virtual Files - Identification (Section 1.5.2) for more.
SFIDRSV1 (Reserved, String(9)) ๐ This field is reserved for future use.
SFIDDATE (Virtual File Date stamp, String(6)) ๐
Format: 'YYMMDD'. That's 6 decimal digits for the year, month and day, respectively [ISO-8601]. The Virtual File's Originator assigns this stamp to show when the file was made available for transmission. See Virtual Files - Identification (Section 1.5.2).
SFIDTIME (Virtual File Time stamp, String(6)) โฐ Format: 'HHMMSS'. That's 6 decimal digits for the hours, minutes and seconds, respectively [ISO-8601]. The Virtual File's Originator assigns this stamp to show when the file was made available for transmission. See Virtual Files - Identification (Section 1.5.2).
SFIDUSER (User Data, String(8)) ๐ธ The ODETTE-FTP is allowed to use this in any way it likes. If it goes unused, it SHOULD be initialised to spaces. A bilateral agreement is expected to exist about what the data means.
SFIDDEST (Destination, String(25)) ๐ Format: See Identification Code (Section 5.4). This is the Final Recipient of the Virtual File. It's the location that will look into the Virtual File content and perform mapping functions. It's also the location that creates the End to End Response (EERP) command for the received file.
SFIDORIG (Originator, String(25)) ๐ง Format: See Identification Code (Section 5.4). This is the Originator of the Virtual File, meaning the location that created (mapped) the data for transmission.
SFIDFMT (File Format, Character) ๐ The values are 'F' for Fixed format binary file, 'V' for Variable format binary file, 'U' for Unstructured binary file, and 'T' for Text. This is the Virtual File format, and it's used to calculate the restart position (Section 1.5.3).
SFIDLRECL (Maximum Record Size, Numeric(5)) ๐ Maximum: 99999. This is the length in octets of the longest logical record that may be transferred to a location. Only user data is included. If SFIDFMT is 'T' or 'U', then this attribute MUST be set to '00000'.
SFIDFSIZ (File Size, Numeric(7)) ๐พ Maximum: 9999999. This is the space, in 1K (1024 octet) blocks, required at the Originator location to store the Virtual File. It's only meant to be a good estimate of the Virtual File size.
SFIDREST (Restart Position, Numeric(9)) ๐ Maximum: 999999999. This is the Virtual File restart position. The count represents:
- The Record Number if SSIDFMT is
'F'or'V'. - The file offset in 1K (1024 octet) blocks if SSIDFMT is
'U'or'T'.
The count expresses the transmitted user data, meaning before compression, with the header not included. After negotiation between adjacent locations, retransmission will start at the lowest value. ๐
5.3.4. SFPA - Start File Positive Answer โจ
o-------------------------------------------------------------------o
| SFPA Start File Positive Answer |
| |
| Start File Phase Speaker <---- Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | SFPACMD | SFPA Command, '2' | F X(1) |
| 1 | SFPAACNT | Answer Count | V 9(9) |
o-------------------------------------------------------------------o
Okay so SFPA is the Listener saying "yes, go ahead" to a Start File ๐ It's giving "I'm ready and I'm listening" ๐
SFPACMD (Command Code, Character) ๐ฆ Value: '2', the SFPA Command identifier.
SFPAACNT (Answer Count, Numeric(9)) ๐งฎ The Listener must enter a count lower or equal to the restart count the Speaker put in the Start File (SFID) command. The count tells you how much user data was received. If restart facilities are not available, a count of zero must be specified. So no restart? Zero, bestie, zero ๐
5.3.5. SFNA - Start File Negative Answer
o-------------------------------------------------------------------o
| SFNA Start File Negative Answer |
| |
| Start File Phase Speaker <---- Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | SFNACMD | SFNA Command, '3' | F X(1) |
| 1 | SFNAREAS | Answer Reason | F 9(2) |
| 3 | SFNARRTR | Retry Indicator, (Y/N) | F X(1) |
o-------------------------------------------------------------------o
SFNA is the opposite energy ๐ The Listener is saying "nah, not today," and it comes with receipts ๐งพ
SFNACMD (Command Code, Character) ๐ฆ Value: '3', the SFNA Command identifier.
SFNAREAS (Answer Reason, Numeric(2)) ๐ โโ๏ธ This is the reason why the transmission can not proceed, and the possible values are:
Value: '01' Invalid filename.
'02' Invalid destination.
'03' Invalid origin.
'04' Storage record format not supported.
'05' Maximum record length not supported.
'06' File size is too big.
'10' Invalid record count.
'11' Invalid byte count.
'12' Access method failure.
'13' Duplicate file.
'99' Unspecified reason.
SFNARRTR (Retry Indicator, Character) ๐ The possible values are:
Value: 'N' Transmission should not be retried.
'Y' The transmission may be retried latter.
This one is the Listener telling the Speaker whether it should try again later, usually because of a temporary thing on the Listener's side, like running out of storage space. It should be used together with the Answer Reason code (SFNAREAS) ๐ง
An invalid file name error can happen because of a problem mapping the Virtual File onto a real file, and those problems can not always be fixed right away ๐ญ So it is recommended that when an SFNA with Retry = Y is received, the User Monitor attempts to retransmit the relevant file in a subsequent session. Patience is a whole vibe ๐ธ
5.3.6. DATA - Data Exchange Buffer
o-------------------------------------------------------------------o
| DATA Data Exchange Buffer |
| |
| Data Transfer Phase Speaker ----> Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | DATACMD | DATA Command, 'D' | F X(1) |
| 1 | DATABUF | Data Exchange Buffer payload | V X(n) |
o-------------------------------------------------------------------o
This is where the actual data goes, the main event ๐ฌ
DATACMD (Command Code, Character) ๐ฆ Value: 'D', the DATA Command identifier.
DATABUF (Data Exchange Buffer payload, String(n)) ๐ฆ A variable length buffer that holds the data payload. The Data Exchange Buffer is described in Section 6, so go check that one out ๐
5.3.7. CDT - Set Credit
o-------------------------------------------------------------------o
| CDT Set Credit |
| |
| Data Transfer Phase Speaker <---- Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | CDTCMD | CDT Command, 'C' | F X(1) |
| 1 | CDTRSV1 | Reserved | F X(2) |
o-------------------------------------------------------------------o
CDT is the credit one, and it's lowkey a flex ๐ณ
CDTCMD (Command Code, Character) ๐ฆ Value: 'C', the CDT Command identifier.
CDTRSV1 (Reserved, String(2)) ๐ซ This field is reserved for future use, so just keep it in your back pocket for now โจ
5.3.8. EFID - End File
o-------------------------------------------------------------------o
| EFID End File |
| |
| End File Phase Speaker ----> Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | EFIDCMD | EFID Command, 'T' | F X(1) |
| 1 | EFIDRCNT | Record Count | V 9(9) |
| 10 | EFIDUCNT | Unit Count | V 9(12) |
o-------------------------------------------------------------------o
EFID is the wrap-up, the "and that's a whole file" moment ๐
EFIDCMD (Command Code, Character) ๐ฆ Value: 'T', the EFID Command identifier.
EFIDRCNT (Record Count, Numeric(9)) ๐
Maximum: 999999999
For SSIDFMT 'F' or 'V', this is the exact record count. For SSIDFMT 'U' or 'T', it's zeros. The count expresses the real size of the file, before compression, and the header is not included. The total count is always used, even during restart processing, no exceptions ๐
EFIDUCNT (Unit Count, Numeric(12)) ๐ข
Maximum: 999999999999
This is the exact number of units (octets) transmitted. The count expresses the real size of the file, and the total count is always used, even during restart processing ๐ซถ
5.3.9. EFPA - End File Positive Answer
o-------------------------------------------------------------------o
| EFPA End File Positive Answer |
| |
| End File Phase Speaker <---- Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | EFPACMD | EFPA Command, '4' | F X(1) |
| 1 | EFPACD | Change Direction Indicator, (Y/N) | F X(1) |
o-------------------------------------------------------------------o
EFPA is the Listener's "yep, we're done, and also can we swap roles?" ๐
EFPACMD (Command Code, Character) ๐ฆ Value: '4', the EFPA Command identifier.
EFPACD (Change Direction Indicator, Character) ๐โโ๏ธ
Value: 'N' Change direction not requested.
'Y' Change direction requested.
This parameter lets the Listener ask the Speaker for a Change Direction (CD) command. Ask and you shall receive ๐
5.3.10. EFNA - End File Negative Answer
o-------------------------------------------------------------------o
| EFNA End File Negative Answer |
| |
| End File Phase Speaker <---- Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | EFNACMD | EFNA Command, '5' | F X(1) |
| 1 | EFNAREAS | Answer Reason | F 9(2) |
o-------------------------------------------------------------------o
EFNA is the end-of-file version of the "nope" ๐ Same vibe as SFNA, just at the end of the file.
EFNACMD (Command Code, Character) ๐ฆ Value: '5', the EFNA Command identifier.
EFNAREAS (Answer Reason, Numeric(2)) ๐ โโ๏ธ This is the reason why the transmission can not proceed, and the possible values are:
Value: '01' Invalid filename.
'02' Invalid destination.
'03' Invalid origin.
'04' Storage record format not supported.
'05' Maximum record length not supported.
'06' File size is too big.
'10' Invalid record count.
'11' Invalid byte count.
'12' Access method failure.
'13' Duplicate file.
'99' Unspecified reason.
Bestie, the file part is basically finished and we're so close to the good stuff ๐โจ
5.3.11 ESID - End Session โจ
Okay so ESID is the "we're done here, bestie" command ๐ It's how the session gets closed out, and it comes with a reason code so the other side knows why it's wrapping up ๐ซถ
o-------------------------------------------------------------------o
| ESID End Session |
| |
| End Session Phase Speaker ----> Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | ESIDCMD | ESID Command, 'F' | F X(1) |
| 1 | ESIDREAS | Reason Code | F 9(2) |
| 3 | ESIDCR | Carriage Return | F X(1) |
o-------------------------------------------------------------------o
ESIDCMD is the command code, and it's a character ๐ค
- Value:
'F', which is the ESID Command identifier.
ESIDREAS is the reason code, a numeric(2) field ๐ข Here are all the reasons:
'00': Normal session termination.'01': Command not recognised. An Exchange Buffer contains an invalid command code (1st octet of the buffer).'02': Protocol violation. An Exchange Buffer contains an invalid command for the current state of the receiver.'03': User code not known. A Start Session (SSID) command contains an unknown or invalid Identification Code.'04': Invalid password. A Start Session (SSID) command contained an invalid password.'05': Local site emergency close down. The local site has entered an emergency close down mode. Communications are being forcibly terminated. this one is serious ๐ญ'06': Command contained invalid data. A field within a Command Exchange buffer contains invalid data.'07': Exchange Buffer size error. The length of the Exchange Buffer as determined by the Stream Transmission Header is different to the length implied by the Command Code.'08': Resources not available. The request for connection has been denied due to a resource shortage. The connection attempt should be retried later.'09': Time out.'10': Mode or capabilities incompatible.'99': Unspecified Abort code. An error was detected for which no specific code is defined.
ESIDCR is the carriage return ๐
- Value: Character with hex value
'0D'or'8D'.
5.3.12 CD - Change Direction ๐ฆ
Next up is CD, the "switch roles, it's my turn" command. It shows up in the Start File, End File and End Session phases, and it's the one that lets the direction of the conversation flip ๐ Honestly iconic energy.
o-------------------------------------------------------------------o
| CD Change Direction |
| |
| Start File Phase Speaker ----> Listener |
| End File Phase Speaker ----> Listener |
| End Session Phase Initiator <---> Responder |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | CDCMD | CD Command, 'R' | F X(1) |
o-------------------------------------------------------------------o
CDCMD is the command code, a character ๐
- Value:
'R', which is the CD Command identifier.
5.3.13 EERP - End to End Response ๐
EERP is the "got it, here's proof" message. It's the End to End Response, and it's basically the receiver telling the sender that the Virtual File made it to the final recipient ๐ฅน It's giving closure.
o-------------------------------------------------------------------o
| EERP End to End Response |
| |
| Start File Phase Speaker ----> Listener |
| End File Phase Speaker ----> Listener |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | EERPCMD | EERP Command, 'E' | F X(1) |
| 1 | EERPDSN | Virtual File Dataset Name | V X(26) |
| 27 | EERPRSV1 | Reserved | F X(9) |
| 36 | EERPDATE | Virtual File Date stamp, (YYMMDD) | V X(6) |
| 42 | EERPTIME | Virtual File Time stamp, (HHMMSS) | V X(6) |
| 48 | EERPUSER | User Data | V X(8) |
| 56 | EERPDEST | Destination | V X(25) |
| 81 | EERPORIG | Originator | V X(25) |
o-------------------------------------------------------------------o
EERPCMD is the command code, a character โจ
- Value:
'E', which is the EERP Command identifier.
EERPDSN is the Virtual File Dataset Name, a String(26) ๐ The name is assigned by bilateral agreement, which means both sides agree on it ahead of time. There's no general structure defined for it. See Virtual Files - Identification (Section 1.5.2).
EERPRSV1 is reserved, a String(9). It's set aside for future use, so hands off ๐ โโ๏ธ
EERPDATE is the Virtual File Date stamp, a String(6) ๐
- Format:
'YYMMDD', which is 6 decimal digits for the year, month and day respectively [ISO-8601]. - It's the date stamp the Virtual File's Originator put on it, showing when the file was made available for transmission. See Virtual Files - Identification (Section 1.5.2).
EERPTIME is the Virtual File Time stamp, a String(6) โฐ
- Format:
'HHMMSS', which is 6 decimal digits for hours, minutes and seconds respectively [ISO-8601]. - It's the time stamp the Virtual File's Originator assigned, showing when the file was made available for transmission. See Virtual Files - Identification (Section 1.5.2).
EERPUSER is User Data, a String(8) ๐ The ODETTE-FTP can use it in any way. If it's unused, it should be initialised to spaces. It's expected that there's a bilateral agreement about what the data means.
EERPDEST is the Destination, a String(25) ๐ฌ
- Format: See Identification Code (Section 5.4).
- It's the Originator of the Virtual File, meaning the location that created (mapped) the data for transmission.
EERPORIG is the Originator, a String(25) ๐ง
- Format: See Identification Code (Section 5.4).
- It's the Final Recipient of the Virtual File. This is the location that will look into the Virtual File content and perform mapping functions. It's also the location that creates the EERP for the received file.
5.3.14 RTR - Ready To Receive ๐ธ
RTR is the "I'm ready, send it over" message ๐ It goes from the Responder back to the Initiator in the Start File and End File phases, so the sender knows it can go ahead.
o-------------------------------------------------------------------o
| RTR Ready To Receive |
| |
| Start File Phase Initiator <---- Responder |
| End File Phase Initiator <---- Responder |
|-------------------------------------------------------------------|
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | RTRCMD | RTR Command, 'P' | F X(1) |
o-------------------------------------------------------------------o
RTRCMD is the command code, a character ๐ซง
- Value:
'P', which is the RTR Command identifier.
5.4 Identification Code ๐ชช
Okay so every party in an ODETTE-FTP session needs a proper ID. The Initiator (sender) and Responder (receiver) are each uniquely identified by an Identification Code based on [ISO 6523], Structure for the Identification of Organisations (SIO) ๐ While the session is going, the two locations are considered adjacent, so they're basically right next to each other for the whole transmission.
The SIO has the following format:
o-------------------------------------------------------------------o
| Pos | Field | Description | Format |
|-----+-----------+---------------------------------------+---------|
| 0 | SIOOID | ODETTE Identifier | F X(1) |
| 1 | SIOICD | International Code Designator | V 9(4) |
| 5 | SIOORG | Organisation Code | V X(14) |
| 19 | SIOCSA | Computer Sub-Address | V X(6) |
o-------------------------------------------------------------------o
SIOOID is the ODETTE Identifier, a character ๐ฆ
- Value:
'O'indicates an ODETTE assigned Organisation Identifier. Other values may be used for non-ODETTE codes.
SIOICD is the International Code Designator, a String(4). It's a code that forms part of the Organisation Identifier.
SIOORG is the Organisation Code, a String(14). It's also a code that forms part of the Organisation Identifier. This field may contain the letters A to Z, the digits 0 to 9, space and hyphen characters ๐ค
SIOCSA is the Computer Sub-Address, a String(6) ๐ป It's a locally assigned address that uniquely identifies a system within an organisation (defined by an Organisation Identifier).
6. ODETTE-FTP Data Exchange Buffer ๐ฆ
6.1 Overview ๐
Okay, the vibe here is that Virtual Files get sent by mapping their records into Data Exchange Buffers โจ The maximum buffer length gets negotiated between the ODETTE-FTP entities through the Start Session (SSID) commands, which get swapped during the Start Session Phase of the protocol. The format is based on the Network Independent File Transfer Protocol [NIFTP] ๐
Virtual File records can be any length, which is so flexible ๐ There's also a simple compression scheme for strings of repeated characters, so you don't have to send the same character over and over again ๐ซถ
If you want to see the Data Exchange Buffer in action, check out Appendix A ๐
6.2. Data Exchange Buffer Format ๐
Okay so for sending Virtual File records, the data gets split into Subrecords, and every single one is preceded by a one octet Subrecord Header ๐
The Data Exchange Buffer is made up of the initial Command character, followed by the Subrecords, like this:
o--------------------------------------------------------
| C | H | | H | | H | | /
| M | D | SUBRECORD | D | SUBRECORD | D | SUBRECORD | /_
| D | R | | R | | R | | /
o-------------------------------------------------------
CMD
The Data Exchange Buffer Command Character, 'D'. ๐
HDR
This is the one octet Subrecord Header, and it's laid out like this:
0 1 2 3 4 5 6 7
o-------------------------------o
| E | C | |
| o | F | C O U N T |
| R | | |
o-------------------------------o
Bits
0 End of Record Flag ๐ฆ Set to indicate that the next subrecord is the last subrecord of the current record.
Unstructured files are transmitted as a single record, and in this case the flag acts as an end of file marker.
1 Compression Flag ๐ธ Set to indicate that the next subrecord is compressed.
2-7 Subrecord Count ๐ง This is the number of octets in the Virtual File represented by the next subrecord, expressed as a binary value.
For uncompressed data this is simply the length of the subrecord.
For compressed data this is the number of times that the single octet in the following subrecord must be inserted in the Virtual File.
Since six bits are available, the next subrecord may represent between 0 and 63 octets of the Virtual File. โจ
6.3. Buffer Filling Rules ๐งฉ
An Exchange Buffer may be any length up to the value negotiated in the Start Session exchange. ๐
Virtual File records may be concatenated within one Exchange Buffer, or split across a number of buffers. ๐
Here's the big one: a subrecord is never split between two Exchange Buffers. ๐ If the remaining space in the current Exchange Buffer is insufficient to contain the next 'complete' subrecord, one of the following strategies should be used:
- Truncate the Exchange Buffer, and put the complete subrecord (preceded by its header octet) in a new Exchange Buffer.
- Split the subrecord into two, filling the remainder of the Exchange Buffer with the first new subrecord and starting a new Exchange Buffer with the second.
A record of length zero may appear anywhere in the Exchange Buffer. ๐ซถ
A subrecord of length zero may appear anywhere in the record and/or the Exchange Buffer. ๐
7. Stream Transmission Buffer (TCP only) ๐
7.1. Introduction
Okay, history lesson but make it tea โ The ODETTE-FTP was originally designed to utilise the ISO Network Service, specifically the X.25 specification. It relies on the fact that the network service will preserve the sequence and boundaries of data units transmitted through the network, and that the network service will pass the length of the data unit to the receiving ODETTE-FTP. TCP, on the other hand, offers a stream based connection which does not provide these functions. ๐ญ
So to use the TCP stream without disrupting the existing ODETTE-FTP, a Stream Transmission Buffer (STB) gets created by adding a Stream Transmission Header (STH) to the start of all Command and Data Exchange Buffers before they're passed to the TCP transport service. โจ This lets the receiving ODETTE-FTP recover the original Exchange Buffers. Iconic ๐
STH - Stream Transmission Header
OEB - ODETTE-FTP Exchange Buffer
The Stream Transmission Buffer comprises of a STH and OEB.
o-----+-----------------+-----+--------------------+-----+------
| STH | OEB | STH | OEB | STH | OEB/
o-----+-----------------+-----+--------------------+-----+----
7.2. Stream Transmission Header Format ๐
The Stream Transmission Header is shown below. The fields are transmitted from left to right. ๐
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| Flags | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Version
Value: 0001 (binary) ๐ธ
Stream Transmission Header version number.
Flags
Value: 0000 (binary) ๐ง
Reserved for future use.
Length
Range: 5 - 100003 (decimal) ๐
The length of the Stream Transmission Buffer (STH+OEB).
The smallest STB is 5 octets, consisting of a 4 octet header followed by a 1 octet Exchange Buffer, such as a Change Direction (CD) command. ๐ฆ
The maximum Exchange Buffer length that can be negotiated is 99999 octets (Section 5.3.2), giving a STB length of 100003. ๐คฏ
The length is expressed as a binary number with the most significant bit on the left.
It is expected that implementations of this protocol will follow the Internet robustness principle of being conservative in what is sent and liberal in what is accepted. ๐ซถ
8. Protocol State Machine ๐ง
8.1. ODETTE-FTP State Machine
The operation of an ODETTE-FTP entity is formally defined by the State Machine presented below. There are five State and Transition tables, and for each table additional information is given in the associated Predicate and Action lists. ๐ฅ
The response of an ODETTE-FTP entity to the receipt of an event is defined by a Transition table entry, indexed by the Event/State intersection within the appropriate State table. ๐
Each Transition table entry defines the actions taken, events generated, and new state entered. Predicates may be used within a table entry to select the correct response on the basis of local information held by the entity. ๐ง
A transition table contains the following fields:
Index(I) State transition index.
Predicate A list of predicates used to select between different
possible transitions. The predicates are defined in the
Predicate and Action list.
Actions A list of actions taken by the entity. The actions are
defined in the Predicate and Action list.
Events Output events generated by the entity
Next State The new state of the entity.
8.2. Error Handling ๐
The receipt of an event in a given state may be invalid for three reasons. Let's go ๐
- The case is impossible by construction of the state automata, denoted
Xin the State tables. For example, a timer which has not been set cannot run out. - The event is the result of an error in the Network Service implementation, also denoted
Xin the state tables. The Network Service implementation is considered to be correct. - For all other cases the event is considered to be a User Error, denoted "U" in the state tables.
The State tables define the conditions under which a User event is valid, thus preventing the generation of a protocol error by the ODETTE-FTP entity as a result of a User Monitor error. The reaction of the entity to such errors is undefined and regarded as a local implementation issue. ๐
The State tables also allow protocol errors due to the receipt of invalid Exchange Buffers to be detected. In such cases, the reaction of the entity to the error is defined. โญ
8.3. States
Okay bestie, the Command Mode is strictly a Half Duplex Flip-Flop Mode ๐ฆ. One side talks, then the other side gets its turn. No talking over each other ๐
A_NC_ONLY(Responder, Network Connection opened): The Responder has sent its Ready Message (SSRM) and is waiting for Start Session (SSID) from the Initiator ๐ธA_WF_CONRS(Responder Waiting for F_CONNECT_RS): The Responder has received the Initiator's Start Session (SSID) and is waiting for a response (F_CONNECT_RS) from its User Monitor ๐CDSTWFCD(CD_RQ stored in WF_CD state): The User Monitor can't see the WF_CD state, so it may send a Change Direction request (F_CD_RQ) before the ODETTE-FTP receives a Change Direction (CD) command ๐CLIP(Close Input Pending): The Listener has received an End File (EFID) command and is waiting for the Close File response (F_CLOSE_FILE_RS) from its User Monitor ๐CLOP(Close Out Pending): The Speaker has sent an End File (EFID) command and is waiting for an End File Answer (EFPA or EFNA) โจERSTWFCD(End to End Response stored in WF_CD state): Same deal asCDSTWFCD. The User Monitor can't see WF_CD, so it may send F_EERP_RQ before the ODETTE-FTP receives a Change Direction (CD) command ๐IDLE(Connection IDLE): Chillin' ๐งIDLELI(Idle Listener): Idle Listener, just vibing ๐IDLELICD(Idle Listener, F_CD_RQ Received): The ODETTE-FTP entity has become the Listener after receiving a Change Direction request (F_CD_RQ) from the User Monitor. Receiving an End Session (ESID) is valid in this state ๐ฅIDLESP(Idle Speaker): Idle Speaker, also chillin' ๐IDLESPCD(Idle Speaker, F_CD_IND Sent): The ODETTE-FTP entity has sent a Change Direction indication (F_CD_IND) to the User Monitor. A Change Direction request (F_CD_RQ) is invalid in this state ๐ซI_WF_NC(Initiator Waiting for Network Connection): The Initiator has requested a new network connection and is waiting for a Connection confirmation (N_CON_CF) from the Network Service ๐กI_WF_RM(Initiator Waiting for Ready Message): Before sending Start Session (SSID), the Initiator must wait for a Ready Message (SSRM) from the Responder โณI_WF_SSID(Initiator Waiting for SSID): The Initiator has sent a Start Session (SSID) command and is waiting for Start Session from the Responder ๐OPI(Open Input, Data Transfer Phase): The Listener is waiting for the Speaker to send a Data Exchange buffer ๐ฆOPIP(Open Input Pending): The Listener has received a Start File (SFID) command and is waiting for the Start File response (F_START_FILE_RS) from its User Monitor ๐ฆOPO(Open Out, Data Transfer Phase): The Speaker has received a Start File Positive Answer (SFPA) and is waiting for a Data (F_DATA_RQ) or Close File (F_CLOSE_FILE) request from its User Monitor ๐OPOP(Open Out Pending): The Speaker has sent a Start File (SFID) command and is waiting for a Start File Answer (SFPA or SFNA) ๐ทOPOWFC(Open Out Wait for Credit): The Speaker is waiting for a Set Credit (CDT) command before sending any more Data Exchange buffers ๐ณSFSTWFCD(Start File Request stored in WF_CD state): The User Monitor can't see WF_CD, so it may send a Start File request (F_START_FILE_RQ) before the ODETTE-FTP receives a Change Direction (CD) command ๐ซถWF_CD(Wait for Change Direction): The Listener wants to become the Speaker and is waiting for a Change Direction (CD) command after sending an End File Positive Answer (EFPA) requesting a change of direction ๐WF_RTR(Wait for Ready To Receive): The Initiator has sent an End to End Response (EERP) command and must wait for Ready To Receive (RTR) from the Responder ๐WF_NDISC(Wait for N_DISC_IND): The ODETTE-FTP has sent an End Session (ESID) command and is waiting for a Disconnection indication (N_DISC_IND) from the Network Service ๐
8.4. Input Events
Here's everything that can walk into the state machine and knock ๐ช
User Monitor Input Events (Section 3)
F_DATA_RQ F_CONNECT_RQ F_START_FILE_RQ F_CLOSE_FILE_RQ
F_EERP_RQ F_CONNECT_RS F_START_FILE_RS(+) F_CLOSE_FILE_RS(+)
F_CD_RQ F_ABORT_RQ F_START_FILE_RS(-) F_CLOSE_FILE_RS(-)
F_RELEASE_RQ
Network Input Events (Section 2.2)
N_CON_IND N_CON_CF N_DATA_IND N_DISC_IND N_RST_IND
Peer ODETTE-FTP Input Events (Section 4)
SSID SFID SFPA SFNA EFID EFPA EFNA
DATA ESID EERP RTR CD CDT SSRM
Internal Input Events
TIME-OUT - Internal ODETTE-FTP timer expires.
Input event parameters are written as I.Event-name.Parameter-name inside the state table action and predicate lists. The ODETTE-FTP entity can look at them, but it can't change them ๐
8.5. Output Events
And here's everything the state machine can send back out ๐ค
User Monitor Output Events (Section 3)
F_DATA_IND F_CONNECT_IND F_START_FILE_IND F_CLOSE_FILE_IND
F_EERP_IND F_CONNECT_CF F_START_FILE_CF(+) F_CLOSE_FILE_CF(+)
F_CD_IND F_ABORT_IND F_START_FILE_CF(-) F_CLOSE_FILE_CF(-)
F_RELEASE_IND
Network Output Events (Section 2.2)
N_CON_RQ N_CON_RS N_DATA_RQ N_DISC_RQ
Peer ODETTE-FTP Output Events (Section 4)
SSID SFID SFPA SFNA EFID EFPA EFNA
DATA ESID EERP RTR CD CDT SSRM
Output event parameters are written as O.Event-name.Parameter-name inside the state table action and predicate lists. This time the ODETTE-FTP entity can both look at them and change them ๐ ๏ธ
8.6. Local Variables
The ODETTE-FTP entity keeps track of these variables to help the protocol run smoothly ๐ง . They're written as V.Variable-name in the action and predicate lists. The entity can look at and change their values, and each one starts out undefined ๐ฑ
Variable Type Comments
---------------------------------------------------------------------
Buf-size Integer Negotiated Exchange Buffer size.
Called-addr Address Used to build O.F_CONNECT_IND.Called-addr
Calling-addr Address To build O.F_CONNECT_IND.Calling-addr
Compression Yes/No Compression in used as agreed.
Credit_L Integer Listeners credit counter.
Credit_S Integer Speaker's credit counter.
Id String Used to build O.SSID.Id
Mode Sender-only, Receiver-only, Both.
Pswd String Password, used to build O.SSID.Pswd
Req-buf Primitive Input event (F_XXX_RQ) stored in WF_CD state.
Restart Yes/No Restart in used as agreed.
Restart-pos Integer Used only during file opening.
Window Integer The Credit value negotiated for the session.
---------------------------------------------------------------------
8.7. Local Constants
These constants describe what a particular ODETTE-FTP entity is capable of ๐ช. They're written as C.Constant-name in the state table action and predicate lists. The entity can look at them but can't change them ๐
Constant Value Comments
---------------------------------------------------------------------
Cap-compression Yes/No Compression supported?
Cap-init Initiator Must be Initiator.
Responder Must be Responder.
Both Can be Initiator or Responder.
Cap-mode Sender-only Must be sender.
Receiver-only Must be receiver.
Both Can be sender or receiver.
Max-buf-size 127 < Int < 100000 Maximum buffer size supported.
Max-window Int < 1000 Local maximum credit value.
---------------------------------------------------------------------
8.8. Session Connection State Table
8.8.1. State Table
Time for the big grid ๐ฐ
o----------------------------------------------o
| | Other States |
| |--------------------------------------o |
| S | A_WF_CONRS | |
| |----------------------------------o | |
| T | A_NC_ONLY | | |
| |------------------------------o | | |
| A | I_WF_SSID | | | |
| |--------------------------o | | | |
| T | I_WF_RM | | | | |
| |----------------------o | | | | |
| E | I_WF_NC | | | | | |
| |------------------o | | | | | |
| | IDLE | | | | | | |
|==================o---+---+---+---+---+---+---|
| | F_CONNECT_RQ | A | X | X | X | X | X | X |
| |--------------+---+---+---+---+---+---+---|
| E | N_CON_CF | X | C | X | X | X | X | X |
| |--------------+---+---+---+---+---+---+---|
| V | SSRM | X | X | H | X | X | X | X |
| |--------------+---+---+---+---+---+---+---|
| E | SSID | X | X | X | D | E | F | F |
| |--------------+---+---+---+---+---+---+---|
| N | N_CON_IND | B | X | X | X | X | X | X |
| |--------------+---+---+---+---+---+---+---|
| T | F_CONNECT_RS | X | U | U | U | U | G | U |
| |--------------+---+---+---+---+---+---+---|
| | ESID(R=10) | X | X | X | F | X | X | X |
o----------------------------------------------o
8.8.2. Transition Table
Now for the letters in the grid. Each one points to a row here, telling us what to check, what to send, and where to land ๐ฏ
I | Predicate Actions Output Events Next State
===o=================================================================
A | P1: F_ABORT_IND IDLE
| not P1: 1 N_CON_RQ I_WF_NC
---+-----------------------------------------------------------------
B | P3: N_DISC_RQ IDLE
| not P3: N_CON_RS
| SSRM A_NC_ONLY
---+-----------------------------------------------------------------
C | 2 I_WF_RM
---+-----------------------------------------------------------------
D | P2: 4,2,5 F_CONNECT_CF IDLESP
| not P2: 4,2 ESID(R=10)
| F_ABORT_IND(R,AO=L) WF_NDISC
---+-----------------------------------------------------------------
E | P4: 4 N_DISC_RQ IDLE
| not P4: F_CONNECT_IND A_WF_CONRS
---+-----------------------------------------------------------------
F | F_ABORT_IND
| N_DISC_RQ IDLE
---+-----------------------------------------------------------------
G | P2: 4,2,5 SSID IDLELI
| not P2: 4,2 ESID(R=10)
| F_ABORT_IND(R,AO=L) WF_NDISC
---+-----------------------------------------------------------------
H | 4,2,3 SSID I_WF_SSID
---------------------------------------------------------------------
8.8.3. Predicates and Actions โจ
Okay so predicates are the yes-or-no checks and actions are the stuff that actually gets done. This is where the session connection logic gets real ๐
Predicate P1: (No resources available) OR
(C.Cap-init = Responder) OR
(C.Cap-mode = Sender-only AND
I.F_CONNECT_RQ.Mode = Receiver-only) OR
(C.Cap-mode = Receiver-only AND
I.F_CONNECT_RQ.Mode = Sender-only)
Predicate P2: Negotiation of (Buf-size, Restart, Compression,
Mode, Credit) is OK.
Predicate P3: C.Cap-init = Initiator
Predicate P4: Mode in SSID incompatible with C.Cap-mode
Action 1: Set V.Mode from (C.Cap-mode, I.F_CONNECT_RQ.Mode)
Set V.Pswd, V.Id, V.Restart from I.F_CONNECT_RQ
Set V.Buf-size = C.Max-buf-size
Set V.Compression = C.Cap-compression
Build O.N_CON_RQ
Action 2: Start inactivity timer
Action 3: Set parameters in O.SSID = from local variables
Action 4: Stop timer
Action 5: Set V.Mode, V.Restart, V.Compression, V.Buf-size,
V.Window = from SSID
8.9. Error and Abort State Table ๐จ
8.9.1. State Table
Here's the grid for the error and abort states. It's giving spreadsheet energy ๐
o--------------------------------------o
| | Other States |
| S |------------------------------o |
| T | WF_NDISC | |
| A |--------------------------o | |
| T | I_WF_NC | | |
| E |----------------------o | | |
| | IDLE | | | |
|======================o---+---+---+---|
| | TIME-OUT | X | X | A | B |
| |------------------+---+---+---+---|
| E | F_ABORT_RQ | X | A | X | C |
| V |------------------+---+---+---+---|
| E | N_RST_IND | X | X | A | D |
| N |------------------+---+---+---+---|
| T | N_DISC_IND | X | E | F | G |
| |------------------+---+---+---+---|
| | Invalid Buffer | X | X | H | I |
o--------------------------------------o
8.9.2. Transition Table
Now the transition table for those letters A through I. Pay attention to the Output Events column, bestie ๐
I | Predicate Actions Output Events Next State
===o=================================================================
A | N_DISC_RQ IDLE
---+-----------------------------------------------------------------
B | F_ABORT_IND
| N_DISC_RQ IDLE
---+-----------------------------------------------------------------
C | 1 N_DISC_RQ IDLE
---+-----------------------------------------------------------------
D | 1 N_DISC_RQ
| F_ABORT_IND IDLE
---+-----------------------------------------------------------------
E | F_ABORT_IND IDLE
---+-----------------------------------------------------------------
F | 1 IDLE
---+-----------------------------------------------------------------
G | 1 F_ABORT_IND IDLE
---+-----------------------------------------------------------------
H | WF_NDISC
---+-----------------------------------------------------------------
I | 1,2 ESID(R=01)
| F_ABORT_IND(R,AO=L) WF_NDISC
---------------------------------------------------------------------
8.9.3. Predicates and Actions
These are the two little actions that start and stop the inactivity timer. Simple, but iconic ๐ฆ
Action 1: Stop inactivity timer
Action 2: Start inactivity timer
8.10. Speaker State Table 1 ๐
8.10.1. State Table
Before the big grid, here are the abbreviations you'll need for the Speaker State table ๐ง
F_REL_RQ(Ok) - F_RELEASE_RQ Reason = Normal
F_REL_RQ(Err) - F_RELEASE_RQ Reason = Error
And this is the Speaker State table itself. It is LONG, so take a deep breath and bring snacks ๐ญ
o------------------------------------------------------------------o
| | Other State |
| |----------------------------------------------------------o |
| | WF_NDISC | |
| |------------------------------------------------------o | |
| | OPOWFC | | |
| |--------------------------------------------------o | | |
| | OPO | | | |
| S |----------------------------------------------o | | | |
| | OPOP | | | | |
| T |------------------------------------------o | | | | |
| | CDSTWFCD | | | | | |
| A |--------------------------------------o | | | | | |
| | SFSTWFCD | | | | | | |
| T |----------------------------------o | | | | | | |
| | ERSTWFCD | | | | | | | |
| E |------------------------------o | | | | | | | |
| | WF_CD | | | | | | | | |
| |--------------------------o | | | | | | | | |
| | WF_RTR | | | | | | | | | |
| |----------------------o | | | | | | | | | |
| | IDLESPCD | | | | | | | | | | |
| |------------------o | | | | | | | | | | |
| | IDLESP | | | | | | | | | | | |
|===+==============o---+---+---+---+---+---+---+---+---+---+---+---|
| | F_EERP_RQ | A | A | W | F | W | U | U | U | U | U | U | U |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| | F_START_ | B | B | W | G | W | U | U | U | U | U | X | U |
| | FILE_RQ | | | | | | | | | | | | |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| | SFPA | C | C | C | C | C | C | C | K | C | C | S | C |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| E | SFNA | C | C | C | C | C | C | C | L | C | C | S | C |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| V | CD | C | C | C | H | R | I | J | C | C | C | S | C |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| E | F_DATA_RQ | U | U | U | U | U | U | U | U | M | V | S | U |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| N | CDT | C | C | C | C | C | C | C | C | P | O | S | C |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| T | F_CD_RQ | D | U | W | T | W | U | U | U | U | U | X | U |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| | F_REL_RQ(Ok) | U | E | U | U | U | U | U | U | U | U | X | U |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| | F_REL_RQ(Err)| Q | Q | Q | Q | Q | Q | Q | Q | Q | Q | S | Q |
| |--------------+---+---+---+---+---+---+---+---+---+---+---+---|
| | RTR | C | C | N | C | C | C | C | C | C | C | S | C |
o------------------------------------------------------------------o
8.10.2. Transition Table
The grid tells you where you are, and this table tells you what happens next. It's a big one, so read it in two chunks ๐
I | Predicate Actions Output Events Next State
===o=================================================================
A | 1,2,3 EERP WF_RTR
---+-----------------------------------------------------------------
B | P1: UE
| not P1: 1,2,5 SFID OPOP
---+-----------------------------------------------------------------
C | 1,2 ESID(R=02)
| F_ABORT_IND(R,AO=L) WF_NDISC
---+-----------------------------------------------------------------
D | 1,2 CD IDLELICD
---+-----------------------------------------------------------------
E | 1,2 ESID(R=00) WF_NDISC
---+-----------------------------------------------------------------
F | 4 ERSTWFCD
---+-----------------------------------------------------------------
G | P1: UE
| not P1: 6 SFSTWFCD
---+-----------------------------------------------------------------
H | 1,2 IDLESP
---+-----------------------------------------------------------------
I | 1,2,10 SFID OPOP
---+-----------------------------------------------------------------
J | 1,2 CD IDLELICD
---+-----------------------------------------------------------------
K | P2: 1,2 ESID(R=02)
| F_ABORT_IND(R,AO=L) WF_NDISC
| not P2: 1,2,7,12 F_START_FILE_CF(+) OPO
---+-----------------------------------------------------------------
L | 1,2,8 F_START_FILE_CF(-) IDLESP
---+-----------------------------------------------------------------
M | P3: 1,2,11,13 DATA OPOWFC
| not P3: 1,2,11,13 DATA OPO
---+-----------------------------------------------------------------
N | Note 3 IDLESP
---+-----------------------------------------------------------------
O | 12 OPO
| See Note 1
---+-----------------------------------------------------------------
P | Protocol 1,2 ESID(R=02)
| Error F_ABORT_IND(R,AO=L) WF_NDISC
---+-----------------------------------------------------------------
Q | 1,2 ESID(R) WF_NDISC
---+-----------------------------------------------------------------
Continued -->
I | Predicate Actions Output Events Next State
===o=================================================================
R | 1,2,9 EERP WF_RTR
---+-----------------------------------------------------------------
S | WF_NDISC
---+-----------------------------------------------------------------
T | CDSTWFCD
---+-----------------------------------------------------------------
U | User Error UE
---+-----------------------------------------------------------------
V | User Error - Note 1 UE
---+-----------------------------------------------------------------
W | User Error - Note 2 UE
---+-----------------------------------------------------------------
X | Error
---------------------------------------------------------------------
8.10.3. Predicates and Actions โจ
okay so here are the predicates for this state. they're the checks that decide what happens next ๐
(I.F_START_FILE_RQ.Restart-pos > 0) AND ((V.Restart = No) OR (V.Mode = Receiver-only))is P1 ๐ Restart was requested, but it isn't supported for this session.(I.SFPA.Restart-pos > V.Restart-pos)is P2 ๐ This is a protocol error, because the restart position in the SFPA acknowledgement is bigger than the position we asked for in the SFID request.V.Credit_S - 1 = 0is P3 ๐ซถ The Speaker's credit is used up.
These are the actions, copied exactly:
Action 1: Stop inactivity timer
Action 2: Start inactivity timer
Action 3: Build an EERP from F_EERP_RQ
Action 4: Store F_EERP_RQ in V.Req-buf
Action 5: Build SFID from F_START_FILE_RQ
V.Restart-pos = I.F_START_FILE_RQ.Restart-pos
Action 6: Store F_START_FILE_RQ in V.Req-buf
Action 7: Build F_START_FILE_CF(+) from I.SFPA
Action 8: Build F_START_FILE_CF(-) from I.SFNA
Action 9: Build EERP from F_EERP_RQ stored in V.Req-buf
Action 10: Build SFID from F_START_FILE_RQ stored in V.Req-buf
Set V.Restart-pos
Action 11: Build Exchange Buffer
Action 12: V.Credit_S = V.Window
Action 13: V.Credit_S = V.Credit_S - 1
Note 1 is the big one ๐ญ In OPOWFC the Speaker literally can't send data buffers, because it's waiting for credit. The ODETTE-FTP entity might need to control how fast Data requests (F_DATA_RQ) come in from its User Monitor, so it doesn't blow up its own buffers. Any mechanism like that, plus what the entity does if a User Error happens, is a local implementation issue. Your call, bestie ๐
Note 2: whether to accept this "Request/Event" while in this state is a local implementation choice ๐ฆ The ODETTE state tables assume this event can't happen in this state, so it counts as a user error (UE).
Note 3: it's a local matter to let the User Monitor know that the RTR has arrived, so the protocol machine is ready for the next request ๐
8.11. Speaker State Table 2 ๐ธ
8.11.1. State Table
o---------------------------------o
| S | CLOP |
| T |-------------------------o |
| A | OPOWFC | |
| T |---------------------o | |
| E | OPO | | |
|=====================o---+---+---|
| E | F_CLOSE_FILE_RQ | A | E | U |
| V |-----------------+---+---+---|
| E | EFPA | B | B | C |
| N |-----------------+---+---+---|
| T | EFNA | B | B | D |
o---------------------------------o
8.11.2. Transition Table
I | Predicate Actions Output Events Next State
===o=================================================================
A | 1,2,5,7 EFID CLOP
---+-----------------------------------------------------------------
B | 1,2 ESID(R=02)
| F_ABORT_IND(R,AO=L) WF_NDISC
---+-----------------------------------------------------------------
C | P1: 1,2,3 F_CLOSE_FILE_CF(+,SP=No)
| CD IDLELI
| not P1: 1,2,4 F_CLOSE_FILE_CF(+,SP=Yes) IDLESP
---+-----------------------------------------------------------------
D | 1,2,6 F_CLOSE_FILE_CF(-) IDLESP
---+-----------------------------------------------------------------
E | See Note 1
---+-----------------------------------------------------------------
U | User Error UE
---------------------------------------------------------------------
8.11.3. Predicates and Actions โจ
(I.EFPA.CD-Request = Yes) AND (V.Mode = Both)is P1 ๐ The check for whether the CD request arrived and the mode is Both.
These are the actions:
Action 1: Stop inactivity timer
Action 2: Start inactivity timer
Action 3: O.F_CLOSE_FILE_CF(+).Speaker = No
Action 4: O.F_CLOSE_FILE_CF(+).Speaker = Yes
Action 5: Build EFID from F_CLOSE_FILE_RQ
Action 6: Build F_CLOSE_FILE_CF(-) from EFNA
Action 7: Set V.Credit_S = 0
Note 1 is about the "half duplex" property of ODETTE-FTP ๐ It's forbidden to send EFID while in the OPOWFC state. EFID can only be sent in the OPO state, so the ODETTE-FTP implementation has to avoid sending EFID (or receiving F_CLOSE_FILE_RQ) while in OPOWFC. Respect the half duplex, periodt ๐ซถ
8.12. Listener State Table ๐ฆ
8.12.1. State Table
o-----------------------------------------o
| | CLIP |
| |---------------------------------o |
| | OPI | |
| S |-----------------------------o | |
| T | OPIP | | |
| A |-------------------------o | | |
| T | IDLELICD | | | |
| E |---------------------o | | | |
| | IDLELI | | | | |
|=====================o---+---+---+---+---|
| | SFID | A | A | B | B | B |
| |-----------------+---+---+---+---+---|
| E | DATA | B | B | B | I | B |
| V |-----------------+---+---+---+---+---|
| E | EFID | B | B | B | J | B |
| N |-----------------+---+---+---+---+---|
| T | F_START_FILE_RS | U | U | H | U | U |
| |-----------------+---+---+---+---+---|
| | F_CLOSE_FILE_RS | U | U | U | U | K |
| |-----------------+---+---+---+---+---|
| | CD | C | B | B | B | B |
| |-----------------+---+---+---+---+---|
| | ESID R=Normal | D | F | D | D | D |
| |-----------------+---+---+---+---+---|
| | ESID R=Error | D | D | D | D | D |
| |-----------------+---+---+---+---+---|
| | EERP | E | G | B | B | B |
o-----------------------------------------o
8.12.2. Transition Table
I | Predicate Actions Output Events Next State
===o=================================================================
A | P1: 1,2 ESID(R=02)
| F_ABORT_IND(R,AO=L) WF_NDISC
| not P1: 1,2,3 F_START_FILE_IND OPIP
---+-----------------------------------------------------------------
B | 1,2 ESID(R=02)
| F_ABORT_IND(R,AO=L) WF_NDISC
---+-----------------------------------------------------------------
C | 1,2 F_CD_IND IDLESPCD
---+-----------------------------------------------------------------
D | 1 F_ABORT_IND(Received
| ESID Reason,AO=D)
| N_DISC_RQ IDLE
---+-----------------------------------------------------------------
E | 4 F_EERP_IND
| 8 See Note 2
| RTR IDLELI
---+-----------------------------------------------------------------
F | 1 F_RELEASE_IND
| N_DISC_RQ IDLE
---+-----------------------------------------------------------------
G | F_EERP_IND
| 8 See Note 2
| RTR IDLELI
---+-----------------------------------------------------------------
H | P4: User Error UE
| P2,not P4: 1,2 SFPA OPI
| not(P2,P4): 1,2 SFNA IDLELI
---+-----------------------------------------------------------------
I | P5: 1,2 ESID(R=02)
| F_ABORT_IND(R,A0=L) WF_NDISC
| not(P5,P6): 1,2,5 F_DATA_IND OPI
| not P5,P6: 1,2 F_DATA_IND
| 6,7 See Note 1
| CDT OPI
---+-----------------------------------------------------------------
J | 1,2 F_CLOSE_FILE_IND CLIP
---+-----------------------------------------------------------------
K | P2,P3: 1,2 EFPA(CD-Req) WF_CD
| P2,not P3: 1,2 EFPA(no CD) IDLELI
| not P2: 1,2 EFNA IDLELI
---+-----------------------------------------------------------------
U | User Error UE
---------------------------------------------------------------------
8.12.3. Predicates and Actions ๐
Here are the predicates. Each one is a check the Listener runs before deciding what to do:
(I.SFID.Restart-pos > 0) AND (V.Restart = No)is P1 ๐ Note: this is an invalid Start File command.- P2 is just "Positive Response" ๐ธ
I.F_CLOSE_FILE_RS(+).Speaker = Yesis P3 ๐งI.F_START_FILE_RS(+).Restart-pos > V.Restartis P4 ๐V.Credit_L - 1 < 0is P5 ๐ Note: this is a protocol error, because the Speaker has gone past its available transmission credit.V.Credit_L - 1 = 0is P6 ๐ Note: the Speaker's credit has to be reset before it can send any more Data Exchange buffers.
These are the actions:
Action 1: Stop inactivity timer.
Action 2: Start inactivity timer
Action 3: Build F_START_FILE_IND from I.SFID
V.Restart-pos = I.SFID.Restart-pos
Action 4: Build F_EERP_IND from I.EERP
Action 5: V.Credit_L = V.Credit_L - 1
Action 6: Wait for sufficient resources to receive up to
V.Window Data Exchange Buffers.
Action 7: V.Credit_L = V.Window
Action 8: Wait for resources required to process a new EERP.
Note 1 is all about flow control on the receiving end ๐ฟ The ODETTE-FTP Listener has to send new credit to the Speaker on a regular basis. When it does that depends on three things:
- How much the User Monitor can take in to receive data.
- How many buffers ODETTE-FTP has available.
- The Speaker's available credit, which must be equal to zero.
Note 2: usually the ODETTE-FTP Listener sends the RTR right after it gets the EERP โจ If it needs to, it can hold off on the RTR until the resources needed to process a new EERP are ready.
8.13 Example โจ
okay so picture an ODETTE-FTP entity that has already sent a Start File (SFID) command and is now chilling in the Open Out Pending (OPOP) state ๐. Its reaction when a Positive Answer (SFPA) comes back is written up in Speaker State Table 1, where transition 'K' is the one that kicks in. Here's how it plays out:
if (I.SFPA.Restart-pos > V.Restart-pos) then
begin // invalid restart
Actions: Stop inactivity timer, // reset timer
Start inactivity timer;
Output: ESID(R=02), // to peer ODETTE-FTP
F_ABORT_IND(R,AO=L); // to user monitor
New State: WF_NDISC;
end
else begin
Actions: Stop inactivity timer, // reset timer
Start inactivity timer;
Build F_START_FILE_CF(+) from I.SFPA
V.Credit_S = V.Window // initialise credit
Output: F_START_FILE_CF(+); // to user monitor
New State: OPO;
end
so the ODETTE-FTP checks the restart position inside the SFPA command it just got ๐. If that position is invalid, it's a no-go: it aborts the session by sending an End Session (ESID) command to its peer, plus an Abort indication (F_ABORT_IND) to its User Monitor ๐. If the restart position checks out, it builds a Start File confirmation (F_START_FILE_CF), sends that up to the User Monitor, initialises the credit window, and moves into the Open Out (OPO) state ๐ โจ
9. Security Considerations ๐
not gonna lie, this part is serious ๐ญ. ODETTE-FTP sends user identity and password info in clear text. So it's recommended that a lower layer (session, network or linkage) security protocol protects the session, so nobody can casually harvest identities off the wire ๐๐
Appendix A. Virtual File Mapping Example ๐ง
this appendix shows how a Virtual File gets mapped into a bunch of ODETTE-FTP Data Exchange Buffers, and how each Stream Transmission Buffer is made from a Data Exchange Buffer with a Stream Transmission Header stuck on the front ๐ฆ
every line in this extract from 'The Hunting of the Snark' by Lewis Carroll [SNARK] is treated as its own record in a file of variable length records. it's not a text file, so CR/LF record separators aren't used at all, and the blank line is just a zero length record ๐
"It's a Snark!" was the sound that first came to their ears,
And seemed almost too good to be true.
Then followed a torrent of laughter and cheers:
Then the ominous words "It's a Boo-"
Then, silence. Some fancied they heard in the air
A weary and wandering sigh
Then sounded like "-jum!" but the others declare
It was only a breeze that went by.
assuming a minimum exchange buffer length of 128 octets has been negotiated, mapping the text into Stream Transmission Buffers could look like this ๐ธ
Stream Transmission Buffer 1
Text : ....D."It' s a Snark! " was the sound that first cam
Hex-H : 10084B2472 7262566762 2276727662 7676627667 2667772666
Hex-L : 00044C2947 30103E12B1 2071304850 3F5E404814 069234031D
Key : ----D!.... .......... .......... .......... ..........
Text : e to their ears,. .A nd seemed almost too good to b
Hex-H : 6276276667 26677242A4 6627666662 6666772766 2666627626
Hex-L : 504F048592 05123C5061 E40355D540 1CDF3404FF 07FF404F02
Key : .......... ......!.!. .......... .......... ..........
Text : e true..Th en followe d a torren t
Hex-H : 6277762156 6626666676 6262767766 72
Hex-L : 504255E848 5E06FCCF75 40104F225E 40
Key : .......!.. .......... .......... ..
Text : ....D.of l aughter an d cheers:. .Then the ominous w
Hex-H : 1007496626 6766767266 6266667734 2A56662766 2666667727
Hex-L : 000847F60C 157845201E 40385523A5 04485E0485 0FD9EF5307
Key : ----D!.... .......... .........! .!........ ..........
Text : ords "It's a Boo-".. Then, sile nce. Some fancied t
Hex-H : 6767224727 262466228B 5666227666 6662225666 2666666627
Hex-L : F243029473 0102FFD202 485EC039C5 E35E003FD5 061E395404
Key : .......... ........!! .......... .......... ..........
Text : hey heard in the air
Hex-H : 6672666762 6627662667
Hex-L : 8590851240 9E04850192
Key : .......... ..........
Stream Transmission Buffer 3
Text : ....D. .A weary and wandering sigh.Then sounded li
Hex-H : 1007442942 7667726662 7666676662 7666B56662 7676666266
Hex-L : 0008450A10 7512901E40 71E4529E70 39780485E0 3F5E4540C9
Key : ----D!.!.. .......... .......... ....!..... ..........
Text : ke "-jum!" but the o thers decl are. .It w as only a
Hex-H : 6622267622 2677276626 7667726666 67642A4727 6726667262
Hex-L : B502DA5D12 025404850F 485230453C 1255029407 130FEC9010
Key : .......... .......... .......... ...!.!.... ..........
Text : breeze tha t went by.
Hex-H : 6766762766 7276672672
Hex-L : 2255A50481 4075E4029E
Key : .......... ..........
Notes:
Hex-H High order bits of octet
Hex-L Low order bits of octet
Key: ---- Stream Transmission Header
D Data Exchange Buffer command code 'D'
! Subrecord header octet
. Place holder
All headers are represented with a period in the Text line.
every Data Exchange Buffer gets a Stream Transmission Header in front of it ๐
the first Data Exchange Buffer is 128 octets long, and the last record in it keeps going into the second buffer ๐โโ๏ธ
the second Data Exchange Buffer gets chopped off at 116 octets so it ends at the end of a record ๐ . the next record then sits completely inside the third buffer. that's an alternative to spanning the record across the first and second buffers, like we saw above ๐ฆ
the blank line gets encoded as one header octet of '80' hex, which means a zero length subrecord with the end of record flag set ๐
and the indented lines have been compressed ๐ซถ
Appendix B. ISO 646 Character Subset ๐ค
here's the ISO 646 character subset laid out as a grid, bit patterns down the side and columns across the top ๐
o-----------------------------------------------------------------o
| | 7| 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
| | B -+-----+-----+-----+-----+-----+-----+-----+-----|
| | I 6| 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
| | T -+-----+-----+-----+-----+-----+-----+-----+-----|
| | 5| 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
| |----+-----+-----+-----+-----+-----+-----+-----+-----|
| | | | | | | | | | |
| | | | | | | | | | |
|------------| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| BIT | | | | | | | | | |
| 4 3 2 1 | | | | | | | | | |
|============o====o=====+=====+=====+=====+=====+=====+=====+=====|
| 0 0 0 0 | 0 | | | SP | 0 | | P | | |
|------------|----|-----+-----+-----+-----+-----+-----+-----+-----|
| 0 0 0 1 | 1 | | | | 1 | A | Q | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 0 0 1 0 | 2 | | | | 2 | B | R | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 0 0 1 1 | 3 | | | | 3 | C | S | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 0 1 0 0 | 4 | | | | 4 | D | T | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 0 1 0 1 | 5 | | | | 5 | E | U | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 0 1 1 0 | 6 | | | & | 6 | F | V | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 0 1 1 1 | 7 | | | | 7 | G | W | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 1 0 0 0 | 8 | | | ( | 8 | H | X | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 1 0 0 1 | 9 | | | ) | 9 | I | Y | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 1 0 1 0 | 10 | | | | | J | Z | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 1 0 1 1 | 11 | | | | | K | | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 1 1 0 0 | 12 | | | | | L | | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 1 1 0 1 | 13 | | | - | | M | | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 1 1 1 0 | 14 | | | . | | N | | | |
|------------+----|-----+-----+-----+-----+-----+-----+-----+-----|
| 1 1 1 1 | 15 | | | / | | O | | | |
o-----------------------------------------------------------------o
Acknowledgements ๐
this whole document leans heavily on revision 1.3 of the ODETTE File Transfer Specification [OFTP] ๐
so many people helped build this protocol, and their work deserves a shoutout ๐. the extensions needed to use the Transmission Control Protocol were worked out and agreed on by the current members of ODETTE Working Group Four, who also gave super helpful reviews and comments on this doc ๐ซถ
References ๐
[OFTP] Organisation for Data Exchange by Tele Transmission in
Europe, Odette File Transfer Protocol, Revision 1.3:1993
[RFC-739] Postel, J., Transmission Control Protocol, STD 7, RFC 739,
September 1981
[ISO-646] International Organisation for Standardisation, ISO
Standard 646:1991, "Information technology -- ISO 7-bit coded
character set for information interchange", 1991
[ISO-6523] International Organisation for Standardisation, ISO
Standard 6523:1984, "Data interchange -- Structures for the
identification of organisations", 1984
[ISO-8601] International Organisation for Standardisation, ISO
Standard 8601:1988 "Data elements and interchange formats --
Information interchange -- Representation of dates and times", 1988
[NIFTP] High Level Protocol Group, "A Network Independent File
Transfer Protocol", 1981
[SNARK] Carroll, Lewis "The Hunting of the Snark", 1876
ODETTE Address ๐ท
the ODETTE File Transfer Protocol is a product of Working Group Four of the Organisation for Data Exchange by Tele Transmission in Europe. you can reach the working group through the ODETTE Secretariat ๐
ODETTE Secretariat
Forbes House
Halkin Street
London
SW1X 7DS
United Kingdom
Phone: +44 (0)171 344 9227
Fax: +44 (0)171 235 7112
EMail odette@odette.org
keith.oxley@odette.org
stephanie.bioux@odette.org
Author's Address โ๏ธ
the author can be contacted at ๐
David Nash
Ford Motor Company Limited
Room 1/148, Central Office
Eagle Way
Warley
Brentwood
Essex
CM13 3BW
United Kingdom
Phone: +44 (0)1277 253043
EMail: dnash@ford.com
๐ฆ where this page comes from
- ietf: rfc2204 1997-09
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms