COSMOS core  1.0.2 (beta)
Comprehensive Open-architecture Solution for Mission Operations Systems
netperf_listen.cpp File Reference
#include "agent/agentclass.h"
#include "support/jsondef.h"
#include "support/sliplib.h"
#include "support/timelib.h"
Include dependency graph for netperf_listen.cpp:

Macros

#define BUFSIZE   10000
 
#define INFO_SIZE   32
 
#define CURRENT_TIME_us   currentmjd()*DAY_TO_SECONDS*1000*1000
 

Functions

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

Variables

bool debug_verbose = false
 
char address [] = "0.0.0.0"
 
uint16_t port = 6101
 
uint16_t bsize = 10000
 

Macro Definition Documentation

#define BUFSIZE   10000
#define INFO_SIZE   32
#define CURRENT_TIME_us   currentmjd()*DAY_TO_SECONDS*1000*1000

Function Documentation

int main ( int  argc,
char *  argv[] 
)
74 {
75  // **** Delcare Variables
76 
77  // Variables: Program Control
78  bool firstpacket; // Flag indicating whether first packet has been received or not
79  unsigned int timeout_count; // Limit on recvfrom timeout intervals to exit after first packet
80  unsigned int idle_count; // UDP recvfrom timeout counter
81  bool quietmode; // Sets interactive or quiet mode
82  double t_display_timer; // Interactive display update timer
83  // bool log_header_print; // Sets whether log header will be printed or not
84 
85 
86  // Variables: Packet Reception: Data handling
87  socket_channel chan; // Agent UDP Channel Sructure
88  unsigned int fromlen; // UDP receive from "fromlen" parameter
89  int received; // Num bytes received per UDP packet
90  uint8_t buf1[BUFSIZE]; // RX Buffer
91  char buf2[BUFSIZE]; // RX Buffer
92  // char *p_data_start; // Pointer to where the packet's payload starts, specified by bsize
93 
94  double cmjd; // Test Packet: Header Mean Julian Date
95  uint16_t crc; // Test Packet: Header CRC
96  uint16_t bindex; // Test Packet: Header Index #
97  uint16_t bsize; // Test Packet: Header Data Size, data start = bytes_received-bsize
98  uint16_t bindex_next_expected; // Test Packet: Next expected header index
99  uint16_t packet_crc_scratch; // Test Packet: Scratchpad for CRC calculation on data
100 
101  // Variables: Packet Reception: Statistics
102  uint32_t packet_count; // Count of packets with data
103  uint32_t packet_count_dropped; // Count of dropped packets (skipped index numbers)
104  uint32_t packet_count_crc_err; // Count of dropped packets (CRC didn't match calculated with data)
105  uint32_t packet_count_runt; // Count of runt packets (payload larger than received)
106  uint32_t data_accumulator=0; // Count of total bytes received
107  double initial_t,final_t; // Initial/Final time of packet activity
108 
109  double data_rate_min,data_rate_max; // Data rate: Variables to hold min/max data rate
110  double data_rate_avg; // Data Rate: Scratchpad to hold current average
111  double data_rate_accumulator; // Data Rate: Accumulator to hold past data rate history
112  uint32_t data_rate_count; // Data Rate: Count of records in accumulator
113  double data_ref_t; // Data rate: Past time record
114  double data_rate; // Data rate: Current data rate scratch
115 
116  double ref_t,new_t,delta_t; // Inter-Packet Latency: Time Variables, Past/new/delta
117  double t_accumulator,t_count; // Inter-Packet Latency: Time accumulator, # accum records count
118  double t_min,t_max,t_avg; // Inter-Packet Latency: Min/Max/Average scratch
119 
120 
121  // Variables: Scratchpad
122  int32_t iretn; // Scratch Return value
123 
124 
125  // **** Initialize Variables
126 
127  // Initialize Program Control Vars
128  timeout_count = 10;
129  idle_count = 0;
130  firstpacket = false;
131  quietmode = false;
132  // log_header_print = true;
133 
134  // Initialize Packet Reception Statistics Vars
135  // Inter-Packet Latency
136  ref_t = CURRENT_TIME_us;
137  new_t = CURRENT_TIME_us;
138  t_min = 99999;
139  t_max = 0;
140  t_accumulator = 0;
141  t_count = 0;
142  // Data Rate
143  data_rate_min=99999999;
144  data_rate_max=0;
145  data_rate_accumulator=0;
146  data_rate_count=0;
147  data_ref_t = CURRENT_TIME_us;
148  // Overall Stats
149  initial_t = CURRENT_TIME_us;
150  packet_count = 0;
151  // Packet Error Counting
152  bindex = 0;
153  bindex_next_expected = 0;
154  packet_count_dropped = 0;
155  packet_count_crc_err = 0;
156  packet_count_runt = 0;
157 
158  switch(argc)
159  {
160  case 2:
161  // 1 arguments = log header only and exit
162  printf("Packet Size [bytes]\tSpeed [bytes/sec]\tRX Time[us]\tPackets Received\tPacket Drops\tPacket CRC Errors\tPacket Runts\tBytes Received\tData Rate: Min [bytes/sec]\tData Rate: Average [bytes/sec]\tData Rate: Max [bytes/sec]\tInter-Packet Delay: Min [us]\tInter-Packet Delay: Avg [us]\tInter-Packet Delay: Max [us]\n");
163  exit(0);
164  break;
165  case 3:
166  // 2 argument = log entry only
167  quietmode = true;
168  // log_header_print = false;
169  break;
170  }
171 
172 
173  // Begin Program, Initialize Socket, Blocking, Timeout set for 1 second
174  if ((iretn=socket_open(&chan, NetworkType::UDP, address, port, SOCKET_LISTEN, SOCKET_BLOCKING, 2000000)) < 0)
175  {
176  printf("Err: Unable to open connection to [%s:%d]\n",address,port);
177  }
178 
179  if(!quietmode) printf("Netperf Listen is now listening on port %d...\n\n",port);
180 
181  // Begin Main Forever Loop
182  while (1)
183  {
184  // UDP Receive: Check for new packet, return -1 if none
185  received = recvfrom( chan.cudp, (char *)buf1, BUFSIZE, 0, (struct sockaddr*) &chan.caddr, (socklen_t*) &fromlen);
186  if (received < 1)
187  {
188  // If result: No new packet received
189  idle_count++; // Increment idle count
190 
191  // Report idle
192  if(!quietmode) printf("[Idle %d...%d]\n",idle_count, received);
193  if(!quietmode) fflush(stdout);
194 
195  if(idle_count >= timeout_count && firstpacket == true)
196  {
197  if(!quietmode) printf("Idle timeout after activity, exiting.\n\n");
198 
199  // Begin Exit Report Code
200  final_t = new_t; // Log final time
201 
202  // Data Rate Statististics
203  data_rate = data_accumulator / ( (final_t - initial_t) / 1000000); // Get [Bytes/s]
204 
205  //printf("Exiting, %.0fus %d \n\n",final_t-initial_t, );
206  if(!quietmode) printf("Final Report: \n");
207  // if(log_header_print) printf("Packet Size [bytes]\tSpeed [bytes/sec]\tRX Time[us]\tPackets Received\tPacket Drops\tPacket CRC Errors\tBytes Received\tData Rate: Average [bytes/sec]\tInter-Packet Delay: Avg [us]\n");
208  if (t_count)
209  {
210  t_avg = t_accumulator / t_count; // Update average IPD
211  }
212  else
213  {
214  t_avg = 0;
215  }
216  printf("%.0f\t%d\t%d\t%d\t%d\t%.0f\t%.0f\n",(final_t-initial_t),packet_count,packet_count_dropped,packet_count_crc_err,data_accumulator,data_rate,t_avg);
217 
218  fflush(stdout);
219  // End Exit Report Code
220 
221  exit(0);
222  }
223  }
224  else
225  {
226  // If result: packet received
227  // Update Inter-Packet Delay Statistics
228  new_t = CURRENT_TIME_us; // Get new time
229  delta_t = new_t - ref_t; // Get time difference in milliseconds
230  ref_t = new_t; // Set new reference time
231  if (delta_t < t_min) t_min = delta_t; // Update minium inter-packet delay
232  if (delta_t > t_max) t_max = delta_t; // Update maximum inter-packet delay
233  t_accumulator += delta_t; // Accumulate inter-packet delay (IPD) records
234  t_count++; // Increment count of accumulated IPD records
235  t_avg = t_accumulator / t_count; // Update average IPD
236 
237  // Parse Packet
238  // Fields: currentmjd, count, slip_calc_crc, bsize, binary data
239  strncpy(buf2,(const char *)buf1,INFO_SIZE);
240  buf2[INFO_SIZE] =0;
241  sscanf((char *)buf2,"%lf %hu %hx %hu",&cmjd,&bindex,&crc,&bsize);
242  if (debug_verbose)
243  {
244  printf("Packet: %f, %hu, %hx, %hu\n", cmjd, bindex, crc, bsize);
245  printf("PACKET: %s\n",buf2);
246  }
247  // numsizeread - bsize = start position
248 
249 
250  // Test Packet: Sequence Check
251  if(bindex != bindex_next_expected)
252  {
253  packet_count_dropped+=(bindex - bindex_next_expected);
254  if (!quietmode) printf("\nError: Index Received: %u, Index Expected: %u, Missed %d packets\n", bindex, bindex_next_expected, bindex-bindex_next_expected);
255  }
256  bindex_next_expected = bindex + 1;
257 
258  // Test Packet: Runt Check
259  // Null terminate at least 5 times beyond buffer to ensure strtok does not crash the program if incomplete packet is received.
260  buf1[received]=0;
261  buf1[received+1]=0;
262  buf1[received+2]=0;
263  buf1[received+3]=0;
264  buf1[received+4]=0;
265 
266  // Advance p_data_start to theoretical beginning of data
267  // p_data_start = strtok((char*)buf1, " ");
268  // p_data_start = strtok(NULL, " ");
269  // p_data_start = strtok(NULL, " ");
270  // p_data_start = strtok(NULL, " ");
271 
272 
273 
274  if (received < bsize)
275  {
276  packet_count_runt++;
277  if (!quietmode) printf("\nError: Bytes dropped: packet %d expected %u received %u\n", bindex_next_expected, bsize, received);
278  }
279  else
280  {
281  // Test Packet: CRC Check
282  packet_crc_scratch = slip_calc_crc((uint8_t *) &buf1[INFO_SIZE],bsize-INFO_SIZE);
283  if (crc != packet_crc_scratch)
284  {
285  packet_count_crc_err++;
286  if (!quietmode) printf("\nError: Index %d has bad CRC when comparing packet %x to calc %x. \n",bindex, crc, packet_crc_scratch);
287  } else {
288  if (debug_verbose)printf("\nIndex %d packet %x calc %x \n",bindex, crc, packet_crc_scratch);
289  }
290  }
291 
292 
293  // Overall statistics
294  packet_count++; // Packet Count update
295  data_accumulator += received; // Increment bytes received
296 
297  // Program control: Reset idle count to back off timeout
298  idle_count = 0; // Reset idle count
299  t_display_timer += delta_t; // Accumulate time since last reset
300 
301  // Check if this is the first packet
302  if (!firstpacket)
303  {
304  // If result: first packet found
305  initial_t = data_ref_t = new_t; // Data rate: update new past-reference time to be first packet time
306  firstpacket = true; // Flag first packet received is now true
307  t_display_timer = 0 ; // Reset display timer, delay 1 second
308  data_accumulator -= received;
309  }
310 
311 
312  // Display Control
313 
314  // Run display routine every second (assuming t_display_timer in microseconds)
315  if (t_display_timer > 1000000) {
316  // If result: display timer beyond 1 second
317  t_display_timer -= 1000000; // Back off display timer by 1 second
318 
319  // Data Rate Statististics
320  data_rate = (data_accumulator) / ((new_t - data_ref_t) / 1000000) ; // get Bytes/s
321  data_rate_accumulator += data_rate; // Add current data rate to accumulator records
322  data_rate_count++; // Update data rate accumulator record count
323  data_rate_avg = data_rate_accumulator / data_rate_count; // Calculate average data rate
324  if (data_rate < data_rate_min) data_rate_min = data_rate; // Update min data rate
325  if (data_rate > data_rate_max) data_rate_max = data_rate; // Update max data rate
326 
327  // Interactive display routine
328  if(!quietmode)
329  {
330  printf("%d packets: DRate(1s/Avg): %.1f/%.1f [Bytes/s], I-P Time (Min/Avg/Max): %.0f/%.0f/%.0f [us]\n",packet_count,data_rate,data_rate_avg,t_min,t_avg,t_max);
331  fflush(stdout);
332  }
333 
334  t_display_timer = 0; // Reset Display Timer
335  // data_ref_t = CURRENT_TIME_us; // Reset reference time for data rate
336 
337  } // End If: Stopwatch Display Routine
338 
339  } // End If: packet reception / parse / idle cycle
340 
341  } // End Main Forever Loop
342 
343 } // End Main
static double cmjd
Definition: agent_monitor.cpp:121
Agent socket using Unicast UDP.
bool debug_verbose
Definition: netperf_listen.cpp:68
uint16_t bsize
Definition: netperf_listen.cpp:71
int iretn
Definition: rw_test.cpp:37
png_uint_32 crc
Definition: png.c:2173
#define BUFSIZE
Definition: netperf_listen.cpp:64
char address[]
Definition: netperf_listen.cpp:69
int32_t cudp
Definition: socketlib.h:120
#define INFO_SIZE
Definition: netperf_listen.cpp:65
Definition: socketlib.h:115
struct sockaddr_in caddr
Definition: socketlib.h:122
#define SOCKET_BLOCKING
Blocking Agent.
Definition: socketlib.h:78
uint16_t slip_calc_crc(uint8_t *buf, uint16_t size)
Calculate CRC-16-CCITT.
Definition: sliplib.cpp:322
#define SOCKET_LISTEN
Listen followed by optional talk (recvfrom INADDRANY)
Definition: socketlib.h:84
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
uint16_t port
Definition: netperf_listen.cpp:70
#define CURRENT_TIME_us
Definition: netperf_listen.cpp:66

Variable Documentation

bool debug_verbose = false
char address[] = "0.0.0.0"
uint16_t port = 6101
uint16_t bsize = 10000