blob: 15340756f0e0c6cbbccaf05d7d95e527d9b16d8e [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// //
// 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