From 5e507f0422d30d98c1b4a446b91b5d6238c631f8 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 17 Nov 2023 18:01:17 +0100 Subject: [PATCH 01/11] PTYSerial: do not trace write data * To trace AT output messages enable AT debug trace in mbed --- libraries/GSM/src/PTYSerial.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/GSM/src/PTYSerial.cpp b/libraries/GSM/src/PTYSerial.cpp index 3a457fcd4..ef1be67fa 100644 --- a/libraries/GSM/src/PTYSerial.cpp +++ b/libraries/GSM/src/PTYSerial.cpp @@ -127,20 +127,17 @@ int PTYSerial::get_port() { } int PTYSerial::write(const void *buffer) { const char *buf_ptr = static_cast(buffer); - tr_info("%s", buffer); return write(buf_ptr, sizeof(buffer)); } int PTYSerial::write(const void *buffer, size_t length) { const char *buf_ptr = static_cast(buffer); - tr_info("%s", buffer); int ret = _parent->populate_tx_buffer(buf_ptr, length, this->get_port()); return ret; } int PTYSerial::write(const void *buffer, size_t length, int id) { const char *buf_ptr = static_cast(buffer); - tr_info("%s", buffer); int ret = _parent->populate_tx_buffer(buf_ptr, length, id); return ret; } From 9d35b94b1bc683a846a21e8a5cac52618cc9944d Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 17 Nov 2023 18:04:54 +0100 Subject: [PATCH 02/11] GSM: allow to enable and disable AT messages trace --- libraries/GSM/src/GSM.cpp | 2 ++ libraries/GSM/src/GSM.h | 3 ++- libraries/GSM/src/GSMTrace.cpp | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/GSM/src/GSM.cpp b/libraries/GSM/src/GSM.cpp index 19305540b..f3db9002d 100644 --- a/libraries/GSM/src/GSM.cpp +++ b/libraries/GSM/src/GSM.cpp @@ -75,6 +75,8 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern _device = _context->get_device(); + _device->modem_debug_on(_at_debug); + _device->set_cmux_status_flag(_cmuxGSMenable); _context->set_sim_pin(pin); diff --git a/libraries/GSM/src/GSM.h b/libraries/GSM/src/GSM.h index 68fe66cec..59743f8f5 100644 --- a/libraries/GSM/src/GSM.h +++ b/libraries/GSM/src/GSM.h @@ -110,7 +110,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); @@ -133,6 +133,7 @@ class GSMClass : public MbedSocketClass { NetworkInterface* gsm_if = nullptr; mbed::CellularContext* _context = nullptr; mbed::CellularDevice* _device = nullptr; + bool _at_debug = false; }; } diff --git a/libraries/GSM/src/GSMTrace.cpp b/libraries/GSM/src/GSMTrace.cpp index 8c65e192a..6c87c54c4 100644 --- a/libraries/GSM/src/GSMTrace.cpp +++ b/libraries/GSM/src/GSMTrace.cpp @@ -47,7 +47,7 @@ static void trace_println(const char* c) { } #endif -void arduino::GSMClass::setTraceLevel(int trace_level, bool timestamp) { +void arduino::GSMClass::setTraceLevel(int trace_level, bool timestamp, bool at_trace) { #if MBED_CONF_MBED_TRACE_ENABLE switch(trace_level) { case 0: mbed_trace_config_set(TRACE_ACTIVE_LEVEL_NONE); break; @@ -60,6 +60,8 @@ void arduino::GSMClass::setTraceLevel(int trace_level, bool timestamp) { default: mbed_trace_config_set(TRACE_ACTIVE_LEVEL_ALL); break; } + _at_debug = at_trace; + if (timestamp) { mbed_trace_prefix_function_set( &trace_time ); } From f4d7f334cb444be3133c8fcc6d06edb93c34ef26 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 21 Nov 2023 08:22:56 +0100 Subject: [PATCH 03/11] GSM: remove unused define --- libraries/GSM/src/GSM.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/GSM/src/GSM.h b/libraries/GSM/src/GSM.h index 59743f8f5..fa63e0153 100644 --- a/libraries/GSM/src/GSM.h +++ b/libraries/GSM/src/GSM.h @@ -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 From 9a81f86e0420d3da9718902f038a59863dde40b4 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 21 Nov 2023 09:35:26 +0100 Subject: [PATCH 04/11] GSM: enable debugging without mbed trace * Based on mbed attach callback and Arduino_DebugUtils --- libraries/GSM/src/GSM.cpp | 14 +- libraries/GSM/src/GSM.h | 36 +++++ libraries/GSM/src/GSMDebug.cpp | 274 +++++++++++++++++++++++++++++++++ 3 files changed, 319 insertions(+), 5 deletions(-) create mode 100644 libraries/GSM/src/GSMDebug.cpp diff --git a/libraries/GSM/src/GSM.cpp b/libraries/GSM/src/GSM.cpp index f3db9002d..165022ac8 100644 --- a/libraries/GSM/src/GSM.cpp +++ b/libraries/GSM/src/GSM.cpp @@ -66,7 +66,7 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern _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); @@ -81,6 +81,10 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern _context->set_sim_pin(pin); +#if GSM_DEBUG_ENABLE + _device->attach(mbed::callback(this, &GSMClass::onStatusChange)); +#endif + _device->init(); _context->set_authentication_type((mbed::CellularContext::AuthenticationType)1); @@ -104,14 +108,14 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern retryCount++; if (connect_status == NSAPI_ERROR_AUTH_FAILURE) { - tr_info("Authentication Failure. Exiting application.\n"); + DEBUG_ERROR("Authentication Failure. Exiting application."); } else if (connect_status == NSAPI_ERROR_OK || connect_status == NSAPI_ERROR_IS_CONNECTED) { connect_status = NSAPI_ERROR_OK; - tr_info("Connection Established.\n"); + DEBUG_INFO("Connection Established."); } else if (retryCount > 2) { - tr_info("Fatal connection failure: %d\n", connect_status); + DEBUG_ERROR("Fatal connection failure: %d", connect_status); } else { - tr_info("Couldn't connect, will retry...\n"); + DEBUG_WARNING("Couldn't connect, will retry..."); continue; } diff --git a/libraries/GSM/src/GSM.h b/libraries/GSM/src/GSM.h index fa63e0153..f090cec32 100644 --- a/libraries/GSM/src/GSM.h +++ b/libraries/GSM/src/GSM.h @@ -63,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); @@ -132,6 +153,21 @@ class GSMClass : public MbedSocketClass { mbed::CellularContext* _context = nullptr; mbed::CellularDevice* _device = nullptr; bool _at_debug = false; + +#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 }; } diff --git a/libraries/GSM/src/GSMDebug.cpp b/libraries/GSM/src/GSMDebug.cpp new file mode 100644 index 000000000..5ec49324d --- /dev/null +++ b/libraries/GSM/src/GSMDebug.cpp @@ -0,0 +1,274 @@ +/* + GSMDebug.cpp - Library for GSM on mbed platforms. + Copyright (c) 2011-2023 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#if GSM_DEBUG_ENABLE + +constexpr const char * const arduino::GSMClass::sim_state_str[] = { + "Ready", + "PIN Needed", + "PUK Needed", + "Unknown" +}; + +constexpr const char * const arduino::GSMClass::reg_type_str[] = { + "Not Registered", + "Registered (Home Network)", + "Searching Network", + "Registration Denied", + "Registration Unknown", + "Registered (Roaming)", + "Registered (SMS Only Home)", + "Registered (SMS Only Roaming)", + "Attached (Emergency Only)", + "Registered (CSFB Not Preferred Home)", + "Registered (CSFB Not Preferred Roaming)", + "Already Registered" +}; + +constexpr const char * const arduino::GSMClass::rat_str[] = { + "GSM", + "GSM_COMPACT", + "UTRAN", + "EGPRS", + "HSDPA", + "HSUPA", + "HSDPA_HSUPA", + "E_UTRAN", + "CATM1", + "NB1", + "RAT unknown", +}; + +constexpr const char * const arduino::GSMClass::state_str[] = { + "Init", + "Power On", + "Device ready", + "SIM PIN", + "Signal quality", + "Registering network", + "Attaching network", + "Unknown" +}; + +constexpr const char * const arduino::GSMClass::event_str[] = { + "Device ready", + "SIM status", + "Registration status", + "Registration type", + "Cell ID", + "RAT", + "Attach network", + "Activate PDP context", + "Signal quality", + "Retry", + "Timeout", +}; + +const char * arduino::GSMClass::getRATString(const mbed::CellularNetwork::RadioAccessTechnology rat) { + switch (rat) { + case mbed::CellularNetwork::RadioAccessTechnology::RAT_GSM: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_GSM_COMPACT: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_UTRAN: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_EGPRS: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_HSDPA: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_HSUPA: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_HSDPA_HSUPA: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_E_UTRAN: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_CATM1: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_NB1: + return rat_str[rat]; + break; + + case mbed::CellularNetwork::RadioAccessTechnology::RAT_UNKNOWN: + case mbed::CellularNetwork::RadioAccessTechnology::RAT_MAX: + default: + return rat_str[mbed::CellularNetwork::RadioAccessTechnology::RAT_UNKNOWN]; + break; + } +} + +const char * arduino::GSMClass::getStateString(const mbed::CellularStateMachine::CellularState state) { + switch (state) { + case mbed::CellularStateMachine::CellularState::STATE_INIT: + case mbed::CellularStateMachine::CellularState::STATE_POWER_ON: + case mbed::CellularStateMachine::CellularState::STATE_DEVICE_READY: + case mbed::CellularStateMachine::CellularState::STATE_SIM_PIN: + case mbed::CellularStateMachine::CellularState::STATE_SIGNAL_QUALITY: + case mbed::CellularStateMachine::CellularState::STATE_REGISTERING_NETWORK: + case mbed::CellularStateMachine::CellularState::STATE_ATTACHING_NETWORK: + return state_str[state]; + break; + + case mbed::CellularStateMachine::CellularState::STATE_MAX_FSM_STATE: + default: + return state_str[mbed::CellularStateMachine::CellularState::STATE_MAX_FSM_STATE]; + break; + } +} + +const char * arduino::GSMClass::getEventString(const cellular_event_status event) { + switch (event) { + case cellular_event_status::CellularDeviceReady: + case cellular_event_status::CellularSIMStatusChanged: + case cellular_event_status::CellularRegistrationStatusChanged: + case cellular_event_status::CellularRegistrationTypeChanged: + case cellular_event_status::CellularCellIDChanged: + case cellular_event_status::CellularRadioAccessTechnologyChanged: + case cellular_event_status::CellularAttachNetwork: + case cellular_event_status::CellularActivatePDPContext: + case cellular_event_status::CellularSignalQuality: + case cellular_event_status::CellularStateRetryEvent: + case cellular_event_status::CellularDeviceTimeout: + return event_str[event - NSAPI_EVENT_CELLULAR_STATUS_BASE]; + break; + + default: + return "Unknown"; + break; + } +} + +const char * arduino::GSMClass::getSIMStateString(const mbed::CellularDevice::SimState state) { + switch (state) { + case mbed::CellularDevice::SimStateReady: + case mbed::CellularDevice::SimStatePinNeeded: + case mbed::CellularDevice::SimStatePukNeeded: + case mbed::CellularDevice::SimStateUnknown: + return sim_state_str[state]; + break; + + default: + return sim_state_str[mbed::CellularDevice::SimStateUnknown]; + } +} + +const char * arduino::GSMClass::getRegistrationStateString(const mbed::CellularNetwork::RegistrationStatus state) { + switch (state) { + case mbed::CellularNetwork::StatusNotAvailable: + case mbed::CellularNetwork::NotRegistered: + case mbed::CellularNetwork::RegisteredHomeNetwork: + case mbed::CellularNetwork::SearchingNetwork: + case mbed::CellularNetwork::RegistrationDenied: + case mbed::CellularNetwork::Unknown: + case mbed::CellularNetwork::RegisteredRoaming: + case mbed::CellularNetwork::RegisteredSMSOnlyHome: + case mbed::CellularNetwork::RegisteredSMSOnlyRoaming: + case mbed::CellularNetwork::AttachedEmergencyOnly: + case mbed::CellularNetwork::RegisteredCSFBNotPreferredHome: + case mbed::CellularNetwork::RegisteredCSFBNotPreferredRoaming: + case mbed::CellularNetwork::AlreadyRegistered: + return reg_type_str[state]; + break; + + default: + return reg_type_str[mbed::CellularNetwork::Unknown]; + } +} + +void arduino::GSMClass::onStatusChange(nsapi_event_t ev, intptr_t in) { + + const cell_callback_data_t *data = (const cell_callback_data_t *)in; + + switch(ev) + { + case CellularDeviceReady: + { + DEBUG_INFO("Modem is powered and ready to receive commands"); + } + break; + + case CellularSIMStatusChanged: + { + const mbed::CellularDevice::SimState state = static_cast(data->status_data); + DEBUG_INFO("SIM status: %s", getSIMStateString(state)); + } + break; + + case CellularRegistrationStatusChanged: + { + const mbed::CellularNetwork::RegistrationStatus state = static_cast(data->status_data); + DEBUG_INFO("Registration status: %s", getRegistrationStateString(state)); + } + break; + + case CellularRegistrationTypeChanged: + { + /* Never called from mbed driver */ + } + break; + + case CellularCellIDChanged: + { + DEBUG_INFO("Cellular ID changed: %d", data->status_data); + } + break; + + case CellularRadioAccessTechnologyChanged: + { + const mbed::CellularNetwork::RadioAccessTechnology rat = static_cast (data->status_data); + DEBUG_INFO("RAT changed: %s", getRATString(rat)); + } + break; + + case CellularAttachNetwork: + { + DEBUG_INFO("Network status: %s", data->status_data ? "Attached" : "Detached"); + } + break; + + case CellularActivatePDPContext: + { + DEBUG_INFO("Activate PDP context %s", (data->error != NSAPI_ERROR_OK) ? "Failure" : "Success"); + } + break; + + case CellularSignalQuality: + { + const cell_signal_quality_t * sig = (const cell_signal_quality_t *)data->data; + if((data->error != NSAPI_ERROR_OK) || (sig->rssi == RSSI_UNKNOWN)) { + DEBUG_INFO("RSSI: Unknown"); + } else { + DEBUG_INFO("RSSI: %d", sig->rssi); + } + } + break; + + case CellularStateRetryEvent: + { + const cell_retry_cb_t * retry_cb_data = (const cell_retry_cb_t *)data->data; + const cellular_event_status event = static_cast(data->status_data); + const mbed::CellularStateMachine::CellularState state = static_cast(retry_cb_data->state); + DEBUG_WARNING("Cellular event %s timed out. Cellular state %s, retry count %d", getEventString(event), getStateString(state), retry_cb_data->retry_count); + } + break; + + case CellularDeviceTimeout: + { + const cell_timeout_cb_t * timeout_cb_data = (const cell_timeout_cb_t *)data->data; + const cellular_event_status event = static_cast(data->status_data); + const mbed::CellularStateMachine::CellularState state = static_cast(timeout_cb_data->state); + DEBUG_DEBUG("Cellular state: %s, waiting for event %s. Timeout %d", getStateString(state), getEventString(event), timeout_cb_data->timeout); + } + break; + } +} + +#endif From c4065f5171d00dc8e679d608d1323f664d5b9b2c Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 21 Nov 2023 13:49:47 +0100 Subject: [PATCH 05/11] GSM: limit the number of internal state machine retries to 6 --- libraries/GSM/src/GSM.cpp | 1 + libraries/GSM/src/GSM.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/libraries/GSM/src/GSM.cpp b/libraries/GSM/src/GSM.cpp index 165022ac8..229183d6d 100644 --- a/libraries/GSM/src/GSM.cpp +++ b/libraries/GSM/src/GSM.cpp @@ -81,6 +81,7 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern _context->set_sim_pin(pin); + _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 diff --git a/libraries/GSM/src/GSM.h b/libraries/GSM/src/GSM.h index f090cec32..46f4932bb 100644 --- a/libraries/GSM/src/GSM.h +++ b/libraries/GSM/src/GSM.h @@ -154,6 +154,11 @@ class GSMClass : public MbedSocketClass { 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[]; From 7d988ba7cf4e1edcaa69a477612aefe65a0c6292 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 21 Nov 2023 14:08:15 +0100 Subject: [PATCH 06/11] GSM: remove begin() retry logic * Internal retries are handled in mbed cellular state machine. If needed user should implement its own retry logic in the sketch. --- libraries/GSM/src/GSM.cpp | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/libraries/GSM/src/GSM.cpp b/libraries/GSM/src/GSM.cpp index 229183d6d..5f3261f38 100644 --- a/libraries/GSM/src/GSM.cpp +++ b/libraries/GSM/src/GSM.cpp @@ -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); @@ -102,24 +100,17 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern _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) { - 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 if (retryCount > 2) { - DEBUG_ERROR("Fatal connection failure: %d", connect_status); - } else { - DEBUG_WARNING("Couldn't connect, will retry..."); - 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; From aec787b1b7304017054a371bade94dda9c448740 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 21 Nov 2023 13:59:31 +0100 Subject: [PATCH 07/11] GSM: move reset logic inside a function --- libraries/GSM/src/GSM.cpp | 32 ++++++++++++++++++-------------- libraries/GSM/src/GSM.h | 1 + 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/libraries/GSM/src/GSM.cpp b/libraries/GSM/src/GSM.cpp index 5f3261f38..77aa49077 100644 --- a/libraries/GSM/src/GSM.cpp +++ b/libraries/GSM/src/GSM.cpp @@ -45,20 +45,8 @@ 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(); @@ -162,4 +150,20 @@ 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); + // 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); +} + arduino::GSMClass GSM; diff --git a/libraries/GSM/src/GSM.h b/libraries/GSM/src/GSM.h index 46f4932bb..4724ca1ac 100644 --- a/libraries/GSM/src/GSM.h +++ b/libraries/GSM/src/GSM.h @@ -173,6 +173,7 @@ class GSMClass : public MbedSocketClass { static const char * getRegistrationStateString(const mbed::CellularNetwork::RegistrationStatus state); void onStatusChange(nsapi_event_t ev, intptr_t in); #endif + void reset(); }; } From 02dfb64925dde9ced2dadc6723127560dd80572c Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 21 Nov 2023 14:10:15 +0100 Subject: [PATCH 08/11] GSM: add function to wait for modem ready with timeout --- libraries/GSM/src/GSM.cpp | 27 +++++++++++++++++++++++---- libraries/GSM/src/GSM.h | 1 + 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/libraries/GSM/src/GSM.cpp b/libraries/GSM/src/GSM.cpp index 77aa49077..215bf23e5 100644 --- a/libraries/GSM/src/GSM.cpp +++ b/libraries/GSM/src/GSM.cpp @@ -61,6 +61,11 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern _device = _context->get_device(); + if (!isReady()) { + DEBUG_ERROR("Cellular device not ready"); + return 0; + } + _device->modem_debug_on(_at_debug); _device->set_cmux_status_flag(_cmuxGSMenable); @@ -160,10 +165,24 @@ void arduino::GSMClass::reset() { 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); +} + +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; diff --git a/libraries/GSM/src/GSM.h b/libraries/GSM/src/GSM.h index 4724ca1ac..43512cec1 100644 --- a/libraries/GSM/src/GSM.h +++ b/libraries/GSM/src/GSM.h @@ -174,6 +174,7 @@ class GSMClass : public MbedSocketClass { void onStatusChange(nsapi_event_t ev, intptr_t in); #endif void reset(); + bool isReady(const int timeout = 5000); }; } From fb10917fe6aff583d7e923dbf59671fd3cd64669 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 21 Nov 2023 14:09:54 +0100 Subject: [PATCH 09/11] GSM: reorder function calls --- libraries/GSM/src/GSM.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/libraries/GSM/src/GSM.cpp b/libraries/GSM/src/GSM.cpp index 215bf23e5..e510697b4 100644 --- a/libraries/GSM/src/GSM.cpp +++ b/libraries/GSM/src/GSM.cpp @@ -55,41 +55,37 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern 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); if (!isReady()) { DEBUG_ERROR("Cellular device not ready"); return 0; } - _device->modem_debug_on(_at_debug); - _device->set_cmux_status_flag(_cmuxGSMenable); - - _context->set_sim_pin(pin); - _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; From c00bdb9fe57035a0dc6d90568111c8015d29ebc1 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 21 Nov 2023 15:20:43 +0100 Subject: [PATCH 10/11] GSM: add keywords file --- libraries/GSM/keywords.txt | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 libraries/GSM/keywords.txt diff --git a/libraries/GSM/keywords.txt b/libraries/GSM/keywords.txt new file mode 100644 index 000000000..b61108b00 --- /dev/null +++ b/libraries/GSM/keywords.txt @@ -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) +####################################### + From 8b85c6b90aacca628ec73cf61e1646c22e957787 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 21 Nov 2023 15:25:27 +0100 Subject: [PATCH 11/11] mbed: add new GSM patches --- ...void-callback-data-is-changed-before.patch | 41 ++++++++ ...-temporarily-change-debug-options-to.patch | 30 ++++++ ...hine-add-state-data-to-timeout-and-r.patch | 97 +++++++++++++++++++ ...malto-Cinterion-improve-trace-output.patch | 68 +++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 patches/0223-CellularDevice-avoid-callback-data-is-changed-before.patch create mode 100644 patches/0224-ATHandler-do-not-temporarily-change-debug-options-to.patch create mode 100644 patches/0225-CellularStateMachine-add-state-data-to-timeout-and-r.patch create mode 100644 patches/0226-Gemalto-Cinterion-improve-trace-output.patch diff --git a/patches/0223-CellularDevice-avoid-callback-data-is-changed-before.patch b/patches/0223-CellularDevice-avoid-callback-data-is-changed-before.patch new file mode 100644 index 000000000..432846512 --- /dev/null +++ b/patches/0223-CellularDevice-avoid-callback-data-is-changed-before.patch @@ -0,0 +1,41 @@ +From 0611201dfb21fcc36e0d37e283a7e8bb44664ec8 Mon Sep 17 00:00:00 2001 +From: pennam +Date: Fri, 17 Nov 2023 17:25:50 +0100 +Subject: [PATCH 223/226] CellularDevice: avoid callback data is changed before + attached callback is changed + +--- + .../source/framework/device/CellularDevice.cpp | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/connectivity/cellular/source/framework/device/CellularDevice.cpp b/connectivity/cellular/source/framework/device/CellularDevice.cpp +index 50d900e14a..1f53b33e61 100644 +--- a/connectivity/cellular/source/framework/device/CellularDevice.cpp ++++ b/connectivity/cellular/source/framework/device/CellularDevice.cpp +@@ -180,6 +180,11 @@ void CellularDevice::stm_callback(nsapi_event_t ev, intptr_t ptr) + + void CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularContext *ctx) + { ++ // forward to callback function if set by attach(...). ++ if (_status_cb) { ++ _status_cb(ev, ptr); ++ } ++ + if (ev >= NSAPI_EVENT_CELLULAR_STATUS_BASE && ev <= NSAPI_EVENT_CELLULAR_STATUS_END) { + cellular_connection_status_t cell_ev = (cellular_connection_status_t)ev; + cell_callback_data_t *ptr_data = (cell_callback_data_t *)ptr; +@@ -220,11 +225,6 @@ void CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularC + } + curr = curr->_next; + } +- +- // forward to callback function if set by attach(...). +- if (_status_cb) { +- _status_cb(ev, ptr); +- } + } + + nsapi_error_t CellularDevice::shutdown() +-- +2.42.0 + diff --git a/patches/0224-ATHandler-do-not-temporarily-change-debug-options-to.patch b/patches/0224-ATHandler-do-not-temporarily-change-debug-options-to.patch new file mode 100644 index 000000000..2cd99db2b --- /dev/null +++ b/patches/0224-ATHandler-do-not-temporarily-change-debug-options-to.patch @@ -0,0 +1,30 @@ +From 973a19b25200a2d11746ea8196a8403f189e13a7 Mon Sep 17 00:00:00 2001 +From: pennam +Date: Fri, 17 Nov 2023 17:29:39 +0100 +Subject: [PATCH 224/226] ATHandler: do not temporarily change debug options to + partially trace AT commands + +--- + connectivity/cellular/source/framework/device/ATHandler.cpp | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/connectivity/cellular/source/framework/device/ATHandler.cpp b/connectivity/cellular/source/framework/device/ATHandler.cpp +index f305fd8af5..36d21243f8 100644 +--- a/connectivity/cellular/source/framework/device/ATHandler.cpp ++++ b/connectivity/cellular/source/framework/device/ATHandler.cpp +@@ -1244,12 +1244,7 @@ void ATHandler::handle_start(const char *cmd, const char *cmd_chr) + } + _cmd_buffer[len] = '\0'; + +- const bool temp_state = get_debug(); +- set_debug(true); +- + cmd_start(_cmd_buffer); +- +- set_debug(temp_state); + } + + void ATHandler::cmd_start_stop(const char *cmd, const char *cmd_chr, const char *format, ...) +-- +2.42.0 + diff --git a/patches/0225-CellularStateMachine-add-state-data-to-timeout-and-r.patch b/patches/0225-CellularStateMachine-add-state-data-to-timeout-and-r.patch new file mode 100644 index 000000000..813262e59 --- /dev/null +++ b/patches/0225-CellularStateMachine-add-state-data-to-timeout-and-r.patch @@ -0,0 +1,97 @@ +From 1e2795ce9a47146d8c87e4ff957ac3784482e075 Mon Sep 17 00:00:00 2001 +From: pennam +Date: Fri, 17 Nov 2023 17:57:49 +0100 +Subject: [PATCH 225/226] CellularStateMachine: add state data to timeout and + retry callbacks + +--- + .../framework/common/CellularCommon.h | 20 +++++++++++++++++++ + .../framework/device/CellularStateMachine.h | 2 ++ + .../framework/device/CellularStateMachine.cpp | 11 +++++++--- + 3 files changed, 30 insertions(+), 3 deletions(-) + +diff --git a/connectivity/cellular/include/cellular/framework/common/CellularCommon.h b/connectivity/cellular/include/cellular/framework/common/CellularCommon.h +index f0466e88cf..96e25dc991 100644 +--- a/connectivity/cellular/include/cellular/framework/common/CellularCommon.h ++++ b/connectivity/cellular/include/cellular/framework/common/CellularCommon.h +@@ -47,6 +47,26 @@ struct cell_signal_quality_t { + } + }; + ++struct cell_timeout_cb_t { ++ int timeout; /* configured timeout */ ++ int state; /* cellular state */ ++ cell_timeout_cb_t() ++ { ++ timeout = -1; ++ state = -1; ++ } ++}; ++ ++struct cell_retry_cb_t { ++ int retry_count; /* retry count */ ++ int state; /* cellular state */ ++ cell_retry_cb_t() ++ { ++ retry_count = -1; ++ state = -1; ++ } ++}; ++ + /** + * Cellular specific event changes. + * Connect and disconnect are handled via NSAPI_EVENT_CONNECTION_STATUS_CHANGE +diff --git a/connectivity/cellular/include/cellular/framework/device/CellularStateMachine.h b/connectivity/cellular/include/cellular/framework/device/CellularStateMachine.h +index 67912e463c..aed9d615ce 100644 +--- a/connectivity/cellular/include/cellular/framework/device/CellularStateMachine.h ++++ b/connectivity/cellular/include/cellular/framework/device/CellularStateMachine.h +@@ -189,6 +189,8 @@ private: + bool _command_success; + bool _is_retry; + cell_callback_data_t _cb_data; ++ cell_timeout_cb_t _timeout_cb_data; ++ cell_retry_cb_t _retry_cb_data; + cellular_connection_status_t _current_event; + int _status; + PlatformMutex _mutex; +diff --git a/connectivity/cellular/source/framework/device/CellularStateMachine.cpp b/connectivity/cellular/source/framework/device/CellularStateMachine.cpp +index 833f1d2239..37416ca72e 100644 +--- a/connectivity/cellular/source/framework/device/CellularStateMachine.cpp ++++ b/connectivity/cellular/source/framework/device/CellularStateMachine.cpp +@@ -61,7 +61,7 @@ CellularStateMachine::CellularStateMachine(CellularDevice &device, events::Event + _start_time(rand() % (MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY)), + #endif // MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY + _event_timeout(-1s), _event_id(-1), _plmn(0), _command_success(false), +- _is_retry(false), _cb_data(), _current_event(CellularDeviceReady), _status(0) ++ _is_retry(false), _cb_data(), _timeout_cb_data(), _retry_cb_data(), _current_event(CellularDeviceReady), _status(0) + { + + // set initial retry values in seconds +@@ -289,8 +289,10 @@ void CellularStateMachine::retry_state_or_fail() + if (_retry_count < _retry_array_length) { + tr_debug("%s: retry %d/%d", get_state_string(_state), _retry_count, _retry_array_length); + // send info to application/driver about error logic so it can implement proper error logic ++ _retry_cb_data.retry_count = _retry_count; ++ _retry_cb_data.state = _state; + _cb_data.status_data = _current_event; +- _cb_data.data = &_retry_count; ++ _cb_data.data = &_retry_cb_data; + _cb_data.error = NSAPI_ERROR_OK; + send_event_cb(CellularStateRetryEvent); + +@@ -680,8 +682,11 @@ void CellularStateMachine::send_event_cb(cellular_connection_status_t status) + + void CellularStateMachine::change_timeout(const std::chrono::duration &timeout) + { ++ _timeout_cb_data.timeout = timeout.count(); ++ _timeout_cb_data.state = _state; ++ + _cb_data.status_data = _current_event; +- _cb_data.data = &timeout; ++ _cb_data.data = &_timeout_cb_data; + _cb_data.error = NSAPI_ERROR_OK; + // event callback is a preferred method to communicate to CellularDevice, + // for example calling CellularDevice::set_timeout would call back to this class +-- +2.42.0 + diff --git a/patches/0226-Gemalto-Cinterion-improve-trace-output.patch b/patches/0226-Gemalto-Cinterion-improve-trace-output.patch new file mode 100644 index 000000000..4bcc28293 --- /dev/null +++ b/patches/0226-Gemalto-Cinterion-improve-trace-output.patch @@ -0,0 +1,68 @@ +From aa22f048ae886adcc032ba2fefc7e1f90aa2b693 Mon Sep 17 00:00:00 2001 +From: pennam +Date: Tue, 21 Nov 2023 14:50:08 +0100 +Subject: [PATCH 226/226] Gemalto Cinterion: improve trace output + + * Do not flood serial monitor with tr_info prints + * Align usage of "\n" +--- + .../CINTERION/GEMALTO_CINTERION_CellularContext.cpp | 2 +- + .../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp | 8 ++++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp +index 7ee2c8e53c..d4ae578f09 100644 +--- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp ++++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp +@@ -122,7 +122,7 @@ nsapi_error_t GEMALTO_CINTERION_CellularContext::do_user_authentication() + return NSAPI_ERROR_AUTH_FAILURE; + } + } else { +- tr_info("Empty pwd and username fields: no need for authentication\n"); ++ tr_info("Empty pwd and username fields: no need for authentication"); + } + + return NSAPI_ERROR_OK; +diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +index fc2e8985d7..ac2a54282a 100644 +--- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp ++++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +@@ -284,7 +284,7 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::gethostbyname(const char *host, S + _at.resp_stop(); + if (size > 0) { + //Valid string received +- tr_info("Read %d bytes. Valid string: %s\n", size, ipAddress); ++ tr_info("Read %d bytes. Valid string: %s", size, ipAddress); + // _at.restore_at_timeout(); + if (!address->set_ip_address(ipAddress)) { + _at.unlock(); +@@ -292,7 +292,7 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::gethostbyname(const char *host, S + } + } else { + //Null string received +- tr_info("Read %d bytes. Null string\n", size); ++ tr_info("Read %d bytes. Null string", size); + return NSAPI_ERROR_NO_ADDRESS; + } + } +@@ -550,7 +550,7 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell + size = UDP_PACKET_SIZE; + } + +- tr_info("requesting %d bytes\n", size); ++ tr_debug("requesting %d bytes\n", size); + _at.cmd_start_stop("^SISR", "=", "%d%d", socket->id, size); + + sisr_retry: +@@ -574,7 +574,7 @@ sisr_retry: + + nsapi_size_or_error_t len = _at.read_int(); + if (len == 0) { +- tr_warn("Socket %d no data", socket->id); ++ tr_debug("Socket %d no data", socket->id); + _at.resp_stop(); + RESTORE_URCs_AND_RETURN(NSAPI_ERROR_WOULD_BLOCK); + } +-- +2.42.0 +