Cellular Modem only works when debugging with visual studio

Hello,

I’m using a FEZ spider board with a MultiConnect Cell 100 Series MTC-EV3 modem. My code works fine and I’m able to establish a cellular connection and send and receive data through the cellular connection when I’m running the code while attached to the board via USB through the visual studio debugger. However, when I try to run the board alone without the USB cable and visual studio debugger plugged into the board every network request fails with a System.Net.WebException. The rest of the code seems to work properly.

I don’t think the issue is related to the modem itself, I’ve added debug statements to print to a log file each step of the process. The modem establishes a connection properly and I do get an IP address and gateway assigned by the cellular network. The code fails when I try to send a HttpWebRequest on the connection, but only when the board isn’t attached to the computer.

Sometimes in the log I just see the exception as “System.Net.WebException” other times I see it as “System.Net.WebException: host not available”. A bit of research points to the “host not available” as a DNS issue.

Why would the code work fine when the debugger is attached but get an exception when the debugger isn’t attached? This doesn’t make any sense to me. The board should be running exactly the same code when not debugging so why does it fail when I run the board by itself? Has anyone had a problem like this? If so any suggestions how to fix the issue?

Thanks,

Phil

the devices startup faster without a USB attachment. you have an initialization race condition which you win with USB and lose without it.

Could it be the extra power provided by the usb connection? Cellular is power hungry.

Feels more like a framework issue. The board initialization is way past complete by the time I bring up the cellular connection with the modem. And I know the modem is connecting because I get a valid IP address and gateway from the cellular network. Its the HttpWebRequest that fails. That method is in the framework, not my code, and it works while debugging.

I get a NetworkAddressChanged event and a NetworkAvailabilityChanged event so I know the framework detects the connection and at least tries to switch the active network interface over to interface 3. But all network calls on the interface fail unless I’m debugging. I’m wondering if something is munged in the interface switch.

The problem I’m having now is that the exception is useless “System.Net.WebException: host not available” isn’t very helpful and when I debug it doesn’t happen at all…

The error suggests a DNS issue, but why would DNS work when I’m debugging but not when I’m running the board stand alone.

I’m powering the modem on its power supply and the board is also powered by a 12v 1.5A power supply seperate from the USB cable during debugging and when running without the USB cable.

The error I’m getting from the request is:
System.Net.WebException
Inner Exception is: System.Net.WebException: host not available
Inner Inner Exception is: System.Net.Sockets.SocketException

This has to be something with the framework only works when the debugger is attached.

If the code only works when the debugger is listening is there some way I can fool the board into thinking the debugger is attached?

Is there a event I can subscribe to which will give me the debugger output? Or some other way to emulate having the debugger listening?

since this doesn’t sound like a common issue (nobody else has reinforced they see the issue, and I don’t recall this coming up explicitly before), I don’t think you can make the claim that it’s the framework…

As Mike said, this appears timing related. Debugging slows down many things as it spews out text to the PC.

Why not use Serial Debug and get content in MFDeploy and see if that changes things?

Why not test for general network connectivity and DNS resolution as well ?

Hi Brett,

I used MFDeploy to grab the full exception message when running without debug.

#### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (8) ####
#### Message: 
#### Microsoft.SPOT.Net.SocketNative::getaddrinfo [IP: 0000] ####
#### System.Net.Dns::GetHostEntry [IP: 0008] ####
#### System.Net.HttpWebRequest::EstablishConnection [IP: 00e1] ####
#### System.Net.HttpWebRequest::SubmitRequest [IP: 0019] ####
#### System.Net.HttpWebRequest::GetResponse [IP: 000c] ####
#### T2.AutoCount.AutoCount::SetTime [IP: 0083] ####
#### T2.AutoCount.Utility.ThreadPool::ActionConsumer [IP: 0057] ####
#### SocketException ErrorCode = 10060
#### Exception System.Net.WebException - 0x00000000 (8) ####
#### Message: host not available
#### System.Net.HttpWebRequest::EstablishConnection [IP: 00f1] ####
#### System.Net.HttpWebRequest::SubmitRequest [IP: 0019] ####
#### System.Net.HttpWebRequest::GetResponse [IP: 000c] ####
#### T2.AutoCount.AutoCount::SetTime [IP: 0083] ####
#### T2.AutoCount.Utility.ThreadPool::ActionConsumer [IP: 0057] ####
#### Exception System.Net.WebException - 0x00000000 (8) ####
#### Message: 
#### System.Net.HttpWebRequest::GetResponse [IP: 00d3] ####
#### T2.AutoCount.AutoCount::SetTime [IP: 0083] ####
#### T2.AutoCount.Utility.ThreadPool::ActionConsumer [IP: 0057] ####

As far as general network connectivity I have to assume that is working, I receive a NetworkAddressChanged event and a NetworkAvailabilityChanged event and when I check the NetworkInterface 3 I see a valid public IP address and a default gateway has been assigned to the interface by DHCP. But every networking call fails with the SocketException.

I did test DNS resolution with Dns.GetHostEntry, that call also fails with a Socket Exception when I try it without the debugger. With the debugger it works fine and I get the correct DNS entry.

I understand the debugger is slowing down execution, but all I’m doing is calling GetResponse() on a HttpWebRequest, and it works when debugging but not when running without the debugger. So maybe it is a timing issue, but I’m only doing 1 thing and waiting for the response so it must be timing inside the framework.

Do you know if there is a way I can “attach” to the debugger though a code interface like an event handler or something? Or is there some other way I can slow execution?

I’ve created a simple program to demonstrate the problem.

using Gadgeteer.Networking;
using GHI.Networking;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Net.NetworkInformation;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using System;
using System.Collections;
using System.IO;
using System.IO.Ports;
using System.Net;
using System.Text;
using System.Threading;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;

namespace ModemTest
{
    public partial class Program
    {
        private SerialPort port;
        private PPPSerialModem modem;

        private void ProgramStarted()
        {
            Debug.Print("Program Started");

            NetworkChange.NetworkAvailabilityChanged += (x, y) => { Debug.Print("Network Available: " + y.IsAvailable); };
            NetworkChange.NetworkAddressChanged += (x, y) => { Debug.Print("Network Address Changed: " + Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[3].IPAddress); };

            //Port is a K socket UART with handshake.
            string serialPortName = GT.Socket.GetSocket(4, false, null, "").SerialPortName;
            port = new SerialPort(serialPortName, 115200, Parity.None, 8, StopBits.One);
            port.Handshake = Handshake.RequestToSend;
            port.ReadTimeout = 100;
            port.Open();
            port.DiscardInBuffer();
            port.DiscardOutBuffer();

            modem = new PPPSerialModem(port);

            new Thread(Work).Start();
        }

        private void Work()
        {
            Thread.Sleep(10000);
            Debug.Print("Thread Start");

            var netIf = NetworkInterface.GetAllNetworkInterfaces()[3];
            if (netIf.IsDynamicDnsEnabled)
                netIf.EnableStaticDns(new string[] { "198.224.152.119", "198.224.154.135" });

            try
            {
                SendATCommand("ATE0", 1000);
                SendATCommand("AT+CSQ", 1000);
                SendATCommand("AT+CREG?", 2000);
                SendATCommand("ATD#777", 40000);

                try
                {
                    modem.Open();
                    modem.Connect(PPPSerialModem.AuthenticationType.Pap, "", "");

                    Thread.Sleep(5000);

                    if (modem.LinkConnected)
                    {
                        var activeInterface = BaseInterface.ActiveInterface;

                        Debug.Print("Active Interface");
                        Debug.Print(string.Concat("Modem IP: ", activeInterface.IPAddress));
                        Debug.Print(string.Concat("Modem Gateway: ", activeInterface.GatewayAddress));
                        Debug.Print(string.Concat("Modem Mask: ", activeInterface.SubnetMask));
                        Debug.Print(string.Concat("Modem DHCP Enabled: ", activeInterface.IsDhcpEnabled));
                        Debug.Print(string.Concat("Modem Dynamic DNS Enabled: ", activeInterface.IsDynamicDnsEnabled));

                        var dnsAddrs = activeInterface.DnsAddresses;
                        for (int j = 0; j < dnsAddrs.Length; j++)
                        {
                            var dns = dnsAddrs[j];
                            Debug.Print(string.Concat("Modem DNS ", j, ": ", dns));
                        }

                        HTTPRequest();

                        modem.Disconnect();
                        modem.Close();
                    }
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.ToString());
                }

                SendATCommand("+++", 5000);
                SendATCommand("ATH", 3000);
                SendATCommand("+++", 5000);
            }
            catch (Exception ex)
            {
                Debug.Print(ex.ToString());
            } 
            finally
            {
                Thread.Sleep(10000);
            }

