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();
 | 
					    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)
 | 
					TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_send_delay)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    FileHandle_stub fh1;
 | 
					    FileHandle_stub fh1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,34 +123,6 @@ TEST_F(TestAT_CellularPower, test_AT_CellularPower_reset)
 | 
				
			||||||
    EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == pow.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)
 | 
					TEST_F(TestAT_CellularPower, test_AT_CellularPower_is_device_ready)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EventQueue que;
 | 
					    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()
 | 
					nsapi_error_t AT_CellularDevice::init_module()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return NSAPI_ERROR_OK;
 | 
					    return NSAPI_ERROR_OK;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,11 +55,6 @@ nsapi_error_t AT_CellularPower::reset()
 | 
				
			||||||
    return NSAPI_ERROR_OK;
 | 
					    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)
 | 
					nsapi_error_t AT_CellularPower::set_device_ready_urc_cb(mbed::Callback<void()> callback)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return NSAPI_ERROR_OK;
 | 
					    return NSAPI_ERROR_OK;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,6 +109,11 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual void modem_debug_on(bool on) {}
 | 
					    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()
 | 
					    virtual nsapi_error_t init_module()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,16 +87,6 @@ static void test_power_interface()
 | 
				
			||||||
    TEST_ASSERT(err == NSAPI_ERROR_OK);
 | 
					    TEST_ASSERT(err == NSAPI_ERROR_OK);
 | 
				
			||||||
    wait_for_power(pwr);
 | 
					    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();
 | 
					    err = pwr->off();
 | 
				
			||||||
    TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
 | 
					    TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@
 | 
				
			||||||
#ifndef CELLULAR_DEVICE_H_
 | 
					#ifndef CELLULAR_DEVICE_H_
 | 
				
			||||||
#define CELLULAR_DEVICE_H_
 | 
					#define CELLULAR_DEVICE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "CellularUtil.h"
 | 
				
			||||||
#include "CellularTargets.h"
 | 
					#include "CellularTargets.h"
 | 
				
			||||||
#include "CellularStateMachine.h"
 | 
					#include "CellularStateMachine.h"
 | 
				
			||||||
#include "Callback.h"
 | 
					#include "Callback.h"
 | 
				
			||||||
| 
						 | 
					@ -249,6 +250,18 @@ public:
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    virtual void modem_debug_on(bool on) = 0;
 | 
					    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.
 | 
					    /** 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
 | 
					     *  For example, when multiple modules are supported in a single AT driver this function detects
 | 
				
			||||||
     *  and adapts to an actual module at runtime.
 | 
					     *  and adapts to an actual module at runtime.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,18 +93,6 @@ public:
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    virtual nsapi_error_t reset() = 0;
 | 
					    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.
 | 
					    /** Check whether the device is ready to accept commands.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     *  @return         NSAPI_ERROR_OK on success
 | 
					     *  @return         NSAPI_ERROR_OK on success
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@
 | 
				
			||||||
#include "UARTSerial.h"
 | 
					#include "UARTSerial.h"
 | 
				
			||||||
#include "FileHandle.h"
 | 
					#include "FileHandle.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace mbed_cellular_util;
 | 
				
			||||||
using namespace events;
 | 
					using namespace events;
 | 
				
			||||||
using namespace mbed;
 | 
					using namespace mbed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -365,6 +366,134 @@ void AT_CellularDevice::modem_debug_on(bool on)
 | 
				
			||||||
    ATHandler::set_debug_list(_modem_debug_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()
 | 
					nsapi_error_t AT_CellularDevice::init_module()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if MBED_CONF_MBED_TRACE_ENABLE
 | 
					#if MBED_CONF_MBED_TRACE_ENABLE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,6 +70,8 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual void modem_debug_on(bool on);
 | 
					    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 nsapi_error_t init_module();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual ATHandler *get_at_handler(FileHandle *fh);
 | 
					    virtual ATHandler *get_at_handler(FileHandle *fh);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,8 +21,6 @@
 | 
				
			||||||
#include "CellularTargets.h"
 | 
					#include "CellularTargets.h"
 | 
				
			||||||
#include "nsapi_types.h"
 | 
					#include "nsapi_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const int PSMTimerBits = 5;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace mbed_cellular_util;
 | 
					using namespace mbed_cellular_util;
 | 
				
			||||||
using namespace mbed;
 | 
					using namespace mbed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -76,132 +74,6 @@ nsapi_error_t AT_CellularPower::reset()
 | 
				
			||||||
    return _at.unlock_return_error();
 | 
					    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()
 | 
					nsapi_error_t AT_CellularPower::is_device_ready()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _at.lock();
 | 
					    _at.lock();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,8 +44,6 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual nsapi_error_t reset();
 | 
					    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 is_device_ready();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual nsapi_error_t set_device_ready_urc_cb(mbed::Callback<void()> callback);
 | 
					    virtual nsapi_error_t set_device_ready_urc_cb(mbed::Callback<void()> callback);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue