MKR1000 - Wifi101.config() - to set ONLY IP & Gateway addr w/o destroying DNS?

Hi guys,

After connecting to my wifi network I would like to reset ONLY the IP address but NOT the DNS and Gateway Address (as I don't always have them for all random Wifi networks I may connect to!).

I can read the assigned gateway address (after connecting to WiFi initially) & reset that together with a "static" IP adress that I want to assign (eg: 192.168.178.195).

the "problem" for me is that the WiFi.config() function is defined as (from Reference):

WiFi.config(ip, dns, gateway);

There seems to be no way I can get the originally assigned (during initial connection to WiFi) DNS entries so I would like to keep using whatever DNS has been assigned during initial connection to WiFo Network.

So how do I set ONLY the IP & Gateway addresses (& leave the DNS entry to whatever it was originally set to after initial connection to Wifi))?

The code I use looks something like this:

// after successul connect to Wifi Network
IPAddress gatewayIP(0,0,0,0);
gatewayIP = WiFi.gatewayIP();
WiFi.config(staticIP,dontHaveDNS,gatewayIP);

Obviously I need to find a way to set that "dontHaveDNS" parameter in such a way that the existing DNS entry(s) are not affected.

Also tried:

IPAddress gatewayIP(0,0,0,0);
gatewayIP = WiFi.gatewayIP();
WiFi.config(staticIP,,gatewayIP);

BUT that won't compile!

Any suggestions on how one does that!?

Thanks!

Gerard

If you look at the WiFi.config() function overloads in the WiFi101 library:

void WiFiClass::config(IPAddress local_ip)
{
 config(local_ip, (uint32_t)0);
}

void WiFiClass::config(IPAddress local_ip, IPAddress dns_server)
{
 config(local_ip, dns_server, (uint32_t)0);
}

void WiFiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway)
{
 config(local_ip, dns_server, gateway, (uint32_t)0);
}

void WiFiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet)
{
 tstrM2MIPConfig conf;

 if (!_init) {
 init();
 }

 conf.u32DNS = (uint32_t)dns_server;
 conf.u32Gateway = (uint32_t)gateway;
 conf.u32StaticIP = (uint32_t)local_ip;
 conf.u32SubnetMask = (uint32_t)subnet;
 _dhcp = 0;
 m2m_wifi_enable_dhcp(0); // disable DHCP
 m2m_wifi_set_static_ip(&conf);
 _localip = conf.u32StaticIP;
 _submask = conf.u32SubnetMask;
 _gateway = conf.u32Gateway;
}

It seems you can pass (uint32_t)0 as an argument for any parameter you want to skip, other than the IP address. So, using your example code above, you could do this:

WiFi.config(staticIP, (uint32_t)0, gatewayIP);

I'd expect there to be some logic like this in the code:

if(dns_server != 0) {
  conf.u32DNS = (uint32_t)dns_server;
}

So that an argument with value 0 would be a signal to leave that part of the configuration the same. However, from my understanding of the code, this doesn't appear to be the case.

I gave it a try and it does work for me though.

Hi Pert,

Thanks for the suggestion - much appreciated.

I tried it:

WiFi.config(staticIP, (uint32_t)0, gatewayIP);

and it does in fact allow me to correctly set BOTH the IP address and the Gateway Address. So that's progress!

However, it seems to destroy the DNS entry (probably sets it to 0?) as I can no longer connect to internet addresses after this.

As there does not seem to be a way to get the DNS settings, it is difficult for me to know for sure what happened to the DNS setting after the above WiFi.config has been executed.

To be clear, I only need to assign a new IP Address but if I use WiFi.config(staticIP) then it destroys the gateway address (sets it to 0,0,0,0). That's why I tried to reset the gateway address to whatever it was originally assigned but then it destroys the DNS!

Any other ideas...!? :slight_smile:

Regards

Gerard

gbucas:
However, it seems to destroy the DNS entry (probably sets it to 0?) as I can no longer connect to internet addresses after this.

Yeah, I feared that would be an issue. What I don't understand is why it didn't cause problems for me on my test. I'm using the File > Examples > WiFi101 > WiFiWebServer example, and I'm able to change the IP address and then load that web page in my browser with the expected results. The only problem I did have was that the first static IP address was already in use by another device on the network. Once I fixed that, it works fine.

Hi again Pert,

Thanks for all the help.

Of course the WebServer example WILL in fact still work because it doesn't INITIATE access to any external internet websites (being a server it only RESPONDS to requests from external clients which doesn't require any DNS).

Instead try the Examples-->WebClient example. You will notice it no longer works after using WiFi.config to reset the IP Address as we discussed.

Can you try that & confirm...?

Thanks!

Gerard

OK, you got it. I tried the WiFiWebClient example with the IP address change and indeed it doesn't work, even though the example works fine if I don't change the IP address.

Hopefully someone who is a bit more knowledgeable than myself will chime in with some advice about how you can get determine the DNS server in your code.

OK Pert - thanks again for verifying.

This is definitely a bug in the WiFi.config() function!
It seems it ONLY works if one supplies ALL four parameters but as there is no way to get the DNS originally assigned during Wifi Connection, one has to set it to a new one (not ideal for all WiFi networks - would prefer to keep whatever DNS was originally assigned - like I am doing with Gateway Address below).

So a temporarily workaround is to set the DNS to Google's DNS (8,8,8,8), so that I can supply ALL FOUR parameters to WiFi.config, ie:

  IPAddress googleDNS(8,8,8,8);       // as bug in WiFi.config(...) destroys DNS if not all parameters supplied, so will set DNS to google's DNS for now!
  IPAddress subnet(255,255,255,0);    // required for WiFi.config()
  IPAddress gatewayIP(0,0,0,0);                    
  gatewayIP = WiFi.gatewayIP();       // get gateway address so that it can be reset to same when new static IP is configured
  WiFi.config(staticIP,googleDNS,gatewayIP,subnet);

So this is OK for now but it would be nice to get the Wifi.config() function to work as advertised (ie: using Wifi.config(newIPaddress) should NOT destroy gateway and DNS addresses).

As you might have guessed from my fumbling, I'm nowhere near to an expert on this topic. It does seem like this is something that should be possible. If you like, you could submit a bug report/feature request to the WiFi101 library's issue tracker:

I did a little searching and didn't find any existing issues on this topic. Interestingly, there was a pull request that seems to have been intended to add the ability to get the current DNS IP address:

You can see here a function that returns the DNS IP:

Unfortunately, that pull request was using files from the Adafruit_WINC1500 library rather than the WiFi101 library and so it had to be rejected. The Arduino developer did say this about it though:

We'd be happy to review any equivalent changes that are made to WiFi101.h and WiFi.cpp

So it sounds like, at least at that time, Arduino was open to adding that functionality.

There are actually two ideas here. The first would be that once you have dnsIP(), you can do this:

WiFi.config(staticIP, WiFi.dnsIP(), WiFi.gatewayIP(), WiFi.subnetMask());

But the library has these function overloads of WiFi.config() that make us think we can leave off parameters if we don't want to change them from the existing value. The other idea would be to add that functionality to the library.

You are right - let me see if I can issue a bug report - which it definitely is.

I still need it as on some WiFi networks submitting a new DNS (even the same one!) seems to break DNS (which means one can no longer access the Internet using website names as opposed to IP addresses).

Ideally (for me) the function to ONLY change the IP Address should be fixed.

So let’s see if anyone is interested...