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

308 lines
7.4 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$
*
**/
#if !defined (EPICS_HANDLER)
#define EPICS_HANDLER
#include "System.h"
#include "GCNamedObject.h"
#include "HttpInterface.h"
#include "FString.h"
#include "CountSem.h"
//#include "epicsGuard.h"
#include "exServer.h"
//
// special gddDestructor guarantees same form of new and delete
//
class float32Destructor: public gddDestructor {
virtual void run ( void * pUntyped ) {
aitFloat32 * pf = reinterpret_cast < aitFloat32 * > ( pUntyped );
delete [] pf;
}
};
class float64Destructor: public gddDestructor {
virtual void run ( void * pUntyped ) {
aitFloat64 * pf = reinterpret_cast < aitFloat64 * > ( pUntyped );
delete [] pf;
}
};
class int8Destructor: public gddDestructor {
virtual void run ( void * pUntyped ) {
aitInt8 * pf = reinterpret_cast < aitInt8 * > ( pUntyped );
delete [] pf;
}
};
class int16Destructor: public gddDestructor {
virtual void run ( void * pUntyped ) {
aitInt16 * pf = reinterpret_cast < aitInt16 * > ( pUntyped );
delete [] pf;
}
};
class int32Destructor: public gddDestructor {
virtual void run ( void * pUntyped ) {
aitInt32 * pf = reinterpret_cast < aitInt32 * > ( pUntyped );
delete [] pf;
}
};
/*
// aitInt64 not supported by GDD
class int64Destructor: public gddDestructor {
virtual void run ( void * pUntyped ) {
aitInt64 * pf = reinterpret_cast < aitInt64 * > ( pUntyped );
delete [] pf;
}
};
*/
/*
void callback (void * args);
void callback_event (void * args);
*/
// nel buffer circolare ogni entry dev'essere casta in questo modo
// value è il contenitore dei dati.
//nel buffer non ce frammentazione perche sfruttiamo un buffer circolare
#define CB_HEADER_MAGIC 0xBEEF
typedef struct _cbHeader {
uint16 magic;
uint16 id;
uint32 timestamp; // aggiunto con dolore per finire il progetto.. :-|
uint32 value [];
} cbHeader;
typedef struct _subscriber {
int count;
int size;
BasicTypeDescriptor type;
int statisticPut;
int statisticGet;
} subscriber;
OBJECT_DLL(EPICSHandler)
;
class EPICSHandler
: public GCNamedObject, public HttpInterface
{
OBJECT_DLL_STUFF(EPICSHandler)
//friend void callback (void * args);
//friend void callback_event (void * args);
private:
//process variables prefix
FString pvPrefix;
bool setup_complete; // setup status (yes complete no nou complete)
//debug level
unsigned debugLevel;
//scanOn true or false
bool scanOn;
//asyncScan true or false
bool asyncScan;
//asyncDelay
double asyncDelay;
//maxsimulasyncio
unsigned maxSimultAsyncIO;
TID threadID;
int32 cpuMask;
TID threadID_event;
int32 cpuMask_event;
//Number of process variables
int32 numberOfPVs;
// PVs are registered in the pCAS
exServer * pCAS;
// list of PV to register to the pCAS
pvInfo ** pvList ;
// subscriber support list
subscriber * subList;
int subListSize;
// buffer support data
int buffer_size ;
int buffer_align ;
int32 buffer_free ;
cbHeader * buffer_head;
cbHeader * buffer_tail;
int buffer_err;
char * buffer_ptr;
CountSem sem;
TimeoutType timeout;
char * subBuffer;
unsigned subSize;
public:
static const char * css;
static const char * aitEnum_strings[];
static const char * excasIoType_strings[];
static const char * tf_strings[];
static const int tf_values[];
static const char * menuAlarmSevr_strings[];
static const char * menuAlarmStat_strings[];
static const char * menuScan_strings[];
static const char * menuYesNo_strings[];
static const int menu_values[];
static const float menuScan_values[];
/**
* Converts a null terminated string to an aitEnum value
*/
static aitEnum ConvertToaitEnum (const char * s );
static excasIoType ConvertToexcasIoType(const char * s);
inline const exServer * getCaServer() const {
return pCAS;
} ;
// TODO
EPICSHandler() {
setup_complete = false;
numberOfPVs = 0;
pCAS = 0;
pvList = 0;
subList = 0;
subListSize = 0;
buffer_size = 0;
buffer_align = 0;
buffer_head = 0;
buffer_tail = 0;
buffer_ptr = 0;
buffer_err = 0; // last error issued by the circular buffer
sem.Create();
timeout = TTInfiniteWait;
subBuffer = 0;
subSize = 0;
}
// TODO
virtual ~EPICSHandler(){
//if(pvList != NULL){
// delete [] pvList;
//}
setup_complete = false;
callback_finalize--;
callback_event_finalize--;
sem.Post();
sem.Close();
// wait for event...
// devo aspettare che i thread escano prima di eliminare gli objects..
if (pCAS)
delete pCAS;
for(int i=0; i<numberOfPVs; i++)
delete pvList[i];
if (pvList)
delete [] pvList;
if (buffer_ptr)
delete [] buffer_ptr;
if (subBuffer)
delete [] subBuffer;
}
/**
* Load and configure object parameters
* @param info the configuration database
* @param err the error stream
* @return True if no errors are found during object configuration
*/
bool ObjectLoadSetup(ConfigurationDataBase &info,StreamInterface *err);
/**
* Http Page that reflects the state of the object
*/
bool ProcessHttpMessage(HttpStream &hStream);
/**
* the data pool stayes in a circular memory buffer
* symbolic name that identify a pv or a mdsplus tree...
* type is the MARTe's basictype on which this signal appears on the DDB
* count is the number of elements of the same type (array support)
* id is the PV's List entry index (handle)
*/
// probabilmente sarebbe da tenere anche un puntatore all'oggetto che fa il subscribing
// -> il numero di buckets dev'essere settato da cfg file
// -> ogni bucket è della stessa grandezza, i bukets sono grandi come la union di tutti
// i tipi base
bool subscribe ( const char * nameIn, BasicTypeDescriptor typeIn, int countIn, unsigned &idOut);
int put (unsigned idIn, void * bufferIn, unsigned timestamp); // al massimo si può estendere per fare put multipli
int get (unsigned &idOut, void * bufferIn, unsigned sizeIn, unsigned &timestamp); // anche in questo caso il buffer dev'essere pre allocato
bool unsubscribe (unsigned id);
private:
static void callback (void * args); //threadID [this must be static also]
static void callback_event (void * args); //threadID_event
static int callback_finalize; //threadID
static int callback_event_finalize; //threadID_event
};
#endif