Honor MS/MSS/MSI flags and fetches timestamps properly too.

This commit is contained in:
Andrew Johnson
2010-01-08 17:15:03 -06:00
parent f7d02cc2a8
commit 75bdfc185e
7 changed files with 220 additions and 118 deletions

View File

@@ -2018,11 +2018,13 @@ char * epicsShareAPI dbGetString(DBENTRY *pdbentry)
}
break;
case PN_LINK:
if(plink->value.pv_link.pvname)
strcpy(message,plink->value.pv_link.pvname);
else
strcpy(message,"");
break;
if(plink->value.pv_link.pvname)
strcpy(message,plink->value.pv_link.pvname);
else
strcpy(message,"");
strcat(message," ");
strcat(message,msstring[plink->value.pv_link.pvlMask&pvlOptMsMode]);
break;
case PV_LINK:
case CA_LINK:
case DB_LINK: {

View File

@@ -11,10 +11,6 @@
* Authors: Marty Kraimer & Andrew Johnson
*/
/* TODO:
* Support MS/MSS/MSI link flags
*/
#include <stdlib.h>
#include <stdio.h>
@@ -25,6 +21,7 @@
#include "dbDefs.h"
#include "dbAccess.h"
#include "dbNotify.h"
#include "epicsAssert.h"
#include "recGbl.h"
#include "recSup.h"
#include "devSup.h"
@@ -32,38 +29,37 @@
#include "aiRecord.h"
#include "epicsExport.h"
#define GET_OPTIONS (DBR_STATUS | DBR_TIME)
typedef struct notifyInfo {
processNotify *ppn;
CALLBACK *pcallback;
double value;
long options;
int status;
int smooth;
struct {
DBRstatus
DBRtime
epicsFloat64 value;
} buffer;
} notifyInfo;
static void getCallback(processNotify *ppn, notifyGetType type)
{
aiRecord *prec = (aiRecord *)ppn->usrPvt;
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
int status = 0;
long no_elements = 1;
long options = 0;
if (ppn->status == notifyCanceled) {
printf("devAiSoftCallback::getCallback notifyCanceled\n");
return;
}
switch (type) {
case getFieldType:
status = dbGetField(ppn->paddr, DBR_DOUBLE, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
case getType:
status = dbGet(ppn->paddr, DBR_DOUBLE, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
}
pnotifyInfo->status = status;
assert(type == getFieldType);
pnotifyInfo->status = dbGetField(ppn->paddr, DBR_DOUBLE,
&pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0);
}
static void doneCallback(processNotify *ppn)
@@ -104,7 +100,7 @@ static long add_record(dbCommon *pcommon)
plink->type = PN_LINK;
plink->value.pv_link.precord = pcommon;
plink->value.pv_link.pvt = pdbaddr;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */
ppn = callocMustSucceed(1, sizeof(*ppn),
"devAiSoftCallback::add_record");
@@ -119,6 +115,7 @@ static long add_record(dbCommon *pcommon)
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
"devAiSoftCallback::add_record");
pnotifyInfo->ppn = ppn;
pnotifyInfo->options = GET_OPTIONS;
prec->dpvt = pnotifyInfo;
return 0;
@@ -130,7 +127,7 @@ static long del_record(dbCommon *pcommon) {
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
if (plink->type == CONSTANT) return 0;
assert (plink->type == PN_LINK);
assert(plink->type == PN_LINK);
dbNotifyCancel(pnotifyInfo->ppn);
free(pnotifyInfo->ppn);
@@ -194,15 +191,32 @@ static long read_ai(aiRecord *prec)
/* Apply smoothing algorithm */
if (prec->smoo != 0.0 && pnotifyInfo->smooth)
prec->val = pnotifyInfo->value * (1.0 - prec->smoo) + prec->val * prec->smoo;
prec->val = prec->val * prec->smoo +
pnotifyInfo->buffer.value * (1.0 - prec->smoo);
else
prec->val = pnotifyInfo->value;
prec->val = pnotifyInfo->buffer.value;
prec->udf = FALSE;
pnotifyInfo->smooth = TRUE;
switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) {
case pvlOptNMS:
break;
case pvlOptMSI:
if (pnotifyInfo->buffer.severity < INVALID_ALARM)
break;
/* else fall through */
case pvlOptMS:
recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity);
break;
case pvlOptMSS:
recGblSetSevr(prec, pnotifyInfo->buffer.status,
pnotifyInfo->buffer.severity);
break;
}
if (prec->tsel.type == CONSTANT &&
prec->tse == epicsTimeEventDeviceTime)
prec->time = prec->inp.value.pv_link.precord->time;
prec->time = pnotifyInfo->buffer.time;
return 2;
}

