Project Embedded Systems E-ict Denayer
Dependencies: BSP_DISCO_F746NG F7_Ethernet LCD_DISCO_F746NG TS_DISCO_F746NG mbed-rtos mbed
ping.h@0:16bcf70d262e, 2017-01-21 (annotated)
- Committer:
- Ayrton_L
- Date:
- Sat Jan 21 23:05:11 2017 +0000
- Revision:
- 0:16bcf70d262e
- Child:
- 1:a2f7adf6db3d
First up
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Ayrton_L | 0:16bcf70d262e | 1 | #ifndef _PING_H_ |
Ayrton_L | 0:16bcf70d262e | 2 | #define _PING_H_ |
Ayrton_L | 0:16bcf70d262e | 3 | |
Ayrton_L | 0:16bcf70d262e | 4 | #include "lwip/opt.h" |
Ayrton_L | 0:16bcf70d262e | 5 | #include "lwip/mem.h" |
Ayrton_L | 0:16bcf70d262e | 6 | #include "lwip/raw.h" |
Ayrton_L | 0:16bcf70d262e | 7 | #include "lwip/icmp.h" |
Ayrton_L | 0:16bcf70d262e | 8 | #include "lwip/netif.h" |
Ayrton_L | 0:16bcf70d262e | 9 | #include "lwip/sys.h" |
Ayrton_L | 0:16bcf70d262e | 10 | #include "lwip/timers.h" |
Ayrton_L | 0:16bcf70d262e | 11 | #include "lwip/inet_chksum.h" |
Ayrton_L | 0:16bcf70d262e | 12 | #include "lwip/sockets.h" |
Ayrton_L | 0:16bcf70d262e | 13 | #include "lwip/inet.h" |
Ayrton_L | 0:16bcf70d262e | 14 | |
Ayrton_L | 0:16bcf70d262e | 15 | #ifndef PING_RCV_TIMEO //ping timeout... geen antwoord binnen deze tijd => timeout request |
Ayrton_L | 0:16bcf70d262e | 16 | #define PING_RCV_TIMEO 1000 |
Ayrton_L | 0:16bcf70d262e | 17 | #endif |
Ayrton_L | 0:16bcf70d262e | 18 | |
Ayrton_L | 0:16bcf70d262e | 19 | #ifndef PING_ID |
Ayrton_L | 0:16bcf70d262e | 20 | #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? :) |
Ayrton_L | 0:16bcf70d262e | 21 | #endif |
Ayrton_L | 0:16bcf70d262e | 22 | |
Ayrton_L | 0:16bcf70d262e | 23 | #ifndef PING_DATA_SIZE //grootte payload: "random" data die ook gematched moet worden in het antwoord |
Ayrton_L | 0:16bcf70d262e | 24 | #define PING_DATA_SIZE 32 |
Ayrton_L | 0:16bcf70d262e | 25 | #endif |
Ayrton_L | 0:16bcf70d262e | 26 | |
Ayrton_L | 0:16bcf70d262e | 27 | #ifndef PING_DELAY |
Ayrton_L | 0:16bcf70d262e | 28 | #define PING_DELAY 500 |
Ayrton_L | 0:16bcf70d262e | 29 | #endif |
Ayrton_L | 0:16bcf70d262e | 30 | |
Ayrton_L | 0:16bcf70d262e | 31 | #ifndef PING_RESULT |
Ayrton_L | 0:16bcf70d262e | 32 | #define PING_RESULT(ping_ok) |
Ayrton_L | 0:16bcf70d262e | 33 | #endif |
Ayrton_L | 0:16bcf70d262e | 34 | |
Ayrton_L | 0:16bcf70d262e | 35 | static void v_PingOntvang( int32_t l_SocketReturn ); |
Ayrton_L | 0:16bcf70d262e | 36 | static void v_MaakPingRequest( struct icmp_echo_hdr *x_ICMPEchoHdr, uint16_t us_Lenght ); |
Ayrton_L | 0:16bcf70d262e | 37 | static err_t ux_Ping( int32_t l_SocketReturn, ip_addr_t *x_IPAddr ); |
Ayrton_L | 0:16bcf70d262e | 38 | static uint16_t us_PingSequenceNummer; |
Ayrton_L | 0:16bcf70d262e | 39 | |
Ayrton_L | 0:16bcf70d262e | 40 | static void v_MaakPingRequest( struct icmp_echo_hdr *x_ICMPEchoHdr, uint16_t us_Lenght ) |
Ayrton_L | 0:16bcf70d262e | 41 | { |
Ayrton_L | 0:16bcf70d262e | 42 | int32_t ul_I; |
Ayrton_L | 0:16bcf70d262e | 43 | int32_t ul_DataLenght; |
Ayrton_L | 0:16bcf70d262e | 44 | ul_DataLenght = us_Lenght - sizeof( struct icmp_echo_hdr ); |
Ayrton_L | 0:16bcf70d262e | 45 | |
Ayrton_L | 0:16bcf70d262e | 46 | ICMPH_TYPE_SET( x_ICMPEchoHdr, ICMP_ECHO ); |
Ayrton_L | 0:16bcf70d262e | 47 | ICMPH_CODE_SET( x_ICMPEchoHdr, 0 ); |
Ayrton_L | 0:16bcf70d262e | 48 | x_ICMPEchoHdr->chksum = 0; |
Ayrton_L | 0:16bcf70d262e | 49 | x_ICMPEchoHdr->id = PING_ID; |
Ayrton_L | 0:16bcf70d262e | 50 | x_ICMPEchoHdr->seqno = htons( ++us_PingSequenceNummer ); //byte order to netwerk byte order |
Ayrton_L | 0:16bcf70d262e | 51 | |
Ayrton_L | 0:16bcf70d262e | 52 | for( ul_I = 0; ul_I < ul_DataLenght; ul_I++ ) //beetje "random" data erin gooien |
Ayrton_L | 0:16bcf70d262e | 53 | { |
Ayrton_L | 0:16bcf70d262e | 54 | ( ( char* ) x_ICMPEchoHdr )[sizeof( struct icmp_echo_hdr ) + ul_I] = ( char )ul_I; |
Ayrton_L | 0:16bcf70d262e | 55 | } |
Ayrton_L | 0:16bcf70d262e | 56 | |
Ayrton_L | 0:16bcf70d262e | 57 | x_ICMPEchoHdr->chksum = inet_chksum( x_ICMPEchoHdr, us_Lenght ); |
Ayrton_L | 0:16bcf70d262e | 58 | } |
Ayrton_L | 0:16bcf70d262e | 59 | |
Ayrton_L | 0:16bcf70d262e | 60 | static err_t ux_Ping( int32_t l_SocketReturn, ip_addr_t *x_IPAddr ) //pingske leggen |
Ayrton_L | 0:16bcf70d262e | 61 | { |
Ayrton_L | 0:16bcf70d262e | 62 | int32_t l_Err; |
Ayrton_L | 0:16bcf70d262e | 63 | struct icmp_echo_hdr *x_ICMPEchoHdr; |
Ayrton_L | 0:16bcf70d262e | 64 | struct sockaddr_in x_VerzendAddr; |
Ayrton_L | 0:16bcf70d262e | 65 | int32_t l_PingGrootte; |
Ayrton_L | 0:16bcf70d262e | 66 | |
Ayrton_L | 0:16bcf70d262e | 67 | l_PingGrootte = sizeof( struct icmp_echo_hdr ) + PING_DATA_SIZE; |
Ayrton_L | 0:16bcf70d262e | 68 | x_ICMPEchoHdr = ( struct icmp_echo_hdr * ) mem_malloc( ( mem_size_t ) l_PingGrootte ); //mallocske doen, is helaas niet toegelaten volgens mistra C :( |
Ayrton_L | 0:16bcf70d262e | 69 | //mem_size_t afhankelijk van hoe groot, uint16_t of uint32_t is van type size_t => malloc heeft verwacht size_t => unsigned type |
Ayrton_L | 0:16bcf70d262e | 70 | if( !x_ICMPEchoHdr ) //heeft ni veel nut dat functie verdergaat en error gooit als Echo failed |
Ayrton_L | 0:16bcf70d262e | 71 | { |
Ayrton_L | 0:16bcf70d262e | 72 | return ERR_MEM; //Out Of memory errorke geven |
Ayrton_L | 0:16bcf70d262e | 73 | } |
Ayrton_L | 0:16bcf70d262e | 74 | |
Ayrton_L | 0:16bcf70d262e | 75 | v_MaakPingRequest( x_ICMPEchoHdr, ( uint16_t ) l_PingGrootte ); |
Ayrton_L | 0:16bcf70d262e | 76 | |
Ayrton_L | 0:16bcf70d262e | 77 | x_VerzendAddr.sin_len = sizeof( x_VerzendAddr ); |
Ayrton_L | 0:16bcf70d262e | 78 | x_VerzendAddr.sin_family = AF_INET; |
Ayrton_L | 0:16bcf70d262e | 79 | inet_addr_from_ipaddr( &x_VerzendAddr.sin_addr, x_IPAddr ); |
Ayrton_L | 0:16bcf70d262e | 80 | l_Err = lwip_sendto( l_SocketReturn, x_ICMPEchoHdr, l_PingGrootte, 0, ( struct sockaddr* ) &x_VerzendAddr, sizeof( x_VerzendAddr ) ); |
Ayrton_L | 0:16bcf70d262e | 81 | |
Ayrton_L | 0:16bcf70d262e | 82 | mem_free( x_ICMPEchoHdr ); |
Ayrton_L | 0:16bcf70d262e | 83 | |
Ayrton_L | 0:16bcf70d262e | 84 | return ( l_Err ? ERR_OK : ERR_VAL ); |
Ayrton_L | 0:16bcf70d262e | 85 | } |
Ayrton_L | 0:16bcf70d262e | 86 | |
Ayrton_L | 0:16bcf70d262e | 87 | static void v_PingOntvang( int32_t l_SocketReturn ) |
Ayrton_L | 0:16bcf70d262e | 88 | { |
Ayrton_L | 0:16bcf70d262e | 89 | char c_Buffer[64]; |
Ayrton_L | 0:16bcf70d262e | 90 | uint32_t ul_FromLen; |
Ayrton_L | 0:16bcf70d262e | 91 | uint32_t ul_RecvLen; |
Ayrton_L | 0:16bcf70d262e | 92 | struct sockaddr_in x_OntvangAdres; |
Ayrton_L | 0:16bcf70d262e | 93 | struct ip_hdr *px_IPHdr; |
Ayrton_L | 0:16bcf70d262e | 94 | struct icmp_echo_hdr *pux_Echo; |
Ayrton_L | 0:16bcf70d262e | 95 | ip_addr_t x_RecvAddr; |
Ayrton_L | 0:16bcf70d262e | 96 | |
Ayrton_L | 0:16bcf70d262e | 97 | ul_RecvLen = lwip_recvfrom( l_SocketReturn, c_Buffer, sizeof( c_Buffer ), 0, ( struct sockaddr* ) &x_OntvangAdres, ( socklen_t* ) &ul_FromLen); |
Ayrton_L | 0:16bcf70d262e | 98 | |
Ayrton_L | 0:16bcf70d262e | 99 | while( ul_RecvLen > 0 ) |
Ayrton_L | 0:16bcf70d262e | 100 | { |
Ayrton_L | 0:16bcf70d262e | 101 | if( ul_RecvLen >= sizeof( struct ip_hdr ) + sizeof( struct icmp_echo_hdr ) ); |
Ayrton_L | 0:16bcf70d262e | 102 | { |
Ayrton_L | 0:16bcf70d262e | 103 | inet_addr_to_ipaddr(&x_RecvAddr, &x_OntvangAdres.sin_addr); |
Ayrton_L | 0:16bcf70d262e | 104 | |
Ayrton_L | 0:16bcf70d262e | 105 | px_IPHdr = ( struct ip_hdr * ) c_Buffer; |
Ayrton_L | 0:16bcf70d262e | 106 | pux_Echo = ( struct icmp_echo_hdr * ) ( c_Buffer + ( IPH_HL( px_IPHdr ) * 4)); |
Ayrton_L | 0:16bcf70d262e | 107 | |
Ayrton_L | 0:16bcf70d262e | 108 | if( ( pux_Echo->id == PING_ID ) && ( pux_Echo->seqno == htons( us_PingSequenceNummer ) ) ) //matchen van data, byte order naar netwerk byte order |
Ayrton_L | 0:16bcf70d262e | 109 | { |
Ayrton_L | 0:16bcf70d262e | 110 | PING_RESULT( ( ICMPH_TYPE( iecho ) == ICMP_ER ) ); //ping resultaat processen |
Ayrton_L | 0:16bcf70d262e | 111 | return; |
Ayrton_L | 0:16bcf70d262e | 112 | } |
Ayrton_L | 0:16bcf70d262e | 113 | } |
Ayrton_L | 0:16bcf70d262e | 114 | |
Ayrton_L | 0:16bcf70d262e | 115 | ul_RecvLen = lwip_recvfrom( l_SocketReturn, c_Buffer, sizeof( c_Buffer ), 0, ( struct sockaddr* ) &x_OntvangAdres, ( socklen_t* ) &ul_FromLen ); |
Ayrton_L | 0:16bcf70d262e | 116 | } |
Ayrton_L | 0:16bcf70d262e | 117 | |
Ayrton_L | 0:16bcf70d262e | 118 | PING_RESULT( 0 ); //ping resultaat processen |
Ayrton_L | 0:16bcf70d262e | 119 | } |
Ayrton_L | 0:16bcf70d262e | 120 | |
Ayrton_L | 0:16bcf70d262e | 121 | void v_Ping( void ) |
Ayrton_L | 0:16bcf70d262e | 122 | { |
Ayrton_L | 0:16bcf70d262e | 123 | int32_t l_SocketReturn; //vooral om te kunnen debuggen binnen LWIP, sockets.c ... -1 on fail |
Ayrton_L | 0:16bcf70d262e | 124 | uint32_t ul_TimeOut; |
Ayrton_L | 0:16bcf70d262e | 125 | |
Ayrton_L | 0:16bcf70d262e | 126 | l_SocketReturn = lwip_socket( AF_INET, SOCK_RAW, IP_PROTO_ICMP ); |
Ayrton_L | 0:16bcf70d262e | 127 | ul_TimeOut = PING_RCV_TIMEO; |
Ayrton_L | 0:16bcf70d262e | 128 | |
Ayrton_L | 0:16bcf70d262e | 129 | if( l_SocketReturn > -1 ) |
Ayrton_L | 0:16bcf70d262e | 130 | { |
Ayrton_L | 0:16bcf70d262e | 131 | lwip_setsockopt( l_SocketReturn, SOL_SOCKET, SO_RCVTIMEO, &ul_TimeOut, sizeof( ul_TimeOut ) ); |
Ayrton_L | 0:16bcf70d262e | 132 | |
Ayrton_L | 0:16bcf70d262e | 133 | while ( 1 ) |
Ayrton_L | 0:16bcf70d262e | 134 | { |
Ayrton_L | 0:16bcf70d262e | 135 | ip_addr_t x_PingTarget = { 0x08080808 }; //Google DNS server, uptime 99.9% => vrij betrouwbaar om naar heen te pingen. Behalve in landen zoals DPRK |
Ayrton_L | 0:16bcf70d262e | 136 | |
Ayrton_L | 0:16bcf70d262e | 137 | if ( ux_Ping( l_SocketReturn, &x_PingTarget ) == ERR_OK ) |
Ayrton_L | 0:16bcf70d262e | 138 | { |
Ayrton_L | 0:16bcf70d262e | 139 | v_PingOntvang( l_SocketReturn ); |
Ayrton_L | 0:16bcf70d262e | 140 | } |
Ayrton_L | 0:16bcf70d262e | 141 | sys_msleep( PING_DELAY ); |
Ayrton_L | 0:16bcf70d262e | 142 | } |
Ayrton_L | 0:16bcf70d262e | 143 | } |
Ayrton_L | 0:16bcf70d262e | 144 | } |
Ayrton_L | 0:16bcf70d262e | 145 | |
Ayrton_L | 0:16bcf70d262e | 146 | #endif |