Introducing mIP - A 100% Managed TCP/IP Stack for .NET MF

I just published a new version of the mIP library with a lot of changes. Some of the Highlights are:

Completely New Driver written from the original Microchip source, so there are no more GPL restrictions (that was hard)
Cable connect disconenct works great with automatic DHCP address update
Fixed DHCP negotiation for several routers (including D-Link and Netgear)
Added device name to DHCP message so it now shows up in router configuration menus!
Made extenstion methods compatible with .NET MF 4.1
Used a Debug.Print command that actually is not compiled in Release mode (reduces memory required)
Fixed a huge memory leak (worked for 24 hours straight today having never failed!)
Added some automatic recovery code (it works, but it could be better. Automatically restarts enc28j60)
Made Netbios over TCP enabled by default (for WinXP compatibility)
Removed Reset pin because it was clear from the spec sheet that it is never necessary when using SPI
And more…[/ul]

Jay Jay, how’s that stab at uPNP coming? If you are making progress let me know. Otherwise, I might look at it myself soon. :slight_smile:



I’m going to repeat my earlier statement:

No more GPL is a winner. You rock!

Nice. I’m intrigued. I’ll be playing with this over the weekend.

Please find below the Desktop version of the Port Forwarding… it was easier to get started with the desktop version to make sure it works now I’ll have to convert it to NetMF… i’ll try to get to it over the weekend.

Edit: removed the Desktop Version of the code to not cause confusion for other user and new netMF code will be released on Codeshare soon....

What’s missing in the above is the Presentation Web Page Icon… the one that popups in windows when it detects UPnp and when you click on it, it takes to a local page … :slight_smile:

I tried to get it up and running today on a modified Discovery board, but it doesn’t work yet. --> works now!

Wiring: Reset --> PB10, CS --> PA13, SCK --> PB3, MISO --> PB4, MOSI --> PB5, INT --> PA14, WOL --> PB11
I removed the SB12 connection from the back of the Discovery board. It connected the PB3 pin to the ST link part of the board and removed the ST-LINK jumpers…

Now the hardware parts works…

No I’m stuck at the following, the code keeps resetting the ENC28:

A first chance exception of type 'System.NotSupportedException' occurred in Microsoft.SPOT.IO.dll
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Executing a Complete RESET at 06/01/2011 00:09:29
The thread '<No Name>' (0x3) has exited with code 0 (0x0).
Link is now up : )
Status Vector = 0
Packets before restart: 1
Executing a Complete RESET at 06/01/2011 00:09:30
Poll Now
Packets after restart: 0
Link is now up : )
Status Vector = 63336
Packets before restart: 3
Executing a Complete RESET at 06/01/2011 00:09:30
Packets after restart: 0

Any clue as to what might be going on?

Very interesting. It looks like you are using the second release, v0.2. In the first release, it had a bad memory leak and I debated a few things with myself. Should I cap the number of connections and buffer, dropping packets when I hit the limit, or should I let the amount of memory you have on your device be your limit. I kind of settled on a hybrid for now. I capped the connections, added a connection timeout, but also decided to do a RESET if I started to run low on memory. This free memory minimum may be too high for some devices though, it’s hard-coded to 10k or 15k (can’t remember exactly). The reason it is so large is because I wanted to trigger the reset before I get an OutOfMemory Exception and 15k was a good number when the web server was getting hammered. Anyway, my first guess it you are hitting the memory minimum. Since it’s managed, you can put a break point on the line that prints “Executing a Complete RESET” and look at the if/then statement to see what condition caused it. Yay for Managed code! Also, you could put some statements in the code to see how much RAM you have, like this: Debug.WriteLine("Free Mem = " + Debug.GC(false));

Also, I have one of these discovery boards, but never used it. Maybe I’ll load up the firmware and try to reproduce this.

Also, WOL I don’t believe is implemented (although I think it’s just an option in the enc28j60). And, RESET should not be necessary.

Also, while the first version of mIP (v0.1) only ran for 15 minutes, the current version (v0.2) has run for 2 days, serving the sample page every 5 minutes.

Update: I just noticed there are 2 link up events! “Link is now up : )” That is suspicious. Like I mentioned above, put a breakpoint on the reset method and see what led to the reset. Also, you can just comment out the call to the reset() method. It is probably not actually necessary…


1 Like

Added the debug info:

[quote]Executing a Complete RESET at 06/01/2011 00:08:17
Packets after restart: 0
Link is now up :slight_smile:
Status Vector = 65535
Packets before restart: 1
Free Mem = 72300
ReceivedByteCount = 14208
Executing a Complete RESET at 06/01/2011 00:08:18
Packets after restart: 0
Link is now up :slight_smile:
Status Vector = 0
Packets before restart: 1
Free Mem = 72300
ReceivedByteCount = 0
Executing a Complete RESET at 06/01/2011 00:08:18
Packets after restart: 0
Link is now up :slight_smile:
Status Vector = 5
Packets before restart: 1
Free Mem = 72300
ReceivedByteCount = 12928
Executing a Complete RESET at 06/01/2011 00:08:19
Packets after restart: 0
Link is now up :slight_smile:
Status Vector = 2570
Packets before restart: 2
Free Mem = 70836
ReceivedByteCount = 0
Executing a Complete RESET at 06/01/2011 00:08:20
Packets after restart: 0
Link is now up :slight_smile:
Status Vector = 3585
Packets before restart: 1
Free Mem = 72300
ReceivedByteCount = 0
Executing a Complete RESET at 06/01/2011 00:08:20
Packets after restart: 0
Link is now up :slight_smile:
Status Vector = 20481
Packets before restart: 1
Free Mem = 70836
ReceivedByteCount = 0
Executing a Complete RESET at 06/01/2011 00:08:21
Packets after restart: 0
Link is now up :slight_smile:
Status Vector = 0
Packets before restart: 1
Free Mem = 70836
ReceivedByteCount = 0
Executing a Complete RESET at 06/01/2011 00:08:21
Packets after restart: 0
Link is now up :)[/quote]
Seems the received bytes is ‘way off’…

