diff --git a/UNITTESTS/stubs/AT_CellularDevice_stub.cpp b/UNITTESTS/stubs/AT_CellularDevice_stub.cpp index 69e8df2f98..f67c86fa3c 100644 --- a/UNITTESTS/stubs/AT_CellularDevice_stub.cpp +++ b/UNITTESTS/stubs/AT_CellularDevice_stub.cpp @@ -242,3 +242,7 @@ nsapi_error_t AT_CellularDevice::soft_power_off() { return NSAPI_ERROR_OK; } + +void AT_CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularContext *ctx) +{ +} diff --git a/features/cellular/framework/API/CellularDevice.h b/features/cellular/framework/API/CellularDevice.h index 292c850e37..122750b7cf 100644 --- a/features/cellular/framework/API/CellularDevice.h +++ b/features/cellular/framework/API/CellularDevice.h @@ -450,7 +450,7 @@ protected: * This method will broadcast to every interested classes: * CellularContext (might be many) and CellularStateMachine if available. */ - void cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularContext *ctx = NULL); + virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularContext *ctx = NULL); void stm_callback(nsapi_event_t ev, intptr_t ptr); int _network_ref_count; int _sms_ref_count; diff --git a/features/cellular/framework/AT/AT_CellularDevice.cpp b/features/cellular/framework/AT/AT_CellularDevice.cpp index 17780e92bf..86676ebafc 100644 --- a/features/cellular/framework/AT/AT_CellularDevice.cpp +++ b/features/cellular/framework/AT/AT_CellularDevice.cpp @@ -601,3 +601,19 @@ nsapi_error_t AT_CellularDevice::set_power_save_mode(int periodic_time, int acti return _at->unlock_return_error(); } + +void AT_CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularContext *ctx) +{ + if (ev >= NSAPI_EVENT_CELLULAR_STATUS_BASE && ev <= NSAPI_EVENT_CELLULAR_STATUS_END) { + cellular_connection_status_t cell_ev = (cellular_connection_status_t)ev; + if (cell_ev == CellularDeviceTimeout) { + cell_callback_data_t *data = (cell_callback_data_t *)ptr; + int timeout = *(int *)data->data; + if (_default_timeout != timeout) { + _default_timeout = timeout; + ATHandler::set_at_timeout_list(_default_timeout, true); + } + } + } + CellularDevice::cellular_callback(ev, ptr, ctx); +} diff --git a/features/cellular/framework/AT/AT_CellularDevice.h b/features/cellular/framework/AT/AT_CellularDevice.h index 258f835895..9167726802 100644 --- a/features/cellular/framework/AT/AT_CellularDevice.h +++ b/features/cellular/framework/AT/AT_CellularDevice.h @@ -141,6 +141,9 @@ public: bool _modem_debug_on; ATHandler *_at; +protected: + virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr, CellularContext *ctx = NULL); + private: void urc_nw_deact(); void urc_pdn_deact(); diff --git a/features/cellular/framework/common/CellularCommon.h b/features/cellular/framework/common/CellularCommon.h index 502ff27c92..10f20478d6 100644 --- a/features/cellular/framework/common/CellularCommon.h +++ b/features/cellular/framework/common/CellularCommon.h @@ -65,6 +65,9 @@ typedef enum cellular_event_status { CellularSignalQuality = NSAPI_EVENT_CELLULAR_STATUS_BASE + 8, /* cell_callback_data_t.error will contains return value when signal quality was queried. data will hold the pointer to cell_signal_quality struct. See possible values from ../API/CellularNetwork.h*/ CellularStateRetryEvent = NSAPI_EVENT_CELLULAR_STATUS_BASE + 9, /* cell_callback_data_t.error contain an error if any. cell_callback_data_t.status_data contains cellular_event_status and it specifies the operation which is retried. cellular_event_status.data contains current retrycount */ + CellularDeviceTimeout = NSAPI_EVENT_CELLULAR_STATUS_BASE + 10,/* cell_callback_data_t.error contain an error or NSAPI_ERROR_OK, + cell_callback_data_t.status_data contains the current cellular_connection_status_t, + cellular_event_status.data contains new timeout value in milliseconds */ } cellular_connection_status_t; #endif // CELLULAR_COMMON_ diff --git a/features/cellular/framework/device/CellularStateMachine.cpp b/features/cellular/framework/device/CellularStateMachine.cpp index 009eae1903..be4bd35f4a 100644 --- a/features/cellular/framework/device/CellularStateMachine.cpp +++ b/features/cellular/framework/device/CellularStateMachine.cpp @@ -305,7 +305,7 @@ void CellularStateMachine::retry_state_or_fail() void CellularStateMachine::state_init() { - _cellularDevice.set_timeout(_state_timeout_power_on); + change_timeout(_state_timeout_power_on); tr_info("Start connecting (timeout %d ms)", _state_timeout_power_on); _cb_data.error = _cellularDevice.is_ready(); _status = _cb_data.error ? 0 : DEVICE_READY; @@ -322,7 +322,7 @@ void CellularStateMachine::state_init() void CellularStateMachine::state_power_on() { - _cellularDevice.set_timeout(_state_timeout_power_on); + change_timeout(_state_timeout_power_on); tr_info("Modem power ON (timeout %d ms)", _state_timeout_power_on); if (power_on()) { enter_to_state(STATE_DEVICE_READY); @@ -354,7 +354,7 @@ bool CellularStateMachine::device_ready() void CellularStateMachine::state_device_ready() { - _cellularDevice.set_timeout(_state_timeout_power_on); + change_timeout(_state_timeout_power_on); if (!(_status & DEVICE_READY)) { tr_debug("Device was not ready, calling soft_power_on()"); _cb_data.error = _cellularDevice.soft_power_on(); @@ -378,7 +378,7 @@ void CellularStateMachine::state_device_ready() void CellularStateMachine::state_sim_pin() { - _cellularDevice.set_timeout(_state_timeout_sim_pin); + change_timeout(_state_timeout_sim_pin); tr_info("Setup SIM (timeout %d ms)", _state_timeout_sim_pin); if (open_sim()) { bool success = false; @@ -433,7 +433,7 @@ void CellularStateMachine::state_signal_quality() void CellularStateMachine::state_registering() { - _cellularDevice.set_timeout(_state_timeout_network); + change_timeout(_state_timeout_network); if (is_registered()) { if (_cb_data.status_data != CellularNetwork::RegisteredHomeNetwork && _cb_data.status_data != CellularNetwork::RegisteredRoaming && _status) { @@ -446,7 +446,7 @@ void CellularStateMachine::state_registering() enter_to_state(STATE_ATTACHING_NETWORK); } else { tr_info("Network registration (timeout %d ms)", _state_timeout_registration); - _cellularDevice.set_timeout(_state_timeout_registration); + change_timeout(_state_timeout_registration); if (!_command_success && !_plmn) { // don't call set_registration twice for manual registration _cb_data.error = _network.set_registration(_plmn); _command_success = (_cb_data.error == NSAPI_ERROR_OK); @@ -458,7 +458,7 @@ void CellularStateMachine::state_registering() void CellularStateMachine::state_attaching() { if (_status != ATTACHED_TO_NETWORK) { - _cellularDevice.set_timeout(_state_timeout_connect); + change_timeout(_state_timeout_connect); tr_info("Attaching network (timeout %d ms)", _state_timeout_connect); _cb_data.error = _network.set_attach(); } @@ -648,6 +648,16 @@ void CellularStateMachine::send_event_cb(cellular_connection_status_t status) } } +void CellularStateMachine::change_timeout(const int &timeout) +{ + _cb_data.status_data = _current_event; + _cb_data.data = &timeout; + _cb_data.error = NSAPI_ERROR_OK; + // event callback is a preferred method to communicate to CellularDevice, + // for example calling CellularDevice::set_timeout would call back to this class + send_event_cb(CellularDeviceTimeout); +} + bool CellularStateMachine::check_is_target_reached() { if (((_target_state == _state || _target_state < _next_state) && _cb_data.error == NSAPI_ERROR_OK && !_is_retry) || diff --git a/features/cellular/framework/device/CellularStateMachine.h b/features/cellular/framework/device/CellularStateMachine.h index ea1a1b16c9..d31bf2167d 100644 --- a/features/cellular/framework/device/CellularStateMachine.h +++ b/features/cellular/framework/device/CellularStateMachine.h @@ -157,6 +157,7 @@ private: void pre_event(CellularState state); bool check_is_target_reached(); void send_event_cb(cellular_connection_status_t status); + void change_timeout(const int &timeout); CellularDevice &_cellularDevice; CellularState _state;