DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦4d0d9d14a⟧ TextFile

    Length: 25344 (0x6300)
    Types: TextFile
    Names: »sddc3«

Derivation

└─⟦a41ae585a⟧ Bits:30001842 SW-save af projekt 1000, Alarm-system
    └─⟦72244f0ef⟧ 
        └─⟦this⟧ »sddc3« 

TextFile

>fo @üSD.DCSYS.3/2ü@
>a1 Introduction
>a1 Data Structures
>a1 Program Structure
>a2 Coding Principles
This module consists of a central procedure "utility"
that can be called from the coroutines AMH
(alarm message handler), SOTH (service order terminal
handler), ALOPT (alarm operator handler), and
TIMEOUT_HANDLER.

It is called when some work has to be done on one
of the current task incarnations, e.g. when one of the
coroutines above receives a message containing a task
incarnation number different from 0.

The task incarnation number is passed on to utility as
first actual parameter in the call. It must be stated as
second actual parameter whether the call is caused by
TIMEOUT_HANDLER or by another coroutine.
If a message is involved in the call an integer array
containing this message is passed as third parameter.

>ne 27
>sp 25

>fg Communication with surroundings
   
Utility fetches the task descriptor (a buffer) corresponding
to the task incarnation. From this description it is decided
which of the local task procedures (create_at, create_ac,
and so on) has to be called. When the task procedure has
been executed the buffer (task descriptor) will be returned and
utility ends.

The utility procedure is structured like this:

>ne23
 procedure utility (task_inc_no, timeout, mess, zout);
 integer task_inc_no;
 boolean timeout;
 real array mess;
 zone zout;

    taskdescr: = wait (sem (task_inc_no));
    state: = buf. taskdescr. tdstate;
    type: = buf. taskdescr. tdtype;

    case type of

      1: create_at;
      2: create_ac;
      3: check_at_ac_conn;
      4: internal_test1;
      5: internal_test2;
      6: dc_start_poll_at;
      7: pac_start_poll_at;
      8: start_poll_ac;
      9: dc_stop_poll;
     10: pac_stop_poll;

    return_buf (taskdescr)


>a2 Modes
>a2 Submodules
Utility involves the following local procedures for the time being:

>ne9
 create_at
 create_ac
 check_at_ac_conn
 internal_test1
 internal_test2
 dc_start_poll_at
 pac_start_poll_at
 start_poll_ac
 dc_stop_poll
 pac_stop_poll

It is common to these task procedures that execution of a
single task incarnation may involve several calls of the
procedure in question. The actual number of calls in each
case depends on both the type of the task and data values
concerning the specific task.

Each call of a task procedure results in execution of a
part of this procedure. The procedures are divided into 
a number of parts (states) each of which is identified
by a state-number. Normal execution of a task involves
calls of the task procedure with increasing values of the 
state variable.

>a3 Create AT
The task procedure create_at will be called in connection with
TIMEOUT_HANDLER. Third parameter is irrelevant in this case.

When an AT is created SOTH will update the database according to the
information given via the terminal and activate a task number. The
corresponding task descriptor will be initialised with task
type 1 indicating create_at, the state number 1, and the
AT-address.

Then the utility-procedure will be called with the task number
given as first actual parameter. Second parameter with the
value false indicates that the calling coroutine is not
TIMEOUT_HANDLER.

The procedure consists of the following actions:

>ne18
 Creation of the subscriber in the database;

 Send create message (type 6.0) to the ATs TS;
 Wait receipt (type 6.1) from ATs TS;
 
 Send code-address message (10.2) to all involved
 ACs;
 Wait receipts (10.3) from all involved ACs;

 Send VCaVCm-table message (10.10) to ATs TS for
 each of the above ACs that are not known by this
 TS until now;
 Wait receipts (10.11) for each 10.10-message;

 Send code-address message (10.0) to AT for each AC;
 Wait receipt (10.1) for each of the 10.0-messages;

 Print order form and confirmation;

Not all of these actions can be executed at once.
It is necessary to wait for the receipts. For this
reason the procedure is divided into states. When
all work in one state has been executed the state
variable in the task description is increased and the
procedure terminates. In this way each
time the procedure is activated work
will be resumed at the proper place.

The procedure is structured like this (a wait is not performed explicitly,
but takes place via a state transition):

