Cellular Modem only works when debugging with visual studio

Hi John,

As you requested I used my Frontline protocol analyzer tool with an RS-232 Probe to intercept and record the communications on the serial connection between the board and the modem.

I have attached screen shots of the protocol analyzer output.

As you can see when I’m debugging and the code is working correctly we can see 2 IP ver4 frames are sent. When the board is not running in debug mode we do not see the IP ver4 frames on the wire.

It looks like all the PPP communications are working as expected both while debugging and not debugging. This seems to confirm my suspicion that the networking stack is not sending the Dns.GetHostEntry() requests on the active network interface unless I’m debugging. And this is the reason why we don’t see the IP ver4 frames.

If you’d like I can send you the protocol analyzer output files and you can look through the raw data for any issues, but I suspect the issue is not the communications on the serial port, but rather the network stack not sending traffic on the correct interface when running without the debugger.

Here is the code I’m running for reference:

using Gadgeteer;
using GHI.Networking;
using Microsoft.SPOT;
using Microsoft.SPOT.Net.NetworkInformation;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Net;

public class Program
{
    private static AutoResetEvent evt;

    private static void Main()
    {
        Thread.Sleep(10000);

        evt = new AutoResetEvent(false);

        NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;

        using (var port = new SerialPort("COM2", 115200, Parity.None, 8, StopBits.One))
        {
            port.ReadTimeout = 100;
            port.Handshake = Handshake.RequestToSend;
            port.Open();
            port.DiscardInBuffer();
            port.DiscardOutBuffer();

            //SendATCommand(port, "AT+CGDCONT=2,\"IP\",\"YOUR APN\"");
            //SendATCommand(port, "ATDT*99***2#");
            SendATCommand(port, "ATD#777");

            using (var netif = new PPPSerialModem(port))
            {
                netif.Open();
                netif.Connect(PPPSerialModem.AuthenticationType.Pap, "", "");

                evt.WaitOne();

                while (netif.IPAddress == "0.0.0.0")
                {
                    Thread.Sleep(100);
                }

                Debug.Print(string.Concat("The IP Address is: ", netif.IPAddress));

                //The network is now ready to use.
                var dnsEntry = Dns.GetHostEntry("google.com");
                Debug.Print(string.Concat("Host Entry: ", dnsEntry.AddressList[0].ToString()));
            }
        }
    }

    private static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
    {
        if (e.IsAvailable)
            evt.Set();
    }

    private static void SendATCommand(SerialPort port, string command)
    {
        var sendBuffer = Encoding.UTF8.GetBytes(command + "\r");
        var readBuffer = new byte[256];
        var read = 0;

        port.Write(sendBuffer, 0, sendBuffer.Length);

        while (true)
        {
            read += port.Read(readBuffer, read, readBuffer.Length - read);

            var response = new string(Encoding.UTF8.GetChars(readBuffer, 0, read));

            if (response.IndexOf("OK") != -1 || response.IndexOf("CONNECT") != -1)
                break;
        }
    }
}

The error which happens when not debugging and we don’t’ see any IP ver4 frames on the wire.

[quote]Connecting to EMX_Gadgeteer…Connected
Created EE.
The IP Address is: 75.237.30.69
#### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (1) ####
#### Message:
#### Microsoft.SPOT.Net.SocketNative::getaddrinfo [IP: 0000] ####
#### System.Net.Dns::GetHostEntry [IP: 0008] ####
#### Program::Main [IP: 009b] ####
#### SocketException ErrorCode = 10060
Uncaught exception
Done.[/quote]

@ PhilH - Thanks for the traces, you don’t have to send them. It sounds like there is a race condition where debugging slows the board down enough to let it function. Can you add a sleep of five seconds after you get the IP address? Like below:


using Gadgeteer;
using GHI.Networking;
using Microsoft.SPOT;
using Microsoft.SPOT.Net.NetworkInformation;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Net;

public class Program
{
     private static AutoResetEvent evt;

