DBR_GR_ENUM monitor updates dont contain enum strings
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
EPICS Base |
Fix Released
|
High
|
Jeff Hill |
Bug Description
From Ken Evans,
There is a problem when using dbr_gr_enum's or dbr_ctrl_enum's
with the Gateway. If you monitor, they have the enum strings the
first time, but not thereafter. The num_str is 0 after the first
monitor callback.
I made a test case:
With the Gateway:
48 krypton:
Nov 08 17:19:10 Search started for evans:bo01
Nov 08 17:19:10 Connection successful
Nov 08 17:19:10 Value is: 0
no_str=2
0 Off
1 On
Nov 08 17:19:10 Value is: 1
no_str=0
Nov 08 17:19:11 Value is: 0
no_str=0
Nov 08 17:19:13 Value is: 1
no_str=0
Nov 08 17:19:14 Value is: 0
no_str=0
Nov 08 17:19:16 Value is: 1
no_str=0
Nov 08 17:19:17 Value is: 0
no_str=0
Nov 08 17:19:19 Value is: 1
no_str=0
Nov 08 17:19:20 Value is: 0
no_str=0
Nov 08 17:19:20 All done after 10 sec
49 krypton:simpleCA>
Direct to the IOC:
45 chiron:
Nov 08 17:22:09 Search started for evans:bo01
Nov 08 17:22:09 Connection successful
Nov 08 17:22:09 Value is: 0
no_str=2
0 Off
1 On
Nov 08 17:22:10 Value is: 1
no_str=2
0 Off
1 On
Nov 08 17:22:11 Value is: 0
no_str=2
0 Off
1 On
Nov 08 17:22:13 Value is: 1
no_str=2
0 Off
1 On
Nov 08 17:22:14 Value is: 0
no_str=2
0 Off
1 On
Nov 08 17:22:16 Value is: 1
no_str=2
0 Off
1 On
Nov 08 17:22:17 Value is: 0
no_str=2
0 Off
1 On
Nov 08 17:22:19 All done after 10 sec
46 chiron:simpleCA>
This is coming from the callback:
/******
static void valueChangedCB(
{
/* Print the value */
if(args.status == ECA_NORMAL && args.dbr) {
int i;
struct dbr_gr_enum *dbr=(struct dbr_gr_enum *)args.dbr;
printf("%s Value is: %hd\\n"
printf(" no_str=
for(i=0; i < dbr->no_str; i++) {
if(dbr->strs && dbr->strs[i]) {
printf(" %2d %s\\n",
} else {
printf(" %2d NA\\n",i);
}
}
} else {
printf("%s Bad value\\
}
}
The whole file is:
--testenum.
/* Test dbr_gr_enum problem */
#define TIMEOUT 10.0
#define SCA_OK 1
#define SCA_ERR 0
#define MAX_STRING 40
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <cadef.h>
/* Function prototypes */
int main(int argc, char **argv);
static void connectionChang
static void valueChangedCB(
static char *timeStamp(void);
static int parseCommand(int argc, char **argv);
static void usage(void);
/* Global variables */
int pvSpecified=0;
char name[MAX_STRING];
time_t curTime, startTime;
double timeout=TIMEOUT;
evid pEv;
/******
int main(int argc, char **argv)
{
int stat;
chid pCh;
/* Parse the command line */
if(
if(
printf("No PV specified\\n");
exit(1);
}
/* Initialize */
#if 0
stat=
#else
stat=
#endif
if(stat != ECA_NORMAL) {
printf(
exit(1);
}
/* Search */
stat=
CA_
if(stat != ECA_NORMAL) {
printf(
exit(1);
}
printf("%s Search started for %s\\n",
/* Wait */
startTime=
ca_
printf("%s All done after %ld sec\\n"
curTime-
/* Clear the channel */
stat=
if(stat != ECA_NORMAL) {
printf(
}
/* Exit */
ca_
return(0);
}
/******
static void connectionChang
{
chid pCh=args.chid;
int stat;
/* Branch depending on the state */
switch (ca_state(pCh)) {
case cs_conn:
printf("%s Connection successful\
if(ca_
printf("This program only works with ENUM process variables\\n");
exit(1);
}
stat=ca_
DBE_
valueChanged
if(stat != ECA_NORMAL) {
printf(
exit(1);
}
break;
case cs_never_conn:
printf("%s Cannot connect\
break;
case cs_prev_conn:
printf("%s Lost connection\
break;
case cs_closed:
printf("%s Connection closed\
break;
}
}
/******
static void valueChangedCB(
{
/* Print the value */
if(args.status == ECA_NORMAL && args.dbr) {
int i;
struct dbr_gr_enum *dbr=(struct dbr_gr_enum *)args.dbr;
printf("%s Value is: %hd\\n"
printf(" no_str=
for(i=0; i < dbr->no_str; i++) {
if(dbr->strs && dbr->strs[i]) {
printf(" %2d %s\\n",
} else {
printf(" %2d NA\\n",i);
}
}
} else {
printf("%s Bad value\\
}
}
/******
static char *timeStamp(void)
/* Gets current time and puts it in a static array
* The calling program should copy it to a safe place
* e.g. strcpy(
{
static char timeStampStr[16];
time_t now;
struct tm *tblock;
time(&now);
curTime=now;
tblock=
strftime(
return timeStampStr;
}
/******
static int parseCommand(int argc, char **argv)
{
int i;
for(i=1; i < argc; i++) {
if (argv[i][0] == '-') {
switch(
case 'h':
usage();
exit(0);
case 't':
timeout=
break;
default:
fprintf(
usage();
return SCA_ERR;
}
} else {
if(
strncpy(
name[
pvSpecified=1;
} else {
printf(
usage();
return SCA_ERR;
}
}
}
return SCA_OK;
}
/******
static void usage(void)
{
printf(
"\\nUsage: testenum [Options] pvname\\n"
" Connects to pvname and monitors the value\\n"
"\\n"
" Options:\\n"
" -h help This message\\n"
" -t float Timeout in seconds (Default: %g)\\n",TIMEOUT);
}
Original Mantis Bug: mantis-159
http://
patch was committed to src/gdd/dbMapper.cc
fixed in R3.14.7