Cannot set network configuration with FEZConfig

I have a Cobra II and I want to use FEZConfig to set the network configuration, instead of in my code. The event handler Ethernet_NetworkAddressChanged() prints out the correct IP addresses but http communication does not work. Communication works only if I use the commented out code to set the IP addresses. Am I missing a function call to make the ENC28 module use the network settings stored by FEZConfig?


private NetworkInterface StartClient(string StaticIP)
        {
            EthernetENC28J60 Ethernet;
            Ethernet = ethernet_ENC28.Interface;
            Ethernet.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(Ethernet_NetworkAddressChanged);
            Ethernet.Open();

            if (!Ethernet.IsCableConnected)
            {
                Debug.Print("Network cable is not connected!");
            }

            NetworkInterface ni = Ethernet.NetworkInterface;
            
            //Commented out so that FEZConfig can set the network addresses
            /* 
            StaticIP = "192.168.8.202";
            if (StaticIP == string.Empty)
            {
                Debug.Print("Starting DHCP client.");
                if (ni.IsDhcpEnabled)
                    ni.RenewDhcpLease();
                else
                    ni.EnableDhcp();
                ni.EnableDynamicDns();
                Debug.Print("DHCP client started.");
            }
            else
            {
                Debug.Print("Using static IP.");
                ni.EnableStaticIP(StaticIP, NetMask, GatewayAddress);
                ni.EnableStaticDns(new string[] { "192.168.8.20", "192.168.8.23" });
                Debug.Print("Static IP enabled.");
            }
             */ 
            
            NetworkInterfaceExtension.AssignNetworkingStackTo(Ethernet);

            return ni;
        }

     void Ethernet_NetworkAddressChanged(object sender, EventArgs e)
        {
            NetworkInterface ni  = ethernet_ENC28.Interface.NetworkInterface;
            Debug.Print("Ethernet_NetworkAddressChanged Event");
            Debug.Print("From StartClient()");
            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);
            }

        }


I fixed the problem by reading the IP addersses from ethernet_ENC28.Interface.NetworkInterface and then writing the IP addresses back into ethernet_ENC28.Interface.NetworkInterface.




        private NetworkInterface StartClient(string StaticIP)
        {
            AddressChangedEvent = new AutoResetEvent(false);
            EthernetENC28J60 Ethernet;
            Ethernet = ethernet_ENC28.Interface;
            Ethernet.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(Ethernet_NetworkAddressChanged);
            Ethernet.Open();

            if (!Ethernet.IsCableConnected)
            {
                Debug.Print("Network cable is not connected!");
            }

            NetworkInterface ni = Ethernet.NetworkInterface;
            
            //Commented out so that FEZConfig can set the network addresses into flash memory
            /* 
            StaticIP = "192.168.8.202";
            if (StaticIP == string.Empty)
            {
                Debug.Print("Starting DHCP client.");
                if (ni.IsDhcpEnabled)
                    ni.RenewDhcpLease();
                else
                    ni.EnableDhcp();
                ni.EnableDynamicDns();
                Debug.Print("DHCP client started.");
            }
            else
            {
                Debug.Print("Using static IP.");
                ni.EnableStaticIP(StaticIP, NetMask, GatewayAddress);
                ni.EnableStaticDns(new string[] { "192.168.8.20", "192.168.8.23" });
                Debug.Print("Static IP enabled.");
            }
             */ 
            
            NetworkInterfaceExtension.AssignNetworkingStackTo(Ethernet);
            AddressChangedEvent.WaitOne();
            return ni;
        }

        void Ethernet_NetworkAddressChanged(object sender, EventArgs e)
        {
            //Print the IP addresses stored in flash memory created by FEZConfig
            NetworkInterface ni  = ethernet_ENC28.Interface.NetworkInterface;
            Debug.Print("Ethernet_NetworkAddressChanged Event");
            Debug.Print("From StartClient()");
            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);
            }

            //In order to get http communication started, the addresses read from flash memory
            //must be written back to their objects where they were read from. Crazy.
            ni.EnableStaticIP(ni.IPAddress, ni.SubnetMask, ni.GatewayAddress);
            ni.EnableStaticDns(ni.DnsAddresses);
            AddressChangedEvent.Set();
        }

@ dspacek -

It looks like you have 2 EthernetENC28J60 objects, one from gadgeteer which is opened already, and you declare one more as a local variable and open again.

Try to use only one of them or show full code, we don’t know what you did with ethernet_ENC28 before.

I don’t see how I could have two EthernetENC28J60 objects. My ethernet_ENC28 object was passed into the class where it appears by the constructor parameter. The object originated from the program.generated.cs produced by the Gadgeteer Visual Studio template, so there is only one object instantiated. I will show all of my code:



