/* * 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 EPICSGAM::GetSignal(const FString &signalName){ return dataCollector.GetSignalData(signalName); }; */ // still to do.. bool EPICSGAM::ProcessMessage(GCRTemplate envelope){ if(!acceptingMessages){ AssertErrorCondition(InitialisationError,"DataCollectionGAM::ProcessMessage: %s: DataCollectionGAM is not accepting messages yet", Name()); return False; } GCRTemplate 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 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 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 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 sendSignal(GCFT_Create); if(!sendSignal.IsValid()){ AssertErrorCondition(FatalError,"DataCollectionGAM::ProcessMessage: %s: GETSIGNALS: Failed creating Message", Name()); return False; } sendSignal->Init(0,"SIGNAL"); GCRTemplate errorMessage(GCFT_Create); if(!errorMessage.IsValid()){ AssertErrorCondition(FatalError,"DataCollectionGAM::ProcessMessage: %s: GETSIGNALS: Failed creating GCNString", Name()); return False; } errorMessage->SetObjectName("ERROR"); GCRTemplate sendSignalsEnvelope(GCFT_Create); if(!sendSignalsEnvelope.IsValid()){ AssertErrorCondition(FatalError,"DataCollectionGAM::ProcessMessage: %s: GETSIGNALS: Failed creating MessageEnvelope", Name()); return False; } sendSignalsEnvelope->PrepareReply(envelope, sendSignal); GCRTemplate 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 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("\n") #define TABLE_ENDROW hStream.Printf("\n") bool EPICSGAM::ProcessHttpMessage(HttpStream &hStream) { hStream.SSPrintf("OutputHttpOtions.Content-Type","text/html"); hStream.keepAlive = False; hStream.Printf("%s", Name()); hStream.Printf( "\n" ); hStream.Printf("

EPICSGAM EPICSSignalTable dump

\n"); hStream.Printf("\n"); EPICSSignal * ptrSignal = dynamic_cast( this->signalTable.List() ); TABLE_NEWROW; hStream.Printf("\n" "\n"); TABLE_ENDROW; while (ptrSignal) { TABLE_NEWROW; BString bsbuf; hStream.Printf("\n" "\n", ptrSignal->GetDDBName(), ptrSignal->GetDDBOffset(), ptrSignal->GetDDBSize(), (ptrSignal->GetDDBType()).ConvertToString(bsbuf), ptrSignal->GetEPICSName(), ptrSignal->GetEPICSIndex(), ptrSignal->GetEPICSSubSample(), ptrSignal->counter); TABLE_ENDROW; ptrSignal =dynamic_cast( ptrSignal->Next() ); } hStream.Printf("
DDB name DDB offset DDB size DDB typeEPICS name EPICS id EPICS subsamples EPICS counter%s %d %d %s%s %d %d %d
\n"); hStream.Printf("
\n"); hStream.Printf(""); hStream.WriteReplyHeader(True); return True; } //----------------------------------------------------------------------------- end ProcessHttpMessage OBJECTLOADREGISTER(EPICSGAM,"$Id: EPICSGAM.cpp,v 1.22 2011/06/26 10:10:10 abarb Exp $")