Files
pcas/src/libCom/sydSubrCF.c
1991-08-21 15:15:33 +00:00

383 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* $Id$
* Author: Roger A. Cole
* Date: 12-04-90
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .00 12-04-90 rac initial version
* .01 06-18-91 rac installed in SCCS
* .02 06-19-91 rac replace <fields.h> with <alarm.h>
* .03 08-06-91 rac allow specifying file name
*
* make options
* -DvxWorks makes a version for VxWorks
* -DNDEBUG don't compile assert() checking
* -DDEBUG compile various debug code, including checks on
* malloc'd memory
*/
/*+/mod***********************************************************************
* TITLE sydSubrCF.c - acquire synchronous samples from `by channel' AR file
*
* DESCRIPTION
*
*-***************************************************************************/
#include <genDefs.h>
#define SYD_PRIVATE
#include <sydDefs.h>
#include <alarm.h>
#ifndef INC_arAccessLib_h
# include <arAccessLib.h>
#endif
#ifndef INC_tsDefs_h
# include <tsDefs.h>
#endif
#ifndef INC_arCS_h
# include <arCS.h>
#endif
#ifndef INCLcadefh
# include <cadef.h>
#endif
#ifdef vxWorks
# include <vxWorks.h>
# include <ioLib.h> /* for O_RDWR and O_RDONLY definitions */
# include <stdioLib.h>
#else
# include <stdio.h>
# include <sys/file.h> /* for O_RDWR and O_RDONLY definitions */
#endif
long sydCFFunc();
long sydCFFuncGetGR();
/*+/subr**********************************************************************
* NAME sydOpenCF - open an AR `by channel' file for retrieval
*
* DESCRIPTION
* Open an archiver `by channel' file for synchronous data retrieval.
*
* RETURNS
* S_syd_OK, or
* S_syd_ERROR, or
* other code indicating error
*
* BUGS
* o text
*
* SEE ALSO
*
* EXAMPLE
*
*-*/
long
sydOpenCF(ppSspec, filePath)
SYD_SPEC **ppSspec; /* O pointer to synchronous set spec pointer */
char *filePath; /* I path name for `by channel' archive file */
{
long stat;
assert(ppSspec != NULL);
if ((*ppSspec = (SYD_SPEC *)GenMalloc(sizeof(SYD_SPEC))) == NULL)
return S_syd_noMem;
(*ppSspec)->pFunc = sydCFFunc;
(*ppSspec)->type = SYD_TY_CF;
if ((stat = sydCFFunc(*ppSspec, NULL, SYD_FC_INIT, filePath)) != S_syd_OK){
GenFree((char *)*ppSspec);
*ppSspec = NULL;
return stat;
}
(*ppSspec)->nInBufs = 2;
return sydOpen(ppSspec);
}
/*+/subr**********************************************************************
* NAME sydCFFunc - handle "by channel" data file interactions
*
* DESCRIPTION
*
* sydCFFunc(pSspec, NULL, SYD_FC_INIT, filePath) open "by channel" file
* sydCFFunc(pSspec, pSChan, SYD_FC_OPEN, NULL) chanName already in pSChan
* sydCFFunc(pSspec, pSChan, SYD_FC_READ, NULL)
* sydCFFunc(pSspec, NULL, SYD_FC_READ_SYNC, NULL) sync "by channel" file
* sydCFFunc(pSspec, pSChan, SYD_FC_POSITION, &stamp)
* sydCFFunc(pSspec, pSChan, SYD_FC_CLOSE, NULL)
* sydCFFunc(pSspec, NULL, SYD_FC_FILEINFO, outFile)
* sydCFFunc(pSspec, NULL, SYD_FC_WRAPUP, NULL) close "by channel" file
*
* RETURNS
* S_syd_OK, or
* S_syd_EOF, or
* other code indicating error
*
* BUGS
* o doesn't detect or report EOF
* o doesn't do anything (or even detect) overwriting un-sampled
* buffers (for SYD_FC_READ)
*
* SEE ALSO
*
* EXAMPLE
*
*-*/
long
sydCFFunc(pSspec, pStruct, funcCode, pArg)
SYD_SPEC *pSspec; /* IO pointer to synchronous set spec */
void *pStruct; /* IO pointer to data struct used by funcCode */
enum sydFuncCode funcCode;/* I function code */
void *pArg; /* I pointer to arg, as required by funcCode */
{
SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */
AR_CHAN_DESC *pChanDesc; /* pointer to chanDesc for channel */
AR_CF_DESC *pCfDesc; /* pointer to cfDesc for channel file */
long retStat=S_syd_OK;
long stat, inStatus;
int i;
pSChan = (SYD_CHAN *)pStruct;
if (pSChan != NULL)
pChanDesc = (AR_CHAN_DESC *)pSChan->pHandle;
if (pSspec != NULL)
pCfDesc = (AR_CF_DESC *)pSspec->pHandle;
if (funcCode == SYD_FC_INIT) {
pCfDesc = arCFOpen("arChan/arChanData.bin", O_RDONLY);
if (pCfDesc == NULL) {
(void)printf("couldn't open arChan/arChanData.bin\n");
retStat = S_syd_ERROR;
}
pSspec->pHandle = (void *)pCfDesc;
}
else if (funcCode == SYD_FC_OPEN) {
pChanDesc = arCFChanOpen(pCfDesc, pSChan->name, O_RDONLY);
if (pChanDesc == NULL)
retStat = S_syd_chanNotFound;
else {
pSChan->pHandle = (void *)pChanDesc;
pSChan->dbfType = ArCFChanFieldType(pChanDesc);
pSChan->dbrType = dbf_type_to_DBR_TIME(pSChan->dbfType);
pSChan->elCount = ArCFChanElementCount(pChanDesc);
sydCFFuncGetGR(pSChan, pChanDesc);
}
}
else if (funcCode == SYD_FC_READ) {
i = NEXT_INBUF(pSChan, pSChan->lastInBuf);
pSChan->inStatus[i] = inStatus = SYD_B_EMPTY;
while (pSChan->inStatus[i] == SYD_B_EMPTY) {
stat = arCFChanRead(pChanDesc,
pSChan->dbrType, pSChan->pInBuf[i], pSChan->elCount);
if (stat == OK) {
if (inStatus == SYD_B_EMPTY)
pSChan->inStatus[i] = SYD_B_FULL;
else
pSChan->inStatus[i] = SYD_B_RESTART;
}
else if ((pChanDesc->flags & AR_CDESC_EOF) != 0)
pSChan->inStatus[i] = SYD_B_EOF;
else if ((pChanDesc->flags & AR_CDESC_BEGIN) != 0)
inStatus = SYD_B_RESTART;
}
pSChan->lastInBuf = i;
if (pSChan->firstInBuf < 0)
pSChan->firstInBuf = i;
}
else if (funcCode == SYD_FC_READ_SYNC) {
/* synchronize file buf in memory with data on disk */
stat = arCFSyncRead(pCfDesc);
if (stat != OK)
retStat = S_syd_ERROR;
}
else if (funcCode == SYD_FC_POSITION) {
stat = arCFChanPosition(pChanDesc, (TS_STAMP *)pArg);
if (stat != OK) {
if ((pChanDesc->flags & AR_CDESC_EOF) == 0) {
(void)printf("error for %s\n", pSChan->name);
assertAlways(0);
}
}
}
else if (funcCode == SYD_FC_CLOSE) {
if (pSChan->pHandle != NULL)
retStat = arCFChanClose((AR_CHAN_DESC **)&pSChan->pHandle);
}
else if (funcCode == SYD_FC_FILEINFO) {
TS_STAMP oldestStamp, newestStamp;
char oldestStampText[28], newestStampText[28];
char name[db_name_dim];
int j;
assert(pCfDesc != NULL);
if (ArB0MIHead(pCfDesc) != 0) {
AR_MI_BUF *pMICurrent;
AR_CHAN_HDR *pChanHdr;
assert(ArB0MIHead(pCfDesc) > 0);
assert(ArB0MITail(pCfDesc) > 0);
assert(ArB0MINblk(pCfDesc) > 0);
assert(pCfDesc->pMIHead != NULL);
assert(pCfDesc->pMITail != NULL);
pMICurrent = pCfDesc->pMIHead;
while (pMICurrent != NULL) {
int i;
for (i=0; i<AR_CF_NHDR; i++) {
pChanHdr = &pMICurrent->chanHdr[i];
if (pChanHdr->name[0] != '\0') {
strcpy(name, pChanHdr->name);
j = strlen(name);
if (j > 4) {
if (strncmp(&name[j-4], ".VAL", 4) == 0)
name[j-4] = '\0';
}
oldestStamp.secPastEpoch = pChanHdr->oldestSecPastEpoch;
oldestStamp.nsec = 0;
newestStamp.secPastEpoch = pChanHdr->newestSecPastEpoch;
newestStamp.nsec = 0;
(void)fprintf((FILE *)pArg, "%s %d %s %s %s\n",
name, pChanHdr->elCount,
dbf_type_to_text(pChanHdr->chanType),
tsStampToText(&oldestStamp, TS_TEXT_MMDDYY,
oldestStampText),
tsStampToText(&newestStamp, TS_TEXT_MMDDYY,
newestStampText) );
}
}
pMICurrent = pMICurrent->pNextMI;
}
}
else
(void)fprintf((FILE *)pArg, "no channels in file\n");
}
else if (funcCode == SYD_FC_WRAPUP) {
if (pCfDesc != NULL) {
if ((stat = arCFClose(&pCfDesc)) != OK) {
(void)printf("trouble closing arChan/arChanData.bin\n");
retStat = S_syd_ERROR;
}
}
pSspec->pHandle = NULL;
}
return retStat;
}
long
sydCFFuncGetGR(pSChan, pChanDesc)
SYD_CHAN *pSChan; /* pointer to syncSet channel descriptor */
AR_CHAN_DESC *pChanDesc; /* pointer to chanDesc for channel */
{
int i;
if (pSChan->dbrType == DBR_TIME_FLOAT) {
#define FLT_SRC ArCDChanHdr(pChanDesc).graphics.floatGr
#define FLT_DEST pSChan->grBuf.gfltval
FLT_DEST.status = NO_ALARM;
FLT_DEST.severity = NO_ALARM;
FLT_DEST.precision = FLT_SRC.precision;
(void)strcpy(FLT_DEST.units, FLT_SRC.units);
FLT_DEST.upper_disp_limit = FLT_SRC.upDispLim;
FLT_DEST.lower_disp_limit = FLT_SRC.lowDispLim;
FLT_DEST.upper_alarm_limit = FLT_SRC.upAlmLim;
FLT_DEST.lower_alarm_limit = FLT_SRC.lowAlmLim;
FLT_DEST.upper_warning_limit = FLT_SRC.upWarnLim;
FLT_DEST.lower_warning_limit = FLT_SRC.lowWarnLim;
pSChan->dbrGrType = DBR_GR_FLOAT;
}
else if (pSChan->dbrType == DBR_TIME_SHORT) {
#define SHRT_SRC ArCDChanHdr(pChanDesc).graphics.shortGr
#define SHRT_DEST pSChan->grBuf.gshrtval
SHRT_DEST.status = NO_ALARM;
SHRT_DEST.severity = NO_ALARM;
(void)strcpy(SHRT_DEST.units, SHRT_SRC.units);
SHRT_DEST.upper_disp_limit = SHRT_SRC.upDispLim;
SHRT_DEST.lower_disp_limit = SHRT_SRC.lowDispLim;
SHRT_DEST.upper_alarm_limit = SHRT_SRC.upAlmLim;
SHRT_DEST.lower_alarm_limit = SHRT_SRC.lowAlmLim;
SHRT_DEST.upper_warning_limit = SHRT_SRC.upWarnLim;
SHRT_DEST.lower_warning_limit = SHRT_SRC.lowWarnLim;
pSChan->dbrGrType = DBR_GR_SHORT;
}
else if (pSChan->dbrType == DBR_TIME_DOUBLE) {
#define DBL_SRC ArCDChanHdr(pChanDesc).graphics.doubleGr
#define DBL_DEST pSChan->grBuf.gdblval
DBL_DEST.status = NO_ALARM;
DBL_DEST.severity = NO_ALARM;
DBL_DEST.precision = DBL_SRC.precision;
(void)strcpy(DBL_DEST.units, DBL_SRC.units);
DBL_DEST.upper_disp_limit = DBL_SRC.upDispLim;
DBL_DEST.lower_disp_limit = DBL_SRC.lowDispLim;
DBL_DEST.upper_alarm_limit = DBL_SRC.upAlmLim;
DBL_DEST.lower_alarm_limit = DBL_SRC.lowAlmLim;
DBL_DEST.upper_warning_limit = DBL_SRC.upWarnLim;
DBL_DEST.lower_warning_limit = DBL_SRC.lowWarnLim;
pSChan->dbrGrType = DBR_GR_DOUBLE;
}
else if (pSChan->dbrType == DBR_TIME_LONG) {
#define LNG_SRC ArCDChanHdr(pChanDesc).graphics.longGr
#define LNG_DEST pSChan->grBuf.glngval
LNG_DEST.status = NO_ALARM;
LNG_DEST.severity = NO_ALARM;
(void)strcpy(LNG_DEST.units, LNG_SRC.units);
LNG_DEST.upper_disp_limit = LNG_SRC.upDispLim;
LNG_DEST.lower_disp_limit = LNG_SRC.lowDispLim;
LNG_DEST.upper_alarm_limit = LNG_SRC.upAlmLim;
LNG_DEST.lower_alarm_limit = LNG_SRC.lowAlmLim;
LNG_DEST.upper_warning_limit = LNG_SRC.upWarnLim;
LNG_DEST.lower_warning_limit = LNG_SRC.lowWarnLim;
pSChan->dbrGrType = DBR_GR_LONG;
}
else if (pSChan->dbrType == DBR_TIME_STRING) {
#define STR_DEST pSChan->grBuf.gstrval
STR_DEST.status = NO_ALARM;
STR_DEST.severity = NO_ALARM;
pSChan->dbrGrType = DBR_GR_STRING;
}
else if (pSChan->dbrType == DBR_TIME_ENUM) {
#define ENM_SRC ArCDChanHdr(pChanDesc).graphics.enumGr
#define ENM_DEST pSChan->grBuf.genmval
ENM_DEST.status = NO_ALARM;
ENM_DEST.severity = NO_ALARM;
ENM_DEST.no_str = ArCFChanNStates(pChanDesc);
for (i=0; i<ENM_DEST.no_str; i++)
(void)strcpy(ENM_DEST.strs[i], ArCFChanStates(pChanDesc)[i]);
pSChan->dbrGrType = DBR_GR_ENUM;
}
else if (pSChan->dbrType == DBR_TIME_CHAR) {
#define CHR_SRC ArCDChanHdr(pChanDesc).graphics.charGr
#define CHR_DEST pSChan->grBuf.gchrval
CHR_DEST.status = NO_ALARM;
CHR_DEST.severity = NO_ALARM;
(void)strcpy(CHR_DEST.units, CHR_SRC.units);
CHR_DEST.upper_disp_limit = CHR_SRC.upDispLim;
CHR_DEST.lower_disp_limit = CHR_SRC.lowDispLim;
CHR_DEST.upper_alarm_limit = CHR_SRC.upAlmLim;
CHR_DEST.lower_alarm_limit = CHR_SRC.lowAlmLim;
CHR_DEST.upper_warning_limit = CHR_SRC.upWarnLim;
CHR_DEST.lower_warning_limit = CHR_SRC.lowWarnLim;
pSChan->dbrGrType = DBR_GR_CHAR;
}
return S_syd_OK;
}