program.generated.cs

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.18052
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace FEZCobra2Device {
    using Gadgeteer;
    using GTM = Gadgeteer.Modules;
    
    
    public partial class Program : Gadgeteer.Program {
        
        /// <summary>The Button module using socket 5 of the mainboard.</summary>
        private Gadgeteer.Modules.GHIElectronics.Button button;
        
        /// <summary>The Ethernet_ENC28  (Premium) module using socket 6 of the mainboard.</summary>
        private Gadgeteer.Modules.GHIElectronics.Ethernet_ENC28 ethernet_ENC28;
        
        /// <summary>This property provides access to the Mainboard API. This is normally not necessary for an end user program.</summary>
        protected new static GHIElectronics.Gadgeteer.FEZCobra_II Mainboard {
            get {
                return ((GHIElectronics.Gadgeteer.FEZCobra_II)(Gadgeteer.Program.Mainboard));
            }
            set {
                Gadgeteer.Program.Mainboard = value;
            }
        }
        
        /// <summary>This method runs automatically when the device is powered, and calls ProgramStarted.</summary>
        public static void Main() {
            // Important to initialize the Mainboard first
            Program.Mainboard = new GHIElectronics.Gadgeteer.FEZCobra_II();
            Program p = new Program();
            p.InitializeModules();
            p.ProgramStarted();
            // Starts Dispatcher
            p.Run();
        }
        
        private void InitializeModules() {
            this.button = new GTM.GHIElectronics.Button(5);
            this.ethernet_ENC28 = new GTM.GHIElectronics.Ethernet_ENC28(6);
        }
    }
}

Program.cs

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 Microsoft.SPOT.Hardware;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
using GHI.Hardware.G120;

namespace FEZCobra2Device
{
    public partial class Program
    {
        /// <summary>
        ///This method is run when the mainboard is powered up or reset.    
        /// </summary>
        /// 

        void ProgramStarted()
        {

            /*******************************************************************************************
            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();
            *******************************************************************************************/


            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
            try
            {
                ThreadStart starter = new ThreadStart(ProcessCommandsLoop);
                Thread th = new Thread(starter);
                th.Start();
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }


        /// <summary>
        /// Endless loop to poll for commands from the DeviceHive server. This must be in a thread so that
        /// the main thread is not blocked and the GHI dispatcher runs to service Gadgeteer devices.
        /// </summary>
        void ProcessCommandsLoop()
        {
            try
            {
                bool rv = false;
                PrototypeDevice Cobra;
                Debug.Print("Command processing has started");
                Cobra = new PrototypeDevice(ethernet_ENC28, button, Mainboard);
                Cobra.Init();
                do
                {
                    rv = Cobra.Connect();
                    while (rv)
                    {
                        rv = Cobra.ProcessCommands();
                    }
                }
                while (true);
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
            finally
            {
                Debug.Print("Command processing has exited");
            }
        }       

    }

}

prototypedevice.cs


using DeviceHive;
using DeviceHive.CommonEquipment;
using GHI.Premium.Hardware;
using GHI.Premium.Net;
//using GHI.Hardware.EMX;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net.NetworkInformation;
using System;
using System.Threading;
using Gadgeteer;
using GTM = Gadgeteer.Modules;
using GTME = Gadgeteer.Modules.GHIElectronics;

namespace FEZCobra2Device
{

    public class PrototypeDevice : DeviceEngine
    {
        private const string NetMask = "255.255.255.0";
        private const string GatewayAddress = "192.168.8.2";
        private const int RequestTimeout = 120000;
        private uint WatchDogTimeout; 
        private AutoResetEvent AddressChangedEvent;

        /// <summary>The Ethernet_ENC28  (Premium) module using socket 9 of the mainboard.</summary>
        private GTME.Ethernet_ENC28 ethernet_ENC28;
        /// <summary>The Button module using socket 11 of the mainboard.</summary>
        private GTME.Button button;
        /// <summary>The SDCard module using socket 5 of the mainboard.</summary>
        /// 
        private GHIElectronics.Gadgeteer.FEZCobra_II Mainboard;

        public PrototypeDevice(
            GTME.Ethernet_ENC28 _ethernet_ENC28,
            GTME.Button _button,
            GHIElectronics.Gadgeteer.FEZCobra_II _Mainboard
            )
        {
            ethernet_ENC28 = _ethernet_ENC28;
            button = _button;

            DcClient = new DeviceHive.HttpClient(Resources.GetString(Resources.StringResources.CloudUrl), RequestTimeout );

            Initializing += new ConnectEventHandler(PreInit);
            Connecting += new ConnectEventHandler(PreConnect);
            Connected += new ConnectEventHandler(PostConnect);
            BeforeCommand += new CommandEventHandler(PreProcessCommand);
            AfterCommand += new CommandEventHandler(PostProcessCommand);
            BeforeNotification += new NotificationEventHandler(PreProcessNotification);
            AfterNotification += new NotificationEventHandler(PostProcessNotification);
            Disconnected += new SimpleEventHandler(OnDisconnect);
            WatchDogTimeout = GHI.Premium.Hardware.LowLevel.Watchdog.MAX_TIMEOUT;   //300000;
            Mainboard = _Mainboard;
        }

