Merge pull request #63 from epics-base/accesss-security

Accesss security
This commit is contained in:
Marty Kraimer
2021-04-01 12:15:38 -04:00
committed by GitHub
37 changed files with 750 additions and 1033 deletions

View File

@ -2,6 +2,13 @@
This document summarizes the changes to the module between releases.
## Release 4.6.0 (EPICS 7.0.5.* April 2021)
* Access Security is now supported.
* <b>special</b> has been revised and extended.
* addRecord, removeRecord, processRecord, and traceRecord are replaced by pvdbcr versions.
* <b>support</b> is DEPRECATED
## Release 4.5.3 (EPICS 7.0.5 Feb 2021)
* The previously deprecated destroy methods have been removed.

View File

@ -1,8 +0,0 @@
TODO
===========
create more regression tests
----------------
Currently only some simple tests exist. Most of the testing has been via the examples

View File

@ -4,72 +4,66 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>pvDatabaseCPP</title>
<title>EPICS pvDatabaseCPP</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
body { margin-right: 10% }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
<script type="text/javascript" src="http://epics-pvdata.sourceforge.net/script/tocgen.js"></script>
</head>
<body>
<div class="head">
<h1>pvDatabaseCPP</h1>
<h2 class="nocount">Release ? - TBD</h2>
Latest update 2019.09.11.
<h1>EPICS pvDatabaseCPP</h1>
<h2 class="nocount">Release 4.6.0 - March 2021</h2>
<h2 class="nocount">Abstract</h2>
<p>This document describes pvDatabaseCPP,
which is a framework for implementing a network accessible database of smart memory resident
<p><b>pvDatabase</b> is a framework for implementing a network accessible database of smart memory resident
records. Network access is via pvAccess. The data in each record is a top level PVStructure as defined by
pvData. The framework includes a complete implementation of ChannelProvider as defined by pvAccess.
The framework can be extended in order to create record instances that implements services.
The minimum that an extension must provide is a top level PVStructure and a process method.
</p>
<!-- last para of Abstract is boilerplate reference to EPICS -->
<p>For more information about EPICS generally, please refer to the home page of the <a
href="http://www.aps.anl.gov/epics/">Experimental Physics and Industrial
Control System</a>.</p>
</div>
<div id="toc">
<h2 class="nocount">Table of Contents</h2>
</div>
</div> <!-- head -->
<div id="contents" class="contents">
<hr />
<h2>Overview</h2>
<p>
Documentation for pvDatabaseCPP is available at:
<a
href="https://mrkraimer.github.io/website/developerGuide/pvDatabase/pvDatabaseCPP.html">
pvDatabase
</a>
</p>
<p>
pvDatabaseCPP is one of the components of
EPICS Version 7
<a href="https://epics-controls.org/resources-and-support/base/epics-7/">
EPICS-7
</a>
</p>
<p>This document is only a guide to help locate code and documentation related to pvDatabaseCPP
</p>
<p>
It is intended for developers that want to use pvDatabaseCPP.
</p>
<h2>Developer Guide</h2>
@ -79,204 +73,28 @@ href="https://mrkraimer.github.io/website/developerGuide/developerGuide.html">
developerGuide
</a>
</p>
<p>This guide discusses all the components that are part of an <b>EPICS V4</b> release.
<p>This guide provides an overview of the components that are part of an <b>EPICS V4</b> release.
Some understanding of the components and how they are related is necessary in order to
develop code that uses pvDatabaseCPP.
In particular read everything related to pvDatabase.
</p>
<p>pvDatabase has plugin support, which is implemented in <b>pvCopy</b>.
<b>pvCopy</b> was originally implemented in <b>pvDataCPP</b>,
but pvDatabaseCPP now implements its own version and adds plugin support.
</p>
<p>
See
<a
href="https://mrkraimer.github.io/website/pvRequest/pvRequest.html">
pvRequest
</a>
for details.
</p>
<p>The developerGuide discusses code in a way that applies to both CPP and C++.
For the descriptions of the CPP specific code consult the following sections.
In particular read everything related to pvaClient.
</p>
<h2>doxygen</h2>
<p>doxygen documentation is available at
<a
href="./html/index.html">doxgen</a>
href="./html/index.html">doxygen</a>
</p>
<h2>pvDatabaseCPP</h2>
<h3>include/pv</h3>
<p>The header files that describe the various components implemented by pvDatabase.
</p>
<dl>
<dt>pvDatabase.h</dt>
<dd>
This describes PVRecord and PVDatabase.
</dd>
<dt>channelProviderLocal.h </dt>
<dd>
This describes a channel provider for PVDatabase
</dd>
<dt>pvSupport.h</dt>
<dd>
This is the base class for support attached to a field of a record.
</dd>
<dt>controlSupport.h</dt>
<dd>
This is support that implements control limits.
</dd>
<dt>scalarAlarmSupport.h</dt>
<dd>
This is support for a alarm limits for a scalar numeric field.
</dd>
<dt>processRecord.h</dt>
<dd>
This is a PVRecord that periodical processes a set of PVRecords in the local PVDatabase.
</dd>
<dt>addRecord.h</dt>
<dd>
This is a PVRecord that adds a new PVRecord to the local PVDatabase.
</dd>
<dt>removeRecord.h</dt>
<dd>
This is a PVRecord that removes a PVRecord in the local PVDatabase.
</dd>
<dt>traceRecord.h</dt>
<dd>
This is a PVRecord that sets the trace value for another PVRecord in the local PVDatabase.
</dd>
<dt>pvStructureCopy.h</dt>
<dd>
This is a facility that allows a client to access a subfield of the fields in a PVRecord.
It also provides record and field options an plugin support.
</dd>
<dt>pvPlugin.h</dt>
<dd>
This is the base class for a plugin attached to a record or field of PVRecord.
</dd>
<dt>pvArrayPlugin.h</dt>
<dd>
A plugin for accessing a subset of the elements in an array field.
</dd>
<dt>pvDeadbandPlugin.h</dt>
<dd>
A deadband plugin for monitors.
</dd>
<dt>pvTimestampPlugin.h</dt>
<dd>
A plugin for timeStamp.
</dd>
</dl>
<h3>src/database</h3>
<p>This has the code that implements pvDatabase and pvRecord.</p>
<h3>src/pvAccess</h3>
<p>This has the code for the channel provider for pvDatabase.
</p>
<h3>src/support</h3>
<p>This has the pvSupport code.</p>
<h3>src/special</h3>
<p>
This has the code for processRecord, addRecord, removeRecord, and traceRecord.
</p>
<h3>src/copy</h3>
<p>This has the code for pvStructureCopy and all the plugin support.
</p>
<h2>exampleCPP</h2>
<p>Example code is available as part of this release.
<p>Example code is available at
<a
href="https://github.com/epics-base/exampleCPP">
exampleCPP
</a>
</p>
<p>In particular look at the example code mentioned in the following sub-sections.
<p>In particular look at database, exampleLink, and helloPutGet.
</p>
<h3>database</h3>
<p>This has many examples of how to create both soft records and records that implement
other functionality.</p>
<dl>
<dt>exampleDatabase.cpp</dt>
<dd>
This shows how to create soft records of each pvData type.<br />
In addition shows how to create instances of the following two records.
</dd>
<dt>exampleHelloRecord.cpp</dt>
<dd>
This is a simple "hello world" that is intentended to be used via a channelPutGet request.
</dd>
<dt>exampleHelloRPC.cpp</dt>
<dd>
This is a simple "hello world" that is intentended to be used via a channelRPC request.
</dd>
<dt>exampleDatabaseMain.cpp</dt>
<dd>
This shows how to create a standalone IOC.
</dd>
<dt>ioc and iocBoot</dt>
<dd>
This has code and examples to create a V3 IOC which also has a PVDatabase.
</dd>
</dl>
<h3>exampleLink</h3>
<p>This shows how to implement a record that has a link to another record</p>
<dl>
<dt>exampleMonitorLinkRecord</dt>
<dd>
This creates a monitor link to another record.
</dd>
<dt>exampleGetLinkRecord</dt>
<dd>
This creates a get link to another record.
</dd>
<dt>examplePutLinkRecord</dt>
<dd>
This creates a put link to another record.
</dd>
</dl>
<h3>support</h3>
<p>This creates records that have the following features:</p>
<dl>
<dt>value</dt>
<dd>
Each record has a value field the is a numeric scalar field.
In addition each has the following fields:
alarm,timeStamp,control,scalarAlarm, and display.
</dd>
<dt>support</dt>
<dd>
Each record uses the control and scalarAlarm support provided by pvDatabaseCPP.
</dd>
</dl>
<p>
It also creates records that can be used by clients to show example of the plugin support.
</p>
<h2>iocshell commands</h2>
<p>Shell commands are made available via the standard DBD include mechanism
provided by iocCore.
The following provide EPICS V4 shell commands:</p>
<pre>
pvAccessCPP
qsrv
pvDatabaseCPP
</pre>
<p>pvDatabaseCPP provides the following iocshell command.</p>
<dl>
<dt>registerChannelProviderLocal</dt>
<dd>Including <b>registerChannelProviderLocal.dbd</b> as a dbd file automatically starts provider local
and also creates the pvdbl shell command.
</dd>
<dt>pvdbl</dt>
<dd>Provides a list of all the pvRecords in database <b>master</b>
</dd>
</dl>
<p>In addition any code that implements a PVRecord must implement an ioc command.
Look at the examples in <b>exampleCPP/support</b> to see how to implement shell commands.</p>
</div>
</div> <!-- class="contents" -->
</body>
</html>

