?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Network Access : XNS Session Protocol Layer' ??
?? NEWTITLE := 'Global Declarations Referenced by This Module' ??
MODULE nlm$sl_internal_interface;
?? PUSH (LISTEXT := ON) ??
*copyc nae$application_interfaces
*copyc nae$namve_conditions
*copyc nat$application_name
*copyc nat$data_fragments
*copyc nat$generic_destination_address
*copyc nat$generic_sap_identifier
*copyc nat$network_address
*copyc nat$network_message_priority
*copyc nat$ta_alternate_protocol_class
*copyc nat$ta_preferred_protocol_class
*copyc nlt$sl_application_name_length
*copyc nlt$sl_clear_reason
*copyc nlt$sl_connection_descriptor
*copyc nlt$sl_discard_options
*copyc nlt$sl_event
*copyc nlt$sl_family_name_length
*copyc nlt$sl_interface
*copyc nlt$sl_machine_state
*copyc nlt$sl_max_active_connections
*copyc nlt$sl_pdu_header
*copyc nlt$sl_user_name_length
*copyc nlt$sl_validation_version
*copyc nlt$ta_event
*copyc oss$job_paged_literal
*copyc ost$wait
?? POP ??
*copyc clp$trimmed_string_size
*copyc jmp$get_job_attributes
*copyc nap$find_sap_priority
*copyc nap$namve_system_error
*copyc nlp$al_get_data_length
*copyc nlp$bm_add_message_prefix
*copyc nlp$bm_create_message
*copyc nlp$bm_extract_message_prefix
*copyc nlp$bm_flush_message
*copyc nlp$bm_get_message_length
*copyc nlp$bm_release_message
*copyc nlp$bm_valid_message_id
*copyc nlp$cancel_timer
*copyc nlp$cl_activate_layer
*copyc nlp$cl_activate_receiver
*copyc nlp$cl_deactivate_layer
*copyc nlp$cl_deactivate_receiver
*copyc nlp$cl_initialize_template
*copyc nlp$cl_get_connection_processor
*copyc nlp$cl_get_layer_connection
*copyc nlp$cl_get_sap_processor
*copyc nlp$osi_get_outbound_capacity
*copyc nlp$select_timer
*copyc nlp$ta_accept_connection
*copyc nlp$ta_close_sap
*copyc nlp$ta_disconnect_connection
*copyc nlp$ta_initialize
*copyc nlp$ta_open_sap
*copyc nlp$ta_request_connection
*copyc nlp$ta_send_aggregate_message
*copyc nlp$ta_send_data
*copyc nlp$ta_send_data_fragments
*copyc nlp$ta_send_expedited_data
*copyc nlp$timer_expired
*copyc osp$append_status_integer
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc pmp$log
*copyc nav$network_procedures
*copyc nlv$bm_nil_message_id
*copyc nlv$bm_null_message_id
?? OLDTITLE ??
?? NEWTITLE := 'Glocal Declarations Declared by This Module', EJECT ??

  VAR
    session_layer: [STATIC, READ, oss$job_paged_literal] string (13) := 'SESSION LAYER',
    nlv$sl_initialized_connection: [STATIC, READ, oss$job_paged_literal] nlt$sl_connection_descriptor :=
          [nlc$sl_closed, FALSE, FALSE, FALSE, FALSE, * , 0, * , * , TRUE, * , TRUE, nac$nil];

