pvAccessCPP  7.1.5
responseHandlers.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 RESPONSEHANDLERS_H_
8 #define RESPONSEHANDLERS_H_
9 
10 #include <list>
11 
12 #include <pv/timer.h>
13 
14 #include <pv/serverContext.h>
15 #include <pv/remote.h>
16 #include <pv/serverChannelImpl.h>
17 #include <pv/baseChannelRequester.h>
18 #include <pv/securityImpl.h>
19 
20 namespace epics {
21 namespace pvAccess {
22 
23 /**
24  */
25 class AbstractServerResponseHandler : public ResponseHandler {
26 protected:
27  ServerContextImpl::shared_pointer _context;
28 public:
29  AbstractServerResponseHandler(ServerContextImpl::shared_pointer const & context, std::string description) :
30  ResponseHandler(context.get(), description), _context(context) {
31  }
32 
33  virtual ~AbstractServerResponseHandler() {}
34 };
35 
36 /**
37  * Bad request handler.
38  */
39 class ServerBadResponse : public AbstractServerResponseHandler {
40 public:
41  ServerBadResponse(ServerContextImpl::shared_pointer const & context) :
42  AbstractServerResponseHandler(context, "Bad request") {
43  }
44 
45  virtual ~ServerBadResponse() {
46  }
47 
48  virtual void handleResponse(osiSockAddr* responseFrom,
51 };
52 
53 /**
54  * Connection validation message handler.
55  */
56 class ServerConnectionValidationHandler : public AbstractServerResponseHandler {
57 public:
58  ServerConnectionValidationHandler(ServerContextImpl::shared_pointer const & context) :
59  AbstractServerResponseHandler(context, "Connection validation") {
60  }
61  virtual ~ServerConnectionValidationHandler() {}
62 
63  virtual void handleResponse(osiSockAddr* responseFrom,
66 };
67 
68 /**
69  * NOOP response.
70  */
71 class ServerNoopResponse : public AbstractServerResponseHandler {
72 public:
73  ServerNoopResponse(ServerContextImpl::shared_pointer const & context, std::string description) :
74  AbstractServerResponseHandler(context, description) {
75  }
76  virtual ~ServerNoopResponse() {}
77 };
78 
79 /**
80  * Echo request handler.
81  */
82 class ServerEchoHandler : public AbstractServerResponseHandler {
83 public:
84  ServerEchoHandler(ServerContextImpl::shared_pointer const & context) :
85  AbstractServerResponseHandler(context, "Echo request") {
86  }
87  virtual ~ServerEchoHandler() {}
88 
89  virtual void handleResponse(osiSockAddr* responseFrom,
92 };
93 
94 class EchoTransportSender : public TransportSender {
95 public:
96  EchoTransportSender(osiSockAddr* echoFrom, size_t payloadSize, epics::pvData::ByteBuffer& payloadBuffer) {
97  memcpy(&_echoFrom, echoFrom, sizeof(osiSockAddr));
98  toEcho.resize(payloadSize);
99  payloadBuffer.getArray(&toEcho[0], payloadSize);
100  }
101 
102  virtual ~EchoTransportSender() {}
103 
104  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL {
105  control->startMessage(CMD_ECHO, toEcho.size(), toEcho.size());
106  control->setRecipient(_echoFrom);
107  buffer->putArray<char>(&toEcho[0], toEcho.size());
108  }
109 
110 private:
111  osiSockAddr _echoFrom;
112  std::vector<char> toEcho;
113 };
114 
115 /****************************************************************************************/
116 /**
117  * Search channel request handler.
118  */
119 // TODO object pool!!!
120 class ServerSearchHandler : public AbstractServerResponseHandler
121 {
122 public:
123  static const std::string SUPPORTED_PROTOCOL;
124 
125  ServerSearchHandler(ServerContextImpl::shared_pointer const & context);
126  virtual ~ServerSearchHandler() {}
127 
128  virtual void handleResponse(osiSockAddr* responseFrom,
131 };
132 
133 
134 class ServerChannelFindRequesterImpl:
135  public ChannelFindRequester,
136  public TransportSender,
137  public epics::pvData::TimerCallback,
138  public std::tr1::enable_shared_from_this<ServerChannelFindRequesterImpl>
139 {
140 public:
141  ServerChannelFindRequesterImpl(ServerContextImpl::shared_pointer const & context,
142  const PeerInfo::const_shared_pointer& peer,
143  epics::pvData::int32 expectedResponseCount);
144  virtual ~ServerChannelFindRequesterImpl() {}
145  void clear();
146  ServerChannelFindRequesterImpl* set(std::string _name, epics::pvData::int32 searchSequenceId,
147  epics::pvData::int32 cid, osiSockAddr const & sendTo, bool responseRequired, bool serverSearch);
148  virtual void channelFindResult(const epics::pvData::Status& status, ChannelFind::shared_pointer const & channelFind, bool wasFound) OVERRIDE FINAL;
149 
150  virtual std::tr1::shared_ptr<const PeerInfo> getPeerInfo() OVERRIDE FINAL;
151  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
152 
153  virtual void callback() OVERRIDE FINAL;
154  virtual void timerStopped() OVERRIDE FINAL;
155 
156 private:
157  ServerGUID _guid;
158  std::string _name;
159  epics::pvData::int32 _searchSequenceId;
160  epics::pvData::int32 _cid;
161  osiSockAddr _sendTo;
162  bool _responseRequired;
163  bool _wasFound;
164  const ServerContextImpl::shared_pointer _context;
165  const PeerInfo::const_shared_pointer _peer;
166  mutable epics::pvData::Mutex _mutex;
167  const epics::pvData::int32 _expectedResponseCount;
168  epics::pvData::int32 _responseCount;
169  bool _serverSearch;
170 };
171 
172 /****************************************************************************************/
173 /**
174  * Create channel request handler.
175  */
176 class ServerCreateChannelHandler : public AbstractServerResponseHandler
177 {
178 public:
179  ServerCreateChannelHandler(ServerContextImpl::shared_pointer const & context)
180  :AbstractServerResponseHandler(context, "Create channel request")
181  {}
182  virtual ~ServerCreateChannelHandler() {}
183 
184  virtual void handleResponse(osiSockAddr* responseFrom,
187 
188 private:
189  // Name of the magic "server" PV used to implement channelList() and server info
190  static const std::string SERVER_CHANNEL_NAME;
191 
192  void disconnect(Transport::shared_pointer const & transport);
193 };
194 
195 namespace detail {
196 class BlockingServerTCPTransportCodec;
197 }
198 
199 class ServerChannelRequesterImpl :
200  public ChannelRequester,
201  public TransportSender,
202  public std::tr1::enable_shared_from_this<ServerChannelRequesterImpl>
203 {
204  friend class ServerCreateChannelHandler;
205 public:
206  typedef std::tr1::shared_ptr<ServerChannelRequesterImpl> shared_pointer;
207  typedef std::tr1::shared_ptr<const ServerChannelRequesterImpl> const_shared_pointer;
208 protected:
209  ServerChannelRequesterImpl(Transport::shared_pointer const & transport,
210  const std::string channelName,
211  const pvAccessID cid);
212 public:
213  virtual ~ServerChannelRequesterImpl() {}
214  static ChannelRequester::shared_pointer create(ChannelProvider::shared_pointer const & provider,
215  Transport::shared_pointer const & transport, const std::string channelName,
216  const pvAccessID cid);
217  virtual void channelCreated(const epics::pvData::Status& status, Channel::shared_pointer const & channel) OVERRIDE FINAL;
218  virtual void channelStateChange(Channel::shared_pointer const & c, const Channel::ConnectionState isConnected) OVERRIDE FINAL;
219  virtual std::tr1::shared_ptr<const PeerInfo> getPeerInfo() OVERRIDE FINAL;
220  virtual std::string getRequesterName() OVERRIDE FINAL;
221  virtual void message(std::string const & message, epics::pvData::MessageType messageType) OVERRIDE FINAL;
222  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
223 private:
224  ServerChannel::weak_pointer _serverChannel;
225  std::tr1::weak_ptr<detail::BlockingServerTCPTransportCodec> _transport;
226  const std::string _channelName;
227  const pvAccessID _cid;
228  bool _created;
229  epics::pvData::Status _status;
230  epics::pvData::Mutex _mutex;
231 };
232 
233 /****************************************************************************************/
234 /**
235  * Destroy channel request handler.
236  */
237 class ServerDestroyChannelHandler : public AbstractServerResponseHandler
238 {
239 public:
240  ServerDestroyChannelHandler(ServerContextImpl::shared_pointer const & context) :
241  AbstractServerResponseHandler(context, "Destroy channel request") {
242  }
243  virtual ~ServerDestroyChannelHandler() {}
244 
245  virtual void handleResponse(osiSockAddr* responseFrom,
248 };
249 
250 
251 class ServerDestroyChannelHandlerTransportSender : public TransportSender
252 {
253 public:
254  ServerDestroyChannelHandlerTransportSender(pvAccessID cid, pvAccessID sid): _cid(cid), _sid(sid) {
255  }
256 
257  virtual ~ServerDestroyChannelHandlerTransportSender() {}
258  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL {
259  control->startMessage((epics::pvData::int8)CMD_DESTROY_CHANNEL, 2*sizeof(epics::pvData::int32)/sizeof(epics::pvData::int8));
260  buffer->putInt(_sid);
261  buffer->putInt(_cid);
262  }
263 
264 private:
265  pvAccessID _cid;
266  pvAccessID _sid;
267 };
268 
269 /****************************************************************************************/
270 /**
271  * Get request handler.
272  */
273 class ServerGetHandler : public AbstractServerResponseHandler
274 {
275 public:
276  ServerGetHandler(ServerContextImpl::shared_pointer const & context) :
277  AbstractServerResponseHandler(context, "Get request") {
278  }
279  virtual ~ServerGetHandler() {}
280 
281  virtual void handleResponse(osiSockAddr* responseFrom,
284 };
285 
286 class ServerChannelGetRequesterImpl :
287  public BaseChannelRequester,
288  public ChannelGetRequester,
289  public std::tr1::enable_shared_from_this<ServerChannelGetRequesterImpl>
290 {
291 public:
292  typedef std::tr1::shared_ptr<ServerChannelGetRequesterImpl> shared_pointer;
293  typedef std::tr1::shared_ptr<const ServerChannelGetRequesterImpl> const_shared_pointer;
294 protected:
295  ServerChannelGetRequesterImpl(ServerContextImpl::shared_pointer const & context,
296  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
297  Transport::shared_pointer const & transport);
298  void activate(epics::pvData::PVStructure::shared_pointer const & pvRequest);
299 public:
300  static ChannelGetRequester::shared_pointer create(ServerContextImpl::shared_pointer const & context,
301  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
302  Transport::shared_pointer const & transport,
303  epics::pvData::PVStructure::shared_pointer const & pvRequest);
304  virtual ~ServerChannelGetRequesterImpl() {}
305  virtual void channelGetConnect(const epics::pvData::Status& status, ChannelGet::shared_pointer const & channelGet,
306  epics::pvData::Structure::const_shared_pointer const & structure) OVERRIDE FINAL;
307  virtual void getDone(const epics::pvData::Status& status, ChannelGet::shared_pointer const & channelGet,
308  epics::pvData::PVStructure::shared_pointer const & pvStructure,
309  epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL;
310  virtual void destroy() OVERRIDE FINAL;
311 
312  ChannelGet::shared_pointer getChannelGet();
313  virtual std::tr1::shared_ptr<ChannelRequest> getOperation() OVERRIDE FINAL { return getChannelGet(); }
314 
315  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
316 private:
317  // Note: this forms a reference loop, which is broken in destroy()
318  ChannelGet::shared_pointer _channelGet;
319  epics::pvData::PVStructure::shared_pointer _pvStructure;
320  epics::pvData::BitSet::shared_pointer _bitSet;
321  epics::pvData::Status _status;
322 };
323 
324 
325 /****************************************************************************************/
326 /**
327  * Put request handler.
328  */
329 class ServerPutHandler : public AbstractServerResponseHandler
330 {
331 public:
332  ServerPutHandler(ServerContextImpl::shared_pointer context) :
333  AbstractServerResponseHandler(context, "Put request") {
334  }
335  virtual ~ServerPutHandler() {}
336 
337  virtual void handleResponse(osiSockAddr* responseFrom,
340 };
341 
342 class ServerChannelPutRequesterImpl :
343  public BaseChannelRequester,
344  public ChannelPutRequester,
345  public std::tr1::enable_shared_from_this<ServerChannelPutRequesterImpl>
346 {
347 public:
348  typedef std::tr1::shared_ptr<ServerChannelPutRequesterImpl> shared_pointer;
349  typedef std::tr1::shared_ptr<const ServerChannelPutRequesterImpl> const_shared_pointer;
350 protected:
351  ServerChannelPutRequesterImpl(ServerContextImpl::shared_pointer const & context,
352  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
353  Transport::shared_pointer const & transport);
354  void activate(epics::pvData::PVStructure::shared_pointer const & pvRequest);
355 public:
356  static ChannelPutRequester::shared_pointer create(ServerContextImpl::shared_pointer const & context,
357  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
358  Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest);
359 
360  virtual ~ServerChannelPutRequesterImpl() {}
361  virtual void channelPutConnect(const epics::pvData::Status& status, ChannelPut::shared_pointer const & channelPut,
362  epics::pvData::Structure::const_shared_pointer const & structure) OVERRIDE FINAL;
363  virtual void putDone(const epics::pvData::Status& status, ChannelPut::shared_pointer const & channelPut) OVERRIDE FINAL;
364  virtual void getDone(const epics::pvData::Status& status, ChannelPut::shared_pointer const & channelPut,
365  epics::pvData::PVStructure::shared_pointer const & pvStructure,
366  epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL;
367  virtual void destroy() OVERRIDE FINAL;
368 
369  ChannelPut::shared_pointer getChannelPut();
370  virtual std::tr1::shared_ptr<ChannelRequest> getOperation() OVERRIDE FINAL { return getChannelPut(); }
371 
372  epics::pvData::BitSet::shared_pointer getPutBitSet();
373  epics::pvData::PVStructure::shared_pointer getPutPVStructure();
374  void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
375 private:
376  // Note: this forms a reference loop, which is broken in destroy()
377  ChannelPut::shared_pointer _channelPut;
378  epics::pvData::BitSet::shared_pointer _bitSet;
379  epics::pvData::PVStructure::shared_pointer _pvStructure;
380  epics::pvData::Status _status;
381 };
382 
383 /****************************************************************************************/
384 /**
385  * Put request handler.
386  */
387 class ServerPutGetHandler : public AbstractServerResponseHandler
388 {
389 public:
390  ServerPutGetHandler(ServerContextImpl::shared_pointer const & context) :
391  AbstractServerResponseHandler(context, "Put-get request") {
392  }
393 
394  virtual ~ServerPutGetHandler() {}
395  virtual void handleResponse(osiSockAddr* responseFrom,
398 };
399 
400 class ServerChannelPutGetRequesterImpl :
401  public BaseChannelRequester,
402  public ChannelPutGetRequester,
403  public std::tr1::enable_shared_from_this<ServerChannelPutGetRequesterImpl>
404 {
405 public:
406  typedef std::tr1::shared_ptr<ServerChannelPutGetRequesterImpl> shared_pointer;
407  typedef std::tr1::shared_ptr<const ServerChannelPutGetRequesterImpl> const_shared_pointer;
408 protected:
409  ServerChannelPutGetRequesterImpl(ServerContextImpl::shared_pointer const & context,
410  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
411  Transport::shared_pointer const & transport);
412  void activate(epics::pvData::PVStructure::shared_pointer const & pvRequest);
413 public:
414  static ChannelPutGetRequester::shared_pointer create(ServerContextImpl::shared_pointer const & context,
415  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
416  Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest);
417  virtual ~ServerChannelPutGetRequesterImpl() {}
418 
419  virtual void channelPutGetConnect(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet,
420  epics::pvData::Structure::const_shared_pointer const & putStructure,
421  epics::pvData::Structure::const_shared_pointer const & getStructure) OVERRIDE FINAL;
422  virtual void getGetDone(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet,
423  epics::pvData::PVStructure::shared_pointer const & pvStructure,
424  epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL;
425  virtual void getPutDone(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet,
426  epics::pvData::PVStructure::shared_pointer const & pvStructure,
427  epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL;
428  virtual void putGetDone(const epics::pvData::Status& status, ChannelPutGet::shared_pointer const & channelPutGet,
429  epics::pvData::PVStructure::shared_pointer const & pvStructure,
430  epics::pvData::BitSet::shared_pointer const & bitSet) OVERRIDE FINAL;
431  virtual void destroy() OVERRIDE FINAL;
432 
433  ChannelPutGet::shared_pointer getChannelPutGet();
434  virtual std::tr1::shared_ptr<ChannelRequest> getOperation() OVERRIDE FINAL { return getChannelPutGet(); }
435 
436  epics::pvData::PVStructure::shared_pointer getPutGetPVStructure();
437  epics::pvData::BitSet::shared_pointer getPutGetBitSet();
438 
439  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
440 private:
441  // Note: this forms a reference loop, which is broken in destroy()
442  ChannelPutGet::shared_pointer _channelPutGet;
443  epics::pvData::PVStructure::shared_pointer _pvPutStructure;
444  epics::pvData::BitSet::shared_pointer _pvPutBitSet;
445  epics::pvData::PVStructure::shared_pointer _pvGetStructure;
446  epics::pvData::BitSet::shared_pointer _pvGetBitSet;
447  epics::pvData::Status _status;
448 };
449 
450 
451 /****************************************************************************************/
452 /**
453  * Monitor request handler.
454  */
455 class ServerMonitorHandler : public AbstractServerResponseHandler
456 {
457 public:
458  ServerMonitorHandler(ServerContextImpl::shared_pointer const & context) :
459  AbstractServerResponseHandler(context, "Monitor request") {
460  }
461  virtual ~ServerMonitorHandler() {}
462 
463  virtual void handleResponse(osiSockAddr* responseFrom,
466 };
467 
468 
469 class ServerMonitorRequesterImpl :
470  public BaseChannelRequester,
471  public MonitorRequester,
472  public std::tr1::enable_shared_from_this<ServerMonitorRequesterImpl>
473 {
474 public:
475  typedef std::tr1::shared_ptr<ServerMonitorRequesterImpl> shared_pointer;
476  typedef std::tr1::shared_ptr<const ServerMonitorRequesterImpl> const_shared_pointer;
477 protected:
478  ServerMonitorRequesterImpl(ServerContextImpl::shared_pointer const & context,
479  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
480  Transport::shared_pointer const & transport);
481  void activate(epics::pvData::PVStructure::shared_pointer const & pvRequest);
482 public:
483  static shared_pointer create(ServerContextImpl::shared_pointer const & context,
484  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
485  Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest);
486  virtual ~ServerMonitorRequesterImpl() {}
487 
488  virtual void monitorConnect(const epics::pvData::Status& status,
489  Monitor::shared_pointer const & monitor,
490  epics::pvData::StructureConstPtr const & structure) OVERRIDE FINAL;
491  virtual void unlisten(Monitor::shared_pointer const & monitor) OVERRIDE FINAL;
492  virtual void monitorEvent(Monitor::shared_pointer const & monitor) OVERRIDE FINAL;
493  virtual void destroy() OVERRIDE FINAL;
494 
495  Monitor::shared_pointer getChannelMonitor();
496  virtual std::tr1::shared_ptr<ChannelRequest> getOperation() OVERRIDE FINAL { return std::tr1::shared_ptr<ChannelRequest>(); }
497 
498  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
499  void ack(size_t cnt);
500 private:
501  // Note: this forms a reference loop, which is broken in destroy()
502  Monitor::shared_pointer _channelMonitor;
503  epics::pvData::StructureConstPtr _structure;
504  epics::pvData::Status _status;
505  // when _pipeline==true
506  // _window_open + _window_closed.size() are together the congestion control window.
507  // _window_open are the number of elements which we can send w/o further ack's
508  size_t _window_open;
509  // The elements we have sent, but have not been acknowledged
510  typedef std::list<epics::pvData::MonitorElementPtr> window_t;
511  window_t _window_closed;
512  bool _unlisten;
513  bool _pipeline; // const after activate()
514 };
515 
516 
517 /****************************************************************************************/
518 /**
519  * Array request handler.
520  */
521 class ServerArrayHandler : public AbstractServerResponseHandler
522 {
523 public:
524  ServerArrayHandler(ServerContextImpl::shared_pointer const & context) :
525  AbstractServerResponseHandler(context, "Array request") {
526  }
527  virtual ~ServerArrayHandler() {}
528 
529  virtual void handleResponse(osiSockAddr* responseFrom,
532 };
533 
534 class ServerChannelArrayRequesterImpl :
535  public BaseChannelRequester,
536  public ChannelArrayRequester,
537  public std::tr1::enable_shared_from_this<ServerChannelArrayRequesterImpl>
538 {
539 public:
540  typedef std::tr1::shared_ptr<ServerChannelArrayRequesterImpl> shared_pointer;
541  typedef std::tr1::shared_ptr<const ServerChannelArrayRequesterImpl> const_shared_pointer;
542 protected:
543  ServerChannelArrayRequesterImpl(ServerContextImpl::shared_pointer const & context,
544  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
545  Transport::shared_pointer const & transport);
546  void activate(epics::pvData::PVStructure::shared_pointer const & pvRequest);
547 public:
548  static ChannelArrayRequester::shared_pointer create(ServerContextImpl::shared_pointer const & context,
549  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
550  Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest);
551  virtual ~ServerChannelArrayRequesterImpl() {}
552 
553  virtual void channelArrayConnect(const epics::pvData::Status& status,
554  ChannelArray::shared_pointer const & channelArray,
555  epics::pvData::Array::const_shared_pointer const & array) OVERRIDE FINAL;
556  virtual void getArrayDone(const epics::pvData::Status& status,
557  ChannelArray::shared_pointer const & channelArray,
558  epics::pvData::PVArray::shared_pointer const & pvArray) OVERRIDE FINAL;
559  virtual void putArrayDone(const epics::pvData::Status& status,
560  ChannelArray::shared_pointer const & channelArray) OVERRIDE FINAL;
561  virtual void setLengthDone(const epics::pvData::Status& status,
562  ChannelArray::shared_pointer const & channelArray) OVERRIDE FINAL;
563  virtual void getLengthDone(const epics::pvData::Status& status,
564  ChannelArray::shared_pointer const & channelArray,
565  std::size_t length) OVERRIDE FINAL;
566  virtual void destroy() OVERRIDE FINAL;
567 
568  ChannelArray::shared_pointer getChannelArray();
569  virtual std::tr1::shared_ptr<ChannelRequest> getOperation() OVERRIDE FINAL { return getChannelArray(); }
570 
571  epics::pvData::PVArray::shared_pointer getPVArray();
572  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
573 
574 private:
575  // Note: this forms a reference loop, which is broken in destroy()
576  ChannelArray::shared_pointer _channelArray;
577  epics::pvData::PVArray::shared_pointer _pvArray;
578 
579  std::size_t _length;
580  epics::pvData::Status _status;
581 };
582 
583 /****************************************************************************************/
584 /**
585  * Destroy request handler.
586  */
587 class ServerDestroyRequestHandler : public AbstractServerResponseHandler
588 {
589 public:
590  ServerDestroyRequestHandler(ServerContextImpl::shared_pointer const & context) :
591  AbstractServerResponseHandler(context, "Destroy request") {
592  }
593  virtual ~ServerDestroyRequestHandler() {}
594 
595  virtual void handleResponse(osiSockAddr* responseFrom,
598 private:
599 
600  void failureResponse(Transport::shared_pointer const & transport, pvAccessID ioid, const epics::pvData::Status& errorStatus);
601 };
602 
603 
604 /****************************************************************************************/
605 /**
606  * Cancel request handler.
607  */
608 class ServerCancelRequestHandler : public AbstractServerResponseHandler
609 {
610 public:
611  ServerCancelRequestHandler(ServerContextImpl::shared_pointer const & context) :
612  AbstractServerResponseHandler(context, "Cancel request") {
613  }
614  virtual ~ServerCancelRequestHandler() {}
615 
616  virtual void handleResponse(osiSockAddr* responseFrom,
619 private:
620 
621  void failureResponse(Transport::shared_pointer const & transport, pvAccessID ioid, const epics::pvData::Status& errorStatus);
622 };
623 
624 
625 /****************************************************************************************/
626 /**
627  * Process request handler.
628  */
629 class ServerProcessHandler : public AbstractServerResponseHandler
630 {
631 public:
632  ServerProcessHandler(ServerContextImpl::shared_pointer const & context) :
633  AbstractServerResponseHandler(context, "Process request") {
634  }
635  virtual ~ServerProcessHandler() {}
636 
637  virtual void handleResponse(osiSockAddr* responseFrom,
640 };
641 
642 class ServerChannelProcessRequesterImpl :
643  public BaseChannelRequester,
644  public ChannelProcessRequester,
645  public std::tr1::enable_shared_from_this<ServerChannelProcessRequesterImpl>
646 {
647 public:
648  typedef std::tr1::shared_ptr<ServerChannelProcessRequesterImpl> shared_pointer;
649  typedef std::tr1::shared_ptr<const ServerChannelProcessRequesterImpl> const_shared_pointer;
650 protected:
651  ServerChannelProcessRequesterImpl(ServerContextImpl::shared_pointer const & context,
652  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
653  Transport::shared_pointer const & transport);
654  void activate(epics::pvData::PVStructure::shared_pointer const & pvRequest);
655 public:
656  static ChannelProcessRequester::shared_pointer create(ServerContextImpl::shared_pointer const & context,
657  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
658  Transport::shared_pointer const & transport, epics::pvData::PVStructure::shared_pointer const & pvRequest);
659  virtual ~ServerChannelProcessRequesterImpl() {}
660 
661  virtual void channelProcessConnect(const epics::pvData::Status& status, ChannelProcess::shared_pointer const & channelProcess) OVERRIDE FINAL;
662  virtual void processDone(const epics::pvData::Status& status, ChannelProcess::shared_pointer const & channelProcess) OVERRIDE FINAL;
663  virtual void destroy() OVERRIDE FINAL;
664 
665  ChannelProcess::shared_pointer getChannelProcess();
666  virtual std::tr1::shared_ptr<ChannelRequest> getOperation() OVERRIDE FINAL { return getChannelProcess(); }
667 
668  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
669 
670 private:
671  // Note: this forms a reference loop, which is broken in destroy()
672  ChannelProcess::shared_pointer _channelProcess;
673  epics::pvData::Status _status;
674 };
675 
676 /****************************************************************************************/
677 /**
678  * Get field request handler.
679  */
680 class ServerGetFieldHandler : public AbstractServerResponseHandler
681 {
682 public:
683  ServerGetFieldHandler(ServerContextImpl::shared_pointer const & context) :
684  AbstractServerResponseHandler(context, "Get field request") {
685  }
686  virtual ~ServerGetFieldHandler() {}
687 
688  virtual void handleResponse(osiSockAddr* responseFrom,
691 private:
692  void getFieldFailureResponse(Transport::shared_pointer const & transport, const pvAccessID ioid, const epics::pvData::Status& errorStatus);
693 };
694 
695 class ServerGetFieldRequesterImpl :
696  public BaseChannelRequester,
697  public GetFieldRequester,
698  public std::tr1::enable_shared_from_this<ServerGetFieldRequesterImpl>
699 {
700 public:
701  typedef std::tr1::shared_ptr<ServerGetFieldRequesterImpl> shared_pointer;
702  typedef std::tr1::shared_ptr<const ServerGetFieldRequesterImpl> const_shared_pointer;
703 
704  ServerGetFieldRequesterImpl(ServerContextImpl::shared_pointer const & context,
705  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
706  Transport::shared_pointer const & transport);
707 
708  virtual std::tr1::shared_ptr<ChannelRequest> getOperation() OVERRIDE FINAL { return std::tr1::shared_ptr<ChannelRequest>(); }
709 
710  virtual ~ServerGetFieldRequesterImpl() {}
711  virtual void getDone(const epics::pvData::Status& status, epics::pvData::FieldConstPtr const & field) OVERRIDE FINAL;
712  virtual void destroy() OVERRIDE FINAL;
713  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
714 private:
715  bool done;
716  epics::pvData::Status _status;
717  epics::pvData::FieldConstPtr _field;
718 };
719 
720 class ServerGetFieldHandlerTransportSender : public TransportSender
721 {
722 public:
723  ServerGetFieldHandlerTransportSender(const pvAccessID ioid,const epics::pvData::Status& status, Transport::shared_pointer const & /*transport*/):
724  _ioid(ioid), _status(status) {
725 
726  }
727  virtual ~ServerGetFieldHandlerTransportSender() {}
728 
729  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL {
730  control->startMessage((epics::pvData::int8)CMD_GET_FIELD, sizeof(epics::pvData::int32)/sizeof(epics::pvData::int8));
731  buffer->putInt(_ioid);
732  _status.serialize(buffer, control);
733  }
734 
735 private:
736  const pvAccessID _ioid;
737  const epics::pvData::Status _status;
738 };
739 
740 
741 
742 /****************************************************************************************/
743 /**
744  * RPC handler.
745  */
746 class ServerRPCHandler : public AbstractServerResponseHandler
747 {
748 public:
749  ServerRPCHandler(ServerContextImpl::shared_pointer const & context) :
750  AbstractServerResponseHandler(context, "RPC request") {
751  }
752  virtual ~ServerRPCHandler() {}
753 
754  virtual void handleResponse(osiSockAddr* responseFrom,
757 };
758 
759 class ServerChannelRPCRequesterImpl :
760  public BaseChannelRequester,
761  public ChannelRPCRequester,
762  public std::tr1::enable_shared_from_this<ServerChannelRPCRequesterImpl>
763 {
764 public:
765  typedef std::tr1::shared_ptr<ServerChannelRPCRequesterImpl> shared_pointer;
766  typedef std::tr1::shared_ptr<const ServerChannelRPCRequesterImpl> const_shared_pointer;
767 protected:
768  ServerChannelRPCRequesterImpl(ServerContextImpl::shared_pointer const & context,
769  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
770  Transport::shared_pointer const & transport);
771  void activate(epics::pvData::PVStructure::shared_pointer const & pvRequest);
772 public:
773  static ChannelRPCRequester::shared_pointer create(ServerContextImpl::shared_pointer const & context,
774  std::tr1::shared_ptr<ServerChannel> const & channel, const pvAccessID ioid,
775  Transport::shared_pointer const & transport,epics::pvData::PVStructure::shared_pointer const & pvRequest);
776  virtual ~ServerChannelRPCRequesterImpl() {}
777 
778  virtual void channelRPCConnect(const epics::pvData::Status& status, ChannelRPC::shared_pointer const & channelRPC) OVERRIDE FINAL;
779  virtual void requestDone(const epics::pvData::Status& status,
780  ChannelRPC::shared_pointer const & channelRPC,
781  epics::pvData::PVStructure::shared_pointer const & pvResponse) OVERRIDE FINAL;
782  virtual void destroy() OVERRIDE FINAL;
783  /**
784  * @return the channelRPC
785  */
786  ChannelRPC::shared_pointer getChannelRPC();
787  virtual std::tr1::shared_ptr<ChannelRequest> getOperation() OVERRIDE FINAL { return getChannelRPC(); }
788 
789  virtual void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control) OVERRIDE FINAL;
790 private:
791  // Note: this forms a reference loop, which is broken in destroy()
792  ChannelRPC::shared_pointer _channelRPC;
793  epics::pvData::PVStructure::shared_pointer _pvResponse;
794  epics::pvData::Status _status;
795 };
796 
797 
798 /**
799  * PVAS request handler - main handler which dispatches requests to appropriate handlers.
800  */
801 class ServerResponseHandler : public ResponseHandler {
802 public:
803  ServerResponseHandler(ServerContextImpl::shared_pointer const & context);
804 
805  virtual ~ServerResponseHandler() {}
806 
807  virtual void handleResponse(osiSockAddr* responseFrom,
810 private:
811  ServerBadResponse handle_bad;
812 
813  ServerNoopResponse handle_beacon;
814  ServerConnectionValidationHandler handle_validation;
815  ServerEchoHandler handle_echo;
816  ServerSearchHandler handle_search;
817  AuthNZHandler handle_authnz;
818  ServerCreateChannelHandler handle_create;
819  ServerDestroyChannelHandler handle_destroy;
820  ServerGetHandler handle_get;
821  ServerPutHandler handle_put;
822  ServerPutGetHandler handle_putget;
823  ServerMonitorHandler handle_monitor;
824  ServerArrayHandler handle_array;
825  ServerDestroyRequestHandler handle_close;
826  ServerProcessHandler handle_process;
827  ServerGetFieldHandler handle_getfield;
828  ServerRPCHandler handle_rpc;
829  ServerCancelRequestHandler handle_cancel;
830  /**
831  * Table of response handlers for each command ID.
832  */
833  std::vector<ResponseHandler*> m_handlerTable;
834 
835 };
836 
837 }
838 }
839 
840 #endif /* RESPONSEHANDLERS_H_ */
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 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 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.
Connection validation message handler.
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 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 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 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 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 authNZMessage(epics::pvData::PVStructure::shared_pointer const &data)=0
Pass data to the active security plug-in session.
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 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.
#define OVERRIDE
Definition: pvAccess.h:55
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 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.
#define FINAL
Copyright - See the COPYRIGHT that is included with this distribution.
Definition: pvAccess.h:48
Destroy channel request handler.
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 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.
Search channel request handler.
PVAS request handler - main handler which dispatches requests to appropriate handlers.
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 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.
Create channel request handler.
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.