This is Unofficial EPICS BASE Doxygen Site
beaconEmitter.cpp
Go to the documentation of this file.
1 
7 #include <algorithm>
8 
9 #define epicsExportSharedSymbols
10 #include <pv/beaconEmitter.h>
11 #include <pv/serializationHelper.h>
12 #include <pv/logger.h>
13 #include <pv/serverContextImpl.h>
14 
15 using namespace std;
16 using namespace epics::pvData;
17 
18 namespace epics {
19 namespace pvAccess {
20 
21 const float BeaconEmitter::EPICS_PVA_MIN_BEACON_PERIOD = 1.0;
22 const float BeaconEmitter::EPICS_PVA_MIN_BEACON_COUNT_LIMIT = 3.0;
23 
24 //BeaconEmitter::BeaconEmitter(Transport::shared_pointer const & transport, ServerContextImpl::shared_pointer const & context) :
25 BeaconEmitter::BeaconEmitter(std::string const & protocol,
26  Transport::shared_pointer const & transport, std::tr1::shared_ptr<ServerContextImpl>& context) :
27  _protocol(protocol),
28  _transport(transport),
29  _beaconSequenceID(0),
30  _guid(context->getGUID()),
31  _fastBeaconPeriod(std::max(context->getBeaconPeriod(), EPICS_PVA_MIN_BEACON_PERIOD)),
32  _slowBeaconPeriod(std::max(180.0, _fastBeaconPeriod)), // TODO configurable
33  _beaconCountLimit((int16)std::max(10.0f, EPICS_PVA_MIN_BEACON_COUNT_LIMIT)), // TODO configurable
34  _serverAddress(*(context->getServerInetAddress())),
35  _serverPort(context->getServerPort()),
36  _serverStatusProvider(context->getBeaconServerStatusProvider()),
37  _timer(context->getTimer())
38 {
39 }
40 
42 {
43  // shared_from_this is not yet allows in destructor
44  // be sure to call destroy() first !!!
45  // destroy();
46 }
47 
49 {
50  // get server status
51  PVField::shared_pointer serverStatus;
52  if(_serverStatusProvider.get())
53  {
54  try
55  {
56  serverStatus = _serverStatusProvider->getServerStatusData();
57  }
58  catch (...) {
59  // we have to proctect internal code from external implementation...
60  LOG(logLevelDebug, "BeaconServerStatusProvider implementation thrown an exception.");
61  }
62  }
63 
64  // send beacon
65  control->startMessage((int8)CMD_BEACON, 12+2+2+16+2);
66 
67  buffer->put(_guid.value, 0, sizeof(_guid.value));
68 
69  // TODO qos/flags (e.g. multicast/unicast)
70  buffer->putByte(0);
71 
72  buffer->putByte(_beaconSequenceID);
73 
74  // TODO for now fixed changeCount
75  buffer->putShort(0);
76 
77  // NOTE: is it possible (very likely) that address is any local address ::ffff:0.0.0.0
78  encodeAsIPv6Address(buffer, &_serverAddress);
79  buffer->putShort((int16)_serverPort);
80 
81  SerializeHelper::serializeString(_protocol, buffer, control);
82 
83  if (serverStatus)
84  {
85  // introspection interface + data
86  serverStatus->getField()->serialize(buffer, control);
87  serverStatus->serialize(buffer, control);
88  }
89  else
90  {
92  }
93  control->flush(true);
94 
95  // increment beacon sequence ID
96  _beaconSequenceID++;
97 
98  reschedule();
99 }
100 
102 {
103  //noop
104 }
105 
107 {
108  Timer::shared_pointer timer(_timer.lock());
109  if(timer)
110  timer->cancel(shared_from_this());
111 }
112 
114 {
115  Timer::shared_pointer timer(_timer.lock());
116  if(timer)
117  timer->scheduleAfterDelay(shared_from_this(), 0.0);
118 }
119 
121 {
122  const double period = (_beaconSequenceID >= _beaconCountLimit) ? _slowBeaconPeriod : _fastBeaconPeriod;
123  if (period > 0)
124  {
125  Timer::shared_pointer timer(_timer.lock());
126  if(timer)
127  timer->scheduleAfterDelay(shared_from_this(), period);
128  }
129 }
130 
132 {
133  _transport->enqueueSendRequest(shared_from_this());
134 }
135 
136 }
137 }
int8_t int8
Definition: pvType.h:75
#define max(x, y)
Definition: flexdef.h:81
void send(epics::pvData::ByteBuffer *buffer, TransportSendControl *control)
static void serializeNullField(epics::pvData::ByteBuffer *buffer, epics::pvData::SerializableControl *control)
Definition: memory.hpp:41
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
virtual void flush(bool lastMessageCompleted)=0
#define LOG(level, format,...)
Definition: logger.h:48
pvData
Definition: monitor.h:428
void encodeAsIPv6Address(ByteBuffer *buffer, const osiSockAddr *address)
EPICS_ALWAYS_INLINE void putByte(int8 value)
Definition: byteBuffer.h:525
This class implements a Bytebuffer that is like the java.nio.ByteBuffer.
Definition: byteBuffer.h:233
static void serializeString(const std::string &value, ByteBuffer *buffer, SerializableControl *flusher)
void cancel()
Definition: timer.cpp:135
int16_t int16
Definition: pvType.h:79
virtual void startMessage(epics::pvData::int8 command, std::size_t ensureCapacity, epics::pvData::int32 payloadSize=0)=0
EPICS_ALWAYS_INLINE void putShort(int16 value)
Definition: byteBuffer.h:531