Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Insights into DHCP issues


  • Please log in to reply
34 replies to this topic

#1 natep

natep

    New Member

  • Members
  • Pip
  • 6 posts

Posted 15 August 2012 - 06:00 PM

The following summarizes a test that I have done regarding DHCP on the netduino plus. The test was done using .NET Micro Framework 4.2 QFE2 and Netduino v4.2.0 RTM firmware. (Tests were also tried using earlier versions with the same results.)

I have been working on getting a Netduino Plus working for the first time. One obvious first step is to get the netduino to obtain a IP from a DHCP server on my network. Like many others who have posted in this forum, I instantly had problems. The solutions posted for most situations is to use a static IP. This is unacceptable for many purposes.

I think that I have found one major bug and would like to report it for the community.

I wrote a simple routine that waits for the netduino to get a DHCP address as follows:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using System.Text;

namespace TestEthernet
{
    public class Program
    {        
        public static void Main() {            
            Microsoft.SPOT.Net.NetworkInformation.NetworkInterface NI = Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];
            NI.EnableDhcp();
            int sec = 0;            
            while (NI.IPAddress == "0.0.0.0")
            {
                string msg = "Waiting for DHCP for " + sec + " sec.  IP="+ NI.IPAddress.ToString();
                Debug.Print(msg);
                Thread.Sleep(5000);
                sec += 5;
            }
            Debug.Print("Got IP" + NI.IPAddress.ToString());                             
        }
    }
}

If you run this code using the Visual Studio debugger or monitor the output using MFDeploy.exe. You will see that the output indefinitely echoes "Waiting for DHCP for XX sec. IP=0.0.0.0". This would lead you to believe that the netduino is having problems with your network and/or DHCP server.

Here is the crux: In reality, the netDuino IS obtaining a DHCP address.

Purely by accident, I happened to notice the MFDeploy console window during testing. Take a look at the attached screenshot from MFDeploy. It shows that the netduino IS obtaining a DHCP IP address from my network after about 30 seconds, but the value at "NI.IPAddress" does not change. So the code above never exits the while loop because it never realizes that the IP address has been obtained. I have not been able to find any other method within the .NET Micro Framework to find the current IP address. It seems to me that there is a major bug here.

The only work around that I found is to put an arbitrary wait (like "System.Threading.Thread.Sleep(60000);") into my code before beginning to use the network. (If you don't wait for the DHCP address to resolve, your application could potentially throw connection exceptions like 10065 "Host unreachable".)

I was completely confused by the fact that many developers in the forums have applications that seem to be using DHCP successfully, while many others can never get it to work. My guess is that developers are falling into two categories:

1) Obliviously lucky developers. They didn't know that they should check whether the IP address is resolved, so their application is running successfully because they never check it.

2) Developers assuming that NI.IPAddress is valid. Like me (having previous experience programming microcontroller network stacks), they check the IP address using NI.IPAddress and therefore assume that DHCP is not working--when in fact, it is working.

People falling into the second category are a real PR problem for the netduino plus. They just assume that there are major network problems with it and change to a different microcontroller. One of my co-workers did this exact thing.

ONE IMPORTANT FINAL NOTE: I had to use MFDeploy to set the IP address to "0.0.0.0" and use "Enable DHCP" before running my code. I have not been able to fully understand (1)how MFDeploy knows that the IP address has changed (as shown by the screenshot), or (2) whether the functions like "NetworkInterface.EnableDHCP" are even working correctly in the code. It seems that the settings saved to the netduino using MFDeploy->Target->Configuration->Network are the only ones that I completely trust. I suspect that there are copied network properties in the firmware and RAM and they are not properly copying to each other--BUT this is purely speculative as I haven't looked at the source.

Hope this helps others with their DHCP problems. Hope the netduino team can get this sorted out in the future.

Attached Files



#2 Coyttl

Coyttl

    Advanced Member

  • Members
  • PipPipPip
  • 61 posts
  • LocationSilver Spring, MD, USA

Posted 15 August 2012 - 07:21 PM

1) Obliviously lucky developers. They didn't know that they should check whether the IP address is resolved, so their application is running successfully because they never check it.


Interesting assumption.

I have a project using the Miko's webserver, and my unit gets a DHCP address immediately upon booting. (And I know, because my LCD screen is set up to display the IP address once obtained, so I can see what address and port the server's running on.)

So while I don't disagree there's a problem there - I take umbrage at being called 'lucky'. :) I'm the most unluckiest guy around!


