This is Unofficial EPICS BASE Doxygen Site
lnkState.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2017 UChicago Argonne LLC, as Operator of Argonne
3 * National Laboratory.
4 * EPICS BASE is distributed subject to a Software License Agreement found
5 * in file LICENSE that is included with this distribution.
6 \*************************************************************************/
7 /* lnkState.c */
8 
9 /* Usage:
10  * {state:green}
11  */
12 
13 #include <string.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <ctype.h>
17 
18 #include "alarm.h"
19 #include "dbDefs.h"
20 #include "errlog.h"
21 #include "epicsAssert.h"
22 #include "epicsString.h"
23 #include "epicsTypes.h"
24 #include "dbAccessDefs.h"
25 #include "dbCommon.h"
26 #include "dbConvertFast.h"
27 #include "dbLink.h"
28 #include "dbJLink.h"
29 #include "dbStaticLib.h"
30 #include "dbStaticPvt.h"
31 #include "dbState.h"
32 #include "recGbl.h"
33 #include "epicsExport.h"
34 
35 
36 typedef long (*FASTCONVERT)();
37 
38 typedef struct state_link {
39  jlink jlink; /* embedded object */
40  char *name;
41  short val;
42  short invert;
43  dbStateId state;
44 } state_link;
45 
46 static lset lnkState_lset;
47 
48 
49 /*************************** jlif Routines **************************/
50 
51 static jlink* lnkState_alloc(short dbfType)
52 {
53  state_link *slink;
54 
55  if (dbfType == DBF_FWDLINK) {
56  errlogPrintf("lnkState: DBF_FWDLINK not supported\n");
57  return NULL;
58  }
59 
60  slink = calloc(1, sizeof(struct state_link));
61  if (!slink) {
62  errlogPrintf("lnkState: calloc() failed.\n");
63  return NULL;
64  }
65 
66  slink->name = NULL;
67  slink->state = NULL;
68  slink->invert = 0;
69  slink->val = 0;
70 
71  return &slink->jlink;
72 }
73 
74 static void lnkState_free(jlink *pjlink)
75 {
76  state_link *slink = CONTAINER(pjlink, struct state_link, jlink);
77 
78  free(slink->name);
79  free(slink);
80 }
81 
82 static jlif_result lnkState_string(jlink *pjlink, const char *val, size_t len)
83 {
84  state_link *slink = CONTAINER(pjlink, struct state_link, jlink);
85 
86  if (len > 1 && val[0] == '!') {
87  slink->invert = 1;
88  val++; len--;
89  }
90 
91  slink->name = epicsStrnDup(val, len);
92  return jlif_continue;
93 }
94 
95 static struct lset* lnkState_get_lset(const jlink *pjlink)
96 {
97  return &lnkState_lset;
98 }
99 
100 static void lnkState_report(const jlink *pjlink, int level, int indent)
101 {
102  state_link *slink = CONTAINER(pjlink, struct state_link, jlink);
103 
104  printf("%*s'state': \"%s\" = %s%s\n", indent, "",
105  slink->name, slink->invert ? "! " : "", slink->val ? "TRUE" : "FALSE");
106 }
107 
108 /*************************** lset Routines **************************/
109 
110 static void lnkState_open(struct link *plink)
111 {
112  state_link *slink = CONTAINER(plink->value.json.jlink,
113  struct state_link, jlink);
114 
115  slink->state = dbStateCreate(slink->name);
116 }
117 
118 static void lnkState_remove(struct dbLocker *locker, struct link *plink)
119 {
120  state_link *slink = CONTAINER(plink->value.json.jlink,
121  struct state_link, jlink);
122 
123  free(slink->name);
124  free(slink);
125 
126  plink->value.json.jlink = NULL;
127 }
128 
129 static int lnkState_getDBFtype(const struct link *plink)
130 {
131  return DBF_SHORT;
132 }
133 
134 static long lnkState_getElements(const struct link *plink, long *nelements)
135 {
136  *nelements = 1;
137  return 0;
138 }
139 
140 static long lnkState_getValue(struct link *plink, short dbrType, void *pbuffer,
141  long *pnRequest)
142 {
143  state_link *slink = CONTAINER(plink->value.json.jlink,
144  struct state_link, jlink);
145  FASTCONVERT conv;
146 
147  if(INVALID_DB_REQ(dbrType))
148  return S_db_badDbrtype;
149 
150  conv = dbFastPutConvertRoutine[DBR_SHORT][dbrType];
151 
152  slink->val = slink->invert ^ dbStateGet(slink->state);
153  return conv(&slink->val, pbuffer, NULL);
154 }
155 
156 static long lnkState_putValue(struct link *plink, short dbrType,
157  const void *pbuffer, long nRequest)
158 {
159  state_link *slink = CONTAINER(plink->value.json.jlink,
160  struct state_link, jlink);
161  short val;
162  const char *pstr;
163 
164  if (nRequest == 0)
165  return 0;
166 
167  switch(dbrType) {
168  case DBR_CHAR:
169  case DBR_UCHAR:
170  val = !! *(const epicsInt8 *) pbuffer;
171  break;
172 
173  case DBR_SHORT:
174  case DBR_USHORT:
175  val = !! *(const epicsInt16 *) pbuffer;
176  break;
177 
178  case DBR_LONG:
179  case DBR_ULONG:
180  val = !! *(const epicsInt32 *) pbuffer;
181  break;
182 
183  case DBR_INT64:
184  case DBR_UINT64:
185  val = !! *(const epicsInt64 *) pbuffer;
186  break;
187 
188  case DBR_FLOAT:
189  val = !! *(const epicsFloat32 *) pbuffer;
190  break;
191 
192  case DBR_DOUBLE:
193  val = !! *(const epicsFloat64 *) pbuffer;
194  break;
195 
196  case DBR_STRING: /* Only "" and "0" are FALSE */
197  pstr = (const char *) pbuffer;
198  val = (pstr[0] != 0) && ((pstr[0] != '0') || (pstr[1] != 0));
199  break;
200 
201  default:
202  return S_db_badDbrtype;
203  }
204  slink->val = val;
205 
206  val ^= slink->invert;
207  (val ? dbStateSet : dbStateClear)(slink->state);
208 
209  return 0;
210 }
211 
212 /************************* Interface Tables *************************/
213 
214 static lset lnkState_lset = {
215  0, 0, /* not constant, always connected */
216  lnkState_open, lnkState_remove,
217  NULL, NULL, NULL,
218  NULL, lnkState_getDBFtype, lnkState_getElements,
219  lnkState_getValue,
220  NULL, NULL, NULL,
221  NULL, NULL,
222  NULL, NULL,
223  lnkState_putValue, NULL,
224  NULL, NULL
225 };
226 
227 static jlif lnkStateIf = {
228  "state", lnkState_alloc, lnkState_free,
229  NULL, NULL, NULL, NULL, lnkState_string,
230  NULL, NULL, NULL,
231  NULL, NULL,
232  NULL, lnkState_get_lset,
233  lnkState_report, NULL, NULL
234 };
235 epicsExportAddress(jlif, lnkStateIf);
#define DBR_CHAR
Definition: db_access.h:74
#define DBR_STRING
Definition: db_access.h:69
double epicsFloat64
Definition: epicsTypes.h:49
An EPICS-specific replacement for ANSI C&#39;s assert.
#define CONTAINER(ptr, structure, member)
Find parent object from a member pointer.
Definition: dbDefs.h:66
#define DBR_USHORT
Definition: dbFldTypes.h:80
#define DBR_FLOAT
Definition: db_access.h:72
#define DBR_INT64
Definition: dbFldTypes.h:83
#define printf
Definition: epicsStdio.h:41
#define INVALID_DB_REQ(x)
Definition: db_access.h:115
#define NULL
Definition: catime.c:38
epicsExportAddress(jlif, lnkStateIf)
dbfType
Definition: dbFldTypes.h:24
Miscellaneous macro definitions.
#define DBR_UINT64
Definition: dbFldTypes.h:84
long(* FASTCONVERT)()
Definition: lnkState.c:36
#define DBR_UCHAR
Definition: dbFldTypes.h:78
float epicsFloat32
Definition: epicsTypes.h:48
#define DBR_DOUBLE
Definition: db_access.h:76
#define DBR_SHORT
Definition: db_access.h:71
char epicsInt8
Definition: epicsTypes.h:38
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
char * epicsStrnDup(const char *s, size_t len)
Definition: epicsString.c:224
char * pbuffer
Definition: errlog.c:85
#define DBR_LONG
Definition: db_access.h:75
struct state_link state_link
short epicsInt16
Definition: epicsTypes.h:40
struct json_link json
Definition: link.h:177
#define DBR_ULONG
Definition: dbFldTypes.h:82
int epicsInt32
Definition: epicsTypes.h:42
long long epicsInt64
Definition: epicsTypes.h:44
Exporting IOC objects.