EPICS Base  7.0.6.1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dbChannel.h
1 /*************************************************************************\
2 * Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2010 Brookhaven National Laboratory.
5 * Copyright (c) 2010 Helmholtz-Zentrum Berlin
6 * fuer Materialien und Energie GmbH.
7 * SPDX-License-Identifier: EPICS
8 * EPICS BASE is distributed subject to a Software License Agreement found
9 * in file LICENSE that is included with this distribution.
10 \*************************************************************************/
11 
12 /*
13  * Author: Andrew Johnson <[email protected]>
14  * Ralph Lange <[email protected]>
15  */
16 
17 #ifndef INC_dbChannel_H
18 #define INC_dbChannel_H
19 
20 #include "dbDefs.h"
21 #include "dbAddr.h"
22 #include "ellLib.h"
23 #include "epicsTypes.h"
24 #include "errMdef.h"
25 #include "db_field_log.h"
26 #include "dbEvent.h"
27 #include "dbCoreAPI.h"
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /*
34  * event subscription
35  */
36 typedef struct evSubscrip {
37  ELLNODE node;
38  struct dbChannel *chan;
39  EVENTFUNC *user_sub;
40  void *user_arg;
41  struct event_que *ev_que;
42  db_field_log **pLastLog;
43  unsigned long npend; /* n times this event is on the queue */
44  unsigned long nreplace; /* n times replacing event on the queue */
45  unsigned char select;
46  char useValque;
47  char callBackInProgress;
48  char enabled;
49 } evSubscrip;
50 
51 typedef struct chFilter chFilter;
52 
53 /* A dbChannel points to a record field, and can have multiple filters */
54 typedef struct dbChannel {
55  const char *name;
56  dbAddr addr; /* address structure for record/field */
57  long final_no_elements; /* final number of elements (arrays) */
58  short final_field_size; /* final size of element */
59  short final_type; /* final type of database field */
60  ELLLIST filters; /* list of filters as created from JSON */
61  ELLLIST pre_chain; /* list of filters to be called pre-event-queue */
62  ELLLIST post_chain; /* list of filters to be called post-event-queue */
63 } dbChannel;
64 
65 /* Prototype for the channel event function that is called in filter stacks
66  *
67  * When invoked the scan lock for the record associated with 'chan' _may_ be locked.
68  * Unless dbfl_has_copy(pLog), it must call dbScanLock before accessing the data,
69  * as this indicates the data is still owned by the record.
70  *
71  * This function has ownership of the field log pLog, if it wishes to discard
72  * this update it should free the field log with db_delete_field_log() and
73  * then return NULL.
74  */
75 typedef db_field_log* (chPostEventFunc)(void *pvt, dbChannel *chan, db_field_log *pLog);
76 
77 /* Return values from chFilterIf->parse_* routines: */
78 typedef enum {
79  parse_stop, parse_continue
80 } parse_result;
81 
82 /* These routines must be implemented by each filter plug-in */
83 typedef struct chFilterIf {
84  /* cleanup pointer passed to dbRegisterFilter().
85  * Called during DB shutdown
86  */
87  void (* priv_free)(void *puser);
88  /* Parsing event handlers: */
89  parse_result (* parse_start)(chFilter *filter);
90  /* If parse_start() returns parse_continue for a filter, one of
91  * parse_abort() or parse_end() will later be called for that same
92  * filter.
93  */
94  void (* parse_abort)(chFilter *filter);
95  /* If parse_abort() is called it should release any memory allocated
96  * for this filter; no further parse_...() calls will be made;
97  */
98  parse_result (* parse_end)(chFilter *filter);
99  /* If parse_end() returns parse_stop it should have released any
100  * memory allocated for this filter; no further parse_...() calls will
101  * be made in this case.
102  */
103 
104  parse_result (* parse_null)(chFilter *filter);
105  parse_result (* parse_boolean)(chFilter *filter, int boolVal);
106  parse_result (* parse_integer)(chFilter *filter, long integerVal);
107  parse_result (* parse_double)(chFilter *filter, double doubleVal);
108  parse_result (* parse_string)(chFilter *filter, const char *stringVal,
109  size_t stringLen); /* NB: stringVal is not zero-terminated: */
110 
111  parse_result (* parse_start_map)(chFilter *filter);
112  parse_result (* parse_map_key)(chFilter *filter, const char *key,
113  size_t stringLen); /* NB: key is not zero-terminated: */
114  parse_result (* parse_end_map)(chFilter *filter);
115 
116  parse_result (* parse_start_array)(chFilter *filter);
117  parse_result (* parse_end_array)(chFilter *filter);
118 
119  /* Channel operations: */
120  long (* channel_open)(chFilter *filter);
121  void (* channel_register_pre) (chFilter *filter, chPostEventFunc **cb_out, void **arg_out, db_field_log *probe);
122  void (* channel_register_post)(chFilter *filter, chPostEventFunc **cb_out, void **arg_out, db_field_log *probe);
123  void (* channel_report)(chFilter *filter, int level, const unsigned short indent);
124  void (* channel_close)(chFilter *filter);
125 } chFilterIf;
126 
127 /* A chFilterPlugin holds data for a filter plugin */
128 typedef struct chFilterPlugin {
129  ELLNODE node;
130  const char *name;
131  const chFilterIf *fif;
132  void *puser;
134 
135 /* A chFilter holds data for a single filter instance */
136 struct chFilter {
137  ELLNODE list_node;
138  ELLNODE pre_node;
139  ELLNODE post_node;
140  dbChannel *chan;
141  const chFilterPlugin *plug;
142  chPostEventFunc *pre_func;
143  void *pre_arg;
144  chPostEventFunc *post_func;
145  void *post_arg;
146  void *puser;
147 };
148 
149 struct dbCommon;
150 struct dbFldDes;
151 
152 DBCORE_API void dbChannelInit (void);
153 DBCORE_API void dbChannelExit(void);
154 DBCORE_API long dbChannelTest(const char *name);
155 DBCORE_API dbChannel * dbChannelCreate(const char *name);
156 DBCORE_API long dbChannelOpen(dbChannel *chan);
157 
158 /*Following is also defined in db_convert.h*/
159 DBCORE_API extern unsigned short dbDBRnewToDBRold[];
160 
161 /* In the following macros pChan is dbChannel* */
162 
163 /* evaluates to const char* */
164 #define dbChannelName(pChan) ((pChan)->name)
165 
166 /* evaluates to struct dbCommon* */
167 #define dbChannelRecord(pChan) ((pChan)->addr.precord)
168 
169 /* evaluates to struct dbFldDes* */
170 #define dbChannelFldDes(pChan) ((pChan)->addr.pfldDes)
171 
172 /* evaluates to long */
173 #define dbChannelElements(pChan) ((pChan)->addr.no_elements)
174 
175 /* evaluates to short */
176 #define dbChannelFieldType(pChan) ((pChan)->addr.field_type)
177 
178 /* evaluates to short */
179 #define dbChannelExportType(pChan) ((pChan)->addr.dbr_field_type)
180 
181 /* evaluates to short */
182 #define dbChannelExportCAType(pChan) (dbDBRnewToDBRold[dbChannelExportType(pChan)])
183 
184 /* evaluates to short */
185 #define dbChannelFieldSize(pChan) ((pChan)->addr.field_size)
186 
187 /* evaluates to long */
188 #define dbChannelFinalElements(pChan) ((pChan)->final_no_elements)
189 
190 /* evaluates to short */
191 #define dbChannelFinalFieldType(pChan) ((pChan)->final_type)
192 
193 /* evaluates to short */
194 #define dbChannelFinalCAType(pChan) (dbDBRnewToDBRold[(pChan)->final_type])
195 
196 /* evaluates to short */
197 #define dbChannelFinalFieldSize(pChan) ((pChan)->final_field_size)
198 
199 /* evaluates to short */
200 #define dbChannelSpecial(pChan) ((pChan)->addr.special)
201 
202 /* Channel filters do not get to interpose here since there are many
203  * places where the field pointer is compared with the address of a
204  * specific record field, so they can't modify the pointer value.
205  */
206 /* evaluates to void* */
207 #define dbChannelField(pChan) ((pChan)->addr.pfield)
208 
209 
210 DBCORE_API long dbChannelGet(dbChannel *chan, short type,
211  void *pbuffer, long *options, long *nRequest, void *pfl);
212 DBCORE_API long dbChannelGetField(dbChannel *chan, short type,
213  void *pbuffer, long *options, long *nRequest, void *pfl);
214 DBCORE_API long dbChannelPut(dbChannel *chan, short type,
215  const void *pbuffer, long nRequest);
216 DBCORE_API long dbChannelPutField(dbChannel *chan, short type,
217  const void *pbuffer, long nRequest);
218 DBCORE_API void dbChannelShow(dbChannel *chan, int level,
219  const unsigned short indent);
220 DBCORE_API void dbChannelFilterShow(dbChannel *chan, int level,
221  const unsigned short indent);
222 DBCORE_API void dbChannelDelete(dbChannel *chan);
223 
224 DBCORE_API void dbRegisterFilter(const char *key, const chFilterIf *fif, void *puser);
225 DBCORE_API db_field_log* dbChannelRunPreChain(dbChannel *chan, db_field_log *pLogIn);
226 DBCORE_API db_field_log* dbChannelRunPostChain(dbChannel *chan, db_field_log *pLogIn);
227 DBCORE_API const chFilterPlugin * dbFindFilter(const char *key, size_t len);
228 DBCORE_API void dbChannelGetArrayInfo(dbChannel *chan,
229  void **pfield, long *no_elements, long *offset);
230 
231 #ifdef __cplusplus
232 }
233 #endif
234 
235 #endif /* INC_dbChannel_H */
List node type.
Definition: ellLib.h:46
The core data types used by epics.
Declaration of dbCommon.
Definition: dbCommon.h:18
Definition: dbAddr.h:17
A doubly-linked list library.
List header type.
Definition: ellLib.h:57
Miscellaneous macro definitions.