1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
|
#ifndef _GATEPV_H_
#define _GATEPV_H_
/*+*********************************************************************
*
* File: gatePv.h
* Project: CA Proxy Gateway
*
* Descr.: PV = Client side (lower half) of Proxy Gateway Channel
* Handles all CAC related stuff:
* - Connections (and exception handling)
* - Monitors (value and ALH data)
* - Put operations (Gets are answered by the VC)
*
* Author(s): J. Kowalkowski, J. Anderson, K. Evans (APS)
* R. Lange (BESSY)
*
* $Revision$
* $Date$
*
* $Author$
*
* $Log$
* Revision 1.12 2000/05/02 13:49:39 lange
* Uses GNU regex library (0.12) for pattern matching;
* Fixed some CAS beacon problems (reconnecting IOCs)
*
* Revision 1.11 2000/04/05 15:59:33 lange
* += ALH awareness; += DENY from <host>; async pvExistTest; some code cleaning
*
*********************************************************************-*/
// Used in put() to specify callback or not
#define GATE_NOCALLBACK 0
#define GATE_DOCALLBACK 1
#include <sys/types.h>
#include <sys/time.h>
#include "aitTypes.h"
#include "gddAppTable.h"
#include "tsDLList.h"
#include "gateAsyncIO.h"
extern "C" {
#include "cadef.h"
#include "db_access.h"
}
typedef evargs EVENT_ARGS;
typedef struct access_rights_handler_args ACCESS_ARGS;
typedef struct connection_handler_args CONNECT_ARGS;
typedef enum {
gatePvDead,
gatePvInactive,
gatePvActive,
gatePvConnect,
gatePvDisconnect
} gatePvState;
// Other state information is boolean:
// monitored state: 0=false or not monitored, 1=true or is monitored
// get state: 0=false or no get pending, 1=true or get pending
// test flag : true if NAK/ACK response required after completion
// complete flag: true if ADD/REMOVE response required after completion
class gdd;
class gateVcData;
class gatePvData;
class gateServer;
class gateAsEntry;
// This class is used by gatePvData to keep track of which associated
// gateVcData initiated a put. It stores the vcID of the gateVcData
// and the gatePvData's this pointer in a list for use by the
// gatePvData's static putCB.
class gatePvCallbackId : public tsDLNode<gatePvCallbackId>
{
public:
gatePvCallbackId(unsigned long idIn, gatePvData *pvIn) :
id(idIn),pv(pvIn) {};
unsigned long getID(void) const { return id; }
gatePvData *getPV(void) const { return pv; }
private:
unsigned long id;
gatePvData *pv;
};
// This class is used to manage one process variable (channel) on the
// client side of the Gateway. It typically stays around a long time,
// whereas the associated gateVcData comes and goes as clients connect
// to the server side of the Gateway.
class gatePvData
{
public:
gatePvData(gateServer*,gateAsEntry*,const char* name);
~gatePvData(void);
typedef gdd* (gatePvData::*gateCallback)(void*);
int active(void) const { return (pv_state==gatePvActive)?1:0; }
int inactive(void) const { return (pv_state==gatePvInactive)?1:0; }
int dead(void) const { return (pv_state==gatePvDead)?1:0; }
int pendingConnect(void) const { return (pv_state==gatePvConnect)?1:0; }
int pendingGet(void) const { return (get_state)?1:0; }
int monitored(void) const { return (mon_state)?1:0; }
int alhMonitored(void) const { return (alh_mon_state)?1:0; }
int needAddRemove(void) const { return (complete_flag)?1:0; }
int abort(void) const { return (abort_flag)?1:0; }
const char* name(void) const { return pv_name; }
gateVcData* VC(void) const { return vc; }
gateAsEntry* getEntry(void) const { return ae; }
gatePvState getState(void) const { return pv_state; }
const char* getStateName(void) const { return pv_state_names[pv_state]; }
int getStatus(void) const { return status; }
chid getChannel(void) const { return chID; }
evid getEvent(void) const { return evID; }
int getCaState(void) const { return ca_state(chID); }
aitInt32 totalElements(void) const { return ca_element_count(chID); }
aitUint32 maxElements(void) const { return max_elements; }
chtype fieldType(void) const { return ca_field_type(chID); }
aitEnum nativeType(void) const;
chtype dataType(void) const { return data_type; }
chtype eventType(void) const { return event_type; }
void checkEvent(void) { ca_poll(); }
double eventRate(void);
int activate(gateVcData* from); // set to active (CAS connect)
int deactivate(void); // set to inactive (CAS disconnect)
int death(void); // set to not connected (CAC disconnect)
int life(void); // set to connected (CAC connect)
int monitor(void); // add monitor
int unmonitor(void); // delete monitor
int alhMonitor(void); // add alh info monitor
int alhUnmonitor(void); // delete alh info monitor
int get(void); // get callback
int put(gdd*, int docallback); // put with or without callback
time_t timeInactive(void) const;
time_t timeActive(void) const;
time_t timeDead(void) const;
time_t timeAlive(void) const;
time_t timeLastTrans(void) const;
time_t timeConnecting(void) const;
void setVC(gateVcData* t) { vc=t; }
void setTransTime(void);
void addET(const casCtx&);
void flushAsyncETQueue(pvExistReturnEnum);
protected:
void init(gateServer*,gateAsEntry*,const char* name);
void initClear(void);
void setInactiveTime(void);
void setActiveTime(void);
void setDeathTime(void);
void setAliveTime(void);
void setReconnectTime(void);
void setTimes(void);
private:
void markMonitored(void) { mon_state=1; }
void markGetPending(void) { get_state=1; }
void markAlhMonitored(void) { alh_mon_state=1; }
void markAlhGetPending(void) { alh_get_state=1; }
void markAddRemoveNeeded(void) { complete_flag=1; }
void markAbort(void) { abort_flag=1; }
void markNotMonitored(void) { mon_state=0; }
void markNoGetPending(void) { get_state=0; }
void markAlhNotMonitored(void) { alh_mon_state=0; }
void markAlhNoGetPending(void) { alh_get_state=0; }
void markAddRemoveNotNeeded(void) { complete_flag=0; }
void markNoAbort(void) { abort_flag=0; }
void setState(gatePvState s) { pv_state=s; }
gdd* runEventCB(void* data) { return (this->*event_func)(data); }
gdd* runDataCB(void* data) { return (this->*data_func)(data); }
tsDLList<gateAsyncE> eio; // pending exist test list
tsDLList<gatePvCallbackId> callback_list; // callback list for puts
gateServer* mrg; // The gateServer that manages this gatePvData
gateVcData* vc; // Pointer to the associated gateVcData, NULL if none
gateAsEntry* ae;
aitUint32 max_elements;
int status;
char* pv_name; // Name of the process variable
chid chID; // Channel access ID
evid evID; // Channel access event id
evid alhID; // Channel access alh info event id
chtype event_type; // DBR type associated with eventCB (event_data)
chtype data_type; // DBR type associated with getCB (pv_data)
gatePvState pv_state; // The state of the connection
unsigned long event_count; // Counter for events received
static const char* const pv_state_names[]; // State strings
gateCallback event_func; // Function called in eventCB for event_data
gateCallback data_func; // Function called in getCB for pv_data
int mon_state; // 0=not monitored, 1=is monitored
int get_state; // 0=no get pending, 1=get pending
int alh_mon_state; // 0=alh info not monitored, 1=alh info is monitored
int alh_get_state; // 0=no alh info get pending, 1=alh info get pending
int abort_flag; // true if activate-connect sequence should be aborted
int complete_flag; // true if ADD/REMOVE required after completion
time_t no_connect_time; // when no one connected to held PV
time_t dead_alive_time; // when PV went dead / came alive
time_t last_trans_time; // last transaction occurred at this time
static void connectCB(CONNECT_ARGS args); // connection callback
static void accessCB(ACCESS_ARGS args); // access security callback
static void eventCB(EVENT_ARGS args); // value-changed callback
static void alhCB(EVENT_ARGS args); // alh info value-changed callback
static void putCB(EVENT_ARGS args); // put callback
static void getCB(EVENT_ARGS args); // get callback
// Callback functions used in eventCB
gdd* eventStringCB(void*);
gdd* eventEnumCB(void*);
gdd* eventShortCB(void*);
gdd* eventFloatCB(void*);
gdd* eventDoubleCB(void*);
gdd* eventCharCB(void*);
gdd* eventLongCB(void*);
gdd* eventSTSAckStringCB(dbr_stsack_string*);
// Callback functions used in getCB
gdd* dataStringCB(void*);
gdd* dataEnumCB(void*);
gdd* dataShortCB(void*);
gdd* dataFloatCB(void*);
gdd* dataDoubleCB(void*);
gdd* dataCharCB(void*);
gdd* dataLongCB(void*);
};
inline void gatePvData::addET(const casCtx& c)
{ eio.add(*(new gateAsyncE(c,&eio))); }
inline time_t gatePvData::timeInactive(void) const
{ return inactive()?(time(NULL)-no_connect_time):0; }
inline time_t gatePvData::timeActive(void) const
{ return active()?(time(NULL)-no_connect_time):0; }
inline time_t gatePvData::timeLastTrans(void) const
{ return time(NULL)-last_trans_time; }
inline time_t gatePvData::timeDead(void) const
{
time_t x=time(NULL)-dead_alive_time;
time_t y=timeLastTrans();
if(dead())
return (x<y)?x:y;
else
return 0;
}
inline time_t gatePvData::timeAlive(void) const
{ return (!dead())?(time(NULL)-dead_alive_time):0; }
inline time_t gatePvData::timeConnecting(void) const
{ return (time(NULL)-dead_alive_time); }
inline void gatePvData::setInactiveTime(void) { time(&no_connect_time); }
inline void gatePvData::setActiveTime(void) { time(&no_connect_time); }
inline void gatePvData::setAliveTime(void) { time(&dead_alive_time); }
inline void gatePvData::setTransTime(void) { time(&last_trans_time); }
inline void gatePvData::setTimes(void)
{
time(&dead_alive_time);
no_connect_time=dead_alive_time;
last_trans_time=dead_alive_time;
}
inline void gatePvData::setDeathTime(void)
{
time(&dead_alive_time);
no_connect_time=dead_alive_time;
}
#endif
/* **************************** Emacs Editing Sequences ***************** */
/* Local Variables: */
/* tab-width: 4 */
/* c-basic-offset: 4 */
/* c-comment-only-line-offset: 0 */
/* c-file-offsets: ((substatement-open . 0) (label . 0)) */
/* End: */
|