PPP trials

Hello
I tried PPP with G120HDR board and CellularRadio module on User socket.
I use the code published in this thread.
Initialy I had the same problem as @ njbuch but I have modify Cellular_43.cs has indicated by @ 4egod and @ Dave McLaughlin and all is OK for me.
My program request every 2mn a server without problem since 1 hour.
I am in France with operator Orange.


this.SendATCommand("AT+CGDCONT=1,\"IP\",\"" + apn + "\"");
this.SendATCommand("ATDT*99#");

Hi there,

I´m completelly new to this type of system and I´m trying to use this piece of software but as soon as I try to create a new “UseThisNetworkInterface” including the new parameter I got errors related to the “serial” object. Could you please tell me how to “fix” the software?.

I reallye apreciate your help!.

Thanks.

@ r.ricardog - consider starting a new thread. Provide code error messages and hardware setup…

@ ChristianJack -

I just read @ ChristianJack - and I think the solution is to modify the mentioned file. Could somebody of you point me to where I can download this (or these) files?.

Thanks a lot.

@ r.ricardog - look at the ghi repository https://bitbucket.org/ghi_elect/gadgeteer/src/985ade835fd675b6b1cf004aa4bc732eca8d5244/Modules/GHIElectronics/CellularRadio/CellularRadio_43/CellularRadio_43.cs?at=master

Edit: I think John has modified already. Remember line numbers has changed.

@ John - can you enlighten us on your newest mods the this driver?

Make sure the serial port is open before you call the PPP functions. It will fail if not so.

in fact, you have to st the APN and then do the dialing before you call it so in theory the port must be open to do these but it may not be obvious the first time you use it.

@ njbuch - Nothing has changed in the CellularRadio driver since the last SDK.

@ r.ricardog
Download the file CellularRadio_43.cs at ghi repository https://bitbucket.org/ghi_elect/gadgeteer/src/985ade835fd675b6b1cf004aa4bc732eca8d5244/Modules/GHIElectronics/CellularRadio/CellularRadio_43/CellularRadio_43.cs?at=master and add this file at your solution.
Modify the line as indicated.

With the code publish in this thread I have sometime two events cellularRadio_ModuleInitialized, and then two threads.
I have modify the code like this to take only one cellularRadio_ModuleInitialized event and to have only one thread to make the treatment. The code run fine. I have suppress all my code for display and publish only my code for CellularRadio…

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 Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
using G120 = GHI.Pins.G120;
using Microsoft.SPOT.Net.NetworkInformation;
using System.Net;
using System.Text;
using GHI.Networking;
using System.IO;

namespace G120MF43
{    
    public partial class Program
    {
        /// <summary>CellularRadio from modified class not the initial GHI class</summary>
        private CellularRadio cellularRadio;
        private bool m_cellularRadioInitialized = false;
        private Thread m_requestThread;
        private void RegisterExtenderSockets()
        {
            // The G120HDR has already 6 sockets, we create and register socket 7
            var socket = GT.Socket.SocketInterfaces.CreateNumberedSocket(7);
            socket.SupportedTypes = new char[] { 'I', 'K', 'U', 'X' };
            socket.CpuPins[3] = G120.P0_10;
            socket.CpuPins[4] = G120.P2_0;
            socket.CpuPins[5] = G120.P0_16;
            socket.CpuPins[6] = G120.P0_6;
            socket.CpuPins[7] = G120.P0_17;
            socket.CpuPins[8] = G120.P0_27;
            socket.CpuPins[9] = G120.P0_28;
            socket.SerialPortName = "COM2";
            GT.Socket.SocketInterfaces.RegisterSocket(socket);
        }
        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
            this.RegisterExtenderSockets();
            cellularRadio = new CellularRadio(7);
            NetworkChange.NetworkAvailabilityChanged += (a, b) => Debug.Print("Network availability changed: " + b.IsAvailable.ToString());
            NetworkChange.NetworkAddressChanged += (a, b) => Debug.Print("Network address changed");
            cellularRadio.ModuleInitialized += this.cellularRadio_ModuleInitialized;
            cellularRadio.PowerOn(40);
        }
 
        void cellularRadio_ModuleInitialized(CellularRadio sender)
        {
            Debug.Print("ModuleInitialized");
            if (m_cellularRadioInitialized)
                return;
            else
                m_cellularRadioInitialized = true;
            // Start a thread to request periodically the server
            m_requestThread = new Thread(ThreadToRequest);
            m_requestThread.Start();
        }

