Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GSM: allow retry if connection fails #975

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 30 additions & 25 deletions libraries/GSM/src/GSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,26 @@ mbed::CellularDevice *mbed::CellularDevice::get_default_instance()

int arduino::GSMClass::begin(const char* pin, const char* apn, const char* username, const char* password, RadioAccessTechnologyType rat, uint32_t band, bool restart) {

/* Assume module is powered ON. Uncomment this line is you are using
* Edge Control without Arduino_ConnectionHandler
* #if defined (ARDUINO_EDGE_CONTROL)
* pinMode(ON_MKR2, OUTPUT);
* digitalWrite(ON_MKR2, HIGH);
* #endif
*/

/* Ensure module is not under reset */
pinMode(MBED_CONF_GEMALTO_CINTERION_RST, OUTPUT);
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, LOW);

/* Reset module if needed */
if (restart || isCmuxEnable()) {
reset();
}

/* Create rising edge on pin ON */
on();

if (!_context) {
_context = mbed::CellularContext::get_default_instance();
}
Expand All @@ -59,20 +75,17 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern
return 0;
}

pinMode(MBED_CONF_GEMALTO_CINTERION_ON, INPUT_PULLDOWN);

#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)
/* This is needed to wakeup module if hw flow control is enabled */
static mbed::DigitalOut rts(MBED_CONF_GEMALTO_CINTERION_RTS, 0);
#endif

_device = _context->get_device();
_device->modem_debug_on(_at_debug);

if (!isReady()) {
DEBUG_ERROR("Cellular device not ready");
return 0;
}

_device->set_cmux_status_flag(_cmuxGSMenable);
_device->set_retry_timeout_array(_retry_timeout, sizeof(_retry_timeout) / sizeof(_retry_timeout[0]));
_device->set_timeout(_timeout);
_device->attach(mbed::callback(this, &GSMClass::onStatusChange));
_device->init();

Expand Down Expand Up @@ -106,6 +119,10 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern
return connect_status == NSAPI_ERROR_OK ? 1 : 0;
}

void arduino::GSMClass::setTimeout(unsigned long timeout) {
_timeout = timeout;
}

void arduino::GSMClass::enableCmux() {
_cmuxGSMenable = true;
}
Expand All @@ -115,7 +132,7 @@ bool arduino::GSMClass::isCmuxEnable() {
}

void arduino::GSMClass::end() {

_device->shutdown();
}

int arduino::GSMClass::disconnect() {
Expand Down Expand Up @@ -159,33 +176,21 @@ NetworkInterface* arduino::GSMClass::getNetwork() {
}

void arduino::GSMClass::reset() {
/* Reset logic is inverted */
pinMode(MBED_CONF_GEMALTO_CINTERION_RST, OUTPUT);
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, HIGH);
delay(800);
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, LOW);
}

void arduino::GSMClass::on() {
/* Module needs a rising edge to power on */
pinMode(MBED_CONF_GEMALTO_CINTERION_ON, OUTPUT);
digitalWrite(MBED_CONF_GEMALTO_CINTERION_ON, LOW);
delay(1);
digitalWrite(MBED_CONF_GEMALTO_CINTERION_ON, HIGH);
delay(1);
}

bool arduino::GSMClass::isReady(const int timeout) {
if (!_device) {
DEBUG_ERROR("No device found");
return false;
}

const unsigned int start = millis();
while (_device->is_ready() != NSAPI_ERROR_OK) {

if (millis() - start > timeout) {
DEBUG_WARNING("Timeout waiting device ready");
return false;
}
delay(100);
}
return true;
}

arduino::GSMClass GSM;
46 changes: 27 additions & 19 deletions libraries/GSM/src/GSM.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,37 @@ class GSMClass : public MbedSocketClass {
}
}

/* Start GSM connection.
* Configure the credentials into the device.
*
* param pin: Pointer to the pin string.
* param apn: Pointer to the apn string.
* param username: Pointer to the username string.
* param password: Pointer to the password string.
* param rat: Radio Access Technology.
*
* return: 0 in case of success, negative number in case of failure
*/
/*
* Start GSM connection. Configure the credentials into the device.
*
* param pin: Pointer to the pin string.
* param apn: Pointer to the apn string.
* param username: Pointer to the username string.
* param password: Pointer to the password string.
* param rat: Radio Access Technology.
*
* return: 0 in case of success, negative number in case of failure
*/
int begin(const char* pin, const char* apn, const char* username, const char* password, RadioAccessTechnologyType rat = CATNB, uint32_t band = BAND_20, bool restart = true);

/*
* Disconnect from the network
*
* return: one value of wl_status_t enum
*/
* Disconnect from the network
*
* return: one value of wl_status_t enum
*/
int disconnect(void);

/*
* Reset internal state machine in order to be ready to reconnect again.
*/
void end(void);

unsigned long getTime();
/*
* Change cellular state timeouts. Needs to be called before GSM.begin()
*/
void setTimeout(unsigned long timeout);

unsigned long getTime();
unsigned long getLocalTime();

bool setTime(unsigned long const epoch, int const timezone = 0);
Expand Down Expand Up @@ -130,11 +137,12 @@ class GSMClass : public MbedSocketClass {
mbed::CellularContext* _context = nullptr;
mbed::CellularDevice* _device = nullptr;
bool _at_debug = false;
unsigned long _timeout = 1000;

/* Internal cellular state machine retries. Values are in seconds.
* This array also defines the maximum number of retries to 6
* This array also defines the maximum number of retries to CELLULAR_RETRY_ARRAY_SIZE
*/
const uint16_t _retry_timeout[6] = {1, 2, 4, 8, 16, 32};
const uint16_t _retry_timeout[CELLULAR_RETRY_ARRAY_SIZE] = {1, 2, 4, 8, 8, 8, 8, 8, 8, 8};

static constexpr int RSSI_UNKNOWN = 99;
static const char * const sim_state_str[];
Expand All @@ -150,7 +158,7 @@ class GSMClass : public MbedSocketClass {
void onStatusChange(nsapi_event_t ev, intptr_t in);

void reset();
bool isReady(const int timeout = 5000);
void on();
};

}
Expand Down
5 changes: 4 additions & 1 deletion libraries/SocketWrapper/src/MbedClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,10 @@ size_t arduino::MbedClient::write(const uint8_t *buf, size_t size) {
return 0;

sock->set_timeout(_timeout);
int ret = sock->send(buf, size);
int ret = NSAPI_ERROR_WOULD_BLOCK;
do {
ret = sock->send(buf, size);
} while ((ret != size && ret == NSAPI_ERROR_WOULD_BLOCK) && connected());
sock->set_blocking(false);
return ret >= 0 ? ret : 0;
}
Expand Down
Loading