View File

@@ -21,6 +21,7 @@
#include "dbDefs.h"
#include "dbAccess.h"
#include "dbNotify.h"
#include "epicsAssert.h"
#include "recGbl.h"
#include "recSup.h"
#include "devSup.h"
@@ -28,37 +29,36 @@
#include "biRecord.h"
#include "epicsExport.h"
#define GET_OPTIONS (DBR_STATUS | DBR_TIME)
typedef struct notifyInfo {
processNotify *ppn;
CALLBACK *pcallback;
epicsEnum16 value;
long options;
int status;
struct {
DBRstatus
DBRtime
epicsEnum16 value;
} buffer;
} notifyInfo;
static void getCallback(processNotify *ppn,notifyGetType type)
{
biRecord *prec = (biRecord *)ppn->usrPvt;
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
int status = 0;
long no_elements = 1;
long options = 0;
if (ppn->status == notifyCanceled) {
printf("devBiSoftCallback::getCallback notifyCanceled\n");
return;
}
switch (type) {
case getFieldType:
status = dbGetField(ppn->paddr, DBR_ENUM, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
case getType:
status = dbGet(ppn->paddr, DBR_ENUM, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
}
pnotifyInfo->status = status;
assert(type == getFieldType);
pnotifyInfo->status = dbGetField(ppn->paddr, DBR_ENUM,
&pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0);
}
static void doneCallback(processNotify *ppn)
@@ -99,7 +99,7 @@ static long add_record(dbCommon *pcommon)
plink->type = PN_LINK;
plink->value.pv_link.precord = pcommon;
plink->value.pv_link.pvt = pdbaddr;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */
ppn = callocMustSucceed(1, sizeof(*ppn),
"devBiSoftCallback::add_record");
@@ -114,6 +114,7 @@ static long add_record(dbCommon *pcommon)
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
"devBiSoftCallback::add_record");
pnotifyInfo->ppn = ppn;
pnotifyInfo->options = GET_OPTIONS;
prec->dpvt = pnotifyInfo;
return 0;
@@ -125,7 +126,7 @@ static long del_record(dbCommon *pcommon) {
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
if (plink->type == CONSTANT) return 0;
assert (plink->type == PN_LINK);
assert(plink->type == PN_LINK);
dbNotifyCancel(pnotifyInfo->ppn);
free(pnotifyInfo->ppn);
@@ -186,12 +187,28 @@ static long read_bi(biRecord *prec)
return 2;
}
prec->val = pnotifyInfo->value;
prec->val = pnotifyInfo->buffer.value;
prec->udf = FALSE;
switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) {
case pvlOptNMS:
break;
case pvlOptMSI:
if (pnotifyInfo->buffer.severity < INVALID_ALARM)
break;
/* else fall through */
case pvlOptMS:
recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity);
break;
case pvlOptMSS:
recGblSetSevr(prec, pnotifyInfo->buffer.status,
pnotifyInfo->buffer.severity);
break;
}
if (prec->tsel.type == CONSTANT &&
prec->tse == epicsTimeEventDeviceTime)
prec->time = prec->inp.value.pv_link.precord->time;
prec->time = pnotifyInfo->buffer.time;
return 2;
}

View File