>ne55
procedure create_at;

  if timeout
  then error_reaction
  else
  case state of

    1:   initialise buf.taskdescr.dbref;
         update the database;
         send 6.0-message to ATs TS;
         increase buf. taskdescr. tdstate by 1
         send timeout;

    2:   (* 6.1-message received *)
         cancel timeout;
         for all ACs involved
         send 10.2-message to AC;
         increase buf. taskdescr. tdstate by 1
         send timeout;

    3:   note receipt of a 10.3-message;
         if all 10.3-messages received
         then

            cancel timeout;
            for all ACs not in ATs TSs
            VCaVCm-table send 10.10-message
            to ATs TS;
            increase buf. taskdescr. tdstate by 1
            send timeout;

    4:   note receipt of a 10.11-message;
         if all 10.11-messages received
         then

            cancel timeout;
            for all ACs involved
            send 10.0-message to AT;
            increase buf. taskdescr. tdstate by 1
            send timeout;

    5:   note receipt of a 10.1-message;
         if all 10.1-messages received
         then

            cancel timeout;
            print order form;
            print confirmation of order;
            clear this task


>a3 Create AC
When an alarm centre is to be created AL_OPT updates the
database with information about the new AC and activates
one of the free task incarnations. Then the corresponding task
descriptor is initialised with the task type indicating
create_ac (= 2), state number = 1, and a reference containing
the AC-address.

Utility is called with the task incarnation number as first
actual parameter, and the value false as second actual parameter
indicating that the calling procedure is not TIMEOUT_HANDLER.
Third parameter is irrelevant.

The task procedure has to perform the following jobs:

 Update the database;
 Send a create-message (7.0) to ACs TS;
 Wait receipt (7.1) from TS;
 Print result to operator;
 Print order form and confirmation;

It is carried out in this way:

>ne20
procedure create_ac;

   if timeout
   then error_reaction
   else
   case state of

     1:   initialise buf.taskdescr.dbref;
          update the database;
          send 7.0-message to ACs TS;
          increase buf. taskdescr. tdstate by 1
          send timeout;

     2:   (* 7.1-message received *)
          cancel timeout;
          write result to operator;
          print order form;
          print confirmation of order;
          clear this task


>a3 Check AT-AC connection
A task incarnation of type check_at_ac_conn can be
activated by AL_OPT on the operator's request.
One of the free task incarnations is activated and the corresponding
task descriptor initialised with task type 3 indicating
check_at_ac_conn, task state 1, and a reference to the
AT and AC in question as stated by the operator.

Then utility will be called with the actual parameters
task incarnation number and false indicating that the 
calling coroutine is not TIMEOUT_HANDLER. Utility calls
the task procedure check_at_ac_conn.

This procedure should:

>ne3
 Send 9.2-message to AT;
 Wait 9.3-receipt from AT;
 Write result to the operator;

Check_at_ac_conn looks like this:

>ne16
procedure check_at_ac_conn;

   if timeout
   then error_reaction
   else
   case state of

    1:   initialise buf. taskdescr. dbref;
         send 9.2-message to AT;
         increase buf. taskdescr. tdstate by 1
         send timeout;

    2:   (* 9.3-message received *)
         cancel timeout;
         write result to the operator;
         clear this task


>a3 Internal test
Task incarnations performing internal tests (1 or 2)
can also be activated by AL_OPT at the operator's
request. During an activation the task descriptor is
initialised with task type 4 meaning internal test 1
or task type 5 indicating internal test 2. The AT-address
stated by the operator is also placed in the task descriptor.

The procedure internal test 1 sends an 8.0-message to AT,
waits for an 8.1-receipt, and writes the result to the 
operator.

The pseudo-code for this is as follows:

>ne16
procedure internal_test 1;

   if timeout
   then error_reaction
   else
   case state of

    1:   initialise buf. taskdescr. dbref;
         send 8.0-message to AT;
         increase buf. taskdescr. tdstate by 1;
         send timeout;

    2:   (* 8.1-message received *)
         cancel timeout;
         write result to operator;
         clear this task


Analogously, internal test 2 sends an 8.2-message to AT,
waits for an 8.3-receipt, and writes the result:

>ne16
procedure internal_test 2;

   if timeout
   then error_reaction
   else
   case state of

    1:   initialise buf. taskdescr. dbref;
         send 8.2-message to AT;
         increase buf. taskdescr. tdstate by 1;
         send timeout

    2:   (* 8.3-message received *)
         cancel timeout;
         write result to operator;
         clear this task


