Changed state machine class name and implementation.

pull/6082/head
Teppo Järvelin 2018-02-28 15:44:45 +02:00 committed by Ari Parkkila
parent b159a51821
commit c9c3f85311
11 changed files with 226 additions and 156 deletions

View File

@ -87,9 +87,9 @@ TEST(AT_CellularNetwork, test_AT_CellularNetwork_get_rate_control)
unit->test_AT_CellularNetwork_get_rate_control();
}
TEST(AT_CellularNetwork, test_AT_CellularNetwork_get_backoff_time)
TEST(AT_CellularNetwork, test_AT_CellularNetwork_get_apn_backoff_timer)
{
unit->test_AT_CellularNetwork_get_backoff_time();
unit->test_AT_CellularNetwork_get_apn_backoff_timer();
}
TEST(AT_CellularNetwork, test_AT_CellularNetwork_get_ip_address)

View File

@ -165,7 +165,7 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_rate_control()
CHECK(NSAPI_ERROR_OK == cn.get_rate_control(reports, timeUnit, ur));
}
void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_backoff_time()
void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_apn_backoff_timer()
{
EventQueue que;
FileHandle_stub fh1;
@ -174,7 +174,7 @@ void Test_AT_CellularNetwork::test_AT_CellularNetwork_get_backoff_time()
AT_CellularNetwork cn(at);
int time;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_CONNECTION_LOST;
CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.get_backoff_time(time));
CHECK(NSAPI_ERROR_CONNECTION_LOST == cn.get_apn_backoff_timer(time));
}

View File

