Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AT_CellularPower.cpp Source File

AT_CellularPower.cpp

00001 /*
00002  * Copyright (c) 2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "AT_CellularPower.h"
00019 #include "CellularUtil.h"
00020 #include "CellularLog.h"
00021 #include "nsapi_types.h"
00022 
00023 static const int PSMTimerBits = 5;
00024 
00025 using namespace mbed_cellular_util;
00026 using namespace mbed;
00027 
00028 AT_CellularPower::AT_CellularPower(ATHandler &at) : AT_CellularBase(at)
00029 {
00030 }
00031 
00032 AT_CellularPower::~AT_CellularPower()
00033 {
00034 }
00035 
00036 nsapi_error_t AT_CellularPower::on()
00037 {
00038     return NSAPI_ERROR_UNSUPPORTED ;
00039 }
00040 
00041 nsapi_error_t AT_CellularPower::off()
00042 {
00043     return NSAPI_ERROR_UNSUPPORTED ;
00044 }
00045 
00046 nsapi_error_t AT_CellularPower::set_at_mode()
00047 {
00048     _at.lock();
00049     _at.flush();
00050     _at.cmd_start("ATE0"); // echo off
00051     _at.cmd_stop();
00052     _at.resp_start();
00053     _at.resp_stop();
00054 
00055     _at.cmd_start("AT+CMEE=1"); // verbose responses
00056     _at.cmd_stop();
00057     _at.resp_start();
00058     _at.resp_stop();
00059     return _at.unlock_return_error();
00060 }
00061 
00062 nsapi_error_t AT_CellularPower::set_power_level(int func_level)
00063 {
00064     _at.lock();
00065     _at.cmd_start("AT+CFUN=");
00066     _at.write_int(func_level);
00067     _at.cmd_stop();
00068     _at.resp_start();
00069     _at.resp_stop();
00070     return _at.unlock_return_error();
00071 }
00072 
00073 nsapi_error_t AT_CellularPower::reset()
00074 {
00075     _at.lock();
00076     _at.cmd_start("AT+CFUN=");// reset to full power levels
00077     _at.write_int(1);
00078     _at.write_int(1);
00079     _at.cmd_stop();
00080     _at.resp_start();
00081     _at.resp_stop();
00082     return _at.unlock_return_error();
00083 }
00084 
00085 nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int active_time)
00086 {
00087     _at.lock();
00088 
00089     if (periodic_time == 0 && active_time == 0) {
00090         // disable PSM
00091         _at.cmd_start("AT+CPSMS=");
00092         _at.write_int(0);
00093         _at.cmd_stop();
00094         _at.resp_start();
00095         _at.resp_stop();
00096     } else {
00097         /**
00098             Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element
00099 
00100             Bits 5 to 1 represent the binary coded timer value.
00101 
00102             Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
00103             8 7 6
00104             0 0 0 value is incremented in multiples of 10 minutes
00105             0 0 1 value is incremented in multiples of 1 hour
00106             0 1 0 value is incremented in multiples of 10 hours
00107             0 1 1 value is incremented in multiples of 2 seconds
00108             1 0 0 value is incremented in multiples of 30 seconds
00109             1 0 1 value is incremented in multiples of 1 minute
00110             1 1 0 value is incremented in multiples of 320 hours (NOTE 1)
00111             1 1 1 value indicates that the timer is deactivated (NOTE 2).
00112          */
00113         char pt[8+1];// timer value encoded as 3GPP IE
00114         const int ie_value_max = 0x1f;
00115         uint32_t periodic_timer = 0;
00116         if (periodic_time <= 2*ie_value_max) { // multiples of 2 seconds
00117             periodic_timer = periodic_time/2;
00118             strcpy(pt, "01100000");
00119         } else {
00120             if (periodic_time <= 30*ie_value_max) { // multiples of 30 seconds
00121                 periodic_timer = periodic_time/30;
00122                 strcpy(pt, "10000000");
00123             } else {
00124                 if (periodic_time <= 60*ie_value_max) { // multiples of 1 minute
00125                     periodic_timer = periodic_time/60;
00126                     strcpy(pt, "10100000");
00127                 } else {
00128                     if (periodic_time <= 10*60*ie_value_max) { // multiples of 10 minutes
00129                         periodic_timer = periodic_time/(10*60);
00130                         strcpy(pt, "00000000");
00131                     } else {
00132                         if (periodic_time <= 60*60*ie_value_max) { // multiples of 1 hour
00133                             periodic_timer = periodic_time/(60*60);
00134                             strcpy(pt, "00100000");
00135                         } else {
00136                             if (periodic_time <= 10*60*60*ie_value_max) { // multiples of 10 hours
00137                                 periodic_timer = periodic_time/(10*60*60);
00138                                 strcpy(pt, "01000000");
00139                             } else { // multiples of 320 hours
00140                                 int t = periodic_time / (320*60*60);
00141                                 if (t > ie_value_max) {
00142                                     t = ie_value_max;
00143                                 }
00144                                 periodic_timer = t;
00145                                 strcpy(pt, "11000000");
00146                             }
00147                         }
00148                     }
00149                 }
00150             }
00151         }
00152 
00153         uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt)-3, PSMTimerBits);
00154         pt[8] = '\0';
00155 
00156         /**
00157             Table 10.5.172/3GPP TS 24.008: GPRS Timer information element
00158 
00159             Bits 5 to 1 represent the binary coded timer value.
00160 
00161             Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
00162 
00163             8 7 6
00164             0 0 0  value is incremented in multiples of 2 seconds
00165             0 0 1  value is incremented in multiples of 1 minute
00166             0 1 0  value is incremented in multiples of decihours
00167             1 1 1  value indicates that the timer is deactivated.
00168 
00169             Other values shall be interpreted as multiples of 1 minute in this version of the protocol.
00170         */
00171         char at[8+1];
00172         uint32_t active_timer; // timer value encoded as 3GPP IE
00173         if (active_time <= 2*ie_value_max) { // multiples of 2 seconds
00174             active_timer = active_time/2;
00175             strcpy(at, "00000000");
00176         } else {
00177             if (active_time <= 60*ie_value_max) { // multiples of 1 minute
00178                 active_timer = (1<<5) | (active_time/60);
00179                 strcpy(at, "00100000");
00180             } else { // multiples of decihours
00181                 int t = active_time / (6*60);
00182                 if (t > ie_value_max) {
00183                     t = ie_value_max;
00184                 }
00185                 active_timer = t;
00186                 strcpy(at, "01000000");
00187             }
00188         }
00189 
00190         uint_to_binary_str(active_timer, &at[3], sizeof(at)-3, PSMTimerBits);
00191         pt[8] = '\0';
00192 
00193         // request for both GPRS and LTE
00194         _at.cmd_start("AT+CPSMS=");
00195         _at.write_int(1);
00196         _at.write_string(pt);
00197         _at.write_string(at);
00198         _at.write_string(pt);
00199         _at.write_string(at);
00200         _at.cmd_stop();
00201         _at.resp_start();
00202         _at.resp_stop();
00203 
00204 
00205         if (_at.get_last_error() != NSAPI_ERROR_OK ) {
00206             tr_warn("Power save mode not enabled!");
00207         } else {
00208             // network may not agree with power save options but
00209             // that should be fine as timeout is not longer than requested
00210         }
00211     }
00212 
00213     return _at.unlock_return_error();
00214 }
00215 
00216 nsapi_error_t AT_CellularPower::opt_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value)
00217 {
00218     char edrx[5];
00219     uint_to_binary_str(edrx_value, edrx, 5, 4);
00220     edrx[4] = '\0';
00221 
00222     _at.lock();
00223 
00224     _at.cmd_start("AT+CEDRXS=");
00225     _at.write_int(mode);
00226     _at.write_int(act_type);
00227     _at.write_string(edrx);
00228     _at.cmd_stop();
00229     _at.resp_start();
00230     _at.resp_stop();
00231 
00232     return _at.unlock_return_error();
00233 }