Functions

int16_t send_ip (SOCKET *so, addr_type *dest, uint16_t len, uint16_t id)
 Low-level send function for sending RAW IP packets. More...
 
int32_t net_send (SOCKET *so, void *data, uint16_t len)
 Send a message via the specified socket. More...
 
int32_t net_send_string (SOCKET *so, char *data)
 Send a zero terminated string via the specified socket. More...
 
int32_t net_send_ready (SOCKET *so, void *data, uint32_t len, uint32_t timeout)
 Send a message via the specified socket, wait until message is successfully transmitted or a timeout occurred. More...
 
int32_t net_recv (SOCKET *so, void *data, uint16_t maxdatasize)
 Receive data via the specified socket. More...
 
int32_t set_recv_buffer (SOCKET *so, void *data, uint16_t maxdatasize)
 Define a socket buffer. More...
 
int32_t net_recv_ready (SOCKET *so, void *data, int32_t *len, uint32_t timeout)
 Receive data via the specified socket, wait until message is successfully received and connection closed from sender or a timeout occurred. More...
 

Detailed Description

Function Documentation

int16_t send_ip ( SOCKET *  so,
addr_type dest,
uint16_t  len,
uint16_t  id 
)
Parameters
so- socket to use
dest- destination address information
len- length of data to be transmitted
id- unique packet id
Returns
  • FALSE => success
  • TRUE => error

This function is used to send RAW IP packets. Address resolution and checksum generation must be performed manually.

Library:
net.lib
Prototype:
net.h
//****************************************************************************
// perform address lookup in ARP cache
//****************************************************************************
arp = arp_check_ip_address (icmp_so-> dest_addr, 0);
if ( arp == NULL)
{
//**************************************************************************
// address not found, start new ARP request
//**************************************************************************
printf ("Address %s not found,\r\n initiate ARP request...\r\n",
inet_ntoa(icmp_so-> dest_addr, temp));
}
else
{
//**************************************************************************
// address found
//**************************************************************************
if (arp->valid == FALSE)
{
///***********************************************************************
// address found, but invalid or timed out
// force stack to perform a new ARP request
//************************************************************************
printf ("Address %s found but invalid,\r\n initiate new ARP request...\r\n",
inet_ntoa(icmp_so-> dest_addr, temp));
//************************************************************************
// if arp-> send is not set to 100000, the stack uses the
// internal backoff algorithm to trigger a new ARP request;
// the backoff algorithm results in the following sequence:
// 2, 3, 5, 9, 17, 26, 37, 50, 65, 82... x ARP_REQUEST_TIME
//************************************************************************
arp-> send = 100000;
}
}
if ( arp != NULL )
{
//**************************************************************************
// the data buffer for ICMP messages is allocated dynamically,
// use socket_get_data_pointer() to get the current data pointer
//**************************************************************************
//**************************************************************************
// fill ICMP header
//**************************************************************************
dp[0] = 8; // ICMP request
dp[1] = 0;
dp[2] = 0; // ICMP checksum, must be zero for check sum calculation
dp[3] = 0; // ICMP checksum, must be zero for check sum calculation
dp[4] = 2; // ICMP id
dp[5] = 0; // ICMP id
dp[6] = (++icmp_seq) & 0xff; // ICMP sequence
dp[7] = (icmp_seq>>8) & 0xff; // ICMP sequence
//**************************************************************************
// fill testdate
//**************************************************************************
//~ db[8] .. db[39] // ICMP data
//**************************************************************************
// calculate checksum
//**************************************************************************
chk = get_checksum (dp, 40);
dp[2] = chk & 0xff; // ICMP checksum
dp[3] = (chk>>8) & 0xff; // ICMP checksum
//**************************************************************************
// send ICMP message; send length MUST not exceed 1500 bytes
//**************************************************************************
send_ip (icmp_so, &(arp -> addr), 40, ++ip_id);
}
Examples:
Ping2.c.
int32_t net_send ( SOCKET *  so,
void *  data,
uint16_t  len 
)
Parameters
so- pointer to socket
data- pointer to data, data type as specified in socket_open()
len- length of data
Returns
  • >0 message was send immediately
  • = 0 message could not be delivered immediately, it was passed to protocol stack for delivery, read socket_struct ->error_code for details
  • <0 unrecoverable error