        private bool PreInit(object sender, EventArgs e)
        {
            return true;
        }

        private bool PreConnect(object sender, EventArgs e)
        {
            if (StartClient(string.Empty) != null)
            {
                return true;
            }
            return false;
        }

        protected override Device CreateDeviceData()
        {
            Debug.Print("Initializing device data");
            
            Device dd = new Device()
            {
                deviceClass = new DeviceClass()
                {
                    name = Resources.GetString(Resources.StringResources.DeviceClass),
                    version = Resources.GetString(Resources.StringResources.Version),
                    offlineTimeout=0
                },
                id = new Guid(Resources.GetBytes(Resources.BinaryResources.guid)),
                key = Resources.GetString(Resources.StringResources.Key),
                name = Resources.GetString(Resources.StringResources.DeviceName),
                network = new DeviceNetwork()
                {
                    name = Resources.GetString(Resources.StringResources.Network),
                    description = Resources.GetString(Resources.StringResources.NetworkDesc)
                },
                status = DeviceStatus.OK,
                
            };
            
            Debug.Print("Done initializing device data.");
            return dd;
        }

        protected override void CreateEquipment()
        {
            Debug.Print("Initializing equipment.");

            ButtonLed led1 = new ButtonLed(this, button, "LED1", false);
            Ds18b20 SensorDevice = new Ds18b20();
            TempSensor ts = new TempSensor(this, "TS1", SensorDevice);

            DeviceData.equipment = new Equipment[]
            {
                led1,
                ts
            };
            Debug.Print("Initializing equipment done.");
        }

        private bool PostConnect(object sender, EventArgs e)
        {
            if (!System.Diagnostics.Debugger.IsAttached)
            {
                //Debug.Print("Watchdog timer enabed.");
                //GHI.Premium.Hardware.LowLevel.Watchdog.Enable(WatchDogTimeout);
            }
            return true;
        }

        public float Abs(float f)
        {
            return f < 0.0F ? -f : f;
        }

        public override bool ProcessCommands()
        {
            return base.ProcessCommands();
        }

        private void PreProcessCommand(object sender, CommandEventArgs e)
        {
            Mainboard.SetDebugLED(false);
        }

        private void PostProcessCommand(object sender, CommandEventArgs e)
        {
            GHI.Premium.Hardware.LowLevel.Watchdog.ResetCounter();
            Mainboard.SetDebugLED(true);
        }

        private void PreProcessNotification(object sender, NotificationEventArgs e)
        {
            Mainboard.SetDebugLED(true);
        }

        private void PostProcessNotification(object sender, NotificationEventArgs e)
        {
            GHI.Premium.Hardware.LowLevel.Watchdog.ResetCounter();
            Mainboard.SetDebugLED(false);
        }

        private void OnDisconnect(object sender, EventArgs e)
        {
        }

        private NetworkInterface StartClient(string StaticIP)
        {
            AddressChangedEvent = new AutoResetEvent(false);
            EthernetENC28J60 Ethernet;
            Ethernet = ethernet_ENC28.Interface;
            Ethernet.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(Ethernet_NetworkAddressChanged);
            Ethernet.Open();

            if (!Ethernet.IsCableConnected)
            {
                Debug.Print("Network cable is not connected!");
            }

            NetworkInterface ni = Ethernet.NetworkInterface;
            
            //Commented out so that FEZConfig can set the network addresses into flash memory
            /* 
            StaticIP = "192.168.8.202";
            if (StaticIP == string.Empty)
            {
                Debug.Print("Starting DHCP client.");
                if (ni.IsDhcpEnabled)
                    ni.RenewDhcpLease();
                else
                    ni.EnableDhcp();
                ni.EnableDynamicDns();
                Debug.Print("DHCP client started.");
            }
            else
            {
                Debug.Print("Using static IP.");
                ni.EnableStaticIP(StaticIP, NetMask, GatewayAddress);
                ni.EnableStaticDns(new string[] { "192.168.8.20", "192.168.8.23" });
                Debug.Print("Static IP enabled.");
            }
             */ 
            
            NetworkInterfaceExtension.AssignNetworkingStackTo(Ethernet);
            AddressChangedEvent.WaitOne();
            return ni;
        }

        void Ethernet_NetworkAddressChanged(object sender, EventArgs e)
        {
            //Print the IP addresses stored in flash memory created by FEZConfig
            NetworkInterface ni  = ethernet_ENC28.Interface.NetworkInterface;
            Debug.Print("Ethernet_NetworkAddressChanged Event");
            Debug.Print("From StartClient()");
            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);
            }

            //In order to get http communication started, the addresses read from flash memory
            //must be written back to their objects where they were read from. Crazy.
            ni.EnableStaticIP(ni.IPAddress, ni.SubnetMask, ni.GatewayAddress);
            ni.EnableStaticDns(ni.DnsAddresses);
            AddressChangedEvent.Set();
        }

    }
}