Add per-session variable server logs

This commit is contained in:
Deans 2023-04-18 16:27:32 -05:00 committed by Jacqueline Deans
parent 99ee88a686
commit a4d49850f3
57 changed files with 894 additions and 193 deletions

2
.gitignore vendored
View File

@ -42,4 +42,4 @@ trickops_logs/
*.gcno
coverage.info
*.dSYM
*.log

View File

@ -0,0 +1,60 @@
/*
PURPOSE:
(Custom log file writable by message_publish.)
ASSUMPTIONS AND LIMITATIONS:
(())
PROGRAMMERS:
(((Jackie Deans) (LinCom) (4/23) (--) (CACI))
*/
#ifndef MESSAGE_CUSTOM_FILE_HH
#define MESSAGE_CUSTOM_FILE_HH
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include "trick/MessageFile.hh"
namespace Trick {
/**
* MessageCustomFile writes all messages its level to the given file
*/
class MessageCustomFile : public MessageFile {
public:
/**
@brief The constructor.
*/
MessageCustomFile() ;
/**
@brief Output message to the file.
*/
virtual void update( unsigned int level , std::string header , std::string message );
/**
* @brief Get the level
*
*/
virtual int get_level();
virtual void set_name(std::string name);
virtual void set_file_name(std::string file_name);
int this_level;
protected:
static int level_counter;
// static std::vector<MessageCustomFile *>& all_instances();
} ;
}
#endif

View File

@ -0,0 +1,53 @@
/*
PURPOSE:
(Track custom log files.)
ASSUMPTIONS AND LIMITATIONS:
(())
PROGRAMMERS:
(((Jackie Deans) (CACI) (4/23) (--) ())
*/
#ifndef MESSAGE_CUSTOM_MANAGER_HH
#define MESSAGE_CUSTOM_MANAGER_HH
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include "trick/MessageCustomFile.hh"
#include "trick/MessageSubscriber.hh"
namespace Trick {
/**
* MessageCustomFile writes all messages its level to the given file
*/
class MessageCustomManager : public MessageSubscriber {
public:
/**
@brief The constructor.
*/
MessageCustomManager() ;
virtual ~MessageCustomManager() ;
virtual int open_custom_message_file(std::string file_name, std::string subscriber_name, int level = -1);
/**
@brief Output message to the file.
*/
virtual void update( unsigned int level , std::string header , std::string message );
int restart();
protected:
std::vector<MessageCustomFile *> custom_message_files;
} ;
}
#endif

View File

