blocksend.c File Reference

Sending a continuous data stream over TCP. More...

#include <BoardSupport/inc/stdtypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <inttypes.h>
#include <time.h>
#include <string.h>
#include <Libs/NETlib/net.h>
#include <BoardSupport/inc/BoardSpecific.h>
#include <Common/Common.h>
#include <Common/uartio.h>
#include <Common/timer.h>
#include <Common/CPrintf.h>
#include <BoardSupport/config/netconfig.c>

Macros

#define LOCAL_TCP_PORT   5031
 

Functions

int32_t tcp_echo_cb (SOCKET *so, void *data, uint32_t len, uint32_t ec)
 
SOCKET * open_tcp_server (void)
 
uint16_t my_monitor_link_status (tpOutputFunc pLog)
 
int main (void)
 

Variables

char * program_name = "blocksend"
 
far char * domain_name
 
static unsigned char data_buffer [TCP_SEND_BUFFER_SIZE]
 
uint8_t _link_mode
 
uint32_t transmitting = FALSE
 
uint32_t dhcp_active = FALSE
 
SOCKET * tcp_server = INVALID_SOCKET
 
static char buffer [100]
 
timeval connect_stamp1
 

Detailed Description

                          _         _             _
                       __| |    ___(_) ____ _ __ | |_
                      / _` |   / __| |/ _` | '_ \| __|
                     | (_| | _ \__ \ | (_| | | | | |_
                      \__,_|(_) ___/_|\__, |_| |_|\__|
                     Signalprocessing |___/ Technology
Author
D.SignT GmbH & Co. KG, Claus Hermbusche
Date
2019-06-03

To verify this program, first 'ping' the DSP:

>ping 192.168.168.200

or, if configured for DHCP

>ping mydemo

If the settings and network connections are correct, the pings will be replied.

Establish a TCP connection on port 5031:

>nc 192.168.168.200 5031 > test.dat

or

>nc mydemo 5031 > test.dat

A continuous data stream will be written into test.dat until the connection is closed.

Macro Definition Documentation

#define LOCAL_TCP_PORT   5031
Examples:
Blocksend.c.

Function Documentation

int32_t tcp_echo_cb ( SOCKET *  so,
void *  data,
uint32_t  len,
uint32_t  ec 
)
Examples:
Blocksend.c, and Echo.c.
190 {
191  /***************************************************************************
192  locals
193  ***************************************************************************/
194  int32_t data_length; // net_recv_event_handler() return parameter
195 
196  /***************************************************************************
197  suppress unused parameter warning
198  ***************************************************************************/
199  UNREFERENCED_PARAMETER(data); // replaced by bctl-> Buf[].Data
200  // UNREFERENCED_PARAMETER(ec); // handled in net_recv_event_handler()
201  UNREFERENCED_PARAMETER(len); // len is ignored, data_len is used instead
202 
203  /***************************************************************************
204  Check events
205  If NULL is passed as pLog parameter, no message is printed to output.
206  Use net_recv_event_handler() to determine the data length waiting in the
207  receive buffer
208  ***************************************************************************/
209  data_length = net_recv_event_handler (so, CPrintf); /* with messages */
210  // data_length = net_recv_event_handler (so, NULL); /* without messages */
211 
212  /***************************************************************************
213  net_recv_event_handler() returns the amount of data waiting in the buffer
214  ***************************************************************************/
215  if (data_length)
216  {
217  // CPrintf ("received %"PRId32" bytes\r\n", data_length);
218 
219  }
220 
221  /***************************************************************************
222  use this callback to detect a timeout
223  ***************************************************************************/
224  switch ( ec & SO_ERROR_MASK )
225  {
226  case SO_TIMED_OUT: // timeout detected, shutdown connection
227  shutdown (tcp_server, 0);
228  break;
229 
230  default:
231  break;
232  }
233 
234  /***************************************************************************
235  Return true, if socket was not closed before
236  ***************************************************************************/
237  return (SOCKET_CB_OK);
238 }
int32_t shutdown(SOCKET *so, int32_t timeout)
Active shut-down of a TCP connection.
#define SO_ERROR_MASK
Definition: net.h:480
int CPrintf(const char *_format,...)
Custom printf function.
Definition: cprintf.c:708
#define SO_TIMED_OUT
Definition: net.h:464
int int32_t
Definition: stdint.h:46
SOCKET * tcp_server
Definition: blocksend.c:157
#define UNREFERENCED_PARAMETER(P)
Definition: Common.h:115
#define SOCKET_CB_OK
Definition: net.h:576
SOCKET* open_tcp_server ( void  )
Examples:
Blocksend.c.
249 {
250  /***************************************************************************
251  locals
252  ***************************************************************************/
253  SOCKET *so = INVALID_SOCKET;
254 
255  so = socket_open (ANY_ADDRESS,
256  ANY_PORT,
259  TCP_INIT_FUNC);
260  if ( so == INVALID_SOCKET )
261  {
262  prg_exit ("socket_open() error"); /* possibly insufficient heap */
263  }
264 
265  /***************************************************************************
266  set keep alive time 5 seconds (three unanswered packets within 5 seconds)
267  ***************************************************************************/
269 
270  /***************************************************************************
271  install callback function
272  ***************************************************************************/
274 
275  /***************************************************************************
276  increase unacknowledged segment size
277  ***************************************************************************/
279 
280  /***************************************************************************
281  set lower re-transmit delay
282  ***************************************************************************/
283  // tcp_set_option( so, TCP_RETRANS_DELAY, 0x20); //default 0x40
284 
285  return (so);
286 
287 }
#define LOCAL_TCP_PORT
Definition: blocksend.c:132
#define prg_exit(s)
Definition: Common.h:267
void socket_define_callback(SOCKET *so, int32_t(*call_back_function)(SOCKET *, void *, uint32_t, uint32_t), void *data, uint16_t maxdata)
Install a user callback function for a specific socket.
int16_t tcp_set_keep_alive_time(SOCKET *so, uint32_t time)
Set keep alive time.
#define ANY_PORT
Definition: net.h:519
#define TCP_MAX_PACKET_SIZE
Definition: net.h:681
#define KA_TIMEOUT(x)
Definition: BoardSpecific.h:230
#define TCP_INIT_FUNC
Definition: net.h:499
static char buffer[100]
Definition: blocksend.c:158
SOCKET * socket_open(char *dest_addr, uint16_t dest_port, uint16_t src_port, uint8_t data_type, int32_t(*init_func)(SOCKET *))
Create a new socket.
uint16_t tcp_set_option(SOCKET *so, uint32_t option, uint32_t val)
Set a TCP option.
#define TCP_UNA_SEG
Definition: net.h:711
int32_t tcp_echo_cb(SOCKET *so, void *data, uint32_t len, uint32_t ec)
Definition: blocksend.c:189
#define ANY_ADDRESS
Definition: net.h:511
#define DATATYPE_CHAR
Definition: net.h:489
#define INVALID_SOCKET
Definition: net.h:540
uint16_t my_monitor_link_status ( tpOutputFunc  pLog)
Examples:
Blocksend.c.
311 {
312  /***************************************************************************
313  locals
314  ***************************************************************************/
315  static uint8_t _link_mode_old = 0xff;
316 
317  if (_link_mode_old != _link_mode)
318  {
319  _link_mode_old = _link_mode;
320  if (pLog) pLog ("\n\r Link status changed: ");
321  switch (_link_mode)
322  {
323  case 0xff:
324  LED_off (2);
325 
326  /***************************************************************
327  shutdown connection and close socket
328  ***************************************************************/
329  shutdown (tcp_server, 0);
332 
333  if (pLog) pLog ("No Link\r\n");
334  break;
335 
336  default:
337  LED_on (2);
338 
339  /***************************************************************
340  if not configured for DHCP, open a new TCP server socket
341  ***************************************************************/
342  if (!dhcp_active)
343  {
345  }
346 
347  if (pLog) pLog ("Linked at %d Mbit %s duplex\r\n",
348  (_link_mode & SPEED_100) ? 100:10,
349  (_link_mode & FULL_DUPLEX) ? "full":"half");
350  break;
351  }
352  return (1);
353  }
354  return (0);
355 }
int32_t shutdown(SOCKET *so, int32_t timeout)
Active shut-down of a TCP connection.
SOCKET * open_tcp_server(void)
Definition: blocksend.c:248
uint32_t dhcp_active
Definition: blocksend.c:155
uint8_t _link_mode
Definition: BoardSpecific.c:138
void LED_on(unsigned int ledNum)
Definition: BoardSpecific.c:1302
unsigned char uint8_t
Definition: stdint.h:43
void LED_off(unsigned int ledNum)
Definition: BoardSpecific.c:1284
int32_t socket_close(SOCKET *so)
Close a socket and free all associated memory.
#define SPEED_100
Definition: net.h:246
#define INVALID_SOCKET
Definition: net.h:540
SOCKET * tcp_server
Definition: blocksend.c:157
#define FULL_DUPLEX
Definition: net.h:231
int main ( void  )
365 {
366  /***************************************************************************
367  locals
368  ***************************************************************************/
369  int main_loop = 1; /* main loop switch, set to 0 to exit */
370  char conversion_buffer[16];
371  struct tm *local_time; /* structure to hold time and date */
372  timeval stamp2, delta; /* used to determine session time */
373  static timeval CurrentTimeStamp;
374 
375  /***************************************************************************
376  initialize application (e.g. timer clocks, PLL settings, EMIF etc.)
377  (ref. \Common\Common.c)
378  ***************************************************************************/
379  AppInit (GET_CLOCK);
380 
381  /***************************************************************************
382  select output device for CPrintf (ref. \Common\cprintf.c)
383  possible settings:
384  CPRINTF_UART_OUTPUT -> output to UART
385  CPRINTF_CCS_OUTPUT -> output to CCS
386  CPRINTF_UART_OUTPUT | CPRINTF_CCS_OUTPUT -> output to UART and CCS
387  ***************************************************************************/
388  CPrintf_select_output (CPRINTF_DEFAULT_OUTPUT); /* default outputs */
389 
390  /***************************************************************************
391  print a start up message
392  ***************************************************************************/
393  START_UP_MESSAGE (BLANK_REV NETLIB_REV);
394 
395  /**************************************************************************/
396  // CPrintfProgress (" Heap check ");
397  // at least 0x2000 bytes required for this app
398  /**************************************************************************/
399  ASSERT_HEAP (initial_heap_size, 0x2000);
400  // CPrintfProgressSuccess();
401 
402  /**************************************************************************/
403  CPrintfProgress (" Setup system time ");
404  /**************************************************************************/
407  CPrintf (" *** timer %d mapped to CPU int %d ***\r\n",
409 
410  /**************************************************************************/
411  CPrintfProgress (" Enable interrupts ");
412  /**************************************************************************/
415 
416  /**************************************************************************/
417  CPrintfProgress (" Start system timer ");
418  /**************************************************************************/
419  StartSystemTimer ();
421  CPrintf (" *** timer %d running at %"PRId32" Hz ***\r\n", SystemTimerDev, RES_SECONDS/GetSystemTimerRes());
422 
423  /**************************************************************************/
424  CPrintfProgress (" Initialize network ");
425  /**************************************************************************/
426  InitializeNetwork ( 64); // 64 bytes for ping
428 
429  /***************************************************************************
430  detect if program was configured for DHCP
431  ***************************************************************************/
432  if (!((eth.ip[0]-'0')<=9))
433  {
434  dhcp_active = TRUE;
435  }
436  else
437  {
439  }
440 
441  /***************************************************************************
442  main program loop: set main_loop to 0 to exit loop
443  ***************************************************************************/
444  CPuts ("\r\n Entering main loop ...");
445  while ( main_loop )
446  {
447  /***********************************************************************
448  process net_isq()
449  ***********************************************************************/
450  net_isq (); // process ISQ
451 
452  /***********************************************************************
453  monitor link status
454  ***********************************************************************/
456 
457  /***********************************************************************
458  try to detect IP assignment
459  if DHCP is used, the assigned IP address may change
460  ***********************************************************************/
462  {
463  /*******************************************************************
464  in case of DHCP open a new TCP server after IP assignment
465  *******************************************************************/
466  if (dhcp_active)
467  {
469  }
470 
471  /*******************************************************************
472  print what to do next
473  *******************************************************************/
474  CPrintf (" Establish a TCP connection on port %d:\r\n", tcp_server-> src_port);
475 
476  if (domain_name) CPrintf (">nc %s.%s %d > test.dat\r\n or\r\n",
477  eth.ip,
478  domain_name,
479  tcp_server-> src_port);
480  CPrintf (">nc %s %d > test.dat\r\n",
481  inet_ntoa(get_ip_address(0), conversion_buffer),
482  tcp_server-> src_port);
483 
484  CPuts (" A continuous data stream will be written into test.dat\r\n until the connection is closed.\r\n");
485  }
486 
487  /***********************************************************************
488  TCP output
489  ***********************************************************************/
490  if ( accept (tcp_server) && (_link_mode != 0xff)) /* if connection established */
491  {
492  /*******************************************************************
493  if TCP connection established but transmitting flag not set, a new
494  connection has started.
495  *******************************************************************/
496  if (transmitting == FALSE)
497  {
498  transmitting = TRUE; /* set flag for transmission */
499 
500  /***************************************************************
501  take time stamp when the connection started
502  ***************************************************************/
504  }
505  else
506  {
507  /***************************************************************
508  show that the program is running, print connection time
509  ***************************************************************/
510  if ( tv_elapsed (&CurrentTimeStamp, UINT32_C(1), UINT32_C(0), TRUE) )
511  {
512  /***********************************************************
513  get current time
514  ***********************************************************/
515  stamp2 = GetTimeStamp();
516 
517  /***********************************************************
518  calculate elapsed time
519  ***********************************************************/
520  tv_interval (&delta, &connect_stamp1, &stamp2);
521  local_time = localtime ((const time_t *)&delta);
522  CPrintf (CLRLINE" %02d:%02d:%02d",
523  local_time->tm_hour, local_time->tm_min, local_time->tm_sec );
524  }
525  }
526 
527  /*******************************************************************
528  check data currently in transmission (wait for completion was not
529  used in net_send_safe() below)
530  two approaches:
531  1. use tcp_tx_complete()
532  2. determine pending data with tcp_pending_window() and decide
533  if sending new data is safe
534  *******************************************************************/
535  if ( tcp_tx_complete (tcp_server) )
536  // if ( tcp_pending_window (tcp_server) < TCP_MAX_PACKET_SIZE )
537  {
538  /***************************************************************
539  process buffer, generate new data
540  ***************************************************************/
541  /* ... */
542 
543  /***************************************************************
544  send data block
545  no need to wait for completion here because tcp_pending_window()
546  is used above to prevent net_send_safe() being called while
547  data is pending.
548  ***************************************************************/
549  if (net_send_safe (tcp_server,
550  data_buffer,
552  TCP_NOWAIT) == 0)
553  {
554  /***********************************************************
555  fatal error occurred, stop transmission
556  ***********************************************************/
557  shutdown (tcp_server, 0);
558  }
559  }
560  else
561  {
562  /***************************************************************
563  more than one packet is pending, don't touch the buffer!
564  ***************************************************************/
565  } // if
566  }
567  else
568  {
569  if (transmitting)
570  {
571  /***************************************************************
572  connection stopped
573  ***************************************************************/
574  transmitting = FALSE; /* clear transmission flag */
575  shutdown (tcp_server, 0);
576 
577  /***************************************************************
578  get current time
579  ***************************************************************/
580  stamp2 = GetTimeStamp();
581 
582  /***************************************************************
583  calculate elapsed time
584  ***************************************************************/
585  tv_interval (&delta, &connect_stamp1, &stamp2);
586  local_time = localtime ((const time_t *)&delta);
587  CPrintf (" connection duration [hh:mm:ss]: ");
589  " %02d:%02d:%02d\r\n"
591  local_time->tm_hour, local_time->tm_min, local_time->tm_sec );
592  }
593 
594  /*******************************************************************
595  show that the program is running
596  *******************************************************************/
597  if ((get_ip_address (0)) != UINT32_C(0))
598  {
599  CPrintProgressBarText ('<', 500000, 1, " waiting for connection ");
600  }
601  }
602  }
603 
604  /***************************************************************************
605  exit program, shut down peripherals
606  ***************************************************************************/
607  return (0);
608 }
#define TCP_SEND_BUFFER_SIZE
Definition: BoardSpecific.h:224
void BoardEnableInterrupts(void)
global enable interrupts
Definition: BoardSpecific.c:365
int32_t shutdown(SOCKET *so, int32_t timeout)
Active shut-down of a TCP connection.
#define CLRLINE
Definition: cprintf.h:171
void StartSystemTimer(void)
start system timer
Definition: timer.c:447
SOCKET * open_tcp_server(void)
Definition: blocksend.c:248
uint16_t tcp_tx_complete(SOCKET *so)
Test if the last TCP transmission was acknowledged.
#define RES_MSECONDS
Definition: timer.h:67
char * inet_ntoa(uint32_t i_addr, char *s)
Convert IP-address from 0xbbaaddcc to "aaa.bbb.ccc.ddd".
uint16_t CPrintf_select_output(uint16_t device)
Definition: cprintf.c:206
#define ASSERT_HEAP(i, h)
Definition: Common.h:262
SOCKET * accept(SOCKET *so)
Check TCP state; if connection established, the socket descriptor is returned else NULL...
uint32_t transmitting
Definition: blocksend.c:154
uint32_t dhcp_active
Definition: blocksend.c:155
uint8_t _link_mode
Definition: BoardSpecific.c:138
time_t GetSystemTimerRes(void)
Definition: timer.c:160
#define UINT32_C(value)
Definition: stdint.h:210
#define GET_CLOCK
Definition: BoardSpecific.h:258
int tv_elapsed(timeval *t, time_t s, time_t u, uint16_t retrigger)
check if given time has elapsed
Definition: timer.c:286
int CPrintf(const char *_format,...)
Custom printf function.
Definition: cprintf.c:708
#define VT100_DEFAULT
Definition: cprintf.h:150
void SetupSystemTime(int32_t cpuint, int port, time_t resolution)
Setup System Time.
Definition: timer.c:392
void AppInit(uint32_t dsp_clock)
Initialize application.
Definition: Common.c:230
uint32_t initial_heap_size
Definition: Common.c:140
timeval connect_stamp1
Definition: blocksend.c:159
#define CPRINTF_DEFAULT_OUTPUT
Definition: BoardSpecific.h:129
#define VT100_RED
Definition: cprintf.h:143
static unsigned char data_buffer[TCP_SEND_BUFFER_SIZE]
Definition: blocksend.c:150
int InitializeNetwork(uint16_t icmp_size)
Initialize MAC, sockets and protocols.
Definition: BoardSpecific.c:597
Definition: timer.h:75
#define GetTimeStamp()
Definition: timer.h:81
void tv_interval(timeval *e, timeval *t1, timeval *t2)
compute elapsed time
Definition: timer.c:336
#define SYSTEM_TIMER_INT
Definition: BoardSpecific.h:174
#define SYSTEM_TIMER
Definition: BoardSpecific.h:167
uint32_t get_ip_address(uint16_t dev_nr)
Get configured IP address.
void net_isq(void)
The main polling function for processing sockets, must be periodically called in the main application...
char ip[31]
Definition: net.h:170
#define BLANK_REV
Definition: BoardSpecific.h:191
uint16_t my_monitor_link_status(tpOutputFunc pLog)
Definition: blocksend.c:310
Uint16 SystemTimerDev
adapter_t eth
Definition: netconfig.c:62
uint16_t monitor_ip_address(tpOutputFunc pLog)
monitor IP assignment
Definition: BoardSpecific.c:545
SOCKET * tcp_server
Definition: blocksend.c:157
int32_t CPrintProgressBarText(char c, time_t period, size_t length, char *text)
Definition: cprintf.c:902
#define START_UP_MESSAGE(rev)
Definition: BoardSpecific.h:192
far char * domain_name
#define RES_SECONDS
Definition: timer.h:70
int CPuts(const char *_ptr)
Definition: cprintf.c:399
#define CPrintfProgress(s)
Definition: cprintf.h:230
#define CPrintfProgressSuccess()
Definition: cprintf.h:263

Variable Documentation

char* program_name = "blocksend"
far char* domain_name
unsigned char data_buffer[TCP_SEND_BUFFER_SIZE]
static
uint8_t _link_mode

use Operation Mode parameter to detect link mode FULL_DUPLEX 0x01 SPEED_100 0x04 SPEED_1000 0x20

uint32_t transmitting = FALSE
Examples:
Blocksend.c.
uint32_t dhcp_active = FALSE
Examples:
Blocksend.c.
SOCKET* tcp_server = INVALID_SOCKET
timeval connect_stamp1
Examples:
Blocksend.c.