?? RIGHT := 110 ??
?? NEWTITLE := ' NOS/VE File Server: log_sdp_data ', EJECT ??
MODULE dfm$log_sdp_data;

{
{  This module contains the processes which construct the System Engineering
{  Log entry for STORNET/ESM side door port Error Log data.
{

?? TITLE := '    Global Definitions ', EJECT ??
*copyc clp$convert_integer_to_string
*copyc cml$5380_100_sdp_failure_data
*copyc cml$7040_200_sdp_failure_data
*copyc cmt$product_identification
*copyc dfi$display
*copyc dfi$log_display
*copyc dfv$file_server_debug_enabled
*copyc oss$job_paged_literal
*copyc ost$status
*copyc pmp$get_compact_date_time
*copyc pmp$zero_out_table
*copyc sfp$activate_system_statistic
*copyc sfp$emit_statistic
?? TITLE := '    Global Declarations ', EJECT ??
*copyc dfc$sdp_driver_error_codes
*copyc dfc$sdp_logging_error_codes
*copyc dft$descriptive_data_descriptor
*copyc dft$sdp_communication_buffer
*copyc dft$sdp_logging_code
?? TITLE := '    build_descriptive_data_message ', EJECT ??

{
{ PURPOSE:
{ This procedure builds the descriptive data portion of the STORNET/ESM
{ statistic.
{

  PROCEDURE build_descriptive_data_message
    (    reason: dft$sdp_logging_code;
         log_data_p: ^dft$sdp_communication_buffer;
         descriptive_data_descriptor: dft$descriptive_data_descriptor;
     VAR communication_buffer_p: ^dft$sdp_communication_buffer;
     VAR descriptive_data_message: ost$string;
     VAR symptom_code: integer;
     VAR status: ost$status);

    VAR
      integer_string: ost$string,
      temporary_string: ost$string,
      symptom_code_message_text: [STATIC, READ, oss$job_paged_literal] array [
            0 .. dfc$max_sdp_logging_error_code - 1] of ost$string :=
            [[52, 'ERR=VP73000000, SIDE DOOR PORT INITIALIZATION STATUS'],
             [49, 'ERR=VP73000001, SIDE DOOR PORT TOP OF HOUR STATUS'],
             [51, 'ERR=VP73000002, SIDE DOOR PORT CHANNEL ACTIVE ERROR'],
             [54, 'ERR=VP73000003, SIDE DOOR PORT NO INACTIVE TO FUNCTION'],
             [49, 'ERR=VP73000004, SIDE DOOR PORT LOST DATA ON INPUT'],
             [51, 'ERR=VP73000005, SIDE DOOR PORT CHANNEL PARITY ERROR'],
             [48, 'ERR=VP73000006, SIDE DOOR PORT CHANNEL NOT EMPTY'],
             [53, 'ERR=VP73000007, SIDE DOOR PORT CHANNEL LOCKWORD ERROR'],
             [0, ''], [0, ''], [0, ''], [0, ''], [0, ''], [0, ''],
             [0, ''], [0, ''], [0, ''], [0, ''], [0, ''], [0, ''],
             [54, 'ERR=VP73000020, SIDE DOOR PORT NO INITIALIZATION ERROR'],
             [54, 'ERR=VP73000021, SIDE DOOR PORT CHANNEL STATE INCORRECT'],
             [50, 'ERR=VP73000022, SIDE DOOR PORT CHANNEL UNAVAILABLE'],
             [45, 'ERR=VP73000023, SIDE DOOR PORT PP UNAVAILABLE'],
             [47, 'ERR=VP73000024, SIDE DOOR PORT NO SDPD RESPONSE']];

{
{ Validate log_data_p.
{

    IF log_data_p <> NIL THEN
      communication_buffer_p := log_data_p;
    IFEND;

{
{ Build the descriptive data message portion of the statistic.
{
{ <mainframe>.

    descriptive_data_message.value (1, STRLENGTH (descriptive_data_descriptor.mainframe)) :=
          descriptive_data_descriptor.mainframe;
    descriptive_data_message.size := STRLENGTH (descriptive_data_descriptor.mainframe);
    descriptive_data_message.value (descriptive_data_message.size + 1, 1) := '.';
    descriptive_data_message.size := descriptive_data_message.size + 1;

{ <iou>.

    temporary_string.value := descriptive_data_descriptor.iou;
    set_string_length (temporary_string);
    descriptive_data_message.value ((descriptive_data_message.size + 1),
          temporary_string.size) := temporary_string.value;
    descriptive_data_message.size := descriptive_data_message.size + temporary_string.size;
    descriptive_data_message.value (descriptive_data_message.size + 1, 1) := '.';
    descriptive_data_message.size := descriptive_data_message.size + 1;

{ <pp>.

    IF log_data_p = NIL THEN
      temporary_string.value := descriptive_data_descriptor.pp;
      set_string_length (temporary_string);
      descriptive_data_message.value ((descriptive_data_message.size + 1),
            temporary_string.size) := temporary_string.value;
      descriptive_data_message.size := descriptive_data_message.size + temporary_string.size;
    ELSE
      IF communication_buffer_p^.word_one.concurrent_pp = 1 THEN
        descriptive_data_message.value (descriptive_data_message.size + 1, 3) := 'CPP';
        descriptive_data_message.size := descriptive_data_message.size + 3;
      ELSE
        descriptive_data_message.value (descriptive_data_message.size + 1, 2) := 'PP';
        descriptive_data_message.size := descriptive_data_message.size + 2;
      IFEND;
      clp$convert_integer_to_string (communication_buffer_p^.word_one.pp_number, 10, FALSE, integer_string,
            status);
      descriptive_data_message.value (descriptive_data_message.size + 1,
            integer_string.size) := integer_string.value;
      descriptive_data_message.size := descriptive_data_message.size + integer_string.size;
    IFEND;
    descriptive_data_message.value (descriptive_data_message.size + 1, 1) := '.';
    descriptive_data_message.size := descriptive_data_message.size + 1;

{ <ch>.

    temporary_string.value := descriptive_data_descriptor.ch;
    set_string_length (temporary_string);
    descriptive_data_message.value ((descriptive_data_message.size + 1),
          temporary_string.size) := temporary_string.value;
    descriptive_data_message.size := descriptive_data_message.size + temporary_string.size;
    descriptive_data_message.value (descriptive_data_message.size + 1, 1) := '.';
    descriptive_data_message.size := descriptive_data_message.size + 1;

{ <element>*

    temporary_string.value := descriptive_data_descriptor.element;
    set_string_length (temporary_string);
    descriptive_data_message.value ((descriptive_data_message.size + 1),
          temporary_string.size) := temporary_string.value;
    descriptive_data_message.size := descriptive_data_message.size + temporary_string.size;
    descriptive_data_message.value (descriptive_data_message.size + 1, 1) := '*';
    descriptive_data_message.size := descriptive_data_message.size + 1;

{ <message>
{
{ Determine symptom code for reference of symptom code message text.

    IF descriptive_data_descriptor.symptom_code > dfc$sdp_no_initialization_error THEN
      symptom_code := descriptive_data_descriptor.symptom_code;
      communication_buffer_p^.word_one.ppu_status := symptom_code;
    ELSEIF communication_buffer_p^.word_one.ppu_status > dfc$sdpd_normal_completion THEN
      symptom_code := communication_buffer_p^.word_one.ppu_status;
    ELSE
      symptom_code := $INTEGER (reason);
    IFEND;
    descriptive_data_message.value (descriptive_data_message.size + 1,
          symptom_code_message_text [symptom_code].size) := symptom_code_message_text [symptom_code].value;
    IF descriptive_data_descriptor.product_id.product_number = ' $7040' THEN
      descriptive_data_message.value (descriptive_data_message.size + 10, 1) := '1';
    IFEND;
    descriptive_data_message.size := descriptive_data_message.size +
          symptom_code_message_text [symptom_code].size;
  PROCEND build_descriptive_data_message;
?? TITLE := '    establish_statistics ', EJECT ??

{
{ PURPOSE:
{ This procedure activates the STORNET/ESM side door port logging statistics
{ (CM7300 & CM7301) in the system.
{

  PROCEDURE establish_statistics
    (    reason: dft$sdp_logging_code;
         descriptive_data_descriptor: dft$descriptive_data_descriptor;
     VAR statistic_code: sft$statistic_code;
     VAR status: ost$status);

    CONST
      number_of_statistics = 2;

    VAR
      statistics: array [1 .. number_of_statistics] of sft$statistic_code,
      statistic: integer;

{
{ Specify statistic code from product identification of the STORNET/ESM
{ memory device.
{

    IF descriptive_data_descriptor.product_id.product_number = ' $5380' THEN
      statistic_code := cml$5380_100_sdp_failure_data;
    ELSE
      statistic_code := cml$7040_200_sdp_failure_data;
    IFEND;

{
{ Establish statistic codes for the STORNET/ESM memory device.
{

    IF reason = dfc$sdp_initialization THEN
      statistics [1] := cml$5380_100_sdp_failure_data;
      statistics [2] := cml$7040_200_sdp_failure_data;
      FOR statistic := 1 TO number_of_statistics DO
        sfp$activate_system_statistic (statistics [statistic], $sft$binary_logset [pmc$engineering_log],
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      FOREND;
    IFEND;
  PROCEND establish_statistics;
?? TITLE := '    set_string_length ', EJECT ??

{
{ PURPOSE:
{   This procedure finds the length of a string that is passed in as a parameter.  It also removes
{   any spaces that are at the beginning and at the end of the string.
{

  PROCEDURE set_string_length
    (VAR string_data: ost$string);

    VAR
      begin_index: ost$string_size,
      end_index: ost$string_size,
      temp_string: string (osc$max_string_size);

{
{ If the string is all blank set the string length to one and return.
{

    IF string_data.value = ' ' THEN
      string_data.size := 1;
      RETURN;
    IFEND;

{
{ Find the first non-blank character in the string.
{

    begin_index := 1;
    WHILE (begin_index <= osc$max_string_size) AND (string_data.value (begin_index) = ' ') DO
      begin_index := begin_index + 1;
    WHILEND;

{
{ Find the last non-blank character in the string.
{

    end_index := osc$max_string_size;
    WHILE (end_index > begin_index) AND (string_data.value (end_index) = ' ') DO
      end_index := end_index - 1;
    WHILEND;

{
{ Move the data in the string so the first non-blank character is the first character in the string and
{ determine the size of the string from the first non-blank character to the last non-blank character.
{

    temp_string := string_data.value;
    string_data.value := temp_string (begin_index, (end_index - begin_index) + 1);
    string_data.size := (end_index - begin_index) + 1;
  PROCEND set_string_length;
?? TITLE := '    [XDCL] dfp$log_sdp_data', EJECT ??

{
{ PURPOSE:
{ This procedure emits STORNET/ESM side door port logging statistics (CM7300 &
{ CM7301 respectively) into the system Engineering Log.
{

  PROCEDURE [XDCL] dfp$log_sdp_data
    (    reason: dft$sdp_logging_code;
         log_data_p: ^dft$sdp_communication_buffer;
         descriptive_data_descriptor: dft$descriptive_data_descriptor;
     VAR status: ost$status);

    VAR
      communication_buffer_p: ^dft$sdp_communication_buffer,
      counters_p: sft$counters,
      date_time_p: ^ost$date_time,
      descriptive_data_message: ost$string,
      sdp_communications_p: ^dft$sdp_communication_buffer,
      statistic_code: sft$statistic_code,
      statistic_data_sequence_p: ^SEQ ( * ),
      statistic_data_size: integer,
      symptom_code: integer;

    status.normal := TRUE;

{
{ Establish statistics for STORNET/ESM side door port logging (CM7300 &
{ CM7301 respectively).
{

    establish_statistics (reason, descriptive_data_descriptor, statistic_code, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{
{ Build the descriptive data message portion of this statistic as follows:
{ <mainframe>.<iou>.<pp>.<ch>.<element>*<message>
{

    PUSH communication_buffer_p;
    pmp$zero_out_table (communication_buffer_p, #SIZE (dft$sdp_communication_buffer));
    build_descriptive_data_message (reason, log_data_p, descriptive_data_descriptor, communication_buffer_p,
          descriptive_data_message, symptom_code, status);

{
{ Create a SEQ to use to build the data to place in the statistic counters.
{
{ Statistic Counters Format:
{ Set counter [1] to DATE/TIME Stamp.
{ Set counter [2] to Analysis Code.
{ Set counter [3] to STORNET/ESM SDP Path.
{ Set counter [4] to STORNET/ESM Error Logs.
{       .                    .
{       .                    .
{ Set counter [20] to STORNET/ESM Error Logs.
{

    statistic_data_size := #SIZE (ost$date_time) + #SIZE (dft$sdp_communication_buffer);
    PUSH statistic_data_sequence_p: [[REP statistic_data_size OF cell]];
    RESET statistic_data_sequence_p;
    NEXT date_time_p IN statistic_data_sequence_p;
    pmp$get_compact_date_time (date_time_p^, status);
    NEXT sdp_communications_p IN statistic_data_sequence_p;
    sdp_communications_p^ := communication_buffer_p^;
    RESET statistic_data_sequence_p;
    NEXT counters_p: [1 .. (statistic_data_size DIV 8)] IN statistic_data_sequence_p;

{
{ The communication_buffer_p.word_zero data is superfluous, an integer symptom
{ code is required.
{

    counters_p^ [2] := symptom_code;

{
{ Emit a statistic to the System Engineering Log via a call to system
{ interface SFP$EMIT_STATISTIC.
{

    sfp$emit_statistic (statistic_code, descriptive_data_message.value (1, descriptive_data_message.size),
          counters_p, status);
    IF dfv$file_server_debug_enabled THEN
      display (descriptive_data_message.value (1, descriptive_data_message.size));
      log_display ($pmt$ascii_logset [pmc$system_log, pmc$job_log],
            descriptive_data_message.value (1, descriptive_data_message.size));
    IFEND;
  PROCEND dfp$log_sdp_data;
MODEND dfm$log_sdp_data;