            if (modem.Opened)
                modem.Close();

            port.Close();

            Debug.Print("Thread End");
        }

        private ModemCommandStatus SendATCommand(string command, int maxWaitTime)
        {
            Debug.Print("Sending Command: " + command);

            if (command != "+++")
                command += "\r";

            WriteToModem(command);

            DateTime cmdExpiration = DateTime.Now.AddMilliseconds(maxWaitTime);
            ModemCommandStatus modemResponse = ModemCommandStatus.Unknown;
            byte[] readBuffer = new byte[0];
            while (DateTime.Now < cmdExpiration)
            {
                Thread.Sleep(0);

                if (port.BytesToRead > 0)
                {
                    byte[] modemBuffer = new byte[port.BytesToRead];
                    int bytesRead = port.Read(modemBuffer, 0, modemBuffer.Length);
                    byte[] tempBuffer = new byte[readBuffer.Length];
                    Array.Copy(readBuffer, tempBuffer, readBuffer.Length);
                    readBuffer = new byte[tempBuffer.Length + modemBuffer.Length];
                    Array.Copy(tempBuffer, readBuffer, tempBuffer.Length);
                    Array.Copy(modemBuffer, 0, readBuffer, tempBuffer.Length, modemBuffer.Length);

                    modemResponse = GetResponse(ref readBuffer);
                    if (modemResponse != ModemCommandStatus.Unknown)
                        break;
                }
            }

            Thread.Sleep(20);

            string responseText = "UNKNOWN";
            switch (modemResponse)
            {
                case ModemCommandStatus.Success:
                    responseText = "OK";
                    break;
                case ModemCommandStatus.Connect:
                    responseText = "CONNECT";
                    break;
                case ModemCommandStatus.NoCarrier:
                    responseText = "NO CARRIER";
                    break;
                case ModemCommandStatus.Error:
                    responseText = "ERROR";
                    break;

            }

            Debug.Print("Modem Response: " + responseText);

            return modemResponse;     
        }

        private ModemCommandStatus GetResponse(ref byte[] data)
        {
            ModemCommandStatus status = ModemCommandStatus.Unknown;

            if (FindMatch(data, new byte[] { 13, 10, 79, 75, 13, 10 }) > -1) //\r\nOK\r\n
            {
                status = ModemCommandStatus.Success;
            }
            else if (FindMatch(data, new byte[] { 13, 10, 69, 82, 82, 79, 82, 13, 10 }) > -1) //\r\nERROR\r\n
            {
                status = ModemCommandStatus.Error;
            }
            else if (FindMatch(data, new byte[] { 13, 10, 67, 79, 78, 78, 69, 67, 84 }) > -1) //\r\nCONNECT
            {
                status = ModemCommandStatus.Connect;
            }
            else if (FindMatch(data, new byte[] { 13, 10, 78, 79, 32, 67, 65, 82, 82, 73, 69, 82, 13, 10 }) > -1) //\r\nNO CARRIER\r\n
            {
                status = ModemCommandStatus.NoCarrier;
            }

            return status;
        }

