Main Site Documentation

PPPSerialModem connection


#1

Hello,

I’m trying to establish a PPP connection with a cellular modem I have connected via a serial port to a FEZ Spider board. Everything seems to work ok except the PPPSerialModem.Connect() method.

I’m able to establish a connection between the board and the modem using the SerialPort class. I send all the AT commands to bring the modem up and establish a data context with a public IP address.

I verified the context is connected and has been assigned a public IP address from the cellular network using AT commands. At this point I put the modem into a data context which allows the modem to accept a PPP connection.

However, when I attempt to connect the NETMF network stack to the modem using PPPSerialModem.Connect() I don’t receive any exceptions but about 4 minutes after the Connect() call I get a NetworkAvailabilityChanged event raised with IsAvailable = false.

Obviously there is some kind of issue establishing the PPP connection to my modem, but I’m not sure what to check next. I’ve tried most of the overloads of the Connect method, none seem to work for me.

Can someone provide some insight or additional troubleshooting I can perform? I feel like I’m at the last hurdle and I’ll have a working cellular connection.

Thanks,
Phil


#2

Please provide more details about modem, antenna, power supply and code sample.


#3

Hello,

The modem is a Verizon CDMA modem - MultiConnect Cell 100 Series MTC-EV3. I am using the fixed paddle shaped antenna that was supplied with the modem. The modem is using its own power supply. The board is also using a 12v 1.2A power supply, not drawing from the USB connection. The modem has good signal strength and I’m able to connect it to my PC and use the windows dialer to establish an internet connection.

I started to consolidate my code into a better example for posting on the forum. During this process I noticed something which I didn’t notice in my previous solution. After sending the ATD#777 command I have no bytes to read from the serial port until I issue an escape “+++” then I see my “CONNECT 3100000” that I was expecting.

When I connect to the modem with Putty and do a ATD#777 after a second or two I get a response of “CONNECT 3100000” which indicates the data connection is established and you’re free to establish a PPP connection. I don’t know much about serial communications, but there is a difference in behavior between Putty and my code. I believe after sending the ATD#777 the modem will raise the Carrier Detect. Is that why I’m not reading any bytes after the ATD command? Obviously I’m still able to send data to the port and modem responds as expected to the escape command.

Here is my simplified program:


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."); };

		//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.ReadTimeout = 100;
		port.Open();
		port.DiscardInBuffer();
		port.DiscardOutBuffer();

		modem = new PPPSerialModem(port);

		new Thread(Work).Start();
	}

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

		try
		{
			SendATCommand("ATE0", 1000);
			//Modem response "ATE0<CR><CR><LF>OK<CR><LF>"

			SendATCommand("AT+CSQ", 1000);
			//Modem response "<CR><LF>+CSQ: 24,99<CR><LF><CR><LF>OK<CR><LF>"

			SendATCommand("AT+CREG?", 2000);
			//Modem response "<CR><LF>+CREG: 0,1<CR><LF><CR><LF>OK<CR><LF>"

			SendATCommand("ATD#777", 5000);
			//Got no reponse, but expected "CONNECT 3100000"
			//At this point modem is all fired up and ready for data transfer.

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

			Thread.Sleep(300000); //Wait 5 minutes for NetworkAvailabilityChanged

			//After 4 minutes I see these:
			//NetworkAddressChanged raised.
			//NetworkAvailabilityChanged raised. IsAvailabe = False 

			HTTPRequest(); //Obviously this fails.

			modem.Disconnect();
			modem.Close();

			SendATCommand("+++", 5000);
			//Here I get "<CR><LF>CONNECT 3100000<CR><LF><CR><LF>NO CARRIER<CR><LF>"
			SendATCommand("ATH", 1000);
			//Modem response "<CR><LF>OK<CR><LF>"

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

		Debug.Print("Thread End");
	}

	private void SendATCommand(string command, int timeout)
	{
		Debug.Print("Command Sent: " + command);

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

		var sendBuffer = Encoding.UTF8.GetBytes(command);
		port.Write(sendBuffer, 0, sendBuffer.Length);
		Thread.Sleep(timeout);
		ReadResponse();
	}

	private void ReadResponse()
	{
		byte[] data = new byte[port.BytesToRead];
		int bytesRead = port.Read(data, 0, data.Length);

		if (bytesRead > 0)
		{
			string response = new string(Encoding.UTF8.GetChars(data, 0, bytesRead));
			response = new StringBuilder(response).Replace("\r", "<CR>").Replace("\n", "<LF>").ToString();
			Debug.Print("Received: " + response);
		}
		else
		{
			Debug.Print("No response from modem.");
		}
	}

	private void HTTPRequest()
	{
		try
		{
			string url = "https://www.google.com/";
			using (var req = System.Net.HttpWebRequest.Create(url))
			{
				using (var res = req.GetResponse())
				{
					Debug.Print("HTTP Response was this long: " + res.ContentLength.ToString());
				}
			}
		}
		catch (Exception ex)
		{
			Debug.Print(ex.ToString());
		}
	}
}