@@ -21,6 +21,7 @@
#include "dbDefs.h"
#include "dbAccess.h"
#include "dbNotify.h"
#include "epicsAssert.h"
#include "recGbl.h"
#include "recSup.h"
#include "devSup.h"
@@ -28,37 +29,36 @@
#include "longinRecord.h"
#include "epicsExport.h"
#define GET_OPTIONS (DBR_STATUS | DBR_TIME)
typedef struct notifyInfo {
processNotify *ppn;
CALLBACK *pcallback;
epicsInt32 value;
long options;
int status;
struct {
DBRstatus
DBRtime
epicsInt32 value;
} buffer;
} notifyInfo;
static void getCallback(processNotify *ppn, notifyGetType type)
{
longinRecord *prec = (longinRecord *)ppn->usrPvt;
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
int status = 0;
long no_elements = 1;
long options = 0;
if (ppn->status == notifyCanceled) {
printf("devLiSoftCallback::getCallback notifyCanceled\n");
return;
}
switch (type) {
case getFieldType:
status = dbGetField(ppn->paddr, DBR_LONG, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
case getType:
status = dbGet(ppn->paddr, DBR_LONG, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
}
pnotifyInfo->status = status;
assert(type == getFieldType);
pnotifyInfo->status = dbGetField(ppn->paddr, DBR_LONG,
&pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0);
}
static void doneCallback(processNotify *ppn)
@@ -99,7 +99,7 @@ static long add_record(dbCommon *pcommon)
plink->type = PN_LINK;
plink->value.pv_link.precord = pcommon;
plink->value.pv_link.pvt = pdbaddr;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */
ppn = callocMustSucceed(1, sizeof(*ppn),
"devLiSoftCallback::add_record");
@@ -114,6 +114,7 @@ static long add_record(dbCommon *pcommon)
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
"devLiSoftCallback::add_record");
pnotifyInfo->ppn = ppn;
pnotifyInfo->options = GET_OPTIONS;
prec->dpvt = pnotifyInfo;
return 0;
@@ -125,7 +126,7 @@ static long del_record(dbCommon *pcommon) {
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
if (plink->type == CONSTANT) return 0;
assert (plink->type == PN_LINK);
assert(plink->type == PN_LINK);
dbNotifyCancel(pnotifyInfo->ppn);
free(pnotifyInfo->ppn);
@@ -186,12 +187,28 @@ static long read_li(longinRecord *prec)
return pnotifyInfo->status;
}
prec->val = pnotifyInfo->value;
prec->val = pnotifyInfo->buffer.value;
prec->udf = FALSE;
switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) {
case pvlOptNMS:
break;
case pvlOptMSI:
if (pnotifyInfo->buffer.severity < INVALID_ALARM)
break;
/* else fall through */
case pvlOptMS:
recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity);
break;
case pvlOptMSS:
recGblSetSevr(prec, pnotifyInfo->buffer.status,
pnotifyInfo->buffer.severity);
break;
}
if (prec->tsel.type == CONSTANT &&
prec->tse == epicsTimeEventDeviceTime)
prec->time = prec->inp.value.pv_link.precord->time;
prec->time = pnotifyInfo->buffer.time;
return 0;
}

View File