?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_sap_event_processor'??
?? NEWTITLE := '<call_wait> <--- <closed> [connect_indication]', EJECT ??

  PROCEDURE [XDCL] nlp$sl_sap_event_processor
    (    cl_connection: ^nlt$cl_connection;
         event: nlt$ta_event;
     VAR accumulated_message_buffers: nlt$ta_inventory_report);

    VAR
      connection: ^nlt$sl_connection_descriptor,
      event_processor: nlt$cl_event_processor,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      message_length: integer,
      sap_priority: nat$network_message_priority,
      status: ost$status;

    IF event.kind = nlc$ta_connect_event THEN
      accumulated_message_buffers.changed := FALSE;
      nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);
      connection^ := nlv$sl_initialized_connection;
      nlp$bm_get_message_length (event.osi_connect.data, message_length);
      IF (message_length = 0) THEN
        connection^.source.kind := nac$osi_transport_address;
        connection^.source.osi_transport_address := event.osi_connect.source_address;
        connection^.sap.kind := nac$osi_sap_identifier;
        connection^.sap.identifier := event.osi_connect.destination_transport_sap;
        nap$find_sap_priority (connection^.sap, sap_priority);
        nlp$ta_accept_connection (cl_connection, {checksum =} FALSE, nlv$bm_null_message_id,
              {expedited_data =} TRUE, sap_priority, {quality_of_service = } NIL, status);
        IF status.normal THEN
          nlp$cl_activate_layer (nlc$xns_session_layer, cl_connection);
          nlp$cancel_timer (connection^.clear_timer);
          connection^.current_state := nlc$sl_call_wait;
          connection^.call_pdu_message_id := nlv$bm_nil_message_id;
          nlp$cl_get_connection_processor (cl_connection^.application_layer, nlc$xns_session_layer,
                event_processor);
          connection^.event_processor := event_processor.se;
          nlp$cl_activate_receiver (cl_connection);
        ELSE
          nap$namve_system_error (TRUE, 'Session accept connection failed.', ^status);
        IFEND;
      ELSE { IF message_length > 0 THEN
        nlp$ta_disconnect_connection (cl_connection, nlv$bm_null_message_id, status);
        message_id := event.osi_connect.data;
        nlp$bm_release_message (message_id);
      IFEND;
    ELSE { IF event.kind <> nlc$ta_connect_event THEN
      nap$namve_system_error (TRUE, 'Session fsm error:  Unexpected event received.', NIL);
    IFEND;
  PROCEND nlp$sl_sap_event_processor;

?? OLDTITLE ??
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_connect_event_processor', EJECT ??

  PROCEDURE [XDCL] nlp$sl_connect_event_processor
    (    cl_connection: ^nlt$cl_connection;
         event: nlt$ta_event;
     VAR accumulated_message_buffers: nlt$ta_inventory_report);

    VAR
      accounting_validation_length: packed record
        accounting: 0 .. 0ffff(16),
        validation: 0 .. 0ffff(16),
      recend,
      accounting_data: ^array [1 .. * ] of cell,
      bytes_moved: nat$data_length,
      call_message: ^array [1 .. * ] of cell,
      call_pdu_message: array [1 .. 1] of nat$data_fragment,
      connection: ^nlt$sl_connection_descriptor,
      end_of_message: boolean,
      event_processor: nlt$cl_event_processor,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      message_length: integer,
      pdu_header: nlt$sl_pdu_header,
      user_event: nlt$sl_event,
      validation_data: ^string ( * <= 512 {nlc$sl_max_validation_length} ),
      status: ost$status;

    accumulated_message_buffers.changed := FALSE;
    nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);

    CASE event.kind OF
?? NEWTITLE := 'data_indication', EJECT ??
?? NEWTITLE := 'pdu_header.pdu_type = nlc$sl_data_type'??

    = nlc$ta_data_event =

      message_id := event.osi_data.data;
      end_of_message := event.osi_data.end_of_message;
      IF connection^.transport_end_of_message THEN
        nlp$bm_extract_message_prefix (^pdu_header, #SIZE (pdu_header), message_id, bytes_moved);
        IF #SIZE(pdu_header) <> bytes_moved THEN
          process_error_indication (cl_connection, connection, accumulated_message_buffers);
          EXIT nlp$sl_connect_event_processor;
        IFEND;
      IFEND;

    /data_indication/
      BEGIN
        IF (NOT connection^.transport_end_of_message) OR (pdu_header.pdu_type = nlc$sl_data_type) THEN
          CASE connection^.current_state OF
          = nlc$sl_data_transfer, nlc$sl_synch_response_wait =
            user_event.kind := nlc$sl_data_event;
            user_event.data.message_id := message_id;
            IF NOT connection^.transport_end_of_message THEN
              user_event.data.qualified_data := connection^.qbit_receive_sequence;
              IF end_of_message THEN
                user_event.data.end_of_message := NOT connection^.receive_sequence_active;
                connection^.transport_end_of_message := TRUE;
              ELSE
                user_event.data.end_of_message := FALSE;
              IFEND;
              nav$network_procedures [connection^.event_processor].
                    sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
            ELSEIF connection^.receive_sequence_active THEN
              IF pdu_header.qualified_data = connection^.qbit_receive_sequence THEN
                user_event.data.qualified_data := pdu_header.qualified_data;
                IF pdu_header.more_data THEN

{ 23

                  user_event.data.end_of_message := FALSE;
                  connection^.transport_end_of_message := end_of_message;
                  nav$network_procedures [connection^.event_processor].
                        sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
                ELSE

{ 24

                  user_event.data.end_of_message := end_of_message;
                  connection^.transport_end_of_message := end_of_message;
                  connection^.receive_sequence_active := FALSE;
                  nav$network_procedures [connection^.event_processor].
                        sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
                IFEND;
              ELSE

{ ERROR 61

                process_error_indication (cl_connection, connection, accumulated_message_buffers);
                nlp$bm_release_message (message_id);
              IFEND;
            ELSE
              user_event.data.qualified_data := pdu_header.qualified_data;
              IF pdu_header.more_data THEN

{ 22

                user_event.data.end_of_message := FALSE;
                connection^.transport_end_of_message := end_of_message;
                connection^.receive_sequence_active := TRUE;
                connection^.qbit_receive_sequence := pdu_header.qualified_data;
                nav$network_procedures [connection^.event_processor].
                      sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
              ELSE

{ 21

                IF end_of_message THEN
                  user_event.data.end_of_message := TRUE;
                ELSE
                  user_event.data.end_of_message := FALSE;
                  connection^.transport_end_of_message := FALSE;
                  connection^.qbit_receive_sequence := pdu_header.qualified_data;
                IFEND;
                nav$network_procedures [connection^.event_processor].
                      sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
              IFEND;
            IFEND;
          = nlc$sl_m_r_fr_wait, nlc$sl_fwd_mark_wait, nlc$sl_rev_mark_wait, nlc$sl_synch_collision_fr,
                nlc$sl_disconnect_wait =

{ 25

            nlp$bm_release_message (message_id);
            connection^.transport_end_of_message := end_of_message;
          ELSE

{ ERROR 55,57,59

            process_error_indication (cl_connection, connection, accumulated_message_buffers);
            nlp$bm_release_message (message_id);
          CASEND;
?? OLDTITLE ??
?? NEWTITLE := 'pdu_header.pdu_type = nlc$sl_mark_type', EJECT ??

        ELSE
          nlp$bm_get_message_length (message_id, message_length);
          IF pdu_header.pdu_type = nlc$sl_mark_type THEN
            IF message_length = 0 THEN
              IF connection^.mark_count > 1 THEN
                IF (connection^.current_state = nlc$sl_m_r_fr_wait) OR
                      (connection^.current_state = nlc$sl_fwd_mark_wait) OR
                      (connection^.current_state = nlc$sl_rev_mark_wait) OR
                      (connection^.current_state = nlc$sl_synch_collision_fr) THEN

{ 47

                  connection^.mark_count := connection^.mark_count - 1;
                ELSEIF connection^.current_state <> nlc$sl_disconnect_wait THEN

{ ERROR 55,57,59,61

                  process_error_indication (cl_connection, connection, accumulated_message_buffers);
                IFEND;
              ELSEIF connection^.mark_count = 1 THEN
                IF connection^.current_state = nlc$sl_m_r_fr_wait THEN

{ 48

                  connection^.current_state := nlc$sl_synch_response_wait;
                  connection^.mark_count := 0;
                ELSEIF connection^.current_state = nlc$sl_fwd_mark_wait THEN

{ 49

                  connection^.current_state := nlc$sl_data_transfer;
                  connection^.mark_count := 0;
                ELSEIF connection^.current_state <> nlc$sl_disconnect_wait THEN
                  IF connection^.current_state = nlc$sl_rev_mark_wait THEN

{ 50

                    user_event.kind := nlc$sl_synch_confirm_event;
                    connection^.current_state := nlc$sl_data_transfer;
                    connection^.mark_count := 0;
                    nav$network_procedures [connection^.event_processor].
                          sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
                  ELSEIF connection^.current_state = nlc$sl_synch_collision_fr THEN

{ 51
{ make synch_confirm_event

                    user_event.kind := nlc$sl_synch_confirm_event;
                    connection^.mark_count := 0;
                    connection^.current_state := nlc$sl_synch_response_wait;
                    nav$network_procedures [connection^.event_processor].
                          sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
                  ELSE

{ ERROR 55,57,59,61

                    process_error_indication (cl_connection, connection, accumulated_message_buffers);
                  IFEND;
                IFEND;
              ELSE { IF connection^.mark_count = 0 THEN

{ Ignore marks received after the connection has been terminated by a clear request.

                IF connection^.current_state <> nlc$sl_disconnect_wait THEN

{ FSM ERROR

                  nap$namve_system_error (TRUE, 'Session fsm error:  Unexpected mark received.', NIL);
                IFEND;
              IFEND;
            ELSE
              process_error_indication (cl_connection, connection, accumulated_message_buffers);
              nlp$bm_release_message (message_id);
            IFEND;
?? OLDTITLE ??
?? NEWTITLE := 'pdu_header.pdu_type = nlc$sl_clear_type', EJECT ??
          ELSEIF pdu_header.pdu_type = nlc$sl_clear_type THEN
            CASE connection^.current_state OF
            = nlc$sl_call_ok_wait, nlc$sl_call_response_wait, nlc$sl_data_transfer, nlc$sl_m_r_fr_wait,
                  nlc$sl_fwd_mark_wait, nlc$sl_synch_response_wait, nlc$sl_rev_mark_wait,
                  nlc$sl_synch_collision_fr =

{ 9
{ Make clear_event and send disconnect_request.

              user_event.kind := nlc$sl_clear_event;
              user_event.clear.reason := nlc$sl_user_clear;
              user_event.clear.message_id := message_id;
              connection^.current_state := nlc$sl_closed;
              nav$network_procedures [connection^.event_processor].
                    sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
              nlp$ta_disconnect_connection (cl_connection, nlv$bm_null_message_id, status);
              nlp$cl_deactivate_layer (nlc$xns_session_layer, cl_connection);
              IF (connection^.current_state = nlc$sl_call_ok_wait) AND
                    (cl_connection^.message_receiver.active) THEN
                nlp$cl_deactivate_receiver (cl_connection);
              IFEND;
            = nlc$sl_disconnect_wait =

{ 15
{ Send disconnect_request.

              nlp$bm_release_message (message_id);
              connection^.current_state := nlc$sl_closed;
              nlp$ta_disconnect_connection (cl_connection, nlv$bm_null_message_id, status);
              nlp$cl_deactivate_layer (nlc$xns_session_layer, cl_connection);
            ELSE

{ ERROR 55

              process_error_indication (cl_connection, connection, accumulated_message_buffers);
              nlp$bm_release_message (message_id);
            CASEND;
?? OLDTITLE ??
?? NEWTITLE := 'pdu_header.pdu_type = nlc$sl_call_type', EJECT ??
          ELSEIF (pdu_header.pdu_type = nlc$sl_call_type) AND
                (connection^.current_state = nlc$sl_call_wait) THEN

{ 5

            IF cl_connection^.message_receiver.active THEN
              nlp$cl_deactivate_receiver (cl_connection);
            IFEND;
            IF pdu_header.version_no = nlc$sl_version_no THEN

{ Validate pdu_header.call.validation.

              IF message_length >= #SIZE (accounting_validation_length) THEN
                nlp$bm_extract_message_prefix (^accounting_validation_length,
                      #SIZE (accounting_validation_length), message_id, {ignore} bytes_moved);
                message_length := message_length - #SIZE (accounting_validation_length);
                IF message_length >= (accounting_validation_length.accounting +
                      accounting_validation_length.validation) THEN
                  IF accounting_validation_length.accounting > 0 THEN
                    PUSH accounting_data: [1 .. accounting_validation_length.accounting];
                    nlp$bm_extract_message_prefix (accounting_data, accounting_validation_length.accounting,
                          message_id, {ignore} bytes_moved);
                    message_length := message_length - accounting_validation_length.accounting;
                  IFEND;

                  IF accounting_validation_length.validation > 0 THEN
                    PUSH validation_data: [accounting_validation_length.validation];
                    nlp$bm_extract_message_prefix (validation_data, accounting_validation_length.validation,
                          message_id, {ignore} bytes_moved);
                    message_length := message_length - accounting_validation_length.validation;
                  IFEND;
                  IF message_length <= nlc$sl_max_call_message THEN
                    user_event.kind := nlc$sl_call_event;
                    user_event.call.source := connection^.source;
                    user_event.call.sap := connection^.sap;
                    user_event.call.message_id := message_id;
                    user_event.call.accounting_length := accounting_validation_length.accounting;
                    IF accounting_validation_length.accounting > 0 THEN
                      user_event.call.accounting_info := accounting_data;
                    ELSE
                      user_event.call.accounting_info := NIL;
                    IFEND;
                    connection^.current_state := nlc$sl_call_response_wait;

{ Deliver the event on the  SAP.

                    nlp$cl_get_sap_processor (cl_connection^.application_layer, nlc$xns_session_layer,
                          event_processor);
                    nav$network_procedures [event_processor.se].sl_event_processor^
                          (cl_connection, user_event, accumulated_message_buffers);
                  ELSE
                    process_error_indication (cl_connection, connection, accumulated_message_buffers);
                    nlp$bm_release_message (message_id);
                  IFEND;
                ELSE
                  process_error_indication (cl_connection, connection, accumulated_message_buffers);
                  nlp$bm_release_message (message_id);
                IFEND;
              ELSE
                process_error_indication (cl_connection, connection, accumulated_message_buffers);
                nlp$bm_release_message (message_id);
              IFEND;
            ELSE
              process_error_indication (cl_connection, connection, accumulated_message_buffers);
              nlp$bm_release_message (message_id);
            IFEND;
?? OLDTITLE ??
?? NEWTITLE := 'pdu_header.pdu_type = nlc$sl_call_ok_type', EJECT ??
          ELSEIF (pdu_header.pdu_type = nlc$sl_call_ok_type) AND
                (connection^.current_state = nlc$sl_call_ok_wait) THEN

{ 3

            IF cl_connection^.message_receiver.active THEN
              nlp$cl_deactivate_receiver (cl_connection);
            IFEND;
            IF pdu_header.version_no = nlc$sl_version_no THEN

{ Validate pdu_header.pdu_type of nlc$sl_call_ok_type.

              IF message_length >= #SIZE (accounting_validation_length) THEN
                nlp$bm_extract_message_prefix (^accounting_validation_length,
                      #SIZE (accounting_validation_length), message_id, {ignore} bytes_moved);
                message_length := message_length - #SIZE (accounting_validation_length);
                IF message_length >= (accounting_validation_length.accounting +
                      accounting_validation_length.validation) THEN
                  IF accounting_validation_length.accounting > 0 THEN
                    PUSH accounting_data: [1 .. accounting_validation_length.accounting];
                    nlp$bm_extract_message_prefix (accounting_data, accounting_validation_length.accounting,
                          message_id, {ignore} bytes_moved);
                    message_length := message_length - accounting_validation_length.accounting;
                  IFEND;

                  IF accounting_validation_length.validation > 0 THEN
                    PUSH validation_data: [accounting_validation_length.validation];
                    nlp$bm_extract_message_prefix (validation_data, accounting_validation_length.validation,
                          message_id, {ignore} bytes_moved);
                    message_length := message_length - accounting_validation_length.validation;
                  IFEND;

                  IF message_length <= nlc$sl_max_call_message THEN
                    connection^.current_state := nlc$sl_data_transfer;
                    user_event.kind := nlc$sl_confirm_event;
                    user_event.confirm.message_id := message_id;
                    IF accounting_validation_length.accounting > 0 THEN
                      user_event.confirm.accounting_info := accounting_data;
                    ELSE
                      user_event.confirm.accounting_info := NIL;
                    IFEND;
                    user_event.confirm.accounting_length := accounting_validation_length.accounting;
                    connection^.current_state := nlc$sl_data_transfer;
                    nav$network_procedures [connection^.event_processor].
                          sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
                  ELSE
                    process_error_indication (cl_connection, connection, accumulated_message_buffers);
                    nlp$bm_release_message (message_id);
                  IFEND;
                ELSE
                  process_error_indication (cl_connection, connection, accumulated_message_buffers);
                  nlp$bm_release_message (message_id);
                IFEND;
              ELSE
                process_error_indication (cl_connection, connection, accumulated_message_buffers);
                nlp$bm_release_message (message_id);
              IFEND;
            ELSE
              process_error_indication (cl_connection, connection, accumulated_message_buffers);
              nlp$bm_release_message (message_id);
            IFEND;
          ELSEIF (pdu_header.pdu_type = nlc$sl_call_ok_type) AND
                (connection^.current_state = nlc$sl_disconnect_wait) THEN
            nlp$bm_release_message (message_id);
          ELSE
            process_error_indication (cl_connection, connection, accumulated_message_buffers);
            nlp$bm_release_message (message_id);
          IFEND;
        IFEND;
      END /data_indication/;
?? OLDTITLE ??
?? OLDTITLE ??
?? NEWTITLE := 'clear_to_send_event', EJECT ??

    = nlc$ta_clear_to_send_event =
      CASE connection^.current_state OF
      = nlc$sl_data_transfer, nlc$sl_fwd_mark_wait, nlc$sl_rev_mark_wait =
        user_event.kind := nlc$sl_clear_to_send_event;
        nav$network_procedures [connection^.event_processor].
              sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
      = nlc$sl_m_r_fr_wait, nlc$sl_synch_response_wait, nlc$sl_synch_collision_fr =
        ;

{ 21
{ Do nothing.

      ELSE

{ Is it possible for this event to occur.

      CASEND;
?? OLDTITLE ??
?? NEWTITLE := 'expedited_data_indication', EJECT ??

    = nlc$ta_expedited_data_event =

      message_id := event.osi_expedited_data.data;
      nlp$bm_extract_message_prefix (^pdu_header, #SIZE (pdu_header), message_id, bytes_moved);
      IF #SIZE(pdu_header) <> bytes_moved THEN
        process_error_indication (cl_connection, connection, accumulated_message_buffers);
        EXIT nlp$sl_connect_event_processor;
      IFEND;


    /expedited_data_indication/
      BEGIN
        nlp$bm_get_message_length (message_id, message_length);
        IF message_length > nlc$sl_max_interrupt_message THEN
          nlp$bm_release_message (message_id);
          process_error_indication (cl_connection, connection, accumulated_message_buffers);
          EXIT /expedited_data_indication/;
        ELSEIF message_length < nlc$sl_min_interrupt_message THEN
          nlp$bm_release_message (message_id);
          process_error_indication (cl_connection, connection, accumulated_message_buffers);
          EXIT /expedited_data_indication/;
        IFEND;
?? NEWTITLE := 'pdu_header.pdu_type = nlc$sl_interrupt_type', EJECT ??
        IF pdu_header.pdu_type = nlc$sl_interrupt_type THEN
          CASE connection^.current_state OF
          = nlc$sl_data_transfer, nlc$sl_m_r_fr_wait, nlc$sl_fwd_mark_wait, nlc$sl_synch_response_wait,
                nlc$sl_rev_mark_wait, nlc$sl_synch_collision_fr =

{ 28
{ Make interrupt_event.

            user_event.kind := nlc$sl_interrupt_event;
            user_event.interrupt.message_id := message_id;
            nav$network_procedures [connection^.event_processor].
                  sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
          = nlc$sl_disconnect_wait =
            nlp$bm_release_message (message_id);
          ELSE

{ ERROR 56,58,60

            process_error_indication (cl_connection, connection, accumulated_message_buffers);
            nlp$bm_release_message (message_id);
          CASEND;
?? OLDTITLE ??
?? NEWTITLE := 'pdu_header.pdu_type = nlc$sl_synch_request_type'??
?? NEWTITLE := 'pdu_header.discard_option = nlc$sl_discard_send', EJECT ??
        ELSEIF pdu_header.pdu_type = nlc$sl_synch_request_type THEN
          IF pdu_header.discard_option = nlc$sl_discard_send THEN
            CASE connection^.current_state OF
            = nlc$sl_data_transfer, nlc$sl_m_r_fr_wait, nlc$sl_fwd_mark_wait, nlc$sl_rev_mark_wait,
                  nlc$sl_synch_collision_fr, nlc$sl_synch_response_wait =

{ 41,42,43

              IF connection^.current_state = nlc$sl_data_transfer THEN
                connection^.current_state := nlc$sl_fwd_mark_wait;
              ELSEIF connection^.current_state = nlc$sl_synch_response_wait THEN
                connection^.current_state := nlc$sl_m_r_fr_wait;
              IFEND;
              connection^.receive_sequence_active := FALSE;
              connection^.mark_count := connection^.mark_count + 1;

{ Make synch_indication_event.

              user_event.kind := nlc$sl_synch_event;
              user_event.synch.discard_option := nlc$sl_discard_send;
              user_event.synch.message_id := message_id;
              nav$network_procedures [connection^.event_processor].
                    sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
            = nlc$sl_disconnect_wait =
              nlp$bm_release_message (message_id);
            ELSE

{ ERROR 56,58,60

              nlp$bm_release_message (message_id);
              process_error_indication (cl_connection, connection, accumulated_message_buffers);
            CASEND;
?? OLDTITLE ??
?? NEWTITLE := 'pdu_header.discard_option = nlc$sl_discard_send_receive', EJECT ??
          ELSEIF pdu_header.discard_option = nlc$sl_discard_send_receive THEN
            CASE connection^.current_state OF
            = nlc$sl_data_transfer, nlc$sl_fwd_mark_wait, nlc$sl_rev_mark_wait =

{ 38,39,40

              IF connection^.current_state = nlc$sl_rev_mark_wait THEN
                connection^.current_state := nlc$sl_synch_collision_fr;
              ELSE
                connection^.current_state := nlc$sl_m_r_fr_wait;
              IFEND;
              connection^.send_sequence_active := FALSE;
              connection^.receive_sequence_active := FALSE;
              connection^.mark_count := connection^.mark_count + 1;

{ Make synch_indication_event.

              user_event.kind := nlc$sl_synch_event;
              user_event.synch.discard_option := nlc$sl_discard_send_receive;
              user_event.synch.message_id := message_id;
              nav$network_procedures [connection^.event_processor].
                    sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
            = nlc$sl_disconnect_wait =
              nlp$bm_release_message (message_id);
            ELSE

{ 56,58,60,64

              process_error_indication (cl_connection, connection, accumulated_message_buffers);
              nlp$bm_release_message (message_id);
            CASEND;
?? OLDTITLE ??
?? NEWTITLE := 'pdu_header.discard_option = nlc$sl_discard_receive', EJECT ??
          ELSEIF pdu_header.discard_option = nlc$sl_discard_receive THEN
            CASE connection^.current_state OF
            = nlc$sl_data_transfer, nlc$sl_fwd_mark_wait, nlc$sl_rev_mark_wait =
              IF connection^.current_state = nlc$sl_data_transfer THEN

{ 44

                connection^.current_state := nlc$sl_synch_response_wait;
              ELSEIF connection^.current_state = nlc$sl_fwd_mark_wait THEN

{ 45

                connection^.current_state := nlc$sl_m_r_fr_wait;
              ELSEIF connection^.current_state = nlc$sl_rev_mark_wait THEN

{ 46

                connection^.current_state := nlc$sl_synch_collision_fr;
              IFEND;
              connection^.send_sequence_active := FALSE;

{ Make synch_indication_event.

              user_event.kind := nlc$sl_synch_event;
              user_event.synch.discard_option := nlc$sl_discard_receive;
              user_event.synch.message_id := message_id;
              nav$network_procedures [connection^.event_processor].
                    sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
            = nlc$sl_disconnect_wait =
              nlp$bm_release_message (message_id);
            ELSE

{ 56,58,60,64

              nlp$bm_release_message (message_id);
              process_error_indication (cl_connection, connection, accumulated_message_buffers);
            CASEND;
          ELSE { Invalid discard option received.

{ FSM ERROR

            nap$namve_system_error (TRUE, 'Session fsm error:  Invalid discard option received.', NIL);
            nlp$bm_release_message (message_id);
          IFEND;
        ELSE

{ 56,58,60,63,64,66

          nlp$bm_release_message (message_id);
          process_error_indication (cl_connection, connection, accumulated_message_buffers);
        IFEND;
      END /expedited_data_indication/;
?? OLDTITLE ??
?? OLDTITLE ??
?? OLDTITLE ??
?? NEWTITLE := 'accept_event_indication', EJECT ??

    = nlc$ta_connect_confirm_event =

      nlp$bm_get_message_length (event.osi_connect_confirm.data, message_length);
      IF message_length = 0 THEN
        IF connection^.current_state = nlc$sl_connect_confirm_wait THEN
          connection^.current_state := nlc$sl_call_ok_wait;
          nlp$ta_send_data (cl_connection, connection^.call_pdu_message_id, TRUE, status);
          IF status.normal THEN
            connection^.call_pdu_message_id := nlv$bm_nil_message_id;
          ELSE
            process_error_indication (cl_connection, connection, accumulated_message_buffers);
          IFEND;
        ELSE
          process_error_indication (cl_connection, connection, accumulated_message_buffers);
        IFEND;
      ELSE { IF message_length > 0 THEN
        message_id := event.osi_connect_confirm.data;
        nlp$bm_release_message (message_id);
      IFEND;
?? OLDTITLE ??
?? NEWTITLE := 'disconnect_indication', EJECT ??

    = nlc$ta_disconnect_event =

    /disconnect_indication/
      BEGIN
        IF ((connection^.current_state = nlc$sl_call_wait) OR
              (connection^.current_state = nlc$sl_connect_confirm_wait)) AND
              (cl_connection^.message_receiver.active) THEN

{ Deactivate the receiver in the connection establishment phase only.  During connection
{ establishment is the only time nlm$sl_internal_interface should have a receiver active.

          nlp$cl_deactivate_receiver (cl_connection);
        IFEND;

        message_id := event.osi_disconnect.data;
        nlp$bm_get_message_length (message_id, message_length);

        IF message_length = 0 THEN
?? NEWTITLE := 'current state of:'??
?? NEWTITLE := 'nlc$sl_call_wait or nlc$sl_disconnect_wait', EJECT ??
          CASE connection^.current_state OF
          = nlc$sl_call_wait, nlc$sl_disconnect_wait =

{ 8,14

            delete_connection (connection, cl_connection);
?? OLDTITLE ??
?? NEWTITLE := 'nlc$sl_call_ok_wait, nlc$sl_call_response_wait, nlc$sl_data_transfer,', EJECT ??
?? NEWTITLE := 'nlc$sl_m_r_fr_wait, nlc$sl_fwd_mark_wait, nlc$sl_synch_response_wait,'??
?? NEWTITLE := 'nlc$sl_rev_mark_wait, nlc$sl_synch_collision_fr, nlc$sl_connect_confirm_wait'??

          = nlc$sl_call_ok_wait, nlc$sl_call_response_wait, nlc$sl_data_transfer, nlc$sl_m_r_fr_wait,
                nlc$sl_fwd_mark_wait, nlc$sl_synch_response_wait, nlc$sl_rev_mark_wait,
                nlc$sl_synch_collision_fr, nlc$sl_connect_confirm_wait =

{ 7, 13

            user_event.kind := nlc$sl_clear_event;
            user_event.clear.reason := nlc$sl_layer_clear;
            user_event.clear.message_id := message_id;
            connection^.current_state := nlc$sl_closed;
            nav$network_procedures [connection^.event_processor].
                  sl_event_processor^ (cl_connection, user_event, accumulated_message_buffers);
            delete_connection (connection, cl_connection);

          = nlc$sl_closed =
            ;
          ELSE
            nap$namve_system_error (TRUE, 'Session fsm error:  Unexpected disconnect event received.', NIL);
          CASEND;
        ELSE
          nlp$bm_release_message (message_id);
        IFEND;
      END /disconnect_indication/;
?? OLDTITLE ??
?? OLDTITLE ??
?? OLDTITLE ??
?? OLDTITLE ??
?? EJECT ??
    ELSE
      nap$namve_system_error (TRUE, 'Invalid transport event received by Session. ', NIL);
    CASEND;
  PROCEND nlp$sl_connect_event_processor;
?? OLDTITLE ??
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_initialize', EJECT ??

  PROCEDURE [XDCL] nlp$sl_initialize (sap_processor: nat$network_procedure;
        connection_processor: nat$network_procedure;
        application_layer: nlt$cl_application_layer);

*copy nlh$sl_initialize

    VAR
      cl_sap_processor: nlt$cl_event_processor,
      cl_connection_processor: nlt$cl_event_processor;

    cl_sap_processor.layer := nlc$xns_session_layer;
    cl_sap_processor.se := sap_processor;
    cl_connection_processor.layer := nlc$xns_session_layer;
    cl_connection_processor.se := connection_processor;
    nlp$cl_initialize_template (application_layer, nlc$xns_session_layer, #SIZE
          (nlt$sl_connection_descriptor), #size(nlt$sl_pdu_header), cl_sap_processor, nac$nil,
          cl_connection_processor, nlc$sl_clear_request_timer);
    nlp$ta_initialize (application_layer, nlc$osi_sl_sap_event_processor,
           nlc$osi_sl_conn_event_processor);
  PROCEND nlp$sl_initialize;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_open_sap', EJECT ??
*copy nlh$sl_open_sap

  PROCEDURE [XDCL] nlp$sl_open_sap
    (    sap_processor: nat$network_procedure;
         connection_processor: nat$network_procedure;
         osi_application_layer: nlt$cl_application_layer;
         accept_connect_events: boolean;
         maximum_active_connections: nlt$sl_max_active_connections;
     VAR status: ost$status);

    VAR
      cl_sap_processor: nlt$cl_event_processor,
      cl_connection_processor: nlt$cl_event_processor,
      local_status: ost$status;

    IF ((maximum_active_connections > 0) AND (maximum_active_connections <=
          UPPERVALUE (nlt$sl_max_active_connections))) THEN
      cl_sap_processor.layer := nlc$xns_session_layer;
      cl_sap_processor.se := sap_processor;
      cl_connection_processor.layer := nlc$xns_session_layer;
      cl_connection_processor.se := connection_processor;
      nlp$cl_initialize_template (osi_application_layer, nlc$xns_session_layer,
            #SIZE (nlt$sl_connection_descriptor), #SIZE (nlt$sl_pdu_header), cl_sap_processor, nac$nil,
            cl_connection_processor, nlc$sl_clear_request_timer);
      nlp$ta_open_sap (osi_application_layer, nlc$osi_sl_sap_event_processor, nlc$osi_sl_conn_event_processor,
            status);
    ELSEIF (maximum_active_connections = 0) THEN
      osp$set_status_condition ( nae$max_active_connections_0,  status);
    ELSE
      osp$set_status_condition ( nae$max_active_conn_exceeded,  status);
    IFEND;
  PROCEND nlp$sl_open_sap;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_close_sap', EJECT ??
*copy nlh$sl_close_sap

  PROCEDURE [XDCL] nlp$sl_close_sap
    (    sap: nat$generic_sap_identifier;
     VAR status: ost$status);

    VAR
      local_status: ost$status;

    nlp$ta_close_sap (sap.osi_sap_identifier, status);
  PROCEND nlp$sl_close_sap;

?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_call_request', EJECT ??
*copy nlh$sl_call_request

  PROCEDURE [XDCL] nlp$sl_call_request
    (    cl_connection: ^nlt$cl_connection;
         sap: nat$generic_sap_identifier;
         destination: nat$network_address;
         application_name: nat$application_name;
         data: nat$data_fragment;
         sap_priority: nat$network_message_priority;
     VAR status: ost$status);

    VAR
      accounting_length: nlc$sl_min_accounting_length .. nlc$sl_max_accounting_length,
      actual_destination_address: ^SEQ ( * ),
      application_name_ptr: ^STRING ( * ),
      application_name_length: nlt$sl_application_name_length,
      application_name_length_ptr: ^nlt$sl_application_name_length,
      connection: ^nlt$sl_connection_descriptor,
      data_fragments: array [1 .. 6] of nat$data_fragment,
      destination_address: ^SEQ ( * ),
      event_processor: nlt$cl_event_processor,
      family_name_ptr: ^STRING ( * ),
      family_name_length: nlt$sl_family_name_length,
      family_name_length_ptr: ^nlt$sl_family_name_length,
      i: integer,
      job_attribute_results: ^array [1 .. *] of jmt$job_attribute_result,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      pdu_header: nlt$sl_pdu_header,
      user_name_ptr: ^STRING ( * ),
      user_name_length: nlt$sl_user_name_length,
      user_name_length_ptr: ^nlt$sl_user_name_length,
      validation_data_length: nlc$sl_min_validation_length .. nlc$sl_max_validation_length,
      validation_data_ptr: ^SEQ ( * ),
      validation_version_ptr: ^nlt$sl_validation_version;

    IF (data.length <= nlc$sl_max_call_message) THEN
      PUSH job_attribute_results: [1 .. 2];
      job_attribute_results^[1].key := jmc$login_user;
      job_attribute_results^[2].key := jmc$login_family;

      jmp$get_job_attributes(job_attribute_results, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      user_name_length := clp$trimmed_string_size (job_attribute_results^[1].login_user);
      family_name_length := clp$trimmed_string_size (job_attribute_results^[2].login_family);
      application_name_length := clp$trimmed_string_size (application_name);

      validation_data_length := #SIZE (nlt$sl_validation_version) + #SIZE (nlt$sl_user_name_length) +
            #SIZE (nlt$sl_family_name_length) + #SIZE (nlt$sl_application_name_length) + user_name_length +
            family_name_length + application_name_length;

      PUSH validation_data_ptr: [[REP validation_data_length OF cell]];
      RESET validation_data_ptr;

{  Build the validation record

      NEXT validation_version_ptr IN validation_data_ptr;
      validation_version_ptr^ := nlc$sl_validation_version;
      NEXT user_name_length_ptr IN validation_data_ptr;
      user_name_length_ptr^ := user_name_length;
      NEXT family_name_length_ptr IN validation_data_ptr;
      family_name_length_ptr^ := family_name_length;
      NEXT application_name_length_ptr IN validation_data_ptr;
      application_name_length_ptr^ := application_name_length;
      NEXT user_name_ptr: [ user_name_length ] IN validation_data_ptr;
      user_name_ptr^ := job_attribute_results^[1].login_user;
      NEXT family_name_ptr: [ family_name_length ] IN validation_data_ptr;
      family_name_ptr^ := job_attribute_results^[2].login_family;
      NEXT application_name_ptr: [ application_name_length ] IN validation_data_ptr;
      application_name_ptr^ := application_name;

      pdu_header.version_no := nlc$sl_version_no;
      pdu_header.pdu_type := nlc$sl_call_type;
      accounting_length := 0;
      data_fragments [1].address := ^pdu_header;
      data_fragments [1].length := #SIZE (pdu_header);
      data_fragments [2].address := ^accounting_length;
      data_fragments [2].length := #SIZE (accounting_length);
      data_fragments [3].address := ^validation_data_length;
      data_fragments [3].length := #SIZE (validation_data_length);
      data_fragments [4].address := NIL; {^accounting_data;}
      data_fragments [4].length := accounting_length;
      data_fragments [5].address := validation_data_ptr;
      data_fragments [5].length := validation_data_length;
      data_fragments [6] := data;
      nlp$bm_create_message (data_fragments, message_id, status);
      IF status.normal THEN
        nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);
        connection^ := nlv$sl_initialized_connection;
        nlp$cancel_timer (connection^.clear_timer);
        connection^.current_state := nlc$sl_connect_confirm_wait;
        connection^.call_pdu_message_id := message_id;
        nlp$cl_get_connection_processor (cl_connection^.application_layer, nlc$xns_session_layer,
              event_processor);
        connection^.event_processor := event_processor.se;
        destination_address := ^destination.osi_transport_address.network_address;
        RESET destination_address;
        NEXT actual_destination_address: [[REP destination.osi_transport_address.network_address_length OF
              cell]] IN destination_address;

        nlp$ta_request_connection (cl_connection, sap.osi_sap_identifier, {checksum =} FALSE,
              nlv$bm_null_message_id, destination.osi_transport_address.
              transport_sap_selector (1, destination.osi_transport_address.transport_sap_selector_length),
              actual_destination_address^, {cdna_destination_address =} TRUE, {expedited_data =} TRUE,
              sap_priority, nac$ta_preferred_class_4_clns, nac$ta_no_alternate_protocol,
              {quality_of_service =} NIL, status);
        IF status.normal THEN
          nlp$cl_activate_layer (nlc$xns_session_layer, cl_connection);
          nlp$cl_activate_receiver (cl_connection);
        ELSE
          nlp$bm_release_message (connection^.call_pdu_message_id);
        IFEND;
      IFEND;
    ELSE
      osp$set_status_condition ( nae$max_data_length_exceeded,  status);
      osp$append_status_integer (osc$status_parameter_delimiter, nlc$sl_max_call_message, 10, TRUE, status);
    IFEND;
  PROCEND nlp$sl_call_request;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_call_response', EJECT ??
*copy nlh$sl_call_response

  PROCEDURE [XDCL] nlp$sl_call_response
    (    cl_connection: ^nlt$cl_connection;
         data: nat$data_fragments;
     VAR status: ost$status);

    VAR
      accounting_length: nlc$sl_min_accounting_length .. nlc$sl_max_accounting_length,
      connection: ^nlt$sl_connection_descriptor,
      data_fragments: ^array [1 .. * ] of nat$data_fragment,
      data_length: nat$data_length,
      i,
      j: integer,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      pdu_header: nlt$sl_pdu_header,
      validation_length: nlc$sl_min_validation_length .. nlc$sl_max_validation_length;

    nlp$al_get_data_length (data, data_length);
    IF (data_length <= nlc$sl_max_call_message) THEN
      pdu_header.version_no := nlc$sl_version_no;
      pdu_header.pdu_type := nlc$sl_call_ok_type;
      accounting_length := 0;
      validation_length := 0;
      PUSH data_fragments: [1 .. (5 + UPPERBOUND (data))];
      data_fragments^ [1].address := ^pdu_header;
      data_fragments^ [1].length := #SIZE (pdu_header);
      data_fragments^ [2].address := ^accounting_length;
      data_fragments^ [2].length := #SIZE (accounting_length);
      data_fragments^ [3].address := ^validation_length;
      data_fragments^ [3].length := #SIZE (validation_length);
      data_fragments^ [4].address := NIL; {^accounting_data;}
      data_fragments^ [4].length := accounting_length;
      data_fragments^ [5].address := NIL; {^validation_data;}
      data_fragments^ [5].length := validation_length;
      j := 1;
      FOR i := 6 TO UPPERBOUND (data_fragments^) DO
        data_fragments^ [i] := data [j];
        j := j + 1;
      FOREND;
      nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);
      IF (layer_active) AND (connection^.current_state = nlc$sl_call_response_wait) THEN
        nlp$ta_send_data_fragments (cl_connection, data_fragments^, TRUE, status);
        IF status.normal THEN
          connection^.current_state := nlc$sl_data_transfer;
        IFEND;
      ELSE
        osp$set_status_condition ( nae$connection_not_proposed,  status);
      IFEND;
    ELSE
      osp$set_status_condition ( nae$max_data_length_exceeded,  status);
      osp$append_status_integer (osc$status_parameter_delimiter, nlc$sl_max_call_message, 10, FALSE, status);
    IFEND;
  PROCEND nlp$sl_call_response;

?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_data_request', EJECT ??
*copy nlh$sl_data_request

  PROCEDURE [XDCL] nlp$sl_data_request
    (    cl_connection: ^nlt$cl_connection;
         qualified_data: boolean,
         end_of_message: boolean,
         data: nat$data_fragments;
     VAR status: ost$status);

    VAR
      connection: ^nlt$sl_connection_descriptor,
      layer_active: boolean,
      i: integer,
      message: ^array [1 .. * ] of nat$data_fragment,
      message_id: nlt$bm_message_id,
      pdu_header: nlt$sl_pdu_header;

    nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);
    IF layer_active THEN
?? NEWTITLE := 'current state of:'??
?? NEWTITLE := 'nlc$sl_data_transfer, nlc$sl_fwd_mark_wait, or nlc$sl_rev_mark_wait', EJECT ??
      CASE connection^.current_state OF
      = nlc$sl_data_transfer, nlc$sl_fwd_mark_wait, nlc$sl_rev_mark_wait =
        IF (connection^.send_sequence_active) AND (connection^.qbit_send_sequence <> qualified_data) THEN
          osp$set_status_condition ( nae$inconsistent_qualified_data,  status);
        ELSE
          PUSH message: [1 .. (UPPERBOUND (data) + 1)];
          pdu_header.qualified_data := qualified_data;
          pdu_header.more_data := NOT end_of_message;
          pdu_header.pdu_type := nlc$sl_data_type;
          message^ [1].address := ^pdu_header;
          message^ [1].length := #SIZE (pdu_header);
          FOR i := 2 TO UPPERBOUND (message^) DO
            message^ [i] := data [i - 1];
          FOREND;
          nlp$ta_send_data_fragments (cl_connection, message^, TRUE, status);
          IF status.normal THEN
            IF connection^.send_sequence_active THEN

{ 19, 20

              connection^.send_sequence_active := NOT end_of_message;
            ELSE
              IF NOT end_of_message THEN

{ 18

                connection^.send_sequence_active := TRUE;
                connection^.qbit_send_sequence := qualified_data;
              ELSE

{ 17

              IFEND;
            IFEND;
          IFEND;
        IFEND;
?? OLDTITLE ??
?? NEWTITLE := 'nlc$sl_m_r_fr_wait, nlc$sl_synch_response_wait, or nlc$sl_synch_collision_fr', EJECT ??

      = nlc$sl_m_r_fr_wait, nlc$sl_synch_response_wait, nlc$sl_synch_collision_fr =
        osp$set_status_condition ( nae$se_synchronize_in_progress,  status);
      ELSE
        osp$set_status_abnormal ('NA', nae$invalid_request, session_layer, status);
      CASEND;
    ELSE
      osp$set_status_condition ( nae$connection_not_open,  status);
    IFEND;
  PROCEND nlp$sl_data_request;
?? OLDTITLE ??
?? OLDTITLE ??
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_clear_request', EJECT ??
*copy nlh$sl_clear_request

  PROCEDURE [XDCL] nlp$sl_clear_request
    (    cl_connection: ^nlt$cl_connection;
         data: nat$data_fragments;
     VAR status: ost$status);

    VAR
      capacity: nat$data_length,
      connection: ^nlt$sl_connection_descriptor,
      data_length: nat$data_length,
      i: integer,
      layer_active: boolean,
      message: ^array [1 .. * ] of nat$data_fragment,
      message_id: nlt$bm_message_id,
      old_state: nlt$sl_machine_state,
      pdu_header: nlt$sl_pdu_header;

    nlp$al_get_data_length (data, data_length);
    IF data_length <= nlc$sl_max_clear_message THEN
      pdu_header.pdu_type := nlc$sl_clear_type;
      PUSH message: [1 .. (UPPERBOUND (data) + 1)];
      message^ [1].address := ^pdu_header;
      message^ [1].length := #SIZE (pdu_header);
      FOR i := 2 TO UPPERBOUND (message^) DO
        message^ [i] := data [i - 1];
      FOREND;
      nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
?? NEWTITLE := 'current state of:'??
?? NEWTITLE := 'nlc$sl_call_ok_wait, nlc$sl_call_response_wait, nlc$sl_data_transfer,'??
?? NEWTITLE := 'nlc$sl_m_r_fr_wait, nlc$sl_fwd_mark_wait, nlc$sl_synch_response_wait,'??
?? NEWTITLE := 'nlc$sl_rev_mark_wait, or nlc$sl_synch_collision_fr', EJECT ??
        CASE connection^.current_state OF
        = nlc$sl_call_ok_wait, nlc$sl_call_response_wait, nlc$sl_data_transfer, nlc$sl_m_r_fr_wait,
              nlc$sl_fwd_mark_wait, nlc$sl_synch_response_wait, nlc$sl_rev_mark_wait,
              nlc$sl_synch_collision_fr =
          nlp$osi_get_outbound_capacity (cl_connection, capacity);
          IF (capacity >= (data_length + #SIZE (pdu_header))) THEN
            old_state := connection^.current_state;
            connection^.current_state := nlc$sl_disconnect_wait;
            nlp$ta_send_data_fragments (cl_connection, message^, TRUE, status);
            IF NOT status.normal THEN
              connection^.current_state := old_state;
            ELSE

{ Start the timer task.

              nlp$select_timer (nlc$sl_max_clear_wait, 0, connection^.clear_timer);
              IF (connection^.current_state = nlc$sl_call_ok_wait) AND
                    (cl_connection^.message_receiver.active) THEN
                nlp$cl_deactivate_receiver (cl_connection);
              IFEND;
            IFEND;
          ELSE

{  No network capacity to send clear, so disconnect.

            nlp$ta_disconnect_connection (cl_connection, nlv$bm_null_message_id, status);
            delete_connection (connection, cl_connection);
          IFEND;
?? OLDTITLE ??
?? OLDTITLE ??
?? OLDTITLE ??
?? NEWTITLE := 'nlc$sl_connect_confirm_wait', EJECT ??

        = nlc$sl_connect_confirm_wait =
          IF cl_connection^.message_receiver.active THEN
            nlp$cl_deactivate_receiver (cl_connection);
          IFEND;
          nlp$ta_disconnect_connection (cl_connection, nlv$bm_null_message_id, status);
          delete_connection (connection, cl_connection);
?? OLDTITLE ??
?? NEWTITLE := 'nlc$sl_closed', EJECT ??

        = nlc$sl_closed =
          delete_connection (connection, cl_connection);
        ELSE
          osp$set_status_abnormal ('NA', nae$protocol_error, session_layer, status);
        CASEND;
      ELSE
        osp$set_status_condition ( nae$connection_not_open,  status);
      IFEND;
    ELSE
      osp$set_status_abnormal ('NA', nae$max_data_length_exceeded, session_layer, status);
      osp$append_status_integer (osc$status_parameter_delimiter, nlc$sl_max_clear_message, 10, FALSE, status);
    IFEND;
  PROCEND nlp$sl_clear_request;
?? OLDTITLE ??
?? OLDTITLE ??
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_synch_request', EJECT ??
*copy nlh$sl_synch_request

  PROCEDURE [XDCL] nlp$sl_synch_request
    (    cl_connection: ^nlt$cl_connection;
         discard_option: nlt$sl_discard_options,
         data: nlt$bm_message_id;
     VAR status: ost$status);

    VAR
      connection: ^nlt$sl_connection_descriptor,
      data_fragments: array [1 .. 1] of nat$data_fragment,
      data_length: integer,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      pdu_header: nlt$sl_pdu_header,
      save_current_state: nlt$sl_machine_state,
      save_receive_sequence_active: boolean,
      save_send_sequence_active: boolean,
      synchronize: ^nlt$ta_aggregate_message;

    message_id := data;
    nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);
    IF layer_active THEN
?? NEWTITLE := 'pdu_header.discard_option = nlc$sl_discard_send', EJECT ??
      IF discard_option = nlc$sl_discard_send THEN
        CASE connection^.current_state OF
        = nlc$sl_data_transfer, nlc$sl_m_r_fr_wait, nlc$sl_fwd_mark_wait, nlc$sl_synch_response_wait,
              nlc$sl_rev_mark_wait, nlc$sl_synch_collision_fr =

{ 29

          save_send_sequence_active := connection^.send_sequence_active;
          connection^.send_sequence_active := FALSE;
        ELSE
          nlp$bm_release_message (message_id);
          osp$set_status_abnormal ('NA', nae$protocol_error, session_layer, status);
        CASEND;
?? OLDTITLE ??
?? NEWTITLE := 'pdu_header.discard_option = nlc$sl_discard_send_receive', EJECT ??

      ELSEIF discard_option = nlc$sl_discard_send_receive THEN
        IF (connection^.current_state = nlc$sl_data_transfer) OR
              (connection^.current_state = nlc$sl_fwd_mark_wait) THEN

{ 30,34

          save_current_state := connection^.current_state;
          save_send_sequence_active := connection^.send_sequence_active;
          save_receive_sequence_active := connection^.receive_sequence_active;
          connection^.current_state := nlc$sl_rev_mark_wait;
          connection^.send_sequence_active := FALSE;
          connection^.receive_sequence_active := FALSE;
          connection^.mark_count := connection^.mark_count + 1;
        ELSEIF (connection^.current_state = nlc$sl_m_r_fr_wait) OR
              (connection^.current_state = nlc$sl_synch_response_wait) THEN

{ 32,36

          save_current_state := connection^.current_state;
          save_send_sequence_active := connection^.send_sequence_active;
          save_receive_sequence_active := connection^.receive_sequence_active;
          connection^.current_state := nlc$sl_synch_collision_fr;
          connection^.send_sequence_active := FALSE;
          connection^.receive_sequence_active := FALSE;
          connection^.mark_count := connection^.mark_count + 1;
        ELSE
          nlp$bm_release_message (message_id);
          osp$set_status_condition ( nae$se_synch_confirm_pending,  status);
        IFEND;
?? OLDTITLE ??
?? NEWTITLE := 'pdu_header.discard_option = nlc$sl_discard_receive', EJECT ??

      ELSE {discard_option = nlc$sl_discard_receive THEN
        IF (connection^.current_state = nlc$sl_data_transfer) OR
              (connection^.current_state = nlc$sl_fwd_mark_wait) THEN

{ 31,35

          save_current_state := connection^.current_state;
          save_receive_sequence_active := connection^.receive_sequence_active;
          connection^.current_state := nlc$sl_rev_mark_wait;
          connection^.receive_sequence_active := FALSE;
          connection^.mark_count := connection^.mark_count + 1;
        ELSEIF (connection^.current_state = nlc$sl_m_r_fr_wait) OR
              (connection^.current_state = nlc$sl_synch_response_wait) THEN

{ 33,37

          save_current_state := connection^.current_state;
          save_receive_sequence_active := connection^.receive_sequence_active;
          connection^.current_state := nlc$sl_synch_collision_fr;
          connection^.receive_sequence_active := FALSE;
          connection^.mark_count := connection^.mark_count + 1;
        ELSE
          nlp$bm_release_message (message_id);
          osp$set_status_condition ( nae$se_synch_confirm_pending,  status);
        IFEND;
      IFEND;
?? OLDTITLE ??
?? EJECT ??

      IF status.normal THEN

{ Interrupt_request.

        nlp$bm_get_message_length (data, data_length);
        IF (data_length <= nlc$sl_max_interrupt_message) AND
              (data_length >= nlc$sl_min_interrupt_message) THEN
          pdu_header.discard_option := discard_option;
          pdu_header.pdu_type := nlc$sl_synch_request_type;
          nlp$bm_add_message_prefix (^pdu_header, #SIZE (pdu_header), message_id);
          IF discard_option = nlc$sl_discard_receive THEN
            nlp$ta_send_expedited_data (cl_connection, message_id, status);
            IF NOT status.normal AND ((status.condition = nae$max_expedited_exceeded) OR
                  (status.condition = nae$connection_full)) THEN
              osp$set_status_abnormal (nac$status_id, nae$supervisory_traffic_limit, 'SYNCH REQUEST', status);
            IFEND;

{ ELSEIF (discard_option = nlc$sl_discard_send) OR
{    (discard_option = nlc$sl_discard_send_receive) THEN

          ELSE
            pdu_header.pdu_type := nlc$sl_mark_type;
            data_fragments [1].address := ^pdu_header;
            data_fragments [1].length := #SIZE (pdu_header);
            PUSH synchronize: [1 .. 2];
            synchronize^ [1].kind := nlc$ta_expedited_data_event;
            synchronize^ [1].expedited_data := message_id;
            synchronize^ [2].kind := nlc$ta_data_event;
            synchronize^ [2].end_of_message := TRUE;
            nlp$bm_create_message (data_fragments, synchronize^ [2].data, status);
            nlp$ta_send_aggregate_message (cl_connection, synchronize^, status);
            IF NOT status.normal AND ((status.condition = nae$max_expedited_exceeded) OR
                  (status.condition = nae$connection_full) OR (status.condition =
                  nae$ta_expedited_request_limit)) THEN
              osp$set_status_abnormal (nac$status_id, nae$supervisory_traffic_limit, 'SYNCH REQUEST', status);
            IFEND;
          IFEND;
        ELSE
          nlp$bm_release_message (message_id);
          osp$set_status_condition ( nae$se_synchronize_length_error,  status);
          osp$append_status_integer (osc$status_parameter_delimiter, nlc$sl_max_interrupt_message, 10, FALSE,
                status);
          osp$append_status_integer (osc$status_parameter_delimiter, nlc$sl_min_interrupt_message, 10, FALSE,
                status);
        IFEND;
        IF NOT status.normal THEN
          IF discard_option = nlc$sl_discard_send THEN
            connection^.send_sequence_active := save_send_sequence_active;
          ELSE
            connection^.mark_count := connection^.mark_count - 1;
            connection^.current_state := save_current_state;
            connection^.send_sequence_active := save_send_sequence_active;
            IF discard_option = nlc$sl_discard_send_receive THEN
              connection^.receive_sequence_active := save_receive_sequence_active;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    ELSE
      nlp$bm_release_message (message_id);
      osp$set_status_condition ( nae$connection_not_open,  status);
    IFEND;
  PROCEND nlp$sl_synch_request;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_synch_response', EJECT ??
*copy nlh$sl_synch_response

  PROCEDURE [XDCL] nlp$sl_synch_response
    (    cl_connection: ^nlt$cl_connection;
     VAR status: ost$status);

    VAR
      connection: ^nlt$sl_connection_descriptor,
      data_fragments: array [1 .. 1] of nat$data_fragment,
      layer_active: boolean,
      old_state: nlt$sl_machine_state,
      pdu_header: nlt$sl_pdu_header,
      synchronize_response: array [1 .. 1] of nlt$ta_aggregate;

    nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);
    IF layer_active THEN
      status.normal := TRUE;
      IF connection^.current_state = nlc$sl_m_r_fr_wait THEN
        old_state := connection^.current_state;
        connection^.current_state := nlc$sl_fwd_mark_wait;
      ELSEIF connection^.current_state = nlc$sl_synch_response_wait THEN
        old_state := connection^.current_state;
        connection^.current_state := nlc$sl_data_transfer;
      ELSEIF connection^.current_state = nlc$sl_synch_collision_fr THEN
        old_state := connection^.current_state;
        connection^.current_state := nlc$sl_rev_mark_wait;
      ELSE
        osp$set_status_condition ( nae$se_no_synch_in_progress,  status);
      IFEND;
      IF status.normal THEN
        pdu_header.pdu_type := nlc$sl_mark_type;
        data_fragments [1].address := ^pdu_header;
        data_fragments [1].length := #SIZE (pdu_header);
        synchronize_response [1].kind := nlc$ta_data_event;
        synchronize_response [1].end_of_message := TRUE;
        nlp$bm_create_message (data_fragments, synchronize_response [1].data, status);
        nlp$ta_send_aggregate_message (cl_connection, synchronize_response, status);
        IF NOT status.normal THEN
          connection^.current_state := old_state;
          IF status.condition = nae$connection_full THEN
            osp$set_status_abnormal (nac$status_id, nae$supervisory_traffic_limit, 'SYNCH RESPONSE', status);
          IFEND;
        IFEND;
      IFEND;
    ELSE
      osp$set_status_condition ( nae$connection_not_open,  status);
    IFEND;
  PROCEND nlp$sl_synch_response;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_interrupt_request', EJECT ??
*copy nlh$sl_interrupt_request

  PROCEDURE [XDCL] nlp$sl_interrupt_request
    (    cl_connection: ^nlt$cl_connection;
         data: nlt$bm_message_id;
     VAR status: ost$status);

    VAR
      connection: ^nlt$sl_connection_descriptor,
      data_length: integer,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      pdu_header: nlt$sl_pdu_header;

    status.normal := TRUE;
    message_id := data;
    nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);
    IF layer_active THEN
      CASE connection^.current_state OF
      = nlc$sl_data_transfer, nlc$sl_fwd_mark_wait, nlc$sl_rev_mark_wait, nlc$sl_m_r_fr_wait,
            nlc$sl_synch_response_wait, nlc$sl_synch_collision_fr =
        nlp$bm_get_message_length (data, data_length);
        IF (data_length <= nlc$sl_max_interrupt_message) AND
              (data_length >= nlc$sl_min_interrupt_message) THEN
          pdu_header.pdu_type := nlc$sl_interrupt_type;
          nlp$bm_add_message_prefix (^pdu_header, #SIZE (pdu_header), message_id);
          nlp$ta_send_expedited_data (cl_connection, message_id, status);
          IF NOT status.normal AND ((status.condition = nae$max_expedited_exceeded) OR
                (status.condition = nae$connection_full)) THEN
            osp$set_status_abnormal (nac$status_id, nae$supervisory_traffic_limit, 'INTERRUPT REQUEST',
                  status);
          IFEND;
        ELSE
          nlp$bm_release_message (message_id);
          osp$set_status_condition ( nae$se_interrupt_length_error,  status);
          osp$append_status_integer (osc$status_parameter_delimiter, nlc$sl_max_interrupt_message, 10, FALSE,
                status);
          osp$append_status_integer (osc$status_parameter_delimiter, nlc$sl_min_interrupt_message, 10, FALSE,
                status);
        IFEND;
      ELSE
        nlp$bm_release_message (message_id);
        osp$set_status_abnormal ('NA', nae$protocol_error, session_layer, status);
      CASEND;
    ELSE
      nlp$bm_release_message (message_id);
      osp$set_status_condition ( nae$connection_not_open,  status);
    IFEND;
  PROCEND nlp$sl_interrupt_request;
?? OLDTITLE ??
?? NEWTITLE := 'process_error_indication', EJECT ??

  PROCEDURE process_error_indication
    (    cl_connection: ^nlt$cl_connection;
     VAR connection: ^nlt$sl_connection_descriptor;
     VAR accumulated_message_buffers: nlt$ta_inventory_report);

    VAR
      event: nlt$sl_event,
      local_status: ost$status;

    CASE connection^.current_state OF
    = nlc$sl_call_wait, nlc$sl_disconnect_wait =
      nlp$ta_disconnect_connection (cl_connection, nlv$bm_null_message_id, local_status);
      nlp$cl_deactivate_layer (nlc$xns_session_layer, cl_connection);
      display_current_state (connection^.current_state);
      connection^.current_state := nlc$sl_closed;
    = nlc$sl_call_ok_wait, nlc$sl_call_response_wait, nlc$sl_data_transfer, nlc$sl_synch_response_wait,
          nlc$sl_m_r_fr_wait, nlc$sl_fwd_mark_wait, nlc$sl_rev_mark_wait, nlc$sl_synch_collision_fr =
      display_current_state (connection^.current_state);
      connection^.current_state := nlc$sl_closed;
      nlp$ta_disconnect_connection (cl_connection, nlv$bm_null_message_id, local_status);
      nlp$cl_deactivate_layer (nlc$xns_session_layer, cl_connection);
      event.kind := nlc$sl_clear_event;
      event.clear.reason := nlc$sl_layer_clear;
      event.clear.message_id := nlv$bm_null_message_id;
      nav$network_procedures [connection^.event_processor].
            sl_event_processor^ (cl_connection, event, accumulated_message_buffers);
    ELSE
    CASEND;

  PROCEND process_error_indication;
?? OLDTITLE ??
?? NEWTITLE := 'delete_connection', EJECT ??

  PROCEDURE [INLINE] delete_connection
    (VAR connection: ^nlt$sl_connection_descriptor;
         cl_connection: ^nlt$cl_connection);

    IF nlp$bm_valid_message_id (connection^.call_pdu_message_id) THEN
      nlp$bm_release_message (connection^.call_pdu_message_id);
    IFEND;
    nlp$cl_deactivate_layer (nlc$xns_session_layer, cl_connection);
  PROCEND delete_connection;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nlp$sl_clear_request_timer', EJECT ??

  PROCEDURE [XDCL] nlp$sl_clear_request_timer
    (    current_time: integer;
         cl_connection: ^nlt$cl_connection);

    VAR
      layer_active: boolean,
      connection: ^nlt$sl_connection_descriptor,
      ignore_status: ost$status;

    nlp$cl_get_layer_connection (nlc$xns_session_layer, cl_connection, layer_active, connection);
    IF layer_active THEN
      IF nlp$timer_expired (current_time, connection^.clear_timer) THEN
        nlp$ta_disconnect_connection (cl_connection, nlv$bm_null_message_id, ignore_status);
        delete_connection (connection, cl_connection);
      IFEND;
    IFEND;
  PROCEND nlp$sl_clear_request_timer;
?? OLDTITLE ??
?? NEWTITLE := 'display_current_state', EJECT ??

  PROCEDURE display_current_state
    (    current_state: nlt$sl_machine_state);

    VAR
      message_string: string (80),
      length: integer,
      status: ost$status;

    STRINGREP (message_string, length, 'CURRENT_STATE=', current_state);
    pmp$log (message_string (1, length), status);
  PROCEND display_current_state;
?? OLDTITLE ??
MODEND nlm$sl_internal_interface;
