Skip to content

GSM patches to allow retries if connection fails #1053

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

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
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
113 changes: 85 additions & 28 deletions libraries/GSM/src/GSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,28 @@ 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) {

if (restart || isCmuxEnable()) {
reset();
/* 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 */
const bool emergencyReset = restart || isCmuxEnable();
DEBUG_INFO("Emergency reset %s", emergencyReset ? "enabled" : "disabled");
if (emergencyReset) {
hardwareReset();
}

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

if (!_context) {
_context = mbed::CellularContext::get_default_instance();
}
Expand All @@ -59,20 +77,18 @@ 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;
}

DEBUG_INFO("CMUX %s", _cmuxGSMenable ? "enabled" : "disabled");
_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 +122,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,13 +135,62 @@ bool arduino::GSMClass::isCmuxEnable() {
}

void arduino::GSMClass::end() {
if(_device) {
_device->shutdown();
}
}

void arduino::GSMClass::reset() {
if(_device) {
_device->soft_reset();
}
}

void arduino::GSMClass::off() {
if(_device) {
_device->soft_power_off();
}
}

int arduino::GSMClass::ping(const char* hostname, int ttl) {

mbed::GEMALTO_CINTERION_CellularStack* stack = (mbed::GEMALTO_CINTERION_CellularStack*)_context->get_stack();
if (!stack) {
return -1;
}
return stack->ping(hostname, ttl);
}

int arduino::GSMClass::ping(const String &hostname, int ttl)
{
return ping(hostname.c_str(), ttl);
}

int arduino::GSMClass::ping(IPAddress ip, int ttl)
{
String host;
host.reserve(15);

host += ip[0];
host += '.';
host += ip[1];
host += '.';
host += ip[2];
host += '.';
host += ip[3];

return ping(host, ttl);
}

int arduino::GSMClass::disconnect() {
if (_context) {
if (!_context) {
return 0;
}

if (_context->is_connected()) {
return _context->disconnect();
}

return 0;
}

Expand Down Expand Up @@ -158,34 +227,22 @@ NetworkInterface* arduino::GSMClass::getNetwork() {
return _context;
}

void arduino::GSMClass::reset() {
void arduino::GSMClass::hardwareReset() {
/* 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;
63 changes: 42 additions & 21 deletions libraries/GSM/src/GSM.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,47 @@ 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
*/
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);
/*
* 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 = false);

/*
* 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();
/*
* Send AT+CFUN=1,1 command to trigger a software reset. To be called only after end();
*/
void reset();

/*
* Send AT^SMSO="fast command to power off the modem. To be called only after end();
*/
void off();

/*
* 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 All @@ -108,6 +125,9 @@ class GSMClass : public MbedSocketClass {
void trace(Stream& stream);
void setTraceLevel(int trace_level, bool timestamp = false, bool at_trace = false);
#endif
int ping(const char* hostname, int ttl = 5000);
int ping(const String& hostname, int ttl = 5000);
int ping(IPAddress host, int ttl = 5000);
bool isConnected();

friend class GSMClient;
Expand All @@ -127,11 +147,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 @@ -146,8 +167,8 @@ class GSMClass : public MbedSocketClass {
static const char * getRegistrationStateString(const mbed::CellularNetwork::RegistrationStatus state);
void onStatusChange(nsapi_event_t ev, intptr_t in);

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

}
Expand Down
20 changes: 20 additions & 0 deletions libraries/GSM/src/GSMClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,29 @@
namespace arduino {

class GSMClient : public AClient {
private:
NetworkInterface *getNetwork() {
return GSM.getNetwork();
}

public:
size_t write(uint8_t b) {
int ret = 0;
do {
ret = client->write(b);
delay(0);
} while (ret == 0 && status());
return ret;
}

size_t write(const uint8_t *buf, size_t size) {
int ret = 0;
do {
ret = client->write(buf, size);
delay(0);
} while (ret == 0 && status());
return ret;
}
};

}
Expand Down
19 changes: 19 additions & 0 deletions libraries/GSM/src/GSMSSLClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,25 @@ class GSMSSLClient : public arduino::ASslClient {
NetworkInterface *getNetwork() {
return GSM.getNetwork();
}

public:
size_t write(uint8_t b) {
int ret = 0;
do {
ret = client->write(b);
delay(0);
} while (ret == 0 && status());
return ret;
}

size_t write(const uint8_t *buf, size_t size) {
int ret = 0;
do {
ret = client->write(buf, size);
delay(0);
} while (ret == 0 && status());
return ret;
}
};

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
From f40d4a9d65ee9163921271697d316c1061aca946 Mon Sep 17 00:00:00 2001
From: pennam <[email protected]>
Date: Thu, 31 Oct 2024 11:05:18 +0100
Subject: [PATCH] GEMALTO CINTERION: cleanup stack before connection

Allows to re-connect after a disconnection
---
.../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp
index 78955c599e..76c788cdaf 100644
--- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp
+++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp
@@ -35,6 +35,11 @@ nsapi_error_t GEMALTO_CINTERION_CellularContext::connect(const char *sim_pin, co
{
nsapi_error_t error = NSAPI_ERROR_OK;

+ if (_stack) {
+ delete _stack;
+ _stack = NULL;
+ }
+
set_sim_pin(sim_pin);
set_credentials(apn, uname, pwd);

--
2.45.2

25 changes: 25 additions & 0 deletions patches/0249-GEMALTO-CINTERION-close-socket-on-timeout.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
From 4b6c6ad0554c88c369fc4e2e5ed543d52117aa3f Mon Sep 17 00:00:00 2001
From: pennam <[email protected]>
Date: Thu, 31 Oct 2024 12:00:51 +0100
Subject: [PATCH] GEMALTO CINTERION: close socket on timeout

---
.../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp
index ac2a54282a..41a01859e7 100644
--- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp
+++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp
@@ -59,7 +59,7 @@ void GEMALTO_CINTERION_CellularStack::urc_sis()
}
if (urc_code == 0) {
int urc_info_id = _at.read_int();
- if (urc_info_id == 48) {
+ if (urc_info_id == 48 || urc_info_id == 20) {
tr_info("Socket closed %d", sock_id);
sock->closed = true;
if (sock->_cb) {
--
2.45.2

Loading
Loading