        public int FindMatch(byte[] buffer, byte[] pattern)
        {
            if (buffer != null && pattern != null && buffer.Length != 0 && pattern.Length != 0 && pattern.Length <= buffer.Length)
            {
                int resumeIndex;
                for (int i = 0; i <= buffer.Length - pattern.Length; i++)
                {
                    if (buffer[i] == pattern[0]) 
                    {
                        resumeIndex = 0;
                        for (int x = 1; x < pattern.Length; x++)
                        {
                            if (buffer[i + x] == pattern[x])
                            {
                                if (x == pattern.Length - 1) 
                                    return i;
                                else if (resumeIndex == 0 && buffer[i + x] == pattern[0])
                                    resumeIndex = i + x;
                            }
                            else
                            {
                                if (resumeIndex > 0)
                                    i = resumeIndex - 1; 
                                else if (x > 1)
                                    i += (x - 1);
                                break;
                            }
                        }
                    }
                }
            }
            return -1;
        }

        public enum ModemCommandStatus
        {
            Success,
            Connect,
            NoCarrier,
            Error,
            Unknown
        }

        private void WriteToModem(string command)
        {
            var sendBuffer = Encoding.UTF8.GetBytes(command);
            port.Write(sendBuffer, 0, sendBuffer.Length);
        }

        private void HTTPRequest()
        {
            try
            {
                Debug.Print("Getting Host Entry for google.com...");
                var dnsEntry = Dns.GetHostEntry("google.com");
                Debug.Print(string.Concat("Host Entry: ", dnsEntry.AddressList[0].ToString()));
            }
            catch (Exception ex)
            {
                Debug.Print(string.Concat("Dns.GetHostEntry() Error: ", ex.ToString()));
            }
        }

        private void LogException(Exception ex)
        {
            Debug.Print(ex.ToString());

            if (ex.InnerException != null)
                LogException(ex.InnerException);
        }
    }
}

Output when running from visual studio debugger:

[quote]Thread Start
Sending Command: ATE0
Modem Response: OK
Sending Command: AT+CSQ
Modem Response: OK
Sending Command: AT+CREG?
Modem Response: OK
Sending Command: ATD#777
Modem Response: CONNECT
Network Address Changed: 75.237.88.238
Network Available: True
Active Interface
Modem IP: 75.237.88.238
Modem Gateway: 66.174.179.228
Modem Mask: 255.255.255.0
Modem DHCP Enabled: True
Modem Dynamic DNS Enabled: False
Modem DNS 0: 208.67.222.222
Getting Host Entry for google.com
Host Entry: 74.125.196.101
Sending Command: +++
Network Address Changed: 0.0.0.0
Network Available: False
Modem Response: UNKNOWN
Sending Command: ATH
Modem Response: OK
Sending Command: +++
Modem Response: UNKNOWN
Thread End[/quote]

Output when running the board without debugger but listening with MFDeploy:

[quote]Thread Start
Sending Command: ATE0
Modem Response: OK
Sending Command: AT+CSQ
Modem Response: OK
Sending Command: AT+CREG?
Modem Response: OK
Sending Command: ATD#777
Modem Response: CONNECT
Network Address Changed: 75.236.150.238
Network Available: True
Active Interface
Modem IP: 75.236.150.238
Modem Gateway: 66.174.179.228
Modem Mask: 255.255.255.0
Modem DHCP Enabled: True
Modem Dynamic DNS Enabled: False
Modem DNS 0: 198.224.152.119
Modem DNS 1: 198.224.154.135
Getting Host Entry for google.com
#### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (4) ####
#### Message:
#### Microsoft.SPOT.Net.SocketNative::getaddrinfo [IP: 0000] ####
#### System.Net.Dns::GetHostEntry [IP: 0008] ####
#### ModemTest.Program::HTTPRequest [IP: 000f] ####
#### ModemTest.Program::Work [IP: 014d] ####
#### SocketException ErrorCode = 10060
Dns.GetHostEntry() Error: System.Net.Sockets.SocketException
Sending Command: +++
Network Address Changed: 0.0.0.0
Network Available: False
Modem Response: UNKNOWN
Sending Command: ATH
Modem Response: OK
Sending Command: +++
Modem Response: UNKNOWN
Thread End[/quote]

