mirror of
https://github.com/nasa/trick.git
synced 2024-12-18 20:57:55 +00:00
Refactor and test Variable Server.
- Split VariableServerThread into VariableServerSession and VariableReference classes - Use C++ streams for data handling - Unit tests
This commit is contained in:
parent
e89bf083b2
commit
c2e42f4ef4
2
.gitignore
vendored
2
.gitignore
vendored
@ -41,3 +41,5 @@ trickops_logs/
|
||||
*.gcda
|
||||
*.gcno
|
||||
coverage.info
|
||||
*.dSYM
|
||||
|
||||
|
3
Makefile
3
Makefile
@ -95,6 +95,7 @@ UTILS_DIRS := \
|
||||
${TRICK_HOME}/trick_source/trick_utils/interpolator \
|
||||
${TRICK_HOME}/trick_source/trick_utils/trick_adt \
|
||||
${TRICK_HOME}/trick_source/trick_utils/comm \
|
||||
${TRICK_HOME}/trick_source/trick_utils/connection_handlers \
|
||||
${TRICK_HOME}/trick_source/trick_utils/shm \
|
||||
${TRICK_HOME}/trick_source/trick_utils/math \
|
||||
${TRICK_HOME}/trick_source/trick_utils/units \
|
||||
@ -105,6 +106,7 @@ UTILS_OBJS := $(addsuffix /object_$(TRICK_HOST_CPU)/*.o ,$(UTILS_DIRS))
|
||||
|
||||
# filter out the directories that make their own libraries
|
||||
UTILS_OBJS := $(filter-out ${TRICK_HOME}/trick_source/trick_utils/comm/%, $(UTILS_OBJS))
|
||||
UTILS_OBJS := $(filter-out ${TRICK_HOME}/trick_source/trick_utils/connection_handlers/%, $(UTILS_OBJS))
|
||||
UTILS_OBJS := $(filter-out ${TRICK_HOME}/trick_source/trick_utils/math/%, $(UTILS_OBJS))
|
||||
UTILS_OBJS := $(filter-out ${TRICK_HOME}/trick_source/trick_utils/units/%, $(UTILS_OBJS))
|
||||
UTILS_OBJS := $(filter-out ${TRICK_HOME}/trick_source/trick_utils/var_binary_parser/%, $(UTILS_OBJS))
|
||||
@ -458,6 +460,7 @@ uninstall:
|
||||
rm -f ${PREFIX}/$(notdir ${TRICK_LIB_DIR})/liber7_utils.a
|
||||
rm -f ${PREFIX}/$(notdir ${TRICK_LIB_DIR})/libtrick.a
|
||||
rm -f ${PREFIX}/$(notdir ${TRICK_LIB_DIR})/libtrick_comm.a
|
||||
rm -f ${PREFIX}/$(notdir ${TRICK_LIB_DIR})/libtrick_connection_handlers.a
|
||||
rm -f ${PREFIX}/$(notdir ${TRICK_LIB_DIR})/libtrick_math.a
|
||||
rm -f ${PREFIX}/$(notdir ${TRICK_LIB_DIR})/libtrick_mm.a
|
||||
rm -f ${PREFIX}/$(notdir ${TRICK_LIB_DIR})/libtrick_pyip.a
|
||||
|
43
include/trick/ClientConnection.hh
Normal file
43
include/trick/ClientConnection.hh
Normal file
@ -0,0 +1,43 @@
|
||||
/************************************************************************
|
||||
PURPOSE: (Abstract base class for a connection to a client. Should
|
||||
be inherited by variable server and web server connections. )
|
||||
LIBRARY DEPENDENCIES:
|
||||
() )
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef CLIENT_CONNECTION_HH
|
||||
#define CLIENT_CONNECTION_HH
|
||||
|
||||
#include <string>
|
||||
// #include <atomic>
|
||||
|
||||
namespace Trick {
|
||||
class ClientConnection {
|
||||
public:
|
||||
// Should this be here? ¯\_(ツ)_/¯
|
||||
enum ConnectionType { TCP, UDP, MCAST, WS } ;
|
||||
|
||||
virtual int initialize() = 0;
|
||||
|
||||
virtual int write (const std::string& message) = 0;
|
||||
virtual int write (char * message, int size) = 0;
|
||||
|
||||
virtual std::string read (int max_len = MAX_CMD_LEN) = 0;
|
||||
|
||||
virtual int disconnect () = 0;
|
||||
virtual std::string get_client_tag () = 0;
|
||||
virtual int set_client_tag(std::string tag) = 0;
|
||||
virtual int setBlockMode (int mode) = 0;
|
||||
|
||||
static const unsigned int MAX_CMD_LEN = 200000 ;
|
||||
|
||||
protected:
|
||||
ConnectionType _connection_type;
|
||||
|
||||
// RHEL appears to have an issue with std::atomic
|
||||
// std::atomic_bool _is_initialized;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
47
include/trick/ClientListener.hh
Normal file
47
include/trick/ClientListener.hh
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef CLIENT_LISTENER_HH
|
||||
#define CLIENT_LISTENER_HH
|
||||
|
||||
#include "trick/tc.h"
|
||||
#include "trick/TCConnection.hh"
|
||||
#include <string>
|
||||
|
||||
namespace Trick {
|
||||
|
||||
class TCConnection;
|
||||
|
||||
class ClientListener {
|
||||
public:
|
||||
ClientListener ();
|
||||
~ClientListener ();
|
||||
|
||||
// We'll see if we need separate methods for these
|
||||
int initialize(std::string hostname, int port);
|
||||
int initialize();
|
||||
|
||||
int setBlockMode(TCCommBlocking mode);
|
||||
|
||||
bool checkForNewConnections();
|
||||
|
||||
const char * getHostname ();
|
||||
|
||||
int getPort();
|
||||
|
||||
int disconnect();
|
||||
|
||||
int checkSocket();
|
||||
|
||||
bool validateSourceAddress(std::string source_address);
|
||||
|
||||
bool isInitialized();
|
||||
|
||||
friend int accept(ClientListener* listener, TCConnection* connection);
|
||||
|
||||
private:
|
||||
TCDevice _listen_dev;
|
||||
std::string saved_source;
|
||||
int port;
|
||||
bool initialized;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
28
include/trick/MulticastManager.hh
Normal file
28
include/trick/MulticastManager.hh
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
PURPOSE: ( Encapsulate multicast functionality. )
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
namespace Trick {
|
||||
class MulticastManager {
|
||||
public:
|
||||
MulticastManager();
|
||||
~MulticastManager();
|
||||
|
||||
int broadcast (std::string message);
|
||||
int addAddress (std::string addr, int port);
|
||||
int restart ();
|
||||
int initialize();
|
||||
int is_initialized();
|
||||
|
||||
|
||||
private:
|
||||
std::vector<struct sockaddr_in> addresses; /**< trick_io(**) Addresses to multicast to. */
|
||||
int mcast_socket; /**< trick_io(**) Socket opened in initialization. */
|
||||
int initialized; /**< trick_io(**) Whether manager is ready */
|
||||
|
||||
};
|
||||
}
|
48
include/trick/TCConnection.hh
Normal file
48
include/trick/TCConnection.hh
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef TC_CONNECTION_HH
|
||||
#define TC_CONNECTION_HH
|
||||
|
||||
/*
|
||||
PURPOSE: ( Encapsulate a connection with TrickComm. )
|
||||
*/
|
||||
|
||||
#include "trick/ClientConnection.hh"
|
||||
#include "trick/ClientListener.hh"
|
||||
#include "tc.h"
|
||||
|
||||
|
||||
namespace Trick {
|
||||
|
||||
class ClientListener;
|
||||
|
||||
class TCConnection : public ClientConnection {
|
||||
public:
|
||||
|
||||
TCConnection ();
|
||||
|
||||
int initialize() override;
|
||||
|
||||
int write (const std::string& message) override;
|
||||
int write (char * message, int size) override;
|
||||
|
||||
std::string read (int max_len) override;
|
||||
|
||||
int disconnect () override;
|
||||
std::string get_client_tag () override;
|
||||
int set_client_tag(std::string tag) override;
|
||||
int get_socket();
|
||||
|
||||
int setBlockMode(int block_mode) override;
|
||||
int setErrorReporting (bool on);
|
||||
|
||||
static const unsigned int MAX_CMD_LEN = 200000 ;
|
||||
|
||||
friend int accept(ClientListener* listener, TCConnection* connection);
|
||||
|
||||
private:
|
||||
TCDevice _device; /**< trick_io(**) */
|
||||
};
|
||||
|
||||
int accept(ClientListener* listener, TCConnection* connection);
|
||||
}
|
||||
|
||||
#endif
|
99
include/trick/VariableReference.hh
Normal file
99
include/trick/VariableReference.hh
Normal file
@ -0,0 +1,99 @@
|
||||
/*************************************************************************
|
||||
PURPOSE: (A variable server variable reference. Refactor of VariableReference
|
||||
based on the VariableServerVariable class previously in the webserver.)
|
||||
**************************************************************************/
|
||||
#ifndef VARIABLE_REFERENCE_HH
|
||||
#define VARIABLE_REFERENCE_HH
|
||||
|
||||
#include <time.h>
|
||||
#include <vector>
|
||||
|
||||
#include <iostream>
|
||||
#include <trick/reference.h>
|
||||
|
||||
#define MAX_ARRAY_LENGTH 4096
|
||||
|
||||
union cv_converter ;
|
||||
namespace Trick {
|
||||
class VariableReference {
|
||||
|
||||
public:
|
||||
friend std::ostream& operator<< (std::ostream& s, const Trick::VariableReference& ref);
|
||||
|
||||
VariableReference(std::string var_name);
|
||||
|
||||
// Special constructor to deal with time
|
||||
VariableReference(std::string var_name, double* time);
|
||||
|
||||
~VariableReference();
|
||||
|
||||
const char* getName() const;
|
||||
TRICK_TYPE getType() const;
|
||||
|
||||
// There are 2 different "units" variables used - REF2->units and REF2->attr->units
|
||||
// REF2->attr->units should not be changed, it is what the variable is represented in internally
|
||||
// REF2->units is the unit that has been requested by the variable server client
|
||||
// REF2->units should be null unless var_units or var_add with units is called
|
||||
// We'll refer to REF2->attr->units as BaseUnits and REF2->units as RequestedUnits
|
||||
// Encapsulate all of this away so that no one else has to think about ref->attr->units vs ref->units
|
||||
// ^ TODO: this is not where the above documentation should be. put it somewhere else.
|
||||
const char* getBaseUnits() const;
|
||||
int setRequestedUnits(std::string new_units);
|
||||
|
||||
// These variables have 2 staging buffers that we can swap between to allow for different copy and write-out modes
|
||||
// stageValue copies data from the simulation into one of the buffers (stage_buffer)
|
||||
// prepareForWrite swaps the pointers for stage_buffer and write_buffer
|
||||
// This way we can have data ready for writing, but also be copying out from the sim at the same time
|
||||
// stageValue must be called first, and then prepare for write, and then writeValue* can be called.
|
||||
int stageValue(bool validate_address = false);
|
||||
int prepareForWrite();
|
||||
bool isStaged() const;
|
||||
bool isWriteReady() const;
|
||||
|
||||
// Write out the value to the given outstream.
|
||||
// write_ready must be true
|
||||
int getSizeAscii() const;
|
||||
int getSizeBinary() const;
|
||||
int writeValueAscii( std::ostream& out ) const;
|
||||
int writeValueBinary( std::ostream& out , bool byteswap = false) const;
|
||||
int writeNameBinary( std::ostream& out, bool byteswap = false) const;
|
||||
int writeSizeBinary( std::ostream& out, bool byteswap = false) const;
|
||||
int writeTypeBinary( std::ostream& out, bool byteswap = false) const;
|
||||
|
||||
bool validate();
|
||||
void tagAsInvalid();
|
||||
|
||||
// Helper method for byteswapping
|
||||
static void byteswap_var (char * out, char * in, const VariableReference& ref);
|
||||
|
||||
// TODO: Some system for error messaging
|
||||
|
||||
private:
|
||||
VariableReference();
|
||||
void byteswap_var(char * out, char * in) const;
|
||||
|
||||
// Error refs
|
||||
static REF2* make_error_ref(std::string in_name);
|
||||
static REF2* make_do_not_resolve_ref(std::string in_name);
|
||||
|
||||
static int bad_ref_int;
|
||||
static int do_not_resolve_bad_ref_int;
|
||||
|
||||
REF2 *var_info;
|
||||
void *address; // -- address of data copied to buffer
|
||||
int size; // -- size of data copied to buffer
|
||||
bool deref; // -- indicates whether variable is pointer that needs to be dereferenced
|
||||
cv_converter * conversion_factor ; // ** udunits conversion factor
|
||||
TRICK_TYPE trick_type ; // -- Trick type of this variable
|
||||
|
||||
// TODO: use atomics for these
|
||||
bool staged;
|
||||
bool write_ready;
|
||||
|
||||
void *stage_buffer;
|
||||
void *write_buffer;
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& s, const Trick::VariableReference& ref);
|
||||
}
|
||||
#endif
|
@ -107,17 +107,33 @@ namespace Trick {
|
||||
*/
|
||||
void add_vst(pthread_t thread_id, VariableServerThread * in_vst ) ;
|
||||
|
||||
/**
|
||||
@brief Adds a vst to the map.
|
||||
*/
|
||||
void add_session(pthread_t thread_id, VariableServerSession * in_session ) ;
|
||||
|
||||
/**
|
||||
@brief Get a vst mapped by thread id
|
||||
@return the VariableServerThread mapped to the thread id if found, or NULL if not found.
|
||||
*/
|
||||
Trick::VariableServerThread * get_vst(pthread_t thread_id) ;
|
||||
|
||||
/**
|
||||
@brief Get a session mapped by thread id
|
||||
@return the VariableServerSession mapped to the thread id if found, or NULL if not found.
|
||||
*/
|
||||
Trick::VariableServerSession * get_session(pthread_t thread_id) ;
|
||||
|
||||
/**
|
||||
@brief Delete a vst in the map
|
||||
*/
|
||||
void delete_vst(pthread_t thread_id) ;
|
||||
|
||||
/**
|
||||
@brief Delete a session in the map
|
||||
*/
|
||||
void delete_session(pthread_t thread_id) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Return host name from the listen device.
|
||||
@par Python Usage:
|
||||
@ -283,6 +299,7 @@ namespace Trick {
|
||||
|
||||
/** Map thread id to the VariableServerThread object.\n */
|
||||
std::map < pthread_t , VariableServerThread * > var_server_threads ; /**< trick_io(**) */
|
||||
std::map < pthread_t , VariableServerSession * > var_server_sessions ; /**< trick_io(**) */
|
||||
|
||||
/** Mutex to ensure only one thread manipulates the map of var_server_threads\n */
|
||||
pthread_mutex_t map_mutex ; /**< trick_io(**) */
|
||||
@ -295,8 +312,6 @@ namespace Trick {
|
||||
|
||||
}
|
||||
|
||||
int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_size);
|
||||
|
||||
Trick::VariableServer * var_server_get_var_server() ;
|
||||
|
||||
// external calls to be made available from input processor
|
||||
@ -331,8 +346,8 @@ int var_set_freeze_frame_multiple(unsigned int mult) ;
|
||||
int var_set_freeze_frame_offset(unsigned int offset) ;
|
||||
int var_byteswap(bool on_off) ;
|
||||
|
||||
int var_signal() ;
|
||||
int var_multicast(bool on_off) ;
|
||||
// int var_signal() ;
|
||||
// int var_multicast(bool on_off) ;
|
||||
|
||||
int var_send_list_size() ;
|
||||
|
||||
|
@ -8,8 +8,11 @@
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "trick/tc.h"
|
||||
// #include "trick/tc.h"
|
||||
#include "trick/ClientListener.hh"
|
||||
#include "trick/SysThread.hh"
|
||||
#include "trick/MulticastManager.hh"
|
||||
|
||||
|
||||
namespace Trick {
|
||||
|
||||
@ -41,8 +44,6 @@ namespace Trick {
|
||||
virtual int init_listen_device() ;
|
||||
virtual int check_and_move_listen_device() ;
|
||||
|
||||
void create_tcp_socket(const char * address, unsigned short in_port ) ;
|
||||
|
||||
virtual void * thread_body() ;
|
||||
|
||||
int restart() ;
|
||||
@ -51,17 +52,21 @@ namespace Trick {
|
||||
void pause_listening() ;
|
||||
void restart_listening() ;
|
||||
|
||||
void create_tcp_socket(const char * address, unsigned short in_port ) ;
|
||||
|
||||
virtual void dump( std::ostream & oss = std::cout ) ;
|
||||
|
||||
protected:
|
||||
void initializeMulticast();
|
||||
|
||||
/** Requested variable server source address\n */
|
||||
std::string source_address ; /**< trick_units(--) */
|
||||
std::string requested_source_address ; /**< trick_units(--) */
|
||||
|
||||
/** Requested variable server port number.\n */
|
||||
unsigned short port ; /**< trick_units(--) */
|
||||
unsigned short requested_port ; /**< trick_units(--) */
|
||||
|
||||
/** User requested specific port number\n */
|
||||
bool user_port_requested ; /**< trick_units(--) */
|
||||
bool user_requested_address ; /**< trick_units(--) */
|
||||
|
||||
/** User defined unique tag to easily identify this variable server port.\n */
|
||||
std::string user_tag; /**< trick_units(--) */
|
||||
@ -69,8 +74,11 @@ namespace Trick {
|
||||
/** Turn on/off broadcasting of variable server port.\n */
|
||||
bool broadcast ; /**< trick_units(--) */
|
||||
|
||||
/** The listen device\n */
|
||||
TCDevice listen_dev; /**< trick_io(**) */
|
||||
/** The listen device */
|
||||
ClientListener listener;
|
||||
|
||||
/* Multicast broadcaster */
|
||||
MulticastManager multicast;
|
||||
|
||||
/** The mutex to stop accepting new connections during restart\n */
|
||||
pthread_mutex_t restart_pause ; /**< trick_io(**) */
|
||||
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
PURPOSE:
|
||||
(VariableServerReference)
|
||||
*/
|
||||
|
||||
#ifndef VARIABLESERVERREFERENCE_HH
|
||||
#define VARIABLESERVERREFERENCE_HH
|
||||
|
||||
#include <iostream>
|
||||
#include "trick/reference.h"
|
||||
|
||||
union cv_converter ;
|
||||
|
||||
#define MAX_ARRAY_LENGTH 4096
|
||||
|
||||
namespace Trick {
|
||||
|
||||
/**
|
||||
This class provides reference information for variables requested from the variable server by the client.
|
||||
@author Alex Lin
|
||||
*/
|
||||
|
||||
class VariableReference {
|
||||
public:
|
||||
VariableReference(REF2 * in_ref) ;
|
||||
~VariableReference() ;
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& s, const Trick::VariableReference& vref);
|
||||
|
||||
/** Pointer to trick variable reference structure.\n */
|
||||
REF2 * ref ;
|
||||
cv_converter * conversion_factor ; // ** udunits conversion factor
|
||||
void * buffer_in ;
|
||||
void * buffer_out ;
|
||||
void * address ; // -- address of data copied to buffer
|
||||
int size ; // -- size of data copied to buffer
|
||||
TRICK_TYPE string_type ; // -- indicate if this is a string or wstring
|
||||
bool need_deref ; // -- inidicate this is a painter to be dereferenced
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
481
include/trick/VariableServerSession.hh
Normal file
481
include/trick/VariableServerSession.hh
Normal file
@ -0,0 +1,481 @@
|
||||
/*************************************************************************
|
||||
PURPOSE: (Represent the state of a variable server connection.)
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef WSSESSION_HH
|
||||
#define WSSESSION_HH
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "trick/VariableReference.hh"
|
||||
#include "trick/ClientConnection.hh"
|
||||
#include "trick/variable_server_sync_types.h"
|
||||
#include "trick/tc.h"
|
||||
#include "trick/variable_server_message_types.h"
|
||||
|
||||
|
||||
namespace Trick {
|
||||
class VariableServerSession {
|
||||
public:
|
||||
VariableServerSession(ClientConnection * connection);
|
||||
~VariableServerSession();
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& s, const Trick::VariableServerSession& session);
|
||||
|
||||
int handleMessage();
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to add a variable to a list of registered variables for value retrieval.
|
||||
The variable server will immediately begin returning the variable values to the client at a
|
||||
frequency according to var_cycle.
|
||||
@par Python Usage:
|
||||
@code trick.var_add("<in_name>") @endcode
|
||||
@param in_name - the variable name to retrieve
|
||||
@return always 0
|
||||
*/
|
||||
int var_add( std::string in_name ) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to add a variable to a list of registered variables for value retrieval,
|
||||
and also instructs the variable server to return the value in the specified measurement units.
|
||||
The unit specification will be returned after the variable's value (var_ascii mode only).
|
||||
Specifying units as "{xx}" will use the unit specification from the variable's model code declaration,
|
||||
which is essentially a method of querying a variable's unit specification.
|
||||
The variable server will immediately begin returning the variable values/units to the client at
|
||||
a frequency according to var_cycle.
|
||||
@par Python Usage:
|
||||
@code trick.var_add("<in_name>", "<units_name>") @endcode
|
||||
@param in_name - the variable name to retrieve
|
||||
@param units_name - the desired units, specified within curly braces
|
||||
@return always 0
|
||||
*/
|
||||
int var_add( std::string in_name, std::string units_name ) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to remove a variable (previously registered with var_add)
|
||||
from the list of registered variables for value retrieval.
|
||||
@par Python Usage:
|
||||
@code trick.var_remove("<in_name>") @endcode
|
||||
@param in_name - the variable name to remove
|
||||
@return always 0
|
||||
*/
|
||||
int var_remove( std::string in_name ) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to return the value of a variable
|
||||
in the specified units (var_ascii mode only).
|
||||
The variable must have been previously registered with the var_add command.
|
||||
The unit specification will be returned after the variable's value.
|
||||
@par Python Usage:
|
||||
@code trick.var_units("<var_name>", "<units_name>") @endcode
|
||||
@param var_name - the variable name previously registered with var_add
|
||||
@param units_name - the desired units, specified within curly braces
|
||||
@return always 0
|
||||
@note trick.var_add("my_object.my_variable"); trick.var_units("my_object.my_variable","{m}")
|
||||
is the same as trick.var_add("my_object.my_variable","{m}")
|
||||
*/
|
||||
int var_units(std::string var_name , std::string units_name) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to send a Boolean value indicating
|
||||
whether the specified variable exists
|
||||
(is a Trick processed variable in the current simulation).
|
||||
- var_binary mode: the message indicator is 1, and the returned value is a binary 0 or 1.
|
||||
- var_ascii mode: the message indicator is "1" followed by a tab, then an ASCII "0" or "1" returned value.
|
||||
.
|
||||
@par Python Usage:
|
||||
@code trick.var_exists("<in_name>") @endcode
|
||||
@param in_name - the variable name to query
|
||||
@return always 0
|
||||
*/
|
||||
int var_exists( std::string in_name ) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to immediately send the value of a comma separated list of variables
|
||||
@par Python Usage:
|
||||
@code trick.var_send_once("<in_name_list>", <number of variables in list>) @endcode
|
||||
@param in_name_list - the variables name to retrieve, comma separated
|
||||
@param num_vars - number of vars in in_name_list
|
||||
@return always 0
|
||||
*/
|
||||
int var_send_once(std::string in_name_list, int num_vars);
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to immediately send back the values of
|
||||
variables that are registered with the var_add command
|
||||
(typically used when var_pause is in effect). Each var_send command sends back all current values
|
||||
once instead of cyclically.
|
||||
@par Python Usage:
|
||||
@code trick.var_send() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_send() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to remove all variables from the list of variables currently
|
||||
registered with the var_add command,
|
||||
so the variable server will no longer send cyclic values until new var_add commands are issued.
|
||||
@par Python Usage:
|
||||
@code trick.var_clear() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_clear() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Turns on validating addresses before they are referenced
|
||||
@par Python Usage:
|
||||
@code trick.var_validate_address() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_validate_address(bool on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to output debug information.
|
||||
@par Python Usage:
|
||||
@code trick.var_debug(<level>) @endcode
|
||||
@return always 0
|
||||
@param level - 1,2,or 3, higher number increases amount of info output
|
||||
*/
|
||||
int var_debug(int level) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to return values in ASCII format (this is the default).
|
||||
@par Python Usage:
|
||||
@code trick.var_ascii() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_ascii() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to return values in binary format.
|
||||
@par Python Usage:
|
||||
@code trick.var_binary() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_binary() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to return values in binary format,
|
||||
but saves space in the returned messages
|
||||
by omitting the variable names.
|
||||
@par Python Usage:
|
||||
@code trick.var_binary_nonames() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_binary_nonames() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to tell the server when to copy data
|
||||
- VS_COPY_ASYNC = copies data asynchronously. (default)
|
||||
- VS_COPY_SCHEDULED = copies data as an automatic_last job in main thread
|
||||
- VS_COPY_TOP_OF_FRAME = copies data at top of frame
|
||||
@par Python Usage:
|
||||
@code trick.var_set_copy_mode(<mode>) @endcode
|
||||
@param mode - One of the above enumerations
|
||||
@return 0 if successful, -1 if error
|
||||
*/
|
||||
int var_set_copy_mode(int on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to tell the server when to copy data
|
||||
- VS_WRITE_ASYNC = writes data asynchronously. (default)
|
||||
- VS_WRITE_WHEN_COPIED = writes data as soon as it's copied from sim
|
||||
@par Python Usage:
|
||||
@code trick.var_set_write_mode(<mode>) @endcode
|
||||
@param mode - One of the above enumerations
|
||||
@return 0 if successful, -1 if error
|
||||
*/
|
||||
int var_set_write_mode(int on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to put the current variable server/client connection in sync mode,
|
||||
so that values to be sent to the client
|
||||
are guaranteed to be homogenous, that is from the same execution frame (the default is asynchronous).
|
||||
- async/async mode: the variable server thread itself copies the client data,
|
||||
independent of the execution frame so may not be homogenous.
|
||||
- sync/async mode: a variable server automatic_last job retrieves client requested data.
|
||||
Data is sent asynchronously on separate thread.
|
||||
- sync/sync mode: a variable server automatic_last job retrieves client requested data.
|
||||
Data is sent in same automatic_last job.
|
||||
.
|
||||
@par Python Usage:
|
||||
@code trick.var_sync(<on_off>) @endcode
|
||||
@param on_off - 0 = fully asynchronous. 1 = sync data gather, async socket write.
|
||||
2 = sync data gather, sync socket write
|
||||
@return always 0
|
||||
*/
|
||||
int var_sync(int on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Set the frame multiple
|
||||
@par Python Usage:
|
||||
@code trick.var_set_frame_multiple(<mult>) @endcode
|
||||
@param mult - The requested multiple
|
||||
@return 0
|
||||
*/
|
||||
int var_set_frame_multiple(unsigned int mult) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Set the frame offset
|
||||
@par Python Usage:
|
||||
@code trick.var_set_frame_offset(<offset>) @endcode
|
||||
@param offset - The requested offset
|
||||
@return 0
|
||||
*/
|
||||
int var_set_frame_offset(unsigned int offset) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Set the frame multiple
|
||||
@par Python Usage:
|
||||
@code trick.var_set_freeze_frame_multiple(<mult>) @endcode
|
||||
@param mult - The requested multiple
|
||||
@return 0
|
||||
*/
|
||||
int var_set_freeze_frame_multiple(unsigned int mult) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Set the frame offset
|
||||
@par Python Usage:
|
||||
@code trick.var_set_freeze_frame_offset(<offset>) @endcode
|
||||
@param offset - The requested offset
|
||||
@return 0
|
||||
*/
|
||||
int var_set_freeze_frame_offset(unsigned int offset) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to byteswap the return values
|
||||
(only has an effect in var_binary mode).
|
||||
The default is no byteswap - it is assumed server and client are same endianness.
|
||||
If not, the user must issue the var_byteswap command.
|
||||
@par Python Usage:
|
||||
@code trick.var_byteswap(<on_off>) @endcode
|
||||
@param on_off - true (or 1) to byteswap the return data, false (or 0) to return data as is
|
||||
@return always 0
|
||||
*/
|
||||
int var_byteswap(bool on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to turn on variable server logged messages to a playback file.
|
||||
All messages received from all clients will be saved to file named "playback" in the RUN directory.
|
||||
@par Python Usage:
|
||||
@code trick.set_log_on() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int set_log_on() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to turn off variable server logged messages to a playback file.
|
||||
@par Python Usage:
|
||||
@code trick.set_log_off() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int set_log_off() ;
|
||||
|
||||
/**
|
||||
@brief Command to send the number of items in the var_add list.
|
||||
The variable server sends a message indicator of "3", followed by the total number of variables being sent.
|
||||
*/
|
||||
int send_list_size();
|
||||
|
||||
/**
|
||||
@brief Special command to instruct the variable server to send the contents of the S_sie.resource file; used by TV.
|
||||
The variable server sends a message indicator of "2", followed by a tab, followed by the file contents
|
||||
which are then sent as sequential ASCII messages with a maximum size of 4096 bytes each.
|
||||
*/
|
||||
int send_sie_resource();
|
||||
|
||||
/**
|
||||
@brief Special command to only send the class sie class information
|
||||
*/
|
||||
int send_sie_class();
|
||||
|
||||
/**
|
||||
@brief Special command to only send the enumeration sie class information
|
||||
*/
|
||||
int send_sie_enum();
|
||||
|
||||
/**
|
||||
@brief Special command to only send the top level objects sie class information
|
||||
*/
|
||||
int send_sie_top_level_objects();
|
||||
|
||||
/**
|
||||
@brief Special command to send an arbitrary file through the variable server.
|
||||
*/
|
||||
int send_file(std::string file_name);
|
||||
|
||||
/**
|
||||
@brief gets the send_stdio flag.
|
||||
*/
|
||||
bool get_send_stdio() ;
|
||||
|
||||
/**
|
||||
@brief sets the send_stdio flag.
|
||||
*/
|
||||
int set_send_stdio(bool on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to set the frequencty at which the variable server will send values
|
||||
of variables that have been registered using
|
||||
the var_add command. If var_cycle is not specified, the default cycle is 0.1 seconds.
|
||||
@par Python Usage:
|
||||
@code trick.var_cycle(<in_cycle>) @endcode
|
||||
@param in_cycle - the desired frequency in seconds
|
||||
@return always 0
|
||||
*/
|
||||
int var_cycle(double in_cycle) ;
|
||||
|
||||
/**
|
||||
@brief Get the pause state of this thread.
|
||||
*/
|
||||
bool get_pause() ;
|
||||
|
||||
/**
|
||||
@brief Set the pause state of this thread.
|
||||
*/
|
||||
void set_pause(bool on_off) ;
|
||||
|
||||
/**
|
||||
@brief Write data in the appropriate format (var_ascii or var_binary) from variable output buffers to socket.
|
||||
*/
|
||||
int write_data();
|
||||
|
||||
/**
|
||||
@brief Write data from the given var only to the appropriate format (var_ascii or var_binary) from variable output buffers to socket.
|
||||
*/
|
||||
int write_data(std::vector<VariableReference *>& var, VS_MESSAGE_TYPE message_type) ;
|
||||
|
||||
/**
|
||||
@brief Copy client variable values from Trick memory to each variable's output buffer.
|
||||
*/
|
||||
int copy_sim_data();
|
||||
|
||||
/**
|
||||
@brief Copy given variable values from Trick memory to each variable's output buffer.
|
||||
cyclical indicated whether it is a normal cyclical copy or a send_once copy
|
||||
*/
|
||||
int copy_sim_data(std::vector<VariableReference *>& given_vars, bool cyclical);
|
||||
|
||||
int var_exit();
|
||||
|
||||
int transmit_file(std::string sie_file);
|
||||
|
||||
int copy_data_freeze();
|
||||
int copy_data_freeze_scheduled(long long curr_tics);
|
||||
int copy_data_scheduled(long long curr_tics);
|
||||
int copy_data_top();
|
||||
|
||||
// VS_COPY_MODE get_copy_mode();
|
||||
// VS_WRITE_MODE get_write_mode();
|
||||
|
||||
void disconnect_references();
|
||||
|
||||
long long get_next_tics() const;
|
||||
|
||||
long long get_freeze_next_tics() const;
|
||||
|
||||
int freeze_init();
|
||||
|
||||
double get_update_rate() const;
|
||||
|
||||
// These should be private probably
|
||||
int write_binary_data(const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type);
|
||||
int write_ascii_data(const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type );
|
||||
int write_stdio(int stream, std::string text);
|
||||
|
||||
VS_WRITE_MODE get_write_mode () const;
|
||||
VS_COPY_MODE get_copy_mode () const;
|
||||
|
||||
|
||||
pthread_mutex_t copy_mutex; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to indicate var_exit commanded.\n */
|
||||
bool exit_cmd ; /**< trick_io(**) */
|
||||
|
||||
private:
|
||||
// int sendErrorMessage(const char* fmt, ... );
|
||||
// int sendSieMessage(void);
|
||||
// int sendUnitsMessage(const char* vname);
|
||||
|
||||
ClientConnection * connection; /**< trick_io(**) */
|
||||
/** The trickcomm device used for the connection to the client.\n */
|
||||
|
||||
VariableReference * find_session_variable(std::string name) const;
|
||||
|
||||
double stageTime;
|
||||
bool dataStaged;
|
||||
|
||||
std::vector<VariableReference *> session_variables; /**< trick_io(**) */
|
||||
bool cyclicSendEnabled; /**< trick_io(**) */
|
||||
long long nextTime; /**< trick_io(**) */
|
||||
long long intervalTimeTics; /**< trick_io(**) */
|
||||
|
||||
/** Value set in var_cycle command.\n */
|
||||
double update_rate ; /**< trick_io(**) */
|
||||
|
||||
/** The update rate in integer tics.\n */
|
||||
long long cycle_tics ; /**< trick_io(**) */
|
||||
|
||||
/** The next call time in integer tics of the job to copy client data (sync mode).\n */
|
||||
long long next_tics ; /**< trick_io(**) */
|
||||
|
||||
/** The next call time in integer tics of the job to copy client data (sync mode).\n */
|
||||
long long freeze_next_tics ; /**< trick_io(**) */
|
||||
|
||||
/** The simulation time converted to seconds\n */
|
||||
double time ; /**< trick_units(s) */
|
||||
|
||||
/** Toggle to set variable server copy as top_of_frame, scheduled, async \n */
|
||||
VS_COPY_MODE copy_mode ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to set variable server writes as when copied or async.\n */
|
||||
VS_WRITE_MODE write_mode ; /**< trick_io(**) */
|
||||
|
||||
/** multiples of frame_count to copy data. Only used at top_of_frame\n */
|
||||
int frame_multiple ; /**< trick_io(**) */
|
||||
|
||||
/** multiples of frame_count to copy data. Only used at top_of_frame\n */
|
||||
int frame_offset ; /**< trick_io(**) */
|
||||
|
||||
/** multiples of frame_count to copy data. Only used at top_of_frame\n */
|
||||
int freeze_frame_multiple ; /**< trick_io(**) */
|
||||
|
||||
/** multiples of frame_count to copy data. Only used at top_of_frame\n */
|
||||
int freeze_frame_offset ; /**< trick_io(**) */
|
||||
|
||||
// The way the modes are handled is confusing. TODO: refactor >:(
|
||||
|
||||
/** Toggle to tell variable server to byteswap returned values.\n */
|
||||
bool byteswap ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to tell variable server return data in binary format.\n */
|
||||
bool binary_data ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to tell variable server return data in binary format without the variable names.\n */
|
||||
bool binary_data_nonames ; /**< trick_io(**) */
|
||||
|
||||
/** Value (1,2,or 3) that causes the variable server to output increasing amounts of debug information.\n */
|
||||
int debug ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to enable/disable this variable server thread.\n */
|
||||
bool enabled ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to turn on/off variable server logged messages to a playback file.\n */
|
||||
bool log ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to indicate var_pause commanded.\n */
|
||||
bool pause_cmd ; /**< trick_io(**) */
|
||||
|
||||
/** Save pause state while reloading a checkpoint.\n */
|
||||
bool saved_pause_cmd ; /**< trick_io(**) */
|
||||
|
||||
bool send_stdio;
|
||||
|
||||
bool validate_address;
|
||||
|
||||
int packets_copied;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -11,16 +11,21 @@
|
||||
#include <iostream>
|
||||
#include <pthread.h>
|
||||
#include "trick/tc.h"
|
||||
#include "trick/TCConnection.hh"
|
||||
#include "trick/SysThread.hh"
|
||||
#include "trick/VariableServerReference.hh"
|
||||
#include "trick/VariableServerSession.hh"
|
||||
#include "trick/variable_server_sync_types.h"
|
||||
#include "trick/variable_server_message_types.h"
|
||||
|
||||
#include "trick/ClientListener.hh"
|
||||
|
||||
namespace Trick {
|
||||
|
||||
class VariableServer ;
|
||||
|
||||
/** Flag to indicate the connection has been made\n */
|
||||
enum ConnectionStatus { CONNECTION_PENDING, CONNECTION_SUCCESS, CONNECTION_FAIL };
|
||||
|
||||
|
||||
/**
|
||||
This class provides variable server command processing on a separate thread for each client.
|
||||
@author Alex Lin
|
||||
@ -28,15 +33,13 @@ namespace Trick {
|
||||
class VariableServerThread : public Trick::SysThread {
|
||||
|
||||
public:
|
||||
enum ConnectionType { TCP, UDP, MCAST } ;
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& s, Trick::VariableServerThread& vst);
|
||||
|
||||
/**
|
||||
@brief Constructor.
|
||||
@param listen_dev - the TCDevice set up in listen()
|
||||
*/
|
||||
VariableServerThread(TCDevice * in_listen_dev ) ;
|
||||
VariableServerThread(ClientListener * in_listen_dev ) ;
|
||||
|
||||
virtual ~VariableServerThread() ;
|
||||
/**
|
||||
@ -45,10 +48,12 @@ namespace Trick {
|
||||
*/
|
||||
static void set_vs_ptr(Trick::VariableServer * in_vs) ;
|
||||
|
||||
void set_client_tag(std::string tag);
|
||||
|
||||
/**
|
||||
@brief Wait for the connection_accepted flag to be set.
|
||||
@brief Block until thread has accepted connection
|
||||
*/
|
||||
void wait_for_accept() ;
|
||||
ConnectionStatus wait_for_accept() ;
|
||||
|
||||
/**
|
||||
@brief The main loop of the variable server thread that reads and processes client commands.
|
||||
@ -56,391 +61,12 @@ namespace Trick {
|
||||
*/
|
||||
virtual void * thread_body() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to add a variable to a list of registered variables for value retrieval.
|
||||
The variable server will immediately begin returning the variable values to the client at a
|
||||
frequency according to var_cycle.
|
||||
@par Python Usage:
|
||||
@code trick.var_add("<in_name>") @endcode
|
||||
@param in_name - the variable name to retrieve
|
||||
@return always 0
|
||||
*/
|
||||
int var_add( std::string in_name ) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to add a variable to a list of registered variables for value retrieval,
|
||||
and also instructs the variable server to return the value in the specified measurement units.
|
||||
The unit specification will be returned after the variable's value (var_ascii mode only).
|
||||
Specifying units as "{xx}" will use the unit specification from the variable's model code declaration,
|
||||
which is essentially a method of querying a variable's unit specification.
|
||||
The variable server will immediately begin returning the variable values/units to the client at
|
||||
a frequency according to var_cycle.
|
||||
@par Python Usage:
|
||||
@code trick.var_add("<in_name>", "<units_name>") @endcode
|
||||
@param in_name - the variable name to retrieve
|
||||
@param units_name - the desired units, specified within curly braces
|
||||
@return always 0
|
||||
*/
|
||||
int var_add( std::string in_name, std::string units_name ) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to remove a variable (previously registered with var_add)
|
||||
from the list of registered variables for value retrieval.
|
||||
@par Python Usage:
|
||||
@code trick.var_remove("<in_name>") @endcode
|
||||
@param in_name - the variable name to remove
|
||||
@return always 0
|
||||
*/
|
||||
int var_remove( std::string in_name ) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to return the value of a variable
|
||||
in the specified units (var_ascii mode only).
|
||||
The variable must have been previously registered with the var_add command.
|
||||
The unit specification will be returned after the variable's value.
|
||||
@par Python Usage:
|
||||
@code trick.var_units("<var_name>", "<units_name>") @endcode
|
||||
@param var_name - the variable name previously registered with var_add
|
||||
@param units_name - the desired units, specified within curly braces
|
||||
@return always 0
|
||||
@note trick.var_add("my_object.my_variable"); trick.var_units("my_object.my_variable","{m}")
|
||||
is the same as trick.var_add("my_object.my_variable","{m}")
|
||||
*/
|
||||
int var_units(std::string var_name , std::string units_name) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to send a Boolean value indicating
|
||||
whether the specified variable exists
|
||||
(is a Trick processed variable in the current simulation).
|
||||
- var_binary mode: the message indicator is 1, and the returned value is a binary 0 or 1.
|
||||
- var_ascii mode: the message indicator is "1" followed by a tab, then an ASCII "0" or "1" returned value.
|
||||
.
|
||||
@par Python Usage:
|
||||
@code trick.var_exists("<in_name>") @endcode
|
||||
@param in_name - the variable name to query
|
||||
@return always 0
|
||||
*/
|
||||
int var_exists( std::string in_name ) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to immediately send the value of a comma separated list of variables
|
||||
@par Python Usage:
|
||||
@code trick.var_send_once("<in_name_list>", <number of variables in list>) @endcode
|
||||
@param in_name_list - the variables name to retrieve, comma separated
|
||||
@param num_vars - number of vars in in_name_list
|
||||
@return always 0
|
||||
*/
|
||||
int var_send_once(std::string in_name_list, int num_vars);
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to immediately send back the values of
|
||||
variables that are registered with the var_add command
|
||||
(typically used when var_pause is in effect). Each var_send command sends back all current values
|
||||
once instead of cyclically.
|
||||
@par Python Usage:
|
||||
@code trick.var_send() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_send() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to remove all variables from the list of variables currently
|
||||
registered with the var_add command,
|
||||
so the variable server will no longer send cyclic values until new var_add commands are issued.
|
||||
@par Python Usage:
|
||||
@code trick.var_clear() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_clear() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to set the frequencty at which the variable server will send values
|
||||
of variables that have been registered using
|
||||
the var_add command. If var_cycle is not specified, the default cycle is 0.1 seconds.
|
||||
@par Python Usage:
|
||||
@code trick.var_cycle(<in_cycle>) @endcode
|
||||
@param in_cycle - the desired frequency in seconds
|
||||
@return always 0
|
||||
*/
|
||||
int var_cycle(double in_cycle) ;
|
||||
|
||||
/**
|
||||
@brief Get the pause state of this thread.
|
||||
*/
|
||||
bool get_pause() ;
|
||||
|
||||
/**
|
||||
@brief Set the pause state of this thread.
|
||||
*/
|
||||
void set_pause(bool on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to terminate the current variable server/client connection.
|
||||
@par Python Usage:
|
||||
@code trick.var_exit() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_exit() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Turns on validating addresses before they are referenced
|
||||
@par Python Usage:
|
||||
@code trick.var_validate_address() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_validate_address(bool on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to output debug information.
|
||||
@par Python Usage:
|
||||
@code trick.var_debug(<level>) @endcode
|
||||
@return always 0
|
||||
@param level - 1,2,or 3, higher number increases amount of info output
|
||||
*/
|
||||
int var_debug(int level) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to return values in ASCII format (this is the default).
|
||||
@par Python Usage:
|
||||
@code trick.var_ascii() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_ascii() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to return values in binary format.
|
||||
@par Python Usage:
|
||||
@code trick.var_binary() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_binary() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to return values in binary format,
|
||||
but saves space in the returned messages
|
||||
by omitting the variable names.
|
||||
@par Python Usage:
|
||||
@code trick.var_binary_nonames() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int var_binary_nonames() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to tell the server when to copy data
|
||||
- VS_COPY_ASYNC = copies data asynchronously. (default)
|
||||
- VS_COPY_SCHEDULED = copies data as an automatic_last job in main thread
|
||||
- VS_COPY_TOP_OF_FRAME = copies data at top of frame
|
||||
@par Python Usage:
|
||||
@code trick.var_set_copy_mode(<mode>) @endcode
|
||||
@param mode - One of the above enumerations
|
||||
@return 0 if successful, -1 if error
|
||||
*/
|
||||
int var_set_copy_mode(int on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to tell the server when to copy data
|
||||
- VS_WRITE_ASYNC = writes data asynchronously. (default)
|
||||
- VS_WRITE_WHEN_COPIED = writes data as soon as it's copied from sim
|
||||
@par Python Usage:
|
||||
@code trick.var_set_write_mode(<mode>) @endcode
|
||||
@param mode - One of the above enumerations
|
||||
@return 0 if successful, -1 if error
|
||||
*/
|
||||
int var_set_write_mode(int on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to put the current variable server/client connection in sync mode,
|
||||
so that values to be sent to the client
|
||||
are guaranteed to be homogenous, that is from the same execution frame (the default is asynchronous).
|
||||
- async/async mode: the variable server thread itself copies the client data,
|
||||
independent of the execution frame so may not be homogenous.
|
||||
- sync/async mode: a variable server automatic_last job retrieves client requested data.
|
||||
Data is sent asynchronously on separate thread.
|
||||
- sync/sync mode: a variable server automatic_last job retrieves client requested data.
|
||||
Data is sent in same automatic_last job.
|
||||
.
|
||||
@par Python Usage:
|
||||
@code trick.var_sync(<on_off>) @endcode
|
||||
@param on_off - 0 = fully asynchronous. 1 = sync data gather, async socket write.
|
||||
2 = sync data gather, sync socket write
|
||||
@return always 0
|
||||
*/
|
||||
int var_sync(int on_off) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Set the frame multiple
|
||||
@par Python Usage:
|
||||
@code trick.var_set_frame_multiple(<mult>) @endcode
|
||||
@param mult - The requested multiple
|
||||
@return 0
|
||||
*/
|
||||
int var_set_frame_multiple(unsigned int mult) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Set the frame offset
|
||||
@par Python Usage:
|
||||
@code trick.var_set_frame_offset(<offset>) @endcode
|
||||
@param offset - The requested offset
|
||||
@return 0
|
||||
*/
|
||||
int var_set_frame_offset(unsigned int offset) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Set the frame multiple
|
||||
@par Python Usage:
|
||||
@code trick.var_set_freeze_frame_multiple(<mult>) @endcode
|
||||
@param mult - The requested multiple
|
||||
@return 0
|
||||
*/
|
||||
int var_set_freeze_frame_multiple(unsigned int mult) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Set the frame offset
|
||||
@par Python Usage:
|
||||
@code trick.var_set_freeze_frame_offset(<offset>) @endcode
|
||||
@param offset - The requested offset
|
||||
@return 0
|
||||
*/
|
||||
int var_set_freeze_frame_offset(unsigned int offset) ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to instruct the variable server to byteswap the return values
|
||||
(only has an effect in var_binary mode).
|
||||
The default is no byteswap - it is assumed server and client are same endianness.
|
||||
If not, the user must issue the var_byteswap command.
|
||||
@par Python Usage:
|
||||
@code trick.var_byteswap(<on_off>) @endcode
|
||||
@param on_off - true (or 1) to byteswap the return data, false (or 0) to return data as is
|
||||
@return always 0
|
||||
*/
|
||||
int var_byteswap(bool on_off) ;
|
||||
|
||||
/**
|
||||
@brief CURRENTLY NOT IMPLEMENTED
|
||||
*/
|
||||
int var_signal() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to turn on variable server logged messages to a playback file.
|
||||
All messages received from all clients will be saved to file named "playback" in the RUN directory.
|
||||
@par Python Usage:
|
||||
@code trick.set_log_on() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int set_log_on() ;
|
||||
|
||||
/**
|
||||
@brief @userdesc Command to turn off variable server logged messages to a playback file.
|
||||
@par Python Usage:
|
||||
@code trick.set_log_off() @endcode
|
||||
@return always 0
|
||||
*/
|
||||
int set_log_off() ;
|
||||
|
||||
/**
|
||||
@brief CURRENTLY NOT IMPLEMENTED\n
|
||||
Command to instruct the variable server to send values via multicast socket.
|
||||
*/
|
||||
int var_multicast(bool on_off) ;
|
||||
|
||||
/**
|
||||
@brief Command to send the number of items in the var_add list.
|
||||
The variable server sends a message indicator of "3", followed by the total number of variables being sent.
|
||||
*/
|
||||
int send_list_size();
|
||||
|
||||
/**
|
||||
@brief Special command to instruct the variable server to send the contents of the S_sie.resource file; used by TV.
|
||||
The variable server sends a message indicator of "2", followed by a tab, followed by the file contents
|
||||
which are then sent as sequential ASCII messages with a maximum size of 4096 bytes each.
|
||||
*/
|
||||
int send_sie_resource();
|
||||
|
||||
/**
|
||||
@brief Special command to only send the class sie class information
|
||||
*/
|
||||
int send_sie_class();
|
||||
|
||||
/**
|
||||
@brief Special command to only send the enumeration sie class information
|
||||
*/
|
||||
int send_sie_enum();
|
||||
|
||||
/**
|
||||
@brief Special command to only send the top level objects sie class information
|
||||
*/
|
||||
int send_sie_top_level_objects();
|
||||
|
||||
/**
|
||||
@brief Special command to send an arbitrary file through the variable server.
|
||||
*/
|
||||
int send_file(std::string file_name);
|
||||
|
||||
/**
|
||||
@brief Copy client variable values from Trick memory to each variable's output buffer.
|
||||
*/
|
||||
int copy_sim_data();
|
||||
|
||||
/**
|
||||
@brief Copy given variable values from Trick memory to each variable's output buffer.
|
||||
cyclical indicated whether it is a normal cyclical copy or a send_once copy
|
||||
*/
|
||||
int copy_sim_data(std::vector<VariableReference *> given_vars, bool cyclical);
|
||||
|
||||
/**
|
||||
@brief Write data in the appropriate format (var_ascii or var_binary) from variable output buffers to socket.
|
||||
*/
|
||||
int write_data();
|
||||
|
||||
/**
|
||||
@brief Write data from the given var only to the appropriate format (var_ascii or var_binary) from variable output buffers to socket.
|
||||
*/
|
||||
int write_data(std::vector<VariableReference *> var) ;
|
||||
|
||||
/**
|
||||
@brief gets the send_stdio flag.
|
||||
*/
|
||||
bool get_send_stdio() ;
|
||||
|
||||
/**
|
||||
@brief sets the send_stdio flag.
|
||||
*/
|
||||
int set_send_stdio(bool on_off) ;
|
||||
|
||||
VariableServer * get_vs() ;
|
||||
TCDevice & get_connection() ;
|
||||
|
||||
/**
|
||||
@brief Internal function used by input processor to send stdout and stderr to the client.
|
||||
@return always 0
|
||||
*/
|
||||
int write_stdio(int stream , std::string text ) ;
|
||||
|
||||
int freeze_init() ;
|
||||
|
||||
int copy_data_freeze() ;
|
||||
int copy_data_freeze_scheduled(long long curr_tics) ;
|
||||
int copy_data_scheduled(long long curr_tics) ;
|
||||
int copy_data_top() ;
|
||||
|
||||
void preload_checkpoint() ;
|
||||
|
||||
void restart() ;
|
||||
|
||||
long long get_next_tics() ;
|
||||
long long get_freeze_next_tics() ;
|
||||
|
||||
/**
|
||||
@brief creates a udp socket with the specified address and port. UDP ports do not go through
|
||||
the listen and accept states
|
||||
*/
|
||||
int create_udp_socket(const char * address, unsigned short in_port) ;
|
||||
|
||||
/**
|
||||
@brief creates a multicast socket with the specified address and port. mcast ports do not go through
|
||||
the listen and accept states
|
||||
*/
|
||||
int create_mcast_socket(const char * mcast_address, const char * address, unsigned short in_port) ;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -448,42 +74,15 @@ namespace Trick {
|
||||
*/
|
||||
int transmit_file(std::string file_name);
|
||||
|
||||
/**
|
||||
@brief Called by write_data to write given variables to socket in var_binary format.
|
||||
*/
|
||||
int write_binary_data( int Start, char *buf1, const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type);
|
||||
|
||||
/**
|
||||
@brief Called by write_data to write given variables to socket in var_ascii format.
|
||||
*/
|
||||
int write_ascii_data(char * dest_buf, size_t dest_buf_size, const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type );
|
||||
|
||||
/**
|
||||
@brief Construct a variable reference from the string in_name and handle error checking
|
||||
*/
|
||||
VariableReference* create_var_reference(std::string in_name);
|
||||
|
||||
/**
|
||||
@brief Make a time reference.
|
||||
*/
|
||||
REF2* make_time_ref();
|
||||
|
||||
/**
|
||||
@brief Make a "bad-reference" reference.
|
||||
*/
|
||||
REF2* make_error_ref(std::string in_name);
|
||||
|
||||
/** The Master variable server object. */
|
||||
static VariableServer * vs ;
|
||||
|
||||
/** this is where a lot of this should happen now */
|
||||
VariableServerSession * session;
|
||||
|
||||
/** The listen device from the variable server\n */
|
||||
TCDevice * listen_dev; /**< trick_io(**) */
|
||||
|
||||
/** The trickcomm device used for the connection to the client.\n */
|
||||
TCDevice connection ; /**< trick_io(**) */
|
||||
|
||||
/** The type of connection we have.\n */
|
||||
ConnectionType conn_type ; /**< trick_io(**) */
|
||||
ClientListener * listener; /**< trick_io(**) */
|
||||
TCConnection connection; /**< trick_io(**) */
|
||||
|
||||
/** Value (1,2,or 3) that causes the variable server to output increasing amounts of debug information.\n */
|
||||
int debug ; /**< trick_io(**) */
|
||||
@ -491,102 +90,25 @@ namespace Trick {
|
||||
/** Toggle to enable/disable this variable server thread.\n */
|
||||
bool enabled ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to turn on/off variable server logged messages to a playback file.\n */
|
||||
bool log ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to indicate var_pause commanded.\n */
|
||||
bool pause_cmd ; /**< trick_io(**) */
|
||||
|
||||
/** Save pause state while reloading a checkpoint.\n */
|
||||
bool saved_pause_cmd ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to indicate var_exit commanded.\n */
|
||||
bool exit_cmd ; /**< trick_io(**) */
|
||||
|
||||
/** Set to true to validate all addresses before copying.\n */
|
||||
bool validate_address ; /**< trick_io(**) */
|
||||
|
||||
/** The mutex to protect variable output buffers when copying variable values to them from Trick memory.\n */
|
||||
pthread_mutex_t copy_mutex ; /**< trick_io(**) */
|
||||
ConnectionStatus connection_status ; /**< trick_io(**) */
|
||||
pthread_mutex_t connection_status_mutex;
|
||||
pthread_cond_t connection_status_cv;
|
||||
|
||||
/** The mutex pauses all processing during checkpoint restart */
|
||||
pthread_mutex_t restart_pause ; /**< trick_io(**) */
|
||||
|
||||
/** Dummy integer for bad references.\n */
|
||||
static int bad_ref_int ; /**< trick_io(**) */
|
||||
|
||||
/** Dummy integer for bad references. If a variable points here, do not try to re-resolve address\n */
|
||||
static int do_not_resolve_bad_ref_int ; /**< trick_io(**) */
|
||||
// bool pause_cmd;
|
||||
bool saved_pause_cmd;
|
||||
|
||||
/** The simulation time converted to seconds\n */
|
||||
double time ; /**< trick_units(s) */
|
||||
|
||||
/** List of client requested variables.\n */
|
||||
std::vector <VariableReference *> vars; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to set variable server copy as top_of_frame, scheduled, async \n */
|
||||
VS_COPY_MODE copy_mode ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to set variable server writes as when copied or async.\n */
|
||||
VS_WRITE_MODE write_mode ; /**< trick_io(**) */
|
||||
|
||||
/** multiples of frame_count to copy data. Only used at top_of_frame\n */
|
||||
int frame_multiple ; /**< trick_io(**) */
|
||||
|
||||
/** multiples of frame_count to copy data. Only used at top_of_frame\n */
|
||||
int frame_offset ; /**< trick_io(**) */
|
||||
|
||||
/** multiples of frame_count to copy data. Only used at top_of_frame\n */
|
||||
int freeze_frame_multiple ; /**< trick_io(**) */
|
||||
|
||||
/** multiples of frame_count to copy data. Only used at top_of_frame\n */
|
||||
int freeze_frame_offset ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to tell variable server to byteswap returned values.\n */
|
||||
bool byteswap ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to tell variable server return data in binary format.\n */
|
||||
bool binary_data ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to tell variable server return data in binary format without the variable names.\n */
|
||||
bool binary_data_nonames ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to tell variable server to send data multicast or point to point.\n */
|
||||
bool multicast ; /**< trick_io(**) */
|
||||
|
||||
/** Flag to indicate the connection has been made\n */
|
||||
bool connection_accepted ; /**< trick_io(**) */
|
||||
|
||||
/** Value set in var_cycle command.\n */
|
||||
double update_rate ; /**< trick_io(**) */
|
||||
|
||||
/** The update rate in integer tics.\n */
|
||||
long long cycle_tics ; /**< trick_io(**) */
|
||||
|
||||
/** The next call time in integer tics of the job to copy client data (sync mode).\n */
|
||||
long long next_tics ; /**< trick_io(**) */
|
||||
|
||||
/** The next call time in integer tics of the job to copy client data (sync mode).\n */
|
||||
long long freeze_next_tics ; /**< trick_io(**) */
|
||||
|
||||
/** Indicate whether variable data has been written into buffer_in.\n */
|
||||
bool var_data_staged; /**< trick_io(**) */
|
||||
|
||||
/** number of packets copied to client \n */
|
||||
unsigned int packets_copied ; /**< trick_io(**) */
|
||||
|
||||
/** Toggle to indicate sending python stdout and stderr to client\n */
|
||||
bool send_stdio ; /**< trick_io(**) */
|
||||
|
||||
/** Holding area for the incoming message\n */
|
||||
char *incoming_msg; /**< trick_io(**) */
|
||||
|
||||
/** Message with '\r' characters removed\n */
|
||||
char *stripped_msg; /**< trick_io(**) */
|
||||
|
||||
/** Maximum size of incoming message\n */
|
||||
static const unsigned int MAX_CMD_LEN = 200000 ;
|
||||
} ;
|
||||
|
||||
std::ostream& operator<< (std::ostream& s, VariableServerThread& vst);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
PURPOSE:
|
||||
(Allows clients to get and set Trick parameters)
|
||||
PROGRAMMERS:
|
||||
(((Keith Vetter) (LinCom) (September 2001) (--)))
|
||||
*/
|
||||
|
||||
#ifndef VARIABLE_SERVER_H
|
||||
#define VARIABLE_SERVER_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "trick/reference.h"
|
||||
#include "trick/tc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
REF2 ref;
|
||||
double scale_factor;
|
||||
double bias;
|
||||
} VARIABLE_NODE;
|
||||
|
||||
typedef struct {
|
||||
int socket ; /* ** multicast socket file descriptor */
|
||||
struct sockaddr_in addr ; /* ** multicast socket info */
|
||||
} MCAST_INFO;
|
||||
|
||||
typedef struct VARIABLE_SERVER_struct {
|
||||
int enabled ;
|
||||
int debug; /* ** Variable_server debugging */
|
||||
int synchronous ;
|
||||
double update_rate;
|
||||
double next;
|
||||
int binary_data;
|
||||
int no_handshake;
|
||||
int num_vars;
|
||||
int clear_cmd;
|
||||
int send_cmd;
|
||||
int pause_cmd;
|
||||
int exists_cmd;
|
||||
int exit_cmd;
|
||||
VARIABLE_NODE *vars;
|
||||
|
||||
int multicast_on ; /* -- flag to switch between TCdevice and multcast socket */
|
||||
TCDevice * connection ;
|
||||
MCAST_INFO mcast_info ;
|
||||
char local_byteorder ;
|
||||
|
||||
pthread_t thread_id ;
|
||||
} VARIABLE_SERVER;
|
||||
|
||||
//void *var_server(void *); /* Server thread */
|
||||
//void *var_serve_init(void *); /* Initialize server */
|
||||
//void exit_var_server(void *); /* Exit handler for var init server */
|
||||
//void exit_var_serv_threads( void ); /* Exit handler for var init server */
|
||||
|
||||
int vs_mcast_init(MCAST_INFO * M, char * address , int port ) ;
|
||||
//int vs_write_data(VARIABLE_SERVER * V) ;
|
||||
//int vs_write_error(VARIABLE_SERVER * V, char * incoming_str , char * error_str ) ;
|
||||
//int vs_format_ascii(REF2 * ref, double scale_factor, double bias, char *value) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -66,7 +66,7 @@ export TRICK_PYTHON_PATH := $(TRICK_PYTHON_PATH)
|
||||
export TRICK_GTE_EXT := $(TRICK_GTE_EXT)
|
||||
export TRICK_HOST_CPU := $(shell TRICK_FORCE_32BIT=$(TRICK_FORCE_32BIT) $(TRICK_HOME)/bin/trick-gte TRICK_HOST_CPU)
|
||||
export TRICK_EXEC_LINK_LIBS := ${PTHREAD_LIBS} $(PYTHON_LIB) $(UDUNITS_LDFLAGS) $(PLATFORM_LIBS) -lm -ldl
|
||||
export TRICK_LIBS := ${RPATH} -L${TRICK_LIB_DIR} -ltrick -ltrick_pyip -ltrick_comm -ltrick_math -ltrick_units -ltrick_mm
|
||||
export TRICK_LIBS := ${RPATH} -L${TRICK_LIB_DIR} -ltrick -ltrick_pyip -ltrick_comm -ltrick_math -ltrick_units -ltrick_mm -ltrick_connection_handlers
|
||||
export TRICK_SYSTEM_LDFLAGS := $(TRICK_SYSTEM_LDFLAGS)
|
||||
export TRICK_SYSTEM_ICG_EXCLUDE := $(TRICK_SYSTEM_ICG_EXCLUDE)
|
||||
export TRICK_SWIG_FLAGS := $(TRICK_SWIG_FLAGS)
|
||||
|
@ -5,7 +5,7 @@ from trick.unit_test import *
|
||||
|
||||
def main():
|
||||
|
||||
trick.var_server_set_port(40000)
|
||||
trick.var_server_set_port(4000)
|
||||
trick.var_ascii()
|
||||
trick.real_time_enable()
|
||||
trick.exec_set_software_frame(0.01)
|
||||
|
@ -150,7 +150,6 @@ class Socket {
|
||||
|
||||
std::string receive () {
|
||||
char buffer[SOCKET_BUF_SIZE];
|
||||
|
||||
int numBytes = recv(_socket_fd, buffer, SOCKET_BUF_SIZE, 0);
|
||||
if (numBytes < 0) {
|
||||
} else if (numBytes < SOCKET_BUF_SIZE) {
|
||||
@ -164,6 +163,25 @@ class Socket {
|
||||
ret = receive();
|
||||
}
|
||||
|
||||
std::vector<unsigned char> receive_bytes() {
|
||||
unsigned char buffer[SOCKET_BUF_SIZE];
|
||||
int numBytes = recv(_socket_fd, buffer, SOCKET_BUF_SIZE, 0);
|
||||
if (numBytes < 0) {
|
||||
std::cout << "Failed to read from socket" << std::endl;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> bytes;
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
bytes.push_back(buffer[i]);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void operator>> (std::string& ret) {
|
||||
ret = receive();
|
||||
}
|
||||
|
||||
std::vector<unsigned char> receive_bytes() {
|
||||
unsigned char buffer[SOCKET_BUF_SIZE];
|
||||
int numBytes = recv(_socket_fd, buffer, SOCKET_BUF_SIZE, 0);
|
||||
@ -412,12 +430,23 @@ TEST_F (VariableServerTestMulticast, Strings) {
|
||||
|
||||
EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0);
|
||||
|
||||
|
||||
expected = std::string("5\tI am already far north of London, and as I walk in the streets of Petersburgh, I feel a cold northern breeze play upon my cheeks, which braces my nerves and fills me with delight. Do you understand this feeling?");
|
||||
socket << "trick.var_send_once(\"vsx.vst.p\")\n";
|
||||
|
||||
multicast_listener >> reply;
|
||||
|
||||
EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0);
|
||||
|
||||
// TODO: Does wchar actually work?
|
||||
// expected = std::string("5\tThis breeze, which has travelled from the regions towards which I am advancing, gives me a foretaste of those icy climes. Inspirited by this wind of promise, my daydreams become more fervent and vivid.");
|
||||
// socket << "trick.var_send_once(\"vsx.vst.q\")\n";
|
||||
|
||||
// socket >> reply;
|
||||
|
||||
// std::cout << "\tExpected: " << expected << "\n\tActual: " << reply << std::endl;
|
||||
|
||||
// EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0);
|
||||
}
|
||||
|
||||
|
||||
@ -572,6 +601,7 @@ TEST_F (VariableServerTestAltListener, Strings) {
|
||||
socket >> reply;
|
||||
|
||||
EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0);
|
||||
|
||||
}
|
||||
|
||||
TEST_F (VariableServerTestAltListener, AddRemove) {
|
||||
@ -649,6 +679,10 @@ TEST_F (VariableServerTestAltListener, RestartAndSet) {
|
||||
/* Normal case tests */
|
||||
/*********************************************/
|
||||
|
||||
void spin (Socket& socket, int wait_cycles = 5) {
|
||||
socket.receive();
|
||||
}
|
||||
|
||||
TEST_F (VariableServerTest, Strings) {
|
||||
if (socket_status != 0) {
|
||||
FAIL();
|
||||
@ -715,7 +749,42 @@ TEST_F (VariableServerTest, NoExtraTab) {
|
||||
EXPECT_STREQ(reply.c_str(), expected.c_str());
|
||||
}
|
||||
|
||||
TEST_F (VariableServerTest, AddRemove) {
|
||||
TEST_F (VariableServerTest, NoExtraTab) {
|
||||
if (socket_status != 0) {
|
||||
FAIL();
|
||||
}
|
||||
|
||||
std::string reply;
|
||||
std::string expected;
|
||||
|
||||
socket << "trick.var_add(\"vsx.vst.c\")\n";
|
||||
socket >> reply;
|
||||
expected = std::string("0\t-1234\n");
|
||||
|
||||
EXPECT_STREQ(reply.c_str(), expected.c_str());
|
||||
|
||||
socket >> reply;
|
||||
|
||||
EXPECT_STREQ(reply.c_str(), expected.c_str());
|
||||
|
||||
socket << "trick.var_add(\"vsx.vst.m\")\n";
|
||||
socket >> reply;
|
||||
expected = std::string("0\t-1234\t1\n");
|
||||
|
||||
EXPECT_STREQ(reply.c_str(), expected.c_str());
|
||||
|
||||
socket << "trick.var_remove(\"vsx.vst.m\")\n";
|
||||
socket >> reply;
|
||||
expected = std::string("0\t-1234\n");
|
||||
|
||||
socket << "trick.var_add(\"vsx.vst.n\")\n";
|
||||
socket >> reply;
|
||||
expected = std::string("0\t-1234\t0,1,2,3,4\n");
|
||||
|
||||
EXPECT_STREQ(reply.c_str(), expected.c_str());
|
||||
}
|
||||
|
||||
TEST_F (VariableServerTest, DISABLED_AddRemove) {
|
||||
if (socket_status != 0) {
|
||||
FAIL();
|
||||
}
|
||||
@ -743,6 +812,10 @@ TEST_F (VariableServerTest, AddRemove) {
|
||||
socket >> reply;
|
||||
expected = std::string("0 -1234");
|
||||
|
||||
socket << "trick.var_add(\"vsx.vst.n\")\n";
|
||||
socket >> reply;
|
||||
expected = std::string("0 -1234 0,1,2,3,4");
|
||||
|
||||
EXPECT_EQ(strcmp_IgnoringWhiteSpace(reply, expected), 0);
|
||||
|
||||
socket << "trick.var_add(\"vsx.vst.n\")\n";
|
||||
@ -1190,7 +1263,18 @@ TEST_F (VariableServerTest, Freeze) {
|
||||
ASSERT_EQ(mode, MODE_RUN);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> 6fe76071 (Add multicast test)
|
||||
TEST_F (VariableServerTest, DISABLED_CopyAndWriteModes) {
|
||||
=======
|
||||
=======
|
||||
>>>>>>> d158199e (Added var_send_list_size test, various other fixes)
|
||||
TEST_F (VariableServerTest, CopyAndWriteModes) {
|
||||
>>>>>>> f9665aba (Fix and test var_send_stdio)
|
||||
if (socket_status != 0) {
|
||||
FAIL();
|
||||
}
|
||||
@ -1388,6 +1472,38 @@ TEST_F (VariableServerTest, send_stdio) {
|
||||
|
||||
std::stringstream message_stream(message);
|
||||
std::string token;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
std::getline(message_stream, token, ' ');
|
||||
int message_type = stoi(token);
|
||||
std::getline(message_stream, token, ' ');
|
||||
int stream_num = stoi(token);
|
||||
std::getline(message_stream, token, '\n');
|
||||
int text_size = stoi(token);
|
||||
std::string text;
|
||||
std::getline(message_stream, text);
|
||||
|
||||
EXPECT_EQ (message_type, 4);
|
||||
EXPECT_EQ (stream_num, 1);
|
||||
EXPECT_EQ (text_size, 41);
|
||||
|
||||
EXPECT_EQ(text, std::string("This message should redirect to varserver"));
|
||||
}
|
||||
|
||||
TEST_F (VariableServerTest, RestartAndSet) {
|
||||
if (socket_status != 0) {
|
||||
FAIL();
|
||||
}
|
||||
|
||||
std::string reply;
|
||||
std::string expected;
|
||||
|
||||
socket << "trick.var_add(\"vsx.vst.c\")\n";
|
||||
socket >> reply;
|
||||
expected = std::string("0\t-1234\n");
|
||||
|
||||
EXPECT_EQ(reply, expected);
|
||||
>>>>>>> f9665aba (Fix and test var_send_stdio)
|
||||
|
||||
int message_type;
|
||||
int stream_num;
|
||||
@ -1414,6 +1530,12 @@ TEST_F (VariableServerTest, send_stdio) {
|
||||
|
||||
#ifndef __APPLE__
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
TEST_F (VariableServerTest, MulticastAfterRestart) {
|
||||
=======
|
||||
=======
|
||||
|
||||
TEST_F (VariableServerTest, MulticastAfterRestart) {
|
||||
if (socket_status != 0) {
|
||||
FAIL();
|
||||
@ -1422,9 +1544,7 @@ TEST_F (VariableServerTest, MulticastAfterRestart) {
|
||||
socket << "trick.var_server_set_user_tag(\"VSTestServer\")\n";
|
||||
|
||||
Socket multicast_socket;
|
||||
if (multicast_socket.init_multicast("224.3.14.15", 9265) != 0) {
|
||||
FAIL() << "Multicast Socket failed to initialize.";
|
||||
}
|
||||
multicast_socket.init_multicast("224.3.14.15", 9265);
|
||||
|
||||
int max_multicast_tries = 100;
|
||||
int tries = 0;
|
||||
@ -1432,7 +1552,7 @@ TEST_F (VariableServerTest, MulticastAfterRestart) {
|
||||
|
||||
char expected_hostname[80];
|
||||
gethostname(expected_hostname, 80);
|
||||
int expected_port = 40000;
|
||||
int expected_port = 4000;
|
||||
|
||||
// get expected username
|
||||
struct passwd *passp = getpwuid(getuid()) ;
|
||||
@ -1488,8 +1608,154 @@ TEST_F (VariableServerTest, MulticastAfterRestart) {
|
||||
FAIL() << "Multicast message never received";
|
||||
}
|
||||
|
||||
>>>>>>> 6490e49d (Add more tests, error handling)
|
||||
TEST_F (VariableServerTest, LargeMessages) {
|
||||
>>>>>>> f9665aba (Fix and test var_send_stdio)
|
||||
if (socket_status != 0) {
|
||||
FAIL();
|
||||
}
|
||||
|
||||
socket << "trick.var_server_set_user_tag(\"VSTestServer\")\n";
|
||||
|
||||
<<<<<<< HEAD
|
||||
Socket multicast_socket;
|
||||
if (multicast_socket.init_multicast("224.3.14.15", 9265) != 0) {
|
||||
FAIL() << "Multicast Socket failed to initialize.";
|
||||
}
|
||||
|
||||
int max_multicast_tries = 100;
|
||||
int tries = 0;
|
||||
bool found = false;
|
||||
|
||||
char expected_hostname[80];
|
||||
gethostname(expected_hostname, 80);
|
||||
int expected_port = 40000;
|
||||
|
||||
// get expected username
|
||||
struct passwd *passp = getpwuid(getuid()) ;
|
||||
char * expected_username;
|
||||
if ( passp == NULL ) {
|
||||
expected_username = strdup("unknown") ;
|
||||
} else {
|
||||
expected_username = strdup(passp->pw_name) ;
|
||||
}
|
||||
|
||||
// Don't care about PID, just check that it's > 0
|
||||
char * expected_sim_dir = "trick/test/SIM_test_varserv"; // Compare against the end of the string for this one
|
||||
// Don't care about cmdline name
|
||||
char * expected_input_file = "RUN_test/unit_test.py";
|
||||
// Don't care about trick_version
|
||||
char * expected_tag = "VSTestServer";
|
||||
|
||||
// Variables to be populated by the multicast message
|
||||
char actual_hostname[80];
|
||||
unsigned short actual_port = 0;
|
||||
char actual_username[80];
|
||||
int actual_pid = 0;
|
||||
char actual_sim_dir[80];
|
||||
char actual_cmdline_name[80];
|
||||
char actual_input_file[80];
|
||||
char actual_trick_version[80];
|
||||
char actual_tag[80];
|
||||
unsigned short actual_duplicate_port = 0;
|
||||
=======
|
||||
socket << "trick.var_pause()\n";
|
||||
|
||||
for (int i = 0; i < 4000; i++) {
|
||||
std::string var_add = "trick.var_add(\"vsx.vst.large_arr[" + std::to_string(i) + "]\")\n";
|
||||
socket << var_add;
|
||||
}
|
||||
|
||||
// Message size limit is 8192
|
||||
// Message size should be somewhere between the limit and limit-5 due to size of variable
|
||||
const static int msg_size_limit = 8192;
|
||||
|
||||
auto get_last_number_in_string = [](const std::string& s) -> int {
|
||||
int index = s.size() - 1;
|
||||
while (!isdigit(s.at(index))) { index--; }
|
||||
int num = 0;
|
||||
int exp = 0;
|
||||
while (isdigit(s.at(index))) {
|
||||
num += (s.at(index) - '0') * pow(10, exp);
|
||||
index--;
|
||||
exp++;
|
||||
}
|
||||
return num;
|
||||
};
|
||||
|
||||
auto get_first_number_in_string = [](const std::string& s) -> int {
|
||||
std::stringstream message_stream(s);
|
||||
std::string token;
|
||||
std::getline(message_stream, token, '\t');
|
||||
if (token.size() == 0) { std::getline(message_stream, token, '\t'); }
|
||||
int ret = stoi(token);
|
||||
return ret;
|
||||
};
|
||||
|
||||
socket.clear_buffered_data();
|
||||
|
||||
bool ready = false;
|
||||
while (!ready) {
|
||||
socket << "trick.var_send_list_size()\n";
|
||||
socket >> reply;
|
||||
if (reply == std::string("3\t4000\n"))
|
||||
ready = true;
|
||||
}
|
||||
|
||||
int new_reply_first = 0;
|
||||
int prev_reply_last = 0;
|
||||
|
||||
socket << "trick.var_send()\n";
|
||||
|
||||
socket >> reply;
|
||||
new_reply_first = get_first_number_in_string(reply);
|
||||
prev_reply_last = get_last_number_in_string(reply);
|
||||
EXPECT_EQ(new_reply_first, 0);
|
||||
EXPECT_TRUE(reply.size() <= msg_size_limit && reply.size() >= msg_size_limit-5);
|
||||
|
||||
while (prev_reply_last != 3999) {
|
||||
socket >> reply;
|
||||
new_reply_first = get_first_number_in_string(reply);
|
||||
|
||||
EXPECT_TRUE(reply.size() <= msg_size_limit);
|
||||
EXPECT_EQ(prev_reply_last + 1, new_reply_first);
|
||||
>>>>>>> d158199e (Added var_send_list_size test, various other fixes)
|
||||
|
||||
<<<<<<< HEAD
|
||||
while (!found && tries++ < max_multicast_tries) {
|
||||
std::string broadcast_data = multicast_socket.receive();
|
||||
sscanf(broadcast_data.c_str(), "%s\t%hu\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%hu\n" , actual_hostname, &actual_port ,
|
||||
actual_username , &actual_pid , actual_sim_dir , actual_cmdline_name ,
|
||||
actual_input_file , actual_trick_version , actual_tag, &actual_duplicate_port) ;
|
||||
|
||||
if (strcmp(actual_hostname, expected_hostname) == 0 && strcmp(expected_tag, actual_tag) == 0) {
|
||||
found = true;
|
||||
EXPECT_STREQ(actual_hostname, expected_hostname);
|
||||
EXPECT_EQ(actual_port, expected_port);
|
||||
EXPECT_STREQ(actual_username, expected_username);
|
||||
EXPECT_GT(actual_pid, 0);
|
||||
std::string expected_sim_dir_str(expected_sim_dir);
|
||||
std::string actual_sim_dir_str(actual_sim_dir);
|
||||
std::string end_of_actual = actual_sim_dir_str.substr(actual_sim_dir_str.length() - expected_sim_dir_str.length(), actual_sim_dir_str.length());
|
||||
EXPECT_EQ(expected_sim_dir_str, end_of_actual);
|
||||
EXPECT_STREQ(actual_input_file, expected_input_file);
|
||||
EXPECT_STREQ(actual_tag, expected_tag);
|
||||
EXPECT_EQ(actual_duplicate_port, expected_port);
|
||||
}
|
||||
=======
|
||||
prev_reply_last = get_last_number_in_string(reply);
|
||||
>>>>>>> 6490e49d (Add more tests, error handling)
|
||||
}
|
||||
|
||||
if (!found)
|
||||
FAIL() << "Multicast message never received";
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
#endif
|
||||
|
||||
=======
|
||||
>>>>>>> f9665aba (Fix and test var_send_stdio)
|
||||
TEST_F (VariableServerTest, Binary) {
|
||||
if (socket_status != 0) {
|
||||
FAIL();
|
||||
@ -1652,7 +1918,7 @@ int main(int argc, char **argv) {
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
Socket socket;
|
||||
socket.init("localhost", 40000);
|
||||
socket.init("localhost", 4000);
|
||||
|
||||
if (result == 0) {
|
||||
// Success
|
||||
|
@ -6,5 +6,10 @@ trick.itimer_enable()
|
||||
trick.exec_set_enable_freeze(True)
|
||||
# trick.exec_set_freeze_command(True)
|
||||
|
||||
# Print stack trace if signal is caught. default True
|
||||
trick.exec_set_stack_trace(False)
|
||||
# Attach a debugger to the process if a signal is caught. default False
|
||||
trick.exec_set_attach_debugger(False)
|
||||
|
||||
simControlPanel = trick.SimControlPanel()
|
||||
trick.add_external_application(simControlPanel)
|
||||
|
@ -146,17 +146,3 @@ else :
|
||||
print('===================================')
|
||||
print('PoolTableDisplay needs to be built.')
|
||||
print('===================================')
|
||||
|
||||
|
||||
# PoolTableDisplay_path = "models/graphics/java/dist/PoolTableDisplay.jar"
|
||||
|
||||
# if (os.path.isfile(PoolTableDisplay_path)) :
|
||||
# PoolTableDisplay_cmd = "java -jar " \
|
||||
# + PoolTableDisplay_path \
|
||||
# + " " + str(varServerPort) + " &" ;
|
||||
# print(PoolTableDisplay_cmd)
|
||||
# os.system( PoolTableDisplay_cmd);
|
||||
# else :
|
||||
# print('=================================================================================================')
|
||||
# print('PoolTableDisplay needs to be built. Please \"cd\" into ../models/graphics/java and type \"make\".')
|
||||
# print('=================================================================================================')
|
||||
|
@ -492,7 +492,7 @@ std::vector<std::string> split (std::string& str, const char delim) {
|
||||
std::stringstream ss(str);
|
||||
std::string s;
|
||||
std::vector<std::string> ret;
|
||||
while (std::getline(ss, s, delim)) {
|
||||
while (ss >> s) {
|
||||
ret.push_back(s);
|
||||
}
|
||||
return ret;
|
||||
@ -526,9 +526,11 @@ template <typename T>
|
||||
T getVar(Socket& socket, std::string varName) {
|
||||
std::string requestString = "trick.var_send_once(\"" + varName + "\")\n";
|
||||
std::string reply;
|
||||
// std::cout << "Request: " << requestString << std::endl;
|
||||
|
||||
socket << requestString;
|
||||
socket >> reply;
|
||||
// std::cout << "Reply: " << reply << std::endl;
|
||||
|
||||
return stringConvert<T>(split(reply, '\t')[1]);
|
||||
}
|
||||
@ -554,10 +556,13 @@ std::vector<T> getVarList(Socket& socket, std::string varName, int num) {
|
||||
}
|
||||
|
||||
std::string requestString = "trick.var_send_once(\"" + totalRequest + "\", " + std::to_string(num) + ")\n";
|
||||
// std::cout << "Request: " << requestString << std::endl;
|
||||
|
||||
std::string reply;
|
||||
socket << requestString;
|
||||
socket >> reply;
|
||||
|
||||
// std::cout << "Reply: " << reply << std::endl;
|
||||
return trickResponseConvert<T>(reply);
|
||||
}
|
||||
|
||||
@ -604,6 +609,13 @@ int main(int argc, char *argv[])
|
||||
std::vector<double> tablePoints = fold(table_x, table_y);
|
||||
|
||||
Table table;
|
||||
// std::cout << "TablePoints: ";
|
||||
|
||||
for (auto point : tablePoints ) {
|
||||
// std::cout << point << " ";
|
||||
}
|
||||
// std::cout << "\ttableShape: " << tableShape << std::endl;
|
||||
|
||||
table.addShape(tablePoints, Eigen::Vector3d(0.2, 0.6, 0.2), true, tableShape, layer_TABLE);
|
||||
|
||||
// Make the rail - translate each point on the table out from center by railWidth
|
||||
@ -697,7 +709,7 @@ int main(int argc, char *argv[])
|
||||
std::string cueRequest = "";
|
||||
std::string templateString = "dyn.table.applyCueForce(%.3f, %.3f) \n";
|
||||
|
||||
char buf[128];
|
||||
char buf[2048];
|
||||
snprintf(buf, sizeof(buf), templateString.c_str(), mouseX, mouseY);
|
||||
cueRequest += std::string(buf);
|
||||
socket << cueRequest;
|
||||
@ -716,7 +728,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
view->callback_pre_draw = [&](igl::opengl::glfw::Viewer& viewer) -> bool {
|
||||
// Look for new data and redraw
|
||||
// std::cout << "Waiting vars" << std::endl;
|
||||
socket >> reply;
|
||||
// std::cout << "Got vars: " << reply << std::endl;
|
||||
|
||||
std::vector<double> replyData = trickResponseConvert<double>(reply);
|
||||
|
||||
if (replyData.size() <= 1) {
|
||||
@ -804,7 +819,7 @@ int main(int argc, char *argv[])
|
||||
std::string positionRequest = "";
|
||||
char * templateString = "trick.var_add(\"dyn.table.balls[%d][0].pos._x\")\ntrick.var_add(\"dyn.table.balls[%d][0].pos._y\")\ntrick.var_add(\"dyn.table.balls[%d][0].inPlay\")\n";
|
||||
for (int i = 0; i < numBalls; i++) {
|
||||
char buf[128];
|
||||
char buf[2048];
|
||||
snprintf(buf, sizeof(buf), templateString, i, i, i);
|
||||
positionRequest += std::string(buf);
|
||||
}
|
||||
|
@ -1572,6 +1572,7 @@ public class SimControlApplication extends TrickApplication implements PropertyC
|
||||
@Override
|
||||
protected void finished() {
|
||||
try {
|
||||
System.out.println("Finished with health status socket channel");
|
||||
if (healthStatusSocketChannel != null) {
|
||||
healthStatusSocketChannel.close() ;
|
||||
}
|
||||
@ -1606,7 +1607,11 @@ public class SimControlApplication extends TrickApplication implements PropertyC
|
||||
|
||||
if (statusSimcom != null) {
|
||||
|
||||
results = statusSimcom.get().split("\t");
|
||||
String resultsStr = statusSimcom.get();
|
||||
if (resultsStr == null)
|
||||
break;
|
||||
|
||||
results = resultsStr.split("\t");
|
||||
ii = 1 ;
|
||||
|
||||
// whenever there is data in statusSimcom socket, do something
|
||||
|
@ -295,7 +295,7 @@ public class SimControlActionController {
|
||||
simcom.put("trick.debug_pause_off()\n" ) ;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println("Put failed!");
|
||||
System.out.println("Put failed! Exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,6 @@ set( SS_SRC
|
||||
VariableServer/VariableServer_shutdown
|
||||
VariableServer/exit_var_thread
|
||||
VariableServer/var_server_ext
|
||||
VariableServer/vs_format_ascii
|
||||
Zeroconf/Zeroconf
|
||||
mains/master
|
||||
)
|
||||
|
@ -135,6 +135,6 @@ object_${TRICK_HOST_CPU}/MTV.o: MTV.cpp ${TRICK_HOME}/include/trick/MTV.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/EventManager_c_intf.hh
|
||||
|
@ -9,7 +9,7 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../../../../share/trick/makefiles/Mak
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
TRICK_CXXFLAGS += -I$(GTEST_HOME)/include -I$(TRICK_HOME)/include -g -Wall -Wextra ${TRICK_TEST_FLAGS}
|
||||
TRICK_LIBS = -L${TRICK_LIB_DIR} -ltrick -ltrick_pyip -ltrick_comm -ltrick_math -ltrick_mm -ltrick_units
|
||||
TRICK_LIBS = -L${TRICK_LIB_DIR} -ltrick -ltrick_pyip -ltrick_comm -ltrick_math -ltrick_mm -ltrick_units -ltrick_var_binary_parser -ltrick_connection_handlers -ltrick_comm
|
||||
TRICK_EXEC_LINK_LIBS += -L${GTEST_HOME}/lib64 -L${GTEST_HOME}/lib -lgtest -lgtest_main
|
||||
|
||||
# All tests produced by this Makefile. Remember to add new tests you
|
||||
|
@ -12,7 +12,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_loop.o: VariableServerThread_loop.
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/input_processor_proto.h \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h \
|
||||
@ -39,7 +40,8 @@ object_${TRICK_HOST_CPU}/VariableServer_copy_data_scheduled.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_shutdown.o: VariableServer_shutdown.cpp \
|
||||
@ -56,7 +58,8 @@ object_${TRICK_HOST_CPU}/VariableServer_shutdown.o: VariableServer_shutdown.cpp
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_copy_data_freeze_scheduled.o: \
|
||||
VariableServer_copy_data_freeze_scheduled.cpp \
|
||||
@ -73,10 +76,11 @@ object_${TRICK_HOST_CPU}/VariableServer_copy_data_freeze_scheduled.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableReference.o: VariableReference.cpp \
|
||||
object_${TRICK_HOST_CPU}/VariableReference.o: \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
@ -90,7 +94,8 @@ object_${TRICK_HOST_CPU}/VariableReference.o: VariableReference.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/memorymanager_c_intf.h \
|
||||
${TRICK_HOME}/include/trick/var.h \
|
||||
@ -113,7 +118,8 @@ object_${TRICK_HOST_CPU}/VariableServer_get_next_freeze_call_time.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread_write_stdio.o: VariableServerThread_write_stdio.cpp \
|
||||
@ -130,7 +136,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_write_stdio.o: VariableServerThrea
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_message_types.h \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h
|
||||
@ -149,7 +156,8 @@ object_${TRICK_HOST_CPU}/VariableServer_get_next_sync_call_time.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_restart.o: VariableServer_restart.cpp \
|
||||
@ -166,7 +174,8 @@ object_${TRICK_HOST_CPU}/VariableServer_restart.o: VariableServer_restart.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/message_proto.h \
|
||||
${TRICK_HOME}/include/trick/message_type.h \
|
||||
@ -185,7 +194,8 @@ object_${TRICK_HOST_CPU}/var_server_ext.o: var_server_ext.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/exec_proto.h \
|
||||
${TRICK_HOME}/include/trick/sim_mode.h \
|
||||
@ -200,7 +210,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_create_socket.o: \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -216,7 +227,8 @@ object_${TRICK_HOST_CPU}/VariableServerListenThread.o: VariableServerListenThrea
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -243,7 +255,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_write_data.o: VariableServerThread
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_message_types.h \
|
||||
${TRICK_HOME}/include/trick/bitfield_proto.h \
|
||||
@ -265,7 +278,8 @@ object_${TRICK_HOST_CPU}/VariableServer_init.o: VariableServer_init.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/exec_proto.hh \
|
||||
${TRICK_HOME}/include/trick/Executive.hh \
|
||||
@ -291,7 +305,8 @@ object_${TRICK_HOST_CPU}/VariableServer_copy_data_freeze.o: VariableServer_copy_
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_default_data.o: VariableServer_default_data.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
@ -307,7 +322,8 @@ object_${TRICK_HOST_CPU}/VariableServer_default_data.o: VariableServer_default_d
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_freeze_init.o: VariableServer_freeze_init.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
@ -323,7 +339,8 @@ object_${TRICK_HOST_CPU}/VariableServer_freeze_init.o: VariableServer_freeze_ini
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_proto.h \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
@ -341,34 +358,17 @@ object_${TRICK_HOST_CPU}/VariableServer.o: VariableServer.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h
|
||||
object_${TRICK_HOST_CPU}/vs_format_ascii.o: vs_format_ascii.cpp \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/bitfield_proto.h \
|
||||
${TRICK_HOME}/include/trick/wcs_ext.h \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/value.h \
|
||||
${TRICK_HOME}/include/trick/dllist.h \
|
||||
${TRICK_HOME}/include/trick/JobData.hh \
|
||||
${TRICK_HOME}/include/trick/InstrumentBase.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread_restart.o: VariableServerThread_restart.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -389,7 +389,8 @@ object_${TRICK_HOST_CPU}/VariableServer_copy_data_top.o: VariableServer_copy_dat
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/exit_var_thread.o: exit_var_thread.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
@ -405,7 +406,8 @@ object_${TRICK_HOST_CPU}/exit_var_thread.o: exit_var_thread.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread_copy_data.o: VariableServerThread_copy_data.cpp \
|
||||
@ -422,7 +424,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_copy_data.o: VariableServerThread_
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/exec_proto.h \
|
||||
${TRICK_HOME}/include/trick/sim_mode.h \
|
||||
@ -443,7 +446,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_connect.o: VariableServerThread_co
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/release.h
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread_copy_sim_data.o: \
|
||||
@ -461,19 +465,21 @@ object_${TRICK_HOST_CPU}/VariableServerThread_copy_sim_data.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/memorymanager_c_intf.h \
|
||||
${TRICK_HOME}/include/trick/var.h \
|
||||
${TRICK_HOME}/include/trick/io_alloc.h \
|
||||
${TRICK_HOME}/include/trick/exec_proto.h \
|
||||
${TRICK_HOME}/include/trick/sim_mode.h
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread_freeze_init.o: VariableServerThread_freeze_init.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
object_${TRICK_HOST_CPU}/VariableServerSession_freeze_init.o: VariableServerSession_freeze_init.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -496,14 +502,16 @@ object_${TRICK_HOST_CPU}/VariableServer_get_var_server_port.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread.o: VariableServerThread.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -527,7 +535,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_loop.o: VariableServerThread_loop.
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/input_processor_proto.h \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h \
|
||||
@ -554,7 +563,8 @@ object_${TRICK_HOST_CPU}/VariableServer_copy_data_scheduled.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_shutdown.o: VariableServer_shutdown.cpp \
|
||||
@ -571,7 +581,8 @@ object_${TRICK_HOST_CPU}/VariableServer_shutdown.o: VariableServer_shutdown.cpp
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_copy_data_freeze_scheduled.o: \
|
||||
VariableServer_copy_data_freeze_scheduled.cpp \
|
||||
@ -588,10 +599,13 @@ object_${TRICK_HOST_CPU}/VariableServer_copy_data_freeze_scheduled.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableReference.o: VariableReference.cpp \
|
||||
object_${TRICK_HOST_CPU}/VariableReference.o: \
|
||||
VariableReference.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
@ -605,7 +619,8 @@ object_${TRICK_HOST_CPU}/VariableReference.o: VariableReference.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/memorymanager_c_intf.h \
|
||||
${TRICK_HOME}/include/trick/var.h \
|
||||
@ -627,7 +642,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_write_stdio.o: VariableServerThrea
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_message_types.h \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h
|
||||
@ -645,7 +661,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_commands.o: VariableServerThread_c
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_message_types.h \
|
||||
${TRICK_HOME}/include/trick/memorymanager_c_intf.h \
|
||||
@ -676,7 +693,8 @@ object_${TRICK_HOST_CPU}/VariableServer_get_next_sync_call_time.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_restart.o: VariableServer_restart.cpp \
|
||||
@ -693,7 +711,8 @@ object_${TRICK_HOST_CPU}/VariableServer_restart.o: VariableServer_restart.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/message_proto.h \
|
||||
${TRICK_HOME}/include/trick/message_type.h \
|
||||
@ -712,7 +731,8 @@ object_${TRICK_HOST_CPU}/var_server_ext.o: var_server_ext.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/exec_proto.h \
|
||||
${TRICK_HOME}/include/trick/sim_mode.h \
|
||||
@ -727,7 +747,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_create_socket.o: \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -741,9 +762,12 @@ object_${TRICK_HOST_CPU}/VariableServerListenThread.o: VariableServerListenThrea
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ClientListener.hh \
|
||||
${TRICK_HOME}/include/trick/MulticastManager.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -770,7 +794,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_write_data.o: VariableServerThread
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_message_types.h \
|
||||
${TRICK_HOME}/include/trick/bitfield_proto.h \
|
||||
@ -792,7 +817,8 @@ object_${TRICK_HOST_CPU}/VariableServer_init.o: VariableServer_init.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/exec_proto.hh \
|
||||
${TRICK_HOME}/include/trick/Executive.hh \
|
||||
@ -818,7 +844,8 @@ object_${TRICK_HOST_CPU}/VariableServer_copy_data_freeze.o: VariableServer_copy_
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_default_data.o: VariableServer_default_data.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
@ -834,7 +861,8 @@ object_${TRICK_HOST_CPU}/VariableServer_default_data.o: VariableServer_default_d
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServer_freeze_init.o: VariableServer_freeze_init.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
@ -850,7 +878,8 @@ object_${TRICK_HOST_CPU}/VariableServer_freeze_init.o: VariableServer_freeze_ini
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_proto.h \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
@ -868,34 +897,17 @@ object_${TRICK_HOST_CPU}/VariableServer.o: VariableServer.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h
|
||||
object_${TRICK_HOST_CPU}/vs_format_ascii.o: vs_format_ascii.cpp \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/bitfield_proto.h \
|
||||
${TRICK_HOME}/include/trick/wcs_ext.h \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/value.h \
|
||||
${TRICK_HOME}/include/trick/dllist.h \
|
||||
${TRICK_HOME}/include/trick/JobData.hh \
|
||||
${TRICK_HOME}/include/trick/InstrumentBase.hh \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread_restart.o: VariableServerThread_restart.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -916,7 +928,8 @@ object_${TRICK_HOST_CPU}/VariableServer_copy_data_top.o: VariableServer_copy_dat
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/exit_var_thread.o: exit_var_thread.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServer.hh \
|
||||
@ -932,7 +945,8 @@ object_${TRICK_HOST_CPU}/exit_var_thread.o: exit_var_thread.cpp \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread_copy_data.o: VariableServerThread_copy_data.cpp \
|
||||
@ -949,7 +963,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_copy_data.o: VariableServerThread_
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/exec_proto.h \
|
||||
${TRICK_HOME}/include/trick/sim_mode.h \
|
||||
@ -971,7 +986,8 @@ object_${TRICK_HOST_CPU}/VariableServer_get_next_freeze_call_time.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread_connect.o: VariableServerThread_connect.cpp \
|
||||
@ -988,7 +1004,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_connect.o: VariableServerThread_co
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/release.h
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread_copy_sim_data.o: \
|
||||
@ -1006,7 +1023,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_copy_sim_data.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh \
|
||||
${TRICK_HOME}/include/trick/memorymanager_c_intf.h \
|
||||
${TRICK_HOME}/include/trick/var.h \
|
||||
@ -1018,7 +1036,8 @@ object_${TRICK_HOST_CPU}/VariableServerThread_freeze_init.o: VariableServerThrea
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -1041,14 +1060,16 @@ object_${TRICK_HOST_CPU}/VariableServer_get_var_server_port.o: \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerListenThread.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServerThread.o: VariableServerThread.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
@ -1058,3 +1079,51 @@ object_${TRICK_HOST_CPU}/VariableServerThread.o: VariableServerThread.cpp \
|
||||
${TRICK_HOME}/include/trick/exec_proto.h \
|
||||
${TRICK_HOME}/include/trick/sim_mode.h \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/VariableServerSession.o: VariableServerSession.cpp \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
${TRICK_HOME}/include/trick/value.h \
|
||||
${TRICK_HOME}/include/trick/dllist.h \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/exec_proto.h \
|
||||
${TRICK_HOME}/include/trick/sim_mode.h \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh
|
||||
object_${TRICK_HOST_CPU}/TCConnection.o: TCConnection.cpp \
|
||||
${TRICK_HOME}/include/trick/TCConnection.hh \
|
||||
${TRICK_HOME}/include/trick/ClientConnection.hh \
|
||||
${TRICK_HOME}/include/trick/ClientListener.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerThread.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/ThreadBase.hh \
|
||||
${TRICK_HOME}/include/trick/VariableReference.hh \
|
||||
${TRICK_HOME}/include/trick/VariableServerSession.hh \
|
||||
${TRICK_HOME}/include/trick/reference.h \
|
||||
${TRICK_HOME}/include/trick/attributes.h \
|
||||
${TRICK_HOME}/include/trick/parameter_types.h \
|
||||
${TRICK_HOME}/include/trick/value.h \
|
||||
${TRICK_HOME}/include/trick/dllist.h \
|
||||
${TRICK_HOME}/include/trick/variable_server_sync_types.h \
|
||||
${TRICK_HOME}/include/trick/exec_proto.h \
|
||||
${TRICK_HOME}/include/trick/sim_mode.h \
|
||||
${TRICK_HOME}/include/trick/TrickConstant.hh \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h
|
||||
object_${TRICK_HOST_CPU}/ClientListener.o: ClientListener.cpp \
|
||||
${TRICK_HOME}/include/trick/TCConnection.hh \
|
||||
${TRICK_HOME}/include/trick/ClientConnection.hh \
|
||||
${TRICK_HOME}/include/trick/ClientListener.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h
|
||||
object_${TRICK_HOST_CPU}/MulticastManager.o: MulticastManager.cpp \
|
||||
${TRICK_HOME}/include/trick/MulticastManager.hh \
|
||||
${TRICK_HOME}/include/trick/tc.h \
|
||||
${TRICK_HOME}/include/trick/trick_error_hndlr.h \
|
||||
${TRICK_HOME}/include/trick/tc_proto.h
|
||||
|
@ -1,80 +1,736 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <udunits2.h>
|
||||
#include "trick/VariableServer.hh"
|
||||
#include <math.h> // for fpclassify
|
||||
#include <iomanip> // for setprecision
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "trick/VariableReference.hh"
|
||||
#include "trick/memorymanager_c_intf.h"
|
||||
#include "trick/wcs_ext.h"
|
||||
#include "trick/map_trick_units_to_udunits.hh"
|
||||
#include "trick/message_proto.h"
|
||||
#include "trick/message_type.h"
|
||||
|
||||
Trick::VariableReference::VariableReference(REF2 * in_ref ) {
|
||||
#include "trick/UdUnits.hh"
|
||||
#include "trick/bitfield_proto.h"
|
||||
#include "trick/trick_byteswap.h"
|
||||
#include "trick/tc_proto.h"
|
||||
|
||||
|
||||
int k ;
|
||||
// Static variables to be addresses that are known to be the error ref address
|
||||
int Trick::VariableReference::bad_ref_int = 0 ;
|
||||
int Trick::VariableReference::do_not_resolve_bad_ref_int = 0 ;
|
||||
|
||||
// VariableReference copy setup: set address & size to copy into buffer
|
||||
conversion_factor = cv_get_trivial() ;
|
||||
REF2* Trick::VariableReference::make_error_ref(std::string in_name) {
|
||||
REF2* new_ref;
|
||||
new_ref = (REF2*)calloc(1, sizeof(REF2));
|
||||
new_ref->reference = strdup(in_name.c_str()) ;
|
||||
new_ref->units = NULL ;
|
||||
new_ref->address = (char *)&bad_ref_int ;
|
||||
new_ref->attr = (ATTRIBUTES*)calloc(1, sizeof(ATTRIBUTES)) ;
|
||||
new_ref->attr->type = TRICK_NUMBER_OF_TYPES ;
|
||||
new_ref->attr->units = (char *)"--" ;
|
||||
new_ref->attr->size = sizeof(int) ;
|
||||
return new_ref;
|
||||
}
|
||||
|
||||
ref = in_ref ;
|
||||
address = ref->address ;
|
||||
size = ref->attr->size ;
|
||||
// char* and wchar* in Trick 7 have a type of string and wstring, respectively
|
||||
// but in Trick 10 they are type char and wchar (probably John Penn's fault),
|
||||
// so we need to keep track that they are really string and wstring
|
||||
string_type = ref->attr->type ;
|
||||
need_deref = false ;
|
||||
REF2* Trick::VariableReference::make_do_not_resolve_ref(std::string in_name) {
|
||||
REF2* new_ref;
|
||||
new_ref = (REF2*)calloc(1, sizeof(REF2));
|
||||
new_ref->reference = strdup(in_name.c_str()) ;
|
||||
new_ref->units = NULL ;
|
||||
new_ref->address = (char *)&do_not_resolve_bad_ref_int ;
|
||||
new_ref->attr = (ATTRIBUTES*)calloc(1, sizeof(ATTRIBUTES)) ;
|
||||
new_ref->attr->type = TRICK_NUMBER_OF_TYPES ;
|
||||
new_ref->attr->units = (char *)"--" ;
|
||||
new_ref->attr->size = sizeof(int) ;
|
||||
return new_ref;
|
||||
}
|
||||
|
||||
if ( ref->num_index == ref->attr->num_index ) {
|
||||
// single value
|
||||
} else if ( ref->attr->index[ref->attr->num_index - 1].size != 0 ) {
|
||||
// fixed array
|
||||
for ( k = ref->attr->num_index-1; k > ref->num_index-1 ; k-- ) {
|
||||
size *= ref->attr->index[k].size ;
|
||||
// Helper function to deal with time variable
|
||||
REF2* make_time_ref(double * time) {
|
||||
REF2* new_ref;
|
||||
new_ref = (REF2*)calloc(1, sizeof(REF2));
|
||||
new_ref->reference = strdup("time") ;
|
||||
new_ref->units = strdup("s") ;
|
||||
new_ref->address = (char *)time ;
|
||||
new_ref->attr = (ATTRIBUTES*)calloc(1, sizeof(ATTRIBUTES)) ;
|
||||
new_ref->attr->type = TRICK_DOUBLE ;
|
||||
new_ref->attr->units = strdup("s") ;
|
||||
new_ref->attr->size = sizeof(double) ;
|
||||
return new_ref;
|
||||
}
|
||||
|
||||
Trick::VariableReference::VariableReference(std::string var_name, double* time) : staged(false), write_ready(false) {
|
||||
if (var_name != "time") {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
var_info = make_time_ref(time);
|
||||
|
||||
// Set up member variables
|
||||
address = var_info->address;
|
||||
size = var_info->attr->size ;
|
||||
deref = false;
|
||||
|
||||
// Deal with weirdness around string vs wstring
|
||||
trick_type = var_info->attr->type ;
|
||||
|
||||
// Allocate stage and write buffers
|
||||
stage_buffer = calloc(size, 1) ;
|
||||
write_buffer = calloc(size, 1) ;
|
||||
|
||||
conversion_factor = cv_get_trivial();
|
||||
}
|
||||
|
||||
Trick::VariableReference::VariableReference(std::string var_name) : staged(false), write_ready(false) {
|
||||
|
||||
if (var_name == "time") {
|
||||
ASSERT(0);
|
||||
} else {
|
||||
// get variable attributes from memory manager
|
||||
var_info = ref_attributes(var_name.c_str());
|
||||
}
|
||||
|
||||
// Handle error cases
|
||||
if ( var_info == NULL ) {
|
||||
// TODO: ERROR LOGGER sendErrorMessage("Variable Server could not find variable %s.\n", var_name);
|
||||
// PRINTF IS NOT AN ERROR LOGGER @me
|
||||
printf("Variable Server could not find variable %s.\n", var_name.c_str());
|
||||
var_info = make_error_ref(var_name);
|
||||
} else if ( var_info->attr ) {
|
||||
if ( var_info->attr->type == TRICK_STRUCTURED ) {
|
||||
// sendErrorMessage("Variable Server: var_add cant add \"%s\" because its a composite variable.\n", var_name);
|
||||
printf("Variable Server: var_add cant add \"%s\" because its a composite variable.\n", var_name.c_str());
|
||||
|
||||
free(var_info);
|
||||
var_info = make_do_not_resolve_ref(var_name);
|
||||
|
||||
} else if ( var_info->attr->type == TRICK_STL ) {
|
||||
// sendErrorMessage("Variable Server: var_add cant add \"%s\" because its an STL variable.\n", var_name);
|
||||
printf("Variable Server: var_add cant add \"%s\" because its an STL variable.\n", var_name.c_str());
|
||||
|
||||
free(var_info);
|
||||
var_info = make_do_not_resolve_ref(var_name);
|
||||
}
|
||||
} else {
|
||||
// arrays with pointers
|
||||
if ((ref->attr->num_index - ref->num_index) > 1 ) {
|
||||
// you cannot request more than one dimension because they are not contiguous
|
||||
message_publish(MSG_ERROR, "Variable Server Error: var_add(%s) requests more than one dimension of dynamic array.\n", ref->reference);
|
||||
message_publish(MSG_ERROR, "Data is not contiguous so returned values are unpredictable.\n") ;
|
||||
// sendErrorMessage("Variable Server: BAD MOJO - Missing ATTRIBUTES.");
|
||||
printf("Variable Server: BAD MOJO - Missing ATTRIBUTES.");
|
||||
|
||||
free(var_info);
|
||||
var_info = make_error_ref(var_name);
|
||||
}
|
||||
|
||||
// Set up member variables
|
||||
var_info->units = NULL;
|
||||
address = var_info->address;
|
||||
size = var_info->attr->size ;
|
||||
deref = false;
|
||||
|
||||
// Deal with weirdness around string vs wstring
|
||||
trick_type = var_info->attr->type ;
|
||||
|
||||
if ( var_info->num_index == var_info->attr->num_index ) {
|
||||
// single value - nothing else necessary
|
||||
} else if ( var_info->attr->index[var_info->attr->num_index - 1].size != 0 ) {
|
||||
// Constrained array
|
||||
for ( int i = var_info->attr->num_index-1; i > var_info->num_index-1 ; i-- ) {
|
||||
size *= var_info->attr->index[i].size ;
|
||||
}
|
||||
if ( ref->attr->type == TRICK_CHARACTER ) {
|
||||
// treat char* like a c++ string (see below)
|
||||
string_type = TRICK_STRING ;
|
||||
need_deref = true;
|
||||
} else if ( ref->attr->type == TRICK_WCHAR ) {
|
||||
// treat wchar_t* like a wstring (see below)
|
||||
string_type = TRICK_WSTRING ;
|
||||
} else {
|
||||
// Unconstrained array
|
||||
if ((var_info->attr->num_index - var_info->num_index) > 1 ) {
|
||||
// TODO: ERROR LOGGER
|
||||
printf("Variable Server Error: var_add(%s) requests more than one dimension of dynamic array.\n", var_info->reference);
|
||||
printf("Data is not contiguous so returned values are unpredictable.\n") ;
|
||||
}
|
||||
if ( var_info->attr->type == TRICK_CHARACTER ) {
|
||||
trick_type = TRICK_STRING ;
|
||||
deref = true;
|
||||
} else if ( var_info->attr->type == TRICK_WCHAR ) {
|
||||
trick_type = TRICK_WSTRING ;
|
||||
deref = true;
|
||||
} else {
|
||||
need_deref = true ;
|
||||
deref = true ;
|
||||
size *= get_size((char*)address) ;
|
||||
}
|
||||
}
|
||||
|
||||
// handle strings: set a max buffer size, the copy size may vary so will be set in copy_sim_data
|
||||
if (( string_type == TRICK_STRING ) || ( string_type == TRICK_WSTRING )) {
|
||||
if (( trick_type == TRICK_STRING ) || ( trick_type == TRICK_WSTRING )) {
|
||||
size = MAX_ARRAY_LENGTH ;
|
||||
}
|
||||
|
||||
buffer_in = calloc( size, 1 ) ;
|
||||
buffer_out = calloc( size, 1 ) ;
|
||||
// Allocate stage and write buffers
|
||||
stage_buffer = calloc(size, 1) ;
|
||||
write_buffer = calloc(size, 1) ;
|
||||
|
||||
conversion_factor = cv_get_trivial();
|
||||
|
||||
}
|
||||
|
||||
std::ostream& Trick::operator<< (std::ostream& s, const Trick::VariableReference& vref) {
|
||||
|
||||
if (vref.ref->reference != NULL) {
|
||||
s << " \"" << vref.ref->reference << "\"";
|
||||
} else {
|
||||
s<< " null";
|
||||
}
|
||||
return s;
|
||||
// Done!
|
||||
}
|
||||
|
||||
Trick::VariableReference::~VariableReference() {
|
||||
free(ref) ;
|
||||
free(buffer_in) ;
|
||||
free(buffer_out) ;
|
||||
if (var_info != NULL) {
|
||||
free( var_info );
|
||||
var_info = NULL;
|
||||
}
|
||||
if (stage_buffer != NULL) {
|
||||
free (stage_buffer);
|
||||
stage_buffer = NULL;
|
||||
}
|
||||
if (write_buffer != NULL) {
|
||||
free (write_buffer);
|
||||
write_buffer = NULL;
|
||||
}
|
||||
if (conversion_factor != NULL) {
|
||||
cv_free(conversion_factor);
|
||||
}
|
||||
}
|
||||
|
||||
const char* Trick::VariableReference::getName() const {
|
||||
return var_info->reference;
|
||||
}
|
||||
|
||||
int Trick::VariableReference::getSizeBinary() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
TRICK_TYPE Trick::VariableReference::getType() const {
|
||||
return trick_type;
|
||||
}
|
||||
|
||||
const char* Trick::VariableReference::getBaseUnits() const {
|
||||
return var_info->attr->units;
|
||||
}
|
||||
|
||||
int Trick::VariableReference::setRequestedUnits(std::string units_name) {
|
||||
// Some error logging lambdas - these should probably go somewhere else
|
||||
// But I do kinda like them
|
||||
auto publish = [](MESSAGE_TYPE type, const std::string& message) {
|
||||
std::ostringstream oss;
|
||||
oss << "Variable Server: " << message << std::endl;
|
||||
message_publish(type, oss.str().c_str());
|
||||
};
|
||||
|
||||
auto publishError = [&](const std::string& units) {
|
||||
std::ostringstream oss;
|
||||
oss << "units error for [" << getName() << "] [" << units << "]";
|
||||
publish(MSG_ERROR, oss.str());
|
||||
};
|
||||
|
||||
// If the units_name parameter is "xx", set it to the current units.
|
||||
if (!units_name.compare("xx")) {
|
||||
units_name = getBaseUnits();
|
||||
}
|
||||
|
||||
// if unitless ('--') then do not convert to udunits
|
||||
if(units_name.compare("--")) {
|
||||
// Check to see if this is an old style Trick unit that needs to be converted to new udunits
|
||||
std::string new_units = map_trick_units_to_udunits(units_name) ;
|
||||
// Warn if a conversion has taken place
|
||||
if ( units_name.compare(new_units) ) {
|
||||
// TODO: MAKE BETTER SYSTEM FOR ERROR LOGGING
|
||||
std::ostringstream oss;
|
||||
oss << "[" << getName() << "] old-style units converted from ["
|
||||
<< units_name << "] to [" << new_units << "]";
|
||||
publish(MSG_WARNING, oss.str());
|
||||
}
|
||||
|
||||
// Interpret base unit
|
||||
ut_unit * from = ut_parse(Trick::UdUnits::get_u_system(), getBaseUnits(), UT_ASCII) ;
|
||||
if ( !from ) {
|
||||
std::cout << "Error in interpreting base units" << std::endl;
|
||||
publishError(getBaseUnits());
|
||||
ut_free(from) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
// Interpret requested unit
|
||||
ut_unit * to = ut_parse(Trick::UdUnits::get_u_system(), new_units.c_str(), UT_ASCII) ;
|
||||
if ( !to ) {
|
||||
std::cout << "Error in interpreting requested units" << std::endl;
|
||||
publishError(new_units);
|
||||
ut_free(from) ;
|
||||
ut_free(to) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
// Create a converter from the base to the requested
|
||||
auto new_conversion_factor = ut_get_converter(from, to) ;
|
||||
ut_free(from) ;
|
||||
ut_free(to) ;
|
||||
if ( !new_conversion_factor ) {
|
||||
std::ostringstream oss;
|
||||
oss << "[" << getName() << "] cannot convert units from [" << getBaseUnits()
|
||||
<< "] to [" << new_units << "]";
|
||||
publish(MSG_ERROR, oss.str());
|
||||
return -1 ;
|
||||
} else {
|
||||
conversion_factor = new_conversion_factor;
|
||||
}
|
||||
|
||||
// Don't memory leak the old units!
|
||||
if (var_info->units != NULL) {
|
||||
free(var_info->units);
|
||||
}
|
||||
|
||||
// Set the requested units. This will cause the unit string to be printed in write_value_ascii
|
||||
var_info->units = strdup(new_units.c_str());;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Trick::VariableReference::stageValue(bool validate_address) {
|
||||
write_ready = false;
|
||||
|
||||
// Copy <size> bytes from <address> to staging_point.
|
||||
|
||||
// Try to recreate connection if it has been broken
|
||||
if (var_info->address == &bad_ref_int) {
|
||||
REF2 *new_ref = ref_attributes(var_info->reference);
|
||||
if (new_ref != NULL) {
|
||||
var_info = new_ref;
|
||||
address = var_info->address;
|
||||
}
|
||||
}
|
||||
|
||||
// if there's a pointer somewhere in the address path, follow it in case pointer changed
|
||||
if ( var_info->pointer_present == 1 ) {
|
||||
address = follow_address_path(var_info) ;
|
||||
if (address == NULL) {
|
||||
tagAsInvalid();
|
||||
} else if ( validate_address ) {
|
||||
validate();
|
||||
} else {
|
||||
var_info->address = address ;
|
||||
}
|
||||
}
|
||||
|
||||
// if this variable is a string we need to get the raw character string out of it.
|
||||
if (( trick_type == TRICK_STRING ) && !deref) {
|
||||
std::string * str_ptr = (std::string *)var_info->address ;
|
||||
// Get a pointer to the internal character array
|
||||
address = (void *)(str_ptr->c_str()) ;
|
||||
}
|
||||
|
||||
// if this variable itself is a pointer, dereference it
|
||||
if ( deref ) {
|
||||
address = *(void**)var_info->address ;
|
||||
}
|
||||
|
||||
// handle c++ string and char*
|
||||
if ( trick_type == TRICK_STRING ) {
|
||||
if (address == NULL) {
|
||||
size = 0 ;
|
||||
} else {
|
||||
size = strlen((char*)address) + 1 ;
|
||||
}
|
||||
}
|
||||
// handle c++ wstring and wchar_t*
|
||||
if ( trick_type == TRICK_WSTRING ) {
|
||||
if (address == NULL) {
|
||||
size = 0 ;
|
||||
} else {
|
||||
size = wcslen((wchar_t *)address) * sizeof(wchar_t);
|
||||
}
|
||||
}
|
||||
if(address != NULL) {
|
||||
memcpy( stage_buffer , address , size ) ;
|
||||
}
|
||||
|
||||
staged = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Trick::VariableReference::validate() {
|
||||
// The address is not NULL.
|
||||
// Should be called by VariableServer Session if validateAddress is on.
|
||||
// check the memory manager if the address falls into
|
||||
// any of the memory blocks it knows of. Don't do this if we have a std::string or
|
||||
// wstring type, or we already are pointing to a bad ref.
|
||||
if ( (trick_type != TRICK_STRING) and
|
||||
(trick_type != TRICK_WSTRING) and
|
||||
(var_info->address != &bad_ref_int) and
|
||||
(get_alloc_info_of(address) == NULL) ) {
|
||||
|
||||
// This variable is broken, make it into an error ref
|
||||
tagAsInvalid();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything is fine
|
||||
return true;
|
||||
}
|
||||
|
||||
static void write_escaped_string( std::ostream& os, const char* s) {
|
||||
for (int ii=0 ; ii<strlen(s) ; ii++) {
|
||||
if (isprint(s[ii])) {
|
||||
os << s[ii];
|
||||
} else {
|
||||
switch ((s)[ii]) {
|
||||
case '\n': os << "\\n"; break;
|
||||
case '\t': os << "\\t"; break;
|
||||
case '\b': os << "\\b"; break;
|
||||
case '\a': os << "\\a"; break;
|
||||
case '\f': os << "\\f"; break;
|
||||
case '\r': os << "\\n"; break;
|
||||
case '\v': os << "\\v"; break;
|
||||
case '\"': os << "\\\""; break;
|
||||
default : {
|
||||
// Replicating behavior from original vs_format_ascii
|
||||
char temp_s[6];
|
||||
sprintf(temp_s, "\\x%02x", s[ii]);
|
||||
os << temp_s ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Trick::VariableReference::getSizeAscii() const {
|
||||
std::stringstream ss;
|
||||
writeValueAscii(ss);
|
||||
return ss.str().length();
|
||||
}
|
||||
|
||||
|
||||
int Trick::VariableReference::writeValueAscii( std::ostream& out ) const {
|
||||
// This is copied and modified from vs_format_ascii
|
||||
// There's a lot here that doesn't make sense to me that I need to come back to
|
||||
// There seems to be a huge buffer overflow issue in the original.
|
||||
// Only strings are checked for length, arrays aren't
|
||||
// But using a stream instead should make that better
|
||||
// The way that arrays are handled seems weird.
|
||||
|
||||
if (!isWriteReady()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int bytes_written = 0;
|
||||
void * buf_ptr = write_buffer ;
|
||||
while (bytes_written < size) {
|
||||
bytes_written += var_info->attr->size ;
|
||||
|
||||
switch (trick_type) {
|
||||
|
||||
case TRICK_CHARACTER:
|
||||
if (var_info->attr->num_index == var_info->num_index) {
|
||||
// Single char
|
||||
out << (int)cv_convert_double(conversion_factor, *(char *)buf_ptr);
|
||||
} else {
|
||||
// All but last dim specified, leaves a char array
|
||||
write_escaped_string(out, (const char *) buf_ptr);
|
||||
bytes_written = size ;
|
||||
}
|
||||
break;
|
||||
case TRICK_UNSIGNED_CHARACTER:
|
||||
if (var_info->attr->num_index == var_info->num_index) {
|
||||
// Single char
|
||||
out << (unsigned int)cv_convert_double(conversion_factor,*(unsigned char *)buf_ptr);
|
||||
} else {
|
||||
// All but last dim specified, leaves a char array
|
||||
write_escaped_string(out, (const char *) buf_ptr);
|
||||
bytes_written = size ;
|
||||
}
|
||||
break;
|
||||
|
||||
case TRICK_WCHAR:{
|
||||
if (var_info->attr->num_index == var_info->num_index) {
|
||||
out << *(wchar_t *) buf_ptr;
|
||||
} else {
|
||||
// convert wide char string char string
|
||||
size_t len = wcs_to_ncs_len((wchar_t *)buf_ptr) + 1 ;
|
||||
|
||||
char temp_buf[len];
|
||||
wcs_to_ncs((wchar_t *) buf_ptr, temp_buf, len);
|
||||
out << temp_buf;
|
||||
bytes_written = size ;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TRICK_STRING:
|
||||
if ((char *) buf_ptr != NULL) {
|
||||
write_escaped_string(out, (const char *) buf_ptr);
|
||||
bytes_written = size ;
|
||||
} else {
|
||||
out << '\0';
|
||||
}
|
||||
break;
|
||||
|
||||
case TRICK_WSTRING:
|
||||
if ((wchar_t *) buf_ptr != NULL) {
|
||||
// convert wide char string char string
|
||||
size_t len = wcs_to_ncs_len( (wchar_t *)buf_ptr) + 1 ;
|
||||
|
||||
char temp_buf[len];
|
||||
wcs_to_ncs( (wchar_t *) buf_ptr, temp_buf, len);
|
||||
out << temp_buf;
|
||||
bytes_written = size ;
|
||||
} else {
|
||||
out << '\0';
|
||||
}
|
||||
break;
|
||||
case TRICK_SHORT:
|
||||
out << (short)cv_convert_double(conversion_factor,*(short *)buf_ptr);
|
||||
break;
|
||||
|
||||
case TRICK_UNSIGNED_SHORT:
|
||||
out << (unsigned short)cv_convert_double(conversion_factor,*(unsigned short *)buf_ptr);
|
||||
break;
|
||||
|
||||
case TRICK_INTEGER:
|
||||
case TRICK_ENUMERATED:
|
||||
out << (int)cv_convert_double(conversion_factor,*(int *)buf_ptr);
|
||||
break;
|
||||
|
||||
case TRICK_BOOLEAN:
|
||||
out << (int)cv_convert_double(conversion_factor,*(bool *)buf_ptr);
|
||||
break;
|
||||
|
||||
case TRICK_BITFIELD:
|
||||
out << (GET_BITFIELD(buf_ptr, var_info->attr->size, var_info->attr->index[0].start, var_info->attr->index[0].size));
|
||||
break;
|
||||
|
||||
case TRICK_UNSIGNED_BITFIELD:
|
||||
out << (GET_UNSIGNED_BITFIELD(buf_ptr, var_info->attr->size, var_info->attr->index[0].start, var_info->attr->index[0].size));
|
||||
break;
|
||||
|
||||
case TRICK_UNSIGNED_INTEGER:
|
||||
out << (unsigned int)cv_convert_double(conversion_factor,*(unsigned int *)buf_ptr);
|
||||
break;
|
||||
|
||||
case TRICK_LONG: {
|
||||
long l = *(long *)buf_ptr;
|
||||
if (conversion_factor != cv_get_trivial()) {
|
||||
l = (long)cv_convert_double(conversion_factor, l);
|
||||
}
|
||||
out << l;
|
||||
break;
|
||||
}
|
||||
|
||||
case TRICK_UNSIGNED_LONG: {
|
||||
unsigned long ul = *(unsigned long *)buf_ptr;
|
||||
if (conversion_factor != cv_get_trivial()) {
|
||||
ul = (unsigned long)cv_convert_double(conversion_factor, ul);
|
||||
}
|
||||
out << ul;
|
||||
break;
|
||||
}
|
||||
|
||||
case TRICK_FLOAT:
|
||||
out << std::setprecision(8) << cv_convert_float(conversion_factor,*(float *)buf_ptr);
|
||||
break;
|
||||
|
||||
case TRICK_DOUBLE:
|
||||
out << std::setprecision(16) << cv_convert_double(conversion_factor,*(double *)buf_ptr);
|
||||
break;
|
||||
|
||||
case TRICK_LONG_LONG: {
|
||||
long long ll = *(long long *)buf_ptr;
|
||||
if (conversion_factor != cv_get_trivial()) {
|
||||
ll = (long long)cv_convert_double(conversion_factor, ll);
|
||||
}
|
||||
out << ll;
|
||||
break;
|
||||
}
|
||||
|
||||
case TRICK_UNSIGNED_LONG_LONG: {
|
||||
unsigned long long ull = *(unsigned long long *)buf_ptr;
|
||||
if (conversion_factor != cv_get_trivial()) {
|
||||
ull = (unsigned long long)cv_convert_double(conversion_factor, ull);
|
||||
}
|
||||
out << ull;
|
||||
break;
|
||||
}
|
||||
|
||||
case TRICK_NUMBER_OF_TYPES:
|
||||
out << "BAD_REF";
|
||||
break;
|
||||
|
||||
default:{
|
||||
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
if (bytes_written < size) {
|
||||
// if returning an array, continue array as comma separated values
|
||||
out << ",";
|
||||
buf_ptr = (void*) ((long)buf_ptr + var_info->attr->size) ;
|
||||
}
|
||||
} //end while
|
||||
|
||||
if (var_info->units) {
|
||||
if ( var_info->attr->mods & TRICK_MODS_UNITSDASHDASH ) {
|
||||
out << " {--}";
|
||||
} else {
|
||||
out << " {" << var_info->units << "}";
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Trick::VariableReference::tagAsInvalid () {
|
||||
std::string save_name(getName()) ;
|
||||
free(var_info) ;
|
||||
var_info = make_error_ref(save_name) ;
|
||||
address = var_info->address ;
|
||||
}
|
||||
|
||||
|
||||
int Trick::VariableReference::prepareForWrite() {
|
||||
if (!staged) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void * temp_p = stage_buffer;
|
||||
stage_buffer = write_buffer;
|
||||
write_buffer = temp_p;
|
||||
|
||||
staged = false;
|
||||
write_ready = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Trick::VariableReference::isStaged() const {
|
||||
return staged;
|
||||
}
|
||||
|
||||
bool Trick::VariableReference::isWriteReady() const {
|
||||
return write_ready;
|
||||
}
|
||||
|
||||
int Trick::VariableReference::writeTypeBinary( std::ostream& out, bool byteswap ) const {
|
||||
int local_type = trick_type;
|
||||
if (byteswap) {
|
||||
local_type = trick_byteswap_int(local_type);
|
||||
}
|
||||
out.write(const_cast<const char *>(reinterpret_cast<char *>(&local_type)), sizeof(int));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Trick::VariableReference::writeSizeBinary( std::ostream& out, bool byteswap ) const {
|
||||
int local_size = size;
|
||||
if (byteswap) {
|
||||
local_size = trick_byteswap_int(local_size);
|
||||
}
|
||||
out.write(const_cast<const char *>(reinterpret_cast<char *>(&local_size)), sizeof(int));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Trick::VariableReference::writeNameBinary( std::ostream& out, bool byteswap ) const {
|
||||
const char * name = getName();
|
||||
|
||||
int name_size = strlen(name);
|
||||
if (byteswap) {
|
||||
name_size = trick_byteswap_int(name_size);
|
||||
}
|
||||
|
||||
out.write(const_cast<const char *>(reinterpret_cast<char *>(&name_size)), sizeof(int));
|
||||
out.write(name, strlen(name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Trick::VariableReference::byteswap_var (char * out, char * in) const {
|
||||
byteswap_var(out, in, *this);
|
||||
}
|
||||
|
||||
|
||||
void Trick::VariableReference::byteswap_var (char * out, char * in, const VariableReference& ref) {
|
||||
ATTRIBUTES * attr = ref.var_info->attr;
|
||||
int array_size = 1;
|
||||
|
||||
// Determine how many elements are in this array if it is an array
|
||||
for (int j = 0; j < ref.var_info->attr->num_index; j++) {
|
||||
array_size *= attr->index[j].size;
|
||||
}
|
||||
|
||||
switch (attr->size) {
|
||||
case 1:
|
||||
// If these are just characters, no need to byteswap
|
||||
for (int j = 0; j < array_size; j++) {
|
||||
out[j] = in[j];
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
short * short_in = reinterpret_cast<short *> (in);
|
||||
short * short_out = reinterpret_cast<short *> (out);
|
||||
|
||||
for (int j = 0; j < array_size; j++) {
|
||||
short_out[j] = trick_byteswap_short(short_in[j]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: {
|
||||
int * int_in = reinterpret_cast<int *> (in);
|
||||
int * int_out = reinterpret_cast<int *> (out);
|
||||
|
||||
for (int j = 0; j < array_size; j++) {
|
||||
int_out[j] = trick_byteswap_int(int_in[j]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
// We don't actually care if this is double or long, just that it's the right size
|
||||
double * double_in = reinterpret_cast<double *> (in);
|
||||
double * double_out = reinterpret_cast<double *> (out);
|
||||
|
||||
for (int j = 0; j < array_size; j++) {
|
||||
double_out[j] = trick_byteswap_double(double_in[j]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Trick::VariableReference::writeValueBinary( std::ostream& out, bool byteswap ) const {
|
||||
|
||||
char buf[20480];
|
||||
int temp_i ;
|
||||
unsigned int temp_ui ;
|
||||
|
||||
// int offset = 0;
|
||||
|
||||
switch ( var_info->attr->type ) {
|
||||
case TRICK_BITFIELD:
|
||||
temp_i = GET_BITFIELD(address , var_info->attr->size ,
|
||||
var_info->attr->index[0].start, var_info->attr->index[0].size) ;
|
||||
memcpy(buf, &temp_i , (size_t)size) ;
|
||||
break ;
|
||||
case TRICK_UNSIGNED_BITFIELD:
|
||||
temp_ui = GET_UNSIGNED_BITFIELD(address , var_info->attr->size ,
|
||||
var_info->attr->index[0].start, var_info->attr->index[0].size) ;
|
||||
memcpy(buf , &temp_ui , (size_t)size) ;
|
||||
break ;
|
||||
case TRICK_NUMBER_OF_TYPES:
|
||||
// TRICK_NUMBER_OF_TYPES is an error case
|
||||
temp_i = 0 ;
|
||||
memcpy(buf , &temp_i , (size_t)size) ;
|
||||
break ;
|
||||
default:
|
||||
if (byteswap)
|
||||
byteswap_var(buf, (char *) address);
|
||||
else
|
||||
memcpy(buf , address , (size_t)size) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
out.write(buf, size);
|
||||
}
|
||||
|
||||
std::ostream& Trick::operator<< (std::ostream& s, const Trick::VariableReference& ref) {
|
||||
|
||||
s << " \"" << ref.getName() << "\"";
|
||||
return s;
|
||||
}
|
@ -16,6 +16,7 @@ Trick::VariableServer::VariableServer() :
|
||||
}
|
||||
|
||||
Trick::VariableServer::~VariableServer() {
|
||||
|
||||
}
|
||||
|
||||
std::ostream& Trick::operator<< (std::ostream& s, Trick::VariableServer& vs) {
|
||||
@ -65,8 +66,8 @@ bool Trick::VariableServer::get_log() {
|
||||
void Trick::VariableServer::set_var_server_log_on() {
|
||||
log = true;
|
||||
// turn log on for all current vs clients
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
std::map < pthread_t , VariableServerSession * >::iterator it ;
|
||||
for ( it = var_server_sessions.begin() ; it != var_server_sessions.end() ; it++ ) {
|
||||
(*it).second->set_log_on();
|
||||
}
|
||||
}
|
||||
@ -74,14 +75,15 @@ void Trick::VariableServer::set_var_server_log_on() {
|
||||
void Trick::VariableServer::set_var_server_log_off() {
|
||||
log = false;
|
||||
// turn log off for all current vs clients
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
std::map < pthread_t , VariableServerSession * >::iterator it ;
|
||||
for ( it = var_server_sessions.begin() ; it != var_server_sessions.end() ; it++ ) {
|
||||
(*it).second->set_log_off();
|
||||
}
|
||||
}
|
||||
|
||||
const char * Trick::VariableServer::get_hostname() {
|
||||
return (listen_thread.get_hostname()) ;
|
||||
const char * ret = (listen_thread.get_hostname()) ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Trick::VariableServerListenThread & Trick::VariableServer::get_listen_thread() {
|
||||
@ -94,6 +96,12 @@ void Trick::VariableServer::add_vst(pthread_t in_thread_id, VariableServerThread
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
}
|
||||
|
||||
void Trick::VariableServer::add_session(pthread_t in_thread_id, VariableServerSession * in_session) {
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
var_server_sessions[in_thread_id] = in_session ;
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
}
|
||||
|
||||
Trick::VariableServerThread * Trick::VariableServer::get_vst(pthread_t thread_id) {
|
||||
std::map < pthread_t , Trick::VariableServerThread * >::iterator it ;
|
||||
Trick::VariableServerThread * ret = NULL ;
|
||||
@ -106,12 +114,30 @@ Trick::VariableServerThread * Trick::VariableServer::get_vst(pthread_t thread_id
|
||||
return ret ;
|
||||
}
|
||||
|
||||
Trick::VariableServerSession * Trick::VariableServer::get_session(pthread_t thread_id) {
|
||||
std::map < pthread_t , Trick::VariableServerSession * >::iterator it ;
|
||||
Trick::VariableServerSession * ret = NULL ;
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
it = var_server_sessions.find(thread_id) ;
|
||||
if ( it != var_server_sessions.end() ) {
|
||||
ret = (*it).second ;
|
||||
}
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
return ret ;
|
||||
}
|
||||
|
||||
void Trick::VariableServer::delete_vst(pthread_t thread_id) {
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
var_server_threads.erase(thread_id) ;
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
}
|
||||
|
||||
void Trick::VariableServer::delete_session(pthread_t thread_id) {
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
var_server_sessions.erase(thread_id) ;
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
}
|
||||
|
||||
void Trick::VariableServer::set_copy_data_job( Trick::JobData * in_job ) {
|
||||
copy_data_job = in_job ;
|
||||
}
|
||||
|
@ -10,37 +10,38 @@
|
||||
#include "trick/message_proto.h"
|
||||
#include "trick/message_type.h"
|
||||
|
||||
|
||||
Trick::VariableServerListenThread::VariableServerListenThread() :
|
||||
Trick::SysThread("VarServListen"),
|
||||
port(0),
|
||||
user_port_requested(false),
|
||||
requested_port(0),
|
||||
requested_source_address(""),
|
||||
user_requested_address(false),
|
||||
broadcast(true),
|
||||
listen_dev()
|
||||
listener()
|
||||
{
|
||||
char hname[80];
|
||||
gethostname(hname , (size_t) 80 ) ;
|
||||
source_address = std::string(hname) ;
|
||||
strcpy(listen_dev.client_tag, "<empty>");
|
||||
tc_error(&listen_dev, 0);
|
||||
pthread_mutex_init(&restart_pause, NULL);
|
||||
}
|
||||
|
||||
Trick::VariableServerListenThread::~VariableServerListenThread() {
|
||||
free(listen_dev.hostname) ;
|
||||
free(listen_dev.error_handler) ;
|
||||
// if (multicast != NULL) {
|
||||
// delete multicast;
|
||||
// multicast = NULL;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
const char * Trick::VariableServerListenThread::get_hostname() {
|
||||
return listen_dev.hostname;
|
||||
const char * ret = listener.getHostname();
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned short Trick::VariableServerListenThread::get_port() {
|
||||
return port;
|
||||
return requested_port;
|
||||
}
|
||||
|
||||
void Trick::VariableServerListenThread::set_port(unsigned short in_port) {
|
||||
port = in_port;
|
||||
user_port_requested = true ;
|
||||
requested_port = in_port;
|
||||
user_requested_address = true ;
|
||||
}
|
||||
|
||||
std::string Trick::VariableServerListenThread::get_user_tag() {
|
||||
@ -57,140 +58,116 @@ void Trick::VariableServerListenThread::set_user_tag(std::string in_tag) {
|
||||
|
||||
void Trick::VariableServerListenThread::set_source_address(const char * address) {
|
||||
if ( address == NULL ) {
|
||||
source_address = std::string("") ;
|
||||
requested_source_address = std::string("") ;
|
||||
} else {
|
||||
source_address = std::string(address) ;
|
||||
requested_source_address = std::string(address) ;
|
||||
}
|
||||
user_port_requested = true ;
|
||||
user_requested_address = true ;
|
||||
}
|
||||
|
||||
std::string Trick::VariableServerListenThread::get_source_address() {
|
||||
return source_address ;
|
||||
return listener.getHostname() ;
|
||||
}
|
||||
|
||||
bool Trick::VariableServerListenThread::get_broadcast() {
|
||||
return broadcast;
|
||||
}
|
||||
|
||||
// in_broadcast atomic? We'll see what tsan says. Maybe go nuts with atomics
|
||||
void Trick::VariableServerListenThread::set_broadcast(bool in_broadcast) {
|
||||
broadcast = in_broadcast;
|
||||
}
|
||||
|
||||
int Trick::VariableServerListenThread::init_listen_device() {
|
||||
int ret;
|
||||
|
||||
ret = tc_init(&listen_dev);
|
||||
if (ret == TC_SUCCESS) {
|
||||
port = listen_dev.port ;
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: Could not establish listen port for Variable Server. Aborting.\n");
|
||||
ret = -1 ;
|
||||
}
|
||||
return ret ;
|
||||
int ret = listener.initialize();
|
||||
requested_port = listener.getPort();
|
||||
requested_source_address = std::string(listener.getHostname());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Trick::VariableServerListenThread::check_and_move_listen_device() {
|
||||
int ret ;
|
||||
|
||||
if ( source_address.compare(listen_dev.hostname) or port != listen_dev.port ) {
|
||||
if ( user_requested_address ) {
|
||||
|
||||
/* The user has requested a different source address or port in the input file */
|
||||
tc_disconnect(&listen_dev) ;
|
||||
ret = tc_init_with_connection_info(&listen_dev, AF_INET, SOCK_STREAM, source_address.c_str(), port) ;
|
||||
listener.disconnect();
|
||||
ret = listener.initialize(requested_source_address, requested_port);
|
||||
requested_port = listener.getPort();
|
||||
requested_source_address = std::string(listener.getHostname());
|
||||
if (ret != TC_SUCCESS) {
|
||||
std::cout << "Unsuccessful initialization " << std::endl;
|
||||
message_publish(MSG_ERROR, "ERROR: Could not establish variable server source_address %s: port %d. Aborting.\n",
|
||||
source_address.c_str(), port);
|
||||
requested_source_address.c_str(), requested_port);
|
||||
return -1 ;
|
||||
}
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
void Trick::VariableServerListenThread::create_tcp_socket(const char * address, unsigned short in_port ) {
|
||||
int result = tc_init_with_connection_info(&listen_dev, AF_INET, SOCK_STREAM, address, in_port) ;
|
||||
if (result != 0) {
|
||||
message_publish(MSG_ERROR, "ERROR: Could not establish additional listen port at address %s and port %d for Variable Server.\n", address, in_port);
|
||||
}
|
||||
listener.initialize(address, in_port);
|
||||
}
|
||||
|
||||
void * Trick::VariableServerListenThread::thread_body() {
|
||||
// This thread listens for incoming client connections, and when one is received, creates a new thread to handle the session
|
||||
// Also broadcasts on multicast channel
|
||||
|
||||
fd_set rfds;
|
||||
struct timeval timeout_time = { 2, 0 };
|
||||
char buf1[1024] = { 0 } ;
|
||||
struct passwd * passp ;
|
||||
Trick::VariableServerThread * vst ;
|
||||
int value;
|
||||
std::string version;
|
||||
char * user_name ;
|
||||
|
||||
int mcast_socket = 0;
|
||||
struct sockaddr_in mcast_addr ;
|
||||
struct sockaddr_in mcast_addr_legacy ;
|
||||
|
||||
version = std::string(exec_get_current_version()) ;
|
||||
std::string version = std::string(exec_get_current_version()) ;
|
||||
version.erase(version.find_last_not_of(" \t\f\v\n\r")+1);
|
||||
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||
|
||||
passp = getpwuid(getuid()) ;
|
||||
|
||||
// get username to broadcast on multicast channel
|
||||
struct passwd *passp = getpwuid(getuid()) ;
|
||||
std::string user_name;
|
||||
if ( passp == NULL ) {
|
||||
user_name = strdup("unknown") ;
|
||||
} else {
|
||||
user_name = strdup(passp->pw_name) ;
|
||||
}
|
||||
|
||||
tc_blockio(&listen_dev, TC_COMM_BLOCKIO);
|
||||
listener.setBlockMode(TC_COMM_BLOCKIO);
|
||||
|
||||
if ( broadcast ) {
|
||||
if ((mcast_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
perror("vs_mcast_init socket");
|
||||
}
|
||||
|
||||
value = 1;
|
||||
if (setsockopt(mcast_socket, SOL_SOCKET, SO_REUSEADDR, (char *) &value, (socklen_t) sizeof(value)) < 0) {
|
||||
perror("setsockopt: reuseaddr");
|
||||
}
|
||||
#ifdef SO_REUSEPORT
|
||||
if (setsockopt(mcast_socket, SOL_SOCKET, SO_REUSEPORT, (char *) &value, sizeof(value)) < 0) {
|
||||
perror("setsockopt: reuseport");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set up destination address */
|
||||
memset(&mcast_addr, 0, sizeof(mcast_addr));
|
||||
mcast_addr.sin_family = AF_INET;
|
||||
mcast_addr.sin_addr.s_addr = inet_addr("239.3.14.15");
|
||||
mcast_addr.sin_port = htons((uint16_t) 9265);
|
||||
|
||||
memset(&mcast_addr_legacy, 0, sizeof(mcast_addr_legacy));
|
||||
mcast_addr_legacy.sin_family = AF_INET;
|
||||
mcast_addr_legacy.sin_addr.s_addr = inet_addr("224.3.14.15");
|
||||
mcast_addr_legacy.sin_port = htons((uint16_t) 9265);
|
||||
initializeMulticast();
|
||||
}
|
||||
|
||||
while (1) {
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(listen_dev.socket, &rfds);
|
||||
timeout_time.tv_sec = 2 ;
|
||||
select(listen_dev.socket + 1, &rfds, NULL, NULL, &timeout_time);
|
||||
|
||||
if (FD_ISSET(listen_dev.socket, &rfds)) {
|
||||
// Look for a new client requesting a connection
|
||||
if (listener.checkForNewConnections()) {
|
||||
// pause here during restart
|
||||
pthread_mutex_lock(&restart_pause) ;
|
||||
vst = new Trick::VariableServerThread(&listen_dev) ;
|
||||
|
||||
// Create a new thread to service this connection
|
||||
VariableServerThread * vst = new Trick::VariableServerThread(&listener) ;
|
||||
vst->copy_cpus(get_cpus()) ;
|
||||
vst->create_thread() ;
|
||||
vst->wait_for_accept() ;
|
||||
|
||||
pthread_mutex_unlock(&restart_pause) ;
|
||||
} else if ( broadcast ) {
|
||||
<<<<<<< HEAD
|
||||
snprintf(buf1 , sizeof(buf1), "%s\t%hu\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%hu\n" , listen_dev.hostname , (unsigned short)listen_dev.port ,
|
||||
user_name , (int)getpid() , command_line_args_get_default_dir() , command_line_args_get_cmdline_name() ,
|
||||
command_line_args_get_input_file() , version.c_str() , user_tag.c_str(), (unsigned short)listen_dev.port ) ;
|
||||
=======
|
||||
// Otherwise, broadcast on the multicast channel if enabled
|
||||
char buf1[1024];
|
||||
sprintf(buf1 , "%s\t%hu\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%hu\n" , listener.getHostname(), (unsigned short)listener.getPort() ,
|
||||
user_name.c_str() , (int)getpid() , command_line_args_get_default_dir() , command_line_args_get_cmdline_name() ,
|
||||
command_line_args_get_input_file() , version.c_str() , user_tag.c_str(), (unsigned short)listener.getPort() ) ;
|
||||
>>>>>>> e8ba4328 (Encapsulated listen device into ClientListener)
|
||||
|
||||
sendto(mcast_socket , buf1 , strlen(buf1) , 0 , (struct sockaddr *)&mcast_addr , (socklen_t)sizeof(mcast_addr)) ;
|
||||
sendto(mcast_socket , buf1 , strlen(buf1) , 0 , (struct sockaddr *)&mcast_addr_legacy , (socklen_t)sizeof(mcast_addr)) ;
|
||||
std::string message = buf1;
|
||||
|
||||
if (!multicast.is_initialized()) {
|
||||
// In case broadcast was turned on after this loop was entered
|
||||
initializeMulticast();
|
||||
}
|
||||
multicast.broadcast(message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,38 +180,34 @@ int Trick::VariableServerListenThread::restart() {
|
||||
|
||||
int ret ;
|
||||
|
||||
if ( user_port_requested ) {
|
||||
if ( user_requested_address ) {
|
||||
|
||||
char hname[80];
|
||||
static struct sockaddr_in s_in;
|
||||
gethostname(hname, (size_t) 80);
|
||||
// Test to see if the restart address is on this machine. If it is not, it's not an error, clear source address
|
||||
if ( strcmp( source_address.c_str(), hname )) {
|
||||
if (! inet_pton(AF_INET, source_address.c_str(), (struct in_addr *)&s_in.sin_addr.s_addr) ) {
|
||||
//printf("clearing source_address\n") ;
|
||||
source_address.clear() ;
|
||||
}
|
||||
if (!listener.validateSourceAddress(requested_source_address)) {
|
||||
requested_source_address.clear() ;
|
||||
}
|
||||
|
||||
printf("variable server restart user_port requested set %d\n", port) ;
|
||||
listener.disconnect();
|
||||
ret = listener.initialize(requested_source_address, requested_port);
|
||||
|
||||
tc_disconnect(&listen_dev) ;
|
||||
ret = tc_init_with_connection_info(&listen_dev, AF_INET, SOCK_STREAM, source_address.c_str(), port) ;
|
||||
if (ret != TC_SUCCESS) {
|
||||
message_publish(MSG_ERROR, "ERROR: Could not establish listen port %d for Variable Server. Aborting.\n", port);
|
||||
message_publish(MSG_ERROR, "ERROR: Could not establish listen port %d for Variable Server. Aborting.\n", requested_port);
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
struct sockaddr_in s_in;
|
||||
int s_in_size = sizeof(s_in) ;
|
||||
getsockname( listen_dev.socket , (struct sockaddr *)&s_in, (socklen_t *)&s_in_size) ;
|
||||
printf("restart variable server message port = %d\n" , ntohs(s_in.sin_port)) ;
|
||||
port = listen_dev.port = ntohs(s_in.sin_port);
|
||||
listener.checkSocket();
|
||||
}
|
||||
|
||||
initializeMulticast();
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
void Trick::VariableServerListenThread::initializeMulticast() {
|
||||
multicast.initialize();
|
||||
multicast.addAddress("239.3.14.15", 9265);
|
||||
multicast.addAddress("224.3.14.15", 9265);
|
||||
}
|
||||
|
||||
void Trick::VariableServerListenThread::pause_listening() {
|
||||
pthread_mutex_lock(&restart_pause) ;
|
||||
}
|
||||
@ -245,9 +218,9 @@ void Trick::VariableServerListenThread::restart_listening() {
|
||||
|
||||
void Trick::VariableServerListenThread::dump( std::ostream & oss ) {
|
||||
oss << "Trick::VariableServerListenThread (" << name << ")" << std::endl ;
|
||||
oss << " source_address = " << source_address << std::endl ;
|
||||
oss << " port = " << port << std::endl ;
|
||||
oss << " user_port_requested = " << user_port_requested << std::endl ;
|
||||
oss << " source_address = " << listener.getHostname() << std::endl ;
|
||||
oss << " port = " << listener.getPort() << std::endl ;
|
||||
oss << " user_requested_address = " << user_requested_address << std::endl ;
|
||||
oss << " user_tag = " << user_tag << std::endl ;
|
||||
oss << " broadcast = " << broadcast << std::endl ;
|
||||
Trick::ThreadBase::dump(oss) ;
|
||||
|
@ -0,0 +1,139 @@
|
||||
#include "trick/VariableServerSession.hh"
|
||||
#include "trick/TrickConstant.hh"
|
||||
#include "trick/exec_proto.h"
|
||||
#include "trick/message_proto.h"
|
||||
#include "trick/input_processor_proto.h"
|
||||
#include "trick/realtimesync_proto.h"
|
||||
|
||||
|
||||
Trick::VariableServerSession::VariableServerSession(ClientConnection * conn) {
|
||||
debug = 0;
|
||||
enabled = true ;
|
||||
log = false ;
|
||||
copy_mode = VS_COPY_ASYNC ;
|
||||
write_mode = VS_WRITE_ASYNC ;
|
||||
frame_multiple = 1 ;
|
||||
frame_offset = 0 ;
|
||||
freeze_frame_multiple = 1 ;
|
||||
freeze_frame_offset = 0 ;
|
||||
update_rate = 0.1 ;
|
||||
cycle_tics = (long long)(update_rate * exec_get_time_tic_value()) ;
|
||||
if (cycle_tics == 0) {
|
||||
cycle_tics = 1;
|
||||
}
|
||||
|
||||
next_tics = TRICK_MAX_LONG_LONG ;
|
||||
freeze_next_tics = TRICK_MAX_LONG_LONG ;
|
||||
// multicast = false;
|
||||
connection = conn;
|
||||
byteswap = false ;
|
||||
validate_address = false ;
|
||||
send_stdio = false ;
|
||||
|
||||
binary_data = false;
|
||||
byteswap = false;
|
||||
binary_data_nonames = false;
|
||||
packets_copied = 0 ;
|
||||
|
||||
exit_cmd = false;
|
||||
pause_cmd = false;
|
||||
|
||||
|
||||
// incoming_msg = (char *) calloc(MAX_CMD_LEN, 1);
|
||||
// stripped_msg = (char *) calloc(MAX_CMD_LEN, 1);
|
||||
|
||||
|
||||
pthread_mutex_init(©_mutex, NULL);
|
||||
}
|
||||
|
||||
Trick::VariableServerSession::~VariableServerSession() {
|
||||
// free (incoming_msg);
|
||||
// free (stripped_msg);
|
||||
}
|
||||
|
||||
// Command to turn on log to varserver_log file
|
||||
int Trick::VariableServerSession::set_log_on() {
|
||||
log = true;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
// Command to turn off log to varserver_log file
|
||||
int Trick::VariableServerSession::set_log_off() {
|
||||
log = false;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
void Trick::VariableServerSession::disconnect_references() {
|
||||
for (VariableReference * variable : session_variables) {
|
||||
variable->tagAsInvalid();
|
||||
}
|
||||
}
|
||||
|
||||
long long Trick::VariableServerSession::get_next_tics() const {
|
||||
if ( ! enabled ) {
|
||||
return TRICK_MAX_LONG_LONG ;
|
||||
}
|
||||
return next_tics ;
|
||||
}
|
||||
|
||||
long long Trick::VariableServerSession::get_freeze_next_tics() const {
|
||||
if ( ! enabled ) {
|
||||
return TRICK_MAX_LONG_LONG ;
|
||||
}
|
||||
return freeze_next_tics ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::handleMessage() {
|
||||
|
||||
std::string received_message = connection->read(ClientConnection::MAX_CMD_LEN);
|
||||
if (received_message.size() > 0) {
|
||||
ip_parse(received_message.c_str()); /* returns 0 if no parsing error */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Trick::VariableReference * Trick::VariableServerSession::find_session_variable(std::string name) const {
|
||||
for (VariableReference * ref : session_variables) {
|
||||
// Look for matching name
|
||||
if (name.compare(ref->getName()) == 0) {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
double Trick::VariableServerSession::get_update_rate() const {
|
||||
return update_rate;
|
||||
}
|
||||
|
||||
VS_WRITE_MODE Trick::VariableServerSession::get_write_mode () const {
|
||||
return write_mode;
|
||||
}
|
||||
|
||||
VS_COPY_MODE Trick::VariableServerSession::get_copy_mode () const {
|
||||
return copy_mode;
|
||||
}
|
||||
|
||||
std::ostream& Trick::operator<< (std::ostream& s, const Trick::VariableServerSession& session) {
|
||||
if (session.binary_data) {
|
||||
s << " \"format\":\"BINARY\",\n";
|
||||
} else {
|
||||
s << " \"format\":\"ASCII\",\n";
|
||||
}
|
||||
s << " \"update_rate\":" << session.get_update_rate() << ",\n";
|
||||
|
||||
s << " \"variables\":[\n";
|
||||
|
||||
int n_vars = (int)session.session_variables.size();
|
||||
for (int i=0 ; i<n_vars ; i++) {
|
||||
s << *(session.session_variables[i]);
|
||||
if ((n_vars-i)>1) {
|
||||
s << "," ;
|
||||
}
|
||||
s << "\n";
|
||||
}
|
||||
s << " ]\n";
|
||||
|
||||
return s;
|
||||
}
|
@ -0,0 +1,401 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <udunits2.h>
|
||||
#include "trick/VariableServerSession.hh"
|
||||
#include "trick/variable_server_message_types.h"
|
||||
#include "trick/memorymanager_c_intf.h"
|
||||
// #include "trick/tc_proto.h"
|
||||
#include "trick/exec_proto.h"
|
||||
#include "trick/command_line_protos.h"
|
||||
#include "trick/message_proto.h"
|
||||
#include "trick/message_type.h"
|
||||
#include "trick/TrickConstant.hh"
|
||||
#include "trick/sie_c_intf.h"
|
||||
#include "trick/UdUnits.hh"
|
||||
#include "trick/map_trick_units_to_udunits.hh"
|
||||
|
||||
|
||||
int Trick::VariableServerSession::var_add(std::string in_name) {
|
||||
VariableReference * new_var;
|
||||
if (in_name == "time") {
|
||||
new_var = new VariableReference(in_name, &time);
|
||||
} else {
|
||||
new_var = new VariableReference(in_name);
|
||||
}
|
||||
|
||||
session_variables.push_back(new_var) ;
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_add(std::string var_name, std::string units_name) {
|
||||
var_add(var_name) ;
|
||||
var_units(var_name, units_name) ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
// Helper function for var_send_once
|
||||
std::vector<std::string> split (const std::string& str, const char delim) {
|
||||
std::stringstream ss(str);
|
||||
std::string s;
|
||||
std::vector<std::string> ret;
|
||||
while (std::getline(ss, s, delim)) {
|
||||
ret.push_back(s);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_send_once(std::string in_name, int num_vars) {
|
||||
std::vector<std::string> var_names = split(in_name, ',');
|
||||
|
||||
if (var_names.size() != num_vars) {
|
||||
message_publish(MSG_ERROR, "Number of variables sent to var_send_once (%d) does not match num_vars (%d).\n", var_names.size(), num_vars);
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<VariableReference *> given_vars;
|
||||
for (auto& varName : var_names) {
|
||||
VariableReference * new_var;
|
||||
if (varName == "time") {
|
||||
new_var = new VariableReference(varName, &time);
|
||||
} else {
|
||||
new_var = new VariableReference(varName);
|
||||
}
|
||||
given_vars.push_back(new_var);
|
||||
}
|
||||
copy_sim_data(given_vars, false);
|
||||
write_data(given_vars, VS_SEND_ONCE);
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
|
||||
int Trick::VariableServerSession::var_remove(std::string in_name) {
|
||||
|
||||
for (unsigned int ii = 0 ; ii < session_variables.size() ; ii++ ) {
|
||||
std::string var_name = session_variables[ii]->getName();
|
||||
if ( ! var_name.compare(in_name) ) {
|
||||
delete session_variables[ii];
|
||||
session_variables.erase(session_variables.begin() + ii) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
return(0) ;
|
||||
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_units(std::string var_name, std::string units_name) {
|
||||
VariableReference * variable = find_session_variable(var_name);
|
||||
|
||||
if (variable == NULL) {
|
||||
// TODO: ERROR LOGGER HERE
|
||||
return -1;
|
||||
}
|
||||
|
||||
return variable->setRequestedUnits(units_name);
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_exists(std::string in_name) {
|
||||
char buf1[5] ;
|
||||
bool error = false ;
|
||||
|
||||
unsigned int msg_type ;
|
||||
REF2* var_ref = ref_attributes(in_name.c_str());
|
||||
|
||||
if ( var_ref == (REF2*)NULL ) {
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (binary_data) {
|
||||
/* send binary 1 or 0 */
|
||||
msg_type = VS_VAR_EXISTS ;
|
||||
memcpy(buf1, &msg_type , sizeof(msg_type)) ;
|
||||
|
||||
buf1[4] = (error==false);
|
||||
|
||||
if (debug >= 2) {
|
||||
// message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending 1 binary byte\n", &connection, connection.client_tag);
|
||||
}
|
||||
|
||||
connection->write(buf1, 5);
|
||||
} else {
|
||||
/* send ascii "1" or "0" */
|
||||
sprintf(buf1, "%d\t%d\n", VS_VAR_EXISTS, (error==false));
|
||||
if (debug >= 2) {
|
||||
// message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending:\n%s\n", &connection, connection.client_tag, buf1) ;
|
||||
}
|
||||
std::string write_string(buf1);
|
||||
if (write_string.length() != strlen(buf1)) {
|
||||
std::cout << "PROBLEM WITH STRING LENGTH: VAR_EXISTS ASCII" << std::endl;
|
||||
}
|
||||
connection->write(write_string);
|
||||
}
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_clear() {
|
||||
|
||||
while( !session_variables.empty() ) {
|
||||
delete session_variables.back();
|
||||
session_variables.pop_back();
|
||||
}
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_send() {
|
||||
copy_sim_data();
|
||||
write_data();
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_cycle(double in_rate) {
|
||||
update_rate = in_rate ;
|
||||
cycle_tics = (long long)(update_rate * exec_get_time_tic_value()) ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
bool Trick::VariableServerSession::get_pause() {
|
||||
return pause_cmd ;
|
||||
}
|
||||
|
||||
void Trick::VariableServerSession::set_pause( bool on_off) {
|
||||
pause_cmd = on_off ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_exit() {
|
||||
exit_cmd = true ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_validate_address(bool on_off) {
|
||||
validate_address = on_off ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_debug(int level) {
|
||||
debug = level ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_ascii() {
|
||||
binary_data = 0 ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_binary() {
|
||||
binary_data = 1 ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_binary_nonames() {
|
||||
binary_data = 1 ;
|
||||
binary_data_nonames = 1 ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_set_copy_mode(int mode) {
|
||||
if ( mode >= VS_COPY_ASYNC and mode <= VS_COPY_TOP_OF_FRAME ) {
|
||||
copy_mode = (VS_COPY_MODE)mode ;
|
||||
if ( copy_mode == VS_COPY_SCHEDULED ) {
|
||||
long long sim_time_tics ;
|
||||
sim_time_tics = exec_get_time_tics() ;
|
||||
// round the next call time to a multiple of the cycle
|
||||
sim_time_tics -= sim_time_tics % cycle_tics ;
|
||||
next_tics = sim_time_tics + cycle_tics ;
|
||||
|
||||
sim_time_tics = exec_get_freeze_time_tics() ;
|
||||
// round the next call time to a multiple of the cycle
|
||||
sim_time_tics -= sim_time_tics % cycle_tics ;
|
||||
freeze_next_tics = sim_time_tics + cycle_tics ;
|
||||
|
||||
} else {
|
||||
next_tics = TRICK_MAX_LONG_LONG ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_set_write_mode(int mode) {
|
||||
if ( mode >= VS_WRITE_ASYNC and mode <= VS_WRITE_WHEN_COPIED ) {
|
||||
write_mode = (VS_WRITE_MODE)mode ;
|
||||
return 0 ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_sync(int mode) {
|
||||
|
||||
switch (mode) {
|
||||
case 1:
|
||||
var_set_copy_mode(VS_COPY_SCHEDULED) ;
|
||||
var_set_write_mode(VS_WRITE_ASYNC) ;
|
||||
break ;
|
||||
case 2:
|
||||
var_set_copy_mode(VS_COPY_SCHEDULED) ;
|
||||
var_set_write_mode(VS_WRITE_WHEN_COPIED) ;
|
||||
break ;
|
||||
case 0:
|
||||
default:
|
||||
var_set_copy_mode(VS_COPY_ASYNC) ;
|
||||
var_set_write_mode(VS_WRITE_ASYNC) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_set_frame_multiple(unsigned int mult) {
|
||||
frame_multiple = mult ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_set_frame_offset(unsigned int offset) {
|
||||
frame_offset = offset ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_set_freeze_frame_multiple(unsigned int mult) {
|
||||
freeze_frame_multiple = mult ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_set_freeze_frame_offset(unsigned int offset) {
|
||||
freeze_frame_offset = offset ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::var_byteswap(bool on_off) {
|
||||
byteswap = on_off ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
bool Trick::VariableServerSession::get_send_stdio() {
|
||||
return send_stdio ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::set_send_stdio(bool on_off) {
|
||||
send_stdio = on_off ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::send_list_size() {
|
||||
|
||||
unsigned int msg_type = VS_LIST_SIZE;
|
||||
int var_count = session_variables.size();
|
||||
|
||||
// send number of variables
|
||||
if (binary_data) {
|
||||
// send in the binary message header format:
|
||||
// <message_indicator><message_size><number_of_variables>
|
||||
char buf1[12] ;
|
||||
|
||||
unsigned int msg_type = VS_LIST_SIZE;
|
||||
memcpy(buf1, &msg_type , sizeof(msg_type)) ;
|
||||
|
||||
memset(&(buf1[4]), 0, sizeof(int)); // message size = 0
|
||||
memcpy(&(buf1[8]), &var_count, sizeof(var_count));
|
||||
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d event variables\n", connection, connection->get_client_tag().c_str(), var_count);
|
||||
}
|
||||
|
||||
connection->write(buf1, sizeof (buf1));
|
||||
} else {
|
||||
std::stringstream write_string;
|
||||
write_string << VS_LIST_SIZE << "\t" << var_count << "\n";
|
||||
// ascii
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending number of event variables:\n%s\n", connection, connection->get_client_tag().c_str(), write_string.str().c_str()) ;
|
||||
}
|
||||
|
||||
connection->write(write_string.str());
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::transmit_file(std::string sie_file) {
|
||||
const unsigned int packet_size = 4095 ;
|
||||
FILE * fp ;
|
||||
unsigned int file_size ;
|
||||
unsigned int current_size = 0 ;
|
||||
unsigned int bytes_read ;
|
||||
char buffer[packet_size+1] ;
|
||||
int ret ;
|
||||
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG,"%p tag=<%s> var_server opening %s.\n", connection, connection->get_client_tag().c_str(), sie_file.c_str()) ;
|
||||
}
|
||||
|
||||
if ((fp = fopen(sie_file.c_str() , "r")) == NULL ) {
|
||||
message_publish(MSG_ERROR,"Variable Server Error: Cannot open %s.\n", sie_file.c_str()) ;
|
||||
sprintf(buffer, "%d\t-1\n", VS_SIE_RESOURCE) ;
|
||||
std::string message(buffer);
|
||||
connection->write(message);
|
||||
return(-1) ;
|
||||
}
|
||||
|
||||
fseek(fp , 0L, SEEK_END) ;
|
||||
file_size = ftell(fp) ;
|
||||
|
||||
sprintf(buffer, "%d\t%u\n\0" , VS_SIE_RESOURCE, file_size) ;
|
||||
std::string message(buffer);
|
||||
connection->write(message);
|
||||
rewind(fp) ;
|
||||
|
||||
// Switch to blocking writes since this could be a large transfer.
|
||||
if (connection->setBlockMode(TC_COMM_BLOCKIO)) {
|
||||
message_publish(MSG_DEBUG,"Variable Server Error: Failed to set TCDevice to TC_COMM_BLOCKIO.\n");
|
||||
}
|
||||
|
||||
while ( current_size < file_size ) {
|
||||
bytes_read = fread(buffer , 1 , packet_size , fp) ;
|
||||
message = std::string(buffer);
|
||||
message.resize(bytes_read);
|
||||
ret = connection->write(message);
|
||||
if (ret != (int)bytes_read) {
|
||||
message_publish(MSG_ERROR,"Variable Server Error: Failed to send SIE file. Bytes read: %d Bytes sent: %d\n", bytes_read, ret) ;
|
||||
return(-1);
|
||||
}
|
||||
current_size += bytes_read ;
|
||||
}
|
||||
|
||||
// Switch back to non-blocking writes.
|
||||
if (connection->setBlockMode(TC_COMM_NOBLOCKIO)) {
|
||||
message_publish(MSG_ERROR,"Variable Server Error: Failed to set TCDevice to TC_COMM_NOBLOCKIO.\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::send_file(std::string file_name) {
|
||||
return transmit_file(file_name) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::send_sie_resource() {
|
||||
sie_append_runtime_objs() ;
|
||||
return transmit_file(std::string(command_line_args_get_default_dir()) + "/S_sie.resource") ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::send_sie_class() {
|
||||
sie_class_attr_map_print_xml() ;
|
||||
return transmit_file(std::string(command_line_args_get_default_dir()) + "/" + "S_sie_class.xml") ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::send_sie_enum() {
|
||||
sie_enum_attr_map_print_xml() ;
|
||||
return transmit_file(std::string(command_line_args_get_default_dir()) + "/" + "S_sie_enum.xml") ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::send_sie_top_level_objects() {
|
||||
sie_top_level_objects_print_xml() ;
|
||||
return transmit_file(std::string(command_line_args_get_default_dir()) + "/" + "S_sie_top_level_objects.xml") ;
|
||||
}
|
@ -2,12 +2,14 @@
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include "trick/VariableServer.hh"
|
||||
#include "trick/VariableServerSession.hh"
|
||||
#include "trick/variable_server_sync_types.h"
|
||||
#include "trick/exec_proto.h"
|
||||
#include "trick/realtimesync_proto.h"
|
||||
|
||||
int Trick::VariableServerThread::copy_data_freeze() {
|
||||
// These methods should be called from main thread jobs
|
||||
|
||||
int Trick::VariableServerSession::copy_data_freeze() {
|
||||
|
||||
int ret = 0 ;
|
||||
long long curr_frame = exec_get_freeze_frame_count() ;
|
||||
@ -28,7 +30,7 @@ int Trick::VariableServerThread::copy_data_freeze() {
|
||||
return ret ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::copy_data_freeze_scheduled(long long curr_tics) {
|
||||
int Trick::VariableServerSession::copy_data_freeze_scheduled(long long curr_tics) {
|
||||
|
||||
int ret = 0 ;
|
||||
|
||||
@ -47,7 +49,7 @@ int Trick::VariableServerThread::copy_data_freeze_scheduled(long long curr_tics)
|
||||
return ret ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::copy_data_scheduled(long long curr_tics) {
|
||||
int Trick::VariableServerSession::copy_data_scheduled(long long curr_tics) {
|
||||
|
||||
int ret = 0 ;
|
||||
|
||||
@ -66,7 +68,7 @@ int Trick::VariableServerThread::copy_data_scheduled(long long curr_tics) {
|
||||
return ret ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::copy_data_top() {
|
||||
int Trick::VariableServerSession::copy_data_top() {
|
||||
|
||||
int ret = 0 ;
|
||||
long long curr_frame = exec_get_frame_count() ;
|
@ -0,0 +1,35 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include "trick/VariableServerSession.hh"
|
||||
#include "trick/memorymanager_c_intf.h"
|
||||
#include "trick/exec_proto.h"
|
||||
|
||||
|
||||
// These actually do the copying
|
||||
|
||||
int Trick::VariableServerSession::copy_sim_data() {
|
||||
return copy_sim_data(session_variables, true);
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::copy_sim_data(std::vector<VariableReference *>& given_vars, bool cyclical) {
|
||||
|
||||
if (given_vars.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( pthread_mutex_trylock(©_mutex) == 0 ) {
|
||||
// Get the simulation time we start this copy
|
||||
time = (double)exec_get_time_tics() / exec_get_time_tic_value() ;
|
||||
|
||||
|
||||
for (auto curr_var : given_vars ) {
|
||||
curr_var->stageValue();
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(©_mutex) ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -2,11 +2,11 @@
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include "trick/VariableServerThread.hh"
|
||||
#include "trick/VariableServerSession.hh"
|
||||
#include "trick/TrickConstant.hh"
|
||||
|
||||
int Trick::VariableServerThread::freeze_init() {
|
||||
if ( enabled and copy_mode == VS_COPY_SCHEDULED) {
|
||||
int Trick::VariableServerSession::freeze_init() {
|
||||
if ( enabled && copy_mode == VS_COPY_SCHEDULED) {
|
||||
freeze_next_tics = cycle_tics ;
|
||||
} else {
|
||||
freeze_next_tics = TRICK_MAX_LONG_LONG ;
|
@ -0,0 +1,188 @@
|
||||
/*
|
||||
PURPOSE: (Allows clients to get and set Trick parameters)
|
||||
PROGRAMMERS: (((Alex Lin) (NASA) (8/06) (--)))
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <pthread.h>
|
||||
#include <iomanip> // for setprecision
|
||||
#include "trick/VariableServerSession.hh"
|
||||
#include "trick/parameter_types.h"
|
||||
#include "trick/bitfield_proto.h"
|
||||
#include "trick/trick_byteswap.h"
|
||||
#include "trick/tc_proto.h"
|
||||
#include "trick/message_proto.h"
|
||||
#include "trick/message_type.h"
|
||||
|
||||
|
||||
extern "C" {
|
||||
void *trick_bswap_buffer(void *out, void *in, ATTRIBUTES * attr, int tofrom) ;
|
||||
}
|
||||
|
||||
#define MAX_MSG_LEN 8192
|
||||
|
||||
|
||||
int Trick::VariableServerSession::write_binary_data(const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type) {
|
||||
// Some constants to make size calculations more readable
|
||||
static const int header_size = 12;
|
||||
static const int sizeof_size = 4;
|
||||
static const int type_size = 4;
|
||||
|
||||
std::vector<std::pair<int,int>> message_sizes_and_num_vars;
|
||||
|
||||
// Calculate how many messages and how many vars in each
|
||||
int total_size = header_size;
|
||||
int num_vars = 0;
|
||||
for (int i = 0; i < given_vars.size(); i++) {
|
||||
const VariableReference * var = given_vars[i];
|
||||
int total_var_size = 0;
|
||||
if (!binary_data_nonames) {
|
||||
total_var_size += sizeof_size;
|
||||
total_var_size += strlen(var->getName());
|
||||
}
|
||||
|
||||
total_var_size += type_size;
|
||||
total_var_size += sizeof_size;
|
||||
total_var_size += var->getSizeBinary();
|
||||
|
||||
// If this variable won't fit in the current message, truncate the message and plan to put this var in a new one
|
||||
if (total_size + total_var_size > MAX_MSG_LEN) {
|
||||
message_sizes_and_num_vars.push_back(std::pair<int,int>(total_size, num_vars));
|
||||
total_size = header_size;
|
||||
num_vars = 0;
|
||||
}
|
||||
total_size += total_var_size;
|
||||
num_vars++;
|
||||
}
|
||||
|
||||
message_sizes_and_num_vars.push_back(std::pair<int,int>(total_size, num_vars));
|
||||
|
||||
// Now write out all of these messages
|
||||
int var_index = 0;
|
||||
for (std::pair<int,int> message_info : message_sizes_and_num_vars) {
|
||||
int curr_message_size = message_info.first;
|
||||
int curr_message_num_vars = message_info.second;
|
||||
|
||||
std::stringstream stream;
|
||||
|
||||
int written_message_type = message_type;
|
||||
int written_header_size = curr_message_size - 4;
|
||||
int written_num_vars = curr_message_num_vars;
|
||||
|
||||
if (byteswap) {
|
||||
written_message_type = trick_byteswap_int(written_message_type);
|
||||
written_header_size = trick_byteswap_int(written_header_size);
|
||||
written_num_vars = trick_byteswap_int(written_num_vars);
|
||||
}
|
||||
|
||||
// Write the header first
|
||||
stream.write((char *)(&written_message_type), sizeof(int));
|
||||
stream.write((char *)(&written_header_size), sizeof(int));
|
||||
stream.write ((char *)(&written_num_vars), sizeof(int));
|
||||
|
||||
// Write variables next
|
||||
for (int i = var_index; i < var_index + curr_message_num_vars; i++) {
|
||||
VariableReference * var = given_vars[i];
|
||||
if (!binary_data_nonames) {
|
||||
var->writeNameBinary(stream, byteswap);
|
||||
}
|
||||
var->writeTypeBinary(stream, byteswap);
|
||||
var->writeSizeBinary(stream, byteswap);
|
||||
var->writeValueBinary(stream, byteswap);
|
||||
}
|
||||
var_index += curr_message_num_vars;
|
||||
|
||||
char write_buf[MAX_MSG_LEN];
|
||||
stream.read(write_buf, curr_message_size);
|
||||
connection->write(write_buf, curr_message_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::write_ascii_data(const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type ) {
|
||||
// Load message type first
|
||||
std::stringstream message_stream;
|
||||
message_stream << (int)message_type;
|
||||
|
||||
int message_size = message_stream.str().size();
|
||||
|
||||
// Load each variable
|
||||
for (int i = 0; i < given_vars.size(); i++) {
|
||||
message_stream << "\t";
|
||||
|
||||
std::stringstream var_stream;
|
||||
if (given_vars[i]->writeValueAscii(var_stream) == -1) {
|
||||
// If one of the values isn't ready, we need to abort the write
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string var_string = var_stream.str();
|
||||
int var_size = var_string.size();
|
||||
|
||||
// Check that there's enough room for the next variable, tab character, and possible newline
|
||||
if (message_size + var_size + 2 > MAX_MSG_LEN) {
|
||||
|
||||
// Write out an incomplete message
|
||||
std::string message = message_stream.str();
|
||||
int result = connection->write(message);
|
||||
if (result < 0)
|
||||
return result;
|
||||
// Clear out the message stream
|
||||
message_stream.str("");
|
||||
message_size = 0;
|
||||
}
|
||||
|
||||
// Concatenate
|
||||
message_stream << var_string;
|
||||
message_size += var_size + 1;
|
||||
}
|
||||
|
||||
|
||||
// End with newline
|
||||
message_stream << '\n';
|
||||
std::string message = message_stream.str();
|
||||
int result = connection->write(message);
|
||||
return result;
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::write_data() {
|
||||
return write_data(session_variables, VS_VAR_LIST);
|
||||
}
|
||||
|
||||
int Trick::VariableServerSession::write_data(std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type) {
|
||||
// do not send anything when there are no variables!
|
||||
if ( given_vars.size() == 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
|
||||
if ( pthread_mutex_trylock(©_mutex) == 0 ) {
|
||||
// Check that all of the variables are staged
|
||||
for (VariableReference * variable : given_vars ) {
|
||||
if (!variable->isStaged()) {
|
||||
pthread_mutex_unlock(©_mutex) ;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Swap buffer_in and buffer_out for each vars[ii].
|
||||
for (VariableReference * variable : given_vars ) {
|
||||
variable->prepareForWrite();
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(©_mutex) ;
|
||||
|
||||
// Send out in correct format
|
||||
if (binary_data) {
|
||||
result = write_binary_data(given_vars, message_type );
|
||||
} else {
|
||||
// ascii mode
|
||||
result = write_ascii_data(given_vars, message_type );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "trick/VariableServerSession.hh"
|
||||
#include "trick/variable_server_message_types.h"
|
||||
#include "trick/tc_proto.h"
|
||||
|
||||
int Trick::VariableServerSession::write_stdio(int stream, std::string text) {
|
||||
|
||||
std::stringstream outstream;
|
||||
|
||||
outstream << VS_STDIO << " " << stream << " " << (int)text.length() << "\n";
|
||||
outstream << text;
|
||||
|
||||
connection->write(outstream.str());
|
||||
|
||||
return 0 ;
|
||||
}
|
@ -7,73 +7,32 @@
|
||||
|
||||
Trick::VariableServer * Trick::VariableServerThread::vs = NULL ;
|
||||
|
||||
Trick::VariableServerThread::VariableServerThread(TCDevice * in_listen_dev) :
|
||||
Trick::SysThread("VarServer", true) ,
|
||||
listen_dev(in_listen_dev) {
|
||||
Trick::VariableServerThread::VariableServerThread(ClientListener * in_listen_dev) :
|
||||
Trick::SysThread("VarServer") , debug(0),
|
||||
listener(in_listen_dev), session(NULL) {
|
||||
|
||||
debug = 0 ;
|
||||
enabled = true ;
|
||||
log = false ;
|
||||
connection_accepted = false ;
|
||||
conn_type = TCP ;
|
||||
copy_mode = VS_COPY_ASYNC ;
|
||||
write_mode = VS_WRITE_ASYNC ;
|
||||
frame_multiple = 1 ;
|
||||
frame_offset = 0 ;
|
||||
freeze_frame_multiple = 1 ;
|
||||
freeze_frame_offset = 0 ;
|
||||
binary_data = false;
|
||||
multicast = false;
|
||||
byteswap = false ;
|
||||
connection_status = CONNECTION_PENDING ;
|
||||
|
||||
pause_cmd = false ;
|
||||
exit_cmd = false ;
|
||||
connection.initialize();
|
||||
|
||||
validate_address = false ;
|
||||
send_stdio = false ;
|
||||
pthread_mutex_init(&connection_status_mutex, NULL);
|
||||
pthread_cond_init(&connection_status_cv, NULL);
|
||||
|
||||
update_rate = 0.1 ;
|
||||
cycle_tics = (long long)(update_rate * exec_get_time_tic_value()) ;
|
||||
|
||||
next_tics = TRICK_MAX_LONG_LONG ;
|
||||
freeze_next_tics = TRICK_MAX_LONG_LONG ;
|
||||
|
||||
connection.disabled = TC_COMM_FALSE ;
|
||||
connection.disable_handshaking = TC_COMM_TRUE ;
|
||||
connection.blockio_limit = 0.0 ;
|
||||
connection.blockio_type = TC_COMM_BLOCKIO ;
|
||||
connection.client_id = 0 ;
|
||||
strcpy(connection.client_tag, "") ;
|
||||
connection.error_handler = (TrickErrorHndlr *) calloc(1, (int)sizeof(TrickErrorHndlr));
|
||||
connection.error_handler->report_level = TRICK_ERROR_CAUTION;
|
||||
|
||||
pthread_mutex_init(©_mutex, NULL);
|
||||
pthread_mutex_init(&restart_pause, NULL);
|
||||
|
||||
var_data_staged = false;
|
||||
packets_copied = 0 ;
|
||||
|
||||
incoming_msg = (char *) calloc(1, MAX_CMD_LEN);
|
||||
stripped_msg = (char *) calloc(1, MAX_CMD_LEN);
|
||||
|
||||
}
|
||||
|
||||
Trick::VariableServerThread::~VariableServerThread() {
|
||||
free( incoming_msg ) ;
|
||||
free( stripped_msg ) ;
|
||||
}
|
||||
|
||||
Trick::VariableServerThread::~VariableServerThread() {}
|
||||
|
||||
std::ostream& Trick::operator<< (std::ostream& s, Trick::VariableServerThread& vst) {
|
||||
|
||||
// Write a JSON representation of a Trick::VariableServerThread to an ostream.
|
||||
struct sockaddr_in otherside;
|
||||
socklen_t len = (socklen_t)sizeof(otherside);
|
||||
|
||||
s << " \"connection\":{\n";
|
||||
s << " \"client_tag\":\"" << vst.connection.client_tag << "\",\n";
|
||||
s << " \"client_tag\":\"" << vst.connection.get_client_tag() << "\",\n";
|
||||
|
||||
int err = getpeername(vst.connection.socket, (struct sockaddr*)&otherside, &len);
|
||||
int err = getpeername(vst.connection.get_socket(), (struct sockaddr*)&otherside, &len);
|
||||
|
||||
if (err == 0) {
|
||||
s << " \"client_IP_address\":\"" << inet_ntoa(otherside.sin_addr) << "\",\n";
|
||||
@ -83,24 +42,8 @@ std::ostream& Trick::operator<< (std::ostream& s, Trick::VariableServerThread& v
|
||||
s << " \"client_port\":\"unknown\",";
|
||||
}
|
||||
|
||||
if (vst.binary_data) {
|
||||
s << " \"format\":\"BINARY\",\n";
|
||||
} else {
|
||||
s << " \"format\":\"ASCII\",\n";
|
||||
}
|
||||
s << " \"update_rate\":" << vst.update_rate << ",\n";
|
||||
s << *(vst.session);
|
||||
|
||||
s << " \"variables\":[\n";
|
||||
|
||||
int n_vars = (int)vst.vars.size();
|
||||
for (int i=0 ; i<n_vars ; i++) {
|
||||
s << *(vst.vars[i]);
|
||||
if ((n_vars-i)>1) {
|
||||
s << "," ;
|
||||
}
|
||||
s << "\n";
|
||||
}
|
||||
s << " ]\n";
|
||||
s << " }" << std::endl;
|
||||
return s;
|
||||
}
|
||||
@ -109,38 +52,60 @@ void Trick::VariableServerThread::set_vs_ptr(Trick::VariableServer * in_vs) {
|
||||
vs = in_vs ;
|
||||
}
|
||||
|
||||
// Command to turn on log to varserver_log file
|
||||
int Trick::VariableServerThread::set_log_on() {
|
||||
log = true;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
// Command to turn off log to varserver_log file
|
||||
int Trick::VariableServerThread::set_log_off() {
|
||||
log = false;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
long long Trick::VariableServerThread::get_next_tics() {
|
||||
if ( ! enabled ) {
|
||||
return TRICK_MAX_LONG_LONG ;
|
||||
}
|
||||
return next_tics ;
|
||||
}
|
||||
|
||||
long long Trick::VariableServerThread::get_freeze_next_tics() {
|
||||
if ( ! enabled ) {
|
||||
return TRICK_MAX_LONG_LONG ;
|
||||
}
|
||||
return freeze_next_tics ;
|
||||
}
|
||||
|
||||
Trick::VariableServer * Trick::VariableServerThread::get_vs() {
|
||||
return vs ;
|
||||
}
|
||||
|
||||
TCDevice & Trick::VariableServerThread::get_connection() {
|
||||
return connection ;
|
||||
void Trick::VariableServerThread::set_client_tag(std::string tag) {
|
||||
connection.set_client_tag(tag);
|
||||
}
|
||||
|
||||
Trick::ConnectionStatus Trick::VariableServerThread::wait_for_accept() {
|
||||
|
||||
pthread_mutex_lock(&connection_status_mutex);
|
||||
while ( connection_status == CONNECTION_PENDING ) {
|
||||
pthread_cond_wait(&connection_status_cv, &connection_status_mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&connection_status_mutex);
|
||||
|
||||
return connection_status;
|
||||
}
|
||||
|
||||
// This should maybe go somewhere completely different
|
||||
// Leaving it in thread for now
|
||||
// Gets called from the main thread as a job
|
||||
void Trick::VariableServerThread::preload_checkpoint() {
|
||||
|
||||
// Stop variable server processing at the top of the processing loop.
|
||||
pthread_mutex_lock(&restart_pause);
|
||||
|
||||
// Let the thread complete any data copying it has to do
|
||||
// and then suspend data copying until the checkpoint is reloaded.
|
||||
pthread_mutex_lock(&(session->copy_mutex));
|
||||
|
||||
// Save the pause state of this thread.
|
||||
saved_pause_cmd = session->get_pause();
|
||||
|
||||
// Disallow data writing.
|
||||
session->set_pause(true);
|
||||
|
||||
// Temporarily "disconnect" the variable references from Trick Managed Memory
|
||||
// by tagging each as a "bad reference".
|
||||
session->disconnect_references();
|
||||
|
||||
|
||||
// Allow data copying to continue.
|
||||
pthread_mutex_unlock(&(session->copy_mutex));
|
||||
|
||||
}
|
||||
|
||||
// Gets called from the main thread as a job
|
||||
void Trick::VariableServerThread::restart() {
|
||||
// Set the pause state of this thread back to its "pre-checkpoint reload" state.
|
||||
session->set_pause(saved_pause_cmd) ;
|
||||
|
||||
// Restart the variable server processing.
|
||||
pthread_mutex_unlock(&restart_pause);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,516 +0,0 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <udunits2.h>
|
||||
#include "trick/VariableServer.hh"
|
||||
#include "trick/variable_server_message_types.h"
|
||||
#include "trick/memorymanager_c_intf.h"
|
||||
#include "trick/tc_proto.h"
|
||||
#include "trick/exec_proto.h"
|
||||
#include "trick/command_line_protos.h"
|
||||
#include "trick/message_proto.h"
|
||||
#include "trick/message_type.h"
|
||||
#include "trick/TrickConstant.hh"
|
||||
#include "trick/sie_c_intf.h"
|
||||
#include "trick/UdUnits.hh"
|
||||
#include "trick/map_trick_units_to_udunits.hh"
|
||||
|
||||
int Trick::VariableServerThread::bad_ref_int = 0 ;
|
||||
int Trick::VariableServerThread::do_not_resolve_bad_ref_int = 0 ;
|
||||
|
||||
REF2* Trick::VariableServerThread::make_time_ref() {
|
||||
REF2* new_ref;
|
||||
new_ref = (REF2*)calloc(1, sizeof(REF2));
|
||||
new_ref->reference = strdup("time") ;
|
||||
new_ref->units = strdup("s") ;
|
||||
new_ref->address = (char *)&time ;
|
||||
new_ref->attr = (ATTRIBUTES*)calloc(1, sizeof(ATTRIBUTES)) ;
|
||||
new_ref->attr->type = TRICK_DOUBLE ;
|
||||
new_ref->attr->units = strdup("s") ;
|
||||
new_ref->attr->size = sizeof(double) ;
|
||||
return new_ref;
|
||||
}
|
||||
|
||||
REF2* Trick::VariableServerThread::make_error_ref(std::string in_name) {
|
||||
REF2* new_ref;
|
||||
new_ref = (REF2*)calloc(1, sizeof(REF2));
|
||||
new_ref->reference = strdup(in_name.c_str()) ;
|
||||
new_ref->units = NULL ;
|
||||
new_ref->address = (char *)&bad_ref_int ;
|
||||
new_ref->attr = (ATTRIBUTES*)calloc(1, sizeof(ATTRIBUTES)) ;
|
||||
new_ref->attr->type = TRICK_NUMBER_OF_TYPES ;
|
||||
new_ref->attr->units = (char *)"--" ;
|
||||
new_ref->attr->size = sizeof(int) ;
|
||||
return new_ref;
|
||||
}
|
||||
|
||||
Trick::VariableReference* Trick::VariableServerThread::create_var_reference(std::string in_name) {
|
||||
REF2 * new_ref ;
|
||||
|
||||
// Time var is treated specially
|
||||
if ( in_name.compare("time") == 0 ) {
|
||||
new_ref = make_time_ref() ;
|
||||
} else {
|
||||
// otherwise ref_attributes takes care of the hard part
|
||||
new_ref = ref_attributes(in_name.c_str()) ;
|
||||
}
|
||||
|
||||
// Check error cases
|
||||
if ( new_ref == NULL ) {
|
||||
message_publish(MSG_ERROR, "Variable Server could not find variable %s.\n", in_name.c_str());
|
||||
new_ref = make_error_ref(in_name);
|
||||
} else if ( new_ref->attr ) {
|
||||
if ( new_ref->attr->type == TRICK_STRUCTURED ) {
|
||||
message_publish(MSG_ERROR, "Variable Server: var_add cant add \"%s\" because its a composite variable.\n", in_name.c_str());
|
||||
// Replace the REF2 object we got from ref_attributes with an error-ref.
|
||||
free(new_ref);
|
||||
new_ref = make_error_ref(in_name);
|
||||
// set the address of the data to the do_not_resolve address. We won't retry resolving the name
|
||||
new_ref->address = (char *)&do_not_resolve_bad_ref_int ;
|
||||
} else if ( new_ref->attr->type == TRICK_STL ) {
|
||||
message_publish(MSG_ERROR, "Variable Server: var_add cant add \"%s\" because its an STL variable.\n", in_name.c_str());
|
||||
// Replace the REF2 object we got from ref_attributes with an error-ref.
|
||||
free(new_ref);
|
||||
new_ref = make_error_ref(in_name);
|
||||
// set the address of the data to the do_not_resolve address. We won't retry resolving the name
|
||||
new_ref->address = (char *)&do_not_resolve_bad_ref_int ;
|
||||
}
|
||||
} else {
|
||||
message_publish(MSG_ERROR, "Variable Server: BAD MOJO - Missing ATTRIBUTES.");
|
||||
new_ref = make_error_ref(in_name);
|
||||
}
|
||||
|
||||
// Actually constructs the variable reference in the success case
|
||||
return new VariableReference(new_ref) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_add(std::string in_name) {
|
||||
VariableReference * new_var = create_var_reference(in_name);
|
||||
vars.push_back(new_var) ;
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_add(std::string var_name, std::string units_name) {
|
||||
var_add(var_name) ;
|
||||
var_units(var_name, units_name) ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
// Helper function for var_send_once
|
||||
std::vector<std::string> split (const std::string& str, const char delim) {
|
||||
std::stringstream ss(str);
|
||||
std::string s;
|
||||
std::vector<std::string> ret;
|
||||
while (std::getline(ss, s, delim)) {
|
||||
ret.push_back(s);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_send_once(std::string in_name, int num_vars) {
|
||||
std::vector<std::string> var_names = split(in_name, ',');
|
||||
|
||||
if (var_names.size() != num_vars) {
|
||||
message_publish(MSG_ERROR, "Number of variables sent to var_send_once (%d) does not match num_vars (%d).\n", var_names.size(), num_vars);
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<VariableReference *> given_vars;
|
||||
for (auto& varName : var_names) {
|
||||
given_vars.push_back(create_var_reference(varName));
|
||||
}
|
||||
copy_sim_data(given_vars, false);
|
||||
write_data(given_vars);
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
|
||||
int Trick::VariableServerThread::var_remove(std::string in_name) {
|
||||
|
||||
unsigned int ii ;
|
||||
for ( ii = 0 ; ii < vars.size() ; ii++ ) {
|
||||
std::string var_name = vars[ii]->ref->reference;
|
||||
if ( ! var_name.compare(in_name) ) {
|
||||
delete vars[ii];
|
||||
vars.erase(vars.begin() + ii) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
return(0) ;
|
||||
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_units(std::string var_name, std::string units_name) {
|
||||
for ( VariableReference* variable : vars ) {
|
||||
if ( std::string(variable->ref->reference).compare(var_name) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!units_name.compare("xx")) {
|
||||
units_name = variable->ref->attr->units;
|
||||
}
|
||||
|
||||
auto publish = [](MESSAGE_TYPE type, const std::string& message) {
|
||||
std::ostringstream oss;
|
||||
oss << "Variable Server: " << message << std::endl;
|
||||
message_publish(type, oss.str().c_str());
|
||||
};
|
||||
/* if unitless ('--') then do not convert to udunits*/
|
||||
if(units_name.compare("--")){
|
||||
std::string new_units = map_trick_units_to_udunits(units_name) ;
|
||||
if ( units_name.compare(new_units) ) {
|
||||
std::ostringstream oss;
|
||||
oss << "[" << var_name << "] old-style units converted from ["
|
||||
<< units_name << "] to [" << new_units << "]";
|
||||
publish(MSG_WARNING, oss.str());
|
||||
}
|
||||
|
||||
auto publishError = [&](const std::string& units) {
|
||||
std::ostringstream oss;
|
||||
oss << "units error for [" << var_name << "] [" << units << "]";
|
||||
publish(MSG_ERROR, oss.str());
|
||||
};
|
||||
|
||||
ut_unit * from = ut_parse(Trick::UdUnits::get_u_system(), variable->ref->attr->units, UT_ASCII) ;
|
||||
if ( !from ) {
|
||||
publishError(variable->ref->attr->units);
|
||||
ut_free(from) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
ut_unit * to = ut_parse(Trick::UdUnits::get_u_system(), new_units.c_str(), UT_ASCII) ;
|
||||
if ( !to ) {
|
||||
publishError(new_units);
|
||||
ut_free(from) ;
|
||||
ut_free(to) ;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
cv_converter * conversion_factor = ut_get_converter(from, to) ;
|
||||
ut_free(from) ;
|
||||
ut_free(to) ;
|
||||
if ( !conversion_factor ) {
|
||||
std::ostringstream oss;
|
||||
oss << "[" << var_name << "] cannot convert units from [" << variable->ref->attr->units
|
||||
<< "] to [" << new_units << "]";
|
||||
publish(MSG_ERROR, oss.str());
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
cv_free(variable->conversion_factor);
|
||||
variable->conversion_factor = conversion_factor ;
|
||||
free(variable->ref->units);
|
||||
variable->ref->units = strdup(new_units.c_str());
|
||||
}
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_exists(std::string in_name) {
|
||||
|
||||
char buf1[5] ;
|
||||
bool error = false ;
|
||||
|
||||
unsigned int msg_type ;
|
||||
REF2* var_ref = ref_attributes(in_name.c_str());
|
||||
|
||||
if ( var_ref == (REF2*)NULL ) {
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (binary_data) {
|
||||
/* send binary 1 or 0 */
|
||||
msg_type = VS_VAR_EXISTS ;
|
||||
memcpy(buf1, &msg_type , sizeof(msg_type)) ;
|
||||
|
||||
buf1[4] = (error==false);
|
||||
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending 1 binary byte\n", &connection, connection.client_tag);
|
||||
}
|
||||
tc_write(&connection, (char *) buf1, 5);
|
||||
} else {
|
||||
/* send ascii "1" or "0" */
|
||||
snprintf(buf1, sizeof(buf1), "%d\t%d\n", VS_VAR_EXISTS, (error==false));
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending:\n%s\n", &connection, connection.client_tag, buf1) ;
|
||||
}
|
||||
tc_write(&connection, (char *) buf1, strlen(buf1));
|
||||
}
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_clear() {
|
||||
while( !vars.empty() ) {
|
||||
delete vars.back();
|
||||
vars.pop_back();
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
|
||||
int Trick::VariableServerThread::var_send() {
|
||||
copy_sim_data();
|
||||
write_data();
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_cycle(double in_rate) {
|
||||
update_rate = in_rate ;
|
||||
cycle_tics = (long long)(update_rate * exec_get_time_tic_value()) ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
bool Trick::VariableServerThread::get_pause() {
|
||||
return pause_cmd ;
|
||||
}
|
||||
|
||||
void Trick::VariableServerThread::set_pause( bool on_off) {
|
||||
pause_cmd = on_off ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_exit() {
|
||||
exit_cmd = true ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_validate_address(bool on_off) {
|
||||
validate_address = on_off ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_debug(int level) {
|
||||
debug = level ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_ascii() {
|
||||
binary_data = 0 ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_binary() {
|
||||
binary_data = 1 ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_binary_nonames() {
|
||||
binary_data = 1 ;
|
||||
binary_data_nonames = 1 ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_set_copy_mode(int mode) {
|
||||
if ( mode >= VS_COPY_ASYNC and mode <= VS_COPY_TOP_OF_FRAME ) {
|
||||
copy_mode = (VS_COPY_MODE)mode ;
|
||||
if ( copy_mode == VS_COPY_SCHEDULED ) {
|
||||
long long sim_time_tics ;
|
||||
sim_time_tics = exec_get_time_tics() ;
|
||||
// round the next call time to a multiple of the cycle
|
||||
sim_time_tics -= sim_time_tics % cycle_tics ;
|
||||
next_tics = sim_time_tics + cycle_tics ;
|
||||
|
||||
sim_time_tics = exec_get_freeze_time_tics() ;
|
||||
// round the next call time to a multiple of the cycle
|
||||
sim_time_tics -= sim_time_tics % cycle_tics ;
|
||||
freeze_next_tics = sim_time_tics + cycle_tics ;
|
||||
|
||||
} else {
|
||||
next_tics = TRICK_MAX_LONG_LONG ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_set_write_mode(int mode) {
|
||||
if ( mode >= VS_WRITE_ASYNC and mode <= VS_WRITE_WHEN_COPIED ) {
|
||||
write_mode = (VS_WRITE_MODE)mode ;
|
||||
return 0 ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_sync(int mode) {
|
||||
|
||||
switch (mode) {
|
||||
case 1:
|
||||
var_set_copy_mode(VS_COPY_SCHEDULED) ;
|
||||
var_set_write_mode(VS_WRITE_ASYNC) ;
|
||||
break ;
|
||||
case 2:
|
||||
var_set_copy_mode(VS_COPY_SCHEDULED) ;
|
||||
var_set_write_mode(VS_WRITE_WHEN_COPIED) ;
|
||||
break ;
|
||||
case 0:
|
||||
default:
|
||||
var_set_copy_mode(VS_COPY_ASYNC) ;
|
||||
var_set_write_mode(VS_WRITE_ASYNC) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_set_frame_multiple(unsigned int mult) {
|
||||
frame_multiple = mult ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_set_frame_offset(unsigned int offset) {
|
||||
frame_offset = offset ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_set_freeze_frame_multiple(unsigned int mult) {
|
||||
freeze_frame_multiple = mult ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_set_freeze_frame_offset(unsigned int offset) {
|
||||
freeze_frame_offset = offset ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_byteswap(bool on_off) {
|
||||
byteswap = on_off ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
bool Trick::VariableServerThread::get_send_stdio() {
|
||||
return send_stdio ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::set_send_stdio(bool on_off) {
|
||||
send_stdio = on_off ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_signal() {
|
||||
|
||||
message_publish(MSG_ERROR,"Variable Server Error: var_signal is currently not implemented.\n") ;
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::var_multicast(bool on_off) {
|
||||
|
||||
multicast = on_off ;
|
||||
|
||||
message_publish(MSG_ERROR, "Variable Server Error: var_multicast is currently not implemented.\n") ;
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::send_list_size() {
|
||||
char buf1[12] ;
|
||||
unsigned int msg_type ;
|
||||
int var_count;
|
||||
|
||||
// send number of variables
|
||||
var_count = vars.size();
|
||||
if (binary_data) {
|
||||
// send in the binary message header format:
|
||||
// <message_indicator><message_size><number_of_variables>
|
||||
msg_type = VS_LIST_SIZE;
|
||||
memcpy(buf1, &msg_type , sizeof(msg_type)) ;
|
||||
|
||||
memset(&(buf1[4]), 0, sizeof(int)); // message size = 0
|
||||
memcpy(&(buf1[8]), &var_count, sizeof(var_count));
|
||||
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d event variables\n", &connection, connection.client_tag, var_count);
|
||||
}
|
||||
tc_write(&connection, (char *) buf1, 12);
|
||||
} else {
|
||||
// ascii
|
||||
snprintf(buf1, sizeof(buf1), "%d\t%d\n", VS_LIST_SIZE, var_count);
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending number of event variables:\n%s\n", &connection, connection.client_tag, buf1) ;
|
||||
}
|
||||
tc_write(&connection, (char *) buf1, strlen(buf1));
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::transmit_file(std::string sie_file) {
|
||||
const unsigned int packet_size = 4095 ;
|
||||
FILE * fp ;
|
||||
unsigned int file_size ;
|
||||
unsigned int current_size = 0 ;
|
||||
unsigned int bytes_read ;
|
||||
char buffer[packet_size] ;
|
||||
int ret ;
|
||||
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG,"%p tag=<%s> var_server opening %s.\n", &connection, connection.client_tag, sie_file.c_str()) ;
|
||||
}
|
||||
|
||||
if ((fp = fopen(sie_file.c_str() , "r")) == NULL ) {
|
||||
message_publish(MSG_ERROR,"Variable Server Error: Cannot open %s.\n", sie_file.c_str()) ;
|
||||
snprintf(buffer, sizeof(buffer), "%d\t-1\n", VS_SIE_RESOURCE) ;
|
||||
tc_write(&connection , buffer , strlen(buffer)) ;
|
||||
return(-1) ;
|
||||
}
|
||||
|
||||
fseek(fp , 0L, SEEK_END) ;
|
||||
file_size = ftell(fp) ;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%d\t%u\n" , VS_SIE_RESOURCE, file_size) ;
|
||||
tc_write(&connection , buffer , strlen(buffer)) ;
|
||||
rewind(fp) ;
|
||||
|
||||
// Switch to blocking writes since this could be a large transfer.
|
||||
if (tc_blockio(&connection, TC_COMM_BLOCKIO)) {
|
||||
message_publish(MSG_DEBUG,"Variable Server Error: Failed to set TCDevice to TC_COMM_BLOCKIO.\n");
|
||||
}
|
||||
|
||||
while ( current_size < file_size ) {
|
||||
bytes_read = fread(buffer , 1 , packet_size , fp) ;
|
||||
ret = tc_write(&connection , buffer , bytes_read ) ;
|
||||
if (ret != (int)bytes_read) {
|
||||
message_publish(MSG_ERROR,"Variable Server Error: Failed to send SIE file.\n", sie_file.c_str()) ;
|
||||
return(-1);
|
||||
}
|
||||
current_size += bytes_read ;
|
||||
}
|
||||
|
||||
// Switch back to non-blocking writes.
|
||||
if (tc_blockio(&connection, TC_COMM_NOBLOCKIO)) {
|
||||
message_publish(MSG_ERROR,"Variable Server Error: Failed to set TCDevice to TC_COMM_NOBLOCKIO.\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::send_file(std::string file_name) {
|
||||
return transmit_file(file_name) ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::send_sie_resource() {
|
||||
sie_append_runtime_objs() ;
|
||||
return transmit_file(std::string(sie_get_runtime_sie_dir()) + "/S_sie.resource") ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::send_sie_class() {
|
||||
sie_class_attr_map_print_xml() ;
|
||||
return transmit_file(std::string(sie_get_runtime_sie_dir()) + "/" + "S_sie_class.xml") ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::send_sie_enum() {
|
||||
sie_enum_attr_map_print_xml() ;
|
||||
return transmit_file(std::string(sie_get_runtime_sie_dir()) + "/" + "S_sie_enum.xml") ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::send_sie_top_level_objects() {
|
||||
sie_top_level_objects_print_xml() ;
|
||||
return transmit_file(std::string(sie_get_runtime_sie_dir()) + "/" + "S_sie_top_level_objects.xml") ;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
|
||||
#include "trick/VariableServer.hh"
|
||||
#include "trick/release.h"
|
||||
|
||||
void Trick::VariableServerThread::wait_for_accept() {
|
||||
while ( connection_accepted == false ) {
|
||||
RELEASE() ;
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include "trick/VariableServer.hh"
|
||||
#include "trick/memorymanager_c_intf.h"
|
||||
#include "trick/exec_proto.h"
|
||||
|
||||
int Trick::VariableServerThread::copy_sim_data() {
|
||||
return copy_sim_data(vars, true);
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::copy_sim_data(std::vector<VariableReference *> given_vars, bool cyclical) {
|
||||
|
||||
if (given_vars.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( pthread_mutex_trylock(©_mutex) == 0 ) {
|
||||
|
||||
// Get the simulation time we start this copy
|
||||
if (cyclical) {
|
||||
time = (double)exec_get_time_tics() / exec_get_time_tic_value() ;
|
||||
}
|
||||
|
||||
for (auto curr_var : given_vars ) {
|
||||
|
||||
if (curr_var->ref->address == &bad_ref_int) {
|
||||
REF2 *new_ref = ref_attributes(curr_var->ref->reference);
|
||||
if (new_ref != NULL) {
|
||||
curr_var->ref = new_ref;
|
||||
}
|
||||
}
|
||||
|
||||
// if there's a pointer somewhere in the address path, follow it in case pointer changed
|
||||
if ( curr_var->ref->pointer_present == 1 ) {
|
||||
curr_var->address = follow_address_path(curr_var->ref) ;
|
||||
if (curr_var->address == NULL) {
|
||||
std::string save_name(curr_var->ref->reference) ;
|
||||
free(curr_var->ref) ;
|
||||
curr_var->ref = make_error_ref(save_name) ;
|
||||
curr_var->address = curr_var->ref->address ;
|
||||
} else if ( validate_address ) {
|
||||
// The address is not NULL.
|
||||
// If validate_address is on, check the memory manager if the address falls into
|
||||
// any of the memory blocks it knows of. Don't do this if we have a std::string or
|
||||
// wstring type, or we already are pointing to a bad ref.
|
||||
if ( (curr_var->string_type != TRICK_STRING) and
|
||||
(curr_var->string_type != TRICK_WSTRING) and
|
||||
(curr_var->ref->address != &bad_ref_int) and
|
||||
(get_alloc_info_of(curr_var->address) == NULL) ) {
|
||||
std::string save_name(curr_var->ref->reference) ;
|
||||
free(curr_var->ref) ;
|
||||
curr_var->ref = make_error_ref(save_name) ;
|
||||
curr_var->address = curr_var->ref->address ;
|
||||
}
|
||||
} else {
|
||||
curr_var->ref->address = curr_var->address ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if this variable is a string we need to get the raw character string out of it.
|
||||
if (( curr_var->string_type == TRICK_STRING ) && !curr_var->need_deref) {
|
||||
std::string * str_ptr = (std::string *)curr_var->ref->address ;
|
||||
curr_var->address = (void *)(str_ptr->c_str()) ;
|
||||
}
|
||||
|
||||
// if this variable itself is a pointer, dereference it
|
||||
if ( curr_var->need_deref) {
|
||||
curr_var->address = *(void**)curr_var->ref->address ;
|
||||
}
|
||||
|
||||
// handle c++ string and char*
|
||||
if ( curr_var->string_type == TRICK_STRING ) {
|
||||
if (curr_var->address == NULL) {
|
||||
curr_var->size = 0 ;
|
||||
} else {
|
||||
curr_var->size = strlen((char*)curr_var->address) + 1 ;
|
||||
}
|
||||
}
|
||||
// handle c++ wstring and wchar_t*
|
||||
if ( curr_var->string_type == TRICK_WSTRING ) {
|
||||
if (curr_var->address == NULL) {
|
||||
curr_var->size = 0 ;
|
||||
} else {
|
||||
curr_var->size = wcslen((wchar_t *)curr_var->address) * sizeof(wchar_t);
|
||||
}
|
||||
}
|
||||
if(curr_var->address != NULL) {
|
||||
memcpy( curr_var->buffer_in , curr_var->address , curr_var->size ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Indicate that sim data has been written and is now ready in the buffer_in's of the vars variable list.
|
||||
if (cyclical) {
|
||||
var_data_staged = true;
|
||||
packets_copied++ ;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(©_mutex) ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "trick/VariableServerThread.hh"
|
||||
#include "trick/tc_proto.h"
|
||||
#include "trick/message_proto.h"
|
||||
#include "trick/message_type.h"
|
||||
|
||||
int Trick::VariableServerThread::create_udp_socket(const char * address, unsigned short in_port) {
|
||||
listen_dev = &connection ;
|
||||
tc_init_with_connection_info(&connection, AF_INET, SOCK_DGRAM, address, in_port) ;
|
||||
message_publish(MSG_INFO, "Created udp variable server %s:%d\n", listen_dev->hostname, listen_dev->port) ;
|
||||
tc_blockio( &connection , TC_COMM_NOBLOCKIO ) ;
|
||||
conn_type = UDP ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::create_mcast_socket(const char * mcast_address, const char * address, unsigned short in_port) {
|
||||
int ret ;
|
||||
if ( mcast_address == NULL || mcast_address[0] == '\0' ) {
|
||||
message_publish(MSG_ERROR, "Multicast address must be defined.\n") ;
|
||||
return -1 ;
|
||||
}
|
||||
create_udp_socket(address, in_port) ;
|
||||
|
||||
conn_type = MCAST ;
|
||||
|
||||
struct ip_mreq mreq;
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(mcast_address);
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
ret = setsockopt(connection.socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) ;
|
||||
if ( ret < 0 ) {
|
||||
perror("ip_add_membership") ;
|
||||
return ret ;
|
||||
}
|
||||
|
||||
memset(&connection.remoteServAddr, 0, sizeof(struct sockaddr_in));
|
||||
connection.remoteServAddr.sin_family = AF_INET;
|
||||
connection.remoteServAddr.sin_addr.s_addr = inet_addr(mcast_address);
|
||||
connection.remoteServAddr.sin_port = htons(in_port);
|
||||
|
||||
message_publish(MSG_INFO, "Multicast variable server output %s:%d\n", mcast_address, listen_dev->port) ;
|
||||
return 0 ;
|
||||
|
||||
}
|
@ -22,141 +22,81 @@ void exit_var_thread(void *in_vst) ;
|
||||
|
||||
void * Trick::VariableServerThread::thread_body() {
|
||||
|
||||
int ii , jj;
|
||||
int msg_len;
|
||||
int ret;
|
||||
int nbytes = -1;
|
||||
char *last_newline ;
|
||||
unsigned int size ;
|
||||
socklen_t sock_size ;
|
||||
|
||||
// We need to make the thread to VariableServerThread map before we accept the connection.
|
||||
// Otherwise we have a race where this thread is unknown to the variable server and the
|
||||
// client gets confirmation that the connection is ready for communication.
|
||||
vs->add_vst( pthread_self() , this ) ;
|
||||
|
||||
if ( listen_dev->socket_type == SOCK_STREAM ) {
|
||||
tc_accept(listen_dev, &connection);
|
||||
tc_blockio(&connection, TC_COMM_ALL_OR_NOTHING);
|
||||
// Accept client connection
|
||||
int accept_status = accept(listener, &connection);
|
||||
if (accept_status != 0) {
|
||||
// TODO: Use a real error handler
|
||||
std::cout << "Accept failed, variable server session exiting" << std::endl;
|
||||
vs->delete_vst(pthread_self());
|
||||
|
||||
// Tell main thread that we failed to initialize
|
||||
pthread_mutex_lock(&connection_status_mutex);
|
||||
connection_status = CONNECTION_FAIL;
|
||||
pthread_cond_signal(&connection_status_cv);
|
||||
pthread_mutex_unlock(&connection_status_mutex);
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
connection_accepted = true ;
|
||||
|
||||
connection.setBlockMode(TC_COMM_ALL_OR_NOTHING);
|
||||
|
||||
// Create session
|
||||
session = new VariableServerSession(&connection);
|
||||
vs->add_session( pthread_self(), session );
|
||||
|
||||
// Tell main that we are ready
|
||||
pthread_mutex_lock(&connection_status_mutex);
|
||||
connection_status = CONNECTION_SUCCESS;
|
||||
pthread_cond_signal(&connection_status_cv);
|
||||
pthread_mutex_unlock(&connection_status_mutex);
|
||||
|
||||
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) ;
|
||||
pthread_cleanup_push(exit_var_thread, (void *) this);
|
||||
|
||||
/* Save off the host and port information of the source port. We want to ignore messages from
|
||||
this port if we are a multicast socket */
|
||||
struct sockaddr_in self_s_in ;
|
||||
int s_in_size = sizeof(self_s_in) ;
|
||||
if ( conn_type == MCAST ) {
|
||||
getsockname( connection.socket , (struct sockaddr *)&self_s_in, (socklen_t *)&s_in_size) ;
|
||||
if ( self_s_in.sin_addr.s_addr == 0 ) {
|
||||
char hname[80];
|
||||
struct hostent *ip_host;
|
||||
gethostname(hname, (size_t) 80);
|
||||
ip_host = gethostbyname(hname);
|
||||
memcpy(&(self_s_in.sin_addr.s_addr), ip_host->h_addr, (size_t) ip_host->h_length);
|
||||
}
|
||||
}
|
||||
pthread_cleanup_push(exit_var_thread, (void *) this) ;
|
||||
|
||||
// if log is set on for variable server (e.g., in input file), turn log on for each client
|
||||
if (vs->get_log()) {
|
||||
log = true ;
|
||||
session->set_log_on();
|
||||
}
|
||||
|
||||
try {
|
||||
while (1) {
|
||||
|
||||
// Pause here if we are in a restart condition
|
||||
pthread_mutex_lock(&restart_pause) ;
|
||||
|
||||
/* Check the length of the message on the socket */
|
||||
nbytes = recvfrom( connection.socket, incoming_msg, MAX_CMD_LEN, MSG_PEEK, NULL, NULL ) ;
|
||||
if (nbytes == 0 ) {
|
||||
break ;
|
||||
}
|
||||
// Look for a message from the client
|
||||
// Parse and execute if one is availible
|
||||
session->handleMessage();
|
||||
|
||||
if (nbytes != -1) { // -1 means socket is nonblocking and no data to read
|
||||
/* find the last newline that is present on the socket */
|
||||
incoming_msg[nbytes] = '\0' ;
|
||||
last_newline = rindex( incoming_msg , '\n') ;
|
||||
|
||||
/* if there is a newline then there is a complete command on the socket */
|
||||
if ( last_newline != NULL ) {
|
||||
/* only remove up to (and including) the last newline on the socket */
|
||||
size = last_newline - incoming_msg + 1;
|
||||
if ( conn_type == UDP ) {
|
||||
// Save the remote host information, that is where we are going to send replies.
|
||||
sock_size = sizeof(connection.remoteServAddr) ;
|
||||
nbytes = recvfrom( connection.socket, incoming_msg, size, 0 ,
|
||||
(struct sockaddr *)&connection.remoteServAddr, &sock_size ) ;
|
||||
} else if ( conn_type == MCAST ) {
|
||||
// Save the remove host information for test against ourself.
|
||||
struct sockaddr_in s_in ;
|
||||
sock_size = sizeof(s_in) ;
|
||||
nbytes = recvfrom( connection.socket, incoming_msg, size, 0 ,
|
||||
(struct sockaddr *)&s_in, &sock_size ) ;
|
||||
// If this message is from us, then ignore it.
|
||||
if ( s_in.sin_addr.s_addr == self_s_in.sin_addr.s_addr and s_in.sin_port == self_s_in.sin_port) {
|
||||
nbytes = 0 ;
|
||||
}
|
||||
} else {
|
||||
// We know where we are sending information, no need to save it.
|
||||
nbytes = recvfrom( connection.socket, incoming_msg, size, 0 , NULL, NULL ) ;
|
||||
}
|
||||
} else {
|
||||
nbytes = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nbytes > 0 ) {
|
||||
|
||||
msg_len = nbytes ;
|
||||
if (debug >= 3) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server received bytes = msg_len = %d\n", &connection, connection.client_tag, nbytes);
|
||||
}
|
||||
|
||||
incoming_msg[msg_len] = '\0' ;
|
||||
|
||||
if (vs->get_info_msg() || (debug >= 1)) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server received: %s", &connection, connection.client_tag, incoming_msg) ;
|
||||
}
|
||||
if (log) {
|
||||
message_publish(MSG_PLAYBACK, "tag=<%s> time=%f %s", connection.client_tag, exec_get_sim_time(), incoming_msg) ;
|
||||
}
|
||||
|
||||
for( ii = 0 , jj = 0 ; ii <= msg_len ; ii++ ) {
|
||||
if ( incoming_msg[ii] != '\r' ) {
|
||||
stripped_msg[jj++] = incoming_msg[ii] ;
|
||||
}
|
||||
}
|
||||
|
||||
ip_parse(stripped_msg); /* returns 0 if no parsing error */
|
||||
|
||||
}
|
||||
|
||||
/* break out of loop if exit command found */
|
||||
if (exit_cmd == true) {
|
||||
// Check to see if exit is necessary
|
||||
if (session->exit_cmd == true) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( copy_mode == VS_COPY_ASYNC ) {
|
||||
copy_sim_data() ;
|
||||
// Copy data out of sim if async mode
|
||||
if ( session->get_copy_mode() == VS_COPY_ASYNC ) {
|
||||
session->copy_sim_data() ;
|
||||
}
|
||||
|
||||
if ( (write_mode == VS_WRITE_ASYNC) or
|
||||
((copy_mode == VS_COPY_ASYNC) and (write_mode == VS_WRITE_WHEN_COPIED)) or
|
||||
(! is_real_time()) ) {
|
||||
if ( !pause_cmd ) {
|
||||
ret = write_data() ;
|
||||
if ( ret < 0 ) {
|
||||
break ;
|
||||
}
|
||||
bool should_write_async = (session->get_write_mode() == VS_WRITE_ASYNC) ||
|
||||
( session->get_copy_mode() == VS_COPY_ASYNC && (session->get_write_mode() == VS_WRITE_WHEN_COPIED)) ||
|
||||
(! is_real_time());
|
||||
|
||||
// Write data out to connection if async mode and not paused
|
||||
if ( should_write_async && !session->get_pause()) {
|
||||
int ret = session->write_data() ;
|
||||
if ( ret < 0 ) {
|
||||
break ;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&restart_pause) ;
|
||||
|
||||
usleep((unsigned int) (update_rate * 1000000));
|
||||
usleep((unsigned int) (session->get_update_rate() * 1000000));
|
||||
}
|
||||
} catch (Trick::ExecutiveException & ex ) {
|
||||
message_publish(MSG_ERROR, "\nVARIABLE SERVER COMMANDED exec_terminate\n ROUTINE: %s\n DIAGNOSTIC: %s\n" ,
|
||||
@ -192,7 +132,7 @@ void * Trick::VariableServerThread::thread_body() {
|
||||
}
|
||||
|
||||
if (debug >= 3) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server receive loop exiting\n", &connection, connection.client_tag);
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server receive loop exiting\n", &connection, connection.get_client_tag().c_str());
|
||||
}
|
||||
|
||||
pthread_cleanup_pop(1);
|
||||
|
@ -1,45 +0,0 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "trick/VariableServerThread.hh"
|
||||
|
||||
void Trick::VariableServerThread::preload_checkpoint() {
|
||||
|
||||
// Stop variable server processing at the top of the processing loop.
|
||||
pthread_mutex_lock(&restart_pause);
|
||||
|
||||
// Let the thread complete any data copying it has to do
|
||||
// and then suspend data copying until the checkpoint is reloaded.
|
||||
pthread_mutex_lock(©_mutex);
|
||||
|
||||
// Save the pause state of this thread.
|
||||
saved_pause_cmd = pause_cmd;
|
||||
|
||||
// Disallow data writing.
|
||||
pause_cmd = true ;
|
||||
|
||||
// Temporarily "disconnect" the variable references from Trick Managed Memory
|
||||
// by tagging each as a "bad reference".
|
||||
std::vector <VariableReference *>::iterator it ;
|
||||
for (it = vars.begin(); it != vars.end() ; it++) {
|
||||
(*it)->ref->address = (char*)&bad_ref_int;
|
||||
(*it)->ref->attr = new ATTRIBUTES() ;
|
||||
(*it)->ref->attr->type = TRICK_NUMBER_OF_TYPES ;
|
||||
(*it)->ref->attr->units = (char *)"--" ;
|
||||
(*it)->ref->attr->size = sizeof(int) ;
|
||||
}
|
||||
|
||||
// Allow data copying to continue.
|
||||
pthread_mutex_unlock(©_mutex);
|
||||
|
||||
}
|
||||
|
||||
void Trick::VariableServerThread::restart() {
|
||||
// Set the pause state of this thread back to its "pre-checkpoint reload" state.
|
||||
pause_cmd = saved_pause_cmd ;
|
||||
|
||||
// Restart the variable server processing.
|
||||
pthread_mutex_unlock(&restart_pause);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,322 +0,0 @@
|
||||
/*
|
||||
PURPOSE: (Allows clients to get and set Trick parameters)
|
||||
PROGRAMMERS: (((Alex Lin) (NASA) (8/06) (--)))
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <pthread.h>
|
||||
#include "trick/VariableServer.hh"
|
||||
#include "trick/parameter_types.h"
|
||||
#include "trick/bitfield_proto.h"
|
||||
#include "trick/trick_byteswap.h"
|
||||
#include "trick/tc_proto.h"
|
||||
#include "trick/message_proto.h"
|
||||
#include "trick/message_type.h"
|
||||
|
||||
|
||||
extern "C" {
|
||||
void *trick_bswap_buffer(void *out, void *in, ATTRIBUTES * attr, int tofrom) ;
|
||||
}
|
||||
|
||||
#define MAX_MSG_LEN 8192
|
||||
|
||||
|
||||
int Trick::VariableServerThread::write_binary_data( int Start, char *buf1, const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type) {
|
||||
int i;
|
||||
int ret ;
|
||||
int HeaderSize, MessageSize;
|
||||
int NumVariablesProcessed;
|
||||
unsigned int msg_type , offset, len ;
|
||||
unsigned int size ;
|
||||
unsigned int swap_int ;
|
||||
char * address = 0 ;
|
||||
char* param_name;
|
||||
|
||||
/* start the offset 4 bytes into the message, we'll subtract the sizeof offset at the end */
|
||||
offset = sizeof(msg_type) + sizeof(offset) ;
|
||||
|
||||
if (byteswap) {
|
||||
/* Swap message type bytes */
|
||||
msg_type = trick_byteswap_int((int)message_type) ;
|
||||
} else {
|
||||
msg_type = message_type;
|
||||
}
|
||||
memcpy(buf1, &msg_type , sizeof(msg_type)) ;
|
||||
HeaderSize = sizeof(msg_type);
|
||||
|
||||
offset += sizeof(unsigned int) ;
|
||||
HeaderSize += sizeof(unsigned int);
|
||||
|
||||
for (i = Start; i < (int)given_vars.size() ; i++) {
|
||||
|
||||
// data to send was copied to buffer in copy_sim_data
|
||||
address = (char *)given_vars[i]->buffer_out;
|
||||
size = given_vars[i]->size ;
|
||||
|
||||
param_name = given_vars[i]->ref->reference;
|
||||
len = strlen(param_name) ;
|
||||
// when var_binary_nonames, do not put the variable names into the message to be sent
|
||||
if (binary_data_nonames) {
|
||||
MessageSize = sizeof(int) + sizeof(size) + size ;
|
||||
} else {
|
||||
MessageSize = sizeof(len) + len + sizeof(int) + sizeof(size) + size ;
|
||||
}
|
||||
|
||||
/* make sure this message will fit in a packet by itself */
|
||||
if ( (HeaderSize + MessageSize) > MAX_MSG_LEN ) {
|
||||
message_publish(MSG_WARNING, "%p Variable Server buffer[%d] too small (need %d) for symbol %s, SKIPPING IT.\n",
|
||||
&connection, MAX_MSG_LEN,
|
||||
(int)(HeaderSize + MessageSize),
|
||||
given_vars[i]->ref->reference );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (offset + MessageSize) < MAX_MSG_LEN ) {
|
||||
if (byteswap) {
|
||||
if (!binary_data_nonames) {
|
||||
swap_int = trick_byteswap_int((int)len) ;
|
||||
memcpy(&buf1[offset] , &swap_int , sizeof(len)) ;
|
||||
offset += sizeof(len) ;
|
||||
|
||||
memcpy(&buf1[offset] , param_name , (size_t)len) ;
|
||||
offset += len ;
|
||||
}
|
||||
|
||||
swap_int = trick_byteswap_int(given_vars[i]->ref->attr->type) ;
|
||||
memcpy(&buf1[offset] , &swap_int , sizeof(int)) ;
|
||||
offset += sizeof(int) ;
|
||||
|
||||
swap_int = trick_byteswap_int((int)size) ;
|
||||
memcpy(&buf1[offset] , &swap_int , sizeof(size)) ;
|
||||
offset += sizeof(size) ;
|
||||
|
||||
trick_bswap_single_parameter(&buf1[offset], address, given_vars[i]->ref->attr, 1);
|
||||
offset += size ;
|
||||
}
|
||||
else {
|
||||
int temp_i ;
|
||||
unsigned int temp_ui ;
|
||||
|
||||
if (!binary_data_nonames) {
|
||||
memcpy(&buf1[offset] , &len , sizeof(len)) ;
|
||||
offset += sizeof(len) ;
|
||||
|
||||
memcpy(&buf1[offset] , param_name , (size_t)len) ;
|
||||
offset += len ;
|
||||
}
|
||||
|
||||
memcpy(&buf1[offset] , &given_vars[i]->ref->attr->type , sizeof(int)) ;
|
||||
offset += sizeof(int) ;
|
||||
|
||||
memcpy(&buf1[offset] , &size , sizeof(size)) ;
|
||||
offset += sizeof(size) ;
|
||||
|
||||
switch ( given_vars[i]->ref->attr->type ) {
|
||||
case TRICK_BITFIELD:
|
||||
temp_i = GET_BITFIELD(address , given_vars[i]->ref->attr->size ,
|
||||
given_vars[i]->ref->attr->index[0].start, given_vars[i]->ref->attr->index[0].size) ;
|
||||
memcpy(&buf1[offset] , &temp_i , (size_t)size) ;
|
||||
break ;
|
||||
case TRICK_UNSIGNED_BITFIELD:
|
||||
temp_ui = GET_UNSIGNED_BITFIELD(address , given_vars[i]->ref->attr->size ,
|
||||
given_vars[i]->ref->attr->index[0].start, given_vars[i]->ref->attr->index[0].size) ;
|
||||
memcpy(&buf1[offset] , &temp_ui , (size_t)size) ;
|
||||
break ;
|
||||
case TRICK_NUMBER_OF_TYPES:
|
||||
// TRICK_NUMBER_OF_TYPES is an error case
|
||||
temp_i = 0 ;
|
||||
memcpy(&buf1[offset] , &temp_i , (size_t)size) ;
|
||||
break ;
|
||||
default:
|
||||
memcpy(&buf1[offset] , address , (size_t)size) ;
|
||||
break ;
|
||||
}
|
||||
offset += size ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* indicate that we're over the maximum size */
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server buffer[%d] too small (need %d), sending multiple binary packets.\n",
|
||||
&connection, connection.client_tag, MAX_MSG_LEN,
|
||||
(int)(offset + MessageSize) );
|
||||
}
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
/* adjust the header with the correct information reflecting what has been accomplished */
|
||||
NumVariablesProcessed = i - Start;
|
||||
|
||||
offset -= sizeof(offset) ;
|
||||
if (byteswap) {
|
||||
swap_int = trick_byteswap_int((int)offset) ;
|
||||
memcpy(buf1 + sizeof(msg_type) , &swap_int , sizeof(offset)) ;
|
||||
|
||||
swap_int = trick_byteswap_int( NumVariablesProcessed ) ;
|
||||
memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &swap_int , sizeof(swap_int)) ;
|
||||
}
|
||||
else {
|
||||
memcpy(buf1 + sizeof(msg_type) , &offset , sizeof(offset)) ;
|
||||
memcpy( buf1 + sizeof(msg_type) + sizeof(offset), &NumVariablesProcessed , sizeof( NumVariablesProcessed )) ;
|
||||
}
|
||||
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %u binary bytes containing %d variables.\n", &connection,
|
||||
connection.client_tag, (unsigned int)(offset + sizeof(offset)), NumVariablesProcessed);
|
||||
}
|
||||
|
||||
len = offset + sizeof(msg_type) ;
|
||||
ret = tc_write(&connection, (char *) buf1, len);
|
||||
if ( ret != (int)len ) {
|
||||
return(-1) ;
|
||||
}
|
||||
|
||||
/* return the index to the next symbol to send or V->num_vars if all done */
|
||||
return i;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::write_ascii_data(char * dest_buf, size_t dest_buf_size, const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type ) {
|
||||
|
||||
snprintf(dest_buf, dest_buf_size, "%d\t", message_type) ;
|
||||
|
||||
for (unsigned long i = 0; i < given_vars.size(); i++) {
|
||||
char curr_buf[MAX_MSG_LEN];
|
||||
int ret = vs_format_ascii( given_vars[i] , curr_buf, sizeof(curr_buf));
|
||||
|
||||
if (ret < 0) {
|
||||
message_publish(MSG_WARNING, "%p Variable Server string buffer[%d] too small for symbol %s, TRUNCATED IT.\n",
|
||||
&connection, MAX_MSG_LEN, given_vars[i]->ref->reference );
|
||||
}
|
||||
|
||||
/* make sure this message will fit in a packet by itself */
|
||||
if( strlen( curr_buf ) + 2 > MAX_MSG_LEN ) {
|
||||
message_publish(MSG_WARNING, "%p Variable Server buffer[%d] too small for symbol %s, TRUNCATED IT.\n",
|
||||
&connection, MAX_MSG_LEN, given_vars[i]->ref->reference );
|
||||
curr_buf[MAX_MSG_LEN - 1] = '\0';
|
||||
}
|
||||
|
||||
int len = strlen(dest_buf) ;
|
||||
|
||||
/* make sure there is space for the next tab or next newline and null */
|
||||
if( len + strlen( curr_buf ) + 2 > MAX_MSG_LEN ) {
|
||||
// If there isn't, send incomplete message
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d ascii bytes:\n%s\n",
|
||||
&connection, connection.client_tag, (int)strlen(dest_buf), dest_buf) ;
|
||||
}
|
||||
|
||||
ret = tc_write(&connection, (char *) dest_buf, len);
|
||||
if ( ret != len ) {
|
||||
return(-1) ;
|
||||
}
|
||||
dest_buf[0] = '\0';
|
||||
}
|
||||
|
||||
strcat(dest_buf, curr_buf);
|
||||
strcat(dest_buf, "\t");
|
||||
}
|
||||
|
||||
int len = strlen(dest_buf) ;
|
||||
|
||||
if ( len > 0 ) {
|
||||
dest_buf[ strlen(dest_buf) - 1 ] = '\n';
|
||||
|
||||
if (debug >= 2) {
|
||||
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d ascii bytes:\n%s\n",
|
||||
&connection, connection.client_tag, (int)strlen(dest_buf), dest_buf) ;
|
||||
}
|
||||
int ret = tc_write(&connection, (char *) dest_buf, (int)strlen(dest_buf));
|
||||
if ( ret != (int)strlen(dest_buf) ) {
|
||||
return(-1) ;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::write_data() {
|
||||
|
||||
int ret;
|
||||
unsigned int i ;
|
||||
char buf1[ MAX_MSG_LEN ];
|
||||
int len ;
|
||||
|
||||
// do not send anything when there are no variables!
|
||||
if ( vars.size() == 0 or packets_copied == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Acquire sole access to vars[ii]->buffer_in. */
|
||||
if ( var_data_staged and pthread_mutex_trylock(©_mutex) == 0 ) {
|
||||
unsigned int ii;
|
||||
void * temp_p;
|
||||
// Swap buffer_in and buffer_out for each vars[ii].
|
||||
for ( ii = 0 ; ii < vars.size() ; ii++ ) {
|
||||
temp_p = vars[ii]->buffer_in;
|
||||
vars[ii]->buffer_in = vars[ii]->buffer_out;
|
||||
vars[ii]->buffer_out = temp_p;
|
||||
}
|
||||
var_data_staged = false;
|
||||
|
||||
/* Relinquish sole access to vars[ii]->buffer_in. */
|
||||
pthread_mutex_unlock(©_mutex) ;
|
||||
|
||||
if (binary_data) {
|
||||
int index = 0;
|
||||
|
||||
do {
|
||||
ret = write_binary_data( index, buf1, vars, VS_VAR_LIST );
|
||||
if ( ret >= 0 ) {
|
||||
index = ret ;
|
||||
} else {
|
||||
return(-1) ;
|
||||
}
|
||||
} while( index < (int)vars.size() );
|
||||
|
||||
return 0;
|
||||
|
||||
} else { /* ascii mode */
|
||||
return write_ascii_data(buf1, sizeof(buf1), vars, VS_VAR_LIST );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Trick::VariableServerThread::write_data(std::vector<VariableReference *> given_vars) {
|
||||
// do not send anything when there are no variables!
|
||||
if ( given_vars.size() == 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Acquire sole access to vars[ii]->buffer_in. */
|
||||
if ( pthread_mutex_trylock(©_mutex) == 0 ) {
|
||||
// Swap buffer_in and buffer_out for each vars[ii].
|
||||
for (int i = 0 ; i < given_vars.size() ; i++ ) {
|
||||
void *temp_p = given_vars[i]->buffer_in;
|
||||
given_vars[i]->buffer_in = given_vars[i]->buffer_out;
|
||||
given_vars[i]->buffer_out = temp_p;
|
||||
}
|
||||
/* Relinquish sole access to vars[ii]->buffer_in. */
|
||||
pthread_mutex_unlock(©_mutex) ;
|
||||
|
||||
char buf1[ MAX_MSG_LEN ];
|
||||
|
||||
if (binary_data) {
|
||||
int index = 0;
|
||||
|
||||
do {
|
||||
int ret = write_binary_data( index, buf1, given_vars, VS_SEND_ONCE );
|
||||
if ( ret >= 0 ) {
|
||||
index = ret ;
|
||||
} else {
|
||||
return(-1) ;
|
||||
}
|
||||
} while( index < (int)given_vars.size() );
|
||||
|
||||
return 0;
|
||||
|
||||
} else { /* ascii mode */
|
||||
return write_ascii_data(buf1, sizeof(buf1), given_vars, VS_SEND_ONCE);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
|
||||
#include "trick/VariableServer.hh"
|
||||
#include "trick/variable_server_message_types.h"
|
||||
#include "trick/tc_proto.h"
|
||||
|
||||
int Trick::VariableServerThread::write_stdio(int stream, std::string text) {
|
||||
|
||||
char header[16] ;
|
||||
snprintf(header, sizeof(header), "%-2d %1d %8d\n" , VS_STDIO, stream , (int)text.length()) ;
|
||||
tc_write(&connection , (char *) header , strlen(header)) ;
|
||||
tc_write(&connection , (char *) text.c_str() , text.length()) ;
|
||||
return 0 ;
|
||||
}
|
@ -6,10 +6,10 @@
|
||||
|
||||
int Trick::VariableServer::copy_data_freeze() {
|
||||
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
std::map < pthread_t , VariableServerSession * >::iterator it ;
|
||||
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
for ( it = var_server_sessions.begin() ; it != var_server_sessions.end() ; it++ ) {
|
||||
(*it).second->copy_data_freeze() ;
|
||||
}
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
|
@ -8,17 +8,16 @@
|
||||
int Trick::VariableServer::copy_data_freeze_scheduled() {
|
||||
|
||||
long long next_call_tics ;
|
||||
VariableServerThread * vst ;
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
std::map < pthread_t , VariableServerSession * >::iterator it ;
|
||||
|
||||
next_call_tics = TRICK_MAX_LONG_LONG ;
|
||||
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
vst = (*it).second ;
|
||||
vst->copy_data_freeze_scheduled(copy_data_freeze_job->next_tics) ;
|
||||
if ( vst->get_freeze_next_tics() < next_call_tics ) {
|
||||
next_call_tics = vst->get_freeze_next_tics() ;
|
||||
for ( it = var_server_sessions.begin() ; it != var_server_sessions.end() ; it++ ) {
|
||||
VariableServerSession * session = (*it).second ;
|
||||
session->copy_data_freeze_scheduled(copy_data_freeze_job->next_tics) ;
|
||||
if ( session->get_freeze_next_tics() < next_call_tics ) {
|
||||
next_call_tics = session->get_freeze_next_tics() ;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
|
@ -8,17 +8,16 @@
|
||||
int Trick::VariableServer::copy_data_scheduled() {
|
||||
|
||||
long long next_call_tics ;
|
||||
VariableServerThread * vst ;
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
std::map < pthread_t , VariableServerSession * >::iterator it ;
|
||||
|
||||
next_call_tics = TRICK_MAX_LONG_LONG ;
|
||||
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
vst = (*it).second ;
|
||||
vst->copy_data_scheduled(copy_data_job->next_tics) ;
|
||||
if ( vst->get_next_tics() < next_call_tics ) {
|
||||
next_call_tics = vst->get_next_tics() ;
|
||||
for ( it = var_server_sessions.begin() ; it != var_server_sessions.end() ; it++ ) {
|
||||
auto session = (*it).second ;
|
||||
session->copy_data_scheduled(copy_data_job->next_tics) ;
|
||||
if ( session->get_next_tics() < next_call_tics ) {
|
||||
next_call_tics = session->get_next_tics() ;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
int Trick::VariableServer::copy_data_top() {
|
||||
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
std::map < pthread_t , VariableServerSession * >::iterator it ;
|
||||
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
for ( it = var_server_sessions.begin() ; it != var_server_sessions.end() ; it++ ) {
|
||||
(*it).second->copy_data_top() ;
|
||||
}
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
|
@ -10,17 +10,17 @@
|
||||
int Trick::VariableServer::freeze_init() {
|
||||
|
||||
long long next_call_tics ;
|
||||
VariableServerThread * vst ;
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
VariableServerSession * session ;
|
||||
std::map < pthread_t , VariableServerSession * >::iterator it ;
|
||||
|
||||
next_call_tics = TRICK_MAX_LONG_LONG ;
|
||||
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
vst = (*it).second ;
|
||||
vst->freeze_init() ;
|
||||
if ( vst->get_freeze_next_tics() < next_call_tics ) {
|
||||
next_call_tics = vst->get_freeze_next_tics() ;
|
||||
for ( it = var_server_sessions.begin() ; it != var_server_sessions.end() ; it++ ) {
|
||||
session = (*it).second ;
|
||||
session->freeze_init() ;
|
||||
if ( session->get_freeze_next_tics() < next_call_tics ) {
|
||||
next_call_tics = session->get_freeze_next_tics() ;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
|
@ -6,18 +6,18 @@
|
||||
|
||||
int Trick::VariableServer::get_next_freeze_call_time() {
|
||||
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
VariableServerThread * vst ;
|
||||
std::map < pthread_t , VariableServerSession * >::iterator it ;
|
||||
VariableServerSession * session ;
|
||||
|
||||
long long next_call_tics ;
|
||||
|
||||
next_call_tics = TRICK_MAX_LONG_LONG ;
|
||||
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
vst = (*it).second ;
|
||||
if ( vst->get_freeze_next_tics() < next_call_tics ) {
|
||||
next_call_tics = vst->get_freeze_next_tics() ;
|
||||
for ( it = var_server_sessions.begin() ; it != var_server_sessions.end() ; it++ ) {
|
||||
session = (*it).second ;
|
||||
if ( session->get_freeze_next_tics() < next_call_tics ) {
|
||||
next_call_tics = session->get_freeze_next_tics() ;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
|
@ -6,18 +6,18 @@
|
||||
|
||||
int Trick::VariableServer::get_next_sync_call_time() {
|
||||
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
VariableServerThread * vst ;
|
||||
std::map < pthread_t , VariableServerSession * >::iterator it ;
|
||||
VariableServerSession * session ;
|
||||
|
||||
long long next_call_tics ;
|
||||
|
||||
next_call_tics = TRICK_MAX_LONG_LONG ;
|
||||
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
vst = (*it).second ;
|
||||
if ( vst->get_next_tics() < next_call_tics ) {
|
||||
next_call_tics = vst->get_next_tics() ;
|
||||
for ( it = var_server_sessions.begin() ; it != var_server_sessions.end() ; it++ ) {
|
||||
session = (*it).second ;
|
||||
if ( session->get_next_tics() < next_call_tics ) {
|
||||
next_call_tics = session->get_next_tics() ;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
|
@ -2,41 +2,42 @@
|
||||
#include <stdio.h>
|
||||
#include "trick/VariableServer.hh"
|
||||
|
||||
|
||||
int Trick::VariableServer::create_tcp_socket(const char * address, unsigned short in_port ) {
|
||||
Trick::VariableServerListenThread * new_listen_thread = new Trick::VariableServerListenThread ;
|
||||
new_listen_thread->create_tcp_socket(address, in_port) ;
|
||||
new_listen_thread->copy_cpus(listen_thread.get_cpus()) ;
|
||||
new_listen_thread->create_thread() ;
|
||||
additional_listen_threads[new_listen_thread->get_pthread_id()] = new_listen_thread ;
|
||||
// additional_listen_threads[new_listen_thread->get_pthread_id()] = new_listen_thread ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServer::create_udp_socket(const char * address, unsigned short in_port ) {
|
||||
int ret ;
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = new Trick::VariableServerThread(NULL) ;
|
||||
ret = vst->create_udp_socket(address, in_port) ;
|
||||
if ( ret == 0 ) {
|
||||
vst->copy_cpus(listen_thread.get_cpus()) ;
|
||||
vst->create_thread() ;
|
||||
}
|
||||
// int ret ;
|
||||
// Trick::VariableServerThread * vst ;
|
||||
// vst = new Trick::VariableServerThread(NULL) ;
|
||||
// ret = vst->create_udp_socket(address, in_port) ;
|
||||
// if ( ret == 0 ) {
|
||||
// vst->copy_cpus(listen_thread.get_cpus()) ;
|
||||
// vst->create_thread() ;
|
||||
// }
|
||||
//vst->var_debug(3) ;
|
||||
|
||||
return ret ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int Trick::VariableServer::create_multicast_socket(const char * mcast_address, const char * address, unsigned short in_port ) {
|
||||
int ret ;
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = new Trick::VariableServerThread(NULL) ;
|
||||
ret = vst->create_mcast_socket(mcast_address, address, in_port) ;
|
||||
if ( ret == 0 ) {
|
||||
vst->copy_cpus(listen_thread.get_cpus()) ;
|
||||
vst->create_thread() ;
|
||||
}
|
||||
// int ret ;
|
||||
// Trick::VariableServerThread * vst ;
|
||||
// vst = new Trick::VariableServerThread(NULL) ;
|
||||
// ret = vst->create_mcast_socket(mcast_address, address, in_port) ;
|
||||
// if ( ret == 0 ) {
|
||||
// vst->copy_cpus(listen_thread.get_cpus()) ;
|
||||
// vst->create_thread() ;
|
||||
// }
|
||||
//vst->var_debug(3) ;
|
||||
|
||||
return ret ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,9 @@
|
||||
|
||||
int Trick::VariableServer::init() {
|
||||
|
||||
int ret ;
|
||||
|
||||
/* start up a thread for the input processor variable server */
|
||||
if ( enabled ) {
|
||||
ret = listen_thread.check_and_move_listen_device() ;
|
||||
int ret = listen_thread.check_and_move_listen_device() ;
|
||||
if ( ret != 0 ) {
|
||||
return ret ;
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ int Trick::VariableServer::restart() {
|
||||
if ( listen_thread.get_pthread_id() == 0 ) {
|
||||
listen_thread.create_thread() ;
|
||||
}
|
||||
std::map < pthread_t , VariableServerListenThread * >::iterator it ;
|
||||
for( it = additional_listen_threads.begin() ; it != additional_listen_threads.end() ; it++ ) {
|
||||
(*it).second->restart() ;
|
||||
}
|
||||
// std::map < pthread_t , VariableServerListenThread * >::iterator it ;
|
||||
// for( it = additional_listen_threads.begin() ; it != additional_listen_threads.end() ; it++ ) {
|
||||
// (*it).second->restart() ;
|
||||
// }
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,19 @@
|
||||
int Trick::VariableServer::shutdown() {
|
||||
listen_thread.cancel_thread() ;
|
||||
std::map < pthread_t , VariableServerThread * >::iterator it ;
|
||||
|
||||
pthread_mutex_lock(&map_mutex) ;
|
||||
std::vector<pthread_t> ids;
|
||||
for ( it = var_server_threads.begin() ; it != var_server_threads.end() ; it++ ) {
|
||||
(*it).second->cancel_thread() ;
|
||||
ids.push_back((*it).first);
|
||||
// cancelling causes each var_server_thread map element to be erased by the exit_var_thread function
|
||||
}
|
||||
pthread_mutex_unlock(&map_mutex) ;
|
||||
|
||||
for (pthread_t id : ids) {
|
||||
pthread_join(id, NULL);
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,9 @@ void exit_var_thread(void *in_vst) {
|
||||
Trick::VariableServerThread * vst = (Trick::VariableServerThread *) in_vst ;
|
||||
Trick::VariableServer * vs = vst->get_vs() ;
|
||||
|
||||
tc_disconnect(&vst->get_connection());
|
||||
// tc_disconnect(&vst->get_connection());
|
||||
|
||||
vs->delete_session(vst->get_pthread_id());
|
||||
// Tell the variable server that this thread is exiting.
|
||||
vs->delete_vst(vst->get_pthread_id()) ;
|
||||
|
||||
|
4
trick_source/sim_services/VariableServer/test/.gitignore
vendored
Normal file
4
trick_source/sim_services/VariableServer/test/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
lcov_html/*
|
||||
*.o
|
||||
*_test
|
||||
*.info
|
87
trick_source/sim_services/VariableServer/test/Makefile
Normal file
87
trick_source/sim_services/VariableServer/test/Makefile
Normal file
@ -0,0 +1,87 @@
|
||||
|
||||
#SYNOPSIS:
|
||||
#
|
||||
# make [all] - makes everything.
|
||||
# make TARGET - makes the given target.
|
||||
# make clean - removes all files generated by make.
|
||||
|
||||
include $(dir $(lastword $(MAKEFILE_LIST)))../../../../share/trick/makefiles/Makefile.common
|
||||
|
||||
# Replace -isystem with -I so ICG doesn't skip Trick headers
|
||||
TRICK_SYSTEM_CXXFLAGS := $(subst -isystem,-I,$(TRICK_SYSTEM_CXXFLAGS))
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
TRICK_CXXFLAGS += -I$(GTEST_HOME)/include -I$(TRICK_HOME)/include -g -Wall -Wextra -Wno-sign-compare -std=c++11 ${TRICK_SYSTEM_CXXFLAGS} ${TRICK_TEST_FLAGS}
|
||||
TRICK_LIBS = -L${TRICK_LIB_DIR} -ltrick_mm -ltrick_units -ltrick_comm -ltrick_pyip -ltrick -ltrick_mm -ltrick_units -ltrick_comm -ltrick_pyip -ltrick -ltrick_var_binary_parser -ltrick_connection_handlers -ltrick_comm
|
||||
TRICK_EXEC_LINK_LIBS += -L${GTEST_HOME}/lib64 -L${GTEST_HOME}/lib -lgtest -lgtest_main -lpthread
|
||||
|
||||
# All tests produced by this Makefile. Remember to add new tests you
|
||||
# created to the list.
|
||||
|
||||
VARIABLE_REFERENCE_TESTS = VariableReference_test \
|
||||
VariableReference_writeValueAscii_test \
|
||||
VariableReference_writeValueBinary_test
|
||||
|
||||
VARIABLE_SESSION_TESTS = VariableServerSession_test
|
||||
|
||||
TESTS = $(VARIABLE_REFERENCE_TESTS) $(VARIABLE_SESSION_TESTS)
|
||||
|
||||
TEST_OBJS = $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(TESTS)))
|
||||
|
||||
TO_ICG = VariableReference_test \
|
||||
TestConnection
|
||||
|
||||
ICG_OBJS = $(addprefix $(OBJ_DIR)/io_, $(addsuffix .o, $(TO_ICG)))
|
||||
|
||||
OBJ_DIR = obj
|
||||
|
||||
print:
|
||||
echo $(ICG_OBJS)
|
||||
|
||||
# House-keeping build targets.
|
||||
|
||||
all : test
|
||||
|
||||
test: $(TESTS)
|
||||
for TEST in $(TESTS) ; do \
|
||||
./$$TEST --gtest_output=xml:${TRICK_HOME}/trick_test/$$TEST.xml ; \
|
||||
done
|
||||
|
||||
$(OBJ_DIR):
|
||||
mkdir $(OBJ_DIR)
|
||||
|
||||
$(TEST_OBJS): $(OBJ_DIR)/%.o: %.cc $(OBJ_DIR)
|
||||
$(TRICK_CXX) $(TRICK_CXXFLAGS) -c $< -o $@ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)
|
||||
|
||||
$(ICG_OBJS): $(OBJ_DIR)/io_%.o : %.hh $(OBJ_DIR)
|
||||
${TRICK_HOME}/bin/trick-ICG -sim_services -o ./io_src $(TRICK_CXXFLAGS) $<
|
||||
$(TRICK_CXX) $(TRICK_CXXFLAGS) -c io_src/io_$*.cpp -o $@ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)
|
||||
|
||||
$(VARIABLE_REFERENCE_TESTS): %: $(OBJ_DIR)/%.o $(OBJ_DIR)/io_VariableReference_test.o
|
||||
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) -o $@ $^ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)
|
||||
|
||||
$(VARIABLE_SESSION_TESTS): %: $(OBJ_DIR)/%.o $(OBJ_DIR)/io_TestConnection.o
|
||||
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) -o $@ $^ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)
|
||||
|
||||
code-coverage: test
|
||||
# Give rid of any old code-coverage HTML we may have.
|
||||
rm -rf lcov_html
|
||||
# Gather coverage information about the src code.
|
||||
lcov --capture \
|
||||
--directory ../object_${TRICK_HOST_CPU} \
|
||||
--base-directory ../ \
|
||||
--output-file src_coverage.info
|
||||
# Filter out information about directories that we don't care about.
|
||||
lcov --remove src_coverage.info '/Applications/*' '/usr/include/*' '/Library/*' \
|
||||
--output-file VariableServer_code_coverage.info
|
||||
# Generate HTML
|
||||
genhtml VariableServer_code_coverage.info \
|
||||
--output-directory lcov_html
|
||||
# Clean up
|
||||
# rm *.info
|
||||
lcov --list VariableServer_code_coverage.info
|
||||
|
||||
clean :
|
||||
rm -f $(TESTS)
|
||||
rm -f *.gcno *.gcda
|
||||
rm -rf io_src xml obj
|
@ -0,0 +1,80 @@
|
||||
#ifndef TEST_CONNECTION_HH
|
||||
#define TEST_CONNECTION_HH
|
||||
|
||||
#include "trick/ClientConnection.hh"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <string.h>
|
||||
|
||||
class TestConnection : public Trick::ClientConnection {
|
||||
public:
|
||||
~TestConnection () {
|
||||
for (char * message : binary_messages_written) {
|
||||
free (message);
|
||||
}
|
||||
}
|
||||
|
||||
int initialize() {
|
||||
valid = true;
|
||||
}
|
||||
|
||||
int write (const std::string& message) {
|
||||
if (!valid)
|
||||
return -1;
|
||||
|
||||
ascii_messages_written.emplace_back(message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write (char * message, int size) {
|
||||
if (!valid)
|
||||
return -1;
|
||||
|
||||
char * msg_copy = (char *) malloc(size+1);
|
||||
memcpy(msg_copy, message, size+1);
|
||||
binary_messages_written.push_back(msg_copy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string read (int max_len = MAX_CMD_LEN) {
|
||||
if (queued_messages.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ret = queued_messages.front();
|
||||
queued_messages.pop();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int disconnect () {
|
||||
valid = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string get_client_tag () {
|
||||
return client_tag;
|
||||
}
|
||||
|
||||
int set_client_tag(std::string tag) {
|
||||
client_tag = tag;
|
||||
}
|
||||
|
||||
int setBlockMode (int mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::queue <std::string> queued_messages;
|
||||
std::vector <std::string> ascii_messages_written;
|
||||
std::vector <char *> binary_messages_written;
|
||||
|
||||
|
||||
std::string client_tag;
|
||||
bool valid = true;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,512 @@
|
||||
#include "VariableReference_test.hh"
|
||||
|
||||
TEST_F(VariableReference_test, getName) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_int = 5;
|
||||
(void) memmgr->declare_extern_var(&test_int, "int test_int");
|
||||
Trick::VariableReference ref("test_int");
|
||||
|
||||
// ACT
|
||||
// ASSERT
|
||||
EXPECT_EQ(strcmp(ref.getName(), "test_int"), 0);
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, validateAddress) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a = 5;
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
|
||||
float test_b = 5.0;
|
||||
(void) memmgr->declare_extern_var(&test_b, "float test_b");
|
||||
Trick::VariableReference ref_broken("test_b");
|
||||
memmgr->delete_var("test_b");
|
||||
|
||||
float test_c = 5.0;
|
||||
(void) memmgr->declare_extern_var(&test_c, "float test_c");
|
||||
Trick::VariableReference ref_tagged("test_c");
|
||||
ref_tagged.tagAsInvalid();
|
||||
|
||||
// ACT
|
||||
// ASSERT
|
||||
EXPECT_EQ(ref.validate(), true);
|
||||
EXPECT_EQ(ref_broken.validate(), false);
|
||||
// A reference already tagged as invalid is considered ok by this check
|
||||
EXPECT_EQ(ref_tagged.validate(), true);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(VariableReference_test, stageValue_set) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a = 5;
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ref.isStaged(), true);
|
||||
EXPECT_EQ(ref.isWriteReady(), false);
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, prepareForWrite_set) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a = 5;
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ref.isStaged(), false);
|
||||
EXPECT_EQ(ref.isWriteReady(), true);
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, prepareForWrite_fails_if_not_staged) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a = 5;
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
|
||||
// ACT
|
||||
ref.prepareForWrite();
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ref.isStaged(), false);
|
||||
EXPECT_EQ(ref.isWriteReady(), false);
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_fails_if_not_write_ready) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a = 5;
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
// ASSERT
|
||||
EXPECT_EQ(ref.writeValueAscii(ss), -1);
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, var_does_not_exist) {
|
||||
// ARRANGE
|
||||
Trick::VariableReference ref("no_such_var");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ref.getType(), TRICK_NUMBER_OF_TYPES);
|
||||
EXPECT_EQ(ss.str(), "BAD_REF");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, stl_var) {
|
||||
// ARRANGE
|
||||
TestObject my_test;
|
||||
my_test.vec.push_back(5);
|
||||
(void) memmgr->declare_extern_var(&my_test, "TestObject my_test");
|
||||
|
||||
Trick::VariableReference ref("my_test.vec");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ref.isWriteReady(), true);
|
||||
EXPECT_EQ(ref.getType(), TRICK_NUMBER_OF_TYPES);
|
||||
EXPECT_EQ(ss.str(), "BAD_REF");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, structured_var) {
|
||||
// ARRANGE
|
||||
TestObject my_test;
|
||||
my_test.obj.a = 5;
|
||||
(void) memmgr->declare_extern_var(&my_test, "TestObject my_test");
|
||||
|
||||
Trick::VariableReference ref("my_test.obj");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ref.isWriteReady(), true);
|
||||
EXPECT_EQ(ref.getType(), TRICK_NUMBER_OF_TYPES);
|
||||
EXPECT_EQ(ss.str(), "BAD_REF");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, printWithoutUnits) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.length = 5000;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.length");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
EXPECT_STREQ(ref.getBaseUnits(), "m");
|
||||
|
||||
// ASSERT
|
||||
// Doesn't actually print with units unless set
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "5000");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, setUnits) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.length = 5000;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.length");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("km");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "5 {km}");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, setUnitsTwice) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.length = 5000;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.length");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("km");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "5 {km}");
|
||||
ss.str("");
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("mm");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "5000000 {mm}");
|
||||
}
|
||||
|
||||
|
||||
TEST_F(VariableReference_test, setUnitsBadFromUnits) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.error_units = 50;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.error_units");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("mm");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "50");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, setUnitsBadToUnits) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.a = 0.5;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("asldfjks");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "0.5");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, setUnitsDouble) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.a = 0.5;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("ms");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "500 {ms}");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, setUnitsLong) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.b = 1;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.b");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("m");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "1852 {m}");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, setUnitsLongLong) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.c = 10000000;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.c");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("m");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "254000 {m}");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, setUnitsUnsignedLong) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.d = 1;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.d");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("mi");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "5878625079535 {mi}");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, setUnitsUnsignedLongLong) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
TestObject obj;
|
||||
obj.e = 1;
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
Trick::VariableReference ref("obj.e");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.setRequestedUnits("mm");
|
||||
|
||||
// ASSERT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
EXPECT_EQ(ss.str(), "1609344 {mm}");
|
||||
}
|
||||
|
||||
// Byteswap tests
|
||||
|
||||
TEST_F(VariableReference_test, byteswap_chars) {
|
||||
// ARRANGE
|
||||
char in = 'a';
|
||||
char out;
|
||||
|
||||
memmgr->declare_extern_var(&in, "char a");
|
||||
Trick::VariableReference ref("a");
|
||||
|
||||
// ACT
|
||||
Trick::VariableReference::byteswap_var(&out, &in, ref);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(in, 'a');
|
||||
EXPECT_EQ(out, 'a');
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, byteswap_char_array) {
|
||||
// ARRANGE
|
||||
char in[7] = "Jackie";
|
||||
char out[7];
|
||||
|
||||
memmgr->declare_extern_var(&in, "char a[7]");
|
||||
Trick::VariableReference ref("a");
|
||||
|
||||
// ACT
|
||||
Trick::VariableReference::byteswap_var(out, in, ref);
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < 7; i++) {
|
||||
EXPECT_EQ(out[i], in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Pointers to the beginning of the variables
|
||||
bool check_that_val_is_byteswapped (char * expected, char * byteswap, int val_size) {
|
||||
for (int i = 0; i < val_size; i++) {
|
||||
if (expected[i] != byteswap[val_size-i-1]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, byteswap_short) {
|
||||
// ARRANGE
|
||||
short in = 100;
|
||||
short out;
|
||||
|
||||
memmgr->declare_extern_var(&in, "short a");
|
||||
Trick::VariableReference ref("a");
|
||||
|
||||
// ACT
|
||||
Trick::VariableReference::byteswap_var((char *)(&out),(char *)(&in), ref);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_TRUE(check_that_val_is_byteswapped((char *)(&out),(char *)(&in), sizeof(short)));
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, byteswap_int) {
|
||||
// ARRANGE
|
||||
int in = 123456;
|
||||
int out;
|
||||
|
||||
memmgr->declare_extern_var(&in, "int a");
|
||||
Trick::VariableReference ref("a");
|
||||
|
||||
// ACT
|
||||
Trick::VariableReference::byteswap_var((char *)(&out),(char *)(&in), ref);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_TRUE(check_that_val_is_byteswapped((char *)(&out),(char *)(&in), sizeof(int)));
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, byteswap_long) {
|
||||
// ARRANGE
|
||||
long in = 123456789;
|
||||
long out;
|
||||
|
||||
memmgr->declare_extern_var(&in, "long a");
|
||||
Trick::VariableReference ref("a");
|
||||
|
||||
// ACT
|
||||
Trick::VariableReference::byteswap_var((char *)(&out),(char *)(&in), ref);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_TRUE(check_that_val_is_byteswapped((char *)(&out),(char *)(&in), sizeof(long)));
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, byteswap_long_arr) {
|
||||
// ARRANGE
|
||||
long in[5] = {123456789, 123456780, __LONG_MAX__, -100000000, 0};
|
||||
long out[5];
|
||||
|
||||
memmgr->declare_extern_var(&in, "long a[5]");
|
||||
Trick::VariableReference ref("a");
|
||||
|
||||
// ACT
|
||||
Trick::VariableReference::byteswap_var((char *)(out),(char *)(in), ref);
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < 5; i++) {
|
||||
EXPECT_TRUE(check_that_val_is_byteswapped((char *)(&out[i]),(char *)(&in[i]), sizeof(long)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, byteswap_int_arr) {
|
||||
// ARRANGE
|
||||
int in[5] = {20945, -29384293, INT32_MAX, INT32_MIN, 0};
|
||||
int out[5];
|
||||
|
||||
memmgr->declare_extern_var(&in, "int a[5]");
|
||||
Trick::VariableReference ref("a");
|
||||
|
||||
// ACT
|
||||
Trick::VariableReference::byteswap_var((char *)(out),(char *)(in), ref);
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < 5; i++) {
|
||||
EXPECT_TRUE(check_that_val_is_byteswapped((char *)(&out[i]),(char *)(&in[i]), sizeof(int)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, byteswap_int_multidimensional_arr) {
|
||||
// ARRANGE
|
||||
int multidim_arr[5][4][3][2];
|
||||
int out[5][4][3][2];
|
||||
|
||||
|
||||
int counter = 500;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int k = 0; k < 3; k++) {
|
||||
for (int l = 0; l < 2; l++) {
|
||||
multidim_arr[i][j][k][l] = counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memmgr->declare_extern_var(&multidim_arr, "int multidim_arr[5][4][3][2]");
|
||||
Trick::VariableReference ref("multidim_arr");
|
||||
|
||||
// ACT
|
||||
Trick::VariableReference::byteswap_var((char *)(out),(char *)(multidim_arr), ref);
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < 5; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int k = 0; k < 3; k++) {
|
||||
for (int l = 0; l < 2; l++) {
|
||||
EXPECT_TRUE(check_that_val_is_byteswapped((char *)(&(out[i][j][k][l])),(char *)(&(multidim_arr[i][j][k][l])), sizeof(int)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/******************************TRICK HEADER*************************************
|
||||
PURPOSE: ( Common definitions for testing the VariableReference class )
|
||||
*******************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "trick/MemoryManager.hh"
|
||||
#include "trick/VariableReference.hh"
|
||||
#include "trick/UdUnits.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class NestedObject {
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
class TestObject {
|
||||
public:
|
||||
TestObject() {}
|
||||
|
||||
int length; /* m xy-position */
|
||||
double a; /* s time */
|
||||
long b; /* nautical_mile miles */
|
||||
long long c; /* in inches */
|
||||
unsigned long d; /* light_year miles */
|
||||
unsigned long long e; /* mi miles */
|
||||
int error_units; /* asvdsfkj fake units */
|
||||
wchar_t * wchar_str;
|
||||
std::vector<int> vec;
|
||||
|
||||
NestedObject obj;
|
||||
};
|
||||
|
||||
/*
|
||||
Test Fixture.
|
||||
*/
|
||||
class VariableReference_test : public ::testing::Test {
|
||||
protected:
|
||||
Trick::MemoryManager *memmgr;
|
||||
Trick::UdUnits * udunits;
|
||||
VariableReference_test() {
|
||||
memmgr = new Trick::MemoryManager;
|
||||
udunits = new Trick::UdUnits;
|
||||
|
||||
udunits->read_default_xml();
|
||||
}
|
||||
~VariableReference_test() { delete memmgr; }
|
||||
void SetUp() {}
|
||||
void TearDown() {}
|
||||
};
|
@ -0,0 +1,252 @@
|
||||
#include "VariableReference_test.hh"
|
||||
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_int) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a = 5;
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ss.str(), "5");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_int_arr) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a[5] = {1, 2, 3, 4, 5};
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a[5]");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ss.str(), "1,2,3,4,5");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_double) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
double test_a = 867.309;
|
||||
(void) memmgr->declare_extern_var(&test_a, "double test_a");
|
||||
Trick::VariableReference ref_a("test_a");
|
||||
std::stringstream ss_a;
|
||||
|
||||
double test_b = std::numeric_limits<double>::max();
|
||||
(void) memmgr->declare_extern_var(&test_b, "double test_b");
|
||||
Trick::VariableReference ref_b("test_b");
|
||||
std::stringstream ss_b;
|
||||
|
||||
double test_c = std::numeric_limits<double>::min();
|
||||
(void) memmgr->declare_extern_var(&test_c, "double test_c");
|
||||
Trick::VariableReference ref_c("test_c");
|
||||
std::stringstream ss_c;
|
||||
|
||||
// ACT
|
||||
ref_a.stageValue();
|
||||
ref_a.prepareForWrite();
|
||||
ref_a.writeValueAscii(ss_a);
|
||||
|
||||
ref_b.stageValue();
|
||||
ref_b.prepareForWrite();
|
||||
ref_b.writeValueAscii(ss_b);
|
||||
|
||||
ref_c.stageValue();
|
||||
ref_c.prepareForWrite();
|
||||
ref_c.writeValueAscii(ss_c);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ss_a.str(), "867.309");
|
||||
EXPECT_EQ(ss_b.str(), "1.797693134862316e+308");
|
||||
EXPECT_EQ(ss_c.str(), "2.225073858507201e-308");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_char) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
char test_a = 'j';
|
||||
(void) memmgr->declare_extern_var(&test_a, "char test_a");
|
||||
Trick::VariableReference ref_a("test_a");
|
||||
std::stringstream ssa;
|
||||
|
||||
char test_b[7] = "jackie";
|
||||
(void) memmgr->declare_extern_var(&test_b, "char test_b[7]");
|
||||
Trick::VariableReference ref_b("test_b");
|
||||
std::stringstream ssb;
|
||||
|
||||
// ACT
|
||||
ref_a.stageValue();
|
||||
ref_b.stageValue();
|
||||
|
||||
ref_a.prepareForWrite();
|
||||
ref_b.prepareForWrite();
|
||||
|
||||
ref_a.writeValueAscii(ssa);
|
||||
ref_b.writeValueAscii(ssb);
|
||||
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ssa.str(), "106");
|
||||
EXPECT_EQ(ssb.str(), "jackie");
|
||||
}
|
||||
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_unsigned_char) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
unsigned char test_a = 'j';
|
||||
(void) memmgr->declare_extern_var(&test_a, "unsigned char test_a");
|
||||
Trick::VariableReference ref_a("test_a");
|
||||
std::stringstream ssa;
|
||||
|
||||
unsigned char test_b[8] = "jackie\n";
|
||||
(void) memmgr->declare_extern_var(&test_b, "unsigned char test_b[8]");
|
||||
Trick::VariableReference ref_b("test_b");
|
||||
std::stringstream ssb;
|
||||
|
||||
// ACT
|
||||
ref_a.stageValue();
|
||||
ref_b.stageValue();
|
||||
|
||||
ref_a.prepareForWrite();
|
||||
ref_b.prepareForWrite();
|
||||
|
||||
ref_a.writeValueAscii(ssa);
|
||||
ref_b.writeValueAscii(ssb);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ssa.str(), "106");
|
||||
EXPECT_EQ(ssb.str(), "jackie\\n");
|
||||
}
|
||||
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_wide_char) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
wchar_t test_a = L'J';
|
||||
(void) memmgr->declare_extern_var(&test_a, "wchar_t test_a");
|
||||
Trick::VariableReference ref_a("test_a");
|
||||
std::stringstream ssa;
|
||||
|
||||
wchar_t test_b[15] = L"jackiebutwider";
|
||||
(void) memmgr->declare_extern_var(&test_b, "wchar_t test_b[15]");
|
||||
Trick::VariableReference ref_b("test_b");
|
||||
std::stringstream ssb;
|
||||
|
||||
// ACT
|
||||
ref_a.stageValue();
|
||||
ref_b.stageValue();
|
||||
|
||||
ref_a.prepareForWrite();
|
||||
ref_b.prepareForWrite();
|
||||
|
||||
ref_a.writeValueAscii(ssa);
|
||||
ref_b.writeValueAscii(ssb);
|
||||
|
||||
// ASSERT
|
||||
// Original variable server behavior prints individual wchar as its ascii value
|
||||
EXPECT_EQ(ssa.str(), "74");
|
||||
EXPECT_EQ(ssb.str(), "jackiebutwider");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_wide_char_unconstrained) {
|
||||
TestObject obj;
|
||||
obj.wchar_str = (wchar_t *) malloc (sizeof(wchar_t) * 7);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
obj.wchar_str[i] = L'j';
|
||||
}
|
||||
obj.wchar_str[6] = L'\0';
|
||||
(void) memmgr->declare_extern_var(&obj, "TestObject obj");
|
||||
// (void) memmgr->declare_extern_var(&obj.wchar_str, "wchar_t * obj.wchar_str");
|
||||
|
||||
Trick::VariableReference ref("obj.wchar_str");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ss.str(), "jjjjjj");
|
||||
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_std_string) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
std::string test_a = "jackiebutstringy";
|
||||
(void) memmgr->declare_extern_var(&test_a, "std::string test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ss.str(), "jackiebutstringy");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_escape_characters) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
std::string test_a = "\n\t\b\a\"\f\r\v";
|
||||
(void) memmgr->declare_extern_var(&test_a, "std::string test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ss.str(), "\\n\\t\\b\\a\"\\f\\n\\v");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_boolean) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
bool test_a = true;
|
||||
(void) memmgr->declare_extern_var(&test_a, "bool test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ss.str(), "1");
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueAscii_short) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
short test_a = 255;
|
||||
(void) memmgr->declare_extern_var(&test_a, "short test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueAscii(ss);
|
||||
|
||||
// ASSERT
|
||||
EXPECT_EQ(ss.str(), "255");
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
#include "VariableReference_test.hh"
|
||||
|
||||
|
||||
TEST_F(VariableReference_test, writeValueBinary_int) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a = 4095;
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueBinary(ss);
|
||||
|
||||
|
||||
unsigned char expected_bytes[4] = {0xFF, 0x0F, 0x00, 0x00};
|
||||
char * actual_bytes = (char *) malloc (sizeof(int));
|
||||
|
||||
ss.read(actual_bytes, 4);
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < 4; i++) {
|
||||
EXPECT_EQ(static_cast<unsigned char>(actual_bytes[i]), expected_bytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueBinary_float) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
float test_a = 40.95;
|
||||
(void) memmgr->declare_extern_var(&test_a, "float test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueBinary(ss);
|
||||
|
||||
unsigned char expected_bytes[4] = {0xcd, 0xcc, 0x23, 0x42};
|
||||
|
||||
char * actual_bytes = (char *) malloc (sizeof(float));
|
||||
|
||||
ss.read(actual_bytes, 4);
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < 4; i++) {
|
||||
EXPECT_EQ(static_cast<unsigned char>(actual_bytes[i]), expected_bytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeValueBinary_int_arr) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a[3] = {1, 2, 3};
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a[3]");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueBinary(ss);
|
||||
|
||||
// ASSERT
|
||||
char * actual_bytes = (char *) malloc (sizeof(int )* 3);
|
||||
ss.read(actual_bytes, sizeof(int) * 3);
|
||||
unsigned char expected_bytes[12] = {0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00};
|
||||
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < 12; i++) {
|
||||
EXPECT_EQ(static_cast<unsigned char>(actual_bytes[i]), expected_bytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_F(VariableReference_test, writeValueBinary_double_arr) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
double test_a[3] = {1.0, 10.0, 100.0};
|
||||
(void) memmgr->declare_extern_var(&test_a, "double test_a[3]");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueBinary(ss);
|
||||
|
||||
// ASSERT
|
||||
char * actual_bytes = (char *) malloc (sizeof(double )* 3);
|
||||
ss.read(actual_bytes, sizeof(double) * 3);
|
||||
unsigned char expected_bytes[24] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x40};
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < 12; i++) {
|
||||
EXPECT_EQ(static_cast<unsigned char>(actual_bytes[i]), expected_bytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_F(VariableReference_test, writeValueBinary_string) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
std::string test_a = "abcdef";
|
||||
(void) memmgr->declare_extern_var(&test_a, "std::string test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueBinary(ss);
|
||||
|
||||
// ASSERT
|
||||
char * actual_bytes = (char *) malloc (test_a.length());
|
||||
ss.read(actual_bytes, test_a.length());
|
||||
unsigned char expected_bytes[6] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < test_a.length(); i++) {
|
||||
EXPECT_EQ(static_cast<unsigned char>(actual_bytes[i]), expected_bytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(VariableReference_test, writeNameBinary) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
std::string test_a = "abcdef";
|
||||
(void) memmgr->declare_extern_var(&test_a, "std::string test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeNameBinary(ss);
|
||||
|
||||
// ASSERT
|
||||
char * actual_bytes = (char *) malloc (sizeof(int) + strlen(ref.getName()));
|
||||
ss.read(actual_bytes, sizeof(int) + 6);
|
||||
unsigned char expected_bytes[sizeof(int) + 6] = {0x06, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61};
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < sizeof(int) + strlen(ref.getName()); i++) {
|
||||
EXPECT_EQ(static_cast<unsigned char>(actual_bytes[i]), expected_bytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_F(VariableReference_test, writeValueBinaryByteswap_int) {
|
||||
// ARRANGE
|
||||
// Create a variable to make a reference for
|
||||
int test_a = 4095;
|
||||
(void) memmgr->declare_extern_var(&test_a, "int test_a");
|
||||
Trick::VariableReference ref("test_a");
|
||||
std::stringstream ss;
|
||||
|
||||
// ACT
|
||||
ref.stageValue();
|
||||
ref.prepareForWrite();
|
||||
ref.writeValueBinary(ss, true);
|
||||
|
||||
|
||||
unsigned char expected_bytes[4] = {0x00, 0x00, 0x0F, 0xFF};
|
||||
char * actual_bytes = (char *) malloc (sizeof(int));
|
||||
|
||||
ss.read(actual_bytes, 4);
|
||||
|
||||
// ASSERT
|
||||
for (int i = 0; i < 4; i++) {
|
||||
EXPECT_EQ(static_cast<unsigned char>(actual_bytes[i]), expected_bytes[i]);
|
||||
}
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
/******************************TRICK HEADER*************************************
|
||||
PURPOSE: ( Tests for the VariableServerSession class )
|
||||
*******************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "trick/MemoryManager.hh"
|
||||
#include "trick/UdUnits.hh"
|
||||
|
||||
#include "TestConnection.hh"
|
||||
#include "trick/VariableServerSession.hh"
|
||||
#include "trick/var_binary_parser.hh"
|
||||
|
||||
|
||||
/*
|
||||
Test Fixture.
|
||||
*/
|
||||
class VariableServerSession_test : public ::testing::Test {
|
||||
protected:
|
||||
Trick::MemoryManager *memmgr;
|
||||
Trick::UdUnits * udunits;
|
||||
|
||||
TestConnection connection;
|
||||
|
||||
VariableServerSession_test() {
|
||||
memmgr = new Trick::MemoryManager;
|
||||
udunits = new Trick::UdUnits;
|
||||
|
||||
udunits->read_default_xml();
|
||||
}
|
||||
~VariableServerSession_test() { delete memmgr; }
|
||||
void SetUp() {}
|
||||
void TearDown() {}
|
||||
};
|
||||
|
||||
TEST_F(VariableServerSession_test, toString) {
|
||||
|
||||
int a = 5;
|
||||
double b = 6;
|
||||
std::string c = "Hello";
|
||||
(void) memmgr->declare_extern_var(&a, "int a");
|
||||
(void) memmgr->declare_extern_var(&b, "double b");
|
||||
(void) memmgr->declare_extern_var(&c, "std::string c");
|
||||
|
||||
Trick::VariableServerSession session(&connection);
|
||||
|
||||
session.var_add("a");
|
||||
session.var_add("b");
|
||||
session.var_add("c");
|
||||
session.var_binary();
|
||||
|
||||
std::stringstream ss;
|
||||
ss << session;
|
||||
|
||||
std::string expected = " \"format\":\"BINARY\",\n \"update_rate\":0.1,\n \"variables\":[\n \"a\",\n \"b\",\n \"c\"\n ]\n";
|
||||
EXPECT_EQ(ss.str(), expected);
|
||||
|
||||
session.var_ascii();
|
||||
expected = " \"format\":\"ASCII\",\n \"update_rate\":0.1,\n \"variables\":[\n \"a\",\n \"b\",\n \"c\"\n ]\n";
|
||||
ss.str("");
|
||||
ss << session;
|
||||
EXPECT_EQ(ss.str(), expected);
|
||||
}
|
||||
|
||||
TEST_F(VariableServerSession_test, var_sync) {
|
||||
// ARRANGE
|
||||
Trick::VariableServerSession session(&connection);
|
||||
|
||||
|
||||
// ACT
|
||||
session.var_sync(0);
|
||||
// ASSERT
|
||||
ASSERT_EQ(session.get_copy_mode(), VS_COPY_ASYNC);
|
||||
ASSERT_EQ(session.get_write_mode(), VS_WRITE_ASYNC);
|
||||
|
||||
|
||||
// ACT
|
||||
session.var_sync(1);
|
||||
// ASSERT
|
||||
ASSERT_EQ(session.get_copy_mode(), VS_COPY_SCHEDULED);
|
||||
ASSERT_EQ(session.get_write_mode(), VS_WRITE_ASYNC);
|
||||
|
||||
// ACT
|
||||
session.var_sync(2);
|
||||
// ASSERT
|
||||
ASSERT_EQ(session.get_copy_mode(), VS_COPY_SCHEDULED);
|
||||
ASSERT_EQ(session.get_write_mode(), VS_WRITE_WHEN_COPIED);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(VariableServerSession_test, large_message_ascii) {
|
||||
// ARRANGE
|
||||
Trick::VariableServerSession session(&connection);
|
||||
|
||||
const static int big_arr_size = 4000;
|
||||
// Make an array too big to fit in a single message
|
||||
|
||||
int big_arr[big_arr_size];
|
||||
for (int i = 0; i < big_arr_size; i++) {
|
||||
big_arr[i] = i;
|
||||
}
|
||||
|
||||
(void) memmgr->declare_extern_var(&big_arr, "int big_arr[4000]");
|
||||
|
||||
for (int i = 0; i < big_arr_size; i++) {
|
||||
std::string var_name = "big_arr[" + std::to_string(i) + "]";
|
||||
session.var_add(var_name.c_str());
|
||||
}
|
||||
|
||||
// ACT
|
||||
session.copy_sim_data();
|
||||
session.write_data();
|
||||
|
||||
// ASSERT
|
||||
ASSERT_TRUE(connection.ascii_messages_written.size() > 1);
|
||||
int counter = 0;
|
||||
|
||||
int message_index = 0;
|
||||
for (int i = 0; i < connection.ascii_messages_written.size(); i++) {
|
||||
std::string message = connection.ascii_messages_written[i];
|
||||
std::stringstream ss(message);
|
||||
std::string token;
|
||||
|
||||
// First val in first message should be the message type, 0
|
||||
if (i == 0) {
|
||||
std::getline(ss, token, '\t');
|
||||
int message_type = stoi(token);
|
||||
EXPECT_EQ(message_type, 0);
|
||||
}
|
||||
|
||||
while (std::getline(ss, token, '\t')) {
|
||||
if (token == "\n") { break; }
|
||||
|
||||
int num = stoi(token);
|
||||
EXPECT_EQ(counter, num);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, big_arr_size);
|
||||
}
|
||||
|
||||
TEST_F(VariableServerSession_test, large_message_binary) {
|
||||
// ARRANGE
|
||||
Trick::VariableServerSession session(&connection);
|
||||
session.var_binary();
|
||||
|
||||
const static int big_arr_size = 4000;
|
||||
// Make an array too big to fit in a single message
|
||||
|
||||
int big_arr[big_arr_size];
|
||||
for (int i = 0; i < big_arr_size; i++) {
|
||||
big_arr[i] = i;
|
||||
}
|
||||
|
||||
(void) memmgr->declare_extern_var(&big_arr, "int big_arr[4000]");
|
||||
|
||||
for (int i = 0; i < big_arr_size; i++) {
|
||||
std::string var_name = "big_arr[" + std::to_string(i) + "]";
|
||||
session.var_add(var_name.c_str());
|
||||
}
|
||||
|
||||
// ACT
|
||||
session.copy_sim_data();
|
||||
session.write_data();
|
||||
|
||||
// ASSERT
|
||||
ParsedBinaryMessage full_message;
|
||||
for (int i = 0; i < connection.binary_messages_written.size(); i++) {
|
||||
ParsedBinaryMessage partial_message;
|
||||
partial_message.parse(connection.binary_messages_written[i]);
|
||||
full_message.combine(partial_message);
|
||||
}
|
||||
|
||||
ASSERT_EQ(full_message.getNumVars(), big_arr_size);
|
||||
for (int i = 0; i < big_arr_size; i++) {
|
||||
try {
|
||||
std::string var_name = "big_arr[" + std::to_string(i) + "]";
|
||||
Var variable = full_message.getVariable(var_name);
|
||||
|
||||
EXPECT_EQ(variable.getValue<int>(), i);
|
||||
} catch (std::exception& ex) {
|
||||
FAIL() << ex.what();
|
||||
}
|
||||
}
|
||||
}
|
@ -11,161 +11,215 @@
|
||||
|
||||
extern Trick::VariableServer * the_vs ;
|
||||
|
||||
int command_debug = 0;
|
||||
|
||||
Trick::VariableServerThread * get_vst() {
|
||||
return the_vs->get_vst(pthread_self()) ;
|
||||
}
|
||||
|
||||
Trick::VariableServerSession * get_session() {
|
||||
return the_vs->get_session(pthread_self()) ;
|
||||
}
|
||||
|
||||
int var_add(std::string in_name) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_add(in_name) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_add: " << in_name << std::endl;
|
||||
}
|
||||
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_add(in_name) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_add(std::string in_name, std::string in_units) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_add(in_name, in_units) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_add: " << in_name << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_add(in_name, in_units) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_remove(std::string in_name) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_remove(in_name) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_remove: " << in_name << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_remove(in_name) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_units(std::string var_name , std::string units_name) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_units(var_name , units_name) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_units: " << var_name << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_units(var_name , units_name) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_exists(std::string in_name) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_exists(in_name) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_exists: " << in_name << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_exists(in_name) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_send_once(std::string in_name) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_send_once(in_name, 1) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_send_once: " << in_name << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_send_once(in_name, 1) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_send_once(std::string in_name, int num) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_send_once(in_name, num) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_send_once: " << in_name << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_send_once(in_name, num) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_send() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_send() ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_send: " << std::endl;
|
||||
}
|
||||
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_send() ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_clear() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_clear() ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_clear: " << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_clear() ;
|
||||
}
|
||||
|
||||
// std::cout << "Done with var_clear" << std::endl;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_cycle(double in_rate) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_cycle(in_rate) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_cycle: " << in_rate << std::endl;
|
||||
}
|
||||
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_cycle(in_rate) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_pause() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->set_pause(true) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_pause" << std::endl;
|
||||
}
|
||||
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->set_pause(true) ;
|
||||
}
|
||||
return(0) ;
|
||||
|
||||
}
|
||||
|
||||
int var_unpause() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->set_pause(false) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_unpause" << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->set_pause(false) ;
|
||||
}
|
||||
return(0) ;
|
||||
|
||||
}
|
||||
|
||||
int var_exit() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_exit() ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_exit" << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_exit() ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_validate_address(int on_off) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_validate_address((bool)on_off) ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_validate_address" << std::endl;
|
||||
}
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_validate_address((bool)on_off) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_debug(int level) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_debug(level) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_debug(level) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_ascii() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_ascii() ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_ascii() ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_binary() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_binary() ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_binary() ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
@ -176,19 +230,19 @@ int var_retry_bad_ref() {
|
||||
}
|
||||
|
||||
int var_binary_nonames() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_binary_nonames() ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_binary_nonames() ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_set_copy_mode(int mode) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_set_copy_mode(mode) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
|
||||
if (session != NULL ) {
|
||||
session->var_set_copy_mode(mode) ;
|
||||
if ( mode == VS_COPY_SCHEDULED ) {
|
||||
the_vs->get_next_sync_call_time() ;
|
||||
the_vs->get_next_freeze_call_time() ;
|
||||
@ -198,28 +252,25 @@ int var_set_copy_mode(int mode) {
|
||||
}
|
||||
|
||||
int var_set_write_mode(int mode) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_set_write_mode(mode) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->var_set_write_mode(mode) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int var_set_send_stdio(int mode) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->set_send_stdio((bool)mode) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->set_send_stdio((bool)mode) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int var_sync(int mode) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_sync(mode) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->var_sync(mode) ;
|
||||
if ( mode ) {
|
||||
the_vs->get_next_sync_call_time() ;
|
||||
the_vs->get_next_freeze_call_time() ;
|
||||
@ -229,73 +280,66 @@ int var_sync(int mode) {
|
||||
}
|
||||
|
||||
int var_set_frame_multiple(unsigned int mult) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_set_frame_multiple(mult) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->var_set_frame_multiple(mult) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int var_set_frame_offset(unsigned int offset) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_set_frame_offset(offset) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->var_set_frame_offset(offset) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int var_set_freeze_frame_multiple(unsigned int mult) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_set_freeze_frame_multiple(mult) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->var_set_freeze_frame_multiple(mult) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int var_set_freeze_frame_offset(unsigned int offset) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_set_freeze_frame_offset(offset) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->var_set_freeze_frame_offset(offset) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int var_byteswap(bool on_off) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_byteswap(on_off) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->var_byteswap(on_off) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int var_signal() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_signal() ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
// int var_signal() {
|
||||
// Trick::VariableServerSession * session = get_session();
|
||||
// if (session != NULL ) {
|
||||
// session->var_signal() ;
|
||||
// }
|
||||
// return(0) ;
|
||||
// }
|
||||
|
||||
int var_multicast(bool on_off) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->var_multicast(on_off) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
// int var_multicast(bool on_off) {
|
||||
// Trick::VariableServerSession * session = get_session();
|
||||
// if (session != NULL ) {
|
||||
// session->var_multicast(on_off) ;
|
||||
// }
|
||||
// return(0) ;
|
||||
// }
|
||||
|
||||
int var_write_stdio(int stream , std::string text ) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL and vst->get_send_stdio() == true) {
|
||||
vst->write_stdio(stream, text) ;
|
||||
// std::cout << "Executing var_write_stdio" << std::endl;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL and session->get_send_stdio() == true) {
|
||||
session->write_stdio(stream, text) ;
|
||||
} else {
|
||||
if ( stream == 1 ) {
|
||||
fprintf( stdout , "%s" , text.c_str() ) ;
|
||||
@ -307,14 +351,14 @@ int var_write_stdio(int stream , std::string text ) {
|
||||
}
|
||||
|
||||
int var_set_client_tag( std::string text ) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_set_client_tag: " << text << std::endl;
|
||||
}
|
||||
Trick::VariableServerThread * vst = get_vst();
|
||||
if (vst != NULL) {
|
||||
// tag char declared length is 80
|
||||
if (text.length()>=80) {
|
||||
text.resize(79);
|
||||
}
|
||||
strcpy(vst->get_connection().client_tag, text.c_str());
|
||||
|
||||
vst->set_client_tag(text);
|
||||
|
||||
#if __linux
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 2
|
||||
@ -328,55 +372,53 @@ int var_set_client_tag( std::string text ) {
|
||||
}
|
||||
|
||||
int var_send_list_size() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->send_list_size() ;
|
||||
if (command_debug) {
|
||||
std::cout << "var_send_list_size" << std::endl;
|
||||
}
|
||||
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->send_list_size() ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
int send_sie_resource() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->send_sie_resource() ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->send_sie_resource() ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int send_sie_class() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->send_sie_class() ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->send_sie_class() ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int send_sie_enum() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
vst->send_sie_enum() ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
session->send_sie_enum() ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int send_sie_top_level_objects() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
return vst->send_sie_top_level_objects() ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
return session->send_sie_top_level_objects() ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int send_file(std::string file_name) {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
return vst->send_file(file_name) ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
return session->send_file(file_name) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
@ -384,20 +426,18 @@ int send_file(std::string file_name) {
|
||||
|
||||
// Command to turn on log to playback file
|
||||
int var_server_log_on() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
return vst->set_log_on() ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
return session->set_log_on() ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
// Command to turn off log to playback file
|
||||
int var_server_log_off() {
|
||||
Trick::VariableServerThread * vst ;
|
||||
vst = get_vst() ;
|
||||
if (vst != NULL ) {
|
||||
return vst->set_log_off() ;
|
||||
Trick::VariableServerSession * session = get_session();
|
||||
if (session != NULL ) {
|
||||
return session->set_log_off() ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
@ -416,7 +456,9 @@ extern "C" void var_server_list_connections(void) {
|
||||
* C wrapper Trick::VariableServer::get_hostname
|
||||
*/
|
||||
extern "C" const char * var_server_get_hostname(void) {
|
||||
return(the_vs->get_hostname()) ;
|
||||
const char * ret = (the_vs->get_hostname()) ;
|
||||
printf("varserverext: %s", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -556,8 +598,10 @@ int var_set_base( const char * var , T value , const char * units ) {
|
||||
ref_assignment(ref , &v_tree) ;
|
||||
if(ref->units != NULL) {
|
||||
free(ref->units) ;
|
||||
ref->units = NULL;
|
||||
}
|
||||
free(ref) ;
|
||||
ref = NULL;
|
||||
} else {
|
||||
message_publish(MSG_WARNING,"Cannot assign to %s because io_spec does not allow input\n", var) ;
|
||||
}
|
||||
|
@ -1,265 +0,0 @@
|
||||
/*
|
||||
PURPOSE: (Allows clients to get and set Trick parameters)
|
||||
PROGRAMMERS: (((Keith Vetter) (LinCom) (September 2001) (--)))
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits>
|
||||
#include <udunits2.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "trick/parameter_types.h"
|
||||
#include "trick/attributes.h"
|
||||
#include "trick/bitfield_proto.h"
|
||||
#include "trick/wcs_ext.h"
|
||||
#include "trick/VariableServer.hh"
|
||||
#include "trick/TrickConstant.hh"
|
||||
|
||||
/* PROTO */
|
||||
size_t escape_str(const char *in_s, char *out_s);
|
||||
|
||||
#define MAX_VAL_STRLEN 2048
|
||||
|
||||
int vs_format_ascii(Trick::VariableReference * var, char *value, size_t value_size) {
|
||||
|
||||
/* for string types, return -1 if string is too big to fit in buffer (MAX_VAL_STRLEN) */
|
||||
REF2 * ref ;
|
||||
ref = var->ref ;
|
||||
std::string var_name = ref->reference;
|
||||
|
||||
// handle returning an array
|
||||
int size = 0 ;
|
||||
value[0] = '\0' ;
|
||||
|
||||
// data to send was copied to buffer in copy_sim_data
|
||||
void * buf_ptr = var->buffer_out ;
|
||||
while (size < var->size) {
|
||||
size += var->ref->attr->size ;
|
||||
char temp_buf[MAX_VAL_STRLEN];
|
||||
|
||||
switch (ref->attr->type) {
|
||||
|
||||
case TRICK_CHARACTER:
|
||||
if (ref->attr->num_index == ref->num_index) {
|
||||
snprintf(temp_buf, value_size, "%d",(char)cv_convert_double(var->conversion_factor, *(char *)buf_ptr));
|
||||
} else {
|
||||
/* All but last dim specified, leaves a char array */
|
||||
escape_str((char *) buf_ptr, temp_buf);
|
||||
size = var->size ;
|
||||
}
|
||||
break;
|
||||
case TRICK_UNSIGNED_CHARACTER:
|
||||
if (ref->attr->num_index == ref->num_index) {
|
||||
snprintf(temp_buf, value_size, "%u",(unsigned char)cv_convert_double(var->conversion_factor,*(unsigned char *)buf_ptr));
|
||||
} else {
|
||||
/* All but last dim specified, leaves a char array */
|
||||
escape_str((char *) buf_ptr, temp_buf);
|
||||
size = var->size ;
|
||||
}
|
||||
break;
|
||||
|
||||
case TRICK_WCHAR:{
|
||||
if (ref->attr->num_index == ref->num_index) {
|
||||
snprintf(temp_buf, value_size, "%d",*(wchar_t *) buf_ptr);
|
||||
} else {
|
||||
// convert wide char string char string
|
||||
size_t len = wcs_to_ncs_len((wchar_t *)buf_ptr) + 1 ;
|
||||
if (len > MAX_VAL_STRLEN) {
|
||||
return (-1);
|
||||
}
|
||||
wcs_to_ncs((wchar_t *) buf_ptr, temp_buf, len);
|
||||
size = var->size ;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TRICK_STRING:
|
||||
if ((char *) buf_ptr != NULL) {
|
||||
escape_str((char *) buf_ptr, temp_buf);
|
||||
size = var->size ;
|
||||
} else {
|
||||
temp_buf[0] = '\0';
|
||||
}
|
||||
break;
|
||||
|
||||
case TRICK_WSTRING:
|
||||
if ((wchar_t *) buf_ptr != NULL) {
|
||||
// convert wide char string char string
|
||||
size_t len = wcs_to_ncs_len((wchar_t *)buf_ptr) + 1 ;
|
||||
if (len > MAX_VAL_STRLEN) {
|
||||
return (-1);
|
||||
}
|
||||
wcs_to_ncs((wchar_t *) buf_ptr, temp_buf, len);
|
||||
size = var->size ;
|
||||
} else {
|
||||
temp_buf[0] = '\0';
|
||||
}
|
||||
break;
|
||||
|
||||
#if ( __linux | __sgi )
|
||||
case TRICK_BOOLEAN:
|
||||
snprintf(temp_buf, value_size, "%d",(unsigned char)cv_convert_double(var->conversion_factor,*(unsigned char *)buf_ptr));
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TRICK_SHORT:
|
||||
snprintf(temp_buf, value_size, "%d", (short)cv_convert_double(var->conversion_factor,*(short *)buf_ptr));
|
||||
break;
|
||||
|
||||
case TRICK_UNSIGNED_SHORT:
|
||||
snprintf(temp_buf, value_size, "%u",(unsigned short)cv_convert_double(var->conversion_factor,*(unsigned short *)buf_ptr));
|
||||
break;
|
||||
|
||||
case TRICK_INTEGER:
|
||||
case TRICK_ENUMERATED:
|
||||
#if ( __sun | __APPLE__ )
|
||||
case TRICK_BOOLEAN:
|
||||
#endif
|
||||
snprintf(temp_buf, value_size, "%d", (int)cv_convert_double(var->conversion_factor,*(int *)buf_ptr));
|
||||
break;
|
||||
|
||||
case TRICK_BITFIELD:
|
||||
snprintf(temp_buf, value_size, "%d", GET_BITFIELD(buf_ptr, ref->attr->size, ref->attr->index[0].start, ref->attr->index[0].size));
|
||||
break;
|
||||
|
||||
case TRICK_UNSIGNED_BITFIELD:
|
||||
snprintf(temp_buf, value_size, "%u", GET_UNSIGNED_BITFIELD(buf_ptr, ref->attr->size, ref->attr->index[0].start, ref->attr->index[0].size));
|
||||
break;
|
||||
case TRICK_UNSIGNED_INTEGER:
|
||||
snprintf(temp_buf, value_size, "%u", (unsigned int)cv_convert_double(var->conversion_factor,*(unsigned int *)buf_ptr));
|
||||
break;
|
||||
|
||||
case TRICK_LONG: {
|
||||
long l = *(long *)buf_ptr;
|
||||
if (var->conversion_factor != cv_get_trivial()) {
|
||||
l = (long)cv_convert_double(var->conversion_factor, l);
|
||||
}
|
||||
snprintf(temp_buf, value_size, "%ld", l);
|
||||
break;
|
||||
}
|
||||
|
||||
case TRICK_UNSIGNED_LONG: {
|
||||
unsigned long ul = *(unsigned long *)buf_ptr;
|
||||
if (var->conversion_factor != cv_get_trivial()) {
|
||||
ul = (unsigned long)cv_convert_double(var->conversion_factor, ul);
|
||||
}
|
||||
snprintf(temp_buf, value_size, "%lu", ul);
|
||||
break;
|
||||
}
|
||||
|
||||
case TRICK_FLOAT:
|
||||
snprintf(temp_buf, value_size, "%.8g", cv_convert_float(var->conversion_factor,*(float *)buf_ptr));
|
||||
break;
|
||||
|
||||
case TRICK_DOUBLE:
|
||||
snprintf(temp_buf, value_size, "%.16g", cv_convert_double(var->conversion_factor,*(double *)buf_ptr));
|
||||
break;
|
||||
|
||||
case TRICK_LONG_LONG: {
|
||||
long long ll = *(long long *)buf_ptr;
|
||||
if (var->conversion_factor != cv_get_trivial()) {
|
||||
ll = (long long)cv_convert_double(var->conversion_factor, ll);
|
||||
}
|
||||
snprintf(temp_buf, value_size, "%lld", ll);
|
||||
break;
|
||||
}
|
||||
|
||||
case TRICK_UNSIGNED_LONG_LONG: {
|
||||
unsigned long long ull = *(unsigned long long *)buf_ptr;
|
||||
if (var->conversion_factor != cv_get_trivial()) {
|
||||
ull = (unsigned long long)cv_convert_double(var->conversion_factor, ull);
|
||||
}
|
||||
snprintf(temp_buf, value_size, "%llu", ull);
|
||||
break;
|
||||
}
|
||||
|
||||
case TRICK_NUMBER_OF_TYPES:
|
||||
snprintf(temp_buf, value_size, "BAD_REF" );
|
||||
break;
|
||||
|
||||
default:{
|
||||
return (-1);
|
||||
}
|
||||
} // end switch
|
||||
|
||||
if (size < var->size) {
|
||||
// if returning an array, continue array as comma separated values
|
||||
strcat(temp_buf, ",") ;
|
||||
buf_ptr = (void*) ((long)buf_ptr + var->ref->attr->size) ;
|
||||
}
|
||||
strncat(value, temp_buf, value_size - strlen(value) - 1);
|
||||
} //end while
|
||||
|
||||
if (ref->units) {
|
||||
std::stringstream unit_str;
|
||||
if ( ref->attr->mods & TRICK_MODS_UNITSDASHDASH ) {
|
||||
unit_str << " {--}";
|
||||
} else {
|
||||
unit_str << " {" << ref->units << "}";
|
||||
|
||||
}
|
||||
size_t max_copy_size = value_size - strlen(value) - 1;
|
||||
strncat(value, unit_str.str().c_str(), max_copy_size);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escape all of the non printable characters in a string.
|
||||
*/
|
||||
size_t escape_str(const char *in_s, char *out_s)
|
||||
{
|
||||
size_t i, in_len, out_len;
|
||||
if (in_s == NULL) {
|
||||
out_s[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
in_len = strlen(in_s);
|
||||
out_len = 0;
|
||||
if (out_s != NULL) {
|
||||
out_s[0] = '\0';
|
||||
}
|
||||
for (i = 0; i < in_len; i++) {
|
||||
int ch = in_s[i];
|
||||
char work_s[6];
|
||||
|
||||
if (isprint(ch)) {
|
||||
work_s[0] = ch;
|
||||
work_s[1] = '\0';
|
||||
} else {
|
||||
if (ch == '\a') {
|
||||
snprintf(work_s, sizeof(work_s), "\\a");
|
||||
} else if (ch == '\b') {
|
||||
snprintf(work_s, sizeof(work_s), "\\b");
|
||||
} else if (ch == '\f') {
|
||||
snprintf(work_s, sizeof(work_s), "\\f");
|
||||
} else if (ch == '\n') {
|
||||
snprintf(work_s, sizeof(work_s), "\\n");
|
||||
} else if (ch == '\r') {
|
||||
snprintf(work_s, sizeof(work_s), "\\n");
|
||||
} else if (ch == '\t') {
|
||||
snprintf(work_s, sizeof(work_s), "\\t");
|
||||
} else if (ch == '\v') {
|
||||
snprintf(work_s, sizeof(work_s), "\\v");
|
||||
} else {
|
||||
snprintf(work_s, sizeof(work_s), "\\x%02x", ch);
|
||||
}
|
||||
}
|
||||
out_len += strlen(work_s);
|
||||
if (out_s != NULL) {
|
||||
if (out_len < MAX_VAL_STRLEN) {
|
||||
strcat(out_s, work_s);
|
||||
} else {
|
||||
// indicate string is truncated because it's too big
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (out_len);
|
||||
}
|
@ -23,6 +23,9 @@ add_library( trick_utils_objs OBJECT ${TRICK_UTILS_SRC} )
|
||||
###############################################################
|
||||
|
||||
add_subdirectory(comm)
|
||||
add_subdirectory(connection_handlers)
|
||||
add_subdirectory(math)
|
||||
add_subdirectory(units)
|
||||
add_subdirectory(var_binary_parser)
|
||||
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
#include "trick/ClientConnection.hh"
|
115
trick_source/trick_utils/connection_handlers/ClientListener.cpp
Normal file
115
trick_source/trick_utils/connection_handlers/ClientListener.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "trick/ClientListener.hh"
|
||||
#include "trick/tc_proto.h"
|
||||
|
||||
|
||||
|
||||
Trick::ClientListener::ClientListener () : _listen_dev(), initialized(false) {
|
||||
char hname[80];
|
||||
gethostname(hname , (size_t) 80 ) ;
|
||||
saved_source = std::string(hname);
|
||||
strcpy(_listen_dev.client_tag, "<empty>");
|
||||
tc_error(&_listen_dev, 0);
|
||||
}
|
||||
|
||||
Trick::ClientListener::~ClientListener () {
|
||||
|
||||
}
|
||||
|
||||
int Trick::ClientListener::initialize(std::string hostname, int port) {
|
||||
int ret = tc_init_with_connection_info(&_listen_dev, AF_INET, SOCK_STREAM, hostname.c_str(), port);
|
||||
initialized = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Trick::ClientListener::initialize() {
|
||||
int ret = tc_init(&_listen_dev);
|
||||
if (ret != TC_SUCCESS) {
|
||||
|
||||
fprintf(stderr, "ERROR: Could not establish listen port for Variable Server. Aborting.\n");
|
||||
ret = -1 ;
|
||||
}
|
||||
initialized = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int Trick::ClientListener::setBlockMode(TCCommBlocking mode) {
|
||||
if (!initialized)
|
||||
return -1;
|
||||
|
||||
return tc_blockio(&_listen_dev, mode);
|
||||
}
|
||||
|
||||
|
||||
bool Trick::ClientListener::checkForNewConnections() {
|
||||
if (!initialized)
|
||||
return -1;
|
||||
|
||||
fd_set rfds;
|
||||
struct timeval timeout_time = { 2, 0 };
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(_listen_dev.socket, &rfds);
|
||||
timeout_time.tv_sec = 2 ;
|
||||
select(_listen_dev.socket + 1, &rfds, NULL, NULL, &timeout_time);
|
||||
|
||||
return FD_ISSET(_listen_dev.socket, &rfds);
|
||||
}
|
||||
|
||||
|
||||
const char * Trick::ClientListener::getHostname () {
|
||||
if (!initialized)
|
||||
return "";
|
||||
|
||||
return _listen_dev.hostname;
|
||||
}
|
||||
|
||||
|
||||
int Trick::ClientListener::getPort() {
|
||||
if (!initialized)
|
||||
return -1;
|
||||
|
||||
return _listen_dev.port;
|
||||
}
|
||||
|
||||
|
||||
int Trick::ClientListener::disconnect() {
|
||||
if (!initialized)
|
||||
return -1;
|
||||
|
||||
return tc_disconnect(&_listen_dev) ;
|
||||
}
|
||||
|
||||
bool Trick::ClientListener::validateSourceAddress(std::string requested_source_address) {
|
||||
char hname[80];
|
||||
static struct sockaddr_in s_in;
|
||||
gethostname(hname, (size_t) 80);
|
||||
|
||||
// Test to see if the restart address is on this machine. If it is not, it's not an error
|
||||
if ( strcmp( requested_source_address.c_str(), hname )) {
|
||||
if (! inet_pton(AF_INET, requested_source_address.c_str(), (struct in_addr *)&s_in.sin_addr.s_addr) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int Trick::ClientListener::checkSocket() {
|
||||
if (!initialized)
|
||||
return -1;
|
||||
|
||||
struct sockaddr_in s_in;
|
||||
int s_in_size = sizeof(s_in) ;
|
||||
getsockname( _listen_dev.socket , (struct sockaddr *)&s_in, (socklen_t *)&s_in_size) ;
|
||||
printf("restart variable server message port = %d\n" , ntohs(s_in.sin_port)) ;
|
||||
_listen_dev.port = ntohs(s_in.sin_port);
|
||||
}
|
||||
|
||||
bool Trick::ClientListener::isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
15
trick_source/trick_utils/connection_handlers/Makefile
Normal file
15
trick_source/trick_utils/connection_handlers/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
TRICK_HOME := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))../../..)
|
||||
|
||||
# set CONFIG_MK to allow compilation without running configure
|
||||
CONFIG_MK = 1
|
||||
|
||||
include ${TRICK_HOME}/share/trick/makefiles/Makefile.common
|
||||
# set the TRICK_LIB variable to create a separate library for comm
|
||||
TRICK_LIB := $(TRICK_LIB_DIR)/libtrick_connection_handlers.a
|
||||
include ${TRICK_HOME}/share/trick/makefiles/Makefile.tricklib
|
||||
-include Makefile_deps
|
||||
|
||||
TRICK_CXXFLAGS += -std=c++11
|
||||
|
||||
# make the comm library when called by the master makefile.
|
||||
trick: ${TRICK_LIB}
|
@ -0,0 +1,63 @@
|
||||
#include "trick/MulticastManager.hh"
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
Trick::MulticastManager::MulticastManager() {
|
||||
}
|
||||
|
||||
Trick::MulticastManager::~MulticastManager() {
|
||||
|
||||
}
|
||||
|
||||
int Trick::MulticastManager::restart () {
|
||||
// Keep address list the same, but we may need to get a new socket
|
||||
return initialize();
|
||||
}
|
||||
|
||||
|
||||
int Trick::MulticastManager::broadcast (std::string message) {
|
||||
if (!is_initialized()) {
|
||||
initialize();
|
||||
}
|
||||
const char * message_send = message.c_str();
|
||||
for (struct sockaddr_in& address : addresses) {
|
||||
sendto(mcast_socket , message_send , strlen(message_send) , 0 , (struct sockaddr *)&address , (socklen_t)sizeof(address)) ;
|
||||
}
|
||||
}
|
||||
|
||||
int Trick::MulticastManager::addAddress (std::string addr, int port) {
|
||||
|
||||
struct sockaddr_in mcast_addr;
|
||||
memset(&mcast_addr, 0, sizeof(mcast_addr));
|
||||
mcast_addr.sin_family = AF_INET;
|
||||
mcast_addr.sin_addr.s_addr = inet_addr(addr.c_str());
|
||||
mcast_addr.sin_port = htons((uint16_t) port);
|
||||
addresses.emplace_back(mcast_addr);
|
||||
}
|
||||
|
||||
int Trick::MulticastManager::is_initialized () {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
int Trick::MulticastManager::initialize() {
|
||||
|
||||
mcast_socket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (mcast_socket < 0) {
|
||||
perror("vs_mcast_init socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int option_value = 1;
|
||||
if (setsockopt(mcast_socket, SOL_SOCKET, SO_REUSEADDR, (char *) &option_value, (socklen_t) sizeof(option_value)) < 0) {
|
||||
perror("setsockopt: reuseaddr");
|
||||
return -1;
|
||||
}
|
||||
#ifdef SO_REUSEPORT
|
||||
if (setsockopt(mcast_socket, SOL_SOCKET, SO_REUSEPORT, (char *) &option_value, sizeof(option_value)) < 0) {
|
||||
perror("setsockopt: reuseport");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
initialized = 1;
|
||||
return 0;
|
||||
}
|
117
trick_source/trick_utils/connection_handlers/TCConnection.cpp
Normal file
117
trick_source/trick_utils/connection_handlers/TCConnection.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include "trick/TCConnection.hh"
|
||||
#include "trick/tc.h"
|
||||
#include "trick/tc_proto.h"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
Trick::TCConnection::TCConnection () {}
|
||||
|
||||
int Trick::accept(ClientListener *listener, Trick::TCConnection *connection) {
|
||||
if (!listener->isInitialized())
|
||||
return -1;
|
||||
|
||||
if ( listener->_listen_dev.socket_type == SOCK_STREAM ) {
|
||||
return tc_accept(&(listener->_listen_dev), &(connection->_device));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Trick::TCConnection::initialize() {
|
||||
_device.disabled = TC_COMM_FALSE ;
|
||||
_device.disable_handshaking = TC_COMM_TRUE ;
|
||||
_device.blockio_limit = 0.0 ;
|
||||
_device.blockio_type = TC_COMM_BLOCKIO ;
|
||||
_device.client_id = 0 ;
|
||||
strcpy(_device.client_tag, "") ;
|
||||
_device.error_handler = (TrickErrorHndlr *) calloc(1, (int)sizeof(TrickErrorHndlr));
|
||||
_device.error_handler->report_level = TRICK_ERROR_CAUTION;
|
||||
}
|
||||
|
||||
int Trick::TCConnection::write (char * message, int size) {
|
||||
int ret = tc_write(&_device, message, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Trick::TCConnection::write (const std::string& message) {
|
||||
char send_buf[message.length()+1];
|
||||
strcpy (send_buf, message.c_str());
|
||||
int ret = tc_write(&_device, send_buf, message.length());
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string Trick::TCConnection::read (int max_len) {
|
||||
char incoming_msg[max_len];
|
||||
int nbytes = recvfrom( _device.socket, incoming_msg, MAX_CMD_LEN, MSG_PEEK, NULL, NULL ) ;
|
||||
if (nbytes == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nbytes != -1) { // -1 means socket is nonblocking and no data to read
|
||||
/* find the last newline that is present on the socket */
|
||||
incoming_msg[nbytes] = '\0' ;
|
||||
char *last_newline = rindex( incoming_msg , '\n') ;
|
||||
|
||||
/* if there is a newline then there is a complete command on the socket */
|
||||
if ( last_newline != NULL ) {
|
||||
/* only remove up to (and including) the last newline on the socket */
|
||||
int size = last_newline - incoming_msg + 1;
|
||||
nbytes = recvfrom( _device.socket, incoming_msg, size, 0 , NULL, NULL ) ;
|
||||
} else {
|
||||
nbytes = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream msg_stream;
|
||||
|
||||
if ( nbytes > 0 ) {
|
||||
|
||||
int msg_len = nbytes ;
|
||||
// if (debug >= 3) {
|
||||
// message_publish(MSG_DEBUG, "%p tag=<%s> var_server received bytes = msg_len = %d\n", &_device, _device.client_tag, nbytes);
|
||||
// }
|
||||
|
||||
incoming_msg[msg_len] = '\0' ;
|
||||
|
||||
for( int ii = 0 , jj = 0 ; ii <= msg_len ; ii++ ) {
|
||||
if ( incoming_msg[ii] != '\r' ) {
|
||||
msg_stream << incoming_msg[ii] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return msg_stream.str();
|
||||
}
|
||||
|
||||
|
||||
std::string Trick::TCConnection::get_client_tag () {
|
||||
return std::string(_device.client_tag);
|
||||
}
|
||||
|
||||
int Trick::TCConnection::set_client_tag(std::string tag) {
|
||||
// Max size of device client tag is 80
|
||||
|
||||
// TODO: Make 80 a constant somewhere, probably in TC device
|
||||
if (tag.length() >= 80) {
|
||||
tag.resize(79);
|
||||
}
|
||||
strcpy(_device.client_tag, tag.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Trick::TCConnection::get_socket() {
|
||||
return _device.socket;
|
||||
}
|
||||
|
||||
|
||||
int Trick::TCConnection::disconnect () {
|
||||
return tc_disconnect(&_device);
|
||||
}
|
||||
|
||||
int Trick::TCConnection::setBlockMode(int block_mode) {
|
||||
return tc_blockio(&_device, (TCCommBlocking)block_mode);
|
||||
}
|
||||
|
||||
int Trick::TCConnection::setErrorReporting (bool on) {
|
||||
return tc_error(&_device, (int)on);
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*************************************************************************
|
||||
PURPOSE: (Represent the state of a variable server websocket connection.)
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef WSSESSION_HH
|
||||
#define WSSESSION_HH
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifndef SWIG
|
||||
#include "CivetServer.h"
|
||||
#endif
|
||||
|
||||
#include "trick/WebSocketSession.hh"
|
||||
#include "VariableServerVariable.hh"
|
||||
|
||||
class VariableServerSession : public WebSocketSession {
|
||||
public:
|
||||
VariableServerSession(struct mg_connection *nc);
|
||||
~VariableServerSession();
|
||||
void marshallData(); /* -- base */
|
||||
void sendMessage(); /* -- base */
|
||||
int handleMessage(const std::string&); /* -- base */
|
||||
|
||||
void setTimeInterval(unsigned int milliseconds);
|
||||
void addVariable(char* vname);
|
||||
void stageValues();
|
||||
void pause();
|
||||
void unpause();
|
||||
void clear();
|
||||
void exit();
|
||||
|
||||
// static int bad_ref_int ;
|
||||
|
||||
private:
|
||||
int sendErrorMessage(const char* fmt, ... );
|
||||
int sendSieMessage(void);
|
||||
int sendUnitsMessage(const char* vname);
|
||||
// REF2* make_error_ref(const char* in_name);
|
||||
double stageTime;
|
||||
bool dataStaged;
|
||||
|
||||
std::vector<VariableServerVariable*> session_variables;
|
||||
bool cyclicSendEnabled;
|
||||
long long nextTime;
|
||||
long long intervalTimeTics;
|
||||
};
|
||||
|
||||
WebSocketSession* makeVariableServerSession( struct mg_connection *nc );
|
||||
#endif
|
@ -37,6 +37,14 @@ class SimTestWorkflow(TrickWorkflow):
|
||||
# are only in the remaining_run_jobs list. - Jordan 2/2023
|
||||
remaining_run_jobs.remove(job)
|
||||
|
||||
# Some tests fail intermittently for reasons not related to the tests themselves, mostly network weirdness.
|
||||
# Allow retries so that we can still cover some network-adjacent code
|
||||
retry_allowed_sims = self.get_sims(labels='retries_allowed')
|
||||
retry_allowed_jobs = [run.get_run_job() for run in [item for sublist in [sim.get_runs() for sim in retry_allowed_sims] for item in sublist]]
|
||||
for job in retry_allowed_jobs:
|
||||
run_jobs.remove(job)
|
||||
|
||||
|
||||
builds_status = self.execute_jobs(build_jobs, max_concurrent=self.cpus, header='Executing all sim builds.')
|
||||
first_phase_run_status = self.execute_jobs(first_run_jobs, max_concurrent=self.cpus, header="Executing first phase runs.")
|
||||
runs_status = self.execute_jobs(remaining_run_jobs, max_concurrent=self.cpus, header='Executing remaining runs.')
|
||||
|
Loading…
Reference in New Issue
Block a user