Transmit function for sending UDP or TCP packets. All protocol specific information are generated automatically. net_send() is a non-blocking function. In case of an unknown address (no or invalid ARP cache entry) net_send() starts the address resolution and returns immediately. The data pointer (void *data) is passed to the protocol stack for later transmission. After successful address resolution the stack maintenance function net_isq() will transmit this packet.

Warning
A return value 'true' does NOT guarantee successful transmission
Due to the zero-copy functionality no data is cached. If the data content changes during address resolution, the old data is lost.
Library:
net.lib
Prototype:
net.h
See also
socket_open(), socket_struct ->error_code,
NET_SEND_PENDING, NET_SEND_SUCCESS, NET_SEND_ERROR,
SO_TRANSMIT_ERROR, SO_NO_ARP_ADDRESS, SO_IN_USE, SO_NOT_ESTABLISHED, SO_NOT_OPEN, SO_CONNECTION_CLOSED, SO_WINDOW_ERR, SO_MMU_ERROR, SO_SEND_PENDING, SO_NO_LINK, SO_DNS_ERR
...
//****************************************************************************
// open socket
//****************************************************************************
udp_socket = socket_open (PC_IP_ADDR, // static pc address
PC_PORT, // destination port
DSP_PORT, // source port
DATATYPE_CHAR, // data type char
UDP_INIT_FUNC); // UDP protocol
{
prg_exit ("socket_open() failed");
} // if
...
if ( seconds_old != seconds )
{
//**************************************************************************
// generate a new time stamp each second
//**************************************************************************
udp_data[0] = (hours / 10) + '0';
udp_data[1] = (hours % 10) + '0';
udp_data[2] = ':';
udp_data[3] = (minutes / 10) + '0';
udp_data[4] = (minutes % 10) + '0';
udp_data[5] = ':';
udp_data[6] = (seconds / 10) + '0';
udp_data[7] = (seconds % 10) + '0';
udp_data[8] = '\r';
udp_data[9] = '\n';
udp_data[10] = '\0';
//**************************************************************************
// send time stamp to PC
//**************************************************************************
net_send (udp_socket, // socket
udp_data, // data to send
10); // length of data
}
Examples:
PServer.c, and Send.c.
int32_t net_send_string ( SOCKET *  so,
char *  data 
)

The string can be longer than the maximum packet size. In this case it's broken into several packets by net_send_ready(). This is a blocking function. a return value true does NOT guarantee successful transmission

