Skip to content
Prev Previous commit
Next Next commit
GSM: enable debugging without mbed trace
  * Based on mbed attach callback and Arduino_DebugUtils
  • Loading branch information
pennam committed Nov 21, 2023
commit 9a81f86e0420d3da9718902f038a59863dde40b4
14 changes: 9 additions & 5 deletions libraries/GSM/src/GSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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;
}

Expand Down
36 changes: 36 additions & 0 deletions libraries/GSM/src/GSM.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
};

}
Expand Down
274 changes: 274 additions & 0 deletions libraries/GSM/src/GSMDebug.cpp
Original file line number Diff line number Diff line change
@@ -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 <GSM.h>

#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<mbed::CellularDevice::SimState>(data->status_data);
DEBUG_INFO("SIM status: %s", getSIMStateString(state));
}
break;

case CellularRegistrationStatusChanged:
{
const mbed::CellularNetwork::RegistrationStatus state = static_cast<mbed::CellularNetwork::RegistrationStatus>(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 <mbed::CellularNetwork::RadioAccessTechnology>(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<cellular_event_status>(data->status_data);
const mbed::CellularStateMachine::CellularState state = static_cast<mbed::CellularStateMachine::CellularState>(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<cellular_event_status>(data->status_data);
const mbed::CellularStateMachine::CellularState state = static_cast<mbed::CellularStateMachine::CellularState>(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