Exemplo n.º 1
0
void DbPvPut::get()
{
    if(DbPvDebug::getLevel()>0) printf("dbPvPut::get()\n");
    {
        Lock lock(dataMutex);
        dbScanLock(dbChannelRecord(dbPv->getDbChannel()));
        bitSet->clear();
        Status status = dbUtil->get(
                    channelPutRequester,
                    propertyMask,
                    dbPv->getDbChannel(),
                    pvStructure,
                    bitSet,
                    0);
        dbScanUnlock(dbChannelRecord(dbPv->getDbChannel()));
        if(firstTime) {
            firstTime = false;
            bitSet->set(pvStructure->getFieldOffset());
        }
    }
    channelPutRequester->getDone(
                status,
                getPtrSelf(),
                pvStructure,
                bitSet);
}
Exemplo n.º 2
0
void DbPvPut::put(PVStructurePtr const &pvStructure, BitSetPtr const & bitSet)
{
    if (DbPvDebug::getLevel() > 0) printf("dbPvPut::put()\n");

    this->pvStructure = pvStructure;
    this->bitSet = bitSet;

    if (block && process) {
        dbProcessNotify(pNotify.get());
        return;
    }

    Lock lock(dataMutex);
    PVFieldPtr pvField = pvStructure.get()->getPVFields()[0];
    if (propertyMask & dbUtil->dbPutBit) {
        status = dbUtil->putField(
                    channelPutRequester,
                    propertyMask,
                    dbPv->getDbChannel(),
                    pvField);
    } else {
        dbScanLock(dbChannelRecord(dbPv->getDbChannel()));
        status = dbUtil->put(
                    channelPutRequester, propertyMask, dbPv->getDbChannel(), pvField);
        if (process) dbProcess(dbChannelRecord(dbPv->getDbChannel()));
        dbScanUnlock(dbChannelRecord(dbPv->getDbChannel()));
    }
    lock.unlock();
    channelPutRequester->putDone(status, getPtrSelf());
}
Exemplo n.º 3
0
static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) {
    epicsTimeStamp now;
    epicsTimeGetCurrent(&now);

    /* If string or array, must make a copy (to ensure coherence between time and data) */
    if (pfl->type == dbfl_type_rec) {
        dbScanLock(dbChannelRecord(chan));
        dbChannelMakeArrayCopy(pvt, pfl, chan);
        dbScanUnlock(dbChannelRecord(chan));
    }

    pfl->time = now;
    return pfl;
}
Exemplo n.º 4
0
void dbNotifyAdd(dbCommon *pfrom, dbCommon *pto)
{
    processNotify *ppn = pfrom->ppn;
    notifyPvt *pnotifyPvt;

    if (pto->pact)
        return; /*if active it will not be processed*/
    epicsMutexMustLock(pnotifyGlobal->lock);
    if (!pto->ppnr) {/* make sure record has a processNotifyRecord*/
        pto->ppnr = dbCalloc(1, sizeof(processNotifyRecord));
        pto->ppnr->precord = pto;
        ellInit(&pto->ppnr->restartList);
    }
    assert(ppn);
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    if (!pto->ppn &&
        (pnotifyPvt->state == notifyProcessInProgress) &&
        (pto != dbChannelRecord(ppn->chan))) {
        notifyPvt *pnotifyPvt;
        pto->ppn = pfrom->ppn;
        pnotifyPvt = (notifyPvt *) pfrom->ppn->pnotifyPvt;
        ellSafeAdd(&pnotifyPvt->waitList, &pto->ppnr->waitNode);
    }
    epicsMutexUnlock(pnotifyGlobal->lock);
}
Exemplo n.º 5
0
void dbProcessNotify(processNotify *ppn)
{
    struct dbChannel *chan = ppn->chan;
    dbCommon *precord = dbChannelRecord(chan);
    short dbfType = dbChannelFieldType(chan);
    notifyPvt *pnotifyPvt;

    /* Must handle DBF_XXXLINKs as special case.
     * Only dbPutField will change link fields.
     * Also the record is not processed as a result
    */
    ppn->status = notifyOK;
    ppn->wasProcessed = 0;
    if (dbfType>=DBF_INLINK && dbfType<=DBF_FWDLINK) {
        if (ppn->requestType == putProcessRequest ||
            ppn->requestType == putProcessGetRequest) {
            /* Check if puts disabled */
            if (precord->disp && (dbChannelField(ppn->chan) != (void *) &precord->disp)) {
                ppn->putCallback(ppn, putDisabledType);
            } else {
                ppn->putCallback(ppn, putFieldType);
            }
        }
        if (ppn->requestType == processGetRequest ||
            ppn->requestType == putProcessGetRequest) {
                ppn->getCallback(ppn, getFieldType);
            
        }
        ppn->doneCallback(ppn);
        return;
    }
    dbScanLock(precord);
    epicsMutexMustLock(pnotifyGlobal->lock);
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    if (pnotifyPvt && (pnotifyPvt->magic != MAGIC)) {
        printf("dbPutNotify:pnotifyPvt was not initialized\n");
        pnotifyPvt = 0;
    }
    if (pnotifyPvt) {
        assert(pnotifyPvt->state == notifyUserCallbackActive);
        pnotifyPvt->userCallbackWait = 1;
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        epicsEventWait(pnotifyPvt->userCallbackEvent);
        dbScanLock(precord);
        epicsMutexMustLock(pnotifyGlobal->lock);
        notifyCleanup(ppn);
    }
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    assert(!pnotifyPvt);
    notifyInit(ppn);
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    if (!precord->ppnr) {
        /* make sure record has a processNotifyRecord*/
        precord->ppnr = dbCalloc(1, sizeof(processNotifyRecord));
        precord->ppnr->precord = precord;
        ellInit(&precord->ppnr->restartList);
    }
    processNotifyCommon(ppn, precord);
}
Exemplo n.º 6
0
static void notifyCallback(CALLBACK *pcallback)
{
    processNotify *ppn = NULL;
    dbCommon  *precord;
    notifyPvt *pnotifyPvt;

    callbackGetUser(ppn,pcallback);
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    precord = dbChannelRecord(ppn->chan);
    dbScanLock(precord);
    epicsMutexMustLock(pnotifyGlobal->lock);
    assert(precord->ppnr);
    assert(pnotifyPvt->state == notifyRestartCallbackRequested ||
           pnotifyPvt->state == notifyUserCallbackRequested);
    assert(ellCount(&pnotifyPvt->waitList) == 0);
    if (pnotifyPvt->cancelWait) {
        if (pnotifyPvt->state == notifyRestartCallbackRequested) {
            restartCheck(precord->ppnr);
        }
        epicsEventSignal(pnotifyPvt->cancelEvent);
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        return;
    }
    if(pnotifyPvt->state == notifyRestartCallbackRequested) {
        processNotifyCommon(ppn, precord);
        return;
    }
    /* All done. Clean up and call userCallback */
    pnotifyPvt->state = notifyUserCallbackActive;
    assert(precord->ppn!=ppn);
    callDone(precord, ppn);
}
Exemplo n.º 7
0
void dbNotifyCancel(processNotify *ppn)
{
    dbCommon *precord = dbChannelRecord(ppn->chan);
    notifyState state;
    notifyPvt *pnotifyPvt;

    dbScanLock(precord);
    epicsMutexMustLock(pnotifyGlobal->lock);
    ppn->status = notifyCanceled;
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    if (!pnotifyPvt || pnotifyPvt->state == notifyNotActive) {
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        return;
    }

    state = pnotifyPvt->state;
    switch (state) {
    case notifyUserCallbackRequested:
    case notifyRestartCallbackRequested:
    case notifyUserCallbackActive:
        /* Callback is scheduled or active, wait for it to complete */
        pnotifyPvt->cancelWait = 1;
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        epicsEventWait(pnotifyPvt->cancelEvent);
        epicsMutexMustLock(pnotifyGlobal->lock);
        notifyCleanup(ppn);
        epicsMutexUnlock(pnotifyGlobal->lock);
        return;
    case notifyNotActive:
    	break;
    case notifyWaitForRestart:
        assert(precord->ppn);
        assert(precord->ppn!=ppn);
        ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode);
        break;
    case notifyRestartInProgress:
    case notifyProcessInProgress:
        { /*Take all records out of wait list */
            processNotifyRecord *ppnrWait;

            while ((ppnrWait = (processNotifyRecord *)
	                       ellFirst(&pnotifyPvt->waitList))) {
                ellSafeDelete(&pnotifyPvt->waitList, &ppnrWait->waitNode);
                restartCheck(ppnrWait);
            }
        }
        if (precord->ppn == ppn)
            restartCheck(precord->ppnr);
        break;
    default:
        printf("dbNotify: illegal state for notifyCallback\n");
    }
    pnotifyPvt->state = notifyNotActive;
    notifyCleanup(ppn);
    epicsMutexUnlock(pnotifyGlobal->lock);
    dbScanUnlock(precord);
}
Exemplo n.º 8
0
static void doneCallback(processNotify *ppn)
{
    tpnInfo *ptpnInfo = (tpnInfo *) ppn->usrPvt;
    notifyStatus status = ppn->status;
    const char *pname = dbChannelRecord(ppn->chan)->name;

    if (status == 0)
        printf("tpnCallback '%s': Success\n", pname);
    else
        printf("tpnCallback '%s': Notify status %d\n", pname, (int)status);
    epicsEventSignal(ptpnInfo->callbackDone);
}
Exemplo n.º 9
0
static void doneCallback(processNotify *ppn)
{
    notifyStatus status = ppn->status;
    tpnInfo *ptpnInfo = (tpnInfo *) ppn->usrPvt;
    const char *pname = dbChannelRecord(ppn->chan)->name;

    if (status == 0)
        printf("dbtpnCallback: success record=%s\n", pname);
    else
        printf("%s dbtpnCallback processNotify.status %d\n",
	    pname, (int) status);
    epicsEventSignal(ptpnInfo->callbackDone);
}
Exemplo n.º 10
0
int gft(const char *pname)
{
    char tgf_buffer[MAX_ELEMS*MAX_STRING_SIZE + sizeof(struct dbr_ctrl_double)];
    struct dbChannel *chan;
    struct dbCommon *precord;
    long elements;
    short type;
    int i;

    chan = dbChannel_create(pname);
    if (!chan) {
        printf("Channel couldn't be created\n");
        return 1;
    }

    precord = dbChannelRecord(chan);
    elements = dbChannelElements(chan);
    type = dbChannelExportCAType(chan);

    printf("   Record Name: %s\n", precord->name);
    printf("Record Address: 0x%p\n", precord);
    printf("   Export Type: %d\n", type);
    printf(" Field Address: 0x%p\n", dbChannelField(chan));
    printf("    Field Size: %d\n", dbChannelFieldSize(chan));
    printf("   No Elements: %ld\n", elements);

    if (elements > MAX_ELEMS)
        elements = MAX_ELEMS;

    for (i = 0; i <= LAST_BUFFER_TYPE; i++) {
        if (type == 0) {
            if ((i != DBR_STRING) && (i != DBR_STS_STRING) &&
                (i != DBR_TIME_STRING) && (i != DBR_GR_STRING) &&
                (i != DBR_CTRL_STRING))
                continue;
        }
        if (dbChannel_get(chan, i, tgf_buffer, elements, NULL) < 0)
            printf("\t%s Failed\n", dbr_text[i]);
        else
            ca_dump_dbr(i, elements, tgf_buffer);
    }

    dbChannelDelete(chan);
    return 0;
}
Exemplo n.º 11
0
void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan)
{
    void *p;
    struct dbCommon *prec = dbChannelRecord(chan);

    if (pfl->type != dbfl_type_rec) return;

    pfl->type = dbfl_type_ref;
    pfl->stat = prec->stat;
    pfl->sevr = prec->sevr;
    pfl->time = prec->time;
    pfl->field_type  = chan->addr.field_type;
    pfl->no_elements = chan->addr.no_elements;
    pfl->field_size  = chan->addr.field_size;
    pfl->u.r.dtor = freeArray;
    pfl->u.r.pvt = pvt;
    if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
        p = freeListCalloc(dbchStringFreeList);
    } else {
        p = calloc(pfl->no_elements, pfl->field_size);
    }
    if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL);
    pfl->u.r.field = p;
}
Exemplo n.º 12
0
/*
 * TPF
 * Test put field
 */