>a3 DC-start poll of AT
When the operator at DC gives his permission to start 
polling an AT, AL_OPT will activate a task incarnation
with task type 6 indicating dc_start_poll_at.

The task procedure dc_start_poll_at accomplishes the
following:

>ne 6
 Set DC-permission to 'start';
 Send DC-permission-message (6.4) to PAC;
 If PAC-permission is 'start'
 then send start-poll message (9.0) to AT
      wait 9.1-message from AT
      write result to operator

The procedure will be programmed following this structure:

>ne23
procedure dc_start_poll_at;

   if timeout
   then error_reaction
   else
   case state of

    1:   initialise buf. taskdescr. dbref;
         set DC-permission bit;
         send DC-permission-message (6.4) to PAC;
         if PAC-permission is 'start' 
         then

            send start-poll message (9.0) to AT;
            increase buf. taskdescr. tdstate by 1;
            send timeout

         else clear this task

    2:   (* 9.1-message from AT received *)
         cancel timeout;
         write result to operator
         clear this task


>a3 PAC-start poll of AT
When PAC gives permission to start polling an AT AMH 
will receive a PAC-permission message (6.4). On receipt
of this message AMH activates a task incarnation setting
task type to 7 indicating pac_start_poll_at.
Utility is called with 3rd actual parameter referencing the
the 6.4-message.

The object of the task procedure pac_start_poll_at is
to do this:

>ne6
 Set PAC-permission to 'start';
 Write PAC-permission to DC-operator;
 If DC-permission is 'start'
 then send start-poll message (9.0) to AT
      wait 9.1-message from AT
      write result to operator

The procedure will be programmed following this structure:

>ne22
procedure pac_start_poll_at;

   if timeout
   then error_reaction
   else
   case state of

    1:   initialise buf. taskdescr. dbref;
         set PAC-permission to 'start';
         write PAC-permission to DC-operator;
         if DC-permission is 'start'
         then

            send start-poll message (9.0) to AT;
            increase buf. taskdescr. tdstate by 1;
            send timeout

         else clear this task

    2:   (* 9.1-message received *)
         cancel timeout;
         write result to operator;
         clear this task


>a3 Start poll of AC
A task incarnation of type start_poll_ac can be started
by AL_OPT at request from the operator. The task type 
in the task descriptor gets the value 8.

The task procedure start_poll_ac sends a start-poll 
message (9.0) to AC, waits for a receipt (9.1), and
writes the result to the operator:

>ne16
procedure start_poll_ac;

   if timeout
   then error_reaction
   else
   case state of

    1:   initialise buf. taskdescr. dbref;
         send start poll message (9.0) to AC;
         increase buf. taskdescr. tdstate by 1;
         send timeout

    2:   (* 9.1-message received *)
         cancel timeout;
         write result to operator;
         clear this task


>a3 Service poll and stop poll of AT
When the operator at DC gives permission to stop or service
poll, AL_OPT activates a task incarnation with task type 9
indicating dc_stop_poll.

The method used by the system to stop poll is quite
analogous to the method used for service poll, the
only difference being in the update part of some of the
messages. However, PAC does not distinguish between stop
poll and service poll, so the messages sent between DC
and PAC indicates stop poll in both cases.
 
DC-stop poll:

 set DC-permission to 'stop' or 'service';
 if poll-value= 'start'
 then send stop-request (6.4) to PAC;
      wait a given timeout period
      if PAC-permission is still 'start'
      then set DC-permission to 'start'
 
 else if poll-value= DC-permission
      then write this to operator
      else send stop-poll message (9.0) to AT
           wait 9.1 answer
           update the database
           write result to operator
 
Transition from polling an AT to stop or service poll requires
permission (a 6.4-message) from both DC-operator and PAC. The
stop poll-message from DC should be sent before the stop 
poll-message from PAC. Permission to stop poll from PAC 
starts a task of type pac_stop_poll.

A 6.4-message from PAC permitting stop poll while DC-persission
has the value 'start' is considered an error. If DC-permission
is 'stop' or 'service' this message will set PAC-permission 
to 'stop' and trigger stop or service poll.


PAC-stop poll:

  if DC-permission= 'stop' or 'service'
  then set PAC-permission to 'stop';
       send stop poll-message (9.0) to AT;
       wait 9.1-answer;
       update the database;
       write result to operator
 
  else write error message to operator

The tasks are programmed according to this structure:

