PPP class and NetworkAvailabilityChanged event

Hi!

I have developed an application that sends messages over a GPRS modem (connected via SerialPort and using your PPP class) using sockets.
In the documentation it is written, that you should subscribe to the following event:
NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
to be informed when the network becomes unavailable - at leas as far as I understood.

When I connect using PPP the first time, that event is fired and tells me that the network is now available.
However when I wrap my modem in alu foil and screw off the antenna that event is not raised, even though I know exactly that it has no connection whatsoever.
(AT+CSQ returns a value between 2,9 and 4, which is not sufficient to attach to the GPRS network and connect via PPP)

The only thing that happens is that the “Socket.Send(byte[] data)” method stucks forever.

Am I doing something wrong - do I miss something, or is the NetworkAvailabilityChanged event just not thought of for this purpose and if so, how can I detect that the network is unavailable and react to that?

Thank you very much! :slight_smile:

The network status is checked every 5 seconds. If you give it some time do you see the disconnection event?

Every five seconds? Thats good to know. :slight_smile:
However, I even let it run for several minutes and got no event.
Even when I ran all the code on a separate thread and sent the main thread to sleep for infinity…
Might there be a problem with the modem itself? I mean how does the PPP stack find out whether the network is available or not?

This is a very good question.
Usually PPP stack gets the disconnection request from the modem then it terminates the connection and send the disconnection event that you get in the application.
But what if the disconnection request was not sent? I guess the PPP stack will assume that the connection is still established. Probably the connection consistency should be verified in a higher layer (TCP/IP). For example, ping the gateway IP address every minute.

Isnt @ Alexander2 essentially trying this, but the socket is never returning:

Not sure if this suggest there is an issue in the stack since the Send is never returning? Wouldn’t a ping at a higher level essentially do the same thing at the socket level?

(Note: I haven’t tries this personally, but am interested as am looking toward using PPP in the near future)

I believe sticking in Socket.Connect()or Socket.Send() happens with only TCP sockets.
UDP or ICMP sockets does not expect ACK messages from the server thus the message will be sent right away.

By the way, the long timeout with Socket.Connect() is a known thing with NETMF TCP/IP stack. To terminate the connection faster, you can dedicate a thread that execute the socket.connect() and you terminate the thread from the main application when desired.
I believe many members have a great experience with NETMF TCP/IP Sockets that can propose a better solution to terminate socket.connect() termination. :wink:

Hi!
Just wanted you to know that I found a solution that works for me.
I did not want to ping my gateway or so as this would cause senseless network traffic. Therefore I don’t like that solution.

I do not think so. Actually for the first ~5 messages sent when the modem already lost its connection, the Socket.Send() method returns instantly and does not throw any exception. The 6th message then causes the Socket.Send() method to stuck. I am pretty sure that this has something to do with an inner buffer of the modem that runs full and therefore does not accept any more bytes. :slight_smile: When it re-connects to the GPRS network, those first ~5 messages are sent and received by my server. So it must be something like a buffer, right?

My solution is simply to run the “Send” method on a separate thread and abort it when it times out, then reschedule the request.

The only thing I am missing is that the NetworkAvailabilityChanged event is never fired. If it was so, I could suspend the worker thread that does the retry work so even less power is consumed… :frowning:

I suppose you are using hardware handshaking. Yes I think the modem has a little FIFO that enqueues the incoming data from EMX’s serial port then it pulls the CTS line high to indicate the it can not receives any data and your application is stuck waiting for the CTS to be cleared to send the data. To to forget that EMX has a hardware fifo and software fifo of TX and RX.

I think something can be added to handle this scenario.
What if you monitor the SerialPort.BytesToWrite in another thread and if the number is not close to zero for long time then you assume that the data is being accumulated in the FiFo and not being sent.
This solution works only if you have handshaking enabled.