Files
ISTTOK/epics/css/sys-mng-opi/CSS/MARTe/Interfaces/EPICSGAM/EPICSGAM.cpp
2019-10-21 16:02:55 +01:00

395 lines
14 KiB
C++

/*
* Copyright 2011 EFDA | European Fusion Development Agreement
*
* Licensed under the EUPL, Version 1.1 or - as soon they
will be approved by the European Commission - subsequent
versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the
Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in
writing, software distributed under the Licence is
distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied.
* See the Licence for the specific language governing
permissions and limitations under the Licence.
*
* $Id$
*
**/
/*
EPICS GAM is a data proxy from/to RTThread and EPICSLib
secondo me bisogna farla a tipo GAM con la sincronizzazione
come visto c'è da risolvere il problema del postEvent che viene
gratis sull'epics thread ma non in MARTe
config parameters
subsampling to epics
thresholds
bandwidth/deadbands
*/
#include "EPICSGAM.h"
#include "ConfigurationDataBase.h"
#include "CDBExtended.h"
#include "GlobalObjectDataBase.h"
#include "GCNString.h"
#include "MenuEntry.h"
EPICSGAM::EPICSGAM(){
usecTime = NULL;
fastTrigger = NULL;
jpfData = NULL;
hasTriggerSignal = False;
acceptingMessages = False;
}
/* in GAMs usually instead of calling ObjectLoadSetup of the single GAM you can
* call the super object ObjectLoadSetup that will call the redefined Initialize
* method, so ObjectLoadSetup is not required
*/
//ObjectLoadSetup() {
bool EPICSGAM::Initialise(ConfigurationDataBase& cdbData) {
acceptingMessages = False;
CDBExtended cdb(cdbData);
//////////////////////////
// Add Time BaseSignal //
//////////////////////////
if(!AddInputInterface(usecTime,"UsecTimeInterface")){
AssertErrorCondition(InitialisationError,"EPICSGAM::Initialise: %s failed to add input interface InputInterface UsecTimeInterface",Name());
return False;
}
FString timeBase;
if(!cdb.ReadFString(timeBase,"UsecTimeSignalName")){
AssertErrorCondition(InitialisationError, "EPICSGAM::Initialise: %s does not specify a UsecTimeSignalName", Name());
return False;
}
FString timeBaseType;
if(!cdb.ReadFString(timeBaseType,"TimeSignalType","int32")){
AssertErrorCondition(Warning, "EPICSGAM::Initialise: %s does not specify a TimeSignalType. Assuming int32", Name());
}
if(!usecTime->AddSignal(timeBase.Buffer(), timeBaseType.Buffer())){
AssertErrorCondition(InitialisationError,"EPICSGAM::Initialise: %s failed to add input Signal %s to interface InputInterface",Name(),timeBase.Buffer());
return False;
}
/////////////////////////////////////
// Add Trigger Signal to Interface //
/////////////////////////////////////
if(cdb->Exists("TriggerSignalName")){
if(!AddIOInterface(fastTrigger,"FastTriggerSignal",DDB_ReadMode|DDB_WriteMode)){
AssertErrorCondition(InitialisationError,"EPICSGAM::Initialise: %s failed to add input interface InputInterface FastTriggerSignal",Name());
return False;
}
FString triggerSignal;
if(!cdb.ReadFString(triggerSignal,"TriggerSignalName")){
AssertErrorCondition(InitialisationError, "EPICSGAM::Initialise: %s does not specify a TriggerSignalName", Name());
return False;
}
if(!fastTrigger->AddSignal(triggerSignal.Buffer(), "int32")){
AssertErrorCondition(InitialisationError,"EPICSGAM::Initialise: %s failed to add input Signal %s to interface InputInterface",Name(),triggerSignal.Buffer());
return False;
}
hasTriggerSignal = True;
}
//////////////////////////////////////
// Add EPICS Signal List to Interface //
//////////////////////////////////////
if(!AddInputInterface(jpfData,"EPICSSignalList")){
AssertErrorCondition(InitialisationError,"EPICSGAM::Initialise: %s failed to add input interface InputInterface JPFSignalList",Name());
return False;
}
// Read Signal Names //
if(!cdb->Move("Signals")){
AssertErrorCondition(InitialisationError,"EPICSGAM::Initialise: %s did not specify Signals entry",Name());
return False;
}
//jpfData is DDBInterface
if(!jpfData->ObjectLoadSetup(cdb,NULL)){
AssertErrorCondition(InitialisationError,"EPICSGAM::Initialise: %s: ObjectLoadSetup Failed DDBInterface %s ",Name(),jpfData->InterfaceName());
return False;
}
cdb->MoveToFather();
// we move this initialization there to let the signal Table fetching "SignalServer" parameter
if(!signalTable.Initialize(*jpfData, cdb)) {
AssertErrorCondition(InitialisationError,"EPICSGAM::Initialise: %s: Failed to initialize signal Table",Name());
return False;
}
acceptingMessages = True;
return True;
} //--------------------------------------------------------------------------- EIPCSGAM::Initialize
bool EPICSGAM::Execute(GAM_FunctionNumbers functionNumber) {
// Read Cycle Time
usecTime->Read();
int32 *timePointer = (int32 *)usecTime->Buffer();
int32 usecTimeSample = timePointer[0];
// Get the Trigger Request
bool fastTriggerRequested = False;
if(hasTriggerSignal){
fastTrigger->Read();
int32 fastTriggerSignal = *((int32 *)fastTrigger->Buffer());
fastTriggerRequested = (fastTriggerSignal != 0);
}
// Read Jpf Data
jpfData->Read();
// Update the signals table
signalTable.UpdateSignals( (char *)jpfData->Buffer(), usecTimeSample);
switch(functionNumber){
case GAMOnline:{
break;
}
case GAMPrepulse:{
// Disable Handling of the Messages
if(acceptingMessages) acceptingMessages = False;
break;
}
case GAMPostpulse:{
// Enable Handling of the Messages
if(!acceptingMessages) acceptingMessages = True;
break;
}
};
// Clear Trigger Request
if(fastTriggerRequested){
int32 *fastTriggerSignal = (int32 *)fastTrigger->Buffer();
*fastTriggerSignal = 0;
fastTrigger->Write();
}
return True;
}
//----------------------------------------------------------------------------- end Execute
/*
GCRTemplate<SignalInterface> EPICSGAM::GetSignal(const FString &signalName){
return dataCollector.GetSignalData(signalName);
};
*/
// still to do..
bool EPICSGAM::ProcessMessage(GCRTemplate<MessageEnvelope> envelope){
if(!acceptingMessages){
AssertErrorCondition(InitialisationError,"DataCollectionGAM::ProcessMessage: %s: DataCollectionGAM is not accepting messages yet", Name());
return False;
}
GCRTemplate<Message> message = envelope->GetMessage();
if (!message.IsValid()){
AssertErrorCondition(InitialisationError,"DataCollectionGAM::ProcessMessage: %s: Received invalid Message", Name());
return False;
}
FString messageContent = message->Content();
FString messageSender = envelope->Sender();
// GAP Message Request
if(messageContent == "LISTSIGNALS"){
GCRTemplate<Message> addSignals(GCFT_Create);
if(!addSignals.IsValid()){
AssertErrorCondition(InitialisationError,"DataCollectionGAM::ProcessMessage: %s: Failed creating Message", Name());
return False;
}
addSignals->Init(0,"ADDSIGNAL");
CDBExtended cdb;
/* if(!dataCollector.ObjectSaveSetup(cdb)){
AssertErrorCondition(InitialisationError,"DataCollectionGAM::ProcessMessage: %s: Failed gathering information about data collection", Name());
return False;
}
*/
int32 nOfAcquiredSignals = 0;
cdb.ReadInt32(nOfAcquiredSignals, "NOfChannels");
if(!cdb->Move("Signals")){
AssertErrorCondition(InitialisationError,"DataCollectionGAM::ProcessMessage: %s: Signals entry not available in the data base", Name());
return False;
}
for(int nSignals = 0; nSignals < nOfAcquiredSignals; nSignals++){
GCRTemplate<GCNString> signalDescription(GCFT_Create);
if(!signalDescription.IsValid()){
AssertErrorCondition(FatalError,"DataCollectionGAM::ProcessMessage: %s: Failed creating GCNString", Name());
return False;
}
cdb->MoveToChildren(nSignals);
FString signalName;
cdb.ReadFString(signalName, "Name");
signalDescription->SetObjectName(signalName.Buffer());
cdb->WriteToStream(*(signalDescription.operator->()));
signalDescription->Seek(0);
addSignals->Insert(signalDescription);
cdb->MoveToFather();
//AssertErrorCondition(Information,"DataCollectionGAM::ProcessMessage: %s: Adding Signal %s to the collection list", Name(), signalName.Buffer());
}
GCRTemplate<MessageEnvelope> addSignalsEnvelope(GCFT_Create);
if(!addSignalsEnvelope.IsValid()){
AssertErrorCondition(FatalError,"DataCollectionGAM::ProcessMessage: %s: Failed creating MessageEnvelope", Name());
return False;
}
addSignalsEnvelope->PrepareReply(envelope, addSignals);
MessageHandler::SendMessage(addSignalsEnvelope);
return True;
}
else if ( messageContent == "INITSIGNAL" ) {
return True;
}else if(messageContent == "GETSIGNAL"){
GCRTemplate<Message> sendSignal(GCFT_Create);
if(!sendSignal.IsValid()){
AssertErrorCondition(FatalError,"DataCollectionGAM::ProcessMessage: %s: GETSIGNALS: Failed creating Message", Name());
return False;
}
sendSignal->Init(0,"SIGNAL");
GCRTemplate<GCNString> errorMessage(GCFT_Create);
if(!errorMessage.IsValid()){
AssertErrorCondition(FatalError,"DataCollectionGAM::ProcessMessage: %s: GETSIGNALS: Failed creating GCNString", Name());
return False;
}
errorMessage->SetObjectName("ERROR");
GCRTemplate<MessageEnvelope> sendSignalsEnvelope(GCFT_Create);
if(!sendSignalsEnvelope.IsValid()){
AssertErrorCondition(FatalError,"DataCollectionGAM::ProcessMessage: %s: GETSIGNALS: Failed creating MessageEnvelope", Name());
return False;
}
sendSignalsEnvelope->PrepareReply(envelope, sendSignal);
GCRTemplate<GCNString> signalName = message->Find(0);
if (!signalName.IsValid()) {
errorMessage->Printf("Missing Signal Name");
sendSignal->Insert(errorMessage);
MessageHandler::SendMessage(sendSignalsEnvelope);
AssertErrorCondition(InitialisationError,"DataCollectionGAM::ProcessMessage: %s: GETSIGNALS: No valid signalName has been specified ", Name());
return False;
}
/*
GCRTemplate<SignalInterface> signal = GetSignal(*(signalName.operator->()));
if (!signal.IsValid()) {
errorMessage->Printf("Signal %s not found in GAM %s", signalName->Buffer(), Name());
sendSignal->Insert(errorMessage);
MessageHandler::SendMessage(sendSignalsEnvelope);
AssertErrorCondition(InitialisationError,"DataCollectionGAM::ProcessMessage: %s: GETSIGNALS: %s ", Name(), errorMessage->Buffer());
return False;
}
sendSignal->Insert(signal);
MessageHandler::SendMessage(sendSignalsEnvelope);
*/
return True;
}
return False;
}
//----------------------------------------------------------------------------- end ProcessMessage
const char* EPICSGAM::css = "table.bltable {"
"margin: 1em 1em 1em 2em;"
"background: whitesmoke;"
"border-collapse: collapse;"
"}"
"table.bltable th, table.bltable td {"
"border: 1px silver solid;"
"padding: 0.2em;"
"}"
"table.bltable th {"
"background: gainsboro;"
"text-align: left;"
"}"
"table.bltable caption {"
"margin-left: inherit;"
"margin-right: inherit;"
"}";
// ----------------------------------------------------------------------------
#define TABLE_NEWROW hStream.Printf("<tr>\n")
#define TABLE_ENDROW hStream.Printf("</tr>\n")
bool EPICSGAM::ProcessHttpMessage(HttpStream &hStream) {
hStream.SSPrintf("OutputHttpOtions.Content-Type","text/html");
hStream.keepAlive = False;
hStream.Printf("<html><head><title>%s</title>", Name());
hStream.Printf( "<style type=\"text/css\">\n" );
hStream.Printf("%s\n", css);
hStream.Printf( "</style></head><body>\n" );
hStream.Printf("<h1> EPICSGAM EPICSSignalTable dump</h1>\n");
hStream.Printf("<table class=\"bltable\">\n");
EPICSSignal * ptrSignal = dynamic_cast<EPICSSignal*>( this->signalTable.List() );
TABLE_NEWROW;
hStream.Printf("<td>DDB name</td> <td>DDB offset</td> <td>DDB size</td> <td>DDB type</td>\n"
"<td>EPICS name</td> <td>EPICS id</td> <td>EPICS subsamples</td> <td>EPICS counter</td>\n");
TABLE_ENDROW;
while (ptrSignal) {
TABLE_NEWROW;
BString bsbuf;
hStream.Printf("<td>%s</td> <td>%d</td> <td>%d</td> <td>%s</td>\n"
"<td>%s</td> <td>%d</td> <td>%d</td> <td>%d</td>\n",
ptrSignal->GetDDBName(), ptrSignal->GetDDBOffset(),
ptrSignal->GetDDBSize(), (ptrSignal->GetDDBType()).ConvertToString(bsbuf),
ptrSignal->GetEPICSName(), ptrSignal->GetEPICSIndex(),
ptrSignal->GetEPICSSubSample(), ptrSignal->counter);
TABLE_ENDROW;
ptrSignal =dynamic_cast<EPICSSignal*>( ptrSignal->Next() );
}
hStream.Printf("</table>\n");
hStream.Printf("<BR>\n");
hStream.Printf("</body></html>");
hStream.WriteReplyHeader(True);
return True;
}
//----------------------------------------------------------------------------- end ProcessHttpMessage
OBJECTLOADREGISTER(EPICSGAM,"$Id: EPICSGAM.cpp,v 1.22 2011/06/26 10:10:10 abarb Exp $")