mirror of https://github.com/ARMmbed/mbed-os.git
Changed state machine class name and implementation.
parent
b159a51821
commit
c9c3f85311
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue