|
1 | 1 | #include "SocketHelpers.h"
|
| 2 | +#include "lwip/prot/icmp.h" |
| 3 | +#include "lwip/inet_chksum.h" |
| 4 | +#include "lwip/prot/ip4.h" |
| 5 | +#include <ICMPSocket.h> |
2 | 6 |
|
3 | 7 | uint8_t* arduino::MbedSocketClass::macAddress(uint8_t* mac) {
|
4 | 8 | const char* mac_str = getNetwork()->get_mac_address();
|
@@ -74,6 +78,24 @@ arduino::IPAddress arduino::MbedSocketClass::dnsIP(int n) {
|
74 | 78 | return ipAddressFromSocketAddress(ip);
|
75 | 79 | }
|
76 | 80 |
|
| 81 | +int arduino::MbedSocketClass::ping(const char *hostname, uint8_t ttl) |
| 82 | +{ |
| 83 | + SocketAddress socketAddress; |
| 84 | + gethostbyname(getNetwork(),hostname, &socketAddress); |
| 85 | + return ping(socketAddress, ttl); |
| 86 | +} |
| 87 | + |
| 88 | +int arduino::MbedSocketClass::ping(const String &hostname, uint8_t ttl) |
| 89 | +{ |
| 90 | + return ping(hostname.c_str(), ttl); |
| 91 | +} |
| 92 | + |
| 93 | +int arduino::MbedSocketClass::ping(IPAddress host, uint8_t ttl) |
| 94 | +{ |
| 95 | + SocketAddress socketAddress = socketAddressFromIpAddress(host, 0); |
| 96 | + return ping(socketAddress, ttl); |
| 97 | +} |
| 98 | + |
77 | 99 | void arduino::MbedSocketClass::config(arduino::IPAddress local_ip) {
|
78 | 100 | IPAddress dns = local_ip;
|
79 | 101 | dns[3] = 1;
|
@@ -119,6 +141,72 @@ void arduino::MbedSocketClass::setDNS(IPAddress dns_server1, IPAddress dns_serve
|
119 | 141 | _dnsServer2 = SocketAddress(convertedDNSServer2);
|
120 | 142 | }
|
121 | 143 |
|
| 144 | +int arduino::MbedSocketClass::ping(SocketAddress &socketAddress, uint8_t ttl) |
| 145 | +{ |
| 146 | + const uint32_t timeout = 5000; |
| 147 | + |
| 148 | + /* ttl is not supported by mbed ICMPSocket. Default value used is 255 */ |
| 149 | + (void)ttl; |
| 150 | + ICMPSocket s; |
| 151 | + s.set_timeout(timeout); |
| 152 | + s.open(getNetwork()); |
| 153 | + |
| 154 | + struct __attribute__((__packed__)) { |
| 155 | + struct icmp_echo_hdr header; |
| 156 | + uint8_t data[32]; |
| 157 | + } request; |
| 158 | + |
| 159 | + ICMPH_TYPE_SET(&request.header, ICMP_ECHO); |
| 160 | + ICMPH_CODE_SET(&request.header, 0); |
| 161 | + request.header.chksum = 0; |
| 162 | + request.header.id = 0xAFAF; |
| 163 | + request.header.seqno = random(0xffff); |
| 164 | + |
| 165 | + for (size_t i = 0; i < sizeof(request.data); i++) { |
| 166 | + request.data[i] = i; |
| 167 | + } |
| 168 | + |
| 169 | + request.header.chksum = inet_chksum(&request, sizeof(request)); |
| 170 | + unsigned long recvTime = 0; |
| 171 | + unsigned long sendTime = millis(); |
| 172 | + |
| 173 | + int res = s.sendto(socketAddress,&request, sizeof(request)); |
| 174 | + if(res <= 0){ |
| 175 | + return -1; |
| 176 | + } |
| 177 | + |
| 178 | + uint32_t startRec = millis(); |
| 179 | + do { |
| 180 | + struct __attribute__((__packed__)) { |
| 181 | + struct ip_hdr ipHeader; |
| 182 | + struct icmp_echo_hdr header; |
| 183 | + } response; |
| 184 | + |
| 185 | + int rxSize = s.recvfrom(&socketAddress, &response, sizeof(response)); |
| 186 | + if (rxSize < 0) { |
| 187 | + // time out |
| 188 | + break; |
| 189 | + } |
| 190 | + |
| 191 | + if (rxSize < sizeof(response)) { |
| 192 | + // too short |
| 193 | + continue; |
| 194 | + } |
| 195 | + |
| 196 | + if ((response.header.id == request.header.id) && (response.header.seqno == request.header.seqno)) { |
| 197 | + recvTime = millis(); |
| 198 | + } |
| 199 | + } while (recvTime == 0 && (millis() - startRec) < timeout); |
| 200 | + |
| 201 | + s.close(); |
| 202 | + |
| 203 | + if (recvTime == 0) { |
| 204 | + return -1; |
| 205 | + } else { |
| 206 | + return (recvTime - sendTime); |
| 207 | + } |
| 208 | +} |
| 209 | + |
122 | 210 | arduino::IPAddress arduino::MbedSocketClass::ipAddressFromSocketAddress(SocketAddress socketAddress) {
|
123 | 211 | nsapi_addr_t address = socketAddress.get_addr();
|
124 | 212 | return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]);
|
|
0 commit comments