COSMOS core  1.0.2 (beta)
Comprehensive Open-architecture Solution for Mission Operations Systems
Agent Server and Client functions
Collaboration diagram for Agent Server and Client functions:

Functions

 Cosmos::Support::Agent::Agent (const string &node_name="", const string &agent_name="", double bprd=0., uint32_t bsize=AGENTMAXBUFFER, bool mflag=false, int32_t portnum=0, NetworkType ntype=NetworkType::UDP, uint16_t dlevel=1)
 
 Cosmos::Support::Agent::~Agent ()
 
int32_t Cosmos::Support::Agent::add_request (string token, external_request_function function, string synopsis="", string description="")
 Add internal request to Agent request list with description and synopsis. More...
 
int32_t Cosmos::Support::Agent::start ()
 Start Agent Request and Heartbeat loops. More...
 
int32_t Cosmos::Support::Agent::start_active_loop ()
 
int32_t Cosmos::Support::Agent::finish_active_loop ()
 
int32_t Cosmos::Support::Agent::shutdown ()
 Shutdown agent gracefully. More...
 
uint16_t Cosmos::Support::Agent::running ()
 Check if we're supposed to be running. More...
 
int32_t Cosmos::Support::Agent::wait (State state=State::RUN, double waitsec=10.)
 
int32_t Cosmos::Support::Agent::last_error ()
 
int32_t Cosmos::Support::Agent::send_request (beatstruc cbeat, string request, string &output, float waitsec=5.)
 Send a request over AGENT. More...
 
int32_t Cosmos::Support::Agent::send_request_jsonnode (beatstruc cbeat, jsonnode &jnode, float waitsec=5.)
 Send request for Node JSON. More...
 
int32_t Cosmos::Support::Agent::get_agent (string node, string agent, double waitsec, beatstruc &cbeat)
 Get specific server. More...
 
int32_t Cosmos::Support::Agent::check_agent (string node, string agent, double waitsec)
 Check agent. More...
 
beatstruc Cosmos::Support::Agent::find_agent (string node, string agent, double waitsec=0.)
 Find agent. More...
 
vector< beatstrucCosmos::Support::Agent::find_agents (double waitsec=0.)
 Find single server. More...
 
int32_t Cosmos::Support::Agent::set_sohstring (string list)
 Set Limited SOH string. More...
 
int32_t Cosmos::Support::Agent::set_fullsohstring (string list)
 Set Full SOH string. More...
 
cosmosstrucCosmos::Support::Agent::get_cosmosstruc ()
 Return Agent cosmosstruc. More...
 
void Cosmos::Support::Agent::heartbeat_loop ()
 Heartbeat Loop. More...
 
void Cosmos::Support::Agent::request_loop () noexcept
 Request Loop. More...
 
int32_t Cosmos::Support::Agent::process_request (string &bufferin, string &bufferout)
 
void Cosmos::Support::Agent::message_loop ()
 
static int32_t Cosmos::Support::Agent::req_forward (string &request, string &response, Agent *agent)
 Built-in Forward request. More...
 
static int32_t Cosmos::Support::Agent::req_echo (string &request, string &response, Agent *agent)
 Built-in Echo request. More...
 
static int32_t Cosmos::Support::Agent::req_help_json (string &request, string &response, Agent *agent)
 Built-in Help request. More...
 
