[r5]: / Tags / The -Proxy- Pattern / Proxy_Application.project  Maximize  Restore  History

Download this file

233 lines (184 with data), 698.1 kB

VAR_GLOBAL
    globalSubjectInstance: Realsubject;
END_VAR

-------------------------------------------------------------------------------
Set_Method
-------------------------------------------------------------------------------


METHOD Set_Method: 

VAR_INPUT
    num: INT;
END_VAR

-------------------------------------------------------------------------------
Get_Method
-------------------------------------------------------------------------------


METHOD Get_Method: INT

-------------------------------------------------------------------------------
PLC_PRG
-------------------------------------------------------------------------------


PROGRAM PLC_PRG

VAR
    localSubjectInstance: Realsubject;
    ptrLocalSubject: pointer;
    ptrNullRealSubject: pointer;
    ptrProxy: pointer;
    iTempPasswordLocal: INT;
    iSetValueLocal: INT;
    bWriteRequest: BOOL;
    bReadRequest: BOOL;
    bReadWriteLocal: BOOL;
END_VAR

VAR_INPUT
    sTempSetLog: string;
    sTempGetLog: string;
    iGetValueLocal: INT;
END_VAR
//The Visualization element can send a GET/SET request with all its parameters.
//Once the request is received by the PLC_PRG, the PLC_PRG creates the Proxy object to delegate the request and subject's connection to it.
//The default password value for the request is: 1234. It is specified in the static field .iRealPassword of the Proxy class

//If a WRITE or SET request is received
IF	bWriteRequest
	THEN
	//We specify TRUE bReadWriteLocal because it is a SET request
	bReadWriteLocal := TRUE;
	//First we verify if the pointer to RealSubject to be used is a valid pointer
	IF ptrLocalSubject <> ptrNullRealSubject
		//If so, 
		THEN
		//The Proxy object is created with all its parameters passed by the PLC_PRG local variables.
		//As there is no "Method Overloading" options is CODESYS (Or at least the constructor cannot be overloaded) the constructor must receive and handle all the possible scenarios
		// .ptrToRealSubject is a Pointer to the RealSubject instance that we try to conncect to
		// .iTempPassword is the password passed by the client in the visualization element
		// .iSetValue is the value passed by the client to be SET on the RealSubject. If the request is a GET request, this value has no effect on the output of the connection.
		// .bReadWrite is the boolean value that specifies if the request is a SET or GET request
		ptrProxy := __NEW( Proxy( ptrToRealSubject := ptrLocalSubject, iTempPassword :=  iTempPasswordLocal, iSetValue := iSetValueLocal, bReadWrite := bReadWriteLocal));
		//Once the Proxy has made the response, the memory is released by deleting the Proxy object
		__DELETE(ptrProxy);
	END_IF
	
	//We delete the local value of last password for security reasons. This way for every request the client must input a password
	iTempPasswordLocal := 0;
	//Once the WRITE request has been handled, we toggle the variable to avoid double requests
	bWriteRequest := FALSE;
END_IF

//If a READ or GET request is received
IF	bReadRequest
	THEN
	//We specify FALSE bReadWriteLocal because it is a GET request
	bReadWriteLocal := FALSE;
	//First we verify if the pointer to RealSubject to be used is a valid pointer
	IF ptrLocalSubject <> ptrNullRealSubject
		//If so,
		THEN
		//The Proxy object is created with all its parameters passed by the PLC_PRG local variables.
		//As there is no "Method Overloading" options is CODESYS (Or at least the constructor cannot be overloaded) the constructor must receive and handle all the possible scenarios
		// .ptrToRealSubject is a Pointer to the RealSubject instance that we try to conncect to
		// .iTempPassword is the password passed by the client in the visualization element
		// .iSetValue is the value passed by the client to be SET on the RealSubject. If the request is a GET request, this value has no effect on the output of the connection.
		// .bReadWrite is the boolean value that specifies if the request is a SET or GET request
		ptrProxy := __NEW(Proxy(ptrToRealSubject := ptrLocalSubject, iTempPassword :=  iTempPasswordLocal, iSetValue := 0, bReadWrite := bReadWriteLocal));
		//Once the Proxy has made the response, the memory is released by deleting the Proxy object
		__DELETE(ptrProxy);	
	END_IF
	
	//We delete the local value of last password for security reasons. This way for every request the client must input a password
	iTempPasswordLocal := 0;
	//Once the READ request has been handled, we toggle the variable to avoid double requests
	bReadRequest := FALSE;
