Hydra + ENC28 = Three network interfaces, none of them works

Hello Folks,
sorry to annoy, but I must report an error with firmware 4.3.7.9 of the Hydra+ - it, sadly, also occurred on 4.3.7.7. My circuit consists of an ENC28 module added to port 3, which is connected to a router.

When running the program, I get the following output from the Network Interface list - it looks as if my Gadgeteer has three network ports:

NetworkAvailabilityChanged: True
IF          : 6
IP          : 0.0.0.0
Mask        : 0.0.0.0
Gateway     : 0.0.0.0
DCHP Enable : True
IF          : 6
IP          : 192.168.0.100
Mask        : 255.255.255.0
Gateway     : 192.168.0.1
DCHP Enable : True
DNS         : 208.67.222.222
IF          : 71
IP          : 0.0.0.0
Mask        : 0.0.0.0
Gateway     : 0.0.0.0
DCHP Enable : True

While this may be but a cosmetic problem, the real crash occurs here:

        private void StartServerInternal()
        {
            while (true)
            {
                try
                {
                    Socket clientSocket = mySocket.Accept();
                    //Process connection
                    Debug.Print("Success");
                }
                catch (Exception e)
                {
                    Debug.Print("Exception E33");
                }
                
            }
        }

Even though the Hydra was provided with an IP adress from the router, invoking Accept() still yields a 10050 error as per below:

   #### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (6) ####
    #### Message: 
    #### Microsoft.SPOT.Net.SocketNative::poll [IP: 0000] ####
    #### System.Net.Sockets.Socket::Poll [IP: 0011] ####
    #### System.Net.Sockets.Socket::Accept [IP: 0017] ####
    #### NMGCustomProtocol.Program::StartServerInternal [IP: 000c] ####
    #### SocketException ErrorCode = 10050
    #### SocketException ErrorCode = 10050
Eine Ausnahme (erste Chance) des Typs "System.Net.Sockets.SocketException" ist in Microsoft.SPOT.Net.dll aufgetreten.
    #### SocketException ErrorCode = 10050
    #### SocketException ErrorCode = 10050

This is my full code:

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
using Microsoft.SPOT.Net.NetworkInformation;
using Microsoft.SPOT.Hardware;
using System.Net.Sockets;
using System.Net;

namespace NMGCustomProtocol
{
    public partial class Program
    {
        Object myLock;
        NetworkInterface myInterface;
        System.Net.Sockets.Socket mySocket;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {

            myLock = new Object();

            var item = NetworkInterface.GetAllNetworkInterfaces();

            var myMac = ethernetENC28.NetworkInterface.PhysicalAddress;

            Thread.Sleep(5000); //Notwenig, aber kA wieso


            ethernetENC28.UseDHCP();
            NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
            NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
            ethernetENC28.NetworkUp += ethernetENC28_NetworkUp;
            ethernetENC28.NetworkDown += ethernetENC28_NetworkDown;

            ethernetENC28.NetworkInterface.Open();

            ethernetENC28.UseThisNetworkInterface();

            while (!ethernetENC28.IsNetworkUp)
            {
                Thread.Sleep(250);
                Debug.Print("ZZZ");
            }


            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
            
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
            
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/
            GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
            timer.Tick += timer_Tick;
                timer.Start();

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

            mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 23);
            mySocket.Bind(localEndPoint);
            mySocket.Listen(2);
            new Thread(StartServerInternal).Start();

        }

        void timer_Tick(GT.Timer timer)
        {
           // Debug.Print("Lebe noch!" + ethernetENC28.NetworkInterface.IPAddress);
        }