Okay, seriously - it may be a hardware issue? What rev is your board? (Mine's a 'B', and again, I have no trouble. Also, when I updated, I used MFDeploy to specify to use DHCP and properly assigned the MAC address..)

Edit: I'm also tempted, now, to turn off that option in MFDeploy and see if it changes my results..

#3 natep

natep

    New Member

  • Members
  • Pip
  • 6 posts

Posted 15 August 2012 - 07:35 PM

I am using a Rev B board. Could you post code as to how you are getting the IP address? If you are able to display a DHCP obtained IP address on an LCD, you must be obtaining it somehow? Are you using the NetworkInterface.IPAddress property as used in my code above? Or something else? Thanks. I would love to find the source of this error.

#4 Coyttl

Coyttl

    Advanced Member

  • Members
  • PipPipPip
  • 61 posts
  • LocationSilver Spring, MD, USA

Posted 15 August 2012 - 07:42 PM

I am using a Rev B board. Could you post code as to how you are getting the IP address? If you are able to display a DHCP obtained IP address on an LCD, you must be obtaining it somehow? Are you using the NetworkInterface.IPAddress property as used in my code above? Or something else? Thanks. I would love to find the source of this error.


Sure -
var interf = NetworkInterface.GetAllNetworkInterfaces()[0];
	if (DhcpEnable)
	{
		interf.EnableDhcp();
		interf.RenewDhcpLease();
	}
Now here's the interesting part, and this may be part of the issue - I'm passing DhcpEnable as 'false'. So the 'if' above isn't even getting called. So the device getting a DHCP address is happening in the firmware, under the software layer. (Again - probably because I have the "DHCP Enabled" in MFDeploy set to true.)

--Mike.

Edit: I'm running a test right now, turning that off in the FW and trying it software-based, I'll post as soon as I have my results.

#5 Victor M.

Victor M.

    Advanced Member

  • Members
  • PipPipPip
  • 39 posts
  • LocationRio de Janeiro, Brazil

Posted 15 August 2012 - 07:43 PM

Hello Natep,
You can try to use NeonMika.Webserver. A made some modification on it to run in .NET Micro Framework 4.2 QFE2. I'm going in the opposite way and tray to fix do IP address but when I made my first test only DHCP work.
At night I will make more test to repeat your procedure. Anyway, here is may code. and files to SD card (needed)

#6 Coyttl

Coyttl

    Advanced Member

  • Members
  • PipPipPip
  • 61 posts
  • LocationSilver Spring, MD, USA

Posted 15 August 2012 - 08:04 PM

Edit: I'm running a test right now, turning that off in the FW and trying it software-based, I'll post as soon as I have my results.


Results -
By turning off the Enable DHCP in MFDeploy, and specifying 'true' in the code above, I do get a DHCP lease, apparently. However, all data returned from the NetworkInterface() is incorrect, I get '0.0.0.0' as my IP. From MFDeploy:
Link Update: 
         IP: 192.168.0.112
         GW: 192.168.0.1
MULTICAST SOCKET_ERROR: 0

Link Update: 
         IP: 192.168.0.112
         GW: 192.168.0.1
So apparently there's something wrong with changing settings via the NetworkInterfaces()?

Edit: Fixed odd wording. :)

#7 nakchak

nakchak

    Advanced Member

  • Members
  • PipPipPip
  • 404 posts
  • LocationBristol, UK

Posted 15 August 2012 - 08:12 PM

interesting I suspect the issue lies in the wrapper to lwip as the standard netmf implementation uses rtip Nak.

#8 natep

natep

    New Member

  • Members
  • Pip
  • 6 posts

Posted 15 August 2012 - 08:12 PM

I had problems finding the part of your code that displays the IP address on an LCD. Is the LCD connected to the netduino? Where is the code that displays the IP on the LCD? I am specifically looking to see if you are using a reference to NetworkInterface.IPAddress to obtain the IP address.

#9 Coyttl

Coyttl

    Advanced Member

  • Members
  • PipPipPip
  • 61 posts
  • LocationSilver Spring, MD, USA

Posted 15 August 2012 - 08:31 PM

I had problems finding the part of your code that displays the IP address on an LCD. Is the LCD connected to the netduino? Where is the code that displays the IP on the LCD? I am specifically looking to see if you are using a reference to NetworkInterface.IPAddress to obtain the IP address.

Different area of code. :)

That code is here:
NetworkInterface interf = NetworkInterface.GetAllNetworkInterfaces()[0];
	string portNum = "Port: " + this._PortNumber;
	string line2 = portNum +
		"                ".Substring(0, ((interf.IsDhcpEnabled) ? 12 - portNum.Length : 16 - portNum.Length)) +
		((interf.IsDhcpEnabled) ? "DHCP" : "");
	this.ServerProgressEvent(this, new EventClasses.ServerProgressEventArgs(interf.IPAddress, line2));
	interf = null; portNum = null; line2 = null;
The progress report (this.ServerProgressReport) is an event, which is handled by this in Program.cs:
/// <summary>Hit when the webserver wants to display something to the screen.</summary>
		/// <param name="sender">Server</param>
		/// <param name="e">ServerProgressEventArgs</param>
		static void WebServer_ServerProgressEvent(object sender, EventClasses.ServerProgressEventArgs e)
		{
			try
			{
				//Clear screen & home cursor.
				if (!lcd.IsOpen) lcd.Open();
				lcd.WriteByte(254);
				lcd.WriteByte(1);

				//Write our first line..
				lcd.Write(getFromString(e.line1), 0, e.line1.Length);

				//Align to second line.
				lcd.WriteByte(254);
				lcd.WriteByte(192);

				//Write our second line..
				lcd.Write(getFromString(e.line2), 0, e.line2.Length);

				//Close port..
				//lcd.Close();
			}
			catch (Exception ex)
			{
				string temp;
			}
		}
'lcd' is declared statically:
public static SerialPort lcd;
and then init'd:
lcd = new SerialPort(SerialPorts.COM1, (int)9600, Parity.None, (int)8, StopBits.One);

..Me.

Addendum: Yes, it's not pretty. Yes, there are faster ways of formatting strings. This is just for testing, and I was lazy! :)

#10 natep

natep

    New Member

  • Members
  • Pip
  • 6 posts

Posted 15 August 2012 - 10:54 PM

I think the code that you posted did not included your modified version of Program.cs. I could not find it. From the code you posted above, I can't see any difference between your code and mine except for the "RenewDhcpLease();" statement. I tried to add that "RenewDhcpLease()" to my code right after "EnableDHCP", but it did not change the behavior, as expected. I am still confused as to how your LCD is displaying the correct address. If you do the following steps, does it still display the correct IP on the LCD: 1) Configure the netduino using MFDeploy for an IP of "0.0.0.0" and then select "Enable DHCP". (I want to ensure that the netduino is not storing an old address in the NetworkInterface. This could trick you into thinking that the NetworkInterface.IPAddress property is valid.) 2) Redeploy your program using Visual Studio. 3) Now does the LCD show a "0.0.0.0" address or a "192.168.x.x" address after DHCP is successful? Let me know what you find. Otherwise, I am stumped. I really do think there is a problem in the framework.

#11 Coyttl

Coyttl

    Advanced Member

  • Members
  • PipPipPip
  • 61 posts
  • LocationSilver Spring, MD, USA

Posted 16 August 2012 - 12:39 AM

I think the code that you posted did not included your modified version of Program.cs. I could not find it.

That's correct. I didn't post it all because it's a huge file at the moment - it takes the Mika webserver and handles a hoard of special requests and such. :)

From the code you posted above, I can't see any difference between your code and mine except for the "RenewDhcpLease();" statement.
I tried to add that "RenewDhcpLease()" to my code right after "EnableDHCP", but it did not change the behavior, as expected.

I am still confused as to how your LCD is displaying the correct address. If you do the following steps, does it still display the correct IP on the LCD:

1) Configure the netduino using MFDeploy for an IP of "0.0.0.0" and then select "Enable DHCP". (I want to ensure that the netduino is not storing an old address in the NetworkInterface. This could trick you into thinking that the NetworkInterface.IPAddress property is valid.)

2) Redeploy your program using Visual Studio.

3) Now does the LCD show a "0.0.0.0" address or a "192.168.x.x" address after DHCP is successful?

Yes - that's correct:

If I set the IP to 0.0.0.0 and Enable DHCP in the Hardware Config, by the time the code above calls the event handler, I have an IP. ('interf.IPAddress')

However, if I give it an IP address of '128.128.128.128' and DISABLE DHCP in the Hardware Config, and then programmitally set it to enable DHCP ('interf.IsDhcpEnabled = true'), I get an IP, BUT - interf.IpAddress always returns 0.0.0.0, even after a lease is acquired.

--Me.

#12 65tux

65tux

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts

Posted 16 August 2012 - 03:12 PM

I've never had a problem with DHCP working. I'm sure I glommed this code from somewhere here:
Microsoft.SPOT.Net.NetworkInformation.NetworkInterface networkInterface = Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];

            Microsoft.SPOT.Debug.Print("my ip address: " + networkInterface.IPAddress.ToString());
            int retries = 0;
            while (retries < 10)
            {
                //no ip adress yet.  increment retries and wait
                if (networkInterface.IPAddress.ToString() == "0.0.0.0") Thread.Sleep(2000);
                retries++;
            }
            if (networkInterface.IPAddress.ToString() == "0.0.0.0")
            {
                //could not get network address, print error and bomb out.
                Thread.Sleep(-1);  //indefinite sleep, should cause watchdog to kick in and restart device
            }


#13 Coyttl

Coyttl

    Advanced Member

  • Members
  • PipPipPip
  • 61 posts
  • LocationSilver Spring, MD, USA

Posted 16 August 2012 - 04:58 PM

I've never had a problem with DHCP working. I'm sure I glommed this code from somewhere here:

In MFDeploy -> Network Config, do you have DHCP enabled or no?

--Mike.

#14 natep

natep

    New Member

  • Members
  • Pip
  • 6 posts

Posted 16 August 2012 - 05:26 PM

If I set the IP to 0.0.0.0 and Enable DHCP in the Hardware Config, by the time the code above calls the event handler, I have an IP. ('interf.IPAddress')

However, if I give it an IP address of '128.128.128.128' and DISABLE DHCP in the Hardware Config, and then programmitally set it to enable DHCP ('interf.IsDhcpEnabled = true'), I get an IP, BUT - interf.IpAddress always returns 0.0.0.0, even after a lease is acquired.


Thank you for testing. This is helpful.

I think that this topic could easily get off track because everyone is using different code. There are too many variables to eliminate while troubleshooting. Here is my suggestion. Could everyone try to replicate what I did in the initial post? Is the behavior different from what I reported? Again, my steps were to use MFDeploy to set the IP address to "0.0.0.0" and Enable DHCP. Then, I used Visual Studio to deploy the program (from the first post). Then, I closed Visual Studio and connected with MFDeploy to monitor the console statements from my program. The result is shown in the MFDeploy screenshot.

It just occurred to me that the problem may be only manifested when using a debugger (either MFDeploy or Visual Studio). I am going to run my code again, but with a UDP broadcast from the netduino and monitor the packets in Wireshark. I will post my results once I have tried this.

To all who are interested in pursuing this, please try to replicate my scenario from the first post and let us know what you get. Screenshots like mine are very helpful if possible.

#15 Coyttl

Coyttl

    Advanced Member

  • Members
  • PipPipPip
  • 61 posts
  • LocationSilver Spring, MD, USA

Posted 16 August 2012 - 06:01 PM

To all who are interested in pursuing this, please try to replicate my scenario from the first post and let us know what you get. Screenshots like mine are very helpful if possible.