I believe the framework bug is around the way the DNS logic is handled when debugging versus not. When I run the code with the visual studio debugger the DNS is reported as 208.67.222.222. This is an OpenDNS server and is not the value I proved when I set the static DNS entries. It looks like there may be something hardcoded in the framework and different code is executed when debugging than when not.

@ PhilH - We don’t hardcode any OpenDNS address. It is possible if dynamic DNS was enabled, it got that address from somewhere on your network.

If you replace the site address with its ip address, can you communicate with it? Have you tried other sites?

HI John,

Thanks for getting back with me. I’m using Verizon Wireless’s cellular network, and after a quick goolge search it appears that Verizon actively blocks OpenDNS servers on their network. I don’t think they’re assigning the DNS servers. So thats why I first tried using the static DNS servers you see in my code. Those are the Verizon DNS servers I should be receiving dynamically. (The servers my computer gets if I use the modem with dial up networking.)

I’m not blaming GHI for the hard coded address, the error looks like it comes from the Microsoft.SPOT.Net assembly. Is it possible Microsoft hard coded DNS entries?

I have tried replacing the hostname with an IP address in my HttpWebRequest. Stack trace is different, we don’t see the use of the GetHostEntry, but it still fails with a SocketException.

Error when using an IP address rather than a hostname in an HttpWebRequest.GetResponse().
[quote]#### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (4) ####
#### Message:
#### Microsoft.SPOT.Net.SocketNative::send [IP: 0000] ####
#### System.Net.Sockets.Socket::Send [IP: 0018] ####
#### System.Net.Sockets.NetworkStream::Write [IP: 0051] ####
#### System.Net.InputNetworkStreamWrapper::Write [IP: 000a] ####
#### System.Net.HttpWebRequest::SubmitRequest [IP: 007d] ####
#### System.Net.HttpWebRequest::GetResponse [IP: 000c] ####
#### ModemTest.Program::HTTPRequest [IP: 0054] ####
#### ModemTest.Program::Work [IP: 014d] ####
#### SocketException ErrorCode = 10053
#### Exception System.Net.WebException - 0x00000000 (4) ####
#### Message:
#### System.Net.HttpWebRequest::GetResponse [IP: 00c8] ####
#### ModemTest.Program::HTTPRequest [IP: 0054] ####
#### ModemTest.Program::Work [IP: 014d] ####[/quote]

It seems like all of the errors are related to socket timing. Either 10060 socket timeout or 10053 which sounds like it could also be related to a timeout.

Is there any way to change the timeout values used by the network stack? The part that kills me is that it works fine when I’m debugging…

@ PhilH - It’s possible there is something with your modem that does not interact well with our PPP support. We’ve only tested it using our cellular modem module. If possible, can you start with the example in https://www.ghielectronics.com/docs/30/networking#3309 and add the bare minimum commands needed to get it working on your modem?

If you connect through MFDeploy instead of Visual Studio, does it still function?

Also take a look at the events in https://www.ghielectronics.com/docs/30/networking#3121, try to wait for the two network events to fire and the IP address to be set before proceeding.

Here is the code modified for use with my modem. I only had made a few minor changes, really just the port read timeout and handshake settings. Then I added the GetHostEntry call to determine if networking calls work after the connection. I’ve never really had any trouble with the PPP not connecting, it always connects ok and gets an IP address from the cell network, I just can’t use any network functionality unless I’m debugging.

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()
    {
        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();

                //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;
        }
    }
}

