Skip to content

Commit a743b4a

Browse files
Teppo Järvelin0xc0170
authored andcommitted
Cellular: fix possible crash in state machine
_sim_pin was changed to pointer from array and length was checked with strlen. If _sim_pin was null it caused crash. Fix by checking _sim_pin against NULL. Power class could have been called without checking if power is NULL. Fix by checking that power class is not null. Fix state machine to return correct states when queried.
1 parent 40db17e commit a743b4a

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

features/cellular/framework/device/CellularStateMachine.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void CellularStateMachine::reset()
8383
_plmn_network_found = false;
8484
_is_retry = false;
8585
_active_context = false;
86+
_target_state = STATE_INIT;
8687
enter_to_state(STATE_INIT);
8788
}
8889

@@ -151,7 +152,7 @@ bool CellularStateMachine::open_sim()
151152
}
152153

153154
if (state == CellularDevice::SimStatePinNeeded) {
154-
if (strlen(_sim_pin)) {
155+
if (_sim_pin) {
155156
tr_info("Entering PIN to open SIM");
156157
_cb_data.error = _cellularDevice.set_pin(_sim_pin);
157158
if (_cb_data.error) {
@@ -515,8 +516,13 @@ void CellularStateMachine::continue_from_state(CellularState state)
515516
nsapi_error_t CellularStateMachine::run_to_state(CellularStateMachine::CellularState state)
516517
{
517518
_mutex.lock();
519+
520+
CellularState tmp_state = state;
521+
if (_plmn && tmp_state == STATE_REGISTERING_NETWORK) {
522+
tmp_state = STATE_MANUAL_REGISTERING_NETWORK;
523+
}
518524
// call pre_event via queue so that it's in same thread and it's safe to decisions
519-
int id = _queue.call_in(0, this, &CellularStateMachine::pre_event, state);
525+
int id = _queue.call_in(0, this, &CellularStateMachine::pre_event, tmp_state);
520526
if (!id) {
521527
stop();
522528
_mutex.unlock();
@@ -558,7 +564,11 @@ bool CellularStateMachine::get_current_status(CellularStateMachine::CellularStat
558564
_mutex.lock();
559565
current_state = _state;
560566
target_state = _target_state;
561-
is_running = _event_id != -1;
567+
if (_event_id == -1 || _event_id == STM_STOPPED) {
568+
is_running = false;
569+
} else {
570+
is_running = true;
571+
}
562572
_mutex.unlock();
563573
return is_running;
564574
}
@@ -660,8 +670,14 @@ void CellularStateMachine::set_cellular_callback(mbed::Callback<void(nsapi_event
660670

661671
bool CellularStateMachine::check_is_target_reached()
662672
{
663-
tr_debug("check_is_target_reached(): target state %s, _state: %s, _cb_data.error: %d, _event_id: %d, _is_retry: %d", get_state_string(_target_state), get_state_string(_state), _cb_data.error, _event_id, _is_retry);
664-
if ((_target_state == _state && _cb_data.error == NSAPI_ERROR_OK && !_is_retry) || _event_id == STM_STOPPED) {
673+
tr_debug("check_is_target_reached(): target state %s, _state: %s, _cb_data.error: %d, _event_id: %d,_is_retry: %d", get_state_string(_target_state), get_state_string(_state), _cb_data.error, _event_id, _is_retry);
674+
675+
if (((_target_state == _state || _target_state < _next_state) && _cb_data.error == NSAPI_ERROR_OK && !_is_retry) ||
676+
_event_id == STM_STOPPED) {
677+
if (_target_state != _state && _target_state < _next_state) {
678+
// we are skipping the state, update _state to current state because we have reached it
679+
_state = _target_state;
680+
}
665681
_event_id = -1;
666682
return true;
667683
}
@@ -717,8 +733,12 @@ void CellularStateMachine::device_ready_cb()
717733
}
718734
}
719735

720-
void CellularStateMachine::set_retry_timeout_array(uint16_t timeout[], int array_len)
736+
void CellularStateMachine::set_retry_timeout_array(uint16_t *timeout, int array_len)
721737
{
738+
if (!timeout || array_len <= 0) {
739+
tr_warn("set_retry_timeout_array, timeout array null or invalid length");
740+
return;
741+
}
722742
_retry_array_length = array_len > RETRY_ARRAY_SIZE ? RETRY_ARRAY_SIZE : array_len;
723743

724744
for (int i = 0; i < _retry_array_length; i++) {

features/cellular/framework/device/CellularStateMachine.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class CellularStateMachine {
4242
// friend of CellularDevice so that it's the only way to close/delete this class.
4343
friend class CellularDevice;
4444
friend class AT_CellularDevice;
45+
friend class UT_CellularStateMachine; // for unit tests
4546
/** Constructor
4647
*
4748
* @param device reference to CellularDevice
@@ -98,7 +99,7 @@ class CellularStateMachine {
9899
* @param timeout timeout array using seconds
99100
* @param array_len length of the array
100101
*/
101-
void set_retry_timeout_array(uint16_t timeout[], int array_len);
102+
void set_retry_timeout_array(uint16_t *timeout, int array_len);
102103

103104
/** Sets the operator plmn which is used when registering to a network specified by plmn. If plmn is not set then automatic
104105
* registering is used when registering to a cellular network. Does not start any operations.

0 commit comments

Comments
 (0)