@@ -21,6 +21,7 @@
#include "dbDefs.h"
#include "dbAccess.h"
#include "dbNotify.h"
#include "epicsAssert.h"
#include "recGbl.h"
#include "recSup.h"
#include "devSup.h"
@@ -28,37 +29,36 @@
#include "mbbiDirectRecord.h"
#include "epicsExport.h"
#define GET_OPTIONS (DBR_STATUS | DBR_TIME)
typedef struct notifyInfo {
processNotify *ppn;
CALLBACK *pcallback;
epicsUInt16 value;
long options;
int status;
struct {
DBRstatus
DBRtime
epicsUInt16 value;
} buffer;
} notifyInfo;
static void getCallback(processNotify *ppn, notifyGetType type)
{
mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt;
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
int status = 0;
long no_elements = 1;
long options = 0;
if (ppn->status == notifyCanceled) {
printf("devMbbiDirectSoftCallback::getCallback notifyCanceled\n");
return;
}
switch (type) {
case getFieldType:
status = dbGetField(ppn->paddr, DBR_USHORT, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
case getType:
status = dbGet(ppn->paddr, DBR_USHORT, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
}
pnotifyInfo->status = status;
assert(type == getFieldType);
pnotifyInfo->status = dbGetField(ppn->paddr, DBR_USHORT,
&pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0);
}
static void doneCallback(processNotify *ppn)
@@ -99,7 +99,7 @@ static long add_record(dbCommon *pcommon)
plink->type = PN_LINK;
plink->value.pv_link.precord = pcommon;
plink->value.pv_link.pvt = pdbaddr;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */
ppn = callocMustSucceed(1, sizeof(*ppn),
"devMbbiDirectSoftCallback::add_record");
@@ -114,6 +114,7 @@ static long add_record(dbCommon *pcommon)
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
"devMbbiDirectSoftCallback::add_record");
pnotifyInfo->ppn = ppn;
pnotifyInfo->options = GET_OPTIONS;
prec->dpvt = pnotifyInfo;
return 0;
@@ -125,7 +126,7 @@ static long del_record(dbCommon *pcommon) {
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
if (plink->type == CONSTANT) return 0;
assert (plink->type == PN_LINK);
assert(plink->type == PN_LINK);
dbNotifyCancel(pnotifyInfo->ppn);
free(pnotifyInfo->ppn);
@@ -186,12 +187,28 @@ static long read_mbbiDirect(mbbiDirectRecord *prec)
return 2;
}
prec->val = pnotifyInfo->value;
prec->val = pnotifyInfo->buffer.value;
prec->udf = FALSE;
switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) {
case pvlOptNMS:
break;
case pvlOptMSI:
if (pnotifyInfo->buffer.severity < INVALID_ALARM)
break;
/* else fall through */
case pvlOptMS:
recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity);
break;
case pvlOptMSS:
recGblSetSevr(prec, pnotifyInfo->buffer.status,
pnotifyInfo->buffer.severity);
break;
}
if (prec->tsel.type == CONSTANT &&
prec->tse == epicsTimeEventDeviceTime)
prec->time = prec->inp.value.pv_link.precord->time;
prec->time = pnotifyInfo->buffer.time;
return 2;
}

View File

@@ -21,6 +21,7 @@
#include "dbDefs.h"
#include "dbAccess.h"
#include "dbNotify.h"
#include "epicsAssert.h"
#include "recGbl.h"
#include "recSup.h"
#include "devSup.h"
@@ -28,37 +29,36 @@
#include "mbbiRecord.h"
#include "epicsExport.h"
#define GET_OPTIONS (DBR_STATUS | DBR_TIME)
typedef struct notifyInfo {
processNotify *ppn;
CALLBACK *pcallback;
epicsEnum16 value;
long options;
int status;
struct {
DBRstatus
DBRtime
epicsEnum16 value;
} buffer;
} notifyInfo;
static void getCallback(processNotify *ppn, notifyGetType type)
{
mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt;
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
int status = 0;
long no_elements = 1;
long options = 0;
if (ppn->status == notifyCanceled) {
printf("devMbbiSoftCallback::getCallback notifyCanceled\n");
return;
}
switch (type) {
case getFieldType:
status = dbGetField(ppn->paddr, DBR_ENUM, &pnotifyInfo->value,
&options, &no_elements,0);
break;
case getType:
status = dbGet(ppn->paddr,DBR_ENUM, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
}
pnotifyInfo->status = status;
assert(type == getFieldType);
pnotifyInfo->status = dbGetField(ppn->paddr, DBR_ENUM,
&pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0);
}
static void doneCallback(processNotify *ppn)
@@ -99,7 +99,7 @@ static long add_record(dbCommon *pcommon)
plink->type = PN_LINK;
plink->value.pv_link.precord = pcommon;
plink->value.pv_link.pvt = pdbaddr;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */
ppn = callocMustSucceed(1, sizeof(*ppn),
"devMbbiSoftCallback::add_record");
@@ -114,6 +114,7 @@ static long add_record(dbCommon *pcommon)
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
"devMbbiSoftCallback::add_record");
pnotifyInfo->ppn = ppn;
pnotifyInfo->options = GET_OPTIONS;
prec->dpvt = pnotifyInfo;
return 0;
@@ -125,7 +126,7 @@ static long del_record(dbCommon *pcommon) {
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
if (plink->type == CONSTANT) return 0;
assert (plink->type == PN_LINK);
assert(plink->type == PN_LINK);
dbNotifyCancel(pnotifyInfo->ppn);
free(pnotifyInfo->ppn);
@@ -186,12 +187,28 @@ static long read_mbbi(mbbiRecord *prec)
return 2;
}
prec->val = pnotifyInfo->value;
prec->val = pnotifyInfo->buffer.value;
prec->udf = FALSE;
switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) {
case pvlOptNMS:
break;
case pvlOptMSI:
if (pnotifyInfo->buffer.severity < INVALID_ALARM)
break;
/* else fall through */
case pvlOptMS:
recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity);
break;
case pvlOptMSS:
recGblSetSevr(prec, pnotifyInfo->buffer.status,
pnotifyInfo->buffer.severity);
break;
}
if (prec->tsel.type == CONSTANT &&
prec->tse == epicsTimeEventDeviceTime)
prec->time = prec->inp.value.pv_link.precord->time;
prec->time = pnotifyInfo->buffer.time;
return 2;
}

