10 #ifdef epicsExportSharedSymbols
11 # define blockingUDPEpicsExportSharedSymbols
12 # undef epicsExportSharedSymbols
17 #include <epicsThread.h>
19 #include <pv/noDefaultMethods.h>
20 #include <pv/byteBuffer.h>
23 #include <pv/pvIntrospect.h>
25 #ifdef blockingUDPEpicsExportSharedSymbols
26 # define epicsExportSharedSymbols
27 # undef blockingUDPEpicsExportSharedSymbols
32 #include <pv/remote.h>
33 #include <pv/pvaConstants.h>
34 #include <pv/inetAddressUtil.h>
39 class ClientChannelImpl;
40 class BlockingUDPConnector;
42 enum InetAddressType { inetAddressType_all, inetAddressType_unicast, inetAddressType_broadcast_multicast };
44 class BlockingUDPTransport :
46 public TransportSendControl,
47 public epicsThreadRunable
49 EPICS_NOT_COPYABLE(BlockingUDPTransport)
51 POINTER_DEFINITIONS(BlockingUDPTransport);
53 static
size_t num_instances;
56 std::tr1::weak_ptr<BlockingUDPTransport> internal_this;
57 friend class BlockingUDPConnector;
58 BlockingUDPTransport(
bool serverFlag,
59 ResponseHandler::shared_pointer const & responseHandler,
60 SOCKET channel, osiSockAddr &bindAddress,
61 short remoteTransportRevision);
64 virtual ~BlockingUDPTransport();
66 virtual
bool isClosed() OVERRIDE FINAL {
70 virtual const osiSockAddr& getRemoteAddress() const OVERRIDE FINAL {
71 return _remoteAddress;
74 virtual const std::string& getRemoteName() const OVERRIDE FINAL {
78 virtual std::string getType() const OVERRIDE FINAL {
82 virtual std::size_t getReceiveBufferSize() const OVERRIDE FINAL {
83 return _receiveBuffer.getSize();
86 virtual epics::pvData::int16 getPriority() const OVERRIDE FINAL {
90 virtual void setRemoteTransportReceiveBufferSize(
91 std::size_t ) OVERRIDE FINAL {
95 virtual void setRemoteTransportSocketReceiveBufferSize(
96 std::size_t ) OVERRIDE FINAL {
100 virtual bool verify(epics::pvData::int32 ) OVERRIDE FINAL {
105 virtual void verified(epics::pvData::Status
const & ) OVERRIDE FINAL {
109 virtual void authNZMessage(epics::pvData::PVStructure::shared_pointer
const & data) OVERRIDE FINAL {
114 virtual void setByteOrder(
int byteOrder) OVERRIDE FINAL {
116 _receiveBuffer.setEndianess(byteOrder);
119 _sendBuffer.setEndianess(byteOrder);
122 virtual void enqueueSendRequest(TransportSender::shared_pointer
const & sender) OVERRIDE FINAL;
124 virtual void flushSendQueue() OVERRIDE FINAL;
128 virtual
void close() OVERRIDE FINAL;
130 virtual
void ensureData(std::
size_t size) OVERRIDE FINAL;
132 virtual
bool directSerialize(epics::pvData::ByteBuffer* , const
char* ,
133 std::
size_t , std::
size_t ) OVERRIDE FINAL
138 virtual bool directDeserialize(epics::pvData::ByteBuffer* ,
char* ,
139 std::size_t , std::size_t ) OVERRIDE FINAL
144 virtual void startMessage(epics::pvData::int8 command, std::size_t ensureCapacity, epics::pvData::int32 payloadSize = 0) OVERRIDE FINAL;
145 virtual
void endMessage() OVERRIDE FINAL;
147 virtual
void flush(
bool ) OVERRIDE FINAL {
151 virtual void setRecipient(
const osiSockAddr& sendTo) OVERRIDE FINAL {
152 _sendToEnabled =
true;
156 void setLocalMulticastAddress(
const osiSockAddr& sendTo) {
157 _localMulticastAddressEnabled =
true;
158 _localMulticastAddress = sendTo;
161 bool hasLocalMulticastAddress()
const {
162 return _localMulticastAddressEnabled;
165 const osiSockAddr& getLocalMulticastAddress()
const {
166 return _localMulticastAddress;
169 virtual void flushSerializeBuffer() OVERRIDE FINAL {
173 virtual void ensureBuffer(std::size_t ) OVERRIDE FINAL {
177 virtual void cachedSerialize(
178 const std::tr1::shared_ptr<const epics::pvData::Field>& field, epics::pvData::ByteBuffer* buffer) OVERRIDE FINAL
181 field->serialize(buffer,
this);
184 virtual std::tr1::shared_ptr<const epics::pvData::Field>
185 cachedDeserialize(epics::pvData::ByteBuffer* buffer) OVERRIDE FINAL
189 return epics::pvData::getFieldCreate()->deserialize(buffer,
this);
192 virtual bool acquire(std::tr1::shared_ptr<ClientChannelImpl>
const & ) OVERRIDE FINAL
197 virtual void release(pvAccessID ) OVERRIDE FINAL {}
203 void setIgnoredAddresses(
const InetAddrVector& addresses) {
204 _ignoredAddresses = addresses;
211 const InetAddrVector& getIgnoredAddresses()
const {
212 return _ignoredAddresses;
219 void setTappedNIF(
const InetAddrVector& addresses) {
220 _tappedNIF = addresses;
227 const InetAddrVector& getTappedNIF()
const {
231 bool send(
const char* buffer,
size_t length,
const osiSockAddr& address);
233 bool send(epics::pvData::ByteBuffer* buffer,
const osiSockAddr& address);
235 bool send(epics::pvData::ByteBuffer* buffer, InetAddressType target = inetAddressType_all);
241 const InetAddrVector& getSendAddresses() {
242 return _sendAddresses;
249 const osiSockAddr* getBindAddress()
const {
250 return &_bindAddress;
253 bool isBroadcastAddress(
const osiSockAddr* address,
const InetAddrVector& broadcastAddresses)
255 for (
size_t i = 0; i < broadcastAddresses.size(); i++)
256 if (broadcastAddresses[i].ia.sin_addr.s_addr == address->ia.sin_addr.s_addr)
262 void setSendAddresses(InetAddrVector& addresses,
std::vector<bool>& address_types) {
263 _sendAddresses.
swap(addresses);
264 _isSendAddressUnicast.swap(address_types);
267 void join(
const osiSockAddr & mcastAddr,
const osiSockAddr & nifAddr);
269 void setMutlicastNIF(
const osiSockAddr & nifAddr,
bool loopback);
272 AtomicBoolean _closed;
277 ResponseHandler::shared_pointer _responseHandler;
279 virtual void run() OVERRIDE FINAL;
282 bool processBuffer(Transport::shared_pointer const & transport, osiSockAddr& fromAddress, epics::pvData::ByteBuffer* receiveBuffer);
284 void close(
bool waitForThreadToComplete);
304 osiSockAddr _bindAddress;
309 osiSockAddr _remoteAddress;
310 std::
string _remoteName;
315 InetAddrVector _sendAddresses;
317 std::vector<
bool> _isSendAddressUnicast;
322 InetAddrVector _ignoredAddresses;
327 InetAddrVector _tappedNIF;
338 osiSockAddr _localMulticastAddress;
339 bool _localMulticastAddressEnabled;
344 epics::pvData::ByteBuffer _receiveBuffer;
349 epics::pvData::ByteBuffer _sendBuffer;
354 int _lastMessageStartPosition;
359 epics::pvData::Mutex _mutex;
360 epics::pvData::Mutex _sendMutex;
365 epics::auto_ptr<epicsThread> _thread;
367 epics::pvData::int8 _clientServerWithEndianFlag;
371 class BlockingUDPConnector{
373 POINTER_DEFINITIONS(BlockingUDPConnector);
375 BlockingUDPConnector(
bool serverFlag) :_serverFlag(serverFlag) {}
380 BlockingUDPTransport::shared_pointer connect(
381 ResponseHandler::shared_pointer
const & responseHandler,
382 osiSockAddr& bindAddress,
383 epics::pvData::int8 transportRevision);
392 EPICS_NOT_COPYABLE(BlockingUDPConnector)
397 void initializeUDPTransports(
399 BlockingUDPTransportVector& udpTransports,
400 const IfaceNodeVector& ifaceList,
401 const ResponseHandler::shared_pointer& responseHandler,
402 BlockingUDPTransport::shared_pointer& sendTransport,
403 epics::pvData::int32& listenPort,
404 bool autoAddressList,
const epics::pvData::int16 PVA_DEFAULT_PRIORITY
Default priority (corresponds to POSIX SCHED_OTHER)
void swap(vector &__x) noexcept
basic_string< char > string