home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / iclvme2900 / kmt_ph_module < prev    next >
Text File  |  2020-01-01  |  36KB  |  902 lines

  1. MODULE KMT_PH_MODULE;
  2.  
  3. @ VME KERMIT PROTOCOL HANDLER @
  4.  
  5. @ GLOBAL VARIABLES @
  6.  
  7. @   PKT_TYPE                    : packet type of current packet     @
  8. @   KMT_PH_INPUT_PACKET_DATA    : pointer to packet data buffer     @
  9. @                                (translated to EBCDIC and decoded) @
  10. @   PKT_SEQ                     : current packet number (expected)  @
  11. @   PKT_NO                      : current packet number (received)  @
  12. @   RETRY_COUNT                 : current retry count               @
  13.  
  14.  
  15. @ Mode declarations: @
  16.  
  17. MODE KMT_BUFFER IS (96)BYTE;
  18. MODE KMT_STRING IS REF()BYTE;
  19. MODE KMT_WORD IS REF()BYTE;
  20.  
  21. MODE KMT_MTUP_VALUES IS ANY
  22.   (LONG WORD      LW_VALUE,
  23.    LONG INT       LI_VALUE,
  24.    REF WORD       RW_VALUE,
  25.    REF INT        RI_VALUE,
  26.    REF LONG WORD  RLW_VALUE,
  27.    REF LONG INT   RLI_VALUE,
  28.    REF()BYTE      RVB_VALUE,
  29.    REF()REF()BYTE RVRVB_VALUE);
  30.  
  31. MODE KMT_PP_PACKET_STATISTICS_S IS STRUCT
  32.    (INT INPUT_TOTAL,
  33.         OUTPUT_TOTAL);
  34.  
  35. MODE KMT_TRACE_FLAGS_S IS WORD STRUCT
  36.   (BIT    PH_TRACING,
  37.           PP_TRACING,
  38.           FH_TRACING,
  39.           DH_TRACING,
  40.    28-BIT SPARE);
  41.  
  42.  
  43. @ External procedures @
  44.  
  45. EXT PROC (INT,RESPONSE)             KMT_MESSAGE;
  46.  
  47. EXT PROC (RESPONSE)                 KMT_UI;
  48.  
  49. EXT PROC (REF()BYTE,INT,RESPONSE)          KMT_FH_OPEN_FILE,
  50.     PROC (RESPONSE)                        KMT_FH_CLOSE_FILE,
  51.     PROC (RESPONSE)                        KMT_FH_SAVE_FILE,
  52.     PROC (REF()BYTE,REF INT,BOOL,RESPONSE) KMT_FH_GIVE_NAME;
  53.  
  54. EXT PROC ()                         KMT_PP_TRANSLATE_TO_EBCDIC,
  55.     PROC (REF()BYTE,RESPONSE)       KMT_PP_BUILD_STRING_PACKET_DATA,
  56.     PROC (RESPONSE)                 KMT_PP_PROCESS_PARAM_PACKET_DATA,
  57.     PROC ()                         KMT_PP_BUILD_PARAM_PACKET_DATA,
  58.     PROC (RESPONSE)                 KMT_PP_BUILD_FILE_RECORD,
  59.     PROC (RESPONSE)                 KMT_PP_BUILD_FILE_PACKET_DATA,
  60.     PROC (REF INT,REF INT,RESPONSE) KMT_PP_GET_PACKET,
  61.     PROC (INT,INT,BOOL,RESPONSE)    KMT_PP_SEND_PACKET;
  62.      @ Any error returned by KMT_PP_SEND_PACKET is fatal and Kermit will exit; @
  63.      @ warnings will have been logged already and are ignored                  @
  64.  
  65. EXT PROC (REF KMT_STRING) KMT_WORD  KMT_SP_GET_WORD,
  66.     PROC (REF KMT_WORD,INT)         KMT_SP_STANDARDISE_FILENAME,
  67.     PROC (INT,REF()KMT_MTUP_VALUES) KMT_SP_LOG_TRACE_MESSAGE;
  68.  
  69. EXT REF INT PKT_SEQ,PKT_NO,MAXTRY,RETRY_COUNT,RETRY_TOTAL,TIMEOUT_TOTAL,
  70.             RC_IGNORED;
  71.  
  72. EXT REF KMT_STRING KMT_PH_INPUT_PACKET_DATA;
  73.  
  74. EXT REF KMT_BUFFER KMT_VME_FILE_BUF,KMT_REM_FILE_BUF;
  75. EXT REF KMT_WORD KMT_VME_FILE,KMT_REM_FILE;
  76.  
  77. EXT INT ENTRY,BREAK_PKT,DATA_PKT,FILE_HDR_PKT,NAK_PKT,SEND_INIT_PKT,ACK_PKT,
  78.         EOF_PKT;
  79.  
  80. EXT INT VME_TERM,VME_STD,KMT_STD;              @ forms of name standardisation @
  81.  
  82. EXT INT REC_SERVER_IDLE,REC_INIT,REC_FILE,REC_DATA,SEND_INIT,SEND_FILE,
  83.         SEND_DATA,SEND_EOF,SEND_BREAK,COMPLETE,ABORT;
  84.  
  85. EXT INT EXIT,LOGOUT,FATAL_ERROR;                                 @ exit states @
  86.  
  87. EXT INT EOF;                                                @ eof on file data @
  88.  
  89. EXT INT SERVER_MODE;
  90.  
  91. EXT REF INT KMT_CURRENT_MODE;
  92.  
  93. EXT BOOL READ_INT,NO_READ_INT;        @ set/don't set read interest after send @
  94.  
  95. EXT REF INT FILE_OPTION;
  96.  
  97. EXT REF BOOL DELAY_TIMER;
  98.  
  99. EXT REF BOOL SAVE_INCOMPLETE_FILE;
  100.  
  101. EXT REF INT EXIT_STATE;
  102.  
  103. EXT REF()KMT_MTUP_VALUES KMT_MTM_AREA;
  104.  
  105. EXT REF KMT_PP_PACKET_STATISTICS_S KMT_PP_PACKET_STATISTICS;
  106.  
  107. EXT REF KMT_TRACE_FLAGS_S KMT_TRACE_FLAGS;
  108.  
  109.  
  110.  
  111.  
  112. STATIC REF KMT_STRING PKT_DATA IS KMT_PH_INPUT_PACKET_DATA;
  113.  
  114.  
  115.  
  116.  
  117. GLOBAL
  118. STATIC (<STATUS 5>)
  119. PROC
  120.    KMT_PH IS (REF INT STATE,INT EVENT,RESPONSE RESULT):
  121.  
  122.    BEGIN
  123.  
  124.       @ procedures for state entry @
  125.  
  126.       SIM PROC KMT_PH_REC_SERVER_IDLE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  127.  
  128.          @ Server idle, waiting for message                                    @
  129.  
  130.          BEGIN
  131.             RETRY_COUNT := 0;          @ try for ever in Rec_Server_Idle state @
  132.             RETRY_TOTAL := TIMEOUT_TOTAL := 0;
  133.             KMT_PP_PACKET_STATISTICS := (0,0);
  134.             PKT_SEQ := 0;                         @ initialise packet sequence @
  135.             RESULT := 0
  136.          END
  137.  
  138.          ; @ KMT_PH_REC_SERVER_IDLE @
  139.  
  140.  
  141.       SIM PROC KMT_PH_REC_INIT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  142.  
  143.          @ Entry point for non-server RECEIVE command                          @
  144.  
  145.          BEGIN
  146.             PKT_SEQ := 0;                         @ initialise packet sequence @
  147.             RESULT := 0
  148.          END
  149.  
  150.          ; @ KMT_PH_REC_INIT @
  151.  
  152.  
  153.       SIM PROC KMT_PH_REC_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  154.  
  155.          @ Look for a file header or EOT message                               @
  156.  
  157.             RESULT := 0             @ nothing to do on entry to Rec_File state @
  158.  
  159.          ; @ KMT_PH_REC_FILE @
  160.  
  161.  
  162.       SIM PROC KMT_PH_REC_DATA IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  163.  
  164.          @ Receive data up to end of file                                      @
  165.  
  166.             RESULT := 0             @ nothing to do on entry to Rec_Data state @
  167.  
  168.          ; @ KMT_PH_REC_DATA @
  169.  
  170.  
  171.       SIM PROC KMT_PH_SEND_INIT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  172.  
  173.          @ Server Send Init, also entry for non-server SEND command            @
  174.  
  175.          BEGIN
  176.             PKT_SEQ := 0;                         @ initialise packet sequence @
  177.  
  178.             IF KMT_CURRENT_MODE NE SERVER_MODE AND RETRY_COUNT LE 1
  179.             THEN                       @ wait for user to set up remote KERMIT @
  180.                INT KMT_EH_SOFTWARE_ERROR IS 80101;
  181.                INT X_TYPE,X_NO;
  182.                DELAY_TIMER := TRUE;                          @ set delay timer @
  183.                KMT_PP_GET_PACKET(X_TYPE,X_NO,RESULT);@ attempt to read packet @
  184.                             @ if we get a packet then they're ready to receive @
  185.                                 @ if the timer expires then we send regardless @
  186.                DELAY_TIMER := FALSE;
  187.                UNLESS RESULT = KMT_EH_SOFTWARE_ERROR
  188.                DO
  189.                   RESULT := 0
  190.                FI
  191.             ELSE
  192.                RESULT := 0
  193.             FI;
  194.  
  195.             IF RESULT = 0
  196.             THEN
  197.                KMT_PP_BUILD_PARAM_PACKET_DATA();   @ send S(0) with parameters @
  198.                KMT_PP_SEND_PACKET(SEND_INIT_PKT,PKT_SEQ,READ_INT,RESULT);
  199.                RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  200.             FI
  201.          END
  202.  
  203.          ; @ KMT_PH_SEND_INIT @
  204.  
  205.  
  206.       SIM PROC KMT_PH_SEND_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  207.  
  208.          @ Send file or text header (we don't send text packets!)              @
  209.  
  210.          BEGIN                  @ send F(n) - packet made by KMT_PH_READY_FILE @
  211.             KMT_PP_SEND_PACKET(FILE_HDR_PKT,PKT_SEQ,READ_INT,RESULT);
  212.             RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  213.          END
  214.  
  215.          ; @ KMT_PH_SEND_FILE @
  216.  
  217.  
  218.       SIM PROC KMT_PH_SEND_DATA IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  219.  
  220.             @ Send contents of file or textual information                     @
  221.             @ (we don't send text packets!)                                    @
  222.  
  223.          BEGIN @ send D(n) with current buffer (pkt made by KMT_PH_READY_DATA) @
  224.             KMT_PP_SEND_PACKET(DATA_PKT,PKT_SEQ,READ_INT,RESULT);
  225.             RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  226.          END
  227.  
  228.          ; @ KMT_PH_SEND_DATA @
  229.  
  230.  
  231.       SIM PROC KMT_PH_SEND_EOF IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  232.  
  233.          @ Send end of file indicator (we don't do interrupts)                 @
  234.  
  235.          BEGIN
  236.             KMT_VME_FILE := NIL;                        @ file has been closed @
  237.             KMT_REM_FILE := NIL;
  238.                                 @ send Z(n) - packet made by KMT_PH_READY_DATA @
  239.             KMT_PP_SEND_PACKET(EOF_PKT,PKT_SEQ,READ_INT,RESULT);
  240.             RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  241.          END
  242.  
  243.          ; @ KMT_PH_SEND_EOF @
  244.  
  245.  
  246.       SIM PROC KMT_PH_SEND_BREAK IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  247.  
  248.          @ End of Transmission                                                 @
  249.  
  250.          BEGIN                  @ send B(n)  - packet made by KMT_PH_SENT_FILE @
  251.             KMT_PP_SEND_PACKET(BREAK_PKT,PKT_SEQ,READ_INT,RESULT);
  252.             RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  253.          END
  254.  
  255.          ; @ KMT_PH_SEND_BREAK @
  256.  
  257.  
  258.  
  259.       @ procedures for expected packets @
  260.  
  261.       SIM PROC KMT_PH_INIT_PARAMS IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  262.  
  263.          @ A Send_Init or Init packet has arrived. If the packet sequence is   @
  264.          @ correct, process their parameters and ack with our parameters.      @
  265.          @ If it's a repeat of their last packet, ack it again with our        @
  266.          @ parameters. Otherwise, report error and in non-Server modes, abort  @
  267.  
  268.             IF (STATE = REC_SERVER_IDLE OR STATE = REC_INIT) AND PKT_NO = 0
  269.             THEN                         @ got right packet, reset retry count @
  270.                RETRY_COUNT := 0;
  271.                KMT_PP_PROCESS_PARAM_PACKET_DATA(RESULT);
  272.                IF RESULT = 0
  273.                THEN
  274.                   KMT_PP_BUILD_PARAM_PACKET_DATA();
  275.                   KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
  276.                   RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI;
  277.                   IF RESULT = 0 AND EVENT = SEND_INIT_PKT
  278.                   THEN                             @ increment packet sequence @
  279.                      PKT_SEQ := PKT_SEQ+1 MOD 64;
  280.                      STATE := REC_FILE
  281.                   FI
  282.                ELSE                                @ their params unacceptable @
  283.                   RESULT := 89070
  284.                FI
  285.             ELSF STATE = REC_FILE AND PKT_NO+1 MOD 64 = PKT_SEQ @ i.e. P = N-1 @
  286.             THEN          @ we've picked up their Send_init again, so send ack @
  287.                KMT_PP_BUILD_PARAM_PACKET_DATA();
  288.                KMT_PP_SEND_PACKET(ACK_PKT,PKT_NO,READ_INT,RESULT);
  289.                RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  290.             ELSE          @ wrong packet sequence, error (abort if non-server) @
  291.                RESULT := 89000
  292.             FI
  293.  
  294.          ; @ KMT_PH_INIT_PARAMS @
  295.  
  296.  
  297.       SIM PROC KMT_PH_GEN_CMD IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  298.  
  299.          @ Generic command received - some are implemented and will be         @
  300.          @ executed and acknowledged - an error packet is sent for the rest    @
  301.  
  302.             IF PKT_NO = 0
  303.             THEN
  304.                BYTE GEN_CMD;
  305.                KMT_PP_TRANSLATE_TO_EBCDIC();
  306.                GEN_CMD := PKT_DATA(0);
  307.                RETRY_COUNT := 0;         @ got right packet, reset retry count @
  308.  
  309.                                         @ check if Generic Command implemented @
  310.                IF GEN_CMD = "F" OR GEN_CMD = "L"
  311.                THEN      @ GF (Finish command): exit Server mode and terminate @
  312.                          @ GL (Logout command): exit Server mode and log out   @
  313.                   EXIT_STATE := IF GEN_CMD = "F" THEN EXIT ELSE LOGOUT FI;
  314.                   STATE := COMPLETE;
  315.                                           @ Generic Command successful, ack it @
  316.                   KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  317.                   KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
  318.                   RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  319.                ELSE  @ this Generic Command not implemented (or doesn't exist) @
  320.                   RESULT := 89011
  321.                FI
  322.             ELSE                @ wrong packet number, wait for their next try @
  323.                RESULT := 89000
  324.             FI
  325.  
  326.          ; @ KMT_PH_GEN_CMD @
  327.  
  328.  
  329.       SIM PROC KMT_PH_KMT_CMD IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  330.  
  331.          @ Packet contains Kermit command, pass it to user interface (KMT_UI)  @
  332.          @ for processing                                                      @
  333.  
  334.             IF PKT_NO = 0
  335.             THEN
  336.                RETRY_COUNT := 0;         @ got right packet, reset retry count @
  337.                                           @ pass command (in packet) to KMT_UI @
  338.                KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  339.                KMT_PP_TRANSLATE_TO_EBCDIC();
  340.                KMT_UI(RESULT);
  341.                IF RESULT = 0
  342.                THEN         @ command has been executed successfully so ack it @
  343.                           @ if there is a reply, KMT_UI has put it into packet @
  344.                   KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
  345.                   RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  346.                FI
  347.             ELSE                @ wrong packet number, wait for their next try @
  348.                RESULT := 89000
  349.             FI
  350.  
  351.          ; @ KMT_PH_KMT_CMD @
  352.  
  353.  
  354.       SIM PROC KMT_PH_GOT_FILENAME IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  355.  
  356.          @ Packet contains name of file to be sent                             @
  357.  
  358.             IF PKT_NO = 0
  359.             THEN                         @ got right packet, reset retry count @
  360.                RETRY_COUNT := 0;
  361.                KMT_PP_TRANSLATE_TO_EBCDIC();
  362.                KMT_VME_FILE := KMT_SP_GET_WORD(PKT_DATA);    @ obtain filename @
  363.                IF NOT (KMT_VME_FILE REF NIL)                 @ must be present @
  364.                THEN
  365.                   KMT_VME_FILE :=
  366.                      KMT_VME_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
  367.                         KMT_VME_FILE;
  368.                   STATE := SEND_INIT;
  369.                   RESULT := 0
  370.                ELSE                             @ no filename, error and abort @
  371.                   RESULT := 89030
  372.                FI
  373.             ELSE                @ wrong packet number, wait for their next try @
  374.                RESULT := 89000
  375.             FI
  376.  
  377.          ; @ KMT_PH_GOT_FILENAME @
  378.  
  379.  
  380.       SIM PROC KMT_PH_BREAK IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  381.  
  382.          @ End of Transmission received                                        @
  383.  
  384.             IF PKT_NO = PKT_SEQ
  385.             THEN                       @ correct sequence, ack it and complete @
  386.                KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  387.                KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,NO_READ_INT,RESULT);
  388.                RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI;
  389.                STATE := COMPLETE
  390.             ELSE                          @ wrong packet sequence, error abort @
  391.                RESULT := 89000
  392.             FI
  393.  
  394.          ; @ KMT_PH_BREAK @
  395.  
  396.  
  397.       SIM PROC KMT_PH_FILE_HDR IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  398.  
  399.          @ Packet contains name of file to be received                         @
  400.  
  401.             IF PKT_NO = PKT_SEQ
  402.             THEN @ obtain filename (may have been specified in Receive command)@
  403.                KMT_PP_TRANSLATE_TO_EBCDIC();
  404.                IF KMT_VME_FILE REF NIL
  405.                THEN                                          @ not already set @
  406.                   KMT_VME_FILE := KMT_SP_GET_WORD(PKT_DATA);
  407.                   IF KMT_VME_FILE REF NIL
  408.                   THEN
  409.                      RESULT := 80931
  410.                   ELSE
  411.                      KMT_VME_FILE :=
  412.                         KMT_VME_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
  413.                            KMT_VME_FILE;
  414.                      RESULT := 0
  415.                   FI
  416.                ELSE          @ already set but verify packet contains filename @
  417.                   KMT_REM_FILE := KMT_SP_GET_WORD(PKT_DATA);
  418.                   RESULT := IF KMT_REM_FILE REF NIL THEN 80931 ELSE 0 FI
  419.                FI;
  420.  
  421.                IF RESULT = 0
  422.                THEN                                                @ open file @
  423.                   KMT_REM_FILE :=                  @ save copy of VME filename @
  424.                      KMT_REM_FILE_BUF(SIZE LENGTH KMT_VME_FILE) :=
  425.                         KMT_VME_FILE;
  426.                                    @ assume filename is name.type, remove type @
  427.                   KMT_SP_STANDARDISE_FILENAME(KMT_VME_FILE,VME_STD);
  428.                   KMT_FH_OPEN_FILE(KMT_VME_FILE,FILE_OPTION,RESULT);
  429.                   IF RESULT <= 0
  430.                   THEN                              @ file open, log full name @
  431.                      INT NAME_LENGTH;
  432.                      RESULT := 0;
  433.                      KMT_FH_GIVE_NAME(KMT_VME_FILE_BUF,NAME_LENGTH,TRUE,RESULT);
  434.                      IF RESULT <= 0
  435.                      THEN                      @ set VME filename to full name @
  436.                         RESULT := 0;
  437.                         KMT_VME_FILE := KMT_VME_FILE_BUF(SIZE NAME_LENGTH);
  438.                         KMT_MTM_AREA(3) := KMT_REM_FILE AS
  439.                                               KMT_MTUP_VALUES.RVB_VALUE;
  440.                         KMT_MTM_AREA(4) := KMT_VME_FILE AS
  441.                                               KMT_MTUP_VALUES.RVB_VALUE;
  442.                         KMT_MESSAGE(-87002,RC_IGNORED);         @ log filename @
  443.                                       @ ack file header including VME filename @
  444.                         KMT_PP_BUILD_STRING_PACKET_DATA(KMT_VME_FILE,
  445.                                                                     RC_IGNORED);
  446.                         KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
  447.                         IF RESULT <= 0
  448.                         THEN
  449.                            PKT_SEQ := PKT_SEQ+1 MOD 64;
  450.                            RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
  451.                            RETRY_COUNT := 0;
  452.                            STATE := REC_DATA;
  453.                            RESULT := 0
  454.                         ELSE
  455.                            RESULT := -89061
  456.                         FI
  457.                      FI
  458.                   ELSE           @ unable to open file, reset result and abort @
  459.                      RESULT := 89040
  460.                   FI
  461.                FI
  462.             ELSE                                  @ wrong packet number, abort @
  463.                RESULT := 89000
  464.             FI
  465.  
  466.          ; @ KMT_PH_FILE_HDR @
  467.  
  468.  
  469.       SIM PROC KMT_PH_GOT_DATA IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  470.  
  471.          @ Received data packet                                                @
  472.  
  473.             IF PKT_NO = PKT_SEQ
  474.             THEN                                          @ write data to file @
  475.                KMT_PP_BUILD_FILE_RECORD(RESULT);
  476.                IF RESULT <= 0
  477.                THEN                                          @ ack data packet @
  478.                   RESULT := 0;
  479.                   KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  480.                   KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
  481.                   IF RESULT <= 0
  482.                   THEN
  483.                      PKT_SEQ := PKT_SEQ+1 MOD 64;
  484.                      RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
  485.                      RETRY_COUNT := 0;
  486.                      RESULT := 0
  487.                   ELSE
  488.                      RESULT := -89061
  489.                   FI
  490.                ELSE                        @ error writing data to file, abort @
  491.                   RESULT := 89046
  492.                FI
  493.             ELSF PKT_NO+1 MOD 64 = PKT_SEQ                      @ i.e. P = N-1 @
  494.             THEN     @ we've picked up their last data packet again, so ack it @
  495.                KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  496.                KMT_PP_SEND_PACKET(ACK_PKT,PKT_NO,READ_INT,RESULT);
  497.                RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  498.             ELSE                            @ wrong packet number, error abort @
  499.                RESULT := 89000
  500.             FI
  501.  
  502.          ; @ KMT_PH_GOT_DATA @
  503.  
  504.  
  505.       SIM PROC KMT_PH_GOT_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  506.  
  507.          @ End of file packet received                                         @
  508.  
  509.             IF PKT_NO = PKT_SEQ
  510.             THEN
  511.                KMT_PP_TRANSLATE_TO_EBCDIC();
  512.                KMT_FH_CLOSE_FILE(RESULT);        @ close file we've just rec'd @
  513.                RESULT := IF RESULT <= 0
  514.                          THEN 0                      @ ignore -ve warning code @
  515.                          ELSE 89042                @ error closing file, abort @
  516.                          FI;
  517.  
  518.                IF (RESULT = 0  OR  SAVE_INCOMPLETE_FILE)
  519.                   AND (LENGTH PKT_DATA = 0 OR PKT_DATA(0) NE "D")
  520.                THEN                 @ no discard signal in packet so save file @
  521.                   INT RC;
  522.                   KMT_FH_SAVE_FILE(RC);
  523.                   IF RC > 0
  524.                   THEN RESULT := 89044              @ error saving file, abort @
  525.                   FI
  526.                FI;
  527.  
  528.                IF RESULT = 0
  529.                THEN
  530.                   KMT_VME_FILE := NIL;
  531.                   KMT_REM_FILE := NIL;
  532.                                         @ no problems closing file, so ack eof @
  533.                   KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  534.                   KMT_PP_SEND_PACKET(ACK_PKT,PKT_SEQ,READ_INT,RESULT);
  535.                   IF RESULT <= 0
  536.                   THEN
  537.                      PKT_SEQ := PKT_SEQ+1 MOD 64;
  538.                      RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
  539.                      RETRY_COUNT := 0;
  540.                      STATE := REC_FILE;
  541.                      RESULT := 0
  542.                   ELSE
  543.                      RESULT := -89061
  544.                   FI
  545.                FI
  546.             ELSE                                  @ wrong packet number, abort @
  547.                RESULT := 89000
  548.             FI
  549.  
  550.          ; @ KMT_PH_GOT_FILE @
  551.  
  552.  
  553.       SIM PROC KMT_PH_READY_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  554.  
  555.          @ Send Init has been acknowledged, open file for transfer             @
  556.  
  557.             IF PKT_NO = 0
  558.             THEN
  559.                KMT_PP_PROCESS_PARAM_PACKET_DATA(RESULT);
  560.                IF RESULT = 0
  561.                THEN                                   @ open file in READ mode @
  562.                                    @ assume filename is name.type, remove type @
  563.                   KMT_SP_STANDARDISE_FILENAME(KMT_VME_FILE,VME_STD);
  564.                   KMT_FH_OPEN_FILE(KMT_VME_FILE,0,RESULT);
  565.                   IF RESULT <= 0
  566.                   THEN                   @ set up filename for file hdr packet @
  567.                      INT NAME_LENGTH;
  568.                      RESULT := 0;
  569.                      KMT_FH_GIVE_NAME(KMT_VME_FILE_BUF,NAME_LENGTH,TRUE,RESULT);
  570.                      IF RESULT <= 0
  571.                      THEN
  572.                         KMT_VME_FILE := KMT_VME_FILE_BUF(SIZE NAME_LENGTH);
  573.                         IF KMT_REM_FILE REF NIL
  574.                         THEN        @ set remote filename to VME terminal name @
  575.                            KMT_REM_FILE :=
  576.                               KMT_REM_FILE_BUF(SIZE NAME_LENGTH) :=
  577.                                  KMT_VME_FILE;
  578.                            KMT_SP_STANDARDISE_FILENAME(KMT_REM_FILE,VME_TERM)
  579.                         ELSE       @ set remote filename to Kermit Normal-Form @
  580.                            KMT_SP_STANDARDISE_FILENAME(KMT_REM_FILE,KMT_STD)
  581.                         FI;
  582.                                                                @ log filenames @
  583.                         KMT_MTM_AREA(3) :=
  584.                            KMT_VME_FILE AS KMT_MTUP_VALUES.RVB_VALUE;
  585.                         KMT_MTM_AREA(4) :=
  586.                            KMT_REM_FILE AS KMT_MTUP_VALUES.RVB_VALUE;
  587.                         KMT_MESSAGE(-87003,RC_IGNORED);
  588.                                           @ put filename in file header packet @
  589.                         KMT_PP_BUILD_STRING_PACKET_DATA(KMT_REM_FILE,RC_IGNORED);
  590.                         PKT_SEQ := PKT_SEQ+1 MOD 64;
  591.                         RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
  592.                         RETRY_COUNT := 0;
  593.                         STATE := SEND_FILE;
  594.                         RESULT := 0
  595.                      FI
  596.                   ELSE           @ unable to open file, reset result and abort @
  597.                      RESULT := 89041
  598.                   FI
  599.                ELSE                                @ their params unacceptable @
  600.                   RESULT := 89070
  601.                FI
  602.             FI
  603.  
  604.          ; @ KMT_PH_READY_FILE @
  605.  
  606.  
  607.       SIM PROC KMT_PH_READY_DATA IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  608.  
  609.          @ Get data ready for transfer                                         @
  610.  
  611.             IF (EVENT = ACK_PKT AND PKT_NO = PKT_SEQ)
  612.                OR (EVENT = NAK_PKT AND PKT_NO = PKT_SEQ+1 MOD 64)
  613.             THEN
  614.                PKT_SEQ := PKT_SEQ+1 MOD 64;
  615.                RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
  616.                RETRY_COUNT := 0;
  617.  
  618.                KMT_PP_TRANSLATE_TO_EBCDIC();
  619.                IF (LENGTH PKT_DATA = 1 AND STATE = SEND_DATA)
  620.                   AND (PKT_DATA(0) = "X" OR PKT_DATA(0) = "Z")
  621.                THEN            @ their ack packet requested interrupt transfer @
  622.                   KMT_FH_CLOSE_FILE(RESULT);     @ closing file shouldn't fail @
  623.                   RESULT := IF RESULT <= 0 THEN 0 ELSE 89043 FI;
  624.                   KMT_MESSAGE(-87000,RC_IGNORED);   @ log cancellation of xfer @
  625.                                                       @ set up eof packet data @
  626.                   KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  627.                   STATE := SEND_EOF
  628.                ELSE       @ check for ack of file header, it may have filename @
  629.                   IF STATE = SEND_FILE   @ used by remote Kermit, if so log it @
  630.                   THEN
  631.                      STATE := SEND_DATA;
  632.                      KMT_MTM_AREA(3) :=
  633.                         KMT_VME_FILE AS KMT_MTUP_VALUES.RVB_VALUE;
  634.                      IF LENGTH PKT_DATA > 0
  635.                      THEN
  636.                         KMT_MTM_AREA(4) :=
  637.                            PKT_DATA AS KMT_MTUP_VALUES.RVB_VALUE
  638.                      ELSE
  639.                         KMT_MTM_AREA(4) :=
  640.                            KMT_REM_FILE AS KMT_MTUP_VALUES.RVB_VALUE
  641.                      FI;
  642.                      KMT_MESSAGE(-87001,RC_IGNORED)
  643.                   FI;
  644.                                                      @ set up next data packet @
  645.                   KMT_PP_BUILD_FILE_PACKET_DATA(RESULT);
  646.                   IF RESULT = EOF
  647.                   THEN           @ all data sent, close file and send eof next @
  648.                      KMT_FH_CLOSE_FILE(RESULT);               @ shouldn't fail @
  649.                      RESULT := IF RESULT <= 0 THEN 0 ELSE 89043 FI;
  650.                      STATE := SEND_EOF                         @ all data sent @
  651.                   ELSE                              @ error reading from file? @
  652.                      RESULT := IF RESULT <= 0 THEN 0 ELSE 89047 FI
  653.                   FI
  654.                FI
  655.             ELSE
  656.                RESULT := 0
  657.             FI
  658.  
  659.          ; @ KMT_PH_MAKE_DATA @
  660.  
  661.  
  662.       SIM PROC KMT_PH_SENT_FILE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  663.  
  664.          @ File sent, check ack                                                @
  665.  
  666.          BEGIN
  667.             IF (EVENT = ACK_PKT AND PKT_NO = PKT_SEQ)
  668.                OR (EVENT = NAK_PKT AND PKT_NO = PKT_SEQ+1 MOD 64)
  669.             THEN           @ any more files? no - we only allow 1 per send so: @
  670.                PKT_SEQ := PKT_SEQ+1 MOD 64;
  671.                RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
  672.                RETRY_COUNT := 0;
  673.                KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED); @ set up break @
  674.                STATE := SEND_BREAK                              @ packet data  @
  675.                @ (ditto if previous pkt_data(0) was "Z") @
  676.             FI;
  677.             RESULT := 0
  678.          END
  679.  
  680.          ; @ KMT_PH_SENT_FILE @
  681.  
  682.  
  683.       SIM PROC KMT_PH_SEND_DONE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  684.  
  685.          @ Break sent, check ack                                               @
  686.  
  687.          BEGIN
  688.             IF EVENT = ACK_PKT
  689.             THEN
  690.                IF PKT_NO = PKT_SEQ
  691.                THEN
  692.                   STATE := COMPLETE
  693.                FI
  694.             ELSF PKT_NO = PKT_SEQ+1 MOD 64 OR PKT_NO = 0
  695.             THEN                             @ they've sent nak(n+1) or nak(0) @
  696.                STATE := COMPLETE
  697.             FI;
  698.             RESULT := 0
  699.          END
  700.  
  701.          ; @ KMT_PH_SEND_DONE @
  702.  
  703.  
  704.  
  705.        @ procedures for unexpected packets @
  706.  
  707.       SIM PROC KMT_PH_REPORT_ERR IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  708.  
  709.          @ unexpected pkt type, send error pkt and remain in same state        @
  710.  
  711.             RESULT := 89000
  712.  
  713.          ; @ KMT_PH_REPORT_ERR @
  714.  
  715.  
  716.       SIM PROC KMT_PH_GOT_ERROR IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  717.  
  718.          @ they've reported an error to us, log error message and abort        @
  719.  
  720.          BEGIN   @ decode packet data and set up message text area for logging @
  721.             KMT_PP_TRANSLATE_TO_EBCDIC();
  722.             KMT_MTM_AREA(3) := PKT_DATA AS KMT_MTUP_VALUES.RVB_VALUE;
  723.             RESULT := -87010
  724.          END
  725.  
  726.          ; @ KMT_PH_GOT_ERROR @
  727.  
  728.  
  729.       SIM PROC KMT_PH_SEND_NAK IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  730.  
  731.          @ send nak packet                                                     @
  732.  
  733.          BEGIN
  734.             KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  735.             KMT_PP_SEND_PACKET(NAK_PKT,PKT_SEQ,READ_INT,RESULT);
  736.             RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  737.          END
  738.  
  739.          ; @ KMT_PH_SEND_NAK @
  740.  
  741.  
  742.       SIM PROC KMT_PH_NAK_ABORT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  743.  
  744.          @ Send NAK and abort                                                  @
  745.  
  746.          BEGIN
  747.             KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  748.             KMT_PP_SEND_PACKET(NAK_PKT,PKT_SEQ,READ_INT,RESULT);
  749.             RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI;
  750.             STATE := ABORT
  751.          END
  752.  
  753.          ; @ KMT_PH_NAK_ABORT @
  754.  
  755.  
  756.       SIM PROC KMT_PH_ACK_LAST IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  757.  
  758.          @ if current packet is repeat of last packet then send ack            @
  759.  
  760.             IF PKT_NO+1 MOD 64 = PKT_SEQ                        @ i.e. P = N-1 @
  761.             THEN
  762.                KMT_PP_BUILD_STRING_PACKET_DATA(NIL,RC_IGNORED);
  763.                KMT_PP_SEND_PACKET(ACK_PKT,PKT_NO,READ_INT,RESULT);
  764.                RESULT := IF RESULT <= 0 THEN 0 ELSE -89061 FI
  765.             ELSE                          @ wrong packet sequence, error abort @
  766.                RESULT := 89000
  767.             FI
  768.  
  769.          ; @ KMT_PH_ACK_LAST @
  770.  
  771.  
  772.       SIM PROC KMT_PH_ERR_ABORT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  773.  
  774.          @ Send error packet and abort                                         @
  775.  
  776.             RESULT := 89001
  777.  
  778.          ; @ KMT_PH_ERR_ABORT @
  779.  
  780.  
  781.       SIM PROC KMT_PH_SEND_IDLE IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  782.  
  783.          @ the wrong type of packet (or a bad packet) has arrived while        @
  784.          @ sending a file - in this case it doesn't matter                     @
  785.  
  786.             RESULT := 0
  787.  
  788.          ; @ KMT_PH_SEND_IDLE @
  789.  
  790.  
  791.       SIM PROC KMT_PH_SET_ABORT IS GROUP KMT_PH_GRP (RESPONSE RESULT):
  792.  
  793.          @ Set ABORT state                                                     @
  794.  
  795.          BEGIN
  796.             STATE := ABORT;
  797.             RESULT := 0
  798.          END
  799.  
  800.          ; @ KMT_PH_SET_ABORT @
  801.  
  802.  
  803.       @ protocol handler state event table                                     @
  804.  
  805.       (9)(15)SIM PROC GROUP KMT_PH_GRP(RESPONSE) KMT_PH_ACTION IS
  806.  
  807.        ((KMT_PH_REC_SERVER_IDLE , KMT_PH_REPORT_ERR  , KMT_PH_REPORT_ERR ,
  808.             KMT_PH_GOT_ERROR    , KMT_PH_REPORT_ERR  , KMT_PH_GEN_CMD    ,
  809.             KMT_PH_INIT_PARAMS  , KMT_PH_KMT_CMD     , KMT_PH_REPORT_ERR ,
  810.             KMT_PH_GOT_FILENAME , KMT_PH_INIT_PARAMS , KMT_PH_REPORT_ERR ,
  811.             KMT_PH_REPORT_ERR   , KMT_PH_SEND_NAK    , KMT_PH_REPORT_ERR),
  812.  
  813.         (KMT_PH_REC_INIT        , KMT_PH_NAK_ABORT   , KMT_PH_NAK_ABORT  ,
  814.             KMT_PH_GOT_ERROR    , KMT_PH_NAK_ABORT   , KMT_PH_NAK_ABORT  ,
  815.             KMT_PH_NAK_ABORT    , KMT_PH_NAK_ABORT   , KMT_PH_NAK_ABORT  ,
  816.             KMT_PH_NAK_ABORT    , KMT_PH_INIT_PARAMS , KMT_PH_NAK_ABORT  ,
  817.             KMT_PH_NAK_ABORT    , KMT_PH_SEND_NAK    , KMT_PH_NAK_ABORT ),
  818.  
  819.         (KMT_PH_REC_FILE        , KMT_PH_BREAK       , KMT_PH_NAK_ABORT  ,
  820.             KMT_PH_GOT_ERROR    , KMT_PH_FILE_HDR    , KMT_PH_NAK_ABORT  ,
  821.             KMT_PH_NAK_ABORT    , KMT_PH_NAK_ABORT   , KMT_PH_NAK_ABORT  ,
  822.             KMT_PH_NAK_ABORT    , KMT_PH_INIT_PARAMS , KMT_PH_NAK_ABORT  ,
  823.             KMT_PH_ACK_LAST     , KMT_PH_SEND_NAK    , KMT_PH_NAK_ABORT ),
  824.  
  825.         (KMT_PH_REC_DATA        , KMT_PH_ERR_ABORT   , KMT_PH_GOT_DATA   ,
  826.             KMT_PH_GOT_ERROR    , KMT_PH_ACK_LAST    , KMT_PH_ERR_ABORT  ,
  827.             KMT_PH_ERR_ABORT    , KMT_PH_ERR_ABORT   , KMT_PH_ERR_ABORT  ,
  828.             KMT_PH_ERR_ABORT    , KMT_PH_ERR_ABORT   , KMT_PH_ERR_ABORT  ,
  829.             KMT_PH_GOT_FILE     , KMT_PH_SEND_NAK    , KMT_PH_ERR_ABORT ),
  830.  
  831.         (KMT_PH_SEND_INIT       , KMT_PH_SEND_IDLE   , KMT_PH_SEND_IDLE  ,
  832.             KMT_PH_GOT_ERROR    , KMT_PH_SEND_IDLE   , KMT_PH_SEND_IDLE  ,
  833.             KMT_PH_SEND_IDLE    , KMT_PH_SEND_IDLE   , KMT_PH_SEND_IDLE  ,
  834.             KMT_PH_SEND_IDLE    , KMT_PH_SEND_IDLE   , KMT_PH_READY_FILE ,
  835.             KMT_PH_SEND_IDLE    , KMT_PH_SEND_IDLE   , KMT_PH_SEND_IDLE ),
  836.  
  837.         (KMT_PH_SEND_FILE       , KMT_PH_SET_ABORT   , KMT_PH_SET_ABORT  ,
  838.             KMT_PH_GOT_ERROR    , KMT_PH_SET_ABORT   , KMT_PH_SET_ABORT  ,
  839.             KMT_PH_SET_ABORT    , KMT_PH_SET_ABORT   , KMT_PH_READY_DATA ,
  840.             KMT_PH_SET_ABORT    , KMT_PH_SET_ABORT   , KMT_PH_READY_DATA ,
  841.             KMT_PH_SET_ABORT    , KMT_PH_SEND_IDLE   , KMT_PH_SET_ABORT ),
  842.  
  843.         (KMT_PH_SEND_DATA       , KMT_PH_SET_ABORT   , KMT_PH_SET_ABORT  ,
  844.             KMT_PH_GOT_ERROR    , KMT_PH_SET_ABORT   , KMT_PH_SET_ABORT  ,
  845.             KMT_PH_SET_ABORT    , KMT_PH_SET_ABORT   , KMT_PH_READY_DATA ,
  846.             KMT_PH_SET_ABORT    , KMT_PH_SET_ABORT   , KMT_PH_READY_DATA ,
  847.             KMT_PH_SET_ABORT    , KMT_PH_SEND_IDLE   , KMT_PH_SET_ABORT ),
  848.  
  849.         (KMT_PH_SEND_EOF        , KMT_PH_SET_ABORT   , KMT_PH_SET_ABORT  ,
  850.             KMT_PH_GOT_ERROR    , KMT_PH_SET_ABORT   , KMT_PH_SET_ABORT  ,
  851.             KMT_PH_SET_ABORT    , KMT_PH_SET_ABORT   , KMT_PH_SENT_FILE  ,
  852.             KMT_PH_SET_ABORT    , KMT_PH_SET_ABORT   , KMT_PH_SENT_FILE  ,
  853.             KMT_PH_SET_ABORT    , KMT_PH_SEND_IDLE   , KMT_PH_SET_ABORT ),
  854.  
  855.         (KMT_PH_SEND_BREAK      , KMT_PH_SET_ABORT   , KMT_PH_SET_ABORT  ,
  856.             KMT_PH_GOT_ERROR    , KMT_PH_SET_ABORT   , KMT_PH_SET_ABORT  ,
  857.             KMT_PH_SET_ABORT    , KMT_PH_SET_ABORT   , KMT_PH_SEND_DONE  ,
  858.             KMT_PH_SET_ABORT    , KMT_PH_SET_ABORT   , KMT_PH_SEND_DONE  ,
  859.             KMT_PH_SET_ABORT    , KMT_PH_SEND_IDLE   , KMT_PH_SET_ABORT ));
  860.  
  861.  
  862.       @ PROTOCOL HANDLER @
  863.  
  864.       IF KMT_TRACE_FLAGS.PH_TRACING
  865.       THEN
  866.          () KMT_MTUP_VALUES PARAMS := (STATE AS KMT_MTUP_VALUES.RI_VALUE,
  867.                                        (L'EVENT) AS KMT_MTUP_VALUES.LI_VALUE);
  868.          KMT_SP_LOG_TRACE_MESSAGE(300,PARAMS)
  869.       FI;
  870.  
  871.       IF EVENT = ENTRY
  872.       THEN                    @ increment retry count and test against maximum @
  873.          RETRY_COUNT := RETRY_COUNT+1;
  874.          IF RETRY_COUNT > MAXTRY
  875.          THEN
  876.             RETRY_TOTAL := RETRY_TOTAL + (RETRY_COUNT - 1);
  877.             RESULT := 89050
  878.          ELSE
  879.             KMT_PH_ACTION(STATE,EVENT)(RESULT)
  880.          FI
  881.       ELSE
  882.          KMT_PH_ACTION(STATE,EVENT)(RESULT)
  883.       FI;
  884.  
  885.       IF RESULT NE 0
  886.       THEN
  887.          IF RESULT = -89061
  888.          THEN                            @ unable to send packet - fatal error @
  889.             STATE := ABORT;
  890.             EXIT_STATE := FATAL_ERROR
  891.          ELSF (RESULT NE 89000) OR (STATE NE REC_SERVER_IDLE)
  892.          THEN             @ abort unless wrong seq no in Rec_Server_Idle state @
  893.             STATE := ABORT
  894.          FI
  895.       FI
  896.  
  897.    END
  898.  
  899.    ; @ KMT_PH @
  900.  
  901. ENDMODULE                                                      @ KMT_PH_MODULE @
  902.