View File

@@ -22,6 +22,7 @@
#include "dbDefs.h"
#include "dbAccess.h"
#include "dbNotify.h"
#include "epicsAssert.h"
#include "recGbl.h"
#include "recSup.h"
#include "devSup.h"
@@ -29,37 +30,36 @@
#include "stringinRecord.h"
#include "epicsExport.h"
#define GET_OPTIONS (DBR_STATUS | DBR_TIME)
typedef struct notifyInfo {
processNotify *ppn;
CALLBACK *pcallback;
char value[MAX_STRING_SIZE];
long options;
int status;
struct {
DBRstatus
DBRtime
char value[MAX_STRING_SIZE];
} buffer;
} notifyInfo;
static void getCallback(processNotify *ppn, notifyGetType type)
{
stringinRecord *prec = (stringinRecord *)ppn->usrPvt;
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
int status = 0;
long no_elements = 1;
long options = 0;
if (ppn->status==notifyCanceled) {
printf("devSiSoftCallback::getCallback notifyCanceled\n");
return;
}
switch(type) {
case getFieldType:
status = dbGetField(ppn->paddr, DBR_STRING, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
case getType:
status = dbGet(ppn->paddr, DBR_STRING, &pnotifyInfo->value,
&options, &no_elements, 0);
break;
}
pnotifyInfo->status = status;
assert(type == getFieldType);
pnotifyInfo->status = dbGetField(ppn->paddr, DBR_STRING,
&pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0);
}
static void doneCallback(processNotify *ppn)
@@ -101,7 +101,7 @@ static long add_record(dbCommon *pcommon)
plink->type = PN_LINK;
plink->value.pv_link.precord = pcommon;
plink->value.pv_link.pvt = pdbaddr;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */
ppn = callocMustSucceed(1, sizeof(*ppn),
"devSiSoftCallback::add_record");
@@ -116,6 +116,7 @@ static long add_record(dbCommon *pcommon)
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
"devSiSoftCallback::add_record");
pnotifyInfo->ppn = ppn;
pnotifyInfo->options = GET_OPTIONS;
prec->dpvt = pnotifyInfo;
return 0;
@@ -127,7 +128,7 @@ static long del_record(dbCommon *pcommon) {
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
if (plink->type == CONSTANT) return 0;
assert (plink->type == PN_LINK);
assert(plink->type == PN_LINK);
dbNotifyCancel(pnotifyInfo->ppn);
free(pnotifyInfo->ppn);
@@ -187,12 +188,29 @@ static long read_si(stringinRecord *prec)
recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
return pnotifyInfo->status;
}
strncpy(prec->val, pnotifyInfo->value, MAX_STRING_SIZE);
strncpy(prec->val, pnotifyInfo->buffer.value, MAX_STRING_SIZE);
prec->val[MAX_STRING_SIZE-1] = 0;
prec->udf = FALSE;
switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) {
case pvlOptNMS:
break;
case pvlOptMSI:
if (pnotifyInfo->buffer.severity < INVALID_ALARM)
break;
/* else fall through */
case pvlOptMS:
recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity);
break;
case pvlOptMSS:
recGblSetSevr(prec, pnotifyInfo->buffer.status,
pnotifyInfo->buffer.severity);
break;
}
if (prec->tsel.type == CONSTANT &&
prec->tse == epicsTimeEventDeviceTime)
prec->time = prec->inp.value.pv_link.precord->time;
prec->time = pnotifyInfo->buffer.time;
return 0;
}