Cellular: Convert to Chrono

Note that documentation for random_max_start_delay config setting has
been changed to indicate that the setting is in seconds, and always has
been. No functional change.
pull/12430/head
Kevin Bracey 2020-02-13 16:39:03 +02:00
parent 029109a2f0
commit 355b45ade1
30 changed files with 226 additions and 147 deletions

View File

@ -33,6 +33,7 @@
using namespace mbed;
using namespace events;
using namespace std::chrono_literals;
// AStyle ignored as the definition is not clear due to preprocessor usage
// *INDENT-OFF*
@ -44,7 +45,7 @@ protected:
ATHandler_stub::nsapi_error_value = 0;
ATHandler_stub::nsapi_error_ok_counter = 0;
ATHandler_stub::int_value = -1;
ATHandler_stub::timeout = 0;
ATHandler_stub::timeout = 0s;
ATHandler_stub::default_timeout = 0;
ATHandler_stub::debug_on = 0;
ATHandler_stub::ssize_value = 0;

View File

@ -22,6 +22,7 @@
using namespace mbed;
using namespace events;
using namespace std::chrono_literals;
class TestAT_CellularDevice : public testing::Test {
protected:
@ -129,17 +130,17 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_set_timeout)
{
FileHandle_stub fh1;
AT_CellularDevice dev(&fh1);
ATHandler_stub::timeout = 0;
ATHandler_stub::timeout = 0s;
ATHandler_stub::default_timeout = false;
dev.set_timeout(5000);
EXPECT_TRUE(ATHandler_stub::timeout == 5000);
EXPECT_TRUE(ATHandler_stub::timeout == 5s);
EXPECT_TRUE(ATHandler_stub::default_timeout == true);
EXPECT_TRUE(dev.open_sms());
dev.set_timeout(5000);
EXPECT_TRUE(ATHandler_stub::timeout == 5000);
EXPECT_TRUE(ATHandler_stub::timeout == 5s);
EXPECT_TRUE(ATHandler_stub::default_timeout == true);
dev.close_sms();

View File

@ -31,7 +31,7 @@ const uint8_t MAX_RESP_LENGTH = 7;
nsapi_error_t ATHandler_stub::nsapi_error_value = 0;
uint8_t ATHandler_stub::nsapi_error_ok_counter = 0;
int ATHandler_stub::int_value = -1;
int ATHandler_stub::timeout = 0;
mbed::chrono::milliseconds_u32 ATHandler_stub::timeout{};
bool ATHandler_stub::default_timeout = 0;
bool ATHandler_stub::debug_on = 0;
ssize_t ATHandler_stub::ssize_value = 0;
@ -81,6 +81,11 @@ void ATHandler_stub::debug_call_count_clear()
}
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay) :
ATHandler(fh, queue, mbed::chrono::milliseconds_u32(timeout), output_delimiter, std::chrono::duration<uint16_t, std::milli>(send_delay))
{
}
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, mbed::chrono::milliseconds_u32 timeout, const char *output_delimiter, std::chrono::duration<uint16_t, std::milli> send_delay) :
#if defined AT_HANDLER_MUTEX && defined MBED_CONF_RTOS_PRESENT
_oobCv(_fileHandleMutex),
#endif
@ -165,7 +170,12 @@ nsapi_error_t ATHandler::unlock_return_error()
void ATHandler::set_at_timeout(uint32_t timeout_milliseconds, bool default_timeout)
{
ATHandler_stub::timeout = timeout_milliseconds;
set_at_timeout(mbed::chrono::milliseconds_u32(timeout_milliseconds), default_timeout);
}
void ATHandler::set_at_timeout(mbed::chrono::milliseconds_u32 timeout, bool default_timeout)
{
ATHandler_stub::timeout = timeout;
ATHandler_stub::default_timeout = default_timeout;
}

View File

@ -37,7 +37,7 @@ namespace ATHandler_stub {
extern nsapi_error_t nsapi_error_value;
extern uint8_t nsapi_error_ok_counter;
extern int int_value;
extern int timeout;
extern mbed::chrono::milliseconds_u32 timeout;
extern bool default_timeout;
extern bool debug_on;
extern ssize_t ssize_value;

View File

@ -137,7 +137,7 @@ AT_CellularInformation *AT_CellularDevice::open_information_impl(ATHandler &at)
void AT_CellularDevice::set_timeout(int timeout)
{
_default_timeout = timeout;
_default_timeout = std::chrono::duration<int, std::milli>(timeout);
}
void AT_CellularDevice::modem_debug_on(bool on)

View File

@ -96,6 +96,6 @@ void CellularStateMachine::set_retry_timeout_array(const uint16_t timeout[], int
}
}
void CellularStateMachine::set_timeout(int timeout)
void CellularStateMachine::set_timeout(std::chrono::duration<int, std::milli> timeout)
{
}

View File

