How to break or come out of a function if no internet connection after 20 sec

Hi,

I am trying to break out of the following connection if there is no internet connectivity after 30 seconds of starting the arduino up and running on Arduino MKR1500. But have been unsuccessful.
Below is the code that I am trying to make the break function for:

void beginGprs() {
  tft.println("Waiting for internet connection");
    if ((narrowband.begin(pinnumber) == NB_READY) && (gprs.attachGPRS() == GPRS_READY)) {
        info("narrowband ready and gprs attached");
        tasks.after(300, connectSocket);
          tft.setTextColor(ST77XX_GREEN);
  tft.setCursor(0, 10);
   
    tft.setCursor(0, 0);
    tft.fillScreen(ST77XX_BLACK);
    
    internet_connected();
    tft.println("connected to the internet");
    delay(2000);
    } else {
        warning("cannot begin narrowband or attach gprs");
        tasks.after(30000, beginGprs); // after 10 seconds call beginGprs() again
        internet_not_connected();
    }
}

Can someone please help me

I tried using millis function to check for timing, but the code never comes out of the begingprs() and continue to do something after that

 tft.println("Waiting for internet connection");
myTime2=millis();
      while ((narrowband.begin(pinnumber) == NB_READY) && (gprs.attachGPRS() == GPRS_READY))
    {
      if ( millis() - myTime >= myTime30)// wait for 30 seconds if it does not complete then break out of the connect
        break;
    
    
  tft.println("Waiting for internet connection");
    //if ((narrowband.begin(pinnumber) == NB_READY) && (gprs.attachGPRS() == GPRS_READY)) {
        info("narrowband ready and gprs attached");
        tasks.after(300, connectSocket);
          tft.setTextColor(ST77XX_GREEN);
  tft.setCursor(0, 10);
   
    tft.setCursor(0, 0);
    tft.fillScreen(ST77XX_BLACK);
    
    internet_connected();
    tft.println("connected to the internet");
    delay(2000);}
    //} else {
        warning("cannot begin narrowband or attach gprs");
        tasks.after(30000, beginGprs); // after 10 seconds call beginGprs() again
        internet_not_connected();
    }

is there something that I am missing?

NM I didn't really have anything...

Yes. The code.

Since I can't see your code, I am only guessing, but why not simply test the status in the loop?

if ((!narrowband.begin(pinnumber) == NB_READY))

Sorry here is the complete code:

/*
 * Copyright (C) 2021 Andreas Motzek andreas-motzek@t-online.de
 *
 * You can use, redistribute and/or modify this file under the terms
 * of the Creative Commons Attribution 4.0 International Public License.
 * See https://creativecommons.org/licenses/by/4.0/ for details.
 *
 * This file is distributed in the hope that it will be useful, but
 * without any warranty; without even the implied warranty of
 * merchantability or fitness for a particular purpose.
 */

#include <MKRNB.h>
#include "CooperativeMultitasking.h"
#include "MQTTClient.h"

const char pinnumber[] = ""; // enter your SIM pin here
const char host[] = "test.mosquitto.org";
const char clientid[] = "1883";
const char username[] = "";
const char password[] = "";
const char topicfilter[]="my_IoT_value1"; // enter your topic here

CooperativeMultitasking tasks;
NBClient client;
GPRS gprs;
NB narrowband;
MQTTClient mqttSocket(&client);

Continuation beginGprs;
Continuation connectSocket;
Guard canReadSocket;
Continuation sendConnect;
Continuation acknowledgeConnect;
Continuation subscribe;
Continuation receive;
Continuation ping;
Continuation closeSocket;
Continuation ledOn;
Continuation ledOff;

void info(String str) {
    if (!Serial) return;
    //
    if (Serial.availableForWrite() < str.length()) {
        Serial.flush();
    }
    //
    Serial.print("INFO ");
    Serial.println(str);
}

void warning(String str) {
    if (!Serial) return;
    //
    Serial.print("WARN ");
    Serial.println(str);
    Serial.flush();
}

void beginGprs() {
 tft.println("Waiting for internet connection");
    if ((narrowband.begin(pinnumber) == NB_READY) && (gprs.attachGPRS() == GPRS_READY)) {
        info("narrowband ready and gprs attached");
        tasks.after(300, connectSocket);
          tft.setTextColor(ST77XX_GREEN);
  tft.setCursor(0, 10);
   
    tft.setCursor(0, 0);
    tft.fillScreen(ST77XX_BLACK);
    
    internet_connected();
    tft.println("connected to the internet");
    delay(2000);
    } else {
        warning("cannot begin narrowband or attach gprs");
        tasks.after(30000, beginGprs); // after 10 seconds call beginGprs() again
        internet_not_connected();
    }
}

void connectSocket() {
    if (client.connect(host, 1883)) {
        info("socket connected");
        tasks.after(300, sendConnect);
    } else {
        warning("cannot connect socket");
        tasks.after(30000, beginGprs);
    }
}

bool canReadSocket() {
    return mqttSocket.canReadSocket();
}