Output from VS debugger: Code seems to run ok.

[quote]The thread ‘’ (0x2) has exited with code 0 (0x0).
Host Entry: 63.84.3.21
The thread ‘’ (0x1) has exited with code 0 (0x0).
Done.
The program ‘[7] Micro Framework application: Managed’ has exited with code 0 (0x0).[/quote]

Output when using MFDeploy and connecting to the board:

[quote]Ready.
#### 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: 006c] ####
#### SocketException ErrorCode = 10060
Uncaught exception
Done.[/quote]

And that really seems to be my only problem. The code runs fine. Its the fact that it won’t run unless I’m actively attached to the board with the visual studio debugger.

@ PhilH - Try… After the event is set, check to see if an IP address has been set on the interface. Do a sleep loop until the IP address is not 0.0.0.0.

Mike thanks for the reply.

I’ve modified the code as you requested to wait for the IP address on the active interface:

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()
    {
        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();

                //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)
        {
            var netIf = BaseInterface.ActiveInterface;
            string IPAddr = netIf.IPAddress;

            while (IPAddr == "0.0.0.0")
            {
                Thread.Sleep(100);
                netIf = BaseInterface.ActiveInterface;
                IPAddr = netIf.IPAddress;
            }

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

            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;
        }
    }
}

Output when debugging with Visual Stuido:

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

Output when connected via MFDeploy:

[quote]Ready.
The IP Address is: 75.223.157.90
#### 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: 006c] ####
#### SocketException ErrorCode = 10060
Uncaught exception
Done.[/quote]

Thanks,

Phil

@ PhilH - you should never have a wait loop in an event handler. Funny things can happen.
Try this… in Main


evt.WaitOne();

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

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

If this does not work, you can try a sleep of a few seconds after the IP address changes.

Thanks for working with me on this. I truly appreciate your input. Here is the modified code and results.

Code:

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()
    {
        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;
        }
    }
}

Output when running via Visual Studio debugger:

[quote]The thread ‘’ (0x2) has exited with code 0 (0x0).
The IP Address is: 75.237.96.129
Host Entry: 173.194.121.35
The thread ‘’ (0x1) has exited with code 0 (0x0).
Done.
The program ‘[2] Micro Framework application: Managed’ has exited with code 0 (0x0).[/quote]

Output from MFDeploy:

[quote]Ready.
The IP Address is: 75.227.44.32
#### 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: 0092] ####
#### SocketException ErrorCode = 10060
Uncaught exception
Done.[/quote]

For what its worth it seems like the network interface isn’t actually switching over to the cellular modem unless I’m debugging through visual studio.

Here is a little example which generates the exact same exception that I see when running the board without debugging. Of course in the below program I’m attempting a Dns.GetHostEntry without establishing any network connections of any sort. But I get the same error that I see when I run the code which actually establishes a network connection first.

Could it be that the network interface change is not getting picked up by framework and the network calls are still trying to go out on an interface which is not actually in use?

public class Program
{
    private static void Main()
    {
        Thread.Sleep(10000);
        var dnsEntry = Dns.GetHostEntry("google.com");
        Debug.Print(string.Concat("Host Entry: ", dnsEntry.AddressList[0].ToString()));
    }
}

[quote] #### 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: 0010] ####
#### SocketException ErrorCode = 10060
#### SocketException ErrorCode = 10060
A first chance exception of type ‘System.Net.Sockets.SocketException’ occurred in Microsoft.SPOT.Net.dll
#### SocketException ErrorCode = 10060
An unhandled exception of type ‘System.Net.Sockets.SocketException’ occurred in Microsoft.SPOT.Net.dll

Done.[/quote]

@ PhilH - There is a default network interface in the firmware, so if you don’t configure anything, it’ll try to use that and fail like you saw. Is it possible to get a capture of the serial data when debugging and not and compare them to see if there’s any difference?