static int32_t Cosmos::Support::Agent::req_help (string &request, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_run (string &request, string &response, Agent *agent)
 Built-in Set state to Run request. More...
 
static int32_t Cosmos::Support::Agent::req_init (string &request, string &response, Agent *agent)
 Built-in Set state to Init request. More...
 
static int32_t Cosmos::Support::Agent::req_idle (string &request, string &response, Agent *agent)
 Built-in Set state to Idle request. More...
 
static int32_t Cosmos::Support::Agent::req_monitor (string &request, string &response, Agent *agent)
 Built-in Set state to Monitor request. More...
 
static int32_t Cosmos::Support::Agent::req_reset (string &request, string &response, Agent *agent)
 Built-in Set state to Reset request. More...
 
static int32_t Cosmos::Support::Agent::req_shutdown (string &request, string &response, Agent *agent)
 Built-in Set state to Shutdown request. More...
 
static int32_t Cosmos::Support::Agent::req_status (string &request, string &response, Agent *agent)
 Built-in Status request. More...
 
static int32_t Cosmos::Support::Agent::req_debug_level (string &request, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_getvalue (string &request, string &response, Agent *agent)
 Built-in Get Internal Value request. More...
 
static int32_t Cosmos::Support::Agent::req_get_value (string &request, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_get_time (string &request, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_get_position_data (string &request, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_get_position (string &request, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_setvalue (string &request, string &response, Agent *agent)
 Built-in Set Internal Value request. More...
 
static int32_t Cosmos::Support::Agent::req_set_value (string &request, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_listnames (string &request, string &response, Agent *agent)
 Built-in List Name Space Names request. More...
 
static int32_t Cosmos::Support::Agent::req_nodejson (string &request, string &response, Agent *agent)
 Built-in Return Node JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_statejson (string &request, string &response, Agent *agent)
 Built-in Return State Vector JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_utcstartjson (string &request, string &response, Agent *agent)
 Built-in Return UTC Start Time JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_piecesjson (string &request, string &response, Agent *agent)
 Built-in Return Pieces JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_facesjson (string &request, string &response, Agent *agent)
 Built-in Return Face JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_vertexsjson (string &request, string &response, Agent *agent)
 Built-in Return Vertex JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_devgenjson (string &request, string &response, Agent *agent)
 Built-in Return devgen JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_devspecjson (string &request, string &response, Agent *agent)
 Built-in Return devspec JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_portsjson (string &request, string &response, Agent *agent)
 Built-in Return Ports JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_targetsjson (string &request, string &response, Agent *agent)
 Built-in Return Target JSON request. More...
 
static int32_t Cosmos::Support::Agent::req_heartbeat (string &request, string &response, Agent *agent)
 Built-in Send Heartbeat request. More...
 
static int32_t Cosmos::Support::Agent::req_postsoh (string &request, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_utc (string &request, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_soh (string &, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_fullsoh (string &, string &response, Agent *agent)
 
static int32_t Cosmos::Support::Agent::req_jsondump (string &, string &response, Agent *agent)
 
int32_t Cosmos::Support::Agent::publish (NetworkType type, uint16_t port)
 Open COSMOS output channel. More...
 
vector< socket_channelCosmos::Support::Agent::find_addresses (NetworkType ntype)
 Discover interfaces. More...
 
int32_t Cosmos::Support::Agent::post (messstruc mess)
 Post a Cosmos::Agent::messstruc. More...
 
int32_t Cosmos::Support::Agent::post (AgentMessage type, string message="")
 Post a JSON message. More...
 
int32_t Cosmos::Support::Agent::post (AgentMessage type, vector< uint8_t > message)
 Post a binary message. More...
 
int32_t Cosmos::Support::Agent::post_beat ()
 
int32_t Cosmos::Support::Agent::post_soh ()
 
int32_t Cosmos::Support::Agent::unpublish ()
 Close COSMOS output channel. More...
 
int32_t Cosmos::Support::Agent::subscribe (NetworkType type, const char *address, uint16_t port, uint32_t usectimeo)
 Open COSMOS channel for polling. More...
 
int32_t Cosmos::Support::Agent::subscribe (NetworkType type, const char *address, uint16_t port)
 Open COSMOS channel for polling with 100 usec timeout. More...
 
int32_t Cosmos::Support::Agent::unsubscribe ()
 Close COSMOS subscription channel. More...
 
int32_t Cosmos::Support::Agent::poll (messstruc &mess, AgentMessage type, float waitsec=1.)
 Listen for message. More...
 
int32_t Cosmos::Support::Agent::readring (messstruc &message, AgentMessage type=Agent::AgentMessage::ALL, float waitsec=1., Where where=Where::TAIL, string proc="", string node="")
 Check Ring for message. More...
 
int32_t Cosmos::Support::Agent::parsering (AgentMessage type=Agent::AgentMessage::ALL, float waitsec=1., Where where=Where::HEAD, string proc="", string node="")
 Parse next message from ring. More...
 
int32_t Cosmos::Support::Agent::resizering (size_t newsize)
 
int32_t Cosmos::Support::Agent::clearring ()
 
string Cosmos::Support::Agent::getNode ()
 Listen for heartbeat. More...
 
string Cosmos::Support::Agent::getAgent ()
 
int32_t Cosmos::Support::Agent::getJson (string node, jsonnode &jnode)
 
FILE * Cosmos::Support::Agent::get_debug_fd (double mjd=0.)
 
int32_t Cosmos::Support::Agent::close_debug_fd ()
 
int32_t Cosmos::Support::Agent::set_agent_time_producer (double(*source)())
 
int32_t Cosmos::Support::Agent::get_agent_time (double &agent_time, double &epsilon, double &delta, string agent, string node="any", double wait_sec=2.)
 

Detailed Description

Function Documentation

Cosmos::Support::Agent::Agent ( const string &  node_name = "",
const string &  agent_name = "",
double  bprd = 0.,
uint32_t  bsize = AGENTMAXBUFFER,
bool  mflag = false,
int32_t  portnum = 0,
NetworkType  ntype = NetworkType::UDP,
uint16_t  dlevel = 1 
)

Add COSMOS awareness. Sets up minimum framework for COSMOS awareness. The minimum call makes a nodeless client, setting up the message ring buffer thread, and a main thread of execution. Additional parameters are related to making the program a true Agent by tieing it to a node, and starting the request and heartbeat threads.

Parameters
ntypeTransport Layer protocol to be used, taken from NetworkType. Defaults to UDP Broadcast.
node_nameNode name. Defaults to empty.
agent_nameAgent name. Defaults to empty. If this is defined, the full Agent code will be started.
bprdPeriod, in seconds, for heartbeat. Defaults to 1.
bsizeSize of interagent communication buffer. Defaults to AGENTMAXBUFFER.
mflagBoolean controlling whether or not multiple instances of the same Agent can start. If true, then Agent names will have an index number appended (eg: myname_001). If false, agent will listen for 5 seconds and terminate if it senses the Agent already running.
portnumThe network port to listen on for requests. Defaults to 0 whereupon it will use whatever th OS assigns.
dleveldebug level. Defaults to 1 so that if there is an error the user can immediately see it. also initialized in the namespace variables

Set up initial requests

87  {
88  int32_t iretn;
89  debug_level = dlevel;
90 
91  // Initialize COSMOS data space
92  cinfo = json_init();
93 
94  if (cinfo == nullptr) {
96  shutdown();
97  return;
98  }
99 
100  cinfo->agent[0].stateflag = static_cast<uint16_t>(State::INIT);
101 
102  // Establish subscribe channel
103  iretn = subscribe(ntype, AGENTMCAST, AGENTSENDPORT, 1000);
104  if (iretn) {
105  error_value = iretn;
106  shutdown();
107  return;
108  }
109 
110  // Set up node: shorten if too long, use hostname if it's empty.
112  if ((iretn=json_setup_node(nodeName, cinfo)) != 0) {
113  error_value = iretn;
114  shutdown();
115  return;
116  }
117 
118  strcpy(cinfo->node.name, nodeName.c_str());
119 
120  cinfo->agent[0].client = 1;
121  cinfo->node.utc = 0.;
122  strncpy(cinfo->agent[0].beat.node, cinfo->node.name ,COSMOS_MAX_NAME);
123 
124  // Establish publish channel
125  cinfo->agent[0].beat.ntype = ntype;
126  iretn = publish(cinfo->agent[0].beat.ntype, AGENTSENDPORT);
127  if (iretn) {
128  error_value = iretn;
129  shutdown();
130  return;
131  }
132 
133  // Start message listening thread
134  mthread = thread([=] { message_loop(); });
135  COSMOS_SLEEP(.1);
136 
137  // Return if all we are doing is setting up client.
138  if (agent_name.empty()) {
139  strcpy(cinfo->agent[0].beat.proc, "");
140  cinfo->agent[0].stateflag = static_cast <uint16_t>(Agent::State::RUN);
141  return;
142  }
143 
144  if (strlen(cinfo->node.name)>COSMOS_MAX_NAME || agent_name.length()>COSMOS_MAX_NAME) {
146  shutdown();
147  return;
148  }
149 
150 
151  // If not Multi, check if this Agent is already running
152  char tname[COSMOS_MAX_NAME+1];
153  if (!mflag) {
156  shutdown();
157  return;
158  }
159  strcpy(tname,agent_name.c_str());
160  } else {
161  // then there is an agent running with the given name, so let's make the name unique
162  if (strlen(cinfo->node.name)>COSMOS_MAX_NAME-4 || agent_name.size()>COSMOS_MAX_NAME-4) {
164  shutdown();
165  return;
166  }
167 
168  uint32_t i=0;
169  do
170  {
171  sprintf(tname,"%s_%03d",agent_name.c_str(),i);
172  if (!check_agent(cinfo->node.name, tname, timeoutSec))
173  {
174  break;
175  }
176  } while (++i<100);
177  }
178 
179  // Initialize important server variables
180 
181  strncpy(cinfo->agent[0].beat.node, cinfo->node.name, COSMOS_MAX_NAME);
182  strncpy(cinfo->agent[0].beat.proc, tname, COSMOS_MAX_NAME);
183  agentName = cinfo->agent[0].beat.proc;
184 
185  if (debug_level>2) {
186  double timeStart = currentmjd();
187  fprintf(get_debug_fd(), "------------------------------------------------------\n");
188  fprintf(get_debug_fd(), "COSMOS AGENT '%s' on node '%s'\n", agent_name.c_str(), node_name.c_str());
189  fprintf(get_debug_fd(), "Version %s built on %s %s\n", version.c_str(), __DATE__, __TIME__);
190  fprintf(get_debug_fd(), "Agent started at %s\n", mjdToGregorian(timeStart).c_str());
191  fprintf(get_debug_fd(), "Debug level %u\n", debug_level);
192  fprintf(get_debug_fd(), "------------------------------------------------------\n");
193  }
194 
195  if (bprd >= AGENT_HEARTBEAT_PERIOD_MIN) {
196  cinfo->agent[0].beat.bprd = bprd;
197  } else {
198  cinfo->agent[0].beat.bprd = 0.;
199  }
200  cinfo->agent[0].stateflag = static_cast<uint16_t>(State::INIT);
201  cinfo->agent[0].beat.port = static_cast<uint16_t>(portnum);
202  cinfo->agent[0].beat.bsz = (bsize<=AGENTMAXBUFFER-4?bsize:AGENTMAXBUFFER-4);
203 
204 #ifdef COSMOS_WIN_BUILD_MSVC
205  cinfo->agent[0].pid = _getpid();
206 #else
207  cinfo->agent[0].pid = getpid();
208 #endif
209  cinfo->agent[0].aprd = 1.;
210  strncpy(cinfo->agent[0].beat.user, "cosmos", COSMOS_MAX_NAME);
211 
212  // Start the heartbeat and request threads running
213  // iretn = start();
214  hthread = thread([=] { heartbeat_loop(); });
215  cthread = thread([=] { request_loop(); });
216  if (!hthread.joinable() || !cthread.joinable()) {
217  // TODO: create error value
218  //error_value = iretn;
219  shutdown();
220  return;
221  }
222 
224  add_request("help",req_help,"","list of available requests for this agent");
225  add_request("help_json",req_help_json,"","list of available requests for this agent (but in json)");
226  add_request("shutdown",req_shutdown,"","request to shutdown this agent");
227  add_request("idle",req_idle,"","request to transition this agent to idle state");
228  add_request("init",req_init,"","request to transition this agent to init state");
229  add_request("monitor",req_monitor,"","request to transition this agent to monitor state");
230  add_request("reset",req_reset,"","request to transition this agent to reset state");
231  add_request("run",req_run,"","request to transition this agent to run state");
232  add_request("status",req_status,"","request the status of this agent");
233  add_request("debug_level",req_debug_level,"{\"name1\",\"name2\",...}","get/set debug_level of agent");
234  add_request("getvalue",req_getvalue,"{\"name1\",\"name2\",...}","get specified value(s) from agent");
235  add_request("get_value",req_get_value,"[{] \"name1\",\"name2\",... [}]","get specified value(s) from agent");
236  add_request("get_time",req_get_time,"","return the current time of the agent");
237  add_request("get_position",req_get_position,"","return the current perifocal position of the agent");
238  add_request("get_position_data",req_get_position_data,"","return the current perifocal position of the agent");
239  add_request("setvalue",req_setvalue,"{\"name1\":value},{\"name2\":value},...","set specified value(s) in agent");
240  add_request("set_value",req_set_value,"{\"name1\":value} [,] {\"name2\":value} [,] ...","set specified value(s) in agent");
241  add_request("listnames",req_listnames,"","list the Namespace of the agent");
242  add_request("forward",req_forward,"nbytes packet","Broadcast JSON packet to the default SEND port on local network");
243  add_request("echo",req_echo,"utc crc nbytes bytes","echo array of nbytes bytes, sent at time utc, with CRC crc.");
244  add_request("nodejson",req_nodejson,"","return description JSON for Node");
245  add_request("statejson",req_statejson,"","return description JSON for State vector");
246  add_request("utcstartjson",req_utcstartjson,"","return description JSON for UTC Start time");
247  add_request("piecesjson",req_piecesjson,"","return description JSON for Pieces");
248  add_request("vertexsjson",req_vertexsjson,"","return description JSON for Pieces");
249  add_request("facesjson",req_facesjson,"","return description JSON for Pieces");
250  add_request("devgenjson",req_devgenjson,"","return description JSON for General Devices");
251  add_request("devspecjson",req_devspecjson,"","return description JSON for Specific Devices");
252  add_request("portsjson",req_portsjson,"","return description JSON for Ports");
253  add_request("targetsjson",req_targetsjson,"","return description JSON for Targets");
254  add_request("heartbeat",req_heartbeat,"","Post a hearbeat");
255  add_request("postsoh",req_postsoh,"","Post a SOH");
256  add_request("utc",req_utc,"","Get UTC as both Modified Julian Day and Unix Time");
257  add_request("soh",req_soh,"","Get Limited SOH string");
258  add_request("fullsoh",req_fullsoh,"","Get Full SOH string");
259  add_request("jsondump",req_jsondump,"","Dump JSON ini files to node folder");
260 
261  // Set up Full SOH string
262 // set_fullsohstring(json_list_of_fullsoh(cinfo));
263 
264  cinfo->agent[0].server = 1;
265  cinfo->agent[0].stateflag = static_cast<uint16_t>(Agent::State::RUN);
266  activeTimeout = currentmjd() + cinfo->agent[0].aprd / 86400.;
267  }
#define AGENT_ERROR_SERVER_RUNNING
Definition: cosmos-errno.h:104
static int32_t req_run(string &request, string &response, Agent *agent)
Built-in Set state to Run request.
Definition: agentclass.cpp:977
static int32_t req_help_json(string &request, string &response, Agent *agent)
Built-in Help request.
Definition: agentclass.cpp:900
uint16_t debug_level
Flag for level of debugging, keep it public so that it can be controlled from the outside...
Definition: agentclass.h:362
FILE * get_debug_fd(double mjd=0.)
Definition: agentclass.cpp:2645
static int32_t req_get_position(string &request, string &response, Agent *agent)
Definition: agentclass.cpp:1253
string version
Definition: agentclass.h:381
static int32_t req_utc(string &request, string &response, Agent *agent)
Definition: agentclass.cpp:1556
static int32_t req_listnames(string &request, string &response, Agent *agent)
Built-in List Name Space Names request.
Definition: agentclass.cpp:1375
uint16_t bsize
Definition: netperf_listen.cpp:71
int32_t json_setup_node(jsonnode json, cosmosstruc *cinfo, bool create_flag)
Setup JSON Namespace using Node description JSON.
Definition: jsonlib.cpp:6869
string nodeName
Definition: agentclass.h:367
int i
Definition: rw_test.cpp:37
static int32_t req_facesjson(string &request, string &response, Agent *agent)
Built-in Return Face JSON request.
Definition: agentclass.cpp:1445
static int32_t req_jsondump(string &, string &response, Agent *agent)
Definition: agentclass.cpp:1576
#define COSMOS_MAX_NAME
Largest JSON name.
Definition: cosmos-defs.h:55
static int32_t req_utcstartjson(string &request, string &response, Agent *agent)
Built-in Return UTC Start Time JSON request.
Definition: agentclass.cpp:1417
static int32_t req_piecesjson(string &request, string &response, Agent *agent)
Built-in Return Pieces JSON request.
Definition: agentclass.cpp:1431
Run without monitoring.
static int32_t req_get_value(string &request, string &response, Agent *agent)
Definition: agentclass.cpp:1123
int iretn
Definition: rw_test.cpp:37
double utc
Overall Node time.
Definition: jsondef.h:3592
static int32_t req_nodejson(string &request, string &response, Agent *agent)
Built-in Return Node JSON request.
Definition: agentclass.cpp:1389
cosmosstruc * json_init()
Initialize JSON pointer map.
Definition: jsonlib.cpp:454
double timeoutSec
Definition: agentclass.h:382
double activeTimeout
Definition: agentclass.h:375
static int32_t req_status(string &request, string &response, Agent *agent)
Built-in Status request.
Definition: agentclass.cpp:1064
static int32_t req_fullsoh(string &, string &response, Agent *agent)
Definition: agentclass.cpp:1569
int32_t mjdToGregorian(double mjd, int32_t &year, int32_t &month, int32_t &day, int32_t &hour, int32_t &minute, int32_t &second)
Definition: timelib.cpp:1364
string node_name
Definition: agent_001.cpp:46
static int32_t req_statejson(string &request, string &response, Agent *agent)
Built-in Return State Vector JSON request.
Definition: agentclass.cpp:1403
thread cthread
Handle for request thread.
Definition: agentclass.h:387
nodestruc node
Structure for summary information in node.
Definition: jsondef.h:4220
static int32_t req_get_time(string &request, string &response, Agent *agent)
Definition: agentclass.cpp:1148
static int32_t req_setvalue(string &request, string &response, Agent *agent)
Built-in Set Internal Value request.
Definition: agentclass.cpp:1345
static int32_t req_reset(string &request, string &response, Agent *agent)
Built-in Set state to Reset request.
Definition: agentclass.cpp:1033
static int32_t req_debug_level(string &request, string &response, Agent *agent)
Definition: agentclass.cpp:1090
static int32_t req_getvalue(string &request, string &response, Agent *agent)
Built-in Get Internal Value request.
Definition: agentclass.cpp:1105
int32_t publish(NetworkType type, uint16_t port)
Open COSMOS output channel.
Definition: agentclass.cpp:1588
int32_t check_agent(string node, string agent, double waitsec)
Check agent.
Definition: agentclass.cpp:546
int32_t add_request(string token, external_request_function function, string synopsis="", string description="")
Add internal request to Agent request list with description and synopsis.
Definition: agentclass.cpp:312
#define AGENTSENDPORT
Default SEND port.
Definition: agentclass.h:198
static int32_t req_soh(string &, string &response, Agent *agent)
Definition: agentclass.cpp:1562
char name[40+1]
Node Name.
Definition: jsondef.h:3556
static int32_t req_monitor(string &request, string &response, Agent *agent)
Built-in Set state to Monitor request.
Definition: agentclass.cpp:1019
#define AGENTMCAST
AGENT heartbeat Multicast address.
Definition: agentclass.h:202
void heartbeat_loop()
Heartbeat Loop.
Definition: agentclass.cpp:671
static int32_t req_devspecjson(string &request, string &response, Agent *agent)
Built-in Return devspec JSON request.
Definition: agentclass.cpp:1487
static int32_t req_echo(string &request, string &response, Agent *agent)
Built-in Echo request.
Definition: agentclass.cpp:880
int32_t shutdown()
Shutdown agent gracefully.
Definition: agentclass.cpp:366
static int32_t req_idle(string &request, string &response, Agent *agent)
Built-in Set state to Idle request.
Definition: agentclass.cpp:1005
#define JSON_ERROR_NAME_LENGTH
Definition: cosmos-errno.h:90
thread mthread
Handle for message thread.
Definition: agentclass.h:391
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
string agent_name
Definition: agent_001.cpp:47
int32_t error_value
Last error.
Definition: agentclass.h:393
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
NetworkType ntype
Definition: agent_node.cpp:50
static int32_t req_init(string &request, string &response, Agent *agent)
Built-in Set state to Init request.
Definition: agentclass.cpp:991
thread hthread
Handle for heartbeat thread.
Definition: agentclass.h:389
void message_loop()
Definition: agentclass.cpp:806
static int32_t req_heartbeat(string &request, string &response, Agent *agent)
Built-in Send Heartbeat request.
Definition: agentclass.cpp:1539
static int32_t req_set_value(string &request, string &response, Agent *agent)
Definition: agentclass.cpp:1352
cosmosstruc * cinfo
Definition: agentclass.h:346
#define AGENTMAXBUFFER
Maximum AGENT transfer buffer size.
Definition: jsondef.h:438
static int32_t req_forward(string &request, string &response, Agent *agent)
Built-in Forward request.
Definition: agentclass.cpp:856
static int32_t req_vertexsjson(string &request, string &response, Agent *agent)
Built-in Return Vertex JSON request.
Definition: agentclass.cpp:1459
static int32_t req_portsjson(string &request, string &response, Agent *agent)
Built-in Return Ports JSON request.
Definition: agentclass.cpp:1501
#define AGENT_ERROR_JSON_CREATE
Definition: cosmos-errno.h:105
static int32_t req_help(string &request, string &response, Agent *agent)
Definition: agentclass.cpp:947
double timeStart
Definition: agentclass.h:384
#define AGENT_HEARTBEAT_PERIOD_MIN
Default minium heartbeat period (10 msec)
Definition: agentclass.h:210
static int32_t req_targetsjson(string &request, string &response, Agent *agent)
Built-in Return Target JSON request.
Definition: agentclass.cpp:1520
string agentName
Definition: agentclass.h:368
static int32_t req_devgenjson(string &request, string &response, Agent *agent)
Built-in Return devgen JSON request.
Definition: agentclass.cpp:1473
void request_loop() noexcept
Request Loop.
Definition: agentclass.cpp:722
int32_t subscribe(NetworkType type, const char *address, uint16_t port)
Open COSMOS channel for polling with 100 usec timeout.
Definition: agentclass.cpp:2242
static int32_t req_shutdown(string &request, string &response, Agent *agent)
Built-in Set state to Shutdown request.
Definition: agentclass.cpp:1047
static int32_t req_get_position_data(string &request, string &response, Agent *agent)
Definition: agentclass.cpp:1156
static int32_t req_postsoh(string &request, string &response, Agent *agent)
Definition: agentclass.cpp:1548
Cosmos::Support::Agent::~Agent ( )
269 { Agent::shutdown(); }
int32_t shutdown()
Shutdown agent gracefully.
Definition: agentclass.cpp:366
int32_t Cosmos::Support::Agent::add_request ( string  token,
Agent::external_request_function  function,
string  synopsis = "",
string  description = "" 
)

Add internal request to Agent request list with description and synopsis.

Adds access to the indicated function by way of the given token. The provided function, internal to the agent, will be called with the request string as its argument. Any result will then be returned in the output pointer.

Parameters
tokenA string of maximum length COSMOS_MAX_NAME containing the token for the request. This should be the first word in the request.
functionThe user supplied function to parse the specified request.
descriptionA brief description of the function performed.
synopsisA usage synopsis for the request.
Returns
Error, if any, otherwise zero.Add external request to Agent request list with description and synopsis.
    Adds access to the indicated function by way of the given token. The provided
function, external to the agent, will be called with the request string as its argument. Any result will then be returned in the output pointer.
Parameters
tokenA string of maximum length COSMOS_MAX_NAME containing the token for the request. This should be the first word in the request.
functionThe user supplied function to parse the specified request.
descriptionA brief description of the function performed.
synopsisA usage synopsis for the request.
Returns
Error, if any, otherwise zero.
317  {
318  if (reqs.size() > AGENTMAXREQUESTCOUNT) return (AGENT_ERROR_REQ_COUNT);
319 
320  request_entry tentry;
321  if (token.size() > COSMOS_MAX_NAME) { token.resize(COSMOS_MAX_NAME); }
322  tentry.token = token;
323 // tentry.ifunction = nullptr;
324  tentry.efunction = function;
325  tentry.synopsis = synopsis;
326  tentry.description = description;
327  reqs.push_back(tentry);
328  return 0;
329  }
#define AGENT_ERROR_REQ_COUNT
Definition: cosmos-errno.h:106
#define COSMOS_MAX_NAME
Largest JSON name.
Definition: cosmos-defs.h:55
#define AGENTMAXREQUESTCOUNT
Maximum number of AGENT requests.
Definition: jsondef.h:446
vector< request_entry > reqs
Definition: agentclass.h:412
int32_t Cosmos::Support::Agent::start ( )

Start Agent Request and Heartbeat loops.

Starts the request and heartbeat threads for an Agent server initialized with Cosmos::Agent::Agent. The Agent will open its request and heartbeat channels using the address and port supplied in cinfo. The heartbeat will cycle with the period requested in cinfo.

Returns
value returned by request thread create
337  {
338  // start heartbeat thread
339  hthread = thread([=] { heartbeat_loop(); });
340  cthread = thread([=] { request_loop(); });
341  return 0;
342  }
thread cthread
Handle for request thread.
Definition: agentclass.h:387
void heartbeat_loop()
Heartbeat Loop.
Definition: agentclass.cpp:671
thread hthread
Handle for heartbeat thread.
Definition: agentclass.h:389
void request_loop() noexcept
Request Loop.
Definition: agentclass.cpp:722
int32_t Cosmos::Support::Agent::start_active_loop ( )

Begin Active Loop Initializes timer for active loop using ::aprd

Returns
Zero or negative error.
347  {
348  activeTimeout = currentmjd() + cinfo->agent[0].aprd / 86400.;
349  return 0;
350  }
double activeTimeout
Definition: agentclass.h:375
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::finish_active_loop ( )

Finish active loop Sleep for the remainder of this loops ::aprd as initialized in ::start_active_loop.

Returns
Zero or negative error.
355  {
356  double sleepsec = 86400.*(activeTimeout - currentmjd());
357  activeTimeout += cinfo->agent[0].aprd / 86400.;
358  COSMOS_SLEEP(sleepsec);
359  return 0;
360  }
double activeTimeout
Definition: agentclass.h:375
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::shutdown ( )

Shutdown agent gracefully.

Waits for threads to stop running if we are a server, then releases everything.

Returns
0 or negative error.
367  {
368  if (debug_level) {
369  fprintf(get_debug_fd(), "Shutting down Agent. Last error: %s\n", cosmos_error_string(error_value).c_str());
370  fflush(stdout);
371  }
372 
373  if (cinfo != nullptr) { cinfo->agent[0].stateflag = static_cast <uint16_t>(Agent::State::SHUTDOWN); }
374 
375  if (agentName.size()) {
376  if (hthread.joinable()) { hthread.join(); }
377  if (cthread.joinable()) { cthread.join(); }
379  }
380  if (mthread.joinable()) { mthread.join(); }
383  return 0;
384  }
uint16_t debug_level
Flag for level of debugging, keep it public so that it can be controlled from the outside...
Definition: agentclass.h:362
FILE * get_debug_fd(double mjd=0.)
Definition: agentclass.cpp:2645
int32_t unsubscribe()
Close COSMOS subscription channel.
Definition: agentclass.cpp:2251
thread cthread
Handle for request thread.
Definition: agentclass.h:387
string cosmos_error_string(int32_t cosmos_errno)
Definition: cosmos-errno.cpp:45
int32_t unpublish()
Close COSMOS output channel.
Definition: agentclass.cpp:2205
void json_destroy(cosmosstruc *cinfo)
Remove JSON pointer map.
Definition: jsonlib.cpp:491
thread mthread
Handle for message thread.
Definition: agentclass.h:391
int32_t error_value
Last error.
Definition: agentclass.h:393
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
thread hthread
Handle for heartbeat thread.
Definition: agentclass.h:389
cosmosstruc * cinfo
Definition: agentclass.h:346
string agentName
Definition: agentclass.h:368
uint16_t Cosmos::Support::Agent::running ( )

Check if we're supposed to be running.

Returns the value of the internal variable that indicates that the threads are running.

Returns
Value of internal state variable, as enumerated in Cosmos::Agent:State.
391 { return cinfo->agent[0].stateflag; }
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::wait ( State  state = State::RUN,
double  waitsec = 10. 
)

Wait on state Wait for up to waitsec seconds for Agent to enter requested state

Parameters
stateDesired ::Agent::State.
waitsecMaximum number of seconds to wait.
Returns
Zero, or timeout error.
398  {
399  if (cinfo == nullptr) { return AGENT_ERROR_NULL; }
400 
401  ElapsedTime et;
402  while (cinfo->agent[0].stateflag != static_cast <uint16_t>(state) && et.split() < waitsec) {
403  COSMOS_SLEEP(.1);
404  }
405  if (cinfo->agent[0].stateflag == static_cast <uint16_t>(state)) {
406  return 0;
407  } else {
408  return GENERAL_ERROR_TIMEOUT;
409  }
410  }
#define AGENT_ERROR_NULL
Definition: cosmos-errno.h:111
#define GENERAL_ERROR_TIMEOUT
Definition: cosmos-errno.h:292
ElapsedTime et
Definition: agent_cpu_device_test.cpp:51
int waitsec
Definition: agent_add_soh.cpp:56
Definition: elapsedtime.h:62
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
double split()
ElapsedTime::split, gets the current elapsed time since the start()
Definition: elapsedtime.cpp:234
int32_t Cosmos::Support::Agent::last_error ( )

Last error value. Get value of last error returned by any function.

414 { return (error_value); }
int32_t error_value
Last error.
Definition: agentclass.h:393
int32_t Cosmos::Support::Agent::send_request ( beatstruc  hbeat,
string  request,
string &  output,
float  waitsec = 5. 
)

Send a request over AGENT.

Send a request string to the process at the provided address

Parameters
hbeatThe agent beatstruc
requestthe request and its arguments
outputany output returned by the request
waitsecMaximum number of seconds to wait
Returns
Either the number of bytes returned, or an error number.
424  {
426  int32_t iretn;
427  int32_t nbytes;
428  vector <char> toutput;
429  toutput.resize(AGENTMAXBUFFER+1);
430 
431  if (hbeat.utc == 0. || hbeat.addr[0] == 0 || hbeat.port == 0) return (AGENT_ERROR_SOCKET);
432 
433  ElapsedTime ep;
434  ep.start();
435 
436  if ((iretn=socket_open(&sendchan, NetworkType::UDP, hbeat.addr, hbeat.port, SOCKET_TALK, SOCKET_BLOCKING, AGENTRCVTIMEO)) < 0) { return (-errno); }
437  //nbytes = strnlen(request.c_str(), hbeat.bsz);
438  nbytes = std::min(request.size(), (size_t)hbeat.bsz);
439 
440  if ((nbytes=sendto(sendchan.cudp, request.c_str(), nbytes, 0, (struct sockaddr *)&sendchan.caddr, sizeof(struct sockaddr_in))) < 0) {
441  CLOSE_SOCKET(sendchan.cudp);
442 #ifdef COSMOS_WIN_OS
443  return(-WSAGetLastError());
444 #else
445  return (-errno);
446 #endif
447  }
448 
449  do {
450  nbytes = recvfrom(sendchan.cudp, toutput.data(), AGENTMAXBUFFER, 0, static_cast<struct sockaddr *>(nullptr), static_cast<socklen_t *>(nullptr));
451  } while ( (nbytes <= 0) && (ep.split() <= waitsec) );
452 
453  CLOSE_SOCKET(sendchan.cudp);
454 
455  if (nbytes < 0) {
456 #ifdef COSMOS_WIN_OS
457  return(-WSAGetLastError());
458 #else
459  return (-errno);
460 #endif
461  } else {
462  //toutput[nbytes] = 0;
463  toutput.resize(nbytes);
464  string reply(toutput.begin(), toutput.end());
465  output = reply;
466  return (nbytes);
467  }
468  }
Agent socket using Unicast UDP.
uint32_t bsz
Transfer buffer size.
Definition: jsondef.h:938
char addr[18]
Protocol Address.
Definition: jsondef.h:934
int iretn
Definition: rw_test.cpp:37
string output
Definition: agent-2-0.cpp:56
#define SOCKET_TALK
Talk followed by optional listen (sendto address)
Definition: socketlib.h:82
void start()
ElapsedTime::start.
Definition: elapsedtime.cpp:203
int32_t cudp
Definition: socketlib.h:120
int waitsec
Definition: agent_add_soh.cpp:56
uint16_t port
AGENT port.
Definition: jsondef.h:936
Definition: socketlib.h:115
struct sockaddr_in caddr
Definition: socketlib.h:122
#define AGENT_ERROR_SOCKET
Definition: cosmos-errno.h:108
#define SOCKET_BLOCKING
Blocking Agent.
Definition: socketlib.h:78
#define AGENTRCVTIMEO
Default AGENT socket RCVTIMEO (100 msec)
Definition: agentclass.h:208
Definition: elapsedtime.h:62
double utc
Definition: jsondef.h:926
#define AGENTMAXBUFFER
Maximum AGENT transfer buffer size.
Definition: jsondef.h:438
int32_t socket_open(socket_channel *channel, NetworkType ntype, const char *address, uint16_t port, uint16_t role, bool blocking, uint32_t usectimeo, uint32_t rcvbuf, uint32_t sndbuf)
Open UDP socket.
Definition: socketlib.cpp:51
double split()
ElapsedTime::split, gets the current elapsed time since the start()
Definition: elapsedtime.cpp:234
static vector< socket_channel > sendchan
Definition: agent_forward.cpp:39
int32_t Cosmos::Support::Agent::send_request_jsonnode ( beatstruc  hbeat,
jsonnode jnode,
float  waitsec = 5. 
)

Send request for Node JSON.

Send a set of requests to return the various JSON strings that make up a jsonnode.

Parameters
hbeatThe agent beatstruc
jnodejsonnode cotaining Node information.
waitsecMaximum number of seconds to wait.
Returns
Either the number of bytes returned, or an error number.
477  {
478  int32_t iretn;
479 
480  jnode.name = hbeat.node;
481  iretn = send_request(hbeat, "nodejson", jnode.node, waitsec);
482  if (iretn < 0) { return iretn; }
483  iretn = send_request(hbeat, "statejson", jnode.state, waitsec);
484  if (iretn < 0) { return iretn; }
485  iretn = send_request(hbeat, "utcstartjson", jnode.utcstart, waitsec);
486  if (iretn < 0) { return iretn; }
487  iretn = send_request(hbeat, "piecesjson", jnode.pieces, waitsec);
488  if (iretn < 0) { return iretn; }
489  iretn = send_request(hbeat, "facesjson", jnode.faces, waitsec);
490  if (iretn < 0) { return iretn; }
491  iretn = send_request(hbeat, "vertexsjson", jnode.vertexs, waitsec);
492  if (iretn < 0) { return iretn; }
493  iretn = send_request(hbeat, "devgenjson", jnode.devgen, waitsec);
494  if (iretn < 0) { return iretn; }
495  iretn = send_request(hbeat, "devspecjson", jnode.devspec, waitsec);
496  if (iretn < 0) { return iretn; }
497  iretn = send_request(hbeat, "portsjson", jnode.ports, waitsec);
498  if (iretn < 0) { return iretn; }
499  iretn = send_request(hbeat, "targetsjson", jnode.targets, waitsec);
500  return iretn;
501  }
int32_t send_request(beatstruc cbeat, string request, string &output, float waitsec=5.)
Send a request over AGENT.
Definition: agentclass.cpp:424
string devspec
Definition: jsondef.h:734
string faces
Definition: jsondef.h:731
string node
Definition: jsondef.h:727
int iretn
Definition: rw_test.cpp:37
char node[40+1]
Definition: jsondef.h:928
string pieces
Definition: jsondef.h:732
int waitsec
Definition: agent_add_soh.cpp:56
string targets
Definition: jsondef.h:736
string utcstart
Definition: jsondef.h:729
string ports
Definition: jsondef.h:735
string name
Definition: jsondef.h:726
string state
Definition: jsondef.h:728
string devgen
Definition: jsondef.h:733
string vertexs
Definition: jsondef.h:730
int32_t Cosmos::Support::Agent::get_agent ( string  node,
string  agent,
double  waitsec,
beatstruc rbeat 
)

Get specific server.

Listen to the multicast/broadcast traffic for a set amount of time, waiting for a specific named server to appear, then return its heartbeat.

Parameters
nodeNode for the server.
nameName of the server.
waitsecMaximum number of seconds to wait
rbeatpointer to a location to store the heartbeat
Returns
1 if found, otherwise 0, or an error number
514  {
515 
516  post(AgentMessage::REQUEST, "heartbeat");
517  COSMOS_SLEEP(.1);
518 
519  ElapsedTime ep;
520  ep.start();
521  do {
522  for (beatstruc &it : agent_list)
523  {
524  if ((node == "any" || string(it.node) == node) && string(it.proc) == agent)
525  {
526  it.exists = true;
527  rbeat = it;
528  return 1;
529  }
530  }
531  COSMOS_SLEEP(.1);
532  } while (ep.split() < waitsec);
533 
534  rbeat.exists = false;
535  rbeat.node[0] = '\0';
536  return 0;
537  }
Definition: jsondef.h:923
bool exists
Existence Flag (if beat exists then flag is set to true, false otherwise)
Definition: jsondef.h:950
int32_t post(messstruc mess)
Post a Cosmos::Agent::messstruc.
Definition: agentclass.cpp:2074
void start()
ElapsedTime::start.
Definition: elapsedtime.cpp:203
char node[40+1]
Definition: jsondef.h:928
static Agent * agent
ensure the Agent constructor creates only one instance per process
Definition: agent_001.cpp:45
int waitsec
Definition: agent_add_soh.cpp:56
Definition: elapsedtime.h:62
vector< beatstruc > agent_list
List of active agents.
Definition: agentclass.h:349
static string node
Definition: agent_monitor.cpp:126
double split()
ElapsedTime::split, gets the current elapsed time since the start()
Definition: elapsedtime.cpp:234
int32_t Cosmos::Support::Agent::check_agent ( string  node,
string  agent,
double  waitsec 
)

Check agent.

Check the Cosmos::Agent::agent_list for the particular agent

Parameters
agentName of agent.
nodeNode that agent is in.
waitsecNumber of seconds to wait
Returns
1 if found, otherwise 0, or an error number
547  {
548  beatstruc tbeat;
549  return get_agent(node, agent, waitsec, tbeat);
550  }
Definition: jsondef.h:923
int32_t get_agent(string node, string agent, double waitsec, beatstruc &cbeat)
Get specific server.
Definition: agentclass.cpp:513
static Agent * agent
ensure the Agent constructor creates only one instance per process
Definition: agent_001.cpp:45
int waitsec
Definition: agent_add_soh.cpp:56
static string node
Definition: agent_monitor.cpp:126
beatstruc Cosmos::Support::Agent::find_agent ( string  node,
string  agent,
double  waitsec = 0. 
)

Find agent.

Check the Cosmos::Agent::agent_list for the particular agent, returning its heartbeat if found.

Parameters
agentName of agent.
nodeNode that agent is in.
Returns
beatstruc of located agent, otherwise empty beatstruc.
560  {
561  beatstruc rbeat;
562  get_agent(node, agent, waitsec, rbeat);
563  return rbeat;
564 
565  // ask all existing agents to send out a heartbeat
566 // post(AgentMessage::REQUEST, "heartbeat");
567 // COSMOS_SLEEP(.1);
568 
569 // ElapsedTime ep;
570 // ep.start();
571 // do {
572 // for (beatstruc &it : agent_list)
573 // {
574 // if ((node == "any" || it.node == node) && it.proc == agent)
575 // {
576 // it.exists = true;
577 // return it;
578 // }
579 // }
580 // COSMOS_SLEEP(.1);
581 // } while (ep.split() < waitsec);
582 
583 // beatstruc nobeat;
584 // nobeat.exists = false;
585 // nobeat.node[0] = '\0';
586 
587 // return nobeat;
588  }
Definition: jsondef.h:923
int32_t get_agent(string node, string agent, double waitsec, beatstruc &cbeat)
Get specific server.
Definition: agentclass.cpp:513
static Agent * agent
ensure the Agent constructor creates only one instance per process
Definition: agent_001.cpp:45
int waitsec
Definition: agent_add_soh.cpp:56
static string node
Definition: agent_monitor.cpp:126
vector< beatstruc > Cosmos::Support::Agent::find_agents ( double  waitsec = 0.)

Find single server.

Listen to the local subnet for a set amount of time, collecting heartbeats, searching for a particular agent.

Parameters
nodeNode that agent is in.
procName of agent.
waitsecMaximum number of seconds to wait.
Returns
beatstruc of located agent, otherwise empty ::beatstruc.Generate a list of request servers.
    Listen to the local subnet for a set amount of time,
collecting heartbeats. Return a list of heartbeats collected.
Parameters
waitsecMaximum number of seconds to wait.
Returns
A vector of beatstruc entries listing the unique servers found.

Loop for waitsec seconds, filling list with any discovered heartbeats.

605  {
606  beatstruc tbeat;
607 
609 
610  ElapsedTime ep;
611  ep.start();
612 
613  do {
614  for (size_t k=0; k<agent_list.size(); ++k) {
615  size_t i;
616  for (i=0; i<slist.size(); i++) {
617  if (!strcmp(agent_list[k].node, slist[i].node) && !strcmp(agent_list[k].proc, slist[i].proc))
618  break;
619  }
620  if (i == slist.size()) {
621  slist.push_back(agent_list[k]);
622  for (size_t j=i; j>0; j--) {
623  if (slist[j].port > slist[j-1].port) { break; }
624  tbeat = slist[j];
625  slist[j] = slist[j-1];
626  slist[j-1] = tbeat;
627  }
628  }
629  }
630  } while (ep.split() <= waitsec);
631  return(slist);
632  }
static string port
Definition: add_radio.cpp:16
Definition: jsondef.h:923
int i
Definition: rw_test.cpp:37
void start()
ElapsedTime::start.
Definition: elapsedtime.cpp:203
int waitsec
Definition: agent_add_soh.cpp:56
vector< beatstruc > slist
Definition: agentclass.h:369
Definition: elapsedtime.h:62
vector< beatstruc > agent_list
List of active agents.
Definition: agentclass.h:349
static string node
Definition: agent_monitor.cpp:126
double split()
ElapsedTime::split, gets the current elapsed time since the start()
Definition: elapsedtime.cpp:234
int32_t Cosmos::Support::Agent::set_sohstring ( string  list)

Set Limited SOH string.

Set the Limited SOH string to a JSON list of JSON Name Space names. A proper JSON list will begin and end with matched curly braces, be comma separated, and have all strings in double quotes.

Parameters
listProperly formatted list of JSON names.
Returns
0, otherwise a negative error.
641  {
642  if (!sohtable.empty()) { sohtable.clear(); }
644  return 0;
645  }
int32_t json_table_of_list(vector< jsonentry * > &table, string tokens, cosmosstruc *cinfo)
Output a vector of JSON entries.
Definition: jsonlib.cpp:3086
cosmosstruc * cinfo
Definition: agentclass.h:346
vector< jsonentry * > sohtable
State of Health element vector.
Definition: agentclass.h:156
int32_t Cosmos::Support::Agent::set_fullsohstring ( string  list)

Set Full SOH string.

Set the Full SOH string to a JSON list of JSON Name Space names. A proper JSON list will begin and end with matched curly braces, be comma separated, and have all strings in double quotes.

Parameters
listProperly formatted list of JSON names.
Returns
0, otherwise a negative error.
654  {
655  if (!fullsohtable.empty()) { fullsohtable.clear(); }
657  return 0;
658  }
int32_t json_table_of_list(vector< jsonentry * > &table, string tokens, cosmosstruc *cinfo)
Output a vector of JSON entries.
Definition: jsonlib.cpp:3086
vector< jsonentry * > fullsohtable
Definition: agentclass.h:157
cosmosstruc * cinfo
Definition: agentclass.h:346
cosmosstruc * Cosmos::Support::Agent::get_cosmosstruc ( )

Return Agent cosmosstruc.

Return a pointer to the Agent's internal copy of the cosmosstruc.

Returns
A pointer to the cosmosstruc, otherwise NULL.
664 { return (cinfo); }
cosmosstruc * cinfo
Definition: agentclass.h:346
void Cosmos::Support::Agent::heartbeat_loop ( )
private

Heartbeat Loop.

This function is run as a thread to provide the Heartbeat for the Agent. The Heartbeat will consist of the contents of Agent::AGENT_MESSAG::BEAT in Cosmos::Agent::poll, plus the contents of the Cosmos::Agent::sohstring. It will come every beatstruc::bprd seconds.

671  {
672  ElapsedTime timer_beat;
673 
674  while (cinfo->agent[0].stateflag) {
675 
676  // compute the jitter
677  if (cinfo->agent[0].beat.bprd == 0.) {
678  cinfo->agent[0].beat.jitter = timer_beat.split() - 1.;
679  } else {
680  cinfo->agent[0].beat.jitter = timer_beat.split() - cinfo->agent[0].beat.bprd;
681  }
682  timer_beat.start();
683 
684  // post comes first
685  if (cinfo->agent[0].beat.bprd != 0.) { post_beat(); }
686 
687  // TODO: move the monitoring calculations to another thread with its own loop time that can be controlled
688  // Compute other monitored quantities if monitoring
689  if (cinfo->agent[0].stateflag == static_cast <uint16_t>(Agent::State::MONITOR)) {
690  // TODO: rename beat.cpu to beat.cpu_percent
691  // add beat.cpu_load
692  cinfo->agent[0].beat.cpu = deviceCpu_.getPercentUseForCurrentProcess();//cpu.getLoad();
693  cinfo->agent[0].beat.memory = deviceCpu_.getVirtualMemoryUsed();
694  }
695 
696  if (cinfo->agent[0].stateflag == static_cast <uint16_t>(Agent::State::SHUTDOWN)) {
697  cinfo->agent[0].beat.cpu = 0;
698  cinfo->agent[0].beat.memory = 0;
699  }
700 
701 
702  if (cinfo->agent[0].beat.bprd < AGENT_HEARTBEAT_PERIOD_MIN) {
703  cinfo->agent[0].beat.bprd = 0.;
704  }
705 
706  if (cinfo->agent[0].beat.bprd == 0.) {
707  COSMOS_SLEEP(1.);
708  } else {
709  if (timer_beat.split() <= cinfo->agent[0].beat.bprd) {
710  COSMOS_SLEEP(cinfo->agent[0].beat.bprd - timer_beat.split());
711  }
712  }
713  }
715  }
double getPercentUseForCurrentProcess()
Definition: devicecpu.cpp:191
void start()
ElapsedTime::start.
Definition: elapsedtime.cpp:203
int32_t unpublish()
Close COSMOS output channel.
Definition: agentclass.cpp:2205
DeviceCpu deviceCpu_
Definition: agentclass.h:420
Definition: elapsedtime.h:62
int32_t post_beat()
Definition: agentclass.cpp:2178
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
double split()
ElapsedTime::split, gets the current elapsed time since the start()
Definition: elapsedtime.cpp:234
double getVirtualMemoryUsed()
Definition: devicecpu.cpp:110
#define AGENT_HEARTBEAT_PERIOD_MIN
Default minium heartbeat period (10 msec)
Definition: agentclass.h:210
void Cosmos::Support::Agent::request_loop ( )
privatenoexcept

Request Loop.

This function is run as a thread to service requests to the Agent. It receives requests on it assigned port number, matches the first word of the request against its set of requests, and then either performs the matched function, or returns [NOK].

722  {
723  int32_t iretn;
724  string bufferin;
725 
726  if ((iretn = socket_open(&cinfo->agent[0].req, NetworkType::UDP, (char *)"", cinfo->agent[0].beat.port, SOCKET_LISTEN, SOCKET_BLOCKING, 2000000)) < 0) { return; }
727 
728  cinfo->agent[0].beat.port = cinfo->agent[0].req.cport;
729 
730  while (cinfo->agent[0].stateflag) {
731  bufferin.resize(cinfo->agent[0].beat.bsz);
732  iretn = recvfrom(cinfo->agent[0].req.cudp, &bufferin[0], bufferin.size(), 0, (struct sockaddr *)&cinfo->agent[0].req.caddr, (socklen_t *)&cinfo->agent[0].req.addrlen);
733 
734  if (iretn > 0) {
735  string bufferout;
736  bufferin.resize(iretn);
737  process_request(bufferin, bufferout);
738  }
739  }
740  return;
741  }
Agent socket using Unicast UDP.
int iretn
Definition: rw_test.cpp:37
int32_t process_request(string &bufferin, string &bufferout)
Definition: agentclass.cpp:743
#define SOCKET_BLOCKING
Blocking Agent.
Definition: socketlib.h:78
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
#define SOCKET_LISTEN
Listen followed by optional talk (recvfrom INADDRANY)
Definition: socketlib.h:84
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t socket_open(socket_channel *channel, NetworkType ntype, const char *address, uint16_t port, uint16_t role, bool blocking, uint32_t usectimeo, uint32_t rcvbuf, uint32_t sndbuf)
Open UDP socket.
Definition: socketlib.cpp:51
int32_t Cosmos::Support::Agent::process_request ( string &  bufferin,
string &  bufferout 
)
private
743  {
744  size_t i;
745  int32_t iretn;
746 
747  process_mutex.lock();
748 
749  if (cinfo->agent[0].stateflag == static_cast <uint16_t>(Agent::State::DEBUG)) {
750  printf("Request: [%lu] %s ",bufferin.size(), &bufferin[0]);
751  fflush(stdout);
752  }
753 
754  string variable;
755  string request;
756  request.resize(AGENTMAXBUFFER+1);
757  for (i=0; i<COSMOS_MAX_NAME; i++) {
758  if (bufferin[i] == ' ' || bufferin[i] == 0) {
759  break;
760  }
761  request[i] = bufferin[i];
762  }
763  //request[i] = 0;
764  request.resize(i);
765 
766  for (i=0; i<reqs.size(); i++) { if (!strcmp(request.c_str(),reqs[i].token.c_str())) break; }
767 
768  if (i < reqs.size()) {
769  iretn = -1;
770 // if (reqs[i].ifunction)
771 // {
772 // iretn = (this->*reqs[i].ifunction)(&bufferin[0], &request[0]);
773 // }
774 // else
775 // {
776 // if (reqs[i].efunction != nullptr)
777 // {
778 // iretn = reqs[i].efunction(&bufferin[0], &request[0], this);
779 // }
780 // }
781  if (reqs[i].efunction != nullptr) {
782  iretn = reqs[i].efunction(bufferin, request, this);
783  }
784  if (iretn >= 0) {
785  request.resize(strlen(&request[0]));
786  bufferout = request;
787  } else {
788  bufferout = "[NOK] " + std::to_string(iretn);
789  }
790  } else {
791  iretn = AGENT_ERROR_NULL;
792  bufferout = "[NOK] " + std::to_string(iretn);
793  }
794 
795  iretn = sendto(cinfo->agent[0].req.cudp, bufferout.data(), bufferout.size(), 0, (struct sockaddr *)&cinfo->agent[0].req.caddr, sizeof(struct sockaddr_in));
796  if (cinfo->agent[0].stateflag == static_cast <uint16_t>(Agent::State::DEBUG)) {
797  printf("[%d] %s\n", iretn, bufferout.data());
798  }
799 
800  process_mutex.unlock();
801 
802  return iretn;
803  }
#define AGENT_ERROR_NULL
Definition: cosmos-errno.h:111
int i
Definition: rw_test.cpp:37
#define COSMOS_MAX_NAME
Largest JSON name.
Definition: cosmos-defs.h:55
string to_string(char *value)
Definition: stringlib.cpp:220
int iretn
Definition: rw_test.cpp:37
mutex process_mutex
mutex to protect process_request
Definition: agentclass.h:395
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
vector< request_entry > reqs
Definition: agentclass.h:412
cosmosstruc * cinfo
Definition: agentclass.h:346
#define AGENTMAXBUFFER
Maximum AGENT transfer buffer size.
Definition: jsondef.h:438
void Cosmos::Support::Agent::message_loop ( )
private
806  {
807  messstruc mess;
808  int32_t iretn;
809  // Initialize things
810 // message_ring.resize(MESSAGE_RING_SIZE);
811  while (Agent::running()) {
812  iretn = Agent::poll(mess, AgentMessage::ALL, 0.);
813  if (iretn > 0) {
814  if (!strcmp(mess.meta.beat.proc, "") && mess.adata.empty()) { continue; }
815  bool agent_found = false;
816 
817  for (beatstruc &i : agent_list) {
818  if (!strcmp(i.node, mess.meta.beat.node) && !strcmp(i.proc, mess.meta.beat.proc)) {
819  agent_found = true;
820  // update all information for the last contact with given (node, agent)...
821  i = mess.meta.beat;
822  break;
823  }
824  }
825 
826  if (!agent_found) { agent_list.push_back(mess.meta.beat); }
827 
828  if (mess.meta.type == AgentMessage::REQUEST && strcmp(cinfo->agent[0].beat.proc, "")) {
829  string response;
830  process_request(mess.adata, response);
832  } else {
833 // size_t new_position;
834 // new_position = message_head + 1;
835 // if (new_position >= message_ring.size())
836 // {
837 // new_position = 0;
838 // }
839 // message_ring[new_position] = mess;
840 // message_head = new_position;
841  message_queue.push_back(mess);
842  if (message_queue.size() > MESSAGE_RING_SIZE) { message_queue.pop_front(); }
843  }
844  }
845  }
846  }
Definition: jsondef.h:923
int i
Definition: rw_test.cpp:37
int iretn
Definition: rw_test.cpp:37
int32_t process_request(string &bufferin, string &bufferout)
Definition: agentclass.cpp:743
int32_t poll(messstruc &mess, AgentMessage type, float waitsec=1.)
Listen for message.
Definition: agentclass.cpp:2264
uint16_t running()
Check if we&#39;re supposed to be running.
Definition: agentclass.cpp:391
int32_t post(messstruc mess)
Post a Cosmos::Agent::messstruc.
Definition: agentclass.cpp:2074
#define MESSAGE_RING_SIZE
Default size of message ring buffer.
Definition: agentclass.h:213
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
deque< messstruc > message_queue
Ring buffer for incoming messages.
Definition: agentclass.h:355
cosmosstruc * cinfo
Definition: agentclass.h:346
vector< beatstruc > agent_list
List of active agents.
Definition: agentclass.h:349
int32_t Cosmos::Support::Agent::req_forward ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Forward request.

Resends the received request, less count bytes, to all Publication channels of the Agent.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
856  {
857  uint16_t count;
858  int32_t iretn=-1;
859 
860 // sscanf(request.c_str(),"%*s %hu",&count);
861  sscanf(request.c_str(),"%*s %hu",&count);
862  for (uint16_t i=0; i<agent->cinfo->agent[0].ifcnt; ++i)
863  {
864 // iretn = sendto(agent->cinfo->agent[0].pub[i].cudp,(const char *)&request[request.length()-count],count,0,(struct sockaddr *)&agent->cinfo->agent[0].pub[i].baddr,sizeof(struct sockaddr_in));
865  iretn = sendto(agent->cinfo->agent[0].pub[i].cudp,(const char *)&request[request.size()-count],count,0,(struct sockaddr *)&agent->cinfo->agent[0].pub[i].baddr,sizeof(struct sockaddr_in));
866  }
867 // sprintf(output,"%.17g %d ",currentmjd(0),iretn);
868  output = std::to_string(currentmjd()) + ' ' + std::to_string(iretn);
869  return(0);
870  }
int i
Definition: rw_test.cpp:37
int count
Definition: rw_test.cpp:36
string to_string(char *value)
Definition: stringlib.cpp:220
int iretn
Definition: rw_test.cpp:37
string output
Definition: agent-2-0.cpp:56
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_echo ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Echo request.

Returns the received packet, reaclculating the CRC, and adding the time.

Parameters
requestText of echo packet.
outputText of echoed packet.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
880  {
881  double mjd;
882  uint16_t crc, count;
883 
884 // sscanf(request.c_str(),"%*s %lf %hx %hu",&mjd,&crc,&count);
885 // sprintf(output,"%.17g %x %u ",currentmjd(0),slip_calc_crc((uint8_t *)&request[request.length()-count],count),count);
886 // strncpy(&output[strlen(output)],&request[request.length()-count],count+1);
887  sscanf(request.c_str(),"%*s %lf %hx %hu",&mjd,&crc,&count);
888  output = to_mjd(currentmjd()) + ' ' + to_hex(crc) + ' ' + std::to_string(count) + ' ' + request;
889  return 0;
890  }
int count
Definition: rw_test.cpp:36
string to_string(char *value)
Definition: stringlib.cpp:220
string output
Definition: agent-2-0.cpp:56
png_uint_32 crc
Definition: png.c:2173
double mjd
Definition: udp_send.cpp:41
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
string to_hex(int64_t value, uint16_t digits, bool zerofill)
Definition: stringlib.cpp:225
string to_mjd(double value)
Definition: stringlib.cpp:298
int32_t Cosmos::Support::Agent::req_help_json ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Help request.

Send help response.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
900  {
901  string help_string, s;
902  size_t qpos, prev_qpos = 0;
903  // help_string += "\n";
904  help_string += "{\"requests\": [";
905  for(uint32_t i = 0; i < agent->reqs.size(); ++i) {
906  // help_string += " ";
907  if(i>0) help_string+=",";
908  help_string += "{\"token\": \"";
909  help_string += agent->reqs[i].token;
910  // help_string += " ";
911  help_string += "\", \"synopsis\": \"";
912  // help_string += agent->reqs[i].synopsis;
913  qpos = 0;
914  prev_qpos = 0;
915  s = agent->reqs[i].synopsis;
916  while((qpos=s.substr(prev_qpos).find("\""))!= string::npos)
917  {
918  s.replace(qpos+prev_qpos, 1, "\\\"");
919  prev_qpos +=qpos+2;
920  }
921  help_string+= s;
922  // help_string += "\n";
923  //size_t blanks = (20 - (signed int)strlen(agent->reqs[i].token)) > 0 ? 20 - strlen(agent->reqs[i].token) : 4;
924  //string blank(blanks,' ');
925  //help_string += blank;
926  // help_string += " ";
927  help_string += "\", \"description\": \"";
928  qpos = 0;
929  prev_qpos = 0;
930  s = agent->reqs[i].description;
931  while((qpos=s.substr(prev_qpos).find("\""))!= string::npos){
932  s.replace(qpos+prev_qpos, 1, "\\\"");
933  prev_qpos +=qpos+2;
934  }
935  help_string+= s;
936  // help_string += agent->reqs[i].description;
937  // help_string += "\n\n";
938  help_string +="\"}";
939  }
940  // help_string += "\n";
941  help_string += "]}";
942 // strcpy(output, (char*)help_string.c_str());
943  output = help_string;
944  return 0;
945  }
int i
Definition: rw_test.cpp:37
string output
Definition: agent-2-0.cpp:56
vector< request_entry > reqs
Definition: agentclass.h:412
int32_t Cosmos::Support::Agent::req_help ( string &  request,
string &  response,
Agent agent 
)
staticprivate
947  {
948  string help_string;
949  help_string += "\n";
950  for(uint32_t i = 0; i < agent->reqs.size(); ++i)
951  {
952  help_string += " ";
953  help_string += agent->reqs[i].token;
954  help_string += " ";
955  help_string += agent->reqs[i].synopsis;
956  help_string += "\n";
957  //size_t blanks = (20 - (signed int)strlen(agent->reqs[i].token)) > 0 ? 20 - strlen(agent->reqs[i].token) : 4;
958  //string blank(blanks,' ');
959  //help_string += blank;
960  help_string += " ";
961  help_string += agent->reqs[i].description;
962  help_string += "\n\n";
963  }
964  help_string += "\n";
965  output = help_string;
966  return 0;
967  }
int i
Definition: rw_test.cpp:37
string output
Definition: agent-2-0.cpp:56
vector< request_entry > reqs
Definition: agentclass.h:412
int32_t Cosmos::Support::Agent::req_run ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Set state to Run request.

Resends the received request, less count bytes, to all Publication channels of the Agent.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
977  {
978  agent->cinfo->agent[0].stateflag = static_cast <uint16_t>(Agent::State::RUN);
979  output[0] = 0;
980  return(0);
981  }
Run without monitoring.
string output
Definition: agent-2-0.cpp:56
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_init ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Set state to Init request.

Resends the received request, less count bytes, to all Publication channels of the Agent.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
991  {
992  agent->cinfo->agent[0].stateflag = static_cast <uint16_t>(Agent::State::INIT);
993  output[0] = 0;
994  return(0);
995  }
string output
Definition: agent-2-0.cpp:56
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_idle ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Set state to Idle request.

Resends the received request, less count bytes, to all Publication channels of the Agent.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1005  {
1006  agent->cinfo->agent[0].stateflag = static_cast <uint16_t>(Agent::State::IDLE);
1007  output[0] = 0;
1008  return(0);
1009  }
string output
Definition: agent-2-0.cpp:56
Do minimal necessary to run.
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_monitor ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Set state to Monitor request.

Resends the received request, less count bytes, to all Publication channels of the Agent.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1019  {
1020  agent->cinfo->agent[0].stateflag = static_cast <uint16_t>(Agent::State::MONITOR);
1021  output[0] = 0;
1022  return(0);
1023  }
string output
Definition: agent-2-0.cpp:56
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_reset ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Set state to Reset request.

Resends the received request, less count bytes, to all Publication channels of the Agent.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1033  {
1034  agent->cinfo->agent[0].stateflag = static_cast <uint16_t>(Agent::State::RESET);
1035  output[0] = 0;
1036  return(0);
1037  }
string output
Definition: agent-2-0.cpp:56
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_shutdown ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Set state to Shutdown request.

Resends the received request, less count bytes, to all Publication channels of the Agent.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1047  {
1048  agent->cinfo->agent[0].stateflag = static_cast <uint16_t>(Agent::State::SHUTDOWN);
1049 // output[0] = 0;
1050  output.clear();
1051  return(0);
1052  }
string output
Definition: agent-2-0.cpp:56
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_status ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Status request.

Returns agent status.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1064  {
1065  string jstring;
1066 
1067  if (json_of_agent(jstring, agent->cinfo) != NULL)
1068  {
1069 // strncpy(output, jstring.c_str(),agent->cinfo->agent[0].beat.bsz);
1070 // output[agent->cinfo->agent[0].beat.bsz-1] = 0;
1071  output = jstring;
1072  if (output.length() > agent->cinfo->agent[0].beat.bsz)
1073  {
1074  output[agent->cinfo->agent[0].beat.bsz-1] = 0;
1075  }
1076  return 0;
1077  } else {
1078  output = "error";
1079  return(JSON_ERROR_SCAN);
1080  }
1081  }
string output
Definition: agent-2-0.cpp:56
const char * json_of_agent(string &jstring, cosmosstruc *cinfo)
Create JSON Agent string.
Definition: jsonlib.cpp:8923
#define JSON_ERROR_SCAN
Definition: cosmos-errno.h:96
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_debug_level ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Get Debug Level request Returns or sets the debug_level value.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1090  {
1091  if (request != "debug_level") {
1092  sscanf(request.c_str(), "debug_level %hu", &agent->debug_level);
1093  }
1094  output = std::to_string(agent->debug_level);
1095  return 0;
1096  }
uint16_t debug_level
Flag for level of debugging, keep it public so that it can be controlled from the outside...
Definition: agentclass.h:362
string to_string(char *value)
Definition: stringlib.cpp:220
string output
Definition: agent-2-0.cpp:56
int32_t Cosmos::Support::Agent::req_getvalue ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Get Internal Value request.

Returns the current value of the requested Name Space values. Names are expressed as a JSON object.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1106  {
1107  cout<<"req_getvalue(): incoming request = <"<<request<<">"<<endl;
1108  cout<<"req_getvalue(): incoming request.size() = "<<request.size()<<endl;
1109  cout<<"req_getvalue(): incoming request.length() = "<<request.length()<<endl;
1110  string jstring;
1111  if (json_of_list(jstring, request, agent->cinfo) != NULL) {
1112  output = jstring;
1113  if (output.length() > agent->cinfo->agent[0].beat.bsz) {
1114  output[agent->cinfo->agent[0].beat.bsz-1] = 0;
1115  }
1116  cout<<"req_getvalue(): outgoing response = <"<<output<<">"<<endl;
1117  return 0;
1118  } else {
1119  return (JSON_ERROR_EOS);
1120  }
1121  }
string output
Definition: agent-2-0.cpp:56
#define JSON_ERROR_EOS
Definition: cosmos-errno.h:95
const char * json_of_list(string &jstring, string list, cosmosstruc *cinfo)
Create JSON stream from list.
Definition: jsonlib.cpp:8714
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_get_value ( string &  request,
string &  response,
Agent agent 
)
staticprivate
1123  {
1124  string req = request;
1125  cout<<"req_get_value():incoming request = <"<<request<<">"<<endl;
1126  cout<<"req_get_value():incoming request.size() = "<<request.size()<<endl;
1127  cout<<"req_get_value():incoming request.length() = "<<request.length()<<endl;
1128  // remove function call and space
1129  req.erase(0,10);
1130  // strip out all names from request
1131  vector<string> names;
1132  for(size_t i = 0; i < req.size(); ++i) {
1133  if(req[i]=='"') {
1134  string name("");
1135  while(req[++i]!='"'&&i<req.size()) { name.push_back(req[i]); }
1136  names.push_back(name);
1137  }
1138  }
1139  // response comes to here with the request function name inside it? it that a bug or a feature?
1140  response.clear();
1141  for(size_t i = 0; i < names.size(); ++i) {
1142  response += agent->cinfo->get_json(names[i]);
1143  }
1144  cout<<"req_get_value():outgoing response = <"<<response<<">"<<endl;
1145  return 0;
1146 }
string get_json(const string &s)
Gets a JSON-formatted string of the data associated with the provided name in Namespace 2...
Definition: jsondef.h:7281
int i
Definition: rw_test.cpp:37
string name
Definition: cubesat2obj.cpp:6
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_get_time ( string &  request,
string &  response,
Agent agent 
)
staticprivate
1148  {
1149  stringstream ss;
1150  ss<<setprecision(numeric_limits<double>::digits10)<<currentmjd();
1151  response = ss.str();
1152  return 0;
1153 }
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
int32_t Cosmos::Support::Agent::req_get_position_data ( string &  request,
string &  response,
Agent agent 
)
staticprivate
1156  {
1157 
1158  //cout<<"\tincoming request = <"<<request<<">"<<endl;
1159  //cout<<"req_get_position():incoming request.size() = "<<request.size()<<endl;
1160  //cout<<"req_get_position():incoming request.length() = "<<request.length()<<endl;
1161 
1162  // remove function call and space
1163  request.erase(0,18);
1164 
1165  // read in mjdtime
1166  stringstream ss;
1167  ss<<request;
1168  double timemjd;
1169  ss>>timemjd;
1170  //cout<<"timemjd = <"<<setprecision(numeric_limits<double>::digits10)<<timemjd<<">"<<endl;
1172  // use mjd to calculate position
1173  cosmosstruc* c = agent->cinfo;
1174  // orbital equations
1175 
1176 c->set_PQW(timemjd);
1177 //cout<<setprecision(numeric_limits<double>::digits10)<<timemjd<<", "<<c->P_pos_t<<", "<<c->Q_pos_t<<", "<<c->W_pos_t<<", "<<c->P_vel_t<<", "<<c->Q_vel_t<<", "<<c->W_vel_t<<endl;
1178 c->set_IJK_from_PQW();
1179 cout<<setprecision(numeric_limits<double>::digits10)<<timemjd<<", "<<c->I_pos_t<<", "<<c->J_pos_t<<", "<<c->K_pos_t<<", "<<c->I_vel_t<<", "<<c->J_vel_t<<", "<<c->K_vel_t<<endl;
1180 
1181 /*
1182  // to find position and velocity at time t
1183  // 0 Make sure all necessary orbital elements are set
1184  c->t = timemjd;
1185  c->l = c->a*(1.0-pow(c->e,2.0));
1186  // 1 Calculate mean anamoly (M)
1187  c->M = fmod(c->n * (c->t - c->tau), 2*M_PI);
1188  // 2 Calculate true anamoly (v)
1189  c->v = c->M + (2.0*c->e-0.25*pow(c->e,3.0))*sin(c->M) + 1.25*pow(c->e,2.0)*sin(2.0*c->M) + (13.0/12.0)*pow(c->e,3.0)*sin(3.0*c->M);
1190  // 3 Calculate radius (r)
1191  c->r = c->l / (1.0 + c->e*cos(c->v));
1192  // 4 Calculate position vector <P_pos_t, Q_pos_t, W_pos_t>
1193  c->P_pos_t = c->r * cos(c->v);
1194  c->Q_pos_t = c->r * sin(c->v);
1195  c->W_pos_t = 0.0;
1196  c->P_vel_t = sqrt(c->mu/c->l) * -sin(c->v);
1197  //c->Q_vel_t = sqrt(c->mu/c->l) * (c->e+cos(c->v))*sin(c->v);
1198  c->Q_vel_t = sqrt(c->mu/c->l) * (c->e+cos(c->v));
1199  c->W_vel_t = 0.0;
1200 */
1201 
1202  response.clear();
1203 
1204  //response = "\t\ttime: [ " + request + " ]";
1205  response = request + "\t";
1206  //response += "\n\t\tposition: [ ";
1207  stringstream sss;
1208  sss<<setprecision(numeric_limits<double>::digits10)<<c->P_pos_t;
1209  response += sss.str();
1210  sss.str("");
1211  //response += " ";
1212  response += "\t";
1213  sss<<setprecision(numeric_limits<double>::digits10)<<c->Q_pos_t;
1214  response += sss.str();
1215  sss.str("");
1216  //response += " ";
1217  response += "\t";
1218  sss<<setprecision(numeric_limits<double>::digits10)<<c->W_pos_t;
1219  response += sss.str();
1220  sss.str("");
1221  //response += " ]";
1222  response += "\t";
1223 
1224  // 5 Calculate velocity vector <P_vel_t, Q_vel_t, W_vel_t>
1225  //response += "\n\t\tvelocity: [ ";
1226  sss<<setprecision(numeric_limits<double>::digits10)<<c->P_vel_t;
1227  response += sss.str();
1228  sss.str("");
1229  //response += " ";
1230  response += "\t";
1231  sss<<setprecision(numeric_limits<double>::digits10)<<c->Q_vel_t;
1232  response += sss.str();
1233  sss.str("");
1234  //response += " ";
1235  response += "\t";
1236  sss<<setprecision(numeric_limits<double>::digits10)<<c->W_vel_t;
1237  response += sss.str();
1238  sss.str("");
1239  //response += " ]";
1240 
1241  // 6 Transform perifocal (PQW) co-ords to geocentric equatorial (IJK) co-ords
1242 
1243  // also calculate distance from mothership?
1244 
1245  // ...
1246 
1247  //response = request;
1248  //cout<<"req_get_position():outgoing response = <"<<response<<">"<<endl;
1249  return 0;
1250 }
double P_vel_t
Definition: jsondef.h:4377
double I_vel_t
Definition: jsondef.h:4420
double K_vel_t
Definition: jsondef.h:4422
double Q_vel_t
Definition: jsondef.h:4378
void set_PQW(double time)
Definition: jsondef.h:4425
double W_pos_t
Definition: jsondef.h:4374
double J_pos_t
Definition: jsondef.h:4418
double K_pos_t
Definition: jsondef.h:4419
double W_vel_t
Definition: jsondef.h:4379
double Q_pos_t
Definition: jsondef.h:4373
double J_vel_t
Definition: jsondef.h:4421
double P_pos_t
Definition: jsondef.h:4372
cosmosstruc * cinfo
Definition: agentclass.h:346
double I_pos_t
Definition: jsondef.h:4417
Definition: jsondef.h:4199
void set_IJK_from_PQW()
Definition: jsondef.h:4451
int32_t Cosmos::Support::Agent::req_get_position ( string &  request,
string &  response,
Agent agent 
)
staticprivate
1253  {
1254 
1255  cout<<"\tincoming request = <"<<request<<">"<<endl;
1256  //cout<<"req_get_position():incoming request.size() = "<<request.size()<<endl;
1257  //cout<<"req_get_position():incoming request.length() = "<<request.length()<<endl;
1258 
1259  // remove function call and space
1260  request.erase(0,13);
1261 
1262  // read in mjdtime
1263  stringstream ss;
1264  ss<<request;
1265  double timemjd;
1266  ss>>timemjd;
1267  //cout<<"timemjd = <"<<setprecision(numeric_limits<double>::digits10)<<timemjd<<">"<<endl;
1268 
1269  // use mjd to calculate position
1270  cosmosstruc* c = agent->cinfo;
1271  // orbital equations
1272 
1273  // to find position and velocity at time t
1274  // 0 Make sure all necessary orbital elements are set
1275  c->t = timemjd;
1276  c->l = c->a*(1.0-pow(c->e,2.0));
1277  // 1 Calculate mean anamoly (M)
1278  c->M = fmod(c->n * (c->t - c->tau), 2*M_PI);
1279  // 2 Calculate true anamoly (v)
1280  c->v = c->M + (2.0*c->e-0.25*pow(c->e,3.0))*sin(c->M) + 1.25*pow(c->e,2.0)*sin(2.0*c->M) + (13.0/12.0)*pow(c->e,3.0)*sin(3.0*c->M);
1281  // 3 Calculate radius (r)
1282  c->r = c->l / (1.0 + c->e*cos(c->v));
1283  // 4 Calculate position vector <P_pos_t, Q_pos_t, W_pos_t>
1284  c->P_pos_t = c->r * cos(c->v);
1285  c->Q_pos_t = c->r * sin(c->v);
1286  c->W_pos_t = 0.0;
1287  c->P_vel_t = sqrt(c->mu/c->l) * -sin(c->v);
1288  //c->Q_vel_t = sqrt(c->mu/c->l) * (c->e+cos(c->v))*sin(c->v);
1289  c->Q_vel_t = sqrt(c->mu/c->l) * (c->e+cos(c->v));
1290  c->W_vel_t = 0.0;
1291 
1292  response.clear();
1293 
1294  response = "\t\ttime: [ " + request + " ]";
1295  response += "\n\t\tposition: [ ";
1296  stringstream sss;
1297  sss<<setprecision(numeric_limits<double>::digits10)<<c->P_pos_t;
1298  response += sss.str();
1299  sss.str("");
1300  response += " ";
1301  sss<<setprecision(numeric_limits<double>::digits10)<<c->Q_pos_t;
1302  response += sss.str();
1303  sss.str("");
1304  response += " ";
1305  sss<<setprecision(numeric_limits<double>::digits10)<<c->W_pos_t;
1306  response += sss.str();
1307  sss.str("");
1308  response += " ]";
1309 
1310  // 5 Calculate velocity vector <P_vel_t, Q_vel_t, W_vel_t>
1311  response += "\n\t\tvelocity: [ ";
1312  sss<<setprecision(numeric_limits<double>::digits10)<<c->P_vel_t;
1313  response += sss.str();
1314  sss.str("");
1315  response += " ";
1316  sss<<setprecision(numeric_limits<double>::digits10)<<c->Q_vel_t;
1317  response += sss.str();
1318  sss.str("");
1319  response += " ";
1320  sss<<setprecision(numeric_limits<double>::digits10)<<c->W_vel_t;
1321  response += sss.str();
1322  sss.str("");
1323  response += " ]";
1324 
1325  // 6 Transform perifocal (PQW) co-ords to geocentric equatorial (IJK) co-ords
1326 
1327  // also calculate distance from mothership?
1328 
1329  // ...
1330 
1331  //response = request;
1332  //cout<<"req_get_position():outgoing response = <"<<response<<">"<<endl;
1333  return 0;
1334 }
double P_vel_t
Definition: jsondef.h:4377
double Q_vel_t
Definition: jsondef.h:4378
double W_pos_t
Definition: jsondef.h:4374
double W_vel_t
Definition: jsondef.h:4379
double l
Definition: jsondef.h:4330
double Q_pos_t
Definition: jsondef.h:4373
double mu
Definition: jsondef.h:4350
double P_pos_t
Definition: jsondef.h:4372
double r
Definition: jsondef.h:4369
double M
Definition: jsondef.h:4363
cosmosstruc * cinfo
Definition: agentclass.h:346
double n
Definition: jsondef.h:4353
Definition: jsondef.h:4199
double a
Definition: jsondef.h:4320
double tau
Definition: jsondef.h:4340
double v
Definition: jsondef.h:4366
double t
Definition: jsondef.h:4359
double e
Definition: jsondef.h:4322
int32_t Cosmos::Support::Agent::req_setvalue ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Set Internal Value request.

Sets the current value of the requested Name Space values. Names and values are expressed as a JSON object.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1345  {
1346  int32_t iretn;
1347  iretn = json_parse(request, agent->cinfo);
1348  output = std::to_string(iretn);
1349  return(iretn);
1350  }
int32_t json_parse(string jstring, cosmosstruc *cinfo)
Parse JSON using Name Space.
Definition: jsonlib.cpp:4799
string to_string(char *value)
Definition: stringlib.cpp:220
int iretn
Definition: rw_test.cpp:37
string output
Definition: agent-2-0.cpp:56
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_set_value ( string &  request,
string &  response,
Agent agent 
)
staticprivate
1352  {
1353  // remove function call and space ('set_value ')
1354  request.erase(0,10);
1355  cout<<"req_set_value():incoming request = <"<<request<<">"<<endl;
1356  cout<<"req_set_value():incoming request.size() = "<<request.size()<<endl;
1357  cout<<"req_set_value():incoming request.length() = "<<request.length()<<endl;
1358  cout<<"req_set_value():incoming response = <"<<response<<">"<<endl;
1359 
1360  // set the value from json string
1361  agent->cinfo->set_json(request);
1362 
1363  cout<<"req_set_value():outgoing response = <"<<response<<">"<<endl;
1364  return 0;
1365 }
void set_json(const string &json)
Sets the data in Namespace 2.0 with a JSON-formatted string.
Definition: jsondef.h:6822
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_listnames ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in List Name Space Names request.

Returns a list of all names in the JSON Name Space.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1375  {
1376  output = json_list_of_all(agent->cinfo);
1377  if (output.length() > agent->cinfo->agent[0].beat.bsz) { output[agent->cinfo->agent[0].beat.bsz-1] = 0; }
1378  return 0;
1379  }
string output
Definition: agent-2-0.cpp:56
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
string json_list_of_all(cosmosstruc *cinfo)
Get list of all Namespace names.
Definition: jsonlib.cpp:9225
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_nodejson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return Node JSON request.

Returns a JSON string representing the Node description.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1389  {
1390  output = agent->cinfo->json.node.c_str();
1391  if (output.length() > agent->cinfo->agent[0].beat.bsz) { output[agent->cinfo->agent[0].beat.bsz-1] = 0; }
1392  return 0;
1393  }
string node
Definition: jsondef.h:727
string output
Definition: agent-2-0.cpp:56
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_statejson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return State Vector JSON request.

Returns a JSON string representing the State Vector.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1403  {
1404  output = agent->cinfo->json.state.c_str();
1405  if (output.length() > agent->cinfo->agent[0].beat.bsz) { output[agent->cinfo->agent[0].beat.bsz-1] = 0; }
1406  return 0;
1407  }
string output
Definition: agent-2-0.cpp:56
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
string state
Definition: jsondef.h:728
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_utcstartjson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return UTC Start Time JSON request.

Returns a JSON string representing the UTC Start Time.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1417  {
1418  output = agent->cinfo->json.utcstart.c_str();
1419  if (output.length() > agent->cinfo->agent[0].beat.bsz) { output[agent->cinfo->agent[0].beat.bsz-1] = 0; }
1420  return 0;
1421  }
string output
Definition: agent-2-0.cpp:56
string utcstart
Definition: jsondef.h:729
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_piecesjson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return Pieces JSON request.

Returns a JSON string representing the Piece information.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1431  {
1432  output = agent->cinfo->json.pieces.c_str();
1433  if (output.length() > agent->cinfo->agent[0].beat.bsz) { output[agent->cinfo->agent[0].beat.bsz-1] = 0; }
1434  return 0;
1435  }
string output
Definition: agent-2-0.cpp:56
string pieces
Definition: jsondef.h:732
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_facesjson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return Face JSON request.

Returns a JSON string representing the Face information.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1445  {
1446  output = agent->cinfo->json.faces.c_str();
1447  if (output.length() > agent->cinfo->agent[0].beat.bsz) { output[agent->cinfo->agent[0].beat.bsz-1] = 0; }
1448  return 0;
1449  }
string faces
Definition: jsondef.h:731
string output
Definition: agent-2-0.cpp:56
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_vertexsjson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return Vertex JSON request.

Returns a JSON string representing the Vertex information.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1459  {
1460  output = agent->cinfo->json.vertexs.c_str();
1461  if (output.length() > agent->cinfo->agent[0].beat.bsz) { output[agent->cinfo->agent[0].beat.bsz-1] = 0; }
1462  return 0;
1463  }
string output
Definition: agent-2-0.cpp:56
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
string vertexs
Definition: jsondef.h:730
int32_t Cosmos::Support::Agent::req_devgenjson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return devgen JSON request.

Returns a JSON string representing the generic device information.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1473  {
1474  output = agent->cinfo->json.devgen.c_str();
1475  if (output.length() > agent->cinfo->agent[0].beat.bsz) { output[agent->cinfo->agent[0].beat.bsz-1] = 0; }
1476  return 0;
1477  }
string output
Definition: agent-2-0.cpp:56
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
string devgen
Definition: jsondef.h:733
int32_t Cosmos::Support::Agent::req_devspecjson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return devspec JSON request.

Returns a JSON string representing the special device information.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1487  {
1488  output = agent->cinfo->json.devspec.c_str();
1489  if (output.length() > agent->cinfo->agent[0].beat.bsz) { output[agent->cinfo->agent[0].beat.bsz-1] = 0; }
1490  return 0;
1491  }
string devspec
Definition: jsondef.h:734
string output
Definition: agent-2-0.cpp:56
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_portsjson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return Ports JSON request.

Returns a JSON string representing the Port information.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1501  {
1502 // strncpy(output, agent->cinfo->json.ports.c_str(), agent->cinfo->json.ports.size()<agent->cinfo->agent[0].beat.bsz-1?agent->cinfo->json.ports.size():agent->cinfo->agent[0].beat.bsz-1);
1503 // output[agent->cinfo->agent[0].beat.bsz-1] = 0;
1504  output = agent->cinfo->json.ports.c_str();
1505  if (output.length() > agent->cinfo->agent[0].beat.bsz)
1506  {
1507  output[agent->cinfo->agent[0].beat.bsz-1] = 0;
1508  }
1509  return 0;
1510  }
string output
Definition: agent-2-0.cpp:56
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
string ports
Definition: jsondef.h:735
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_targetsjson ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Return Target JSON request.

Returns a JSON string representing the Target information.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1520  {
1521 // strncpy(output, agent->cinfo->json.targets.c_str(), agent->cinfo->json.targets.size()<agent->cinfo->agent[0].beat.bsz-1?agent->cinfo->json.targets.size():agent->cinfo->agent[0].beat.bsz-1);
1522 // output[agent->cinfo->agent[0].beat.bsz-1] = 0;
1523  output = agent->cinfo->json.targets.c_str();
1524  if (output.length() > agent->cinfo->agent[0].beat.bsz)
1525  {
1526  output[agent->cinfo->agent[0].beat.bsz-1] = 0;
1527  }
1528  return 0;
1529  }
string output
Definition: agent-2-0.cpp:56
string targets
Definition: jsondef.h:736
jsonnode json
JSON descriptive information.
Definition: jsondef.h:4262
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_heartbeat ( string &  request,
string &  output,
Agent agent 
)
staticprivate

Built-in Send Heartbeat request.

Send a Heartbeat out of the regular time for heartbeats.

Parameters
requestText of request.
outputText of response to request.
agentPointer to Cosmos::Agent to use.
Returns
0, or negative error.
1539  {
1540 // output[0] = 0;
1541  output.clear();
1542  int32_t iretn = 0;
1543  iretn = agent->post_beat();
1544  return iretn;
1545  }
int iretn
Definition: rw_test.cpp:37
string output
Definition: agent-2-0.cpp:56
int32_t post_beat()
Definition: agentclass.cpp:2178
int32_t Cosmos::Support::Agent::req_postsoh ( string &  request,
string &  response,
Agent agent 
)
staticprivate
1548  {
1549 // output[0] = 0;
1550  output.clear();
1551  int32_t iretn = 0;
1552  iretn = agent->post_soh();
1553  return iretn;
1554  }
int iretn
Definition: rw_test.cpp:37
string output
Definition: agent-2-0.cpp:56
int32_t post_soh()
Definition: agentclass.cpp:2194
int32_t Cosmos::Support::Agent::req_utc ( string &  request,
string &  response,
Agent agent 
)
staticprivate
1556  {
1557 // response = " %.15g %lf ", agent->agent_time_producer(), utc2unixseconds(agent->agent_time_producer()));
1558  response = to_mjd(agent->agent_time_producer()) + ' ' + std::to_string(utc2unixseconds(agent->agent_time_producer()));
1559  return 0;
1560  }
double(* agent_time_producer)()
Function in which we generate our time, for the mjd request.
Definition: agentclass.h:398
string to_string(char *value)
Definition: stringlib.cpp:220
double utc2unixseconds(double utc)
UTC to Unix time.
Definition: timelib.cpp:167
string to_mjd(double value)
Definition: stringlib.cpp:298
int32_t Cosmos::Support::Agent::req_soh ( string &  ,
string &  response,
Agent agent 
)
staticprivate
1562  {
1563  string rjstring;
1564  response = json_of_table(rjstring, agent->sohtable, agent->cinfo);
1565 
1566  return 0;
1567  }
const char * json_of_table(string &jstring, vector< jsonentry * > table, cosmosstruc *cinfo)
Create JSON stream from entries.
Definition: jsonlib.cpp:8733
cosmosstruc * cinfo
Definition: agentclass.h:346
vector< jsonentry * > sohtable
State of Health element vector.
Definition: agentclass.h:156
int32_t Cosmos::Support::Agent::req_fullsoh ( string &  ,
string &  response,
Agent agent 
)
staticprivate
1569  {
1570  string rjstring;
1571  response = json_of_table(rjstring, agent->fullsohtable, agent->cinfo);
1572  return 0;
1573  }
const char * json_of_table(string &jstring, vector< jsonentry * > table, cosmosstruc *cinfo)
Create JSON stream from entries.
Definition: jsonlib.cpp:8733
vector< jsonentry * > fullsohtable
Definition: agentclass.h:157
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::req_jsondump ( string &  ,
string &  response,
Agent agent 
)
staticprivate
1576  {
1577  json_dump_node(agent->cinfo);
1578  return 0;
1579  }
int32_t json_dump_node(cosmosstruc *cinfo)
Save Node entries to disk.
Definition: jsonlib.cpp:7233
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::publish ( NetworkType  type,
uint16_t  port 
)

Open COSMOS output channel.

Establish a multicast socket for publishing COSMOS messages using the specified address and port.

Parameters
typeOne of NetworkType.
portPort number to publish on.
Returns
0, otherwise negative error.
1589  {
1590  int32_t iretn = 0;
1591  int on = 1;
1592 
1593  // Return immediately if we've already done this
1594  if (cinfo->agent[0].pub[0].cport)
1595  return 0;
1596 
1597  switch (type)
1598  {
1600  case NetworkType::UDP:
1602  {
1603  for (uint32_t i=0; i<AGENTMAXIF; i++) { cinfo->agent[0].pub[i].cudp = -1; }
1604 
1605  if ((cinfo->agent[0].pub[0].cudp=socket(AF_INET,SOCK_DGRAM,0)) < 0) { return (AGENT_ERROR_SOCKET); }
1606 
1607 #ifdef COSMOS_WIN_OS
1608  u_long nonblocking = 1;;
1609  if (ioctlsocket(cinfo->agent[0].pub[0].cudp, FIONBIO, &nonblocking) != 0) { iretn = -WSAGetLastError(); }
1610 #else
1611  if (fcntl(cinfo->agent[0].pub[0].cudp, F_SETFL,O_NONBLOCK) < 0) { iretn = -errno; }
1612 #endif
1613  if (iretn < 0) {
1614  CLOSE_SOCKET(cinfo->agent[0].pub[0].cudp);
1615  cinfo->agent[0].pub[0].cudp = iretn;
1616  return iretn;
1617  }
1618 
1619  // Use above socket to find available interfaces and establish
1620  // publication on each.
1621  cinfo->agent[0].ifcnt = 0;
1622 
1623 #if defined(COSMOS_WIN_OS)
1624  struct sockaddr_storage ss;
1625  int sslen;
1626  INTERFACE_INFO ilist[20];
1627  unsigned long nbytes;
1628  uint32_t nif;
1629  if (WSAIoctl(cinfo->agent[0].pub[0].cudp, SIO_GET_INTERFACE_LIST, 0, 0, &ilist,sizeof(ilist), &nbytes, 0, 0) == SOCKET_ERROR) {
1630  CLOSE_SOCKET(cinfo->agent[0].pub[0].cudp);
1631  return (AGENT_ERROR_DISCOVERY);
1632  }
1633 
1634  nif = nbytes / sizeof(INTERFACE_INFO);
1635  for (uint32_t i=0; i<nif; i++) {
1636  inet_ntop(ilist[i].iiAddress.AddressIn.sin_family,&ilist[i].iiAddress.AddressIn.sin_addr,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address,sizeof(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address));
1637  // strcpy(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address,inet_ntoa(((struct sockaddr_in*)&(ilist[i].iiAddress))->sin_addr));
1638  if (!strcmp(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address,"127.0.0.1")) {
1639  if (cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp >= 0) {
1640  CLOSE_SOCKET(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp);
1641  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp = -1;
1642  }
1643  continue;
1644  }
1645 
1646  // No need to open first socket again
1647  if (cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp < 0) {
1648  if ((cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
1649  continue;
1650  }
1651  u_long nonblocking = 1;
1652  if (ioctlsocket(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp, FIONBIO, &nonblocking) != 0) {
1653  continue;
1654  }
1655  }
1656 
1657  memset(&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr,0,sizeof(struct sockaddr_in));
1658  cinfo->agent[0].pub[i].caddr.sin_family = AF_INET;
1659  cinfo->agent[0].pub[i].baddr.sin_family = AF_INET;
1660  if (type == NetworkType::MULTICAST) {
1661  sslen = sizeof(ss);
1662  WSAStringToAddressA((char *)AGENTMCAST,AF_INET,NULL,(struct sockaddr*)&ss,&sslen);
1663  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr;
1664  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr;
1665  } else {
1666  if ((iretn = setsockopt(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on))) < 0)
1667  {
1668  CLOSE_SOCKET(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp);
1669  continue;
1670  }
1671 
1672  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_addr = ((struct sockaddr_in *)&ilist[i].iiAddress)->sin_addr;
1673  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr = ((struct sockaddr_in *)&ilist[i].iiAddress)->sin_addr;
1674 
1675  uint32_t ip, net, bcast;
1676  ip = ((struct sockaddr_in*)&(ilist[i].iiAddress))->sin_addr.S_un.S_addr;
1677  net = ((struct sockaddr_in*)&(ilist[i].iiNetmask))->sin_addr.S_un.S_addr;
1678  bcast = ip | (~net);
1679  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr.S_un.S_addr = bcast;
1680  }
1681  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_port = htons(port);
1682  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_port = htons(port);
1683  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].type = type;
1684  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cport = port;
1685  cinfo->agent[0].ifcnt++;
1686  }
1687 #elif defined(COSMOS_MAC_OS)
1688  struct ifaddrs *if_addrs = NULL;
1689  struct ifaddrs *if_addr = NULL;
1690  if (0 == getifaddrs(&if_addrs)) {
1691  for (if_addr = if_addrs; if_addr != NULL; if_addr = if_addr->ifa_next) {
1692  if (if_addr->ifa_addr->sa_family != AF_INET) { continue; }
1693  inet_ntop(if_addr->ifa_addr->sa_family,&((struct sockaddr_in*)if_addr->ifa_addr)->sin_addr,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address,sizeof(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address));
1694  memcpy((char *)&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr, (char *)if_addr->ifa_addr, sizeof(if_addr->ifa_addr));
1695 
1696  if ((if_addr->ifa_flags & IFF_POINTOPOINT) || (if_addr->ifa_flags & IFF_UP) == 0 || (if_addr->ifa_flags & IFF_LOOPBACK) || (if_addr->ifa_flags & (IFF_BROADCAST)) == 0)
1697  {
1698  continue;
1699  }
1700 
1701  // No need to open first socket again
1702  if (cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp < 0) {
1703  if ((cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
1704  continue;
1705  }
1706 
1707  if (fcntl(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp, F_SETFL,O_NONBLOCK) < 0) {
1708  iretn = -errno;
1709  CLOSE_SOCKET(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp);
1710  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp = iretn;
1711  continue;
1712  }
1713  }
1714 
1715  if (type == NetworkType::MULTICAST) {
1716  inet_pton(AF_INET,AGENTMCAST,&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_addr);
1717  inet_pton(AF_INET,AGENTMCAST,&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr);
1718  } else {
1719  if ((iretn = setsockopt(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on))) < 0) {
1720  CLOSE_SOCKET(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp);
1721  continue;
1722  }
1723 
1724  // if (ioctl(cinfo->agent[0].pub[0].cudp,SIOCGIFBRDADDR,(char *)ifra) < 0)
1725  // {
1726  // continue;
1727  // }
1728  // cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr = cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr;
1729  memcpy((char *)&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr, (char *)if_addr->ifa_netmask, sizeof(if_addr->ifa_netmask));
1730 
1731  uint32_t ip, net, bcast;
1732  ip = cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_addr.s_addr;
1733  net = cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr.s_addr;
1734  bcast = ip | (~net);
1735  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr.s_addr = bcast;
1736  inet_ntop(if_addr->ifa_netmask->sa_family,&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddress,sizeof(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddress));
1737  }
1738  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_port = htons(port);
1739  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_port = htons(port);
1740  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].type = type;
1741  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cport = port;
1742  cinfo->agent[0].ifcnt++;
1743  }
1744  freeifaddrs(if_addrs);
1745  if_addrs = NULL;
1746  }
1747 #else
1748  struct ifconf confa;
1749  struct ifreq *ifra;
1750  char data[512];
1751 
1752  confa.ifc_len = sizeof(data);
1753  confa.ifc_buf = (caddr_t)data;
1754  if (ioctl(cinfo->agent[0].pub[0].cudp,SIOCGIFCONF,&confa) < 0)
1755  {
1756  CLOSE_SOCKET(cinfo->agent[0].pub[0].cudp);
1757  return (AGENT_ERROR_DISCOVERY);
1758  }
1759  // Use result to discover interfaces.
1760  ifra = confa.ifc_req;
1761  bool found_bcast = false;
1762  int16_t lo_index = -1;
1763  for (int32_t n=confa.ifc_len/sizeof(struct ifreq); --n >= 0; ifra++) {
1764 
1765  if (ifra->ifr_addr.sa_family != AF_INET)
1766  {
1767  continue;
1768  }
1769 
1770  inet_ntop(ifra->ifr_addr.sa_family,&((struct sockaddr_in*)&ifra->ifr_addr)->sin_addr,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address,sizeof(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address));
1771  memcpy((char *)&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr, (char *)&ifra->ifr_addr, sizeof(ifra->ifr_addr));
1772 
1773  if (ioctl(cinfo->agent[0].pub[0].cudp,SIOCGIFFLAGS, (char *)ifra) < 0) continue;
1774 
1775 // if ((ifra->ifr_flags & IFF_POINTOPOINT) || (ifra->ifr_flags & IFF_UP) == 0 || (ifra->ifr_flags & IFF_LOOPBACK) || (ifra->ifr_flags & (IFF_BROADCAST)) == 0)
1776  if ((ifra->ifr_flags & IFF_UP) == 0)
1777  {
1778  continue;
1779  }
1780  else if (ifra->ifr_flags & IFF_LOOPBACK)
1781  {
1782  // Don't enable loopback if we found broadcast interface
1783  if (found_bcast)
1784  {
1785  continue;
1786  }
1787  lo_index = cinfo->agent[0].ifcnt;
1788  }
1789  else if (ifra->ifr_flags & IFF_BROADCAST)
1790  {
1791  found_bcast = true;
1792  if (lo_index >= 0)
1793  {
1794  // Remove loopback if we found broadcast interface
1795  if (cinfo->agent[0].pub[lo_index].cudp >= 0)
1796  {
1797  CLOSE_SOCKET(cinfo->agent[0].pub[lo_index].cudp);
1798  }
1799  for (uint16_t i=lo_index+1; i<cinfo->agent[0].ifcnt+1; ++i)
1800  {
1801  cinfo->agent[0].pub[i-1] = cinfo->agent[0].pub[i];
1802  }
1803  lo_index = -1;
1804  --cinfo->agent[0].ifcnt;
1805  }
1806  }
1807 
1808 
1809  // Open socket again if we had to close it
1810  if (cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp < 0)
1811  {
1812  if ((cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp=socket(AF_INET,SOCK_DGRAM,0)) < 0)
1813  {
1814  continue;
1815  }
1816 
1817  if (fcntl(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp, F_SETFL,O_NONBLOCK) < 0)
1818  {
1819  iretn = -errno;
1820  CLOSE_SOCKET(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp);
1821  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp = iretn;
1822  continue;
1823  }
1824  }
1825 
1826  if (type == NetworkType::MULTICAST)
1827  {
1828  inet_pton(AF_INET,AGENTMCAST,&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_addr);
1829  inet_pton(AF_INET,AGENTMCAST,&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr);
1830  }
1831  else
1832  {
1833 // int val = IP_PMTUDISC_DO;
1834 // if ((iretn = setsockopt(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) < 0)
1835 // {
1836 // CLOSE_SOCKET(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp);
1837 // continue;
1838 // }
1839 
1840  if ((ifra->ifr_flags & IFF_POINTOPOINT))
1841  {
1842  if (ioctl(cinfo->agent[0].pub[0].cudp,SIOCGIFDSTADDR,(char *)ifra) < 0)
1843  {
1844  continue;
1845  }
1846  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr = cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr;
1847  inet_ntop(ifra->ifr_dstaddr.sa_family,&((struct sockaddr_in*)&ifra->ifr_dstaddr)->sin_addr,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddress,sizeof(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddress));
1848  inet_pton(AF_INET,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddress,&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr);
1849 
1850  }
1851  else
1852  {
1853  if ((iretn = setsockopt(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp, SOL_SOCKET, SO_BROADCAST, (char*)&on, sizeof(on))) < 0)
1854  {
1855  CLOSE_SOCKET(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp);
1856  continue;
1857  }
1858 
1859  if (ioctl(cinfo->agent[0].pub[0].cudp,SIOCGIFBRDADDR,(char *)ifra) < 0)
1860  {
1861  continue;
1862  }
1863  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr = cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr;
1864  inet_ntop(ifra->ifr_broadaddr.sa_family,&((struct sockaddr_in*)&ifra->ifr_broadaddr)->sin_addr,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddress,sizeof(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddress));
1865  inet_pton(AF_INET,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddress,&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_addr);
1866  }
1867 
1868  if (ioctl(cinfo->agent[0].pub[0].cudp,SIOCGIFADDR,(char *)ifra) < 0)
1869  {
1870  continue;
1871  }
1872  inet_ntop(ifra->ifr_addr.sa_family,&((struct sockaddr_in*)&ifra->ifr_addr)->sin_addr,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address,sizeof(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address));
1873  inet_pton(AF_INET,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address,&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_addr);
1874  }
1875 
1876  iretn = sendto(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp, // socket
1877  (const char *)nullptr, // buffer to send
1878  0, // size of buffer
1879  0, // flags
1880  (struct sockaddr *)&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr, // socket address
1881  sizeof(struct sockaddr_in) // size of address to socket pointer
1882  );
1883  // Find assigned port, place in cport, and set caddr to requested port
1884  socklen_t namelen = sizeof(struct sockaddr_in);
1885  if ((iretn = getsockname(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp, (sockaddr*)&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr, &namelen)) == -1)
1886  {
1887  CLOSE_SOCKET(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp);
1888  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cudp = -errno;
1889  return (-errno);
1890  }
1891  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].cport = ntohs(cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_port);
1892  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_port = htons(port);
1893  inet_pton(AF_INET,cinfo->agent[0].pub[cinfo->agent[0].ifcnt].address,&cinfo->agent[0].pub[cinfo->agent[0].ifcnt].caddr.sin_addr);
1894  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].baddr.sin_port = htons(port);
1895  cinfo->agent[0].pub[cinfo->agent[0].ifcnt].type = type;
1896 
1897 
1898  cinfo->agent[0].ifcnt++;
1899  }
1900 #endif // COSMOS_WIN_OS
1901  }
1902  break;
1903  default:
1904  return SOCKET_ERROR_PROTOCOL;
1905  break;
1906  }
1907 
1908  return 0;
1909  }
static string port
Definition: add_radio.cpp:16
Agent socket using Unicast UDP.
int i
Definition: rw_test.cpp:37
#define SOCKET_ERROR_PROTOCOL
Definition: cosmos-errno.h:230
int iretn
Definition: rw_test.cpp:37
#define AGENT_ERROR_DISCOVERY
Definition: cosmos-errno.h:112
#define AGENTMCAST
AGENT heartbeat Multicast address.
Definition: agentclass.h:202
#define AGENT_ERROR_SOCKET
Definition: cosmos-errno.h:108
Agent socket using Broadcast UDP.
#define AGENTMAXIF
Maximum number of supported publication interfaces.
Definition: jsondef.h:440
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
Agent socket using Multicast UDP.
vector< socket_channel > Cosmos::Support::Agent::find_addresses ( NetworkType  ntype)

Discover interfaces.

Return a vector of socket_channel containing info on each valid interface. For IPV4 this will include the address and broadcast address, in both string sockaddr_in format.

Parameters
ntypeType of network (Multicast, Broadcast UDP, CSP)
Returns
Vector of interfaces
1918  {
1919  vector<socket_channel> iface;
1920  socket_channel tiface;
1921 
1922 #ifdef COSMOS_WIN_OS
1923  struct sockaddr_storage ss;
1924  int sslen;
1925  INTERFACE_INFO ilist[20];
1926  unsigned long nbytes;
1927  size_t nif, ssize;
1928  uint32_t ip, net, bcast;
1929 #else
1930  struct ifconf confa;
1931  struct ifreq *ifra;
1932  char data[512];
1933 #endif // COSMOS_WIN_OS
1934  int32_t iretn;
1935  int on = 1;
1936  int32_t cudp;
1937 
1938  switch (ntype)
1939  {
1941  case NetworkType::UDP:
1942  {
1943  if ((cudp=socket(AF_INET,SOCK_DGRAM,0)) < 0) { return (iface); }
1944 
1945  // Use above socket to find available interfaces and establish
1946  // publication on each.
1947 #ifdef COSMOS_WIN_OS
1948  if (WSAIoctl(cudp, SIO_GET_INTERFACE_LIST, 0, 0, &ilist,sizeof(ilist), &nbytes, 0, 0) == SOCKET_ERROR) {
1949  CLOSE_SOCKET(cudp);
1950  return (iface);
1951  }
1952 
1953  nif = nbytes / sizeof(INTERFACE_INFO);
1954  PIP_ADAPTER_ADDRESSES pAddresses = NULL;
1955  PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
1956  pAddresses = (IP_ADAPTER_ADDRESSES *) calloc(sizeof(IP_ADAPTER_ADDRESSES), 2*nif);
1957  ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 2 * nif;
1958  DWORD dwRetVal;
1959  if ((dwRetVal=GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &outBufLen)) == ERROR_BUFFER_OVERFLOW)
1960  {
1961  free(pAddresses);
1962  return (iface);
1963  }
1964 
1965  for (uint32_t i=0; i<nif; i++)
1966  {
1967  inet_ntop(ilist[i].iiAddress.AddressIn.sin_family,&ilist[i].iiAddress.AddressIn.sin_addr,tiface.address,sizeof(tiface.address));
1968  // strcpy(tiface.address,inet_ntoa(((struct sockaddr_in*)&(ilist[i].iiAddress))->sin_addr));
1969  if (!strcmp(tiface.address,"127.0.0.1")) { continue; }
1970 
1971  pCurrAddresses = pAddresses;
1972  while (pAddresses) {
1973  if (((struct sockaddr_in *)(pCurrAddresses->FirstUnicastAddress->Address.lpSockaddr))->sin_addr.s_addr == ((struct sockaddr_in*)&(ilist[i].iiAddress))->sin_addr.s_addr)
1974  {
1975  strcpy(tiface.name, pCurrAddresses->AdapterName);
1976  break;
1977  }
1978  pCurrAddresses = pCurrAddresses->Next;
1979  }
1980  memset(&tiface.caddr,0,sizeof(struct sockaddr_in));
1981  memset(&tiface.baddr,0,sizeof(struct sockaddr_in));
1982  tiface.caddr.sin_family = AF_INET;
1983  tiface.baddr.sin_family = AF_INET;
1985  {
1986  sslen = sizeof(ss);
1987  WSAStringToAddressA((char *)AGENTMCAST,AF_INET,NULL,(struct sockaddr*)&ss,&sslen);
1988  tiface.caddr.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr;
1989  tiface.baddr.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr;
1990  } else {
1991  if ((iretn = setsockopt(cudp,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on))) < 0)
1992  {
1993  continue;
1994  }
1995  ip = ((struct sockaddr_in*)&(ilist[i].iiAddress))->sin_addr.S_un.S_addr;
1996  net = ((struct sockaddr_in*)&(ilist[i].iiNetmask))->sin_addr.S_un.S_addr;
1997  bcast = ip | (~net);
1998 
1999  tiface.caddr.sin_addr = ((struct sockaddr_in *)&ilist[i].iiAddress)->sin_addr;
2000  tiface.caddr.sin_addr.S_un.S_addr = ip;
2001  tiface.baddr.sin_addr = ((struct sockaddr_in *)&ilist[i].iiAddress)->sin_addr;
2002  tiface.baddr.sin_addr.S_un.S_addr = bcast;
2003  }
2004  ((struct sockaddr_in *)&ss)->sin_addr = tiface.caddr.sin_addr;
2005  ssize = strlen(tiface.address);
2006  WSAAddressToStringA((struct sockaddr *)&tiface.caddr.sin_addr, sizeof(struct sockaddr_in), 0, tiface.address, (LPDWORD)&ssize);
2007  ssize = strlen(tiface.baddress);
2008  WSAAddressToStringA((struct sockaddr *)&tiface.baddr.sin_addr, sizeof(struct sockaddr_in), 0, tiface.baddress, (LPDWORD)&ssize);
2009  tiface.type = ntype;
2010  iface.push_back(tiface);
2011  }
2012 #else
2013  confa.ifc_len = sizeof(data);
2014  confa.ifc_buf = (caddr_t)data;
2015  if (ioctl(cudp,SIOCGIFCONF,&confa) < 0)
2016  {
2017  CLOSE_SOCKET(cudp);
2018  return (iface);
2019  }
2020  // Use result to discover interfaces.
2021  ifra = confa.ifc_req;
2022  for (int32_t n=confa.ifc_len/sizeof(struct ifreq); --n >= 0; ifra++)
2023  {
2024  if (ifra->ifr_addr.sa_family != AF_INET) { continue; }
2025  inet_ntop(ifra->ifr_addr.sa_family,&((struct sockaddr_in*)&ifra->ifr_addr)->sin_addr,tiface.address,sizeof(tiface.address));
2026 
2027  if (ioctl(cudp,SIOCGIFFLAGS, (char *)ifra) < 0) { continue; }
2028 
2029  if ((ifra->ifr_flags & IFF_UP) == 0 || (ifra->ifr_flags & IFF_LOOPBACK) || (ifra->ifr_flags & (IFF_BROADCAST)) == 0)
2030  {
2031  continue;
2032  }
2033 
2034  // Open socket again if we had to close it
2035  if (cudp < 0) {
2036  if ((cudp=socket(AF_INET,SOCK_DGRAM,0)) < 0) { continue; }
2037  }
2038 
2039  if (ntype == NetworkType::MULTICAST) {
2040  inet_pton(AF_INET,AGENTMCAST,&tiface.caddr.sin_addr);
2041  // strcpy(tiface.baddress, AGENTMCAST);
2042  inet_pton(AF_INET,AGENTMCAST,&tiface.baddr.sin_addr);
2043  } else {
2044  if ((iretn = setsockopt(cudp,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on))) < 0) {
2045  CLOSE_SOCKET(cudp);
2046  continue;
2047  }
2048 
2049  // strncpy(tiface.name, ifra->ifr_name, COSMOS_MAX_NAME);
2050  if (ioctl(cudp,SIOCGIFBRDADDR,(char *)ifra) < 0) { continue; }
2051  memcpy((char *)&tiface.baddr, (char *)&ifra->ifr_broadaddr, sizeof(ifra->ifr_broadaddr));
2052  if (ioctl(cudp,SIOCGIFADDR,(char *)ifra) < 0) { continue; }
2053  memcpy((char *)&tiface.caddr, (char *)&ifra->ifr_addr, sizeof(ifra->ifr_addr));
2054  inet_ntop(tiface.baddr.sin_family,&tiface.baddr.sin_addr,tiface.baddress,sizeof(tiface.baddress));
2055  }
2056  tiface.type = ntype;
2057  iface.push_back(tiface);
2058  }
2059 
2060 #endif // COSMOS_WIN_OS
2061  }
2062  break;
2063  default:
2064  break;
2065  }
2066  return (iface);
2067  }
Agent socket using Unicast UDP.
int i
Definition: rw_test.cpp:37
int iretn
Definition: rw_test.cpp:37
struct sockaddr_in baddr
Definition: socketlib.h:124
char address[17]
Definition: socketlib.h:134
char name[COSMOS_MAX_NAME+1]
Definition: socketlib.h:138
NetworkType type
Definition: socketlib.h:118
Definition: socketlib.h:115
#define AGENTMCAST
AGENT heartbeat Multicast address.
Definition: agentclass.h:202
struct sockaddr_in caddr
Definition: socketlib.h:122
NetworkType ntype
Definition: agent_node.cpp:50
Agent socket using Multicast UDP.
char baddress[17]
Definition: socketlib.h:136
int32_t Cosmos::Support::Agent::post ( messstruc  mess)

Post a Cosmos::Agent::messstruc.

Post an already defined message on the previously opened publication channel.

Parameters
messCosmos::Agent::messstruc containing everything necessary, including type, header and data.
Returns
0, otherwise negative error.
2074  {
2075  int32_t iretn;
2076  if (mess.meta.type < Agent::AgentMessage::BINARY) {
2077  iretn = post(mess.meta.type, mess.adata);
2078  } else {
2079  iretn = post(mess.meta.type, mess.bdata);
2080  }
2081  return iretn;
2082  }
int iretn
Definition: rw_test.cpp:37
int32_t post(messstruc mess)
Post a Cosmos::Agent::messstruc.
Definition: agentclass.cpp:2074
int32_t Cosmos::Support::Agent::post ( AgentMessage  type,
string  message = "" 
)

Post a JSON message.

Post a vector of bytes on the previously opened publication channel.

Parameters
typeA byte indicating the type of message.
messageA NULL terminated JSON text string to post.
Returns
0, otherwise negative error.
2091  {
2092  int32_t iretn;
2093  vector<uint8_t> bytes(message.begin(), message.end());
2094  // bytes.push_back(0);
2095  iretn = post(type, bytes);
2096  return iretn;
2097  }
int iretn
Definition: rw_test.cpp:37
int32_t post(messstruc mess)
Post a Cosmos::Agent::messstruc.
Definition: agentclass.cpp:2074
uint8_t message[300]
Definition: kpc9612p_send.cpp:36
int32_t Cosmos::Support::Agent::post ( AgentMessage  type,
vector< uint8_t >  message 
)

Post a binary message.

Post a vector of bytes on the previously opened publication channel.

Parameters
typeA byte indicating the type of message.
messageAn array of bytes to post.
Returns
0, otherwise negative error.
2106  {
2107  size_t nbytes;
2108  int32_t iretn=0;
2109  uint8_t post[AGENTMAXBUFFER];
2110 
2111  cinfo->agent[0].beat.utc = currentmjd();
2112  post[0] = (uint8_t)type;
2113  // this will broadcast messages to all external interfaces (ifcnt = interface count)
2114  for (size_t i=0; i<cinfo->agent[0].ifcnt; i++)
2115  {
2116  sprintf((char *)&post[3],"{\"agent_utc\":%.15g,\"agent_node\":\"%s\",\"agent_proc\":\"%s\",\"agent_addr\":\"%s\",\"agent_port\":%u,\"agent_bprd\":%f,\"agent_bsz\":%u,\"agent_cpu\":%f,\"agent_memory\":%f,\"agent_jitter\":%f,\"node_utcoffset\":%.15g}",
2117  cinfo->agent[0].beat.utc,
2118  cinfo->agent[0].beat.node,
2119  cinfo->agent[0].beat.proc,
2120  cinfo->agent[0].pub[i].address,
2121  cinfo->agent[0].beat.port,
2122  cinfo->agent[0].beat.bprd,
2123  cinfo->agent[0].beat.bsz,
2124  cinfo->agent[0].beat.cpu,
2125  cinfo->agent[0].beat.memory,
2126  cinfo->agent[0].beat.jitter,
2127  cinfo->node.utcoffset);
2128  size_t hlength = strlen((char *)&post[3]);
2129  post[1] = hlength%256;
2130  post[2] = hlength / 256;
2131  nbytes = hlength + 3;
2132 
2133  if (message.size())
2134  {
2135  if (nbytes+message.size() > AGENTMAXBUFFER)
2136  return (AGENT_ERROR_BUFLEN);
2137  memcpy(&post[nbytes], &message[0], message.size());
2138  }
2139  iretn = sendto(cinfo->agent[0].pub[i].cudp, // socket
2140  (const char *)post, // buffer to send
2141  nbytes+message.size(), // size of buffer
2142  0, // flags
2143  (struct sockaddr *)&cinfo->agent[0].pub[i].baddr, // socket address
2144  sizeof(struct sockaddr_in) // size of address to socket pointer
2145  );
2146  if (iretn < 0)
2147  {
2148 #ifdef COSMOS_WIN_OS
2149  if (WSAGetLastError() != EAGAIN && WSAGetLastError() != EWOULDBLOCK)
2150  {
2151  iretn = -WSAGetLastError();
2152  }
2153 #else
2154  if (errno != EAGAIN && errno != EWOULDBLOCK)
2155  {
2156  iretn = -errno;
2157  }
2158 #endif
2159  else
2160  {
2161  iretn= 0;
2162  }
2163  }
2164  // printf("Post: Type: %d Port: %d %d\n", type, cinfo->agent[0].pub[i].cport, htons(cinfo->agent[0].pub[i].caddr.sin_port));
2165  }
2166 
2167  if (iretn<0)
2168  {
2169 #ifdef COSMOS_WIN_OS
2170  return(-WSAGetLastError());
2171 #else
2172  return (-errno);
2173 #endif
2174  }
2175  return 0;
2176  }
int i
Definition: rw_test.cpp:37
int iretn
Definition: rw_test.cpp:37
nodestruc node
Structure for summary information in node.
Definition: jsondef.h:4220
int32_t post(messstruc mess)
Post a Cosmos::Agent::messstruc.
Definition: agentclass.cpp:2074
double utcoffset
MJD Offset between system UT and simulated UT.
Definition: jsondef.h:3590
uint8_t message[300]
Definition: kpc9612p_send.cpp:36
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
#define AGENTMAXBUFFER
Maximum AGENT transfer buffer size.
Definition: jsondef.h:438
#define AGENT_ERROR_BUFLEN
Definition: cosmos-errno.h:110
int32_t Cosmos::Support::Agent::post_beat ( )
2179  {
2180  int32_t iretn = 0;
2181  cinfo->agent[0].beat.utc = currentmjd(0.);
2182  iretn = post(AgentMessage::BEAT);
2183 // if (!sohtable.empty())
2184 // {
2185 // iretn = post(AgentMessage::BEAT, json_of_table(hbjstring, sohtable, (cosmosstruc *)cinfo));
2186 // }
2187 // else
2188 // {
2189 // iretn = post(AgentMessage::BEAT,"");
2190 // }
2191  return iretn;
2192  }
int iretn
Definition: rw_test.cpp:37
int32_t post(messstruc mess)
Post a Cosmos::Agent::messstruc.
Definition: agentclass.cpp:2074
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::post_soh ( )
2194  {
2195  int32_t iretn = 0;
2196  cinfo->agent[0].beat.utc = currentmjd(0.);
2198  return iretn;
2199  }
const char * json_of_table(string &jstring, vector< jsonentry * > table, cosmosstruc *cinfo)
Create JSON stream from entries.
Definition: jsonlib.cpp:8733
string hbjstring
Definition: agentclass.h:385
int iretn
Definition: rw_test.cpp:37
int32_t post(messstruc mess)
Post a Cosmos::Agent::messstruc.
Definition: agentclass.cpp:2074
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
vector< jsonentry * > sohtable
State of Health element vector.
Definition: agentclass.h:156
Definition: jsondef.h:4199
int32_t Cosmos::Support::Agent::unpublish ( )

Close COSMOS output channel.

Close previously opened publication channels and recover any allocated resources.

Returns
0, otherwise negative error.
2205  {
2206  if (cinfo == nullptr) { return 0; }
2207  for (size_t i=0; i<cinfo->agent[0].ifcnt; ++i) { CLOSE_SOCKET(cinfo->agent[0].pub[i].cudp); }
2208  return 0;
2209  }
int i
Definition: rw_test.cpp:37
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::subscribe ( NetworkType  type,
const char *  address,
uint16_t  port,
uint32_t  usectimeo 
)

Open COSMOS channel for polling.

This establishes a multicast channel for subscribing to COSMOS messages.

Parameters
type0=Multicast, 1=Broadcast UDP, 2=Broadcast CSP.
addressThe IP Multicast address of the channel.
portThe port to use for the channel.
usectimeoBlocking read timeout in micro seconds.
Returns
0, otherwise negative error.
2220  {
2221  int32_t iretn = 0;
2222 
2223  // ?? this is preventing from running socket_open if
2224  // for some reason cinfo->agent[0].sub.cport was ill initialized
2225 #ifndef COSMOS_WIN_BUILD_MSVC
2226  if (cinfo->agent[0].sub.cport) { return 0; }
2227 #endif
2228  if ((iretn=socket_open(&cinfo->agent[0].sub,type,address,port,SOCKET_LISTEN,SOCKET_BLOCKING, usectimeo)) < 0) {
2229  return iretn;
2230  }
2231  return 0;
2232  }
static string port
Definition: add_radio.cpp:16
int iretn
Definition: rw_test.cpp:37
char address[]
Definition: netperf_listen.cpp:69
#define SOCKET_BLOCKING
Blocking Agent.
Definition: socketlib.h:78
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
#define SOCKET_LISTEN
Listen followed by optional talk (recvfrom INADDRANY)
Definition: socketlib.h:84
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t socket_open(socket_channel *channel, NetworkType ntype, const char *address, uint16_t port, uint16_t role, bool blocking, uint32_t usectimeo, uint32_t rcvbuf, uint32_t sndbuf)
Open UDP socket.
Definition: socketlib.cpp:51
int32_t Cosmos::Support::Agent::subscribe ( NetworkType  type,
const char *  address,
uint16_t  port 
)

Open COSMOS channel for polling with 100 usec timeout.

This establishes a multicast channel for subscribing to COSMOS messages. The timeout is set to 100 usec.

Parameters
type0=Multicast, 1=Broadcast UDP, 2=Broadcast CSP.
addressThe IP Multicast address of the channel.
portThe port to use for the channel.
Returns
0, otherwise negative error.
2242  {
2243  int32_t iretn = 0;
2244  if ((iretn=Agent::subscribe(type, address, port, 100)) < 0) { return iretn; }
2245  return 0;
2246  }
static string port
Definition: add_radio.cpp:16
int iretn
Definition: rw_test.cpp:37
char address[]
Definition: netperf_listen.cpp:69
int32_t subscribe(NetworkType type, const char *address, uint16_t port)
Open COSMOS channel for polling with 100 usec timeout.
Definition: agentclass.cpp:2242
int32_t Cosmos::Support::Agent::unsubscribe ( )

Close COSMOS subscription channel.

Close channel previously opened for polling for messages and recover resources.

Returns
0, otherwise negative error.
2251  {
2252  if (cinfo != nullptr) { CLOSE_SOCKET(cinfo->agent[0].sub.cudp); }
2253  return 0;
2254  }
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
int32_t Cosmos::Support::Agent::poll ( messstruc mess,
AgentMessage  type,
float  waitsec = 1. 
)

Listen for message.

Poll the subscription channel for the requested amount of time. Return as soon as a single message comes in, or the timer runs out.

Parameters
messCosmos::Agent::messstruc for storing incoming message.
typeType of message to look for, taken from Cosmos::Agent::AgentMessage.
waitsecNumber of seconds in timer.
Returns
If a message comes in, return its type. If none comes in, return zero, otherwise negative error.
2265  {
2266  int nbytes;
2267  uint8_t input[AGENTMAXBUFFER+1];
2268 
2269  if (cinfo == nullptr) { return AGENT_ERROR_NULL; }
2270 
2271  if (!cinfo->agent[0].sub.cport) { return (AGENT_ERROR_CHANNEL); }
2272 
2273  ElapsedTime ep;
2274  ep.start();
2275  do
2276  {
2277  nbytes = 0;
2278  switch (cinfo->agent[0].sub.type)
2279  {
2281  case NetworkType::UDP:
2282 
2283  nbytes = recvfrom(cinfo->agent[0].sub.cudp, (char *)input,AGENTMAXBUFFER, 0, (struct sockaddr *)&cinfo->agent[0].sub.caddr, (socklen_t *)&cinfo->agent[0].sub.addrlen);
2284 
2285  // Return if error
2286  if (nbytes < 0) { return nbytes; }
2287 
2288  // printf("Poll: %f %f Type: %d Port %d %d\n", 86400.*(currentmjd()-58496), ep.split(), input[0], cinfo->agent[0].sub.cport, htons(cinfo->agent[0].sub.caddr.sin_port));
2289 
2290  // Return if port and address are our own
2291  for (uint16_t i=0; i<cinfo->agent[0].ifcnt; ++i) {
2292  if (cinfo->agent[0].sub.caddr.sin_port == ntohs(cinfo->agent[0].pub[i].cport) &&
2293  cinfo->agent[0].sub.caddr.sin_addr.s_addr == cinfo->agent[0].pub[i].caddr.sin_addr.s_addr) {
2294  return 0;
2295  }
2296  }
2297  break;
2298  default:
2299  break;
2300  }
2301 
2302  if (nbytes > 0) {
2303  if (type == Agent::AgentMessage::ALL || type == (AgentMessage)input[0]) {
2304  // Determine if old or new message
2305  uint8_t start_byte;
2306  if (input[1] == '{') {
2307  start_byte = 1;
2308  } else {
2309  start_byte = 3;
2310  }
2311  // Provide support for older messages that did not include jlength
2312  if (start_byte > 1) {
2313  mess.meta.type = (AgentMessage)input[0];
2314  mess.meta.jlength = input[1] + 256 * input[2];
2315  } else {
2316  mess.meta.type = (AgentMessage)(input[0] + 1);
2317  mess.meta.jlength = nbytes;
2318  }
2319 
2320  // Copy message parts to ring, placing in appropriate buffers.
2321  // First: JSON header
2322  mess.jdata.assign((const char *)&input[start_byte], mess.meta.jlength);
2323 
2324  // Next: ASCII or BINARY message, depending on message type.
2325  if (mess.meta.type < Agent::AgentMessage::BINARY) {
2326  mess.adata.clear();
2327  mess.adata.assign((const char *)&input[start_byte+mess.meta.jlength], nbytes - (start_byte + mess.meta.jlength));
2328  } else {
2329  mess.bdata.resize(nbytes - (start_byte + mess.meta.jlength));
2330  memcpy(mess.bdata.data(), &input[start_byte + mess.meta.jlength], nbytes - (start_byte + mess.meta.jlength));
2331  }
2332 
2333  // Extract meta data
2334  if (mess.jdata.find("}{") == string::npos)
2335  {
2336  sscanf((const char *)mess.jdata.data(), "{\"agent_utc\":%lg,\"agent_node\":\"%40[^\"]\",\"agent_proc\":\"%40[^\"]\",\"agent_addr\":\"%17[^\"]\",\"agent_port\":%hu,\"agent_bprd\":%lf,\"agent_bsz\":%u,\"agent_cpu\":%f,\"agent_memory\":%f,\"agent_jitter\":%lf}",
2337  &mess.meta.beat.utc,
2338  mess.meta.beat.node,
2339  mess.meta.beat.proc,
2340  mess.meta.beat.addr,
2341  &mess.meta.beat.port,
2342  &mess.meta.beat.bprd,
2343  &mess.meta.beat.bsz,
2344  &mess.meta.beat.cpu,
2345  &mess.meta.beat.memory,
2346  &mess.meta.beat.jitter);
2347  }
2348  else if (mess.jdata.find("agent_bprd") == string::npos)
2349  {
2350  sscanf((const char *)mess.jdata.data(), "{\"agent_utc\":%lg}{\"agent_node\":\"%40[^\"]\"}{\"agent_proc\":\"%40[^\"]\"}{\"agent_addr\":\"%17[^\"]\"}{\"agent_port\":%hu}{\"agent_bsz\":%u}{\"agent_cpu\":%f}{\"agent_memory\":%f}{\"agent_jitter\":%lf}",
2351  &mess.meta.beat.utc,
2352  mess.meta.beat.node,
2353  mess.meta.beat.proc,
2354  mess.meta.beat.addr,
2355  &mess.meta.beat.port,
2356  &mess.meta.beat.bsz,
2357  &mess.meta.beat.cpu,
2358  &mess.meta.beat.memory,
2359  &mess.meta.beat.jitter);
2360  } else {
2361  sscanf((const char *)mess.jdata.data(), "{\"agent_utc\":%lg}{\"agent_node\":\"%40[^\"]\"}{\"agent_proc\":\"%40[^\"]\"}{\"agent_addr\":\"%17[^\"]\"}{\"agent_port\":%hu}{\"agent_bprd\":%lf}{\"agent_bsz\":%u}{\"agent_cpu\":%f}{\"agent_memory\":%f}{\"agent_jitter\":%lf}",
2362  &mess.meta.beat.utc,
2363  mess.meta.beat.node,
2364  mess.meta.beat.proc,
2365  mess.meta.beat.addr,
2366  &mess.meta.beat.port,
2367  &mess.meta.beat.bprd,
2368  &mess.meta.beat.bsz,
2369  &mess.meta.beat.cpu,
2370  &mess.meta.beat.memory,
2371  &mess.meta.beat.jitter);
2372  }
2373  return ((int)mess.meta.type);
2374  }
2375  }
2376  if (ep.split() >= waitsec) {
2377  nbytes = 0;
2378  } else {
2379  COSMOS_SLEEP(.1);
2380  }
2381  } while (nbytes != 0);
2382 
2383  return 0;
2384  }
AgentMessage
Type of Agent Message. Types > 127 are binary.
Definition: agentclass.h:216
#define AGENT_ERROR_NULL
Definition: cosmos-errno.h:111
Agent socket using Unicast UDP.
int i
Definition: rw_test.cpp:37
#define AGENT_ERROR_CHANNEL
Definition: cosmos-errno.h:109
void start()
ElapsedTime::start.
Definition: elapsedtime.cpp:203
int waitsec
Definition: agent_add_soh.cpp:56
Definition: elapsedtime.h:62
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
cosmosstruc * cinfo
Definition: agentclass.h:346
#define AGENTMAXBUFFER
Maximum AGENT transfer buffer size.
Definition: jsondef.h:438
Agent socket using Multicast UDP.
double split()
ElapsedTime::split, gets the current elapsed time since the start()
Definition: elapsedtime.cpp:234
int32_t Cosmos::Support::Agent::readring ( messstruc message,
AgentMessage  type = Agent::AgentMessage::ALL,
float  waitsec = 1.,
Where  where = Where::TAIL,
string  proc = "",
string  node = "" 
)

Check Ring for message.

Check the message ring for the requested amount of time. Return as soon as a message of the right type is available, or the timer runs out.

Parameters
messageVector for storing incoming message.
typeType of message to look for, taken from Cosmos::Agent::AgentMessage.
waitsecNumber of seconds in timer. If 0, return last message in ring immediatelly.
whereOne of Where::HEAD or Where::TAIL, indicating whether to start at the head or tail of the ring.
Returns
If a message comes in, return its type. If none comes in, return zero, otherwise negative error.
2396  {
2397  if (waitsec < 0.f) { waitsec = 0.; }
2398  if (cinfo == nullptr) { return AGENT_ERROR_NULL; }
2399  if (where == Where::HEAD) { message_queue.clear(); }
2400  ElapsedTime ep;
2401  ep.start();
2402  do {
2403  while (message_queue.size()) {
2404  message = message_queue.front();
2405  message_queue.pop_front();
2406  if (type == Agent::AgentMessage::ALL || type == static_cast<Agent::AgentMessage>(message.meta.type)) {
2407  if (proc.empty() || !strcmp(proc.c_str(), message.meta.beat.proc)) {
2408  if (node.empty() || !strcmp(node.c_str(), message.meta.beat.node)) {
2409  return (static_cast<int32_t>(message.meta.type));
2410  }
2411  }
2412  }
2413  }
2414 
2415  if (ep.split() < waitsec) {
2416  if (waitsec - ep.split() > .1) {
2417  COSMOS_SLEEP(.1);
2418  } else {
2419  COSMOS_SLEEP(.05);
2420  }
2421  }
2422  } while (ep.split() < waitsec);
2423 
2424  return 0;
2425  }
#define AGENT_ERROR_NULL
Definition: cosmos-errno.h:111
void start()
ElapsedTime::start.
Definition: elapsedtime.cpp:203
uint8_t message[300]
Definition: kpc9612p_send.cpp:36
int waitsec
Definition: agent_add_soh.cpp:56
Definition: elapsedtime.h:62
deque< messstruc > message_queue
Ring buffer for incoming messages.
Definition: agentclass.h:355
cosmosstruc * cinfo
Definition: agentclass.h:346
static string node
Definition: agent_monitor.cpp:126
double split()
ElapsedTime::split, gets the current elapsed time since the start()
Definition: elapsedtime.cpp:234
int32_t Cosmos::Support::Agent::parsering ( AgentMessage  type = Agent::AgentMessage::ALL,
float  waitsec = 1.,
Where  where = Where::HEAD,
string  proc = "",
string  node = "" 
)

Parse next message from ring.

2429  {
2430  int32_t iretn;
2431  messstruc message;
2432 
2433  if (where == Where::HEAD) { message_queue.clear(); }
2434  post(Agent::AgentMessage::REQUEST, "heartbeat");
2435  ElapsedTime et;
2436  do {
2437  iretn = readring(message, type, waitsec, where, proc, node);
2438  } while (et.split() < waitsec);
2439 
2440  if (iretn >= 0 && iretn < static_cast <int32_t>(Agent::AgentMessage::BINARY))
2441  {
2442  json_parse(message.adata, cinfo);
2443  return iretn;
2444  }
2445 
2446  return GENERAL_ERROR_TIMEOUT;
2447  }
int32_t json_parse(string jstring, cosmosstruc *cinfo)
Parse JSON using Name Space.
Definition: jsonlib.cpp:4799
#define GENERAL_ERROR_TIMEOUT
Definition: cosmos-errno.h:292
int iretn
Definition: rw_test.cpp:37
ElapsedTime et
Definition: agent_cpu_device_test.cpp:51
int32_t post(messstruc mess)
Post a Cosmos::Agent::messstruc.
Definition: agentclass.cpp:2074
uint8_t message[300]
Definition: kpc9612p_send.cpp:36
int waitsec
Definition: agent_add_soh.cpp:56
Definition: elapsedtime.h:62
deque< messstruc > message_queue
Ring buffer for incoming messages.
Definition: agentclass.h:355
cosmosstruc * cinfo
Definition: agentclass.h:346
static string node
Definition: agent_monitor.cpp:126
double split()
ElapsedTime::split, gets the current elapsed time since the start()
Definition: elapsedtime.cpp:234
int32_t readring(messstruc &message, AgentMessage type=Agent::AgentMessage::ALL, float waitsec=1., Where where=Where::TAIL, string proc="", string node="")
Check Ring for message.
Definition: agentclass.cpp:2395
int32_t Cosmos::Support::Agent::resizering ( size_t  newsize)

Change size of message ring. Resize the message ring to hold a new maximum number of messages. Adjust the message pointers in the ring to be appropriate.

Parameters
newsizeNew maximum message count.
Returns
Negative error, or zero.
2455  {
2456  if (message_head >= newsize) { message_head = 0; }
2457  if (message_tail >= newsize) { message_tail = newsize - 1; }
2458  return 0;
2459  }
size_t message_tail
Last message rad in message ring buffer.
Definition: agentclass.h:359
size_t message_head
Last message placed in message ring buffer.
Definition: agentclass.h:357
int32_t Cosmos::Support::Agent::clearring ( )

Empty message ring. Set the internal pointers such that it appears that we have read any messages that are in the message ring. This has the effect of emptying the message ring as far as Cosmos::Agent::readring is concerned.

Returns
Negative error or zero.
2467  {
2469  return 0;
2470  }
size_t message_tail
Last message rad in message ring buffer.
Definition: agentclass.h:359
size_t message_head
Last message placed in message ring buffer.
Definition: agentclass.h:357
string Cosmos::Support::Agent::getNode ( )

Listen for heartbeat.

Poll the subscription channel until you receive a heartbeat message, or the timer runs out.

Parameters
waitsecNumber of seconds to wait before timing out.
Returns
beatstruc with acquired heartbeat. The UTC will be set to 0 if no heartbeat was acquired.Listen for Time
    Poll the subscription channel until you receive a time message, or the timer runs out.
Parameters
waitsecNumber of seconds to wait before timing out.
Returns
timestruc with acquired time. The UTC will be set to 0 if no heartbeat was acquired.Listen for Location
    Poll the subscription channel until you receive a location message, or the timer runs out.
Parameters
waitsecNumber of seconds to wait before timing out.
Returns
locstruc with acquired location. The UTC will be set to 0 if no heartbeat was acquired.Listen for Beacon
    Poll the subscription channel until you receive a info message, or the timer runs out.
Parameters
waitsecNumber of seconds to wait before timing out.
Returns
nodestruc with acquired info. The UTC will be set to 0 if no info was acquired.Listen for IMU device
    Poll the subscription channel until you receive a IMU device message, or the timer runs out.
Parameters
waitsecNumber of seconds to wait before timing out.
Returns
beatstruc with acquired heartbeat. The UTC will be set to 0 if no heartbeat was acquired.
2607 { return nodeName; }
string nodeName
Definition: agentclass.h:367
string Cosmos::Support::Agent::getAgent ( )
2609 { return agentName; }
string agentName
Definition: agentclass.h:368
int32_t Cosmos::Support::Agent::getJson ( string  node,
jsonnode jnode 
)
2613  {
2614  int32_t iretn=0;
2615 
2616  bool node_found = false;
2617  for (jsonnode json : node_list)
2618  {
2619  if (!node.compare(json.name))
2620  {
2621  node_found = true;
2622  }
2623  }
2624 
2625  if (!node_found)
2626  {
2627  for (beatstruc beat : agent_list)
2628  {
2629  if (!node.compare(beat.node))
2630  {
2631  if ((iretn=send_request_jsonnode(beat, jnode)) >= 0)
2632  {
2633  node_list.push_back(jnode);
2634  node_found = true;
2635  }
2636  }
2637  }
2638  }
2639 
2640  if (!node_found) { iretn = GENERAL_ERROR_UNDEFINED; }
2641 
2642  return iretn;
2643  }
Definition: jsondef.h:923
int iretn
Definition: rw_test.cpp:37
Definition: jsondef.h:724
#define GENERAL_ERROR_UNDEFINED
Definition: cosmos-errno.h:295
int32_t send_request_jsonnode(beatstruc cbeat, jsonnode &jnode, float waitsec=5.)
Send request for Node JSON.
Definition: agentclass.cpp:477
vector< beatstruc > agent_list
List of active agents.
Definition: agentclass.h:349
static string node
Definition: agent_monitor.cpp:126
vector< jsonnode > node_list
List of active Nodes.
Definition: agentclass.h:351
FILE * Cosmos::Support::Agent::get_debug_fd ( double  mjd = 0.)
2645  {
2646  static double oldmjd=0.;
2647  if (debug_level == 0) {
2648  debug_fd = nullptr;
2649  debug_pathName.clear();
2650  }
2651  else if (debug_level == 1) {
2652  if (debug_fd != stdout) {
2653  if (debug_fd != nullptr) {
2654  fclose(debug_fd);
2655  }
2656  debug_fd = stdout;
2657  debug_pathName.clear();
2658  }
2659  } else {
2660  if (mjd == 0.) {
2661  mjd = currentmjd();
2662  oldmjd = mjd;
2663  }
2664  mjd = mjd - fmod(mjd, 1./24.);
2665  string pathName = data_type_path(nodeName, "temp", agentName, mjd, agentName, "debug");
2666 
2667  if (debug_fd != nullptr) {
2668  if (pathName != debug_pathName) {
2669  FILE *fd = fopen(pathName.c_str(), "a");
2670  if (fd != nullptr) {
2671  if (debug_fd != stdout) {
2672  fclose(debug_fd);
2673  string final_filepath = data_type_path(nodeName, "outgoing", agentName, oldmjd, agentName, "debug");
2674  rename(debug_pathName.c_str(), final_filepath.c_str());
2675  }
2676  debug_fd = fd;
2677  debug_pathName = pathName;
2678  }
2679  oldmjd = mjd;
2680  }
2681  } else {
2682  FILE *fd = fopen(pathName.c_str(), "a");
2683  if (fd != nullptr) {
2684  debug_fd = fd;
2685  debug_pathName = pathName;
2686  }
2687  }
2688  }
2689  return debug_fd;
2690  }
uint16_t debug_level
Flag for level of debugging, keep it public so that it can be controlled from the outside...
Definition: agentclass.h:362
FILE * debug_fd
Definition: agentclass.h:379
int fd
Definition: arduino_lib.cpp:61
string nodeName
Definition: agentclass.h:367
string data_type_path(string node, string location, string agent, double mjd, string type)
Create data file path.
Definition: datalib.cpp:910
double mjd
Definition: udp_send.cpp:41
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
string debug_pathName
Definition: agentclass.h:380
string agentName
Definition: agentclass.h:368
int32_t Cosmos::Support::Agent::close_debug_fd ( )
2692  {
2693  int32_t iretn;
2694  if (debug_fd != nullptr && debug_fd != stdout)
2695  {
2696  iretn = fclose(debug_fd);
2697  if (iretn != 0) { return -errno; }
2698  debug_fd = nullptr;
2699  }
2700  return 0;
2701  }
FILE * debug_fd
Definition: agentclass.h:379
int iretn
Definition: rw_test.cpp:37
int32_t Cosmos::Support::Agent::set_agent_time_producer ( double(*)()  source)
2704  {
2705  this->agent_time_producer = source;
2706  return 0;
2707  }
double(* agent_time_producer)()
Function in which we generate our time, for the mjd request.
Definition: agentclass.h:398
static string source
Definition: ax25_recv.cpp:42
int32_t Cosmos::Support::Agent::get_agent_time ( double &  agent_time,
double &  epsilon,
double &  delta,
string  agent,
string  node = "any",
double  wait_sec = 2. 
)
2711  {
2712  static beatstruc agent_beat;
2713  string agent_response;
2714  double mjd_0, mjd_1;
2715  int32_t iretn;
2716 
2717  if (!agent_beat.exists) {
2718  agent_beat = find_agent(node, agent, wait_sec);
2719  } else {
2720  if (strcmp(node.c_str(), agent_beat.node) || (strcmp(agent.c_str(), agent_beat.proc))) {
2721  agent_beat = find_agent(node, agent, wait_sec);
2722  }
2723  }
2724 
2725  // Do not proceed if we cannot find the agent.
2726  if (!agent_beat.exists) return AGENT_ERROR_DISCOVERY;
2727 
2728  mjd_0 = currentmjd();
2729  iretn = send_request(agent_beat, "utc", agent_response, 0);
2730  if (iretn >= 0) {
2731  mjd_1 = currentmjd();
2732 
2733  epsilon = (mjd_1 - mjd_0) / 2.0; // RTT / 2.0
2734  agent_time = stod(agent_response.substr(0, agent_response.find("["))) + epsilon;
2735  delta = agent_time - mjd_1; // We do not have a lower bound on the time to transmit a message one way.
2736 
2737  return 0;
2738  } else {
2739  agent_time = 0.;
2740  epsilon = 0.;
2741  return GENERAL_ERROR_TIMEOUT;
2742  }
2743  }
static double delta
Definition: agent_exec-2-0.cpp:141
Definition: jsondef.h:923
int32_t send_request(beatstruc cbeat, string request, string &output, float waitsec=5.)
Send a request over AGENT.
Definition: agentclass.cpp:424
#define GENERAL_ERROR_TIMEOUT
Definition: cosmos-errno.h:292
int iretn
Definition: rw_test.cpp:37
static double epsilon
Definition: agent_exec-2-0.cpp:140
#define AGENT_ERROR_DISCOVERY
Definition: cosmos-errno.h:112
bool exists
Existence Flag (if beat exists then flag is set to true, false otherwise)
Definition: jsondef.h:950
char proc[40+1]
Heartbeat Agent Name.
Definition: jsondef.h:930
char node[40+1]
Definition: jsondef.h:928
static Agent * agent
ensure the Agent constructor creates only one instance per process
Definition: agent_001.cpp:45
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
beatstruc find_agent(string node, string agent, double waitsec=0.)
Find agent.
Definition: agentclass.cpp:559
static string node
Definition: agent_monitor.cpp:126