And when I run the version 0.1 it says: Verify that you have selected the correct InterfaceProfile in the Networking.Adapter.Start method

After removing the U9 chip from the board (using a cutter :S) that message dissapears… but still no connection possible (but also no debug messages)

Grmbl… seems I need to lay my hands on an ENC28 module and a cerberus board in order to determine where the problem resides… I could try switching the ethernet module…

There is something wrong with the interrupt on your enc28j60. Your output keeps showing “Link is now up :)”. That’s a big clue because it should only invoke that event for when the link has changed, but it is up every time… So it appears that the link has not changed, but according to the PHIR_PLNKIF register bit, it has changed… First, try a different port on your router and a different cable (probably won’t help).

Your enc28j60 controller could be a different rev and there are differences in the revs… There is a line commented out in the driver to get the RevID. Use that to get the Rev and I’ll check mine to see if there is a difference there… And, if there is, we can look at the errata for the revs to see if there is an issue with that register.

This is the code from the driver…

                // 12.1.5 -- Performing an MII read on the PHIR register will clear the LINKIF, PGIF and PLNKIF bits automatically
                var physicalInterruptRegister = ReadPhyReg(PHIR);

                bool linkChange = (physicalInterruptRegister & PHIR_PLNKIF) != 0;

                // now we can fire events
                if (linkChange && OnLinkChangedEvent != null) OnLinkChangedEvent.Invoke(this, time, IsLinkUp);

Alternatively, I could try to setup what you have there or you could ship yours to me…


I have the exact same setup here: discovery board + chinese ENC28J60 module, but mine does work:

Link is now up :slight_smile:
Setting IP Address to
DHCP SUCCESS! We have an IP Address!
Updating Gateway Mac from ARP
Local Name Request (LLMNR, Type A) for discovery
LLMNR Response sent

the ENC28J60 chip on my board has revision 6.

Excellent! Does it server up the default web page from a browser at http://mip.local ?
Also, what brand/model of router are you using for the DHCP?


How did you do the wiring? And how can you check the revision? I bought 3 of em, so I’ll replace the one I’m currently using to see if it’s broken.

@ Valkyrie-MT
It serves up the default webpage when i navigate to the device hostname (in my case http://discovery)
My router is a US Robotics USR5464 Wireless NDX router.

@ iwritecode
My wiring is done exactly like yours, which is as per the Cerb40_ENC28J60 InterfaceProfile.
I’ve also removed the SB12 solderbridge, but i left all IC’s ob the board.

You can uncomment and modify the code to print de revision register byte in void Restart():
ENCRevID = ReadEthReg(EREVID);
Debug.WriteLine("ENC28J60 Revision " + ENCRevID.ToString());

(Remember to also uncomment the declaration: private byte ENCRevID = 0x00;)

Hello guys,
good news…

I finally had the time to work on Upnp and i successfully opened a port on my Router’s firewall from my spider… and started a web server listening on that port… Yaaaaaaaaaaaayyyy

i will be cleaning up the code and add the other required functions… like deletePort and Discover the External IP and so on…

Edit: now i can delete the port as well… cool

next to do is Discover the external IP of the Router…


Fantastic! I also have more improvements after serving up pages from an SD card. I’ll be integrating those within the next week, but they should not conflict with this. Super!

thank you Valkyrie-MT,
and i’m making good progress here…

So far i have the following working:

  1. Discover if UPnP is enabled.
  2. Open Firewall ports
  3. remove the opened port.
  4. Get the external IP Address.

To Do:

  1. Listen to Broadcast and show the device as a Home Automation Device for example with a Presentation Web Page. (So far i can listen to Broadcasts successfully) now i just need to filter the data and reply back with the proper Soap xml…more research and readings…
  2. return a Proper Soap Error when we get invalid data from other UPnP devices.
  3. QueryStateVariable
  4. GetStatusInfo
  5. GetConnectionTypeInfo
  6. GetNATRSIPStatus
  7. GetGenericPortMappingEntry
  8. GetSpecificPortMappingEntry
  9. AddAnyPortMapping
  10. DeletePortMappingRange
  11. GetListOfPortMappings

and more…

now i do have questions for those who are going to be interested in this:
how do you think this library should constructed, should be made a class or an interface? since it will require info from the end user to configure the device…like device friendly name, presentation url and so on…quite a bit of info actually.

thank you.

I would lean toward a class. But, construct it such that a small change can disable the feature (in case someone needs the memory… let’s take advantage of having a managed stack!)
For Device Friendly name, can you use the Name Property of the Network.Adapter class? Maybe that is the default value?
Can Presentation URL just be contructed from the network adapter name? like http://adapterName

Those 4 features you have there will be fantastic!


A Class it is…

Everything the class will required is going to be in the form of a string (Property), so you can make it anything you want.
so for question 1: yes…
and question 2: yes


Post some examples of the library API you are planning so that we can review it.

Hi Gralin,
i most certainly will…
i just need to get the stuff working and once i have all of the above implemented i will post what i have…

So far i think the Class will be a singleton class since you can only have one single Control Point device started per device… this will avoid user starting multiple control points per device…

most required info will be added as fields i think instead of Properties… man i miss Custom Attributes i wish NetMF would include those in the future… still not sure which way to go yet…