Parameters
so- pointer to socket
data- pointer to zero terminated data, data type as specified in socket_open()
Returns
Library:
net.lib
Prototype:
net.h
See also
socket_open(), socket_struct ->error_code
SO_TRANSMIT_ERROR, SO_NO_ARP_ADDRESS, SO_IN_USE, SO_NOT_ESTABLISHED, SO_NOT_OPEN, SO_CONNECTION_CLOSED, SO_WINDOW_ERR, SO_MMU_ERROR, SO_SEND_PENDING, SO_NO_LINK, SO_DNS_ERR
char out_of_memory_msg[] = "error: out of memory\r\n";
...
//**************************************************************************
// malloc some space for transmission
// note: the used data buffer for file transmission must be dynamic; it is
// freed automatically after file transmission
//**************************************************************************
buffer = (char *) malloc (1500 * sizeof (char));
if ( buffer == NULL ) // out of memory
{
net_send_string (server, out_of_memory_msg);
ret = FALSE;
}
else
{
//**********************************************************************
// initialize sending
//**********************************************************************
Examples:
SMTP.c, and Telnet.c.
int32_t net_send_ready ( SOCKET *  so,
void *  data,
uint32_t  len,
uint32_t  timeout 
)
Parameters
so- pointer to socket
data- pointer to the data, data type as specified in socket_open()
len- length of data
timeout- timeout for transmission = number of re-tries
Returns

Send a message via the specified socket, wait until message is successfully transmitted or a time out occurred.

Library:
net.lib
Prototype:
net.h
See also
socket_open(), socket_struct ->error_code
SO_TRANSMIT_ERROR, SO_NO_ARP_ADDRESS, SO_IN_USE, SO_NOT_ESTABLISHED, SO_NOT_OPEN, SO_CONNECTION_CLOSED, SO_WINDOW_ERR, SO_MMU_ERROR, SO_SEND_PENDING, SO_NO_LINK, SO_DNS_ERR
unsigned char telnet_option_msg[]= { TELNET_IAC, TELNET_WILL, 1, 0 };
...
//****************************************************************************
//
// @brief send a Telnet option
//
// @param tcp_server - current connection
// @param option - option to send
// @param c - option value
// @return nothing
// @sa net_send_ready() - netlib
//
//****************************************************************************
void send_telnet_option ( SOCKET *tcp_server, unsigned char option, unsigned char c )
{
telnet_option_msg[1] = option;
telnet_option_msg[2] = c;
net_send_ready (tcp_server, telnet_option_msg, 4, 100000);
}
int32_t net_recv ( SOCKET *  so,
void *  data,
uint16_t  maxdatasize 
)
Parameters
so- pointer to socket
data- pointer to receive buffer
maxdatasize- maximum allowed length
Returns
  • > 0 new data received, return value equal to length of received data
  • = 0 nothing received
  • < 0 event occurred that may require further user intervention, read socket_struct ->error_code for specific event

This function returns the number of previously received bytes or in case of errors/events NET_RECV_EVENT (-1). For TCP a connection status change (SO_CONNECTION_RESET, SO_CONNECTION_CLOSED and SO_CONNECTION_ESTABLISHED) is also signalled with NET_RECV_EVENT. If no callback function (socket_define_callback) is installed for this socket, these events have to be cleared by the user to avoid further event/error checking. A special case exists for a TCP socket being closed (SO_CONNECTION_RESET or SO_CONNECTION_CLOSED) while data is received. The connection status change event may cover a final received data packet. Check socket_struct -> in. data_len to determine if data was received with the last packet.

Library:
net.lib
Prototype:
net.h
See also
Error/Event Codes , socket_struct ->error_code, NET_RECV_EVENT
Note
If the Support Function Framework is used, function net_recv_event_handler() can be used to handle all possible events and to determine received data length.

Examples:

return_code = net_recv (tcp_server,
600);
if ( return_code == NET_RECV_EVENT ) // handle event
{
switch ( tcp_server-> error_code & SO_ERROR_MASK )
{
received_len = tcp_server->in.data_len;
// new data received, last packet
so->error_code = 0; // reset error code
break;
}
}
if ( return_code > 0 )
{
// new data received //
received_len = tcp_server->in.data_len;
// alternative: //
// received_len = return_code; //
}
if ( received_len )
{
// new data received, process data
...
received_len = 0;
}

Example using the Support Function Framework

return_code = net_recv (tcp_server,
600);
if ( return_code ) // handle event
{
received_len = net_recv_event_handler (tcp_server, CPrintf); // with messages
// received_len = net_recv_event_handler (tcp_server, NULL); // without messages
if ( received_len )
{
// new data received, process data
...
received_len = 0;
}
}
Examples:
Chat.c, NetTest.c, and SMTP.c.
int32_t set_recv_buffer ( SOCKET *  so,
void *  data,
uint16_t  maxdatasize 
)
Parameters
so- pointer to socket
data- pointer to receive buffer
maxdatasize- maximum allowed length
Returns
  • (1) - success
  • < 0 socket error

Due to the zero-copy functionality net_isq() transfers all data to a user defined buffer. To initialize this buffer use set_recv_buffer().

Library:
net.lib
Prototype:
net.h
//****************************************************************************
// malloc space for data
//****************************************************************************
udp_data = (char *) malloc (MAX_DATA * sizeof(char));
if (udp_data == NULL)
{
return; // out of memory
}
//****************************************************************************
// set receive buffer
//****************************************************************************
Examples:
Chat.c, and SMTP.c.
int32_t net_recv_ready ( SOCKET *  so,
void *  data,
int32_t len,
uint32_t  timeout 
)
Parameters
so- pointer to socket
data- pointer to receive buffer
len- pointer to maximum receive length, returns received data length
timeout- timeout for receive = number of loop count
Returns
  • > 0 success, maximum data length received
  • = 0 success, data received and connection closed
  • < 0 event occurred that may require further user intervention, read socket_struct ->error_code for specific event
See also
Error/Event Codes , socket_struct ->error_code
Library:
net.lib
Prototype:
net.h