?? RIGHT := 110 ??
?? NEWTITLE := 'VTP Terminal Interface' ??
MODULE iim$vtp_terminal_interface;

{ PURPOSE:
{
{ This module provides procedures IIP$VTP_OPEN_NETWORK, IIP$VTP_GET_NEXT, and
{ IIP$VTP_PUT_NEXT.  These are alternatives to FSP$OPEN_FILE, AMP$GET_xxx, and
{ AMP$PUT_xxx.  There are two primary effects of using this interface:
{ some overhead is avoided by going as directly as possible to NAM/VE without
{ using the Interactive FAP, and the application gets visibility to the
{ VTP (virtual terminal protocol) headers in CDCNET.  The VTP header is
{ useful for applications that need to determine which of several possible
{ transparent input forwarding conditions have occurred.
{

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clc$standard_file_names
*copyc ife$error_codes
*copyc ife$interactive_exception_codes
*copyc nae$application_interfaces
*copyc nae$namve_conditions
*copyc nat$data_fragments
*copyc iit$cdcnet_conn_reject_reasons
*copyc iit$vt_attributes
*copyc iit$vt_attribute_descriptions
*copyc iit$vt_attribute_kinds
*copyc iit$vt_change_error_codes
*copyc iit$vt_connections
*copyc iit$vt_input_information
*copyc iit$vt_message_types
*copyc iit$vt_octet_header
*copyc iit$vt_output_information
*copyc iit$vt_timeout
?? POP ??
*copyc bav$last_tft_entry
*copyc bav$task_file_table
*copyc clp$get_system_file_id
*copyc fsp$close_file
*copyc fsp$open_file
*copyc i#move
*copyc i#ptr
*copyc nap$await_data_available
*copyc nap$se_receive_data
*copyc nap$se_send_data
*copyc nap$se_synchronize
*copyc nap$se_synchronize_confirm
*copyc osp$generate_log_message
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc oss$job_paged_literal
*copyc pmp$log

?? OLDTITLE ??
?? TITLE := ' iip$vtp_open_network ', EJECT ??

*copyc iih$vtp_open_network

  PROCEDURE [XDCL, #GATE] iip$vtp_open_network
    (VAR file_id: amt$file_identifier;
     VAR status: ost$status);

    VAR
      i: integer,
      network_lfn: ost$name;

    status.normal := TRUE;
    network_lfn := ':$LOCAL.$TERMINAL';
    fsp$open_file (network_lfn, amc$record, NIL, NIL, NIL, NIL, NIL, file_id, status);

  PROCEND iip$vtp_open_network;
?? TITLE := ' iip$vtp_put_next ', EJECT ??

*copyc iih$vtp_put_next

  PROCEDURE [XDCL, #GATE] iip$vtp_put_next
    (    file_identifier: amt$file_identifier;
         working_storage_area: ^cell;
         working_storage_length: amt$working_storage_length;
     VAR status: ost$status);

    VAR
      activity_status: ost$activity_status,
      data_fragment: array [1 .. 1] of nat$data_fragment,
      local_status: ost$status;

    data_fragment [1].address := working_storage_area;
    data_fragment [1].length := working_storage_length;
    nap$se_send_data (file_identifier, data_fragment, TRUE, FALSE, osc$wait, activity_status, status);
    IF NOT status.normal THEN
      osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], status, local_status);
      pmp$log ('VTP-PUT 01', local_status);
      RETURN;
    IFEND;

  PROCEND iip$vtp_put_next;
?? TITLE := ' iip$vtp_get_next ', EJECT ??

*copyc iih$vtp_get_next

  PROCEDURE [XDCL, #GATE] iip$vtp_get_next
    (    file_identifier: amt$file_identifier;
         working_storage_area: ^cell;
         working_storage_length: amt$working_storage_length;
         timeout: iit$vt_timeout;
     VAR input_information: iit$vt_input_information;
     VAR transfer_count: amt$transfer_count;
     VAR status: ost$status);

    VAR
      activity_status: ost$activity_status,
      data_fragment: array [1 .. 1] of nat$data_fragment,
      end_of_message: boolean,
      local_status: ost$status,
      message_received: boolean,
      output_information: iit$vt_output_information;

    output_information.message_type := iic$vt_output_data_message;
    output_information.fill_0 := 0;
    output_information.reserved_1 := 0;
    output_information.reserved_2 := 0;
    output_information.formatting_mode := 0;
    output_information.secured.suppress_end_line_positioning := FALSE;
    output_information.secured.suppress_echoplexing := FALSE;
    output_information.partial := FALSE;
    data_fragment [1].address := ^output_information;
    data_fragment [1].length := #SIZE (output_information);
    nap$se_send_data (file_identifier, data_fragment, TRUE, FALSE, osc$wait, activity_status, status);
    IF NOT status.normal THEN
      osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], status, local_status);
      pmp$log ('VTP-GET 01', local_status);
      RETURN;
    IFEND;

    get_next_special_block (file_identifier, working_storage_area, working_storage_length, osc$wait, timeout,
          message_received, end_of_message, transfer_count, input_information, status);

  PROCEND iip$vtp_get_next;
?? TITLE := ' iip$vtp_del_paired_con_first ', EJECT ??

  PROCEDURE [XDCL, #GATE] iip$vtp_del_paired_con_first
    (    paired_connection_data: ^SEQ ( * );
     VAR status: ost$status);

    TYPE
      delete_connection_type = record
        message_type: iit$vt_message_types,
        paired_connection_data: SEQ ( * ),
      recend;

    VAR
      delete_connection: ^delete_connection_type,
      delete_connection_message: ^cell,
      delete_conn_msg_length: amt$working_storage_length,
      ignore_status: ost$status,
      local_status: ost$status,
      network_fid: amt$file_identifier;

    status.normal := TRUE;

    iip$vtp_open_network (network_fid, status);
    IF NOT status.normal THEN
      osp$generate_log_message ($pmt$ascii_logset [pmc$system_log, pmc$job_log], status, local_status);
      pmp$log ('VTP-DC 01', local_status);
      RETURN;
    IFEND;

    PUSH delete_connection: [[REP #SIZE (paired_connection_data^) OF cell]];
    delete_connection^.message_type := iic$vt_delete_paired_connection;
    delete_connection^.paired_connection_data := paired_connection_data^;
    delete_connection_message := delete_connection;
    delete_conn_msg_length := #SIZE (delete_connection^);
    iip$vtp_put_next (network_fid, delete_connection_message, delete_conn_msg_length, status);

    fsp$close_file (network_fid, ignore_status);
  PROCEND iip$vtp_del_paired_con_first;

?? TITLE := ' iip$vtp_delete_paired_connect ', EJECT ??

*copyc iih$vtp_delete_paired_connect

  PROCEDURE [XDCL, #GATE] iip$vtp_delete_paired_connect
    (    file_identifier: amt$file_identifier;
         paired_connection_data: ^SEQ ( * );
     VAR status: ost$status);

    TYPE
      delete_connection_type = record
        message_type: iit$vt_message_types,
        paired_connection_data: SEQ ( * ),
      recend;

    VAR
      delete_connection: ^delete_connection_type,
      delete_connection_message: ^cell,
      delete_conn_msg_length: amt$working_storage_length,
      file_id_is_valid: boolean,
      file_instance: ^bat$task_file_entry,
      local_status: ost$status,
      network_fid: amt$file_identifier,
      st_open_file_dsc_pointer: ^iit$st_open_file_description;

    status.normal := TRUE;

*copy bai$validate_file_identifier
*copy iii$fetch_st_open_file_desc_ptr
    IF NOT status.normal THEN
      osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], status, local_status);
      pmp$log ('VTP-DC 02', local_status);
      RETURN;
    IFEND;
    network_fid := st_open_file_dsc_pointer^.vtp_file_id;
    PUSH delete_connection: [[REP #SIZE (paired_connection_data^) OF cell]];
    delete_connection^.message_type := iic$vt_delete_paired_connection;
    delete_connection^.paired_connection_data := paired_connection_data^;
    delete_connection_message := delete_connection;
    delete_conn_msg_length := #SIZE (delete_connection^);
    iip$vtp_put_next (network_fid, delete_connection_message, delete_conn_msg_length, status);

  PROCEND iip$vtp_delete_paired_connect;
?? TITLE := '[XDCL, #GATE] iip$vtp_create_paired_connect ', EJECT ??

*copyc iih$vtp_create_paired_connect

  PROCEDURE [XDCL, #GATE] iip$vtp_create_paired_connect
    (    file_identifier: amt$file_identifier;
         destination_title: ost$name;
         paired_connection_data: ^SEQ ( * );
         timeout_interval_in_ms: 0 .. 0ffffffff(16);
     VAR status: ost$status);

    TYPE
      create_connection_type = record
        message_type: iit$vt_message_types,
        destination_id_type: 0 .. 0ff(16),
        destination_title: ost$name,
        paired_connection_data: SEQ ( * ),
      recend;

    VAR

      buffer: SEQ (REP 1 of cell),
      create_connection: ^create_connection_type,
      create_connection_message: ^cell,
      create_conn_msg_length: amt$working_storage_length,
      file_id_is_valid: boolean,
      file_instance: ^bat$task_file_entry,
      input_information: iit$vt_input_information,
      local_status: ost$status,
      network_fid: amt$file_identifier,
      st_open_file_dsc_pointer: ^iit$st_open_file_description,
      timeout: iit$vt_timeout,
      transfer_count: amt$transfer_count,
      working_storage_area: ^cell,
      working_storage_length: amt$working_storage_length;

    status.normal := TRUE;

*copy bai$validate_file_identifier
*copy iii$fetch_st_open_file_desc_ptr
    IF NOT status.normal THEN
      osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], status, local_status);
      pmp$log ('VTP-CPC 02', local_status);
      RETURN;
    IFEND;
    network_fid := st_open_file_dsc_pointer^.vtp_file_id;
    PUSH create_connection: [[REP #SIZE (paired_connection_data^) OF cell]];
    create_connection^.message_type := iic$vt_create_paired_connection;
    create_connection^.destination_id_type := 1;
    create_connection^.destination_title := destination_title;
    create_connection^.paired_connection_data := paired_connection_data^;
    create_connection_message := create_connection;
    create_conn_msg_length := #SIZE (create_connection^);
    iip$vtp_put_next (network_fid, create_connection_message, create_conn_msg_length, status);
    IF NOT status.normal THEN
      osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], status, local_status);
      pmp$log ('VTP-CPC 03', local_status);
      RETURN;
    IFEND;

    IF timeout_interval_in_ms <> 0 THEN
      timeout. ON := TRUE;
      timeout.length := timeout_interval_in_ms;
      timeout.purge := FALSE;
    ELSE
      timeout. ON := FALSE;
    IFEND;

    working_storage_area := ^buffer;
    working_storage_length := 1;
    iip$vtp_get_next (network_fid, working_storage_area, working_storage_length, timeout, input_information,
          transfer_count, status);
    IF NOT status.normal THEN
      osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], status, local_status);
      pmp$log ('VTP-CPC 04', local_status);
      RETURN;
    IFEND;

    IF input_information.message_type = iic$vt_create_paired_conn_cnfrm THEN
      RETURN;
    ELSE { input_information.message_type = iic$vt_create_paired_conn_rejct.
      osp$set_status_condition (ife$vt_create_paired_conn_rejct, status);
    IFEND;

  PROCEND iip$vtp_create_paired_connect;
?? TITLE := '[XDCL, #GATE] iip$vtp_create_cdcnet_connect ', EJECT ??

*copyc iih$vtp_create_cdcnet_connect

  PROCEDURE [XDCL, #GATE] iip$vtp_create_cdcnet_connect
    (    service_name: ost$name;
         service_data: ^SEQ ( * );
         connection_data_1: ^SEQ ( * );
         connection_data_2: ^SEQ ( * );
         connection_data_3: ^SEQ ( * );
         end_discard_prompt: ^SEQ ( * );
         timeout_interval_in_ms: 0 .. 0ffffffff(16);
     VAR status: ost$status);

    TYPE
      create_connection_type = record
        message_type: iit$vt_message_types,
        service_name: ost$name,
        length: 0 .. 0ff(16),
        service_data: SEQ ( * ),
      recend;

    TYPE
      create_connection_type2 = record
        message_type: iit$vt_message_types,
        service_name: ost$name,
        length: 0 .. 0ff(16),
      recend;

    TYPE
      connection_data_type = record
        length: 0 .. 0ff(16),
        connection_data: SEQ ( * ),
      recend;

    TYPE
      receive_data = record
        case boolean of
        = true =
          input_info: iit$vt_input_information,
        = false =
          data: packed record
            fill1: 0 .. 1fff(16),
            reason: iit$cdcnet_conn_reject_reasons,
            fill2: 0 .. 0ffff(16),
          recend,
        casend,
      recend;


    VAR
      activity_status: ost$activity_status,
      buffer: SEQ (REP 1 of cell),
      create_connection: ^create_connection_type,
      create_connection_no_serv_data: ^create_connection_type2,
      cdata1: ^connection_data_type,
      cdata2: ^connection_data_type,
      cdata3: ^connection_data_type,
      data_fragment: array [1 .. 5] of nat$data_fragment,
      edp_data: ^connection_data_type,
      end_discard_prompt_length: 0 .. 16,
      file_identifier: amt$file_identifier,
      file_id_is_valid: boolean,
      file_instance: ^bat$task_file_entry,
      i: 1 .. 5,
      input_information: iit$vt_input_information,
      local_status: ost$status,
      network_fid: amt$file_identifier,
      received: receive_data,
      st_open_file_dsc_pointer: ^iit$st_open_file_description,
      timeout: iit$vt_timeout,
      transfer_count: amt$transfer_count,
      working_storage_area: ^cell,
      working_storage_length: amt$working_storage_length;


    status.normal := TRUE;

    clp$get_system_file_id (clc$job_output, file_identifier, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

*copy bai$validate_file_identifier
*copy iii$fetch_st_open_file_desc_ptr
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    network_fid := st_open_file_dsc_pointer^.vtp_file_id;
    IF service_data <> NIL THEN
      PUSH create_connection: [[REP #SIZE (service_data^) OF cell]];
      create_connection^.message_type := iic$vt_create_cdcnet_connection;
      create_connection^.service_name := service_name;
      create_connection^.length := #SIZE (service_data^);
      create_connection^.service_data := service_data^;
      data_fragment [1].address := create_connection;
      data_fragment [1].length := #SIZE (create_connection^);
    ELSE
      PUSH create_connection_no_serv_data;
      create_connection_no_serv_data^.message_type := iic$vt_create_cdcnet_connection;
      create_connection_no_serv_data^.service_name := service_name;
      create_connection_no_serv_data^.length := 0;
      data_fragment [1].address := create_connection_no_serv_data;
      data_fragment [1].length := #SIZE (create_connection_no_serv_data^);
    IFEND;

    IF end_discard_prompt = NIL THEN
      end_discard_prompt_length := 0;
      data_fragment [2].address := ^end_discard_prompt_length;
      data_fragment [2].length := #SIZE (end_discard_prompt_length);
    ELSE
      PUSH edp_data: [[REP #SIZE (end_discard_prompt^) OF cell]];
      edp_data^.length := #SIZE (end_discard_prompt^);
      edp_data^.connection_data := end_discard_prompt^;
      data_fragment [2].address := edp_data;
      data_fragment [2].length := #SIZE (edp_data^);
    IFEND;

    FOR i := 3 TO 5 DO
      data_fragment [i].address := NIL;
      data_fragment [i].length := 0;
    FOREND;

    IF connection_data_1 <> NIL THEN
      PUSH cdata1: [[REP #SIZE (connection_data_1^) OF cell]];
      cdata1^.length := #SIZE (connection_data_1^);
      cdata1^.connection_data := connection_data_1^;
      data_fragment [3].address := cdata1;
      data_fragment [3].length := #SIZE (cdata1^);
      IF connection_data_2 <> NIL THEN
        PUSH cdata2: [[REP #SIZE (connection_data_2^) OF cell]];
        cdata2^.length := #SIZE (connection_data_2^);
        cdata2^.connection_data := connection_data_2^;
        data_fragment [4].address := cdata2;
        data_fragment [4].length := #SIZE (cdata2^);
        IF connection_data_3 <> NIL THEN
          PUSH cdata3: [[REP #SIZE (connection_data_3^) OF cell]];
          cdata3^.length := #SIZE (connection_data_3^);
          cdata3^.connection_data := connection_data_3^;
          data_fragment [5].address := cdata3;
          data_fragment [5].length := #SIZE (cdata3^);
        IFEND;
      IFEND;
    IFEND;

    nap$se_send_data (network_fid, data_fragment, TRUE, FALSE, osc$wait, activity_status, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF timeout_interval_in_ms <> 0 THEN
      timeout. ON := TRUE;
      timeout.length := timeout_interval_in_ms;
      timeout.purge := FALSE;
    ELSE
      timeout. ON := FALSE;
    IFEND;

    working_storage_area := ^buffer;
    working_storage_length := 1;
    iip$vtp_get_next (network_fid, working_storage_area, working_storage_length, timeout, input_information,
          transfer_count, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF input_information.message_type <> iic$vt_create_cdcnet_conn_cnfrm THEN
      received.input_info := input_information;
      IF received.data.reason = iic$cannot_locate_service THEN
        osp$set_status_abnormal ('IF', ife$cannot_locate_service, service_name, status);
      ELSEIF received.data.reason = iic$connection_already_switched THEN
        osp$set_status_condition (ife$connection_already_switched, status);
      ELSEIF received.data.reason = iic$cannot_create_connection THEN
        osp$set_status_condition (ife$cannot_create_connection, status);
      ELSEIF received.data.reason = iic$service_is_busy THEN
        osp$set_status_condition (ife$service_is_busy, status);
      ELSEIF received.data.reason = iic$invalid_service_data THEN
        osp$set_status_condition (ife$invalid_service_data, status);
      ELSEIF received.data.reason = iic$invalid_connection_data THEN
        osp$set_status_condition (ife$invalid_connection_data, status);
      ELSE
        pmp$log ('VTP - CCC - UNKNOWN REJECT REASON', local_status);
        osp$set_status_condition (ife$cannot_create_connection, status);
      IFEND;
    IFEND;

  PROCEND iip$vtp_create_cdcnet_connect;
?? TITLE := 'GET_NEXT_SPECIAL_BLOCK', EJECT ??

  PROCEDURE get_next_special_block
    (    input_file_identifier: amt$file_identifier;
         buffer_ptr: ^cell;
         buffer_length: nat$data_length;
         wait: ost$wait;
         timeout: iit$vt_timeout;
     VAR message_received: boolean;
     VAR end_of_message: boolean;
     VAR transfer_count: nat$data_length;
     VAR input: iit$vt_input_information;
     VAR status: ost$status);


    VAR
      activity_status: ost$activity_status,
      data: array [1 .. 2] of nat$data_fragment,
      data1: array [1 .. 1] of nat$data_fragment,
      empty_header: [STATIC, READ, oss$job_paged_literal] iit$vt_input_information :=
            [0, iic$vt_input_data_message, 0, 0, iic$vt_character, FALSE, FALSE, TRUE, FALSE, 'a'],
      file_identifier: amt$file_identifier,
      ibs_buffer: ^SEQ (REP 2048 of cell),
      move_ptr: ^cell,
      non_eom_buffer: SEQ (REP 2048 of cell),
      peer_operation: nat$se_peer_operation,
      queue_type_from_message: [STATIC, READ, oss$job_paged_literal] iit$vt_queue_type_from_message :=
            [iic$vt_output, iic$vt_input, iic$vt_change, iic$vt_change, iic$vt_change, iic$vt_indications,
            iic$vt_status, iic$vt_status, iic$vt_status, iic$vt_start_stop_comm, iic$vt_start_stop_comm_resp,
            iic$vt_start_stop_comm, iic$vt_start_stop_comm_resp, iic$vt_change, iic$vt_version, iic$vt_create,
            iic$vt_create_status, iic$vt_create_status, iic$vt_delete, iic$vt_status, iic$vt_status,
            iic$vt_status, iic$vt_create, iic$vt_create_status, iic$vt_create_status],
      status_save: ost$status,
      timeout_data: SEQ (REP 1 of cell),
      wait_time: integer;


    status.normal := TRUE;
    message_received := FALSE;
    transfer_count := 0;

    REPEAT
      IF timeout. ON THEN
        wait_time := timeout.length;
        nap$await_data_available (input_file_identifier, wait_time, wait_time, status);
        IF NOT status.normal THEN
          IF (status.condition = nae$no_event) OR (status.condition = nae$no_data_available) OR
                (status.condition = nae$data_transfer_timeout) THEN
            status_save := status;
            IF timeout.length <> 0 THEN
              IF timeout.purge THEN
                nap$se_synchronize (input_file_identifier, nac$se_synchronize_all_data, timeout_data, status);
                IF NOT status.normal THEN
                  IF status.condition = nae$se_synch_confirm_pending THEN
                    status.normal := TRUE;
                  IFEND;
                  RETURN;
                ELSE
                  status := status_save;
                IFEND;
              IFEND; { of timeout.purge }
            IFEND; { of timeout.length nonzero }
          IFEND; { of timeout-related status }
          RETURN; { for any abnormal status }
        IFEND; { of abnormal status }
      IFEND; { of timeout.on }

{ Receive block and return it or queue it.

      data [1].address := ^input;
      data [1].length := iic$vt_header_length_input;
      data [2].address := buffer_ptr;
      data [2].length := buffer_length;
      nap$se_receive_data (input_file_identifier, data, wait, peer_operation, activity_status, status);
      IF (status.normal) AND (activity_status.complete) AND (NOT activity_status.status.normal) THEN
        status := activity_status.status;
      IFEND;
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      CASE peer_operation.kind OF
      = nac$se_interrupt =
        osp$set_status_condition (ife$vt_unsupported_event, status);
        RETURN;

      = nac$se_synchronize =
        IF peer_operation.direction = nac$se_synchronize_receive_data THEN
          transfer_count := 0;
          input := empty_header;
          message_received := TRUE;
        ELSE
          nap$se_synchronize_confirm (input_file_identifier, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;

      = nac$se_synchronize_confirm =
        ; { add code someday if there is  anything to do }

      = nac$se_send_data =
        IF queue_type_from_message [input.message_type] = iic$vt_input THEN
          IF NOT peer_operation.end_of_message THEN
            message_received := TRUE;
            transfer_count := peer_operation.data_length - iic$vt_header_length_input;
            end_of_message := FALSE;
            ibs_buffer := ^non_eom_buffer;
            RESET ibs_buffer;
            move_ptr := ibs_buffer;
            i#move (^input, move_ptr, iic$vt_header_length_input);
            data1 [1].address := i#ptr (iic$vt_header_length_input, move_ptr);
            data1 [1].length := iic$vt_max_transfer_length - iic$vt_header_length_input;
            nap$se_receive_data (input_file_identifier, data1, wait, peer_operation, activity_status, status);
            IF (status.normal) AND (activity_status.complete) AND (NOT activity_status.status.normal) THEN
              status := activity_status.status;
            IFEND;
            IF NOT status.normal THEN
              RETURN;
            IFEND;

            IF NOT peer_operation.end_of_message THEN
              osp$set_status_condition (ife$vt_no_eom_found, status);
              RETURN;
            IFEND;

            CASE peer_operation.kind OF

            = nac$se_interrupt =
              osp$set_status_condition (ife$vt_unsupported_event, status);
              RETURN;

            = nac$se_synchronize =
              IF peer_operation.direction = nac$se_synchronize_receive_data THEN
                transfer_count := 0;
                input := empty_header;
                message_received := TRUE;
              ELSE
                nap$se_synchronize_confirm (input_file_identifier, status);
                IF NOT status.normal THEN
                  RETURN;
                IFEND;
              IFEND;

            = nac$se_synchronize_confirm =
              ; { add code someday if there is  anything to do }

            = nac$se_send_data =

{ Discarding data after non-EOM

              RETURN;

            CASEND; { of peer_operation.kind, inner layer }

          ELSE {eom encountered}
            end_of_message := peer_operation.end_of_message;
            IF queue_type_from_message [input.message_type] = iic$vt_input THEN
              message_received := TRUE;
              transfer_count := peer_operation.data_length - iic$vt_header_length_input;
              RETURN;
            IFEND;
          IFEND; { eom encountered }

        ELSE { not input data}

          CASE peer_operation.kind OF
          = nac$se_interrupt =
            osp$set_status_condition (ife$vt_unsupported_event, status);
            RETURN;

          = nac$se_synchronize =
            IF peer_operation.direction = nac$se_synchronize_receive_data THEN
              transfer_count := 0;
              input := empty_header;
              message_received := TRUE;
            ELSE
              nap$se_synchronize_confirm (input_file_identifier, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
            IFEND;

          = nac$se_synchronize_confirm =

{ add code if there is anything to be done here

          = nac$se_send_data =
            IF NOT peer_operation.end_of_message THEN
              osp$set_status_condition (ife$vt_no_eom_found, status);
              RETURN;
            IFEND;
            message_received := TRUE;
            transfer_count := peer_operation.data_length;
            RETURN;
          ELSE
          CASEND; { of peer_operation.kind, not input data}
        IFEND; { not input data}
      ELSE
      CASEND; { of peer_operation.kind, outer layer }

    UNTIL message_received;

  PROCEND get_next_special_block;

?? OLDTITLE ??
?? OLDTITLE ??
MODEND iim$vtp_terminal_interface;
