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