| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // 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_RendezvousClient_Functions |
| // |
| // Purpose: |
| // Creates and manages a RendezvousClient that can connect to RendezvousServer. |
| // |
| // Module depends on: |
| // <EPTF_CLL_Common_Definitions> |
| // <EPTF_CLL_Base_Functions> |
| // <EPTF_CLL_Semaphore_Functions> |
| // <EPTF_CLL_Logging_Definitions> |
| // <EPTF_CLL_Logging_Functions> |
| // <EPTF_CLL_FQB_Functions> |
| // <EPTF_CLL_Rendezvous_Definitions> |
| // |
| // Module Parameters: |
| // tsp_debug_EPTF_Rendezvous_Client_Functions - boolean |
| // |
| // Current Owner: |
| // Bence Molnar (EBENMOL) |
| // |
| // Last Review Date: |
| // 2009-06-08 |
| // |
| // Detailed Comments: |
| // Creates and manages a RendezvousClient that can connect to RendezvousServer. |
| // |
| // <f_EPTF_RendezvousClient_init_CT> - Function to initialize Rendezvous Client CT. |
| // |
| // <f_EPTF_RendezvousClient_cleanup_CT> - Function to stop Rendezvous Client CT. |
| // |
| // <f_EPTF_RendezvousClient_StartWaitForATrigger> - Function to send a WaitForATrigger type request. |
| // |
| // <f_EPTF_RendezvousClient_StartWaitForNTrigger> - Function to send a WaitForNTrigger type request. |
| // |
| // <f_EPTF_RendezvousClient_WaitForResponse> - Function to wait for the WaitForATrigger type response message. |
| // |
| // <as_EPTF_RendezvousClient_receiveMessage> - Default altstep for receiving messages |
| // |
| /////////////////////////////////////////////////////////// |
| |
| module EPTF_CLL_RendezvousClient_Functions |
| { |
| |
| import from EPTF_CLL_Common_Definitions all; |
| import from EPTF_CLL_Base_Functions all; |
| import from EPTF_CLL_Semaphore_Functions all; |
| import from EPTF_CLL_Logging_Definitions all; |
| import from EPTF_CLL_Logging_Functions all; |
| import from EPTF_CLL_FBQ_Functions all; |
| import from EPTF_CLL_Rendezvous_Definitions all; |
| |
| modulepar boolean tsp_debug_EPTF_RendezvousClient_Functions := false; |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_init_CT() |
| // |
| // Purpose: |
| // Function to initialize Rendezvous Client |
| // |
| // Parameters: |
| // pl_selfName - *in* *charstring* - the name of the Rendezvous Client |
| // pl_server - *in* <EPTF_Rendezvous_CT> - the Rendezvous Server component |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function initializes the Rendezvous Client CT. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| public function f_EPTF_RendezvousClient_init_CT(in charstring pl_selfName, in |
| |
| EPTF_Rendezvous_CT pl_server) runs on EPTF_RendezvousClient_CT { |
| if (v_EPTF_RendezvousClient_initialized) { |
| return; // already initialized |
| } |
| f_EPTF_Base_init_CT(pl_selfName); |
| |
| f_EPTF_Semaphore_init_CT(pl_selfName); |
| |
| f_EPTF_Logging_init_CT(pl_selfName); |
| v_RendezvousClient_loggingMaskId := f_EPTF_Logging_registerComponentMasks(tsp_EPTF_RendezvousClient_loggingComponentMask, c_EPTF_Rendezvous_loggingEventClasses, EPTF_Logging_CLL); |
| if(tsp_debug_EPTF_RendezvousClient_Functions) { |
| f_EPTF_Logging_enableLocalMask(v_RendezvousClient_loggingMaskId, c_EPTF_Rendezvous_loggingClassIdx_Debug); |
| } else { |
| f_EPTF_Logging_disableLocalMask(v_RendezvousClient_loggingMaskId, c_EPTF_Rendezvous_loggingClassIdx_Debug); |
| } |
| f_EPTF_RendezvousClient_debug("----- EPTF_RendezvousClient Init "&pl_selfName&" -----"); |
| |
| f_EPTF_FBQ_initFreeBusyQueue(v_EPTF_RendezvousClient_ActionQueue); |
| |
| v_EPTF_RendezvousClient_Server:= pl_server; |
| connect(self:EPTF_RendezvousClient_Port_CP, v_EPTF_RendezvousClient_Server:EPTF_RendezvousServer_Port_CP); |
| |
| v_EPTF_RendezvousClient_initialized:=true; |
| f_EPTF_Base_registerCleanup(refers(f_EPTF_RendezvousClient_cleanup_CT)); |
| |
| v_EPTF_RendezvousClient_def:=activate(as_EPTF_RendezvousClient_receiveMessage()); |
| |
| f_EPTF_RendezvousClient_debug("----- EPTF_RendezvousClient Init "&pl_selfName&" Done -----"); |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_StartWaitForATrigger() |
| // |
| // Purpose: |
| // Function to send a WaitForATrigger type request |
| // |
| // Parameters: |
| // pl_rendezvousID - *in* *integer* - the ID of the rendezvous type |
| // |
| // Return Value: |
| // integer - the ID of the semaphore that can be waited for. |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function creates and sends a WaitForATrigger type request message to the rendezvous Server. This rendezvous type |
| // can be used by 2 clients. The function creates a semaphore, and returns its ID. |
| // This semaphore is used for blocking the execution until the response message arrives. |
| // The semaphore is locked until the response message arrives. When the response arrived the semaphore unlocks itself. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| public function f_EPTF_RendezvousClient_StartWaitForATrigger( |
| in integer pl_rendezvousID) runs on EPTF_RendezvousClient_CT return integer{ |
| |
| var integer pl_semaphore; |
| pl_semaphore:= f_EPTF_Semaphore_new(); |
| |
| var EPTF_Rendezvous_Msg v_client_req; |
| v_client_req:={ |
| Rendezvous_Client_Req:={ |
| rendezvousType:=WaitForATrigger,//0 |
| semaphoreID:=pl_semaphore, |
| rendezvousID:=pl_rendezvousID, |
| rendezvousParam:={}, |
| extendedRendezvousID := "" |
| } |
| }; |
| |
| EPTF_RendezvousClient_Port_CP.send(v_client_req); |
| |
| f_EPTF_RendezvousClient_debug("----- EPTF_RendezvousClient WaitForATrigger type message sent "); |
| |
| return pl_semaphore; |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_StartWaitForNTrigger() |
| // |
| // Purpose: |
| // Function to send a WaitForNTrigger type request |
| // |
| // Parameters: |
| // pl_rendezvousID - *in* *integer* - the ID of the rendezvous type |
| // pl_numberOfClients - *in* *integer* - the number of rendezvous clients |
| // |
| // Return Value: |
| // integer - the ID of the semaphore that can be waited for. |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function creates and sends a WaitForNTrigger type request message to the rendezvous Server. This rendezvous type |
| // can be used by pl_numberOfClients clients. The function creates a semaphore, and returns its ID. |
| // This semaphore is used for blocking the execution until the response message arrives. |
| // The semaphore is locked until the response message arrives. When the response arrived the semaphore unlocks itself. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| public function f_EPTF_RendezvousClient_StartWaitForNTrigger( |
| in integer pl_rendezvousID, |
| in integer pl_numberOfClients:=2) runs on EPTF_RendezvousClient_CT return integer{ |
| |
| //f_EPTF_Base_assert(" In WaitForNTrigger type rendezvous the number of clients must be more than 1 ",pl_numberOfClients>1); |
| |
| var integer pl_semaphore; |
| pl_semaphore:= f_EPTF_Semaphore_new(); |
| |
| var EPTF_Rendezvous_Msg v_client_req; |
| v_client_req:={ |
| Rendezvous_Client_Req:={ |
| rendezvousType:=WaitForNTrigger,//1 |
| semaphoreID:=pl_semaphore, |
| rendezvousID:=pl_rendezvousID, |
| rendezvousParam:={pl_numberOfClients}, |
| extendedRendezvousID := "" |
| } |
| }; |
| |
| EPTF_RendezvousClient_Port_CP.send(v_client_req); |
| |
| f_EPTF_RendezvousClient_debug("----- EPTF_RendezvousClient WaitForNTrigger type message sent "); |
| |
| return pl_semaphore; |
| } |
| |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_WaitForResponse() |
| // |
| // Purpose: |
| // Function to wait for the WaitForATrigger and WaitForNTrigger type response messages |
| // |
| // Parameters: |
| // pl_semaphore - *in* *integer* - the ID of the semaphore that can be waited for. |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function can be used for waiting the Response messages from the Rendezvous Server. |
| // The user should provide the ID of the semaphore returned by the function <f_EPTF_RendezvousClient_WaitForATrigger> or <f_EPTF_RendezvousClient_WaitForNTrigger>. |
| // The semaphore is locked and this function blocks the execution until the response message arrives. When the response arrived |
| // the semaphore unlocks itself and the function returns true. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| public function f_EPTF_RendezvousClient_WaitForResponse( |
| in integer pl_semaphore) runs on EPTF_RendezvousClient_CT return boolean |
| { |
| |
| if(f_EPTF_Semaphore_waitForUnlock(pl_semaphore)) |
| { |
| //never returned |
| return false; |
| } |
| |
| return true; |
| |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_SubscribeToState |
| // |
| // Purpose: |
| // Function to send a StateTrigger type request |
| // |
| // Parameters: |
| // pl_rendezvousID - *in* *charstring* - the ID of the rendezvous type |
| // pl_action - *in* *ft_EPTF_Rendezvous_NotifyAction* - action to take when triggering |
| // pl_permanentsubs - *in* *boolean* - True when the subscription should be permanent |
| // |
| // Return Value: |
| // - |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // Sends a subscription note to the Rendezvous server to a StateTrigger type of Rendezvous |
| // |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_RendezvousClient_SubscribeToState( |
| in charstring pl_rendezvousID, |
| in ft_EPTF_Rendezvous_NotifyAction pl_action, |
| in boolean pl_permanentsubs := false |
| ) runs on EPTF_RendezvousClient_CT{ |
| // you only need semaphore if you want to ask if there was a state change lately... |
| |
| var integer actionIdx := f_EPTF_FBQ_getOrCreateFreeSlot(v_EPTF_RendezvousClient_ActionQueue); |
| f_EPTF_FBQ_moveFromFreeToBusyTail(actionIdx,v_EPTF_RendezvousClient_ActionQueue); |
| v_EPTF_RendezvousClient_Actions[actionIdx] := pl_action; |
| |
| var EPTF_IntegerList rParams:=c_StateTrigger_InitinalParams; |
| rParams[c_StateTrigger_OPERATIONIDX] := c_StateTrigger_SUBSCRIBE; |
| rParams[c_StateTrigger_ACTIONIDX] := actionIdx; |
| if (pl_permanentsubs) { |
| rParams[c_StateTrigger_PARAMIDX] := c_StateTrigger_PERMANENTSUBS; |
| } |
| |
| var EPTF_Rendezvous_Msg v_client_req; |
| v_client_req:={ |
| Rendezvous_Client_Req:={ |
| rendezvousType:=StateTrigger, |
| semaphoreID:=-1, |
| rendezvousID:=-1, |
| rendezvousParam:= rParams, |
| extendedRendezvousID := pl_rendezvousID |
| } |
| }; |
| |
| EPTF_RendezvousClient_Port_CP.send(v_client_req); |
| f_EPTF_RendezvousClient_debug("----- EPTF_RendezvousClient StateTrigger type message sent "); |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_NewState |
| // |
| // Purpose: |
| // Function to send a StateTrigger type StateChange |
| // |
| // Parameters: |
| // pl_rendezvousID - *in* *charstring* - the ID of the rendezvous type |
| // pl_rendezvousID_int - *in* *integer* - additional optional data to send out to the clients |
| // |
| // Return Value: |
| // - |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // Triggers a StateChange |
| // |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_RendezvousClient_NewState( |
| in charstring pl_rendezvousID, |
| in integer pl_rendezvousID_int := -1 |
| ) runs on EPTF_RendezvousClient_CT{ |
| |
| var EPTF_IntegerList rParams:=c_StateTrigger_InitinalParams; |
| rParams[c_StateTrigger_OPERATIONIDX] := c_StateTrigger_NEWSTATE; |
| |
| var EPTF_Rendezvous_Msg v_client_req; |
| v_client_req:={ |
| Rendezvous_Client_Req:={ |
| rendezvousType:=StateTrigger, |
| semaphoreID:=-1, |
| rendezvousID:=pl_rendezvousID_int, |
| rendezvousParam:=rParams, |
| extendedRendezvousID := pl_rendezvousID |
| } |
| }; |
| |
| EPTF_RendezvousClient_Port_CP.send(v_client_req); |
| f_EPTF_RendezvousClient_debug("----- EPTF_RendezvousClient StateTrigger type message sent "); |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_Unsubscribe |
| // |
| // Purpose: |
| // Function to send a StateTrigger type unsubscription |
| // |
| // Parameters: |
| // pl_rendezvousID - *in* *charstring* - the ID of the rendezvous type |
| // |
| // Return Value: |
| // - |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // Unsubscribes the client from a State. |
| // |
| /////////////////////////////////////////////////////////// |
| public function f_EPTF_RendezvousClient_Unsubscribe( |
| in charstring pl_rendezvousID |
| ) runs on EPTF_RendezvousClient_CT{ |
| |
| var EPTF_IntegerList rParams:=c_StateTrigger_InitinalParams; |
| rParams[c_StateTrigger_OPERATIONIDX] := c_StateTrigger_UNSUBS; |
| |
| var EPTF_Rendezvous_Msg v_client_req; |
| v_client_req:={ |
| Rendezvous_Client_Req:={ |
| rendezvousType:=StateTrigger, |
| semaphoreID:=-1, |
| rendezvousID:=-1, |
| rendezvousParam:=rParams, |
| extendedRendezvousID := pl_rendezvousID |
| } |
| }; |
| |
| EPTF_RendezvousClient_Port_CP.send(v_client_req); |
| f_EPTF_RendezvousClient_debug("----- EPTF_RendezvousClient StateTrigger type message sent "); |
| } |
| |
| |
| |
| /////////////////////////////////////////////////////////// |
| // Group: Private |
| // |
| // Purpose: |
| // Private functions. These functions must not be used by the user of <EPTF_RendezvousClient_CT> |
| // |
| // Elements: |
| /////////////////////////////////////////////////////////// |
| |
| group Private { |
| |
| ////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_cleanup_CT() |
| // |
| // Purpose: |
| // Function to shutdown Rendezvous Client |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This function stops the Rendezvous Client CT. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| private function f_EPTF_RendezvousClient_cleanup_CT() runs on EPTF_RendezvousClient_CT { |
| //log("----- RendezvousClient CLEANUP -------"); |
| if (v_EPTF_RendezvousClient_initialized == false) { |
| return; |
| } |
| disconnect(self:EPTF_RendezvousClient_Port_CP, v_EPTF_RendezvousClient_Server:EPTF_RendezvousServer_Port_CP); |
| |
| v_EPTF_RendezvousClient_initialized := false; |
| } |
| |
| ////////////////////////////////////////////////////////// |
| // Altstep: as_EPTF_RendezvousClient_receiveMessage() |
| // |
| // Purpose: |
| // Default altstep for receiving messages |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // - |
| // |
| // Errors: |
| // - (none) |
| // |
| // Detailed Comments: |
| // This altstep manages the Response messages arrived from the Rendezvous Server. |
| // If an <EPTF_Rendezvous_Msg> type response message arrives the altstep unlocks the blocking semaphore, |
| // and the execution can be continued. |
| // |
| /////////////////////////////////////////////////////////// |
| |
| private altstep as_EPTF_RendezvousClient_receiveMessage() runs on EPTF_RendezvousClient_CT |
| { |
| |
| var EPTF_Rendezvous_Msg v_rendezvousMsg; |
| var EPTF_Rendezvous_CT v_send; |
| |
| [] EPTF_RendezvousClient_Port_CP.receive(t_EPTF_Rendezvous_WaitForATrigger_Resp) -> value |
| v_rendezvousMsg |
| { |
| |
| if(v_rendezvousMsg.Rendezvous_Client_Resp.semaphoreID>=0) |
| { |
| f_EPTF_Semaphore_unlock(v_rendezvousMsg.Rendezvous_Client_Resp.semaphoreID); |
| } |
| repeat; |
| } |
| [] EPTF_RendezvousClient_Port_CP.receive(t_EPTF_Rendezvous_WaitForNTrigger_Resp) -> value |
| v_rendezvousMsg |
| { |
| |
| if(v_rendezvousMsg.Rendezvous_Client_Resp.semaphoreID>=0) |
| { |
| f_EPTF_Semaphore_unlock(v_rendezvousMsg.Rendezvous_Client_Resp.semaphoreID); |
| } |
| repeat; |
| } |
| [] EPTF_RendezvousClient_Port_CP.receive(t_EPTF_Rendezvous_StateTrigger_Resp) -> value |
| v_rendezvousMsg{ |
| f_EPTF_RendezvousClient_processStateResponse(v_rendezvousMsg); |
| repeat; |
| } |
| [] EPTF_RendezvousClient_Port_CP.receive(?) -> value v_rendezvousMsg sender v_send |
| { |
| f_EPTF_RendezvousClient_warning("Unexpected message has arrived from sender "&int2str(f_EPTF_Base_upcast(v_send))&", discarded"); |
| repeat; |
| } |
| } |
| |
| private function f_EPTF_RendezvousClient_processStateResponse(in EPTF_Rendezvous_Msg pl_msg) |
| runs on EPTF_RendezvousClient_CT{ |
| var integer actionIdx := pl_msg.Rendezvous_Client_Resp.rendezvousParam[c_StateTrigger_ACTIONIDX]; |
| if(pl_msg.Rendezvous_Client_Resp.rendezvousParam[c_StateTrigger_PARAMIDX] != c_StateTrigger_PERMANENTSUBS){ |
| f_EPTF_FBQ_moveFromBusyToFreeTail(actionIdx, v_EPTF_RendezvousClient_ActionQueue); |
| } |
| v_EPTF_RendezvousClient_Actions[actionIdx].apply(pl_msg.Rendezvous_Client_Resp.extendedRendezvousID, pl_msg.Rendezvous_Client_Resp.rendezvousID); |
| } |
| |
| group Logging { |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_error |
| // |
| // Purpose: |
| // Function to log an error from RendezvousClient feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_RendezvousClient_error(in charstring pl_message) |
| runs on EPTF_RendezvousClient_CT |
| { |
| f_EPTF_Logging_error(true, tsp_EPTF_RendezvousClient_loggingComponentMask&": "&pl_message); |
| f_EPTF_Base_stopAll(); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_warning |
| // |
| // Purpose: |
| // Function to log a warning from RendezvousClient feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_RendezvousClient_warning(in @lazy charstring pl_message) |
| runs on EPTF_RendezvousClient_CT |
| { |
| f_EPTF_Logging_warningV2(pl_message, v_RendezvousClient_loggingMaskId, {c_EPTF_Rendezvous_loggingClassIdx_Warning}); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_debug |
| // |
| // Purpose: |
| // Function to log a debug message from RendezvousClient feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_RendezvousClient_debug(in @lazy charstring pl_message) |
| runs on EPTF_RendezvousClient_CT |
| { |
| f_EPTF_Logging_debugV2(pl_message, v_RendezvousClient_loggingMaskId, {c_EPTF_Rendezvous_loggingClassIdx_Debug}); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_RendezvousClient_debugEnabled |
| // |
| // Purpose: |
| // Function to check if debug is enabled for RendezvousClient |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // *boolean* - true if debug enalbed |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_RendezvousClient_debugEnabled() |
| runs on EPTF_RendezvousClient_CT |
| return boolean |
| { |
| return f_EPTF_Logging_isEnabled(v_RendezvousClient_loggingMaskId, c_EPTF_Rendezvous_loggingClassIdx_Debug); |
| } |
| } // group Logging |
| |
| |
| } // group Private |
| |
| } // end of module |