added routines to obtain options for link field

This commit is contained in:
Marty Kraimer
1996-09-04 15:27:53 +00:00
parent 333b379287
commit afa44fae79
3 changed files with 210 additions and 0 deletions

View File

@@ -298,6 +298,17 @@ void dbCaRemoveLink(struct link *plink);
long dbCaGetLink(struct link *plink,short dbrType,void *pbuffer,
unsigned short *psevr,long *nRequest);
long dbCaPutLink(struct link *plink,short dbrType,void *pbuffer,long nRequest);
long dbCaGetAttributes(struct link *plink,
void (*callback)(void *usrPvt),void *usrPvt);
long dbCaGetControlLimits(struct link *plink,double *low, double *high);
long dbCaGetGraphicLimits(struct link *plink,double *low, double *high);
long dbCaGetAlarmLimits(struct link *plink,
double *lolo, double *low, double *high, double *hihi);
long dbCaGetNelements(struct link *plink,long *nelements);
long dbCaGetPrecision(struct link *plink,short *precision);
long dbCaGetSevr(struct link *plink,short *severity);
long dbCaGetUnits(struct link *plink,char *units,int unitsSize);
int dbCaIsLinkConnected(struct link *plink);
#else
struct rset *dbGetRset();

View File

@@ -260,6 +260,152 @@ long dbCaPutLink(struct link *plink,short dbrType,
return(status);
}
long dbCaGetAttributes(struct link *plink,
void (*callback)(void *usrPvt),void *usrPvt)
{
caLink *pca;
long status = 0;
STATUS semStatus;
short link_action = 0;
caAttributes *pcaAttributes;
if(!plink || (plink->type!=CA_LINK)) {
epicsPrintf("dbCaGetAttributes: called for non CA_LINK\n");
return(-1);
}
pca = (caLink *)plink->value.pv_link.pvt;
if(!pca) {
epicsPrintf("dbCaGetAttributes: record %s pv_link.pvt is NULL\n",
plink->value.pv_link.precord);
return(-1);
}
if(pca->pcaAttributes) {
epicsPrintf("dbCaGetAttributes: record %s duplicate call\n",
plink->value.pv_link.precord);
return(-1);
}
pcaAttributes = dbCalloc(1,sizeof(caAttributes));
pcaAttributes->callback = callback;
pcaAttributes->usrPvt = usrPvt;
semStatus = semTake(pca->lock,WAIT_FOREVER);
if(semStatus!=OK) {
epicsPrintf("dbCaGetLink: semStatus!OK\n");
return(-1);
}
pca->pcaAttributes = pcaAttributes;
link_action |= CA_GET_ATTRIBUTES;
semGive(pca->lock);
addAction(pca,link_action);
return(status);
}
caAttributes *getpcaAttributes(struct link *plink)
{
caLink *pca;
if(!plink || (plink->type!=CA_LINK)) return(NULL);
pca = (caLink *)plink->value.pv_link.pvt;
if(!pca) return(NULL);
if(ca_state(pca->chid)!=cs_conn) return(NULL);
return(pca->pcaAttributes);
}
long dbCaGetControlLimits(struct link *plink,double *low, double *high)
{
caAttributes *pcaAttributes;
pcaAttributes = getpcaAttributes(plink);
if(!pcaAttributes) return(-1);
*low = pcaAttributes->data.lower_ctrl_limit;
*high = pcaAttributes->data.upper_ctrl_limit;
return(0);
}
long dbCaGetGraphicLimits(struct link *plink,double *low, double *high)
{
caAttributes *pcaAttributes;
pcaAttributes = getpcaAttributes(plink);
if(!pcaAttributes) return(-1);
*low = pcaAttributes->data.lower_disp_limit;
*high = pcaAttributes->data.upper_disp_limit;
return(0);
}
long dbCaGetAlarmLimits(struct link *plink,
double *lolo, double *low, double *high, double *hihi)
{
caAttributes *pcaAttributes;
pcaAttributes = getpcaAttributes(plink);
if(!pcaAttributes) return(-1);
*lolo = pcaAttributes->data.lower_alarm_limit;
*low = pcaAttributes->data.lower_warning_limit;
*high = pcaAttributes->data.upper_warning_limit;
*hihi = pcaAttributes->data.upper_alarm_limit;
return(0);
}
long dbCaGetPrecision(struct link *plink,short *precision)
{
caAttributes *pcaAttributes;
pcaAttributes = getpcaAttributes(plink);
if(!pcaAttributes) return(-1);
*precision = pcaAttributes->data.precision;
return(0);
}
long dbCaGetUnits(struct link *plink,char *units,int unitsSize)
{
caAttributes *pcaAttributes;
pcaAttributes = getpcaAttributes(plink);
if(!pcaAttributes) return(-1);
strncpy(units,pcaAttributes->data.units,unitsSize);
units[unitsSize-1] = 0;
return(0);
}
long dbCaGetNelements(struct link *plink,long *nelements)
{
caLink *pca;
if(!plink) return(-1);
if(plink->type != CA_LINK) return(-1);
pca = (caLink *)plink->value.pv_link.pvt;
if(!pca) return(-1);
if(ca_state(pca->chid)!=cs_conn) return(-1);
*nelements = pca->nelements;
return(0);
}
long dbCaGetSevr(struct link *plink,short *severity)
{
caLink *pca;
if(!plink) return(-1);
if(plink->type != CA_LINK) return(-1);
pca = (caLink *)plink->value.pv_link.pvt;
if(!pca) return(-1);
if(ca_state(pca->chid)!=cs_conn) return(-1);
*severity = pca->sevr;
return(0);
}
int dbCaIsLinkConnected(struct link *plink)
{
caLink *pca;
if(!plink) return(FALSE);
if(plink->type != CA_LINK) return(FALSE);
pca = (caLink *)plink->value.pv_link.pvt;
if(!pca) return(FALSE);
if(!pca->chid) return(FALSE);
if(ca_state(pca->chid)==cs_conn) return(TRUE);
return(FALSE);
}
static void eventCallback(struct event_handler_args arg)
{
caLink *pca = (caLink *)arg.usr;
@@ -326,6 +472,39 @@ done:
semGive(pca->lock);
}
static void getAttribEventCallback(struct event_handler_args arg)
{
caLink *pca = (caLink *)arg.usr;
struct link *plink;
STATUS semStatus;
struct dbr_ctrl_double *dbr;
caAttributes *pcaAttributes = NULL;
if(!pca) {
epicsPrintf("getAttribEventCallback why was arg.usr NULL\n");
return;
}
semStatus = semTake(pca->lock,WAIT_FOREVER);
if(semStatus!=OK) {
epicsPrintf("getAttribEventCallback: semStatus!OK\n");
return;
}
plink = pca->plink;
if(!plink) goto done;
if(!arg.dbr) {
epicsPrintf("getAttribEventCallback why was arg.dbr NULL\n");
goto done;
}
dbr = arg.dbr;
pcaAttributes = pca->pcaAttributes;
if(!pcaAttributes) goto done;
pcaAttributes->data = *dbr; /*copy entire structure*/
pcaAttributes->gotData = TRUE;
(pcaAttributes->callback)(pcaAttributes->usrPvt);
done:
semGive(pca->lock);
}
static void accessRightsCallback(struct access_rights_handler_args arg)
{
caLink *pca = (caLink *)ca_puser(arg.chid);
@@ -414,6 +593,7 @@ static void connectionCallback(struct connection_handler_args arg)
if((plink->value.pv_link.pvlMask & pvlOptOutString) && (pca->gotOutString)){
link_action |= CA_WRITE_STRING;
}
if(pca->pcaAttributes) link_action |= CA_GET_ATTRIBUTES;
done:
semGive(pca->lock);
if(link_action) addAction(pca,link_action);
@@ -442,6 +622,7 @@ void dbCaTask()
free(pca->pputNative);
free(pca->pgetString);
free(pca->pputString);
free(pca->pcaAttributes);
semDelete(pca->lock);
free(pca);
continue; /*No other link_action makes sense*/
@@ -499,6 +680,13 @@ void dbCaTask()
epicsPrintf("dbCaTask ca_add_array_event %s\n",
ca_message(status));
}
if(link_action&CA_GET_ATTRIBUTES) {
status = ca_get_callback(DBR_CTRL_DOUBLE,
pca->chid,getAttribEventCallback,pca);
if(status!=ECA_NORMAL)
epicsPrintf("dbCaTask ca_add_array_event %s\n",
ca_message(status));
}
} else { /* caList was empty */
semGive(caListSem);
break; /*caList is empty*/

View File

@@ -30,6 +30,16 @@ of this distribution.
#define CA_WRITE_STRING 0x8
#define CA_MONITOR_NATIVE 0x10
#define CA_MONITOR_STRING 0x20
#define CA_GET_ATTRIBUTES 0x40
typedef struct caAttributes
{
void (*callback)(void *usrPvt);
struct dbr_ctrl_double data;
void *usrPvt;
int gotData;
}caAttributes;
typedef struct caLink
{
ELLNODE node;
@@ -39,6 +49,7 @@ typedef struct caLink
void *pputNative;
char *pgetString;
char *pputString;
caAttributes *pcaAttributes;
long nelements;
SEM_ID lock;
unsigned long nDisconnect;