]> jspc29.x-matter.uni-frankfurt.de Git - daqdata.git/commitdiff
*** empty log message ***
authorhades <hades>
Wed, 14 Mar 2001 09:56:05 +0000 (09:56 +0000)
committerhades <hades>
Wed, 14 Mar 2001 09:56:05 +0000 (09:56 +0000)
allParam/ca/server/paramGetRecord.cc [new file with mode: 0644]
allParam/ca/server/paramGetRecord.h [new file with mode: 0644]
allParam/ca/server/paramRecord.cc [new file with mode: 0644]
allParam/ca/server/paramRecord.h [new file with mode: 0644]
allParam/ca/server/paramRecordSet.cc [new file with mode: 0644]
allParam/ca/server/paramRecordSet.h [new file with mode: 0644]
allParam/ca/server/paramServer.cc [new file with mode: 0644]
allParam/ca/server/paramStoreRecord.cc [new file with mode: 0644]
allParam/ca/server/paramStoreRecord.h [new file with mode: 0644]
allParam/ca/server/record.cc [new file with mode: 0644]
allParam/ca/server/record.h [new file with mode: 0644]

diff --git a/allParam/ca/server/paramGetRecord.cc b/allParam/ca/server/paramGetRecord.cc
new file mode 100644 (file)
index 0000000..71dbf6b
--- /dev/null
@@ -0,0 +1,144 @@
+#define _POSIX_C_SOURCE 199509L
+
+extern "C" {
+  #include <string.h>
+}
+
+#include "paramGetRecord.h"
+
+void ArrayDestructor::run(void *todelete) {
+       aitString *pd = (aitString *) todelete;
+       delete [] pd;
+}
+
+ParamGetRecord::ParamGetRecord(caServer& cas, const Param *p, const char *rn, const char *u) :
+  ParamRecord(cas, p, rn, u)
+{
+       index = 0;
+       funcTable.installReadFunc("units", &Record::readUnits);
+       funcTable.installReadFunc("status", &Record::readStatus);
+       funcTable.installReadFunc("severity", &Record::readSeverity);
+
+       funcTable.installReadFunc("controlLow", &ParamRecord::readLowCtrl);
+       funcTable.installReadFunc("controlHigh", &ParamRecord::readHighCtrl);
+       funcTable.installReadFunc("graphicLow", &ParamRecord::readLopr);
+       funcTable.installReadFunc("graphicHigh", &ParamRecord::readHopr);
+       funcTable.installReadFunc("precision", &ParamRecord::readPrecision);
+
+       funcTable.installReadFunc("value", &ParamGetRecord::readValue);
+}
+
+ParamGetRecord::~ParamGetRecord()
+{
+       for(int k = 0 ; k < index ; k++) {
+               delete ourValue[k];
+       }
+}
+
+aitBool ParamGetRecord::paramDoesReallyExist()
+{
+       aitBool retVal = aitFalse;
+       for (int k = 0 ; k < PARAM_MAX_ARRAY_LEN ; k++) {
+               ourValue[k] = new char[PARAM_MAX_VALUE_LEN];
+       }
+
+       int rows;
+
+       if((Param_getStringArray(param, name, idx, PARAM_MAX_ARRAY_LEN, &rows, ourValue) == 0) && (rows > 0)) {
+               index = rows;
+               retVal = aitTrue;
+       }
+
+       for(int k = index ; k < PARAM_MAX_ARRAY_LEN ; k++) {
+               delete ourValue[k];
+       }
+       return retVal;
+}
+
+epicsShareFunc unsigned ParamGetRecord::maxDimension() const
+{
+       return 1u;
+}
+
+epicsShareFunc aitIndex ParamGetRecord::maxBound(unsigned dimension) const
+{
+       aitIndex retVal;
+       if(dimension == 0) {
+               retVal = index;
+       } else {
+               retVal = 1u;
+       }
+       return retVal;
+}
+
+gddAppFuncTableStatus ParamGetRecord::readValue(gdd &value)
+{
+       if(index == 1) {
+               aitString stringValue = new aitString;
+
+               stringValue = ourValue[0];
+
+               value.putConvert(stringValue);
+       } else {
+               aitString *stringValue;
+               stringValue = new aitString[index];
+               for (int k = 0 ; k < index ; k++) {
+                       stringValue[k] = ourValue[k];
+               }
+
+               value.putRef(stringValue);
+       }
+
+       return S_casApp_success;
+}
+
+caStatus ParamGetRecord::scan()
+{
+       caStatus retVal;
+       caServer *pCAS = this->getCAS();
+
+       if(index == 1) {
+               aitString stringValue = new aitString;
+               val = new gddScalar(gddAppType_value, aitEnumString);
+
+               stringValue = ourValue[0];
+
+               val->putConvert(stringValue);
+       } else {
+               aitString *stringValue;
+
+               val = new gddAtomic(gddAppType_value, aitEnumString, 1, index);
+
+               stringValue = new aitString[index];
+               for (int k = 0 ; k < index ; k++) {
+                       stringValue[k] = ourValue[k];
+               }
+
+               ArrayDestructor *pDest = new ArrayDestructor;
+
+               val->putRef(stringValue, pDest);
+       }
+
+       val->setStat(epicsAlarmNone);
+       val->setSevr(epicsSevNone);
+
+       if (this->interest == aitTrue && pCAS != NULL) {
+               casEventMask select(pCAS->valueEventMask|pCAS->logEventMask|pCAS->alarmEventMask);
+               this->postEvent (select, *val);
+       }
+
+       retVal = S_cas_success;
+
+       return retVal;
+}
+
+caStatus ParamGetRecord::read(const casCtx &ctx, gdd &prototype)
+{
+       return ((scan() == S_cas_success) && funcTable.read(*this, prototype));
+}
+
+caStatus ParamGetRecord::write(const casCtx &ctx, gdd &value)
+{
+       return S_cas_noWrite;
+}
+
diff --git a/allParam/ca/server/paramGetRecord.h b/allParam/ca/server/paramGetRecord.h
new file mode 100644 (file)
index 0000000..ae9ada5
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef PARAMGETRECORD_H
+#define PARAMGETRECORD_H
+
+#include "paramRecord.h"
+
+class ArrayDestructor : public gddDestructor {
+       virtual void run(void *);
+};
+
+class ParamGetRecord : public ParamRecord {
+  private:
+       aitIndex index;
+       char *ourValue[PARAM_MAX_ARRAY_LEN];
+       gddAppFuncTable<ParamGetRecord> funcTable;
+
+  public:
+       ParamGetRecord(caServer&, const Param *, const char *, const char *);
+       ~ParamGetRecord();
+
+       aitBool paramDoesReallyExist();
+       epicsShareFunc unsigned maxDimension() const;
+       epicsShareFunc aitIndex maxBound(unsigned int) const;
+       gddAppFuncTableStatus readValue(gdd &);
+       caStatus scan();
+       caStatus read(const casCtx &, gdd &);
+       caStatus write(const casCtx &, gdd &);
+};
+
+#endif
+
diff --git a/allParam/ca/server/paramRecord.cc b/allParam/ca/server/paramRecord.cc
new file mode 100644 (file)
index 0000000..bf0bf48
--- /dev/null
@@ -0,0 +1,78 @@
+#define _POSIX_C_SOURCE 199509L
+
+extern "C" {
+  #include <stdio.h>
+  #include <string.h>
+  #include <ctype.h>
+}
+
+#include "paramRecord.h"
+
+ParamRecord::ParamRecord(caServer& cas, const Param *p, const char *rn, const char *u) :
+  Record(cas, rn, u, aitEnumString), param(p)
+{
+       char tmp;
+       char buf1[PARAM_MAX_NAME_LEN];
+       char buf2[PARAM_MAX_NAME_LEN];
+       char buf3[PARAM_MAX_NAME_LEN];
+
+       strcpy(buf1, "");
+       strcpy(buf2, "");
+       strcpy(buf3, "");
+       sscanf(rn, "HAD:P%c:%[^:]:%[^:]:%[^:]", &tmp, buf1, buf2, buf3);
+       if(strcmp(buf3, "") == 0) {
+               strcpy(name, buf1);
+               strcpy(idx, buf2);
+       } else {
+               strcpy(name, buf2);
+               strcpy(idx, buf3);
+       }
+
+       for (int i = 0 ; i < strlen(name) ; i++) {
+               name[i] = tolower(name[i]);
+       }
+       for (int i = 0 ; i < strlen(idx) ; i++) {
+               idx[i] = tolower(idx[i]);
+       }
+       interest = aitFalse;
+}
+
+ParamRecord::~ParamRecord()
+{
+}
+
+epicsShareFunc aitEnum ParamRecord::bestExternalType() const
+{
+       return aitEnumString;
+}
+
+gddAppFuncTableStatus ParamRecord::readLowCtrl(gdd &value)
+{
+       value.putConvert(0);
+       return S_casApp_success;
+}
+
+gddAppFuncTableStatus ParamRecord::readHighCtrl(gdd &value)
+{
+       value.putConvert(0);
+       return S_casApp_success;
+}
+
+gddAppFuncTableStatus ParamRecord::readLopr(gdd &value)
+{
+       value.putConvert(0);
+       return S_casApp_success;
+}
+
+gddAppFuncTableStatus ParamRecord::readHopr(gdd &value)
+{
+       value.putConvert(0);
+       return S_casApp_success;
+}
+
+gddAppFuncTableStatus ParamRecord::readPrecision(gdd &value)
+{
+       value.putConvert(0);
+       return S_casApp_success;
+}
+
diff --git a/allParam/ca/server/paramRecord.h b/allParam/ca/server/paramRecord.h
new file mode 100644 (file)
index 0000000..a40b21a
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef PARAMRECORD_H
+#define PARAMRECORD_H
+
+extern "C" {
+  #include <allParam.h>
+}
+
+#include <gdd.h>
+
+#include "record.h"
+
+class ParamRecord : public Record {
+  protected:
+       const Param *param;
+       char name[PARAM_MAX_VALUE_LEN];
+       char idx[PARAM_MAX_VALUE_LEN];
+  public:
+       ParamRecord(caServer&, const Param *, const char *, const char *);
+       ~ParamRecord();
+
+       epicsShareFunc aitEnum bestExternalType() const;
+
+       virtual gddAppFuncTableStatus readLowCtrl(gdd &);
+       virtual gddAppFuncTableStatus readHighCtrl(gdd &);
+       virtual gddAppFuncTableStatus readLopr(gdd &);
+       virtual gddAppFuncTableStatus readHopr(gdd &);
+       virtual gddAppFuncTableStatus readPrecision(gdd &);
+
+       virtual gddAppFuncTableStatus readValue(gdd &) = 0;
+
+       virtual caStatus scan() = 0;
+       virtual caStatus read(const casCtx &, gdd &) = 0;
+       virtual caStatus write(const casCtx &, gdd &) = 0;
+};
+
+#endif
+
diff --git a/allParam/ca/server/paramRecordSet.cc b/allParam/ca/server/paramRecordSet.cc
new file mode 100644 (file)
index 0000000..1239e15
--- /dev/null
@@ -0,0 +1,168 @@
+#define _POSIX_C_SOURCE 199509L
+
+extern "C" {
+  #include <stdio.h>
+  #include <string.h>
+  #include <stdlib.h>
+  #include <ctype.h>
+  #include <syslog.h>
+}
+
+#include "paramRecordSet.h"
+#include "paramGetRecord.h"
+#include "paramStoreRecord.h"
+
+ParamRecordSet::ParamRecordSet(unsigned int pvCountEstimate) :
+  caServer(pvCountEstimate)
+{
+       numParamSrc = 0;
+       numPv = 0;
+}
+
+ParamRecordSet::~ParamRecordSet()
+{
+       for (int i = 0 ; i < numParamSrc ; i++) {
+               desParam(param[i]);
+               delete param[i];
+       }
+}
+
+Param *ParamRecordSet::pParam(const char *setup)
+{
+       for (int i = 0 ; i < numParamSrc ; i++) {
+               if (param[i]->setup != NULL) {
+                       if (strcmp(param[i]->setup, setup) == 0) {
+                               return param[i];
+                       }
+               } else {
+                       if (setup == NULL) {
+                               return param[i];
+                       }
+               }
+       }
+       return NULL;
+}
+
+pvExistReturn ParamRecordSet::pvExistTest(const casCtx &ctx, const char *pPVName)
+{
+       char *setup;
+       char buf1[PARAM_MAX_NAME_LEN];
+       char buf2[PARAM_MAX_NAME_LEN];
+       char buf3[PARAM_MAX_NAME_LEN];
+
+       strcpy(buf1, "");
+       strcpy(buf2, "");
+       strcpy(buf3, "");
+       if(strncmp(pPVName, "HAD:PS:", strlen("HAD:PS:")) == 0) {
+               sscanf(pPVName, "HAD:PS:[^:]:[^:]:[^:]", buf1, buf2, buf3);
+               if (strcmp(buf3, "") == 0) {
+                       setup = NULL;
+               } else {
+                       setup = buf1;
+                       for (int i = 0 ; i < strlen(setup) ; i++) {
+                               setup[i] = tolower(setup[i]);
+                       }
+               }
+               if(pParam(setup) == NULL) {
+                       param[numParamSrc] = new Param;
+                       if (conSetupParam(param[numParamSrc], setup) == 0) {
+                               numParamSrc++;
+                       } else {
+                               desParam(param[numParamSrc]);
+                               delete param[numParamSrc];
+                       }
+               }
+               if(pParam(setup) != NULL) {
+                       return pverExistsHere;
+               } else {
+                       return pverDoesNotExistHere;
+               }
+       } else if(strncmp(pPVName, "HAD:PG:", strlen("HAD:PG:")) == 0) {
+               sscanf(pPVName, "HAD:PG:[^:]:[^:]:[^:]", buf1, buf2, buf3);
+               if (strcmp(buf3, "") == 0) {
+                       setup = NULL;
+               } else {
+                       setup = buf1;
+                       for (int i = 0 ; i < strlen(setup) ; i++) {
+                               setup[i] = tolower(setup[i]);
+                       }
+               }
+               if(pParam(setup) == NULL) {
+                       param[numParamSrc] = new Param;
+                       if (conSetupParam(param[numParamSrc], setup) == 0) {
+                               numParamSrc++;
+                       } else {
+                               desParam(param[numParamSrc]);
+                               delete param[numParamSrc];
+                       }
+               }
+               if(pParam(setup) != NULL) {
+                       ParamGetRecord *record = new ParamGetRecord(*this, pParam(setup), pPVName, "String Array");
+                       if(record->paramDoesReallyExist()) {
+                               delete record;
+                               return pverExistsHere;
+                       } else {
+                               delete record;
+                               return pverDoesNotExistHere;
+                       }
+               } else {
+                       return pverDoesNotExistHere;
+               }
+       }
+       return pverDoesNotExistHere;
+}
+
+pvCreateReturn ParamRecordSet::createPV(const casCtx &ctx, const char *pPVName)
+{
+       pvCreateReturn retVal(S_casApp_pvNotFound);
+       char *setup;
+       char buf1[PARAM_MAX_NAME_LEN];
+       char buf2[PARAM_MAX_NAME_LEN];
+       char buf3[PARAM_MAX_NAME_LEN];
+
+       strcpy(buf1, "");
+       strcpy(buf2, "");
+       strcpy(buf3, "");
+       if(strncmp(pPVName, "HAD:PS:", strlen("HAD:PS:")) == 0) {
+               sscanf(pPVName, "HAD:PS:[^:]:[^:]:[^:]", buf1, buf2, buf3);
+               if (strcmp(buf3, "") == 0) {
+                       setup = NULL;
+               } else {
+                       setup = buf1;
+                       for (int i = 0 ; i < strlen(setup) ; i++) {
+                               setup[i] = tolower(setup[i]);
+                       }
+               }
+               if(pParam(setup) != NULL) {
+                       retVal = (pvs[numPv++] = new ParamStoreRecord(*this, pParam(setup), pPVName, "String"));
+                       return retVal;
+               } else {
+                       return S_casApp_pvNotFound;
+               }
+       } else if(strncmp(pPVName, "HAD:PG:", strlen("HAD:PG:")) == 0) {
+               sscanf(pPVName, "HAD:PG:[^:]:[^:]:[^:]", buf1, buf2, buf3);
+               if (strcmp(buf3, "") == 0) {
+                       setup = NULL;
+               } else {
+                       setup = buf1;
+                       for (int i = 0 ; i < strlen(setup) ; i++) {
+                               setup[i] = tolower(setup[i]);
+                       }
+               }
+               if(pParam(setup) != NULL) {
+                       ParamGetRecord *record = new ParamGetRecord(*this, pParam(setup), pPVName, "String Array");
+                       if(record->paramDoesReallyExist()) {
+                               pvs[numPv++] = record;
+                               retVal = record;
+                               return retVal;
+                       } else {
+                               delete record;
+                               return S_casApp_pvNotFound;
+                       }
+               } else {
+                       return S_casApp_pvNotFound;
+               }
+       }
+       return S_casApp_pvNotFound;
+}
+
diff --git a/allParam/ca/server/paramRecordSet.h b/allParam/ca/server/paramRecordSet.h
new file mode 100644 (file)
index 0000000..a3b66c3
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef PARAMRECORDSET_H
+#define PARAMRECORDSET_H
+
+extern "C" {
+  #include <allParam.h>
+}
+
+#include <casdef.h>
+
+#include "paramRecord.h"
+
+#define MAX_PARAM_SRC 16
+#define PV_COUNT_EST 1024
+
+class ParamRecordSet : public caServer {
+  private:
+    int numPv;
+    ParamRecord *pvs[PV_COUNT_EST];
+
+    int numParamSrc;
+    Param *param[MAX_PARAM_SRC];
+       Param *pParam(const char *);
+
+  public:
+       ParamRecordSet(unsigned int);
+       ~ParamRecordSet();
+       pvExistReturn pvExistTest(const casCtx &, const char *);
+       pvCreateReturn createPV(const casCtx &, const char *);
+};
+
+#endif
+
diff --git a/allParam/ca/server/paramServer.cc b/allParam/ca/server/paramServer.cc
new file mode 100644 (file)
index 0000000..4f2bdc8
--- /dev/null
@@ -0,0 +1,37 @@
+#define _POSIX_C_SOURCE 199509L
+
+#include <stdiostream.h>
+
+extern "C" {
+  #include <unistd.h>
+  #include <string.h>
+  #include <ctype.h>
+  #include <syslog.h>
+}
+
+#include <fdManager.h>
+
+#include "paramRecordSet.h"
+
+int main(int argc, char *argv[]) {
+       openlog(argv[0], LOG_PERROR | LOG_PID, LOG_LOCAL0);
+
+       ParamRecordSet *cas;
+
+       if (NULL == (cas = new ParamRecordSet(PV_COUNT_EST))) {
+               syslog(LOG_ERR, "Cannot allocate memory for the RecordSet. Exiting.\n");
+               exit(-1);
+       }                                                                       
+
+       cas->setDebugLevel(0u);
+
+       while (aitTrue) {
+               osiTime delay(1000u, 0u);
+               fileDescriptorManager.process(delay);
+       }
+
+       delete cas;
+       closelog();
+       return 0;
+}
+
diff --git a/allParam/ca/server/paramStoreRecord.cc b/allParam/ca/server/paramStoreRecord.cc
new file mode 100644 (file)
index 0000000..e226e3e
--- /dev/null
@@ -0,0 +1,62 @@
+#define _POSIX_C_SOURCE 199509L
+
+extern "C" {
+  #include <string.h>
+}
+
+#include "paramStoreRecord.h"
+
+ParamStoreRecord::ParamStoreRecord(caServer& cas, const Param *p, const char *rn, const char *u) :
+  ParamRecord(cas, p, rn, u)
+{
+       funcTable.installReadFunc("units", &Record::readUnits);
+       funcTable.installReadFunc("status", &Record::readStatus);
+       funcTable.installReadFunc("severity", &Record::readSeverity);
+
+       funcTable.installReadFunc("controlLow", &ParamRecord::readLowCtrl);
+       funcTable.installReadFunc("controlHigh", &ParamRecord::readHighCtrl);
+       funcTable.installReadFunc("graphicLow", &ParamRecord::readLopr);
+       funcTable.installReadFunc("graphicHigh", &ParamRecord::readHopr);
+       funcTable.installReadFunc("precision", &ParamRecord::readPrecision);
+
+       funcTable.installReadFunc("value", &ParamStoreRecord::readValue);
+}
+
+ParamStoreRecord::~ParamStoreRecord()
+{
+}
+
+gddAppFuncTableStatus ParamStoreRecord::readValue(gdd &value)
+{
+       return S_casApp_noSupport;
+}
+
+caStatus ParamStoreRecord::scan()
+{
+       return S_casApp_noSupport;
+}
+
+caStatus ParamStoreRecord::read(const casCtx &ctx, gdd &prototype)
+{
+       return S_casApp_noSupport;
+}
+
+caStatus ParamStoreRecord::write(const casCtx &ctx, gdd &value)
+{
+       fprintf(stderr, "Entered ParamStoreRecord::write\n");
+       caServer *pCAS = this->getCAS();
+
+       aitString stringValue;
+
+       value.getConvert(stringValue);
+
+       char ourValue[PARAM_MAX_VALUE_LEN];
+       strcpy(ourValue, (const char *) stringValue);
+       fprintf(stderr, "ourValue to write: %s\n", ourValue);
+
+       Param_storeString(param, name, idx, ourValue);
+
+       fprintf(stderr, "Leaving ParamStoreRecord::write\n");
+       return S_cas_success;
+}
+
diff --git a/allParam/ca/server/paramStoreRecord.h b/allParam/ca/server/paramStoreRecord.h
new file mode 100644 (file)
index 0000000..154a871
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef PARAMSTORERECORD_H
+#define PARAMSTORERECORD_H
+
+#include "paramRecord.h"
+
+class ParamStoreRecord : public ParamRecord {
+  private:
+       aitIndex index;
+       gddAppFuncTable<ParamStoreRecord> funcTable;
+
+  public:
+       ParamStoreRecord(caServer&, const Param *, const char *, const char *);
+       ~ParamStoreRecord();
+
+       gddAppFuncTableStatus readValue(gdd &);
+       caStatus scan();
+       caStatus read(const casCtx &, gdd &);
+       caStatus write(const casCtx &, gdd &);
+};
+
+#endif
+
diff --git a/allParam/ca/server/record.cc b/allParam/ca/server/record.cc
new file mode 100644 (file)
index 0000000..900cde7
--- /dev/null
@@ -0,0 +1,79 @@
+#define _POSIX_C_SOURCE 199509L
+
+extern "C" {
+  #include <string.h>
+}
+
+#include "record.h"
+
+/******************** 
+ * record Functions *
+ ********************/
+
+Record::Record(caServer &cas, const char *n, const char *u, aitEnum t) : casPV(cas), units(u), type(t) {
+       strcpy (name, n);
+       interest = aitFalse;
+
+       alarmStatus = epicsAlarmNone;
+       alarmSeverity = epicsSevNone;
+
+       recordScanTimer = new scanTimer(*this);
+}
+
+Record::~Record() {
+}
+
+/* Misc Functions which are the same in all records */
+
+void Record::destroy() {
+}
+
+caStatus Record::interestRegister() {
+       interest = aitTrue;
+       return S_casApp_success;
+}
+
+void Record::interestDelete() {
+       interest = aitFalse;
+}
+
+const char *Record::getName() const {
+       return name;
+}
+
+aitEnum Record::bestExternalType() const {
+       return type;
+}
+
+/* Read Functions which are the same for all records */
+
+gddAppFuncTableStatus Record::readUnits(gdd &value) {
+       value.putConvert(*units);
+       return S_casApp_success;
+}
+
+gddAppFuncTableStatus Record::readStatus(gdd &value) {
+       value.putConvert(alarmStatus);
+       return S_casApp_success;
+}
+
+gddAppFuncTableStatus Record::readSeverity(gdd &value) {
+       value.putConvert(alarmSeverity);
+       return S_casApp_success;
+}
+
+/***********************
+ * scanTimer Functions *
+ ***********************/
+
+scanTimer::scanTimer (Record &pv) : osiTimer(1.0), procVar(pv) {
+}
+
+void scanTimer::expire() {
+       procVar.scan();
+}
+
+osiBool scanTimer::again() const {
+       return osiTrue;
+}
+
diff --git a/allParam/ca/server/record.h b/allParam/ca/server/record.h
new file mode 100644 (file)
index 0000000..8035113
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef RECORD_H
+#define RECORD_H
+
+#include <casdef.h>
+
+#include <osiTimer.h>
+#include <aitTypes.h>
+#include <aitHelpers.h>
+
+#include <gddApps.h>
+#include <gddAppFuncTable.h>
+
+#define NAMELENGTH 28
+
+class scanTimer;
+
+class Record : public casPV {
+  protected:
+       char name[NAMELENGTH + 1];
+       const char *units;
+       aitEnum type;
+       gdd *val;
+       scanTimer *recordScanTimer;
+       aitBool interest;
+       epicsAlarmCondition alarmStatus;
+       epicsAlarmSeverity alarmSeverity;
+  public:
+       Record(caServer&, const char*, const char*, aitEnum);
+       ~Record();
+
+       void destroy();
+       caStatus interestRegister();
+       void interestDelete();
+       const char *getName() const;
+       aitEnum bestExternalType() const;
+
+       gddAppFuncTableStatus readUnits(gdd &);
+       gddAppFuncTableStatus readStatus(gdd &);
+       gddAppFuncTableStatus readSeverity(gdd &);
+
+       virtual gddAppFuncTableStatus readValue(gdd &) = 0;
+       virtual caStatus scan() = 0;
+       virtual caStatus read(const casCtx &, gdd &) = 0;
+       virtual caStatus write(const casCtx &, gdd &) = 0;
+};
+
+class scanTimer : public osiTimer {
+  private:
+       Record &procVar;
+  public:
+       scanTimer(Record &);
+       void expire();
+       osiBool again() const;
+};
+
+#endif
+