>ne 30
procedure dc_stop_poll;

   if timeout 
   then if state= 1 
        then if PAC-permission is 'start'
             then set DC-permission to 'start';
             write result to operator;
             clear this task
        else error_reaction
   else 
   case state of

    1:   initialise buf.taskdescr.dbref;
         set DC-permission to 'stop' or 'service';
         if ATs poll-value= 'start'
         then send 6.4-message to PAC;
              send timeout
 
         else if AT's poll-value= DC-permission
              then write this to operator
              else  send stop-poll message (9.0) to AT;
                    increase buf. taskdescr. tdstate by 1;
                    send timeout

    2:   (* 9.1-message received *)
         cancel timeout;
         update the database;
         write result to operator
         clear this task
 
>ne22
procedure pac_stop_poll;
   if timeout
   then error_reaction
   else
   case state of

    1:   initialise buf. taskdescr. dbref;
         if DC-permission= 'stop' or 'service'
         then set PAC-permission to 'stop';
              send stop poll-message (9.0) to AT;
              increase buf. taskdescr. tdstate by 1;
              send timeout;
 
         else write error message to operator;
              clear this task
 
    2:   (* 9.1-message received *)
         cancel timeout;
         update the database;
         write result to operator;
         clear this task
 
 
 
>a3 Create TS
A task incarnation with task type create_ts (=14) is started as a
result of typing the command "<altso" on the operator console.

The task descriptor should be initialized with the alarm macro
address of the logical TS and the alarm macro address of the physical
machine for this TS.

The operations to be performed depend on whether the physical machine
contains a logical machine (DC, NC, or TS) already. This is the case
if and only if the macro addresses of the two machines differ.

The task procedure performs the following:

  Update the database;
  Send a 10.12-message conc. the TS to DC's
  netconnector; wait receipt;

  If DC <> physical machine for the TS then
  send a 10.12-message to netconnector in
  physical machine concerning TS's alarm and
  paxnet addresses; wait receipt;

  If logical machine = physical machine then
    Send 10.12-message to DC's netconnector
    to modify the TS-address; wait receipt;
    Send 10.12-message to TS's netconnector
    describing DC as global exit; wait receipt;

  If NC is not in paxtable of physical machine
  for TS, then send 10.12-message to netconnector
  in physical machine concerning NC; wait receipt;

  If TS is not in paxtable of NC's physical
  machine, then send 10.12-message to netconnector
  in NC's physical machine concerning TS; wait receipt;

  Send 11.0-message to TS-supervisor; wait receipt;
 
  

It is programmed like this:
procedure create_ts;

   if timeout
   then error_reaction
   else
   case state of

>ne 26
    1;  insert tsid-record in the database:
        insert TS as global/local record in paxtable
        for DC;
        if physical TS <> DC then
          if physical TS = logical TS then
          insert TS as own record in paxtable for TS;
          insert DC as global exit in paxtable for TS
        else insert TS as local record in paxtable for
          physical TS;
        if <*physical TS <> physical NC and *> NC is not
           in paxtable of physical TS
        then insert NC as global record in physical TS;
        if physical NC <> DC and physical NC <> physical TS
        then insert TS as global record in physical NC;

        <* insert TS in DC's paxtable *>
        send 10.12-message to DC's netcon describing TS
        as next global/local record stating log_macro as
        0-0-0 if logical macro = physical macro and logical
        macro otherwise;

        send timeout;
        buf.taskdescr.td_state:= if physical TS <> DC
        then 2
        else if physical NC <> DC and physical NC <> physical TS
          then 6
          else 7


>ne 17
    2:  <* physical TS <> DC *>
        <* insert TS as own or local record in physical TS *>
        cancel timeout;

        send 10.12-message to physical TS describing TS as
        own if logical TS = physical TS and local record 
        otherwise. If logical TS = physical TS then receiver
        of this message is 0-0-0-3;

        send timeout;
        buf.taskdescr.td_state:= if logical TS = physical TS
          then 3
          else if physical TS @@ physical NC
               then if NC is not in paxtable of physical TS
                    then 5
                    else 6
               else 7;


>ne9
    3:  <* physical TS <> DC and logical TS = physical TS *>
        <* modify TS record in DC's paxtable *>
        cancel timeout;

        send 10.12-message to DC's netcon modifying
        TS's log_macro from 0-0-0 to logical TS_macro;
    
        send timeout;
        buf.taskdescr.td_state:= 4;


