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) {
case STATE_INIT:
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;
static const char *strings[] = { "Init", "Power", "Device ready", "SIM pin", "Register network", "Registering network", "Attach network", "Attaching network", "Connect network", "Connected"};
return strings[state];
}
bool CellularConnectionFSM::is_automatic_registering()
{
CellularNetwork::NWRegisteringMode 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) {
return true;
}
@ -397,7 +362,7 @@ void CellularConnectionFSM::retry_state_or_fail()
void CellularConnectionFSM::state_init()
{
_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);
}
@ -435,7 +400,6 @@ void CellularConnectionFSM::state_sim_pin()
if (open_sim()) {
enter_to_state(STATE_REGISTERING_NETWORK);
_state_retry_count = 0;
tr_info("Check for network registration");
} else {
retry_state_or_fail();
}
@ -443,6 +407,11 @@ void CellularConnectionFSM::state_sim_pin()
void CellularConnectionFSM::state_registering()
{
if (is_registered()) {
// we are already registered, go to attach
_next_state = STATE_ATTACHING_NETWORK;
} else {
// by default we and start the registering but if automatic mode is on then we start waiting for async response
_cellularDevice->set_timeout(TIMEOUT_NETWORK);
_next_state = STATE_REGISTER_NETWORK;
if (is_automatic_registering()) {
@ -450,7 +419,7 @@ void CellularConnectionFSM::state_registering()
// 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("STATE_REGISTERING_NETWORK, event timeout 180s");
tr_info("Automatic register was already on. Start waiting urc's: event timeout %ds", _event_timeout/1000);
}
if (_retry_count > 3) {
@ -460,6 +429,7 @@ void CellularConnectionFSM::state_registering()
_retry_count++;
}
}
}
void CellularConnectionFSM::state_register()
{
@ -528,7 +498,14 @@ void CellularConnectionFSM::state_connect_to_network()
tr_info("Connect to cellular network (timeout %d ms)", TIMEOUT_NETWORK);
nsapi_error_t err = _network->connect();
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;
#endif // NSAPI_PPP_AVAILABLE
} else {
if (_retry_count < _retry_array_length) {
_event_timeout = _retry_timeout_array[_retry_count] * 1000;
@ -613,9 +590,6 @@ void CellularConnectionFSM::event()
nsapi_error_t CellularConnectionFSM::start_dispatch()
{
tr_info("CellularConnectionUtil::start");
tr_info("Create cellular thread");
MBED_ASSERT(!_queue_thread);
_queue_thread = new rtos::Thread;
@ -628,7 +602,6 @@ nsapi_error_t CellularConnectionFSM::start_dispatch()
return NSAPI_ERROR_NO_MEMORY;
}
tr_info("CellularConnectionUtil::started");
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)
{
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 (ptr == CellularRegistrationStatusChanged && _state == STATE_REGISTERING_NETWORK) {
// check for registration status
if (is_registered()) {
tr_info("Registered, cancel state and continue to attach...");
_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);
bool is_automatic_registering();
char* get_state_string(CellularState state);
const char* get_state_string(CellularState state);
private:
bool power_on();
bool open_sim();

View File

@ -37,33 +37,35 @@ namespace mbed {
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 next_state: %s", _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)next_state));
tr_info("cellular_status: %s ==> %s", _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)state),
_cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)next_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));
MBED_ASSERT(_cellularSemaphore.release() == osOK);
return false;
} else {
_is_connected = false;
return false; // return false -> state machine is halted
}
return true;
}
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) :
_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)
NSAPI_ERROR_OK), _status_cb(0)
{
tr_info("EasyCellularConnection()");
#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)
{
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)
{
_status_cb = status_cb;
_cellularConnectionFSM.attach(status_cb);
}

View File

@ -132,6 +132,7 @@ public:
*/
void modem_debug_on(bool on);
void set_is_blocking(bool blocking);
protected:
/** Provide access to the NetworkStack object
@ -161,6 +162,7 @@ private:
rtos::Semaphore _cellularSemaphore;
CellularConnectionFSM _cellularConnectionFSM;
nsapi_error_t _credentials_err;
Callback<void(nsapi_event_t, intptr_t)> _status_cb;
};
} // 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)
{
_async = blocking;
_async = !blocking;
#if NSAPI_PPP_AVAILABLE
return nsapi_ppp_set_blocking(blocking);
#else
@ -572,7 +572,6 @@ nsapi_error_t AT_CellularNetwork::set_registration_urc(bool urc_on)
if (has_registration(at_reg[i].type)) {
_last_reg_type = at_reg[i].type;
if (urc_on) {
tr_info("setting reg urc for i: %d", i);
_at.cmd_start(at_reg[i].cmd);
_at.write_string("=2", false);
_at.cmd_stop();
@ -596,7 +595,6 @@ nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode
_at.cmd_stop();
_at.resp_start("+COPS:");
int tmpmode = (NWRegisteringMode)_at.read_int();
tr_info("get_network_registering_mode, tmpmode: %d", tmpmode);
_at.resp_stop();
mode = (NWRegisteringMode)tmpmode;
@ -714,6 +712,10 @@ nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type,
_at.resp_stop();
}
if (_at.get_last_error() == NSAPI_ERROR_OK) {
_last_reg_type = type;
}
return _at.unlock_return_error();
}