        private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            lock (myLock)
            {
                foreach (var item in NetworkInterface.GetAllNetworkInterfaces())
                {
                    Debug.Print("IF-ID: " + item.NetworkInterfaceType);
                    Debug.Print("IP: " + item.IPAddress);
                }
            }
        }






        private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            Debug.Print("NetworkAvailabilityChanged: " + e.IsAvailable);

            if (e.IsAvailable)
            {
                foreach (var item in NetworkInterface.GetAllNetworkInterfaces())
                {
                    Debug.Print("IF          : " + item.NetworkInterfaceType);
                    Debug.Print("IP          : " + item.IPAddress);
                    Debug.Print("Mask        : " + item.SubnetMask);
                    Debug.Print("Gateway     : " + item.GatewayAddress);
                    Debug.Print("DCHP Enable : " + item.IsDhcpEnabled);
                    foreach (var dns in item.DnsAddresses)
                    {
                        Debug.Print("DNS         : " + dns);
                    }
                    if (item.IPAddress != "0.0.0.0")
                    {
                        myInterface = item;

  


                    }
                }
            }

        }

        private void StartServerInternal()
        {
            while (true)
            {
                try
                {
                    Socket clientSocket = mySocket.Accept();
                    //Process connection
                    Debug.Print("Success");
                }
                catch (Exception e)
                {
                    Debug.Print("Exception E33");
                }
                
            }
        }

        private void ethernetENC28_NetworkUp(GTM.Module.NetworkModule sender, GTM.Module.NetworkModule.NetworkState state)
        {
           Debug.Print("ENC-Verbindung aktiviert. IP-Adresse: " + ethernetENC28.NetworkInterface.IPAddress);
        }

        void ethernetENC28_NetworkDown(GTM.Module.NetworkModule sender, GTM.Module.NetworkModule.NetworkState state)
        {
           Debug.Print("ENC-Verbindung verloren. Kabelzustand: " + ethernetENC28.NetworkInterface.CableConnected);

        }
    }
}

To me, it looks as if the ethernetENC28 interface does never get the IP adress from the router, which is, instead, assigned to the “phantom” interface.

Anyone have any ideas for me?

Just stumbled across one more oddity in the logs, namely this.

NetworkAvailabilityChanged: True
IF          : 6
IP          : 0.0.0.0
Mask        : 0.0.0.0
Gateway     : 0.0.0.0
DCHP Enable : True
IF          : 6
IP          : 192.168.0.100
Mask        : 255.255.255.0
Gateway     : 192.168.0.1
DCHP Enable : True
DNS         : 208.67.222.222
IF          : 71
IP          : 0.0.0.0
Mask        : 0.0.0.0
Gateway     : 0.0.0.0
DCHP Enable : True
IF-ID: 6
IP: 0.0.0.0
IF-ID: 6
IP: 0.0.0.0
IF-ID: 71
IP: 0.0.0.0

Looks like the system first calls NetworkChange_NetworkAvailabilityChanged with the right IP, and thgen NetworkChange_NetworkAddressChanged with the wrong one

Oh, and one more truly odd thing. If I configure the Ethernet in the FEZ Config and DONT call UseDHCP, the process computer seems to fetch the IP automatically:

    public partial class Program
    {
        Object myLock;
        NetworkInterface myInterface;
        System.Net.Sockets.Socket mySocket;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {

            myLock = new Object();

            var item = NetworkInterface.GetAllNetworkInterfaces();

            var myMac = ethernetENC28.NetworkInterface.PhysicalAddress;

            Thread.Sleep(5000); //Notwenig, aber kA wieso


            //ethernetENC28.UseDHCP(); //NEVER invoke this!
            NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
            NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
            ethernetENC28.NetworkUp += ethernetENC28_NetworkUp;
            ethernetENC28.NetworkDown += ethernetENC28_NetworkDown;

Weird, weird…

P.S. Sorry for spamming…but I try to update this as I find out stuff.

never perform a waiting operation in the ProgramStarted method. Perform your initialization and get out. All sorts of funny things can happen if you do not exit. Wait for the network to become available through events.

Also, do not perform a wait in any event handler. If you want to loop, waiting for the network to become available, do it in a seperate thread.