Add [08_m1284p_WIZNET_ICMP_aka_ping] prj
This commit is contained in:
370
08_m1284p_WIZNET_ICMP_aka_ping/Application/PING/ping.c
Normal file
370
08_m1284p_WIZNET_ICMP_aka_ping/Application/PING/ping.c
Normal file
@@ -0,0 +1,370 @@
|
||||
#include <stdio.h>
|
||||
#include "ping.h"
|
||||
#include "socket.h"
|
||||
#include <util/delay.h>
|
||||
|
||||
#ifndef Sn_PROTO
|
||||
#define Sn_PROTO(N) (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
|
||||
#endif
|
||||
|
||||
PINGMSGR PingRequest; // Variable for Ping Request
|
||||
PINGMSGR PingReply; // Variable for Ping Reply
|
||||
static uint16_t RandomID = 0x1234;
|
||||
static uint16_t RandomSeqNum = 0x4321;
|
||||
|
||||
void wait_1ms(unsigned int cnt);
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t ping_request(uint8_t s, uint8_t *addr){
|
||||
uint16_t i;
|
||||
|
||||
/* make header of the ping-request */
|
||||
PingRequest.Type = PING_REQUEST; // Ping-Request
|
||||
PingRequest.Code = CODE_ZERO; // Always '0'
|
||||
PingRequest.ID = htons(RandomID++); // set ping-request's ID to random integer value
|
||||
PingRequest.SeqNum =htons(RandomSeqNum++);// set ping-request's sequence number to ramdom integer value
|
||||
//size = 32; // set Data size
|
||||
|
||||
/* Fill in Data[] as size of BIF_LEN (Default = 32)*/
|
||||
for(i = 0 ; i < PING_BUF_LEN; i++){
|
||||
PingRequest.Data[i] = (i) % 8; //'0'~'8' number into ping-request's data
|
||||
}
|
||||
/* Do checksum of Ping Request */
|
||||
PingRequest.CheckSum = 0; // value of checksum before calucating checksum of ping-request packet
|
||||
PingRequest.CheckSum = htons(checksum((uint8_t*)&PingRequest,(uint16_t)(sizeof(PingRequest)-PING_BUF_LEN))); // Calculate checksum
|
||||
|
||||
/* sendto ping_request to destination */
|
||||
if(sendto(s,(uint8_t *)&PingRequest,(uint16_t)(sizeof(PingRequest)-PING_BUF_LEN),addr,3000)==0){ // Send Ping-Request to the specified peer.
|
||||
#ifdef PING_DEBUG
|
||||
printf( "\r\n Fail to send ping-request packet r\n");
|
||||
|
||||
#endif
|
||||
}else{
|
||||
#ifdef PING_DEBUG
|
||||
printf( "Send Ping Request to Destination (");
|
||||
printf( "%d.%d.%d.%d )",
|
||||
(int16_t) addr[0],
|
||||
(int16_t) addr[1],
|
||||
(int16_t) addr[2],
|
||||
(int16_t) addr[3]);
|
||||
printf( " ID:%x SeqNum:%x CheckSum:%x\r\n",
|
||||
htons(PingRequest.ID),
|
||||
htons(PingRequest.SeqNum),
|
||||
htons(PingRequest.CheckSum)) ;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
} // ping request
|
||||
|
||||
|
||||
uint16_t checksum(uint8_t * data_buf, uint16_t len)
|
||||
{
|
||||
uint16_t sum, tsum, i, j;
|
||||
uint32_t lsum;
|
||||
|
||||
j = len >> 1;
|
||||
lsum = 0;
|
||||
tsum = 0;
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
tsum = data_buf[i * 2];
|
||||
tsum = tsum << 8;
|
||||
tsum += data_buf[i * 2 + 1];
|
||||
lsum += tsum;
|
||||
}
|
||||
if (len % 2)
|
||||
{
|
||||
tsum = data_buf[i * 2];
|
||||
lsum += (tsum << 8);
|
||||
}
|
||||
sum = (uint16_t)lsum;
|
||||
sum = ~(sum + (lsum >> 16));
|
||||
return sum;
|
||||
|
||||
}
|
||||
|
||||
//!!Comment this line for STM8
|
||||
#define LITTLE_ENDIAN // for STM32, ATMEGA
|
||||
|
||||
uint16_t htons( uint16_t hostshort)
|
||||
{
|
||||
#ifdef LITTLE_ENDIAN
|
||||
uint16_t netshort=0;
|
||||
netshort = (hostshort & 0xFF) << 8;
|
||||
|
||||
netshort |= ((hostshort >> 8)& 0xFF);
|
||||
return netshort;
|
||||
#else
|
||||
return hostshort;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
Function name: wait_1us
|
||||
Input : cnt; Delay duration = cnt * 1u seconds
|
||||
Output : non
|
||||
Description
|
||||
: A delay function for waiting cnt*1u second.
|
||||
*****************************************************************************************/
|
||||
void wait_1us(unsigned int cnt)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i = 0; i<cnt; i++) {
|
||||
/*
|
||||
nop();
|
||||
nop();
|
||||
nop();
|
||||
nop();
|
||||
*/
|
||||
_delay_us(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************************
|
||||
Function name: wait_1ms
|
||||
Input : cnt; Delay duration = cnt * 1m seconds
|
||||
Output : non
|
||||
Description
|
||||
: A delay function for waiting cnt*1m second. This function use wait_1us but the wait_1us
|
||||
has some error (not accurate). So if you want exact time delay, please use the Timer.
|
||||
*****************************************************************************************/
|
||||
void wait_1ms(unsigned int cnt)
|
||||
{
|
||||
unsigned int i;
|
||||
//for (i = 0; i < cnt; i++) wait_1us(1000);
|
||||
for (i = 0; i < cnt; i++) _delay_ms(1);
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
Function name: wait_10ms
|
||||
Input : cnt; Delay duration = cnt * 10m seconds
|
||||
Output : non
|
||||
Description
|
||||
: A delay function for waiting cnt*10m second. This function use wait_1ms but the wait_1ms
|
||||
has some error (not accurate more than wait_1us). So if you want exact time delay,
|
||||
please use the Timer.
|
||||
*****************************************************************************************/
|
||||
void wait_10ms(unsigned int cnt)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < cnt; i++) wait_1ms(10);
|
||||
}
|
||||
|
||||
uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t len){
|
||||
|
||||
//uint16_t i;
|
||||
|
||||
PingReply.Type = PING_REPLY; // Ping-Reply
|
||||
/* make header of the ping-request */
|
||||
/*
|
||||
//PingRequest.Type = PING_REQUEST; // Ping-Request
|
||||
PingRequest.Type = PING_REPLY; // Ping-Reply
|
||||
//PingRequest.ID = htons(RandomID++); // set ping-request's ID to random integer value
|
||||
//PingRequest.SeqNum =htons(RandomSeqNum++);// set ping-request's sequence number to ramdom integer value
|
||||
PingRequest.ID = id;
|
||||
PingRequest.SeqNum = seq;
|
||||
//size = 32; // set Data size
|
||||
*/
|
||||
/* Fill in Data[] as size of BIF_LEN (Default = 32)*/
|
||||
/*
|
||||
for(i = 0 ; i < PING_BUF_LEN; i++){
|
||||
PingRequest.Data[i] = (i) % 8; //'0'~'8' number into ping-request's data
|
||||
}
|
||||
*/
|
||||
/* Do checksum of Ping Request */
|
||||
PingReply.CheckSum = 0; // value of checksum before calucating checksum of ping-request packet
|
||||
PingReply.CheckSum = htons(checksum((uint8_t*)&PingReply,len)); // Calculate checksum
|
||||
|
||||
/*
|
||||
PingRequest.CheckSum = 0; // value of checksum before calucating checksum of ping-request packet
|
||||
PingRequest.CheckSum = htons(checksum((uint8_t*)&PingRequest,sizeof(PingRequest))); // Calculate checksum
|
||||
*/
|
||||
/* sendto ping_request to destination */
|
||||
// if(sendto(s,(uint8_t *)&PingRequest,sizeof(PingRequest),addr,3000)==0){ // Send Ping-Request to the specified peer.
|
||||
if(sendto(s,(uint8_t *)&PingReply,len,addr,3000)==0){ // Send Ping-Request to the specified peer.
|
||||
#ifdef PING_DEBUG
|
||||
printf( "\r\n Fail to send ping-reply packet r\n");
|
||||
|
||||
#endif
|
||||
}else{
|
||||
#ifdef PING_DEBUG
|
||||
printf( "Send Ping Reply to Destination (");
|
||||
printf( "%d.%d.%d.%d )",
|
||||
(int16_t) addr[0],
|
||||
(int16_t) addr[1],
|
||||
(int16_t) addr[2],
|
||||
(int16_t) addr[3]);
|
||||
printf( " ID:%x SeqNum:%x CheckSum:%x\r\n",
|
||||
/*
|
||||
PingRequest.ID,
|
||||
PingRequest.SeqNum,
|
||||
PingRequest.CheckSum) ;
|
||||
*/
|
||||
PingReply.ID,
|
||||
PingReply.SeqNum,
|
||||
htons(PingReply.CheckSum)) ;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
} // ping request
|
||||
|
||||
void ping_read(uint8_t s, uint8_t *addr, uint16_t rlen)
|
||||
{
|
||||
//uint16_t tmp_checksum;
|
||||
uint16_t len;
|
||||
uint16_t i;
|
||||
uint8_t data_buf[128];
|
||||
uint16_t port = 3000;
|
||||
/* receive data from a destination */
|
||||
len = recvfrom(s, (uint8_t *)data_buf,rlen,addr,&port);
|
||||
//printf(">>rlen: %u, len: %u\r\n", rlen, len);
|
||||
if(data_buf[0] == PING_REPLY)
|
||||
{
|
||||
PingReply.Type = data_buf[0];
|
||||
PingReply.Code = data_buf[1];
|
||||
PingReply.CheckSum = (data_buf[3]<<8) + data_buf[2];
|
||||
PingReply.ID = (data_buf[5]<<8) + data_buf[4];
|
||||
PingReply.SeqNum = (data_buf[7]<<8) + data_buf[6];
|
||||
|
||||
for(i=0; i<len-8 ; i++)
|
||||
{
|
||||
PingReply.Data[i] = data_buf[8+i];
|
||||
}
|
||||
//CRC ICMP computation here is useful
|
||||
/*
|
||||
// check Checksum of Ping Reply
|
||||
tmp_checksum = ~checksum(data_buf,len);
|
||||
if(tmp_checksum != 0xffff) {
|
||||
#ifdef PING_DEBUG
|
||||
printf( "tmp_checksum = %x\r\n",tmp_checksum);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*/
|
||||
if(1)
|
||||
{
|
||||
/* Output the Destination IP and the size of the Ping Reply Message*/
|
||||
#ifdef PING_DEBUG
|
||||
printf(
|
||||
"PING Reply from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n",
|
||||
(int16_t) addr[0],
|
||||
(int16_t) addr[1],
|
||||
(int16_t) addr[2],
|
||||
(int16_t) addr[3],
|
||||
htons(PingReply.ID), htons(PingReply.SeqNum),
|
||||
(int16_t) (len+6));
|
||||
printf("\r\n");
|
||||
#endif
|
||||
//Fire call-buck function
|
||||
icmp_cb(s, addr, PingReply.Type, PingReply.ID, PingReply.SeqNum, len-8);
|
||||
}
|
||||
}
|
||||
else if(data_buf[0] == PING_REQUEST)
|
||||
{
|
||||
PingReply.Type = data_buf[0];
|
||||
PingReply.Code = data_buf[1];
|
||||
PingReply.CheckSum = (data_buf[3]<<8) + data_buf[2];
|
||||
PingReply.ID = (data_buf[5]<<8) + data_buf[4];
|
||||
PingReply.SeqNum = (data_buf[7]<<8) + data_buf[6];
|
||||
|
||||
for(i=0; i<len-8 ; i++)
|
||||
{
|
||||
PingReply.Data[i] = data_buf[8+i];
|
||||
}
|
||||
|
||||
/* Output the Destination IP and the size of the Ping Reply Message*/
|
||||
#ifdef PING_DEBUG
|
||||
printf( "\r\nPING Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n",
|
||||
(int16_t) addr[0],
|
||||
(int16_t) addr[1],
|
||||
(int16_t) addr[2],
|
||||
(int16_t) addr[3],
|
||||
(PingReply.ID),
|
||||
(PingReply.SeqNum),
|
||||
(int16_t)(len+6));
|
||||
#endif
|
||||
|
||||
#ifdef PING_DEBUG
|
||||
//CRC ICMP computation here actually is useful
|
||||
/* check Checksum of Ping Reply var.1*/
|
||||
tmp_checksum = PingReply.CheckSum;
|
||||
PingReply.CheckSum = 0;
|
||||
PingReply.CheckSum = htons(checksum((uint8_t *) &PingReply,len));
|
||||
|
||||
if(tmp_checksum != PingReply.CheckSum){
|
||||
printf( "--CRC is ERROR %x should be %x \n",
|
||||
tmp_checksum,
|
||||
htons(PingReply.CheckSum)) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "++CRC is OK\r\n") ;
|
||||
}
|
||||
#endif
|
||||
/* check Checksum of Ping Reply added by maxxir var.2*/
|
||||
/*
|
||||
#ifdef PING_DEBUG
|
||||
tmp_checksum = ~checksum(data_buf,len);
|
||||
if(tmp_checksum != 0xffff) {
|
||||
printf( "--crc is error= %x\r\n",tmp_checksum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "++crc is ok\r\n");
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
//Fire call-buck function
|
||||
icmp_cb(s, addr, PingReply.Type, PingReply.ID, PingReply.SeqNum, len-8);
|
||||
//Send ping REPLY to PING REQUEST to addr
|
||||
ping_reply(s, addr, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PING_DEBUG
|
||||
printf(" Unkonwn ICMP type msg:%u\n", data_buf[0]);
|
||||
#endif
|
||||
}
|
||||
}// ping_read
|
||||
|
||||
void ping_srv(uint8_t s)
|
||||
{
|
||||
int32_t len = 0;
|
||||
uint8_t dest_ip[4] = { 0, 0, 0, 0 };
|
||||
switch(getSn_SR(s))
|
||||
{
|
||||
case SOCK_CLOSED:
|
||||
close(s);
|
||||
// set ICMP Protocol
|
||||
IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP);
|
||||
// open the SOCKET with IPRAW mode,
|
||||
if(socket(s,Sn_MR_IPRAW,3000,0)!=s){
|
||||
//if fail then Error
|
||||
printf("\r\n socket %d fail r\n",s);
|
||||
return;
|
||||
}
|
||||
/* Check socket register */
|
||||
while(getSn_SR(s)!=SOCK_IPRAW);
|
||||
//wait_1ms(100); // wait 100ms
|
||||
_delay_us(1000); // wait 1 ms
|
||||
printf("%d:Opened, IPRAW mode (ICMP ping)\r\n",s);
|
||||
break;
|
||||
case SOCK_IPRAW:
|
||||
|
||||
//Check if IPRAW socket have RX data
|
||||
if ( (len = getSn_RX_RSR(s) ) > 0)
|
||||
{
|
||||
//Yes, RX data is present
|
||||
ping_read(s, dest_ip, len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
47
08_m1284p_WIZNET_ICMP_aka_ping/Application/PING/ping.h
Normal file
47
08_m1284p_WIZNET_ICMP_aka_ping/Application/PING/ping.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "wizchip_conf.h"
|
||||
|
||||
#define PING_BUF_LEN 32
|
||||
#define PING_REQUEST 8
|
||||
#define PING_REPLY 0
|
||||
#define CODE_ZERO 0
|
||||
|
||||
#define SOCKET_ERROR 1
|
||||
#define TIMEOUT_ERROR 2
|
||||
#define SUCCESS 3
|
||||
#define REPLY_ERROR 4
|
||||
|
||||
|
||||
//#define PING_DEBUG
|
||||
|
||||
|
||||
typedef struct pingmsg
|
||||
{
|
||||
uint8_t Type; // 0 - Ping Reply, 8 - Ping Request
|
||||
uint8_t Code; // Always 0
|
||||
int16_t CheckSum; // Check sum
|
||||
int16_t ID; // Identification
|
||||
int16_t SeqNum; // Sequence Number
|
||||
int8_t Data[PING_BUF_LEN*2];// Ping Data : 1452 = IP RAW MTU - sizeof(Type+Code+CheckSum+ID+SeqNum)
|
||||
} PINGMSGR;
|
||||
|
||||
void ping_srv(uint8_t s);
|
||||
uint8_t ping_request(uint8_t s, uint8_t *addr);
|
||||
uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t len);
|
||||
uint16_t checksum(uint8_t * data_buf, uint16_t len);
|
||||
uint16_t htons( uint16_t hostshort); /* htons function converts a unsigned short from host to TCP/IP network byte order (which is big-endian).*/
|
||||
|
||||
//ICMP callback (fire on ICMP request/reply from ping_srv), must be realize somewhere on main.c etc..
|
||||
/*
|
||||
* socket - socket number
|
||||
* ip_query - IP from which ICMP query (like 192.168.0.x)
|
||||
* type_query - ICMP query type: PING_REQUEST or PING_REPLY
|
||||
* id_query - ICMP query Identificator: ID ICMP [0..0xFFFF]
|
||||
* seq_query - ICMP query Sequence Number : ID Seq num [0..0xFFFF]
|
||||
* len_query - ICMP query length of the data
|
||||
*/
|
||||
extern void icmp_cb(uint8_t socket,\
|
||||
uint8_t* ip_query,\
|
||||
uint8_t type_query,\
|
||||
uint16_t id_query,\
|
||||
uint16_t seq_query,\
|
||||
uint16_t len_query);
|
||||
225
08_m1284p_WIZNET_ICMP_aka_ping/Application/loopback/loopback.c
Normal file
225
08_m1284p_WIZNET_ICMP_aka_ping/Application/loopback/loopback.c
Normal file
@@ -0,0 +1,225 @@
|
||||
#include <stdio.h>
|
||||
#include "loopback.h"
|
||||
#include "socket.h"
|
||||
#include "wizchip_conf.h"
|
||||
|
||||
#if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK
|
||||
|
||||
int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port)
|
||||
{
|
||||
int32_t ret;
|
||||
uint16_t size = 0, sentsize=0;
|
||||
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
uint8_t destip[4];
|
||||
uint16_t destport;
|
||||
#endif
|
||||
|
||||
switch(getSn_SR(sn))
|
||||
{
|
||||
case SOCK_ESTABLISHED :
|
||||
if(getSn_IR(sn) & Sn_IR_CON)
|
||||
{
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
getSn_DIPR(sn, destip);
|
||||
destport = getSn_DPORT(sn);
|
||||
|
||||
printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);
|
||||
#endif
|
||||
setSn_IR(sn,Sn_IR_CON);
|
||||
}
|
||||
if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur.
|
||||
{
|
||||
if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
|
||||
ret = recv(sn, buf, size);
|
||||
|
||||
if(ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
|
||||
size = (uint16_t) ret;
|
||||
sentsize = 0;
|
||||
|
||||
while(size != sentsize)
|
||||
{
|
||||
ret = send(sn, buf+sentsize, size-sentsize);
|
||||
if(ret < 0)
|
||||
{
|
||||
close(sn);
|
||||
return ret;
|
||||
}
|
||||
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SOCK_CLOSE_WAIT :
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
//printf("%d:CloseWait\r\n",sn);
|
||||
#endif
|
||||
if((ret = disconnect(sn)) != SOCK_OK) return ret;
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
printf("%d:Socket Closed\r\n", sn);
|
||||
#endif
|
||||
break;
|
||||
case SOCK_INIT :
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
printf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port);
|
||||
#endif
|
||||
if( (ret = listen(sn)) != SOCK_OK) return ret;
|
||||
break;
|
||||
case SOCK_CLOSED:
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
//printf("%d:TCP server loopback start\r\n",sn);
|
||||
#endif
|
||||
if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret;
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
//printf("%d:Socket opened\r\n",sn);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport)
|
||||
{
|
||||
int32_t ret; // return value for SOCK_ERRORs
|
||||
uint16_t size = 0, sentsize=0;
|
||||
|
||||
// Destination (TCP Server) IP info (will be connected)
|
||||
// >> loopback_tcpc() function parameter
|
||||
// >> Ex)
|
||||
// uint8_t destip[4] = {192, 168, 0, 214};
|
||||
// uint16_t destport = 5000;
|
||||
|
||||
// Port number for TCP client (will be increased)
|
||||
static uint16_t any_port = 50000;
|
||||
|
||||
// Socket Status Transitions
|
||||
// Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status)
|
||||
switch(getSn_SR(sn))
|
||||
{
|
||||
case SOCK_ESTABLISHED :
|
||||
if(getSn_IR(sn) & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
|
||||
{
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);
|
||||
#endif
|
||||
setSn_IR(sn, Sn_IR_CON); // this interrupt should be write the bit cleared to '1'
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data Transaction Parts; Handle the [data receive and send] process
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
|
||||
{
|
||||
if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
|
||||
ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
|
||||
|
||||
if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end
|
||||
size = (uint16_t) ret;
|
||||
sentsize = 0;
|
||||
|
||||
// Data sentsize control
|
||||
while(size != sentsize)
|
||||
{
|
||||
ret = send(sn, buf+sentsize, size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
|
||||
if(ret < 0) // Send Error occurred (sent data length < 0)
|
||||
{
|
||||
close(sn); // socket close
|
||||
return ret;
|
||||
}
|
||||
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
break;
|
||||
|
||||
case SOCK_CLOSE_WAIT :
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
//printf("%d:CloseWait\r\n",sn);
|
||||
#endif
|
||||
if((ret=disconnect(sn)) != SOCK_OK) return ret;
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
printf("%d:Socket Closed\r\n", sn);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SOCK_INIT :
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
|
||||
#endif
|
||||
if( (ret = connect(sn, destip, destport)) != SOCK_OK) return ret; // Try to TCP connect to the TCP server (destination)
|
||||
break;
|
||||
|
||||
case SOCK_CLOSED:
|
||||
close(sn);
|
||||
if((ret=socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn){
|
||||
if(any_port == 0xffff) any_port = 50000;
|
||||
return ret; // TCP socket open with 'any_port' port number
|
||||
}
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
//printf("%d:TCP client loopback start\r\n",sn);
|
||||
//printf("%d:Socket opened\r\n",sn);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port)
|
||||
{
|
||||
int32_t ret;
|
||||
uint16_t size, sentsize;
|
||||
uint8_t destip[4];
|
||||
uint16_t destport;
|
||||
|
||||
switch(getSn_SR(sn))
|
||||
{
|
||||
case SOCK_UDP :
|
||||
if((size = getSn_RX_RSR(sn)) > 0)
|
||||
{
|
||||
if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
|
||||
ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport);
|
||||
if(ret <= 0)
|
||||
{
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
printf("%d: recvfrom error. %ld\r\n",sn,ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
size = (uint16_t) ret;
|
||||
sentsize = 0;
|
||||
while(sentsize != size)
|
||||
{
|
||||
ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport);
|
||||
if(ret < 0)
|
||||
{
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
printf("%d: sendto error. %ld\r\n",sn,ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SOCK_CLOSED:
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
//printf("%d:UDP loopback start\r\n",sn);
|
||||
#endif
|
||||
if((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn)
|
||||
return ret;
|
||||
#ifdef _LOOPBACK_DEBUG_
|
||||
printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port);
|
||||
#endif
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef _LOOPBACK_H_
|
||||
#define _LOOPBACK_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Loopback test debug message printout enable */
|
||||
#define _LOOPBACK_DEBUG_
|
||||
|
||||
/* DATA_BUF_SIZE define for Loopback example */
|
||||
#ifndef DATA_BUF_SIZE
|
||||
#define DATA_BUF_SIZE 2048
|
||||
#endif
|
||||
|
||||
/************************/
|
||||
/* Select LOOPBACK_MODE */
|
||||
/************************/
|
||||
#define LOOPBACK_MAIN_NOBLOCK 0
|
||||
#define LOOPBACK_MODE LOOPBACK_MAIN_NOBLOCK
|
||||
|
||||
|
||||
/* TCP server Loopback test example */
|
||||
int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port);
|
||||
|
||||
/* TCP client Loopback test example */
|
||||
int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport);
|
||||
|
||||
/* UDP Loopback test example */
|
||||
int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user