From e67ef8a0050aa096cda9eb07cea4874104683d0a Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 27 Apr 2012 13:21:59 -0400 Subject: [PATCH] Add ts filter plugin to set timestamp to "now" --- src/ioc/db/Makefile | 5 ++ src/ioc/db/filters/filters.dbd | 1 + src/ioc/db/filters/ts.c | 123 +++++++++++++++++++++++++++++++++ src/std/softIoc/base.dbd | 3 + 4 files changed, 132 insertions(+) create mode 100644 src/ioc/db/filters/filters.dbd create mode 100644 src/ioc/db/filters/ts.c diff --git a/src/ioc/db/Makefile b/src/ioc/db/Makefile index 3a47dae3e..ad3d2fe91 100644 --- a/src/ioc/db/Makefile +++ b/src/ioc/db/Makefile @@ -53,6 +53,9 @@ menuGlobal_DBD += menuSimm.dbd DBDINC += $(basename $(menuGlobal_DBD)) DBDINC += dbCommon +DBD_INSTALLS += filters.dbd + + dbCore_SRCS += dbLock.c dbCore_SRCS += dbAccess.c dbCore_SRCS += dbBkpt.c @@ -81,3 +84,5 @@ dbCore_SRCS += templateInstances.cpp dbCore_SRCS += dbIocRegister.c dbCore_SRCS += chfPlugin.c +LIB_SRCS += ts.c + diff --git a/src/ioc/db/filters/filters.dbd b/src/ioc/db/filters/filters.dbd new file mode 100644 index 000000000..bc84b4568 --- /dev/null +++ b/src/ioc/db/filters/filters.dbd @@ -0,0 +1 @@ +registrar(tsInitialize) diff --git a/src/ioc/db/filters/ts.c b/src/ioc/db/filters/ts.c new file mode 100644 index 000000000..af6149b7c --- /dev/null +++ b/src/ioc/db/filters/ts.c @@ -0,0 +1,123 @@ +/*************************************************************************\ +* Copyright (c) 2010 Brookhaven National Laboratory. +* Copyright (c) 2010 Helmholtz-Zentrum Berlin +* fuer Materialien und Energie GmbH. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* + * Author: Ralph Lange + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +static short mapDBFToDBR[DBF_NTYPES] = { + /* DBF_STRING => */ DBR_STRING, + /* DBF_CHAR => */ DBR_CHAR, + /* DBF_UCHAR => */ DBR_UCHAR, + /* DBF_SHORT => */ DBR_SHORT, + /* DBF_USHORT => */ DBR_USHORT, + /* DBF_LONG => */ DBR_LONG, + /* DBF_ULONG => */ DBR_ULONG, + /* DBF_FLOAT => */ DBR_FLOAT, + /* DBF_DOUBLE => */ DBR_DOUBLE, + /* DBF_ENUM, => */ DBR_ENUM, + /* DBF_MENU, => */ DBR_ENUM, + /* DBF_DEVICE => */ DBR_ENUM, + /* DBF_INLINK => */ DBR_STRING, + /* DBF_OUTLINK => */ DBR_STRING, + /* DBF_FWDLINK => */ DBR_STRING, + /* DBF_NOACCESS => */ DBR_NOACCESS +}; + +static void *tsStringFreeList; + +void freeArray(db_field_log *pfl) { + if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) { + freeListFree(tsStringFreeList, pfl->u.r.field); + } else { + free(pfl->u.r.field); + } +} + +static db_field_log* tsFilter(void* pvt, dbChannel *chan, db_field_log *pfl) { + epicsTimeStamp now; + epicsTimeGetCurrent(&now); + + /* If string or array, must make a copy (to ensure coherence between time and data) */ + if (pfl->type == dbfl_type_rec) { + void *p; + struct dbCommon *prec = dbChannelRecord(chan); + pfl->type = dbfl_type_ref; + pfl->stat = prec->stat; + pfl->sevr = prec->sevr; + pfl->field_type = chan->addr.field_type; + pfl->no_elements = chan->addr.no_elements; + pfl->field_size = chan->addr.field_size; + pfl->u.r.dtor = freeArray; + pfl->u.r.pvt = pvt; + if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) { + p = freeListCalloc(tsStringFreeList); + } else { + p = calloc(pfl->no_elements, pfl->field_size); + } + if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL); + pfl->u.r.field = p; + } + + pfl->time = now; + return pfl; +} + +static void channelRegisterPre(dbChannel *chan, void *pvt, + chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) +{ + *cb_out = tsFilter; +} + +void channel_report(dbChannel *chan, void *user, int level, const unsigned short indent) +{ + int i; + for (i = 0; i < indent; i++) printf(" "); + printf(" plugin ts\n"); +} + +static chfPluginIf tsPif = { + NULL, /* allocPvt, */ + NULL, /* freePvt, */ + + NULL, /* parse_error, */ + NULL, /* parse_ok, */ + + NULL, /* channel_open, */ + channelRegisterPre, + NULL, /* channelRegisterPost, */ + channel_report, + NULL /* channel_close */ +}; + +static void tsInitialize(void) +{ + static int firstTime = 1; + + if(!firstTime) return; + firstTime = 0; + + if (!tsStringFreeList) { + freeListInitPvt(&tsStringFreeList, + sizeof(epicsOldString), 64); + } + + chfPluginRegister("ts", &tsPif, NULL); +} + +epicsExportRegistrar(tsInitialize); diff --git a/src/std/softIoc/base.dbd b/src/std/softIoc/base.dbd index 894a46722..3134fc4fe 100644 --- a/src/std/softIoc/base.dbd +++ b/src/std/softIoc/base.dbd @@ -10,6 +10,9 @@ include "menuConvert.dbd" # Record types include "stdRecords.dbd" +# Channel filters & plugins +include "filters.dbd" + # "Soft Channel", "Raw Soft Channel", and "Async Soft Channel" device support include "devSoft.dbd"