Add [08_m1284p_WIZNET_ICMP_aka_ping] prj

This commit is contained in:
maxxir_w
2019-01-18 13:58:49 +04:00
parent 5710a9e18c
commit 3e9f3fac48
17 changed files with 7808 additions and 0 deletions

View 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;
}
}

View 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);

View 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

View File

@@ -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