View File

@ -23,11 +23,6 @@ INC += pv/pvDatabase.h
INC += pv/channelProviderLocal.h
INC += pv/traceRecord.h
INC += pv/removeRecord.h
INC += pv/addRecord.h
INC += pv/processRecord.h
INC += pv/pvSupport.h
INC += pv/controlSupport.h
INC += pv/scalarAlarmSupport.h

View File

@ -1,63 +0,0 @@
/* addRecord.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2013.04.18
*/
#ifndef ADDRECORD_H
#define ADDRECORD_H
#include <pv/channelProviderLocal.h>
#include <shareLib.h>
namespace epics { namespace pvDatabase {
class AddRecord;
typedef std::tr1::shared_ptr<AddRecord> AddRecordPtr;
/**
* @brief Add another record in the same database.
*
* A record to add another record
* It is meant to be used via a channelPutGet request.
* The argument has one field: recordName.
* The result has a field named status.
*/
class epicsShareClass AddRecord :
public PVRecord
{
public:
POINTER_DEFINITIONS(AddRecord);
/**
* Factory methods to create AddRecord.
* @param recordName The name for the AddRecord.
* @return A shared pointer to AddRecord..
*/
static AddRecordPtr create(
std::string const & recordName);
/**
* standard init method required by PVRecord
* @return true unless record name already exists.
*/
virtual bool init();
/**
* @brief Add the record specified by recordName.
*/
virtual void process();
private:
AddRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVStringPtr pvResult;
};
}}
#endif /* ADDRECORD_H */

View File

@ -362,6 +362,12 @@ public:
* @return true if client can write
*/
virtual bool canWrite();
/**
* @brief determines if client can read
*
* @return true if client can read
*/
virtual bool canRead();
protected:
shared_pointer getPtrSelf()
{

View File

@ -1,89 +0,0 @@
/* processRecord.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2019.06.07
*/
#ifndef PROCESSRECORD_H
#define PROCESSRECORD_H
#include <map>
#include <epicsThread.h>
#include <pv/event.h>
#include <pv/channelProviderLocal.h>
#include <shareLib.h>
namespace epics { namespace pvDatabase {
typedef std::tr1::shared_ptr<epicsThread> EpicsThreadPtr;
class ProcessRecord;
typedef std::tr1::shared_ptr<ProcessRecord> ProcessRecordPtr;
/**
* @brief Process another record in the same database.
*
* A record to process another record
* It is meant to be used via a channelPutGet request.
* The argument has one field: recordName.
* The result has a field named status.
*/
class epicsShareClass ProcessRecord :
public PVRecord,
public epicsThreadRunable
{
public:
POINTER_DEFINITIONS(ProcessRecord);
/**
* Factory methods to create ProcessRecord.
* @param recordName The name for the ProcessRecord.
* @param delay Delay time to wait between process requests.
* @return A shared pointer to ProcessRecord.
*/
static ProcessRecordPtr create(
std::string const & recordName,double delay);
/**
* standard init method required by PVRecord
* @return true unless record name already exists.
*/
virtual bool init();
/**
* @brief Process the record specified by recordName.
*/
virtual void process();
/**
* @brief The run method for the thread.
*/
virtual void run();
/**
* @brief Start the thread
*/
void startThread();
/**
* @brief Stop the thread
*/
void stop();
private:
ProcessRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure,double delay);
double delay;
EpicsThreadPtr thread;
epics::pvData::Event runStop;
epics::pvData::Event runReturn;
PVDatabasePtr pvDatabase;
PVRecordMap pvRecordMap;
epics::pvData::PVStringPtr pvCommand;
epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVStringPtr pvResult;
epics::pvData::Mutex mutex;
};
}}
#endif /* PROCESSRECORD_H */