@ -19,11 +19,13 @@
#define AT_HANDLER_H_
#include "platform/mbed_retarget.h"
#include "platform/mbed_chrono.h"
#include "events/EventQueue.h"
#include "nsapi_types.h"
#include "Callback.h"
#include "rtos/Kernel.h"
#include <cstdarg>
@ -78,6 +80,16 @@ public:
*/
ATHandler(FileHandle *fh, events::EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay = 0);
/** Constructor
*
* @param fh file handle used for reading AT responses and writing AT commands
* @param queue Event queue used to transfer sigio events to this thread
* @param timeout Timeout when reading for AT response
* @param output_delimiter delimiter used when parsing at responses, "\r" should be used as output_delimiter
* @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command
*/
ATHandler(FileHandle *fh, events::EventQueue &queue, mbed::chrono::milliseconds_u32 timeout, const char *output_delimiter, std::chrono::duration<uint16_t, std::milli> send_delay = std::chrono::milliseconds(0));
~ATHandler();
/** Return used file handle.
@ -126,6 +138,13 @@ public:
*/
void set_at_timeout(uint32_t timeout_milliseconds, bool default_timeout = false);
/** Set timeout in milliseconds for AT commands
*
* @param timeout Timeout in milliseconds
* @param default_timeout Store as default timeout
*/
void set_at_timeout(mbed::chrono::milliseconds_u32 timeout, bool default_timeout = false);
/** Restore timeout to previous timeout. Handy if there is a need to change timeout temporarily.
*/
void restore_at_timeout();
@ -157,6 +176,13 @@ public:
*/
bool sync(int timeout_ms);
/** Synchronize AT command and response handling to modem.
*
* @param timeout ATHandler timeout when trying to sync. Will be restored when function returns.
* @return true is synchronization was successful, false in case of failure
*/
bool sync(std::chrono::duration<int, std::milli> timeout);
/** Sets the delay to be applied before sending any AT command.
*
* @param send_delay the minimum delay in ms between the end of last response and the beginning of a new command
@ -565,11 +591,11 @@ private: //Member variables
char *_output_delimiter;
oob_t *_oobs;
uint32_t _at_timeout;
uint32_t _previous_at_timeout;
mbed::chrono::milliseconds_u32 _at_timeout;
mbed::chrono::milliseconds_u32 _previous_at_timeout;
uint16_t _at_send_delay;
uint64_t _last_response_stop;
std::chrono::duration<uint16_t, std::milli> _at_send_delay;
rtos::Kernel::Clock::time_point _last_response_stop;
int32_t _ref_count;
bool _is_fh_usable;
@ -610,7 +636,7 @@ private: //Member variables
bool _use_delimiter;
// time when a command or an URC processing was started
uint64_t _start_time;
rtos::Kernel::Clock::time_point _start_time;
// eventqueue event id
int _event_id;

View File

@ -27,13 +27,13 @@
#endif // #if DEVICE_SERIAL
#include "ThisThread.h"
#define NETWORK_TIMEOUT 30 * 60 * 1000 // 30 minutes
#define DEVICE_TIMEOUT 5 * 60 * 1000 // 5 minutes
#define NETWORK_TIMEOUT 30min
#define DEVICE_TIMEOUT 5min
// Timeout to wait for URC indicating ciot optimization support from network
#define CP_OPT_NW_REPLY_TIMEOUT 3000 // 3 seconds
#define CP_OPT_NW_REPLY_TIMEOUT 3s
#if NSAPI_PPP_AVAILABLE
#define AT_SYNC_TIMEOUT 1000 // 1 second timeout
#define AT_SYNC_TIMEOUT 1s
#include "nsapi_ppp.h"
#endif
@ -45,6 +45,7 @@
using namespace mbed_cellular_util;
using namespace mbed;
using namespace rtos;
using namespace std::chrono_literals;
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
_current_op(OP_INVALID), _dcd_pin(NC), _active_high(false), _cp_req(cp_req), _is_connected(false), _at(at)
@ -118,7 +119,7 @@ nsapi_error_t AT_CellularContext::connect()
} else {
if (_cb_data.error == NSAPI_ERROR_ALREADY) {
// device is already attached, to be async we must use queue to connect and give proper callbacks
int id = _device->get_queue()->call_in(0, this, &AT_CellularContext::do_connect_with_retry);
int id = _device->get_queue()->call(this, &AT_CellularContext::do_connect_with_retry);
if (id == 0) {
return NSAPI_ERROR_NO_MEMORY;
}
@ -162,7 +163,8 @@ nsapi_error_t AT_CellularContext::check_operation(nsapi_error_t err, ContextOper
_current_op = op;
if (err == NSAPI_ERROR_IN_PROGRESS || err == NSAPI_ERROR_OK) {
if (_is_blocking) {
int sema_acq = _semaphore.try_acquire_for(get_timeout_for_operation(op)); // cellular network searching may take several minutes
auto d = std::chrono::duration<uint32_t, std::milli>(get_timeout_for_operation(op));
int sema_acq = _semaphore.try_acquire_for(d); // cellular network searching may take several minutes
if (!sema_acq) {
tr_warning("No cellular connection");
return NSAPI_ERROR_TIMEOUT;
@ -181,11 +183,11 @@ nsapi_connection_status_t AT_CellularContext::get_connection_status() const
uint32_t AT_CellularContext::get_timeout_for_operation(ContextOperation op) const
{
uint32_t timeout = NETWORK_TIMEOUT; // default timeout is 30 minutes as registration and attach may take time
std::chrono::duration<uint32_t, std::milli> timeout = NETWORK_TIMEOUT; // default timeout is 30 minutes as registration and attach may take time
if (op == OP_SIM_READY || op == OP_DEVICE_READY) {
timeout = DEVICE_TIMEOUT; // use 5 minutes for device ready and sim
}
return timeout;
return timeout.count();
}
bool AT_CellularContext::is_connected()
@ -716,7 +718,7 @@ nsapi_error_t AT_CellularContext::disconnect()
do_disconnect();
return _cb_data.error;
} else {
int event_id = _device->get_queue()->call_in(0, this, &AT_CellularContext::do_disconnect);
int event_id = _device->get_queue()->call(this, &AT_CellularContext::do_disconnect);
if (event_id == 0) {
return NSAPI_ERROR_NO_MEMORY;
}
@ -742,7 +744,7 @@ void AT_CellularContext::deactivate_context()
void AT_CellularContext::check_and_deactivate_context()
{
// CGACT and CGATT commands might take up to 3 minutes to respond.
_at.set_at_timeout(180 * 1000);
_at.set_at_timeout(3min);
int active_contexts_count = 0;
_is_context_active = _nw->is_active_context(&active_contexts_count, _cid);

View File

@ -34,8 +34,9 @@
using namespace mbed_cellular_util;
using namespace events;
using namespace mbed;
using namespace std::chrono_literals;
#define DEFAULT_AT_TIMEOUT 1000 // at default timeout in milliseconds
#define DEFAULT_AT_TIMEOUT 1s // at default timeout
const int MAX_SIM_RESPONSE_LENGTH = 16;
AT_CellularDevice::AT_CellularDevice(FileHandle *fh) :
@ -388,7 +389,7 @@ void AT_CellularDevice::close_information()
void AT_CellularDevice::set_timeout(int timeout)
{
_default_timeout = timeout;
_default_timeout = std::chrono::duration<int, std::milli>(timeout);
_at.set_at_timeout(_default_timeout, true);
@ -420,7 +421,7 @@ nsapi_error_t AT_CellularDevice::init()
}
}
tr_debug("Wait 100ms to init modem");
rtos::ThisThread::sleep_for(100); // let modem have time to get ready
rtos::ThisThread::sleep_for(100ms); // let modem have time to get ready
}
return _at.unlock_return_error();
@ -577,7 +578,7 @@ void AT_CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr, Cellul
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;
auto timeout = *(std::chrono::duration<int, std::milli> *)data->data;
if (_default_timeout != timeout) {
_default_timeout = timeout;
_at.set_at_timeout(_default_timeout, true);
@ -611,7 +612,7 @@ nsapi_error_t AT_CellularDevice::set_baud_rate(int baud_rate)
_at.set_baud(baud_rate);
// Give some time before starting using the UART with the new baud rate
rtos::ThisThread::sleep_for(3000);
rtos::ThisThread::sleep_for(3s);
#else
// Currently ATHandler only supports BufferedSerial based communication and
// if serial is disabled, baud rate cannot be set

View File

@ -197,7 +197,7 @@ private:
AT_CellularInformation *_information;
AT_CellularContext *_context_list;
int _default_timeout;
std::chrono::duration<int, std::milli> _default_timeout;
bool _modem_debug_on;
const intptr_t *_property_array;
};

View File

@ -32,6 +32,7 @@
using namespace mbed;
using namespace events;
using namespace mbed_cellular_util;
using namespace std::chrono_literals;
#include "CellularLog.h"
@ -42,7 +43,7 @@ using namespace mbed_cellular_util;
#endif
// URCs should be handled fast, if you add debug traces within URC processing then you also need to increase this time
#define PROCESS_URC_TIME 20
#define PROCESS_URC_TIME 20ms
// Suppress logging of very big packet payloads, maxlen is approximate due to write/read are cached
#define DEBUG_MAXLEN 60
@ -70,6 +71,11 @@ static const uint8_t map_3gpp_errors[][2] = {
};
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const char *output_delimiter, uint16_t send_delay) :
ATHandler(fh, queue, mbed::chrono::milliseconds_u32(timeout), output_delimiter, std::chrono::duration<uint16_t, std::milli>(send_delay))
{
}
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, mbed::chrono::milliseconds_u32 timeout, const char *output_delimiter, std::chrono::duration<uint16_t, std::milli> send_delay) :
#if defined AT_HANDLER_MUTEX && defined MBED_CONF_RTOS_PRESENT
_oobCv(_fileHandleMutex),
#endif
@ -82,7 +88,7 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const
_at_timeout(timeout),
_previous_at_timeout(timeout),
_at_send_delay(send_delay),
_last_response_stop(0),
_last_response_stop(0s),
_ref_count(1),
_is_fh_usable(false),
_stop_tag(NULL),
@ -94,7 +100,7 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, uint32_t timeout, const
_debug_on(DEBUG_AT_ENABLED),
_cmd_start(false),
_use_delimiter(true),
_start_time(0),
_start_time(),
_event_id(0)
{
clear_error();
@ -264,7 +270,7 @@ void ATHandler::lock()
_fileHandleMutex.lock();
#endif
clear_error();
_start_time = rtos::Kernel::get_ms_count();
_start_time = rtos::Kernel::Clock::now();
}
void ATHandler::unlock()
@ -285,14 +291,19 @@ nsapi_error_t ATHandler::unlock_return_error()
}
void ATHandler::set_at_timeout(uint32_t timeout_milliseconds, bool default_timeout)
{
set_at_timeout(mbed::chrono::milliseconds_u32(timeout_milliseconds), default_timeout);
}
void ATHandler::set_at_timeout(mbed::chrono::milliseconds_u32 timeout, bool default_timeout)
{
lock();
if (default_timeout) {
_previous_at_timeout = timeout_milliseconds;
_at_timeout = timeout_milliseconds;
} else if (timeout_milliseconds != _at_timeout) {
_previous_at_timeout = timeout;
_at_timeout = timeout;
} else if (timeout != _at_timeout) {
_previous_at_timeout = _at_timeout;
_at_timeout = timeout_milliseconds;
_at_timeout = timeout;
}
unlock();
}
@ -320,7 +331,7 @@ void ATHandler::process_oob()
if (_fileHandle->readable() || (_recv_pos < _recv_len)) {
tr_debug("AT OoB readable %d, len %u", _fileHandle->readable(), _recv_len - _recv_pos);
_current_scope = NotSet;
uint32_t timeout = _at_timeout;
auto timeout = _at_timeout;
while (true) {
_at_timeout = timeout;
if (match_urc()) {
@ -337,7 +348,7 @@ void ATHandler::process_oob()
break;
}
}
_start_time = rtos::Kernel::get_ms_count();
_start_time = rtos::Kernel::Clock::now();
}
_at_timeout = timeout;
tr_debug("AT OoB done");
@ -366,20 +377,20 @@ void ATHandler::rewind_buffer()
int ATHandler::poll_timeout(bool wait_for_timeout)
{
int timeout;
std::chrono::duration<int, std::milli> timeout;
if (wait_for_timeout) {
uint64_t now = rtos::Kernel::get_ms_count();
auto now = rtos::Kernel::Clock::now();
if (now >= _start_time + _at_timeout) {
timeout = 0;
} else if (_start_time + _at_timeout - now > INT_MAX) {
timeout = INT_MAX;
timeout = 0s;
} else if (_start_time + _at_timeout - now > timeout.max()) {
timeout = timeout.max();
} else {
timeout = _start_time + _at_timeout - now;
}
} else {
timeout = 0;
timeout = 0s;
}
return timeout;
return timeout.count();
}
bool ATHandler::fill_buffer(bool wait_for_timeout)
@ -1138,7 +1149,7 @@ void ATHandler::resp_stop()
// Reset info resp prefix
memset(_info_resp_prefix, 0, sizeof(_info_resp_prefix));
_last_response_stop = rtos::Kernel::get_ms_count();
_last_response_stop = rtos::Kernel::Clock::now();
}
void ATHandler::information_response_stop()
@ -1178,7 +1189,7 @@ void ATHandler::cmd_start(const char *cmd)
return;
}
if (_at_send_delay) {
if (_at_send_delay != 0s) {
rtos::ThisThread::sleep_until(_last_response_stop + _at_send_delay);
}
@ -1495,6 +1506,12 @@ void ATHandler::debug_print(const char *p, int len, ATType type)
}
bool ATHandler::sync(int timeout_ms)
{
return sync(std::chrono::duration<int, std::milli>(timeout_ms));
}
bool ATHandler::sync(std::chrono::duration<int, std::milli> timeout)
{
if (!_is_fh_usable) {
_last_err = NSAPI_ERROR_BUSY;
@ -1502,14 +1519,14 @@ bool ATHandler::sync(int timeout_ms)
}
tr_debug("AT sync");
lock();
uint32_t timeout = _at_timeout;
_at_timeout = timeout_ms;
auto old_timeout = _at_timeout;
_at_timeout = timeout;
// poll for 10 seconds
for (int i = 0; i < 10; i++) {
// For sync use an AT command that is supported by all modems and likely not used frequently,
// especially a common response like OK could be response to previous request.
clear_error();
_start_time = rtos::Kernel::get_ms_count();
_start_time = rtos::Kernel::Clock::now();
cmd_start("AT+CMEE?");
cmd_stop();
resp_start();
@ -1518,20 +1535,20 @@ bool ATHandler::sync(int timeout_ms)
set_stop_tag(OK);
consume_to_stop_tag();
if (!_last_err) {
_at_timeout = timeout;
_at_timeout = old_timeout;
unlock();
return true;
}
}
tr_error("AT sync failed");
_at_timeout = timeout;
_at_timeout = old_timeout;
unlock();
return false;
}
void ATHandler::set_send_delay(uint16_t send_delay)
{
_at_send_delay = send_delay;
_at_send_delay = std::chrono::duration<uint16_t, std::milli>(send_delay);
}
void ATHandler::write_hex_string(const char *str, size_t size)

View File

@ -18,6 +18,8 @@
#include "CellularLog.h"
#include "ThisThread.h"
using namespace std::chrono_literals;
MBED_WEAK CellularInterface *CellularInterface::get_target_default_instance()
{
return mbed::CellularContext::get_default_instance();
@ -83,7 +85,7 @@ void CellularContext::set_authentication_type(AuthenticationType type)
void CellularContext::validate_ip_address()
{
const int IP_MAX_TRIES = 10; // maximum of 2 seconds as we wait 200ms between tries
const int IP_WAIT_INTERVAL = 200; // 200 ms between retries
const auto IP_WAIT_INTERVAL = 200ms; // 200 ms between retries
SocketAddress ip;
int i = 0;
@ -151,7 +153,7 @@ void CellularContext::do_connect_with_retry()
if (_is_blocking) {
while (_retry_count < _retry_array_length) {
tr_debug("SYNC do_connect failed with %d, retry after %d seconds", _cb_data.error, _retry_timeout_array[_retry_count]);
rtos::ThisThread::sleep_for(_retry_timeout_array[_retry_count] * 1000);
rtos::ThisThread::sleep_for(_retry_timeout_array[_retry_count] * 1s);
do_connect();
if (_cb_data.error == NSAPI_ERROR_OK) {
return;
@ -165,7 +167,7 @@ void CellularContext::do_connect_with_retry()
_cb_data.final_try = true;
}
tr_debug("ASYNC do_connect failed with %d, retry after %d seconds", _cb_data.error, _retry_timeout_array[_retry_count]);
int id = _device->get_queue()->call_in(_retry_timeout_array[_retry_count] * 1000, this, &CellularContext::do_connect_with_retry);
int id = _device->get_queue()->call_in(_retry_timeout_array[_retry_count] * 1s, this, &CellularContext::do_connect_with_retry);
if (id == 0) {
tr_error("Failed call via eventqueue in do_connect_with_retry()");
#if !NSAPI_PPP_AVAILABLE

View File

@ -20,24 +20,26 @@
#include "CellularLog.h"
#include "CellularInformation.h"
using namespace std::chrono_literals;
#ifndef MBED_TRACE_MAX_LEVEL
#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_INFO
#endif
// timeout to wait for AT responses
#define TIMEOUT_POWER_ON (1*1000)
#define TIMEOUT_SIM_PIN (1*1000)
#define TIMEOUT_NETWORK (10*1000)
#define TIMEOUT_POWER_ON 1s
#define TIMEOUT_SIM_PIN 1s
#define TIMEOUT_NETWORK 10s
/** CellularStateMachine does connecting up to packet service attach, and
* after that it's up to CellularContext::connect() to connect to PDN.
* If CellularContext or an application does not set timeout (via `CellularDevice::set_timeout`)
* then TIMEOUT_CONNECT is used also for connecting to PDN and also for socket operations.
*/
#define TIMEOUT_CONNECT (60*1000)
#define TIMEOUT_REGISTRATION (180*1000)
#define TIMEOUT_CONNECT 1min
#define TIMEOUT_REGISTRATION 3min
// maximum time when retrying network register, attach and connect in seconds ( 20minutes )
#define TIMEOUT_NETWORK_MAX (20*60)
#define TIMEOUT_NETWORK_MAX 20min
#define RETRY_COUNT_DEFAULT 3
@ -52,26 +54,26 @@ namespace mbed {
CellularStateMachine::CellularStateMachine(CellularDevice &device, events::EventQueue &queue, CellularNetwork &nw) :
_cellularDevice(device), _state(STATE_INIT), _next_state(_state), _target_state(_state),
_event_status_cb(), _network(nw), _queue(queue), _sim_pin(0), _retry_count(0),
_event_timeout(-1), _event_id(-1), _plmn(0), _command_success(false),
_is_retry(false), _cb_data(), _current_event(CellularDeviceReady), _status(0)
{
#if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0
_start_time = 0;
_start_time(),
#else
// so that not every device don't start at the exact same time (for example after power outage)
_start_time = rand() % (MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY);
_start_time(rand() % (MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY)),
#endif // MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY
_event_timeout(-1s), _event_id(-1), _plmn(0), _command_success(false),
_is_retry(false), _cb_data(), _current_event(CellularDeviceReady), _status(0)
{
// set initial retry values in seconds
_retry_timeout_array[0] = 1; // double time on each retry in order to keep network happy
_retry_timeout_array[1] = 2;
_retry_timeout_array[2] = 4;
_retry_timeout_array[3] = 8;
_retry_timeout_array[4] = 16;
_retry_timeout_array[5] = 32;
_retry_timeout_array[6] = 64;
_retry_timeout_array[7] = 128; // if around two minutes was not enough then let's wait much longer
_retry_timeout_array[8] = 600;
_retry_timeout_array[0] = 1s; // double time on each retry in order to keep network happy
_retry_timeout_array[1] = 2s;
_retry_timeout_array[2] = 4s;
_retry_timeout_array[3] = 8s;
_retry_timeout_array[4] = 16s;
_retry_timeout_array[5] = 32s;
_retry_timeout_array[6] = 64s;
_retry_timeout_array[7] = 128s; // if around two minutes was not enough then let's wait much longer
_retry_timeout_array[8] = 10min;
_retry_timeout_array[9] = TIMEOUT_NETWORK_MAX;
_retry_array_length = CELLULAR_RETRY_ARRAY_SIZE;
@ -91,7 +93,7 @@ CellularStateMachine::~CellularStateMachine()
void CellularStateMachine::reset()
{
_state = STATE_INIT;
_event_timeout = -1;
_event_timeout = -1s;
_event_id = -1;
_is_retry = false;
_status = 0;
@ -310,8 +312,8 @@ void CellularStateMachine::state_init()
_status = _cb_data.error ? 0 : DEVICE_READY;
if (_cb_data.error != NSAPI_ERROR_OK) {
_event_timeout = _start_time;
if (_start_time > 0) {
tr_info("Startup delay %d ms", _start_time);
if (_start_time > 0s) {
tr_info("Startup delay %d s", _start_time.count());
}
enter_to_state(STATE_POWER_ON);
} else {
@ -503,7 +505,7 @@ void CellularStateMachine::continue_from_state(CellularState state)
get_state_string((CellularStateMachine::CellularState)state));
_state = state;
enter_to_state(state);
_event_id = _queue.call_in(0, this, &CellularStateMachine::event);
_event_id = _queue.call(this, &CellularStateMachine::event);
if (!_event_id) {
_event_id = -1;
_cb_data.error = NSAPI_ERROR_NO_MEMORY;
@ -517,7 +519,7 @@ nsapi_error_t CellularStateMachine::run_to_state(CellularStateMachine::CellularS
{
_mutex.lock();
// call pre_event via queue so that it's in same thread and it's safe to decisions
int id = _queue.call_in(0, this, &CellularStateMachine::pre_event, state);
int id = _queue.call(this, &CellularStateMachine::pre_event, state);
if (!id) {
report_failure("Failed to call queue.");
stop();
@ -545,7 +547,7 @@ void CellularStateMachine::pre_event(CellularState state)
_state = _next_state;
}
enter_to_state(_next_state);
_event_id = _queue.call_in(0, this, &CellularStateMachine::event);
_event_id = _queue.call(this, &CellularStateMachine::event);
if (!_event_id) {
_event_id = -1;
report_failure("Failed to call queue.");
@ -586,7 +588,7 @@ void CellularStateMachine::event()
}
}
_event_timeout = -1;
_event_timeout = -1s;
_is_retry = false;
switch (_state) {
@ -628,7 +630,7 @@ void CellularStateMachine::event()
return;
}
if (_next_state != _state || _event_timeout >= 0) {
if (_next_state != _state || _event_timeout >= 0s) {
if (_next_state != _state) { // state exit condition
tr_debug("%s => %s", get_state_string((CellularStateMachine::CellularState)_state),
get_state_string((CellularStateMachine::CellularState)_next_state));
@ -636,10 +638,10 @@ void CellularStateMachine::event()
tr_info("Continue after %d seconds", _event_timeout);
}
_state = _next_state;
if (_event_timeout == -1) {
_event_timeout = 0;
if (_event_timeout == -1s) {
_event_timeout = 0s;
}
_event_id = _queue.call_in(_event_timeout * 1000, callback(this, &CellularStateMachine::event));
_event_id = _queue.call_in(_event_timeout, callback(this, &CellularStateMachine::event));
if (!_event_id) {
_cb_data.error = NSAPI_ERROR_NO_MEMORY;
report_failure("CellularStateMachine event failure!");
@ -670,7 +672,7 @@ void CellularStateMachine::send_event_cb(cellular_connection_status_t status)
}
}
void CellularStateMachine::change_timeout(const int &timeout)
void CellularStateMachine::change_timeout(const std::chrono::duration<int, std::milli> &timeout)
{
_cb_data.status_data = _current_event;
_cb_data.data = &timeout;
@ -746,19 +748,19 @@ void CellularStateMachine::set_retry_timeout_array(const uint16_t timeout[], int
}
_retry_array_length = array_len > CELLULAR_RETRY_ARRAY_SIZE ? CELLULAR_RETRY_ARRAY_SIZE : array_len;
for (int i = 0; i < _retry_array_length; i++) {
_retry_timeout_array[i] = timeout[i];
_retry_timeout_array[i] = std::chrono::duration<uint16_t>(timeout[i]);
}
}
void CellularStateMachine::get_retry_timeout_array(uint16_t *timeout, int &array_len) const
{
for (int i = 0; i < _retry_array_length; i++) {
timeout[i] = _retry_timeout_array[i];
timeout[i] = _retry_timeout_array[i].count();
}
array_len = _retry_array_length;
}
void CellularStateMachine::set_timeout(int timeout)
void CellularStateMachine::set_timeout(std::chrono::duration<int, std::milli> timeout)
{
_state_timeout_power_on = timeout;
_state_timeout_sim_pin = timeout;

View File

@ -138,7 +138,7 @@ public:
*
* @param timeout Timeout value (milliseconds)
*/
void set_timeout(int timeout);
void set_timeout(std::chrono::duration<int, std::milli> timeout);
private:
bool power_on();
@ -164,7 +164,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);
void change_timeout(const std::chrono::duration<int, std::milli> &timeout);
private:
CellularDevice &_cellularDevice;
@ -179,10 +179,10 @@ private:
const char *_sim_pin;
int _retry_count;
int _start_time;
int _event_timeout;
std::chrono::duration<int> _start_time;
std::chrono::duration<int> _event_timeout;
uint16_t _retry_timeout_array[CELLULAR_RETRY_ARRAY_SIZE];
std::chrono::duration<uint16_t> _retry_timeout_array[CELLULAR_RETRY_ARRAY_SIZE];
int _retry_array_length;
int _event_id;
const char *_plmn;
@ -194,11 +194,11 @@ private:
PlatformMutex _mutex;
// Cellular state timeouts
int _state_timeout_power_on;
int _state_timeout_sim_pin;
int _state_timeout_registration;
int _state_timeout_network;
int _state_timeout_connect; // timeout for PS attach, PDN connect and socket operations
std::chrono::duration<int, std::milli> _state_timeout_power_on;
std::chrono::duration<int, std::milli> _state_timeout_sim_pin;
std::chrono::duration<int, std::milli> _state_timeout_registration;
std::chrono::duration<int, std::milli> _state_timeout_network;
std::chrono::duration<int, std::milli> _state_timeout_connect; // timeout for PS attach, PDN connect and socket operations
cell_signal_quality_t _signal_quality;
};

View File

@ -20,9 +20,11 @@
#include "GEMALTO_CINTERION.h"
#include "CellularLog.h"
using namespace std::chrono_literals;
// defines as per ELS61-E2_ATC_V01.000 and BGS2-W_ATC_V00.100
#define UDP_PACKET_SIZE 1460
#define FAILURE_TIMEOUT (30*1000) // failure timeout in milliseconds on modem side
#define FAILURE_TIMEOUT 30s // failure timeout on modem side
using namespace mbed;

View File

@ -23,6 +23,8 @@
#include "QUECTEL_BG96_CellularContext.h"
#include "CellularLog.h"
using std::milli;
using namespace std::chrono;
using namespace mbed;
using namespace events;
using namespace rtos;
@ -134,7 +136,7 @@ nsapi_error_t QUECTEL_BG96::soft_power_off()
if (_at.get_last_error() != NSAPI_ERROR_OK) {
tr_warn("Force modem off");
if (_pwr.is_connected()) {
press_button(_pwr, 650); // BG96_Hardware_Design_V1.1: Power off signal at least 650 ms
press_button(_pwr, 650ms); // BG96_Hardware_Design_V1.1: Power off signal at least 650 ms
}
}
return _at.unlock_return_error();
@ -170,7 +172,7 @@ void QUECTEL_BG96::urc_pdpdeact()
send_disconnect_to_context(cid);
}
void QUECTEL_BG96::press_button(DigitalOut &button, uint32_t timeout)
void QUECTEL_BG96::press_button(DigitalOut &button, duration<uint32_t, milli> timeout)
{
if (!button.is_connected()) {
return;
@ -185,7 +187,7 @@ bool QUECTEL_BG96::wake_up(bool reset)
// check if modem is already ready
_at.lock();
_at.flush();
_at.set_at_timeout(30);
_at.set_at_timeout(30ms);
_at.cmd_start("AT");
_at.cmd_stop_read_resp();
nsapi_error_t err = _at.get_last_error();
@ -196,14 +198,14 @@ bool QUECTEL_BG96::wake_up(bool reset)
if (!reset) {
// BG96_Hardware_Design_V1.1 requires VBAT to be stable over 30 ms, that's handled above
tr_info("Power on modem");
press_button(_pwr, 250); // BG96_Hardware_Design_V1.1 requires time 100 ms, but 250 ms seems to be more robust
press_button(_pwr, 250ms); // BG96_Hardware_Design_V1.1 requires time 100 ms, but 250 ms seems to be more robust
} else {
tr_warn("Reset modem");
press_button(_rst, 150); // BG96_Hardware_Design_V1.1 requires RESET_N timeout at least 150 ms
press_button(_rst, 150ms); // BG96_Hardware_Design_V1.1 requires RESET_N timeout at least 150 ms
}
_at.lock();
// According to BG96_Hardware_Design_V1.1 USB is active after 4.2s, but it seems to take over 5s
_at.set_at_timeout(6000);
_at.set_at_timeout(6s);
_at.resp_start();
_at.set_stop_tag("RDY");
bool rdy = _at.consume_to_stop_tag();

View File

@ -27,6 +27,7 @@
#endif
#endif /* TARGET_FF_ARDUINO */
#include <chrono>
#include "DigitalOut.h"
#include "AT_CellularDevice.h"
@ -49,7 +50,7 @@ public:
void handle_urc(FileHandle *fh);
private:
void press_button(DigitalOut &button, uint32_t timeout);
void press_button(DigitalOut &button, std::chrono::duration<uint32_t, std::milli> timeout);
bool wake_up(bool reset = false);
bool _active_high;
DigitalOut _pwr;

View File

@ -32,6 +32,7 @@ static const int sslctxID = 0;
static const int BG96_ASYNC_DNS_QUERY_ID = 1; // BG96 driver only supports one request, so using id 1
using namespace mbed;
using namespace std::chrono_literals;
QUECTEL_BG96_CellularStack::QUECTEL_BG96_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
AT_CellularStack(atHandler, cid, stack_type, device)
@ -465,7 +466,7 @@ nsapi_error_t QUECTEL_BG96_CellularStack::gethostbyname(const char *host, Socket
}
if (!address->set_ip_address(host)) {
_at.set_at_timeout(60 * 1000); // from BG96_TCP/IP_AT_Commands_Manual_V1.0
_at.set_at_timeout(1min); // from BG96_TCP/IP_AT_Commands_Manual_V1.0
_at.at_cmd_discard("+QIDNSGIP", "=", "%d%s", _cid, host);
_at.resp_start("+QIURC: \"dnsgip\",");
_at.restore_at_timeout();

View File

@ -22,8 +22,8 @@
namespace mbed {
#define BG96_CREATE_SOCKET_TIMEOUT 150000 //150 seconds
#define BG96_CLOSE_SOCKET_TIMEOUT 20000 // TCP socket max timeout is >10sec
#define BG96_CREATE_SOCKET_TIMEOUT 150s
#define BG96_CLOSE_SOCKET_TIMEOUT 20s // TCP socket max timeout is >10sec
#define BG96_MAX_RECV_SIZE 1500
#define BG96_MAX_SEND_SIZE 1460
#define BG96_SOCKET_BIND_FAIL 556

View File

@ -22,6 +22,7 @@
#include "rtos/ThisThread.h"
#include "drivers/BufferedSerial.h"
using namespace std::chrono;
using namespace mbed;
using namespace rtos;
using namespace events;
@ -100,13 +101,13 @@ CellularDevice *CellularDevice::get_default_instance()
}
#endif
nsapi_error_t QUECTEL_EC2X::press_power_button(uint32_t timeout)
nsapi_error_t QUECTEL_EC2X::press_power_button(duration<uint32_t, std::milli> timeout)
{
if (_pwr_key.is_connected()) {
_pwr_key = _active_high;
ThisThread::sleep_for(timeout);
_pwr_key = !_active_high;
ThisThread::sleep_for(100);
ThisThread::sleep_for(100ms);
}
return NSAPI_ERROR_OK;
@ -114,26 +115,26 @@ nsapi_error_t QUECTEL_EC2X::press_power_button(uint32_t timeout)
nsapi_error_t QUECTEL_EC2X::hard_power_on()
{
return press_power_button(600);
return press_power_button(600ms);
}
nsapi_error_t QUECTEL_EC2X::hard_power_off()
{
return press_power_button(750);
return press_power_button(750ms);
}
nsapi_error_t QUECTEL_EC2X::soft_power_on()
{
if (_rst.is_connected()) {
_rst = _active_high;
ThisThread::sleep_for(460);
ThisThread::sleep_for(460ms);
_rst = !_active_high;
ThisThread::sleep_for(100);
ThisThread::sleep_for(100ms);
_at.lock();
_at.set_at_timeout(MBED_CONF_QUECTEL_EC2X_START_TIMEOUT);
_at.set_at_timeout(milliseconds(MBED_CONF_QUECTEL_EC2X_START_TIMEOUT));
_at.resp_start();
_at.set_stop_tag("RDY");
bool rdy = _at.consume_to_stop_tag();

View File

@ -18,6 +18,7 @@
#ifndef QUECTEL_EC2X_H
#define QUECTEL_EC2X_H
#include <chrono>
#include "DigitalOut.h"
#include "AT_CellularDevice.h"
@ -39,7 +40,7 @@ public:
virtual nsapi_error_t soft_power_off();
private:
nsapi_error_t press_power_button(uint32_t timeout);
nsapi_error_t press_power_button(std::chrono::duration<uint32_t, std::milli> timeout);
bool _active_high;
DigitalOut _pwr_key;
DigitalOut _rst;

View File

@ -19,8 +19,10 @@
#include "QUECTEL/M26/QUECTEL_M26_CellularStack.h"
#include "CellularLog.h"
#define SOCKET_SEND_READY_TIMEOUT (30*1000)
#define SOCKET_READ_TIMEOUT 1000
using namespace std::chrono;
#define SOCKET_SEND_READY_TIMEOUT 30s
#define SOCKET_READ_TIMEOUT 1s
using namespace mbed;
@ -402,8 +404,8 @@ nsapi_size_or_error_t QUECTEL_M26_CellularStack::socket_sendto_impl(CellularSock
if (socket->proto == NSAPI_TCP) {
bool ready_to_send = false;
uint64_t start_time = rtos::Kernel::get_ms_count();
while (!ready_to_send && start_time < rtos::Kernel::get_ms_count() + SOCKET_SEND_READY_TIMEOUT) {
auto start_time = rtos::Kernel::Clock::now() ;
while (!ready_to_send && rtos::Kernel::Clock::now() < start_time + SOCKET_SEND_READY_TIMEOUT) {
_at.cmd_start_stop("+QISACK", "=", "%d", socket->id);
_at.resp_start("+QISACK:");
sent_len_before = _at.read_int();
@ -485,7 +487,7 @@ nsapi_size_or_error_t QUECTEL_M26_CellularStack::socket_recvfrom_impl(CellularSo
tr_debug("QUECTEL_M26_CellularStack:%s:%u:[%d]", __FUNCTION__, __LINE__, size);
uint64_t start_time = rtos::Kernel::get_ms_count();
auto start_time = rtos::Kernel::Clock::now();
nsapi_size_t len = 0;
for (; len < size;) {
unsigned int read_len = (size - len > M26_RECV_BYTE_MAX) ? M26_RECV_BYTE_MAX : size - len;
@ -511,7 +513,7 @@ nsapi_size_or_error_t QUECTEL_M26_CellularStack::socket_recvfrom_impl(CellularSo
return NSAPI_ERROR_DEVICE_ERROR;
}
if (rtos::Kernel::get_ms_count() > start_time + SOCKET_READ_TIMEOUT) {
if (rtos::Kernel::Clock::now() > start_time + SOCKET_READ_TIMEOUT) {
tr_warn("QUECTEL_M26_CellularStack:%s:%u:[ERROR NSAPI_ERROR_TIMEOUT]", __FUNCTION__, __LINE__);
return NSAPI_ERROR_TIMEOUT;
}

View File

@ -20,9 +20,11 @@
#include "AT_CellularStack.h"
using namespace std::chrono_literals;
namespace mbed {
#define M26_CREATE_SOCKET_TIMEOUT 75000 //75 seconds
#define M26_CREATE_SOCKET_TIMEOUT 75s
#define M26_SENT_BYTE_MAX 1460
#define M26_RECV_BYTE_MAX 1024

View File

@ -27,6 +27,7 @@
using namespace mbed;
using namespace events;
using namespace std::chrono_literals;
static const uint16_t retry_timeout[] = {1, 2, 4};
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
AT_CellularNetwork::RegistrationModeLAC,// C_EREG
@ -80,7 +81,7 @@ nsapi_error_t RM1000_AT::init()
_at.at_cmd_discard("+SIM", "=physical");
_at.set_at_timeout(5000);
_at.set_at_timeout(5s);
_at.at_cmd_discard("+CFUN", "=1"); // set full functionality
_at.at_cmd_discard("+VERBOSE", "=0"); // verbose responses

View File

@ -26,6 +26,7 @@
using namespace mbed;
using namespace mbed_cellular_util;
using namespace std::chrono_literals;
RM1000_AT_CellularStack::RM1000_AT_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
AT_CellularStack(atHandler, cid, stack_type, device)
@ -327,7 +328,7 @@ nsapi_error_t RM1000_AT_CellularStack::gethostbyname(const char *host, SocketAdd
_at.write_string(host, false);
_at.cmd_stop();
_at.set_at_timeout(70000);
_at.set_at_timeout(70s);
_at.resp_start("+RDNS:");
if (_at.info_resp()) {
_at.read_string(ipAddress, sizeof(ipAddress));

View File

@ -22,6 +22,7 @@
#include "PinNames.h"
#include "rtos/ThisThread.h"
using namespace std::chrono_literals;
using namespace mbed;
using namespace rtos;
using namespace events;
@ -163,11 +164,11 @@ nsapi_error_t TELIT_ME910::hard_power_on()
nsapi_error_t TELIT_ME910::soft_power_on()
{
_pwr_key = _active_high;
ThisThread::sleep_for(500);
ThisThread::sleep_for(500ms);
_pwr_key = !_active_high;
ThisThread::sleep_for(5000);
ThisThread::sleep_for(5s);
_pwr_key = _active_high;
ThisThread::sleep_for(5000);
ThisThread::sleep_for(5s);
return NSAPI_ERROR_OK;
}
@ -175,7 +176,7 @@ nsapi_error_t TELIT_ME910::soft_power_on()
nsapi_error_t TELIT_ME910::hard_power_off()
{
_pwr_key = !_active_high;
ThisThread::sleep_for(10000);
ThisThread::sleep_for(10s);
return NSAPI_ERROR_OK;
}

View File

@ -20,6 +20,8 @@
#include "CellularLog.h"
#include "rtos/ThisThread.h"
using namespace std::chrono_literals;
namespace mbed {
UBLOX_AT_CellularContext::UBLOX_AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
@ -69,7 +71,7 @@ void UBLOX_AT_CellularContext::do_connect()
CellularNetwork::RadioAccessTechnology rat = read_radio_technology();
if (rat == CellularNetwork::RadioAccessTechnology::RAT_EGPRS) {
if (!_is_context_active) {
_at.set_at_timeout(150 * 1000);
_at.set_at_timeout(150s);
_at.at_cmd_discard("+CGACT", "=", "%d%d", 1, 1);
_at.cmd_start_stop("+CGACT", "?");
@ -208,16 +210,15 @@ bool UBLOX_AT_CellularContext::activate_profile(const char *apn,
if (_at.at_cmd_discard("+UPSD", "=", "%d%d%d", PROFILE, 6, nsapi_security_to_modem_security(auth)) == NSAPI_ERROR_OK) {
// Activate, wait upto 30 seconds for the connection to be made
_at.set_at_timeout(30000);
_at.set_at_timeout(30s);
nsapi_error_t err = _at.at_cmd_discard("+UPSDA", "=", "%d%d", PROFILE, 3);
_at.restore_at_timeout();
if (err == NSAPI_ERROR_OK) {
Timer t1;
t1.start();
while (!(t1.read() >= 180)) {
auto end_time = rtos::Kernel::Clock::now() + 3min;
do {
_at.lock();
_at.cmd_start_stop("+UPSND", "=", "%d%d", PROFILE, 8);
_at.resp_start("+UPSND:");
@ -229,9 +230,8 @@ bool UBLOX_AT_CellularContext::activate_profile(const char *apn,
if (activated) { //If context is activated, exit while loop and return status
break;
}
rtos::ThisThread::sleep_for(5000); //Wait for 5 seconds and then try again
}
t1.stop();
rtos::ThisThread::sleep_for(5s); //Wait for 5 seconds and then try again
} while (rtos::Kernel::Clock::now() < end_time);
}
}
}

View File

@ -18,6 +18,7 @@
#include "UBLOX_AT_CellularNetwork.h"
#include "rtos/ThisThread.h"
using namespace std::chrono_literals;
using namespace mbed;
UBLOX_AT_CellularNetwork::UBLOX_AT_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device) : AT_CellularNetwork(atHandler, device)
@ -94,7 +95,7 @@ nsapi_error_t UBLOX_AT_CellularNetwork::ubx_reboot()
} else {
//Don't clear err here so that we get some error in case of failure
_at.clear_error();
rtos::ThisThread::sleep_for(1000);
rtos::ThisThread::sleep_for(1s);
}
}
t1.stop();

View File

@ -20,6 +20,7 @@
using namespace mbed;
using namespace mbed_cellular_util;
using namespace std::chrono_literals;
UBLOX_AT_CellularStack::UBLOX_AT_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
AT_CellularStack(atHandler, cid, stack_type, device)
@ -454,9 +455,9 @@ nsapi_error_t UBLOX_AT_CellularStack::gethostbyname(const char *host, SocketAddr
err = NSAPI_ERROR_OK;
} else {
#ifdef UBX_MDM_SARA_R41XM
_at.set_at_timeout(70000);
_at.set_at_timeout(70s);
#else
_at.set_at_timeout(120000);
_at.set_at_timeout(120s);
#endif
// This interrogation can sometimes take longer than the usual 8 seconds
_at.cmd_start_stop("+UDNSRN", "=0,", "%s", host);

View File

@ -10,7 +10,7 @@
"value": false
},
"random_max_start_delay": {
"help": "Maximum random delay value used in start-up sequence in milliseconds",
"help": "Maximum random delay value used in start-up sequence in seconds",
"value": 0
},
"debug-at": {