int pft(const char *pname, const char *pvalue)
{
    struct dbChannel *chan;
    struct dbCommon *precord;
    long elements;
    short type;
    char buffer[500];
    short shortvalue;
    long longvalue;
    float floatvalue;
    unsigned char charvalue;
    double doublevalue;

    chan = dbChannel_create(pname);
    if (!chan) {
        printf("Channel couldn't be created\n");
        return 1;
    }

    precord = dbChannelRecord(chan);
    elements = dbChannelElements(chan);
    type = dbChannelExportCAType(chan);

    printf("   Record Name: %s\n", precord->name);
    printf("Record Address: 0x%p\n", precord);
    printf("   Export Type: %d\n", type);
    printf(" Field Address: 0x%p\n", dbChannelField(chan));
    printf("    Field Size: %d\n", dbChannelFieldSize(chan));
    printf("   No Elements: %ld\n", elements);

    if (dbChannel_put(chan, DBR_STRING,pvalue, 1) < 0)
        printf("\n\t failed ");
    if (dbChannel_get(chan, DBR_STRING,buffer, 1, NULL) < 0)
        printf("\n\tfailed");
    else
        ca_dump_dbr(DBR_STRING,1, buffer);

    if (type <= DBF_STRING || type == DBF_ENUM)
        return 0;

    if (sscanf(pvalue, "%hd", &shortvalue) == 1) {
        if (dbChannel_put(chan, DBR_SHORT,&shortvalue, 1) < 0)
            printf("\n\t SHORT failed ");
        if (dbChannel_get(chan, DBR_SHORT,buffer, 1, NULL) < 0)
            printf("\n\t SHORT GET failed");
        else
            ca_dump_dbr(DBR_SHORT,1, buffer);
    }
    if (sscanf(pvalue, "%ld", &longvalue) == 1) {
        if (dbChannel_put(chan, DBR_LONG,&longvalue, 1) < 0)
            printf("\n\t LONG failed ");
        if (dbChannel_get(chan, DBR_LONG,buffer, 1, NULL) < 0)
            printf("\n\t LONG GET failed");
        else
            ca_dump_dbr(DBR_LONG,1, buffer);
    }
    if (epicsScanFloat(pvalue, &floatvalue) == 1) {
        if (dbChannel_put(chan, DBR_FLOAT,&floatvalue, 1) < 0)
            printf("\n\t FLOAT failed ");
        if (dbChannel_get(chan, DBR_FLOAT,buffer, 1, NULL) < 0)
            printf("\n\t FLOAT GET failed");
        else
            ca_dump_dbr(DBR_FLOAT,1, buffer);
    }
    if (epicsScanFloat(pvalue, &floatvalue) == 1) {
        doublevalue = floatvalue;
        if (dbChannel_put(chan, DBR_DOUBLE,&doublevalue, 1) < 0)
            printf("\n\t DOUBLE failed ");
        if (dbChannel_get(chan, DBR_DOUBLE,buffer, 1, NULL) < 0)
            printf("\n\t DOUBLE GET failed");
        else
            ca_dump_dbr(DBR_DOUBLE,1, buffer);
    }
    if (sscanf(pvalue, "%hd", &shortvalue) == 1) {
        charvalue = (unsigned char) shortvalue;
        if (dbChannel_put(chan, DBR_CHAR,&charvalue, 1) < 0)
            printf("\n\t CHAR failed ");
        if (dbChannel_get(chan, DBR_CHAR,buffer, 1, NULL) < 0)
            printf("\n\t CHAR GET failed");
        else
            ca_dump_dbr(DBR_CHAR,1, buffer);
    }
    if (sscanf(pvalue, "%hd", &shortvalue) == 1) {
        if (dbChannel_put(chan, DBR_ENUM,&shortvalue, 1) < 0)
            printf("\n\t ENUM failed ");
        if (dbChannel_get(chan, DBR_ENUM,buffer, 1, NULL) < 0)
            printf("\n\t ENUM GET failed");
        else
            ca_dump_dbr(DBR_ENUM,1, buffer);
    }
    printf("\n");
    dbChannelDelete(chan);
    return (0);
}
Exemplo n.º 13
0
int dbNotifyDump(void)
{
    epicsMutexLockStatus lockStatus;
    dbRecordType *pdbRecordType;
    processNotify *ppnRestart;
    processNotifyRecord *ppnr;
    int itry;

    for (itry = 0; itry < 100; itry++) {
        lockStatus = epicsMutexTryLock(pnotifyGlobal->lock);
        if (lockStatus == epicsMutexLockOK)
            break;
        epicsThreadSleep(.05);
    }

    for (pdbRecordType = (dbRecordType *) ellFirst(&pdbbase->recordTypeList);
         pdbRecordType;
         pdbRecordType = (dbRecordType *) ellNext(&pdbRecordType->node)) {
        dbRecordNode *pdbRecordNode;

        for (pdbRecordNode = (dbRecordNode *) ellFirst(&pdbRecordType->recList);
             pdbRecordNode;
             pdbRecordNode = (dbRecordNode *) ellNext(&pdbRecordNode->node)) {
            dbCommon *precord = pdbRecordNode->precord;
            processNotify *ppn;
            notifyPvt *pnotifyPvt;

            if (!precord->name[0] || pdbRecordNode->flags & DBRN_FLAGS_ISALIAS)
                continue;
            ppn = precord->ppn;
            if (!ppn || !precord->ppnr)
                continue;
            if (dbChannelRecord(precord->ppn->chan) != precord)
                continue;

            pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
            printf("%s state %d ppn %p\n  waitList\n",
                precord->name, pnotifyPvt->state, (void*) ppn);
            ppnr = (processNotifyRecord *) ellFirst(&pnotifyPvt->waitList);
            while (ppnr) {
                printf("    %s pact %d\n",
                    ppnr->precord->name, ppnr->precord->pact);
                ppnr = (processNotifyRecord *) ellNext(&ppnr->waitNode.node);
            }
            ppnr = precord->ppnr;
            if (ppnr)  {
                ppnRestart = (processNotify *)ellFirst(
                    &precord->ppnr->restartList);
                if (ppnRestart)
		    printf("%s restartList\n", precord->name);
                while (ppnRestart) {
                    printf("    %s\n", dbChannelRecord(ppnRestart->chan)->name);
                    ppnRestart = (processNotify *) ellNext(
                        &ppnRestart->restartNode.node);
                }
            }
        }
    }
    if (lockStatus == epicsMutexLockOK)
        epicsMutexUnlock(pnotifyGlobal->lock);
    return 0;
}
Exemplo n.º 14
0
/* 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;
}