Problem with server.connect on RETURN_ON_ERROR

Hi
i use the following code to make a connection to several wifi’s
function changeWiFi(ssid, password) { if (server.isconnected()) server.log(format("Device disconnecting from %s",imp.getssid())); // Wait for the WiFi buffer to empty before disconnecting server.flush(10); server.disconnect(); // Change the WiFI configuration with the passed parameters imp.setwificonfiguration(ssid, password); // Attempt to reconnect synchronously //server.connect(); server.connect(function(state) { if (state == SERVER_CONNECTED) { // ok verbunden server.log(format("und wieder verbunden mit %s",ssid)); //onConnect(); } else { // nicht verbunden } }, 5); // Log that we're connected to make sure it worked! server.log("Device now connected to " + ssid); }

Everything works fine if i set the servertimeoutpolicy to default SUSPEND_ON_ERROR but if i set the servertimeoutpolicy to RETURN_ON_ERROR the system hangs in server.connect.
I use the following command before i call changeWiFI
server.setsendtimeoutpolicy(RETURN_ON_ERROR, WAIT_TIL_SENT, 10);

What is going wrong in server.connect ?

According to the documentation (https://electricimp.com/docs/api/server/connect/), when you use RETURN_ON_ERROR the server.connect call is not blocking. Thereforeyour last server.log is executing before the connection is set up.

Noop, soory
i’ve commented out all server.log calls but the situation is the same.
In the Server Log i get the message "[Status]Device disconnected"
but it seems the one of the following commands block:

imp.setwificonfiguration(ssid, password); // Attempt to reconnect synchronously server.connect(function(state)...

The connection will definitly disconnected but the new wlan ssid will not connected.
There is no disconnectHandler installed with server.onunexpecteddisconnect
So the problem seems to be in the call of server.connect
But whats wrong in this call ?

My first comment is that 5 seconds is quite short. Have you tried 10 or more seconds? Do you have an LED or a UART available that you can control on the imp? This could give you some indication while you are offline. You could flash the LED a couple of times. At this stage, you don’t need a handler for server.onunexpecteddisconnect because the disconnection is not unexpected if you do it.

Yes i’ve tried more then 5 sec. It seems that the connect call isn’t able to connect. It blocks!
I didn’t have a uart, but I can flash a led, but it seems that connect blocks.
What I didn’t understand is that it works if I set the policy to default SUSPEND_ON_ERROR

When SUSPEND_ON_ERROR is in place, server.connect() proceeds synchronously and will spend 60s trying to reconnect. It does this automatically, and if reconnection is quick, it might well appear to be working as speedily as you expect RETURN_ON_ERROR to do so. Your system is reconnecting within that 60s period.

I think that your RETURN_ON_ERROR required server.connect() callback function is called too soon (a server.log() in the else… will probably confirm this), mostly likely while the state variable doesn’t yet equal SERVER_CONNECTED.

So your system, in these two cases, is connecting somewhere between 5s and 60s, so your should apply a much longer timeout period. I would try 30s.

I don’t think you’d see server.log() called from the else, since it’s not connected :slight_smile:

We’ve fixed a few related bugs in impOS release 30, so this should become less puzzling very soon. In the meantime please try increasing your server.connect time out to at least 10 seconds and adding imp.sleep(1) immediately after the server.disconnect().

Also note that with RETURN_ON_ERROR, if the connect callback returns a state other than SERVER_CONNECTED you have to manually retry in your else block.

i’ve increased the server.connect time and also added the sleep but the situation is the same.
But if i disable wlan in my router, then start the imp, wait 10 seconds and then start the wlan everything works and the imp connected.
So it seems that the problem only happens if i disconnect an existing wlan connection first and than try to reconnect it, this is the situation the system will block.
someone any ideas how to disconnect and than reconnect to the same wlan ?

I can get my imps to disconnect and reconnect to the same wlan. Offline operation of the imp can be tricky, as philmy has said, the next release should make it easier.

This is the code I use:
` // public method, accepts callback and optional field “delay” in secs
function disconnect(parameters){
parameters.callback(true);
local delay = 0;
if (“delay” in parameters) {
delay = parameters.delay;
server.expectonlinein(delay);
}

    // use imp wakeup to trigger when we reconnect
    _disconnect();
    imp.wakeup(delay,_connect.bindenv(this));
}

// connects to existing configured wifi SSID
function _connect(network=null) {
    debug.write("connect");
    if (network!=null)
        _change(network);
    server.connect(_onConnect.bindenv(this), _config.timeout);
    debug.write("WIFI Attempting connection: "+imp.getssid());
}

// disconnect gracefully from connection 
function _disconnect() {
    server.flush(_config.timeout);
    server.disconnect();
    debug.write("WIFI Locally disconnected");
}`

@Joergtiedemann if you provide your mac address then I can give you release 30 which addresses a lot of issues related to programmatic wifi joins…

thanks Hugo,
but i’ve solved the problem.
The problem was that i not noticed that the server.connect() runs asynchronous and returns immetiately
So i block somewhere later in my program code if i will communicate with a disconnected server
I’ve used the sample code from the documentation https://electricimp.com/docs/resources/offline/ and it runs and then i edit my code in the same matter as in the sample, now it works perfect.
Thanks to the team for the support !
But one last question: What will be improved in release 30 to this case and which time is the release date ?

Release 30 is going out on monday. You can scan for wifi networks at any time with that release, it deals with powering up the wifi chip etc.