merging
This commit is contained in:
11
.cproject
11
.cproject
@@ -307,7 +307,6 @@
|
||||
<buildTargets>
|
||||
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
@@ -315,7 +314,6 @@
|
||||
</target>
|
||||
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
@@ -323,11 +321,20 @@
|
||||
</target>
|
||||
<target name="uninstall" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>uninstall</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
<target name="debug" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>clean all DEBUG=1</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
|
||||
@@ -24,4 +24,11 @@
|
||||
# take effect.
|
||||
#IOCS_APPL_TOP = </IOC/path/to/application/top>
|
||||
|
||||
USR_LDFLAGS += -lpthread
|
||||
ifeq ($(DEBUG),1)
|
||||
DEBUG_CFLAGS=-O0 -g -ggdb
|
||||
endif
|
||||
|
||||
ifeq ($(EPICS_HOST_ARCH),linux-x86)
|
||||
USR_LDFLAGS += -lpthread
|
||||
endif
|
||||
|
||||
|
||||
@@ -67,6 +67,12 @@ LIBSRCS += blockingTCPConnector.cpp
|
||||
LIBSRCS += blockingServerTCPTransport.cpp
|
||||
LIBSRCS += blockingTCPAcceptor.cpp
|
||||
LIBSRCS += channelSearchManager.cpp
|
||||
LIBSRCS += abstractResponseHandler.cpp
|
||||
|
||||
|
||||
SRC_DIRS += $(PVACCESS)/remoteClient
|
||||
INC += clientContextImpl.h
|
||||
|
||||
|
||||
LIBRARY = pvAccess
|
||||
pvAccess_LIBS += Com
|
||||
|
||||
42
pvAccessApp/remote/abstractResponseHandler.cpp
Normal file
42
pvAccessApp/remote/abstractResponseHandler.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* abstractResponseHandler.cpp
|
||||
*
|
||||
* Created on: Jan 10, 2011
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#include "remote.h"
|
||||
#include "hexDump.h"
|
||||
|
||||
#include <byteBuffer.h>
|
||||
|
||||
#include <osiSock.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
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"<<hex<<(int)command<<", v0x"<<hex;
|
||||
prologue<<(int)version<<"] received from "<<ipAddrStr;
|
||||
|
||||
hexDump(prologue.str(), _description,
|
||||
(const int8*)payloadBuffer->getArray(),
|
||||
payloadBuffer->getPosition(), payloadSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,9 @@
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace pvAccess {
|
||||
//TODO delete this
|
||||
|
||||
class ClientContextImpl;
|
||||
|
||||
/**
|
||||
* BeaconHandler
|
||||
*/
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace epics {
|
||||
if(_closed) return false;
|
||||
|
||||
char ipAddrStr[48];
|
||||
ipAddrToA(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
ipAddrToDottedIP(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
errlogSevPrintf(errlogInfo, "Acquiring transport to %s.", ipAddrStr);
|
||||
|
||||
_ownersMutex->lock();
|
||||
@@ -127,7 +127,7 @@ namespace epics {
|
||||
int refs = _owners->size();
|
||||
if(refs>0) {
|
||||
char ipAddrStr[48];
|
||||
ipAddrToA(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
ipAddrToDottedIP(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
errlogSevPrintf(
|
||||
errlogInfo,
|
||||
"Transport to %s still has %d client(s) active and closing...",
|
||||
@@ -145,7 +145,7 @@ namespace epics {
|
||||
if(_closed) return;
|
||||
|
||||
char ipAddrStr[48];
|
||||
ipAddrToA(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
ipAddrToDottedIP(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
|
||||
errlogSevPrintf(errlogInfo, "Releasing transport to %s.", ipAddrStr);
|
||||
|
||||
|
||||
@@ -52,14 +52,14 @@ namespace epics {
|
||||
if(_channels->size()==0) return;
|
||||
|
||||
char ipAddrStr[64];
|
||||
ipAddrToA(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
ipAddrToDottedIP(&_socketAddress->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
|
||||
errlogSevPrintf(
|
||||
errlogInfo,
|
||||
"Transport to %s still has %d channel(s) active and closing...",
|
||||
ipAddrStr, _channels->size());
|
||||
|
||||
map<int, ServerChannel*>::iterator it = _channels->begin();
|
||||
map<pvAccessID, ServerChannel*>::iterator it = _channels->begin();
|
||||
for(; it!=_channels->end(); it++)
|
||||
it->second->destroy();
|
||||
|
||||
@@ -71,30 +71,30 @@ namespace epics {
|
||||
destroyAllChannels();
|
||||
}
|
||||
|
||||
int BlockingServerTCPTransport::preallocateChannelSID() {
|
||||
pvAccessID BlockingServerTCPTransport::preallocateChannelSID() {
|
||||
Lock lock(_channelsMutex);
|
||||
// search first free (theoretically possible loop of death)
|
||||
int sid = ++_lastChannelSID;
|
||||
pvAccessID sid = ++_lastChannelSID;
|
||||
while(_channels->find(sid)!=_channels->end())
|
||||
sid = ++_lastChannelSID;
|
||||
return sid;
|
||||
}
|
||||
|
||||
void BlockingServerTCPTransport::registerChannel(int sid,
|
||||
void BlockingServerTCPTransport::registerChannel(pvAccessID sid,
|
||||
ServerChannel* channel) {
|
||||
Lock lock(_channelsMutex);
|
||||
(*_channels)[sid] = channel;
|
||||
}
|
||||
|
||||
void BlockingServerTCPTransport::unregisterChannel(int sid) {
|
||||
void BlockingServerTCPTransport::unregisterChannel(pvAccessID sid) {
|
||||
Lock lock(_channelsMutex);
|
||||
_channels->erase(sid);
|
||||
}
|
||||
|
||||
ServerChannel* BlockingServerTCPTransport::getChannel(int sid) {
|
||||
ServerChannel* BlockingServerTCPTransport::getChannel(pvAccessID sid) {
|
||||
Lock lock(_channelsMutex);
|
||||
|
||||
map<int, ServerChannel*>::iterator it = _channels->find(sid);
|
||||
map<pvAccessID, ServerChannel*>::iterator it = _channels->find(sid);
|
||||
if(it!=_channels->end()) return it->second;
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -547,13 +547,13 @@ namespace epics {
|
||||
* Preallocate new channel SID.
|
||||
* @return new channel server id (SID).
|
||||
*/
|
||||
virtual int preallocateChannelSID();
|
||||
virtual pvAccessID preallocateChannelSID();
|
||||
|
||||
/**
|
||||
* De-preallocate new channel SID.
|
||||
* @param sid preallocated channel SID.
|
||||
*/
|
||||
virtual void depreallocateChannelSID(int sid) {
|
||||
virtual void depreallocateChannelSID(pvAccessID sid) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@@ -562,20 +562,20 @@ namespace epics {
|
||||
* @param sid preallocated channel SID.
|
||||
* @param channel channel to register.
|
||||
*/
|
||||
virtual void registerChannel(int sid, ServerChannel* channel);
|
||||
virtual void registerChannel(pvAccessID sid, ServerChannel* channel);
|
||||
|
||||
/**
|
||||
* Unregister a new channel (and deallocates its handle).
|
||||
* @param sid SID
|
||||
*/
|
||||
virtual void unregisterChannel(int sid);
|
||||
virtual void unregisterChannel(pvAccessID sid);
|
||||
|
||||
/**
|
||||
* Get channel by its SID.
|
||||
* @param sid channel SID
|
||||
* @return channel with given SID, <code>NULL</code> otherwise
|
||||
*/
|
||||
virtual ServerChannel* getChannel(int sid);
|
||||
virtual ServerChannel* getChannel(pvAccessID sid);
|
||||
|
||||
/**
|
||||
* Get channel count.
|
||||
@@ -640,12 +640,12 @@ namespace epics {
|
||||
/**
|
||||
* Last SID cache.
|
||||
*/
|
||||
volatile int _lastChannelSID;
|
||||
volatile pvAccessID _lastChannelSID;
|
||||
|
||||
/**
|
||||
* Channel table (SID -> channel mapping).
|
||||
*/
|
||||
std::map<int, ServerChannel*>* _channels;
|
||||
std::map<pvAccessID, ServerChannel*>* _channels;
|
||||
|
||||
Mutex* _channelsMutex;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace epics {
|
||||
if(tryCount>0) epicsThreadSleep(0.1);
|
||||
|
||||
char strBuffer[64];
|
||||
ipAddrToA(&address.ia, strBuffer, sizeof(strBuffer));
|
||||
ipAddrToDottedIP(&address.ia, strBuffer, sizeof(strBuffer));
|
||||
|
||||
errlogSevPrintf(errlogInfo,
|
||||
"Opening socket to CA server %s, attempt %d.",
|
||||
@@ -73,7 +73,7 @@ namespace epics {
|
||||
SOCKET socket = INVALID_SOCKET;
|
||||
|
||||
char ipAddrStr[64];
|
||||
ipAddrToA(&address.ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
ipAddrToDottedIP(&address.ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
|
||||
// first try to check cache w/o named lock...
|
||||
BlockingClientTCPTransport
|
||||
@@ -106,6 +106,17 @@ namespace epics {
|
||||
ipAddrStr);
|
||||
|
||||
socket = tryConnect(address, 3);
|
||||
// verify
|
||||
if(socket==INVALID_SOCKET) {
|
||||
errlogSevPrintf(
|
||||
errlogMajor,
|
||||
"Connection to CA server %s failed.",
|
||||
ipAddrStr);
|
||||
ostringstream temp;
|
||||
temp<<"Failed to verify TCP connection to '"<<ipAddrStr
|
||||
<<"'.";
|
||||
THROW_BASE_EXCEPTION(temp.str().c_str());
|
||||
}
|
||||
|
||||
// use blocking channel
|
||||
// socket is blocking bya default
|
||||
@@ -138,7 +149,7 @@ namespace epics {
|
||||
if(!transport->waitUntilVerified(3.0)) {
|
||||
transport->close(true);
|
||||
errlogSevPrintf(
|
||||
errlogInfo,
|
||||
errlogMinor,
|
||||
"Connection to CA server %s failed to be validated, closing it.",
|
||||
ipAddrStr);
|
||||
ostringstream temp;
|
||||
|
||||
@@ -24,216 +24,6 @@ using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace pvAccess {
|
||||
|
||||
typedef int32 pvAccessID;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
//TODO this will be deleted
|
||||
class ChannelImpl;
|
||||
class ChannelSearchManager;
|
||||
class ClientContextImpl : public ClientContext
|
||||
{
|
||||
private:
|
||||
Timer* _timer;
|
||||
public:
|
||||
|
||||
ClientContextImpl()
|
||||
{
|
||||
_timer = new Timer("krneki",lowPriority);
|
||||
}
|
||||
|
||||
virtual Version* getVersion() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual ChannelProvider* getProvider() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Timer* getTimer()
|
||||
{
|
||||
return _timer;
|
||||
}
|
||||
|
||||
virtual void initialize() {
|
||||
|
||||
}
|
||||
|
||||
virtual void printInfo() {
|
||||
|
||||
}
|
||||
|
||||
virtual void printInfo(epics::pvData::StringBuilder out) {
|
||||
|
||||
}
|
||||
|
||||
virtual void destroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BlockingUDPTransport* getSearchTransport()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a channel with given channel ID.
|
||||
* @param channelID CID.
|
||||
* @return channel with given CID, <code>0</code> if non-existent.
|
||||
*/
|
||||
ChannelImpl* getChannel(pvAccessID channelID)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
~ClientContextImpl() { delete _timer;};
|
||||
private:
|
||||
|
||||
|
||||
void loadConfiguration() {
|
||||
|
||||
}
|
||||
|
||||
void internalInitialize() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void initializeUDPTransport() {
|
||||
|
||||
}
|
||||
|
||||
void internalDestroy() {
|
||||
|
||||
}
|
||||
|
||||
void destroyAllChannels() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check channel name.
|
||||
*/
|
||||
void checkChannelName(String& name) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check context state and tries to establish necessary state.
|
||||
*/
|
||||
void checkState() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generate Client channel ID (CID).
|
||||
* @return Client channel ID (CID).
|
||||
*/
|
||||
pvAccessID generateCID()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free generated channel ID (CID).
|
||||
*/
|
||||
void freeCID(int cid)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get, or create if necessary, transport of given server address.
|
||||
* @param serverAddress required transport address
|
||||
* @param priority process priority.
|
||||
* @return transport for given address
|
||||
*/
|
||||
Transport* getTransport(TransportClient* client, osiSockAddr* serverAddress, int16 minorRevision, int16 priority)
|
||||
{
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal create channel.
|
||||
*/
|
||||
// TODO no minor version with the addresses
|
||||
// TODO what if there is an channel with the same name, but on different host!
|
||||
Channel* createChannelInternal(String name, ChannelRequester* requester, short priority,
|
||||
InetAddrVector* addresses) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy channel.
|
||||
* @param channel
|
||||
* @param force
|
||||
* @throws CAException
|
||||
* @throws IllegalStateException
|
||||
*/
|
||||
void destroyChannel(ChannelImpl* channel, bool force) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get channel search manager.
|
||||
* @return channel search manager.
|
||||
*/
|
||||
ChannelSearchManager* getChannelSearchManager() {
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//TODO check the const of paramerers
|
||||
|
||||
/**
|
||||
@@ -250,13 +40,13 @@ public:
|
||||
*
|
||||
* @return channel ID.
|
||||
*/
|
||||
virtual pvAccessID getChannelID() = 0;
|
||||
virtual pvAccessID getSearchInstanceID() = 0;
|
||||
/**
|
||||
* Return channel name.
|
||||
* Return search instance, e.g. channel, name.
|
||||
*
|
||||
* @return channel channel name.
|
||||
*/
|
||||
virtual String getChannelName() = 0;
|
||||
virtual String getSearchInstanceName() = 0;
|
||||
/**
|
||||
* Removes the owner of this search instance.
|
||||
*/
|
||||
@@ -303,8 +93,8 @@ class BaseSearchInstance : public SearchInstance
|
||||
{
|
||||
public:
|
||||
virtual ~BaseSearchInstance() {};
|
||||
virtual pvAccessID getChannelID() = 0;
|
||||
virtual string getChannelName() = 0;
|
||||
virtual pvAccessID getSearchInstanceID() = 0;
|
||||
virtual String getSearchInstanceName() = 0;
|
||||
virtual void unsetListOwnership();
|
||||
virtual void addAndSetListOwnership(ArrayFIFO<SearchInstance*>* newOwner, Mutex* ownerMutex, int32 index);
|
||||
virtual void removeAndUnsetListOwnership();
|
||||
@@ -479,7 +269,7 @@ public:
|
||||
* Constructor.
|
||||
* @param context
|
||||
*/
|
||||
ChannelSearchManager(ClientContextImpl* context);
|
||||
ChannelSearchManager(Context* context);
|
||||
/**
|
||||
* Constructor.
|
||||
* @param context
|
||||
@@ -533,7 +323,7 @@ private:
|
||||
/**
|
||||
* Context.
|
||||
*/
|
||||
ClientContextImpl* _context;
|
||||
Context* _context;
|
||||
/**
|
||||
* Canceled flag.
|
||||
*/
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "caConstants.h"
|
||||
#include "transportRegistry.h"
|
||||
#include "introspectionRegistry.h"
|
||||
#include "serverContext.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#include <serialize.h>
|
||||
#include <pvType.h>
|
||||
@@ -31,6 +31,47 @@ namespace epics {
|
||||
TCP, UDP, SSL
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
typedef int32 pvAccessID;
|
||||
|
||||
enum MessageCommands {
|
||||
CMD_BEACON = 0, CMD_CONNECTION_VALIDATION = 1, CMD_ECHO = 2,
|
||||
CMD_SEARCH = 3, CMD_SEARCH_RESPONSE = 4,
|
||||
@@ -212,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 <a href="mailto:matej.sekoranjaATcosylab.com">Matej Sekoranja</a>
|
||||
@@ -219,12 +289,9 @@ namespace epics {
|
||||
*/
|
||||
class ResponseHandler {
|
||||
public:
|
||||
virtual ~ResponseHandler() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle response.
|
||||
* @param[in] responseFrom remote address of the responder, <code>null</code> if unknown.
|
||||
* @param[in] responseFrom remote address of the responder, <code>0</code> if unknown.
|
||||
* @param[in] transport response source transport.
|
||||
* @param[in] version message version.
|
||||
* @param[in] payloadSize size of this message data available in the <code>payloadBuffer</code>.
|
||||
@@ -248,9 +315,9 @@ namespace epics {
|
||||
/**
|
||||
* @param description
|
||||
*/
|
||||
AbstractResponseHandler(String description) :
|
||||
_description(description), _debug(true) {
|
||||
//debug = System.getProperties().containsKey(CAConstants.CAJ_DEBUG);
|
||||
AbstractResponseHandler(Context* context, String description) :
|
||||
_description(description),
|
||||
_debug(context->getConfiguration()->getPropertyAsBoolean("PVACCESS_DEBUG", false)) {
|
||||
}
|
||||
|
||||
virtual ~AbstractResponseHandler() {
|
||||
@@ -332,23 +399,6 @@ namespace epics {
|
||||
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface defining reference counting transport IF.
|
||||
* @author <a href="mailto:matej.sekoranjaATcosylab.com">Matej Sekoranja</a>
|
||||
@@ -381,7 +431,7 @@ namespace epics {
|
||||
* Get channel SID.
|
||||
* @return channel SID.
|
||||
*/
|
||||
virtual int getSID() =0;
|
||||
virtual pvAccessID getSID() =0;
|
||||
|
||||
/**
|
||||
* Destroy server channel.
|
||||
@@ -410,33 +460,34 @@ namespace epics {
|
||||
* Preallocate new channel SID.
|
||||
* @return new channel server id (SID).
|
||||
*/
|
||||
virtual int preallocateChannelSID() =0;
|
||||
virtual pvAccessID preallocateChannelSID() =0;
|
||||
|
||||
/**
|
||||
* De-preallocate new channel SID.
|
||||
* @param sid preallocated channel SID.
|
||||
*/
|
||||
virtual void depreallocateChannelSID(int sid) =0;
|
||||
virtual void depreallocateChannelSID(pvAccessID sid) =0;
|
||||
|
||||
/**
|
||||
* Register a new channel.
|
||||
* @param sid preallocated channel SID.
|
||||
* @param channel channel to register.
|
||||
*/
|
||||
virtual void registerChannel(int sid, ServerChannel* channel) =0;
|
||||
virtual void
|
||||
registerChannel(pvAccessID sid, ServerChannel* channel) =0;
|
||||
|
||||
/**
|
||||
* Unregister a new channel (and deallocates its handle).
|
||||
* @param sid SID
|
||||
*/
|
||||
virtual void unregisterChannel(int sid) =0;
|
||||
virtual void unregisterChannel(pvAccessID sid) =0;
|
||||
|
||||
/**
|
||||
* Get channel by its SID.
|
||||
* @param sid channel SID
|
||||
* @return channel with given SID, <code>null</code> otherwise
|
||||
*/
|
||||
virtual ServerChannel* getChannel(int sid) =0;
|
||||
virtual ServerChannel* getChannel(pvAccessID sid) =0;
|
||||
|
||||
/**
|
||||
* Get channel count.
|
||||
@@ -445,6 +496,44 @@ namespace epics {
|
||||
virtual int getChannelCount() =0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A request that expects an response.
|
||||
* Responses identified by its I/O ID.
|
||||
* This interface needs to be extended (to provide method called on response).
|
||||
* @author <a href="mailto:matej.sekoranjaATcosylab.com">Matej Sekoranja</a>
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
53
pvAccessApp/remoteClient/clientContextImpl.h
Normal file
53
pvAccessApp/remoteClient/clientContextImpl.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* clientContext.h
|
||||
*
|
||||
* Created on: Dec 21, 2010
|
||||
* Author: msekoran
|
||||
*/
|
||||
|
||||
#ifndef CLIENTCONTEXTIMPL_H_
|
||||
#define CLIENTCONTEXTIMPL_H_
|
||||
|
||||
#include <pvAccess.h>
|
||||
#include <remote.h>
|
||||
#include <channelSearchManager.h>
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
class ChannelImpl :
|
||||
public Channel ,
|
||||
public TransportClient,
|
||||
public TransportSender,
|
||||
public BaseSearchInstance
|
||||
{
|
||||
public:
|
||||
virtual pvAccessID getChannelID() = 0;
|
||||
virtual void destroyChannel(bool force) = 0;
|
||||
virtual void connectionCompleted(pvAccessID sid/*, rights*/) = 0;
|
||||
virtual void createChannelFailed() = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class ClientContextImpl : public ClientContext, public Context
|
||||
{
|
||||
public:
|
||||
virtual ChannelSearchManager* getChannelSearchManager() = 0;
|
||||
virtual void checkChannelName(String& name) = 0;
|
||||
|
||||
virtual void registerChannel(ChannelImpl* channel) = 0;
|
||||
virtual void unregisterChannel(ChannelImpl* channel) = 0;
|
||||
|
||||
virtual void destroyChannel(ChannelImpl* channel, bool force) = 0;
|
||||
virtual ChannelImpl* createChannelInternal(String name, ChannelRequester* requester, short priority, InetAddrVector* addresses) = 0;
|
||||
|
||||
virtual Transport* getTransport(TransportClient* client, osiSockAddr* serverAddress, int16 minorRevision, int16 priority) = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CLIENTCONTEXTIMPL_H_ */
|
||||
@@ -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];
|
||||
ipAddrToA(&responseFrom->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
|
||||
ostringstream prologue;
|
||||
prologue<<"Message [0x"<<hex<<(int)command<<", v0x"<<hex;
|
||||
prologue<<(int)version<<"] received from "<<ipAddrStr;
|
||||
|
||||
hexDump(prologue.str(), _description,
|
||||
(const int8*)payloadBuffer->getArray(),
|
||||
payloadBuffer->getPosition(), payloadSize);
|
||||
}
|
||||
}
|
||||
|
||||
void BadResponse::handleResponse(osiSockAddr* responseFrom,
|
||||
Transport* transport, int8 version, int8 command,
|
||||
int payloadSize, ByteBuffer* payloadBuffer) {
|
||||
@@ -48,7 +31,7 @@ namespace epics {
|
||||
transport, version, command, payloadSize, payloadBuffer);
|
||||
|
||||
char ipAddrStr[48];
|
||||
ipAddrToA(&responseFrom->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
ipAddrToDottedIP(&responseFrom->ia, ipAddrStr, sizeof(ipAddrStr));
|
||||
|
||||
errlogSevPrintf(errlogInfo,
|
||||
"Undecipherable message (bad response type %d) from %s.",
|
||||
@@ -56,16 +39,15 @@ namespace epics {
|
||||
|
||||
}
|
||||
|
||||
ServerResponseHandler::ServerResponseHandler(ServerContextImpl* context) :
|
||||
_context(context) {
|
||||
ServerResponseHandler::ServerResponseHandler(ServerContextImpl* 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;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef RESPONSEHANDLERS_H_
|
||||
#define RESPONSEHANDLERS_H_
|
||||
|
||||
#include "serverContext.h"
|
||||
#include "remote.h"
|
||||
|
||||
namespace epics {
|
||||
@@ -18,20 +19,19 @@ namespace epics {
|
||||
* @version $Id: AbstractServerResponseHandler.java,v 1.1 2010/05/03 14:45:39 mrkraimer Exp $
|
||||
*/
|
||||
class AbstractServerResponseHandler : public AbstractResponseHandler {
|
||||
protected:
|
||||
ServerContextImpl* _context;
|
||||
public:
|
||||
/**
|
||||
* @param context
|
||||
* @param description
|
||||
*/
|
||||
AbstractServerResponseHandler(ServerContextImpl* context,
|
||||
String description) :
|
||||
AbstractResponseHandler(description), _context(context) {
|
||||
AbstractServerResponseHandler(ServerContextImpl* context, String description) :
|
||||
AbstractResponseHandler(context, description), _context(context) {
|
||||
}
|
||||
|
||||
virtual ~AbstractServerResponseHandler() {
|
||||
}
|
||||
protected:
|
||||
ServerContextImpl* _context;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -77,11 +77,6 @@ namespace epics {
|
||||
*/
|
||||
ResponseHandler** _handlerTable;
|
||||
|
||||
/**
|
||||
* Context instance.
|
||||
*/
|
||||
ServerContextImpl* _context;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
#ifndef SERVERCONTEXT_H_
|
||||
#define SERVERCONTEXT_H_
|
||||
|
||||
#include "remote.h"
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
|
||||
class ServerContextImpl {
|
||||
class ServerContextImpl : public Context {
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ namespace epics {
|
||||
T ArrayFIFO<T>::pollFirst() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
if(isEmpty()) THROW_BASE_EXCEPTION("ArrayFIFO empty");
|
||||
if(isEmpty()) return 0;
|
||||
|
||||
T result = _elements[_head]; // Element is null if deque empty
|
||||
_head = (_head+1)&(_size-1);
|
||||
@@ -254,7 +254,7 @@ namespace epics {
|
||||
T ArrayFIFO<T>::pollLast() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
if(isEmpty()) THROW_BASE_EXCEPTION("ArrayFIFO empty");
|
||||
if(isEmpty()) return 0;
|
||||
|
||||
_tail = (_tail-1)&(_size-1);
|
||||
return _elements[_tail];
|
||||
@@ -264,7 +264,7 @@ namespace epics {
|
||||
T ArrayFIFO<T>::peekFirst() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
if(isEmpty()) THROW_BASE_EXCEPTION("ArrayFIFO empty");
|
||||
if(isEmpty()) return 0;
|
||||
|
||||
return _elements[_head];
|
||||
}
|
||||
@@ -273,7 +273,7 @@ namespace epics {
|
||||
T ArrayFIFO<T>::peekLast() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
if(isEmpty()) THROW_BASE_EXCEPTION("ArrayFIFO empty");
|
||||
if(isEmpty()) return 0;
|
||||
|
||||
return _elements[(_tail-1)&(_size-1)];
|
||||
}
|
||||
|
||||
@@ -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<class T>
|
||||
void GrowingCircularBuffer<T>::arraycopy(T* src, size_t srcPos, T* dest,
|
||||
size_t destPos, size_t length) {
|
||||
void GrowingCircularBuffer<T>::arraycopy(T* src, size_t srcPos,
|
||||
T* dest, size_t destPos, size_t length) {
|
||||
if(srcPos<destPos) // this takes care of same-buffer copy
|
||||
for(int i = length-1; i>=0; i--)
|
||||
dest[destPos+i] = src[srcPos+i];
|
||||
@@ -111,17 +107,16 @@ namespace epics {
|
||||
|
||||
template<class T>
|
||||
bool GrowingCircularBuffer<T>::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<class T>
|
||||
@@ -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 T>
|
||||
class GrowingCircularBuffer<T*> {
|
||||
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 <code>true</code> 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<class T>
|
||||
void GrowingCircularBuffer<T*>::arraycopy(T** src, size_t srcPos,
|
||||
T** dest, size_t destPos, size_t length) {
|
||||
if(srcPos<destPos) // this takes care of same-buffer copy
|
||||
for(int i = length-1; i>=0; i--)
|
||||
dest[destPos+i] = src[srcPos+i];
|
||||
else
|
||||
for(size_t i = 0; i<length; i++)
|
||||
dest[destPos++] = src[srcPos++];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool GrowingCircularBuffer<T*>::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<T*>(x);
|
||||
if(++_putPointer>=_size) _putPointer = 0;
|
||||
return _count==1;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* GrowingCircularBuffer<T*>::extract() {
|
||||
if(_count==0) return NULL;
|
||||
|
||||
_count--;
|
||||
T* old = _elements[_takePointer];
|
||||
if(++_takePointer>=_size) _takePointer = 0;
|
||||
return old;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* GROWINGCIRCULARBUFFER_H_ */
|
||||
|
||||
@@ -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,53 +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);
|
||||
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;
|
||||
}
|
||||
|
||||
errlogPrintf("Found %d interfaces\n", ifconf.ifc_len);
|
||||
int maxNodes = ifconf.ifc_len/sizeof(ifreq);
|
||||
//errlogPrintf("Found %d interfaces\n", maxNodes);
|
||||
|
||||
pifreq = pIfreqList;
|
||||
|
||||
for(int i = 0; i<maxNodes; i++) {
|
||||
if(!(*pifreq->ifr_name)) break;
|
||||
|
||||
if(i>0) {
|
||||
size_t n = pifreq->ifr_addr.sa_len+sizeof(pifreq->ifr_name);
|
||||
if(n<sizeof(ifreq))
|
||||
pifreq++;
|
||||
else
|
||||
pifreq = (struct ifreq *)((char *)pifreq+n);
|
||||
}
|
||||
|
||||
for(int i = 0; i<=ifconf.ifc_len; i++) {
|
||||
/*
|
||||
* If its not an internet interface then dont use it
|
||||
*/
|
||||
if(pIfreqList[i].ifr_addr.sa_family!=AF_INET) continue;
|
||||
if(pifreq->ifr_addr.sa_family!=AF_INET) continue;
|
||||
|
||||
status = ioctl(sock, SIOCGIFFLAGS, &pIfreqList[i]);
|
||||
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",
|
||||
pIfreqList[i].ifr_name);
|
||||
pifreq->ifr_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* dont bother with interfaces that have been disabled
|
||||
*/
|
||||
if(!(pIfreqList[i].ifr_flags&IFF_UP)) continue;
|
||||
if(!(ifrBuff.ifr_flags&IFF_UP)) continue;
|
||||
|
||||
/*
|
||||
* dont use the loop back interface
|
||||
*/
|
||||
if(pIfreqList[i].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;
|
||||
}
|
||||
|
||||
@@ -114,40 +144,45 @@ namespace epics {
|
||||
* Otherwise CA will not query through the
|
||||
* interface.
|
||||
*/
|
||||
if(pIfreqList[i].ifr_flags&IFF_BROADCAST) {
|
||||
status = ioctl(sock, SIOCGIFBRDADDR, &pIfreqList[i]);
|
||||
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",
|
||||
pIfreqList->ifr_name);
|
||||
pifreq->ifr_name);
|
||||
delete pNewNode;
|
||||
continue;
|
||||
}
|
||||
pNewNode->sa = pIfreqList[i].ifr_broadaddr;
|
||||
pNewNode->sa = ifrBuff.ifr_broadaddr;
|
||||
}
|
||||
#ifdef IFF_POINTOPOINT
|
||||
else if(pIfreqList->ifr_flags&IFF_POINTOPOINT) {
|
||||
status = ioctl(sock, SIOCGIFDSTADDR, &pIfreqList[i]);
|
||||
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",
|
||||
pIfreqList[i].ifr_name);
|
||||
pifreq->ifr_name);
|
||||
delete pNewNode;
|
||||
continue;
|
||||
}
|
||||
pNewNode->sa = pIfreqList[i].ifr_dstaddr;
|
||||
pNewNode->sa = ifrBuff.ifr_dstaddr;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
errlogSevPrintf(
|
||||
errlogMinor,
|
||||
"getBroadcastAddresses(): net intf \"%s\": not point to point or bcast?",
|
||||
pIfreqList[i].ifr_name);
|
||||
pifreq->ifr_name);
|
||||
delete pNewNode;
|
||||
continue;
|
||||
}
|
||||
pNewNode->ia.sin_port = htons(defaultPort);
|
||||
|
||||
retVector->push_back(pNewNode);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -18,6 +18,8 @@ using namespace epics::pvData;
|
||||
class DummyResponseHandler : public ResponseHandler
|
||||
{
|
||||
public:
|
||||
DummyResponseHandler(Context* ctx) : ResponseHandler() {}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ void decodeFromIPv6Address(ByteBuffer* buffer, osiSockAddr* address)
|
||||
class BeaconResponseHandler : public ResponseHandler
|
||||
{
|
||||
public:
|
||||
BeaconResponseHandler()
|
||||
BeaconResponseHandler(Context* ctx) : ResponseHandler()
|
||||
{
|
||||
_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;
|
||||
|
||||
@@ -29,26 +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 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() {
|
||||
}
|
||||
|
||||
virtual void handleResponse(osiSockAddr* responseFrom,
|
||||
Transport* transport, int8 version, int8 command, int payloadSize,
|
||||
ByteBuffer* payloadBuffer) {
|
||||
@@ -108,7 +112,7 @@ void testBlockingTCPSender() {
|
||||
|
||||
DummyTransportClient dtc;
|
||||
DummyTransportSender dts;
|
||||
DummyResponseHandler drh;
|
||||
DummyResponseHandler drh(&ctx);
|
||||
|
||||
osiSockAddr srvAddr;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "blockingTCP.h"
|
||||
#include "remote.h"
|
||||
#include "logger.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -21,16 +22,22 @@ 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;
|
||||
}
|
||||
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 testServerConnections() {
|
||||
@@ -40,7 +47,7 @@ void testServerConnections() {
|
||||
1024);
|
||||
|
||||
cout<<"Press any key to stop the server...";
|
||||
char c = cin.peek();
|
||||
cin.peek();
|
||||
|
||||
delete srv;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,43 @@ 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)
|
||||
{ }
|
||||
|
||||
virtual void handleResponse(osiSockAddr* responseFrom,
|
||||
Transport* transport, int8 version, int8 command, int payloadSize,
|
||||
ByteBuffer* payloadBuffer) {
|
||||
@@ -69,9 +104,10 @@ private:
|
||||
|
||||
void testBlockingUDPSender() {
|
||||
BlockingUDPConnector connector(false, NULL, true);
|
||||
ContextImpl ctx;
|
||||
|
||||
DummyTransportSender dts;
|
||||
DummyResponseHandler drh;
|
||||
DummyResponseHandler drh(&ctx);
|
||||
|
||||
osiSockAddr bindAddr;
|
||||
|
||||
|
||||
@@ -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)
|
||||
: 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;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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."<<endl;
|
||||
|
||||
ArrayFIFO<int> 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."<<endl;
|
||||
|
||||
int testVals[] = {0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20};
|
||||
|
||||
ArrayFIFO<int*> fifoInt;
|
||||
|
||||
assert(fifoInt.size()==0);
|
||||
assert(fifoInt.isEmpty());
|
||||
|
||||
cout<<"Testing clear."<<endl;
|
||||
fifoInt.push(&testVals[3]);
|
||||
assert(fifoInt.size()==1);
|
||||
|
||||
fifoInt.clear();
|
||||
assert(fifoInt.isEmpty());
|
||||
|
||||
cout<<"Testing push/pop."<<endl;
|
||||
fifoInt.push(&testVals[5]);
|
||||
fifoInt.push(&testVals[6]);
|
||||
fifoInt.push(&testVals[7]);
|
||||
assert(fifoInt.size()==3);
|
||||
|
||||
assert(fifoInt.pop()==&testVals[7]);
|
||||
assert(fifoInt.size()==2);
|
||||
|
||||
assert(fifoInt.pop()==&testVals[6]);
|
||||
assert(fifoInt.size()==1);
|
||||
|
||||
assert(fifoInt.pop()==&testVals[5]);
|
||||
assert(fifoInt.size()==0);
|
||||
|
||||
cout<<"Testing FIFO ops (first/last)."<<endl;
|
||||
fifoInt.addFirst(&testVals[1]);
|
||||
fifoInt.addFirst(&testVals[2]);
|
||||
fifoInt.addFirst(&testVals[3]);
|
||||
fifoInt.addFirst(&testVals[4]);
|
||||
fifoInt.addFirst(&testVals[5]);
|
||||
|
||||
assert(fifoInt.size()==5);
|
||||
assert(fifoInt.pollLast()==&testVals[1]);
|
||||
assert(fifoInt.pollLast()==&testVals[2]);
|
||||
assert(fifoInt.pollLast()==&testVals[3]);
|
||||
assert(fifoInt.pollLast()==&testVals[4]);
|
||||
assert(fifoInt.pollLast()==&testVals[5]);
|
||||
assert(fifoInt.isEmpty());
|
||||
|
||||
cout<<"Testing FIFO ops (last/first)."<<endl;
|
||||
fifoInt.addLast(&testVals[7]);
|
||||
fifoInt.addLast(&testVals[8]);
|
||||
fifoInt.addLast(&testVals[9]);
|
||||
fifoInt.addLast(&testVals[10]);
|
||||
fifoInt.addLast(&testVals[11]);
|
||||
assert(fifoInt.size()==5);
|
||||
|
||||
assert(fifoInt.pollFirst()==&testVals[7]);
|
||||
assert(fifoInt.pollFirst()==&testVals[8]);
|
||||
assert(fifoInt.pollFirst()==&testVals[9]);
|
||||
assert(fifoInt.pollFirst()==&testVals[10]);
|
||||
assert(fifoInt.pollFirst()==&testVals[11]);
|
||||
assert(fifoInt.isEmpty());
|
||||
|
||||
cout<<"Testing remove, peek."<<endl;
|
||||
fifoInt.addFirst(&testVals[1]);
|
||||
fifoInt.addFirst(&testVals[2]);
|
||||
fifoInt.addFirst(&testVals[3]);
|
||||
fifoInt.addFirst(&testVals[4]);
|
||||
fifoInt.addFirst(&testVals[5]);
|
||||
fifoInt.addFirst(&testVals[6]);
|
||||
fifoInt.addFirst(&testVals[7]);
|
||||
// - - - - - - - - - - - -
|
||||
fifoInt.addFirst(&testVals[8]);
|
||||
fifoInt.addFirst(&testVals[9]);
|
||||
fifoInt.addFirst(&testVals[10]);
|
||||
|
||||
assert(fifoInt.peekFirst()==&testVals[10]);
|
||||
assert(fifoInt.peekLast()==&testVals[1]);
|
||||
|
||||
assert(fifoInt.size()==10);
|
||||
assert(fifoInt.remove(&testVals[9]));
|
||||
assert(fifoInt.size()==9);
|
||||
assert(!fifoInt.remove(&testVals[15]));
|
||||
assert(fifoInt.size()==9);
|
||||
|
||||
assert(fifoInt.pollLast()==&testVals[1]);
|
||||
assert(fifoInt.pollLast()==&testVals[2]);
|
||||
assert(fifoInt.pollLast()==&testVals[3]);
|
||||
assert(fifoInt.pollLast()==&testVals[4]);
|
||||
assert(fifoInt.pollLast()==&testVals[5]);
|
||||
assert(fifoInt.pollLast()==&testVals[6]);
|
||||
assert(fifoInt.pollLast()==&testVals[7]);
|
||||
assert(fifoInt.pollLast()==&testVals[8]);
|
||||
// - - - - - - - - - - - -
|
||||
assert(fifoInt.pollLast()==&testVals[10]);
|
||||
assert(fifoInt.isEmpty());
|
||||
|
||||
cout<<"Testing increase buffer."<<endl;
|
||||
fifoInt.addLast(&testVals[2]);
|
||||
fifoInt.addLast(&testVals[3]);
|
||||
fifoInt.addLast(&testVals[4]);
|
||||
fifoInt.addLast(&testVals[5]);
|
||||
fifoInt.addLast(&testVals[6]);
|
||||
fifoInt.addLast(&testVals[7]);
|
||||
fifoInt.addLast(&testVals[8]);
|
||||
fifoInt.addLast(&testVals[9]);
|
||||
fifoInt.addLast(&testVals[10]);
|
||||
fifoInt.addLast(&testVals[11]);
|
||||
fifoInt.addLast(&testVals[12]);
|
||||
fifoInt.addLast(&testVals[13]);
|
||||
fifoInt.addLast(&testVals[14]);
|
||||
fifoInt.addLast(&testVals[15]);
|
||||
fifoInt.addLast(&testVals[16]);
|
||||
fifoInt.addLast(&testVals[17]);
|
||||
fifoInt.addLast(&testVals[18]);
|
||||
fifoInt.addLast(&testVals[19]);
|
||||
|
||||
assert(fifoInt.size()==18);
|
||||
fifoInt.debugState();
|
||||
fifoInt.clear();
|
||||
assert(fifoInt.isEmpty());
|
||||
|
||||
|
||||
cout<<"\nPASSED!\n";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
testSimpleType();
|
||||
cout<<endl;
|
||||
testPointerType();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -16,19 +16,19 @@ using std::endl;
|
||||
|
||||
const size_t CAPACITY = 10;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
void testSimpleType() {
|
||||
GrowingCircularBuffer<int> cb(CAPACITY);
|
||||
|
||||
cout<<"Testing circular buffer."<<endl;
|
||||
cout<<"Testing circular buffer simple type."<<endl;
|
||||
|
||||
assert(cb.capacity()==CAPACITY);
|
||||
assert(cb.size()==0);
|
||||
|
||||
// insert, get test
|
||||
bool first = cb.insert(1);
|
||||
assert(first);
|
||||
assert(cb.size()==1);
|
||||
assert(cb.extract()==1);
|
||||
assert(first);
|
||||
assert(cb.size()==0);
|
||||
|
||||
for(size_t i = 0; i<2*CAPACITY; i++) {
|
||||
@@ -45,6 +45,45 @@ int main(int argc, char *argv[]) {
|
||||
assert(cb.size()==0);
|
||||
|
||||
cout<<"\nPASSED!\n";
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void testPointerType() {
|
||||
GrowingCircularBuffer<int*> 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."<<endl;
|
||||
|
||||
assert(cb.capacity()==CAPACITY);
|
||||
assert(cb.size()==0);
|
||||
|
||||
// insert, get test
|
||||
bool first = cb.insert(&testVals[1]);
|
||||
assert(first);
|
||||
assert(cb.size()==1);
|
||||
assert(cb.extract()==&testVals[1]);
|
||||
assert(cb.size()==0);
|
||||
|
||||
for(size_t i = 0; i<2*CAPACITY; i++) {
|
||||
first = cb.insert(&testVals[i]);
|
||||
assert(cb.size()==i+1);
|
||||
assert((cb.size() == 1)==first);
|
||||
}
|
||||
assert(cb.size()==2*CAPACITY);
|
||||
|
||||
for(size_t i = 0; i<2*CAPACITY; i++) {
|
||||
assert(cb.extract()==&testVals[i]);
|
||||
assert(cb.size()==2*CAPACITY-i-1);
|
||||
}
|
||||
assert(cb.size()==0);
|
||||
|
||||
cout<<"\nPASSED!\n";
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
testSimpleType();
|
||||
cout<<endl;
|
||||
testPointerType();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "inetAddressUtil.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <byteBuffer.h>
|
||||
#include <pvType.h>
|
||||
@@ -23,6 +24,7 @@ using std::stringstream;
|
||||
using std::hex;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
createFileLogger("inetAddresUtils.log");
|
||||
|
||||
InetAddrVector *vec;
|
||||
InetAddrVector *vec1;
|
||||
@@ -127,11 +129,11 @@ int main(int argc, char *argv[]) {
|
||||
cout<<"\nPASSED!\n";
|
||||
|
||||
SOCKET socket = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
InetAddrVector* broadcasts = getBroadcastAddresses(socket);
|
||||
InetAddrVector* broadcasts = getBroadcastAddresses(socket,6678);
|
||||
cout<<"Broadcast addresses: "<<broadcasts->size()<<endl;
|
||||
for(size_t i = 0; i<broadcasts->size(); i++) {
|
||||
cout<<"Broadcast address: ";
|
||||
cout<<inetAddressToString(broadcasts->at(i), false)<<endl;
|
||||
cout<<inetAddressToString(broadcasts->at(i))<<endl;
|
||||
}
|
||||
|
||||
delete broadcasts;
|
||||
|
||||
Reference in New Issue
Block a user