Skip to content

Commit

Permalink
[gen2, threading] Fixes Cellular taking up to 10 minutes to shutoff m…
Browse files Browse the repository at this point in the history
…odem with Cellular.off() if there is no cell connection [ch73242]
  • Loading branch information
technobly committed Feb 19, 2021
1 parent f7b43ca commit 3a88180
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 72 deletions.
4 changes: 3 additions & 1 deletion system/src/system_network_cellular.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class CellularNetworkInterface : public ManagedIPNetworkInterface<CellularConfig
virtual void on_finalize_listening(bool complete) override { /* n/a */ }

virtual void on_start_listening() override {
connect_cancelled = false;
cellular_cancel(false, true, NULL); // resume
}

Expand Down Expand Up @@ -84,6 +85,7 @@ class CellularNetworkInterface : public ManagedIPNetworkInterface<CellularConfig

int on_now() override {
// Resume unconditionally
connect_cancelled = false;
cellular_cancel(false, HAL_IsISR(), nullptr);
cellular_result_t ret = cellular_on(nullptr);
if (ret != 0) {
Expand Down Expand Up @@ -166,7 +168,7 @@ class CellularNetworkInterface : public ManagedIPNetworkInterface<CellularConfig
ATOMIC_BLOCK() {
if (connecting || !SPARK_WLAN_STARTED)
{
if (cancel!=connect_cancelled) {
if (cancel != connect_cancelled) {
require_cancel = true;
connect_cancelled = cancel;
}
Expand Down
14 changes: 0 additions & 14 deletions user/tests/wiring/cell_connect_after_off/application.cpp

This file was deleted.

This file was deleted.

5 changes: 0 additions & 5 deletions user/tests/wiring/cell_connect_after_off/readme.md

This file was deleted.

39 changes: 39 additions & 0 deletions user/tests/wiring/cellular_no_antenna/application.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 Particle Industries, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PARTICLE_TEST_RUNNER
#include "application.h"
#include "unit-test/unit-test.h"

SYSTEM_MODE(MANUAL);

// make clean all TEST=wiring/cellular_no_antenna PLATFORM=electron -s COMPILE_LTO=n program-dfu
// make clean all TEST=wiring/cellular_no_antenna PLATFORM=electron -s COMPILE_LTO=n program-dfu USE_THREADING=y
//
// Serial1LogHandler logHandler(115200, LOG_LEVEL_ALL, {
// { "comm", LOG_LEVEL_NONE }, // filter out comm messages
// { "system", LOG_LEVEL_INFO } // only info level for system messages
// });

UNIT_TEST_APP();

// Enable threading if compiled with "USE_THREADING=y"
#if PLATFORM_THREADING == 1 && USE_THREADING == 1
SYSTEM_THREAD(ENABLED);
#endif

#endif // PARTICLE_TEST_RUNNER
118 changes: 118 additions & 0 deletions user/tests/wiring/cellular_no_antenna/cellular_no_antenna.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Copyright (c) 2021 Particle Industries, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/


/*
*************************************************
* Keep antenna disconnected for all tests below *
*************************************************
*/

#include "application.h"
#include "unit-test/unit-test.h"

#if Wiring_Cellular

void disconnect_from_cloud(system_tick_t timeout) {
Particle.disconnect();
waitFor(Particle.disconnected, timeout);

Cellular.disconnect();
waitForNot(Cellular.ready, timeout);

// Avoids some sort of race condition in AUTOMATIC mode
delay(1000);
}
void connect_to_cloud(system_tick_t timeout) {
Particle.connect();
waitFor(Particle.connected, timeout);
}
// Global variable to indicate a connection attempt
int g_state_conn_attempt = 0;
void nwstatus_callback_handler(system_event_t ev, int param) {
if (param == network_status_connecting){
g_state_conn_attempt = 1;
}
}
int network_is_connecting() {
return g_state_conn_attempt;
}

/*
* The following illustrates the problem statement:
* > Keep antenna disconnected for this test
* 1. With antenna disconnected, run `Particle.connect()`
* 2. Run `Cellular.off()`
* 3. After 60 sec, run `Particle.connect()` again, and verify that you see cellular AT traffic to turn on the modem or connect to the network.
*/
test(CELLULAR_NO_ANTENNA_01_conn_after_off) {
/* This test should only be run with threading enabled */
if (system_thread_get_state(nullptr) != spark::feature::ENABLED) {
skip();
return;
}

// Connect to Particle cloud
Particle.connect();
delay(30000);
// Power off the cell radio
Cellular.off();
delay(60000);
// Callback handler for network_status
System.on(network_status, nwstatus_callback_handler);
// clear g_state_conn_attempt just-in-case
g_state_conn_attempt = 0;
// Check that Particle.connect() attempts to work after the delay
Particle.connect();
// Wait sometime for Particle.connect() to try
waitFor(network_is_connecting, 30000);
// Verify that a connection attempt has been made
assertEqual(g_state_conn_attempt, 1);
}

// Test for ch73242
test(CELLULAR_NO_ANTENNA_02_device_will_poweroff_quickly_when_modem_cannot_connect) {
/* This test should only be run with threading enabled */
if (system_thread_get_state(nullptr) != spark::feature::ENABLED) {
skip();
return;
}

const system_tick_t waitMs[9] = {2000, 4000, 5000, 7500, 10000, 12500, 15000, 25000};
// Callback handler for network_status
System.on(network_status, nwstatus_callback_handler);
// clear g_state_conn_attempt just-in-case
g_state_conn_attempt = 0;
for (int x = 0; x < 9; x++) {
Particle.connect();
// Log.info("delaying: %lu", waitMs[x]);
delay(waitMs[x]);
assertTrue(Particle.disconnected());
// cellular_cancel(true, false, NULL); // Workaround: call before Cellular.off()
Cellular.off();
waitFor(Cellular.isOff, 60000);
assertTrue(Cellular.isOff());
}
// Check that Particle.connect() attempts to work after the delay
Particle.connect();
// Wait sometime for Particle.connect() to try
waitFor(network_is_connecting, 30000);
// Verify that a connection attempt has been made
assertEqual(g_state_conn_attempt, 1);
}

#endif // Wiring_Cellular
18 changes: 18 additions & 0 deletions user/tests/wiring/cellular_no_antenna/test.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
INCLUDE_DIRS += $(SOURCE_PATH)/$(USRSRC) # add user sources to include path
# add C and CPP files - if USRSRC is not empty, then add a slash
CPPSRC += $(call target_files,$(USRSRC_SLASH),*.cpp)
CSRC += $(call target_files,$(USRSRC_SLASH),*.c)

APPSOURCES=$(call target_files,$(USRSRC_SLASH),*.cpp)
APPSOURCES+=$(call target_files,$(USRSRC_SLASH),*.c)
ifeq ($(strip $(APPSOURCES)),)
$(error "No sources found in $(SOURCE_PATH)/$(USRSRC)")
endif

ifeq ("${USE_THREADING}","y")
USE_THREADING_VALUE=1
else
USE_THREADING_VALUE=0
endif

CFLAGS += -DUSE_THREADING=${USE_THREADING_VALUE}

0 comments on commit 3a88180

Please sign in to comment.