Sorry if there is a bunch of whitespace. Not sure why its doing that. Hopefully that’s just the preview…

Thanks for your help.

-Phil


#4

After some additional testing I noticed that my “ATD#777” command is in fact received by the modem and a data connection is opened.

I can confirm this even though I don’t receive the response in my code because the modem had a “CD” light on the front which according to the documentation is lit when a data connection has been established. After the ATD#777 command the light does indeed turn on.

However shortly after I call the Connect method on the PPPSerialModem class the CD light on the modem goes out again. I’m assuming the PPPSerialModem is sending something the modem does not like and the modem is terminating the data connection.

:wall:


#5

Hmm, interesting case you have there. I am not able to pin-point the problem, but I can tell you that I was struggling a lot with the serial communication to my modem as well.

The things is, when you want to communicate the data, you should according to the manual wait for a “>” sign, and then start sending the data.

But the “>” never turns up.

Then I just thought, what the heck, I will try sending it anyway, and guess what, the first character in the echoed response from the modem is “>”.

I have no clue why this happens, but I guess some of the experienced people in here can help us understand the issue…?


#6

Actually making really good progress. Not sure why it took me so long to figure this out, but I just added a Handshake.RequestToSend to my port and now things are working well. I’m now getting the event with IsAvailable = true and I’m also seeing the CONNECT response from the modem.

But then I get this error. It looks like the network interface is having issues with DHCP?

#### Exception System.Exception - CLR_E_FAIL (4) ####
#### Message: 
#### Microsoft.SPOT.Net.NetworkInformation.NetworkInterface::UpdateConfiguration [IP: 0000] ####
#### Microsoft.SPOT.Net.NetworkInformation.NetworkInterface::EnableDhcp [IP: 000f] ####
#### GHI.Networking.BaseInterface::EnableDhcp [IP: 0011] ####

A first chance exception of type ‘System.Exception’ occurred in Microsoft.SPOT.Net.dll


#7

@ PhilH - We do not support calling EnableDhcp on the PPP connection. Look into the overrides on Connect that take an IPAddress or not. The connection should automatically negotiate an IP if you do not provide one.


#8

Thanks John I was able to get around that error by removing the calls to the EnableDhcp() method. My modem now works and I’m up and running! :clap: Thanks to everyone for the help.

But I’ve run into a new issue. After I call modem.Disconnect() and modem.Close() when I try to send the data mode escape command “+++” on the serial port so I can hang up the modem I get a CLR_E_WRONG_TYPE (4) when trying to read from the serial port.

Exception System.Exception - CLR_E_WRONG_TYPE (4)

Message:

System.Text.UTF8Encoding::GetChars [IP: 0000]

ModemTest.Program::ReadResponse [IP: 002e]

ModemTest.Program::SendATCommand [IP: 0041]

ModemTest.Program::Work [IP: 0092]

A first chance exception of type ‘System.Exception’ occurred in mscorlib.dll

Do I need to do something special with my serial port after calling Close() on the PPPSerialModem? I tried a DiscardInBuffer() and DiscardOutBuffer() after the Close(). It didn’t seem to help.


#9

@ PhilH - Usually that means that the character decoder received an invalid UTF8 value. If you can capture the data that causes the exception we can take a look.


#10

Thanks John. That makes perfect sense. There is some garbage left in the buffer that was probably unread data from the PPP connection I just closed. Then I’m trying to read it and convert it to a string but its not string data.

SO I’ll just get around that by discarding the buffer after I send the “+++” escape command.

Here were the bytes that were in the buffer. In case the method should fail more gracefully if you feed it garbage.

[0] = 126
[1] = 255
[2] = 125
[3] = 35
[4] = 192
[5] = 33
[6] = 125
[7] = 38
[8] = 125
[9] = 34
[10] = 125
[11] = 32
[12] = 125
[13] = 36
[14] = 148
[15] = 125
[16] = 45
[17] = 126
[18] = 13
[19] = 10
[20] = 78
[21] = 79
[22] = 32
[23] = 67
[24] = 65
[25] = 82
[26] = 82
[27] = 73
[28] = 69
[29] = 82
[30] = 13
[31] = 10