View File

@ -248,6 +248,16 @@ public:
* @return The name.
*/
std::string getAsGroup() const {return asGroup;}
/**
* @brief set access security level.
* @param level The level
*/
void setAsLevel(int level) {asLevel=level;}
/**
* @brief set access security group
* @param group The group name
*/
void setAsGroup(const std::string& group) {asGroup = group;}
protected:
/**
* @brief Constructor

View File

@ -1,63 +0,0 @@
/* removeRecord.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2013.04.18
*/
#ifndef REMOVERECORD_H
#define REMOVERECORD_H
#include <pv/channelProviderLocal.h>
#include <shareLib.h>
namespace epics { namespace pvDatabase {
class RemoveRecord;
typedef std::tr1::shared_ptr<RemoveRecord> RemoveRecordPtr;
/**
* @brief Remove another record in the same database.
*
* A record to remove another record
* It is meant to be used via a channelPutGet request.
* The argument has one field: recordName.
* The result has a field named status.
*/
class epicsShareClass RemoveRecord :
public PVRecord
{
public:
POINTER_DEFINITIONS(RemoveRecord);
/**
* Factory methods to create RemoveRecord.
* @param recordName The name for the RemoveRecord.
* @return A shared pointer to RemoveRecord..
*/
static RemoveRecordPtr create(
std::string const & recordName);
/**
* standard init method required by PVRecord
* @return true unless record name already exists.
*/
virtual bool init();
/**
* @brief Remove the record specified by recordName.
*/
virtual void process();
private:
RemoveRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVStringPtr pvResult;
};
}}
#endif /* REMOVERECORD_H */

View File

@ -1,66 +0,0 @@
/* traceRecord.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2013.04.18
*/
#ifndef TRACERECORD_H
#define TRACERECORD_H
#include <pv/channelProviderLocal.h>
#include <shareLib.h>
namespace epics { namespace pvDatabase {
class TraceRecord;
typedef std::tr1::shared_ptr<TraceRecord> TraceRecordPtr;
/**
* @brief Trace activity of PVRecord.
*
* A record to set the trace value for another record
* It is meant to be used via a channelPutGet request.
* The argument has two fields: recordName and level.
* The result has a field named status.
*/
class epicsShareClass TraceRecord :
public PVRecord
{
public:
POINTER_DEFINITIONS(TraceRecord);
/**
* @brief Factory method to create TraceRecord.
*
* @param recordName The name for the TraceRecord.
* @return A shared pointer to TraceRecord..
*/
static TraceRecordPtr create(
std::string const & recordName);
/**
* standard init method required by PVRecord
* @return true unless record name already exists.
*/
virtual bool init();
/**
* @brief Set the trace level for record specified by recordName.
*/
virtual void process();
private:
TraceRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVIntPtr pvLevel;
epics::pvData::PVStringPtr pvResult;
};
}}
#endif /* TRACERECORD_H */

View File