I'll give it a try tomorrow - I'm stuck on another (late) project today at the office. However, I don't think attaching a debugger affected it - I got the same result a couple times when I wasn't attaching VS or MFDeploy. :(

#16 natep

natep

    New Member

  • Members
  • Pip
  • 6 posts

Posted 16 August 2012 - 06:17 PM

It just occurred to me that the problem may be only manifested when using a debugger (either MFDeploy or Visual Studio). I am going to run my code again, but with a UDP broadcast from the netduino and monitor the packets in Wireshark. I will post my results once I have tried this.

I tried my idea. I sent debug info over UDP broadcast. Then, by monitoring the UDP packets in Wireshark, I was able to confirm that the problem is present even with neither MFDeploy or Visual Studio open. The NetworkInterface.Address property is still 0.0.0.0. (I also verified the Gateway property. It is exhibiting the same problem.)

I am hoping that one of the SecretLabs staff will jump in and give some thoughts. I have tried to make this as simple and reproducible as possible from the very beginning.

Has anyone been able to reproduce the problem from my first post? Any workarounds or solutions other than a blind Sleep statement?

#17 65tux

65tux

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts

Posted 16 August 2012 - 11:26 PM

In MFDeploy -> Network Config, do you have DHCP enabled or no?

--Mike.

Yes. DHCP is enabled in MFDeploy.

#18 Coyttl

Coyttl

    Advanced Member

  • Members
  • PipPipPip
  • 61 posts
  • LocationSilver Spring, MD, USA

Posted 17 August 2012 - 12:29 AM

Yes. DHCP is enabled in MFDeploy.

Okay. Disable it, and ten run your same code. Bet it won't work. :) That's the same test I did with my code, and got the same results you did. With it enabled in MFDeploy, it works fine. With it *disabled* and then programmitically enabled in the program, it won't work.

#19 Nobby

Nobby

    Advanced Member

  • Members
  • PipPipPip
  • 70 posts

Posted 17 August 2012 - 04:15 AM

I'm also having ethernet issues with the latest firmware. Although, I can't confirm if the issue exists with older versions. I discovered that the ethernet interface never works at all if a network connection doesn't exist on boot. I made a thread here: http://forums.netdui...h__1#entry32165 Nobody has shared any discussion on the matter. I'm using static IP in this case and absense of network connectivity is fine as long as it occurs after boot/powerup.

#20 baxter

baxter

    Advanced Member

  • Members
  • PipPipPip
  • 415 posts

Posted 17 August 2012 - 06:44 AM

I fail to understand what the problem is ... I have been working with the Netduino Plus starting with MF4.2 beta through Mf4.2 QFE2 running
a web server written in Visual Basic. With each iteration of the system software, I always enable DHCP in MFDeploy, set the MAC address
and the DNS server IPs and I never fail to obtain a Netduino IP address. I am using a cheap refurb Cisco-Linksys E2000 router running DD-WRT.
Also, it doesn't matter whether the ethernet cable is plugged in upon startup or not. I just ran the following test:

1. Unplug Netduino USB cable (no power)

2. Unplug ethernet cable

3. plug in USB, without ethernet cable

4. run MFDeploy, select USB, Ping. MFDeploy shows this stack trace:

Pinging... caught Exception (ex as SocketException) Microsoft.SPOT.Net.SocketNative::poll
System.Net.Sockets.Socket::Poll
System.Net.STinyCLR
Sockets.Socket::Accept
Webserver_Plus_SDcard_V9.WebServer::Listen

5. connect ethernet cable, MFDeploy Ping shows:

Pinging... TinyCLR

6. MFDeploy --> Target --> connect

7. Press Netduino button running button interrupt code below, MFDeploy shows:

IP Address 192.168.0.130
GatewayAddress 192.168.0.1
PhysicalAddress 5C 86 4A 00 06 9A
dnsAddress 0 8.8.8.8
dnsAddress 1 8.8.4.4
IsDhcpEnabled True
freemem: 46224

I think you need to look to your router for DHCP issues and stop blaming Netduino for arcane problems. For ethernet connected or not,
you need a try-catch in your listener code in order to recover. Upon startup, in Main I am calling the NIST DayTime TCP client to set
the Netduino clock. Without an ethernet connection an exception is thrown. Catching it allows a graceful recovery.

Try-Catch
 Private Sub Listen()
        While (True)
            Try
               Using client As Socket = _socket.Accept()
                  --
                  --
                  --
               End Using
            Catch ex As SocketException
                Debug.Print("caught Exception (ex as SocketException)   " & ex.StackTrace)
            End Try
        End While

Baxter


Button code:
Private Sub onBoardButton_OnInterrupt(data1 As UInt32, data2 As UInt32, time As DateTime)

        If (data2 = 0) Then
            _onBoardLED.Write(True)
            Thread.Sleep(250)
            _onBoardLED.Write(False)
            Thread.Sleep(250)
            _onBoardLED.Write(True)
            Thread.Sleep(250)
            _onBoardLED.Write(False)
        End If

        Dim NetInfo As NetworkInterface = NetworkInterface.GetAllNetworkInterfaces()(0)
        Dim IPaddress As String = NetInfo.IPAddress
        Dim DnsAddresses() As String = NetInfo.DnsAddresses
        Dim GatewayAddress As String = NetInfo.GatewayAddress
        Dim PhysicalAddress As Byte() = NetInfo.PhysicalAddress
        Dim IsDhcpEnabled As Boolean = NetInfo.IsDhcpEnabled
        Debug.Print("IP Address " & IPaddress)
        Debug.Print("GatewayAddress " & GatewayAddress)
        Debug.Print("PhysicalAddress " & bytesToHexString(PhysicalAddress, True))
        For i As Integer = 0 To DnsAddresses.Length - 1
            Debug.Print("dnsAddress " & i.ToString & " " & DnsAddresses(i))
        Next
        Debug.Print("IsDhcpEnabled " & IsDhcpEnabled.ToString)
        Debug.Print("freemem: " & Debug.GC(True))
End Sub





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.