| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // Copyright (c) 2000-2019 Ericsson Telecom AB // |
| // // |
| // All rights reserved. This program and the accompanying materials // |
| // are made available under the terms of the Eclipse Public License v2.0 // |
| // which accompanies this distribution, and is available at // |
| // https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| /////////////////////////////////////////////////////////// |
| // Module: EPTF_CLL_Rendezvous_Functions |
| // |
| // Purpose: |
| // Creates and manages a RendezvousServer to provide synchronization among various entities. |
| // |
| // Module depends on: |
| // <EPTF_CLL_Base_Functions> |
| // <EPTF_CLL_Base_Definitions> |
| // <EPTF_CLL_HashMapInt2Int_Functions> |
| // <EPTF_CLL_Logging_Functions> |
| // <EPTF_CLL_Rendezvous_Definitions> |
| // <EPTF_CLL_FBQ_Definitions> |
| // <EPTF_CLL_FBQ_Functions> |
| // <EPTF_CLL_HashMap_Functions> |
| // |
| // Current Owner: |
| // Bence Molnar (EBENMOL) |
| // |
| // Last Review Date: |
| // 2009-06-08 |
| // |
| // Detailed Comments: |
| // Creates and manages a RendezvousServer to provide synchronization among various entities. |
| // |
| // <f_EPTF_Rendezvous_init_CT> - Function to initialize Rendezvous Server CT. |
| // |
| // <f_EPTF_Rendezvous_cleanup_CT> - Function to stop Rendezvous Server CT. |
| // |
| // <as_EPTF_RendezvousServer_main_CT> - Rendezvous server main altstep. |
| // |
| // <f_EPTF_RendezvousServer_processWaitForATrigger> - Function for processing the "Wait For A Trigger" type request messages. |
| // |
| // <f_EPTF_RendezvousServer_processWaitForNTrigger> - Function for processing the "Wait For N Trigger" type request messages. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| module EPTF_CLL_Rendezvous_Functions |
| { |
| |
| import from EPTF_CLL_Common_Definitions all; |
| import from EPTF_CLL_Base_Functions all; |
| import from EPTF_CLL_Base_Definitions all; |
| |
| import from EPTF_CLL_HashMapInt2Int_Functions all; |
| import from EPTF_CLL_HashMapStr2Int_Functions all; |
| |
| import from EPTF_CLL_Logging_Definitions all; |
| import from EPTF_CLL_Logging_Functions all; |
| import from EPTF_CLL_FBQ_Definitions all; |
| import from EPTF_CLL_FBQ_Functions all; |
| |
| //import from EPTF_CLL_FBQ_PrivateFunctions all; |
| |
| import from EPTF_CLL_Rendezvous_Definitions all; |
| |
| import from EPTF_CLL_HashMap_Functions all; |
| |
| modulepar boolean tsp_debug_EPTF_Rendezvous_Functions := false; |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_Rendezvous_init_CT() |
| // |
| // Purpose: |
| // Function to initialize Rendezvous Server |
| // |
| // Parameters: |
| // pl_selfName - *in* *charstring* - the name of the Rendezvous Server |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function initializes the Rendezvous Server CT. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| public function f_EPTF_Rendezvous_init_CT(in charstring pl_selfName) runs on EPTF_Rendezvous_CT { |
| if (v_EPTF_RendezvousServer_initialized) { |
| return; // already initialized |
| } |
| f_EPTF_Base_init_CT(pl_selfName); |
| |
| f_EPTF_HashMap_init_CT (pl_selfName); |
| |
| f_EPTF_FBQ_init_CT(pl_selfName); |
| |
| f_EPTF_Logging_init_CT(pl_selfName); |
| v_Rendezvous_loggingMaskId := f_EPTF_Logging_registerComponentMasks(tsp_EPTF_Rendezvous_loggingComponentMask, c_EPTF_Rendezvous_loggingEventClasses, EPTF_Logging_CLL); |
| if(tsp_debug_EPTF_Rendezvous_Functions) { |
| f_EPTF_Logging_enableLocalMask(v_Rendezvous_loggingMaskId, c_EPTF_Rendezvous_loggingClassIdx_Debug); |
| } else { |
| f_EPTF_Logging_disableLocalMask(v_Rendezvous_loggingMaskId, c_EPTF_Rendezvous_loggingClassIdx_Debug); |
| } |
| f_EPTF_Rendezvous_debug("----- EPTF_Rendezvous Init "&pl_selfName&" -----"); |
| |
| vg_EPTF_Rendezvous_Wait4TriggerLookupTable:= "Rendezvous_Wait4TriggerLookupTable" |
| vg_EPTF_Rendezvous_Wait4TriggerLookupTableID:=f_EPTF_int2int_HashMap_New (vg_EPTF_Rendezvous_Wait4TriggerLookupTable); |
| vg_EPTF_Rendezvous_Wait4NTriggerLookupTable:= "Rendezvous_Wait4NTriggerLookupTable" |
| vg_EPTF_Rendezvous_Wait4NTriggerLookupTableID:=f_EPTF_int2int_HashMap_New (vg_EPTF_Rendezvous_Wait4NTriggerLookupTable); |
| vg_EPTF_Rendezvous_StateTriggerLookupTable := "Rendezvous_StateTriggerLookupTable"; |
| vg_EPTF_Rendezvous_StateTriggerLookupTableID := f_EPTF_str2int_HashMap_New (vg_EPTF_Rendezvous_StateTriggerLookupTable); |
| |
| vg_EPTF_Rendezvous_freeBusyQueue := c_EPTF_emptyFreeBusyQueue; |
| f_EPTF_FBQ_initFreeBusyQueue(vg_EPTF_Rendezvous_freeBusyQueue); |
| f_EPTF_FBQ_initFreeBusyQueue(vg_EPTF_Rendezvous_StateTriggerQueue); |
| |
| v_EPTF_RendezvousServer_initialized:=true; |
| |
| f_EPTF_Base_registerCleanup(refers(f_EPTF_Rendezvous_cleanup_CT)); |
| |
| v_EPTF_RendezvousServer_def:=activate(as_EPTF_RendezvousServer_main_CT()); |
| |
| f_EPTF_Rendezvous_debug("----- EPTF_Rendezvous Init "&pl_selfName&" Done -----"); |
| |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Group: Private |
| // |
| // Purpose: |
| // Private functions. These functions must not be used by the user of <EPTF_Rendezvous_CT> |
| // |
| // Elements: |
| /////////////////////////////////////////////////////////// |
| |
| group Private { |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_Rendezvous_cleanup_CT() |
| // |
| // Purpose: |
| // Function to shutdown Rendezvous Server |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function stops the Rendezvous Server CT. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| private function f_EPTF_Rendezvous_cleanup_CT() runs on EPTF_Rendezvous_CT { |
| //log("----- RendezvousServer CLEANUP -------"); |
| if (v_EPTF_RendezvousServer_initialized == false) { |
| return; |
| } |
| |
| f_EPTF_int2int_HashMap_Delete(vg_EPTF_Rendezvous_Wait4TriggerLookupTable); |
| f_EPTF_int2int_HashMap_Delete(vg_EPTF_Rendezvous_Wait4NTriggerLookupTable); |
| f_EPTF_str2int_HashMap_Delete(vg_EPTF_Rendezvous_StateTriggerLookupTable); |
| |
| v_EPTF_RendezvousServer_initialized := false; |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Altstep: as_EPTF_RendezvousServer_main_CT() |
| // |
| // Purpose: |
| // Rendezvous server main altstep |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // Main behaviour of the rendezvous server. Waits for requests. If a request received, |
| // calls processing functions. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| private altstep as_EPTF_RendezvousServer_main_CT() runs on EPTF_Rendezvous_CT { |
| |
| var EPTF_RendezvousClient_CT v_send; |
| var EPTF_Rendezvous_Msg v_rendezvousMsg; |
| |
| [] EPTF_RendezvousServer_Port_CP.receive(t_EPTF_Rendezvous_WaitForATrigger) -> value v_rendezvousMsg sender v_send{ |
| f_EPTF_RendezvousServer_processWaitForATrigger(v_send,v_rendezvousMsg); |
| repeat; |
| } |
| [] EPTF_RendezvousServer_Port_CP.receive(t_EPTF_Rendezvous_WaitForNTrigger) -> value v_rendezvousMsg sender v_send{ |
| f_EPTF_RendezvousServer_processWaitForNTrigger(v_send,v_rendezvousMsg); |
| repeat; |
| } |
| [] EPTF_RendezvousServer_Port_CP.receive(t_EPTF_Rendezvous_StateTrigger) -> value v_rendezvousMsg sender v_send{ |
| f_EPTF_RendezvousServer_processStateTrigger(v_send, v_rendezvousMsg); |
| repeat; |
| } |
| [] EPTF_RendezvousServer_Port_CP.receive(?) -> value v_rendezvousMsg sender v_send{ |
| f_EPTF_Rendezvous_warning("Unexpected message has arrived from sender "&int2str(f_EPTF_Base_upcast(v_send))&", discarded"); |
| repeat; |
| } |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousServer_processWaitForATrigger() |
| // |
| // Purpose: |
| // Function for processing the "Wait For A Trigger" type request messages |
| // |
| // Parameters: |
| // pl_send - *in* <EPTF_RendezvousClient_CT> - the name of the Rendezvous Client who sends the request |
| // pl_rendezvousMsg - *in* <EPTF_Rendezvous_Msg> - the request message sent by the Rendezvous Client |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function processes "Wait For A Trigger" type rendezvous. |
| // Function check whether the requested rendezvous type ID exists. If the ID exists server sends a response out. |
| // If the ID not exists it stores the rendezvous type ID and the ID of the sender in a HashMap and do nothing. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| private function f_EPTF_RendezvousServer_processWaitForATrigger( |
| in EPTF_RendezvousClient_CT pl_send, |
| in EPTF_Rendezvous_Msg pl_rendezvousMsg) runs on EPTF_Rendezvous_CT { |
| //log("----- RendezvousServer_processWaitForATrigger -------",pl_rendezvousMsg); |
| |
| var integer vl_semaphoreID; |
| var integer vl_rendezvousID; |
| var integer vl_senderID; |
| var EPTF_Base_CT vl_requestor; |
| var integer vl_requestorID; |
| |
| vl_semaphoreID := pl_rendezvousMsg.Rendezvous_Client_Req.semaphoreID; |
| vl_rendezvousID := pl_rendezvousMsg.Rendezvous_Client_Req.rendezvousID; |
| |
| //find if rendezvous ID exist |
| if(f_EPTF_int2int_HashMap_Find(vg_EPTF_Rendezvous_Wait4TriggerLookupTableID,2*vl_rendezvousID,vl_requestorID)) |
| { |
| //log("-------RequestorID: ",vl_requestorID); |
| //if exists send response: |
| var EPTF_Rendezvous_Msg v_server_resp; |
| v_server_resp:={ |
| Rendezvous_Client_Resp:={ |
| rendezvousType:=WaitForATrigger,//0 |
| semaphoreID:=vl_semaphoreID, |
| rendezvousID:=vl_rendezvousID, |
| rendezvousParam:={}, |
| extendedRendezvousID := "" |
| } |
| }; |
| |
| var integer vl_requestor_semaphoreID; |
| if(not f_EPTF_int2int_HashMap_Find(vg_EPTF_Rendezvous_Wait4TriggerLookupTableID,2*vl_rendezvousID+1,vl_requestor_semaphoreID)) { |
| /*This can never happen*/ |
| } |
| |
| vl_requestor:=f_EPTF_Base_downcast(vl_requestorID); |
| EPTF_RendezvousServer_Port_CP.send(v_server_resp) to pl_send; |
| v_server_resp.Rendezvous_Client_Resp.semaphoreID := vl_requestor_semaphoreID; |
| EPTF_RendezvousServer_Port_CP.send(v_server_resp) to vl_requestor; |
| |
| //log("----- Response sent -------") |
| f_EPTF_int2int_HashMap_Erase(vg_EPTF_Rendezvous_Wait4TriggerLookupTableID,2*vl_rendezvousID); |
| f_EPTF_int2int_HashMap_Erase(vg_EPTF_Rendezvous_Wait4TriggerLookupTableID,2*vl_rendezvousID+1); |
| } |
| else |
| { |
| //if not exists store the ID: |
| vl_senderID:=f_EPTF_Base_upcast(pl_send); |
| f_EPTF_int2int_HashMap_Insert(vg_EPTF_Rendezvous_Wait4TriggerLookupTableID,2*vl_rendezvousID,vl_senderID); // even numbers store the vl_senderID |
| f_EPTF_int2int_HashMap_Insert(vg_EPTF_Rendezvous_Wait4TriggerLookupTableID,2*vl_rendezvousID+1,vl_semaphoreID);// odd numbers store the vl_semaphoreID |
| } |
| //log("----- RendezvousServer_processWaitForATrigger ends -------"); |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousServer_processWaitForNTrigger() |
| // |
| // Purpose: |
| // Function for processing the "Wait For N Trigger" type request messages |
| // |
| // Parameters: |
| // pl_send - *in* <EPTF_RendezvousClient_CT> - the name of the Rendezvous Client who sends the request |
| // pl_rendezvousMsg - *in* <EPTF_Rendezvous_Msg> - the request message sent by the Rendezvous Client |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function processes "Wait For N Trigger" type rendezvous. |
| // The function checks whether the requested rendezvous type ID exists. If the ID exists it checks whether all the clients |
| // sent their requests. If all the clients sent a request, the server sends responses out to the clients, else stores the client IDs. |
| // If the rendezvous type ID not exists it stores the rendezvous type ID and the ID of the sender. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| private function f_EPTF_RendezvousServer_processWaitForNTrigger( |
| in EPTF_RendezvousClient_CT pl_send, |
| in EPTF_Rendezvous_Msg pl_rendezvousMsg) runs on EPTF_Rendezvous_CT { |
| //log("----- RendezvousServer_processWaitForNTrigger -------",pl_rendezvousMsg); |
| |
| var integer vl_semaphoreID; |
| var integer vl_rendezvousID; |
| var integer vl_rendezvousParam; |
| var integer vl_senderID; |
| var EPTF_Base_CT vl_requestor; |
| var integer vl_waitForNTriggerID; |
| |
| vl_senderID:=f_EPTF_Base_upcast(pl_send); |
| vl_semaphoreID := pl_rendezvousMsg.Rendezvous_Client_Req.semaphoreID; |
| vl_rendezvousID := pl_rendezvousMsg.Rendezvous_Client_Req.rendezvousID; |
| vl_rendezvousParam := pl_rendezvousMsg.Rendezvous_Client_Req.rendezvousParam[0]; |
| |
| //find if rendezvous ID exist |
| if(f_EPTF_int2int_HashMap_Find(vg_EPTF_Rendezvous_Wait4NTriggerLookupTableID,vl_rendezvousID,vl_waitForNTriggerID)) |
| { |
| //if exists checks maxClients and registeredClients |
| //log("-------vl_rendezvousID exists: ",vl_rendezvousID," waitForNTriggerID: ",vl_waitForNTriggerID); |
| |
| var integer vl_maxClients := vg_WaitForNTriggerClients[vl_waitForNTriggerID].maxClients; |
| var integer vl_registeredClients := vg_WaitForNTriggerClients[vl_waitForNTriggerID].registeredClients; |
| //stores the ClientID and semaphoreID |
| if(vg_WaitForNTriggerClients[vl_waitForNTriggerID].maxClients<vl_rendezvousParam) |
| { |
| vg_WaitForNTriggerClients[vl_waitForNTriggerID].maxClients := vl_rendezvousParam; |
| } |
| vg_WaitForNTriggerClients[vl_waitForNTriggerID].registeredClients := vl_registeredClients + 1; |
| vg_WaitForNTriggerClients[vl_waitForNTriggerID].clientIDs[vl_registeredClients] := vl_senderID; |
| vg_WaitForNTriggerClients[vl_waitForNTriggerID].semaphoreIDs[vl_registeredClients] := vl_semaphoreID ; |
| //log("----- vg_WaitForNTriggerClients: ",vg_WaitForNTriggerClients[vl_waitForNTriggerID]); |
| |
| if(vl_maxClients <= vl_registeredClients + 1) |
| { |
| //if maxClients=registeredClients+1, send response to all clients, frees freebusyqueue and hashmap: |
| |
| for(var integer i:=0; i < vl_registeredClients + 1; i:=i+1) |
| { |
| var EPTF_Rendezvous_Msg v_server_resp; |
| v_server_resp:={ |
| Rendezvous_Client_Resp:={ |
| rendezvousType:=WaitForNTrigger,//1 |
| semaphoreID:=vg_WaitForNTriggerClients[vl_waitForNTriggerID].semaphoreIDs[i], |
| rendezvousID:=vl_rendezvousID, |
| rendezvousParam:={vl_rendezvousParam}, |
| extendedRendezvousID := "" |
| } |
| }; |
| vl_requestor:=f_EPTF_Base_downcast(vg_WaitForNTriggerClients[vl_waitForNTriggerID].clientIDs[i]); |
| EPTF_RendezvousServer_Port_CP.send(v_server_resp) to vl_requestor; |
| } |
| |
| //log("----- Response sent -------"); |
| f_EPTF_FBQ_moveFromBusyToFreeTail(vl_waitForNTriggerID,vg_EPTF_Rendezvous_freeBusyQueue); |
| f_EPTF_int2int_HashMap_Erase(vg_EPTF_Rendezvous_Wait4NTriggerLookupTableID,vl_rendezvousID); |
| } |
| } |
| else |
| { |
| //if not exists store the ID in hashmap, store the clientID in freebusyqueue: |
| //log("-----vl_rendezvousID not exists: ",vl_rendezvousID); |
| vl_waitForNTriggerID:=f_EPTF_FBQ_getOrCreateFreeSlot(vg_EPTF_Rendezvous_freeBusyQueue); |
| |
| vg_WaitForNTriggerClients[vl_waitForNTriggerID].maxClients := vl_rendezvousParam; |
| vg_WaitForNTriggerClients[vl_waitForNTriggerID].registeredClients := 1; |
| vg_WaitForNTriggerClients[vl_waitForNTriggerID].clientIDs[0] := vl_senderID; |
| vg_WaitForNTriggerClients[vl_waitForNTriggerID].semaphoreIDs[0] := vl_semaphoreID ; |
| //log("----- vg_WaitForNTriggerClients: ",vg_WaitForNTriggerClients[vl_waitForNTriggerID]); |
| |
| f_EPTF_int2int_HashMap_Insert(vg_EPTF_Rendezvous_Wait4NTriggerLookupTableID,vl_rendezvousID,vl_waitForNTriggerID); |
| f_EPTF_FBQ_moveFromFreeToBusyTail(vl_waitForNTriggerID,vg_EPTF_Rendezvous_freeBusyQueue); |
| |
| //logging freebusyqueue: f_EPTF_FBQ_logChain(busy_chain,vg_EPTF_Rendezvous_freeBusyQueue) |
| } |
| //log("----- RendezvousServer_processWaitForNTrigger ends -------"); |
| } |
| |
| private function f_EPTF_RendezvousServer_sendNotify(in charstring pl_rendezvousID, in integer pl_rendezvousID_int, |
| in integer pl_actionIdx, in integer pl_ClientIdx) runs on EPTF_Rendezvous_CT{ |
| var EPTF_IntegerList rParam := c_StateTrigger_InitinalParams; |
| rParam[c_StateTrigger_OPERATIONIDX] := c_StateTrigger_NOTIFY; |
| rParam[c_StateTrigger_ACTIONIDX] := vg_StateTriggerClients[pl_actionIdx].actionIDs[pl_ClientIdx]; |
| rParam[c_StateTrigger_PARAMIDX] := vg_StateTriggerClients[pl_actionIdx].paramList[pl_ClientIdx]; |
| var EPTF_Rendezvous_Msg v_server_resp; |
| v_server_resp:={ |
| Rendezvous_Client_Resp:={ |
| rendezvousType:=StateTrigger, |
| semaphoreID:= -1, |
| rendezvousID:= pl_rendezvousID_int, |
| rendezvousParam:=rParam, |
| extendedRendezvousID := pl_rendezvousID |
| } |
| }; |
| var EPTF_Base_CT vl_requestor:=f_EPTF_Base_downcast(vg_StateTriggerClients[pl_actionIdx].clientIDs[pl_ClientIdx]); |
| EPTF_RendezvousServer_Port_CP.send(v_server_resp) to vl_requestor; |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousServer_processStateTrigger() |
| // |
| // Purpose: |
| // Function for processing the "StateTrigger" type request messages |
| // |
| // Parameters: |
| // pl_send - *in* <EPTF_RendezvousClient_CT> - the name of the Rendezvous Client who sends the request |
| // pl_rendezvousMsg - *in* <EPTF_Rendezvous_Msg> - the request message sent by the Rendezvous Client |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_RendezvousServer_processStateTrigger( |
| in EPTF_RendezvousClient_CT pl_send, |
| in EPTF_Rendezvous_Msg pl_rendezvousMsg) runs on EPTF_Rendezvous_CT { |
| |
| var charstring vl_rendezvousID; |
| var integer vl_rendezvousID_int := pl_rendezvousMsg.Rendezvous_Client_Req.rendezvousID; |
| var EPTF_IntegerList vl_rParams; |
| var integer vl_senderID; |
| var EPTF_Base_CT vl_requestor; |
| var integer actionIdx := 0; |
| |
| vl_senderID:=f_EPTF_Base_upcast(pl_send); |
| vl_rendezvousID := pl_rendezvousMsg.Rendezvous_Client_Req.extendedRendezvousID; |
| vl_rParams := pl_rendezvousMsg.Rendezvous_Client_Req.rendezvousParam; |
| |
| if(vl_rParams[c_StateTrigger_OPERATIONIDX] == c_StateTrigger_SUBSCRIBE){ |
| if(f_EPTF_str2int_HashMap_Find(vg_EPTF_Rendezvous_StateTriggerLookupTableID,vl_rendezvousID,actionIdx)){ |
| // if action is present |
| var integer i:=0; |
| for (i:=0;i<vg_StateTriggerClients[actionIdx].registeredClients;i:=i+1){ // this could be slow when there are at least 6-10 registered clients |
| if(vg_StateTriggerClients[actionIdx].clientIDs[i]==vl_senderID){ |
| break; |
| } |
| } |
| if (i<vg_StateTriggerClients[actionIdx].registeredClients){ |
| // sender client is already registered |
| } else { |
| var integer vl_registeredClients := vg_StateTriggerClients[actionIdx].registeredClients; |
| vg_StateTriggerClients[actionIdx].registeredClients := vl_registeredClients + 1; |
| vg_StateTriggerClients[actionIdx].clientIDs[vl_registeredClients] := vl_senderID; |
| vg_StateTriggerClients[actionIdx].actionIDs[vl_registeredClients] := vl_rParams[c_StateTrigger_ACTIONIDX]; |
| vg_StateTriggerClients[actionIdx].paramList[vl_registeredClients] := vl_rParams[c_StateTrigger_PARAMIDX]; |
| } |
| } else { |
| // state is not present |
| actionIdx:=f_EPTF_FBQ_getOrCreateFreeSlot(vg_EPTF_Rendezvous_StateTriggerQueue); |
| vg_StateTriggerClients[actionIdx].fired := 0; |
| vg_StateTriggerClients[actionIdx].registeredClients := 1; |
| vg_StateTriggerClients[actionIdx].clientIDs[0] := vl_senderID; |
| vg_StateTriggerClients[actionIdx].actionIDs[0] := vl_rParams[c_StateTrigger_ACTIONIDX]; |
| vg_StateTriggerClients[actionIdx].paramList[0] := vl_rParams[c_StateTrigger_PARAMIDX]; |
| |
| f_EPTF_str2int_HashMap_Insert(vg_EPTF_Rendezvous_StateTriggerLookupTableID,vl_rendezvousID,actionIdx); |
| f_EPTF_FBQ_moveFromFreeToBusyTail(actionIdx,vg_EPTF_Rendezvous_StateTriggerQueue); |
| } |
| } else if(vl_rParams[c_StateTrigger_OPERATIONIDX] == c_StateTrigger_NEWSTATE){ |
| // NEWSTATE request |
| if(f_EPTF_str2int_HashMap_Find(vg_EPTF_Rendezvous_StateTriggerLookupTableID,vl_rendezvousID,actionIdx)){ |
| vg_StateTriggerClients[actionIdx].fired := vg_StateTriggerClients[actionIdx].fired + 1; |
| var integer vl_registeredClients := vg_StateTriggerClients[actionIdx].registeredClients; |
| var boolean hasPermanentClient := false; |
| for(var integer i:=0; i < vl_registeredClients; i:=i+1) |
| { |
| if (vg_StateTriggerClients[actionIdx].actionIDs[i] != -1){ // this means not disabled for sendign |
| f_EPTF_RendezvousServer_sendNotify(vl_rendezvousID, vl_rendezvousID_int, actionIdx, i); |
| // test is its a permanent sunscription or not; if not, have to disable it by actionIds |
| if(vg_StateTriggerClients[actionIdx].paramList[i] != c_StateTrigger_PERMANENTSUBS){ |
| vg_StateTriggerClients[actionIdx].actionIDs[i] := -1; |
| } else { |
| hasPermanentClient := true; |
| } |
| } |
| } |
| if(not hasPermanentClient){ |
| f_EPTF_FBQ_moveFromBusyToFreeTail(actionIdx,vg_EPTF_Rendezvous_StateTriggerQueue); |
| f_EPTF_str2int_HashMap_Erase(vg_EPTF_Rendezvous_StateTriggerLookupTableID,vl_rendezvousID); |
| } |
| } else { // no subscription to this state yet |
| var boolean vl_allowEarlyState := false; |
| if (vl_allowEarlyState){ |
| actionIdx:=f_EPTF_FBQ_getOrCreateFreeSlot(vg_EPTF_Rendezvous_StateTriggerQueue); |
| |
| vg_StateTriggerClients[actionIdx].fired := 1; |
| vg_StateTriggerClients[actionIdx].registeredClients := 0; |
| vg_StateTriggerClients[actionIdx].clientIDs := {}; |
| vg_StateTriggerClients[actionIdx].actionIDs := {}; |
| vg_StateTriggerClients[actionIdx].paramList := {}; |
| |
| f_EPTF_str2int_HashMap_Insert(vg_EPTF_Rendezvous_StateTriggerLookupTableID,vl_rendezvousID,actionIdx); |
| f_EPTF_FBQ_moveFromFreeToBusyTail(actionIdx,vg_EPTF_Rendezvous_StateTriggerQueue); |
| } |
| } |
| } if (vl_rParams[c_StateTrigger_OPERATIONIDX] == c_StateTrigger_UNSUBS){ |
| if(f_EPTF_str2int_HashMap_Find(vg_EPTF_Rendezvous_StateTriggerLookupTableID,vl_rendezvousID,actionIdx)){ |
| var boolean hasPermanentClient := false; |
| for (var integer i:=0;i<vg_StateTriggerClients[actionIdx].registeredClients;i:=i+1){ // this could be slow when there are at least 6-10 registered clients |
| if(vg_StateTriggerClients[actionIdx].clientIDs[i]==vl_senderID){ |
| vg_StateTriggerClients[actionIdx].actionIDs[i] := -1; |
| if (hasPermanentClient) {break;} |
| } |
| if (vg_StateTriggerClients[actionIdx].actionIDs[i] != -1){ hasPermanentClient := true; } |
| } |
| if(not hasPermanentClient){ |
| f_EPTF_FBQ_moveFromBusyToFreeTail(actionIdx,vg_EPTF_Rendezvous_StateTriggerQueue); |
| f_EPTF_str2int_HashMap_Erase(vg_EPTF_Rendezvous_StateTriggerLookupTableID,vl_rendezvousID); |
| } |
| } else { f_EPTF_Rendezvous_debug("Unknown ACTION on Rendezvous!"); return; } |
| } else { |
| f_EPTF_Rendezvous_debug("Unknown OPERATION on Rendezvous!"); |
| return; |
| } |
| } |
| |
| group Logging { |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_Rendezvous_error |
| // |
| // Purpose: |
| // Function to log an error from Rendezvous feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_Rendezvous_error(in charstring pl_message) |
| runs on EPTF_Rendezvous_CT |
| { |
| f_EPTF_Logging_error(true, tsp_EPTF_Rendezvous_loggingComponentMask&": "&pl_message); |
| f_EPTF_Base_stopAll(); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_Rendezvous_warning |
| // |
| // Purpose: |
| // Function to log a warning from Rendezvous feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_Rendezvous_warning(in @lazy charstring pl_message) |
| runs on EPTF_Rendezvous_CT |
| { |
| f_EPTF_Logging_warningV2(pl_message, v_Rendezvous_loggingMaskId, {c_EPTF_Rendezvous_loggingClassIdx_Warning}); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_Rendezvous_debug |
| // |
| // Purpose: |
| // Function to log a debug message from Rendezvous feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_Rendezvous_debug(in @lazy charstring pl_message) |
| runs on EPTF_Rendezvous_CT |
| { |
| f_EPTF_Logging_debugV2(pl_message, v_Rendezvous_loggingMaskId, {c_EPTF_Rendezvous_loggingClassIdx_Debug}); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_Rendezvous_debugEnabled |
| // |
| // Purpose: |
| // Function to check if debug is enabled for Rendezvous |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // *boolean* - true if debug enalbed |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_RendezvousdebugEnabled() |
| runs on EPTF_Rendezvous_CT |
| return boolean |
| { |
| return f_EPTF_Logging_isEnabled(v_Rendezvous_loggingMaskId, c_EPTF_Rendezvous_loggingClassIdx_Debug); |
| } |
| } // group Logging |
| |
| |
| } // group Private |
| |
| } // end of module |