void sendConnect() {
    info("before connect request");
    //
    if (mqttSocket.sendConnectRequest(clientid, username, password, 600)) {
        info("sent connect request");
        auto task1 = tasks.ifForThen(canReadSocket, 300, acknowledgeConnect);
        auto task2 = tasks.after(10000, closeSocket);
        tasks.onlyOneOf(task1, task2);
    } else {
        warning("cannot send connect request");
        tasks.now(closeSocket);
    }
}

void acknowledgeConnect() {
    info("before receive");
    auto packet = mqttSocket.receive();
    //
    if (packet) {
        if (packet->getType() == 2) {
            auto acknowledgement = (ConnectAcknowledgement*) packet;
            //
            if (acknowledgement->isConnectionAccepted()) {
                info("connection accepted");
                tasks.after(300, subscribe);
            } else {
                warning("connection not accepted");
                tasks.now(closeSocket);
            }
        } else {
            warning("unexpected packet in acknowledge connect");
            tasks.now(closeSocket);
        }
        //
        delete packet;
    } else {
        warning("no packet in acknowledge connect");
        tasks.now(closeSocket);
    }
}

void subscribe() {
    info("before subscribe request");
    //
    if (mqttSocket.sendSubscribeRequest(topicfilter, 1)) {
        info("sent subscribe request");
        auto task1 = tasks.ifForThen(canReadSocket, 300, receive);
        auto task2 = tasks.after(10000, closeSocket);
        tasks.onlyOneOf(task1, task2);
    } else {
        warning("cannot send subscribe request");
        tasks.now(closeSocket);
    }
}

void receive() {
    info("before receive");
    auto packet = mqttSocket.receive();
    //
    if (packet) {
        switch (packet->getType()) {
            case 9: {
                auto acknowledgement = (SubscribeAcknowledgement*) packet;
                //
                if (acknowledgement->hasPacketId(mqttSocket.getPacketId()) && acknowledgement->isSubscriptionAccepted()) {
                    info("subscription accepted");
                    tasks.now(ledOn);
                } else {
                    warning("wrong packet id or subscription not accepted");
                }
                //
                break;
            }
            case 13: {
                info("ping response");
                //
                break;
            }
            case 3: {
                auto notification = (PublishNotification*) packet;
                info("publish notification");
                 info(notification->getPayload());

            /*  char *expected = "fast";

              char *actual = (notification->getPayload());
              int compare = strcmp(expected, notification->getPayload());*/

              /*if (strcmp(expected, actual) == 0) 
              {
              info("equal");
                }
                else
                {
              info("nothing");
                }*/
                char *expected = "slow";

int compare = strcmp(expected, notification->getPayload());
Serial.println("compare is: ");
Serial.println(compare);
                
                if (notification->getPacketId() != 0) {
                    info("before publish acknowledgement");
                    //
                    if (mqttSocket.sendPublishAcknowledgement(notification->getPacketId())) {
                        info("sent publish acknowledgement");
                    } else {
                        warning("cannot send publish acknowledgement");
                    }
                }
                //
                tasks.now(ledOff);
                tasks.after(3000, ledOn);
                //
                break;
            }
        }
        //
        delete packet;
    } else {
        warning("cannot receive packet");
    }
    //
    if (mqttSocket.isReadComplete() && mqttSocket.isWriteComplete()) {
        auto task1 = tasks.ifForThen(canReadSocket, 300, receive);
        auto task2 = tasks.after(300000, ping);
        tasks.onlyOneOf(task1, task2);
    } else {
        tasks.after(5000, closeSocket);
    }
}

void ping() {
    info("before ping request");
    //
    if (mqttSocket.sendPingRequest()) {
        info("sent ping request");
        auto task1 = tasks.ifForThen(canReadSocket, 300, receive);
        auto task2 = tasks.after(10000, closeSocket);
        tasks.onlyOneOf(task1, task2);
    } else {
        warning("cannot send ping request");
        tasks.now(closeSocket);
    }
}

void closeSocket() {
    info("close socket");
    mqttSocket.close();
    tasks.now(ledOff);
    tasks.after(25000, connectSocket);
}

void ledOn() {
    digitalWrite(LED_BUILTIN, HIGH);
}

void ledOff() {
    digitalWrite(LED_BUILTIN, LOW);
}

void setup() {
    Serial.begin(115200);
    //
    if (!Serial) {
        delay(1000);
    }
    //
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);
    tasks.now(beginGprs);
}

void loop() {
    if (tasks.available() > 0) {
        tasks.run();
    }
}

That code did not work.. still stuck saying connected to internet

but that will just check if it is connected or not, right?
I need to timeout after 30 seconds.

There it is, just don't call it again...

Aah! Makes sense. Sorry missed it

Even if I comment that, it still stuck at waiting for internet connection.

Too much monkeying around. I think it's time to start again clean with the original sketch, no modifications...

I agree with Aarg. Start simple and reduce your rather complex program into something small that exhibits the problem. You are using some constructs I've never seen, but I've only been in the Arduino world for three or four years.

What data type is : Continuation
I.E.
Continuation ledOn;

And I have never seen the tasks functions:
tasks.after(300, connectSocket);
So, maybe I am not the right person to help you.

Does seem weird to see a multitasking library used with things like delay(2000).