        private void ThreadToRequest()
        {
            Thread.Sleep(15000);
            cellularRadio.UseThisNetworkInterface("orange.fr", "orange", "orange", PPPSerialModem.AuthenticationType.Pap);
            while (cellularRadio.NetworkInterface.IPAddress == "0.0.0.0")
            {
                Debug.Print("Waiting on DHCP");
                Thread.Sleep(1000); // (250);
            }
            Thread.Sleep(2000);

            if (cellularRadio.NetworkInterface.IPAddress != "0.0.0.0")
            {
              while (1 == 1)
                {
                    GetCounters();
   
                    Debug.Print("Hibernating");
                    Thread.Sleep(30000);
                }
            }
        }
        private const string GETURL = "http://myurltomyserver.com";
        #region GetCounters
        /// <summary>
        /// Send a HTTP request to get counters values on serveur
        /// </summary>
        private void GetCounters()
        {
            string m_countersString = string.Empty;
            try
            {
                Debug.Print("Send request");
                // Send Http request
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(GETURL);
                req.ContentType = "text/json";
                req.Timeout = 5000;
                req.KeepAlive = false;  // No keep the socket
                // Retrieve response
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                // We examine only OK-200 Http response to avoid to display server error message
                if (resp.StatusCode == HttpStatusCode.OK)
                {
                    StreamReader sr = new StreamReader(resp.GetResponseStream());
                    m_countersString = sr.ReadToEnd();
                    sr.Close();
                    sr.Dispose();
                }
                resp.Close();
                resp.Dispose();
                req.Dispose();
                Debug.Print("Server response : " + m_countersString);
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                    Debug.Print("GetCounters Error : " + ex.InnerException.Message);
            }
        }
        #endregion
    }
}

@ njbuch, 4egod, and ChristianJack - I reworked the cellular radio’s response parsing quite a bit. If you would like to give it a try to see if there are some more issues to fix before the next SDK, you can download the current source from https://bitbucket.org/ghi_elect/gadgeteer/src/0fb97f7fae14e1c301791caff3ac143ee6a0f09e/Modules/GHIElectronics/CellularRadio/CellularRadio_43/CellularRadio_43.cs?at=master I’ve tested most public functions so far and they work.

@ John - can you be more specific? And mabybe even have a look at my thread about async serial stuff…?

@ njbuch - The most visible result should be far fewer race conditions and missed data. PPP should be handled better as well.

As mentioned in your other thread, matching requests to responses and even returning that result from the original function is something on our list of improvements but that hasn’t been done yet.

@ John - I watched the corrections. The event ModuleInitialized no longer exists, how to wait for the initialization of the module? What is the new way to manage the module, have you an example?
Thank you

@ ChristianJack - Previously, PowerOn would spawn a thread that would do the initialization. After it finished, it raised the ModuleInitialized event. Now, the module does all of that work in PowerOn, then returns. As soon as it does return, it is ready to be used.

As andre.m said, though, you want to watch the registration changed handlers to make sure you are connected to the network.

@ John - Sorry but I am not able to use the new CellularRadio source.

I try to adapt my old initialization code https://www.ghielectronics.com/community/forum/topic?id=17217&page=3#msg172260

but if I use this code instead previous code :

cellularRadio = new CellularRadio(7);
            cellularRadio.GprsNetworkRegistrationChanged += cellularRadio_GprsNetworkRegistrationChanged;
             cellularRadio.PowerOn();            

and I put the previous code of cellularRadio_ModuleInitialized in the GprsNetworkRegistrationChanged event treatment.
I received never the GprsNetworkRegistrationChanged event.

If i use this code

cellularRadio = new CellularRadio(7);
            cellularRadio.GsmNetworkRegistrationChanged += cellularRadio_GsmNetworkRegistrationChanged;
             cellularRadio.PowerOn();            

I received one time 2 or 3 the GsmNetworkRegistrationChanged event.

If I back to previous CellularRadio43.cs source with modification and previous initialization code

            cellularRadio = new CellularRadio(7);
             cellularRadio.ModuleInitialized += this.cellularRadio_ModuleInitialized;
           cellularRadio.PowerOn(40)

It is always OK.

@ ChristianJack - You shouldn’t put your code in the registration changed event handlers. In the old driver, ModuleInitialized was fired at the end of the thread PowerOn started. Since the thread body was moved into PowerOn, firing the event at the end no longer made sense. The return of PowerOn is now equivalent to the ModuleInitialized event.

If you do not always get the registration changed handlers, you can try to send the at command “AT+CREG?”. That should trigger the GSM event.

@ John - It is Ok for me now with this initialization code

          
cellularRadio = new CellularRadio(7);
NetworkChange.NetworkAvailabilityChanged += (a, b) => Debug.Print("Network availability changed: " + b.IsAvailable.ToString());
NetworkChange.NetworkAddressChanged += (a, b) => Debug.Print("Network address changed");
cellularRadio.GprsNetworkRegistrationChanged += cellularRadio_GprsNetworkRegistrationChanged;
cellularRadio.PowerOn();            
m_requestThread = new Thread(ThreadToRequest);
m_requestThread.Start();

       void cellularRadio_GprsNetworkRegistrationChanged(CellularRadio sender, CellularRadio.NetworkRegistrationState networkState)
        {
            Debug.Print("Gprs status : " + networkState.ToString());
        }

        private void ThreadToRequest()
        {
            Thread.Sleep(40000);            
            Debug.Print("Init PPP");
            cellularRadio.UseThisNetworkInterface("orange.fr", "orange", "orange", PPPSerialModem.AuthenticationType.Pap);

            while (cellularRadio.NetworkInterface.IPAddress == "0.0.0.0")
            {
                Debug.Print("Waiting on DHCP");
                Thread.Sleep(1000); // (250);
            }
            Thread.Sleep(2000);

            if (cellularRadio.NetworkInterface.IPAddress != "0.0.0.0")
            {
                while (true)
                {
                    GetCounters();
                    Debug.Print("Hibernating");
                    Thread.Sleep(30000);
                 }
            }
        }

-[quote] The return of PowerOn is now equivalent to the ModuleInitialized event[/quote].
I do not see that. If I suppress the Sleep(40000), the PPP initialization is made while the fixed green led on the CellularRadio module is off.

A question, during my first test I have received 2 or 3 time the following error: “SocketException ErrorCode = -1728053248” . I have not keep all the trace. Where can I find the explaination of this error code ?
John thank you for your help.

@ ChristianJack - Usually the socket error codes are around 10,000. I’ve never seen that specific code before. If you see it again and can get more information, we can look into it.

Windows Sockets Error Codes (Winsock2.h) - Win32 apps | Microsoft Learn is usually helpful for seeing what the code means.

@ John - Last night I had occasionally this error:

Send request
#### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (6) ####
#### Message:
#### Microsoft.SPOT.Net.SocketNative::recv [IP: 0000] ####
#### System.Net.Sockets.Socket::Receive [IP: 0018] ####
#### System.Net.Sockets.NetworkStream::Read [IP: 0062] ####
#### System.Net.InputNetworkStreamWrapper::RefillInternalBuffer [IP: 0038] ####
#### System.Net.InputNetworkStreamWrapper::Read_HTTP_Line [IP: 004b] ####
#### System.Net.HttpWebRequest::ParseHTTPResponse [IP: 002e] ####
#### System.Net.HttpWebRequest::GetResponse [IP: 0035] ####
#### KapitenG120MF43.Program::GetCounters [IP: 002b] ####
#### KapitenG120MF43.Program::ThreadToRequest [IP: 0073] ####
#### SocketException ErrorCode = -1728053248
#### SocketException ErrorCode = -1728053248
Une exception de première chance de type ‘System.Net.Sockets.SocketException’ s’est produite dans Microsoft.SPOT.Net.dll
#### SocketException ErrorCode = -1728053248
#### SocketException ErrorCode = -1728053248
#### Exception System.Net.WebException - 0x00000000 (6) ####
#### Message:
#### System.Net.HttpWebRequest::GetResponse [IP: 00c8] ####
#### KapitenG120MF43.Program::GetCounters [IP: 002b] ####
#### KapitenG120MF43.Program::ThreadToRequest [IP: 0073] ####
Une exception de première chance de type ‘System.Net.WebException’ s’est produite dans System.Http.dll
GetCounters Error : Exception was thrown: System.Net.Sockets.SocketException
Hibernating

With this code:

      private void GetCounters()
        {
            string m_countersString = string.Empty;

            try
            {
                Debug.Print("Send request");

                // Send Http request
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(GETURL);
                req.Timeout = 5000;
                req.KeepAlive = false;  // No keep the socket

                // Retrieve response
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

                // We examine only OK-200 Http response to avoid to display server error message
                if (resp.StatusCode == HttpStatusCode.OK)
                {
                    StreamReader sr = new StreamReader(resp.GetResponseStream());
                    m_countersString = sr.ReadToEnd();

                    sr.Close();
                    sr.Dispose();
                }
                resp.Close();
                resp.Dispose();
                req.Dispose();

                Debug.Print("Server response : " + m_countersString);
                myDisplay.PrintNewMessage(m_countersString);
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                    Debug.Print("GetCounters Error : " + ex.InnerException.Message);
            }
        }

This morning no error since 1h.

@ ChristianJack - We will take a look and see if we can’t find anything.