From c26311b071ef6072097b8f86157d5c1cb047b506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teppo=20J=C3=A4rvelin?= Date: Fri, 9 Mar 2018 13:10:51 +0200 Subject: [PATCH] async works. Retry logic needs refining. --- .../easy_cellular/CellularConnectionFSM.cpp | 104 +++++++----------- .../easy_cellular/CellularConnectionFSM.h | 2 +- .../easy_cellular/EasyCellularConnection.cpp | 32 ++++-- .../easy_cellular/EasyCellularConnection.h | 2 + .../framework/AT/AT_CellularNetwork.cpp | 8 +- 5 files changed, 70 insertions(+), 78 deletions(-) diff --git a/features/cellular/easy_cellular/CellularConnectionFSM.cpp b/features/cellular/easy_cellular/CellularConnectionFSM.cpp index aee17cd0d7..99ae068116 100644 --- a/features/cellular/easy_cellular/CellularConnectionFSM.cpp +++ b/features/cellular/easy_cellular/CellularConnectionFSM.cpp @@ -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,21 +407,27 @@ void CellularConnectionFSM::state_sim_pin() void CellularConnectionFSM::state_registering() { - _cellularDevice->set_timeout(TIMEOUT_NETWORK); - _next_state = STATE_REGISTER_NETWORK; - 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("STATE_REGISTERING_NETWORK, event timeout 180s"); - } + 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()) { + _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) { - _event_timeout = -1; - } - if (_next_state == STATE_REGISTERING_NETWORK) { - _retry_count++; + if (_retry_count > 3) { + _event_timeout = -1; + } + if (_next_state == STATE_REGISTERING_NETWORK) { + _retry_count++; + } } } @@ -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 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); } } } diff --git a/features/cellular/easy_cellular/CellularConnectionFSM.h b/features/cellular/easy_cellular/CellularConnectionFSM.h index 0d83e19574..7d0f2730d2 100644 --- a/features/cellular/easy_cellular/CellularConnectionFSM.h +++ b/features/cellular/easy_cellular/CellularConnectionFSM.h @@ -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(); diff --git a/features/cellular/easy_cellular/EasyCellularConnection.cpp b/features/cellular/easy_cellular/EasyCellularConnection.cpp index ba5e009710..1f7c7f9152 100644 --- a/features/cellular/easy_cellular/EasyCellularConnection.cpp +++ b/features/cellular/easy_cellular/EasyCellularConnection.cpp @@ -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 status_cb) { + _status_cb = status_cb; _cellularConnectionFSM.attach(status_cb); } diff --git a/features/cellular/easy_cellular/EasyCellularConnection.h b/features/cellular/easy_cellular/EasyCellularConnection.h index 909499600f..c7e9f4c68b 100644 --- a/features/cellular/easy_cellular/EasyCellularConnection.h +++ b/features/cellular/easy_cellular/EasyCellularConnection.h @@ -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 _status_cb; }; } // namespace diff --git a/features/cellular/framework/AT/AT_CellularNetwork.cpp b/features/cellular/framework/AT/AT_CellularNetwork.cpp index 31812bf98b..e0b5c0ab2d 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.cpp +++ b/features/cellular/framework/AT/AT_CellularNetwork.cpp @@ -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(); }