blob: 7f5bcf269753b5bc5d09904a2ac6f9c494e531dc [file] [log] [blame]
[comment encoding = UTF-8 /]
[comment
-----------------------------------------------------------------------
-- Ada infrastructural code generator --
-- for the CHESS component model --
-- --
-- Copyright (C) 2011-2012 --
-- University of Padova, ITALY --
-- --
-- Author: Marco Panunzio panunzio@math.unipd.it --
-- --
-- All rights reserved. This program and the accompanying materials --
-- are made available under the terms of the Eclipse Public License --
-- v1.0 which accompanies this distribution, and is available at --
-- http://www.eclipse.org/legal/epl-v20.html --
-----------------------------------------------------------------------
/]
[module RemoteMsgClient('http://www.eclipse.org/uml2/3.0.0/UML', 'http://www.eclipse.org/papyrus/GCM/1')]
[import org::polarsys::chess::codegen::ada::main::Copyright /]
[import org::polarsys::chess::codegen::ada::middleware::CRClib /]
[template public generateRemoteMsgClient(model : Model, procNode: InstanceSpecification, compInstInputList : Sequence(OclAny), connectorInstInputList: Sequence(OclAny)) {
procNodeName : String = procNode.name;
clSvPortStName : String = 'MARTE::MARTE_DesignModel::GCM::ClientServerPort';
assignStName : String = 'MARTE::MARTE_Foundations::Alloc::Assign';
compImplStName : String = 'CHESS::ComponentModel::ComponentImplementation';
transmissionWithProtocolStName : String = 'CHESS::Dependability::MitigationMeans::TransmissionWithProtocol';
chHwProcessorStName : String = 'CHESS::Predictability::DeploymentConfiguration::HardwareBaseline::CH_HwProcessor';
isSingleNodeSystem : Boolean = isSingleNodeSystem(InstanceSpecification.allInstances()->asSequence(), chHwProcessorStName);
compInstList : Sequence(InstanceSpecification) = compInstInputList->filter(InstanceSpecification);
requiredInterfaceSlotList : Sequence(Slot) = getRequiredInterfaceSlotList(compInstList, clSvPortStName)->filter(Slot);
providedInterfaceSlotList : Sequence(Slot) = getProvidedInterfaceSlotList(compInstList, clSvPortStName)->filter(Slot);
connectorInstList : Sequence(InstanceSpecification) = connectorInstInputList->filter(InstanceSpecification);
remoteRIslotList : Sequence(Slot) = getRemoteRIslotList(requiredInterfaceSlotList, procNode, connectorInstList, Comment.allInstances()->asSequence(), assignStName)->filter(Slot);
isRemoteMsgClientNecessary : Boolean = isRemoteMsgClientNecessary(requiredInterfaceSlotList, procNode, connectorInstList, Comment.allInstances()->asSequence(), assignStName);
}
]
[comment RemoteMsgClient.ads /]
[if (isRemoteMsgClientNecessary)]
[file (procNodeName.concat('/middleware/src/remote_msg_client.ads').toLower(), false, 'UTF-8')]
[generateCopyrightAda(model)/]
[for (boundSlot : Slot | remoteRIslotList)]
with [getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/];
[/for]
with Datatype; use Datatype;
package Remote_Msg_Client is
[for (boundSlot : Slot | remoteRIslotList)]
function Get_[getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/] return [getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/].[getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/]_ptr;
[/for]
procedure Init_Remote_Msg_Client;
private
type Remote_Msg_Client_T is new [getProvidedInterface((remoteRIslotList->first().definingFeature.oclAsType(Port)), clSvPortStName).name/].[getProvidedInterface((remoteRIslotList->first().definingFeature.oclAsType(Port)), clSvPortStName).name/][for (boundSlot : Slot | remoteRIslotList->excluding(remoteRIslotList->first()))] and [getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/].[getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/][/for] with null record;
[for (boundSlot : Slot | remoteRIslotList)]
[for (op : Operation | getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).ownedOperation)]
[if not (isFunction(op))]
[if (op.ownedParameter->size() = 0)]
overriding
procedure [op.name /] (Self : in out Remote_Msg_Client_T);
[else]
overriding
procedure [op.name /] (Self : in out Remote_Msg_Client_T[for (par : Parameter | op.ownedParameter)];
[par.name/] : [par.direction/] [par.type.name/][/for]);
[/if]
[/if]
[/for]
[/for]
Remote_Msg_Client_T_inst0 : aliased Remote_Msg_Client_T;
end Remote_Msg_Client;
[/file]
[comment RemoteMsgClient.adb /]
[file (procNodeName.concat('/middleware/src/remote_msg_client.adb').toLower(), false, 'UTF-8')]
[generateCopyrightAda(model)/]
with Ada.Streams;
with YAMI.Core.Agents;
with YAMI.Core.Closed_Connection_Handlers;
with YAMI.Core.Message_Progress_Handlers;
with YAMI.Core.New_Connection_Handlers;
with YAMI.Parameters;
with Ada.Real_Time;
with Distribution_Naming_Data; use Distribution_Naming_Data;
with Ada.Text_IO;
with CRC_lib;
with Interfaces;
package body Remote_Msg_Client is
type New_Connection_Handler is
new YAMI.Core.New_Connection_Handlers.Handler with null record;
type Closed_Connection_Handler is
new YAMI.Core.Closed_Connection_Handlers.Handler with null record;
type Message_Progress_Handler is
new YAMI.Core.Message_Progress_Handlers.Handler with null record;
overriding
procedure New_Connection (H : in out New_Connection_Handler;
Source : in String;
Channel : in YAMI.Core.Channel_Descriptor);
overriding
procedure Closed_Connection (H : in out Closed_Connection_Handler;
Source : in String);
overriding
procedure Progress (H : in out Message_Progress_Handler;
Sent_Bytes : in Ada.Streams.Stream_Element_Count;
Total_Byte_Count : in Ada.Streams.Stream_Element_Count);
Client_Target : String (1 .. YAMI.Core.Agents.Max_Target_Length);
Client_Target_Last : Natural;
Closed_Connection_Called : Boolean := False;
pragma Volatile (Closed_Connection_Called);
Progress_Called : Boolean := False;
pragma Volatile (Progress_Called);
Call_Called : Boolean := False;
pragma Volatile (Call_Called);
procedure New_Connection (H : in out New_Connection_Handler;
Source : in String;
Channel : in YAMI.Core.Channel_Descriptor) is
begin
Client_Target_Last := Source'Length;
Client_Target (1 .. Client_Target_Last) := Source;
end New_Connection;
procedure Closed_Connection (H : in out Closed_Connection_Handler;
Source : in String) is
begin
pragma Assert (Source = Client_Target (1 .. Client_Target_Last));
Closed_Connection_Called := True;
end Closed_Connection;
procedure Progress (H : in out Message_Progress_Handler;
Sent_Bytes : in Ada.Streams.Stream_Element_Count;
Total_Byte_Count : in Ada.Streams.Stream_Element_Count) is
use type Ada.Streams.Stream_Element_Count;
begin
-- assume that the whole message fits in a single frame
-- and that the whole frame can be pushed as a single I/O operation
pragma Assert (Sent_Bytes = Total_Byte_Count);
pragma Assert (Sent_Bytes > 0);
Progress_Called := True;
end Progress;
My_New_Connection_Handler : aliased New_Connection_Handler;
My_Closed_Connection_Handler : aliased Closed_Connection_Handler;
My_Message_Progress_Handler : aliased Message_Progress_Handler;
Resolved_Target : String (1 .. YAMI.Core.Agents.Max_Target_Length);
Resolved_Target_Last : Natural := 21;
Timed_Out : Boolean;
Delay_Time : constant Ada.Real_Time.Time_Span := Ada.Real_Time.To_Time_Span(2.0);
Client_Agent : YAMI.Core.Agents.Agent;
Channel : YAMI.Core.Channel_Descriptor;
Outgoing_Header : YAMI.Parameters.Parameters_Collection;
Outgoing_Body : YAMI.Parameters.Parameters_Collection;
Created_New : Boolean;
procedure Init_Remote_Msg_Client is
use type YAMI.Parameters.Count_Type;
begin
Ada.Text_IO.Put_Line("Initializing Remote Msg Client...");
Resolved_Target (1 .. Resolved_Target_Last) := "tcp://127.0.0.1:12207";
YAMI.Core.Agents.Init_Agent(Client_Agent, null, null);
YAMI.Parameters.Init_Parameters(Outgoing_Header);
YAMI.Parameters.Init_Parameters(Outgoing_Body);
-- open new connection
Ada.Text_IO.Put_Line("Opening TCP channel...");
Client_Agent.Open
(Resolved_Target (1 .. Resolved_Target_Last),
Channel, Created_New);
Ada.Text_IO.Put_Line("Remote Msg Client initialized.");
end Init_Remote_Msg_Client;
[for (boundSlot : Slot | remoteRIslotList)]
function Get_[getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/] return [getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/].[getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/]_ptr is
begin
return Remote_Msg_Client_T_inst0'access;
end Get_[getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/];
[/for]
[for (boundSlot : Slot | remoteRIslotList)]
[for (op : Operation | getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).ownedOperation)]
--Sequence ID counter
[boundSlot.definingFeature.name/]_[op.name/]_Sequence_ID : Integer := 0;
[if (op.ownedParameter->size() = 0)]
overriding
procedure [op.name /] (Self : in out Remote_Msg_Client_T) is
[else]
overriding
procedure [op.name /] (Self : in out Remote_Msg_Client_T[for (par : Parameter | op.ownedParameter)];
[par.name/] : [par.direction/] [par.type.name/][/for]) is
[/if]
pragma Warnings (Off, Self);
begin
-- Preparing message for operation [getProvidedInterface((boundSlot.definingFeature.oclAsType(Port)), clSvPortStName).name/].[op.name/]
Outgoing_Header.Set_String("Source_Instance", "UNSUPPORTED_FEATURE");
[let useSequenceID : Boolean = useSequenceID(boundSlot, connectorInstList, Connector.allInstances()->asSequence(), transmissionWithProtocolStName)]
Outgoing_Header.Set_Boolean("Has_Sequence_ID", [useSequenceID/]);
[if useSequenceID]
-- Adding Sequence ID to the message header
Outgoing_Header.Set_Integer("Sequence_ID", YAMI.Parameters.YAMI_Integer([boundSlot.definingFeature.name/]_[op.name/]_Sequence_ID));
[boundSlot.definingFeature.name/]_[op.name/]_Sequence_ID := [boundSlot.definingFeature.name/]_[op.name/]_Sequence_ID + 1;
[/if]
[/let]
Outgoing_Body.Set_Integer("Destination_Instance_Name", Destination_Instance_Name'Pos([boundSlot.owningInstance.name.replaceAll('\\.','_')/]));
Outgoing_Body.Set_Integer("Instance_Operation_Name", Instance_Operation_Name'Pos([op.name/]));
[if (op.ownedParameter->size() > 0)]
[for (p : Parameter | op.ownedParameter)]
[if (p.type.name = 'Float')]
Outgoing_Body.Set_Long_Float("[p.name/]", YAMI.Parameters.YAMI_Long_Float([p.name/]));
[elseif (p.type.name = 'Integer')]
Outgoing_Body.Set_Integer("[p.name/]", YAMI.Parameters.YAMI_Integer([p.name/]));
[elseif (p.type.name = 'Boolean')]
Outgoing_Body.Set_Boolean("[p.name/]", [p.name/]);
[elseif (p.type->filter(Enumeration)->size() = 1)]
Outgoing_Body.Set_Integer("[p.name/]", YAMI.Parameters.YAMI_Integer'Pos([p.name/]));
[elseif (p.type->filter(DataType)->size() = 1)]
[for (pr : Property | p.type->filter(DataType).attribute)]
[if (p.type.name = 'Float')]
Outgoing_Body.Set_Long_Float("[p.name/].[pr.name/]", YAMI.Parameters.YAMI_Long_Float([p.name/].[pr.name/]));
[elseif (p.type.name = 'Integer')]
Outgoing_Body.Set_Integer("[p.name/].[pr.name/]", YAMI.Parameters.YAMI_Integer([p.name/].[pr.name/]));
[elseif (p.type.name = 'Boolean')]
Outgoing_Body.Set_Boolean("[p.name/].[pr.name/]", [p.name/].[pr.name/]);
[elseif (pr.type->filter(Enumeration)->size() = 1)]
Outgoing_Body.Set_Integer("[p.name/].[pr.name/]", YAMI.Parameters.YAMI_Integer([pr.type.name/]'Pos([p.name/].[pr.name/])));
[else]
Outgoing_Body.Set_Long_Float("[p.name/].[pr.name/]", YAMI.Parameters.YAMI_Long_Float([p.name/].[pr.name/]));
[/if]
[/for]
[/if]
[/for]
[/if]
[let CRClib : String = getCRClib(boundSlot, connectorInstList, Connector.allInstances()->asSequence(), transmissionWithProtocolStName)]
[if (CRClib = 'CRC32')]
Outgoing_Header.Set_Boolean("Has_Payload_CRC", true);
--Initialize CRC
CRC_lib.Init;
-- Updating CRC with values of destination and instance
CRC_lib.Update(Destination_Instance_Name'Pos([boundSlot.owningInstance.name/]));
CRC_lib.Update(Instance_Operation_Name'Pos([op.name/]));
[if (op.ownedParameter->size() > 0)]
-- Updating CRC with values of operation parameters
[for (p : Parameter | op.ownedParameter)]
[if (p.type.name = 'Float' or p.type.name = 'Integer' or p.type.name = 'Boolean')]
CRC_lib.Update([p.name/]);
[elseif (p.type->filter(Enumeration)->size() = 1)]
CRC_lib.Update([p.type/]'Pos([p.name/]));
[elseif (p.type->filter(DataType)->size() = 1)]
[for (pr : Property | p.type->filter(DataType).attribute)]
[if ((pr.type.name = 'Float') or (pr.type.name = 'Integer') or (pr.type.name = 'Boolean')) ]
CRC_lib.Update([p.name/].[pr.name/]);
[elseif (pr.type->filter(Enumeration)->size() = 1)]
CRC_lib.Update([pr.type.name/]'Pos([p.name/].[pr.name/]));
[else]
CRC_lib.Update(Float([p.name/].[pr.name/]));
[/if]
[/for]
[/if]
[/for]
[/if]
--Inserting CRC in message header
Ada.Text_IO.Put_Line("Payload_CRC: " & Interfaces.Unsigned_32'Image(CRC_lib.Get_Value));
Outgoing_Header.Set_String("Payload_CRC", Interfaces.Unsigned_32'Image(CRC_lib.Get_Value));
[else]
Outgoing_Header.Set_Boolean("Has_Payload_CRC", false);
[/if]
[/let]
-- Sending message
Client_Agent.Post
(Channel, Outgoing_Header, Outgoing_Body, 0,
My_Message_Progress_Handler'Unchecked_Access);
Client_Agent.Do_Some_Work (0.0, Timed_Out);
pragma Assert (not Timed_Out);
end [op.name/];
[/for]
[/for]
end Remote_Msg_Client;
[/file]
[/if]
[/template]
[query public getBoundPIslot(arg0 : Slot, arg1 : Sequence(OclAny)) : Slot
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'getBoundPIslot(org.eclipse.uml2.uml.Slot, java.util.List)', Sequence{arg0, arg1}) /]
[query public getDeploymentProcessingNode(arg0: Slot, arg1 : Sequence(OclAny), arg2 : String) : InstanceSpecification
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'getDeploymentProcessingNode(org.eclipse.uml2.uml.Slot, java.util.List, java.lang.String)', Sequence{arg0, arg1, arg2}) /]
[query public isSingleNodeSystem(arg0 : Sequence(OclAny), arg1 : String) : Boolean
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'isSingleNodeSystem(java.util.List, java.lang.String)', Sequence{arg0, arg1}) /]
[query public getProvidedInterface(arg0 : Port, arg1 : String) : Interface
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'getProvidedInterface(org.eclipse.uml2.uml.Port, java.lang.String)', Sequence{arg0, arg1}) /]
[query public getProvidedInterfaceSlotList(arg0 : Sequence(OclAny), arg1 : String) : Sequence(OclAny)
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'getProvidedInterfaceSlotList(java.util.List, java.lang.String)', Sequence{arg0, arg1}) /]
[query public getRequiredInterfaceSlotList(arg0 : Sequence(OclAny), arg1 : String) : Sequence(OclAny)
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'getRequiredInterfaceSlotList(java.util.List, java.lang.String)', Sequence{arg0, arg1}) /]
[query public getRemoteRIslotList(arg0 : Sequence(OclAny), arg1 : InstanceSpecification, arg2 : Sequence(OclAny), arg3 : Sequence(OclAny), arg4 : String) : Sequence(OclAny)
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'getRemoteRIslotList(java.util.List, org.eclipse.uml2.uml.InstanceSpecification, java.util.List, java.util.List, java.lang.String)', Sequence{arg0, arg1, arg2, arg3, arg4}) /]
[query public isRemoteMsgClientNecessary(arg0: Sequence(OclAny), arg1 : InstanceSpecification, arg2 : Sequence(OclAny), arg3 : Sequence(OclAny), arg4 : String) : Boolean
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'isRemoteMsgClientNecessary(java.util.List, org.eclipse.uml2.uml.InstanceSpecification, java.util.List, java.util.List, java.lang.String)', Sequence{arg0, arg1, arg2, arg3, arg4}) /]
[query public useSequenceID(arg0 : Slot, arg1 : Sequence(OclAny), arg2 : Sequence(OclAny), arg3 : String) : Boolean
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'useSequenceID(org.eclipse.uml2.uml.Slot, java.util.List, java.util.List, java.lang.String)', Sequence{arg0, arg1, arg2, arg3}) /]
[query public getCRClib(arg0 : Slot, arg1 : Sequence(OclAny), arg2 : Sequence(OclAny), arg3 : String) : String
= invoke('org.polarsys.chess.codegen.ada.service.UML2Service', 'getCRClib(org.eclipse.uml2.uml.Slot, java.util.List, java.util.List, java.lang.String)', Sequence{arg0, arg1, arg2, arg3}) /]
[query public isFunction(arg : Operation) : Boolean
= invoke ('org.polarsys.chess.codegen.ada.service.UML2Service', 'isFunction(org.eclipse.uml2.uml.Operation)', Sequence{arg}) /]