async works. Retry logic needs refining.

pull/6496/head
Teppo Järvelin 2018-03-09 13:10:51 +02:00
parent 83ea9be5f5
commit c26311b071
5 changed files with 70 additions and 78 deletions

View File

@ -297,52 +297,17 @@ void CellularConnectionFSM::report_failure(const char* msg)
} }
} }
char* CellularConnectionFSM::get_state_string(CellularState state) const char* CellularConnectionFSM::get_state_string(CellularState state)
{ {
switch (state) { static const char *strings[] = { "Init", "Power", "Device ready", "SIM pin", "Register network", "Registering network", "Attach network", "Attaching network", "Connect network", "Connected"};
case STATE_INIT: return strings[state];
strcpy(_st_string, "Init");
break;
case STATE_POWER_ON:
strcpy(_st_string, "Power");
break;
case STATE_DEVICE_READY:
strcpy(_st_string, "Device Ready");
break;
case STATE_SIM_PIN:
strcpy(_st_string, "SIM Pin");
break;
case STATE_REGISTER_NETWORK:
strcpy(_st_string, "Register network");
break;
case STATE_REGISTERING_NETWORK:
strcpy(_st_string, "Registering network");
break;
case STATE_ATTACH_NETWORK:
strcpy(_st_string, "Attach network");
break;
case STATE_ATTACHING_NETWORK:
strcpy(_st_string, "Attaching network");
break;
case STATE_CONNECT_NETWORK:
strcpy(_st_string, "Connect network");
break;
case STATE_CONNECTED:
strcpy(_st_string, "Connected");
break;
default:
MBED_ASSERT(0);
break;
}
return _st_string;
} }
bool CellularConnectionFSM::is_automatic_registering() bool CellularConnectionFSM::is_automatic_registering()
{ {
CellularNetwork::NWRegisteringMode mode; CellularNetwork::NWRegisteringMode mode;
nsapi_error_t err = _network->get_network_registering_mode(mode); nsapi_error_t err = _network->get_network_registering_mode(mode);
tr_info("automatic registering err: %d, mode: %d", err, mode); tr_debug("automatic registering mode: %d", mode);
if (err == NSAPI_ERROR_OK && mode == CellularNetwork::NWModeAutomatic) { if (err == NSAPI_ERROR_OK && mode == CellularNetwork::NWModeAutomatic) {
return true; return true;
} }
@ -397,7 +362,7 @@ void CellularConnectionFSM::retry_state_or_fail()
void CellularConnectionFSM::state_init() void CellularConnectionFSM::state_init()
{ {
_event_timeout = _start_time; _event_timeout = _start_time;
tr_info("INIT state, waiting %d ms before POWER state)", _start_time); tr_info("Init state, waiting %d ms before POWER state)", _start_time);
enter_to_state(STATE_POWER_ON); enter_to_state(STATE_POWER_ON);
} }
@ -435,7 +400,6 @@ void CellularConnectionFSM::state_sim_pin()
if (open_sim()) { if (open_sim()) {
enter_to_state(STATE_REGISTERING_NETWORK); enter_to_state(STATE_REGISTERING_NETWORK);
_state_retry_count = 0; _state_retry_count = 0;
tr_info("Check for network registration");
} else { } else {
retry_state_or_fail(); retry_state_or_fail();
} }
@ -443,21 +407,27 @@ void CellularConnectionFSM::state_sim_pin()
void CellularConnectionFSM::state_registering() void CellularConnectionFSM::state_registering()
{ {
_cellularDevice->set_timeout(TIMEOUT_NETWORK); if (is_registered()) {
_next_state = STATE_REGISTER_NETWORK; // we are already registered, go to attach
if (is_automatic_registering()) { _next_state = STATE_ATTACHING_NETWORK;
_network->set_registration_urc(true); } else {
// Automatic registering is on, we now wait for async response with max time 180s // by default we and start the registering but if automatic mode is on then we start waiting for async response
_next_state = STATE_REGISTERING_NETWORK; _cellularDevice->set_timeout(TIMEOUT_NETWORK);
_event_timeout = 180*1000; _next_state = STATE_REGISTER_NETWORK;
tr_info("STATE_REGISTERING_NETWORK, event timeout 180s"); if (is_automatic_registering()) {
} _network->set_registration_urc(true);
// Automatic registering is on, we now wait for async response with max time 180s
_next_state = STATE_REGISTERING_NETWORK;
_event_timeout = 180*1000;
tr_info("Automatic register was already on. Start waiting urc's: event timeout %ds", _event_timeout/1000);
}
if (_retry_count > 3) { if (_retry_count > 3) {
_event_timeout = -1; _event_timeout = -1;
} }
if (_next_state == STATE_REGISTERING_NETWORK) { if (_next_state == STATE_REGISTERING_NETWORK) {
_retry_count++; _retry_count++;
}
} }
} }
@ -528,7 +498,14 @@ void CellularConnectionFSM::state_connect_to_network()
tr_info("Connect to cellular network (timeout %d ms)", TIMEOUT_NETWORK); tr_info("Connect to cellular network (timeout %d ms)", TIMEOUT_NETWORK);
nsapi_error_t err = _network->connect(); nsapi_error_t err = _network->connect();
if (!err) { if (!err) {
#if NSAPI_PPP_AVAILABLE
// In ppp mode connect is almost synchronous
_event_timeout = 180*1000;//_retry_timeout_array[_retry_count] * 1000;
tr_info("Waiting for connect...");
#else
// when using modems stack connect is synchronous
_next_state = STATE_CONNECTED; _next_state = STATE_CONNECTED;
#endif // NSAPI_PPP_AVAILABLE
} else { } else {
if (_retry_count < _retry_array_length) { if (_retry_count < _retry_array_length) {
_event_timeout = _retry_timeout_array[_retry_count] * 1000; _event_timeout = _retry_timeout_array[_retry_count] * 1000;
@ -613,9 +590,6 @@ void CellularConnectionFSM::event()
nsapi_error_t CellularConnectionFSM::start_dispatch() nsapi_error_t CellularConnectionFSM::start_dispatch()
{ {
tr_info("CellularConnectionUtil::start");
tr_info("Create cellular thread");
MBED_ASSERT(!_queue_thread); MBED_ASSERT(!_queue_thread);
_queue_thread = new rtos::Thread; _queue_thread = new rtos::Thread;
@ -628,7 +602,6 @@ nsapi_error_t CellularConnectionFSM::start_dispatch()
return NSAPI_ERROR_NO_MEMORY; return NSAPI_ERROR_NO_MEMORY;
} }
tr_info("CellularConnectionUtil::started");
return NSAPI_ERROR_OK; return NSAPI_ERROR_OK;
} }
@ -662,14 +635,21 @@ void CellularConnectionFSM::attach(mbed::Callback<void(nsapi_event_t, intptr_t)>
void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr) void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr)
{ {
tr_info("network_callback called with ev: %d, intptr: %d", ev, ptr); tr_debug("FSM: network_callback called with event: %d, intptr: %d", ev, ptr);
if (ev == NSAPI_EVENT_CELLULAR_STATUS_CHANGE) { if (ev == NSAPI_EVENT_CELLULAR_STATUS_CHANGE) {
if (ptr == CellularRegistrationStatusChanged && _state == STATE_REGISTERING_NETWORK) { if (ptr == CellularRegistrationStatusChanged && _state == STATE_REGISTERING_NETWORK) {
// check for registration status // check for registration status
if (is_registered()) { if (is_registered()) {
tr_info("Registered, cancel state and continue to attach...");
_queue.cancel(_eventID); _queue.cancel(_eventID);
continue_from_state(STATE_ATTACH_NETWORK); continue_from_state(STATE_ATTACHING_NETWORK);
}
}
} else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
if (ptr == NSAPI_STATUS_GLOBAL_UP) {
// we are connected
if (_state == STATE_CONNECT_NETWORK) {
_queue.cancel(_eventID);
continue_from_state(STATE_CONNECTED);
} }
} }
} }

View File

@ -142,7 +142,7 @@ public:
void set_retry_timeout_array(uint16_t timeout[], int array_len); void set_retry_timeout_array(uint16_t timeout[], int array_len);
bool is_automatic_registering(); bool is_automatic_registering();
char* get_state_string(CellularState state); const char* get_state_string(CellularState state);
private: private:
bool power_on(); bool power_on();
bool open_sim(); bool open_sim();

View File

@ -37,33 +37,35 @@ namespace mbed {
bool EasyCellularConnection::cellular_status(int state, int next_state) bool EasyCellularConnection::cellular_status(int state, int next_state)
{ {
tr_info("cellular_status state: %s", _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)state)); tr_info("cellular_status: %s ==> %s", _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)state),
tr_info("cellular_status next_state: %s", _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)next_state)); _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)next_state));
if (_target_state == state) { if (_target_state == state) {
if (state == CellularConnectionFSM::STATE_CONNECTED) {
_is_connected = true;
} else {
_is_connected = false;
}
tr_info("Target state reached: %s", _cellularConnectionFSM.get_state_string(_target_state)); tr_info("Target state reached: %s", _cellularConnectionFSM.get_state_string(_target_state));
MBED_ASSERT(_cellularSemaphore.release() == osOK); MBED_ASSERT(_cellularSemaphore.release() == osOK);
return false; return false; // return false -> state machine is halted
} else {
_is_connected = false;
} }
return true; return true;
} }
void EasyCellularConnection::network_callback(nsapi_event_t ev, intptr_t ptr) void EasyCellularConnection::network_callback(nsapi_event_t ev, intptr_t ptr)
{ {
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
if (ptr == NSAPI_STATUS_GLOBAL_UP) {
_is_connected = true;
} else {
_is_connected = false;
}
}
if (_status_cb) {
_status_cb(ev, ptr);
}
} }
EasyCellularConnection::EasyCellularConnection(bool debug) : EasyCellularConnection::EasyCellularConnection(bool debug) :
_is_connected(false), _is_initialized(false), _target_state(CellularConnectionFSM::STATE_POWER_ON), _cellularSerial( _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( MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE), _cellularSemaphore(0), _cellularConnectionFSM(), _credentials_err(
NSAPI_ERROR_OK) NSAPI_ERROR_OK), _status_cb(0)
{ {
tr_info("EasyCellularConnection()"); tr_info("EasyCellularConnection()");
#if USE_APN_LOOKUP #if USE_APN_LOOKUP
@ -128,6 +130,11 @@ void EasyCellularConnection::set_sim_pin(const char *sim_pin)
} }
} }
void EasyCellularConnection::set_is_blocking(bool blocking)
{
}
nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd) nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
{ {
if (_is_connected) { if (_is_connected) {
@ -265,6 +272,7 @@ const char *EasyCellularConnection::get_gateway()
void EasyCellularConnection::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb) void EasyCellularConnection::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
{ {
_status_cb = status_cb;
_cellularConnectionFSM.attach(status_cb); _cellularConnectionFSM.attach(status_cb);
} }

View File

@ -132,6 +132,7 @@ public:
*/ */
void modem_debug_on(bool on); void modem_debug_on(bool on);
void set_is_blocking(bool blocking);
protected: protected:
/** Provide access to the NetworkStack object /** Provide access to the NetworkStack object
@ -161,6 +162,7 @@ private:
rtos::Semaphore _cellularSemaphore; rtos::Semaphore _cellularSemaphore;
CellularConnectionFSM _cellularConnectionFSM; CellularConnectionFSM _cellularConnectionFSM;
nsapi_error_t _credentials_err; nsapi_error_t _credentials_err;
Callback<void(nsapi_event_t, intptr_t)> _status_cb;
}; };
} // namespace } // namespace

View File

@ -343,7 +343,7 @@ nsapi_connection_status_t AT_CellularNetwork::get_connection_status() const
nsapi_error_t AT_CellularNetwork::set_blocking(bool blocking) nsapi_error_t AT_CellularNetwork::set_blocking(bool blocking)
{ {
_async = blocking; _async = !blocking;
#if NSAPI_PPP_AVAILABLE #if NSAPI_PPP_AVAILABLE
return nsapi_ppp_set_blocking(blocking); return nsapi_ppp_set_blocking(blocking);
#else #else
@ -572,7 +572,6 @@ nsapi_error_t AT_CellularNetwork::set_registration_urc(bool urc_on)
if (has_registration(at_reg[i].type)) { if (has_registration(at_reg[i].type)) {
_last_reg_type = at_reg[i].type; _last_reg_type = at_reg[i].type;
if (urc_on) { if (urc_on) {
tr_info("setting reg urc for i: %d", i);
_at.cmd_start(at_reg[i].cmd); _at.cmd_start(at_reg[i].cmd);
_at.write_string("=2", false); _at.write_string("=2", false);
_at.cmd_stop(); _at.cmd_stop();
@ -596,7 +595,6 @@ nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode
_at.cmd_stop(); _at.cmd_stop();
_at.resp_start("+COPS:"); _at.resp_start("+COPS:");
int tmpmode = (NWRegisteringMode)_at.read_int(); int tmpmode = (NWRegisteringMode)_at.read_int();
tr_info("get_network_registering_mode, tmpmode: %d", tmpmode);
_at.resp_stop(); _at.resp_stop();
mode = (NWRegisteringMode)tmpmode; mode = (NWRegisteringMode)tmpmode;
@ -714,6 +712,10 @@ nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type,
_at.resp_stop(); _at.resp_stop();
} }
if (_at.get_last_error() == NSAPI_ERROR_OK) {
_last_reg_type = type;
}
return _at.unlock_return_error(); return _at.unlock_return_error();
} }