Project Embedded Systems E-ict Denayer
Dependencies: BSP_DISCO_F746NG F7_Ethernet LCD_DISCO_F746NG TS_DISCO_F746NG mbed-rtos mbed
ping.h
- Committer:
- Ayrton_L
- Date:
- 2017-01-21
- Revision:
- 0:16bcf70d262e
- Child:
- 1:a2f7adf6db3d
File content as of revision 0:16bcf70d262e:
#ifndef _PING_H_ #define _PING_H_ #include "lwip/opt.h" #include "lwip/mem.h" #include "lwip/raw.h" #include "lwip/icmp.h" #include "lwip/netif.h" #include "lwip/sys.h" #include "lwip/timers.h" #include "lwip/inet_chksum.h" #include "lwip/sockets.h" #include "lwip/inet.h" #ifndef PING_RCV_TIMEO //ping timeout... geen antwoord binnen deze tijd => timeout request #define PING_RCV_TIMEO 1000 #endif #ifndef PING_ID #define PING_ID 0x2601 //identifier om te matchen (antwoord matched hiermee. Linux => uniek, Windows => vast, maar wel verschillend per vesrie), subtiele hint 2601 voor beter resultaat? :) #endif #ifndef PING_DATA_SIZE //grootte payload: "random" data die ook gematched moet worden in het antwoord #define PING_DATA_SIZE 32 #endif #ifndef PING_DELAY #define PING_DELAY 500 #endif #ifndef PING_RESULT #define PING_RESULT(ping_ok) #endif static void v_PingOntvang( int32_t l_SocketReturn ); static void v_MaakPingRequest( struct icmp_echo_hdr *x_ICMPEchoHdr, uint16_t us_Lenght ); static err_t ux_Ping( int32_t l_SocketReturn, ip_addr_t *x_IPAddr ); static uint16_t us_PingSequenceNummer; static void v_MaakPingRequest( struct icmp_echo_hdr *x_ICMPEchoHdr, uint16_t us_Lenght ) { int32_t ul_I; int32_t ul_DataLenght; ul_DataLenght = us_Lenght - sizeof( struct icmp_echo_hdr ); ICMPH_TYPE_SET( x_ICMPEchoHdr, ICMP_ECHO ); ICMPH_CODE_SET( x_ICMPEchoHdr, 0 ); x_ICMPEchoHdr->chksum = 0; x_ICMPEchoHdr->id = PING_ID; x_ICMPEchoHdr->seqno = htons( ++us_PingSequenceNummer ); //byte order to netwerk byte order for( ul_I = 0; ul_I < ul_DataLenght; ul_I++ ) //beetje "random" data erin gooien { ( ( char* ) x_ICMPEchoHdr )[sizeof( struct icmp_echo_hdr ) + ul_I] = ( char )ul_I; } x_ICMPEchoHdr->chksum = inet_chksum( x_ICMPEchoHdr, us_Lenght ); } static err_t ux_Ping( int32_t l_SocketReturn, ip_addr_t *x_IPAddr ) //pingske leggen { int32_t l_Err; struct icmp_echo_hdr *x_ICMPEchoHdr; struct sockaddr_in x_VerzendAddr; int32_t l_PingGrootte; l_PingGrootte = sizeof( struct icmp_echo_hdr ) + PING_DATA_SIZE; x_ICMPEchoHdr = ( struct icmp_echo_hdr * ) mem_malloc( ( mem_size_t ) l_PingGrootte ); //mallocske doen, is helaas niet toegelaten volgens mistra C :( //mem_size_t afhankelijk van hoe groot, uint16_t of uint32_t is van type size_t => malloc heeft verwacht size_t => unsigned type if( !x_ICMPEchoHdr ) //heeft ni veel nut dat functie verdergaat en error gooit als Echo failed { return ERR_MEM; //Out Of memory errorke geven } v_MaakPingRequest( x_ICMPEchoHdr, ( uint16_t ) l_PingGrootte ); x_VerzendAddr.sin_len = sizeof( x_VerzendAddr ); x_VerzendAddr.sin_family = AF_INET; inet_addr_from_ipaddr( &x_VerzendAddr.sin_addr, x_IPAddr ); l_Err = lwip_sendto( l_SocketReturn, x_ICMPEchoHdr, l_PingGrootte, 0, ( struct sockaddr* ) &x_VerzendAddr, sizeof( x_VerzendAddr ) ); mem_free( x_ICMPEchoHdr ); return ( l_Err ? ERR_OK : ERR_VAL ); } static void v_PingOntvang( int32_t l_SocketReturn ) { char c_Buffer[64]; uint32_t ul_FromLen; uint32_t ul_RecvLen; struct sockaddr_in x_OntvangAdres; struct ip_hdr *px_IPHdr; struct icmp_echo_hdr *pux_Echo; ip_addr_t x_RecvAddr; ul_RecvLen = lwip_recvfrom( l_SocketReturn, c_Buffer, sizeof( c_Buffer ), 0, ( struct sockaddr* ) &x_OntvangAdres, ( socklen_t* ) &ul_FromLen); while( ul_RecvLen > 0 ) { if( ul_RecvLen >= sizeof( struct ip_hdr ) + sizeof( struct icmp_echo_hdr ) ); { inet_addr_to_ipaddr(&x_RecvAddr, &x_OntvangAdres.sin_addr); px_IPHdr = ( struct ip_hdr * ) c_Buffer; pux_Echo = ( struct icmp_echo_hdr * ) ( c_Buffer + ( IPH_HL( px_IPHdr ) * 4)); if( ( pux_Echo->id == PING_ID ) && ( pux_Echo->seqno == htons( us_PingSequenceNummer ) ) ) //matchen van data, byte order naar netwerk byte order { PING_RESULT( ( ICMPH_TYPE( iecho ) == ICMP_ER ) ); //ping resultaat processen return; } } ul_RecvLen = lwip_recvfrom( l_SocketReturn, c_Buffer, sizeof( c_Buffer ), 0, ( struct sockaddr* ) &x_OntvangAdres, ( socklen_t* ) &ul_FromLen ); } PING_RESULT( 0 ); //ping resultaat processen } void v_Ping( void ) { int32_t l_SocketReturn; //vooral om te kunnen debuggen binnen LWIP, sockets.c ... -1 on fail uint32_t ul_TimeOut; l_SocketReturn = lwip_socket( AF_INET, SOCK_RAW, IP_PROTO_ICMP ); ul_TimeOut = PING_RCV_TIMEO; if( l_SocketReturn > -1 ) { lwip_setsockopt( l_SocketReturn, SOL_SOCKET, SO_RCVTIMEO, &ul_TimeOut, sizeof( ul_TimeOut ) ); while ( 1 ) { ip_addr_t x_PingTarget = { 0x08080808 }; //Google DNS server, uptime 99.9% => vrij betrouwbaar om naar heen te pingen. Behalve in landen zoals DPRK if ( ux_Ping( l_SocketReturn, &x_PingTarget ) == ERR_OK ) { v_PingOntvang( l_SocketReturn ); } sys_msleep( PING_DELAY ); } } } #endif