diff --git a/.cproject b/.cproject
index e91f269..0e0c996 100644
--- a/.cproject
+++ b/.cproject
@@ -307,7 +307,6 @@
make
-
all
true
true
@@ -315,7 +314,6 @@
make
-
clean
true
true
@@ -323,11 +321,20 @@
make
+
uninstall
true
true
false
+
+ make
+
+ clean all DEBUG=1
+ true
+ true
+ false
+
diff --git a/configure/CONFIG_SITE b/configure/CONFIG_SITE
index 287667b..7f70b02 100644
--- a/configure/CONFIG_SITE
+++ b/configure/CONFIG_SITE
@@ -24,4 +24,11 @@
# take effect.
#IOCS_APPL_TOP =
-USR_LDFLAGS += -lpthread
+ifeq ($(DEBUG),1)
+ DEBUG_CFLAGS=-O0 -g -ggdb
+endif
+
+ifeq ($(EPICS_HOST_ARCH),linux-x86)
+ USR_LDFLAGS += -lpthread
+endif
+
diff --git a/pvAccessApp/Makefile b/pvAccessApp/Makefile
index 687ee94..ce364c2 100644
--- a/pvAccessApp/Makefile
+++ b/pvAccessApp/Makefile
@@ -67,6 +67,7 @@ LIBSRCS += blockingTCPConnector.cpp
LIBSRCS += blockingServerTCPTransport.cpp
LIBSRCS += blockingTCPAcceptor.cpp
LIBSRCS += channelSearchManager.cpp
+LIBSRCS += abstractResponseHandler.cpp
SRC_DIRS += $(PVACCESS)/remoteClient
diff --git a/pvAccessApp/remote/abstractResponseHandler.cpp b/pvAccessApp/remote/abstractResponseHandler.cpp
new file mode 100644
index 0000000..2d5f0b3
--- /dev/null
+++ b/pvAccessApp/remote/abstractResponseHandler.cpp
@@ -0,0 +1,42 @@
+/*
+ * abstractResponseHandler.cpp
+ *
+ * Created on: Jan 10, 2011
+ * Author: Miha Vitorovic
+ */
+
+#include "remote.h"
+#include "hexDump.h"
+
+#include
+
+#include
+
+#include
+
+using std::ostringstream;
+using std::hex;
+
+using namespace epics::pvData;
+
+namespace epics {
+ namespace pvAccess {
+
+ void AbstractResponseHandler::handleResponse(osiSockAddr* responseFrom,
+ Transport* transport, int8 version, int8 command,
+ int payloadSize, ByteBuffer* payloadBuffer) {
+ if(_debug) {
+ char ipAddrStr[48];
+ ipAddrToDottedIP(&responseFrom->ia, ipAddrStr, sizeof(ipAddrStr));
+
+ ostringstream prologue;
+ prologue<<"Message [0x"<getArray(),
+ payloadBuffer->getPosition(), payloadSize);
+ }
+ }
+ }
+}
diff --git a/pvAccessApp/remote/blockingServerTCPTransport.cpp b/pvAccessApp/remote/blockingServerTCPTransport.cpp
index 9048920..042a2b8 100644
--- a/pvAccessApp/remote/blockingServerTCPTransport.cpp
+++ b/pvAccessApp/remote/blockingServerTCPTransport.cpp
@@ -52,7 +52,7 @@ namespace epics {
if(_channels->size()==0) return;
char ipAddrStr[64];
- ipAddrToA(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
+ ipAddrToDottedIP(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
errlogSevPrintf(
errlogInfo,
diff --git a/pvAccessApp/remote/blockingTCPAcceptor.cpp b/pvAccessApp/remote/blockingTCPAcceptor.cpp
index c5bfcb7..10c5f21 100644
--- a/pvAccessApp/remote/blockingTCPAcceptor.cpp
+++ b/pvAccessApp/remote/blockingTCPAcceptor.cpp
@@ -51,7 +51,7 @@ namespace epics {
char strBuffer[64];
char ipAddrStr[48];
- ipAddrToA(&_bindAddress->ia, ipAddrStr, sizeof(ipAddrStr));
+ ipAddrToDottedIP(&_bindAddress->ia, ipAddrStr, sizeof(ipAddrStr));
int tryCount = 0;
while(tryCount<2) {
@@ -150,7 +150,7 @@ namespace epics {
void BlockingTCPAcceptor::handleEvents() {
// rise level if port is assigned dynamically
char ipAddrStr[48];
- ipAddrToA(&_bindAddress->ia, ipAddrStr, sizeof(ipAddrStr));
+ ipAddrToDottedIP(&_bindAddress->ia, ipAddrStr, sizeof(ipAddrStr));
errlogSevPrintf(errlogInfo, "Accepting connections at %s.",
ipAddrStr);
@@ -183,7 +183,8 @@ namespace epics {
_serverSocketChannel, &address.sa, &len);
if(newClient!=INVALID_SOCKET) {
// accept succeeded
- ipAddrToA(&address.ia, ipAddrStr, sizeof(ipAddrStr));
+ ipAddrToDottedIP(&address.ia, ipAddrStr,
+ sizeof(ipAddrStr));
errlogSevPrintf(errlogInfo,
"Accepted connection from CA client: %s",
ipAddrStr);
@@ -273,7 +274,8 @@ namespace epics {
if(_serverSocketChannel!=INVALID_SOCKET) {
char ipAddrStr[48];
- ipAddrToA(&_bindAddress->ia, ipAddrStr, sizeof(ipAddrStr));
+ ipAddrToDottedIP(&_bindAddress->ia, ipAddrStr,
+ sizeof(ipAddrStr));
errlogSevPrintf(errlogInfo,
"Stopped accepting connections at %s.", ipAddrStr);
diff --git a/pvAccessApp/remote/blockingTCPConnector.cpp b/pvAccessApp/remote/blockingTCPConnector.cpp
index 1bd09d4..5c3b021 100644
--- a/pvAccessApp/remote/blockingTCPConnector.cpp
+++ b/pvAccessApp/remote/blockingTCPConnector.cpp
@@ -106,8 +106,17 @@ namespace epics {
ipAddrStr);
socket = tryConnect(address, 3);
- if (socket == INVALID_SOCKET)
- return 0;
+ // verify
+ if(socket==INVALID_SOCKET) {
+ errlogSevPrintf(
+ errlogMajor,
+ "Connection to CA server %s failed.",
+ ipAddrStr);
+ ostringstream temp;
+ temp<<"Failed to verify TCP connection to '"<waitUntilVerified(3.0)) {
transport->close(true);
errlogSevPrintf(
- errlogInfo,
+ errlogMinor,
"Connection to CA server %s failed to be validated, closing it.",
ipAddrStr);
ostringstream temp;
diff --git a/pvAccessApp/remote/remote.h b/pvAccessApp/remote/remote.h
index f5129d1..8a8aaea 100644
--- a/pvAccessApp/remote/remote.h
+++ b/pvAccessApp/remote/remote.h
@@ -11,7 +11,7 @@
#include "caConstants.h"
#include "transportRegistry.h"
#include "introspectionRegistry.h"
-#include "serverContext.h"
+#include "configuration.h"
#include
#include
@@ -32,42 +32,42 @@ namespace epics {
};
enum QoS {
- /**
- * Default behavior.
- */
- DEFAULT = 0x00,
- /**
- * Require reply (acknowledgment for reliable operation).
- */
- REPLY_REQUIRED = 0x01,
- /**
- * Best-effort option (no reply).
- */
- BESY_EFFORT = 0x02,
- /**
- * Process option.
- */
- PROCESS = 0x04,
- /**
- * Initialize option.
- */
- INIT = 0x08,
- /**
- * Destroy option.
- */
- DESTROY = 0x10,
- /**
- * Share data option.
- */
- SHARE = 0x20,
- /**
- * Get.
- */
- GET = 0x40,
- /**
- * Get-put.
- */
- GET_PUT =0x80
+ /**
+ * Default behavior.
+ */
+ DEFAULT = 0x00,
+ /**
+ * Require reply (acknowledgment for reliable operation).
+ */
+ REPLY_REQUIRED = 0x01,
+ /**
+ * Best-effort option (no reply).
+ */
+ BESY_EFFORT = 0x02,
+ /**
+ * Process option.
+ */
+ PROCESS = 0x04,
+ /**
+ * Initialize option.
+ */
+ INIT = 0x08,
+ /**
+ * Destroy option.
+ */
+ DESTROY = 0x10,
+ /**
+ * Share data option.
+ */
+ SHARE = 0x20,
+ /**
+ * Get.
+ */
+ GET = 0x40,
+ /**
+ * Get-put.
+ */
+ GET_PUT = 0x80
};
typedef int32 pvAccessID;
@@ -253,6 +253,35 @@ namespace epics {
};
+ class Channel;
+
+ /**
+ * Not public IF, used by Transports, etc.
+ */
+ class Context {
+ public:
+ virtual ~Context() {
+ }
+ /**
+ * Get timer.
+ * @return timer.
+ */
+ virtual Timer* getTimer() = 0;
+
+ /**
+ * Get transport (virtual circuit) registry.
+ * @return transport (virtual circuit) registry.
+ */
+ virtual TransportRegistry* getTransportRegistry() = 0;
+
+ virtual Channel* getChannel(pvAccessID id) = 0;
+
+ virtual Transport* getSearchTransport() = 0;
+
+ virtual Configuration* getConfiguration() = 0;
+
+ };
+
/**
* Interface defining response handler.
* @author Matej Sekoranja
@@ -260,6 +289,10 @@ namespace epics {
*/
class ResponseHandler {
public:
+ ResponseHandler(Context* context) :
+ _context(context) {
+ }
+
virtual ~ResponseHandler() {
}
@@ -277,6 +310,9 @@ namespace epics {
handleResponse(osiSockAddr* responseFrom, Transport* transport,
int8 version, int8 command, int payloadSize,
epics::pvData::ByteBuffer* payloadBuffer) =0;
+
+ protected:
+ Context* _context;
};
/**
@@ -289,9 +325,10 @@ namespace epics {
/**
* @param description
*/
- AbstractResponseHandler(String description) :
- _description(description), _debug(true) {
- //debug = System.getProperties().containsKey(CAConstants.CAJ_DEBUG);
+ AbstractResponseHandler(Context* context, String description) :
+ ResponseHandler(context), _description(description), _debug(
+ _context->getConfiguration()->getPropertyAsBoolean(
+ "PVACCESS_DEBUG", false)) {
}
virtual ~AbstractResponseHandler() {
@@ -373,33 +410,6 @@ namespace epics {
};
- class Channel;
-
- /**
- * Not public IF, used by Transports, etc.
- */
- class Context {
- public:
- virtual ~Context() {
- }
- /**
- * Get timer.
- * @return timer.
- */
- virtual Timer* getTimer() =0;
-
- /**
- * Get transport (virtual circuit) registry.
- * @return transport (virtual circuit) registry.
- */
- virtual TransportRegistry* getTransportRegistry() =0;
-
- virtual Channel* getChannel(pvAccessID id) = 0;
-
- virtual Transport* getSearchTransport() = 0;
-
- };
-
/**
* Interface defining reference counting transport IF.
* @author Matej Sekoranja
@@ -474,7 +484,8 @@ namespace epics {
* @param sid preallocated channel SID.
* @param channel channel to register.
*/
- virtual void registerChannel(pvAccessID sid, ServerChannel* channel) =0;
+ virtual void
+ registerChannel(pvAccessID sid, ServerChannel* channel) =0;
/**
* Unregister a new channel (and deallocates its handle).
@@ -495,44 +506,44 @@ namespace epics {
*/
virtual int getChannelCount() =0;
};
-
+
/**
* A request that expects an response.
- * Responses identified by its I/O ID.
+ * Responses identified by its I/O ID.
* This interface needs to be extended (to provide method called on response).
* @author Matej Sekoranja
*/
class ResponseRequest {
- public:
-
- /**
- * Get I/O ID.
- * @return ioid
- */
- virtual pvAccessID getIOID() = 0;
-
- /**
- * Timeout notification.
- */
- virtual void timeout() = 0;
-
- /**
- * Cancel response request (always to be called to complete/destroy).
- */
- virtual void cancel() = 0;
-
- /**
- * Report status to clients (e.g. disconnected).
- * @param status to report.
- */
- virtual void reportStatus(epics::pvData::Status* status) = 0;
-
- /**
- * Get request requester.
- * @return request requester.
- */
- virtual epics::pvData::Requester* getRequester() = 0;
- };
+ public:
+
+ /**
+ * Get I/O ID.
+ * @return ioid
+ */
+ virtual pvAccessID getIOID() = 0;
+
+ /**
+ * Timeout notification.
+ */
+ virtual void timeout() = 0;
+
+ /**
+ * Cancel response request (always to be called to complete/destroy).
+ */
+ virtual void cancel() = 0;
+
+ /**
+ * Report status to clients (e.g. disconnected).
+ * @param status to report.
+ */
+ virtual void reportStatus(epics::pvData::Status* status) = 0;
+
+ /**
+ * Get request requester.
+ * @return request requester.
+ */
+ virtual epics::pvData::Requester* getRequester() = 0;
+ };
}
}
diff --git a/pvAccessApp/server/responseHandlers.cpp b/pvAccessApp/server/responseHandlers.cpp
index f191c32..fe57284 100644
--- a/pvAccessApp/server/responseHandlers.cpp
+++ b/pvAccessApp/server/responseHandlers.cpp
@@ -24,23 +24,6 @@ using namespace epics::pvData;
namespace epics {
namespace pvAccess {
- void AbstractResponseHandler::handleResponse(osiSockAddr* responseFrom,
- Transport* transport, int8 version, int8 command,
- int payloadSize, ByteBuffer* payloadBuffer) {
- if(_debug) {
- char ipAddrStr[48];
- ipAddrToDottedIP(&responseFrom->ia, ipAddrStr, sizeof(ipAddrStr));
-
- ostringstream prologue;
- prologue<<"Message [0x"<getArray(),
- payloadBuffer->getPosition(), payloadSize);
- }
- }
-
void BadResponse::handleResponse(osiSockAddr* responseFrom,
Transport* transport, int8 version, int8 command,
int payloadSize, ByteBuffer* payloadBuffer) {
@@ -57,15 +40,15 @@ namespace epics {
}
ServerResponseHandler::ServerResponseHandler(ServerContextImpl* context) :
- _context(context) {
+ ResponseHandler(context) {
BadResponse* badResponse = new BadResponse(context);
_handlerTable = new ResponseHandler*[HANDLER_TABLE_LENGTH];
// TODO add real handlers, as they are developed
- _handlerTable[0] = new NoopResponse(_context, "Beacon");
- _handlerTable[1] = new ConnectionValidationHandler(_context);
- _handlerTable[2] = new EchoHandler(_context);
+ _handlerTable[0] = new NoopResponse(context, "Beacon");
+ _handlerTable[1] = new ConnectionValidationHandler(context);
+ _handlerTable[2] = new EchoHandler(context);
_handlerTable[3] = badResponse;
_handlerTable[4] = badResponse;
_handlerTable[5] = badResponse;
diff --git a/pvAccessApp/server/responseHandlers.h b/pvAccessApp/server/responseHandlers.h
index afbcdba..7aeab36 100644
--- a/pvAccessApp/server/responseHandlers.h
+++ b/pvAccessApp/server/responseHandlers.h
@@ -8,6 +8,7 @@
#ifndef RESPONSEHANDLERS_H_
#define RESPONSEHANDLERS_H_
+#include "serverContext.h"
#include "remote.h"
namespace epics {
@@ -25,13 +26,11 @@ namespace epics {
*/
AbstractServerResponseHandler(ServerContextImpl* context,
String description) :
- AbstractResponseHandler(description), _context(context) {
+ AbstractResponseHandler(context, description) {
}
virtual ~AbstractServerResponseHandler() {
}
- protected:
- ServerContextImpl* _context;
};
/**
@@ -77,11 +76,6 @@ namespace epics {
*/
ResponseHandler** _handlerTable;
- /**
- * Context instance.
- */
- ServerContextImpl* _context;
-
};
/**
diff --git a/pvAccessApp/server/serverContext.h b/pvAccessApp/server/serverContext.h
index d535616..c01d52e 100644
--- a/pvAccessApp/server/serverContext.h
+++ b/pvAccessApp/server/serverContext.h
@@ -8,11 +8,12 @@
#ifndef SERVERCONTEXT_H_
#define SERVERCONTEXT_H_
+#include "remote.h"
+
namespace epics {
namespace pvAccess {
-
- class ServerContextImpl {
+ class ServerContextImpl : public Context {
};
diff --git a/pvAccessApp/utils/growingCircularBuffer.h b/pvAccessApp/utils/growingCircularBuffer.h
index 6a993a1..63bb242 100644
--- a/pvAccessApp/utils/growingCircularBuffer.h
+++ b/pvAccessApp/utils/growingCircularBuffer.h
@@ -28,8 +28,8 @@ namespace epics {
* Create a GrowingCircularBuffer with the given capacity.
**/
GrowingCircularBuffer(size_t capacity = 16) :
- _elements(new T[capacity]), _takePointer(0), _putPointer(0), _count(0), _size(capacity)
- {
+ _elements(new T[capacity]), _takePointer(0), _putPointer(0),
+ _count(0), _size(capacity) {
}
~GrowingCircularBuffer() {
@@ -94,13 +94,9 @@ namespace epics {
size_t length);
};
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * g++ requires template definition inside a header file.
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
template
- void GrowingCircularBuffer::arraycopy(T* src, size_t srcPos, T* dest,
- size_t destPos, size_t length) {
+ void GrowingCircularBuffer::arraycopy(T* src, size_t srcPos,
+ T* dest, size_t destPos, size_t length) {
if(srcPos=0; i--)
dest[destPos+i] = src[srcPos+i];
@@ -111,17 +107,16 @@ namespace epics {
template
bool GrowingCircularBuffer::insert(const T x) {
- if (_count == _size)
- {
+ if(_count==_size) {
// we are full, grow by factor 2
- T* newElements = new T[_size * 2];
+ T* newElements = new T[_size*2];
// invariant: _takePointer < _size
- size_t split = _size - _takePointer;
- if (split > 0)
- arraycopy(_elements, _takePointer, newElements, 0, split);
- if (_takePointer != 0)
- arraycopy(_elements, 0, newElements, split, _putPointer);
+ size_t split = _size-_takePointer;
+ if(split>0) arraycopy(_elements, _takePointer, newElements, 0,
+ split);
+ if(_takePointer!=0) arraycopy(_elements, 0, newElements, split,
+ _putPointer);
_takePointer = 0;
_putPointer = _size;
@@ -132,8 +127,8 @@ namespace epics {
_count++;
_elements[_putPointer] = x;
- if (++_putPointer >= _size) _putPointer = 0;
- return _count == 1;
+ if(++_putPointer>=_size) _putPointer = 0;
+ return _count==1;
}
template
@@ -146,6 +141,141 @@ namespace epics {
return old;
}
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /**
+ * Template specialization for pointers.
+ * Implementation of circular FIFO unbouded buffer.
+ * Instance is not thread safe.
+ * @author Miha Vitorovic
+ */
+ template
+ class GrowingCircularBuffer {
+ public:
+
+ /**
+ * Create a GrowingCircularBuffer with the given capacity.
+ **/
+ GrowingCircularBuffer(size_t capacity = 16) :
+ _elements(new T*[capacity]), _takePointer(0), _putPointer(0),
+ _count(0), _size(capacity) {
+ }
+
+ ~GrowingCircularBuffer() {
+ delete[] _elements;
+ }
+
+ /**
+ * Get number of elements in the buffer.
+ * @return number of elements in the buffer.
+ */
+ inline size_t size() {
+ return _count;
+ }
+
+ /**
+ * Get current buffer capacity.
+ * @return buffer current capacity.
+ */
+ inline size_t capacity() {
+ return _size;
+ }
+
+ /**
+ * Insert a new element in to the buffer.
+ * If buffer full the buffer is doubled.
+ *
+ * @param x element to insert.
+ * @return true if first element.
+ */
+ bool insert(const T* x);
+
+ /**
+ * Extract the oldest element from the buffer.
+ * @return the oldest element from the buffer.
+ */
+ T* extract();
+
+ private:
+ /**
+ * Array (circular buffer) of elements.
+ */
+ T** _elements;
+
+ /**
+ * Take (read) pointer.
+ */
+ size_t _takePointer;
+
+ /**
+ * Put (write) pointer.
+ */
+ size_t _putPointer;
+
+ /**
+ * Number of elements in the buffer.
+ */
+ size_t _count;
+
+ size_t _size;
+
+ void arraycopy(T** src, size_t srcPos, T** dest, size_t destPos,
+ size_t length);
+ };
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * g++ requires template definition inside a header file.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ template
+ void GrowingCircularBuffer::arraycopy(T** src, size_t srcPos,
+ T** dest, size_t destPos, size_t length) {
+ if(srcPos=0; i--)
+ dest[destPos+i] = src[srcPos+i];
+ else
+ for(size_t i = 0; i
+ bool GrowingCircularBuffer::insert(const T* x) {
+ if(_count==_size) {
+ // we are full, grow by factor 2
+ T** newElements = new T*[_size*2];
+
+ // invariant: _takePointer < _size
+ size_t split = _size-_takePointer;
+ if(split>0) arraycopy(_elements, _takePointer, newElements, 0,
+ split);
+ if(_takePointer!=0) arraycopy(_elements, 0, newElements, split,
+ _putPointer);
+
+ _takePointer = 0;
+ _putPointer = _size;
+ _size *= 2;
+ delete[] _elements;
+ _elements = newElements;
+ }
+ _count++;
+
+ _elements[_putPointer] = const_cast(x);
+ if(++_putPointer>=_size) _putPointer = 0;
+ return _count==1;
+ }
+
+ template
+ T* GrowingCircularBuffer::extract() {
+ if(_count==0) return NULL;
+
+ _count--;
+ T* old = _elements[_takePointer];
+ if(++_takePointer>=_size) _takePointer = 0;
+ return old;
+ }
+
}
}
#endif /* GROWINGCIRCULARBUFFER_H_ */
diff --git a/pvAccessApp/utils/inetAddressUtil.cpp b/pvAccessApp/utils/inetAddressUtil.cpp
index e9ab30f..18e1d18 100644
--- a/pvAccessApp/utils/inetAddressUtil.cpp
+++ b/pvAccessApp/utils/inetAddressUtil.cpp
@@ -32,14 +32,25 @@ using namespace epics::pvData;
namespace epics {
namespace pvAccess {
+ void addDefaultBroadcastAddress(InetAddrVector* v, in_port_t p) {
+ osiSockAddr* pNewNode = new osiSockAddr;
+ pNewNode->ia.sin_family = AF_INET;
+ pNewNode->ia.sin_addr.s_addr = htonl(INADDR_BROADCAST);
+ pNewNode->ia.sin_port = htons(p);
+ v->push_back(pNewNode);
+ }
+
/* port of osiSockDiscoverBroadcastAddresses() in
* epics/base/src/libCom/osi/os/default/osdNetIntf.c
*/
- InetAddrVector* getBroadcastAddresses(SOCKET sock) {
+ InetAddrVector* getBroadcastAddresses(SOCKET sock,
+ in_port_t defaultPort) {
static const unsigned nelem = 100;
int status;
struct ifconf ifconf;
struct ifreq* pIfreqList;
+ struct ifreq* pifreq;
+ struct ifreq ifrBuff;
osiSockAddr* pNewNode;
InetAddrVector* retVector = new InetAddrVector();
@@ -54,68 +65,72 @@ namespace epics {
if(!pIfreqList) {
errlogSevPrintf(errlogMajor,
"getBroadcastAddresses(): no memory to complete request");
+ addDefaultBroadcastAddress(retVector, defaultPort);
return retVector;
}
// get number of interfaces
ifconf.ifc_len = nelem*sizeof(ifreq);
ifconf.ifc_req = pIfreqList;
- memset(ifconf.ifc_req,0,ifconf.ifc_len);
+ memset(ifconf.ifc_req, 0, ifconf.ifc_len);
status = ioctl(sock, SIOCGIFCONF, &ifconf);
if(status<0||ifconf.ifc_len==0) {
- errlogSevPrintf(
- errlogMinor,
+ errlogSevPrintf(errlogMinor,
"getBroadcastAddresses(): unable to fetch network interface configuration");
delete[] pIfreqList;
+ addDefaultBroadcastAddress(retVector, defaultPort);
return retVector;
}
- struct ifreq* p = pIfreqList;
int maxNodes = ifconf.ifc_len/sizeof(ifreq);
- for(int i = 0; iifr_name)) break;
- //printf("[%i] plen %d name %s\n", i,p->ifr_addr.sa_len, p->ifr_name);
-
-
- size_t n = p->ifr_addr.sa_len + sizeof(p->ifr_name);
- if (n < sizeof(*p))
- p++;
- else
- p = (struct ifreq *)((char *)p + n);
+ //errlogPrintf("Found %d interfaces\n", maxNodes);
+ pifreq = pIfreqList;
+
+ for(int i = 0; iifr_name)) break;
+
+ if(i>0) {
+ size_t n = pifreq->ifr_addr.sa_len+sizeof(pifreq->ifr_name);
+ if(nifr_addr.sa_family!=AF_INET) continue;
+ if(pifreq->ifr_addr.sa_family!=AF_INET) continue;
- struct ifreq ifrflags;
- strncpy(ifrflags.ifr_name, p->ifr_name,
- sizeof(ifrflags.ifr_name));
- status = ioctl(sock, SIOCGIFFLAGS, (char*)&ifrflags);
+ strncpy(ifrBuff.ifr_name, pifreq->ifr_name,
+ sizeof(ifrBuff.ifr_name));
+ status = ioctl(sock, SIOCGIFFLAGS, &ifrBuff);
if(status) {
errlogSevPrintf(
errlogMinor,
"getBroadcastAddresses(): net intf flags fetch for \"%s\" failed",
- p->ifr_name);
+ pifreq->ifr_name);
continue;
}
/*
* dont bother with interfaces that have been disabled
*/
- if(!(ifrflags.ifr_flags&IFF_UP)) continue;
+ if(!(ifrBuff.ifr_flags&IFF_UP)) continue;
/*
* dont use the loop back interface
*/
- if(ifrflags.ifr_flags&IFF_LOOPBACK) continue;
+ if(ifrBuff.ifr_flags&IFF_LOOPBACK) continue;
pNewNode = new osiSockAddr;
if(pNewNode==NULL) {
errlogSevPrintf(errlogMajor,
"getBroadcastAddresses(): no memory available for configuration");
delete[] pIfreqList;
+ if(retVector->size()==0) addDefaultBroadcastAddress(
+ retVector, defaultPort);
return retVector;
}
@@ -129,46 +144,45 @@ namespace epics {
* Otherwise CA will not query through the
* interface.
*/
- if(ifrflags.ifr_flags&IFF_BROADCAST) {
- struct ifreq ifrflags;
- strncpy(ifrflags.ifr_name, p->ifr_name,
- sizeof(ifrflags.ifr_name));
- status = ioctl(sock, SIOCGIFBRDADDR, (char*)&ifrflags);
+ if(ifrBuff.ifr_flags&IFF_BROADCAST) {
+ strncpy(ifrBuff.ifr_name, pifreq->ifr_name,
+ sizeof(ifrBuff.ifr_name));
+ status = ioctl(sock, SIOCGIFBRDADDR, &ifrBuff);
if(status) {
errlogSevPrintf(
errlogMinor,
"getBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail",
- p->ifr_name);
+ pifreq->ifr_name);
delete pNewNode;
continue;
}
- pNewNode->sa = ifrflags.ifr_broadaddr;
+ pNewNode->sa = ifrBuff.ifr_broadaddr;
}
#ifdef IFF_POINTOPOINT
- else if(ifrflags.ifr_flags&IFF_POINTOPOINT) {
- struct ifreq ifrflags;
- strncpy(ifrflags.ifr_name, p->ifr_name,
- sizeof(ifrflags.ifr_name));
- status = ioctl(sock, SIOCGIFDSTADDR, (char*)&ifrflags);
+ else if(ifrBuff.ifr_flags&IFF_POINTOPOINT) {
+ strncpy(ifrBuff.ifr_name, pifreq->ifr_name,
+ sizeof(ifrBuff.ifr_name));
+ status = ioctl(sock, SIOCGIFDSTADDR, &ifrBuff);
if(status) {
errlogSevPrintf(
errlogMinor,
"getBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail",
- p->ifr_name);
+ pifreq->ifr_name);
delete pNewNode;
continue;
}
- pNewNode->sa = ifrflags.ifr_dstaddr;
+ pNewNode->sa = ifrBuff.ifr_dstaddr;
}
#endif
else {
errlogSevPrintf(
errlogMinor,
"getBroadcastAddresses(): net intf \"%s\": not point to point or bcast?",
- p->ifr_name);
+ pifreq->ifr_name);
delete pNewNode;
continue;
}
+ pNewNode->ia.sin_port = htons(defaultPort);
retVector->push_back(pNewNode);
}
@@ -185,16 +199,12 @@ namespace epics {
buffer->putShort(0);
// next 16-bits are 1
buffer->putShort(0xFFFF);
- buffer->putInt(ntohl(address->ia.sin_addr.s_addr));
-
- /*
// following IPv4 address in big-endian (network) byte order
in_addr_t ipv4Addr = ntohl(address->ia.sin_addr.s_addr);
buffer->putByte((int8)((ipv4Addr>>24)&0xFF));
buffer->putByte((int8)((ipv4Addr>>16)&0xFF));
buffer->putByte((int8)((ipv4Addr>>8)&0xFF));
buffer->putByte((int8)(ipv4Addr&0xFF));
- */
}
osiSockAddr* intToIPv4Address(int32 addr) {
diff --git a/pvAccessApp/utils/inetAddressUtil.h b/pvAccessApp/utils/inetAddressUtil.h
index ee7f381..e8ee082 100644
--- a/pvAccessApp/utils/inetAddressUtil.h
+++ b/pvAccessApp/utils/inetAddressUtil.h
@@ -33,8 +33,12 @@ namespace epics {
/**
* returns a vector containing all the IPv4 broadcast addresses
* on this machine. IPv6 doesn't have a local broadcast address.
- */
- InetAddrVector* getBroadcastAddresses(SOCKET sock);
+ * Conversion of the defaultPort to network byte order performed by
+ * the function.
+ * TODO: Windows implementation of the function.
+ */
+ InetAddrVector* getBroadcastAddresses(SOCKET sock,
+ in_port_t defaultPort);
/**
* Encode IPv4 address as IPv6 address.
diff --git a/testApp/remote/testBeaconEmitter.cpp b/testApp/remote/testBeaconEmitter.cpp
index 0d3c904..c1a3026 100644
--- a/testApp/remote/testBeaconEmitter.cpp
+++ b/testApp/remote/testBeaconEmitter.cpp
@@ -18,6 +18,8 @@ using namespace epics::pvData;
class DummyResponseHandler : public ResponseHandler
{
public:
+ DummyResponseHandler(Context* ctx) : ResponseHandler(ctx) {}
+
virtual void handleResponse(osiSockAddr* responseFrom,
Transport* transport, int8 version, int8 command, int payloadSize,
ByteBuffer* payloadBuffer)
@@ -27,9 +29,33 @@ public:
};
+class ContextImpl : public Context {
+public:
+ ContextImpl() :
+ _tr(new TransportRegistry()), _timer(new Timer("server thread",
+ lowPriority)), _conf(new SystemConfigurationImpl()) {
+ }
+ virtual ~ContextImpl() {
+ delete _tr;
+ delete _timer;
+ }
+ virtual Timer* getTimer() { return _timer; }
+ virtual TransportRegistry* getTransportRegistry() { return _tr; }
+ virtual Channel* getChannel(epics::pvAccess::pvAccessID) { return 0; }
+ virtual Transport* getSearchTransport() { return 0; }
+ virtual Configuration* getConfiguration() { return _conf; }
+
+private:
+ TransportRegistry* _tr;
+ Timer* _timer;
+ Configuration* _conf;
+};
+
+
void testBeaconEmitter()
{
- DummyResponseHandler drh;
+ ContextImpl ctx;
+ DummyResponseHandler drh(&ctx);
/* SOCKET mysocket;
if ((mysocket = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
{
diff --git a/testApp/remote/testBeaconHandler.cpp b/testApp/remote/testBeaconHandler.cpp
index 0ac231c..6690ab4 100644
--- a/testApp/remote/testBeaconHandler.cpp
+++ b/testApp/remote/testBeaconHandler.cpp
@@ -37,7 +37,7 @@ void decodeFromIPv6Address(ByteBuffer* buffer, osiSockAddr* address)
class BeaconResponseHandler : public ResponseHandler
{
public:
- BeaconResponseHandler()
+ BeaconResponseHandler(Context* ctx) : ResponseHandler(ctx)
{
_pvDataCreate = getPVDataCreate();
}
@@ -103,9 +103,33 @@ private:
};
+class ContextImpl : public Context {
+public:
+ ContextImpl() :
+ _tr(new TransportRegistry()), _timer(new Timer("server thread",
+ lowPriority)), _conf(new SystemConfigurationImpl()) {
+ }
+ virtual ~ContextImpl() {
+ delete _tr;
+ delete _timer;
+ }
+ virtual Timer* getTimer() { return _timer; }
+ virtual TransportRegistry* getTransportRegistry() { return _tr; }
+ virtual Channel* getChannel(epics::pvAccess::pvAccessID) { return 0; }
+ virtual Transport* getSearchTransport() { return 0; }
+ virtual Configuration* getConfiguration() { return _conf; }
+
+private:
+ TransportRegistry* _tr;
+ Timer* _timer;
+ Configuration* _conf;
+};
+
+
void testBeaconHandler()
{
- BeaconResponseHandler brh;
+ ContextImpl ctx;
+ BeaconResponseHandler brh(&ctx);
BlockingUDPConnector connector(false, NULL, true);
osiSockAddr bindAddr;
diff --git a/testApp/remote/testBlockingTCPClnt.cpp b/testApp/remote/testBlockingTCPClnt.cpp
index a3bde97..d845c1b 100644
--- a/testApp/remote/testBlockingTCPClnt.cpp
+++ b/testApp/remote/testBlockingTCPClnt.cpp
@@ -29,28 +29,30 @@ using std::sscanf;
class ContextImpl : public Context {
public:
ContextImpl() :
- _tr(new TransportRegistry()), _timer(new Timer("client thread",
- lowPriority)) {
+ _tr(new TransportRegistry()), _timer(new Timer("server thread",
+ lowPriority)), _conf(new SystemConfigurationImpl()) {
}
virtual ~ContextImpl() {
delete _tr;
delete _timer;
}
- virtual Timer* getTimer() {
- return _timer;
- }
- virtual TransportRegistry* getTransportRegistry() {
- return _tr;
- }
- virtual Channel* getChannel(epics::pvAccess::pvAccessID) { return 0; }
- virtual Transport* getSearchTransport() { return 0; }
+ virtual Timer* getTimer() { return _timer; }
+ virtual TransportRegistry* getTransportRegistry() { return _tr; }
+ virtual Channel* getChannel(epics::pvAccess::pvAccessID) { return 0; }
+ virtual Transport* getSearchTransport() { return 0; }
+ virtual Configuration* getConfiguration() { return _conf; }
+
private:
TransportRegistry* _tr;
Timer* _timer;
+ Configuration* _conf;
};
class DummyResponseHandler : public ResponseHandler {
public:
+ DummyResponseHandler(Context* ctx) : ResponseHandler(ctx) {
+ }
+
virtual void handleResponse(osiSockAddr* responseFrom,
Transport* transport, int8 version, int8 command, int payloadSize,
ByteBuffer* payloadBuffer) {
@@ -110,7 +112,7 @@ void testBlockingTCPSender() {
DummyTransportClient dtc;
DummyTransportSender dts;
- DummyResponseHandler drh;
+ DummyResponseHandler drh(&ctx);
osiSockAddr srvAddr;
diff --git a/testApp/remote/testBlockingTCPSrv.cpp b/testApp/remote/testBlockingTCPSrv.cpp
index 6ab54f6..c7ced35 100644
--- a/testApp/remote/testBlockingTCPSrv.cpp
+++ b/testApp/remote/testBlockingTCPSrv.cpp
@@ -8,6 +8,7 @@
#include "blockingTCP.h"
#include "remote.h"
#include "logger.h"
+#include "configuration.h"
#include
@@ -21,7 +22,8 @@ class ContextImpl : public Context {
public:
ContextImpl() :
_tr(new TransportRegistry()),
- _timer(new Timer("server thread", lowPriority)) {}
+ _timer(new Timer("server thread", lowPriority)),
+ _conf(new SystemConfigurationImpl()) {}
virtual ~ContextImpl() {
delete _tr;
delete _timer;
@@ -30,10 +32,12 @@ public:
virtual TransportRegistry* getTransportRegistry() { return _tr; }
virtual Channel* getChannel(epics::pvAccess::pvAccessID) { return 0; }
virtual Transport* getSearchTransport() { return 0; }
-
+ virtual Configuration* getConfiguration() { return _conf; }
+
private:
TransportRegistry* _tr;
Timer* _timer;
+ Configuration* _conf;
};
void testServerConnections() {
@@ -43,7 +47,7 @@ void testServerConnections() {
1024);
cout<<"Press any key to stop the server...";
- char c = cin.peek();
+ cin.peek();
delete srv;
}
diff --git a/testApp/remote/testBlockingUDPClnt.cpp b/testApp/remote/testBlockingUDPClnt.cpp
index 06443aa..3e124d9 100644
--- a/testApp/remote/testBlockingUDPClnt.cpp
+++ b/testApp/remote/testBlockingUDPClnt.cpp
@@ -26,8 +26,44 @@ using std::sscanf;
static osiSockAddr sendTo;
+class ContextImpl : public Context {
+public:
+ ContextImpl() :
+ _tr(new TransportRegistry()), _timer(new Timer("server thread",
+ lowPriority)), _conf(new SystemConfigurationImpl()) {
+ }
+ virtual ~ContextImpl() {
+ delete _tr;
+ delete _timer;
+ }
+ virtual Timer* getTimer() {
+ return _timer;
+ }
+ virtual TransportRegistry* getTransportRegistry() {
+ return _tr;
+ }
+ virtual Channel* getChannel(epics::pvAccess::pvAccessID) {
+ return 0;
+ }
+ virtual Transport* getSearchTransport() {
+ return 0;
+ }
+ virtual Configuration* getConfiguration() {
+ return _conf;
+ }
+
+private:
+ TransportRegistry* _tr;
+ Timer* _timer;
+ Configuration* _conf;
+};
+
class DummyResponseHandler : public ResponseHandler {
public:
+ DummyResponseHandler(Context* ctx) :
+ ResponseHandler(ctx) {
+ }
+
virtual void handleResponse(osiSockAddr* responseFrom,
Transport* transport, int8 version, int8 command, int payloadSize,
ByteBuffer* payloadBuffer) {
@@ -69,9 +105,10 @@ private:
void testBlockingUDPSender() {
BlockingUDPConnector connector(false, NULL, true);
+ ContextImpl ctx;
DummyTransportSender dts;
- DummyResponseHandler drh;
+ DummyResponseHandler drh(&ctx);
osiSockAddr bindAddr;
diff --git a/testApp/remote/testBlockingUDPSrv.cpp b/testApp/remote/testBlockingUDPSrv.cpp
index 6b713bb..16612ac 100644
--- a/testApp/remote/testBlockingUDPSrv.cpp
+++ b/testApp/remote/testBlockingUDPSrv.cpp
@@ -21,10 +21,42 @@ using std::endl;
using std::hex;
using std::dec;
+class ContextImpl : public Context {
+public:
+ ContextImpl() :
+ _tr(new TransportRegistry()), _timer(new Timer("server thread",
+ lowPriority)), _conf(new SystemConfigurationImpl()) {
+ }
+ virtual ~ContextImpl() {
+ delete _tr;
+ delete _timer;
+ }
+ virtual Timer* getTimer() {
+ return _timer;
+ }
+ virtual TransportRegistry* getTransportRegistry() {
+ return _tr;
+ }
+ virtual Channel* getChannel(epics::pvAccess::pvAccessID) {
+ return 0;
+ }
+ virtual Transport* getSearchTransport() {
+ return 0;
+ }
+ virtual Configuration* getConfiguration() {
+ return _conf;
+ }
+
+private:
+ TransportRegistry* _tr;
+ Timer* _timer;
+ Configuration* _conf;
+};
+
class DummyResponseHandler : public ResponseHandler {
public:
- DummyResponseHandler() :
- packets(0) {
+ DummyResponseHandler(Context* context) :
+ ResponseHandler(context), packets(0) {
}
int getPackets() {
@@ -71,8 +103,9 @@ void DummyResponseHandler::handleResponse(osiSockAddr* responseFrom,
void testBlockingUDPConnector() {
BlockingUDPConnector connector(false, NULL, true);
+ ContextImpl ctx;
- DummyResponseHandler drh;
+ DummyResponseHandler drh(&ctx);
osiSockAddr bindAddr;
diff --git a/testApp/remote/testRemoteClientImpl.cpp b/testApp/remote/testRemoteClientImpl.cpp
index de251df..5f8c362 100644
--- a/testApp/remote/testRemoteClientImpl.cpp
+++ b/testApp/remote/testRemoteClientImpl.cpp
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
using namespace epics::pvData;
using namespace epics::pvAccess;
@@ -35,7 +36,7 @@ class ChannelImplProcess : public ChannelProcess
ChannelProcessRequester* m_channelProcessRequester;
PVStructure* m_pvStructure;
PVScalar* m_valueField;
-
+
private:
~ChannelImplProcess()
{
@@ -54,29 +55,29 @@ class ChannelImplProcess : public ChannelProcess
Status* noValueFieldStatus = getStatusCreate()->createStatus(STATUSTYPE_ERROR, "no 'value' field");
m_channelProcessRequester->channelProcessConnect(noValueFieldStatus, this);
delete noValueFieldStatus;
-
+
// NOTE client must destroy this instance...
// do not access any fields and return ASAP
return;
}
-
+
if (field->getField()->getType() != scalar)
{
Status* notAScalarStatus = getStatusCreate()->createStatus(STATUSTYPE_ERROR, "'value' field not scalar type");
m_channelProcessRequester->channelProcessConnect(notAScalarStatus, this);
delete notAScalarStatus;
-
+
// NOTE client must destroy this instance….
// do not access any fields and return ASAP
return;
}
-
+
m_valueField = static_cast(field);
-
- // TODO pvRequest
+
+ // TODO pvRequest
m_channelProcessRequester->channelProcessConnect(getStatusCreate()->getStatusOK(), this);
}
-
+
virtual void process(bool lastRequest)
{
switch (m_valueField->getScalar()->getScalarType())
@@ -148,19 +149,19 @@ class ChannelImplProcess : public ChannelProcess
default:
// noop
break;
-
- }
+
+ }
m_channelProcessRequester->processDone(getStatusCreate()->getStatusOK());
-
+
if (lastRequest)
destroy();
}
-
+
virtual void destroy()
{
delete this;
}
-
+
};
@@ -177,7 +178,7 @@ class ChannelImplGet : public ChannelGet
PVStructure* m_pvStructure;
BitSet* m_bitSet;
volatile bool m_first;
-
+
private:
~ChannelImplGet()
{
@@ -191,10 +192,10 @@ class ChannelImplGet : public ChannelGet
{
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(mockChannelGet);
- // TODO pvRequest
+ // TODO pvRequest
m_channelGetRequester->channelGetConnect(getStatusCreate()->getStatusOK(), this, m_pvStructure, m_bitSet);
}
-
+
virtual void get(bool lastRequest)
{
m_channelGetRequester->getDone(getStatusCreate()->getStatusOK());
@@ -203,17 +204,17 @@ class ChannelImplGet : public ChannelGet
m_first = false;
m_bitSet->set(0); // TODO
}
-
+
if (lastRequest)
destroy();
}
-
+
virtual void destroy()
{
delete m_bitSet;
delete this;
}
-
+
};
@@ -232,7 +233,7 @@ class ChannelImplPut : public ChannelPut
PVStructure* m_pvStructure;
BitSet* m_bitSet;
volatile bool m_first;
-
+
private:
~ChannelImplPut()
{
@@ -246,17 +247,17 @@ class ChannelImplPut : public ChannelPut
{
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(mockChannelPut);
- // TODO pvRequest
+ // TODO pvRequest
m_channelPutRequester->channelPutConnect(getStatusCreate()->getStatusOK(), this, m_pvStructure, m_bitSet);
}
-
+
virtual void put(bool lastRequest)
{
m_channelPutRequester->putDone(getStatusCreate()->getStatusOK());
if (lastRequest)
destroy();
}
-
+
virtual void get()
{
m_channelPutRequester->getDone(getStatusCreate()->getStatusOK());
@@ -267,7 +268,7 @@ class ChannelImplPut : public ChannelPut
delete m_bitSet;
delete this;
}
-
+
};
@@ -288,7 +289,7 @@ class MockMonitor : public Monitor, public MonitorElement
volatile bool m_first;
Mutex* m_lock;
volatile int m_count;
-
+
private:
~MockMonitor()
{
@@ -307,16 +308,16 @@ class MockMonitor : public Monitor, public MonitorElement
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(mockMonitor);
m_changedBitSet->set(0);
-
- // TODO pvRequest
+
+ // TODO pvRequest
m_monitorRequester->monitorConnect(getStatusCreate()->getStatusOK(), this, const_cast(m_pvStructure->getStructure()));
}
-
+
virtual Status* start()
{
// fist monitor
m_monitorRequester->monitorEvent(this);
-
+
// client needs to delete status, so passing shared OK instance is not right thing to do
return getStatusCreate()->createStatus(STATUSTYPE_OK, "Monitor started.");
}
@@ -347,24 +348,24 @@ class MockMonitor : public Monitor, public MonitorElement
if (m_count)
m_count--;
}
-
+
virtual void destroy()
{
delete stop();
-
+
delete m_lock;
delete m_overrunBitSet;
delete m_changedBitSet;
delete this;
}
-
+
// ============ MonitorElement ============
-
+
virtual PVStructure* getPVStructure()
{
return m_pvStructure;
}
-
+
virtual BitSet* getChangedBitSet()
{
return m_changedBitSet;
@@ -374,8 +375,8 @@ class MockMonitor : public Monitor, public MonitorElement
{
return m_overrunBitSet;
}
-
-
+
+
};
@@ -395,7 +396,8 @@ typedef std::map IOIDResponseRequestMap;
/**
* @param context
*/
- DebugResponse()
+ DebugResponse(Context* ctx) :
+ ResponseHandler(ctx)
{
}
@@ -409,7 +411,6 @@ typedef std::map IOIDResponseRequestMap;
char ipAddrStr[48];
ipAddrToDottedIP(&responseFrom->ia, ipAddrStr, sizeof(ipAddrStr));
-
ostringstream prologue;
prologue<<"Message [0x"< IOIDResponseRequestMap;
hexDump(prologue.str(), "received",
(const int8*)payloadBuffer->getArray(),
payloadBuffer->getPosition(), payloadSize);
-
+
}
};
@@ -426,7 +427,7 @@ typedef std::map IOIDResponseRequestMap;
private:
ClientContextImpl* m_context;
public:
- SearchResponseHandler(ClientContextImpl* context) : m_context(context)
+ SearchResponseHandler(ClientContextImpl* context) : ResponseHandler(context), m_context(context)
{
}
@@ -492,30 +493,30 @@ typedef std::map IOIDResponseRequestMap;
*/
class ClientResponseHandler : public ResponseHandler, private epics::pvData::NoDefaultMethods {
private:
-
+
/**
* Table of response handlers for each command ID.
*/
ResponseHandler** m_handlerTable;
- /**
- * Context instance.
+ /*
+ * Context instance is part of the response handler now
*/
- ClientContextImpl* m_context;
-
+ //ClientContextImpl* m_context;
+
public:
-
+
~ClientResponseHandler() {
delete[] m_handlerTable;
}
-
+
/**
* @param context
*/
- ClientResponseHandler(ClientContextImpl* context) : m_context(context) {
- static ResponseHandler* badResponse = new DebugResponse();
+ ClientResponseHandler(ClientContextImpl* context) : ResponseHandler((Context*)context) {
+ static ResponseHandler* badResponse = new DebugResponse((Context*)context);
static ResponseHandler* dataResponse = 0; //new DataResponseHandler(context);
-
+
#define HANDLER_COUNT 28
m_handlerTable = new ResponseHandler*[HANDLER_COUNT];
m_handlerTable[ 0] = badResponse; // TODO new BeaconHandler(context), /* 0 */
@@ -564,7 +565,7 @@ class ClientResponseHandler : public ResponseHandler, private epics::pvData::NoD
hexDump(buf, (const int8*)(payloadBuffer->getArray()), payloadBuffer->getPosition(), payloadSize);
return;
}
-
+
// delegate
m_handlerTable[c]->handleResponse(responseFrom, transport, version, command, payloadSize, payloadBuffer);
}
@@ -587,7 +588,7 @@ class ClientResponseHandler : public ResponseHandler, private epics::pvData::NoD
};
-
+
@@ -617,7 +618,7 @@ enum ContextState {
*/
CONTEXT_DESTROYED
};
-
+
class TestClientContextImpl : public ClientContextImpl
{
@@ -633,7 +634,7 @@ class TestClientContextImpl : public ClientContextImpl
*/
class TestChannelImpl : public ChannelImpl {
private:
-
+
/**
* Context.
*/
@@ -643,12 +644,12 @@ class TestChannelImpl : public ChannelImpl {
* Client channel ID.
*/
pvAccessID m_channelID;
-
+
/**
* Channel name.
*/
String m_name;
-
+
/**
* Channel requester.
*/
@@ -658,48 +659,48 @@ class TestChannelImpl : public ChannelImpl {
* Process priority.
*/
short m_priority;
-
+
/**
* List of fixed addresses, if name resolution will be used.
*/
InetAddrVector* m_addresses;
-
+
/**
* Connection status.
*/
ConnectionState m_connectionState;
-
+
/**
- * List of all channel's pending requests (keys are subscription IDs).
+ * List of all channel's pending requests (keys are subscription IDs).
*/
IOIDResponseRequestMap m_responseRequests;
-
+
/**
- * Allow reconnection flag.
+ * Allow reconnection flag.
*/
bool m_allowCreation;
-
+
/**
* Reference counting.
- * NOTE: synced on m_channelMutex.
+ * NOTE: synced on m_channelMutex.
*/
int m_references;
-
+
/* ****************** */
- /* CA protocol fields */
+ /* CA protocol fields */
/* ****************** */
-
+
/**
* Server transport.
*/
Transport* m_transport;
-
+
/**
* Server channel ID.
*/
pvAccessID m_serverChannelID;
-
+
/**
* Context sync. mutex.
*/
@@ -707,20 +708,20 @@ class TestChannelImpl : public ChannelImpl {
/**
* Flag indicting what message to send.
- */
+ */
bool m_issueCreateMessage;
-
+
// TODO mock
PVStructure* m_pvStructure;
-
+
private:
~TestChannelImpl()
{
PVDATA_REFCOUNT_MONITOR_DESTRUCT(channel);
}
-
+
public:
-
+
/**
* Constructor.
* @param context
@@ -749,15 +750,14 @@ class TestChannelImpl : public ChannelImpl {
m_issueCreateMessage(true)
{
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(channel);
-
+
// register before issuing search request
m_context->registerChannel(this);
-
+
// connect
connect();
-
}
-
+
virtual void destroy()
{
if (m_addresses) delete m_addresses;
@@ -769,13 +769,13 @@ class TestChannelImpl : public ChannelImpl {
{
return getChannelName();
};
-
- virtual void message(String message,MessageType messageType)
+
+ virtual void message(String message,MessageType messageType)
{
- std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
+ std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
- virtual ChannelProvider* getProvider()
+ virtual ChannelProvider* getProvider()
{
return m_context->getProvider();
}
@@ -852,14 +852,14 @@ class TestChannelImpl : public ChannelImpl {
throw std::runtime_error("Channel destroyed.");
else if (m_connectionState == CONNECTED)
disconnect(false, true);
- }
-
+ }
+
/**
* Create a channel, i.e. submit create channel request to the server.
* This method is called after search is complete.
* @param transport
*/
- void createChannel(Transport* transport)
+ void createChannel(Transport* transport)
{
Lock guard(&m_channelMutex);
@@ -867,12 +867,12 @@ class TestChannelImpl : public ChannelImpl {
if (!m_allowCreation)
return;
m_allowCreation = false;
-
+
// check existing transport
if (m_transport && m_transport != transport)
{
disconnectPendingIO(false);
-
+
ReferenceCountingTransport* rct = dynamic_cast(m_transport);
if (rct) rct->release(this);
}
@@ -882,11 +882,11 @@ class TestChannelImpl : public ChannelImpl {
// this happens when server is slower (processing search requests) than client generating it
return;
}
-
+
m_transport = transport;
m_transport->enqueueSendRequest(this);
}
-
+
virtual void cancel() {
// noop
}
@@ -912,7 +912,7 @@ class TestChannelImpl : public ChannelImpl {
* sid might not be valid, this depends on protocol revision.
* @param sid
*/
- void connectionCompleted(pvAccessID sid/*, rights*/)
+ void connectionCompleted(pvAccessID sid/*, rights*/)
{
Lock guard(&m_channelMutex);
@@ -929,16 +929,16 @@ class TestChannelImpl : public ChannelImpl {
// user might create monitors in listeners, so this has to be done before this can happen
// however, it would not be nice if events would come before connection event is fired
- // but this cannot happen since transport (TCP) is serving in this thread
+ // but this cannot happen since transport (TCP) is serving in this thread
resubscribeSubscriptions();
setConnectionState(CONNECTED);
allOK = true;
}
catch (...) {
// noop
- // TODO at least log something??
+ // TODO at least log something??
}
-
+
if (!allOK)
{
// end connection request
@@ -953,10 +953,10 @@ class TestChannelImpl : public ChannelImpl {
Lock guard(&m_channelMutex);
if (m_connectionState == DESTROYED)
throw std::runtime_error("Channel already destroyed.");
-
+
// do destruction via context
m_context->destroyChannel(this, force);
-
+
}
/**
@@ -983,7 +983,7 @@ class TestChannelImpl : public ChannelImpl {
m_references--;
if (m_references > 0 && !force)
return;
-
+
// stop searching...
m_context->getChannelSearchManager()->unregisterChannel(this);
cancel();
@@ -1003,7 +1003,7 @@ class TestChannelImpl : public ChannelImpl {
}
setConnectionState(DESTROYED);
-
+
// unregister
m_context->unregisterChannel(this);
}
@@ -1015,10 +1015,10 @@ class TestChannelImpl : public ChannelImpl {
*/
void disconnect(bool initiateSearch, bool remoteDestroy) {
Lock guard(&m_channelMutex);
-
+
if (m_connectionState != CONNECTED && !m_transport)
return;
-
+
if (!initiateSearch) {
// stop searching...
m_context->getChannelSearchManager()->unregisterChannel(this);
@@ -1035,12 +1035,12 @@ class TestChannelImpl : public ChannelImpl {
m_issueCreateMessage = false;
m_transport->enqueueSendRequest(this);
}
-
+
ReferenceCountingTransport* rct = dynamic_cast(m_transport);
if (rct) rct->release(this);
m_transport = 0;
}
-
+
if (initiateSearch)
this->initiateSearch();
@@ -1054,7 +1054,7 @@ class TestChannelImpl : public ChannelImpl {
Lock guard(&m_channelMutex);
m_allowCreation = true;
-
+
if (!m_addresses)
m_context->getChannelSearchManager()->registerChannel(this);
/* TODO
@@ -1079,7 +1079,7 @@ class TestChannelImpl : public ChannelImpl {
return;
}
}
-
+
transport = m_context->getTransport(this, serverAddress, minorRevision, m_priority);
if (!transport)
{
@@ -1104,7 +1104,7 @@ class TestChannelImpl : public ChannelImpl {
if (m_connectionState == DISCONNECTED)
{
updateSubscriptions();
-
+
// reconnect using existing IDs, data
connectionCompleted(m_serverChannelID/*, accessRights*/);
}
@@ -1117,7 +1117,7 @@ class TestChannelImpl : public ChannelImpl {
// NOTE: 2 types of disconnected state - distinguish them
setConnectionState(DISCONNECTED);
- // ... CA notifies also w/ no access rights callback, although access right are not changed
+ // ... CA notifies also w/ no access rights callback, although access right are not changed
}
}
@@ -1131,7 +1131,7 @@ class TestChannelImpl : public ChannelImpl {
if (m_connectionState != connectionState)
{
m_connectionState = connectionState;
-
+
//bool connectionStatusToReport = (connectionState == CONNECTED);
//if (connectionStatusToReport != lastReportedConnectionState)
{
@@ -1146,16 +1146,16 @@ class TestChannelImpl : public ChannelImpl {
// noop
}
-
+
virtual void send(ByteBuffer* buffer, TransportSendControl* control) {
m_channelMutex.lock();
bool issueCreateMessage = m_issueCreateMessage;
m_channelMutex.unlock();
-
+
if (issueCreateMessage)
{
control->startMessage((int8)7, 2+4);
-
+
// count
buffer->putShort((int16)1);
// array of CIDs and names
@@ -1194,9 +1194,9 @@ class TestChannelImpl : public ChannelImpl {
{
// TODO
}
-
+
/**
- * Resubscribe subscriptions.
+ * Resubscribe subscriptions.
*/
// TODO to be called from non-transport thread !!!!!!
void resubscribeSubscriptions()
@@ -1205,7 +1205,7 @@ class TestChannelImpl : public ChannelImpl {
}
/**
- * Update subscriptions.
+ * Update subscriptions.
*/
// TODO to be called from non-transport thread !!!!!!
void updateSubscriptions()
@@ -1246,7 +1246,7 @@ class TestChannelImpl : public ChannelImpl {
// TODO
return 0;
}
-
+
virtual ChannelRPC* createChannelRPC(ChannelRPCRequester *channelRPCRequester,
epics::pvData::PVStructure *pvRequest)
{
@@ -1268,20 +1268,20 @@ class TestChannelImpl : public ChannelImpl {
// TODO
return 0;
}
-
-
-
+
+
+
virtual void printInfo() {
String info;
printInfo(&info);
std::cout << info.c_str() << std::endl;
}
-
+
virtual void printInfo(epics::pvData::StringBuilder out) {
//Lock lock(&m_channelMutex);
//std::ostringstream ostr;
//static String emptyString;
-
+
out->append( "CHANNEL : "); out->append(m_name);
out->append("\nSTATE : "); out->append(ConnectionStateNames[m_connectionState]);
if (m_connectionState == CONNECTED)
@@ -1292,72 +1292,72 @@ class TestChannelImpl : public ChannelImpl {
out->append("\n");
}
};
-
+
class ChannelProviderImpl;
-
+
class ChannelImplFind : public ChannelFind
{
public:
ChannelImplFind(ChannelProvider* provider) : m_provider(provider)
{
}
-
+
virtual void destroy()
{
// one instance for all, do not delete at all
}
-
+
virtual ChannelProvider* getChannelProvider()
{
return m_provider;
};
-
+
virtual void cancelChannelFind()
{
throw std::runtime_error("not supported");
}
-
+
private:
-
+
// only to be destroyed by it
friend class ChannelProviderImpl;
virtual ~ChannelImplFind() {}
-
- ChannelProvider* m_provider;
+
+ ChannelProvider* m_provider;
};
-
+
class ChannelProviderImpl : public ChannelProvider {
public:
-
+
ChannelProviderImpl(ClientContextImpl* context) :
m_context(context) {
}
-
+
virtual epics::pvData::String getProviderName()
{
return "ChannelProviderImpl";
}
-
+
virtual void destroy()
{
delete this;
}
-
+
virtual ChannelFind* channelFind(
epics::pvData::String channelName,
ChannelFindRequester *channelFindRequester)
{
m_context->checkChannelName(channelName);
-
+
if (!channelFindRequester)
throw std::runtime_error("null requester");
-
+
std::auto_ptr errorStatus(getStatusCreate()->createStatus(STATUSTYPE_ERROR, "not implemented", 0));
channelFindRequester->channelFindResult(errorStatus.get(), 0, false);
return 0;
}
-
+
virtual Channel* createChannel(
epics::pvData::String channelName,
ChannelRequester *channelRequester,
@@ -1365,7 +1365,7 @@ class TestChannelImpl : public ChannelImpl {
{
return createChannel(channelName, channelRequester, priority, emptyString);
}
-
+
virtual Channel* createChannel(
epics::pvData::String channelName,
ChannelRequester *channelRequester,
@@ -1377,19 +1377,18 @@ class TestChannelImpl : public ChannelImpl {
if (channel)
channelRequester->channelCreated(getStatusCreate()->getStatusOK(), channel);
return channel;
-
+
// NOTE it's up to internal code to respond w/ error to requester and return 0 in case of errors
}
-
+
private:
~ChannelProviderImpl() {};
-
+
/* TODO static*/ String emptyString;
ClientContextImpl* m_context;
};
public:
-
TestClientContextImpl() :
m_addressList(""), m_autoAddressList(true), m_connectionTimeout(30.0f), m_beaconPeriod(15.0f),
m_broadcastPort(CA_BROADCAST_PORT), m_receiveBufferSize(MAX_TCP_RECV), m_timer(0),
@@ -1397,11 +1396,15 @@ class TestChannelImpl : public ChannelImpl {
m_namedLocker(0), m_lastCID(0), m_lastIOID(0), m_channelSearchManager(0),
m_version(new Version("CA Client", "cpp", 0, 0, 0, 1)),
m_provider(new ChannelProviderImpl(this)),
- m_contextState(CONTEXT_NOT_INITIALIZED)
+ m_contextState(CONTEXT_NOT_INITIALIZED), m_configuration(new SystemConfigurationImpl())
{
loadConfiguration();
}
-
+
+ virtual Configuration* getConfiguration() {
+ return m_configuration;
+ }
+
virtual Version* getVersion() {
return m_version;
}
@@ -1431,28 +1434,28 @@ class TestChannelImpl : public ChannelImpl {
virtual void initialize() {
Lock lock(&m_contextMutex);
-
+
if (m_contextState == CONTEXT_DESTROYED)
throw std::runtime_error("Context destroyed.");
else if (m_contextState == CONTEXT_INITIALIZED)
throw std::runtime_error("Context already initialized.");
-
+
internalInitialize();
m_contextState = CONTEXT_INITIALIZED;
}
-
+
virtual void printInfo() {
String info;
printInfo(&info);
std::cout << info.c_str() << std::endl;
}
-
+
virtual void printInfo(epics::pvData::StringBuilder out) {
Lock lock(&m_contextMutex);
std::ostringstream ostr;
static String emptyString;
-
+
out->append( "CLASS : ::epics::pvAccess::ClientContextImpl");
out->append("\nVERSION : "); out->append(m_version->getVersionString());
out->append("\nADDR_LIST : "); ostr << m_addressList; out->append(ostr.str()); ostr.str(emptyString);
@@ -1478,7 +1481,7 @@ class TestChannelImpl : public ChannelImpl {
}
out->append("\n");
}
-
+
virtual void destroy()
{
m_contextMutex.lock();
@@ -1488,21 +1491,21 @@ class TestChannelImpl : public ChannelImpl {
m_contextMutex.unlock();
throw std::runtime_error("Context already destroyed.");
}
-
- // go into destroyed state ASAP
+
+ // go into destroyed state ASAP
m_contextState = CONTEXT_DESTROYED;
internalDestroy();
}
-
+
virtual void dispose()
{
destroy();
- }
-
+ }
+
private:
~TestClientContextImpl() {};
-
+
void loadConfiguration() {
// TODO
/*
@@ -1516,19 +1519,19 @@ class TestChannelImpl : public ChannelImpl {
}
void internalInitialize() {
-
+
m_timer = new Timer("pvAccess-client timer", lowPriority);
m_connector = new BlockingTCPConnector(this, m_receiveBufferSize, m_beaconPeriod);
m_transportRegistry = new TransportRegistry();
m_namedLocker = new NamedLockPattern();
-
+
// setup UDP transport
initializeUDPTransport();
// setup search manager
m_channelSearchManager = new ChannelSearchManager(this);
}
-
+
/**
* Initialized UDP transport (broadcast socket and repeater connection).
*/
@@ -1541,13 +1544,12 @@ class TestChannelImpl : public ChannelImpl {
listenLocalAddress.ia.sin_family = AF_INET;
listenLocalAddress.ia.sin_port = htons(m_broadcastPort);
listenLocalAddress.ia.sin_addr.s_addr = htonl(INADDR_ANY);
-
+
// where to send address
SOCKET socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0);
- InetAddrVector* broadcastAddresses = getBroadcastAddresses(socket);
+ InetAddrVector* broadcastAddresses = getBroadcastAddresses(socket, m_broadcastPort);
cout<<"Broadcast addresses: "<size()<size(); i++) {
- broadcastAddresses->at(i)->ia.sin_port = htons(m_broadcastPort);
cout<<"Broadcast address: ";
cout<at(i))<connect(
0, new ClientResponseHandler(this),
listenLocalAddress, CA_MINOR_PROTOCOL_REVISION,
CA_DEFAULT_PRIORITY);
BlockingUDPConnector* searchConnector = new BlockingUDPConnector(false, broadcastAddresses, true);
-
+
// undefined address
osiSockAddr undefinedAddress;
undefinedAddress.ia.sin_family = AF_INET;
undefinedAddress.ia.sin_port = htons(0);
undefinedAddress.ia.sin_addr.s_addr = htonl(INADDR_ANY);
-
+
m_searchTransport = (BlockingUDPTransport*)searchConnector->connect(
0, new ClientResponseHandler(this),
undefinedAddress, CA_MINOR_PROTOCOL_REVISION,
@@ -1582,7 +1584,7 @@ class TestChannelImpl : public ChannelImpl {
InetAddrVector* appendList = 0;
if (m_autoAddressList)
appendList = m_broadcastTransport->getSendAddresses();
-
+
InetAddrVector* list = getSocketAddressList(m_addressList, m_broadcastPort, appendList);
// TODO delete !!!!
if (list && list->size()) {
@@ -1600,40 +1602,41 @@ class TestChannelImpl : public ChannelImpl {
// TODO
}
}
-
+
void internalDestroy() {
-
+
// stop searching
if (m_channelSearchManager)
delete m_channelSearchManager; //->destroy();
-
+
// stop timer
- if (m_timer)
+ if (m_timer)
delete m_timer;
//
// cleanup
//
-
+
// this will also close all CA transports
destroyAllChannels();
-
+
// TODO destroy !!!
if (m_broadcastTransport)
delete m_broadcastTransport; //->destroy(true);
if (m_searchTransport)
delete m_searchTransport; //->destroy(true);
-
+
if (m_namedLocker) delete m_namedLocker;
if (m_transportRegistry) delete m_transportRegistry;
if (m_connector) delete m_connector;
+ if (m_configuration) delete m_configuration;
m_provider->destroy();
delete m_version;
m_contextMutex.unlock();
delete this;
}
-
+
void destroyAllChannels() {
// TODO
}
@@ -1688,18 +1691,18 @@ class TestChannelImpl : public ChannelImpl {
ChannelImpl* getChannel(pvAccessID channelID)
{
Lock guard(&m_cidMapMutex);
- CIDChannelMap::iterator it = m_channelsByCID.find(channelID);
+ CIDChannelMap::iterator it = m_channelsByCID.find(channelID);
return (it == m_channelsByCID.end() ? 0 : it->second);
}
/**
* Generate Client channel ID (CID).
- * @return Client channel ID (CID).
+ * @return Client channel ID (CID).
*/
pvAccessID generateCID()
{
Lock guard(&m_cidMapMutex);
-
+
// search first free (theoretically possible loop of death)
while (m_channelsByCID.find(++m_lastCID) != m_channelsByCID.end());
// reserve CID
@@ -1716,7 +1719,7 @@ class TestChannelImpl : public ChannelImpl {
m_channelsByCID.erase(cid);
}
-
+
/**
* Get, or create if necessary, transport of given server address.
* @param serverAddress required transport address
@@ -1736,7 +1739,7 @@ class TestChannelImpl : public ChannelImpl {
return 0;
}
}
-
+
/**
* Internal create channel.
*/
@@ -1747,16 +1750,16 @@ class TestChannelImpl : public ChannelImpl {
checkState();
checkChannelName(name);
-
+
if (requester == 0)
throw std::runtime_error("null requester");
-
+
if (priority < ChannelProvider::PRIORITY_MIN || priority > ChannelProvider::PRIORITY_MAX)
throw std::range_error("priority out of bounds");
bool lockAcquired = true; // TODO namedLocker->acquireSynchronizationObject(name, LOCK_TIMEOUT);
if (lockAcquired)
- {
+ {
try
{
pvAccessID cid = generateCID();
@@ -1766,10 +1769,10 @@ class TestChannelImpl : public ChannelImpl {
// TODO
return 0;
}
- // TODO namedLocker.releaseSynchronizationObject(name);
+ // TODO namedLocker.releaseSynchronizationObject(name);
}
else
- {
+ {
// TODO is this OK?
throw std::runtime_error("Failed to obtain synchronization lock for '" + name + "', possible deadlock.");
}
@@ -1783,23 +1786,23 @@ class TestChannelImpl : public ChannelImpl {
* @throws IllegalStateException
*/
void destroyChannel(ChannelImpl* channel, bool force) {
-
+
String name = channel->getChannelName();
bool lockAcquired = true; //namedLocker->acquireSynchronizationObject(name, LOCK_TIMEOUT);
if (lockAcquired)
- {
+ {
try
- {
+ {
channel->destroyChannel(force);
}
catch(...) {
// TODO
}
- // TODO namedLocker->releaseSynchronizationObject(channel.getChannelName());
+ // TODO namedLocker->releaseSynchronizationObject(channel.getChannelName());
}
else
- {
- // TODO is this OK?
+ {
+ // TODO is this OK?
throw std::runtime_error("Failed to obtain synchronization lock for '" + name + "', possible deadlock.");
}
}
@@ -1811,15 +1814,15 @@ class TestChannelImpl : public ChannelImpl {
ChannelSearchManager* getChannelSearchManager() {
return m_channelSearchManager;
}
-
+
/**
* A space-separated list of broadcast address for process variable name resolution.
* Each address must be of the form: ip.number:port or host.name:port
*/
String m_addressList;
-
+
/**
- * Define whether or not the network interfaces should be discovered at runtime.
+ * Define whether or not the network interfaces should be discovered at runtime.
*/
bool m_autoAddressList;
@@ -1830,22 +1833,22 @@ class TestChannelImpl : public ChannelImpl {
* the server is no longer present on the network and disconnect.
*/
float m_connectionTimeout;
-
+
/**
* Period in second between two beacon signals.
*/
float m_beaconPeriod;
-
+
/**
* Broadcast (beacon, search) port number to listen to.
*/
int m_broadcastPort;
-
+
/**
* Receive buffer size (max size of payload).
*/
int m_receiveBufferSize;
-
+
/**
* Timer.
*/
@@ -1855,7 +1858,7 @@ class TestChannelImpl : public ChannelImpl {
* Broadcast transport needed to listen for broadcasts.
*/
BlockingUDPTransport* m_broadcastTransport;
-
+
/**
* UDP transport needed for channel searches.
*/
@@ -1868,7 +1871,7 @@ class TestChannelImpl : public ChannelImpl {
/**
* CA transport (virtual circuit) registry.
- * This registry contains all active transports - connections to CA servers.
+ * This registry contains all active transports - connections to CA servers.
*/
TransportRegistry* m_transportRegistry;
@@ -1895,7 +1898,7 @@ class TestChannelImpl : public ChannelImpl {
Mutex m_cidMapMutex;
/**
- * Last CID cache.
+ * Last CID cache.
*/
pvAccessID m_lastCID;
@@ -1907,7 +1910,7 @@ class TestChannelImpl : public ChannelImpl {
IOIDResponseRequestMap m_pendingResponseRequests;
/**
- * Last IOID cache.
+ * Last IOID cache.
*/
pvAccessID m_lastIOID;
@@ -1923,7 +1926,7 @@ class TestChannelImpl : public ChannelImpl {
// TODO consider std::unordered_map
// typedef std::map AddressBeaconHandlerMap;
// AddressBeaconHandlerMap m_beaconHandlers;
-
+
/**
* Version.
*/
@@ -1933,18 +1936,20 @@ class TestChannelImpl : public ChannelImpl {
* Provider implementation.
*/
ChannelProviderImpl* m_provider;
-
+
/**
* Context state.
*/
ContextState m_contextState;
-
+
/**
* Context sync. mutex.
*/
Mutex m_contextMutex;
friend class ChannelProviderImpl;
+
+ Configuration* m_configuration;
};
@@ -1953,7 +1958,7 @@ class ChannelFindRequesterImpl : public ChannelFindRequester
virtual void channelFindResult(epics::pvData::Status *status,ChannelFind *channelFind,bool wasFound)
{
std::cout << "[ChannelFindRequesterImpl] channelFindResult("
- << status->toString() << ", ..., " << wasFound << ")" << std::endl;
+ << status->toString() << ", ..., " << wasFound << ")" << std::endl;
}
};
@@ -1963,10 +1968,10 @@ class ChannelRequesterImpl : public ChannelRequester
{
return "ChannelRequesterImpl";
};
-
- virtual void message(String message,MessageType messageType)
+
+ virtual void message(String message,MessageType messageType)
{
- std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
+ std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
virtual void channelCreated(epics::pvData::Status* status, Channel *channel)
@@ -1974,7 +1979,7 @@ class ChannelRequesterImpl : public ChannelRequester
std::cout << "channelCreated(" << status->toString() << ", "
<< (channel ? channel->getChannelName() : "(null)") << ")" << std::endl;
}
-
+
virtual void channelStateChange(Channel *c, ConnectionState connectionState)
{
std::cout << "channelStateChange(" << c->getChannelName() << ", " << ConnectionStateNames[connectionState] << ")" << std::endl;
@@ -1987,10 +1992,10 @@ class GetFieldRequesterImpl : public GetFieldRequester
{
return "GetFieldRequesterImpl";
};
-
- virtual void message(String message,MessageType messageType)
+
+ virtual void message(String message,MessageType messageType)
{
- std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
+ std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
virtual void getDone(epics::pvData::Status *status,epics::pvData::FieldConstPtr field)
@@ -2013,22 +2018,22 @@ class ChannelGetRequesterImpl : public ChannelGetRequester
ChannelGet *m_channelGet;
epics::pvData::PVStructure *m_pvStructure;
epics::pvData::BitSet *m_bitSet;
-
+
virtual String getRequesterName()
{
return "ChannelGetRequesterImpl";
};
-
- virtual void message(String message,MessageType messageType)
+
+ virtual void message(String message,MessageType messageType)
{
- std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
+ std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
virtual void channelGetConnect(epics::pvData::Status *status,ChannelGet *channelGet,
epics::pvData::PVStructure *pvStructure,epics::pvData::BitSet *bitSet)
{
std::cout << "channelGetConnect(" << status->toString() << ")" << std::endl;
-
+
// TODO sync
m_channelGet = channelGet;
m_pvStructure = pvStructure;
@@ -2050,22 +2055,22 @@ class ChannelPutRequesterImpl : public ChannelPutRequester
ChannelPut *m_channelPut;
epics::pvData::PVStructure *m_pvStructure;
epics::pvData::BitSet *m_bitSet;
-
+
virtual String getRequesterName()
{
return "ChannelPutRequesterImpl";
};
-
- virtual void message(String message,MessageType messageType)
+
+ virtual void message(String message,MessageType messageType)
{
- std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
+ std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
virtual void channelPutConnect(epics::pvData::Status *status,ChannelPut *channelPut,
epics::pvData::PVStructure *pvStructure,epics::pvData::BitSet *bitSet)
{
std::cout << "channelPutConnect(" << status->toString() << ")" << std::endl;
-
+
// TODO sync
m_channelPut = channelPut;
m_pvStructure = pvStructure;
@@ -2091,20 +2096,20 @@ class ChannelPutRequesterImpl : public ChannelPutRequester
}
};
-
-
+
+
class MonitorRequesterImpl : public MonitorRequester
{
virtual String getRequesterName()
{
return "MonitorRequesterImpl";
};
-
- virtual void message(String message,MessageType messageType)
+
+ virtual void message(String message,MessageType messageType)
{
- std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
+ std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
-
+
virtual void monitorConnect(Status* status, Monitor* monitor, Structure* structure)
{
std::cout << "monitorConnect(" << status->toString() << ")" << std::endl;
@@ -2115,13 +2120,13 @@ class MonitorRequesterImpl : public MonitorRequester
std::cout << str << std::endl;
}
}
-
+
virtual void monitorEvent(Monitor* monitor)
{
std::cout << "monitorEvent" << std::endl;
MonitorElement* element = monitor->poll();
-
+
String str("changed/overrun ");
element->getChangedBitSet()->toString(&str);
str += '/';
@@ -2129,35 +2134,35 @@ class MonitorRequesterImpl : public MonitorRequester
str += '\n';
element->getPVStructure()->toString(&str);
std::cout << str << std::endl;
-
+
monitor->release(element);
}
-
+
virtual void unlisten(Monitor* monitor)
{
std::cout << "unlisten" << std::endl;
}
-};
+};
class ChannelProcessRequesterImpl : public ChannelProcessRequester
{
ChannelProcess *m_channelProcess;
-
+
virtual String getRequesterName()
{
return "ProcessRequesterImpl";
};
-
- virtual void message(String message,MessageType messageType)
+
+ virtual void message(String message,MessageType messageType)
{
- std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
+ std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl;
}
virtual void channelProcessConnect(epics::pvData::Status *status,ChannelProcess *channelProcess)
{
std::cout << "channelProcessConnect(" << status->toString() << ")" << std::endl;
-
+
// TODO sync
m_channelProcess = channelProcess;
}
@@ -2174,33 +2179,33 @@ int main(int argc,char *argv[])
TestClientContextImpl* context = new TestClientContextImpl();
context->printInfo();
- context->initialize();
+ context->initialize();
context->printInfo();
-
+
epicsThreadSleep ( 1.0 );
-
+
//ChannelFindRequesterImpl findRequester;
//context->getProvider()->channelFind("something", &findRequester);
-
+
ChannelRequesterImpl channelRequester;
Channel* channel = context->getProvider()->createChannel("structureArrayTest", &channelRequester);
channel->printInfo();
/*
GetFieldRequesterImpl getFieldRequesterImpl;
channel->getField(&getFieldRequesterImpl, "timeStamp.secondsPastEpoch");
-
+
ChannelGetRequesterImpl channelGetRequesterImpl;
ChannelGet* channelGet = channel->createChannelGet(&channelGetRequesterImpl, 0);
channelGet->get(false);
channelGet->destroy();
-
+
ChannelPutRequesterImpl channelPutRequesterImpl;
ChannelPut* channelPut = channel->createChannelPut(&channelPutRequesterImpl, 0);
channelPut->get();
channelPut->put(false);
channelPut->destroy();
-
-
+
+
MonitorRequesterImpl monitorRequesterImpl;
Monitor* monitor = channel->createMonitor(&monitorRequesterImpl, 0);
@@ -2213,20 +2218,20 @@ int main(int argc,char *argv[])
ChannelProcess* channelProcess = channel->createChannelProcess(&channelProcessRequester, 0);
channelProcess->process(false);
channelProcess->destroy();
-
+
status = monitor->stop();
std::cout << "monitor->stop() = " << status->toString() << std::endl;
delete status;
-
-
+
+
monitor->destroy();
*/
epicsThreadSleep ( 100.0 );
channel->destroy();
-
+
context->destroy();
-
+
std::cout << "-----------------------------------------------------------------------" << std::endl;
getShowConstructDestruct()->constuctDestructTotals(stdout);
return(0);
diff --git a/testApp/utils/arrayFIFOTest.cpp b/testApp/utils/arrayFIFOTest.cpp
index 61cbfc7..966d2c1 100644
--- a/testApp/utils/arrayFIFOTest.cpp
+++ b/testApp/utils/arrayFIFOTest.cpp
@@ -15,7 +15,9 @@ using namespace epics::pvAccess;
using std::cout;
using std::endl;
-int main(int argc, char *argv[]) {
+void testSimpleType() {
+ cout<<"\nTests for simple type template."< fifoInt;
assert(fifoInt.size()==0);
@@ -133,5 +135,137 @@ int main(int argc, char *argv[]) {
assert(fifoInt.isEmpty());
cout<<"\nPASSED!\n";
+}
+
+void testPointerType() {
+ cout<<"\nTests for pointer type template."< fifoInt;
+
+ assert(fifoInt.size()==0);
+ assert(fifoInt.isEmpty());
+
+ cout<<"Testing clear."< cb(CAPACITY);
- cout<<"Testing circular buffer."< cb(CAPACITY);
+ int testVals[] = {0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20};
+
+ cout<<"Testing circular buffer pointer type."<
#include
@@ -23,6 +24,7 @@ using std::stringstream;
using std::hex;
int main(int argc, char *argv[]) {
+ createFileLogger("inetAddresUtils.log");
InetAddrVector *vec;
InetAddrVector *vec1;
@@ -126,12 +128,12 @@ int main(int argc, char *argv[]) {
assert(strncmp(buff->getArray(), src, 16)==0);
cout<<"\nPASSED!\n";
- SOCKET socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0);
- InetAddrVector* broadcasts = getBroadcastAddresses(socket);
+ SOCKET socket = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ InetAddrVector* broadcasts = getBroadcastAddresses(socket,6678);
cout<<"Broadcast addresses: "<size()<size(); i++) {
cout<<"Broadcast address: ";
- cout<at(i), false)<at(i))<