Skip to content

Ping command #1014

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 5, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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
@@ -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:
3 changes: 0 additions & 3 deletions libraries/GSM/src/GSM.h
Original file line number Diff line number Diff line change
@@ -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;
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();
@@ -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;
@@ -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]);
12 changes: 12 additions & 0 deletions libraries/SocketWrapper/src/SocketHelpers.h
Original file line number Diff line number Diff line change
@@ -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
@@ -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);
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 <m.pennasilico@arduino.cc>
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
@@ -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
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
@@ -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",
2 changes: 1 addition & 1 deletion variants/EDGE_CONTROL/defines.txt
Original file line number Diff line number Diff line change
@@ -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
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
@@ -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
2 changes: 1 addition & 1 deletion variants/GENERIC_STM32H747_M4/defines.txt
Original file line number Diff line number Diff line change
@@ -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
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
@@ -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",
Loading