LOCAL int queueRecord (const char *precName) { DBENTRY dbentry; DBENTRY *pdbentry=&dbentry; dbCommon *pdbc; msg_t msg; dbInitEntry (pdbbase, pdbentry); if (dbFindRecord (pdbentry, precName) != 0) { dbFinishEntry (pdbentry); return ERROR; } pdbc = dbentry.precnode->precord; dbFinishEntry (pdbentry); DEBUG2(4,"queueRecord: Name: %s ptr: 0x%x\n",precName,(unsigned)pdbc) msg.pdbc = pdbc; msg.osevr = pdbc->sevr; msg.ostat = pdbc->stat; msg.nsevr = pdbc->sevr; msg.nstat = pdbc->stat; tsLocalTime (&msg.stamp); msg.msgType = mt_Status; ringInsert (&msg); return OK; }
static long getIoIntInfo(int cmd, dbCommon *pr, IOSCANPVT *iopvt) { devInt32Pvt *pPvt = (devInt32Pvt *)pr->dpvt; asynStatus status; const char *sizeString; /* If initCommon failed then pPvt->pint32 is NULL, return error */ if (!pPvt->pint32) return -1; if (cmd == 0) { /* Add to scan list. Register interrupts */ asynPrint(pPvt->pasynUser, ASYN_TRACE_FLOW, "%s devAsynInt32::getIoIntInfo registering interrupt\n", pr->name); if (!pPvt->ringBuffer) { DBENTRY *pdbentry = dbAllocEntry(pdbbase); pPvt->ringBufferSize = DEFAULT_RING_BUFFER_SIZE; status = dbFindRecord(pdbentry, pr->name); if (status) asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s devAsynInt32::getIoIntInfo error finding record\n", pr->name); sizeString = dbGetInfo(pdbentry, "FIFO"); if (sizeString) pPvt->ringBufferSize = atoi(sizeString); pPvt->ringBuffer = epicsRingBytesCreate(pPvt->ringBufferSize*sizeof(epicsInt32)); if (!pPvt->ringBuffer) asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s devAsynInt32::getIoIntInfo error creating ring buffer\n", pr->name); else asynPrint(pPvt->pasynUser, ASYN_TRACE_FLOW, "%s devAsynInt32::getIoIntInfo created ring buffer, size=%d\n", pr->name, pPvt->ringBufferSize); } status = pPvt->pint32->registerInterruptUser( pPvt->int32Pvt,pPvt->pasynUser, pPvt->interruptCallback,pPvt,&pPvt->registrarPvt); if(status!=asynSuccess) { printf("%s devAsynInt32 registerInterruptUser %s\n", pr->name,pPvt->pasynUser->errorMessage); } } else { asynPrint(pPvt->pasynUser, ASYN_TRACE_FLOW, "%s devAsynInt32::getIoIntInfo cancelling interrupt\n", pr->name); status = pPvt->pint32->cancelInterruptUser(pPvt->int32Pvt, pPvt->pasynUser,pPvt->registrarPvt); if(status!=asynSuccess) { printf("%s devAsynInt32 cancelInterruptUser %s\n", pr->name,pPvt->pasynUser->errorMessage); } } *iopvt = pPvt->ioScanPvt; return 0; }
long epicsShareAPI dbGetField(DBADDR *paddr,short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { short dbfType = paddr->field_type; dbCommon *precord = paddr->precord; long status = 0; dbScanLock(precord); if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { DBENTRY dbEntry; dbFldDes *pfldDes = paddr->pfldDes; char *rtnString; char *pbuf = (char *)pbuffer; int maxlen; if (options && (*options)) getOptions(paddr, &pbuf, options, pflin); if (nRequest && *nRequest == 0) goto done; switch (dbrType) { case DBR_STRING: maxlen = MAX_STRING_SIZE - 1; if (nRequest && *nRequest > 1) *nRequest = 1; break; case DBR_CHAR: case DBR_UCHAR: if (nRequest && *nRequest > 0) { maxlen = *nRequest - 1; break; } /* else fall through ... */ default: status = S_db_badDbrtype; goto done; } dbInitEntry(pdbbase, &dbEntry); status = dbFindRecord(&dbEntry, precord->name); if (!status) status = dbFindField(&dbEntry, pfldDes->name); if (!status) { rtnString = dbGetString(&dbEntry); strncpy(pbuf, rtnString, maxlen); pbuf[maxlen] = 0; } dbFinishEntry(&dbEntry); } else { status = dbGet(paddr, dbrType, pbuffer, options, nRequest, pflin); } done: dbScanUnlock(precord); return status; }
LOCAL int connect(void **pab1771IXPvt,DBLINK *plink,boolean *isEng) { DBENTRY dbEntry; DBENTRY *pdbEntry = &dbEntry; DBADDR dbAddr; deviceData *pdeviceData; ab1771IXRecord *precord; recordPvt *precordPvt; long status; char buffer[MAX_BUFFER]; char *recordname = &buffer[0]; char *pstring; unsigned short signal; char *pLeftbracket; char *pRightbracket; if(plink->type!=INST_IO) return(ab1771IXFatalError); pstring = plink->value.instio.string; if(strlen(pstring)>=MAX_BUFFER) return(ab1771IXFatalError); strcpy(buffer,pstring); pLeftbracket = strchr(buffer,'['); pRightbracket = strchr(buffer,']'); if(!pLeftbracket || !pRightbracket) { errlogPrintf("link was not of the form record[signal]\n"); return(ab1771IXFatalError); } *pLeftbracket++ = '\0'; *pRightbracket = '\0'; sscanf(pLeftbracket,"%hu",&signal); dbInitEntry(pdbbase,pdbEntry); status = dbFindRecord(pdbEntry,recordname); if(status) return(ab1771IXNoRecord); if(strcmp(dbGetRecordTypeName(pdbEntry),"ab1771IX")!=0) return(ab1771IXIllegalRecordType); dbFinishEntry(pdbEntry); status = dbNameToAddr(recordname,&dbAddr); if(status) return(ab1771IXNoRecord); precord = (ab1771IXRecord *)dbAddr.precord; if(!(precordPvt = (recordPvt *)precord->dpvt)) { printf("%s precordPvt is NULL ?\n",precord->name); return(ab1771IXFatalError); } if(signal>=NUM_CHANS) return(ab1771IXIllegalType); if(signal<=3) { *isEng = ((precord->typa==ab1771IX_TYPE_MV)?FALSE:TRUE); } else { *isEng = ((precord->typb==ab1771IX_TYPE_MV)?FALSE:TRUE); } pdeviceData = dbCalloc(1,sizeof(deviceData)); pdeviceData->precord = precord; pdeviceData->signal = signal; *pab1771IXPvt = (void *)pdeviceData; return(ab1771IXOK); }
/*utility routine to dump raw messages*/ int ab1771IXpm(char *recordname) { DBENTRY dbEntry; DBENTRY *pdbEntry = &dbEntry; DBADDR dbAddr; ab1771IXRecord *precord; recordPvt *precordPvt; long status; short *pdata; int i; dbInitEntry(pdbbase,pdbEntry); status = dbFindRecord(pdbEntry,recordname); if(status) { printf("Cant find %s\n",recordname); return(0); } if(strcmp(dbGetRecordTypeName(pdbEntry),"ab1771IX")!=0) { printf("Not a ab1771IXRecord\n"); return(0); } dbFinishEntry(pdbEntry); status = dbNameToAddr(recordname,&dbAddr); if(status) { printf("Cant find %s\n",recordname); return(0); } precord = (ab1771IXRecord *)dbAddr.precord; if(!(precordPvt = (recordPvt *)precord->dpvt)) { printf("dpvt is NULL\n"); return(0); } printf("output message"); pdata = precord->outm; for(i=0; i< NUM_WORDS_OUT; i++) { if(i%10 == 0) printf("\n"); printf(" %4hx",*pdata); pdata++; } printf("\ninput message"); pdata = precord->inpm; for(i=0; i< NUM_WORDS_IN; i++) { if(i%10 == 0) printf("\n"); printf(" %4hx",*pdata); pdata++; } printf("\n"); return(0); }
static void dbAlias(char *name, char *alias) { DBENTRY dbEntry; DBENTRY *pdbEntry = &dbEntry; dbInitEntry(pdbbase, pdbEntry); if (dbFindRecord(pdbEntry, name)) { epicsPrintf("Alias \"%s\" refers to unknown record \"%s\"\n", alias, name); yyerror(NULL); } else if (dbCreateAlias(pdbEntry, alias)) { epicsPrintf("Can't create alias \"%s\" referring to \"%s\"\n", alias, name); yyerror(NULL); } dbFinishEntry(pdbEntry); }
static long getLinkValue(DBADDR *paddr, short dbrType, char *pbuf, long *nRequest) { dbCommon *precord = paddr->precord; dbFldDes *pfldDes = paddr->pfldDes; int maxlen; DBENTRY dbEntry; long status; switch (dbrType) { case DBR_STRING: maxlen = MAX_STRING_SIZE - 1; if (nRequest && *nRequest > 1) *nRequest = 1; break; case DBR_DOUBLE: /* Needed for dbCa links */ if (nRequest && *nRequest) *nRequest = 1; *(double *)pbuf = epicsNAN; return 0; case DBR_CHAR: case DBR_UCHAR: if (nRequest && *nRequest > 0) { maxlen = *nRequest - 1; break; } /* else fall through ... */ default: return S_db_badDbrtype; } dbInitEntry(pdbbase, &dbEntry); status = dbFindRecord(&dbEntry, precord->name); if (!status) status = dbFindField(&dbEntry, pfldDes->name); if (!status) { char *rtnString = dbGetString(&dbEntry); strncpy(pbuf, rtnString, --maxlen); pbuf[maxlen] = 0; } dbFinishEntry(&dbEntry); return status; }
static long createRingBuffer(dbCommon *pr) { devPvt *pPvt = (devPvt *)pr->dpvt; asynStatus status; const char *sizeString; if (!pPvt->ringBuffer) { DBENTRY *pdbentry = dbAllocEntry(pdbbase); pPvt->ringSize = DEFAULT_RING_BUFFER_SIZE; status = dbFindRecord(pdbentry, pr->name); if (status) { asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s devAsynFloat64::createRingBufffer error finding record\n", pr->name); return -1; } sizeString = dbGetInfo(pdbentry, "asyn:FIFO"); if (sizeString) pPvt->ringSize = atoi(sizeString); pPvt->ringBuffer = callocMustSucceed(pPvt->ringSize+1, sizeof *pPvt->ringBuffer, "devAsynFloat64::createRingBuffer"); } return asynSuccess; }
static void hookPass1(initHookState state) { DBENTRY entry; DBADDR addr; if(state!=initHookAfterInitDatabase) return; testDiag("initHookAfterInitDatabase"); dbInitEntry(pdbbase, &entry); if(dbFindRecord(&entry, "rec0.VAL")==0) { aoRecord *prec = entry.precnode->precord; testOk(prec->val==3, "VAL %d==3 (init_record value)", (int)prec->val); testOk1(dbPutString(&entry, "4")==0); testOk(prec->val==4, "VAL %d==4", (int)prec->val); } else{ testFail("Missing rec0"); testSkip(1, "missing record"); } /* Can't restore links in pass 1 */ if(dbNameToAddr("rec1.VAL", &addr)) { testFail("missing rec1"); testSkip(3, "missing record"); } else { struct rset *prset = dbGetRset(&addr); dbfType ftype = addr.field_type; long count=-1, offset=-1, maxcount = addr.no_elements; testOk1(prset && prset->get_array_info && prset->put_array_info); testOk1((*prset->get_array_info)(&addr, &count, &offset)==0); /* count is ignored */ testOk1((*dbPutConvertRoutine[DBF_DOUBLE][ftype])(&addr, values, NELEMENTS(values), maxcount,offset)==0); testOk1((*prset->put_array_info)(&addr, NELEMENTS(values))==0); } dbFinishEntry(&entry); }
static long initCommon(dbCommon *pr, DBLINK *plink, userCallback processCallback,interruptCallbackFloat64 interruptCallback) { devPvt *pPvt; asynStatus status; asynUser *pasynUser; asynInterface *pasynInterface; pPvt = callocMustSucceed(1, sizeof(*pPvt), "devAsynFloat64::initCommon"); pr->dpvt = pPvt; pPvt->pr = pr; /* Create asynUser */ pasynUser = pasynManager->createAsynUser(processCallback, 0); pasynUser->userPvt = pPvt; pPvt->pasynUser = pasynUser; pPvt->ringBufferLock = epicsMutexCreate(); /* Parse the link to get addr and port */ status = pasynEpicsUtils->parseLink(pasynUser, plink, &pPvt->portName, &pPvt->addr,&pPvt->userParam); if (status != asynSuccess) { printf("%s devAsynFloat64::initCommon %s\n", pr->name, pasynUser->errorMessage); goto bad; } /* Connect to device */ status = pasynManager->connectDevice(pasynUser, pPvt->portName, pPvt->addr); if (status != asynSuccess) { printf("%s devAsynFloat64::initCommon connectDevice failed %s\n", pr->name, pasynUser->errorMessage); goto bad; } status = pasynManager->canBlock(pPvt->pasynUser, &pPvt->canBlock); if (status != asynSuccess) { printf("%s devAsynFloat64::initCommon canBlock failed %s\n", pr->name, pasynUser->errorMessage); goto bad; } /*call drvUserCreate*/ pasynInterface = pasynManager->findInterface(pasynUser,asynDrvUserType,1); if(pasynInterface && pPvt->userParam) { asynDrvUser *pasynDrvUser; void *drvPvt; pasynDrvUser = (asynDrvUser *)pasynInterface->pinterface; drvPvt = pasynInterface->drvPvt; status = pasynDrvUser->create(drvPvt,pasynUser,pPvt->userParam,0,0); if(status!=asynSuccess) { printf("%s devAsynFloat64::initCommon drvUserCreate %s\n", pr->name, pasynUser->errorMessage); goto bad; } } /* Get interface asynFloat64 */ pasynInterface = pasynManager->findInterface(pasynUser, asynFloat64Type, 1); if (!pasynInterface) { printf("%s devAsynFloat64::initCommon findInterface asynFloat64Type %s\n", pr->name,pasynUser->errorMessage); goto bad; } pPvt->pfloat64 = pasynInterface->pinterface; pPvt->float64Pvt = pasynInterface->drvPvt; /* Initialize synchronous interface */ status = pasynFloat64SyncIO->connect(pPvt->portName, pPvt->addr, &pPvt->pasynUserSync, pPvt->userParam); if (status != asynSuccess) { printf("%s devAsynFloat64::initCommon Float64SyncIO->connect failed %s\n", pr->name, pPvt->pasynUserSync->errorMessage); goto bad; } scanIoInit(&pPvt->ioScanPvt); pPvt->interruptCallback = interruptCallback; /* If the info field "asyn:READBACK" is 1 and interruptCallback is not NULL * then register for callbacks on output records */ if (interruptCallback) { int enableCallbacks=0; const char *callbackString; DBENTRY *pdbentry = dbAllocEntry(pdbbase); status = dbFindRecord(pdbentry, pr->name); if (status) { asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s devAsynFloat64::initCommon error finding record\n", pr->name); goto bad; } callbackString = dbGetInfo(pdbentry, "asyn:READBACK"); if (callbackString) enableCallbacks = atoi(callbackString); if (enableCallbacks) { status = createRingBuffer(pr); if (status!=asynSuccess) goto bad; status = pPvt->pfloat64->registerInterruptUser( pPvt->float64Pvt,pPvt->pasynUser, pPvt->interruptCallback,pPvt,&pPvt->registrarPvt); if(status!=asynSuccess) { printf("%s devAsynFloat64::initRecord error calling registerInterruptUser %s\n", pr->name,pPvt->pasynUser->errorMessage); } } } return INIT_OK; bad: recGblSetSevr(pr,LINK_ALARM,INVALID_ALARM); pr->pact=1; return INIT_ERROR; }
static long initCommon(dbCommon *pr, DBLINK *plink, userCallback processCallback,interruptCallbackUInt32Digital interruptCallback, interruptCallbackEnum callbackEnum, int maxEnums, char *pFirstString, int *pFirstValue, epicsEnum16 *pFirstSeverity) { devPvt *pPvt; asynStatus status; asynUser *pasynUser; asynInterface *pasynInterface; pPvt = callocMustSucceed(1, sizeof(*pPvt), "devAsynUInt32Digital::initCommon"); pr->dpvt = pPvt; pPvt->pr = pr; /* Create asynUser */ pasynUser = pasynManager->createAsynUser(processCallback, 0); pasynUser->userPvt = pPvt; pPvt->pasynUser = pasynUser; pPvt->ringBufferLock = epicsMutexCreate(); /* Parse the link to get addr and port */ status = pasynEpicsUtils->parseLinkMask(pasynUser, plink, &pPvt->portName, &pPvt->addr, &pPvt->mask,&pPvt->userParam); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon %s\n", pr->name, pasynUser->errorMessage); goto bad; } /* Connect to device */ status = pasynManager->connectDevice(pasynUser, pPvt->portName, pPvt->addr); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon connectDevice failed %s\n", pr->name, pasynUser->errorMessage); goto bad; } status = pasynManager->canBlock(pPvt->pasynUser, &pPvt->canBlock); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon canBlock failed %s\n", pr->name, pasynUser->errorMessage); goto bad; } /*call drvUserCreate*/ pasynInterface = pasynManager->findInterface(pasynUser,asynDrvUserType,1); if(pasynInterface && pPvt->userParam) { asynDrvUser *pasynDrvUser; void *drvPvt; pasynDrvUser = (asynDrvUser *)pasynInterface->pinterface; drvPvt = pasynInterface->drvPvt; status = pasynDrvUser->create(drvPvt,pasynUser,pPvt->userParam,0,0); if(status!=asynSuccess) { printf("%s devAsynUInt32Digital::initCommon drvUserCreate %s\n", pr->name, pasynUser->errorMessage); goto bad; } } /* Get interface asynUInt32Digital */ pasynInterface = pasynManager->findInterface(pasynUser, asynUInt32DigitalType, 1); if (!pasynInterface) { printf("%s devAsynUInt32Digital::initCommon " "findInterface asynUInt32DigitalType %s\n", pr->name,pasynUser->errorMessage); goto bad; } pPvt->puint32 = pasynInterface->pinterface; pPvt->uint32Pvt = pasynInterface->drvPvt; /* Initialize synchronous interface */ status = pasynUInt32DigitalSyncIO->connect(pPvt->portName, pPvt->addr, &pPvt->pasynUserSync, pPvt->userParam); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon UInt32DigitalSyncIO->connect failed %s\n", pr->name, pPvt->pasynUserSync->errorMessage); goto bad; } pPvt->interruptCallback = interruptCallback; scanIoInit(&pPvt->ioScanPvt); /* Initialize asynEnum interfaces */ pasynInterface = pasynManager->findInterface(pPvt->pasynUser,asynEnumType,1); if (pasynInterface && (maxEnums > 0)) { size_t numRead; asynEnum *pasynEnum = pasynInterface->pinterface; void *registrarPvt; status = pasynEnumSyncIO->connect(pPvt->portName, pPvt->addr, &pPvt->pasynUserEnumSync, pPvt->userParam); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon EnumSyncIO->connect failed %s\n", pr->name, pPvt->pasynUserEnumSync->errorMessage); goto bad; } status = pasynEnumSyncIO->read(pPvt->pasynUserEnumSync, pPvt->enumStrings, pPvt->enumValues, pPvt->enumSeverities, maxEnums, &numRead, pPvt->pasynUser->timeout); if (status == asynSuccess) { setEnums(pFirstString, pFirstValue, pFirstSeverity, pPvt->enumStrings, pPvt->enumValues, pPvt->enumSeverities, numRead, maxEnums); } status = pasynEnum->registerInterruptUser( pasynInterface->drvPvt, pPvt->pasynUser, callbackEnum, pPvt, ®istrarPvt); if(status!=asynSuccess) { printf("%s devAsynUInt32Digital enum registerInterruptUser %s\n", pr->name,pPvt->pasynUser->errorMessage); } } /* If the info field "asyn:READBACK" is 1 and interruptCallback is not NULL * then register for callbacks on output records */ if (interruptCallback) { int enableCallbacks=0; const char *callbackString; DBENTRY *pdbentry = dbAllocEntry(pdbbase); status = dbFindRecord(pdbentry, pr->name); if (status) { asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s devAsynUInt32Digital::initCommon error finding record\n", pr->name); goto bad; } callbackString = dbGetInfo(pdbentry, "asyn:READBACK"); if (callbackString) enableCallbacks = atoi(callbackString); if (enableCallbacks) { status = createRingBuffer(pr); if (status!=asynSuccess) goto bad; status = pPvt->puint32->registerInterruptUser( pPvt->uint32Pvt,pPvt->pasynUser, pPvt->interruptCallback,pPvt,pPvt->mask, &pPvt->registrarPvt); if(status!=asynSuccess) { printf("%s devAsynUInt32Digital::initRecord error calling registerInterruptUser %s\n", pr->name,pPvt->pasynUser->errorMessage); } } } return INIT_OK; bad: recGblSetSevr(pr,LINK_ALARM,INVALID_ALARM); pr->pact=1; return INIT_ERROR; }
static void hookPass0(initHookState state) { DBENTRY entry; if(state!=initHookAfterInitDevSup) return; testDiag("initHookAfterInitDevSup"); dbInitEntry(pdbbase, &entry); testDiag("restore integer pass0"); /* rec0.VAL is initially 1, set it to 2 */ if(dbFindRecord(&entry, "rec0.VAL")==0) { aoRecord *prec = entry.precnode->precord; testOk(prec->val==1, "VAL %d==1 (initial value from .db)", (int)prec->val); checkGetString(&entry, "1"); testOk1(dbPutString(&entry, "2")==0); testOk(prec->val==2, "VAL %d==2", (int)prec->val); checkGetString(&entry, "2"); } else { testFail("Missing rec0"); testSkip(4, "missing record"); } testDiag("restore string pass0"); if(dbFindRecord(&entry, "rec0.DESC")==0) { aoRecord *prec = entry.precnode->precord; testOk1(strcmp(prec->desc, "foobar")==0); checkGetString(&entry, "foobar"); testOk1(dbPutString(&entry, "hello")==0); testOk1(strcmp(prec->desc, "hello")==0); checkGetString(&entry, "hello"); } else { testFail("Missing rec0"); testSkip(4, "missing record"); } if(dbFindRecord(&entry, "rec1.DESC")==0) { aoRecord *prec = entry.precnode->precord; testOk1(strcmp(prec->desc, "")==0); checkGetString(&entry, ""); testOk1(dbPutString(&entry, "world")==0); testOk1(strcmp(prec->desc, "world")==0); checkGetString(&entry, "world"); } else { testFail("Missing rec1"); testSkip(4, "missing record"); } testDiag("restore link pass0"); /* rec0.OUT is initially "rec0.DISV", set it to "rec0.SEVR" */ if(dbFindRecord(&entry, "rec0.OUT")==0) { aoRecord *prec = entry.precnode->precord; if(prec->out.type==CONSTANT) testOk(strcmp(prec->out.text,"rec0.DISV")==0, "%s==rec0.DISV (initial value from .db)", prec->out.text); else testFail("Wrong link type: %d", (int)prec->out.type); /* note that dbGetString() reads an empty string before links are initialized * should probably be considered a bug, but has been the case for so long * we call it a 'feature'. */ checkGetString(&entry, ""); testOk1(dbPutString(&entry, "rec0.SEVR")==0); } else{ testFail("Missing rec0"); testSkip(1, "missing record"); } /* rec0.SDIS is initially NULL, set it to "rec0.STAT" */ if(dbFindRecord(&entry, "rec0.SDIS")==0) { aoRecord *prec = entry.precnode->precord; if(prec->sdis.type==CONSTANT) testOk1(prec->sdis.value.constantStr==NULL); else testFail("Wrong link type: %d", (int)prec->sdis.type); testOk1(dbPutString(&entry, "rec0.STAT")==0); } else{ testFail("Missing rec0"); testSkip(1, "missing record"); } /* can't restore array field in pass0 */ dbFinishEntry(&entry); }
static int dbpr_report( const char *pname, DBADDR *paddr, int interest_level, TAB_BUFFER *pMsgBuff, int tab_size) { char *pmsg; dbFldDes *pdbFldDes = paddr->pfldDes; dbRecordType *pdbRecordType = pdbFldDes->pdbRecordType; short n2; void *pfield; char *pfield_name; char *pfield_value; DBENTRY dbentry; DBENTRY *pdbentry = &dbentry; long status; dbInitEntry(pdbbase,pdbentry); status = dbFindRecord(pdbentry,pname); if (status) { errMessage(status,pname); return -1; } pmsg = pMsgBuff->message; for (n2 = 0; n2 <= pdbRecordType->no_fields - 1; n2++) { pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->sortFldInd[n2]]; pfield_name = pdbFldDes->name; pfield = ((char *)paddr->precord) + pdbFldDes->offset; if (pdbFldDes->interest > interest_level ) continue; switch (pdbFldDes->field_type) { case DBF_STRING: case DBF_USHORT: case DBF_ENUM: case DBF_FLOAT: case DBF_CHAR: case DBF_UCHAR: case DBF_SHORT: case DBF_LONG: case DBF_ULONG: case DBF_DOUBLE: case DBF_MENU: case DBF_DEVICE: status = dbFindField(pdbentry,pfield_name); pfield_value = dbGetString(pdbentry); sprintf(pmsg, "%s: %s", pfield_name, (pfield_value ? pfield_value : "<nil>")); dbpr_msgOut(pMsgBuff, tab_size); break; case DBF_INLINK: case DBF_OUTLINK: case DBF_FWDLINK: { DBLINK *plink = (DBLINK *)pfield; int ind; status = dbFindField(pdbentry,pfield_name); for (ind=0; ind<LINK_NTYPES; ind++) { if (pamaplinkType[ind].value == plink->type) break; } if (ind>=LINK_NTYPES) { sprintf(pmsg,"%s: Illegal Link Type", pfield_name); } else { sprintf(pmsg,"%s:%s %s", pfield_name, pamaplinkType[ind].strvalue,dbGetString(pdbentry)); } dbpr_msgOut(pMsgBuff, tab_size); } break; case DBF_NOACCESS: if (pfield == (void *)&paddr->precord->time) { /* Special for the TIME field, make it human-readable */ char time_buf[40]; epicsTimeToStrftime(time_buf, 40, "%Y-%m-%d %H:%M:%S.%09f", &paddr->precord->time); sprintf(pmsg, "%s: %s", pfield_name, time_buf); dbpr_msgOut(pMsgBuff, tab_size); } else if (pdbFldDes->size == sizeof(void *) && strchr(pdbFldDes->extra, '*')) { /* Special for pointers, needed on little-endian CPUs */ sprintf(pmsg, "%s: %p", pfield_name, *(void **)pfield); dbpr_msgOut(pMsgBuff, tab_size); } else { /* just print field as hex bytes */ unsigned char *pchar = (unsigned char *)pfield; char temp_buf[61]; char *ptemp_buf = &temp_buf[0]; short n = pdbFldDes->size; short i; unsigned int value; if (n > sizeof(temp_buf)/3) n = sizeof(temp_buf)/3; for (i=0; i<n; i++, ptemp_buf += 3, pchar++) { value = (unsigned int)*pchar; sprintf(ptemp_buf, "%02x ", value); } sprintf(pmsg, "%s: %s", pfield_name,temp_buf); dbpr_msgOut(pMsgBuff, tab_size); } break; default: sprintf(pmsg, "%s: dbpr: Unknown field_type", pfield_name); dbpr_msgOut(pMsgBuff, tab_size); break; } } pmsg[0] = '\0'; dbpr_msgOut(pMsgBuff, tab_size); dbFinishEntry(pdbentry); return (0); }
static long dbPutFieldLink(DBADDR *paddr, short dbrType, const void *pbuffer, long nRequest) { dbCommon *precord = paddr->precord; dbFldDes *pfldDes = paddr->pfldDes; long special = paddr->special; DBLINK *plink = (DBLINK *)paddr->pfield; const char *pstring = (const char *)pbuffer; DBENTRY dbEntry; DBADDR dbaddr; struct dsxt *old_dsxt = NULL; struct dset *new_dset = NULL; struct dsxt *new_dsxt = NULL; long status; int isDevLink; short scan; switch (dbrType) { case DBR_CHAR: case DBR_UCHAR: if (pstring[nRequest - 1] != '\0') return S_db_badDbrtype; break; case DBR_STRING: break; default: return S_db_badDbrtype; } dbInitEntry(pdbbase, &dbEntry); status = dbFindRecord(&dbEntry, precord->name); if (!status) status = dbFindField(&dbEntry, pfldDes->name); if (status) goto finish; isDevLink = ellCount(&precord->rdes->devList) > 0 && (strcmp(pfldDes->name, "INP") == 0 || strcmp(pfldDes->name, "OUT") == 0); dbLockSetGblLock(); dbLockSetRecordLock(precord); scan = precord->scan; if (isDevLink) { devSup *pdevSup = dbDTYPtoDevSup(precord->rdes, precord->dtyp); if (pdevSup) { new_dset = pdevSup->pdset; new_dsxt = pdevSup->pdsxt; } if (precord->dset) { pdevSup = dbDSETtoDevSup(precord->rdes, precord->dset); if (pdevSup) old_dsxt = pdevSup->pdsxt; } if (new_dsxt == NULL || new_dsxt->add_record == NULL || (precord->dset && old_dsxt == NULL) || (old_dsxt && old_dsxt->del_record == NULL)) { status = S_db_noSupport; goto unlock; } if (scan == menuScanI_O_Intr) { scanDelete(precord); precord->scan = menuScanPassive; } if (old_dsxt) { status = old_dsxt->del_record(precord); if (status) goto restoreScan; } } switch (plink->type) { /* Old link type */ case DB_LINK: free(plink->value.pv_link.pvt); plink->value.pv_link.pvt = 0; plink->type = PV_LINK; plink->value.pv_link.getCvt = 0; plink->value.pv_link.pvlMask = 0; plink->value.pv_link.lastGetdbrType = 0; dbLockSetSplit(precord); break; case CA_LINK: dbCaRemoveLink(plink); plink->type = PV_LINK; plink->value.pv_link.getCvt = 0; plink->value.pv_link.pvlMask = 0; plink->value.pv_link.lastGetdbrType = 0; break; case CONSTANT: break; /* do nothing */ case PV_LINK: case MACRO_LINK: break; /* should never get here */ default: /* Hardware address */ if (!isDevLink) { status = S_db_badHWaddr; goto restoreScan; } break; } if (special) status = dbPutSpecial(paddr, 0); if (!status) status = dbPutString(&dbEntry, pstring); if (!status && special) status = dbPutSpecial(paddr, 1); if (status) { if (isDevLink) { precord->dset = NULL; precord->pact = TRUE; } goto postScanEvent; } if (isDevLink) { precord->dpvt = NULL; precord->dset = new_dset; precord->pact = FALSE; status = new_dsxt->add_record(precord); if (status) { precord->dset = NULL; precord->pact = TRUE; goto postScanEvent; } } switch (plink->type) { /* New link type */ case PV_LINK: if (plink == &precord->tsel) recGblTSELwasModified(plink); plink->value.pv_link.precord = precord; if (!(plink->value.pv_link.pvlMask & (pvlOptCA|pvlOptCP|pvlOptCPP)) && (dbNameToAddr(plink->value.pv_link.pvname, &dbaddr) == 0)) { /* It's a DB link */ DBADDR *pdbAddr; plink->type = DB_LINK; pdbAddr = dbMalloc(sizeof(struct dbAddr)); *pdbAddr = dbaddr; /* NB: structure copy */; plink->value.pv_link.pvt = pdbAddr; dbLockSetRecordLock(pdbAddr->precord); dbLockSetMerge(precord, pdbAddr->precord); } else { /* Make it a CA link */ char *pperiod; plink->type = CA_LINK; if (pfldDes->field_type == DBF_INLINK) { plink->value.pv_link.pvlMask |= pvlOptInpNative; } dbCaAddLink(plink); if (pfldDes->field_type == DBF_FWDLINK) { pperiod = strrchr(plink->value.pv_link.pvname, '.'); if (pperiod && strstr(pperiod, "PROC")) plink->value.pv_link.pvlMask |= pvlOptFWD; } } break; case CONSTANT: break; case DB_LINK: case CA_LINK: case MACRO_LINK: break; /* should never get here */ default: /* Hardware address */ if (!isDevLink) { status = S_db_badHWaddr; goto postScanEvent; } break; } db_post_events(precord, plink, DBE_VALUE | DBE_LOG); restoreScan: if (isDevLink && scan == menuScanI_O_Intr) { /* undo scanDelete() */ precord->scan = scan; scanAdd(precord); } postScanEvent: if (scan != precord->scan) db_post_events(precord, &precord->scan, DBE_VALUE|DBE_LOG); unlock: dbLockSetGblUnlock(); finish: dbFinishEntry(&dbEntry); return status; }
/* Performs the work of the public db_get_field API, but also returns the number * of elements actually copied to the buffer. The caller is responsible for * zeroing the remaining part of the buffer. */ int dbChannel_get_count( struct dbChannel *chan, int buffer_type, void *pbuffer, long *nRequest, void *pfl) { long status; long options; long i; long zero = 0; /* The order of the DBR* elements in the "newSt" structures below is * very important and must correspond to the order of processing * in the dbAccess.c dbGet() and getOptions() routines. */ dbScanLock(dbChannelRecord(chan)); switch(buffer_type) { case(oldDBR_STRING): status = dbChannelGet(chan, DBR_STRING, pbuffer, &zero, nRequest, pfl); break; /* case(oldDBR_INT): */ case(oldDBR_SHORT): status = dbChannelGet(chan, DBR_SHORT, pbuffer, &zero, nRequest, pfl); break; case(oldDBR_FLOAT): status = dbChannelGet(chan, DBR_FLOAT, pbuffer, &zero, nRequest, pfl); break; case(oldDBR_ENUM): status = dbChannelGet(chan, DBR_ENUM, pbuffer, &zero, nRequest, pfl); break; case(oldDBR_CHAR): status = dbChannelGet(chan, DBR_CHAR, pbuffer, &zero, nRequest, pfl); break; case(oldDBR_LONG): status = dbChannelGet(chan, DBR_LONG, pbuffer, &zero, nRequest, pfl); break; case(oldDBR_DOUBLE): status = dbChannelGet(chan, DBR_DOUBLE, pbuffer, &zero, nRequest, pfl); break; case(oldDBR_STS_STRING): case(oldDBR_GR_STRING): case(oldDBR_CTRL_STRING): { struct dbr_sts_string *pold = (struct dbr_sts_string *)pbuffer; struct { DBRstatus } newSt; options = DBR_STATUS; status = dbChannelGet(chan, DBR_STRING, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; status = dbChannelGet(chan, DBR_STRING, pold->value, &zero, nRequest, pfl); } break; /* case(oldDBR_STS_INT): */ case(oldDBR_STS_SHORT): { struct dbr_sts_int *pold = (struct dbr_sts_int *)pbuffer; struct { DBRstatus } newSt; options = DBR_STATUS; status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; status = dbChannelGet(chan, DBR_SHORT, &pold->value, &zero, nRequest, pfl); } break; case(oldDBR_STS_FLOAT): { struct dbr_sts_float *pold = (struct dbr_sts_float *)pbuffer; struct { DBRstatus } newSt; options = DBR_STATUS; status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &zero, nRequest, pfl); } break; case(oldDBR_STS_ENUM): { struct dbr_sts_enum *pold = (struct dbr_sts_enum *)pbuffer; struct { DBRstatus } newSt; options = DBR_STATUS; status = dbChannelGet(chan, DBR_ENUM, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; status = dbChannelGet(chan, DBR_ENUM, &pold->value, &zero, nRequest, pfl); } break; case(oldDBR_STS_CHAR): { struct dbr_sts_char *pold = (struct dbr_sts_char *)pbuffer; struct { DBRstatus } newSt; options = DBR_STATUS; status = dbChannelGet(chan, DBR_UCHAR, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; status = dbChannelGet(chan, DBR_UCHAR, &pold->value, &zero, nRequest, pfl); } break; case(oldDBR_STS_LONG): { struct dbr_sts_long *pold = (struct dbr_sts_long *)pbuffer; struct { DBRstatus } newSt; options = DBR_STATUS; status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; status = dbChannelGet(chan, DBR_LONG, &pold->value, &zero, nRequest, pfl); } break; case(oldDBR_STS_DOUBLE): { struct dbr_sts_double *pold = (struct dbr_sts_double *)pbuffer; struct { DBRstatus } newSt; options = DBR_STATUS; status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; options = 0; status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_TIME_STRING): { struct dbr_time_string *pold = (struct dbr_time_string *)pbuffer; struct { DBRstatus DBRtime } newSt; options = DBR_STATUS | DBR_TIME; status = dbChannelGet(chan, DBR_STRING, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->stamp = newSt.time; /* structure copy */ options = 0; status = dbChannelGet(chan, DBR_STRING, pold->value, &options, nRequest, pfl); } break; /* case(oldDBR_TIME_INT): */ case(oldDBR_TIME_SHORT): { struct dbr_time_short *pold = (struct dbr_time_short *)pbuffer; struct { DBRstatus DBRtime } newSt; options = DBR_STATUS | DBR_TIME; status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->stamp = newSt.time; /* structure copy */ options = 0; status = dbChannelGet(chan, DBR_SHORT, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_TIME_FLOAT): { struct dbr_time_float *pold = (struct dbr_time_float *)pbuffer; struct { DBRstatus DBRtime } newSt; options = DBR_STATUS | DBR_TIME; status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->stamp = newSt.time; /* structure copy */ options = 0; status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_TIME_ENUM): { struct dbr_time_enum *pold = (struct dbr_time_enum *)pbuffer; struct { DBRstatus DBRtime } newSt; options = DBR_STATUS | DBR_TIME; status = dbChannelGet(chan, DBR_ENUM, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->stamp = newSt.time; /* structure copy */ options = 0; status = dbChannelGet(chan, DBR_ENUM, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_TIME_CHAR): { struct dbr_time_char *pold = (struct dbr_time_char *)pbuffer; struct { DBRstatus DBRtime } newSt; options = DBR_STATUS | DBR_TIME; status = dbChannelGet(chan, DBR_CHAR, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->stamp = newSt.time; /* structure copy */ options = 0; status = dbChannelGet(chan, DBR_CHAR, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_TIME_LONG): { struct dbr_time_long *pold = (struct dbr_time_long *)pbuffer; struct { DBRstatus DBRtime } newSt; options = DBR_STATUS | DBR_TIME; status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->stamp = newSt.time; /* structure copy */ options = 0; status = dbChannelGet(chan, DBR_LONG, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_TIME_DOUBLE): { struct dbr_time_double *pold = (struct dbr_time_double *)pbuffer; struct { DBRstatus DBRtime } newSt; options = DBR_STATUS | DBR_TIME; status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->stamp = newSt.time; /* structure copy */ options = 0; status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options, nRequest, pfl); } break; /* case(oldDBR_GR_STRING): NOT IMPLEMENTED - use DBR_STS_STRING */ /* case(oldDBR_GR_INT): */ case(oldDBR_GR_SHORT): { struct dbr_gr_int *pold = (struct dbr_gr_int *)pbuffer; struct { DBRstatus DBRunits DBRgrLong DBRalLong } newSt; options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG; status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = newSt.upper_disp_limit; pold->lower_disp_limit = newSt.lower_disp_limit; pold->upper_alarm_limit = newSt.upper_alarm_limit; pold->upper_warning_limit = newSt.upper_warning_limit; pold->lower_warning_limit = newSt.lower_warning_limit; pold->lower_alarm_limit = newSt.lower_alarm_limit; options = 0; status = dbChannelGet(chan, DBR_SHORT, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_GR_FLOAT): { struct dbr_gr_float *pold = (struct dbr_gr_float *)pbuffer; struct { DBRstatus DBRunits DBRprecision DBRgrDouble DBRalDouble } newSt; options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE | DBR_AL_DOUBLE; status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->precision = (dbr_short_t) newSt.precision.dp; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = epicsConvertDoubleToFloat(newSt.upper_disp_limit); pold->lower_disp_limit = epicsConvertDoubleToFloat(newSt.lower_disp_limit); pold->upper_alarm_limit = epicsConvertDoubleToFloat(newSt.upper_alarm_limit); pold->lower_alarm_limit = epicsConvertDoubleToFloat(newSt.lower_alarm_limit); pold->upper_warning_limit = epicsConvertDoubleToFloat(newSt.upper_warning_limit); pold->lower_warning_limit = epicsConvertDoubleToFloat(newSt.lower_warning_limit); options = 0; status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &options, nRequest, pfl); } break; /* case(oldDBR_GR_ENUM): see oldDBR_CTRL_ENUM */ case(oldDBR_GR_CHAR): { struct dbr_gr_char *pold = (struct dbr_gr_char *)pbuffer; struct { DBRstatus DBRunits DBRgrLong DBRalLong } newSt; options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG; status = dbChannelGet(chan, DBR_UCHAR, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = newSt.upper_disp_limit; pold->lower_disp_limit = newSt.lower_disp_limit; pold->upper_alarm_limit = newSt.upper_alarm_limit; pold->upper_warning_limit = newSt.upper_warning_limit; pold->lower_warning_limit = newSt.lower_warning_limit; pold->lower_alarm_limit = newSt.lower_alarm_limit; options = 0; status = dbChannelGet(chan, DBR_UCHAR, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_GR_LONG): { struct dbr_gr_long *pold = (struct dbr_gr_long *)pbuffer; struct { DBRstatus DBRunits DBRgrLong DBRalLong } newSt; options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG; status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = newSt.upper_disp_limit; pold->lower_disp_limit = newSt.lower_disp_limit; pold->upper_alarm_limit = newSt.upper_alarm_limit; pold->upper_warning_limit = newSt.upper_warning_limit; pold->lower_warning_limit = newSt.lower_warning_limit; pold->lower_alarm_limit = newSt.lower_alarm_limit; options = 0; status = dbChannelGet(chan, DBR_LONG, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_GR_DOUBLE): { struct dbr_gr_double *pold = (struct dbr_gr_double *)pbuffer; struct { DBRstatus DBRunits DBRprecision DBRgrDouble DBRalDouble } newSt; options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE | DBR_AL_DOUBLE; status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->precision = (dbr_short_t) newSt.precision.dp; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = newSt.upper_disp_limit; pold->lower_disp_limit = newSt.lower_disp_limit; pold->upper_alarm_limit = newSt.upper_alarm_limit; pold->upper_warning_limit = newSt.upper_warning_limit; pold->lower_warning_limit = newSt.lower_warning_limit; pold->lower_alarm_limit = newSt.lower_alarm_limit; options = 0; status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options, nRequest, pfl); } break; /* case(oldDBR_CTRL_INT): */ case(oldDBR_CTRL_SHORT): { struct dbr_ctrl_int *pold = (struct dbr_ctrl_int *)pbuffer; struct { DBRstatus DBRunits DBRgrLong DBRctrlLong DBRalLong } newSt; options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG | DBR_AL_LONG; status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = newSt.upper_disp_limit; pold->lower_disp_limit = newSt.lower_disp_limit; pold->upper_alarm_limit = newSt.upper_alarm_limit; pold->upper_warning_limit = newSt.upper_warning_limit; pold->lower_warning_limit = newSt.lower_warning_limit; pold->lower_alarm_limit = newSt.lower_alarm_limit; pold->upper_ctrl_limit = newSt.upper_ctrl_limit; pold->lower_ctrl_limit = newSt.lower_ctrl_limit; options = 0; status = dbChannelGet(chan, DBR_SHORT, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_CTRL_FLOAT): { struct dbr_ctrl_float *pold = (struct dbr_ctrl_float *)pbuffer; struct { DBRstatus DBRunits DBRprecision DBRgrDouble DBRctrlDouble DBRalDouble } newSt; options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE | DBR_CTRL_DOUBLE | DBR_AL_DOUBLE; status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->precision = (dbr_short_t) newSt.precision.dp; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = epicsConvertDoubleToFloat(newSt.upper_disp_limit); pold->lower_disp_limit = epicsConvertDoubleToFloat(newSt.lower_disp_limit); pold->upper_alarm_limit = epicsConvertDoubleToFloat(newSt.upper_alarm_limit); pold->lower_alarm_limit = epicsConvertDoubleToFloat(newSt.lower_alarm_limit); pold->upper_warning_limit = epicsConvertDoubleToFloat(newSt.upper_warning_limit); pold->lower_warning_limit = epicsConvertDoubleToFloat(newSt.lower_warning_limit); pold->upper_ctrl_limit = epicsConvertDoubleToFloat(newSt.upper_ctrl_limit); pold->lower_ctrl_limit = epicsConvertDoubleToFloat(newSt.lower_ctrl_limit); options = 0; status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_GR_ENUM): case(oldDBR_CTRL_ENUM): { struct dbr_ctrl_enum *pold = (struct dbr_ctrl_enum *)pbuffer; struct { DBRstatus DBRenumStrs } newSt; short no_str; memset(pold, '\0', sizeof(struct dbr_ctrl_enum)); /* first get status and severity */ options = DBR_STATUS | DBR_ENUM_STRS; status = dbChannelGet(chan, DBR_ENUM, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; no_str = newSt.no_str; if (no_str>16) no_str=16; pold->no_str = no_str; for (i = 0; i < no_str; i++) strncpy(pold->strs[i], newSt.strs[i], sizeof(pold->strs[i])); /*now get values*/ options = 0; status = dbChannelGet(chan, DBR_ENUM, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_CTRL_CHAR): { struct dbr_ctrl_char *pold = (struct dbr_ctrl_char *)pbuffer; struct { DBRstatus DBRunits DBRgrLong DBRctrlLong DBRalLong } newSt; options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG | DBR_AL_LONG; status = dbChannelGet(chan, DBR_UCHAR, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = newSt.upper_disp_limit; pold->lower_disp_limit = newSt.lower_disp_limit; pold->upper_alarm_limit = newSt.upper_alarm_limit; pold->upper_warning_limit = newSt.upper_warning_limit; pold->lower_warning_limit = newSt.lower_warning_limit; pold->lower_alarm_limit = newSt.lower_alarm_limit; pold->upper_ctrl_limit = newSt.upper_ctrl_limit; pold->lower_ctrl_limit = newSt.lower_ctrl_limit; options = 0; status = dbChannelGet(chan, DBR_UCHAR, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_CTRL_LONG): { struct dbr_ctrl_long *pold = (struct dbr_ctrl_long *)pbuffer; struct { DBRstatus DBRunits DBRgrLong DBRctrlLong DBRalLong } newSt; options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG | DBR_AL_LONG; status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = newSt.upper_disp_limit; pold->lower_disp_limit = newSt.lower_disp_limit; pold->upper_alarm_limit = newSt.upper_alarm_limit; pold->upper_warning_limit = newSt.upper_warning_limit; pold->lower_warning_limit = newSt.lower_warning_limit; pold->lower_alarm_limit = newSt.lower_alarm_limit; pold->upper_ctrl_limit = newSt.upper_ctrl_limit; pold->lower_ctrl_limit = newSt.lower_ctrl_limit; options = 0; status = dbChannelGet(chan, DBR_LONG, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_CTRL_DOUBLE): { struct dbr_ctrl_double *pold = (struct dbr_ctrl_double *)pbuffer; struct { DBRstatus DBRunits DBRprecision DBRgrDouble DBRctrlDouble DBRalDouble } newSt; options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE | DBR_CTRL_DOUBLE | DBR_AL_DOUBLE; status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->precision = (dbr_short_t) newSt.precision.dp; strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; pold->upper_disp_limit = newSt.upper_disp_limit; pold->lower_disp_limit = newSt.lower_disp_limit; pold->upper_alarm_limit = newSt.upper_alarm_limit; pold->upper_warning_limit = newSt.upper_warning_limit; pold->lower_warning_limit = newSt.lower_warning_limit; pold->lower_alarm_limit = newSt.lower_alarm_limit; pold->upper_ctrl_limit = newSt.upper_ctrl_limit; pold->lower_ctrl_limit = newSt.lower_ctrl_limit; options = 0; status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options, nRequest, pfl); } break; case(oldDBR_STSACK_STRING): { struct dbr_stsack_string *pold = (struct dbr_stsack_string *)pbuffer; struct { DBRstatus } newSt; options = DBR_STATUS; status = dbChannelGet(chan, DBR_STRING, &newSt, &options, &zero, pfl); pold->status = newSt.status; pold->severity = newSt.severity; pold->ackt = newSt.ackt; pold->acks = newSt.acks; options = 0; status = dbChannelGet(chan, DBR_STRING, pold->value, &options, nRequest, pfl); } break; case(oldDBR_CLASS_NAME): { DBENTRY dbEntry; char *name = 0; char *pto = (char *)pbuffer; if (!pdbbase) { status = S_db_notFound; break; } dbInitEntry(pdbbase, &dbEntry); status = dbFindRecord(&dbEntry, dbChannelRecord(chan)->name); if (!status) name = dbGetRecordTypeName(&dbEntry); dbFinishEntry(&dbEntry); if (status) break; if (!name) { status = S_dbLib_recordTypeNotFound; break; } pto[MAX_STRING_SIZE-1] = 0; strncpy(pto, name, MAX_STRING_SIZE-1); } break; default: status = -1; break; } dbScanUnlock(dbChannelRecord(chan)); if (status) return -1; return 0; }