|
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»