@ -32,7 +32,7 @@ namespace Trick {
public:
/** The file name of a file which the messages goes to. \n*/
std::string file_name ; /**< trick_units(--) trick_io(*i) */
std::string file_name ; /**< trick_units(--) trick_io(io) */
/**
@brief The constructor.
@ -47,7 +47,7 @@ namespace Trick {
/**
@brief Output message to the file.
*/
virtual void update( unsigned int level , std::string header , std::string message ) ;
virtual void update( unsigned int level , std::string header , std::string message );
/**
@brief Set a file name for a file which the messages received by this subscriber goes to.
@ -61,6 +61,9 @@ namespace Trick {
*/
virtual int init() ;
virtual int restart() ;
protected:
/** The output file stream. \n */
std::fstream out_stream ; /**< trick_io(**) */

View File

@ -0,0 +1,47 @@
/*
PURPOSE:
(Trick runtime simulation executive parameter definition.)
REFERENCE:
(((Bailey, R.W, and Paddock, E.J.) (Trick Simulation Environment)
(NASA:JSC #37943)
(JSC / Engineering Directorate / Automation and Robotics Division)
(June 1994) (--)))
ASSUMPTIONS AND LIMITATIONS:
((Only 64 levels of nested input data file inclusion.))
PROGRAMMERS:
(((Robert W. Bailey) (LinCom) (4/92) (--) (Realtime))
((Robert W. Bailey) (LinCom) (6/1/91) (Trick-CR-00000) (Initial Release)))
*/
#ifndef MESSAGE_HS_FILE_HH
#define MESSAGE_HS_FILE_HH
#include <string>
#include <iostream>
#include <fstream>
#include "trick/MessageFile.hh"
namespace Trick {
/**
* MessageHSFile writes all messages of levels 0-99 to the send_hs file
*/
class MessageHSFile : public MessageFile {
public:
/**
@brief The constructor.
*/
MessageHSFile() ;
/**
@brief Output message to the file.
*/
virtual void update( unsigned int level , std::string header , std::string message );
} ;
}
#endif

View File

@ -41,6 +41,7 @@ namespace Trick {
@brief The constructor.
*/
MessagePublisher() ;
virtual ~MessagePublisher();
/**
@brief Initialization job. Sets tics_per_sec and print format.
@ -66,7 +67,7 @@ namespace Trick {
@param message - the text of the message
@return always 0
*/
int publish(int level, std::string message) ;
virtual int publish(int level, std::string message) ;
/**
@brief gets the subscriber from the list

View File

@ -22,5 +22,7 @@
int message_subscribe( Trick::MessageSubscriber * in_ms ) ;
int message_unsubscribe( Trick::MessageSubscriber * in_ms ) ;
int open_custom_message_file(std::string file_name, std::string subscriber_name, int level = -1);
#endif

View File

@ -0,0 +1,13 @@
#ifndef MOCK_EXECUTIVE_HH
#define MOCK_EXECUTIVE_HH
#include "trick/Executive.hh"
#include <gmock/gmock.h>
class MockExecutive : public Trick::Executive {
public:
MOCK_METHOD0(get_time_tics, long long());
MOCK_METHOD0(get_sim_time, double());
};
#endif

View File

@ -0,0 +1,13 @@
#ifndef MOCK_INPUT_PROCESSOR_HH
#define MOCK_INPUT_PROCESSOR_HH
#include "trick/InputProcessor.hh"
#include <gmock/gmock.h>
class MockInputProcessor : public Trick::InputProcessor {
public:
MOCK_METHOD1(parse, int(std::string in_string));
};
#endif

View File

@ -0,0 +1,13 @@
#ifndef MOCK_MESSAGE_CUSTOM_MANAGER_HH
#define MOCK_MESSAGE_CUSTOM_MANAGER_HH
#include "trick/MessageCustomManager.hh"
#include <gmock/gmock.h>
class MockMessageCustomManager : public Trick::MessageCustomManager {
public:
MOCK_METHOD3(update, void(int level, std::string header, std::string message));
MOCK_METHOD3(open_custom_message_file, int(std::string file_name, std::string subscriber_name, int level));
};
#endif

View File

@ -0,0 +1,12 @@
#ifndef MOCK_MESSAGE_PUBLISHER_HH
#define MOCK_MESSAGE_PUBLISHER_HH
#include "trick/MessagePublisher.hh"
#include <gmock/gmock.h>
class MockMessagePublisher : public Trick::MessagePublisher {
public:
MOCK_METHOD2(publish, int(int level, std::string message));
};
#endif

View File

@ -0,0 +1,21 @@
#ifndef MOCK_REALTIME_SYNC_HH
#define MOCK_REALTIME_SYNC_HH
#include "trick/GetTimeOfDayClock.hh"
#include "trick/RealtimeSync.hh"
#include <gmock/gmock.h>
// This sucks but refactoring this is out of the scope for now
Trick::GetTimeOfDayClock& my_static_clock() {
static Trick::GetTimeOfDayClock clock;
return clock;
}
class MockRealtimeSync : public Trick::RealtimeSync {
public:
MockRealtimeSync() : RealtimeSync(&(my_static_clock())) {}
MOCK_METHOD0(is_active, bool());
};
#endif

View File

@ -27,6 +27,7 @@ class MockVariableServerSession : public Trick::VariableServerSession {
MOCK_METHOD0(copy_and_write_async, int());
// Accessor for the concrete version
int copy_and_write_async_concrete() { return Trick::VariableServerSession::copy_and_write_async(); }
};

View File

@ -256,6 +256,12 @@ namespace Trick {
*/
virtual int start_sleep_timer();
/**
@brief Return whether realtime is currently active
@return True if active, false otherwise
*/
virtual bool is_active();
} ;
} ;

