mirror of https://github.com/ARMmbed/mbed-os.git
Cellular: Move PSM setting from power to device
parent
36292a4f14
commit
38f79a9b65
|
|
@ -232,6 +232,34 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_modem_debug_on)
|
|||
dev.close_sms();
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_set_power_save_mode)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(0, 0));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(10, 0));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(912, 0));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(1834, 1834));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(18345, 18345));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(101234, 101234));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(1012345, 1012345));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.set_power_save_mode(39612345, 39612345));
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
|
||||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == dev.set_power_save_mode(0));
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_send_delay)
|
||||
{
|
||||
FileHandle_stub fh1;
|
||||
|
|
|
|||
|
|
@ -123,34 +123,6 @@ TEST_F(TestAT_CellularPower, test_AT_CellularPower_reset)
|
|||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == pow.reset());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularPower, test_AT_CellularPower_opt_power_save_mode)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularPower pow(at);
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(0, 0));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(10, 0));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(912, 0));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(1834, 1834));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(18345, 18345));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(101234, 101234));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(1012345, 1012345));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == pow.opt_power_save_mode(39612345, 39612345));
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
|
||||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == pow.opt_power_save_mode(0, 0));
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularPower, test_AT_CellularPower_is_device_ready)
|
||||
{
|
||||
EventQueue que;
|
||||
|
|
|
|||
|
|
@ -151,6 +151,11 @@ void AT_CellularDevice::modem_debug_on(bool on)
|
|||
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularDevice::set_power_save_mode(int periodic_time, int active_time)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularDevice::init_module()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
|
|
|
|||
|
|
@ -55,11 +55,6 @@ nsapi_error_t AT_CellularPower::reset()
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int active_time)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularPower::set_device_ready_urc_cb(mbed::Callback<void()> callback)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,11 @@ public:
|
|||
|
||||
virtual void modem_debug_on(bool on) {}
|
||||
|
||||
nsapi_error_t set_power_save_mode(int periodic_time, int active_time)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
virtual nsapi_error_t init_module()
|
||||
{
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -87,16 +87,6 @@ static void test_power_interface()
|
|||
TEST_ASSERT(err == NSAPI_ERROR_OK);
|
||||
wait_for_power(pwr);
|
||||
|
||||
wait(1);
|
||||
err = pwr->opt_power_save_mode(0, 0);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
|
||||
if (err == NSAPI_ERROR_DEVICE_ERROR) {
|
||||
if (!(strcmp(devi, "TELIT_HE910") == 0 || strcmp(devi, "QUECTEL_BG96") == 0)) { // TELIT_HE910 and QUECTEL_BG96 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command
|
||||
TEST_ASSERT(((AT_CellularPower *)pwr)->get_device_error().errCode == 100 && // 100 == unknown command for modem
|
||||
((AT_CellularPower *)pwr)->get_device_error().errType == 3); // 3 == CME error from the modem
|
||||
}
|
||||
}
|
||||
|
||||
err = pwr->off();
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#ifndef CELLULAR_DEVICE_H_
|
||||
#define CELLULAR_DEVICE_H_
|
||||
|
||||
#include "CellularUtil.h"
|
||||
#include "CellularTargets.h"
|
||||
#include "CellularStateMachine.h"
|
||||
#include "Callback.h"
|
||||
|
|
@ -249,6 +250,18 @@ public:
|
|||
*/
|
||||
virtual void modem_debug_on(bool on) = 0;
|
||||
|
||||
/** Set power save mode
|
||||
*
|
||||
* @remark See 3GPP TS 27.007 PSM for details
|
||||
*
|
||||
* @param periodic_time in seconds to enable power save, or zero to disable
|
||||
* @param active_time in seconds to wait before entering power save mode
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_DEVICE_ERROR on failure
|
||||
*/
|
||||
virtual nsapi_error_t set_power_save_mode(int periodic_time, int active_time = 0) = 0;
|
||||
|
||||
/** Initialize cellular module must be called right after module is ready.
|
||||
* For example, when multiple modules are supported in a single AT driver this function detects
|
||||
* and adapts to an actual module at runtime.
|
||||
|
|
|
|||
|
|
@ -93,18 +93,6 @@ public:
|
|||
*/
|
||||
virtual nsapi_error_t reset() = 0;
|
||||
|
||||
/** Opt for power save setting on cellular device. If both parameters are zero, this disables PSM.
|
||||
*
|
||||
* @remark See 3GPP TS 27.007 PSM for details
|
||||
*
|
||||
* @param periodic_time Timeout in seconds IoT subsystem is not expecting messaging
|
||||
* @param active_time Timeout in seconds IoT subsystem waits for response
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_DEVICE_ERROR on failure
|
||||
*/
|
||||
virtual nsapi_error_t opt_power_save_mode(int periodic_time, int active_time) = 0;
|
||||
|
||||
/** Check whether the device is ready to accept commands.
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "UARTSerial.h"
|
||||
#include "FileHandle.h"
|
||||
|
||||
using namespace mbed_cellular_util;
|
||||
using namespace events;
|
||||
using namespace mbed;
|
||||
|
||||
|
|
@ -365,6 +366,134 @@ void AT_CellularDevice::modem_debug_on(bool on)
|
|||
ATHandler::set_debug_list(_modem_debug_on);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularDevice::set_power_save_mode(int periodic_time, int active_time)
|
||||
{
|
||||
_at->lock();
|
||||
|
||||
if (periodic_time == 0 && active_time == 0) {
|
||||
// disable PSM
|
||||
_at->cmd_start("AT+CPSMS=");
|
||||
_at->write_int(0);
|
||||
_at->cmd_stop_read_resp();
|
||||
} else {
|
||||
const int PSMTimerBits = 5;
|
||||
|
||||
/**
|
||||
Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element
|
||||
|
||||
Bits 5 to 1 represent the binary coded timer value.
|
||||
|
||||
Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
|
||||
8 7 6
|
||||
0 0 0 value is incremented in multiples of 10 minutes
|
||||
0 0 1 value is incremented in multiples of 1 hour
|
||||
0 1 0 value is incremented in multiples of 10 hours
|
||||
0 1 1 value is incremented in multiples of 2 seconds
|
||||
1 0 0 value is incremented in multiples of 30 seconds
|
||||
1 0 1 value is incremented in multiples of 1 minute
|
||||
1 1 0 value is incremented in multiples of 320 hours (NOTE 1)
|
||||
1 1 1 value indicates that the timer is deactivated (NOTE 2).
|
||||
*/
|
||||
char pt[8 + 1]; // timer value encoded as 3GPP IE
|
||||
const int ie_value_max = 0x1f;
|
||||
uint32_t periodic_timer = 0;
|
||||
if (periodic_time <= 2 * ie_value_max) { // multiples of 2 seconds
|
||||
periodic_timer = periodic_time / 2;
|
||||
strcpy(pt, "01100000");
|
||||
} else {
|
||||
if (periodic_time <= 30 * ie_value_max) { // multiples of 30 seconds
|
||||
periodic_timer = periodic_time / 30;
|
||||
strcpy(pt, "10000000");
|
||||
} else {
|
||||
if (periodic_time <= 60 * ie_value_max) { // multiples of 1 minute
|
||||
periodic_timer = periodic_time / 60;
|
||||
strcpy(pt, "10100000");
|
||||
} else {
|
||||
if (periodic_time <= 10 * 60 * ie_value_max) { // multiples of 10 minutes
|
||||
periodic_timer = periodic_time / (10 * 60);
|
||||
strcpy(pt, "00000000");
|
||||
} else {
|
||||
if (periodic_time <= 60 * 60 * ie_value_max) { // multiples of 1 hour
|
||||
periodic_timer = periodic_time / (60 * 60);
|
||||
strcpy(pt, "00100000");
|
||||
} else {
|
||||
if (periodic_time <= 10 * 60 * 60 * ie_value_max) { // multiples of 10 hours
|
||||
periodic_timer = periodic_time / (10 * 60 * 60);
|
||||
strcpy(pt, "01000000");
|
||||
} else { // multiples of 320 hours
|
||||
int t = periodic_time / (320 * 60 * 60);
|
||||
if (t > ie_value_max) {
|
||||
t = ie_value_max;
|
||||
}
|
||||
periodic_timer = t;
|
||||
strcpy(pt, "11000000");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt) - 3, PSMTimerBits);
|
||||
pt[8] = '\0';
|
||||
|
||||
/**
|
||||
Table 10.5.172/3GPP TS 24.008: GPRS Timer information element
|
||||
|
||||
Bits 5 to 1 represent the binary coded timer value.
|
||||
|
||||
Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
|
||||
|
||||
8 7 6
|
||||
0 0 0 value is incremented in multiples of 2 seconds
|
||||
0 0 1 value is incremented in multiples of 1 minute
|
||||
0 1 0 value is incremented in multiples of decihours
|
||||
1 1 1 value indicates that the timer is deactivated.
|
||||
|
||||
Other values shall be interpreted as multiples of 1 minute in this version of the protocol.
|
||||
*/
|
||||
char at[8 + 1];
|
||||
uint32_t active_timer; // timer value encoded as 3GPP IE
|
||||
if (active_time <= 2 * ie_value_max) { // multiples of 2 seconds
|
||||
active_timer = active_time / 2;
|
||||
strcpy(at, "00000000");
|
||||
} else {
|
||||
if (active_time <= 60 * ie_value_max) { // multiples of 1 minute
|
||||
active_timer = (1 << 5) | (active_time / 60);
|
||||
strcpy(at, "00100000");
|
||||
} else { // multiples of decihours
|
||||
int t = active_time / (6 * 60);
|
||||
if (t > ie_value_max) {
|
||||
t = ie_value_max;
|
||||
}
|
||||
active_timer = t;
|
||||
strcpy(at, "01000000");
|
||||
}
|
||||
}
|
||||
|
||||
uint_to_binary_str(active_timer, &at[3], sizeof(at) - 3, PSMTimerBits);
|
||||
at[8] = '\0';
|
||||
|
||||
// request for both GPRS and LTE
|
||||
_at->cmd_start("AT+CPSMS=");
|
||||
_at->write_int(1);
|
||||
_at->write_string(pt);
|
||||
_at->write_string(at);
|
||||
_at->write_string(pt);
|
||||
_at->write_string(at);
|
||||
_at->cmd_stop_read_resp();
|
||||
|
||||
if (_at->get_last_error() != NSAPI_ERROR_OK) {
|
||||
tr_warn("Power save mode not enabled!");
|
||||
} else {
|
||||
// network may not agree with power save options but
|
||||
// that should be fine as timeout is not longer than requested
|
||||
}
|
||||
}
|
||||
|
||||
return _at->unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularDevice::init_module()
|
||||
{
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ public:
|
|||
|
||||
virtual void modem_debug_on(bool on);
|
||||
|
||||
virtual nsapi_error_t set_power_save_mode(int periodic_time, int active_time = 0);
|
||||
|
||||
virtual nsapi_error_t init_module();
|
||||
|
||||
virtual ATHandler *get_at_handler(FileHandle *fh);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@
|
|||
#include "CellularTargets.h"
|
||||
#include "nsapi_types.h"
|
||||
|
||||
static const int PSMTimerBits = 5;
|
||||
|
||||
using namespace mbed_cellular_util;
|
||||
using namespace mbed;
|
||||
|
||||
|
|
@ -76,132 +74,6 @@ nsapi_error_t AT_CellularPower::reset()
|
|||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int active_time)
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
if (periodic_time == 0 && active_time == 0) {
|
||||
// disable PSM
|
||||
_at.cmd_start("AT+CPSMS=");
|
||||
_at.write_int(0);
|
||||
_at.cmd_stop_read_resp();
|
||||
} else {
|
||||
/**
|
||||
Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element
|
||||
|
||||
Bits 5 to 1 represent the binary coded timer value.
|
||||
|
||||
Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
|
||||
8 7 6
|
||||
0 0 0 value is incremented in multiples of 10 minutes
|
||||
0 0 1 value is incremented in multiples of 1 hour
|
||||
0 1 0 value is incremented in multiples of 10 hours
|
||||
0 1 1 value is incremented in multiples of 2 seconds
|
||||
1 0 0 value is incremented in multiples of 30 seconds
|
||||
1 0 1 value is incremented in multiples of 1 minute
|
||||
1 1 0 value is incremented in multiples of 320 hours (NOTE 1)
|
||||
1 1 1 value indicates that the timer is deactivated (NOTE 2).
|
||||
*/
|
||||
char pt[8 + 1]; // timer value encoded as 3GPP IE
|
||||
const int ie_value_max = 0x1f;
|
||||
uint32_t periodic_timer = 0;
|
||||
if (periodic_time <= 2 * ie_value_max) { // multiples of 2 seconds
|
||||
periodic_timer = periodic_time / 2;
|
||||
strcpy(pt, "01100000");
|
||||
} else {
|
||||
if (periodic_time <= 30 * ie_value_max) { // multiples of 30 seconds
|
||||
periodic_timer = periodic_time / 30;
|
||||
strcpy(pt, "10000000");
|
||||
} else {
|
||||
if (periodic_time <= 60 * ie_value_max) { // multiples of 1 minute
|
||||
periodic_timer = periodic_time / 60;
|
||||
strcpy(pt, "10100000");
|
||||
} else {
|
||||
if (periodic_time <= 10 * 60 * ie_value_max) { // multiples of 10 minutes
|
||||
periodic_timer = periodic_time / (10 * 60);
|
||||
strcpy(pt, "00000000");
|
||||
} else {
|
||||
if (periodic_time <= 60 * 60 * ie_value_max) { // multiples of 1 hour
|
||||
periodic_timer = periodic_time / (60 * 60);
|
||||
strcpy(pt, "00100000");
|
||||
} else {
|
||||
if (periodic_time <= 10 * 60 * 60 * ie_value_max) { // multiples of 10 hours
|
||||
periodic_timer = periodic_time / (10 * 60 * 60);
|
||||
strcpy(pt, "01000000");
|
||||
} else { // multiples of 320 hours
|
||||
int t = periodic_time / (320 * 60 * 60);
|
||||
if (t > ie_value_max) {
|
||||
t = ie_value_max;
|
||||
}
|
||||
periodic_timer = t;
|
||||
strcpy(pt, "11000000");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt) - 3, PSMTimerBits);
|
||||
pt[8] = '\0';
|
||||
|
||||
/**
|
||||
Table 10.5.172/3GPP TS 24.008: GPRS Timer information element
|
||||
|
||||
Bits 5 to 1 represent the binary coded timer value.
|
||||
|
||||
Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
|
||||
|
||||
8 7 6
|
||||
0 0 0 value is incremented in multiples of 2 seconds
|
||||
0 0 1 value is incremented in multiples of 1 minute
|
||||
0 1 0 value is incremented in multiples of decihours
|
||||
1 1 1 value indicates that the timer is deactivated.
|
||||
|
||||
Other values shall be interpreted as multiples of 1 minute in this version of the protocol.
|
||||
*/
|
||||
char at[8 + 1];
|
||||
uint32_t active_timer; // timer value encoded as 3GPP IE
|
||||
if (active_time <= 2 * ie_value_max) { // multiples of 2 seconds
|
||||
active_timer = active_time / 2;
|
||||
strcpy(at, "00000000");
|
||||
} else {
|
||||
if (active_time <= 60 * ie_value_max) { // multiples of 1 minute
|
||||
active_timer = (1 << 5) | (active_time / 60);
|
||||
strcpy(at, "00100000");
|
||||
} else { // multiples of decihours
|
||||
int t = active_time / (6 * 60);
|
||||
if (t > ie_value_max) {
|
||||
t = ie_value_max;
|
||||
}
|
||||
active_timer = t;
|
||||
strcpy(at, "01000000");
|
||||
}
|
||||
}
|
||||
|
||||
uint_to_binary_str(active_timer, &at[3], sizeof(at) - 3, PSMTimerBits);
|
||||
at[8] = '\0';
|
||||
|
||||
// request for both GPRS and LTE
|
||||
_at.cmd_start("AT+CPSMS=");
|
||||
_at.write_int(1);
|
||||
_at.write_string(pt);
|
||||
_at.write_string(at);
|
||||
_at.write_string(pt);
|
||||
_at.write_string(at);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
tr_warn("Power save mode not enabled!");
|
||||
} else {
|
||||
// network may not agree with power save options but
|
||||
// that should be fine as timeout is not longer than requested
|
||||
}
|
||||
}
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularPower::is_device_ready()
|
||||
{
|
||||
_at.lock();
|
||||
|
|
|
|||
|
|
@ -44,8 +44,6 @@ public:
|
|||
|
||||
virtual nsapi_error_t reset();
|
||||
|
||||
virtual nsapi_error_t opt_power_save_mode(int periodic_time, int active_time);
|
||||
|
||||
virtual nsapi_error_t is_device_ready();
|
||||
|
||||
virtual nsapi_error_t set_device_ready_urc_cb(mbed::Callback<void()> callback);
|
||||
|
|
|
|||
Loading…
Reference in New Issue