/*************************************************************************\ * Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * SPDX-License-Identifier: EPICS * EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* database access subroutines */ /* * Author: Bob Dalesio * Andrew Johnson */ #include #include #include #include "cadef.h" #include "dbDefs.h" #include "epicsStdio.h" #include "epicsStdlib.h" #include "epicsString.h" #include "errlog.h" #include "epicsEvent.h" #include "db_access_routines.h" #include "dbChannel.h" #include "dbCommon.h" #include "dbNotify.h" #include "db_test.h" #define MAX_ELEMS 10 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; if (!pname) { printf("Usage: gft \"pv_name\"\n"); return -1; } 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; } /* * 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; if (!pname || !pvalue) { printf("Usage: pft \"pv_name\", \"value\"\n"); return -1; } 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); } typedef struct tpnInfo { epicsEventId callbackDone; processNotify *ppn; char buffer[80]; } tpnInfo; static int putCallback(processNotify *ppn,notifyPutType type) { tpnInfo *ptpnInfo = (tpnInfo *)ppn->usrPvt; return db_put_process(ppn, type, DBR_STRING, ptpnInfo->buffer, 1); } 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); } static void tpnThread(void *pvt) { tpnInfo *ptpnInfo = (tpnInfo *) pvt; processNotify *ppn = (processNotify *) ptpnInfo->ppn; dbProcessNotify(ppn); epicsEventWait(ptpnInfo->callbackDone); dbNotifyCancel(ppn); epicsEventDestroy(ptpnInfo->callbackDone); dbChannelDelete(ppn->chan); free(ppn); free(ptpnInfo); } int tpn(const char *pname, const char *pvalue) { struct dbChannel *chan; tpnInfo *ptpnInfo; processNotify *ppn = NULL; if (!pname || !pvalue) { printf("Usage: tpn \"pv_name\", \"value\"\n"); return -1; } chan = dbChannel_create(pname); if (!chan) { printf("Channel couldn't be created\n"); return 1; } ppn = calloc(1, sizeof(processNotify)); if (!ppn) { printf("calloc failed\n"); dbChannelDelete(chan); return -1; } ppn->requestType = putProcessRequest; ppn->chan = chan; ppn->putCallback = putCallback; ppn->doneCallback = doneCallback; ptpnInfo = calloc(1, sizeof(tpnInfo)); if (!ptpnInfo) { printf("calloc failed\n"); free(ppn); dbChannelDelete(chan); return -1; } ptpnInfo->ppn = ppn; ptpnInfo->callbackDone = epicsEventCreate(epicsEventEmpty); strncpy(ptpnInfo->buffer, pvalue, 80); ptpnInfo->buffer[79] = 0; ppn->usrPvt = ptpnInfo; epicsThreadCreate("tpn", epicsThreadPriorityHigh, epicsThreadGetStackSize(epicsThreadStackMedium), tpnThread, ptpnInfo); return 0; }