Added support for new MSI and MSS link flags
This commit is contained in:
@@ -12,6 +12,19 @@
|
||||
<h2 align="center">Changes between 3.14.10 and 3.14.11</h2>
|
||||
<!-- Insert new items below here ... -->
|
||||
|
||||
<h4>New link flags for alarm severity/status inheritance</h4>
|
||||
|
||||
<p>Two new link flags have been introduced: MSI (maximize severity INVALID)
|
||||
and MSS (maximize severity and status).</p>
|
||||
|
||||
<p>Through a link flagged as MSI the receiver side inherits the severity
|
||||
(similar to the MS flag), but only if it is INVALID.</p>
|
||||
|
||||
<p>Through a link flagged as MSS the receiver side inherits as well the
|
||||
severity (similar to the MS flag) as the alarm status, thereby preserving
|
||||
the alarm status through MS chains instead of setting the status to LINK
|
||||
unconditionally.</p>
|
||||
|
||||
<h4>New behaviour of get_alarm_double() in analog records</h4>
|
||||
|
||||
<p>The behavior of get_alarm_double() in several record types, which
|
||||
|
||||
+24
-11
@@ -90,6 +90,17 @@ static short mapDBFToDBR[DBF_NTYPES] = {
|
||||
/* The following is to handle SPC_AS */
|
||||
static SPC_ASCALLBACK spcAsCallback = 0;
|
||||
|
||||
static void inherit_severity(const struct pv_link *ppv_link,
|
||||
dbCommon *pdest, epicsEnum16 stat, epicsEnum16 sevr)
|
||||
{
|
||||
switch(ppv_link->pvlMask&pvlOptMsMode) {
|
||||
case pvlOptNMS: break;
|
||||
case pvlOptMSI: if (sevr < INVALID_ALARM) break;
|
||||
case pvlOptMS: recGblSetSevr(pdest,LINK_ALARM,sevr); break;
|
||||
case pvlOptMSS: recGblSetSevr(pdest,stat,sevr); break;
|
||||
}
|
||||
}
|
||||
|
||||
void epicsShareAPI dbSpcAsRegisterCallback(SPC_ASCALLBACK func)
|
||||
{
|
||||
spcAsCallback = func;
|
||||
@@ -837,8 +848,9 @@ long epicsShareAPI dbGetLinkValue(struct link *plink, short dbrType,
|
||||
precord->pact = pact;
|
||||
if (status) return status;
|
||||
}
|
||||
if (ppv_link->pvlMask & pvlOptMS && precord != paddr->precord)
|
||||
recGblSetSevr(precord, LINK_ALARM, paddr->precord->sevr);
|
||||
if(precord!= paddr->precord) {
|
||||
inherit_severity(ppv_link,precord,paddr->precord->stat,paddr->precord->sevr);
|
||||
}
|
||||
|
||||
if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) {
|
||||
status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr);
|
||||
@@ -873,13 +885,13 @@ long epicsShareAPI dbGetLinkValue(struct link *plink, short dbrType,
|
||||
} else if (plink->type == CA_LINK) {
|
||||
struct dbCommon *precord = plink->value.pv_link.precord;
|
||||
const struct pv_link *pcalink = &plink->value.pv_link;
|
||||
unsigned short sevr;
|
||||
epicsEnum16 sevr, stat;
|
||||
|
||||
status = dbCaGetLink(plink, dbrType, pbuffer, &sevr, pnRequest);
|
||||
status=dbCaGetLink(plink,dbrType,pbuffer,&stat,&sevr,pnRequest);
|
||||
if (status) {
|
||||
recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
|
||||
} else if (pcalink->pvlMask & pvlOptMS) {
|
||||
recGblSetSevr(precord, LINK_ALARM, sevr);
|
||||
} else {
|
||||
inherit_severity(pcalink,precord,stat,sevr);
|
||||
}
|
||||
if (poptions) *poptions = 0;
|
||||
} else {
|
||||
@@ -900,8 +912,7 @@ long epicsShareAPI dbPutLinkValue(struct link *plink, short dbrType,
|
||||
dbCommon *pdest = paddr->precord;
|
||||
|
||||
status = dbPut(paddr, dbrType, pbuffer, nRequest);
|
||||
if (ppv_link->pvlMask & pvlOptMS)
|
||||
recGblSetSevr(pdest, LINK_ALARM, psource->nsev);
|
||||
inherit_severity(ppv_link,pdest,psource->nsta,psource->nsev);
|
||||
if (status) return status;
|
||||
|
||||
if (paddr->pfield == (void *)&pdest->proc ||
|
||||
@@ -1567,14 +1578,16 @@ long epicsShareAPI dbGetUnits(
|
||||
return(0);
|
||||
}
|
||||
|
||||
long epicsShareAPI dbGetSevr(const struct link *plink,short *severity)
|
||||
long epicsShareAPI dbGetAlarm(const struct link *plink,
|
||||
epicsEnum16 *status,epicsEnum16 *severity)
|
||||
{
|
||||
DBADDR *paddr;
|
||||
|
||||
if(plink->type == CA_LINK) return(dbCaGetSevr(plink,severity));
|
||||
if(plink->type == CA_LINK) return(dbCaGetAlarm(plink,status,severity));
|
||||
if(plink->type !=DB_LINK) return(S_db_notFound);
|
||||
paddr = (DBADDR *)plink->value.pv_link.pvt;
|
||||
*severity = paddr->precord->sevr;
|
||||
if (status) *status = paddr->precord->stat;
|
||||
if (severity) *severity = paddr->precord->sevr;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -215,6 +215,8 @@ struct dbr_alDouble {DBRalDouble};
|
||||
( ( (PLNK)->type != DB_LINK ) \
|
||||
? 0 \
|
||||
: ( ( (struct dbAddr *)( (PLNK)->value.pv_link.pvt) ) ) )
|
||||
#define dbGetSevr(PLINK,PSEVERITY) \
|
||||
dbGetAlarm((PLINK),NULL,(PSEVERITY));
|
||||
|
||||
epicsShareFunc long epicsShareAPI dbPutSpecial(struct dbAddr *paddr,int pass);
|
||||
epicsShareFunc struct rset * epicsShareAPI dbGetRset(const struct dbAddr *paddr);
|
||||
@@ -262,8 +264,8 @@ epicsShareFunc long epicsShareAPI dbGetPrecision(
|
||||
const struct link *plink,short *precision);
|
||||
epicsShareFunc long epicsShareAPI dbGetUnits(
|
||||
const struct link *plink,char *units,int unitsSize);
|
||||
epicsShareFunc long epicsShareAPI dbGetSevr(
|
||||
const struct link *plink,short *severity);
|
||||
epicsShareFunc long epicsShareAPI dbGetAlarm(
|
||||
const struct link *plink, epicsEnum16 *status,epicsEnum16 *severity);
|
||||
epicsShareFunc long epicsShareAPI dbGetTimeStamp(
|
||||
const struct link *plink,epicsTimeStamp *pstamp);
|
||||
|
||||
|
||||
+10
-3
@@ -246,7 +246,7 @@ void epicsShareAPI dbCaRemoveLink(struct link *plink)
|
||||
}
|
||||
|
||||
long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest,
|
||||
unsigned short *psevr,long *nelements)
|
||||
epicsEnum16 *pstat, epicsEnum16 *psevr, long *nelements)
|
||||
{
|
||||
caLink *pca = (caLink *)plink->value.pv_link.pvt;
|
||||
long status = 0;
|
||||
@@ -258,6 +258,7 @@ long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest,
|
||||
assert(pca->plink);
|
||||
if (!pca->isConnected || !pca->hasReadAccess) {
|
||||
pca->sevr = INVALID_ALARM;
|
||||
pca->stat = LINK_ALARM;
|
||||
status = -1;
|
||||
goto done;
|
||||
}
|
||||
@@ -271,6 +272,7 @@ long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest,
|
||||
}
|
||||
if (!pca->gotInString) {
|
||||
pca->sevr = INVALID_ALARM;
|
||||
pca->stat = LINK_ALARM;
|
||||
status = -1;
|
||||
goto done;
|
||||
}
|
||||
@@ -285,6 +287,7 @@ long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest,
|
||||
}
|
||||
if (!pca->gotInNative){
|
||||
pca->sevr = INVALID_ALARM;
|
||||
pca->stat = LINK_ALARM;
|
||||
status = -1;
|
||||
goto done;
|
||||
}
|
||||
@@ -315,6 +318,7 @@ long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest,
|
||||
aConvert(&dbAddr, pdest, ntoget, ntoget, 0);
|
||||
}
|
||||
done:
|
||||
if (pstat) *pstat = pca->stat;
|
||||
if (psevr) *psevr = pca->sevr;
|
||||
if (link_action) addAction(pca, link_action);
|
||||
epicsMutexUnlock(pca->lock);
|
||||
@@ -423,12 +427,14 @@ long epicsShareAPI dbCaGetNelements(const struct link *plink, long *nelements)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long epicsShareAPI dbCaGetSevr(const struct link *plink, short *severity)
|
||||
long epicsShareAPI dbCaGetAlarm(const struct link *plink,
|
||||
epicsEnum16 *pstat, epicsEnum16 *psevr)
|
||||
{
|
||||
caLink *pca;
|
||||
|
||||
pcaGetCheck
|
||||
*severity = pca->sevr;
|
||||
if (pstat) *pstat = pca->stat;
|
||||
if (psevr) *psevr = pca->sevr;
|
||||
epicsMutexUnlock(pca->lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -677,6 +683,7 @@ static void eventCallback(struct event_handler_args arg)
|
||||
}
|
||||
pdbr_time_double = (struct dbr_time_double *)arg.dbr;
|
||||
pca->sevr = pdbr_time_double->severity;
|
||||
pca->stat = pdbr_time_double->status;
|
||||
memcpy(&pca->timeStamp, &pdbr_time_double->stamp, sizeof(epicsTimeStamp));
|
||||
if (precord) {
|
||||
struct pv_link *ppv_link = &plink->value.pv_link;
|
||||
|
||||
+5
-3
@@ -33,7 +33,7 @@ epicsShareFunc void epicsShareAPI dbCaAddLinkCallback(struct link *plink,
|
||||
epicsShareFunc void epicsShareAPI dbCaRemoveLink(struct link *plink);
|
||||
epicsShareFunc long epicsShareAPI dbCaGetLink(
|
||||
struct link *plink,short dbrType,void *pbuffer,
|
||||
unsigned short *psevr,long *nRequest);
|
||||
epicsEnum16 *pstat,epicsEnum16 *psevr,long *nRequest);
|
||||
epicsShareFunc long epicsShareAPI dbCaPutLinkCallback(
|
||||
struct link *plink,short dbrType,const void *pbuffer,long nRequest,
|
||||
dbCaCallback callback,void *userPvt);
|
||||
@@ -43,8 +43,10 @@ epicsShareFunc int epicsShareAPI dbCaIsLinkConnected(const struct link *plink);
|
||||
/* The following are available after the link is connected*/
|
||||
epicsShareFunc long epicsShareAPI dbCaGetNelements(
|
||||
const struct link *plink,long *nelements);
|
||||
epicsShareFunc long epicsShareAPI dbCaGetSevr(
|
||||
const struct link *plink,short *severity);
|
||||
#define dbCaGetSevr(plink,severity) \
|
||||
dbCaGetAlarm((plink),NULL,(severity))
|
||||
epicsShareFunc long epicsShareAPI dbCaGetAlarm(const struct link *plink,
|
||||
epicsEnum16 *status,epicsEnum16 *severity);
|
||||
epicsShareFunc long epicsShareAPI dbCaGetTimeStamp(
|
||||
const struct link *plink,epicsTimeStamp *pstamp);
|
||||
epicsShareFunc int epicsShareAPI dbCaGetLinkDBFtype(const struct link *plink);
|
||||
|
||||
+2
-1
@@ -40,7 +40,8 @@ typedef struct caLink
|
||||
chid chid;
|
||||
short link_action;
|
||||
/* The following have new values after each data event*/
|
||||
unsigned short sevr;
|
||||
epicsEnum16 sevr;
|
||||
epicsEnum16 stat;
|
||||
epicsTimeStamp timeStamp;
|
||||
/* The following have values after connection*/
|
||||
short dbrType;
|
||||
|
||||
+2
-1
@@ -82,6 +82,7 @@ static ELLLIST lockSetList[nlistType];
|
||||
static epicsMutexId globalLock;
|
||||
static epicsMutexId lockSetModifyLock;
|
||||
static unsigned long id = 0;
|
||||
static char *msstring[4]={"NMS","MS","MSI","MSS"};
|
||||
|
||||
typedef enum {
|
||||
lockSetStateFree=0, lockSetStateScanLock, lockSetStateRecordLock
|
||||
@@ -546,7 +547,7 @@ long epicsShareAPI dblsr(char *recordname,int level)
|
||||
}
|
||||
printf(" %s %s",
|
||||
((plink->value.pv_link.pvlMask&pvlOptPP)?" PP":"NPP"),
|
||||
((plink->value.pv_link.pvlMask&pvlOptMS)?" MS":"NMS"));
|
||||
msstring[plink->value.pv_link.pvlMask&pvlOptMsMode]);
|
||||
printf(" %s\n",pdbAddr->precord->name);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-13
@@ -48,7 +48,7 @@ static char *pNullString = "";
|
||||
#define RPCL_LEN 184
|
||||
|
||||
static char *ppstring[5]={"NPP","PP","CA","CP","CPP"};
|
||||
static char *msstring[2]={"NMS","MS"};
|
||||
static char *msstring[4]={"NMS","MS","MSI","MSS"};
|
||||
|
||||
epicsShareDef maplinkType pamaplinkType[LINK_NTYPES] = {
|
||||
{"CONSTANT",CONSTANT},
|
||||
@@ -91,7 +91,7 @@ static char *promptCONSTANT[] = {
|
||||
static char *promptINLINK[] = {
|
||||
" PV Name:",
|
||||
"NPP PP CA CP CPP:",
|
||||
" NMS or MS:"};
|
||||
" NMS MS MSI MSS:"};
|
||||
static char *promptOUTLINK[] = {
|
||||
" PV Name:",
|
||||
"NPP PP CA:",
|
||||
@@ -2032,7 +2032,7 @@ char * epicsShareAPI dbGetString(DBENTRY *pdbentry)
|
||||
strcat(message," ");
|
||||
strcat(message,ppstring[ppind]);
|
||||
strcat(message," ");
|
||||
strcat(message,msstring[pvlMask&pvlOptMS]);
|
||||
strcat(message,msstring[pvlMask&pvlOptMsMode]);
|
||||
break;
|
||||
}
|
||||
case VME_IO:
|
||||
@@ -2290,8 +2290,10 @@ long epicsShareAPI dbPutString(DBENTRY *pdbentry,const char *pstring)
|
||||
else if(strstr(end,"CA")) ppOpt = pvlOptCA;
|
||||
else if(strstr(end,"CP")) ppOpt = pvlOptCP;
|
||||
else ppOpt = 0;
|
||||
if(strstr(end,"NMS")) msOpt = 0;
|
||||
else if(strstr(end,"MS")) msOpt = pvlOptMS;
|
||||
if(strstr(end,"NMS")) msOpt = pvlOptNMS;
|
||||
else if(strstr(end,"MSI")) msOpt = pvlOptMSI;
|
||||
else if(strstr(end,"MSS")) msOpt = pvlOptMSS;
|
||||
/*must be the last one:*/ else if(strstr(end,"MS")) msOpt = pvlOptMS;
|
||||
else msOpt = 0;
|
||||
*end = 0;
|
||||
}
|
||||
@@ -2301,8 +2303,10 @@ long epicsShareAPI dbPutString(DBENTRY *pdbentry,const char *pstring)
|
||||
else if(strstr(end,"PP")) ppOpt = pvlOptPP;
|
||||
else if(strstr(end,"CA")) ppOpt = pvlOptCA;
|
||||
else ppOpt = 0;
|
||||
if(strstr(end,"NMS")) msOpt = 0;
|
||||
else if(strstr(end,"MS")) msOpt = pvlOptMS;
|
||||
if(strstr(end,"NMS")) msOpt = pvlOptNMS;
|
||||
else if(strstr(end,"MSI")) msOpt = pvlOptMSI;
|
||||
else if(strstr(end,"MSS")) msOpt = pvlOptMSS;
|
||||
/*must be the last one:*/ else if(strstr(end,"MS")) msOpt = pvlOptMS;
|
||||
else msOpt = 0;
|
||||
*end = 0;
|
||||
}
|
||||
@@ -3104,8 +3108,7 @@ char ** epicsShareAPI dbGetFormValue(DBENTRY *pdbentry)
|
||||
else if(pvlMask&pvlOptCPP) strcpy(*value,"CPP");
|
||||
else strcpy(*value,"NPP");
|
||||
value++;
|
||||
if(pvlMask&pvlOptMS) strcpy(*value,"MS");
|
||||
else strcpy(*value,"NMS");
|
||||
strcpy(*value, msstring[pvlMask&pvlOptMsMode]);
|
||||
value++;
|
||||
}
|
||||
break;
|
||||
@@ -3121,8 +3124,7 @@ char ** epicsShareAPI dbGetFormValue(DBENTRY *pdbentry)
|
||||
else if(pvlMask&pvlOptCA) strcpy(*value,"CA");
|
||||
else strcpy(*value,"NPP");
|
||||
value++;
|
||||
if(pvlMask&pvlOptMS) strcpy(*value,"MS");
|
||||
else strcpy(*value,"NMS");
|
||||
strcpy(*value, msstring[pvlMask&pvlOptMsMode]);
|
||||
value++;
|
||||
}
|
||||
break;
|
||||
@@ -3295,7 +3297,10 @@ long epicsShareAPI dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
value++; verify++;
|
||||
**verify = 0; /*Initialize verify to NULL*/
|
||||
if((*value==NULL) || (strcmp(*value,"")==0)) msOpt = 0;
|
||||
else if(strstr(*value,"NMS")) msOpt = 0;
|
||||
else if(strstr(*value,"NMS")) msOpt = pvlOptNMS;
|
||||
else if(strstr(*value,"MSI")) msOpt = pvlOptMSI;
|
||||
else if(strstr(*value,"MSS")) msOpt = pvlOptMSS;
|
||||
/*must be the last one:*/
|
||||
else if(strstr(*value,"MS")) msOpt = pvlOptMS;
|
||||
else strcpy(*verify,"Illegal. Chose a value");
|
||||
dbCopyEntryContents(pdbentry,plinkentry);
|
||||
@@ -3329,7 +3334,10 @@ long epicsShareAPI dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
value++; verify++;
|
||||
**verify = 0; /*Initialize verify to NULL*/
|
||||
if((*value==NULL) || (strcmp(*value,"")==0)) msOpt = 0;
|
||||
else if(strstr(*value,"NMS")) msOpt = 0;
|
||||
else if(strstr(*value,"NMS")) msOpt = pvlOptNMS;
|
||||
else if(strstr(*value,"MSI")) msOpt = pvlOptMSI;
|
||||
else if(strstr(*value,"MSS")) msOpt = pvlOptMSS;
|
||||
/*must be the last one:*/
|
||||
else if(strstr(*value,"MS")) msOpt = pvlOptMS;
|
||||
else strcpy(*verify,"Illegal. Chose a value");
|
||||
dbCopyEntryContents(pdbentry,plinkentry);
|
||||
|
||||
+15
-11
@@ -54,17 +54,21 @@ epicsShareExtern maplinkType pamaplinkType[];
|
||||
|
||||
/* structure of a PV_LINK DB_LINK and a CA_LINK */
|
||||
/*Options defined by pvlMask */
|
||||
#define pvlOptMS 0x1 /*Maximize Severity*/
|
||||
#define pvlOptPP 0x2 /*Process Passive*/
|
||||
#define pvlOptCA 0x4 /*Always make it a CA link*/
|
||||
#define pvlOptCP 0x8 /*CA + process on monitor*/
|
||||
#define pvlOptCPP 0x10 /*CA + process passive record on monitor*/
|
||||
#define pvlOptFWD 0x20 /*Generate ca_put for forward link*/
|
||||
#define pvlOptInpNative 0x40 /*Input native*/
|
||||
#define pvlOptInpString 0x80 /*Input as string*/
|
||||
#define pvlOptOutNative 0x100 /*Output native*/
|
||||
#define pvlOptOutString 0x200 /*Output as string*/
|
||||
#define pvlOptTSELisTime 0x400 /*Field TSEL is getting timeStamp*/
|
||||
#define pvlOptMsMode 0x3 /*Maximize Severity mode selection*/
|
||||
#define pvlOptNMS 0 /*Dont Maximize Severity*/
|
||||
#define pvlOptMS 1 /*Maximize Severity allways*/
|
||||
#define pvlOptMSI 2 /*Maximize Severity if INVALID*/
|
||||
#define pvlOptMSS 3 /*Maximize Severity and copy Status*/
|
||||
#define pvlOptPP 0x4 /*Process Passive*/
|
||||
#define pvlOptCA 0x8 /*Always make it a CA link*/
|
||||
#define pvlOptCP 0x10 /*CA + process on monitor*/
|
||||
#define pvlOptCPP 0x20 /*CA + process passive record on monitor*/
|
||||
#define pvlOptFWD 0x40 /*Generate ca_put for forward link*/
|
||||
#define pvlOptInpNative 0x80 /*Input native*/
|
||||
#define pvlOptInpString 0x100 /*Input as string*/
|
||||
#define pvlOptOutNative 0x200 /*Output native*/
|
||||
#define pvlOptOutString 0x400 /*Output as string*/
|
||||
#define pvlOptTSELisTime 0x800 /*Field TSEL is getting timeStamp*/
|
||||
|
||||
typedef long (*LINKCVT)();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user