     private static void Main()
     {
         Thread.Sleep(10000);

         evt = new AutoResetEvent(false);

         NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;

         using (var port = new SerialPort("COM2", 115200, Parity.None, 8, StopBits.One))
         {
             port.ReadTimeout = 100;
             port.Handshake = Handshake.RequestToSend;
             port.Open();
             port.DiscardInBuffer();
             port.DiscardOutBuffer();

             //SendATCommand(port, "AT+CGDCONT=2,\"IP\",\"YOUR APN\"");
             //SendATCommand(port, "ATDT*99***2#");
             SendATCommand(port, "ATD#777");

             using (var netif = new PPPSerialModem(port))
             {
                 netif.Open();
                 netif.Connect(PPPSerialModem.AuthenticationType.Pap, "", "");

                 evt.WaitOne();

                 while (netif.IPAddress == "0.0.0.0")
                 {
                     Thread.Sleep(100);
                 }

                 Debug.Print(string.Concat("The IP Address is: ", netif.IPAddress));   

                 Thread.Sleep(5000);

                 //The network is now ready to use.
                 var dnsEntry = Dns.GetHostEntry("google.com");
                 Debug.Print(string.Concat("Host Entry: ", dnsEntry.AddressList[0].ToString()));
             }
         }
     }

     private static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
     {
         if (e.IsAvailable)
             evt.Set();
     }

     private static void SendATCommand(SerialPort port, string command)
     {
         var sendBuffer = Encoding.UTF8.GetBytes(command + "\r");
         var readBuffer = new byte[256];
         var read = 0;

         port.Write(sendBuffer, 0, sendBuffer.Length);

         while (true)
         {
             read += port.Read(readBuffer, read, readBuffer.Length - read);

             var response = new string(Encoding.UTF8.GetChars(readBuffer, 0, read));

             if (response.IndexOf("OK") != -1 || response.IndexOf("CONNECT") != -1)
                 break;
         }
     }
}

Hi John,

I added the additional sleep for 5 seconds as you requested. I still see the SocketException when running without debugging.

With Debugging:

[quote]The thread ‘’ (0x2) has exited with code 0 (0x0).
The IP Address is: 75.227.123.250
Host Entry: 173.194.219.100
The thread ‘’ (0x1) has exited with code 0 (0x0).
Done.
The program ‘[1] Micro Framework application: Managed’ has exited with code 0 (0x0).[/quote]
Without Debugging:

[quote]Ready.
The IP Address is: 75.236.233.55
#### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (1) ####
#### Message:
#### Microsoft.SPOT.Net.SocketNative::getaddrinfo [IP: 0000] ####
#### System.Net.Dns::GetHostEntry [IP: 0008] ####
#### Program::Main [IP: 00a4] ####
#### SocketException ErrorCode = 10060
Uncaught exception
Done.[/quote]

Hello,

With the 2015 R1 pre-release SDK I’m still having the same issue with the spider board

However, now that the raptor serial port handshake issue has been resolved I gave this code a run on the raptor and I do not have the same issue. The raptor is able to use the modem without Visual Studio attached in debug mode and everything works as expected.

As far as I can tell this seems to be an issue with the spider board specifically. Again with the spider attached to Visual Studio and actively debugging everything works as expected. When the board runs without Visual Studio attached networking does not work at all and I just get the errors shown in the earlier posts in this thread.

Thanks,

Phil

Hi there,

I´m having exactly the same problem, but I really need to solve it. Did you have any news with this?.

[11:52:05 p. m. 4/09/2015] Connecting to EMX_Gadgeteer…Connected
[11:52:05 p. m. 4/09/2015] Created EE.
[11:52:05 p. m. 4/09/2015] Program Started
[11:52:05 p. m. 4/09/2015] Network Down Event - Down
[11:52:06 p. m. 4/09/2015] Gprs Network Registration Changed - Registration Denied
[11:52:45 p. m. 4/09/2015] Gprs Network Registration Changed - Not Searching
[11:52:52 p. m. 4/09/2015] Gprs Network Registration Changed - Registered
[11:52:55 p. m. 4/09/2015] #### Exception System.Threading.ThreadAbortException - 0x00000000 (5) ####
[11:52:55 p. m. 4/09/2015] #### Message:
[11:52:55 p. m. 4/09/2015] #### System.Threading.Thread::Sleep [IP: 0000] ####
[11:52:55 p. m. 4/09/2015] #### Gadgeteer.Modules.GHIElectronics.CellularRadio::DoWork [IP: 0012] ####
[11:53:18 p. m. 4/09/2015] Network Up Event - Up 191.108.99.189
[11:53:18 p. m. 4/09/2015] IP Address: 191.108.99.189
[11:53:18 p. m. 4/09/2015] Gateway Address: 192.200.1.21
[11:53:48 p. m. 4/09/2015] #### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (1) ####
[11:53:48 p. m. 4/09/2015] #### Message:
[11:53:48 p. m. 4/09/2015] #### Microsoft.SPOT.Net.SocketNative::getaddrinfo [IP: 0000] ####
[11:53:48 p. m. 4/09/2015] #### System.Net.Dns::GetHostEntry [IP: 0008] ####
[11:53:48 p. m. 4/09/2015] #### ConnectTheDotsGadgeteer.Program::NTPTime [IP: 0008] ####
[11:53:48 p. m. 4/09/2015] #### ConnectTheDotsGadgeteer.Program::cellularRadio_NetworkUp [IP: 007e] ####
[11:53:48 p. m. 4/09/2015] #### Gadgeteer.Modules.Module+NetworkModule::OnNetworkEvent [IP: 004d] ####
[11:53:48 p. m. 4/09/2015] #### System.Reflection.MethodBase::Invoke [IP: 0000] ####
[11:53:48 p. m. 4/09/2015] #### Gadgeteer.Program::DoOperation [IP: 001a] ####
[11:53:48 p. m. 4/09/2015] #### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 0054] ####
[11:53:48 p. m. 4/09/2015] #### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001a] ####
[11:53:48 p. m. 4/09/2015] #### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
[11:53:48 p. m. 4/09/2015] #### Gadgeteer.Program::Run [IP: 001d] ####
[11:53:48 p. m. 4/09/2015] #### SocketException ErrorCode = 10060
[11:53:48 p. m. 4/09/2015] #### Exception System.NullReferenceException - CLR_E_NULL_REFERENCE (1) ####
[11:53:48 p. m. 4/09/2015] #### Message:
[11:53:48 p. m. 4/09/2015] #### ConnectTheDotsGadgeteer.Program::NTPTime [IP: 0104] ####
[11:53:48 p. m. 4/09/2015] #### ConnectTheDotsGadgeteer.Program::cellularRadio_NetworkUp [IP: 007e] ####
[11:53:48 p. m. 4/09/2015] #### Gadgeteer.Modules.Module+NetworkModule::OnNetworkEvent [IP: 004d] ####
[11:53:48 p. m. 4/09/2015] #### System.Reflection.MethodBase::Invoke [IP: 0000] ####
[11:53:48 p. m. 4/09/2015] #### Gadgeteer.Program::DoOperation [IP: 001a] ####
[11:53:48 p. m. 4/09/2015] #### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 0054] ####
[11:53:48 p. m. 4/09/2015] #### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001a] ####
[11:53:48 p. m. 4/09/2015] #### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
[11:53:48 p. m. 4/09/2015] #### Gadgeteer.Program::Run [IP: 001d] ####
[11:53:48 p. m. 4/09/2015] Time: 06/01/2011 00:01:51
[11:53:53 p. m. 4/09/2015] LWIP Assertion “DNS response for wrong host name” failed at line 1552 in C:\MicroFrameworkPK_v4_3\DeviceCode\pal\lwip\lwip\src\api\api_msg.c
[11:54:18 p. m. 4/09/2015] #### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (1) ####
[11:54:18 p. m. 4/09/2015] #### Message:
[11:54:18 p. m. 4/09/2015] #### Microsoft.SPOT.Net.SocketNative::getaddrinfo [IP: 0000] ####
[11:54:18 p. m. 4/09/2015] #### System.Net.Dns::GetHostEntry [IP: 0008] ####
[11:54:18 p. m. 4/09/2015] #### Amqp.TcpTransport::Connect [IP: 0007] ####
[11:54:18 p. m. 4/09/2015] #### Amqp.Connection::Connect [IP: 0010] ####
[11:54:18 p. m. 4/09/2015] #### Amqp.Connection::.ctor [IP: 0016] ####
[11:54:18 p. m. 4/09/2015] #### Amqp.Connection::.ctor [IP: 0008] ####
[11:54:18 p. m. 4/09/2015] #### ConnectTheDotsGadgeteer.Program::InitAMQPconnection [IP: 0013] ####
[11:54:18 p. m. 4/09/2015] #### Gadgeteer.Modules.Module+NetworkModule::OnNetworkEvent [IP: 004d] ####
[11:54:18 p. m. 4/09/2015] #### System.Reflection.MethodBase::Invoke [IP: 0000] ####
[11:54:18 p. m. 4/09/2015] #### Gadgeteer.Program::DoOperation [IP: 001a] ####
[11:54:18 p. m. 4/09/2015] #### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 0054] ####
[11:54:18 p. m. 4/09/2015] #### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001a] ####
[11:54:18 p. m. 4/09/2015] #### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
[11:54:18 p. m. 4/09/2015] #### Gadgeteer.Program::Run [IP: 001d] ####
[11:54:18 p. m. 4/09/2015] #### SocketException ErrorCode = 10060
[11:54:18 p. m. 4/09/2015] Error invoking method “Gadgeteer.Modules.Module+NetworkModule” (check arguments to Program.BeginInvoke are correct)

Thanks.

Having the debugger attached or not attached significantly changes the speed at which your program runs, and changes thread task switching order, so this is almost always related to race conditions and deadlocks.

John’s advice is sound - did you add the Sleep? Are you sure you stopped all your other threads from going forward until 5 seconds after IP acquisition? Get the network established and do the delay before spawning other tasks. If 5s doesn’t do it, try longer.

It sounds like John identified the cause (and hopefully, they will guard against it in a future release), but until then you are going to need to fiddle around to get the timing right when not under the debugger.

1 Like

Hi and thanks for the response,

Here is the code:

private void cellularRadio_NetworkUp(GTM.Module.NetworkModule sender,
            GTM.Module.NetworkModule.NetworkState state)
        {
            switch (state)
            {
                case GTM.Module.NetworkModule.NetworkState.Down:
                    Debug.Print("Network Up Event - Down");
                    _timer.Stop();
                    break;
                case GTM.Module.NetworkModule.NetworkState.Up:
                    Thread.Sleep(75000);
                    Debug.Print("Network Up Event - Up " + cellularRadio.NetworkInterface.IPAddress);

                    if (cellularRadio.NetworkInterface.IPAddress != "0.0.0.0")
                    {
                        //have a PPP connection and valid IP address
                        
                        Debug.Print("IP Address: " + cellularRadio.NetworkInterface.IPAddress);
                        Debug.Print("Gateway Address: " + cellularRadio.NetworkInterface.GatewayAddress);
                        
                        foreach (var dns in cellularRadio.NetworkInterface.DnsAddresses)
                        {
                            Debug.Print("DNS Address: " + dns);
                        }

                        

                        // get Internet Time using NTP
                        NTPTime("time.windows.com", -360);
                        Debug.Print("Time: " + DateTime.Now);

                        // Initialize AMQP _connection with Azure Event Hub
                        InitAMQPconnection();

                        //start collecting and sending data to Azure.
                        _timer.Start();
                    }
                    break;
            }
        }

As you can see I´m trying to delay as you mentioned. The point is where should I put the delay and how to debug (the biggest delay, the shortest delay, some technique?).

Thanks a lot.

Hey everyone. Not sure how the resolution missed this topic, but this was an identified and resolved issue. Download the latest SDK and the problem is resolved.

Thanks,

Phil

1 Like

Hi PhillH,

You were totally corrrect. As soon as I updated to the new SDK it started to work!!!.

Thanks a lot!!

Can you specify the latest version of the SDK? Is it GHI Electronics NETMF SDK 2015 R1.exe?

@ elissard - Correct