>ne15
    4:  <* physical TS <> DC and logical TS = physical TS *>
        <* insert  DC as global exit in (physical) TS's 
         paxtable *>
        cancel timeout;

        send 10.12-message to TS's netcon describing
        DC as global exit;

        send timeout;
        buf.taskdescr.tdstate:= if physical TS <> 
        physical NC
        then
             if NC is not in paxtable of physical TS
             then 5 
             else 6
        else 7;


>ne13
    5:  <* physical TS <> DC and physical TS <> physical
         NC and NC is not in paxtable of physical TS *>
        <* insert NC as global record in physical
         TS's paxtable *>
        cancel timeout;

        send 10.12-message to physical TS' netcon
        describing NC as global record;

        send timeout;
        buf.taskdescr.tdstate:= if physical NC <> DC
           then 6
           else 7;


>ne11
    6:  <* physical NC <> DC and physical NC <> 
         physical TS *>
        <* insert TS as global record in physical
         NC's paxtable *>
        cancel timeout;

        send 10.12-message to physical NC's netcon
        describing TS as global record;

        send timeout;
        buf.taskdescr.tdstate:= 7;


>ne 6
    7:  <* send TS-address *>
        cancel timeout;

        send 11.0-message to TS-supervisor;
        send timeout;
        buf.taskdescr.tdstate:= 8;


>ne6
    8:  <* 11.1-message from TS received *>
        cancel timeout;

        write result to operator;
        update database;
        clear this task;


>a3 Create NC
When a DC-operator types the command for NC-creation a task
in_carnation with type create_nc (=15) will be started.

The task descriptor should be initialized with the alarm macro
address of the new NC (logical machine) and the alarm macro
address of the physical machine for this NC.

The operations to be performed depend on whether the physical
machine contains a logical machine (DC, NC, or TS) already. This
is the case if and only if the macro addresses of the two
machines differ.


The task procedure performs the following:

  Update the database;
  Send a 10.12-message (update paxtable) to DC's
  netconnector; wait receipt.

  If DC <> physical machine then 
    send a 10.12-message to netconnector
    in physical machine containing NC's
    addresses; wait receipt.

  If the logical macro address = the
  physical macro address then

    send 10.12-message to DC's netconnector
    to modify NC's record in paxtable, wait receipt;
    send 10.12-message to NC's netconnector
    containing DC-address; wait receipt;

  Send 11.0-message to NC-supervisor; wait receipt;
  Write result to operator;

It is programmed according to this structure:

>np
procedure create_nc;

   if timeout
   then error_reaction
   else
   case state of

    1:  insert ncid-record in the database;
        insert NC as next global local record in paxtable
        for DC;
        if logical macro = physical macro
           insert NC as own record in paxtable for NC;
           insert DC as global exit in paxtable for NC
        else if physical macro <> DC macro then
           insert NC as local record in paxtable for
           physical machine;

        send 10.12-message to DC's netcon describing NC
        as next global or local record stating log_macro
        as 0-0-0 if logical macro = physical macro and
        as NC-macro otherwise;

        send timeout;
        buf.taskdescr.tdstate:= if DC macro <> physical
        macro then 2 else 5;



    2:  <* 10.13-message from DC's netcon received *>
        cancel timeout;

        send 10.12-message to physical machine describing
        NC as own if logical macro = physical macro, and
        local otherwise. Receiver of this message is 
        0-0-0-3; if logical macro = physical macro,
        otherwise it is netconnector in physical machine.

        send timeout;
        buf.taskdescr.tdstate:= if logical macro = physical
        macro then 3 else 5;


    3:  <* 10.13-message from physical machine received *>
        <* logical macro = physical macro *>
        cancel timeout;
        send 10.12-message to DC's netcon modifying
        NC's log_macro from 0-0-0 to NC-macro;

        send timeout;
        buf.taskdescr.tdstate:= 4;



    4:  <* 10.13-message from DC's netcon received *>
        <* logical macro = physical macro *>
         cancel timeout;

        send 10.12-message to NC's netcon describing
        DC as global exit;

        send timeout;
        buf.taskdescr.tdstate:= 5;


    5:  <* 10.13-message from physical machine received *>
        cancel timeout;
        send 11.0-message to NC-supervisor;
        send timeout;
        buf.taskdescr.tdstate:= 6;


    6:  <* 11.1-message from NC received *>
        cancel timeout;
        write result to operator;
        update database;
        clear this task;

▶EOF◀