20 #include <epicsTypes.h>
21 #include <epicsTime.h>
22 #include <epicsThread.h>
23 #include <epicsString.h>
24 #include <epicsTimer.h>
25 #include <epicsMutex.h>
26 #include <epicsEvent.h>
31 #include <epicsExport.h>
55 int function = pasynUser->reason;
56 asynStatus status = asynSuccess;
57 const char *paramName = NULL;
59 getParamName(
function, ¶mName);
64 throw std::runtime_error(
"m_lvdcom is NULL");
67 asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
68 "%s:%s: function=%d, name=%s, value=%s\n",
72 catch(
const std::exception& ex)
74 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
75 "%s:%s: status=%d, function=%d, name=%s, value=%s, error=%s",
84 int function = pasynUser->reason;
85 asynStatus status = asynSuccess;
86 const char *paramName = NULL;
88 getParamName(
function, ¶mName);
93 throw std::runtime_error(
"m_lvdcom is NULL");
96 asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
97 "%s:%s: function=%d, name=%s, value=%s\n",
101 catch(
const std::exception& ex)
103 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
104 "%s:%s: status=%d, function=%d, name=%s, value=%s, error=%s",
113 int function = pasynUser->reason;
114 asynStatus status = asynSuccess;
115 const char *paramName = NULL;
117 getParamName(
function, ¶mName);
123 throw std::runtime_error(
"m_lvdcom is NULL");
126 asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
127 "%s:%s: function=%d, name=%s\n",
128 driverName, functionName,
function, paramName);
131 catch(
const std::exception& ex)
134 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
135 "%s:%s: status=%d, function=%d, name=%s, error=%s",
136 driverName, functionName, status,
function, paramName, ex.what());
143 return writeValue(pasynUser,
"writeFloat64", value);
148 return writeValue(pasynUser,
"writeInt32", value);
153 return readArray(pasynUser,
"readFloat64Array", value, nElements, nIn);
158 return readArray(pasynUser,
"readInt32Array", value, nElements, nIn);
163 return readValue(pasynUser,
"readFloat64", value);
168 return readValue(pasynUser,
"readInt32", value);
173 int function = pasynUser->reason;
175 const char *functionName =
"readOctet";
176 const char *paramName = NULL;
178 getParamName(
function, ¶mName);
184 throw std::runtime_error(
"m_lvdcom is NULL");
187 if ( value_s.size() > maxChars )
190 if (eomReason) { *eomReason = ASYN_EOM_CNT | ASYN_EOM_END; }
191 asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
192 "%s:%s: function=%d, name=%s, value=\"%s\" (TRUNCATED from %d chars)\n",
193 driverName, functionName,
function, paramName, value_s.substr(0,*nActual).c_str(), value_s.size());
197 *nActual = value_s.size();
198 if (eomReason) { *eomReason = ASYN_EOM_END; }
199 asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
200 "%s:%s: function=%d, name=%s, value=\"%s\"\n",
201 driverName, functionName,
function, paramName, value_s.c_str());
203 strncpy(value, value_s.c_str(), maxChars);
206 catch(
const std::exception& ex)
208 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
209 "%s:%s: status=%d, function=%d, name=%s, value=\"%s\", error=%s",
210 driverName, functionName, status,
function, paramName, value_s.c_str(), ex.what());
212 if (eomReason) { *eomReason = ASYN_EOM_END; }
220 int function = pasynUser->reason;
221 asynStatus status = asynSuccess;
222 const char *paramName = NULL;
224 getParamName(
function, ¶mName);
225 const char* functionName =
"writeOctet";
226 std::string value_s(value, maxChars);
231 throw std::runtime_error(
"m_lvdcom is NULL");
234 asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
235 "%s:%s: function=%d, name=%s, value=%s\n",
236 driverName, functionName,
function, paramName, value_s.c_str());
237 *nActual = value_s.size();
240 catch(
const std::exception& ex)
242 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
243 "%s:%s: status=%d, function=%d, name=%s, value=%s, error=%s",
244 driverName, functionName, status,
function, paramName, value_s.c_str(), ex.what());
254 for(std::map<std::string,std::string>::const_iterator it=
m_params.begin(); it !=
m_params.end(); ++it)
256 fprintf(fp,
"Asyn param \"%s\" lvdcom type \"%s\"\n", it->first.c_str(), it->second.c_str());
264 fprintf(fp,
"DCOM pointer is NULL\n");
266 asynPortDriver::report(fp, details);
276 : asynPortDriver(portName,
279 asynInt32Mask | asynInt32ArrayMask | asynFloat64Mask | asynFloat64ArrayMask | asynOctetMask | asynDrvUserMask,
280 asynInt32Mask | asynInt32ArrayMask | asynFloat64Mask | asynFloat64ArrayMask | asynOctetMask,
288 const char *functionName =
"lvDCOMDriver";
290 for(std::map<std::string,std::string>::const_iterator it=
m_params.begin(); it !=
m_params.end(); ++it)
292 if (it->second ==
"float64")
294 createParam(it->first.c_str(), asynParamFloat64, &i);
296 else if (it->second ==
"int32" || it->second ==
"enum" || it->second ==
"ring" || it->second ==
"boolean")
298 createParam(it->first.c_str(), asynParamInt32, &i);
300 else if (it->second ==
"string")
302 createParam(it->first.c_str(), asynParamOctet, &i);
304 else if (it->second ==
"float64array")
306 createParam(it->first.c_str(), asynParamFloat64Array, &i);
308 else if (it->second ==
"int32array")
310 createParam(it->first.c_str(), asynParamInt32Array, &i);
314 errlogSevPrintf(errlogMajor,
"%s:%s: unknown type %s for parameter %s\n",
driverName, functionName, it->second.c_str(), it->first.c_str());
320 if (epicsThreadCreate(
"lvDCOMDriverTask",
321 epicsThreadPriorityMedium,
322 epicsThreadGetStackSize(epicsThreadStackMedium),
325 printf(
"%s:%s: epicsThreadCreate failure\n",
driverName, functionName);
347 std::cerr <<
"Terminating as in SECI mode and new blocks detected" << std::endl;
350 epicsThreadSleep(30);
367 int lvDCOMConfigure(
const char *portName,
const char* configSection,
const char *configFile,
const char *host,
int options,
368 const char* progid,
const char* username,
const char* password)
381 errlogSevPrintf(errlogFatal,
"lvDCOMConfigure failed (NULL)\n");
386 catch(
const std::exception& ex)
388 errlogSevPrintf(errlogFatal,
"lvDCOMConfigure failed: %s\n", ex.what());
404 int lvDCOMSECIConfigure(
const char *portName,
const char* macros,
const char* configSection,
const char *configFile,
405 const char* dbSubFile,
const char *host,
int options,
const char* blocks_match,
const char* progid,
const char* username,
const char* password)
418 std::cerr <<
"lvDCOMSECIConfigure found no blocks - retrying\n";
419 epicsThreadSleep(30);
421 return lvDCOMConfigure(portName, configSection, configFile, host, options, progid, username, password);
425 errlogSevPrintf(errlogFatal,
"lvDCOMSECIConfigure failed (NULL)\n");
429 catch(
const std::exception& ex)
431 errlogSevPrintf(errlogFatal,
"lvDCOMSECIConfigure failed: %s\n", ex.what());
437 static const iocshArg
initArg0 = {
"portName", iocshArgString};
438 static const iocshArg
initArg1 = {
"configSection", iocshArgString};
439 static const iocshArg
initArg2 = {
"configFile", iocshArgString};
440 static const iocshArg
initArg3 = {
"host", iocshArgString};
441 static const iocshArg
initArg4 = {
"options", iocshArgInt};
442 static const iocshArg
initArg5 = {
"progid", iocshArgString};
443 static const iocshArg
initArg6 = {
"username", iocshArgString};
444 static const iocshArg
initArg7 = {
"password", iocshArgString};
448 static const iocshArg
initArgSECI2 = {
"configSection", iocshArgString};
453 static const iocshArg
initArgSECI7 = {
"blocks_match", iocshArgString};
479 static const iocshFuncDef
initFuncDef = {
"lvDCOMConfigure",
sizeof(
initArgs) /
sizeof(iocshArg*), initArgs};
484 lvDCOMConfigure(args[0].sval, args[1].sval, args[2].sval, args[3].sval, args[4].ival, args[5].sval, args[6].sval, args[7].sval);
489 lvDCOMSECIConfigure(args[0].sval, args[1].sval, args[2].sval, args[3].sval, args[4].sval, args[5].sval, args[6].ival, args[7].sval, args[8].sval, args[9].sval, args[10].sval);
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value)
std::string convertToString(T t)
Convert a numeric type to a string.
int lvDCOMConfigure(const char *portName, const char *configSection, const char *configFile, const char *host, int options, const char *progid, const char *username, const char *password)
EPICS iocsh callable function to call constructor of lvDCOMInterface().
EPICS Asyn port driver class.
virtual void report(FILE *fp, int details)
EPICS driver report function for iocsh dbior command.
static const iocshArg initArg2
Path to the XML input file to load configuration information from.
virtual asynStatus readFloat64Array(asynUser *pasynUser, epicsFloat64 *value, size_t nElements, size_t *nIn)
virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value)
static void initCallFuncSECI(const iocshArgBuf *args)
bool checkForNewBlockDetails()
asynStatus readArray(asynUser *pasynUser, const char *functionName, T *value, size_t nElements, size_t *nIn)
An STL exception describing a Win32 Structured Exception.
static const iocshArg initArgSECI9
(optional) remote username for host
Header file for various COM utilities.
static const iocshArg initArgSECI1
macros to substitute when generating dbSubFile
static const iocshArg initArgSECI7
(optional) PCRE expression for blocks to match, default: all
static const iocshArg initArgSECI2
section name of configFile to write settings to
static void seTransFunction(unsigned int u, EXCEPTION_POINTERS *pExp)
Function to translate a Win32 structured exception into a standard C++ exception. ...
virtual asynStatus readInt32Array(asynUser *pasynUser, epicsInt32 *value, size_t nElements, size_t *nIn)
static void lvDCOMTaskC(void *arg)
static const iocshArg initArg0
A name for the asyn driver instance we will create - used to refer to it from EPICS DB files...
epicsExportRegistrar(lvDCOMRegister)
static const iocshArg initArg3
host name where LabVIEW is running ("" for localhost)
virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value)
static const char * driverName
Name of driver for use in message printing.
void report(FILE *fp, int details)
Helper for EPICS driver report function.
asynStatus readValue(asynUser *pasynUser, const char *functionName, T *value)
static const iocshArg initArg1
section name of configFile we will load settings from
lvDCOMInterface * m_lvdcom
(16) Do not start LabVIEW, connect to existing instance otherwise fail. As loading a Vi starts labvie...
virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value)
header for lvDCOMInterface class.
static const iocshArg initArg6
(optional) remote username for host
static const iocshArg initArgSECI0
A name for the asyn driver instance we will create - used to refer to it from EPICS DB files...
void getParams(std::map< std::string, std::string > &res)
asynStatus writeValue(asynUser *pasynUser, const char *functionName, T value)
(32) Automatically set if lvDCOMSECIConfigure() has been used
static const iocshArg *const initArgsSECI[]
int lvDCOMSECIConfigure(const char *portName, const char *macros, const char *configSection, const char *configFile, const char *dbSubFile, const char *host, int options, const char *blocks_match, const char *progid, const char *username, const char *password)
A name for the asyn driver instance we will create - used to refer to it from EPICS DB files...
Header for lvDCOMDriver class.
static const iocshArg *const initArgs[]
std::map< std::string, std::string > m_params
Header for templated number to string conversion functions.
virtual asynStatus readOctet(asynUser *pasynUser, char *value, size_t maxChars, size_t *nActual, int *eomReason)
int generateFilesFromSECI(const char *portName, const char *macros, const char *configSection, const char *configFile, const char *dbSubFile, const char *blocks_match, bool no_setter)
generate XML and DB files for SECI blocks
Manager class for LabVIEW DCOM Interaction. Parses an lvinput.xml file and provides access to the Lab...
void setLabviewValue(const char *param, const T &value)
static void lvDCOMRegister(void)
Register new commands with EPICS IOC shell.
static const iocshFuncDef initFuncDef
virtual asynStatus writeOctet(asynUser *pasynUser, const char *value, size_t maxChars, size_t *nActual)
static const iocshArg initArg5
(optional) DCOM ProgID (required if connecting to a compiled LabVIEW application) ...
static const iocshArg initArgSECI4
Path to the epics db substitution file to generate.
lvDCOMDriver(lvDCOMInterface *dcomint, const char *portName)
Constructor for the lvDCOMDriver class.
void getLabviewValue(const char *param, T *value)
static void initCallFunc(const iocshArgBuf *args)
static const iocshArg initArg7
(optional) remote password for username on host
(64) Do not generate setter XML / :SP PVs in SECI mode
static const iocshFuncDef initFuncDefSECI
static const iocshArg initArgSECI5
host name where LabVIEW is running ("" for localhost)
static void registerStructuredExceptionHandler()
Register a handler for Win32 structured exceptions. This needs to be done on a per thread basis...
static const iocshArg initArgSECI10
(optional) remote password for username on host
static const iocshArg initArgSECI3
Path to the XML output file name to write configuration information to.
static const iocshArg initArg4
options as per lvDCOMOptions enum
static const iocshArg initArgSECI6
options as per lvDCOMOptions enum
static const iocshArg initArgSECI8
(optional) DCOM ProgID (required if connecting to a compiled LabVIEW application) ...