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: Add cellular state machine events reporting #767

Merged
merged 11 commits into from
Nov 21, 2023
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
Loading