View File

@ -1,3 +1,7 @@
/*
PURPOSE: (A wrapper for system calls to facilitate testing.)
*/
#ifndef __SYSTEM_INTERFACE__
#define __SYSTEM_INTERFACE__

View File

@ -50,6 +50,7 @@ namespace Trick {
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 writeNameLengthBinary( 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;

View File

@ -340,8 +340,6 @@ 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_send_list_size() ;

View File

@ -359,6 +359,13 @@ namespace Trick {
*/
virtual int set_log_off() ;
/**
@brief @userdesc Command to set info messages.
@return always 0
*/
virtual int set_info_message(bool on) ;
/**
@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.
@ -412,6 +419,7 @@ namespace Trick {
virtual int var_exit();
private:
static int instance_counter;
pthread_mutex_t _copy_mutex; /**< trick_io(**) */
@ -440,6 +448,16 @@ namespace Trick {
virtual int get_freeze_frame_offset () const;
virtual bool get_enabled () const;
// Check settings and log to appropriate places
void log_received_message(const std::string& msg);
void log_connection_opened ();
bool is_log_open();
void open_session_log();
void write_to_session_log(const std::string& msg);
/** Value set in var_cycle command.\n */
double _update_rate ; /**< trick_io(**) */
@ -491,6 +509,12 @@ namespace Trick {
/** Toggle to turn on/off variable server logged messages to a playback file.\n */
bool _log ; /**< trick_io(**) */
/** Toggle to turn on/off debug info messages.\n */
bool _info_msg ;
/** Message stream number for the log file */
int _log_msg_stream;
/** Toggle to indicate var_pause commanded.\n */
bool _pause_cmd ; /**< trick_io(**) */
@ -504,6 +528,8 @@ namespace Trick {
/** Toggle to indicate var_exit commanded.\n */
bool _exit_cmd ; /**< trick_io(**) */
int _instance_num;
};
}

View File

@ -36,6 +36,9 @@
#include "trick/MessageCout.hh"
#include "trick/MessageThreadedCout.hh"
#include "trick/MessageFile.hh"
#include "trick/MessageHSFile.hh"
#include "trick/MessageCustomFile.hh"
#include "trick/MessageCustomManager.hh"
#include "trick/MessageLCout.hh"
#include "trick/MessagePublisher.hh"
#include "trick/MessageTCDevice.hh"

View File

@ -48,6 +48,9 @@ a replacement SimObject will create an uncompilable sim.
##include "trick/MessageThreadedCout.hh"
##include "trick/MessageLCout.hh"
##include "trick/MessageFile.hh"
##include "trick/MessageHSFile.hh"
##include "trick/MessageCustomFile.hh"
##include "trick/MessageCustomManager.hh"
##include "trick/MessageTCDevice.hh"
##include "trick/PlaybackFile.hh"
##include "trick/MemoryManager.hh"
@ -258,9 +261,10 @@ class MessageSimObject : public Trick::SimObject {
Trick::MessagePublisher mpublisher ;
Trick::MessageCout mcout ;
Trick::MessageThreadedCout mtcout ;
Trick::MessageFile mfile ;
Trick::MessageHSFile mfile ;
Trick::MessageTCDevice mdevice ;
Trick::PlaybackFile pfile ;
Trick::MessageCustomManager message_file_manager ;
MessageSimObject() {
@ -269,6 +273,7 @@ class MessageSimObject : public Trick::SimObject {
{TRK} ("default_data") mpublisher.subscribe(&mfile) ;
{TRK} ("default_data") mpublisher.subscribe(&mdevice) ;
{TRK} ("default_data") mpublisher.subscribe(&pfile) ;
{TRK} ("default_data") mpublisher.subscribe(&message_file_manager) ;
{TRK} ("default_data") mdevice.default_data() ;
{TRK} P1 ("initialization") mpublisher.init() ;
//{TRK} P1 ("initialization") mtcout.init() ;
@ -278,9 +283,9 @@ class MessageSimObject : public Trick::SimObject {
{TRK} ("exec_time_tic_changed") mpublisher.init() ;
{TRK} P1 ("restart") mdevice.restart() ;
{TRK} P1 ("restart") message_file_manager.restart() ;
{TRK} ("shutdown") mtcout.shutdown() ;
{TRK} ("shutdown") mdevice.shutdown() ;
}
private:

View File

@ -9,6 +9,7 @@ def main():
trick.real_time_enable()
trick.exec_set_software_frame(0.01)
# trick.set_var_server_info_msg_on()
trick.set_var_server_log_on()
hostname = trick.var_server_get_hostname()

View File

@ -904,6 +904,7 @@ TEST_F (VariableServerTest, Cycle) {
socket << command;
// Give it a cycle to update
socket.receive();
socket.receive();
double sim_time = parse_message_for_sim_time(socket.receive());
compare_cycle(num_cycles, sim_time);
};

View File

@ -35,7 +35,6 @@ class Socket {
_hostname = hostname;
_port = port;
int tries = 0;
_socket_fd = socket(AF_INET, mode, 0);
if (_socket_fd < 0) {
@ -58,7 +57,6 @@ class Socket {
return -1;
}
tries = 0;
int connection_status;
connection_status = connect(_socket_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
@ -76,7 +74,6 @@ class Socket {
_multicast_socket = true;
_hostname = hostname;
_port = port;
int tries = 0;
_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (_socket_fd < 0) {

View File

@ -54,6 +54,7 @@ int VSTest::default_vars() {
blocked_from_input = 500;
blocked_from_output = 1000;
return 0;
}
int VSTest::init() {

View File

@ -6,4 +6,4 @@ include ${TRICK_HOME}/share/trick/makefiles/Makefile.common
unexport TRICK_PYTHON_PATH
sim_test:
python3 trickops.py --quiet
python3 trickops.py

View File

@ -130,6 +130,8 @@ set( SS_SRC
MasterSlave/Slave
Message/MessageCout
Message/MessageFile
Message/MessageHSFile
Message/MessageCustomFile
Message/MessageLCout
Message/MessagePublisher
Message/MessageSubscriber

View File

@ -1,3 +1,5 @@
include $(dir $(lastword $(MAKEFILE_LIST)))../../../share/trick/makefiles/Makefile.common
include ${TRICK_HOME}/share/trick/makefiles/Makefile.tricklib
-include Makefile_deps
TRICK_CXXFLAGS += -std=c++11

View File

@ -31,6 +31,8 @@ object_${TRICK_HOST_CPU}/Message_c_intf.o: Message_c_intf.cpp \
${TRICK_HOME}/include/trick/MessageSubscriber.hh \
${TRICK_HOME}/include/trick/MessageCout.hh \
${TRICK_HOME}/include/trick/MessageFile.hh \
${TRICK_HOME}/include/trick/MessageHSFile.hh \
${TRICK_HOME}/include/trick/MessageCustomFile.hh \
${TRICK_HOME}/include/trick/MessageTCDevice.hh \
${TRICK_HOME}/include/trick/ThreadBase.hh \
${TRICK_HOME}/include/trick/tc.h \

View File

@ -0,0 +1,46 @@
#include <iostream>
#include <unistd.h>
#include "trick/MessageCustomFile.hh"
#include "trick/Message_proto.hh"
int Trick::MessageCustomFile::level_counter = 200;
/**
@details
-# Initializes everything
*/
Trick::MessageCustomFile::MessageCustomFile() : this_level(level_counter++) {
}
/**
@details
-# If enabled and level is this file's level
-# Write the header and message to the file stream
-# Flush the stream
*/
void Trick::MessageCustomFile::update( unsigned int level , std::string header, std::string message ) {
if ( enabled && level == this_level ) {
out_stream << header << message ;
out_stream.flush() ;
}
}
int Trick::MessageCustomFile::get_level() {
return this_level;
}
void Trick::MessageCustomFile::set_name(std::string name) {
if (name == "") {
name = "CustomLog" + this_level;
}
this->name = name;
}
void Trick::MessageCustomFile::set_file_name(std::string file_name) {
this->file_name = file_name;
}

View File

@ -0,0 +1,58 @@
#include "trick/MessageCustomManager.hh"
#include "trick/Message_proto.hh"
#include "trick/memorymanager_c_intf.h"
Trick::MessageCustomManager * the_message_custom_manager ;
int open_custom_message_file(std::string file_name, std::string subscriber_name, int level) {
if (the_message_custom_manager == NULL) {
std::cout << "Problem: custom_message_manager not yet intantiated" << std::endl;
return -1;
}
return the_message_custom_manager->open_custom_message_file(file_name, subscriber_name, level);
}
/**
@brief The constructor.
*/
Trick::MessageCustomManager::MessageCustomManager() {
the_message_custom_manager = this;
}
Trick::MessageCustomManager::~MessageCustomManager() {
the_message_custom_manager = NULL;
for (Trick::MessageCustomFile * message_file : custom_message_files) {
TMM_delete_var_a(message_file);
}
}
int Trick::MessageCustomManager::open_custom_message_file(std::string file_name, std::string subscriber_name, int level) {
Trick::MessageCustomFile * new_message_file = (Trick::MessageCustomFile *) TMM_declare_var_s("Trick::MessageCustomFile");
new_message_file->set_file_name(file_name);
new_message_file->set_name(subscriber_name);
new_message_file->init();
custom_message_files.push_back(new_message_file);
return new_message_file->get_level();
}
/**
@brief Output message to the file.
*/
void Trick::MessageCustomManager::update( unsigned int level , std::string header , std::string message ) {
for (MessageCustomFile* message_file : custom_message_files) {
message_file->update(level, header, message);
}
}
int Trick::MessageCustomManager::restart( ) {
for (MessageCustomFile* message_file : custom_message_files) {
message_file->restart();
}
return 0;
}

View File

@ -10,12 +10,8 @@
-# Initializes everything
*/
Trick::MessageFile::MessageFile() {
enabled = 1 ;
color = 0 ;
file_name = "send_hs" ;
name = "file" ;
}
/**
@ -29,18 +25,6 @@ int Trick::MessageFile::set_file_name(std::string in_name) {
}
/**
@details
-# Deletes the current output file
-# Opens a new file with the name "file_name"
*/
int Trick::MessageFile::init() {
unlink((std::string(command_line_args_get_output_dir()) + "/" + file_name).c_str()) ;
out_stream.open((std::string(command_line_args_get_output_dir()) + "/" + file_name).c_str() , std::fstream::out | std::fstream::app ) ;
return(0) ;
}
/**
@details
-# If enabled and level < 100
@ -56,6 +40,23 @@ void Trick::MessageFile::update( unsigned int level , std::string header, std::s
}
/**
@details
-# Deletes the current output file
-# Opens a new file with the name "file_name"
*/
int Trick::MessageFile::init() {
unlink((std::string(command_line_args_get_output_dir()) + "/" + file_name).c_str()) ;
out_stream.open((std::string(command_line_args_get_output_dir()) + "/" + file_name).c_str() , std::fstream::out | std::fstream::app ) ;
return(0) ;
}
int Trick::MessageFile::restart() {
out_stream.open((std::string(command_line_args_get_output_dir()) + "/" + file_name).c_str() , std::fstream::out | std::fstream::app ) ;
return(0) ;
}
/**
@details
-# Close the file stream

View File

@ -0,0 +1,32 @@
#include <iostream>
#include <unistd.h>
#include "trick/MessageHSFile.hh"
#include "trick/command_line_protos.h"
/**
@details
-# Initializes everything
*/
Trick::MessageHSFile::MessageHSFile() {
name = "file";
file_name = "send_hs";
}
/**
@details
-# If enabled and level < 100
-# Write the header and message to the file stream
-# Flush the stream
*/
void Trick::MessageHSFile::update( unsigned int level , std::string header, std::string message ) {
if ( enabled && level < 100 ) {
out_stream << header << message ;
out_stream.flush() ;
}
}

View File

@ -25,6 +25,10 @@ Trick::MessagePublisher::MessagePublisher() {
}
Trick::MessagePublisher::~MessagePublisher() {
the_message_publisher = NULL;
}
void Trick::MessagePublisher::set_print_format() {
num_digits = (int)round(log10((double)tics_per_sec)) ;
snprintf(print_format, sizeof(print_format), "|L %%3d|%%s|%%s|%%s|T %%d|%%lld.%%0%dlld| ", num_digits) ;

View File

@ -6,6 +6,7 @@
#include "trick/MessagePublisher.hh"
#include "trick/MessageCout.hh"
#include "trick/MessageFile.hh"
#include "trick/MessageCustomFile.hh"
#include "trick/MessageTCDevice.hh"
#include "trick/message_proto.h"

View File

@ -502,3 +502,6 @@ int Trick::RealtimeSync::shutdown() {
return(0) ;
}
bool Trick::RealtimeSync::is_active() {
return active;
}

View File

@ -59,7 +59,7 @@ extern "C" int real_time_restart(long long ref_time ) {
*/
extern "C" int is_real_time() {
if ( the_rts != NULL ) {
return((int)(the_rts->active)) ;
return((int)(the_rts->is_active())) ;
}
return(0) ;
}

View File

@ -99,26 +99,26 @@ Trick::VariableReference::VariableReference(std::string var_name) : _staged(fals
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());
message_publish(MSG_ERROR, "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());
message_publish(MSG_ERROR, "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());
message_publish(MSG_ERROR,"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 {
// sendErrorMessage("Variable Server: BAD MOJO - Missing ATTRIBUTES.");
printf("Variable Server: BAD MOJO - Missing ATTRIBUTES.");
message_publish(MSG_ERROR, "Variable Server: BAD MOJO - Missing ATTRIBUTES.");
free(_var_info);
_var_info = make_error_ref(var_name);
@ -143,9 +143,8 @@ Trick::VariableReference::VariableReference(std::string var_name) : _staged(fals
} 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") ;
message_publish(MSG_ERROR, "Variable Server Error: var_add(%s) requests more than one dimension of dynamic array.\n", _var_info->reference);
message_publish(MSG_ERROR, "Data is not contiguous so returned values are unpredictable.\n") ;
}
if ( _var_info->attr->type == TRICK_CHARACTER ) {
_trick_type = TRICK_STRING ;
@ -622,18 +621,23 @@ int Trick::VariableReference::writeSizeBinary( std::ostream& out, bool byteswap
int Trick::VariableReference::writeNameBinary( std::ostream& out, bool byteswap ) const {
std::string name = getName();
out.write(name.c_str(), name.size());
int name_size = name.size();
return 0;
}
int Trick::VariableReference::writeNameLengthBinary( std::ostream& out, bool byteswap ) const {
int name_size = getName().size();
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.c_str(), name.size());
return 0;
}
void Trick::VariableReference::byteswap_var (char * out, char * in) const {
byteswap_var(out, in, *this);
}

View File

@ -53,10 +53,16 @@ bool Trick::VariableServer::get_info_msg() {
void Trick::VariableServer::set_var_server_info_msg_on() {
info_msg = true;
for ( auto& session_it : var_server_sessions ) {
session_it.second->set_info_message(info_msg);
}
}
void Trick::VariableServer::set_var_server_info_msg_off() {
info_msg = false;
for ( auto& session_it : var_server_sessions ) {
session_it.second->set_info_message(info_msg);
}
}
bool Trick::VariableServer::get_log() {

View File

@ -206,19 +206,19 @@ int Trick::VariableServerListenThread::restart() {
_requested_source_address.clear() ;
}
printf("variable server restart user_port requested set %s:%d\n",_requested_source_address.c_str(), _requested_port);
message_publish(MSG_INFO, "variable server restart user_port requested set %s:%d\n",_requested_source_address.c_str(), _requested_port);
_listener->disconnect();
ret = _listener->initialize(_requested_source_address, _requested_port);
if (ret != TC_SUCCESS) {
if (ret != 0) {
message_publish(MSG_ERROR, "ERROR: Could not establish listen port %d for Variable Server. Aborting.\n", _requested_port);
return (-1);
}
} else {
// Otherwise, just ask the listener what port it's using
_listener->checkSocket();
printf("restart variable server message port = %d\n", _listener->getPort());
message_publish(MSG_INFO, "restart variable server message port = %d\n", _listener->getPort());
}
initializeMulticast();
@ -233,14 +233,12 @@ void Trick::VariableServerListenThread::initializeMulticast() {
}
void Trick::VariableServerListenThread::pause_listening() {
// pthread_mutex_lock(&_restart_pause) ;
force_thread_to_pause();
}
void Trick::VariableServerListenThread::restart_listening() {
_listener->restart();
unpause_thread();
// pthread_mutex_unlock(&_restart_pause) ;
}
void Trick::VariableServerListenThread::dump( std::ostream & oss ) {

View File

@ -1,15 +1,19 @@
#include "trick/VariableServerSession.hh"
#include "trick/TrickConstant.hh"
#include "trick/exec_proto.h"
#include "trick/Message_proto.hh"
#include "trick/message_proto.h"
#include "trick/input_processor_proto.h"
#include "trick/realtimesync_proto.h"
int Trick::VariableServerSession::instance_counter = 0;
Trick::VariableServerSession::VariableServerSession() {
_debug = 0;
_enabled = true ;
_log = false ;
_log_msg_stream = -1;
_info_msg = false;
_copy_mode = VS_COPY_ASYNC ;
_write_mode = VS_WRITE_ASYNC ;
_frame_multiple = 1 ;
@ -35,6 +39,8 @@ Trick::VariableServerSession::VariableServerSession() {
_exit_cmd = false;
_pause_cmd = false;
_instance_num = instance_counter++;
pthread_mutex_init(&_copy_mutex, NULL);
}
@ -47,6 +53,16 @@ Trick::VariableServerSession::~VariableServerSession() {
void Trick::VariableServerSession::set_connection(ClientConnection * conn) {
_connection = conn;
log_connection_opened();
}
bool Trick::VariableServerSession::is_log_open() {
return _log_msg_stream != -1;
}
void Trick::VariableServerSession::open_session_log() {
std::string name = "VSSession" + std::to_string(_instance_num);
_log_msg_stream = open_custom_message_file(name + ".log", name);
}
@ -103,11 +119,41 @@ long long Trick::VariableServerSession::get_freeze_next_tics() const {
return _freeze_next_tics ;
}
void Trick::VariableServerSession::log_connection_opened() {
if (_log) {
if (!is_log_open()) {
open_session_log();
}
message_publish(_log_msg_stream, "Variable Server Session started with %s:%d\n", _connection->getClientHostname().c_str(), _connection->getClientPort());
}
}
void Trick::VariableServerSession::log_received_message(const std::string& msg) {
if (_log) {
message_publish(MSG_PLAYBACK, "tag=<%s> time=%f %s", _connection->getClientTag().c_str(), exec_get_sim_time(), msg.c_str());
if (!is_log_open()) open_session_log();
message_publish(_log_msg_stream, "tag=<%s> time=%f %s", _connection->getClientTag().c_str(), exec_get_sim_time(), msg.c_str());
}
if (_debug >= 3) {
message_publish(MSG_DEBUG, "%p tag=<%s> var_server received bytes = msg_len = %d\n", _connection, _connection->getClientTag().c_str(), msg.size());
}
if (_debug >= 1 || _info_msg) {
message_publish(MSG_DEBUG, "tag=<%s> time=%f %s", _connection->getClientTag().c_str(), exec_get_sim_time(), msg.c_str());
}
}
int Trick::VariableServerSession::handle_message() {
std::string received_message;
int nbytes = _connection->read(received_message);
if (nbytes > 0) {
log_received_message(received_message);
ip_parse(received_message.c_str()); /* returns 0 if no parsing error */
}
@ -125,6 +171,11 @@ Trick::VariableReference * Trick::VariableServerSession::find_session_variable(s
return NULL;
}
int Trick::VariableServerSession::set_info_message(bool on) {
_info_msg = on;
return 0;
}
double Trick::VariableServerSession::get_update_rate() const {
return _update_rate;
}

View File

@ -39,6 +39,15 @@ void * Trick::VariableServerSessionThread::thread_body() {
thread_shutdown();
}
// if log is set on for variable server (e.g., in input file), turn log on for each client
if (_vs->get_log()) {
_session->set_log_on();
}
if (_vs->get_info_msg()) {
_session->set_info_message(true);
}
// Give the initialized connection to the session
// Don't touch the connection anymore until we shut them both down
_session->set_connection(_connection);
@ -50,11 +59,6 @@ void * Trick::VariableServerSessionThread::thread_body() {
pthread_cond_signal(&_connection_status_cv);
pthread_mutex_unlock(&_connection_status_mutex);
// if log is set on for variable server (e.g., in input file), turn log on for each client
if (_vs->get_log()) {
_session->set_log_on();
}
try {
while (1) {
// Shutdown here if it's time

View File

@ -117,7 +117,7 @@ int Trick::VariableServerSession::var_exists(std::string in_name) {
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);
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending 1 binary byte\n", _connection, _connection->getClientTag().c_str());
}
_connection->write(buf1, 5);
@ -125,7 +125,7 @@ int Trick::VariableServerSession::var_exists(std::string in_name) {
/* 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) ;
message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending:\n%s\n", _connection, _connection->getClientTag().c_str(), buf1) ;
}
std::string write_string(buf1);
if (write_string.length() != strlen(buf1)) {
@ -312,7 +312,7 @@ int Trick::VariableServerSession::send_list_size() {
return 0 ;
}
int Trick::VariableServerSession::transmit_file(std::string sie_file) {
int Trick::VariableServerSession::transmit_file(std::string filename) {
const unsigned int packet_size = 4095 ;
FILE * fp ;
unsigned int file_size ;
@ -322,11 +322,11 @@ int Trick::VariableServerSession::transmit_file(std::string sie_file) {
int ret ;
if (_debug >= 2) {
message_publish(MSG_DEBUG,"%p tag=<%s> var_server opening %s.\n", _connection, _connection->getClientTag().c_str(), sie_file.c_str()) ;
message_publish(MSG_DEBUG,"%p tag=<%s> var_server opening %s.\n", _connection, _connection->getClientTag().c_str(), filename.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()) ;
if ((fp = fopen(filename.c_str() , "r")) == NULL ) {
message_publish(MSG_ERROR,"Variable Server Error: Cannot open %s.\n", filename.c_str()) ;
sprintf(buffer, "%d\t-1\n", VS_SIE_RESOURCE) ;
std::string message(buffer);
_connection->write(message);
@ -352,7 +352,7 @@ int Trick::VariableServerSession::transmit_file(std::string sie_file) {
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) ;
message_publish(MSG_ERROR,"Variable Server Error: Failed to send file. Bytes read: %d Bytes sent: %d\n", bytes_read, ret) ;
return(-1);
}
current_size += bytes_read ;

View File

@ -18,19 +18,24 @@ PROGRAMMERS: (((Alex Lin) (NASA) (8/06) (--)))
#define MAX_MSG_LEN 8192
int Trick::VariableServerSession::write_binary_data(const std::vector<VariableReference *>& given_vars, VS_MESSAGE_TYPE message_type) {
typedef std::vector<VariableReference *> VarList;
typedef std::pair<int,VarList> MessageData;
// 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;
std::vector<MessageData> message_sizes_and_vars;
// Calculate how many messages and how many vars in each
// Calculate how many messages and what vars in each
int total_size = header_size;
int num_vars = 0;
VarList curr_message_vars;
for (int i = 0; i < given_vars.size(); i++) {