Skip to content

Commit

Permalink
Merge pull request #1014 from fabik111/add-ping-command
Browse files Browse the repository at this point in the history
Ping command
  • Loading branch information
pennam authored Feb 5, 2025
2 parents 540c1cd + 17ff057 commit d00befa
Show file tree
Hide file tree
Showing 41 changed files with 303 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class WhdSTAInterface : public WiFiInterface, public EMACInterface {
nsapi_error_t set_timeout(uint32_t timeout)
{
_timeout = timeout;
return NSAPI_ERROR_OK;
}

/** Set blocking status of interface.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

#define WHD_VERSION "v1.94.0"
/* This define is used by arduino::WiFiClass::firmwareVersion() do not prepend v */
#define WHD_VERSION "1.94.0"
#define WHD_BRANCH "v1.94.0"
#define WHD_DATE "2021-04-27 16:54:34 +0800"
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class ICMPSocket : public InternetDatagramSocket {
*/
ICMPSocket();

#if MBED_CONF_LWIP_RAW_SOCKET_ENABLED
int ping(SocketAddress &socketAddress, uint32_t timeout);
#endif

#if !defined(DOXYGEN_ONLY)

protected:
Expand Down
3 changes: 0 additions & 3 deletions libraries/GSM/src/GSM.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@ class GSMClass : public MbedSocketClass {
void trace(Stream& stream);
void setTraceLevel(int trace_level, bool timestamp = false, bool at_trace = false);
#endif
int ping(const char* hostname, uint8_t ttl = 128);
int ping(const String& hostname, uint8_t ttl = 128);
int ping(IPAddress host, uint8_t ttl = 128);
bool isConnected();

friend class GSMClient;
Expand Down
32 changes: 32 additions & 0 deletions libraries/SocketWrapper/src/SocketHelpers.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "SocketHelpers.h"
#include <ICMPSocket.h>

uint8_t* arduino::MbedSocketClass::macAddress(uint8_t* mac) {
const char* mac_str = getNetwork()->get_mac_address();
Expand Down Expand Up @@ -74,6 +75,24 @@ arduino::IPAddress arduino::MbedSocketClass::dnsIP(int n) {
return ipAddressFromSocketAddress(ip);
}

int arduino::MbedSocketClass::ping(const char *hostname, uint8_t ttl)
{
SocketAddress socketAddress;
gethostbyname(getNetwork(),hostname, &socketAddress);
return ping(socketAddress, ttl);
}

int arduino::MbedSocketClass::ping(const String &hostname, uint8_t ttl)
{
return ping(hostname.c_str(), ttl);
}

int arduino::MbedSocketClass::ping(IPAddress host, uint8_t ttl)
{
SocketAddress socketAddress = socketAddressFromIpAddress(host, 0);
return ping(socketAddress, ttl);
}

void arduino::MbedSocketClass::config(arduino::IPAddress local_ip) {
IPAddress dns = local_ip;
dns[3] = 1;
Expand Down Expand Up @@ -119,6 +138,19 @@ void arduino::MbedSocketClass::setDNS(IPAddress dns_server1, IPAddress dns_serve
_dnsServer2 = SocketAddress(convertedDNSServer2);
}

int arduino::MbedSocketClass::ping(SocketAddress &socketAddress, uint8_t ttl, uint32_t timeout)
{
/* ttl is not supported by mbed ICMPSocket. Default value used is 255 */
(void)ttl;
ICMPSocket s;
s.set_timeout(timeout);
s.open(getNetwork());
int response = s.ping(socketAddress, timeout);
s.close();

return response;
}

arduino::IPAddress arduino::MbedSocketClass::ipAddressFromSocketAddress(SocketAddress socketAddress) {
nsapi_addr_t address = socketAddress.get_addr();
return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]);
Expand Down
12 changes: 12 additions & 0 deletions libraries/SocketWrapper/src/SocketHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,17 @@ class MbedSocketClass {

virtual NetworkInterface* getNetwork() = 0;

/*
* Ping the specified target.
*
* ttl value is unused, but kept for API compatibility
*
* return: RTT in milliseconds or -1 on error
*/
int ping(const char* hostname, uint8_t ttl = 255);
int ping(const String &hostname, uint8_t ttl = 255);
int ping(IPAddress host, uint8_t ttl = 255);

/*
* Download a file from an HTTP endpoint and save it in the provided `target` location on the fs
* The parameter cbk can be used to perform actions on the buffer before saving on the fs
Expand Down Expand Up @@ -174,6 +185,7 @@ class MbedSocketClass {

void body_callback(const char* data, uint32_t data_len);

int ping(SocketAddress &socketAddress, uint8_t ttl, uint32_t timeout = 5000);
static arduino::IPAddress ipAddressFromSocketAddress(SocketAddress socketAddress);
static SocketAddress socketAddressFromIpAddress(arduino::IPAddress ip, uint16_t port);
static nsapi_error_t gethostbyname(NetworkInterface* interface, const char* aHostname, SocketAddress* socketAddress);
Expand Down
114 changes: 114 additions & 0 deletions libraries/WiFi/examples/WiFiPing/WiFiPing.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
Web ICMP Ping
This sketch pings a device based on the IP address or the hostname
using the WiFi module.
This example is written for a network using WPA encryption. For
WEP or WPA, change the WiFi.begin() call accordingly.
created 14 February 2024
by paulvha
modified 8 Jenuary 2025
by fabik111
*/

#include <WiFi.h>
#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)

int status = WL_IDLE_STATUS;

/* -------------------------------------------------------------------------- */
void setup() {
/* -------------------------------------------------------------------------- */
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed.");
// don't continue
while (true);
}

// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);

// wait 3 seconds for connection:
delay(3000);
}

printWifiStatus();
}

/* -------------------------------------------------------------------------- */
void loop() {
/* -------------------------------------------------------------------------- */

// Ping IP
const IPAddress remote_ip(140,82,121,4);
Serial.print("Trying to ping github.com on IP: ");
Serial.println(remote_ip);

// using default ping count of 1
int res = WiFi.ping(remote_ip);

if (res > 0) {
Serial.print("Ping response time: ");
Serial.print(res);
Serial.println(" ms");
}
else {
Serial.println("Timeout on IP!");
}

// Ping Host
const char* remote_host = "www.google.com";
Serial.print("Trying to ping host: ");
Serial.println(remote_host);

int res1 = WiFi.ping(remote_host);

if (res1 > 0) {
Serial.print("Ping response time: ");
Serial.print(res1);
Serial.println(" ms");
}
else {
Serial.println("Timeout on host!");
}

Serial.println();
delay(5000);
}

/* -------------------------------------------------------------------------- */
void printWifiStatus() {
/* -------------------------------------------------------------------------- */
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());

// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);

// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
2 changes: 2 additions & 0 deletions libraries/WiFi/examples/WiFiPing/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#define SECRET_SSID ""
#define SECRET_PASS ""
106 changes: 106 additions & 0 deletions patches/0247-ICMPSocket-add-ping.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
From 933694e0f35451d21eed77a93fa346570de20878 Mon Sep 17 00:00:00 2001
From: pennam <[email protected]>
Date: Tue, 4 Feb 2025 14:31:59 +0100
Subject: [PATCH] ICMPSocket: add ping

---
.../netsocket/include/netsocket/ICMPSocket.h | 4 ++
connectivity/netsocket/source/ICMPSocket.cpp | 61 +++++++++++++++++++
2 files changed, 65 insertions(+)

diff --git a/connectivity/netsocket/include/netsocket/ICMPSocket.h b/connectivity/netsocket/include/netsocket/ICMPSocket.h
index 1837bc8e09..5e1ee8fb03 100644
--- a/connectivity/netsocket/include/netsocket/ICMPSocket.h
+++ b/connectivity/netsocket/include/netsocket/ICMPSocket.h
@@ -37,6 +37,10 @@ public:
*/
ICMPSocket();

+#if MBED_CONF_LWIP_RAW_SOCKET_ENABLED
+ int ping(SocketAddress &socketAddress, uint32_t timeout);
+#endif
+
#if !defined(DOXYGEN_ONLY)

protected:
diff --git a/connectivity/netsocket/source/ICMPSocket.cpp b/connectivity/netsocket/source/ICMPSocket.cpp
index f6c9b98de1..d8ea954835 100644
--- a/connectivity/netsocket/source/ICMPSocket.cpp
+++ b/connectivity/netsocket/source/ICMPSocket.cpp
@@ -16,12 +16,73 @@
*/

#include "ICMPSocket.h"
+#if MBED_CONF_LWIP_RAW_SOCKET_ENABLED
+#include "drivers/Timer.h"
+#include "lwip/prot/icmp.h"
+#include "lwip/inet_chksum.h"
+#include "lwip/prot/ip4.h"
+#endif

ICMPSocket::ICMPSocket()
{
_socket_stats.stats_update_proto(this, NSAPI_ICMP);
}

+#if MBED_CONF_LWIP_RAW_SOCKET_ENABLED
+int ICMPSocket::ping(SocketAddress &socketAddress, uint32_t timeout)
+{
+ struct __attribute__((__packed__)) {
+ struct icmp_echo_hdr header;
+ uint8_t data[32];
+ } request;
+
+ ICMPH_TYPE_SET(&request.header, ICMP_ECHO);
+ ICMPH_CODE_SET(&request.header, 0);
+ request.header.chksum = 0;
+ request.header.id = 0xAFAF;
+ request.header.seqno = random();
+
+ for (size_t i = 0; i < sizeof(request.data); i++) {
+ request.data[i] = i;
+ }
+
+ request.header.chksum = inet_chksum(&request, sizeof(request));
+
+ int res = sendto(socketAddress, &request, sizeof(request));
+ if (res <= 0){
+ return -1;
+ }
+
+ mbed::Timer timer;
+ timer.start();
+ int elapsed = -1;
+ do {
+ struct __attribute__((__packed__)) {
+ struct ip_hdr ipHeader;
+ struct icmp_echo_hdr header;
+ } response;
+
+ int rxSize = recvfrom(&socketAddress, &response, sizeof(response));
+ if (rxSize < 0) {
+ // time out
+ break;
+ }
+
+ if (rxSize < sizeof(response)) {
+ // too short
+ continue;
+ }
+
+ if ((response.header.id == request.header.id) && (response.header.seqno == request.header.seqno)) {
+ elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count();
+ timer.stop();
+ }
+ } while (elapsed == -1 && std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count() < timeout);
+
+ return elapsed;
+}
+#endif
+
nsapi_protocol_t ICMPSocket::get_proto()
{
return NSAPI_ICMP;
--
2.47.2

2 changes: 1 addition & 1 deletion variants/ARDUINO_NANO33BLE/defines.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
-DFEATURE_STORAGE=1
-D__FPU_PRESENT=1
-D__MBED__=1
-DMBED_BUILD_TIMESTAMP=1730202709.4767566
-DMBED_BUILD_TIMESTAMP=1738678457.278008
-D__MBED_CMSIS_RTOS_CM
-DMBED_MPU_CUSTOM
-DMBED_TICKLESS
Expand Down
Binary file modified variants/ARDUINO_NANO33BLE/libs/libmbed.a
Binary file not shown.
3 changes: 2 additions & 1 deletion variants/EDGE_CONTROL/conf/mbed_app.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"cellular.offload-dns-queries": true,
"cellular.at-handler-buffer-size": 1024,
"mbed-trace.enable": true,
"target.mbed_app_start": "0x10000"
"target.mbed_app_start": "0x10000",
"lwip.raw-socket-enabled": true
},
"EDGE_CONTROL": {
"sd.SPI_MOSI": "P0_20",
Expand Down
2 changes: 1 addition & 1 deletion variants/EDGE_CONTROL/defines.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
-DFEATURE_STORAGE=1
-D__FPU_PRESENT=1
-D__MBED__=1
-DMBED_BUILD_TIMESTAMP=1730202880.502858
-DMBED_BUILD_TIMESTAMP=1738678638.4581091
-D__MBED_CMSIS_RTOS_CM
-DMBED_MPU_CUSTOM
-DMBED_TICKLESS
Expand Down
Binary file modified variants/EDGE_CONTROL/libs/libmbed.a
Binary file not shown.
2 changes: 1 addition & 1 deletion variants/EDGE_CONTROL/mbed_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@
#define MBED_CONF_LWIP_PPP_IPV6_ENABLED 0 // set by library:lwip
#define MBED_CONF_LWIP_PPP_THREAD_STACKSIZE 768 // set by library:lwip
#define MBED_CONF_LWIP_PRESENT 1 // set by library:lwip
#define MBED_CONF_LWIP_RAW_SOCKET_ENABLED 0 // set by library:lwip
#define MBED_CONF_LWIP_RAW_SOCKET_ENABLED 1 // set by application[*]
#define MBED_CONF_LWIP_SOCKET_MAX 4 // set by library:lwip
#define MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY osPriorityNormal // set by library:lwip
#define MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE 1200 // set by library:lwip
Expand Down
2 changes: 1 addition & 1 deletion variants/GENERIC_STM32H747_M4/defines.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
-DFEATURE_BLE=1
-D__FPU_PRESENT=1
-D__MBED__=1
-DMBED_BUILD_TIMESTAMP=1730202826.649384
-DMBED_BUILD_TIMESTAMP=1738678579.8515525
-D__MBED_CMSIS_RTOS_CM
-DMBED_MPU_CUSTOM
-DMBED_TICKLESS
Expand Down
Binary file modified variants/GENERIC_STM32H747_M4/libs/libmbed.a
Binary file not shown.
1 change: 1 addition & 0 deletions variants/GIGA/conf/mbed_app.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"target.mbed_app_start": "0x8040000",
"nsapi.dns-response-wait-time": 5000,
"nsapi.dns-total-attempts": 3,
"lwip.raw-socket-enabled": true,
"target.macros_add": [
"METAL_INTERNAL",
"VIRTIO_DRIVER_ONLY",
Expand Down
Loading

0 comments on commit d00befa

Please sign in to comment.