@ -329,6 +329,13 @@ void ChannelGetLocal::get()
{
ChannelGetRequester::shared_pointer requester = channelGetRequester.lock();
if(!requester) return;
ChannelLocalPtr channel(channelLocal.lock());
if(!channel) throw std::logic_error("channel is deleted");
if(!channel->canRead()) {
Status status = Status::error("ChannelGet::get is not allowed");
requester->getDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
return;
}
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
@ -490,6 +497,13 @@ void ChannelPutLocal::get()
{
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
if(!requester) return;
ChannelLocalPtr channel(channelLocal.lock());
if(!channel) throw std::logic_error("channel is deleted");
if(!channel->canRead()) {
Status status = Status::error("ChannelPut::get is not allowed");
requester->getDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
return;
}
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
@ -521,8 +535,9 @@ void ChannelPutLocal::put(
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
if(!requester) return;
ChannelLocalPtr channel(channelLocal.lock());
if(!channel) throw std::logic_error("channel is deleted");
if(!channel->canWrite()) {
Status status = Status::error("Channel put is not allowed");
Status status = Status::error("ChannelPut::put is not allowed");
requester->putDone(status,getPtrSelf());
return;
}
@ -688,9 +703,10 @@ void ChannelPutGetLocal::putGet(
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
if(!requester) return;
ChannelLocalPtr channel(channelLocal.lock());
if(!channel->canWrite()) {
Status status = Status::error("Channel putGet is not allowed");
requester->putGetDone(status,getPtrSelf(),pvGetStructure,getBitSet);
if(!channel) throw std::logic_error("channel is deleted");
if(!channel->canWrite()||!channel->canRead() ) {
Status status = Status::error("ChannelPutGet::putGet is not allowed");
requester->putGetDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
return;
}
PVRecordPtr pvr(pvRecord.lock());
@ -721,6 +737,13 @@ void ChannelPutGetLocal::getPut()
{
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
if(!requester) return;
ChannelLocalPtr channel(channelLocal.lock());
if(!channel) throw std::logic_error("channel is deleted");
if(!channel->canRead()) {
Status status = Status::error("ChannelPutGet::getPut is not allowed");
requester->getPutDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
return;
}
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
@ -748,6 +771,13 @@ void ChannelPutGetLocal::getGet()
{
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
if(!requester) return;
ChannelLocalPtr channel(channelLocal.lock());
if(!channel) throw std::logic_error("channel is deleted");
if(!channel->canRead()) {
Status status = Status::error("ChannelPutGet::getGet is not allowed");
requester->getPutDone(status,getPtrSelf(),PVStructurePtr(),BitSetPtr());
return;
}
PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted");
try {
@ -1324,9 +1354,15 @@ bool ChannelLocal::canWrite()
return false;
}
bool ChannelLocal::canRead()
{
if(!asActive || (asClientPvt && asCheckGet(asClientPvt))) {
return true;
}
return false;
}
ChannelLocal::~ChannelLocal()
{
// cout << "~ChannelLocal()" << endl;
if(asMemberPvt) {
asRemoveMember(&asMemberPvt);
asMemberPvt = 0;

View File

@ -2,17 +2,18 @@
SRC_DIRS += $(PVDATABASE_SRC)/special
LIBSRCS += traceRecord.cpp
LIBSRCS += removeRecord.cpp
LIBSRCS += addRecord.cpp
LIBSRCS += processRecord.cpp
DBD += pvdbcrTraceRecordRegister.dbd
DBD += pvdbcrRemoveRecordRegister.dbd
DBD += pvdbcrAddRecordRegister.dbd
DBD += pvdbcrProcessRecordRegister.dbd
DBD += pvdbcrScalarRegister.dbd
DBD += pvdbcrScalarArrayRegister.dbd
DBD += pvdbSpecialRegister.dbd
DBD += traceRecordRegister.dbd
DBD += removeRecordRegister.dbd
DBD += addRecordRegister.dbd
DBD += processRecordRegister.dbd
LIBSRCS += pvdbcrTraceRecordRegister.cpp
LIBSRCS += pvdbcrRemoveRecordRegister.cpp
LIBSRCS += pvdbcrAddRecordRegister.cpp
LIBSRCS += pvdbcrProcessRecordRegister.cpp
LIBSRCS += pvdbcrScalarRegister.cpp
LIBSRCS += pvdbcrScalarArrayRegister.cpp
LIBSRCS += traceRecordRegister.cpp
LIBSRCS += removeRecordRegister.cpp
LIBSRCS += addRecordRegister.cpp
LIBSRCS += processRecordRegister.cpp

View File

@ -1,62 +0,0 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.07.24
*/
/* Author: Marty Kraimer */
#include <epicsThread.h>
#include <iocsh.h>
#include <pv/event.h>
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
#include <pv/rpcService.h>
// The following must be the last include for code pvDatabase uses
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/pvDatabase.h"
#include "pv/addRecord.h"
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg testArg0 = { "recordName", iocshArgString };
static const iocshArg *testArgs[] = {
&testArg0};
static const iocshFuncDef addRecordFuncDef = {"addRecordCreate", 1,testArgs};
static void addRecordCallFunc(const iocshArgBuf *args)
{
char *recordName = args[0].sval;
if(!recordName) {
throw std::runtime_error("addRecordCreate invalid number of arguments");
}
AddRecordPtr record = AddRecord::create(recordName);
bool result = PVDatabase::getMaster()->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl;
}
static void addRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&addRecordFuncDef, addRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(addRecordRegister);
}

View File

@ -1 +0,0 @@
registrar("addRecordRegister")

View File

@ -1,67 +0,0 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.07.24
*/
/* Author: Marty Kraimer */
#include <epicsThread.h>
#include <iocsh.h>
#include <pv/event.h>
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
#include <pv/rpcService.h>
// The following must be the last include for code pvDatabase uses
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/pvDatabase.h"
#include "pv/processRecord.h"
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg testArg0 = { "recordName", iocshArgString };
static const iocshArg testArg1 = { "delay", iocshArgDouble };
static const iocshArg *testArgs[] = {
&testArg0,&testArg1};
static const iocshFuncDef processRecordFuncDef = {"processRecordCreate", 2,testArgs};
static void processRecordCallFunc(const iocshArgBuf *args)
{
char *recordName = args[0].sval;
if(!recordName) {
throw std::runtime_error("processRecordCreate invalid number of arguments");
}
double delay = args[1].dval;
if(delay<0.0) delay = 1.0;
ProcessRecordPtr record = ProcessRecord::create(recordName,delay);
bool result = PVDatabase::getMaster()->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl;
}
static void processRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&processRecordFuncDef, processRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(processRecordRegister);
}

View File

@ -1 +0,0 @@
registrar("processRecordRegister")

View File

@ -0,0 +1,6 @@
include "pvdbcrAddRecordRegister.dbd"
include "pvdbcrRemoveRecordRegister.dbd"
include "pvdbcrProcessRecordRegister.dbd"
include "pvdbcrTraceRecordRegister.dbd"
include "pvdbcrScalarRegister.dbd"
include "pvdbcrScalarArrayRegister.dbd"

View File

@ -1,45 +1,57 @@
/* addRecord.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.04.18
* @date 2021.03.12
*/
#include <string>
#include <cstring>
#include <stdexcept>
#include <memory>
#include <set>
#include <pv/lock.h>
#include <pv/pvType.h>
#include <pv/pvData.h>
#include <iocsh.h>
#include <pv/standardField.h>
#include <pv/pvTimeStamp.h>
#include <pv/standardPVField.h>
#include <pv/timeStamp.h>
#include <pv/rpcService.h>
#include <pv/pvTimeStamp.h>
#include <pv/alarm.h>
#include <pv/pvAlarm.h>
#include <pv/pvAccess.h>
#include <pv/status.h>
#include <pv/serverContext.h>
// The following must be the last include for code exampleLink uses
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/channelProviderLocal.h"
#include "pv/pvDatabase.h"
#include "pv/addRecord.h"
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
namespace epics { namespace pvDatabase {
class PvdbcrAddRecord;
typedef std::tr1::shared_ptr<PvdbcrAddRecord> PvdbcrAddRecordPtr;
AddRecordPtr AddRecord::create(
class epicsShareClass PvdbcrAddRecord :
public PVRecord
{
private:
PvdbcrAddRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
PVStringPtr pvRecordName;
epics::pvData::PVStringPtr pvResult;
public:
POINTER_DEFINITIONS(PvdbcrAddRecord);
static PvdbcrAddRecordPtr create(
std::string const & recordName);
virtual bool init();
virtual void process();
};
PvdbcrAddRecordPtr PvdbcrAddRecord::create(
std::string const & recordName)
{
FieldCreatePtr fieldCreate = getFieldCreate();
@ -55,20 +67,20 @@ AddRecordPtr AddRecord::create(
endNested()->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
AddRecordPtr pvRecord(
new AddRecord(recordName,pvStructure));
PvdbcrAddRecordPtr pvRecord(
new PvdbcrAddRecord(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset();
return pvRecord;
}
AddRecord::AddRecord(
PvdbcrAddRecord::PvdbcrAddRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
}
bool AddRecord::init()
bool PvdbcrAddRecord::init()
{
initPVRecord();
PVStructurePtr pvStructure = getPVStructure();
@ -79,7 +91,7 @@ bool AddRecord::init()
return true;
}
void AddRecord::process()
void PvdbcrAddRecord::process()
{
PVDataCreatePtr pvDataCreate = getPVDataCreate();
string name = pvRecordName->get();
@ -113,5 +125,43 @@ void AddRecord::process()
}
}
static const iocshArg arg0 = { "recordName", iocshArgString };
static const iocshArg arg1 = { "asLevel", iocshArgInt };
static const iocshArg arg2 = { "asGroup", iocshArgString };
static const iocshArg *args[] = {&arg0,&arg1,&arg2};
}}
static const iocshFuncDef pvdbcrAddRecordFuncDef = {"pvdbcrAddRecord", 3,args};
static void pvdbcrAddRecordCallFunc(const iocshArgBuf *args)
{
char *sval = args[0].sval;
if(!sval) {
throw std::runtime_error("pvdbcrAddRecord recordName not specified");
}
string recordName = string(sval);
int asLevel = args[1].ival;
string asGroup("DEFAULT");
sval = args[2].sval;
if(sval) {
asGroup = string(sval);
}
PvdbcrAddRecordPtr record = PvdbcrAddRecord::create(recordName);
record->setAsLevel(asLevel);
record->setAsGroup(asGroup);
PVDatabasePtr master = PVDatabase::getMaster();
bool result = master->addRecord(record);
if(!result) cout << "recordname " << recordName << " not added" << endl;
}
static void pvdbcrAddRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&pvdbcrAddRecordFuncDef, pvdbcrAddRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(pvdbcrAddRecordRegister);
}

View File

@ -0,0 +1 @@
registrar("pvdbcrAddRecordRegister")

View File

@ -1,46 +1,70 @@
/* processRecord.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.04.18
* @date 2021.03.12
*/
#include <map>
#include <epicsThread.h>
#include <epicsGuard.h>
#include <pv/event.h>
#include <shareLib.h>
#include <string>
#include <cstring>
#include <stdexcept>
#include <memory>
#include <set>
#include <pv/lock.h>
#include <pv/pvType.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
#include <iocsh.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/timeStamp.h>
#include <pv/rpcService.h>
#include <pv/pvTimeStamp.h>
#include <pv/alarm.h>
#include <pv/pvAlarm.h>
#include <pv/pvAccess.h>
#include <pv/status.h>
#include <pv/serverContext.h>
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/channelProviderLocal.h"
#include "pv/pvDatabase.h"
#include "pv/processRecord.h"
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
namespace epics { namespace pvDatabase {
typedef std::tr1::shared_ptr<epicsThread> EpicsThreadPtr;
class PvdbcrProcessRecord;
typedef std::tr1::shared_ptr<PvdbcrProcessRecord> PvdbcrProcessRecordPtr;
ProcessRecordPtr ProcessRecord::create(
class epicsShareClass PvdbcrProcessRecord :
public PVRecord,
public epicsThreadRunable
{
public:
POINTER_DEFINITIONS(PvdbcrProcessRecord);
static PvdbcrProcessRecordPtr create(
std::string const & recordName,double delay);
virtual bool init();
virtual void process();
virtual void run();
void startThread();
void stop();
private:
PvdbcrProcessRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure,double delay);
double delay;
EpicsThreadPtr thread;
epics::pvData::Event runStop;
epics::pvData::Event runReturn;
PVDatabasePtr pvDatabase;
PVRecordMap pvRecordMap;
epics::pvData::PVStringPtr pvCommand;
epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVStringPtr pvResult;
epics::pvData::Mutex mutex;
};
PvdbcrProcessRecordPtr PvdbcrProcessRecord::create(
std::string const & recordName,double delay)
{
FieldCreatePtr fieldCreate = getFieldCreate();
@ -55,13 +79,13 @@ ProcessRecordPtr ProcessRecord::create(
endNested()->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
ProcessRecordPtr pvRecord(
new ProcessRecord(recordName,pvStructure,delay));
PvdbcrProcessRecordPtr pvRecord(
new PvdbcrProcessRecord(recordName,pvStructure,delay));
if(!pvRecord->init()) pvRecord.reset();
return pvRecord;
}
void ProcessRecord::startThread()
void PvdbcrProcessRecord::startThread()
{
thread = EpicsThreadPtr(new epicsThread(
*this,
@ -71,14 +95,14 @@ void ProcessRecord::startThread()
thread->start();
}
void ProcessRecord::stop()
void PvdbcrProcessRecord::stop()
{
runStop.signal();
runReturn.wait();
}
ProcessRecord::ProcessRecord(
PvdbcrProcessRecord::PvdbcrProcessRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure,double delay)
: PVRecord(recordName,pvStructure),
@ -87,7 +111,7 @@ ProcessRecord::ProcessRecord(
{
}
bool ProcessRecord::init()
bool PvdbcrProcessRecord::init()
{
initPVRecord();
PVStructurePtr pvStructure = getPVStructure();
@ -100,7 +124,7 @@ bool ProcessRecord::init()
return true;
}
void ProcessRecord::process()
void PvdbcrProcessRecord::process()
{
string recordName = pvRecordName->get();
string command = pvCommand->get();
@ -135,7 +159,7 @@ void ProcessRecord::process()
}
}
void ProcessRecord::run()
void PvdbcrProcessRecord::run()
{
while(true) {
if(runStop.tryWait()) {
@ -162,5 +186,46 @@ void ProcessRecord::run()
}
}
static const iocshArg arg0 = { "recordName", iocshArgString };
static const iocshArg arg1 = { "delay", iocshArgDouble };
static const iocshArg arg2 = { "asLevel", iocshArgInt };
static const iocshArg arg3 = { "asGroup", iocshArgString };
static const iocshArg *args[] = {&arg0,&arg1,&arg2,&arg3};
}}
static const iocshFuncDef pvdbcrProcessRecordFuncDef = {"pvdbcrProcessRecord", 4,args};
static void pvdbcrProcessRecordCallFunc(const iocshArgBuf *args)
{
char *sval = args[0].sval;
if(!sval) {
throw std::runtime_error("pvdbcrProcessRecord recordName not specified");
}
string recordName = string(sval);
double delay = args[1].dval;
if(delay<0.0) delay = 1.0;
int asLevel = args[2].ival;
string asGroup("DEFAULT");
sval = args[3].sval;
if(sval) {
asGroup = string(sval);
}
PvdbcrProcessRecordPtr record = PvdbcrProcessRecord::create(recordName,delay);
record->setAsLevel(asLevel);
record->setAsGroup(asGroup);
PVDatabasePtr master = PVDatabase::getMaster();
bool result = master->addRecord(record);
if(!result) cout << "recordname " << recordName << " not added" << endl;
}
static void pvdbcrProcessRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&pvdbcrProcessRecordFuncDef, pvdbcrProcessRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(pvdbcrProcessRecordRegister);
}

View File

@ -0,0 +1 @@
registrar("pvdbcrProcessRecordRegister")

View File

@ -0,0 +1,140 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2021.03.12
*/
#include <iocsh.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/timeStamp.h>
#include <pv/pvTimeStamp.h>
#include <pv/alarm.h>
#include <pv/pvAlarm.h>
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/channelProviderLocal.h"
#include "pv/pvDatabase.h"
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
class PvdbcrRemoveRecord;
typedef std::tr1::shared_ptr<PvdbcrRemoveRecord> PvdbcrRemoveRecordPtr;
class epicsShareClass PvdbcrRemoveRecord :
public PVRecord
{
public:
POINTER_DEFINITIONS(PvdbcrRemoveRecord);
static PvdbcrRemoveRecordPtr create(
std::string const & recordName);
virtual bool init();
virtual void process();
private:
PvdbcrRemoveRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVStringPtr pvResult;
};
PvdbcrRemoveRecordPtr PvdbcrRemoveRecord::create(
std::string const & recordName)
{
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
addNestedStructure("argument")->
add("recordName",pvString)->
endNested()->
addNestedStructure("result") ->
add("status",pvString) ->
endNested()->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
PvdbcrRemoveRecordPtr pvRecord(
new PvdbcrRemoveRecord(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset();
return pvRecord;
}
PvdbcrRemoveRecord::PvdbcrRemoveRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
}
bool PvdbcrRemoveRecord::init()
{
initPVRecord();
PVStructurePtr pvStructure = getPVStructure();
pvRecordName = pvStructure->getSubField<PVString>("argument.recordName");
if(!pvRecordName) return false;
pvResult = pvStructure->getSubField<PVString>("result.status");
if(!pvResult) return false;
return true;
}
void PvdbcrRemoveRecord::process()
{
string name = pvRecordName->get();
PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name);
if(!pvRecord) {
pvResult->put(name + " not found");
return;
}
pvRecord->remove();
pvResult->put("success");
}
static const iocshArg arg0 = { "recordName", iocshArgString };
static const iocshArg arg1 = { "asLevel", iocshArgInt };
static const iocshArg arg2 = { "asGroup", iocshArgString };
static const iocshArg *args[] = {&arg0,&arg1,&arg2};
static const iocshFuncDef pvdbcrRemoveRecordFuncDef = {"pvdbcrRemoveRecord", 3,args};
static void pvdbcrRemoveRecordCallFunc(const iocshArgBuf *args)
{
char *sval = args[0].sval;
if(!sval) {
throw std::runtime_error("pvdbcrRemoveRecord recordName not specified");
}
string recordName = string(sval);
int asLevel = args[1].ival;
string asGroup("DEFAULT");
sval = args[2].sval;
if(sval) {
asGroup = string(sval);
}
PvdbcrRemoveRecordPtr record = PvdbcrRemoveRecord::create(recordName);
record->setAsLevel(asLevel);
record->setAsGroup(asGroup);
PVDatabasePtr master = PVDatabase::getMaster();
bool result = master->addRecord(record);
if(!result) cout << "recordname " << recordName << " not added" << endl;
}
static void pvdbcrRemoveRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&pvdbcrRemoveRecordFuncDef, pvdbcrRemoveRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(pvdbcrRemoveRecordRegister);
}

View File

@ -0,0 +1 @@
registrar("pvdbcrRemoveRecordRegister")

View File

@ -0,0 +1,83 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2021.03.12
*/
/* Author: Marty Kraimer */
#include <iocsh.h>
#include <pv/standardField.h>
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
// The following must be the last include for code pvDatabase implements
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/channelProviderLocal.h"
#include "pv/pvDatabase.h"
using namespace epics::pvData;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg arg0 = { "recordName", iocshArgString };
static const iocshArg arg1 = { "scalarType", iocshArgString };
static const iocshArg arg2 = { "asLevel", iocshArgInt };
static const iocshArg arg3 = { "asGroup", iocshArgString };
static const iocshArg *args[] = {&arg0,&arg1,&arg2,&arg3};
static const iocshFuncDef pvdbcrScalarArrayFuncDef = {"pvdbcrScalarArray", 4,args};
static void pvdbcrScalarArrayCallFunc(const iocshArgBuf *args)
{
char *sval = args[0].sval;
if(!sval) {
throw std::runtime_error("pvdbcrScalarArrayCreate recordName not specified");
}
string recordName = string(sval);
sval = args[1].sval;
if(!sval) {
throw std::runtime_error("pvdbcrScalarArrayCreate scalarType not specified");
}
string scalarType = string(sval);
int asLevel = args[2].ival;
string asGroup("DEFAULT");
sval = args[3].sval;
if(sval) {
asGroup = string(sval);
}
ScalarType st = epics::pvData::ScalarTypeFunc::getScalarType(scalarType);
FieldCreatePtr fieldCreate = getFieldCreate();
StandardFieldPtr standardField = getStandardField();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
StructureConstPtr top = fieldCreate->createFieldBuilder()->
addArray("value",st) ->
add("timeStamp",standardField->timeStamp()) ->
add("alarm",standardField->alarm()) ->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(top);
PVRecordPtr record = PVRecord::create(recordName,pvStructure);
record->setAsLevel(asLevel);
record->setAsGroup(asGroup);
PVDatabasePtr master = PVDatabase::getMaster();
bool result = master->addRecord(record);
if(!result) cout << "recordname " << recordName << " not added" << endl;
}
static void pvdbcrScalarArrayRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&pvdbcrScalarArrayFuncDef, pvdbcrScalarArrayCallFunc);
}
}
extern "C" {
epicsExportRegistrar(pvdbcrScalarArrayRegister);
}

View File

@ -0,0 +1 @@
registrar("pvdbcrScalarArrayRegister")

View File

@ -0,0 +1,80 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2021.03.12
*/
#include <iocsh.h>
#include <pv/standardField.h>
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
// The following must be the last include for code pvDatabase implements
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/channelProviderLocal.h"
#include "pv/pvDatabase.h"
using namespace epics::pvData;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg arg0 = { "recordName", iocshArgString };
static const iocshArg arg1 = { "scalarType", iocshArgString };
static const iocshArg arg2 = { "asLevel", iocshArgInt };
static const iocshArg arg3 = { "asGroup", iocshArgString };
static const iocshArg *args[] = {&arg0,&arg1,&arg2,&arg3};
static const iocshFuncDef pvdbcrScalarFuncDef = {"pvdbcrScalar", 4,args};
static void pvdbcrScalarCallFunc(const iocshArgBuf *args)
{
char *sval = args[0].sval;
if(!sval) {
throw std::runtime_error("pvdbcrScalarArrayCreate recordName not specified");
}
string recordName = string(sval);
sval = args[1].sval;
if(!sval) {
throw std::runtime_error("pvdbcrScalarArrayCreate scalarType not specified");
}
string scalarType = string(sval);
int asLevel = args[2].ival;
string asGroup("DEFAULT");
sval = args[3].sval;
if(sval) {
asGroup = string(sval);
}
ScalarType st = epics::pvData::ScalarTypeFunc::getScalarType(scalarType);
FieldCreatePtr fieldCreate = getFieldCreate();
StandardFieldPtr standardField = getStandardField();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
StructureConstPtr top = fieldCreate->createFieldBuilder()->
add("value",st) ->
add("timeStamp",standardField->timeStamp()) ->
add("alarm",standardField->alarm()) ->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(top);
PVRecordPtr record = PVRecord::create(recordName,pvStructure);
record->setAsLevel(asLevel);
record->setAsGroup(asGroup);
PVDatabasePtr master = PVDatabase::getMaster();
bool result = master->addRecord(record);
if(!result) cout << "recordname " << recordName << " not added" << endl;
}
static void pvdbcrScalarRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&pvdbcrScalarFuncDef, pvdbcrScalarCallFunc);
}
}
extern "C" {
epicsExportRegistrar(pvdbcrScalarRegister);
}

View File

@ -0,0 +1 @@
registrar("pvdbcrScalarRegister")

View File

@ -0,0 +1,146 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2021.03.12
*/
#include <iocsh.h>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/timeStamp.h>
#include <pv/pvTimeStamp.h>
#include <pv/alarm.h>
#include <pv/pvAlarm.h>
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
// The following must be the last include
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/channelProviderLocal.h"
#include "pv/pvDatabase.h"
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
class PvdbcrTraceRecord;
typedef std::tr1::shared_ptr<PvdbcrTraceRecord> PvdbcrTraceRecordPtr;
class epicsShareClass PvdbcrTraceRecord :
public PVRecord
{
public:
POINTER_DEFINITIONS(PvdbcrTraceRecord);
static PvdbcrTraceRecordPtr create(
std::string const & recordName);
virtual bool init();
virtual void process();
private:
PvdbcrTraceRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVIntPtr pvLevel;
epics::pvData::PVStringPtr pvResult;
};
PvdbcrTraceRecordPtr PvdbcrTraceRecord::create(
std::string const & recordName)
{
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
addNestedStructure("argument")->
add("recordName",pvString)->
add("level",pvInt)->
endNested()->
addNestedStructure("result") ->
add("status",pvString) ->
endNested()->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
PvdbcrTraceRecordPtr pvRecord(
new PvdbcrTraceRecord(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset();
return pvRecord;
}
PvdbcrTraceRecord::PvdbcrTraceRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
}
bool PvdbcrTraceRecord::init()
{
initPVRecord();
PVStructurePtr pvStructure = getPVStructure();
pvRecordName = pvStructure->getSubField<PVString>("argument.recordName");
if(!pvRecordName) return false;
pvLevel = pvStructure->getSubField<PVInt>("argument.level");
if(!pvLevel) return false;
pvResult = pvStructure->getSubField<PVString>("result.status");
if(!pvResult) return false;
return true;
}
void PvdbcrTraceRecord::process()
{
string name = pvRecordName->get();
PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name);
if(!pvRecord) {
pvResult->put(name + " not found");
return;
}
pvRecord->setTraceLevel(pvLevel->get());
pvResult->put("success");
}
static const iocshArg arg0 = { "recordName", iocshArgString };
static const iocshArg arg1 = { "asLevel", iocshArgInt };
static const iocshArg arg2 = { "asGroup", iocshArgString };
static const iocshArg *args[] = {&arg0,&arg1,&arg2};
static const iocshFuncDef pvdbcrTraceRecordFuncDef = {"pvdbcrTraceRecord", 3,args};
static void pvdbcrTraceRecordCallFunc(const iocshArgBuf *args)
{
char *sval = args[0].sval;
if(!sval) {
throw std::runtime_error("pvdbcrTraceRecord recordName not specified");
}
string recordName = string(sval);
int asLevel = args[1].ival;
string asGroup("DEFAULT");
sval = args[2].sval;
if(sval) {
asGroup = string(sval);
}
PvdbcrTraceRecordPtr record = PvdbcrTraceRecord::create(recordName);
record->setAsLevel(asLevel);
record->setAsGroup(asGroup);
PVDatabasePtr master = PVDatabase::getMaster();
bool result = master->addRecord(record);
if(!result) cout << "recordname " << recordName << " not added" << endl;
}
static void pvdbcrTraceRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&pvdbcrTraceRecordFuncDef, pvdbcrTraceRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(pvdbcrTraceRecordRegister);
}

View File

@ -0,0 +1 @@
registrar("pvdbcrTraceRecordRegister")

View File

@ -1,92 +0,0 @@
/* removeRecord.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2013.04.18
*/
#include <string>
#include <cstring>
#include <stdexcept>
#include <memory>
#include <set>
#include <pv/lock.h>
#include <pv/pvType.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
#include <pv/timeStamp.h>
#include <pv/rpcService.h>
#include <pv/pvAccess.h>
#include <pv/status.h>
#include <pv/serverContext.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/pvDatabase.h"
#include "pv/removeRecord.h"
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pvDatabase {
RemoveRecordPtr RemoveRecord::create(
std::string const & recordName)
{
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
addNestedStructure("argument")->
add("recordName",pvString)->
endNested()->
addNestedStructure("result") ->
add("status",pvString) ->
endNested()->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
RemoveRecordPtr pvRecord(
new RemoveRecord(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset();
return pvRecord;
}
RemoveRecord::RemoveRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
}
bool RemoveRecord::init()
{
initPVRecord();
PVStructurePtr pvStructure = getPVStructure();
pvRecordName = pvStructure->getSubField<PVString>("argument.recordName");
if(!pvRecordName) return false;
pvResult = pvStructure->getSubField<PVString>("result.status");
if(!pvResult) return false;
return true;
}
void RemoveRecord::process()
{
string name = pvRecordName->get();
PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name);
if(!pvRecord) {
pvResult->put(name + " not found");
return;
}
pvRecord->remove();
pvResult->put("success");
}
}}

View File

@ -1,62 +0,0 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.07.24
*/
/* Author: Marty Kraimer */
#include <epicsThread.h>
#include <iocsh.h>
#include <pv/event.h>
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
#include <pv/rpcService.h>
// The following must be the last include for code pvDatabase uses
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/pvDatabase.h"
#include "pv/removeRecord.h"
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg testArg0 = { "recordName", iocshArgString };
static const iocshArg *testArgs[] = {
&testArg0};
static const iocshFuncDef removeRecordFuncDef = {"removeRecordCreate", 1,testArgs};
static void removeRecordCallFunc(const iocshArgBuf *args)
{
char *recordName = args[0].sval;
if(!recordName) {
throw std::runtime_error("removeRecordCreate invalid number of arguments");
}
RemoveRecordPtr record = RemoveRecord::create(recordName);
bool result = PVDatabase::getMaster()->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl;
}
static void removeRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&removeRecordFuncDef, removeRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(removeRecordRegister);
}

View File

@ -1 +0,0 @@
registrar("removeRecordRegister")

View File

@ -1,95 +0,0 @@
/* traceRecord.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2013.04.18
*/
#include <string>
#include <cstring>
#include <stdexcept>
#include <memory>
#include <set>
#include <pv/lock.h>
#include <pv/pvType.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
#include <pv/timeStamp.h>
#include <pv/rpcService.h>
#include <pv/pvAccess.h>
#include <pv/status.h>
#include <pv/serverContext.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/channelProviderLocal.h"
#include "pv/traceRecord.h"
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pvDatabase {
TraceRecordPtr TraceRecord::create(
std::string const & recordName)
{
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
addNestedStructure("argument")->
add("recordName",pvString)->
add("level",pvInt)->
endNested()->
addNestedStructure("result") ->
add("status",pvString) ->
endNested()->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
TraceRecordPtr pvRecord(
new TraceRecord(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset();
return pvRecord;
}
TraceRecord::TraceRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
}
bool TraceRecord::init()
{
initPVRecord();
PVStructurePtr pvStructure = getPVStructure();
pvRecordName = pvStructure->getSubField<PVString>("argument.recordName");
if(!pvRecordName) return false;
pvLevel = pvStructure->getSubField<PVInt>("argument.level");
if(!pvLevel) return false;
pvResult = pvStructure->getSubField<PVString>("result.status");
if(!pvResult) return false;
return true;
}
void TraceRecord::process()
{
string name = pvRecordName->get();
PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name);
if(!pvRecord) {
pvResult->put(name + " not found");
return;
}
pvRecord->setTraceLevel(pvLevel->get());
pvResult->put("success");
}
}}

View File

@ -1,63 +0,0 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.07.24
*/
/* Author: Marty Kraimer */
#include <epicsThread.h>
#include <iocsh.h>
#include <pv/event.h>
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
#include <pv/rpcService.h>
// The following must be the last include for code pvDatabase uses
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/pvDatabase.h"
#include "pv/traceRecord.h"
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg testArg0 = { "recordName", iocshArgString };
static const iocshArg *testArgs[] = {
&testArg0};
static const iocshFuncDef traceRecordFuncDef = {"traceRecordCreate", 1,testArgs};
static void traceRecordCallFunc(const iocshArgBuf *args)
{
char *recordName = args[0].sval;
if(!recordName) {
throw std::runtime_error("traceRecordCreate invalid number of arguments");
}
TraceRecordPtr record = TraceRecord::create(recordName);
bool result = PVDatabase::getMaster()->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl;
}
static void traceRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&traceRecordFuncDef, traceRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(traceRecordRegister);
}

View File

@ -1 +0,0 @@
registrar("traceRecordRegister")

View File

@ -46,6 +46,7 @@ epics::pvData::StructureConstPtr ControlSupport::controlField(ScalarType scalarT
ControlSupportPtr ControlSupport::create(PVRecordPtr const & pvRecord)
{
cerr << "ControlSupport IS DEPRECATED\n";
ControlSupportPtr support(new ControlSupport(pvRecord));
return support;
}

View File

@ -48,6 +48,7 @@ epics::pvData::StructureConstPtr ScalarAlarmSupport::scalarAlarmField()
ScalarAlarmSupportPtr ScalarAlarmSupport::create(PVRecordPtr const & pvRecord)
{
cerr << "ScalarAlarmSupport IS DEPRECATED\n";
ScalarAlarmSupportPtr support(new ScalarAlarmSupport(pvRecord));
return support;
}