Skip to content

Commit

Permalink
Merge pull request #767 from pennam/gsm_debug_retry
Browse files Browse the repository at this point in the history
GSM: Add cellular state machine events reporting
  • Loading branch information
facchinm authored Nov 21, 2023
2 parents 17873e0 + 8b85c6b commit 7b95100
Show file tree
Hide file tree
Showing 10 changed files with 651 additions and 48 deletions.
35 changes: 35 additions & 0 deletions libraries/GSM/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#######################################
# Syntax Coloring Map For GSM
#######################################

#######################################
# Class (KEYWORD1)
#######################################

GSM KEYWORD1
GSMClient KEYWORD1
GSMSSLClient KEYWORD1
GSMUDP KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin
disconnect
end
getTime
getLocalTime
setTime
enableCmux
isCmuxEnable
trace
setTraceLevel
ping
isConnected
getNetwork

#######################################
# Constants (LITERAL1)
#######################################

99 changes: 58 additions & 41 deletions libraries/GSM/src/GSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
#include "CellularInterface.h"
#include "GEMALTO_CINTERION_CellularStack.h"

#define MAXRETRY 3

arduino::CMUXClass *arduino::CMUXClass::get_default_instance()
{
static mbed::UnbufferedSerial serial(MBED_CONF_GEMALTO_CINTERION_TX, MBED_CONF_GEMALTO_CINTERION_RX, 115200);
Expand All @@ -47,72 +45,61 @@ 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()) {
pinMode(MBED_CONF_GEMALTO_CINTERION_RST, OUTPUT);
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, HIGH);
delay(800);
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, LOW);
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);
// this timer is to make sure that at boottime and when the CMUX is used,
// ^SYSTART is received in time to avoid stranger behaviour
// from HW serial
delay(2000);
if (restart || isCmuxEnable()) {
reset();
}

_context = mbed::CellularContext::get_default_instance();

if (_context == nullptr) {
printf("Invalid context\n");
DEBUG_ERROR("Invalid mbed::CellularContext");
return 0;
}

pinMode(MBED_CONF_GEMALTO_CINTERION_ON, INPUT_PULLDOWN);

static mbed::DigitalOut rts(MBED_CONF_GEMALTO_CINTERION_RTS, 0);

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

_device->set_cmux_status_flag(_cmuxGSMenable);

_context->set_sim_pin(pin);
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]));
#if GSM_DEBUG_ENABLE
_device->attach(mbed::callback(this, &GSMClass::onStatusChange));
#endif
_device->init();

_context->set_authentication_type((mbed::CellularContext::AuthenticationType)1);

_pin = pin;
_apn = apn;
_username = username;
_password = password;
_rat = rat;
_band = (FrequencyBand) band;
_context->set_credentials(apn, username, password);

_context->set_access_technology(rat);
_context->set_sim_pin(pin);
_context->set_authentication_type(mbed::CellularContext::AuthenticationType::PAP);
_context->set_credentials(_apn, _username, _password);
_context->set_access_technology(_rat);
_context->set_band(_band);