END_IF
-------------------------------------------------------------------------------
Realsubject
-------------------------------------------------------------------------------


FUNCTION_BLOCK Realsubject

VAR
    iProp: INT;
END_VAR

-------------------------------------------------------------------------------
Set_Method
-------------------------------------------------------------------------------


METHOD Set_Method: 

VAR_INPUT
    num: INT;
END_VAR
//Stores the value of the caller object on iProp variable. 

THIS^.iProp := num;
-------------------------------------------------------------------------------
Get_Method
-------------------------------------------------------------------------------


METHOD Get_Method: INT
//Asks for the value of the object's iProp variable and passes it to the caller

Get_Method := THIS^.iProp; 
-------------------------------------------------------------------------------
Proxy
-------------------------------------------------------------------------------


FUNCTION_BLOCK Proxy

VAR
    refToRealSubject: pointer;
    iTempPassword: INT;
END_VAR

VAR_GLOBAL
    iRealPassword: INT;
END_VAR

-------------------------------------------------------------------------------
Set_Method
-------------------------------------------------------------------------------


METHOD Set_Method: 

VAR_INPUT
    num: INT;
END_VAR
//Calls the Set_Method of the subject through the proxy to write the iProp field of the subject 
// thanks to the pointer reference saved in the field refToRealSubject of the proxy object.

THIS^.refToRealSubject^.Set_Method(num);

-------------------------------------------------------------------------------
Get_Method
-------------------------------------------------------------------------------


METHOD Get_Method: INT
//Calls the Get_Method of the subject through the proxy to read the iProp value of the subject 
// thanks to the pointer reference saved in the field refToRealSubject of the proxy object. 

Get_Method := THIS^.refToRealSubject^.Get_Method();


-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
    ptrToRealSubject: pointer;
    iTempPassword: INT;
    iSetValue: INT;
    bReadWrite: BOOL;
END_VAR
//Stores the address of the subject on a field in th Proxy.
THIS^.refToRealSubject := ptrToRealSubject;
//Stores the password value of the client on a field in the Proxy
THIS^.iTempPassword := iTempPassword;

//For security reasons, the Password passed by the client and the Proxi's connection password are compared
IF	THIS^.iTempPassword = THIS^.iRealPassword 
	//If the password sent by the client is correct,
	THEN
	//We verify is the request is a SET or GET request
	IF bReadWrite
		//If the request is a SET request: boolean value TRUE
		THEN
		//The Proxy passes the request to the subject
		THIS^.Set_Method(iSetValue);
		//Once the request is completed, the Proxy responds to the client that the request has been accepted
		PLC_PRG.sTempSetLog := 'Request "SET" accepted';
		//If the request is a GET request: boolean value FALSE
		ELSE
		//The Proxy passes the request to the subject
		PLC_PRG.iGetValueLocal:= THIS^.Get_Method();
		//Once the request is completed, the Proxy responds to the client that the request has been accepted
		PLC_PRG.sTempGetLog := 'Request "GET" accepted';
	END_IF
	
	//If the password sent by the client is incorrect
	ELSE 
	//We verify is the request is a SET or GET request
	IF bReadWrite
		//If the request is a SET request: boolean value TRUE
		THEN
		//The Proxy handles the bad request and response to the client without the subject intervention
		PLC_PRG.sTempSetLog := 'Request denied. Wrong password.';
		//If the request is a GET request: boolean value FALSE
		ELSE
		//The Proxy handles the bad request and response to the client without the subject intervention
		PLC_PRG.sTempGetLog := 'Request denied. Wrong password.';
	END_IF

END_IF