|
|
DataMuseum.dkPresents historical artifacts from the history of: RC3500 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC3500 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 33024 (0x8100)
Types: TextFileVerbose
Names: »athedit«
└─⟦a41ae585a⟧ Bits:30001842 SW-save af projekt 1000, Alarm-system
└─⟦72244f0ef⟧
└─⟦this⟧ »athedit«
job nla 4 200 time 11 0 area 9 size 90000 perm disc1 1000 2
(mode list.yes
source = copy 25.1
tsathlst= set 1 disc1
tsathlst = indent source mark lc
athlst = cross tsathlst
o errors
pascal80 codesize.12000 alarmenv tsenvir source
o c
lookup pass6code
if ok.yes
( tsathbin= set 1 disc1
tsathbin = move pass6code
scope user tsathbin)
tsathlst=copy athlst errors
scope user tsathlst
convert errors
finis)
process at_handler(
op_sem : sempointer;
var
dc_address ,
own_address : !macroaddr;
var
sem : !ts_pointer_vector
);
const
version = "vers 3.18 /";
(* ------------------------------------------------------------------------
.
. The at_handler presupposes the following surroundings:
.
. - at runtime:
.
. Libraries: tslib.
.
. Externals: at_connector, receipt_message, reject_message.
.
.
. - at compile time:
.
. Environments: alarmenv, tsenvir
.
. Call: <object> = pascal80 <options> alarmenv tsenvir <source>
.
------------------------------------------------------------------------ *)
\f
(*
INTRODUCTION TO THE AT-HANDLER:
Abbreviation list for the AT-HANDLER process:
---------------------------------------------
ac alarm centre
addr address
at alarm terminal
atc at-connector
ath at-handler
dc district centre
del delete
incar incarnation
ins insert
ix index
locvar local variable
mac macro address
max greatest
mic micro address
min smallest
msg message
no number
pac primary alarm centre
rac receiving alarm centre
rec receiver
sac sending alarm centre
sem semaphore
send sender
tss ts-supervisor
\f
Pseudo-code for the AT-HANDLER process:
--------------------------------------
( this pseudo_code will be updated regularly - last time was 80.06.03 )
PROCESS at_handler("process_parameters");
CONST
. "process_constants, installation dependent" (may be moved to alarm-environment);
TYPE
. "message_format" (may be moved to alarm-environment);
VAR
. "sac_rac_table";
. "atc_table, binary search";
. "addressing_data";
. "atc_incarnation_data";
. "error_handling_data";
. "input_semaphore";
BEGIN
. "initialization";
. REPEAT
. "collect a buffer on the input_semaphore, and
. "handle the message in the buffer, corresponding to the
. operation_code, and produce resulting messages";
. "for each resulting message do addressing/indexing
. do supervising and signal each of the buffers to the
. corresponding input_semaphore";
. UNTIL forever;
END;
(end of pseudo_code)
*)
\f
(* ------------------------------------------------------------------------
. Declaration part 1: sac_rac table and table control variables.
------------------------------------------------------------------------ *)
var
sac_rac_tbl : sac_rac_table
:= sac_rac_table( sac_rac_lth ***
sac_rac_tbl_entry ( sac_rac_entry( empty_addr, empty_addr ), false ) );
sac_rac_ix : sac_rac_range := 1;
sac_rac_top : upper_sac_rac_index := 0; (* Indicates the highest used sac_rac_index *)
\f
(* ------------------------------------------------------------------------
. Declaration part 2: ATC incarnation table and ATC shadow table and table
. control variables.
------------------------------------------------------------------------ *)
var
atc_tbl : atc_table
:= atc_table( atc_tbl_lth *** atc_description( 0, 1, 1, 0, poll_delay_time,
(..), stop_code, stop_code, 1 ) );
shadows : atc_shadow_table;
atc_tbl_ix : atc_table_range := 1;
atc_tbl_top : upper_atc_tbl_index := 0;
\f
(* ------------------------------------------------------------------------
. Declaration part 3: resource handling.
------------------------------------------------------------------------ *)
var
main_wait : (
idle_main ,
busy_main ,
busy_pool ) := idle_main;
claim_level : atc_inc_claim := claim_none;
resource_claims : integer := 0;
queue_lth : byte := 0;
aux_msg ,
working_0404_msg ,
working_0608_msg : reference;
\f
(* ------------------------------------------------------------------------
. Declaration part 4: main part.
------------------------------------------------------------------------ *)
type
route_vector = array( netc_route..netc_route1 ) of byte;
const
route_vct = route_vector( at_route, at_route1 );
var
main_msg : reference;
result_code : result_range := accepted;
atc_name : alfa;
atc_no : integer := at_addr_limit;
alfa_pos : 1..alfalength := 1;
\f
(* ------------------------------------------------------------------------
. Declaration part 5: supervision.
------------------------------------------------------------------------ *)
var
book_up_pool : pool 1 of updates;
time_out_pool : pool 1 of integer;
book_up_msg ,
time_out_msg : reference;
node_test_freq : integer := max_int;
traffic_test_freq : integer := max_int;
nt_time_out : boolean := false;
dc_disconnect : boolean := true;
\f
(* ------------------------------------------------------------------------
. Declaration part 6: miscellaneous.
------------------------------------------------------------------------ *)
var
(*q test : boolean := false; q*)
z : zone;
\f
(* ------------------------------------------------------------------------
. Declaration part 7: Externals.
------------------------------------------------------------------------ *)
process atconnector(
op_sem : sempointer;
var
main_sem ,
queue_sem : !ts_pointer;
var
ath_sem ,
driversem ,
com_pool : !sempointer;
var
actual_activity : !connector_state;
var
poll_delay : !integer;
var
traffic_test_freq : !integer;
var
traffic_counter : integer;
var
own_dc ,
own_ts : !macroaddr;
ownaddr : !integer;
channelno : !byte
);
external;
\f
procedure book_up(
var
time_out_msg ,
book_up_msg : reference;
seconds : integer
);
(* -----------------------------------------------------------------------
----------------------------------------------------------------------- *)
begin
if not nil( book_up_msg ) then
begin
lock book_up_msg as locvar: updates do
with locvar do
count:= seconds
;
if nil( time_out_msg ) then
begin
book_up_msg^.u1:= update_req;
book_up_msg^.u4:= #hc4
end
else
begin
book_up_msg^.u1:= book_req;
book_up_msg^.u4:= #hc3;
push( time_out_msg, book_up_msg )
end;
signal( book_up_msg, sem( timeout_sem_no ).s^ )
end
end; (* procedure book_up *)
\f
function get_message(
var
msg : reference;
route ,
opc : byte;
noofbytes : integer;
rec_macro : macroaddr;
rec_micro : integer;
upd : update_range;
res : result_range
): boolean;
(* -----------------------------------------------------------------------
. Function : Returns as true with a message, supplied with a fully
. updated alarmlabel, if one is available on the
. semaphore, that holds the vacant resources, and if
. no messages are hanging on the main semaphore.
----------------------------------------------------------------------- *)
begin
if passive( sem( ath_sem_no ).w^ ) then
begin
sensesem( msg, sem( com_pool ).w^ );
if not nil( msg ) then
lock msg as locvar: alarmlabel do
with msg^, locvar do
begin
u3:= route;
u4:= opc;
no_of_by:= label_size + noofbytes;
rec.macro:= rec_macro;
rec.micro:= rec_micro;
send.macro:= own_address;
send.micro:= ath_mic_addr;
update:= upd;
result:= res;
main_wait:= idle_main
end
else
main_wait:= busy_pool
end
else
main_wait:= busy_main
;
get_message:= not nil( msg )
end; (* function get_message *)
\f
function foreign_nc(
node_address : macroaddr
): boolean;
(* -----------------------------------------------------------------------
. Function : Returns as true if - in the alarm net hierarchy - the node
. in question is a foreign NC or located below a foreign NC.
----------------------------------------------------------------------- *)
begin
with node_address do
foreign_nc:= ( dc_addr <> own_address.dc_addr )
or
( nc_addr <> own_address.nc_addr )
end; (* function foreign_nc *)
\f
function acting_ac(
sac_rac_ix : sac_rac_range
): alarmnetaddr;
(* -----------------------------------------------------------------------
. function : Returns with the alarm net address of the AC that
. for the moment is functioning as receiver/sender at the
. entry in sac_rac table indicated by sac_rac_ix.
----------------------------------------------------------------------- *)
begin
with sac_rac_tbl( sac_rac_ix ).sac_rac_e do
if ( substitute_ac_addr <> empty_addr ) then
acting_ac:= substitute_ac_addr
else
acting_ac:= usual_ac_addr
end; (* function acting_ac *)
\f
function search_sac_rac(
ac_address : alarmnetaddr;
var
sac_rac_ix : sac_rac_range
): boolean;
(* -----------------------------------------------------------------------
. function : Searches the sac_rac table for an entry, where
. ac_address is the functioning AC.
----------------------------------------------------------------------- *)
begin
sac_rac_ix:= 1;
while ( acting_ac( sac_rac_ix ) <> ac_address ) and ( sac_rac_ix < sac_rac_top ) do
sac_rac_ix:= sac_rac_ix + 1;
search_sac_rac:= acting_ac( sac_rac_ix ) = ac_address
end; (* function search_sac_rac *)
\f
(*------------ atc_tbl-part ------------*)
function find_atc_tbl_entry(
mic_addr : integer;
var
atc_tbl_ix : atc_table_range
): boolean;
(* ----------------------------------------------------------------------
. This function returns the index of the element with the given micro address.
. If not found, then the index is the place of the new element.
. The search strategy is a binary search in an ordered list of
. elements. The smallest element has the index = 1.
. Error - will not appear.
----------------------------------------------------------------------- *)
VAR
low, mid : atc_table_range;
BEGIN
if ( atc_tbl_top > 0 ) then
begin (* now the search is started *)
low := 1;
atc_tbl_ix:= atc_tbl_top;
while ( atc_tbl( atc_tbl_ix ).atc_mic_addr > mic_addr ) and ( ( atc_tbl_ix - low ) > 0 ) do
begin
mid:= ( atc_tbl_ix - low ) div 2 + low;
if ( atc_tbl( mid ).atc_mic_addr < mic_addr ) then
low:= mid + 1
else
atc_tbl_ix:= mid
end;
if ( atc_tbl( atc_tbl_ix ).atc_mic_addr <> mic_addr ) then
begin
find_atc_tbl_entry:= false;
atc_tbl_ix:= atc_tbl_ix + ord( atc_tbl( atc_tbl_ix ).atc_mic_addr < mic_addr )
end
else
find_atc_tbl_entry:= true
end
else
begin
find_atc_tbl_entry:= false;
atc_tbl_ix:= 1
end
end; (* find_atc_tbl_entry *)
\f
procedure place_atc_tbl_entry(
atc_tbl_ix : atc_table_range;
atc_mic : integer;
pac_index : sac_rac_range
);
(* ---------------------------------------------------------------------
. Function : Enters and initialize a new entry and re-arranges the
. table.
. Call only if there's room in the table and the position
. in the table is located.
----------------------------------------------------------------------- *)
var
work_ix : upper_atc_tbl_index;
work_entry : atc_description;
begin
work_entry:= atc_tbl( atc_tbl_top + 1 );
for work_ix:= atc_tbl_top downto atc_tbl_ix do
atc_tbl( work_ix + 1 ):= atc_tbl( work_ix );
atc_tbl( atc_tbl_ix ):= work_entry;
with atc_tbl( atc_tbl_ix ) do
begin
atc_mic_addr := atc_mic;
pac_ix := pac_index;
traffic_count:= 0;
delay:= poll_delay_time;
claim_set:= (..);
actual_activity:= stop_code;
wanted_activity := stop_code
end;
atc_tbl_top:= atc_tbl_top + 1
end (* place_atc_tbl_entry *);
\f
procedure del_atc_tbl_entry(
atc_tbl_ix : atc_table_range
);
(* ---------------------------------------------------------------------
. Function : Removes the entry and re-arranges the table.
. Call only if the entry in question is located.
---------------------------------------------------------------------- *)
var
work_entry : atc_description;
begin
if not nil( shadows( atc_tbl( atc_tbl_ix ).shad_ix ) ) then
remove( shadows( atc_tbl( atc_tbl_ix ).shad_ix ) );
work_entry:= atc_tbl( atc_tbl_ix );
while ( atc_tbl_ix < atc_tbl_top ) do
begin
atc_tbl( atc_tbl_ix ):= atc_tbl( atc_tbl_ix + 1 );
atc_tbl_ix:= atc_tbl_ix + 1
end;
atc_tbl( atc_tbl_top ):= work_entry;
atc_tbl_top := atc_tbl_top - 1
end (* del_atc_tbl_entry *);
\f
procedure decrease_claims(
var
claim_set : atc_claim_set;
msg_kind : atc_inc_claim
);
(* -----------------------------------------------------------------------
----------------------------------------------------------------------- *)
begin
if msg_kind in claim_set then
begin
claim_set:= claim_set - (.msg_kind.);
resource_claims:= resource_claims - 1
end
end; (* procedure decrease_claims *)
\f
procedure increase_claims(
first_ix ,
last_ix : atc_table_range;
msg_kind : atc_inc_claim
);
(* -----------------------------------------------------------------------
----------------------------------------------------------------------- *)
begin
for first_ix:= first_ix to last_ix do
with atc_tbl( first_ix ) do
if not ( msg_kind in claim_set ) then
begin
claim_set:= claim_set + (.msg_kind.);
resource_claims:= resource_claims + 1
end
;
if ( msg_kind > claim_level ) then
claim_level:= msg_kind
end; (* procedure increase_claims *)
\f
procedure atc_stop_poll(
first_ix : atc_table_range;
last_ix : upper_atc_tbl_index
);
(* -----------------------------------------------------------------------
----------------------------------------------------------------------- *)
var
msg : reference;
begin
if ( first_ix <= last_ix ) then
repeat
with atc_tbl( first_ix ), sac_rac_tbl( pac_ix ) do
if ( disconnected and ( actual_activity = start_code ) )
or
( dc_disconnect and ( actual_activity = service_code ) ) then
if get_message( msg, netc_route1, #h90, 0,
own_address, atc_mic_addr, stop_code, accepted ) then
begin
signal( msg, sem( ts_vect_ix ).s^ );
decrease_claims( claim_set, msg_0900_stop );
first_ix:= ( first_ix mod last_ix ) + 1
end
else
increase_claims( first_ix, last_ix, msg_0900_stop )
until ( first_ix = 1 ) or ( main_wait <> idle_main )
end; (* procedure atc_stop_poll *)
\f
procedure atc_start_poll(
first_ix : atc_table_range;
last_ix : upper_atc_tbl_index
);
(* -----------------------------------------------------------------------
----------------------------------------------------------------------- *)
var
msg : reference;
begin
if ( first_ix <= last_ix ) then
repeat
with atc_tbl( first_ix ), sac_rac_tbl( pac_ix ) do
if ( actual_activity <> break_code ) then
if ( actual_activity <> wanted_activity ) then
if ( ( not disconnected ) and ( wanted_activity = start_code ) )
or
( ( not dc_disconnect ) and ( wanted_activity = service_code ) ) then
if get_message( msg, netc_route1, #h90, 4, own_address, atc_mic_addr,
wanted_activity, accepted ) then
begin
lock msg as locvar: al_form_0900 do
with locvar do
begin
t_e_c_init:= 0;
frequence:= delay
end
;
signal( msg, sem( ts_vect_ix ).s^ );
decrease_claims( claim_set, msg_0900_start );
first_ix:= ( first_ix mod last_ix ) + 1
end
else
increase_claims( first_ix, last_ix, msg_0900_start )
until ( first_ix = 1 ) or ( main_wait <> idle_main )
end; (* procedure atc_start_poll *)
\f
procedure atc_supervise;
(* -----------------------------------------------------------------------
----------------------------------------------------------------------- *)
var
msg : reference;
begin
if ( atc_tbl_top > 0 ) then
begin
atc_tbl_ix:= 1;
repeat
with atc_tbl( atc_tbl_ix ) do
if ( actual_activity <> break_code ) then
begin
if ( traffic_count > 0 ) then (* - Traffic since the last test - *)
traffic_count:= 0
else
if ( traffic_count < 0 ) then
begin (* - No reaction on the last node test - *)
end
else
begin (* - No traffic since the last node test. Node test the ATC - *)
traffic_count:= -1;
if get_message( msg, netc_route1, #hc0, 0,
own_address, atc_mic_addr, read_code, accepted ) then
begin
signal( msg, sem( ts_vect_ix ).s^ );
decrease_claims( claim_set, msg_1200 );
atc_tbl_ix:= ( atc_tbl_ix mod atc_tbl_top ) + 1
end
else
increase_claims( atc_tbl_ix, atc_tbl_top, msg_1200 )
end
end
until ( atc_tbl_ix = 1 ) or ( main_wait <> idle_main )
end
end; (* procedure atc_supervise *)
\f
procedure ac_check_connection(
sac_rac_ix : sac_rac_range
);
(* -----------------------------------------------------------------------
. Function : Signals a check of the connection to an disconnected AC
. if there is a vacant resource.
----------------------------------------------------------------------- *)
var
msg : reference;
begin
with sac_rac_tbl( sac_rac_ix ) do
if disconnected then
if get_message( msg, at_route, #hc8, 0,
acting_ac( sac_rac_ix ).macro, acting_ac( sac_rac_ix ).micro, read_code, accepted ) then
signal( msg, sem( tssup_sem_no ).s^ )
end; (* procedure ac_check_connection *)
\f
begin
(*------------ main program ------------*)
testopen( z, own.incname, op_sem );
testout( z, version, ts_env_vers );
(*------------ initialisation ------------*)
for atc_tbl_ix:= 1 to atc_tbl_lth do
with atc_tbl( atc_tbl_ix ) do
begin
shad_ix:= atc_tbl_ix;
ts_vect_ix:= atc_sem_no + 2 * ( atc_tbl_ix - 1 )
end;
alloc( book_up_msg, book_up_pool, sem( ath_sem_no ).s^ );
with book_up_msg^ do
u3:= netc_route1;
lock book_up_msg as locvar: updates do
with locvar do
object:= ath_mic_addr;
alloc( time_out_msg, time_out_pool, sem( ath_sem_no ).s^ );
with time_out_msg^ do
begin
u1:= book_req;
u3:= netc_route1;
u4:= #hc2
end;
lock time_out_msg as locvar: integer do
locvar:= ath_mic_addr;
if ( link( "atconnector ", atconnector ) = accepted ) then
book_up( time_out_msg, book_up_msg, node_test_freq );
\f
repeat (* ......................... forever .............................. *)
repeat
case main_wait of
idle_main,
busy_main:
wait( main_msg, sem( ath_sem_no ).w^ )
;
busy_pool:
case waitsd( main_msg, sem( ath_sem_no ).w^, wait_sem_delay ) of
a_semaphore:
;
a_delay:
;
otherwise
end
;
otherwise
end
until not nil( main_msg )
;
result_code:= accepted;
(*q if test then testout(z,"main_msg u3:",main_msg^.u3);
if test then testout(z," u4:",main_msg^.u4); q*)
with main_msg^ do
case u3 (* this is the routings information *) of
(* And then we handle the message depending on the receiver address.
*)
dummy_route:
return( main_msg )
;
\f
at_route: (* Message from an ATC to be routed through ATH *)
begin
(*q if test then testout(z,"from an atc ",0); q*)
case u4 of (* Operation code *)
(* 00.01 - Log to PAC. Enter AC net addresses *)
#h01:
lock main_msg as locvar: al_form_0001 do
with locvar, al_label, aac_address do
if ( 0 < ts_add( 0 ) ) and ( ts_add( 0 ) <= sac_rac_top ) then
begin
rec:= acting_ac( ts_add( 0 ) );
if ( 0 < micro ) and ( micro <= sac_rac_top ) then
aac_address:= acting_ac( micro )
end
else
result_code:= unknown_receiver
;
(* 03.00 *)
(* 03.01 *)
(* 03.02 - Alarms. Enter AC address *)
#h30..#h32:
lock main_msg as locvar: alarmlabel do
with locvar do
begin
if ( ( 0 < ts_add( 0 ) ) and ( ts_add( 0 ) <= sac_rac_top ) ) then
rec:= acting_ac( ts_add( 0 ) )
else
result_code:= unknown_receiver;
(* inconsistency between ac_address table in ATC and sac_rac_table
- maybe because of a time dependent event *)
end
;
\f
(* 09.01 - Receipt for change of poll activity. Actual activity is modified of ATC. *)
#h91:
lock main_msg as locvar: al_form_0900 do
with locvar, al_label do
if find_atc_tbl_entry( send.micro, atc_tbl_ix ) then
if ( result = accepted ) then
with atc_tbl( atc_tbl_ix ), sac_rac_tbl( pac_ix ) do
begin
wanted_activity:= update;
if disconnected or dc_disconnect then
atc_stop_poll( atc_tbl_ix, atc_tbl_ix )
end
else
else
result_code:= unknown_sender
;
otherwise
(* Other operation code are passed uninspected and unaltered *)
end (* case u4 *)
;
if ( result_code <> accepted ) then
reject_message( main_msg,
sem( tssup_sem_no ).s, route_vct( u3 ), own_address, ath_mic_addr, result_code )
else
signal( main_msg, sem( tssup_sem_no ).s^ )
end (* Message from an ATC *)
;
\f
at_route1: (* Message from ATC to ATH *)
begin
case u4 of (* Operation code *)
(* 01.02 - Rejected message *)
#h12:
testout( z, "garb return ", u3 )
;
(* 04.05 - Receipt for group control. Dropped unless ATC says serious error *)
#h45:
lock main_msg as locvar: alarmlabel do
with locvar do
if not ( result in (.accepted, not_steering, unknown_sender.) ) then
begin
result_code:= result;
lock working_0404_msg as a_label: alarmlabel do
rec:= a_label.send
end
;
(* 09.01 - Receipt for modification of connector state. *)
#h91:
;
(* 12.15 - Receipt for completion of break routine. *)
#hcf:
lock main_msg as locvar: alarmlabel do
with locvar, send do
if find_atc_tbl_entry( micro, atc_tbl_ix ) then
begin
del_atc_tbl_entry( atc_tbl_ix );
end
;
otherwise
testout( z, "at_route1 ", u4 )
end
;
if ( result_code <> accepted ) then
signal( main_msg, sem( tssup_sem_no ).s^ )
else
return( main_msg )
end
;
\f
netc_route1: (* Message from TSS or from time out process to ATH *)
begin
case u4 of (* Operation code *)
(* 01.02 - Rejected message *)
#h12:
testout( z, "garb return ", u3 );
;
(* 02.00 - Broadcast. DC fall-out. *)
#h20:
lock main_msg as locvar: al_form_020_ do
with locvar, al_net_addr, macro do
if ( dc_addr <> own_address.dc_addr ) then
begin (* - Foreign DC - *)
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if ( acting_ac( sac_rac_ix ).macro.dc_addr <> own_address.dc_addr ) then
sac_rac_tbl( sac_rac_ix ).disconnected:= true
;
atc_stop_poll( 1, atc_tbl_top )
end
else
begin (* - Own DC - *)
dc_disconnect:= true;
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if foreign_nc( acting_ac( sac_rac_ix ).macro ) then
sac_rac_tbl( sac_rac_ix ).disconnected:= true
;
atc_stop_poll( 1, atc_tbl_top )
end
;
\f
(* 02.01 - Broadcast. DC re-established. *)
#h21:
lock main_msg as locvar: al_form_020_ do
with locvar, al_net_addr, macro do
if ( dc_addr <> own_address.dc_addr ) then
begin (* - Foreign DC - *)
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if ( acting_ac( sac_rac_ix ).macro.dc_addr <> own_address.dc_addr ) then
ac_check_connection( sac_rac_ix )
end
else
begin (* - Own DC - *)
if dc_disconnect then
if get_message( aux_msg, at_route, #hc8, 0,
dc_address, dc_erh_mic_addr, read_code, accepted ) then
signal( aux_msg, sem( tssup_sem_no ).s^ )
;
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if foreign_nc( acting_ac( sac_rac_ix ).macro ) then
ac_check_connection( sac_rac_ix )
end
;
\f
(* 02.02 - Broadcast. NC fall-out. *)
#h22:
lock main_msg as locvar: al_form_020_ do
with locvar, al_net_addr, macro do
if foreign_nc( macro ) then
begin (* - Foreign NC - *)
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if foreign_nc( acting_ac( sac_rac_ix ).macro ) then
sac_rac_tbl( sac_rac_ix ).disconnected:= true
;
atc_stop_poll( 1, atc_tbl_top )
end
else
begin (* - Own NC - *)
dc_disconnect:= true;
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if ( acting_ac( sac_rac_ix ).macro <> own_address ) then
sac_rac_tbl( sac_rac_ix ).disconnected:= true
;
atc_stop_poll( 1, atc_tbl_top )
end
;
\f
(* 02.03 - Broadcast. NC re-established. *)
#h23:
lock main_msg as locvar: al_form_020_ do
with locvar, al_net_addr, macro do
if foreign_nc( macro ) then
begin (* - Foreign NC - *)
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if foreign_nc( acting_ac( sac_rac_ix ).macro ) then
ac_check_connection( sac_rac_ix )
end
else
begin (* - Own NC - *)
if dc_disconnect then
if get_message( aux_msg, at_route, #hc8, 0,
dc_address, dc_erh_mic_addr, read_code, accepted ) then
signal( aux_msg, sem( tssup_sem_no ).s^ )
;
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to atc_tbl_top do
if ( acting_ac( sac_rac_ix ).macro <> own_address ) then
ac_check_connection( sac_rac_ix )
end
;
\f
(* 02.04 - Broadcast. TS fall-out. *)
#h24:
lock main_msg as locvar: al_form_020_ do
with locvar, al_net_addr do
begin
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if ( acting_ac( sac_rac_ix ).macro = macro ) then
sac_rac_tbl( sac_rac_ix ).disconnected:= true
;
atc_stop_poll( 1, atc_tbl_top )
end
;
\f
(* 02.05 - Broadcast. TS re-established. *)
#h25:
lock main_msg as locvar: al_form_020_ do
with locvar, al_net_addr do
begin
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if ( acting_ac( sac_rac_ix ).macro = macro ) then
ac_check_connection( sac_rac_ix )
end
;
\f
(* 02.06 - Broadcast. AC fall-out. *)
#h26:
begin
lock main_msg as locvar: al_form_020_ do
with locvar do
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if ( acting_ac( sac_rac_ix ) = al_net_addr ) then
sac_rac_tbl( sac_rac_ix ).disconnected:= true
;
atc_stop_poll( 1, atc_tbl_top )
end
;
\f
(* 02.07 - Broadcast. AC re-established. *)
#h27:
lock main_msg as locvar: al_form_020_ do
with locvar do
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if ( acting_ac( sac_rac_ix ) = al_net_addr ) then
ac_check_connection( sac_rac_ix )
;
\f
(* 04.04 - Group control is multiplied by ATH - if the sender is known *)
#h44:
if atc_tbl_top > 0 then
begin
lock main_msg as locvar: al_form_0404 do
with locvar, al_label do
if ( ( no_of_by - 4 ) > 0 ) and ( ( high_micro - low_micro ) > - 1 ) then
begin
if search_sac_rac( send, sac_rac_ix ) then
ts_add( 0 ):= sac_rac_ix
else
result_code:= unknown_sender
end
else
result_code:= data_inconsistent;
if ( result_code = accepted ) then
signal( main_msg, sem( ath_int1 ).s^ )
end
else
result_code:= unknown_receiver
;
\f
(* 06.00 - Creation of an ATC incarnation *)
#h60:
if ( atc_tbl_top < atc_tbl_lth ) then
begin
lock main_msg as locvar: al_form_0600 do
with locvar, al_label, atc_tbl_e do
if ( send.macro <> dc_address ) then
result_code:= forbidden
else
begin
if find_atc_tbl_entry( atc_mic, atc_tbl_ix ) then
result_code:= existing_entry
else
if ( pac_ix < 1 ) or ( sac_rac_top < pac_ix ) then
result_code:= out_of_range
else
begin
place_atc_tbl_entry( atc_tbl_ix, atc_mic, pac_ix );
(* calculate an unambigouos atc_name *)
atc_name:= "atc__ ";
atc_no:= atc_mic;
alfa_pos:= 8;
repeat
atc_name( alfa_pos ):= chr( atc_no mod 10 + ord( "0" ) );
atc_no:= atc_no div 10;
alfa_pos:= alfa_pos - 1
until ( alfa_pos = 4 );
(* Create and start the incarnation *)
with atc_tbl( atc_tbl_ix ) do
result_code:= create(
atc_name ,
atconnector(
op_sem ,
sem( ts_vect_ix ) ,
sem( ts_vect_ix + 1 ) ,
sem( ath_sem_no ).s ,
sem( lam_no + lam_sem_no ).s ,
sem( com_pool ).w ,
actual_activity ,
delay ,
node_test_freq ,
traffic_test_freq ,
dc_address ,
own_address ,
atc_mic ,
port_no
) ,
shadows( shad_ix ) ,
atc_size
);
if ( result_code = accepted ) then
start( shadows( atc_tbl( atc_tbl_ix ).shad_ix ), atc_pri )
else
begin
del_atc_tbl_entry( atc_tbl_ix );
result_code:= breaked
end
end
end
end
else
result_code:= no_room
;
\f
(* 06.08 - Remove ATC incarnation. *)
#h68:
lock main_msg as locvar: al_form_0608 do
with locvar, al_label, atc_tbl_e do
if ( send.macro <> dc_address ) then
result:= forbidden
else
if find_atc_tbl_entry( atc_mic, atc_tbl_ix ) then
del_atc_tbl_entry( atc_tbl_ix )
else
result_code:= not_found
;
\f
(* 10.10 - Operation on sac_rac table *)
#haa:
lock main_msg as locvar: al_form_1010 do
with locvar, al_label do
if ( send.macro <> dc_address ) then
result_code:= forbidden
else
if ( sac_rac_tbl_ix < 1 ) or ( sac_rac_lth < sac_rac_tbl_ix ) then
result_code:= out_of_range
else
case update of
read_code:
tbl_entry:= sac_rac_tbl( sac_rac_tbl_ix ).sac_rac_e
;
insert_code:
with sac_rac_tbl( sac_rac_tbl_ix ) do
begin
sac_rac_e:= tbl_entry;
disconnected:= true;
if ( sac_rac_tbl_ix > sac_rac_top ) then
sac_rac_top:= sac_rac_tbl_ix
;
ac_check_connection( sac_rac_tbl_ix )
end
;
remove_code:
with sac_rac_tbl( sac_rac_tbl_ix ) do
begin
sac_rac_e:= sac_rac_entry( empty_addr, empty_addr );
disconnected:= false;
if ( sac_rac_top = sac_rac_tbl_ix ) then
begin
while ( sac_rac_top > 1 ) and ( acting_ac( sac_rac_top ) = empty_addr ) do
sac_rac_top:= sac_rac_top - 1
;
if ( acting_ac( sac_rac_top ) = empty_addr ) then
sac_rac_top:= sac_rac_top - 1
end
end
;
otherwise
result_code:= unknown_update
end
;
\f
(* 12.00 - Node test. Check connection to disconnected DC and AC's. *)
#hc0:
begin
lock main_msg as locvar: al_form_1200 do
with locvar do
begin
node_test_freq:= master_time_out;
traffic_test_freq:= master_time_out + tolerance
end
;
book_up( time_out_msg, book_up_msg, node_test_freq );
if dc_disconnect then
if get_message( aux_msg, at_route, #hc8, 0,
dc_address, dc_erh_mic_addr, read_code, accepted ) then
signal( aux_msg, sem( tssup_sem_no ).s^ )
;
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
ac_check_connection( sac_rac_ix )
;
nt_time_out:= false;
atc_supervise
end
;
\f
(* 12.02 - Time out alarm on own TSS. Overtake the node test function.
- Disconnect DC and all AC's and stop all ATC's. *)
#hc2:
begin
book_up( main_msg, book_up_msg, node_test_freq );
if not nt_time_out then
begin
nt_time_out:= true;
dc_disconnect:= true;
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if ( acting_ac( sac_rac_ix ) <> empty_addr ) then
sac_rac_tbl( sac_rac_ix ).disconnected:= true
;
atc_stop_poll( 1, atc_tbl_top )
end
;
atc_supervise
end
;
\f
(* 12.03 *)
(* 12.04 - Returned book/update message from time out process *)
#hc3..#hc4:
book_up_msg :=: main_msg
;
(* 12.09 - Receipt for dummy alarm from PAC or from DC. *)
#hc9:
begin
lock main_msg as locvar: alarmlabel do
with locvar do
if ( send.macro = dc_address ) then
dc_disconnect:= false
else
if ( sac_rac_top > 0 ) then
for sac_rac_ix:= 1 to sac_rac_top do
if ( acting_ac( sac_rac_ix ) = send ) then
sac_rac_tbl( sac_rac_ix ).disconnected:= false
;
atc_start_poll( 1, atc_tbl_top )
end
;
\f
otherwise
reject_message( main_msg,
sem( tssup_sem_no ).s, route_vct( u3 ), own_address, ath_mic_addr, unknown_opcode )
end (* case u4 to ATH *)
;
if not nil( main_msg ) then
if main_msg^.u4 in (.#h12, #h20..#h27, #hc9.) then
return( main_msg )
else
receipt_message( main_msg, sem( tssup_sem_no ).s, route_vct( u3 ), 0, result_code )
end (* Message from TSS to ATH *)
;
\f
netc_route: (* Message to an ATC from TSS to be routed through ATH *)
begin
(*q if test then testout(z,"to an atc ",0); q*)
if atc_tbl_top > 0 then
lock main_msg as locvar: alarmlabel do
with locvar do
if find_atc_tbl_entry( rec.micro, atc_tbl_ix ) then
with atc_tbl( atc_tbl_ix ) do
if ( actual_activity <> break_code ) then
case u4 of (* Operation code *)
(* 04.00 - Control. Find index of AC in sac_rac table. *)
#h40:
begin
if ( acting_ac( pac_ix ) <> send ) then
begin
if search_sac_rac( send, sac_rac_ix ) then
result_code:= accepted
else
result_code:= unknown_sender
end
else
sac_rac_ix:= pac_ix;
if ( result_code = accepted ) then
ts_add( 0 ):= sac_rac_ix
end
;
(* 08.04 - Extern test. Check the legitimacy *)
#h84:
if ( acting_ac( pac_ix ) <> send ) then
result_code:= forbidden
else
ts_add( 0 ):= pac_ix
;
otherwise
(* Other operation codes are passed uninspected and unaltered *)
\f
end (* case operation code *)
else
result_code:= breaked
else
result_code:= not_found
else
result_code:= unknown_receiver
;
(* end - lock main_msg. end - with locvar, atc_tbl *)
if ( result_code <> accepted ) then
reject_message( main_msg,
sem( tssup_sem_no ).s, route_vct( u3 ), own_address, ath_mic_addr, result_code )
else
signal( main_msg, sem( atc_tbl( atc_tbl_ix ).ts_vect_ix ).s^ )
end (* Message from TSS to an AT *)
;
otherwise (* Unknown route *)
begin
(*q test := not test;
if test then testout(z,"starttestout",0);
if not test then testout(z,"stop testout",0); q*)
reject_message( main_msg,
sem( tssup_sem_no ).s, at_route, own_address, ath_mic_addr, unknown_route )
end
;
end (* case route - with main_msg^ *)
until forever
end (* process at_handler *).
«eof»