COSMOS core  1.0.2 (beta)
Comprehensive Open-architecture Solution for Mission Operations Systems
agent.cpp File Reference

Agent control program source. More...

#include "support/configCosmos.h"
#include <stdlib.h>
#include "agent/agentclass.h"
#include "support/jsonlib.h"
#include "physics/physicslib.h"
#include "support/datalib.h"
#include "sys/stat.h"
#include "limits.h"
#include <iostream>
Include dependency graph for agent.cpp:

Functions

int main (int argc, char *argv[])
 

Variables

const int REQUEST_WAIT_TIME = 2
 
const int SERVER_WAIT_TIME = 6
 
string output
 
string node_name = ""
 
string agent_name = ""
 

Detailed Description

Agent control program source.

Function Documentation

int main ( int  argc,
char *  argv[] 
)
75 {
76  int nbytes;
78  vector<string> nl;
79  data_list_nodes(nl);
80  Agent *agent;
81 
82  // dont' print debug messages
83  //agent->debug_level = 0;
84  agent = new Agent();
85  if (agent->cinfo == nullptr)
86  {
87  fprintf(agent->get_debug_fd(), "%16.10f %s Failed to start Agent %s on Node %s Dated %s : %s\n",currentmjd(), mjd2iso8601(currentmjd()).c_str(), agent->getAgent().c_str(), agent->getNode().c_str(), utc2iso8601(data_ctime(argv[0])).c_str(), cosmos_error_string(NODE_ERROR_NODE).c_str());
88  exit(NODE_ERROR_NODE);
89  }
90 
91 
92  // check command line arguments
93  switch (argc)
94  {
95  case 1:
96  {
97  printf("Usage: agent [ list | dump [soh, beat, ###] | node_name agent_name \"request [ arguments ]\" ]\n");
98  // printf("\n List of available nodes:\n\n");
99  // print_node_list(nl);
100  // printf("\n");
101  exit(1);
102  }
103  break;
104  case 2:
105  case 3:
106  case 4:
107  case 5:
108  // agent dump request
109  if (!strcmp(argv[1],"dump"))
110  {
111  double lmjd = 0., dmjd;
112  string channel;
113  Agent::AgentMessage cnum;
115  int i;
116  locstruc loc;
117 
118 // JIMNOTE: this block will never be entered
119 
120  switch(argc)
121  {
122  case 5:
123  agent_name = argv[4];
124  case 4:
125  node_name = argv[3];
126  case 3:
127  channel = argv[2];
128  if (channel == "soh")
129  {
130  cnum = Agent::AgentMessage::SOH;
131  }
132  else if (channel == "beat")
133  {
134  cnum = Agent::AgentMessage::BEAT;
135  }
136  else if (channel == "request")
137  {
138  cnum = Agent::AgentMessage::REQUEST;
139  }
140  else if (channel == "response")
141  {
142  cnum = Agent::AgentMessage::RESPONSE;
143  }
144  else
145  {
146  cnum = (Agent::AgentMessage)atoi(channel.c_str());
147  }
148  break;
149  case 2:
150  channel.clear();
151  cnum = Agent::AgentMessage::ALL;
152  break;
153  }
154 
155  while (1)
156  {
157  int32_t iretn;
158  if ((iretn=agent->readring(message, cnum, 1., Agent::Where::TAIL)) > 0)
159  {
161 
162  // Skip if either not Agent::AgentMessage::ALL, or not desired AGENT_MESSAGE
163  if (!channel.empty() && cnum != pretn)
164  {
165  continue;
166  }
167 
168  if (!node_name.empty() && node_name != message.meta.beat.node)
169  {
170  continue;
171  }
172 
173  if (!agent_name.empty() && agent_name != message.meta.beat.proc)
174  {
175  continue;
176  }
177 
178  switch (pretn)
179  {
180  case Agent::AgentMessage::SOH:
181  printf("[SOH]");
182  break;
183  case Agent::AgentMessage::BEAT:
184  printf("[BEAT]");
185  break;
186  case Agent::AgentMessage::REQUEST:
187  printf("[REQUEST]");
188  break;
189  case Agent::AgentMessage::RESPONSE:
190  printf("[RESPONSE]");
191  break;
192  default:
193  printf("[%d]",pretn);
194  break;
195  }
196 
197  printf("%.15g:[%s:%s][%s:%u](%lu:%lu:%zu)\n",message.meta.beat.utc, message.meta.beat.node, message.meta.beat.proc, message.meta.beat.addr, message.meta.beat.port, message.jdata.size(), message.adata.size(), message.bdata.size());
198  printf("%s\n",message.jdata.c_str());
199  if (pretn < Agent::AgentMessage::BINARY)
200  {
201  if (!channel.empty())
202  {
203  printf("%s\n",message.adata.c_str());
204  }
205  }
206 
207  if ((channel=="info") && pretn == Agent::AgentMessage::TRACK)
208  {
209  if (agent->cinfo->node.loc.utc > 0.)
210  {
211  if (lmjd > 0.)
212  dmjd = 86400.*(agent->cinfo->node.loc.utc-lmjd);
213  else
214  dmjd = 0.;
215  loc.pos.icrf.s = agent->cinfo->node.loc.pos.icrf.s;
216  loc.pos.utc = agent->cinfo->node.loc.utc;
217  pos_eci(&loc);
218  printf("%16.15g %6.4g %s %8.3f %8.3f %8.3f %5.1f %5.1f %5.1f\n",agent->cinfo->node.loc.utc,dmjd,agent->cinfo->node.name,DEGOF(loc.pos.geod.s.lon),DEGOF(loc.pos.geod.s.lat),loc.pos.geod.s.h,agent->cinfo->node.phys.powgen,agent->cinfo->node.phys.powuse,agent->cinfo->node.phys.battlev);
219  lmjd = agent->cinfo->node.loc.utc;
220  }
221  }
222 
223  if ((channel=="imu") && pretn == Agent::AgentMessage::IMU)
224  {
225  for (i=0; i<agent->cinfo->devspec.imu_cnt; i++)
226  {
227  if (agent->cinfo->agent[0].beat.utc > 0.)
228  {
229  if (lmjd > 0.)
230  dmjd = 86400.*(agent->cinfo->agent[0].beat.utc-lmjd);
231  else
232  dmjd = 0.;
233  printf("%.15g %.4g\n",loc.utc,dmjd);
234  lmjd = agent->cinfo->agent[0].beat.utc;
235  }
236  }
237  }
238  }
239  fflush(stdout);
240  } //end infinite while loop
241  break;
242  }
243  else if (!strcmp(argv[1],"list"))
244  {
245  size_t agent_count = 0;
246  ElapsedTime et;
247  agent->post(Agent::AgentMessage::REQUEST, "heartbeat");
248  COSMOS_SLEEP(.5);
249  do
250  {
251  if (agent->agent_list.size() > agent_count)
252  {
253  for (size_t i=agent_count; i<agent->agent_list.size(); ++i)
254  {
255  beatstruc cbeat = agent->agent_list[i];
256  agent->send_request(cbeat,(char *)"getvalue {\"agent_pid\"}", output, REQUEST_WAIT_TIME);
257  printf("[%lu] %.15g %s %s %s %hu %u\n",i,cbeat.utc,cbeat.node,cbeat.proc,cbeat.addr,cbeat.port,cbeat.bsz);
258  printf("\t%s\n",output.c_str());
259  fflush(stdout);
260  }
261  agent_count = agent->agent_list.size();
262  }
263  COSMOS_SLEEP(.1);
264  } while (et.split() < SERVER_WAIT_TIME);
265  exit(0);
266  break;
267  }
268  // bug: no trailing ] for JSON vector (Scott try fix)
269  else if (!strcmp(argv[1],"list_json"))
270  {
271  size_t agent_count = 0;
272  ElapsedTime et;
273  agent->post(Agent::AgentMessage::REQUEST, "heartbeat");
274  COSMOS_SLEEP(.1);
275  printf("{\"agent_list\":[");
276  do
277  {
278  if (agent->agent_list.size() > agent_count)
279  {
280 
281  for (size_t i=agent_count; i<agent->agent_list.size(); ++i)
282  {
283  beatstruc cbeat = agent->agent_list[i];
284  agent->send_request(cbeat,(char *)"getvalue {\"agent_pid\"}", output, REQUEST_WAIT_TIME);
285  if(i>0) printf(",");
286  printf("{\"agent_proc\": \"%s\", ", cbeat.proc);
287  printf("\"agent_utc\": %.15g, ", cbeat.utc);
288  printf("\"agent_node\": \"%s\", ", cbeat.node);
289  printf("\"agent_addr\": \"%s\", ", cbeat.addr);
290  printf("\"agent_port\": %hu, ", cbeat.port);
291  printf("\"agent_bsz\": %u, ", cbeat.bsz);
292  // HANDLE RESPONSE OUTPUT FORMAT
293  size_t status_pos;
294  if((status_pos= output.find("[OK]") )!= string::npos){
295  if(output.at(0) == '{'){
296  if(status_pos - 1 >= 0 && output.at(status_pos - 1) == '}'){
297  printf("\"output\": %s,", output.substr(0, status_pos).c_str());
298  } else {
299  printf("\"output\": %s,", output.c_str());
300  }
301  } else {
302  printf("\"output\": \"%s\",", output.substr(status_pos ).c_str());
303  }
304  printf("\"status\": \"OK\"}");
305  } else if((status_pos = output.find("[NOK]") )!= string::npos){
306  printf("\"status\": \"NOK\"}");
307  } else {
308  printf("\"output\": %s }", output.c_str());
309  }
310  fflush(stdout);
311  }
312 
313  fflush(stdout);
314  agent_count = agent->agent_list.size();
315  }
316  COSMOS_SLEEP(.1);
317  } while (et.split() < SERVER_WAIT_TIME);
318  printf("]}\n");
319  exit(0);
320  break;
321  }
322 
323  default:
324  if (!strcmp(argv[1],"dump"))
325  {
326  double lmjd = 0., dmjd;
327  string channel;
328  Agent::AgentMessage cnum;
330  string header;
331  int i;
332  locstruc loc;
333 
334  if(argc == 3)
335  {
336  channel = argv[2];
337  if (channel == "soh")
338  {
339  cnum = Agent::AgentMessage::SOH;
340  }
341  else
342  {
343  if (channel == "beat")
344  {
345  cnum = Agent::AgentMessage::BEAT;
346  }
347  else
348  {
349  cnum = (Agent::AgentMessage)atoi(channel.c_str());
350  }
351  }
352  }
353  else
354  {
355  channel.clear();
356  cnum = Agent::AgentMessage::ALL;
357  }
358 
359  while (1)
360  {
361  int32_t iretn;
362  if ((iretn=agent->readring(message, Agent::AgentMessage::ALL, 1., Agent::Where::TAIL)) > 0)
363  {
365  // Skip if either not Agent::AgentMessage::ALL, or not desired AGENT_MESSAGE
366  if (!channel.empty() && cnum != pretn)
367  {
368  continue;
369  }
370 
371  header.resize(message.meta.jlength);
372  if (pretn < Agent::AgentMessage::BINARY)
373  {
374  memcpy(&header[0], message.adata.data(), message.meta.jlength);
377  json_parse(message.adata.c_str(), agent->cinfo);
378  }
379  else
380  {
381  memcpy(&header[0], message.bdata.data(), message.meta.jlength);
382  }
383 
384  switch (pretn)
385  {
386  case Agent::AgentMessage::SOH:
387  printf("[SOH]");
388  break;
389  case Agent::AgentMessage::BEAT:
390  printf("[BEAT]");
391  break;
392  case Agent::AgentMessage::REQUEST:
393  printf("[REQUEST]");
394  break;
395  case Agent::AgentMessage::RESPONSE:
396  printf("[RESPONSE]");
397  break;
398  default:
399  printf("[%d]",pretn);
400  break;
401  }
402 
403  printf("[%d] %.15g %s %s %s %hu %u\n",i,message.meta.beat.utc,message.meta.beat.node,message.meta.beat.proc,message.meta.beat.addr,message.meta.beat.port,message.meta.beat.bsz);
404 
405  if (pretn < Agent::AgentMessage::BINARY && !channel.empty())
406  {
407  printf("%s\n",message.adata.c_str());
408  }
409 
410  if ((channel=="info") && pretn == Agent::AgentMessage::TRACK)
411  {
412  if (agent->cinfo->node.loc.utc > 0.)
413  {
414  if (lmjd > 0.)
415  dmjd = 86400.*(agent->cinfo->node.loc.utc-lmjd);
416  else
417  dmjd = 0.;
418  loc.pos.icrf.s = agent->cinfo->node.loc.pos.icrf.s;
419  loc.pos.utc = agent->cinfo->node.loc.utc;
420  pos_eci(&loc);
421  printf("%16.15g %6.4g %s %8.3f %8.3f %8.3f %5.1f %5.1f %5.1f\n",agent->cinfo->node.loc.utc,dmjd,agent->cinfo->node.name,DEGOF(loc.pos.geod.s.lon),DEGOF(loc.pos.geod.s.lat),loc.pos.geod.s.h,agent->cinfo->node.phys.powgen,agent->cinfo->node.phys.powuse,agent->cinfo->node.phys.battlev);
422  lmjd = agent->cinfo->node.loc.utc;
423  }
424  }
425 
426  if ((channel=="imu") && pretn == Agent::AgentMessage::IMU)
427  {
428  for (i=0; i<agent->cinfo->devspec.imu_cnt; i++)
429  {
430  if (agent->cinfo->agent[0].beat.utc > 0.)
431  {
432  if (lmjd > 0.)
433  dmjd = 86400.*(agent->cinfo->agent[0].beat.utc-lmjd);
434  else
435  dmjd = 0.;
436  printf("%.15g %.4g\n",loc.utc,dmjd);
437  lmjd = agent->cinfo->agent[0].beat.utc;
438  }
439  }
440  }
441  }
442  fflush(stdout);
443  } //end infinite while loop
444  }
445  else
446  {
447  nl.clear();
448 
449 // cbeat = agent->find_agent(argv[1], argv[2], SERVER_WAIT_TIME);
450 // if (cbeat.exists)
451  if ((nbytes = agent->get_agent(argv[1], argv[2], SERVER_WAIT_TIME, cbeat)) > 0)
452  {
453  if(argc == 3)
454  {
455  nbytes = agent->send_request(cbeat, "help", std::ref(output), REQUEST_WAIT_TIME);
456  printf("%s [%d]\n", output.c_str(), nbytes);
457  }
458  else
459  {
460  string request;
461  request = argv[3];
462  for (size_t i=0; i<(size_t)argc-4; ++i)
463  {
464  request += " ";
465  request += argv[i+4];
466  }
467  nbytes = agent->send_request(cbeat,request.c_str(), output, REQUEST_WAIT_TIME);
468 // printf("%s [%d]\n", output.c_str(), nbytes);
469 // printf("{\"request_output\": %s, \"bytes\": %d }\n", output.c_str(), nbytes);
470  // HANDLE RESPONSE OUTPUT FORMAT
471  printf("{");
472  size_t status_pos;
473  if((status_pos= output.find("[OK]") )!= string::npos){
474  if(output.at(0) == '{'){
475  if(status_pos - 1 >= 0 && output.at(status_pos - 1) == '}'){
476  printf("\"output\": %s,", output.substr(0, status_pos).c_str());
477  } else {
478  printf("\"output\": %s,", output.c_str());
479  }
480  } else {
481  printf("\"output\": \"%s\",", output.substr(0,status_pos ).c_str());
482  }
483  printf("\"status\": \"OK\"}\n");
484  } else if((status_pos = output.find("[NOK]") )!= string::npos){
485  printf("\"status\": \"NOK\"}\n");
486  } else {
487  printf("\"output\": %s }\n", output.c_str());
488  }
489  }
490  }
491  else
492  {
493  if (!nbytes){
494  fprintf(stderr,"node-agent pair [%s:%s] not found\n",argv[1],argv[2]);
495  printf("{\"error\": \"node-agent pair [%s:%s] not found\" }\n",argv[1],argv[2]);
496  }
497  else
498  printf("Error: %d\n", nbytes);
499  }
500  }
501  }
502 }
uint16_t imu_cnt
Definition: jsondef.h:3871
FILE * get_debug_fd(double mjd=0.)
Definition: agentclass.cpp:2645
AgentMessage
Type of Agent Message. Types > 127 are binary.
Definition: agentclass.h:216
beatstruc beat
Definition: agentclass.h:268
vector< uint8_t > bdata
Definition: agentclass.h:275
Definition: jsondef.h:923
int i
Definition: rw_test.cpp:37
int32_t json_parse(string jstring, cosmosstruc *cinfo)
Parse JSON using Name Space.
Definition: jsonlib.cpp:4799
int32_t send_request(beatstruc cbeat, string request, string &output, float waitsec=5.)
Send a request over AGENT.
Definition: agentclass.cpp:424
string getNode()
Listen for heartbeat.
Definition: agentclass.cpp:2607
string node_name
Definition: agent.cpp:70
uint32_t bsz
Transfer buffer size.
Definition: jsondef.h:938
char addr[18]
Protocol Address.
Definition: jsondef.h:934
float battlev
Definition: jsondef.h:3431
int iretn
Definition: rw_test.cpp:37
int32_t json_clear_cosmosstruc(int32_t type, cosmosstruc *cinfo)
Clear global data structure.
Definition: jsonlib.cpp:6268
double utc
Master time for location, in Modified Julian Day.
Definition: convertdef.h:879
devicestruc
Definition: jsondef.h:150
ElapsedTime et
Definition: agent_cpu_device_test.cpp:51
string adata
Definition: agentclass.h:276
vector< string > data_list_nodes()
Get list of Nodes, directly.
Definition: datalib.cpp:583
nodestruc node
Structure for summary information in node.
Definition: jsondef.h:4220
string cosmos_error_string(int32_t cosmos_errno)
Definition: cosmos-errno.cpp:45
int32_t get_agent(string node, string agent, double waitsec, beatstruc &cbeat)
Get specific server.
Definition: agentclass.cpp:513
rvector s
Location.
Definition: convertdef.h:163
int32_t post(messstruc mess)
Post a Cosmos::Agent::messstruc.
Definition: agentclass.cpp:2074
char proc[40+1]
Heartbeat Agent Name.
Definition: jsondef.h:930
char node[40+1]
Definition: jsondef.h:928
string getAgent()
Definition: agentclass.cpp:2609
static Agent * agent
ensure the Agent constructor creates only one instance per process
Definition: agent_001.cpp:45
string output
Definition: agent.cpp:69
double utc
Definition: convertdef.h:735
uint8_t message[300]
Definition: kpc9612p_send.cpp:36
char name[40+1]
Node Name.
Definition: jsondef.h:3556
uint16_t port
AGENT port.
Definition: jsondef.h:936
Definition: agentclass.h:139
uint16_t jlength
Definition: agentclass.h:267
locstruc loc
Location structure.
Definition: jsondef.h:3596
#define DEGOF(rad)
Degrees of a Radian value.
Definition: math/constants.h:33
int32_t pos_eci(locstruc *loc)
Set ECI position.
Definition: convertlib.cpp:258
double h
Height in meters.
Definition: vector.h:229
Storage for messages.
Definition: agentclass.h:272
nodestruc
Definition: jsondef.h:146
double lon
Longitude in radians.
Definition: vector.h:227
double data_ctime(string path)
Definition: datalib.cpp:1910
float powuse
Definition: jsondef.h:3433
const int REQUEST_WAIT_TIME
Definition: agent.cpp:53
Definition: elapsedtime.h:62
double currentmjd(double offset)
Current UTC in Modified Julian Days.
Definition: timelib.cpp:65
posstruc pos
posstruc for this time.
Definition: convertdef.h:881
gvector s
Position vector.
Definition: convertdef.h:263
double lat
Latitude in radians.
Definition: vector.h:225
pollstruc meta
Definition: agentclass.h:274
string jdata
Definition: agentclass.h:277
const int SERVER_WAIT_TIME
Definition: agent.cpp:54
string utc2iso8601(double utc)
ISO 8601 version of time.
Definition: timelib.cpp:1286
vector< agentstruc > agent
Single entry vector for agent information.
Definition: jsondef.h:4247
double utc
Definition: jsondef.h:926
static beatstruc cbeat
Definition: agent_file.cpp:92
cosmosstruc * cinfo
Definition: agentclass.h:346
vector< beatstruc > agent_list
List of active agents.
Definition: agentclass.h:349
geoidpos geod
Definition: convertdef.h:741
string agent_name
Definition: agent.cpp:71
devspecstruc devspec
Structure for devices (components) special data in node, by type.
Definition: jsondef.h:4241
double split()
ElapsedTime::split, gets the current elapsed time since the start()
Definition: elapsedtime.cpp:234
string mjd2iso8601(double mjd)
Definition: timelib.cpp:1316
cartpos icrf
Definition: convertdef.h:736
Inertial Measurement Unit.
Definition: jsondef.h:496
Definition: convertdef.h:876
physicsstruc phys
Definition: jsondef.h:3597
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
float powgen
Definition: jsondef.h:3432
#define NODE_ERROR_NODE
Definition: cosmos-errno.h:143

Variable Documentation

const int REQUEST_WAIT_TIME = 2
const int SERVER_WAIT_TIME = 6
string output
string node_name = ""
string agent_name = ""