ublox-cellular-base

Committer:
wajahat.abbas@u-blox.com
Date:
Wed May 29 12:39:28 2019 +0500
Revision:
25:e67d3d9d2e7e
Parent:
24:e26a6ab0dd75
Child:
26:e4e444cc7b14
Added support for +UPSV (idle mode) for C030_R412M

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RobMeades 0:5cffef3371f6 1 /* Copyright (c) 2017 ublox Limited
RobMeades 0:5cffef3371f6 2 *
RobMeades 0:5cffef3371f6 3 * Licensed under the Apache License, Version 2.0 (the "License");
RobMeades 0:5cffef3371f6 4 * you may not use this file except in compliance with the License.
RobMeades 0:5cffef3371f6 5 * You may obtain a copy of the License at
RobMeades 0:5cffef3371f6 6 *
RobMeades 0:5cffef3371f6 7 * http://www.apache.org/licenses/LICENSE-2.0
RobMeades 0:5cffef3371f6 8 *
RobMeades 0:5cffef3371f6 9 * Unless required by applicable law or agreed to in writing, software
RobMeades 0:5cffef3371f6 10 * distributed under the License is distributed on an "AS IS" BASIS,
RobMeades 0:5cffef3371f6 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
RobMeades 0:5cffef3371f6 12 * See the License for the specific language governing permissions and
RobMeades 0:5cffef3371f6 13 * limitations under the License.
RobMeades 0:5cffef3371f6 14 */
RobMeades 0:5cffef3371f6 15
RobMeades 0:5cffef3371f6 16 #include "UARTSerial.h"
RobMeades 0:5cffef3371f6 17 #include "APN_db.h"
RobMeades 0:5cffef3371f6 18 #include "UbloxCellularBase.h"
RobMeades 0:5cffef3371f6 19 #include "onboard_modem_api.h"
RobMeades 0:5cffef3371f6 20 #ifdef FEATURE_COMMON_PAL
RobMeades 0:5cffef3371f6 21 #include "mbed_trace.h"
RobMeades 0:5cffef3371f6 22 #define TRACE_GROUP "UCB"
RobMeades 0:5cffef3371f6 23 #else
rob.meades@u-blox.com 2:73fcc33c9400 24 #define tr_debug(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
rob.meades@u-blox.com 2:73fcc33c9400 25 #define tr_info(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
rob.meades@u-blox.com 2:73fcc33c9400 26 #define tr_warn(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
rob.meades@u-blox.com 2:73fcc33c9400 27 #define tr_error(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
RobMeades 0:5cffef3371f6 28 #endif
RobMeades 0:5cffef3371f6 29
RobMeades 14:e420232ee4e7 30 /* Array to convert the 3G qual number into a median EC_NO_LEV number.
RobMeades 14:e420232ee4e7 31 */
RobMeades 14:e420232ee4e7 32 /* 0 1 2 3 4 5 6 7 */
fahim.alavi@u-blox.com 15:93b157a47b8d 33 /* 44, 41, 35, 29, 23, 17, 11, 7*/
fahim.alavi@u-blox.com 15:93b157a47b8d 34 const int qualConvert3G[] = {-2, -4, -7, -10, -13, -16, -19, -21};
RobMeades 14:e420232ee4e7 35
RobMeades 14:e420232ee4e7 36 /* Array to convert the 3G "rssi" number into a dBm RSCP value rounded up to the
RobMeades 14:e420232ee4e7 37 * nearest whole number.
RobMeades 14:e420232ee4e7 38 */
RobMeades 14:e420232ee4e7 39 const int rscpConvert3G[] = {-108, -105, -103, -100, -98, -96, -94, -93, /* 0 - 7 */
RobMeades 14:e420232ee4e7 40 -91, -89, -88, -85, -83, -80, -78, -76, /* 8 - 15 */
RobMeades 14:e420232ee4e7 41 -74, -73, -70, -68, -66, -64, -63, -60, /* 16 - 23 */
RobMeades 14:e420232ee4e7 42 -58, -56, -54, -53, -51, -49, -48, -46}; /* 24 - 31 */
RobMeades 14:e420232ee4e7 43
RobMeades 14:e420232ee4e7 44 /* Array to convert the LTE rssi number into a dBm value rounded up to the
RobMeades 14:e420232ee4e7 45 * nearest whole number.
RobMeades 14:e420232ee4e7 46 */
RobMeades 14:e420232ee4e7 47 const int rssiConvertLte[] = {-118, -115, -113, -110, -108, -105, -103, -100, /* 0 - 7 */
RobMeades 14:e420232ee4e7 48 -98, -95, -93, -90, -88, -85, -83, -80, /* 8 - 15 */
RobMeades 14:e420232ee4e7 49 -78, -76, -74, -73, -71, -69, -68, -65, /* 16 - 23 */
RobMeades 14:e420232ee4e7 50 -63, -61, -60, -59, -58, -55, -53, -48}; /* 24 - 31 */
RobMeades 14:e420232ee4e7 51
RobMeades 0:5cffef3371f6 52 /**********************************************************************
RobMeades 0:5cffef3371f6 53 * PRIVATE METHODS
RobMeades 0:5cffef3371f6 54 **********************************************************************/
RobMeades 0:5cffef3371f6 55
RobMeades 0:5cffef3371f6 56 void UbloxCellularBase::set_nwk_reg_status_csd(int status)
RobMeades 0:5cffef3371f6 57 {
RobMeades 0:5cffef3371f6 58 switch (status) {
RobMeades 0:5cffef3371f6 59 case CSD_NOT_REGISTERED_NOT_SEARCHING:
RobMeades 0:5cffef3371f6 60 case CSD_NOT_REGISTERED_SEARCHING:
RobMeades 0:5cffef3371f6 61 tr_info("Not (yet) registered for circuit switched service");
RobMeades 0:5cffef3371f6 62 break;
RobMeades 0:5cffef3371f6 63 case CSD_REGISTERED:
RobMeades 0:5cffef3371f6 64 case CSD_REGISTERED_ROAMING:
RobMeades 0:5cffef3371f6 65 tr_info("Registered for circuit switched service");
RobMeades 0:5cffef3371f6 66 break;
RobMeades 0:5cffef3371f6 67 case CSD_REGISTRATION_DENIED:
RobMeades 0:5cffef3371f6 68 tr_info("Circuit switched service denied");
RobMeades 0:5cffef3371f6 69 break;
RobMeades 0:5cffef3371f6 70 case CSD_UNKNOWN_COVERAGE:
RobMeades 0:5cffef3371f6 71 tr_info("Out of circuit switched service coverage");
RobMeades 0:5cffef3371f6 72 break;
RobMeades 0:5cffef3371f6 73 case CSD_SMS_ONLY:
RobMeades 0:5cffef3371f6 74 tr_info("SMS service only");
RobMeades 0:5cffef3371f6 75 break;
RobMeades 0:5cffef3371f6 76 case CSD_SMS_ONLY_ROAMING:
RobMeades 0:5cffef3371f6 77 tr_info("SMS service only");
RobMeades 0:5cffef3371f6 78 break;
RobMeades 0:5cffef3371f6 79 case CSD_CSFB_NOT_PREFERRED:
RobMeades 0:5cffef3371f6 80 tr_info("Registered for circuit switched service with CSFB not preferred");
RobMeades 0:5cffef3371f6 81 break;
RobMeades 0:5cffef3371f6 82 default:
RobMeades 0:5cffef3371f6 83 tr_info("Unknown circuit switched service registration status. %d", status);
RobMeades 0:5cffef3371f6 84 break;
RobMeades 0:5cffef3371f6 85 }
RobMeades 0:5cffef3371f6 86
RobMeades 0:5cffef3371f6 87 _dev_info.reg_status_csd = static_cast<NetworkRegistrationStatusCsd>(status);
RobMeades 0:5cffef3371f6 88 }
RobMeades 0:5cffef3371f6 89
RobMeades 0:5cffef3371f6 90 void UbloxCellularBase::set_nwk_reg_status_psd(int status)
RobMeades 0:5cffef3371f6 91 {
RobMeades 0:5cffef3371f6 92 switch (status) {
RobMeades 0:5cffef3371f6 93 case PSD_NOT_REGISTERED_NOT_SEARCHING:
RobMeades 0:5cffef3371f6 94 case PSD_NOT_REGISTERED_SEARCHING:
RobMeades 0:5cffef3371f6 95 tr_info("Not (yet) registered for packet switched service");
RobMeades 0:5cffef3371f6 96 break;
RobMeades 0:5cffef3371f6 97 case PSD_REGISTERED:
RobMeades 0:5cffef3371f6 98 case PSD_REGISTERED_ROAMING:
RobMeades 0:5cffef3371f6 99 tr_info("Registered for packet switched service");
RobMeades 0:5cffef3371f6 100 break;
RobMeades 0:5cffef3371f6 101 case PSD_REGISTRATION_DENIED:
RobMeades 0:5cffef3371f6 102 tr_info("Packet switched service denied");
RobMeades 0:5cffef3371f6 103 break;
RobMeades 0:5cffef3371f6 104 case PSD_UNKNOWN_COVERAGE:
RobMeades 0:5cffef3371f6 105 tr_info("Out of packet switched service coverage");
RobMeades 0:5cffef3371f6 106 break;
RobMeades 0:5cffef3371f6 107 case PSD_EMERGENCY_SERVICES_ONLY:
RobMeades 0:5cffef3371f6 108 tr_info("Limited access for packet switched service. Emergency use only.");
RobMeades 0:5cffef3371f6 109 break;
RobMeades 0:5cffef3371f6 110 default:
RobMeades 0:5cffef3371f6 111 tr_info("Unknown packet switched service registration status. %d", status);
RobMeades 0:5cffef3371f6 112 break;
RobMeades 0:5cffef3371f6 113 }
RobMeades 0:5cffef3371f6 114
RobMeades 0:5cffef3371f6 115 _dev_info.reg_status_psd = static_cast<NetworkRegistrationStatusPsd>(status);
RobMeades 0:5cffef3371f6 116 }
RobMeades 0:5cffef3371f6 117
RobMeades 0:5cffef3371f6 118 void UbloxCellularBase::set_nwk_reg_status_eps(int status)
RobMeades 0:5cffef3371f6 119 {
RobMeades 0:5cffef3371f6 120 switch (status) {
RobMeades 0:5cffef3371f6 121 case EPS_NOT_REGISTERED_NOT_SEARCHING:
RobMeades 0:5cffef3371f6 122 case EPS_NOT_REGISTERED_SEARCHING:
RobMeades 0:5cffef3371f6 123 tr_info("Not (yet) registered for EPS service");
RobMeades 0:5cffef3371f6 124 break;
RobMeades 0:5cffef3371f6 125 case EPS_REGISTERED:
RobMeades 0:5cffef3371f6 126 case EPS_REGISTERED_ROAMING:
RobMeades 0:5cffef3371f6 127 tr_info("Registered for EPS service");
RobMeades 0:5cffef3371f6 128 break;
RobMeades 0:5cffef3371f6 129 case EPS_REGISTRATION_DENIED:
RobMeades 0:5cffef3371f6 130 tr_info("EPS service denied");
RobMeades 0:5cffef3371f6 131 break;
RobMeades 0:5cffef3371f6 132 case EPS_UNKNOWN_COVERAGE:
RobMeades 0:5cffef3371f6 133 tr_info("Out of EPS service coverage");
RobMeades 0:5cffef3371f6 134 break;
RobMeades 0:5cffef3371f6 135 case EPS_EMERGENCY_SERVICES_ONLY:
RobMeades 0:5cffef3371f6 136 tr_info("Limited access for EPS service. Emergency use only.");
RobMeades 0:5cffef3371f6 137 break;
RobMeades 0:5cffef3371f6 138 default:
RobMeades 0:5cffef3371f6 139 tr_info("Unknown EPS service registration status. %d", status);
RobMeades 0:5cffef3371f6 140 break;
RobMeades 0:5cffef3371f6 141 }
RobMeades 0:5cffef3371f6 142
RobMeades 0:5cffef3371f6 143 _dev_info.reg_status_eps = static_cast<NetworkRegistrationStatusEps>(status);
RobMeades 0:5cffef3371f6 144 }
RobMeades 0:5cffef3371f6 145
wajahat.abbas@u-blox.com 23:eaab8e812a5d 146 #ifdef TARGET_UBLOX_C030_R412M
wajahat.abbas@u-blox.com 23:eaab8e812a5d 147 void UbloxCellularBase::set_modem_psm_state(int status)
wajahat.abbas@u-blox.com 23:eaab8e812a5d 148 {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 149 switch (status) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 150 case ASLEEP:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 151 tr_info("Modem is going in PSM sleep");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 152 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 153 case AWAKE:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 154 tr_info("Modem is awake from PSM sleep");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 155 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 156 default:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 157 tr_info("Unknown PSM state. %d", status);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 158 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 159 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 160
wajahat.abbas@u-blox.com 23:eaab8e812a5d 161 _dev_info.modem_psm_state = static_cast<ModemPSMState>(status);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 162 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 163 #endif
wajahat.abbas@u-blox.com 23:eaab8e812a5d 164
RobMeades 14:e420232ee4e7 165 void UbloxCellularBase::set_rat(int acTStatus)
RobMeades 0:5cffef3371f6 166 {
RobMeades 14:e420232ee4e7 167 switch (acTStatus) {
RobMeades 0:5cffef3371f6 168 case GSM:
RobMeades 0:5cffef3371f6 169 case COMPACT_GSM:
RobMeades 0:5cffef3371f6 170 tr_info("Connected in GSM");
RobMeades 0:5cffef3371f6 171 break;
RobMeades 0:5cffef3371f6 172 case UTRAN:
RobMeades 0:5cffef3371f6 173 tr_info("Connected to UTRAN");
RobMeades 0:5cffef3371f6 174 break;
RobMeades 0:5cffef3371f6 175 case EDGE:
RobMeades 0:5cffef3371f6 176 tr_info("Connected to EDGE");
RobMeades 0:5cffef3371f6 177 break;
RobMeades 0:5cffef3371f6 178 case HSDPA:
RobMeades 0:5cffef3371f6 179 tr_info("Connected to HSDPA");
RobMeades 0:5cffef3371f6 180 break;
RobMeades 0:5cffef3371f6 181 case HSUPA:
RobMeades 0:5cffef3371f6 182 tr_info("Connected to HSPA");
RobMeades 0:5cffef3371f6 183 break;
RobMeades 0:5cffef3371f6 184 case HSDPA_HSUPA:
RobMeades 0:5cffef3371f6 185 tr_info("Connected to HDPA/HSPA");
RobMeades 0:5cffef3371f6 186 break;
RobMeades 0:5cffef3371f6 187 case LTE:
RobMeades 0:5cffef3371f6 188 tr_info("Connected to LTE");
RobMeades 0:5cffef3371f6 189 break;
fahimalavi 10:c4281fa79b8f 190 case EC_GSM_IoT:
fahimalavi 10:c4281fa79b8f 191 tr_info("Connected to EC_GSM_IoT");
fahimalavi 10:c4281fa79b8f 192 break;
fahimalavi 10:c4281fa79b8f 193 case E_UTRAN_NB_S1:
fahimalavi 10:c4281fa79b8f 194 tr_info("Connected to E_UTRAN NB1");
fahimalavi 10:c4281fa79b8f 195 break;
RobMeades 0:5cffef3371f6 196 default:
RobMeades 14:e420232ee4e7 197 tr_info("Unknown RAT %d", acTStatus);
RobMeades 0:5cffef3371f6 198 break;
RobMeades 0:5cffef3371f6 199 }
RobMeades 0:5cffef3371f6 200
RobMeades 14:e420232ee4e7 201 _dev_info.rat = static_cast<RadioAccessNetworkType>(acTStatus);
RobMeades 0:5cffef3371f6 202 }
RobMeades 0:5cffef3371f6 203
RobMeades 0:5cffef3371f6 204 bool UbloxCellularBase::get_iccid()
RobMeades 0:5cffef3371f6 205 {
RobMeades 0:5cffef3371f6 206 bool success;
RobMeades 0:5cffef3371f6 207 LOCK();
RobMeades 0:5cffef3371f6 208
RobMeades 0:5cffef3371f6 209 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 210
RobMeades 0:5cffef3371f6 211 // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
RobMeades 0:5cffef3371f6 212 // ICCID is a serial number identifying the SIM.
RobMeades 0:5cffef3371f6 213 // AT Command Manual UBX-13002752, section 4.12
RobMeades 0:5cffef3371f6 214 success = _at->send("AT+CCID") && _at->recv("+CCID: %20[^\n]\nOK\n", _dev_info.iccid);
RobMeades 0:5cffef3371f6 215 tr_info("DevInfo: ICCID=%s", _dev_info.iccid);
RobMeades 0:5cffef3371f6 216
RobMeades 0:5cffef3371f6 217 UNLOCK();
RobMeades 0:5cffef3371f6 218 return success;
RobMeades 0:5cffef3371f6 219 }
RobMeades 0:5cffef3371f6 220
RobMeades 0:5cffef3371f6 221 bool UbloxCellularBase::get_imsi()
RobMeades 0:5cffef3371f6 222 {
RobMeades 0:5cffef3371f6 223 bool success;
RobMeades 0:5cffef3371f6 224 LOCK();
RobMeades 0:5cffef3371f6 225
RobMeades 0:5cffef3371f6 226 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 227
RobMeades 0:5cffef3371f6 228 // International mobile subscriber identification
RobMeades 0:5cffef3371f6 229 // AT Command Manual UBX-13002752, section 4.11
RobMeades 0:5cffef3371f6 230 success = _at->send("AT+CIMI") && _at->recv("%15[^\n]\nOK\n", _dev_info.imsi);
RobMeades 0:5cffef3371f6 231 tr_info("DevInfo: IMSI=%s", _dev_info.imsi);
RobMeades 0:5cffef3371f6 232
RobMeades 0:5cffef3371f6 233 UNLOCK();
RobMeades 0:5cffef3371f6 234 return success;
RobMeades 0:5cffef3371f6 235 }
RobMeades 0:5cffef3371f6 236
RobMeades 0:5cffef3371f6 237 bool UbloxCellularBase::get_imei()
RobMeades 0:5cffef3371f6 238 {
RobMeades 0:5cffef3371f6 239 bool success;
RobMeades 0:5cffef3371f6 240 LOCK();
RobMeades 0:5cffef3371f6 241
RobMeades 0:5cffef3371f6 242 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 243
RobMeades 0:5cffef3371f6 244 // International mobile equipment identifier
RobMeades 0:5cffef3371f6 245 // AT Command Manual UBX-13002752, section 4.7
RobMeades 0:5cffef3371f6 246 success = _at->send("AT+CGSN") && _at->recv("%15[^\n]\nOK\n", _dev_info.imei);
RobMeades 0:5cffef3371f6 247 tr_info("DevInfo: IMEI=%s", _dev_info.imei);
RobMeades 0:5cffef3371f6 248
RobMeades 0:5cffef3371f6 249 UNLOCK();
RobMeades 0:5cffef3371f6 250 return success;
RobMeades 0:5cffef3371f6 251 }
RobMeades 0:5cffef3371f6 252
RobMeades 0:5cffef3371f6 253 bool UbloxCellularBase::get_meid()
RobMeades 0:5cffef3371f6 254 {
RobMeades 0:5cffef3371f6 255 bool success;
RobMeades 0:5cffef3371f6 256 LOCK();
RobMeades 0:5cffef3371f6 257
RobMeades 0:5cffef3371f6 258 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 259
RobMeades 0:5cffef3371f6 260 // Mobile equipment identifier
RobMeades 0:5cffef3371f6 261 // AT Command Manual UBX-13002752, section 4.8
RobMeades 0:5cffef3371f6 262 success = _at->send("AT+GSN") && _at->recv("%18[^\n]\nOK\n", _dev_info.meid);
RobMeades 0:5cffef3371f6 263 tr_info("DevInfo: MEID=%s", _dev_info.meid);
RobMeades 0:5cffef3371f6 264
RobMeades 0:5cffef3371f6 265 UNLOCK();
RobMeades 0:5cffef3371f6 266 return success;
RobMeades 0:5cffef3371f6 267 }
RobMeades 0:5cffef3371f6 268
RobMeades 0:5cffef3371f6 269 bool UbloxCellularBase::set_sms()
RobMeades 0:5cffef3371f6 270 {
RobMeades 0:5cffef3371f6 271 bool success = false;
RobMeades 0:5cffef3371f6 272 char buf[32];
RobMeades 0:5cffef3371f6 273 LOCK();
RobMeades 0:5cffef3371f6 274
RobMeades 0:5cffef3371f6 275 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 276
RobMeades 0:5cffef3371f6 277 // Set up SMS format and enable URC
RobMeades 0:5cffef3371f6 278 // AT Command Manual UBX-13002752, section 11
RobMeades 0:5cffef3371f6 279 if (_at->send("AT+CMGF=1") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 280 tr_debug("SMS in text mode");
RobMeades 0:5cffef3371f6 281 if (_at->send("AT+CNMI=2,1") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 282 tr_debug("SMS URC enabled");
RobMeades 0:5cffef3371f6 283 // Set to CS preferred since PS preferred doesn't work
RobMeades 0:5cffef3371f6 284 // on some networks
RobMeades 0:5cffef3371f6 285 if (_at->send("AT+CGSMS=1") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 286 tr_debug("SMS set to CS preferred");
RobMeades 0:5cffef3371f6 287 success = true;
RobMeades 0:5cffef3371f6 288 memset (buf, 0, sizeof (buf));
RobMeades 0:5cffef3371f6 289 if (_at->send("AT+CSCA?") &&
RobMeades 0:5cffef3371f6 290 _at->recv("+CSCA: \"%31[^\"]\"", buf) &&
RobMeades 0:5cffef3371f6 291 _at->recv("OK")) {
RobMeades 0:5cffef3371f6 292 tr_info("SMS Service Centre address is \"%s\"", buf);
RobMeades 0:5cffef3371f6 293 }
RobMeades 0:5cffef3371f6 294 }
RobMeades 0:5cffef3371f6 295 }
RobMeades 0:5cffef3371f6 296 }
RobMeades 0:5cffef3371f6 297
RobMeades 0:5cffef3371f6 298 UNLOCK();
RobMeades 0:5cffef3371f6 299 return success;
RobMeades 0:5cffef3371f6 300 }
RobMeades 0:5cffef3371f6 301
RobMeades 0:5cffef3371f6 302 void UbloxCellularBase::parser_abort_cb()
RobMeades 0:5cffef3371f6 303 {
RobMeades 0:5cffef3371f6 304 _at->abort();
RobMeades 0:5cffef3371f6 305 }
RobMeades 0:5cffef3371f6 306
RobMeades 0:5cffef3371f6 307 // Callback for CME ERROR and CMS ERROR.
RobMeades 0:5cffef3371f6 308 void UbloxCellularBase::CMX_ERROR_URC()
RobMeades 0:5cffef3371f6 309 {
RobMeades 0:5cffef3371f6 310 char buf[48];
RobMeades 0:5cffef3371f6 311
RobMeades 0:5cffef3371f6 312 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 0:5cffef3371f6 313 tr_debug("AT error %s", buf);
RobMeades 0:5cffef3371f6 314 }
RobMeades 0:5cffef3371f6 315 parser_abort_cb();
RobMeades 0:5cffef3371f6 316 }
RobMeades 0:5cffef3371f6 317
RobMeades 0:5cffef3371f6 318 // Callback for circuit switched registration URC.
RobMeades 0:5cffef3371f6 319 void UbloxCellularBase::CREG_URC()
RobMeades 0:5cffef3371f6 320 {
RobMeades 0:5cffef3371f6 321 char buf[10];
RobMeades 0:5cffef3371f6 322 int status;
RobMeades 14:e420232ee4e7 323 int acTStatus;
RobMeades 0:5cffef3371f6 324
RobMeades 0:5cffef3371f6 325 // If this is the URC it will be a single
RobMeades 0:5cffef3371f6 326 // digit followed by \n. If it is the
RobMeades 0:5cffef3371f6 327 // answer to a CREG query, it will be
RobMeades 0:5cffef3371f6 328 // a ": %d,%d\n" where the second digit
RobMeades 0:5cffef3371f6 329 // indicates the status
RobMeades 0:5cffef3371f6 330 // Note: not calling _at->recv() from here as we're
RobMeades 0:5cffef3371f6 331 // already in an _at->recv()
RobMeades 0:5cffef3371f6 332 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 14:e420232ee4e7 333 if (sscanf(buf, ": %*d,%d,%*d,%*d,%d,", &status, &acTStatus) == 2) {
RobMeades 14:e420232ee4e7 334 set_nwk_reg_status_csd(status);
RobMeades 14:e420232ee4e7 335 set_rat(acTStatus);
RobMeades 14:e420232ee4e7 336 } else if (sscanf(buf, ": %*d,%d", &status) == 1) {
RobMeades 0:5cffef3371f6 337 set_nwk_reg_status_csd(status);
RobMeades 0:5cffef3371f6 338 } else if (sscanf(buf, ": %d", &status) == 1) {
RobMeades 0:5cffef3371f6 339 set_nwk_reg_status_csd(status);
RobMeades 0:5cffef3371f6 340 }
RobMeades 0:5cffef3371f6 341 }
RobMeades 0:5cffef3371f6 342 }
RobMeades 0:5cffef3371f6 343
RobMeades 0:5cffef3371f6 344 // Callback for packet switched registration URC.
RobMeades 0:5cffef3371f6 345 void UbloxCellularBase::CGREG_URC()
RobMeades 0:5cffef3371f6 346 {
RobMeades 0:5cffef3371f6 347 char buf[10];
RobMeades 0:5cffef3371f6 348 int status;
RobMeades 14:e420232ee4e7 349 int acTStatus;
RobMeades 0:5cffef3371f6 350
RobMeades 0:5cffef3371f6 351 // If this is the URC it will be a single
RobMeades 0:5cffef3371f6 352 // digit followed by \n. If it is the
RobMeades 0:5cffef3371f6 353 // answer to a CGREG query, it will be
RobMeades 0:5cffef3371f6 354 // a ": %d,%d\n" where the second digit
RobMeades 0:5cffef3371f6 355 // indicates the status
RobMeades 0:5cffef3371f6 356 // Note: not calling _at->recv() from here as we're
RobMeades 0:5cffef3371f6 357 // already in an _at->recv()
RobMeades 0:5cffef3371f6 358 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 14:e420232ee4e7 359 if (sscanf(buf, ": %*d,%d,%*d,%*d,%d,", &status, &acTStatus) == 2) {
RobMeades 14:e420232ee4e7 360 set_nwk_reg_status_csd(status);
RobMeades 14:e420232ee4e7 361 set_rat(acTStatus);
RobMeades 14:e420232ee4e7 362 } else if (sscanf(buf, ": %*d,%d", &status) == 1) {
RobMeades 0:5cffef3371f6 363 set_nwk_reg_status_psd(status);
RobMeades 0:5cffef3371f6 364 } else if (sscanf(buf, ": %d", &status) == 1) {
RobMeades 0:5cffef3371f6 365 set_nwk_reg_status_psd(status);
RobMeades 0:5cffef3371f6 366 }
RobMeades 0:5cffef3371f6 367 }
RobMeades 0:5cffef3371f6 368 }
RobMeades 0:5cffef3371f6 369
RobMeades 0:5cffef3371f6 370 // Callback for EPS registration URC.
RobMeades 0:5cffef3371f6 371 void UbloxCellularBase::CEREG_URC()
RobMeades 0:5cffef3371f6 372 {
RobMeades 0:5cffef3371f6 373 char buf[10];
RobMeades 0:5cffef3371f6 374 int status;
RobMeades 14:e420232ee4e7 375 int acTStatus;
RobMeades 0:5cffef3371f6 376
RobMeades 0:5cffef3371f6 377 // If this is the URC it will be a single
RobMeades 0:5cffef3371f6 378 // digit followed by \n. If it is the
RobMeades 0:5cffef3371f6 379 // answer to a CEREG query, it will be
RobMeades 0:5cffef3371f6 380 // a ": %d,%d\n" where the second digit
RobMeades 0:5cffef3371f6 381 // indicates the status
RobMeades 0:5cffef3371f6 382 // Note: not calling _at->recv() from here as we're
RobMeades 0:5cffef3371f6 383 // already in an _at->recv()
RobMeades 0:5cffef3371f6 384 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 14:e420232ee4e7 385 if (sscanf(buf, ": %*d,%d,%*d,%*d,%d,", &status, &acTStatus) == 2) {
RobMeades 14:e420232ee4e7 386 set_nwk_reg_status_csd(status);
RobMeades 14:e420232ee4e7 387 set_rat(acTStatus);
RobMeades 14:e420232ee4e7 388 } else if (sscanf(buf, ": %*d,%d", &status) == 1) {
RobMeades 0:5cffef3371f6 389 set_nwk_reg_status_eps(status);
RobMeades 0:5cffef3371f6 390 } else if (sscanf(buf, ": %d", &status) == 1) {
RobMeades 0:5cffef3371f6 391 set_nwk_reg_status_eps(status);
RobMeades 0:5cffef3371f6 392 }
RobMeades 0:5cffef3371f6 393 }
RobMeades 0:5cffef3371f6 394 }
RobMeades 0:5cffef3371f6 395
RobMeades 0:5cffef3371f6 396 // Callback UMWI, just filtering it out.
RobMeades 0:5cffef3371f6 397 void UbloxCellularBase::UMWI_URC()
RobMeades 0:5cffef3371f6 398 {
RobMeades 0:5cffef3371f6 399 char buf[10];
RobMeades 0:5cffef3371f6 400
RobMeades 0:5cffef3371f6 401 // Note: not calling _at->recv() from here as we're
RobMeades 0:5cffef3371f6 402 // already in an _at->recv()
RobMeades 0:5cffef3371f6 403 read_at_to_char(buf, sizeof (buf), '\n');
RobMeades 0:5cffef3371f6 404 }
RobMeades 0:5cffef3371f6 405
wajahat.abbas@u-blox.com 23:eaab8e812a5d 406 #ifdef TARGET_UBLOX_C030_R412M
wajahat.abbas@u-blox.com 23:eaab8e812a5d 407 // Callback UUPSMR, set/clear flag for modem psm state.
wajahat.abbas@u-blox.com 23:eaab8e812a5d 408 void UbloxCellularBase::UUPSMR_URC()
wajahat.abbas@u-blox.com 23:eaab8e812a5d 409 {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 410 int status;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 411 char buf[10];
wajahat.abbas@u-blox.com 23:eaab8e812a5d 412
wajahat.abbas@u-blox.com 23:eaab8e812a5d 413 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 414 if (sscanf(buf, ": %d", &status) == 1) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 415 set_modem_psm_state(status);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 416 //call application registered callbacks
wajahat.abbas@u-blox.com 23:eaab8e812a5d 417 if (status == AWAKE) { //modem coming out of sleep
wajahat.abbas@u-blox.com 23:eaab8e812a5d 418 if (_func_psm_coming_out) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 419 _func_psm_coming_out(_cb_param_psm_coming_out);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 420 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 421 } else if(status == ASLEEP) { //modem going into sleep
wajahat.abbas@u-blox.com 23:eaab8e812a5d 422 if (_func_psm_going_in) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 423 _func_psm_going_in(_cb_param_psm_going_in);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 424 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 425 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 426 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 427 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 428 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 429 #endif
RobMeades 0:5cffef3371f6 430 /**********************************************************************
RobMeades 0:5cffef3371f6 431 * PROTECTED METHODS
RobMeades 0:5cffef3371f6 432 **********************************************************************/
RobMeades 0:5cffef3371f6 433
RobMeades 0:5cffef3371f6 434 #if MODEM_ON_BOARD
RobMeades 0:5cffef3371f6 435 void UbloxCellularBase::modem_init()
RobMeades 0:5cffef3371f6 436 {
RobMeades 0:5cffef3371f6 437 ::onboard_modem_init();
RobMeades 0:5cffef3371f6 438 }
RobMeades 0:5cffef3371f6 439
RobMeades 0:5cffef3371f6 440 void UbloxCellularBase::modem_deinit()
RobMeades 0:5cffef3371f6 441 {
RobMeades 0:5cffef3371f6 442 ::onboard_modem_deinit();
RobMeades 0:5cffef3371f6 443 }
RobMeades 0:5cffef3371f6 444
RobMeades 0:5cffef3371f6 445 void UbloxCellularBase::modem_power_up()
RobMeades 0:5cffef3371f6 446 {
RobMeades 0:5cffef3371f6 447 ::onboard_modem_power_up();
RobMeades 0:5cffef3371f6 448 }
RobMeades 0:5cffef3371f6 449
RobMeades 0:5cffef3371f6 450 void UbloxCellularBase::modem_power_down()
RobMeades 0:5cffef3371f6 451 {
RobMeades 0:5cffef3371f6 452 ::onboard_modem_power_down();
RobMeades 0:5cffef3371f6 453 }
RobMeades 0:5cffef3371f6 454 #else
RobMeades 0:5cffef3371f6 455 void UbloxCellularBase::modem_init()
RobMeades 0:5cffef3371f6 456 {
RobMeades 0:5cffef3371f6 457 // Meant to be overridden
RobMeades 0:5cffef3371f6 458 }
RobMeades 0:5cffef3371f6 459
RobMeades 0:5cffef3371f6 460 void UbloxCellularBase::modem_deinit()
RobMeades 0:5cffef3371f6 461 {
RobMeades 0:5cffef3371f6 462 // Meant to be overridden
RobMeades 0:5cffef3371f6 463 }
RobMeades 0:5cffef3371f6 464
RobMeades 0:5cffef3371f6 465 void UbloxCellularBase::modem_power_up()
RobMeades 0:5cffef3371f6 466 {
RobMeades 0:5cffef3371f6 467 // Meant to be overridden
RobMeades 0:5cffef3371f6 468 }
RobMeades 0:5cffef3371f6 469
RobMeades 0:5cffef3371f6 470 void UbloxCellularBase::modem_power_down()
RobMeades 0:5cffef3371f6 471 {
RobMeades 0:5cffef3371f6 472 // Mmeant to be overridden
RobMeades 0:5cffef3371f6 473 }
RobMeades 0:5cffef3371f6 474 #endif
RobMeades 0:5cffef3371f6 475
RobMeades 0:5cffef3371f6 476 // Constructor.
RobMeades 0:5cffef3371f6 477 // Note: to allow this base class to be inherited as a virtual base class
RobMeades 0:5cffef3371f6 478 // by everyone, it takes no parameters. See also comment above classInit()
RobMeades 0:5cffef3371f6 479 // in the header file.
RobMeades 0:5cffef3371f6 480 UbloxCellularBase::UbloxCellularBase()
RobMeades 0:5cffef3371f6 481 {
RobMeades 0:5cffef3371f6 482 _pin = NULL;
RobMeades 0:5cffef3371f6 483 _at = NULL;
RobMeades 0:5cffef3371f6 484 _at_timeout = AT_PARSER_TIMEOUT;
RobMeades 0:5cffef3371f6 485 _fh = NULL;
RobMeades 0:5cffef3371f6 486 _modem_initialised = false;
RobMeades 0:5cffef3371f6 487 _sim_pin_check_enabled = false;
RobMeades 0:5cffef3371f6 488 _debug_trace_on = false;
RobMeades 0:5cffef3371f6 489
RobMeades 0:5cffef3371f6 490 _dev_info.dev = DEV_TYPE_NONE;
RobMeades 0:5cffef3371f6 491 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 492 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 493 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 494 #ifdef TARGET_UBLOX_C030_R412M
wajahat.abbas@u-blox.com 23:eaab8e812a5d 495 _dev_info.modem_psm_state = AWAKE;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 496 _psm_status = false;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 497 _cb_param_psm_going_in = NULL;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 498 _func_psm_going_in = NULL;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 499 _cb_param_psm_coming_out = NULL;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 500 _func_psm_coming_out = NULL;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 501 #endif
RobMeades 0:5cffef3371f6 502 }
RobMeades 0:5cffef3371f6 503
RobMeades 0:5cffef3371f6 504 // Destructor.
RobMeades 0:5cffef3371f6 505 UbloxCellularBase::~UbloxCellularBase()
RobMeades 0:5cffef3371f6 506 {
RobMeades 0:5cffef3371f6 507 deinit();
RobMeades 0:5cffef3371f6 508 delete _at;
RobMeades 0:5cffef3371f6 509 delete _fh;
RobMeades 0:5cffef3371f6 510 }
RobMeades 0:5cffef3371f6 511
RobMeades 0:5cffef3371f6 512 // Initialise the portions of this class that are parameterised.
RobMeades 0:5cffef3371f6 513 void UbloxCellularBase::baseClassInit(PinName tx, PinName rx,
RobMeades 0:5cffef3371f6 514 int baud, bool debug_on)
RobMeades 0:5cffef3371f6 515 {
RobMeades 0:5cffef3371f6 516 // Only initialise ourselves if it's not already been done
RobMeades 0:5cffef3371f6 517 if (_at == NULL) {
RobMeades 0:5cffef3371f6 518 if (_debug_trace_on == false) {
RobMeades 0:5cffef3371f6 519 _debug_trace_on = debug_on;
RobMeades 0:5cffef3371f6 520 }
rob.meades@u-blox.com 4:2e640a101db1 521 _baud = baud;
RobMeades 0:5cffef3371f6 522
RobMeades 0:5cffef3371f6 523 // Set up File Handle for buffered serial comms with cellular module
RobMeades 0:5cffef3371f6 524 // (which will be used by the AT parser)
rob.meades@u-blox.com 4:2e640a101db1 525 // Note: the UART is initialised to run no faster than 115200 because
rob.meades@u-blox.com 4:2e640a101db1 526 // the modems cannot reliably auto-baud at faster rates. The faster
rob.meades@u-blox.com 4:2e640a101db1 527 // rate is adopted later with a specific AT command and the
rob.meades@u-blox.com 4:2e640a101db1 528 // UARTSerial rate is adjusted at that time
rob.meades@u-blox.com 4:2e640a101db1 529 if (baud > 115200) {
rob.meades@u-blox.com 4:2e640a101db1 530 baud = 115200;
rob.meades@u-blox.com 4:2e640a101db1 531 }
RobMeades 0:5cffef3371f6 532 _fh = new UARTSerial(tx, rx, baud);
RobMeades 0:5cffef3371f6 533
RobMeades 0:5cffef3371f6 534 // Set up the AT parser
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 535 #ifdef TARGET_UBLOX_C030_R41XM
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 536 _at = new UbloxATCmdParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE,
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 537 _at_timeout, _debug_trace_on);
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 538 #else
RobMeades 0:5cffef3371f6 539 _at = new ATCmdParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE,
rob.meades@u-blox.com 3:f9b2cd6f72b1 540 _at_timeout, _debug_trace_on);
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 541 #endif
RobMeades 0:5cffef3371f6 542
RobMeades 0:5cffef3371f6 543 // Error cases, out of band handling
RobMeades 0:5cffef3371f6 544 _at->oob("ERROR", callback(this, &UbloxCellularBase::parser_abort_cb));
RobMeades 0:5cffef3371f6 545 _at->oob("+CME ERROR", callback(this, &UbloxCellularBase::CMX_ERROR_URC));
RobMeades 0:5cffef3371f6 546 _at->oob("+CMS ERROR", callback(this, &UbloxCellularBase::CMX_ERROR_URC));
RobMeades 0:5cffef3371f6 547
RobMeades 0:5cffef3371f6 548 // Registration status, out of band handling
RobMeades 0:5cffef3371f6 549 _at->oob("+CREG", callback(this, &UbloxCellularBase::CREG_URC));
RobMeades 0:5cffef3371f6 550 _at->oob("+CGREG", callback(this, &UbloxCellularBase::CGREG_URC));
RobMeades 0:5cffef3371f6 551 _at->oob("+CEREG", callback(this, &UbloxCellularBase::CEREG_URC));
RobMeades 0:5cffef3371f6 552
RobMeades 0:5cffef3371f6 553 // Capture the UMWI, just to stop it getting in the way
RobMeades 0:5cffef3371f6 554 _at->oob("+UMWI", callback(this, &UbloxCellularBase::UMWI_URC));
wajahat.abbas@u-blox.com 23:eaab8e812a5d 555 #ifdef TARGET_UBLOX_C030_R412M
wajahat.abbas@u-blox.com 23:eaab8e812a5d 556 // Handle PSM URC for going in and coming out of PSM
wajahat.abbas@u-blox.com 23:eaab8e812a5d 557 _at->oob("+UUPSMR", callback(this, &UbloxCellularBase::UUPSMR_URC));
wajahat.abbas@u-blox.com 23:eaab8e812a5d 558 #endif
RobMeades 0:5cffef3371f6 559 }
RobMeades 0:5cffef3371f6 560 }
RobMeades 0:5cffef3371f6 561
RobMeades 0:5cffef3371f6 562 // Set the AT parser timeout.
RobMeades 0:5cffef3371f6 563 // Note: the AT interface should be locked before this is called.
RobMeades 0:5cffef3371f6 564 void UbloxCellularBase::at_set_timeout(int timeout) {
RobMeades 0:5cffef3371f6 565
RobMeades 0:5cffef3371f6 566 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 567
RobMeades 0:5cffef3371f6 568 _at_timeout = timeout;
RobMeades 0:5cffef3371f6 569 _at->set_timeout(timeout);
RobMeades 0:5cffef3371f6 570 }
RobMeades 0:5cffef3371f6 571
RobMeades 0:5cffef3371f6 572 // Read up to size bytes from the AT interface up to a "end".
RobMeades 0:5cffef3371f6 573 // Note: the AT interface should be locked before this is called.
RobMeades 0:5cffef3371f6 574 int UbloxCellularBase::read_at_to_char(char * buf, int size, char end)
RobMeades 0:5cffef3371f6 575 {
RobMeades 0:5cffef3371f6 576 int count = 0;
RobMeades 0:5cffef3371f6 577 int x = 0;
RobMeades 0:5cffef3371f6 578
RobMeades 0:5cffef3371f6 579 if (size > 0) {
RobMeades 0:5cffef3371f6 580 for (count = 0; (count < size) && (x >= 0) && (x != end); count++) {
RobMeades 0:5cffef3371f6 581 x = _at->getc();
RobMeades 0:5cffef3371f6 582 *(buf + count) = (char) x;
RobMeades 0:5cffef3371f6 583 }
RobMeades 0:5cffef3371f6 584
RobMeades 0:5cffef3371f6 585 count--;
RobMeades 0:5cffef3371f6 586 *(buf + count) = 0;
RobMeades 0:5cffef3371f6 587
RobMeades 0:5cffef3371f6 588 // Convert line endings:
RobMeades 0:5cffef3371f6 589 // If end was '\n' (0x0a) and the preceding character was 0x0d, then
RobMeades 0:5cffef3371f6 590 // overwrite that with null as well.
RobMeades 0:5cffef3371f6 591 if ((count > 0) && (end == '\n') && (*(buf + count - 1) == '\x0d')) {
RobMeades 0:5cffef3371f6 592 count--;
RobMeades 0:5cffef3371f6 593 *(buf + count) = 0;
RobMeades 0:5cffef3371f6 594 }
RobMeades 0:5cffef3371f6 595 }
RobMeades 0:5cffef3371f6 596
RobMeades 0:5cffef3371f6 597 return count;
RobMeades 0:5cffef3371f6 598 }
RobMeades 0:5cffef3371f6 599
RobMeades 0:5cffef3371f6 600 // Power up the modem.
RobMeades 0:5cffef3371f6 601 // Enables the GPIO lines to the modem and then wriggles the power line in short pulses.
RobMeades 0:5cffef3371f6 602 bool UbloxCellularBase::power_up()
RobMeades 0:5cffef3371f6 603 {
RobMeades 0:5cffef3371f6 604 bool success = false;
RobMeades 0:5cffef3371f6 605 int at_timeout;
RobMeades 0:5cffef3371f6 606 LOCK();
RobMeades 0:5cffef3371f6 607
RobMeades 0:5cffef3371f6 608 at_timeout = _at_timeout; // Has to be inside LOCK()s
RobMeades 0:5cffef3371f6 609
RobMeades 0:5cffef3371f6 610 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 611
RobMeades 0:5cffef3371f6 612 /* Initialize GPIO lines */
RobMeades 0:5cffef3371f6 613 tr_info("Powering up modem...");
pilotak 7:c2cf27a981b3 614 modem_init();
RobMeades 0:5cffef3371f6 615 /* Give modem a little time to settle down */
RobMeades 0:5cffef3371f6 616 wait_ms(250);
RobMeades 0:5cffef3371f6 617
RobMeades 0:5cffef3371f6 618 for (int retry_count = 0; !success && (retry_count < 20); retry_count++) {
wajahat.abbas@u-blox.com 16:afb3ca2d9915 619 //In case of SARA-R4, modem takes a while to turn on, constantly toggling the power pin every ~2 secs causes the modem to never power up.
wajahat.abbas@u-blox.com 16:afb3ca2d9915 620 if ( (retry_count % 5) == 0) {
wajahat.abbas@u-blox.com 16:afb3ca2d9915 621 modem_power_up();
wajahat.abbas@u-blox.com 16:afb3ca2d9915 622 }
RobMeades 0:5cffef3371f6 623 wait_ms(500);
RobMeades 0:5cffef3371f6 624 // Modem tends to spit out noise during power up - don't confuse the parser
RobMeades 0:5cffef3371f6 625 _at->flush();
RobMeades 0:5cffef3371f6 626 at_set_timeout(1000);
RobMeades 0:5cffef3371f6 627 if (_at->send("AT")) {
RobMeades 0:5cffef3371f6 628 // C027 needs a delay here
RobMeades 0:5cffef3371f6 629 wait_ms(100);
RobMeades 0:5cffef3371f6 630 if (_at->recv("OK")) {
RobMeades 0:5cffef3371f6 631 success = true;
RobMeades 0:5cffef3371f6 632 }
RobMeades 0:5cffef3371f6 633 }
RobMeades 0:5cffef3371f6 634 at_set_timeout(at_timeout);
RobMeades 0:5cffef3371f6 635 }
RobMeades 0:5cffef3371f6 636
rob.meades@u-blox.com 4:2e640a101db1 637 if (success) {
rob.meades@u-blox.com 4:2e640a101db1 638 // Set the final baud rate
rob.meades@u-blox.com 4:2e640a101db1 639 if (_at->send("AT+IPR=%d", _baud) && _at->recv("OK")) {
rob.meades@u-blox.com 4:2e640a101db1 640 // Need to wait for things to be sorted out on the modem side
rob.meades@u-blox.com 4:2e640a101db1 641 wait_ms(100);
rob.meades@u-blox.com 4:2e640a101db1 642 ((UARTSerial *)_fh)->set_baud(_baud);
rob.meades@u-blox.com 4:2e640a101db1 643 }
rob.meades@u-blox.com 4:2e640a101db1 644
rob.meades@u-blox.com 4:2e640a101db1 645 // Turn off modem echoing and turn on verbose responses
rob.meades@u-blox.com 4:2e640a101db1 646 success = _at->send("ATE0;+CMEE=2") && _at->recv("OK") &&
rob.meades@u-blox.com 4:2e640a101db1 647 // The following commands are best sent separately
rob.meades@u-blox.com 4:2e640a101db1 648 _at->send("AT&K0") && _at->recv("OK") && // Turn off RTC/CTS handshaking
rob.meades@u-blox.com 4:2e640a101db1 649 _at->send("AT&C1") && _at->recv("OK") && // Set DCD circuit(109), changes in accordance with the carrier detect status
rob.meades@u-blox.com 4:2e640a101db1 650 _at->send("AT&D0") && _at->recv("OK"); // Set DTR circuit, we ignore the state change of DTR
rob.meades@u-blox.com 4:2e640a101db1 651 }
RobMeades 0:5cffef3371f6 652
RobMeades 0:5cffef3371f6 653 if (!success) {
RobMeades 0:5cffef3371f6 654 tr_error("Preliminary modem setup failed.");
RobMeades 0:5cffef3371f6 655 }
RobMeades 0:5cffef3371f6 656
RobMeades 0:5cffef3371f6 657 UNLOCK();
RobMeades 0:5cffef3371f6 658 return success;
RobMeades 0:5cffef3371f6 659 }
RobMeades 0:5cffef3371f6 660
RobMeades 0:5cffef3371f6 661 // Power down modem via AT interface.
RobMeades 0:5cffef3371f6 662 void UbloxCellularBase::power_down()
RobMeades 0:5cffef3371f6 663 {
RobMeades 0:5cffef3371f6 664 LOCK();
RobMeades 0:5cffef3371f6 665
RobMeades 0:5cffef3371f6 666 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 667
Mudassar Hussain 17:c6a4d5072589 668 // power-off modem
pilotak 7:c2cf27a981b3 669 modem_power_down();
pilotak 7:c2cf27a981b3 670 modem_deinit();
RobMeades 0:5cffef3371f6 671
Mudassar Hussain 17:c6a4d5072589 672 if (_modem_initialised && (_at != NULL)) {
Mudassar Hussain 17:c6a4d5072589 673 int at_timeout = _at_timeout; // Save previous timeout
wajahat.abbas@u-blox.com 23:eaab8e812a5d 674 _at->set_timeout(1000);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 675 // Check modem is powered off
wajahat.abbas@u-blox.com 23:eaab8e812a5d 676 if(_at->send("AT") && _at->recv("OK")) {
Mudassar Hussain 17:c6a4d5072589 677 _at->send("AT+CPWROFF") && _at->recv("OK");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 678 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 679 _at->set_timeout(at_timeout);
Mudassar Hussain 17:c6a4d5072589 680 }
Mudassar Hussain 17:c6a4d5072589 681
RobMeades 0:5cffef3371f6 682 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 683 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 684 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 685
RobMeades 0:5cffef3371f6 686 UNLOCK();
RobMeades 0:5cffef3371f6 687 }
RobMeades 0:5cffef3371f6 688
RobMeades 0:5cffef3371f6 689 // Get the device ID.
RobMeades 0:5cffef3371f6 690 bool UbloxCellularBase::set_device_identity(DeviceType *dev)
RobMeades 0:5cffef3371f6 691 {
RobMeades 0:5cffef3371f6 692 char buf[20];
RobMeades 0:5cffef3371f6 693 bool success;
RobMeades 0:5cffef3371f6 694 LOCK();
RobMeades 0:5cffef3371f6 695
RobMeades 0:5cffef3371f6 696 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 697
RobMeades 0:5cffef3371f6 698 success = _at->send("ATI") && _at->recv("%19[^\n]\nOK\n", buf);
RobMeades 0:5cffef3371f6 699
RobMeades 0:5cffef3371f6 700 if (success) {
RobMeades 0:5cffef3371f6 701 if (strstr(buf, "SARA-G35"))
RobMeades 0:5cffef3371f6 702 *dev = DEV_SARA_G35;
RobMeades 0:5cffef3371f6 703 else if (strstr(buf, "LISA-U200-03S"))
RobMeades 0:5cffef3371f6 704 *dev = DEV_LISA_U2_03S;
RobMeades 0:5cffef3371f6 705 else if (strstr(buf, "LISA-U2"))
RobMeades 0:5cffef3371f6 706 *dev = DEV_LISA_U2;
RobMeades 0:5cffef3371f6 707 else if (strstr(buf, "SARA-U2"))
RobMeades 0:5cffef3371f6 708 *dev = DEV_SARA_U2;
fahimalavi 10:c4281fa79b8f 709 else if (strstr(buf, "SARA-R4"))
fahimalavi 10:c4281fa79b8f 710 *dev = DEV_SARA_R4;
RobMeades 0:5cffef3371f6 711 else if (strstr(buf, "LEON-G2"))
RobMeades 0:5cffef3371f6 712 *dev = DEV_LEON_G2;
RobMeades 0:5cffef3371f6 713 else if (strstr(buf, "TOBY-L2"))
RobMeades 0:5cffef3371f6 714 *dev = DEV_TOBY_L2;
RobMeades 0:5cffef3371f6 715 else if (strstr(buf, "MPCI-L2"))
RobMeades 0:5cffef3371f6 716 *dev = DEV_MPCI_L2;
RobMeades 0:5cffef3371f6 717 }
RobMeades 0:5cffef3371f6 718
RobMeades 0:5cffef3371f6 719 UNLOCK();
RobMeades 0:5cffef3371f6 720 return success;
RobMeades 0:5cffef3371f6 721 }
RobMeades 0:5cffef3371f6 722
RobMeades 0:5cffef3371f6 723 // Send initialisation AT commands that are specific to the device.
RobMeades 0:5cffef3371f6 724 bool UbloxCellularBase::device_init(DeviceType dev)
RobMeades 0:5cffef3371f6 725 {
RobMeades 0:5cffef3371f6 726 bool success = false;
RobMeades 0:5cffef3371f6 727 LOCK();
RobMeades 0:5cffef3371f6 728
RobMeades 0:5cffef3371f6 729 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 730
RobMeades 0:5cffef3371f6 731 if ((dev == DEV_LISA_U2) || (dev == DEV_LEON_G2) || (dev == DEV_TOBY_L2)) {
RobMeades 0:5cffef3371f6 732 success = _at->send("AT+UGPIOC=20,2") && _at->recv("OK");
RobMeades 0:5cffef3371f6 733 } else if ((dev == DEV_SARA_U2) || (dev == DEV_SARA_G35)) {
RobMeades 0:5cffef3371f6 734 success = _at->send("AT+UGPIOC=16,2") && _at->recv("OK");
RobMeades 0:5cffef3371f6 735 } else {
RobMeades 0:5cffef3371f6 736 success = true;
RobMeades 0:5cffef3371f6 737 }
RobMeades 0:5cffef3371f6 738
RobMeades 0:5cffef3371f6 739 UNLOCK();
RobMeades 0:5cffef3371f6 740 return success;
RobMeades 0:5cffef3371f6 741 }
RobMeades 0:5cffef3371f6 742
RobMeades 0:5cffef3371f6 743 // Get the SIM card going.
RobMeades 0:5cffef3371f6 744 bool UbloxCellularBase::initialise_sim_card()
RobMeades 0:5cffef3371f6 745 {
RobMeades 0:5cffef3371f6 746 bool success = false;
RobMeades 0:5cffef3371f6 747 int retry_count = 0;
RobMeades 0:5cffef3371f6 748 bool done = false;
RobMeades 0:5cffef3371f6 749 LOCK();
RobMeades 0:5cffef3371f6 750
RobMeades 0:5cffef3371f6 751 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 752
RobMeades 0:5cffef3371f6 753 /* SIM initialisation may take a significant amount, so an error is
RobMeades 0:5cffef3371f6 754 * kind of expected. We should retry 10 times until we succeed or timeout. */
RobMeades 0:5cffef3371f6 755 for (retry_count = 0; !done && (retry_count < 10); retry_count++) {
RobMeades 0:5cffef3371f6 756 char pinstr[16];
RobMeades 0:5cffef3371f6 757
RobMeades 0:5cffef3371f6 758 if (_at->send("AT+CPIN?") && _at->recv("+CPIN: %15[^\n]\n", pinstr) &&
RobMeades 0:5cffef3371f6 759 _at->recv("OK")) {
RobMeades 0:5cffef3371f6 760 done = true;
RobMeades 0:5cffef3371f6 761 if (strcmp(pinstr, "SIM PIN") == 0) {
RobMeades 0:5cffef3371f6 762 _sim_pin_check_enabled = true;
RobMeades 0:5cffef3371f6 763 if (_at->send("AT+CPIN=\"%s\"", _pin)) {
RobMeades 0:5cffef3371f6 764 if (_at->recv("OK")) {
RobMeades 0:5cffef3371f6 765 tr_info("PIN correct");
RobMeades 0:5cffef3371f6 766 success = true;
RobMeades 0:5cffef3371f6 767 } else {
RobMeades 0:5cffef3371f6 768 tr_error("Incorrect PIN");
RobMeades 0:5cffef3371f6 769 }
RobMeades 0:5cffef3371f6 770 }
RobMeades 0:5cffef3371f6 771 } else if (strcmp(pinstr, "READY") == 0) {
RobMeades 0:5cffef3371f6 772 _sim_pin_check_enabled = false;
RobMeades 0:5cffef3371f6 773 tr_info("No PIN required");
RobMeades 0:5cffef3371f6 774 success = true;
RobMeades 0:5cffef3371f6 775 } else {
RobMeades 0:5cffef3371f6 776 tr_debug("Unexpected response from SIM: \"%s\"", pinstr);
RobMeades 0:5cffef3371f6 777 }
RobMeades 0:5cffef3371f6 778 }
RobMeades 0:5cffef3371f6 779
RobMeades 0:5cffef3371f6 780 /* wait for a second before retry */
RobMeades 0:5cffef3371f6 781 wait_ms(1000);
RobMeades 0:5cffef3371f6 782 }
RobMeades 0:5cffef3371f6 783
RobMeades 0:5cffef3371f6 784 if (done) {
RobMeades 0:5cffef3371f6 785 tr_info("SIM Ready.");
RobMeades 0:5cffef3371f6 786 } else {
RobMeades 0:5cffef3371f6 787 tr_error("SIM not ready.");
RobMeades 0:5cffef3371f6 788 }
RobMeades 0:5cffef3371f6 789
RobMeades 0:5cffef3371f6 790 UNLOCK();
RobMeades 0:5cffef3371f6 791 return success;
RobMeades 0:5cffef3371f6 792 }
RobMeades 0:5cffef3371f6 793
RobMeades 0:5cffef3371f6 794 /**********************************************************************
RobMeades 0:5cffef3371f6 795 * PUBLIC METHODS
RobMeades 0:5cffef3371f6 796 **********************************************************************/
RobMeades 0:5cffef3371f6 797
RobMeades 0:5cffef3371f6 798 // Initialise the modem.
RobMeades 0:5cffef3371f6 799 bool UbloxCellularBase::init(const char *pin)
RobMeades 0:5cffef3371f6 800 {
RobMeades 8:a15349fcab25 801 int x;
RobMeades 0:5cffef3371f6 802 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 803
RobMeades 0:5cffef3371f6 804 if (!_modem_initialised) {
RobMeades 0:5cffef3371f6 805 if (power_up()) {
RobMeades 0:5cffef3371f6 806 tr_info("Modem Ready.");
RobMeades 0:5cffef3371f6 807 if (pin != NULL) {
RobMeades 0:5cffef3371f6 808 _pin = pin;
RobMeades 0:5cffef3371f6 809 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 810 #ifdef TARGET_UBLOX_C027
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 811 if (set_functionality_mode(FUNC_MIN)) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 812 #else
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 813 if (set_functionality_mode(FUNC_AIRPLANE)) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 814 #endif
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 815 if (initialise_sim_card()) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 816 #ifdef TARGET_UBLOX_C030_R412M
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 817 if (_psm_status == false) { //psm is not enabled by application yet so disable it at start-up
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 818 set_power_saving_mode(0, 0);
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 819 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 820 #endif
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 821 #ifdef TARGET_UBLOX_C030_R41XM
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 822 if (_at->is_idle_mode_enabled() == false) {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 823 set_idle_mode(false); //disable idle mode at start up
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 824 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 825 #endif
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 826 if (set_device_identity(&_dev_info.dev) && // Set up device identity
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 827 device_init(_dev_info.dev)) {// Initialise this device
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 828 // Get the integrated circuit ID of the SIM
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 829 if (get_iccid()) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 830 // Try a few times to get the IMSI (since on some modems this can
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 831 // take a while to be retrieved, especially if a SIM PIN
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 832 // was set)
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 833 for (x = 0; (x < 3) && !get_imsi(); x++) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 834 wait_ms(1000);
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 835 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 836
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 837 if (x < 3) { // If we got the IMSI, can get the others
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 838 if (get_imei() && // Get international mobile equipment identifier
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 839 get_meid() && // Probably the same as the IMEI
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 840 set_sms()) { // And set up SMS
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 841 // The modem is initialised.
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 842 _modem_initialised = true;
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 843 }
rob.meades@u-blox.com 6:8fadf1e49487 844 }
rob.meades@u-blox.com 6:8fadf1e49487 845 }
rob.meades@u-blox.com 6:8fadf1e49487 846 }
RobMeades 0:5cffef3371f6 847 }
RobMeades 0:5cffef3371f6 848 }
RobMeades 0:5cffef3371f6 849 }
RobMeades 0:5cffef3371f6 850 }
RobMeades 0:5cffef3371f6 851
RobMeades 0:5cffef3371f6 852 return _modem_initialised;
RobMeades 0:5cffef3371f6 853 }
RobMeades 0:5cffef3371f6 854
RobMeades 0:5cffef3371f6 855 // Perform registration.
RobMeades 0:5cffef3371f6 856 bool UbloxCellularBase::nwk_registration()
RobMeades 0:5cffef3371f6 857 {
RobMeades 0:5cffef3371f6 858 bool atSuccess = false;
RobMeades 0:5cffef3371f6 859 bool registered = false;
RobMeades 0:5cffef3371f6 860 int status;
RobMeades 0:5cffef3371f6 861 int at_timeout;
RobMeades 0:5cffef3371f6 862 LOCK();
RobMeades 0:5cffef3371f6 863
RobMeades 0:5cffef3371f6 864 at_timeout = _at_timeout; // Has to be inside LOCK()s
RobMeades 0:5cffef3371f6 865
RobMeades 0:5cffef3371f6 866 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 867
RobMeades 0:5cffef3371f6 868 if (!is_registered_psd() && !is_registered_csd() && !is_registered_eps()) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 869 if (set_functionality_mode(FUNC_FULL)) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 870 tr_info("Searching Network...");
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 871 // Enable the packet switched and network registration unsolicited result codes
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 872 if (_at->send("AT+CREG=1") && _at->recv("OK") &&
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 873 _at->send("AT+CGREG=1") && _at->recv("OK")) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 874 atSuccess = true;
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 875 if (_at->send("AT+CEREG=1")) {
RobMeades 0:5cffef3371f6 876 _at->recv("OK");
RobMeades 0:5cffef3371f6 877 // Don't check return value as this works for LTE only
RobMeades 0:5cffef3371f6 878 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 879
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 880 if (atSuccess) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 881 // See if we are already in automatic mode
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 882 if (_at->send("AT+COPS?") && _at->recv("+COPS: %d", &status) &&
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 883 _at->recv("OK")) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 884 // If not, set it
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 885 if (status != 0) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 886 // Don't check return code here as there's not much
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 887 // we can do if this fails.
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 888 _at->send("AT+COPS=0") && _at->recv("OK");
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 889 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 890 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 891
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 892 // Query the registration status directly as well,
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 893 // just in case
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 894 if (_at->send("AT+CREG?") && _at->recv("OK")) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 895 // Answer will be processed by URC
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 896 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 897 if (_at->send("AT+CGREG?") && _at->recv("OK")) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 898 // Answer will be processed by URC
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 899 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 900 if (_at->send("AT+CEREG?")) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 901 _at->recv("OK");
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 902 // Don't check return value as this works for LTE only
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 903 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 904 }
RobMeades 0:5cffef3371f6 905 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 906 // Wait for registration to succeed
RobMeades 0:5cffef3371f6 907 at_set_timeout(1000);
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 908 for (int waitSeconds = 0; !registered && (waitSeconds < 180); waitSeconds++) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 909 registered = is_registered_psd() || is_registered_csd() || is_registered_eps();
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 910 _at->recv(UNNATURAL_STRING);
RobMeades 0:5cffef3371f6 911 }
RobMeades 0:5cffef3371f6 912 at_set_timeout(at_timeout);
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 913
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 914 if (registered) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 915 // This should return quickly but sometimes the status field is not returned
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 916 // so make the timeout short
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 917 at_set_timeout(1000);
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 918 if (_at->send("AT+COPS?") && _at->recv("+COPS: %*d,%*d,\"%*[^\"]\",%d\n", &status)) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 919 set_rat(status);
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 920 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 921 at_set_timeout(at_timeout);
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 922 }
RobMeades 0:5cffef3371f6 923 }
RobMeades 0:5cffef3371f6 924 } else {
RobMeades 0:5cffef3371f6 925 registered = true;
RobMeades 0:5cffef3371f6 926 }
RobMeades 0:5cffef3371f6 927
RobMeades 0:5cffef3371f6 928 UNLOCK();
RobMeades 0:5cffef3371f6 929 return registered;
RobMeades 0:5cffef3371f6 930 }
RobMeades 0:5cffef3371f6 931
RobMeades 0:5cffef3371f6 932 bool UbloxCellularBase::is_registered_csd()
RobMeades 0:5cffef3371f6 933 {
RobMeades 0:5cffef3371f6 934 return (_dev_info.reg_status_csd == CSD_REGISTERED) ||
RobMeades 0:5cffef3371f6 935 (_dev_info.reg_status_csd == CSD_REGISTERED_ROAMING) ||
RobMeades 0:5cffef3371f6 936 (_dev_info.reg_status_csd == CSD_CSFB_NOT_PREFERRED);
RobMeades 0:5cffef3371f6 937 }
RobMeades 0:5cffef3371f6 938
RobMeades 0:5cffef3371f6 939 bool UbloxCellularBase::is_registered_psd()
RobMeades 0:5cffef3371f6 940 {
RobMeades 0:5cffef3371f6 941 return (_dev_info.reg_status_psd == PSD_REGISTERED) ||
RobMeades 0:5cffef3371f6 942 (_dev_info.reg_status_psd == PSD_REGISTERED_ROAMING);
RobMeades 0:5cffef3371f6 943 }
RobMeades 0:5cffef3371f6 944
RobMeades 0:5cffef3371f6 945 bool UbloxCellularBase::is_registered_eps()
RobMeades 0:5cffef3371f6 946 {
RobMeades 0:5cffef3371f6 947 return (_dev_info.reg_status_eps == EPS_REGISTERED) ||
RobMeades 0:5cffef3371f6 948 (_dev_info.reg_status_eps == EPS_REGISTERED_ROAMING);
RobMeades 0:5cffef3371f6 949 }
RobMeades 0:5cffef3371f6 950
RobMeades 0:5cffef3371f6 951 // Perform deregistration.
RobMeades 0:5cffef3371f6 952 bool UbloxCellularBase::nwk_deregistration()
RobMeades 0:5cffef3371f6 953 {
RobMeades 0:5cffef3371f6 954 bool success = false;
RobMeades 0:5cffef3371f6 955 LOCK();
RobMeades 0:5cffef3371f6 956
RobMeades 0:5cffef3371f6 957 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 958
RobMeades 0:5cffef3371f6 959 if (_at->send("AT+COPS=2") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 960 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 961 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 962 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 963 success = true;
RobMeades 0:5cffef3371f6 964 }
RobMeades 0:5cffef3371f6 965
RobMeades 0:5cffef3371f6 966 UNLOCK();
RobMeades 0:5cffef3371f6 967 return success;
RobMeades 0:5cffef3371f6 968 }
RobMeades 0:5cffef3371f6 969
RobMeades 0:5cffef3371f6 970 // Put the modem into its lowest power state.
RobMeades 0:5cffef3371f6 971 void UbloxCellularBase::deinit()
RobMeades 0:5cffef3371f6 972 {
RobMeades 0:5cffef3371f6 973 power_down();
RobMeades 0:5cffef3371f6 974 _modem_initialised = false;
RobMeades 0:5cffef3371f6 975 }
RobMeades 0:5cffef3371f6 976
RobMeades 0:5cffef3371f6 977 // Set the PIN.
RobMeades 0:5cffef3371f6 978 void UbloxCellularBase::set_pin(const char *pin) {
RobMeades 0:5cffef3371f6 979 _pin = pin;
RobMeades 0:5cffef3371f6 980 }
RobMeades 0:5cffef3371f6 981
RobMeades 0:5cffef3371f6 982 // Enable or disable SIM pin checking.
rob.meades@u-blox.com 4:2e640a101db1 983 bool UbloxCellularBase::sim_pin_check_enable(bool enableNotDisable)
RobMeades 0:5cffef3371f6 984 {
RobMeades 0:5cffef3371f6 985 bool success = false;;
RobMeades 0:5cffef3371f6 986 LOCK();
RobMeades 0:5cffef3371f6 987
RobMeades 0:5cffef3371f6 988 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 989
RobMeades 0:5cffef3371f6 990 if (_pin != NULL) {
RobMeades 0:5cffef3371f6 991 if (_sim_pin_check_enabled && !enableNotDisable) {
RobMeades 0:5cffef3371f6 992 // Disable the SIM lock
RobMeades 0:5cffef3371f6 993 if (_at->send("AT+CLCK=\"SC\",0,\"%s\"", _pin) && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 994 _sim_pin_check_enabled = false;
RobMeades 0:5cffef3371f6 995 success = true;
RobMeades 0:5cffef3371f6 996 }
RobMeades 0:5cffef3371f6 997 } else if (!_sim_pin_check_enabled && enableNotDisable) {
RobMeades 0:5cffef3371f6 998 // Enable the SIM lock
RobMeades 0:5cffef3371f6 999 if (_at->send("AT+CLCK=\"SC\",1,\"%s\"", _pin) && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 1000 _sim_pin_check_enabled = true;
RobMeades 0:5cffef3371f6 1001 success = true;
RobMeades 0:5cffef3371f6 1002 }
RobMeades 0:5cffef3371f6 1003 } else {
RobMeades 0:5cffef3371f6 1004 success = true;
RobMeades 0:5cffef3371f6 1005 }
RobMeades 0:5cffef3371f6 1006 }
RobMeades 0:5cffef3371f6 1007
RobMeades 0:5cffef3371f6 1008 UNLOCK();
RobMeades 0:5cffef3371f6 1009 return success;
RobMeades 0:5cffef3371f6 1010 }
RobMeades 0:5cffef3371f6 1011
RobMeades 0:5cffef3371f6 1012 // Change the pin code for the SIM card.
RobMeades 0:5cffef3371f6 1013 bool UbloxCellularBase::change_sim_pin(const char *pin)
RobMeades 0:5cffef3371f6 1014 {
RobMeades 0:5cffef3371f6 1015 bool success = false;;
RobMeades 0:5cffef3371f6 1016 LOCK();
RobMeades 0:5cffef3371f6 1017
RobMeades 0:5cffef3371f6 1018 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 1019
RobMeades 0:5cffef3371f6 1020 // Change the SIM pin
RobMeades 0:5cffef3371f6 1021 if ((pin != NULL) && (_pin != NULL)) {
RobMeades 0:5cffef3371f6 1022 if (_at->send("AT+CPWD=\"SC\",\"%s\",\"%s\"", _pin, pin) && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 1023 _pin = pin;
RobMeades 0:5cffef3371f6 1024 success = true;
RobMeades 0:5cffef3371f6 1025 }
RobMeades 0:5cffef3371f6 1026 }
RobMeades 0:5cffef3371f6 1027
RobMeades 0:5cffef3371f6 1028 UNLOCK();
RobMeades 0:5cffef3371f6 1029 return success;
RobMeades 0:5cffef3371f6 1030 }
RobMeades 0:5cffef3371f6 1031
RobMeades 14:e420232ee4e7 1032 // Get the IMEI.
fahim alavi 13:158a035b1b50 1033 bool UbloxCellularBase::get_imei(char *imei_to_send, int size)
fahim alavi 13:158a035b1b50 1034 {
fahim alavi 13:158a035b1b50 1035 bool success;
fahim alavi 13:158a035b1b50 1036 LOCK();
fahim alavi 13:158a035b1b50 1037
fahim alavi 13:158a035b1b50 1038 MBED_ASSERT(_at != NULL);
fahim alavi 13:158a035b1b50 1039
fahim alavi 13:158a035b1b50 1040 // International mobile equipment identifier
fahim alavi 13:158a035b1b50 1041 // AT Command Manual UBX-13002752, section 4.7
fahim alavi 13:158a035b1b50 1042 success = _at->send("AT+CGSN") && _at->recv("%15[^\n]\nOK\n", _dev_info.imei);
fahim alavi 13:158a035b1b50 1043 tr_info("DevInfo: IMEI=%s", _dev_info.imei);
fahim alavi 13:158a035b1b50 1044
fahim alavi 13:158a035b1b50 1045 if (success) {
fahim alavi 13:158a035b1b50 1046 memcpy(imei_to_send,_dev_info.imei,size);
fahim alavi 13:158a035b1b50 1047 imei_to_send[size-1] = '\0';
fahim alavi 13:158a035b1b50 1048 }
fahim alavi 13:158a035b1b50 1049
fahim alavi 13:158a035b1b50 1050 UNLOCK();
fahim alavi 13:158a035b1b50 1051 return success;
fahim alavi 13:158a035b1b50 1052 }
fahim alavi 13:158a035b1b50 1053
RobMeades 14:e420232ee4e7 1054 // Get the IMEI of the module.
RobMeades 14:e420232ee4e7 1055 const char *UbloxCellularBase::imei()
RobMeades 14:e420232ee4e7 1056 {
RobMeades 14:e420232ee4e7 1057 return _dev_info.imei;
RobMeades 14:e420232ee4e7 1058 }
RobMeades 14:e420232ee4e7 1059
RobMeades 14:e420232ee4e7 1060 // Get the Mobile Equipment ID (which may be the same as the IMEI).
RobMeades 14:e420232ee4e7 1061 const char *UbloxCellularBase::meid()
RobMeades 14:e420232ee4e7 1062 {
RobMeades 14:e420232ee4e7 1063 return _dev_info.meid;
RobMeades 14:e420232ee4e7 1064 }
RobMeades 14:e420232ee4e7 1065
RobMeades 14:e420232ee4e7 1066 // Get the IMSI of the SIM.
RobMeades 14:e420232ee4e7 1067 const char *UbloxCellularBase::imsi()
RobMeades 14:e420232ee4e7 1068 {
RobMeades 14:e420232ee4e7 1069 // (try) to update the IMSI, just in case the SIM has changed
RobMeades 14:e420232ee4e7 1070 get_imsi();
RobMeades 14:e420232ee4e7 1071
RobMeades 14:e420232ee4e7 1072 return _dev_info.imsi;
RobMeades 14:e420232ee4e7 1073 }
RobMeades 14:e420232ee4e7 1074
RobMeades 14:e420232ee4e7 1075 // Get the ICCID of the SIM.
RobMeades 14:e420232ee4e7 1076 const char *UbloxCellularBase::iccid()
RobMeades 14:e420232ee4e7 1077 {
RobMeades 14:e420232ee4e7 1078 // (try) to update the ICCID, just in case the SIM has changed
RobMeades 14:e420232ee4e7 1079 get_iccid();
RobMeades 14:e420232ee4e7 1080
RobMeades 14:e420232ee4e7 1081 return _dev_info.iccid;
RobMeades 14:e420232ee4e7 1082 }
RobMeades 14:e420232ee4e7 1083
RobMeades 14:e420232ee4e7 1084 // Get the RSSI in dBm.
RobMeades 14:e420232ee4e7 1085 int UbloxCellularBase::rssi()
RobMeades 14:e420232ee4e7 1086 {
RobMeades 14:e420232ee4e7 1087 char buf[7] = {0};
RobMeades 14:e420232ee4e7 1088 int rssi = 0;
RobMeades 14:e420232ee4e7 1089 int qual = 0;
RobMeades 14:e420232ee4e7 1090 int rssiRet = 0;
RobMeades 14:e420232ee4e7 1091 bool success;
RobMeades 14:e420232ee4e7 1092 LOCK();
RobMeades 14:e420232ee4e7 1093
RobMeades 14:e420232ee4e7 1094 MBED_ASSERT(_at != NULL);
RobMeades 14:e420232ee4e7 1095
RobMeades 14:e420232ee4e7 1096 success = _at->send("AT+CSQ") && _at->recv("+CSQ: %6[^\n]\nOK\n", buf);
RobMeades 14:e420232ee4e7 1097
RobMeades 14:e420232ee4e7 1098 if (success) {
RobMeades 14:e420232ee4e7 1099 if (sscanf(buf, "%d,%d", &rssi, &qual) == 2) {
RobMeades 14:e420232ee4e7 1100 // AT+CSQ returns a coded RSSI value and an RxQual value
RobMeades 14:e420232ee4e7 1101 // For 2G an RSSI of 0 corresponds to -113 dBm or less,
RobMeades 14:e420232ee4e7 1102 // an RSSI of 31 corresponds to -51 dBm or less and hence
RobMeades 14:e420232ee4e7 1103 // each value is a 2 dB step.
RobMeades 14:e420232ee4e7 1104 // For LTE the mapping is defined in the array rssiConvertLte[].
RobMeades 14:e420232ee4e7 1105 // For 3G the mapping to RSCP is defined in the array rscpConvert3G[]
RobMeades 14:e420232ee4e7 1106 // and the RSSI value is then RSCP - the EC_NO_LEV number derived
RobMeades 14:e420232ee4e7 1107 // by putting the qual number through qualConvert3G[].
RobMeades 14:e420232ee4e7 1108 if ((rssi >= 0) && (rssi <= 31)) {
RobMeades 14:e420232ee4e7 1109 switch (_dev_info.rat) {
RobMeades 14:e420232ee4e7 1110 case UTRAN:
RobMeades 14:e420232ee4e7 1111 case HSDPA:
RobMeades 14:e420232ee4e7 1112 case HSUPA:
RobMeades 14:e420232ee4e7 1113 case HSDPA_HSUPA:
RobMeades 14:e420232ee4e7 1114 // 3G
RobMeades 14:e420232ee4e7 1115 if ((qual >= 0) && (qual <= 7)) {
RobMeades 14:e420232ee4e7 1116 qual = qualConvert3G[qual];
fahim.alavi@u-blox.com 15:93b157a47b8d 1117 rssiRet = rscpConvert3G[rssi];
fahim.alavi@u-blox.com 15:93b157a47b8d 1118 rssiRet -= qual;
RobMeades 14:e420232ee4e7 1119 }
fahim.alavi@u-blox.com 15:93b157a47b8d 1120
RobMeades 14:e420232ee4e7 1121 break;
RobMeades 14:e420232ee4e7 1122 case LTE:
RobMeades 14:e420232ee4e7 1123 // LTE
RobMeades 14:e420232ee4e7 1124 rssiRet = rssiConvertLte[rssi];
RobMeades 14:e420232ee4e7 1125 break;
RobMeades 14:e420232ee4e7 1126 case GSM:
RobMeades 14:e420232ee4e7 1127 case COMPACT_GSM:
RobMeades 14:e420232ee4e7 1128 case EDGE:
RobMeades 14:e420232ee4e7 1129 default:
RobMeades 14:e420232ee4e7 1130 // GSM or assumed GSM if the RAT is not known
RobMeades 14:e420232ee4e7 1131 rssiRet = -(113 - (rssi << 2));
RobMeades 14:e420232ee4e7 1132 break;
RobMeades 14:e420232ee4e7 1133 }
RobMeades 14:e420232ee4e7 1134 }
RobMeades 14:e420232ee4e7 1135 }
RobMeades 14:e420232ee4e7 1136 }
RobMeades 14:e420232ee4e7 1137
RobMeades 14:e420232ee4e7 1138 UNLOCK();
RobMeades 14:e420232ee4e7 1139 return rssiRet;
RobMeades 14:e420232ee4e7 1140 }
RobMeades 14:e420232ee4e7 1141
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1142 //RAT should be set in a detached state (AT+COPS=2)
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1143 bool UbloxCellularBase::set_modem_rat(RAT selected_rat, RAT preferred_rat, RAT second_preferred_rat)
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1144 {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1145 bool success = false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1146 char command[16] = {0x00};
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1147
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1148 //check if modem is registered with network
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1149 if (is_registered_csd() || is_registered_psd() || is_registered_eps()) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1150 tr_error("RAT should only be set in detached state");
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1151 return false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1152 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1153
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1154 if (preferred_rat != NOT_USED && second_preferred_rat != NOT_USED) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1155 sprintf(command, "AT+URAT=%d,%d,%d", selected_rat, preferred_rat, second_preferred_rat);
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1156 } else if (preferred_rat != NOT_USED) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1157 sprintf(command, "AT+URAT=%d,%d", selected_rat, preferred_rat);
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1158 } else if (second_preferred_rat != NOT_USED) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1159 sprintf(command, "AT+URAT=%d,%d", selected_rat, second_preferred_rat);
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1160 } else {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1161 sprintf(command, "AT+URAT=%d", selected_rat);
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1162 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1163
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1164 LOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1165 if (_at->send(command) && _at->recv("OK")) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1166 success = true;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1167 } else {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1168 tr_error("unable to set the specified RAT");
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1169 success = false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1170 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1171 UNLOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1172
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1173 return success;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1174 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1175
wajahat.abbas@u-blox.com 22:779971811c46 1176 bool UbloxCellularBase::get_modem_rat(int *selected_rat, int *preferred_rat, int *second_preferred_rat)
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1177 {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1178 bool success = false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1179 char buf[24] = {0x00};
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1180
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1181 if (selected_rat == NULL || preferred_rat == NULL || second_preferred_rat == NULL) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1182 tr_info("invalid pointers");
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1183 return false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1184 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1185
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1186 MBED_ASSERT(_at != NULL);
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1187
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1188 *selected_rat = NOT_USED;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1189 *preferred_rat = NOT_USED;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1190 *second_preferred_rat = NOT_USED;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1191
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1192 LOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1193
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1194 if (_at->send("AT+URAT?") && _at->recv("%23[^\n]\nOK\n", buf)) {
wajahat.abbas@u-blox.com 22:779971811c46 1195 if (sscanf(buf, "+URAT: %d,%d,%d", selected_rat, preferred_rat, second_preferred_rat) == 3) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1196 success = true;
wajahat.abbas@u-blox.com 22:779971811c46 1197 } else if (sscanf(buf, "+URAT: %d,%d", selected_rat, preferred_rat) == 2) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1198 success = true;
wajahat.abbas@u-blox.com 22:779971811c46 1199 } else if (sscanf(buf, "+URAT: %d", selected_rat) == 1) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1200 success = true;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1201 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1202 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1203
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1204 UNLOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1205 return success;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1206 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1207
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1208 //application should call init() or connect() in order to initialize the modem
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1209 bool UbloxCellularBase::reboot_modem()
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1210 {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1211 return (set_functionality_mode(FUNC_RESET));
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1212 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1213
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1214 bool UbloxCellularBase::set_functionality_mode(FunctionalityMode mode)
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1215 {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1216 bool return_val = false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1217 int at_timeout;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1218 LOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1219
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1220 MBED_ASSERT(_at != NULL);
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1221
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1222 at_timeout = _at_timeout; // Has to be inside LOCK()s
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1223 at_set_timeout(3*60*1000); //command has 3 minutes timeout
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1224
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1225 if (_at->send("AT+CFUN=%d", mode) && _at->recv("OK")) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1226 return_val = true;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1227 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1228
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1229 if (mode == FUNC_RESET || mode == FUNC_RESET_WITH_SIM) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1230 _modem_initialised = false;
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1231 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1232
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1233 at_set_timeout(at_timeout);
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1234 UNLOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1235
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1236 return return_val;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1237 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1238
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1239 bool UbloxCellularBase::get_functionality_mode(int *mode)
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1240 {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1241 bool return_val = false;
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1242
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1243 if (mode == NULL) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1244 return false;
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1245 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1246
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1247 LOCK();
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1248 MBED_ASSERT(_at != NULL);
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1249
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1250 if ( (_at->send("AT+CFUN?") && _at->recv("+CFUN: %d", mode) && _at->recv("OK")) ) {
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1251 return_val = true;
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1252 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1253
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1254 UNLOCK();
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1255 return return_val;
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1256 }
wajahat.abbas@u-blox.com 24:e26a6ab0dd75 1257
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1258 #ifdef TARGET_UBLOX_C030_R41XM
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1259 bool UbloxCellularBase::set_mno_profile(MNOProfile profile)
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1260 {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1261 bool return_val = false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1262
wajahat.abbas@u-blox.com 22:779971811c46 1263 int mno_profile;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1264 if (get_mno_profile(&mno_profile)) {
wajahat.abbas@u-blox.com 22:779971811c46 1265 tr_info("Current MNO profile is: %d", mno_profile);
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1266 if (mno_profile != profile) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1267
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1268 if (is_registered_csd() || is_registered_psd() || is_registered_eps()) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1269 tr_error("MNO profile should only be set in detached state");
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1270 return false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1271 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1272
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1273 LOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1274 if (_at->send("AT+UMNOPROF=%d", profile) && _at->recv("OK")) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1275 return_val = true;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1276 } else {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1277 tr_error("unable to set specified profile");
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1278 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1279 UNLOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1280
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1281 } else {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1282 return_val = true;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1283 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1284 } else {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1285 tr_error("could not read MNO profile");
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1286 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1287
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1288 return return_val;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1289 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1290
wajahat.abbas@u-blox.com 22:779971811c46 1291 bool UbloxCellularBase::get_mno_profile(int *profile)
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1292 {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1293 bool return_val = false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1294
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1295 if (profile == NULL) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1296 return false;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1297 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1298
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1299 LOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1300 MBED_ASSERT(_at != NULL);
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1301
wajahat.abbas@u-blox.com 22:779971811c46 1302 if ( (_at->send("AT+UMNOPROF?") && _at->recv("+UMNOPROF: %d", profile) && _at->recv("OK")) ) {
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1303 return_val = true;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1304 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1305
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1306 UNLOCK();
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1307 return return_val;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1308 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1309 // Enable or Disable the UPSV power saving mode
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1310 bool UbloxCellularBase::set_idle_mode(bool enable)
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1311 {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1312 #ifdef TARGET_UBLOX_C030_R412M
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1313 if (_psm_status == true && enable == true) {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1314 return false;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1315 }
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1316 #endif
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1317
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1318 bool success = false;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1319 LOCK();
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1320
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1321 MBED_ASSERT(_at != NULL);
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1322
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1323 if (_at->send("AT+UPSV=%d", enable ? 4 : 0) && _at->recv("OK")) {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1324 if (enable == true) {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1325 _at->idle_mode_enabled();
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1326 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1327 else {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1328 _at->idle_mode_disabled();
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1329 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1330 success = true;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1331 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1332
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1333 UNLOCK();
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1334 return success;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1335 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1336
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1337 bool UbloxCellularBase::get_idle_mode(int *status)
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1338 {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1339 bool return_val = false;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1340
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1341 if (status == NULL) {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1342 return false;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1343 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1344
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1345 LOCK();
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1346 MBED_ASSERT(_at != NULL);
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1347
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1348 if ( (_at->send("AT+UPSV?") && _at->recv("+UPSV: %d", status) && _at->recv("OK")) ) {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1349 if (*status == 4) {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1350 *status = 1;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1351 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1352 return_val = true;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1353 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1354
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1355 UNLOCK();
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1356 return return_val;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1357 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1358 #endif
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1359
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1360 #ifdef TARGET_UBLOX_C030_R412M
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1361 bool UbloxCellularBase::get_power_saving_mode(int *status, int *periodic_time, int *active_time)
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1362 {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1363 char pt_encoded[8+1];// timer value encoded as 3GPP IE
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1364 char at_encoded[8+1];// timer value encoded as 3GPP IE
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1365 int value, multiplier;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1366 bool return_val;
wajahat.abbas@u-blox.com 20:31d5e048fbfa 1367
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1368 if (status == NULL || periodic_time == NULL || active_time == NULL) {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1369 return false;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1370 }
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1371
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1372 LOCK();
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1373 //+UCPSMS:1,,,"01000011","01000011"
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1374 if (_at->send("AT+UCPSMS?") && _at->recv("+UCPSMS:%d,,,\"%8c\",\"%8c\"\n", status, pt_encoded, at_encoded)) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1375 if (*status == true) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1376 //PSM is enabled, decode the timer values, periodic TAU first
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1377 value = (pt_encoded[7]- '0');
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1378 value += (pt_encoded[6]- '0') << 1;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1379 value += (pt_encoded[5]- '0') << 2;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1380 value += (pt_encoded[4]- '0') << 3;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1381 value += (pt_encoded[3]- '0') << 4;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1382
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1383 multiplier = (pt_encoded[2]- '0');
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1384 multiplier += (pt_encoded[1]- '0') << 1;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1385 multiplier += (pt_encoded[0]- '0') << 2;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1386
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1387 switch(multiplier) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1388 //10 minutes
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1389 case 0:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1390 value = value*10*60;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1391 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1392
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1393 //1 hour
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1394 case 1:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1395 value = value*60*60;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1396 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1397
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1398 //10 hours
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1399 case 2:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1400 value = value*10*60*60;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1401 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1402
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1403 //2 seconds
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1404 case 3:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1405 value = value*2;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1406 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1407
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1408 //30 seconds
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1409 case 4:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1410 value = value*30;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1411 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1412
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1413 //1 minute
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1414 case 5:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1415 value = value*60;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1416 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1417
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1418 //320 hours
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1419 case 6:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1420 value = value*320*60*60;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1421 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1422
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1423 default:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1424 value = 0;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1425 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1426 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1427 *periodic_time = value;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1428
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1429 //decode the active time
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1430 value = (at_encoded[7]- '0');
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1431 value += (at_encoded[6]- '0') << 1;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1432 value += (at_encoded[5]- '0') << 2;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1433 value += (at_encoded[4]- '0') << 3;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1434 value += (at_encoded[3]- '0') << 4;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1435
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1436 multiplier = (at_encoded[2]- '0');
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1437 multiplier += (at_encoded[1]- '0') << 1;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1438 multiplier += (at_encoded[0]- '0') << 2;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1439
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1440 switch(multiplier) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1441 //2 seconds
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1442 case 0:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1443 value = value*2;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1444 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1445
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1446 //1 minute
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1447 case 1:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1448 value = value*60;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1449 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1450
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1451 //decihours (6minutes)
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1452 case 2:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1453 value = value*6*60;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1454 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1455
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1456 default:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1457 value = 0;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1458 break;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1459 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1460 *active_time = value;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1461 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1462 return_val = true;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1463 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1464 return_val = false;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1465 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1466 UNLOCK();
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1467 return return_val;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1468 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1469
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1470 bool UbloxCellularBase::set_power_saving_mode(int periodic_time, int active_time)
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1471 {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1472 if (_at->is_idle_mode_enabled() == true && periodic_time != 0 && active_time != 0 ) {
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1473 return false;
wajahat.abbas@u-blox.com 25:e67d3d9d2e7e 1474 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1475 bool return_val = false;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1476
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1477 LOCK();
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1478 int at_timeout = _at_timeout;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1479 at_set_timeout(10000); //AT+CPSMS has response time of < 10s
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1480
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1481 //check if modem supports PSM URCs
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1482 if (_at->send("AT+UPSMR?") && _at->recv("OK")) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1483 if (periodic_time == 0 && active_time == 0) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1484 // disable PSM
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1485 if (_at->send("AT+CPSMS=0") && _at->recv("OK")) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1486 if (_at->send("AT+UPSMR=0") && _at->recv("OK")) {//disable the URC
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1487 //de-register the callback
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1488 detach_cb_psm_going_in();
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1489 detach_cb_psm_coming_out();
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1490 _psm_status = false;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1491 return_val = true;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1492 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1493 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1494 } else { //PSM string encoding code borrowed from AT_CellularPower.cpp
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1495 /**
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1496 Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1497
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1498 Bits 5 to 1 represent the binary coded timer value.
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1499
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1500 Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1501 8 7 6
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1502 0 0 0 value is incremented in multiples of 10 minutes
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1503 0 0 1 value is incremented in multiples of 1 hour
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1504 0 1 0 value is incremented in multiples of 10 hours
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1505 0 1 1 value is incremented in multiples of 2 seconds
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1506 1 0 0 value is incremented in multiples of 30 seconds
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1507 1 0 1 value is incremented in multiples of 1 minute
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1508 1 1 0 value is incremented in multiples of 320 hours (NOTE 1)
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1509 1 1 1 value indicates that the timer is deactivated (NOTE 2).
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1510 */
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1511 char pt[8+1];// timer value encoded as 3GPP IE
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1512 const int ie_value_max = 0x1f;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1513 uint32_t periodic_timer = 0;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1514 if (periodic_time <= 2*ie_value_max) { // multiples of 2 seconds
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1515 periodic_timer = periodic_time/2;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1516 strcpy(pt, "01100000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1517 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1518 if (periodic_time <= 30*ie_value_max) { // multiples of 30 seconds
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1519 periodic_timer = periodic_time/30;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1520 strcpy(pt, "10000000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1521 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1522 if (periodic_time <= 60*ie_value_max) { // multiples of 1 minute
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1523 periodic_timer = periodic_time/60;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1524 strcpy(pt, "10100000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1525 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1526 if (periodic_time <= 10*60*ie_value_max) { // multiples of 10 minutes
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1527 periodic_timer = periodic_time/(10*60);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1528 strcpy(pt, "00000000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1529 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1530 if (periodic_time <= 60*60*ie_value_max) { // multiples of 1 hour
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1531 periodic_timer = periodic_time/(60*60);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1532 strcpy(pt, "00100000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1533 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1534 if (periodic_time <= 10*60*60*ie_value_max) { // multiples of 10 hours
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1535 periodic_timer = periodic_time/(10*60*60);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1536 strcpy(pt, "01000000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1537 } else { // multiples of 320 hours
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1538 int t = periodic_time / (320*60*60);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1539 if (t > ie_value_max) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1540 t = ie_value_max;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1541 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1542 periodic_timer = t;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1543 strcpy(pt, "11000000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1544 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1545 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1546 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1547 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1548 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1549 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1550
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1551 uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt)-3, 5);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1552 pt[8] = '\0';
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1553
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1554 /**
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1555 Table 10.5.172/3GPP TS 24.008: GPRS Timer information element
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1556
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1557 Bits 5 to 1 represent the binary coded timer value.
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1558
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1559 Bits 6 to 8 defines the timer value unit for the GPRS timer as follows:
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1560
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1561 8 7 6
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1562 0 0 0 value is incremented in multiples of 2 seconds
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1563 0 0 1 value is incremented in multiples of 1 minute
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1564 0 1 0 value is incremented in multiples of decihours
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1565 1 1 1 value indicates that the timer is deactivated.
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1566
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1567 Other values shall be interpreted as multiples of 1 minute in this version of the protocol.
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1568 */
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1569 char at[8+1];
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1570 uint32_t active_timer; // timer value encoded as 3GPP IE
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1571 if (active_time <= 2*ie_value_max) { // multiples of 2 seconds
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1572 active_timer = active_time/2;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1573 strcpy(at, "00000000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1574 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1575 if (active_time <= 60*ie_value_max) { // multiples of 1 minute
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1576 active_timer = (1<<5) | (active_time/60);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1577 strcpy(at, "00100000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1578 } else { // multiples of decihours
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1579 int t = active_time / (6*60);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1580 if (t > ie_value_max) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1581 t = ie_value_max;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1582 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1583 active_timer = t;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1584 strcpy(at, "01000000");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1585 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1586 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1587
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1588 uint_to_binary_str(active_timer, &at[3], sizeof(at)-3, 5);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1589 at[8] = '\0';
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1590
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1591 if (_at->send("AT+CPSMS=1,,,\"%s\",\"%s\"", pt, at) && _at->recv("OK")) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1592 if (_at->send("AT+UPSMR=1") && _at->recv("OK")) {//enable the PSM URC
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1593 tr_info("PSM enabled successfully!");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1594 _psm_status = true;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1595 return_val = true;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1596 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1597 tr_error("PSM URCs not supported");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1598 return_val = false;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1599 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1600 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1601 tr_error("+CPSMS command failed");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1602 return_val = false;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1603 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1604 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1605 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1606 tr_error("PSM URCs not supported by this version of modem");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1607 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1608 at_set_timeout(at_timeout);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1609 UNLOCK();
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1610 return return_val;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1611 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1612
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1613 void UbloxCellularBase::uint_to_binary_str(uint32_t num, char* str, int str_size, int bit_cnt)
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1614 {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1615 if (!str || str_size < bit_cnt) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1616 return;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1617 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1618 int tmp, pos = 0;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1619
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1620 for (int i = 31; i >= 0; i--) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1621 tmp = num >> i;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1622 if (i < bit_cnt) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1623 if (tmp&1) {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1624 str[pos] = 1 + '0';
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1625 } else {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1626 str[pos] = 0 + '0';
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1627 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1628 pos++;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1629 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1630 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1631 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1632
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1633 bool UbloxCellularBase::is_modem_awake()
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1634 {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1635 return (_dev_info.modem_psm_state == AWAKE);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1636 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1637
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1638 //application should call init() or connect() in order to initialize the modem
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1639 void UbloxCellularBase::wakeup_modem()
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1640 {
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1641 LOCK();
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1642
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1643 MBED_ASSERT(_at != NULL);
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1644
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1645 tr_info("Waking up modem...");
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1646
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1647 modem_power_up();
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1648
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1649 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1650 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1651 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1652 _modem_initialised = false;
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1653
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1654 UNLOCK();
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1655 }
wajahat.abbas@u-blox.com 23:eaab8e812a5d 1656 #endif
RobMeades 0:5cffef3371f6 1657 // End of File
RobMeades 0:5cffef3371f6 1658