Main Site Documentation

Trouble in shut down and restart of GHI.Premium.Net.EthernetENC28J60 in Cobra II


#1

In Cobra II project, I am trying to make my device fault tolerant by handling network socket exceptions and keep the code running after an exception. Upon getting a network exception, I want to shut down the ENC28 module and restart it. I get an exception when I try to shut down the ENC28, my shutdown function OnDisconnect() causes a pop up message window in Visual Studio, saying this:

“An unhandled exception of type ‘System.Exception’ occurred in GHI.Premium.Net.dll
Additional information: NetworkEventFlags: This should never happen!”

My shutdown code does this:



        using GHINET = GHI.Premium.Net;
        private GHINET.EthernetENC28J60 eth;

        private void OnDisconnect(object sender, EventArgs e)
        {
            try
            {
                if ( eth != null)
                {
                    GHINET.NetworkInterfaceExtension.AssignNetworkingStackTo(null);
                    if ( eth.IsOpen )  eth.Close();
                    eth.Dispose();
                    eth = null;
                }
            }
            catch (Exception ex)
            {
                Debug.Print("OnDisconnect() exception " + ex.Message);
            }
        }


My startup code does this:



        private NetworkInterface StartClient()
        {
            NetworkInterface ni = null;
            try
            {
                eth = new GHINET.EthernetENC28J60(SPI.SPI_module.SPI2, Pin.P1_10, Pin.P2_11, Pin.P1_9, 4000);
                eth.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(eth_NetworkAddressChanged);
                if (!eth.IsOpen) eth.Open();
                ni = eth.NetworkInterface;

                ni.EnableStaticIP(StaticIP, NetMask, GatewayAddress);
                ni.EnableStaticDns(new string[] {  PrimaryDNS, SecondaryDNS  });
               
                Debug.Print("Static IP enabled.");
                Debug.Print("IP address = " + ni.IPAddress);
                Debug.Print("Gateway address = " + ni.GatewayAddress);
                Debug.Print("Subnet mask = " + ni.SubnetMask);
                foreach (string address in ni.DnsAddresses)
                {
                    Debug.Print("DNS address  = " + address);
                }

                GHINET.NetworkInterfaceExtension.AssignNetworkingStackTo(eth);
            }
            catch (Exception ex)
            {
                Debug.Print("Start Client() exception " + ex.Message);
            }
            return ni;
        }


How can I shut down and re-start the GHI.Premium.Net.EthernetENC28J60 in Cobra II after a socket exception?


#2

@ dspacek - It seems as though you are disposing of the object properly, but your issue may be caused by the fact that you are disposing the object while it is actively referenced as ‘sender’ in the on disconnect. Could you try:

 
private static bool NetworkClosing = false;

private void OnDisconnect(object sender, EventArgs e)
        {
            try
            {
                if ( eth != null)
                   NetworkClosing = true;
            }
            catch (Exception ex)
            {
                Debug.Print("OnDisconnect() exception " + ex.Message);
            }
        }

private void CheckNetworkClosing()
{
    if(NetworkClosing)
    {
        GHINET.NetworkInterfaceExtension.AssignNetworkingStackTo(null);
        if ( eth.IsOpen )  eth.Close();
        eth.Dispose();
        eth = null;
        NetworkClosing = false;
    }
}


#3

Thanks, but that can’t be it. sender is a DeviceEngine object from the DeviceHive framework. I think I found a fix, but it may not be the best solution. I created an event object “NetworkShutDown” and wait for the event object to be set with NetworkShutDown.WaitOne(). The event object gets set in the eth_NetworkAddressChanged event handler, when the IP address becomes “0.0.0.0”. I hope this is the correct method.


        private AutoResetEvent NetworkShutDown = new AutoResetEvent(false);

        private void OnDisconnect(object sender, EventArgs e)
        {
            try
            {
                if ( eth != null)
                {
                    NetworkShutDown.Reset();
                    GHINET.NetworkInterfaceExtension.AssignNetworkingStackTo(null);
                    NetworkShutDown.WaitOne(10000, false);
                    if ( eth.IsOpen )  eth.Close();
                    eth.Dispose();
                    eth = null;
                }
            }
            catch (Exception ex)
            {
                Debug.Print("OnDisconnect() exception " + ex.Message);
            }
        }


        void eth_NetworkAddressChanged(object sender, EventArgs e)
        {
            NetworkInterface ni = eth.NetworkInterface;
            Debug.Print("Ethernet_NetworkAddressChanged Event");
            if (ni.IsDhcpEnabled)
                Debug.Print("DHCP is enabled");
            else
                Debug.Print("DHCP is disabled");
            Debug.Print("IP address = " + ni.IPAddress);
            Debug.Print("Gateway address = " + ni.GatewayAddress);
            Debug.Print("Subnet mask = " + ni.SubnetMask);

            foreach (string address in ni.DnsAddresses)
            {
                Debug.Print("DNS address  = " + address);
            }

            if (ni.IPAddress == "0.0.0.0")
            {
                NetworkShutDown.Set();
            }
        }