pvAccessCPP  7.1.5
remote.h
1 /**
2  * Copyright - See the COPYRIGHT that is included with this distribution.
3  * pvAccessCPP is distributed subject to a Software License Agreement found
4  * in file LICENSE that is included with this distribution.
5  */
6 
7 #ifndef REMOTE_H_
8 #define REMOTE_H_
9 
10 #ifdef epicsExportSharedSymbols
11 # define remoteEpicsExportSharedSymbols
12 # undef epicsExportSharedSymbols
13 #endif
14 
15 #include <map>
16 #include <string>
17 
18 #include <osiSock.h>
19 
20 #include <pv/serialize.h>
21 #include <pv/pvType.h>
22 #include <pv/byteBuffer.h>
23 #include <pv/timer.h>
24 #include <pv/pvData.h>
25 #include <pv/sharedPtr.h>
26 
27 #ifdef remoteEpicsExportSharedSymbols
28 # define epicsExportSharedSymbols
29 # undef remoteEpicsExportSharedSymbols
30 #endif
31 
32 #include <pv/pvaConstants.h>
33 #include <pv/configuration.h>
34 #include <pv/fairQueue.h>
35 #include <pv/pvaDefs.h>
36 
37 /// TODO only here because of the Lockable
38 #include <pv/pvAccess.h>
39 
40 namespace epics {
41 namespace pvAccess {
42 
43 class TransportRegistry;
44 class ClientChannelImpl;
45 
46 enum QoS {
47  /**
48  * Default behavior.
49  */
50  QOS_DEFAULT = 0x00,
51  /**
52  * Require reply (acknowledgment for reliable operation).
53  */
55  /**
56  * Best-effort option (no reply).
57  */
59  /**
60  * Process option.
61  */
62  QOS_PROCESS = 0x04,
63  /**
64  * Initialize option.
65  */
66  QOS_INIT = 0x08,
67  /**
68  * Destroy option.
69  */
70  QOS_DESTROY = 0x10,
71  /**
72  * Share data option.
73  */
74  QOS_SHARE = 0x20,
75  /**
76  * Get.
77  */
78  QOS_GET = 0x40,
79  /**
80  * Get-put.
81  */
82  QOS_GET_PUT = 0x80
83 };
84 
85 enum ApplicationCommands {
86  CMD_BEACON = 0,
87  CMD_CONNECTION_VALIDATION = 1,
88  CMD_ECHO = 2,
89  CMD_SEARCH = 3,
90  CMD_SEARCH_RESPONSE = 4,
91  CMD_AUTHNZ = 5,
92  CMD_ACL_CHANGE = 6,
93  CMD_CREATE_CHANNEL = 7,
94  CMD_DESTROY_CHANNEL = 8,
95  CMD_CONNECTION_VALIDATED = 9,
96  CMD_GET = 10,
97  CMD_PUT = 11,
98  CMD_PUT_GET = 12,
99  CMD_MONITOR = 13,
100  CMD_ARRAY = 14,
101  CMD_DESTROY_REQUEST = 15,
102  CMD_PROCESS = 16,
103  CMD_GET_FIELD = 17,
104  CMD_MESSAGE = 18,
105  CMD_MULTIPLE_DATA = 19,
106  CMD_RPC = 20,
107  CMD_CANCEL_REQUEST = 21,
108  CMD_ORIGIN_TAG = 22
109 };
110 
111 enum ControlCommands {
112  CMD_SET_MARKER = 0,
113  CMD_ACK_MARKER = 1,
114  CMD_SET_ENDIANESS = 2
115 };
116 
117 void hackAroundRTEMSSocketInterrupt();
118 
119 /**
120  * Interface defining transport send control.
121  */
122 class TransportSendControl : public epics::pvData::SerializableControl {
123 public:
124  POINTER_DEFINITIONS(TransportSendControl);
125 
126  virtual ~TransportSendControl() {}
127 
128  virtual void startMessage(epics::pvData::int8 command, std::size_t ensureCapacity, epics::pvData::int32 payloadSize = 0) = 0;
129  virtual void endMessage() = 0;
130 
131  virtual void flush(bool lastMessageCompleted) = 0;
132 
133  virtual void setRecipient(osiSockAddr const & sendTo) = 0;
134 };
135 
136 /**
137  * Interface defining transport sender (instance sending data over transport).
138  */
139 class TransportSender : public Lockable, public fair_queue<TransportSender>::entry {
140 public:
141  POINTER_DEFINITIONS(TransportSender);
142 
143  TransportSender() :bytesTX(0u), bytesRX(0u) {}
144  virtual ~TransportSender() {}
145 
146  /**
147  * Called by transport.
148  * By this call transport gives callee ownership over the buffer.
149  * Calls on <code>TransportSendControl</code> instance must be made from
150  * calling thread. Moreover, ownership is valid only for the time of call
151  * of this method.
152  * NOTE: these limitations allow efficient implementation.
153  */
154  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) = 0;
155 
156  size_t bytesTX;
157  size_t bytesRX;
158 };
159 
160 class ClientChannelImpl;
161 class SecuritySession;
162 
163 /**
164  * Interface defining transport (connection).
165  */
166 class epicsShareClass Transport : public epics::pvData::DeserializableControl {
167 public:
169 
170  static size_t num_instances;
171 
172  Transport();
173  virtual ~Transport();
174 
175  /**
176  * Acquires transport.
177  * @param client client (channel) acquiring the transport
178  * @return <code>true</code> if transport was granted, <code>false</code> otherwise.
179  */
180  virtual bool acquire(std::tr1::shared_ptr<ClientChannelImpl> const & client) = 0;
181 
182  /**
183  * Releases transport.
184  * @param client client (channel) releasing the transport
185  */
186  virtual void release(pvAccessID clientId) = 0;
187 
188  /**
189  * Get protocol type (tcp, udp, ssl, etc.).
190  * @return protocol type.
191  */
192  virtual std::string getType() const = 0;
193 
194  virtual const osiSockAddr& getRemoteAddress() const = 0;
195 
196  virtual const std::string& getRemoteName() const = 0;
197 
198  // TODO getContext?
199 
200  /**
201  * Get receive buffer size.
202  * @return receive buffer size.
203  */
204  virtual std::size_t getReceiveBufferSize() const = 0;
205 
206  /**
207  * Transport priority.
208  * @return protocol priority.
209  */
210  virtual epics::pvData::int16 getPriority() const = 0;
211 
212  /**
213  * Set remote transport receive buffer size.
214  * @param receiveBufferSize receive buffer size.
215  */
217 
218  /**
219  * Set remote transport socket receive buffer size.
220  * @param socketReceiveBufferSize remote socket receive buffer size.
221  */
223 
224  /**
225  * Set byte order.
226  * @param byteOrder byte order to set.
227  */
228  // TODO enum
229  virtual void setByteOrder(int byteOrder) = 0;
230 
231  /**
232  * Enqueue send request.
233  * @param sender
234  */
235  virtual void enqueueSendRequest(TransportSender::shared_pointer const & sender) = 0;
236 
237  /**
238  * Flush send queue (sent messages).
239  */
240  virtual void flushSendQueue() = 0;
241 
242  /**
243  * Notify transport that it is has been verified.
244  * @param status vefification status;
245  */
246  virtual void verified(epics::pvData::Status const & status) = 0;
247 
248  /**
249  * Waits (if needed) until transport is verified, i.e. verified() method is being called.
250  * @param timeoutMs timeout to wait for verification, infinite if 0.
251  */
252  virtual bool verify(epics::pvData::int32 timeoutMs) = 0;
253 
254  /**
255  * Close transport.
256  */
257  virtual void close() = 0;
258 
259  //! Call after close() to wait for any worker threads to exit
260  virtual void waitJoin() {}
261 
262  /**
263  * Check connection status.
264  * @return <code>true</code> if connected.
265  */
266  virtual bool isClosed() = 0;
267 
268  /**
269  * Pass data to the active security plug-in session.
270  * @param data the data (any data), can be <code>null</code>.
271  */
272  virtual void authNZMessage(epics::pvData::PVStructure::shared_pointer const & data) = 0;
273 
276 };
277 
278 class Channel;
279 class SecurityPlugin;
280 class AuthenticationRegistry;
281 
282 /**
283  * Not public IF, used by Transports, etc.
284  */
285 class Context {
286 public:
287  POINTER_DEFINITIONS(Context);
288 
289  virtual ~Context() {}
290 
291  virtual epics::pvData::Timer::shared_pointer getTimer() = 0;
292 
293  virtual TransportRegistry* getTransportRegistry() = 0;
294 
295 
296 
297 
298  virtual Configuration::const_shared_pointer getConfiguration() = 0;
299 
300  ///
301  /// due to ClientContextImpl
302  ///
303 
304  virtual void newServerDetected() = 0;
305 
306  virtual std::tr1::shared_ptr<Channel> getChannel(pvAccessID id) = 0;
307  virtual Transport::shared_pointer getSearchTransport() = 0;
308 };
309 
310 /**
311  * Interface defining response handler.
312  */
313 class ResponseHandler {
314 public:
315  POINTER_DEFINITIONS(ResponseHandler);
316 
317  static size_t num_instances;
318 
319  ResponseHandler(Context* context, const std::string& description);
320  virtual ~ResponseHandler();
321 
322  /**
323  * Handle response.
324  * @param[in] responseFrom remote address of the responder, <code>0</code> if unknown.
325  * @param[in] transport response source transport.
326  * @param[in] version message version.
327  * @param[in] payloadSize size of this message data available in the <code>payloadBuffer</code>.
328  * @param[in] payloadBuffer message payload data.
329  * Note that this might not be the only message in the buffer.
330  * Code must not manipulate buffer.
331  */
332  virtual void
333  handleResponse(osiSockAddr* responseFrom, Transport::shared_pointer const & transport,
336 
337 protected:
338  /**
339  * Response hanlder description.
340  */
342 
343  /**
344  * Debug flag.
345  */
347 };
348 
349 /**
350  * A request that expects an response.
351  * Responses identified by its I/O ID.
352  */
353 class ResponseRequest : public TransportSender {
354 public:
355  POINTER_DEFINITIONS(ResponseRequest);
356 
357  virtual ~ResponseRequest() {}
358 
359  /**
360  * Get I/O ID.
361  * @return ioid
362  */
363  virtual pvAccessID getIOID() const = 0;
364 
365  /**
366  * Timeout notification.
367  */
368  virtual void timeout() = 0;
369 
370  /**
371  * Cancel response request (always to be called to complete/destroy).
372  */
373  virtual void cancel() = 0;
374 
375  /**
376  * Report status to clients (e.g. disconnected).
377  * @param status to report.
378  */
379  virtual void reportStatus(Channel::ConnectionState status) = 0;
380 
381  /**
382  * used by MessageHandler and reportChannelStateChange().
383  *
384  * May return NULL
385  */
387 
388  /**
389  * Notification response.
390  * @param transport
391  * @param version
392  * @param payloadBuffer
393  */
395 
396 };
397 
398 
399 }
400 }
401 
402 #endif /* REMOTE_H_ */
virtual pvAccessID getIOID() const =0
Get I/O ID.
virtual void timeout()=0
Timeout notification.
Interface defining transport (connection).
Definition: remote.h:166
Process option.
Definition: remote.h:62
Require reply (acknowledgment for reliable operation).
Definition: remote.h:54
std::string _description
Response hanlder description.
Definition: remote.h:341
Destroy option.
Definition: remote.h:70
virtual std::tr1::shared_ptr< ChannelBaseRequester > getRequester()=0
used by MessageHandler and reportChannelStateChange().
Best-effort option (no reply).
Definition: remote.h:58
Initialize option.
Definition: remote.h:66
virtual void authNZMessage(epics::pvData::PVStructure::shared_pointer const &data)=0
Pass data to the active security plug-in session.
epics::pvData::int32 _debugLevel
Debug flag.
Definition: remote.h:346
virtual void send(epics::pvData::ByteBuffer *buffer, TransportSendControl *control)=0
Called by transport.
Default behavior.
Definition: remote.h:50
virtual void response(Transport::shared_pointer const &transport, epics::pvData::int8 version, epics::pvData::ByteBuffer *payloadBuffer)=0
Notification response.
virtual void newServerDetected()=0
due to ClientContextImpl
Share data option.
Definition: remote.h:74
virtual void cancel()=0
Cancel response request (always to be called to complete/destroy).
virtual void handleResponse(osiSockAddr *responseFrom, Transport::shared_pointer const &transport, epics::pvData::int8 version, epics::pvData::int8 command, std::size_t payloadSize, epics::pvData::ByteBuffer *payloadBuffer)
Handle response.
virtual void reportStatus(Channel::ConnectionState status)=0
Report status to clients (e.g.