int connect_status = NSAPI_ERROR_AUTH_FAILURE;
uint8_t retryCount = 0;
while(connect_status != NSAPI_ERROR_OK && retryCount < MAXRETRY) {

connect_status = _context->connect(pin, apn, username, password);
retryCount++;

if (connect_status == NSAPI_ERROR_AUTH_FAILURE) {
tr_info("Authentication Failure. Exiting application.\n");
} else if (connect_status == NSAPI_ERROR_OK || connect_status == NSAPI_ERROR_IS_CONNECTED) {
connect_status = NSAPI_ERROR_OK;
tr_info("Connection Established.\n");
} else if (retryCount > 2) {
tr_info("Fatal connection failure: %d\n", connect_status);
} else {
tr_info("Couldn't connect, will retry...\n");
continue;
}

DEBUG_INFO("Connecting...");
connect_status = _context->connect(pin, apn, username, password);

if (connect_status == NSAPI_ERROR_AUTH_FAILURE) {
DEBUG_ERROR("Authentication Failure. Exiting application.");
} else if (connect_status == NSAPI_ERROR_OK || connect_status == NSAPI_ERROR_IS_CONNECTED) {
connect_status = NSAPI_ERROR_OK;
DEBUG_INFO("Connection Established.");
} else {
DEBUG_ERROR("Couldn't connect.");
}

return connect_status == NSAPI_ERROR_OK ? 1 : 0;
Expand Down Expand Up @@ -164,4 +151,34 @@ NetworkInterface* arduino::GSMClass::getNetwork() {
return _context;
}

void arduino::GSMClass::reset() {
pinMode(MBED_CONF_GEMALTO_CINTERION_RST, OUTPUT);
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, HIGH);
delay(800);
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, LOW);
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;
48 changes: 45 additions & 3 deletions libraries/GSM/src/GSM.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@
#error Gemalto Cinterion cellular connectivity not supported
#endif

#define MBED_CONF_APP_SOCK_TYPE 1

#if defined __has_include
#if __has_include ("GPS.h")
# define _CMUX_ENABLE 1
Expand All @@ -65,6 +63,27 @@
#endif
#endif

#if defined __has_include
#if __has_include ("Arduino_DebugUtils.h")
#include "Arduino_DebugUtils.h"
#define GSM_DEBUG_ENABLE 1
#else
#define DEBUG_ERROR(fmt, ...)
#define DEBUG_WARNING(fmt, ...)
#define DEBUG_INFO(fmt, ...)
#define DEBUG_DEBUG(fmt, ...)
#define DEBUG_VERBOSE(fmt, ...)
#define GSM_DEBUG_ENABLE 0
#endif
#else
#define DEBUG_ERROR(fmt, ...)
#define DEBUG_WARNING(fmt, ...)
#define DEBUG_INFO(fmt, ...)
#define DEBUG_DEBUG(fmt, ...)
#define DEBUG_VERBOSE(fmt, ...)
#define GSM_DEBUG_ENABLE 0
#endif

namespace arduino {

typedef void* (*voidPrtFuncPtr)(void);
Expand Down Expand Up @@ -110,7 +129,7 @@ class GSMClass : public MbedSocketClass {
bool isCmuxEnable();
#if MBED_CONF_MBED_TRACE_ENABLE
void trace(Stream& stream);
void setTraceLevel(int trace_level, bool timestamp = false);
void setTraceLevel(int trace_level, bool timestamp = false, bool at_trace = false);
#endif
int ping(const char* hostname, uint8_t ttl = 128);
int ping(const String& hostname, uint8_t ttl = 128);
Expand All @@ -133,6 +152,29 @@ class GSMClass : public MbedSocketClass {
NetworkInterface* gsm_if = nullptr;
mbed::CellularContext* _context = nullptr;
mbed::CellularDevice* _device = nullptr;
bool _at_debug = false;

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

#if GSM_DEBUG_ENABLE
static constexpr int RSSI_UNKNOWN = 99;
static const char * const sim_state_str[];
static const char * const reg_type_str[];
static const char * const rat_str[];
static const char * const state_str[];
static const char * const event_str[];
static const char * getRATString(const mbed::CellularNetwork::RadioAccessTechnology rat);
static const char * getStateString(const mbed::CellularStateMachine::CellularState state);
static const char * getEventString(const cellular_event_status event);
static const char * getSIMStateString(const mbed::CellularDevice::SimState state);
static const char * getRegistrationStateString(const mbed::CellularNetwork::RegistrationStatus state);
void onStatusChange(nsapi_event_t ev, intptr_t in);
#endif
void reset();
bool isReady(const int timeout = 5000);
};

}
Expand Down
Loading

0 comments on commit 7b95100

Please sign in to comment.