Skip to content
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

Ping excessive delay or loop halt when target offline #18

Closed
drakerex opened this issue Sep 25, 2018 · 3 comments
Closed

Ping excessive delay or loop halt when target offline #18

drakerex opened this issue Sep 25, 2018 · 3 comments
Labels
status: waiting for information More information must be provided before work can proceed

Comments

@drakerex
Copy link

As requested from https://forum.arduino.cc/index.php?topic=569872.0

When a WiFi.ping is sent to a host (by dns) which is offline, there's an excessive delay. If the WiFi.ping command is sent by IPAddress the loop() halts. See the attached forum for example sketch.

@sandeepmistry
Copy link
Contributor

Hi @drakerex,

I tried to reproduce this now.

  1. The bad DNS stall added 10s, so I've submitted pull request Speed up resolving bad host names #21 to resolve this.

  2. I could not reproduce the "halt" however, the firmware has a 5 second timeout for the ping result. Is this what you are seeing?

@facchinm facchinm added the status: waiting for information More information must be provided before work can proceed label Oct 5, 2018
@apetryk2
Copy link

I can reproduce the 'halt' issue with the following code. The IP address I'm trying to ping (192.168.0.2 in this case) doesn't belong to anything. The debug trace gets to "calling ping" and then just hangs.

`
#include <SPI.h>
#include <WiFiNINA.h>
#include <utility/wifi_drv.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; // the WiFi radio's status
char debug = 1;

// Specify IP address or hostname
IPAddress pingHost(192,168,0,2);
int pingResult;

void setup() {

if (debug) {
//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);
}

String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
  Serial.println("Please upgrade the firmware");
}

}
}

void loop() {

TestWiFiConnection();

if (debug) Serial.println("calling ping");
pingResult = WiFi.ping(pingHost);
if (debug) Serial.println("done calling ping");

delay(500);
}

void TestWiFiConnection()
//test if always connected
{
int StatusWiFi=WiFi.status();
if(StatusWiFi!=WL_CONNECTED) //if no connection
{
WiFiConnect(); //if my SSID is present, connect
}
}

void WiFiConnect()
//connect to my SSID
{
status= WL_IDLE_STATUS;
while(status!=WL_CONNECTED)
{
status = WiFi.begin(ssid,pass);
if(status!=WL_CONNECTED) delay(500);
}
if (debug) printWiFiData();
}

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

Serial.print("Subnet mask: ");
Serial.println((IPAddress)WiFi.subnetMask());

Serial.print("Gateway IP : ");
Serial.println((IPAddress)WiFi.gatewayIP());

// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}

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

// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI): ");
Serial.println(rssi);

// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type: ");
Serial.println(encryption, HEX);
Serial.println();
}

void printMacAddress(byte mac[]) {
for (int i = 5; i >= 0; i--) {
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX);
if (i > 0) {
Serial.print(":");
}
}
Serial.println();
}
`

@szaiftamas
Copy link

szaiftamas commented May 17, 2020

I changed a bit the spi_drv.cpp in the WiFiNINA library. I added timeout for these two function, and the hang is over, now I able to reconnect to the wifi router, if the connection is drop.
This problem happened when the wifi channel was overloaded, it means 20 wifi router in the same place, and the other when the signal strength can reached only the minimum level, and it is sometime lost the connection.

void SpiDrv::waitForSlaveSign()
{
uint32_t timeOut = millis() + 10000;
while (!waitSlaveSign() && timeOut > millis());
}

void SpiDrv::waitForSlaveReady()
{
uint32_t timeOut = millis() + 10000;
while (!waitSlaveReady() && timeOut > millis());
}

This is the request handler function
bool API_Handler::requestWiFi(char *data, uint8_t length, uint8_t &errStatus)
{
if(isWaitToReconnect && millis() < nextWiFiStatusCheck)
{
errStatus = Network_Wait_To_Reconnect;
return false;
}
if(isWaitToReconnect && isDebug)
Serial.println("Waited to reconnect!");
isWaitToReconnect = false;
if (!wificlient.connect(server, 80))
{
if(isDebug)
Serial.println("Server Connection Failed!");

    if(WiFi.status() != WL_CONNECTED)
    {
        WiFi.end();
        if(isDebug)
            Serial.println("WiFi Connection Failed!");
        isWaitToReconnect = true;
        nextWiFiStatusCheck = millis() + 10000;
        errStatus = Network_Wait_To_Reconnect;
        WiFi.begin(wifi_ssid_p, wifi_pass_p);
        if(isDebug)
            Serial.println("WiFi Begin Sent!");
    }
    return false;
}
responsePointer = 0;
wificlient.print("POST ");
wificlient.print(address_p);
wificlient.println(" HTTP/1.1");
wificlient.print("Host: ");
wificlient.print(serverIPChar[0]);
wificlient.print(".");
wificlient.print(serverIPChar[1]);
wificlient.print(".");
wificlient.print(serverIPChar[2]);
wificlient.print(".");
wificlient.println(serverIPChar[3]);
wificlient.println("Content-Type: application/json");
wificlient.print("Content-Length: ");
wificlient.println(length);// number of bytes in the payload
wificlient.println("Connection: close");
wificlient.println();// important need an empty line here
wificlient.println(data);// the payload
wificlient.flush();
return true;

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting for information More information must be provided before work can proceed
Projects
None yet
Development

No branches or pull requests

5 participants