@ -136,7 +136,7 @@ nsapi_error_t AT_CellularNetwork::get_attach(AttachStatus &status)
}
nsapi_error_t AT_CellularNetwork::get_backoff_time(int &backoffTime)
nsapi_error_t AT_CellularNetwork::get_apn_backoff_timer(int &backoffTime)
{
return NSAPI_ERROR_OK;
}

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
#include "CellularConnectionUtil.h"
#include <CellularConnectionFSM.h>
#ifdef CELLULAR_DEVICE
#ifndef MBED_TRACE_MAX_LEVEL
@ -29,25 +29,49 @@
#define TIMEOUT_NETWORK (10*1000)
#define TIMEOUT_REGISTRATION (180*1000)
// maximum time when retrying network register, attach and connect in seconds ( 20minutes )
#define TIMEOUT_NETWORK_MAX (20*60)
#define RETRY_COUNT_DEFAULT 3
namespace mbed {
static events::EventQueue at_queue(8 * EVENTS_EVENT_SIZE);
static CELLULAR_DEVICE cellularDevice(at_queue);
static char device_info_buf[2048];
CellularConnectionUtil::CellularConnectionUtil() : _serial(0), _state(STATE_POWER_ON), _next_state(_state),
_status_callback(0), _network(0), _power(0), _sim(0), _queue(8 * EVENTS_EVENT_SIZE),
_queue_thread(0), _cellularDevice(&cellularDevice)
CellularConnectionFSM::CellularConnectionFSM() :
_serial(0), _state(STATE_INIT), _next_state(_state), _status_callback(0), _network(0), _power(0), _sim(0), _queue(
8 * EVENTS_EVENT_SIZE), _queue_thread(0), _cellularDevice(&cellularDevice), _retry_count(0), _state_retry_count(
0)
{
memset(_sim_pin, 0, sizeof(_sim_pin));
#if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0
_start_time = 0;
#else
_start_time = rand() % (MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY);
#endif // MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY
// set initial retry values in seconds
_retry_timeout_array[0] = 1;
_retry_timeout_array[1] = 2;
_retry_timeout_array[2] = 4;
_retry_timeout_array[3] = 16;
_retry_timeout_array[4] = 32;
_retry_timeout_array[5] = 60;
_retry_timeout_array[6] = 120;
_retry_timeout_array[7] = 360;
_retry_timeout_array[8] = 600;
_retry_timeout_array[9] = TIMEOUT_NETWORK_MAX;
_retry_array_length = MAX_RETRY_ARRAY_SIZE;
}
CellularConnectionUtil::~CellularConnectionUtil()
CellularConnectionFSM::~CellularConnectionFSM()
{
stop();
}
nsapi_error_t CellularConnectionUtil::init()
nsapi_error_t CellularConnectionFSM::init()
{
_power = _cellularDevice->open_power(_serial);
if (!_power) {
@ -72,7 +96,7 @@ nsapi_error_t CellularConnectionUtil::init()
return NSAPI_ERROR_OK;
}
bool CellularConnectionUtil::open_power(FileHandle *fh)
bool CellularConnectionFSM::open_power(FileHandle *fh)
{
if (!_power) {
_power = _cellularDevice->open_power(fh);
@ -80,7 +104,6 @@ bool CellularConnectionUtil::open_power(FileHandle *fh)
return false;
}
}
nsapi_error_t err = _power->on();
if (err != NSAPI_ERROR_OK && err != NSAPI_ERROR_UNSUPPORTED) {
tr_warn("Cellular start failed. Power off/on.");
@ -93,12 +116,12 @@ bool CellularConnectionUtil::open_power(FileHandle *fh)
return true;
}
void CellularConnectionUtil::set_sim_pin(const char * sim_pin)
void CellularConnectionFSM::set_sim_pin(const char * sim_pin)
{
strncpy(_sim_pin, sim_pin, sizeof(_sim_pin));
}
bool CellularConnectionUtil::open_sim()
bool CellularConnectionFSM::open_sim()
{
CellularSIM::SimState state = CellularSIM::SimStateUnknown;
// wait until SIM is readable
@ -123,7 +146,7 @@ bool CellularConnectionUtil::open_sim()
if (_sim->get_sim_state(state) == NSAPI_ERROR_OK && state == CellularSIM::SimStateReady) {
break;
}
tr_debug("SIM state: %d", state);
tr_info("SIM state: %d", state);
return false;
}
}
@ -134,7 +157,7 @@ bool CellularConnectionUtil::open_sim()
return state == CellularSIM::SimStateReady;
}
void CellularConnectionUtil::device_ready()
void CellularConnectionFSM::device_ready()
{
CellularInformation *info = _cellularDevice->open_information(_serial);
@ -149,15 +172,7 @@ void CellularConnectionUtil::device_ready()
}
}
bool CellularConnectionUtil::open_network()
{
if (!_network) {
_network = _cellularDevice->open_network(_serial);
}
return (_network != NULL);
}
bool CellularConnectionUtil::set_network_registration(char *plmn)
bool CellularConnectionFSM::set_network_registration(char *plmn)
{
if (_network->set_registration(plmn) != NSAPI_ERROR_OK) {
tr_error("Failed to set network registration.");
@ -166,13 +181,13 @@ bool CellularConnectionUtil::set_network_registration(char *plmn)
return true;
}
bool CellularConnectionUtil::get_network_registration(CellularNetwork::RegistrationType type,
bool CellularConnectionFSM::get_network_registration(CellularNetwork::RegistrationType type,
CellularNetwork::RegistrationStatus &status, bool &is_registered)
{
is_registered = false;
bool is_roaming = false;
nsapi_error_t err = _network->get_registration_status(type, status);
if (err != NSAPI_ERROR_OK) {
if (err != NSAPI_ERROR_OK) {
if (err != NSAPI_ERROR_UNSUPPORTED) {
tr_warn("Get network registration failed (type %d)!", type);
}
@ -181,19 +196,19 @@ bool CellularConnectionUtil::get_network_registration(CellularNetwork::Registrat
switch (status) {
case CellularNetwork::RegisteredRoaming:
is_roaming = true;
// fall-through
// fall-through
case CellularNetwork::RegisteredHomeNetwork:
is_registered = true;
break;
case CellularNetwork::RegisteredSMSOnlyRoaming:
is_roaming = true;
// fall-through
// fall-through
case CellularNetwork::RegisteredSMSOnlyHome:
tr_warn("SMS only network registration!");
break;
case CellularNetwork::RegisteredCSFBNotPreferredRoaming:
is_roaming = true;
// fall-through
// fall-through
case CellularNetwork::RegisteredCSFBNotPreferredHome:
tr_warn("Not preferred network registration!");
break;
@ -215,7 +230,7 @@ bool CellularConnectionUtil::get_network_registration(CellularNetwork::Registrat
return true;
}
bool CellularConnectionUtil::get_attach_network(CellularNetwork::AttachStatus &status)
bool CellularConnectionFSM::get_attach_network(CellularNetwork::AttachStatus &status)
{
nsapi_error_t err = _network->get_attach(status);
if (err != NSAPI_ERROR_OK) {
@ -224,7 +239,7 @@ bool CellularConnectionUtil::get_attach_network(CellularNetwork::AttachStatus &s
return true;
}
bool CellularConnectionUtil::set_attach_network()
bool CellularConnectionFSM::set_attach_network()
{
nsapi_error_t attach_err = _network->set_attach();
if (attach_err != NSAPI_ERROR_OK) {
@ -233,7 +248,7 @@ bool CellularConnectionUtil::set_attach_network()
return true;
}
void CellularConnectionUtil::report_failure(const char* msg)
void CellularConnectionFSM::report_failure(const char* msg)
{
tr_error("Cellular network failed: %s", msg);
if (_status_callback) {
@ -241,12 +256,12 @@ void CellularConnectionUtil::report_failure(const char* msg)
}
}
nsapi_error_t CellularConnectionUtil::continue_to_state(CellularState state)
nsapi_error_t CellularConnectionFSM::continue_to_state(CellularState state)
{
if (state < _state) {
_state = state;
}
if (!_queue.call_in(0, callback(this, &CellularConnectionUtil::event))) {
if (!_queue.call_in(0, callback(this, &CellularConnectionFSM::event))) {
stop();
return NSAPI_ERROR_NO_MEMORY;
}
@ -254,22 +269,27 @@ nsapi_error_t CellularConnectionUtil::continue_to_state(CellularState state)
return NSAPI_ERROR_OK;
}
void CellularConnectionUtil::event()
void CellularConnectionFSM::event()
{
nsapi_error_t err;
int event_timeout = -1;
switch (_state) {
case STATE_INIT:
event_timeout = _start_time;
tr_info("INIT state, waiting %d ms before POWER state)", _start_time);
_next_state = STATE_POWER_ON;
break;
case STATE_POWER_ON:
cellularDevice.set_timeout(TIMEOUT_POWER_ON);
tr_info("Cellular power ON (timeout %d ms)", TIMEOUT_POWER_ON);
if (open_power(_serial)) {
_next_state = STATE_DEVICE_READY;
_retry_count = 0;
} else {
static int retry_count;
if (++retry_count <= 10) {
tr_warn("Power ON retry %d", retry_count);
event_timeout = 1000;
if (++_retry_count <= RETRY_COUNT_DEFAULT) {
tr_warn("Power ON retry %d", _retry_count);
event_timeout = 3 * 1000;
} else {
report_failure("Power");
return;
@ -280,36 +300,32 @@ void CellularConnectionUtil::event()
cellularDevice.set_timeout(TIMEOUT_POWER_ON);
if (_power->set_at_mode() == NSAPI_ERROR_OK) {
tr_info("Cellular device ready");
_next_state = STATE_START_CELLULAR;
_next_state = STATE_SIM_PIN;
_retry_count = 0;
device_ready();
} else {
static int retry_count = 0;
tr_info("Waiting for cellular device (retry %d/10, timeout %d ms)", retry_count, TIMEOUT_POWER_ON);
if (++retry_count <= 10) {
event_timeout = 1000;
tr_info("Waiting for cellular device (retry %d/%d, timeout %d ms)", _retry_count, RETRY_COUNT_DEFAULT,
TIMEOUT_POWER_ON);
if (_retry_count++ <= RETRY_COUNT_DEFAULT) {
event_timeout = 3 * 1000;
} else {
report_failure("Power");
return;
}
}
break;
case STATE_START_CELLULAR:
cellularDevice.set_timeout(TIMEOUT_NETWORK);
tr_info("Start cellular (timeout %d ms)", TIMEOUT_NETWORK);
open_network();
_next_state = STATE_SIM_PIN;
break;
case STATE_SIM_PIN:
cellularDevice.set_timeout(TIMEOUT_SIM_PIN);
tr_info("Start cellular (timeout %d ms)", TIMEOUT_SIM_PIN);
if (open_sim()) {
_next_state = STATE_REGISTERING_NETWORK;
_retry_count = 0;
_state_retry_count = 0;
tr_info("Check for network registration");
} else {
static int retry_count;
if (++retry_count <= 10) {
tr_warn("Waiting for SIM %d", retry_count);
event_timeout = 1000;
if (_retry_count++ <= RETRY_COUNT_DEFAULT) {
tr_warn("Waiting for SIM %d/%d", _retry_count, RETRY_COUNT_DEFAULT);
event_timeout = 3 * 1000;
} else {
report_failure("Entering SIM PIN");
return;
@ -322,48 +338,50 @@ void CellularConnectionUtil::event()
bool is_registered;
_next_state = STATE_REGISTER_NETWORK;
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
if (get_network_registration((CellularNetwork::RegistrationType)type, status, is_registered)) {
if (get_network_registration((CellularNetwork::RegistrationType) type, status, is_registered)) {
tr_debug("get_network_registration: type=%d, status=%d", type, status);
if (is_registered) {
tr_info("Registered to cellular network (type %d, status %d)", type, status);
_next_state = STATE_ATTACH_NETWORK;
_next_state = STATE_ATTACHING_NETWORK;
_retry_count = 0;
_state_retry_count = 0;
event_timeout = 0;
tr_info("Check cellular network attach state");
break;
} else {
if (status == CellularNetwork::RegistrationDenied) {
static int backoff_timeout = 1;
tr_warn("Network registration denied (type %d)! Retry after %d seconds.", type, backoff_timeout);
event_timeout = backoff_timeout * 1000;
backoff_timeout *= 2;
break;
} else if (status != CellularNetwork::NotRegistered) {
static int retry_count;
if (++retry_count <= 180) {
tr_info("Waiting for registration %d/180 (type %d, status %d)", retry_count, type, status);
event_timeout = 1*1000;
_next_state = STATE_REGISTERING_NETWORK;
} else {
tr_info("Start cellular registration");
_next_state = STATE_REGISTER_NETWORK;
retry_count = 0;
break;
}
if (_retry_count < 180) {
event_timeout = 1000;
_next_state = STATE_REGISTERING_NETWORK;
tr_info("Waiting for registration %d/180 (type %d, status %d)", _retry_count, type, status);
} else {
// modem is not yet searching network for this technology
tr_info("Start cellular registration");
_next_state = STATE_REGISTER_NETWORK;
_retry_count = 0;
break;
}
}
}
}
if (_next_state == STATE_REGISTERING_NETWORK) {
_retry_count++;
}
break;
case STATE_REGISTER_NETWORK:
cellularDevice.set_timeout(TIMEOUT_REGISTRATION);
tr_info("Register to cellular network (timeout %d ms)", TIMEOUT_REGISTRATION);
if (set_network_registration()) {
_next_state = STATE_REGISTERING_NETWORK;
_retry_count = 0;
if (_state_retry_count > RETRY_COUNT_DEFAULT) {
report_failure("Registration retry");
return;
}
_state_retry_count++;
} else {
static int retry_count;
if (++retry_count <= 3) {
event_timeout = 1000;
if (_retry_count < _retry_array_length) {
event_timeout = _retry_timeout_array[_retry_count] * 1000;
_retry_count++;
} else {
report_failure("Registration");
return;
@ -376,11 +394,18 @@ void CellularConnectionUtil::event()
if (get_attach_network(attach_status)) {
if (attach_status == CellularNetwork::Attached) {
_next_state = STATE_CONNECT_NETWORK;
_retry_count = 0;
} else {
_next_state = STATE_ATTACH_NETWORK;
_retry_count = 0;
}
} else {
event_timeout = 0;
if (_retry_count++ <= RETRY_COUNT_DEFAULT) {
event_timeout = 1 * 1000;
} else {
report_failure("Attaching");
return;
}
}
break;
case STATE_ATTACH_NETWORK:
@ -388,9 +413,21 @@ void CellularConnectionUtil::event()
tr_info("Attach to cellular network (timeout %d ms)", TIMEOUT_NETWORK);
if (set_attach_network()) {
_next_state = STATE_ATTACHING_NETWORK;
_retry_count = 0;
if (_state_retry_count >= RETRY_COUNT_DEFAULT) {
report_failure("Attach retry");
return;
}
_state_retry_count++;
tr_info("Cellular network attaching");
} else {
event_timeout = 0;
if (_retry_count < _retry_array_length) {
event_timeout = _retry_timeout_array[_retry_count] * 1000;
_retry_count++;
} else {
report_failure("Attach");
return;
}
}
break;
case STATE_CONNECT_NETWORK:
@ -400,8 +437,13 @@ void CellularConnectionUtil::event()
if (!err) {
_next_state = STATE_CONNECTED;
} else {
report_failure("Network connect");
return;
if (_retry_count < _retry_array_length) {
event_timeout = _retry_timeout_array[_retry_count] * 1000;
_retry_count++;
} else {
report_failure("Network Connect");
return;
}
}
break;
case STATE_CONNECTED:
@ -419,7 +461,7 @@ void CellularConnectionUtil::event()
}
if (_next_state != _state || event_timeout >= 0) {
if (_next_state != _state) {
if (_next_state != _state) { // state exit condition
tr_info("Cellular state from %d to %d", _state, _next_state);
if (_status_callback) {
if (!_status_callback(_state, _next_state)) {
@ -443,14 +485,14 @@ void CellularConnectionUtil::event()
if (event_timeout == -1) {
event_timeout = 0;
}
if (!_queue.call_in(event_timeout, callback(this, &CellularConnectionUtil::event))) {
if (!_queue.call_in(event_timeout, callback(this, &CellularConnectionFSM::event))) {
report_failure("Cellular event failure!");
return;
}
}
}
nsapi_error_t CellularConnectionUtil::start_dispatch()
nsapi_error_t CellularConnectionFSM::start_dispatch()
{
tr_info("CellularConnectionUtil::start");
tr_info("Create cellular thread");
@ -471,7 +513,7 @@ nsapi_error_t CellularConnectionUtil::start_dispatch()
return NSAPI_ERROR_OK;
}
void CellularConnectionUtil::stop()
void CellularConnectionFSM::stop()
{
tr_info("CellularConnectionUtil::stop");
_cellularDevice->close_power();
@ -482,41 +524,50 @@ void CellularConnectionUtil::stop()
}
}
void CellularConnectionUtil::set_serial(UARTSerial *serial)
void CellularConnectionFSM::set_serial(UARTSerial *serial)
{
_serial = serial;
}
void CellularConnectionUtil::set_callback(mbed::Callback<bool(int, int)> status_callback)
void CellularConnectionFSM::set_callback(mbed::Callback<bool(int, int)> status_callback)
{
_status_callback = status_callback;
}
events::EventQueue *CellularConnectionUtil::get_queue()
events::EventQueue *CellularConnectionFSM::get_queue()
{
return &_queue;
}
CellularNetwork* CellularConnectionUtil::get_network()
CellularNetwork* CellularConnectionFSM::get_network()
{
return _network;
}
CellularDevice* CellularConnectionUtil::get_device()
CellularDevice* CellularConnectionFSM::get_device()
{
return _cellularDevice;
}
CellularSIM* CellularConnectionUtil::get_sim()
CellularSIM* CellularConnectionFSM::get_sim()
{
return _sim;
}
NetworkStack *CellularConnectionUtil::get_stack()
NetworkStack *CellularConnectionFSM::get_stack()
{
return _cellularDevice->get_stack();
}
void CellularConnectionFSM::set_retry_timeout_array(uint16_t timeout[], int array_len)
{
_retry_array_length = array_len > MAX_RETRY_ARRAY_SIZE ? MAX_RETRY_ARRAY_SIZE : array_len;
for (int i = 0; i < _retry_array_length; i++) {
_retry_timeout_array[i] = timeout[i];
}
}
} // namespace
#endif // CELLULAR_DEVICE

View File

@ -38,31 +38,32 @@
namespace mbed {
const int PIN_SIZE = 8;
const int MAX_RETRY_ARRAY_SIZE = 10;
/** CellularConnectionUtil class
/** CellularConnectionFSM class
*
* Utility class for cellular connection
* Finite State Machine for connecting to cellular network
*/
class CellularConnectionUtil
class CellularConnectionFSM
{
public:
CellularConnectionUtil();
virtual ~CellularConnectionUtil();
CellularConnectionFSM();
virtual ~CellularConnectionFSM();
public:
/** Cellular connection states
*/
enum CellularState {
STATE_POWER_ON = 0,
STATE_DEVICE_READY = 1,
STATE_START_CELLULAR = 2,
STATE_SIM_PIN = 3,
STATE_REGISTER_NETWORK = 4,
STATE_REGISTERING_NETWORK = 5,
STATE_ATTACH_NETWORK = 7,
STATE_ATTACHING_NETWORK = 8,
STATE_CONNECT_NETWORK = 9,
STATE_CONNECTED = 10,
STATE_INIT = 0,
STATE_POWER_ON,
STATE_DEVICE_READY,
STATE_SIM_PIN,
STATE_REGISTER_NETWORK,
STATE_REGISTERING_NETWORK,
STATE_ATTACH_NETWORK,
STATE_ATTACHING_NETWORK,
STATE_CONNECT_NETWORK,
STATE_CONNECTED,
};
public:
@ -122,10 +123,17 @@ public:
*/
void set_sim_pin(const char *sim_pin);
/** Sets the timeout array for network rejects. After reject next item is tried and after all items are waited and
* still fails then current network event will fail.
*
* @param timeout timeout array using seconds
* @param array_len length of the array
*/
void set_retry_timeout_array(uint16_t timeout[], int array_len);
private:
bool open_power(FileHandle *fh);
bool open_sim();
bool open_network();
bool get_network_registration(CellularNetwork::RegistrationType type, CellularNetwork::RegistrationStatus &status, bool &is_registered);
bool set_network_registration(char *plmn = 0);
bool get_attach_network(CellularNetwork::AttachStatus &status);
@ -153,6 +161,11 @@ private:
rtos::Thread *_queue_thread;
CellularDevice *_cellularDevice;
char _sim_pin[PIN_SIZE+1];
int _retry_count;
int _state_retry_count;
int _start_time;
uint16_t _retry_timeout_array[MAX_RETRY_ARRAY_SIZE];
int _retry_array_length;
};
} // namespace

View File

@ -22,28 +22,29 @@
#include "nsapi_ppp.h"
#endif
#include "CellularConnectionUtil.h"
#include "CellularConnectionFSM.h"
#include "CellularUtil.h"
#include "EasyCellularConnection.h"
#include "CellularLog.h"
#include "mbed_wait_api.h"
#if MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
#include "APN_db.h"
#endif //MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
namespace mbed
{
namespace mbed {
bool EasyCellularConnection::cellular_status(int state, int next_state)
{
tr_info("cellular_status %d=>%d", state, next_state);
if (_target_state == state) {
if (state == CellularConnectionUtil::STATE_CONNECTED) {
if (state == CellularConnectionFSM::STATE_CONNECTED) {
_is_connected = true;
} else {
_is_connected = false;
}
tr_info("Target state reached: %d", _target_state);
MBED_ASSERT(_cellularSemaphore.release() == osOK);
return false;
} else {
@ -52,10 +53,10 @@ bool EasyCellularConnection::cellular_status(int state, int next_state)
return true;
}
EasyCellularConnection::EasyCellularConnection() : _is_connected(false), _is_initialized(false),
_target_state(CellularConnectionUtil::STATE_POWER_ON),
_cellularSerial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE),
_cellularSemaphore(0), _cellularConnectionUtil(), _credentials_err(NSAPI_ERROR_OK)
EasyCellularConnection::EasyCellularConnection() :
_is_connected(false), _is_initialized(false), _target_state(CellularConnectionFSM::STATE_POWER_ON), _cellularSerial(
MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE), _cellularSemaphore(0), _cellularConnectionFSM(), _credentials_err(
NSAPI_ERROR_OK)
{
#if MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
_credentials_set = false;
@ -65,7 +66,7 @@ EasyCellularConnection::EasyCellularConnection() : _is_connected(false), _is_in
EasyCellularConnection::~EasyCellularConnection()
{
_cellularConnectionUtil.stop();
_cellularConnectionFSM.stop();
}
nsapi_error_t EasyCellularConnection::init()
@ -75,13 +76,13 @@ nsapi_error_t EasyCellularConnection::init()
#if defined (MDMRTS) && defined (MDMCTS)
_cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
#endif
_cellularConnectionUtil.set_serial(&_cellularSerial);
_cellularConnectionUtil.set_callback(callback(this, &EasyCellularConnection::cellular_status));
_cellularConnectionFSM.set_serial(&_cellularSerial);
_cellularConnectionFSM.set_callback(callback(this, &EasyCellularConnection::cellular_status));
err = _cellularConnectionUtil.init();
err = _cellularConnectionFSM.init();
if (err == NSAPI_ERROR_OK) {
err = _cellularConnectionUtil.start_dispatch();
err = _cellularConnectionFSM.start_dispatch();
}
_is_initialized = true;
}
@ -97,7 +98,7 @@ void EasyCellularConnection::set_credentials(const char *apn, const char *uname,
if (_credentials_err) {
return;
}
CellularNetwork * network = _cellularConnectionUtil.get_network();
CellularNetwork * network = _cellularConnectionFSM.get_network();
if (network) {
_credentials_err = network->set_credentials(apn, uname, pwd);
#if MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
@ -114,7 +115,7 @@ void EasyCellularConnection::set_credentials(const char *apn, const char *uname,
void EasyCellularConnection::set_sim_pin(const char *sim_pin)
{
if (sim_pin) {
_cellularConnectionUtil.set_sim_pin(sim_pin);
_cellularConnectionFSM.set_sim_pin(sim_pin);
}
}
@ -130,7 +131,7 @@ nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *a
}
if (sim_pin) {
_cellularConnectionUtil.set_sim_pin(sim_pin);
_cellularConnectionFSM.set_sim_pin(sim_pin);
}
return connect();
@ -163,16 +164,17 @@ nsapi_error_t EasyCellularConnection::connect()
}
#if MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
if (!_credentials_set) {
_target_state = CellularConnectionUtil::STATE_SIM_PIN;
err = _cellularConnectionUtil.continue_to_state(_target_state);
_target_state = CellularConnectionFSM::STATE_SIM_PIN;
err = _cellularConnectionFSM.continue_to_state(_target_state);
if (err == NSAPI_ERROR_OK) {
int sim_wait = _cellularSemaphore.wait(6*1000); // reserve 6 seconds to access to SIM
int sim_wait = _cellularSemaphore.wait(60*1000); // reserve 60 seconds to access to SIM
if (sim_wait != 1) {
tr_error("NO SIM ACCESS");
err = NSAPI_ERROR_NO_CONNECTION;
} else {
char imsi[MAX_IMSI_LENGTH+1];
err = _cellularConnectionUtil.get_sim()->get_imsi(imsi);
wait(1); // need to wait to access SIM in some modems
err = _cellularConnectionFSM.get_sim()->get_imsi(imsi);
if (err == NSAPI_ERROR_OK) {
const char *apn_config = apnconfig(imsi);
if (apn_config) {
@ -180,21 +182,22 @@ nsapi_error_t EasyCellularConnection::connect()
const char* uname = _APN_GET(apn_config);
const char* pwd = _APN_GET(apn_config);
tr_info("Looked up APN %s", apn);
err = _cellularConnectionUtil.get_network()->set_credentials(apn, uname, pwd);
err = _cellularConnectionFSM.get_network()->set_credentials(apn, uname, pwd);
}
}
}
}
if (err) {
tr_info("APN lookup failed");
return err;
}
}
#endif // MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
_target_state = CellularConnectionUtil::STATE_CONNECTED;
err = _cellularConnectionUtil.continue_to_state(_target_state);
_target_state = CellularConnectionFSM::STATE_CONNECTED;
err = _cellularConnectionFSM.continue_to_state(_target_state);
if (err == NSAPI_ERROR_OK) {
int ret_wait = _cellularSemaphore.wait(10*60*1000); // cellular network searching may take several minutes
int ret_wait = _cellularSemaphore.wait(10 * 60 * 1000); // cellular network searching may take several minutes
if (ret_wait != 1) {
tr_info("No cellular connection");
err = NSAPI_ERROR_NO_CONNECTION;
@ -211,10 +214,10 @@ nsapi_error_t EasyCellularConnection::disconnect()
#if MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
_credentials_set = false;
#endif // #if MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
if (!_cellularConnectionUtil.get_network()) {
if (!_cellularConnectionFSM.get_network()) {
return NSAPI_ERROR_NO_CONNECTION;
}
return _cellularConnectionUtil.get_network()->disconnect();
return _cellularConnectionFSM.get_network()->disconnect();
}
bool EasyCellularConnection::is_connected()
@ -224,16 +227,16 @@ bool EasyCellularConnection::is_connected()
const char *EasyCellularConnection::get_ip_address()
{
CellularNetwork *network = _cellularConnectionUtil.get_network();
CellularNetwork *network = _cellularConnectionFSM.get_network();
if (!network) {
return NULL;
}
return _cellularConnectionUtil.get_network()->get_ip_address();
return _cellularConnectionFSM.get_network()->get_ip_address();
}
const char *EasyCellularConnection::get_netmask()
{
CellularNetwork *network = _cellularConnectionUtil.get_network();
CellularNetwork *network = _cellularConnectionFSM.get_network();
if (!network) {
return NULL;
}
@ -243,7 +246,7 @@ const char *EasyCellularConnection::get_netmask()
const char *EasyCellularConnection::get_gateway()
{
CellularNetwork *network = _cellularConnectionUtil.get_network();
CellularNetwork *network = _cellularConnectionFSM.get_network();
if (!network) {
return NULL;
}
@ -253,7 +256,7 @@ const char *EasyCellularConnection::get_gateway()
void EasyCellularConnection::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
{
CellularNetwork *network = _cellularConnectionUtil.get_network();
CellularNetwork *network = _cellularConnectionFSM.get_network();
if (network) {
network->attach(status_cb);
}
@ -261,7 +264,7 @@ void EasyCellularConnection::attach(mbed::Callback<void(nsapi_event_t, intptr_t)
void EasyCellularConnection::modem_debug_on(bool on)
{
CellularDevice *dev =_cellularConnectionUtil.get_device();
CellularDevice *dev = _cellularConnectionFSM.get_device();
if (dev) {
dev->modem_debug_on(on);
}
@ -269,7 +272,7 @@ void EasyCellularConnection::modem_debug_on(bool on)
NetworkStack *EasyCellularConnection::get_stack()
{
return _cellularConnectionUtil.get_stack();
return _cellularConnectionFSM.get_stack();
}
} // namespace

View File

@ -16,9 +16,10 @@
*/
#ifndef EASY_CELLULAR_CONNECTION_H
#define EASY_CELLULAR_CONNECTION_H
#include "CellularConnectionUtil.h"
#include "CellularConnectionFSM.h"
#ifdef CELLULAR_DEVICE
#include "netsocket/CellularBase.h"
@ -147,12 +148,11 @@ private:
#if MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
bool _credentials_set;
#endif // #if MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
CellularConnectionUtil::CellularState _target_state;
CellularConnectionFSM::CellularState _target_state;
UARTSerial _cellularSerial;
rtos::Semaphore _cellularSemaphore;
CellularConnectionUtil _cellularConnectionUtil;
CellularConnectionFSM _cellularConnectionFSM;
nsapi_error_t _credentials_err;
};

View File

@ -264,10 +264,10 @@ public:
/** Get backoff timer value
*
* @param backoff_time Backoff timer value associated with PDP APN in seconds
* @return zero on success
* @param backoff_timer Backoff timer value associated with PDP APN in seconds
* @return zero on success
*/
virtual nsapi_error_t get_backoff_time(int &backoff_time) = 0;
virtual nsapi_error_t get_apn_backoff_timer(int &backoff_timer) = 0;
/** Sets radio access technology.
*
@ -381,7 +381,6 @@ public:
* @return NSAPI_ERROR_OK on success, negative error code on failure
*/
virtual nsapi_error_t get_operator_params(int &format, operator_t &operator_params) = 0;
};
} // namespace mbed

View File

@ -685,7 +685,7 @@ nsapi_error_t AT_CellularNetwork::get_attach(AttachStatus &status)
}
nsapi_error_t AT_CellularNetwork::get_backoff_time(int &backoffTime)
nsapi_error_t AT_CellularNetwork::get_apn_backoff_timer(int &backoff_timer)
{
_at.lock();
@ -697,7 +697,7 @@ nsapi_error_t AT_CellularNetwork::get_backoff_time(int &backoffTime)
_at.resp_start("+CABTRDP:");
if (_at.info_resp()) {
_at.skip_param();
backoffTime = _at.read_int();
backoff_timer = _at.read_int();
}
_at.resp_stop();
}

View File

@ -71,7 +71,7 @@ public: // CellularNetwork
virtual nsapi_error_t get_rate_control(CellularNetwork::RateControlExceptionReports &reports,
CellularNetwork::RateControlUplinkTimeUnit &time_unit, int &uplink_rate);
virtual nsapi_error_t get_backoff_time(int &backoff_time);
virtual nsapi_error_t get_apn_backoff_timer(int &backoff_timer);
virtual void attach(Callback<void(nsapi_event_t, intptr_t)> status_cb);

View File

@ -8,6 +8,10 @@
"mux-enabled": {
"help": "Use cellular modem over MUX",
"value": false
},
"random_max_start_delay": {
"help": "Maximum random delay value used in start-up sequence in milliseconds",
"value": 0
}
}
}
}