Fork of ublox-cellular-base to add LARA-R2 support

Fork of ublox-cellular-base by u-blox

Committer:
Curt Black
Date:
Fri Oct 12 02:17:18 2018 -0500
Revision:
19:98e4136e3980
Parent:
17:a01b693a2e63
Child:
20:9fedc922868e
Increase default timeout for AT commands, many can take up to a minute.
Some modems cannot auto-baud (R410), even below 115200, so if the baud
is not 115200 (not just greater than), start at 115200 then switch later

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
RobMeades 14:e420232ee4e7 146 void UbloxCellularBase::set_rat(int acTStatus)
RobMeades 0:5cffef3371f6 147 {
RobMeades 14:e420232ee4e7 148 switch (acTStatus) {
RobMeades 0:5cffef3371f6 149 case GSM:
RobMeades 0:5cffef3371f6 150 case COMPACT_GSM:
RobMeades 0:5cffef3371f6 151 tr_info("Connected in GSM");
RobMeades 0:5cffef3371f6 152 break;
RobMeades 0:5cffef3371f6 153 case UTRAN:
RobMeades 0:5cffef3371f6 154 tr_info("Connected to UTRAN");
RobMeades 0:5cffef3371f6 155 break;
RobMeades 0:5cffef3371f6 156 case EDGE:
RobMeades 0:5cffef3371f6 157 tr_info("Connected to EDGE");
RobMeades 0:5cffef3371f6 158 break;
RobMeades 0:5cffef3371f6 159 case HSDPA:
RobMeades 0:5cffef3371f6 160 tr_info("Connected to HSDPA");
RobMeades 0:5cffef3371f6 161 break;
RobMeades 0:5cffef3371f6 162 case HSUPA:
RobMeades 0:5cffef3371f6 163 tr_info("Connected to HSPA");
RobMeades 0:5cffef3371f6 164 break;
RobMeades 0:5cffef3371f6 165 case HSDPA_HSUPA:
RobMeades 0:5cffef3371f6 166 tr_info("Connected to HDPA/HSPA");
RobMeades 0:5cffef3371f6 167 break;
RobMeades 0:5cffef3371f6 168 case LTE:
RobMeades 0:5cffef3371f6 169 tr_info("Connected to LTE");
RobMeades 0:5cffef3371f6 170 break;
fahimalavi 10:c4281fa79b8f 171 case EC_GSM_IoT:
fahimalavi 10:c4281fa79b8f 172 tr_info("Connected to EC_GSM_IoT");
fahimalavi 10:c4281fa79b8f 173 break;
fahimalavi 10:c4281fa79b8f 174 case E_UTRAN_NB_S1:
fahimalavi 10:c4281fa79b8f 175 tr_info("Connected to E_UTRAN NB1");
fahimalavi 10:c4281fa79b8f 176 break;
RobMeades 0:5cffef3371f6 177 default:
RobMeades 14:e420232ee4e7 178 tr_info("Unknown RAT %d", acTStatus);
RobMeades 0:5cffef3371f6 179 break;
RobMeades 0:5cffef3371f6 180 }
RobMeades 0:5cffef3371f6 181
RobMeades 14:e420232ee4e7 182 _dev_info.rat = static_cast<RadioAccessNetworkType>(acTStatus);
RobMeades 0:5cffef3371f6 183 }
RobMeades 0:5cffef3371f6 184
RobMeades 0:5cffef3371f6 185 bool UbloxCellularBase::get_iccid()
RobMeades 0:5cffef3371f6 186 {
RobMeades 0:5cffef3371f6 187 bool success;
RobMeades 0:5cffef3371f6 188 LOCK();
RobMeades 0:5cffef3371f6 189
RobMeades 0:5cffef3371f6 190 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 191
RobMeades 0:5cffef3371f6 192 // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
RobMeades 0:5cffef3371f6 193 // ICCID is a serial number identifying the SIM.
RobMeades 0:5cffef3371f6 194 // AT Command Manual UBX-13002752, section 4.12
RobMeades 0:5cffef3371f6 195 success = _at->send("AT+CCID") && _at->recv("+CCID: %20[^\n]\nOK\n", _dev_info.iccid);
RobMeades 0:5cffef3371f6 196 tr_info("DevInfo: ICCID=%s", _dev_info.iccid);
RobMeades 0:5cffef3371f6 197
RobMeades 0:5cffef3371f6 198 UNLOCK();
RobMeades 0:5cffef3371f6 199 return success;
RobMeades 0:5cffef3371f6 200 }
RobMeades 0:5cffef3371f6 201
RobMeades 0:5cffef3371f6 202 bool UbloxCellularBase::get_imsi()
RobMeades 0:5cffef3371f6 203 {
RobMeades 0:5cffef3371f6 204 bool success;
RobMeades 0:5cffef3371f6 205 LOCK();
RobMeades 0:5cffef3371f6 206
RobMeades 0:5cffef3371f6 207 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 208
RobMeades 0:5cffef3371f6 209 // International mobile subscriber identification
RobMeades 0:5cffef3371f6 210 // AT Command Manual UBX-13002752, section 4.11
RobMeades 0:5cffef3371f6 211 success = _at->send("AT+CIMI") && _at->recv("%15[^\n]\nOK\n", _dev_info.imsi);
RobMeades 0:5cffef3371f6 212 tr_info("DevInfo: IMSI=%s", _dev_info.imsi);
RobMeades 0:5cffef3371f6 213
RobMeades 0:5cffef3371f6 214 UNLOCK();
RobMeades 0:5cffef3371f6 215 return success;
RobMeades 0:5cffef3371f6 216 }
RobMeades 0:5cffef3371f6 217
RobMeades 0:5cffef3371f6 218 bool UbloxCellularBase::get_imei()
RobMeades 0:5cffef3371f6 219 {
RobMeades 0:5cffef3371f6 220 bool success;
RobMeades 0:5cffef3371f6 221 LOCK();
RobMeades 0:5cffef3371f6 222
RobMeades 0:5cffef3371f6 223 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 224
RobMeades 0:5cffef3371f6 225 // International mobile equipment identifier
RobMeades 0:5cffef3371f6 226 // AT Command Manual UBX-13002752, section 4.7
RobMeades 0:5cffef3371f6 227 success = _at->send("AT+CGSN") && _at->recv("%15[^\n]\nOK\n", _dev_info.imei);
RobMeades 0:5cffef3371f6 228 tr_info("DevInfo: IMEI=%s", _dev_info.imei);
RobMeades 0:5cffef3371f6 229
RobMeades 0:5cffef3371f6 230 UNLOCK();
RobMeades 0:5cffef3371f6 231 return success;
RobMeades 0:5cffef3371f6 232 }
RobMeades 0:5cffef3371f6 233
RobMeades 0:5cffef3371f6 234 bool UbloxCellularBase::get_meid()
RobMeades 0:5cffef3371f6 235 {
RobMeades 0:5cffef3371f6 236 bool success;
RobMeades 0:5cffef3371f6 237 LOCK();
RobMeades 0:5cffef3371f6 238
RobMeades 0:5cffef3371f6 239 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 240
RobMeades 0:5cffef3371f6 241 // Mobile equipment identifier
RobMeades 0:5cffef3371f6 242 // AT Command Manual UBX-13002752, section 4.8
RobMeades 0:5cffef3371f6 243 success = _at->send("AT+GSN") && _at->recv("%18[^\n]\nOK\n", _dev_info.meid);
RobMeades 0:5cffef3371f6 244 tr_info("DevInfo: MEID=%s", _dev_info.meid);
RobMeades 0:5cffef3371f6 245
RobMeades 0:5cffef3371f6 246 UNLOCK();
RobMeades 0:5cffef3371f6 247 return success;
RobMeades 0:5cffef3371f6 248 }
RobMeades 0:5cffef3371f6 249
RobMeades 0:5cffef3371f6 250 bool UbloxCellularBase::set_sms()
RobMeades 0:5cffef3371f6 251 {
RobMeades 0:5cffef3371f6 252 bool success = false;
RobMeades 0:5cffef3371f6 253 char buf[32];
RobMeades 0:5cffef3371f6 254 LOCK();
RobMeades 0:5cffef3371f6 255
RobMeades 0:5cffef3371f6 256 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 257
RobMeades 0:5cffef3371f6 258 // Set up SMS format and enable URC
RobMeades 0:5cffef3371f6 259 // AT Command Manual UBX-13002752, section 11
RobMeades 0:5cffef3371f6 260 if (_at->send("AT+CMGF=1") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 261 tr_debug("SMS in text mode");
RobMeades 0:5cffef3371f6 262 if (_at->send("AT+CNMI=2,1") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 263 tr_debug("SMS URC enabled");
RobMeades 0:5cffef3371f6 264 // Set to CS preferred since PS preferred doesn't work
RobMeades 0:5cffef3371f6 265 // on some networks
RobMeades 0:5cffef3371f6 266 if (_at->send("AT+CGSMS=1") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 267 tr_debug("SMS set to CS preferred");
RobMeades 0:5cffef3371f6 268 success = true;
RobMeades 0:5cffef3371f6 269 memset (buf, 0, sizeof (buf));
RobMeades 0:5cffef3371f6 270 if (_at->send("AT+CSCA?") &&
RobMeades 0:5cffef3371f6 271 _at->recv("+CSCA: \"%31[^\"]\"", buf) &&
RobMeades 0:5cffef3371f6 272 _at->recv("OK")) {
RobMeades 0:5cffef3371f6 273 tr_info("SMS Service Centre address is \"%s\"", buf);
RobMeades 0:5cffef3371f6 274 }
RobMeades 0:5cffef3371f6 275 }
RobMeades 0:5cffef3371f6 276 }
RobMeades 0:5cffef3371f6 277 }
RobMeades 0:5cffef3371f6 278
RobMeades 0:5cffef3371f6 279 UNLOCK();
RobMeades 0:5cffef3371f6 280 return success;
RobMeades 0:5cffef3371f6 281 }
RobMeades 0:5cffef3371f6 282
RobMeades 0:5cffef3371f6 283 void UbloxCellularBase::parser_abort_cb()
RobMeades 0:5cffef3371f6 284 {
RobMeades 0:5cffef3371f6 285 _at->abort();
RobMeades 0:5cffef3371f6 286 }
RobMeades 0:5cffef3371f6 287
RobMeades 0:5cffef3371f6 288 // Callback for CME ERROR and CMS ERROR.
RobMeades 0:5cffef3371f6 289 void UbloxCellularBase::CMX_ERROR_URC()
RobMeades 0:5cffef3371f6 290 {
RobMeades 0:5cffef3371f6 291 char buf[48];
RobMeades 0:5cffef3371f6 292
RobMeades 0:5cffef3371f6 293 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 0:5cffef3371f6 294 tr_debug("AT error %s", buf);
RobMeades 0:5cffef3371f6 295 }
RobMeades 0:5cffef3371f6 296 parser_abort_cb();
RobMeades 0:5cffef3371f6 297 }
RobMeades 0:5cffef3371f6 298
RobMeades 0:5cffef3371f6 299 // Callback for circuit switched registration URC.
RobMeades 0:5cffef3371f6 300 void UbloxCellularBase::CREG_URC()
RobMeades 0:5cffef3371f6 301 {
RobMeades 0:5cffef3371f6 302 char buf[10];
RobMeades 0:5cffef3371f6 303 int status;
RobMeades 14:e420232ee4e7 304 int acTStatus;
RobMeades 0:5cffef3371f6 305
RobMeades 0:5cffef3371f6 306 // If this is the URC it will be a single
RobMeades 0:5cffef3371f6 307 // digit followed by \n. If it is the
RobMeades 0:5cffef3371f6 308 // answer to a CREG query, it will be
RobMeades 0:5cffef3371f6 309 // a ": %d,%d\n" where the second digit
RobMeades 0:5cffef3371f6 310 // indicates the status
RobMeades 0:5cffef3371f6 311 // Note: not calling _at->recv() from here as we're
RobMeades 0:5cffef3371f6 312 // already in an _at->recv()
RobMeades 0:5cffef3371f6 313 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 14:e420232ee4e7 314 if (sscanf(buf, ": %*d,%d,%*d,%*d,%d,", &status, &acTStatus) == 2) {
RobMeades 14:e420232ee4e7 315 set_nwk_reg_status_csd(status);
RobMeades 14:e420232ee4e7 316 set_rat(acTStatus);
RobMeades 14:e420232ee4e7 317 } else if (sscanf(buf, ": %*d,%d", &status) == 1) {
RobMeades 0:5cffef3371f6 318 set_nwk_reg_status_csd(status);
RobMeades 0:5cffef3371f6 319 } else if (sscanf(buf, ": %d", &status) == 1) {
RobMeades 0:5cffef3371f6 320 set_nwk_reg_status_csd(status);
RobMeades 0:5cffef3371f6 321 }
RobMeades 0:5cffef3371f6 322 }
RobMeades 0:5cffef3371f6 323 }
RobMeades 0:5cffef3371f6 324
RobMeades 0:5cffef3371f6 325 // Callback for packet switched registration URC.
RobMeades 0:5cffef3371f6 326 void UbloxCellularBase::CGREG_URC()
RobMeades 0:5cffef3371f6 327 {
RobMeades 0:5cffef3371f6 328 char buf[10];
RobMeades 0:5cffef3371f6 329 int status;
RobMeades 14:e420232ee4e7 330 int acTStatus;
RobMeades 0:5cffef3371f6 331
RobMeades 0:5cffef3371f6 332 // If this is the URC it will be a single
RobMeades 0:5cffef3371f6 333 // digit followed by \n. If it is the
RobMeades 0:5cffef3371f6 334 // answer to a CGREG query, it will be
RobMeades 0:5cffef3371f6 335 // a ": %d,%d\n" where the second digit
RobMeades 0:5cffef3371f6 336 // indicates the status
RobMeades 0:5cffef3371f6 337 // Note: not calling _at->recv() from here as we're
RobMeades 0:5cffef3371f6 338 // already in an _at->recv()
RobMeades 0:5cffef3371f6 339 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 14:e420232ee4e7 340 if (sscanf(buf, ": %*d,%d,%*d,%*d,%d,", &status, &acTStatus) == 2) {
RobMeades 14:e420232ee4e7 341 set_nwk_reg_status_csd(status);
RobMeades 14:e420232ee4e7 342 set_rat(acTStatus);
RobMeades 14:e420232ee4e7 343 } else if (sscanf(buf, ": %*d,%d", &status) == 1) {
RobMeades 0:5cffef3371f6 344 set_nwk_reg_status_psd(status);
RobMeades 0:5cffef3371f6 345 } else if (sscanf(buf, ": %d", &status) == 1) {
RobMeades 0:5cffef3371f6 346 set_nwk_reg_status_psd(status);
RobMeades 0:5cffef3371f6 347 }
RobMeades 0:5cffef3371f6 348 }
RobMeades 0:5cffef3371f6 349 }
RobMeades 0:5cffef3371f6 350
RobMeades 0:5cffef3371f6 351 // Callback for EPS registration URC.
RobMeades 0:5cffef3371f6 352 void UbloxCellularBase::CEREG_URC()
RobMeades 0:5cffef3371f6 353 {
RobMeades 0:5cffef3371f6 354 char buf[10];
RobMeades 0:5cffef3371f6 355 int status;
RobMeades 14:e420232ee4e7 356 int acTStatus;
RobMeades 0:5cffef3371f6 357
RobMeades 0:5cffef3371f6 358 // If this is the URC it will be a single
RobMeades 0:5cffef3371f6 359 // digit followed by \n. If it is the
RobMeades 0:5cffef3371f6 360 // answer to a CEREG query, it will be
RobMeades 0:5cffef3371f6 361 // a ": %d,%d\n" where the second digit
RobMeades 0:5cffef3371f6 362 // indicates the status
RobMeades 0:5cffef3371f6 363 // Note: not calling _at->recv() from here as we're
RobMeades 0:5cffef3371f6 364 // already in an _at->recv()
RobMeades 0:5cffef3371f6 365 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 14:e420232ee4e7 366 if (sscanf(buf, ": %*d,%d,%*d,%*d,%d,", &status, &acTStatus) == 2) {
RobMeades 14:e420232ee4e7 367 set_nwk_reg_status_csd(status);
RobMeades 14:e420232ee4e7 368 set_rat(acTStatus);
RobMeades 14:e420232ee4e7 369 } else if (sscanf(buf, ": %*d,%d", &status) == 1) {
RobMeades 0:5cffef3371f6 370 set_nwk_reg_status_eps(status);
RobMeades 0:5cffef3371f6 371 } else if (sscanf(buf, ": %d", &status) == 1) {
RobMeades 0:5cffef3371f6 372 set_nwk_reg_status_eps(status);
RobMeades 0:5cffef3371f6 373 }
RobMeades 0:5cffef3371f6 374 }
RobMeades 0:5cffef3371f6 375 }
RobMeades 0:5cffef3371f6 376
RobMeades 0:5cffef3371f6 377 // Callback UMWI, just filtering it out.
RobMeades 0:5cffef3371f6 378 void UbloxCellularBase::UMWI_URC()
RobMeades 0:5cffef3371f6 379 {
RobMeades 0:5cffef3371f6 380 char buf[10];
RobMeades 0:5cffef3371f6 381
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 read_at_to_char(buf, sizeof (buf), '\n');
RobMeades 0:5cffef3371f6 385 }
RobMeades 0:5cffef3371f6 386
RobMeades 0:5cffef3371f6 387 /**********************************************************************
RobMeades 0:5cffef3371f6 388 * PROTECTED METHODS
RobMeades 0:5cffef3371f6 389 **********************************************************************/
RobMeades 0:5cffef3371f6 390
RobMeades 0:5cffef3371f6 391 #if MODEM_ON_BOARD
RobMeades 0:5cffef3371f6 392 void UbloxCellularBase::modem_init()
RobMeades 0:5cffef3371f6 393 {
RobMeades 0:5cffef3371f6 394 ::onboard_modem_init();
RobMeades 0:5cffef3371f6 395 }
RobMeades 0:5cffef3371f6 396
RobMeades 0:5cffef3371f6 397 void UbloxCellularBase::modem_deinit()
RobMeades 0:5cffef3371f6 398 {
RobMeades 0:5cffef3371f6 399 ::onboard_modem_deinit();
RobMeades 0:5cffef3371f6 400 }
RobMeades 0:5cffef3371f6 401
RobMeades 0:5cffef3371f6 402 void UbloxCellularBase::modem_power_up()
RobMeades 0:5cffef3371f6 403 {
RobMeades 0:5cffef3371f6 404 ::onboard_modem_power_up();
RobMeades 0:5cffef3371f6 405 }
RobMeades 0:5cffef3371f6 406
RobMeades 0:5cffef3371f6 407 void UbloxCellularBase::modem_power_down()
RobMeades 0:5cffef3371f6 408 {
RobMeades 0:5cffef3371f6 409 ::onboard_modem_power_down();
RobMeades 0:5cffef3371f6 410 }
RobMeades 0:5cffef3371f6 411 #else
RobMeades 0:5cffef3371f6 412 void UbloxCellularBase::modem_init()
RobMeades 0:5cffef3371f6 413 {
RobMeades 0:5cffef3371f6 414 // Meant to be overridden
RobMeades 0:5cffef3371f6 415 }
RobMeades 0:5cffef3371f6 416
RobMeades 0:5cffef3371f6 417 void UbloxCellularBase::modem_deinit()
RobMeades 0:5cffef3371f6 418 {
RobMeades 0:5cffef3371f6 419 // Meant to be overridden
RobMeades 0:5cffef3371f6 420 }
RobMeades 0:5cffef3371f6 421
RobMeades 0:5cffef3371f6 422 void UbloxCellularBase::modem_power_up()
RobMeades 0:5cffef3371f6 423 {
RobMeades 0:5cffef3371f6 424 // Meant to be overridden
RobMeades 0:5cffef3371f6 425 }
RobMeades 0:5cffef3371f6 426
RobMeades 0:5cffef3371f6 427 void UbloxCellularBase::modem_power_down()
RobMeades 0:5cffef3371f6 428 {
RobMeades 0:5cffef3371f6 429 // Mmeant to be overridden
RobMeades 0:5cffef3371f6 430 }
RobMeades 0:5cffef3371f6 431 #endif
RobMeades 0:5cffef3371f6 432
RobMeades 0:5cffef3371f6 433 // Constructor.
RobMeades 0:5cffef3371f6 434 // Note: to allow this base class to be inherited as a virtual base class
RobMeades 0:5cffef3371f6 435 // by everyone, it takes no parameters. See also comment above classInit()
RobMeades 0:5cffef3371f6 436 // in the header file.
RobMeades 0:5cffef3371f6 437 UbloxCellularBase::UbloxCellularBase()
RobMeades 0:5cffef3371f6 438 {
RobMeades 0:5cffef3371f6 439 _pin = NULL;
RobMeades 0:5cffef3371f6 440 _at = NULL;
RobMeades 0:5cffef3371f6 441 _at_timeout = AT_PARSER_TIMEOUT;
RobMeades 0:5cffef3371f6 442 _fh = NULL;
RobMeades 0:5cffef3371f6 443 _modem_initialised = false;
RobMeades 0:5cffef3371f6 444 _sim_pin_check_enabled = false;
RobMeades 0:5cffef3371f6 445 _debug_trace_on = false;
RobMeades 0:5cffef3371f6 446
RobMeades 0:5cffef3371f6 447 _dev_info.dev = DEV_TYPE_NONE;
RobMeades 0:5cffef3371f6 448 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 449 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 450 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 451 }
RobMeades 0:5cffef3371f6 452
RobMeades 0:5cffef3371f6 453 // Destructor.
RobMeades 0:5cffef3371f6 454 UbloxCellularBase::~UbloxCellularBase()
RobMeades 0:5cffef3371f6 455 {
RobMeades 0:5cffef3371f6 456 deinit();
RobMeades 0:5cffef3371f6 457 delete _at;
RobMeades 0:5cffef3371f6 458 delete _fh;
RobMeades 0:5cffef3371f6 459 }
RobMeades 0:5cffef3371f6 460
RobMeades 0:5cffef3371f6 461 // Initialise the portions of this class that are parameterised.
RobMeades 0:5cffef3371f6 462 void UbloxCellularBase::baseClassInit(PinName tx, PinName rx,
RobMeades 0:5cffef3371f6 463 int baud, bool debug_on)
RobMeades 0:5cffef3371f6 464 {
RobMeades 0:5cffef3371f6 465 // Only initialise ourselves if it's not already been done
RobMeades 0:5cffef3371f6 466 if (_at == NULL) {
RobMeades 0:5cffef3371f6 467 if (_debug_trace_on == false) {
RobMeades 0:5cffef3371f6 468 _debug_trace_on = debug_on;
RobMeades 0:5cffef3371f6 469 }
rob.meades@u-blox.com 4:2e640a101db1 470 _baud = baud;
RobMeades 0:5cffef3371f6 471
RobMeades 0:5cffef3371f6 472 // Set up File Handle for buffered serial comms with cellular module
RobMeades 0:5cffef3371f6 473 // (which will be used by the AT parser)
rob.meades@u-blox.com 4:2e640a101db1 474 // Note: the UART is initialised to run no faster than 115200 because
rob.meades@u-blox.com 4:2e640a101db1 475 // the modems cannot reliably auto-baud at faster rates. The faster
rob.meades@u-blox.com 4:2e640a101db1 476 // rate is adopted later with a specific AT command and the
rob.meades@u-blox.com 4:2e640a101db1 477 // UARTSerial rate is adjusted at that time
Curt Black 19:98e4136e3980 478 if (baud != 115200) {
rob.meades@u-blox.com 4:2e640a101db1 479 baud = 115200;
rob.meades@u-blox.com 4:2e640a101db1 480 }
RobMeades 0:5cffef3371f6 481 _fh = new UARTSerial(tx, rx, baud);
RobMeades 0:5cffef3371f6 482
RobMeades 0:5cffef3371f6 483 // Set up the AT parser
RobMeades 0:5cffef3371f6 484 _at = new ATCmdParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE,
rob.meades@u-blox.com 3:f9b2cd6f72b1 485 _at_timeout, _debug_trace_on);
RobMeades 0:5cffef3371f6 486
RobMeades 0:5cffef3371f6 487 // Error cases, out of band handling
RobMeades 0:5cffef3371f6 488 _at->oob("ERROR", callback(this, &UbloxCellularBase::parser_abort_cb));
RobMeades 0:5cffef3371f6 489 _at->oob("+CME ERROR", callback(this, &UbloxCellularBase::CMX_ERROR_URC));
RobMeades 0:5cffef3371f6 490 _at->oob("+CMS ERROR", callback(this, &UbloxCellularBase::CMX_ERROR_URC));
RobMeades 0:5cffef3371f6 491
RobMeades 0:5cffef3371f6 492 // Registration status, out of band handling
RobMeades 0:5cffef3371f6 493 _at->oob("+CREG", callback(this, &UbloxCellularBase::CREG_URC));
RobMeades 0:5cffef3371f6 494 _at->oob("+CGREG", callback(this, &UbloxCellularBase::CGREG_URC));
RobMeades 0:5cffef3371f6 495 _at->oob("+CEREG", callback(this, &UbloxCellularBase::CEREG_URC));
RobMeades 0:5cffef3371f6 496
RobMeades 0:5cffef3371f6 497 // Capture the UMWI, just to stop it getting in the way
RobMeades 0:5cffef3371f6 498 _at->oob("+UMWI", callback(this, &UbloxCellularBase::UMWI_URC));
RobMeades 0:5cffef3371f6 499 }
RobMeades 0:5cffef3371f6 500 }
RobMeades 0:5cffef3371f6 501
RobMeades 0:5cffef3371f6 502 // Set the AT parser timeout.
RobMeades 0:5cffef3371f6 503 // Note: the AT interface should be locked before this is called.
RobMeades 0:5cffef3371f6 504 void UbloxCellularBase::at_set_timeout(int timeout) {
RobMeades 0:5cffef3371f6 505
RobMeades 0:5cffef3371f6 506 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 507
RobMeades 0:5cffef3371f6 508 _at_timeout = timeout;
RobMeades 0:5cffef3371f6 509 _at->set_timeout(timeout);
RobMeades 0:5cffef3371f6 510 }
RobMeades 0:5cffef3371f6 511
RobMeades 0:5cffef3371f6 512 // Read up to size bytes from the AT interface up to a "end".
RobMeades 0:5cffef3371f6 513 // Note: the AT interface should be locked before this is called.
RobMeades 0:5cffef3371f6 514 int UbloxCellularBase::read_at_to_char(char * buf, int size, char end)
RobMeades 0:5cffef3371f6 515 {
RobMeades 0:5cffef3371f6 516 int count = 0;
RobMeades 0:5cffef3371f6 517 int x = 0;
RobMeades 0:5cffef3371f6 518
RobMeades 0:5cffef3371f6 519 if (size > 0) {
RobMeades 0:5cffef3371f6 520 for (count = 0; (count < size) && (x >= 0) && (x != end); count++) {
RobMeades 0:5cffef3371f6 521 x = _at->getc();
RobMeades 0:5cffef3371f6 522 *(buf + count) = (char) x;
RobMeades 0:5cffef3371f6 523 }
RobMeades 0:5cffef3371f6 524
RobMeades 0:5cffef3371f6 525 count--;
RobMeades 0:5cffef3371f6 526 *(buf + count) = 0;
RobMeades 0:5cffef3371f6 527
RobMeades 0:5cffef3371f6 528 // Convert line endings:
RobMeades 0:5cffef3371f6 529 // If end was '\n' (0x0a) and the preceding character was 0x0d, then
RobMeades 0:5cffef3371f6 530 // overwrite that with null as well.
RobMeades 0:5cffef3371f6 531 if ((count > 0) && (end == '\n') && (*(buf + count - 1) == '\x0d')) {
RobMeades 0:5cffef3371f6 532 count--;
RobMeades 0:5cffef3371f6 533 *(buf + count) = 0;
RobMeades 0:5cffef3371f6 534 }
RobMeades 0:5cffef3371f6 535 }
RobMeades 0:5cffef3371f6 536
RobMeades 0:5cffef3371f6 537 return count;
RobMeades 0:5cffef3371f6 538 }
RobMeades 0:5cffef3371f6 539
RobMeades 0:5cffef3371f6 540 // Power up the modem.
RobMeades 0:5cffef3371f6 541 // Enables the GPIO lines to the modem and then wriggles the power line in short pulses.
RobMeades 0:5cffef3371f6 542 bool UbloxCellularBase::power_up()
RobMeades 0:5cffef3371f6 543 {
RobMeades 0:5cffef3371f6 544 bool success = false;
RobMeades 0:5cffef3371f6 545 int at_timeout;
RobMeades 0:5cffef3371f6 546 LOCK();
RobMeades 0:5cffef3371f6 547
RobMeades 0:5cffef3371f6 548 at_timeout = _at_timeout; // Has to be inside LOCK()s
RobMeades 0:5cffef3371f6 549
RobMeades 0:5cffef3371f6 550 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 551
RobMeades 0:5cffef3371f6 552 /* Initialize GPIO lines */
RobMeades 0:5cffef3371f6 553 tr_info("Powering up modem...");
pilotak 7:c2cf27a981b3 554 modem_init();
RobMeades 0:5cffef3371f6 555 /* Give modem a little time to settle down */
RobMeades 0:5cffef3371f6 556 wait_ms(250);
RobMeades 0:5cffef3371f6 557
RobMeades 0:5cffef3371f6 558 for (int retry_count = 0; !success && (retry_count < 20); retry_count++) {
pilotak 7:c2cf27a981b3 559 modem_power_up();
RobMeades 0:5cffef3371f6 560 wait_ms(500);
RobMeades 0:5cffef3371f6 561 // Modem tends to spit out noise during power up - don't confuse the parser
RobMeades 0:5cffef3371f6 562 _at->flush();
RobMeades 0:5cffef3371f6 563 at_set_timeout(1000);
RobMeades 0:5cffef3371f6 564 if (_at->send("AT")) {
RobMeades 0:5cffef3371f6 565 // C027 needs a delay here
RobMeades 0:5cffef3371f6 566 wait_ms(100);
RobMeades 0:5cffef3371f6 567 if (_at->recv("OK")) {
RobMeades 0:5cffef3371f6 568 success = true;
RobMeades 0:5cffef3371f6 569 }
RobMeades 0:5cffef3371f6 570 }
RobMeades 0:5cffef3371f6 571 at_set_timeout(at_timeout);
RobMeades 0:5cffef3371f6 572 }
RobMeades 0:5cffef3371f6 573
rob.meades@u-blox.com 4:2e640a101db1 574 if (success) {
rob.meades@u-blox.com 4:2e640a101db1 575 // Set the final baud rate
rob.meades@u-blox.com 4:2e640a101db1 576 if (_at->send("AT+IPR=%d", _baud) && _at->recv("OK")) {
rob.meades@u-blox.com 4:2e640a101db1 577 // Need to wait for things to be sorted out on the modem side
rob.meades@u-blox.com 4:2e640a101db1 578 wait_ms(100);
rob.meades@u-blox.com 4:2e640a101db1 579 ((UARTSerial *)_fh)->set_baud(_baud);
rob.meades@u-blox.com 4:2e640a101db1 580 }
rob.meades@u-blox.com 4:2e640a101db1 581
rob.meades@u-blox.com 4:2e640a101db1 582 // Turn off modem echoing and turn on verbose responses
rob.meades@u-blox.com 4:2e640a101db1 583 success = _at->send("ATE0;+CMEE=2") && _at->recv("OK") &&
rob.meades@u-blox.com 4:2e640a101db1 584 // The following commands are best sent separately
rob.meades@u-blox.com 4:2e640a101db1 585 _at->send("AT&K0") && _at->recv("OK") && // Turn off RTC/CTS handshaking
rob.meades@u-blox.com 4:2e640a101db1 586 _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 587 _at->send("AT&D0") && _at->recv("OK"); // Set DTR circuit, we ignore the state change of DTR
rob.meades@u-blox.com 4:2e640a101db1 588 }
RobMeades 0:5cffef3371f6 589
RobMeades 0:5cffef3371f6 590 if (!success) {
RobMeades 0:5cffef3371f6 591 tr_error("Preliminary modem setup failed.");
RobMeades 0:5cffef3371f6 592 }
RobMeades 0:5cffef3371f6 593
RobMeades 0:5cffef3371f6 594 UNLOCK();
RobMeades 0:5cffef3371f6 595 return success;
RobMeades 0:5cffef3371f6 596 }
RobMeades 0:5cffef3371f6 597
RobMeades 0:5cffef3371f6 598 // Power down modem via AT interface.
RobMeades 0:5cffef3371f6 599 void UbloxCellularBase::power_down()
RobMeades 0:5cffef3371f6 600 {
RobMeades 0:5cffef3371f6 601 LOCK();
RobMeades 0:5cffef3371f6 602
RobMeades 0:5cffef3371f6 603 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 604
RobMeades 0:5cffef3371f6 605 // If we have been running, do a soft power-off first
RobMeades 0:5cffef3371f6 606 if (_modem_initialised && (_at != NULL)) {
RobMeades 0:5cffef3371f6 607 _at->send("AT+CPWROFF") && _at->recv("OK");
RobMeades 0:5cffef3371f6 608 }
RobMeades 0:5cffef3371f6 609
RobMeades 0:5cffef3371f6 610 // Now do a hard power-off
pilotak 7:c2cf27a981b3 611 modem_power_down();
pilotak 7:c2cf27a981b3 612 modem_deinit();
RobMeades 0:5cffef3371f6 613
RobMeades 0:5cffef3371f6 614 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 615 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 616 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 617
RobMeades 0:5cffef3371f6 618 UNLOCK();
RobMeades 0:5cffef3371f6 619 }
RobMeades 0:5cffef3371f6 620
RobMeades 0:5cffef3371f6 621 // Get the device ID.
RobMeades 0:5cffef3371f6 622 bool UbloxCellularBase::set_device_identity(DeviceType *dev)
RobMeades 0:5cffef3371f6 623 {
RobMeades 0:5cffef3371f6 624 char buf[20];
RobMeades 0:5cffef3371f6 625 bool success;
RobMeades 0:5cffef3371f6 626 LOCK();
RobMeades 0:5cffef3371f6 627
RobMeades 0:5cffef3371f6 628 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 629
RobMeades 0:5cffef3371f6 630 success = _at->send("ATI") && _at->recv("%19[^\n]\nOK\n", buf);
RobMeades 0:5cffef3371f6 631
RobMeades 0:5cffef3371f6 632 if (success) {
RobMeades 0:5cffef3371f6 633 if (strstr(buf, "SARA-G35"))
RobMeades 0:5cffef3371f6 634 *dev = DEV_SARA_G35;
RobMeades 0:5cffef3371f6 635 else if (strstr(buf, "LISA-U200-03S"))
RobMeades 0:5cffef3371f6 636 *dev = DEV_LISA_U2_03S;
RobMeades 0:5cffef3371f6 637 else if (strstr(buf, "LISA-U2"))
RobMeades 0:5cffef3371f6 638 *dev = DEV_LISA_U2;
RobMeades 0:5cffef3371f6 639 else if (strstr(buf, "SARA-U2"))
RobMeades 0:5cffef3371f6 640 *dev = DEV_SARA_U2;
fahimalavi 10:c4281fa79b8f 641 else if (strstr(buf, "SARA-R4"))
fahimalavi 10:c4281fa79b8f 642 *dev = DEV_SARA_R4;
RobMeades 0:5cffef3371f6 643 else if (strstr(buf, "LEON-G2"))
RobMeades 0:5cffef3371f6 644 *dev = DEV_LEON_G2;
RobMeades 0:5cffef3371f6 645 else if (strstr(buf, "TOBY-L2"))
RobMeades 0:5cffef3371f6 646 *dev = DEV_TOBY_L2;
RobMeades 0:5cffef3371f6 647 else if (strstr(buf, "MPCI-L2"))
RobMeades 0:5cffef3371f6 648 *dev = DEV_MPCI_L2;
cblack 17:a01b693a2e63 649 else if (strstr(buf, "LARA-R2"))
cblack 17:a01b693a2e63 650 *dev = DEV_LARA_R2;
RobMeades 0:5cffef3371f6 651 }
RobMeades 0:5cffef3371f6 652
RobMeades 0:5cffef3371f6 653 UNLOCK();
RobMeades 0:5cffef3371f6 654 return success;
RobMeades 0:5cffef3371f6 655 }
RobMeades 0:5cffef3371f6 656
RobMeades 0:5cffef3371f6 657 // Send initialisation AT commands that are specific to the device.
RobMeades 0:5cffef3371f6 658 bool UbloxCellularBase::device_init(DeviceType dev)
RobMeades 0:5cffef3371f6 659 {
RobMeades 0:5cffef3371f6 660 bool success = false;
RobMeades 0:5cffef3371f6 661 LOCK();
RobMeades 0:5cffef3371f6 662
RobMeades 0:5cffef3371f6 663 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 664
RobMeades 0:5cffef3371f6 665 if ((dev == DEV_LISA_U2) || (dev == DEV_LEON_G2) || (dev == DEV_TOBY_L2)) {
RobMeades 0:5cffef3371f6 666 success = _at->send("AT+UGPIOC=20,2") && _at->recv("OK");
cblack 17:a01b693a2e63 667 } else if ((dev == DEV_SARA_U2) || (dev == DEV_SARA_G35) || (dev == DEV_LARA_R2)) {
RobMeades 0:5cffef3371f6 668 success = _at->send("AT+UGPIOC=16,2") && _at->recv("OK");
RobMeades 0:5cffef3371f6 669 } else {
RobMeades 0:5cffef3371f6 670 success = true;
RobMeades 0:5cffef3371f6 671 }
RobMeades 0:5cffef3371f6 672
RobMeades 0:5cffef3371f6 673 UNLOCK();
RobMeades 0:5cffef3371f6 674 return success;
RobMeades 0:5cffef3371f6 675 }
RobMeades 0:5cffef3371f6 676
RobMeades 0:5cffef3371f6 677 // Get the SIM card going.
RobMeades 0:5cffef3371f6 678 bool UbloxCellularBase::initialise_sim_card()
RobMeades 0:5cffef3371f6 679 {
RobMeades 0:5cffef3371f6 680 bool success = false;
RobMeades 0:5cffef3371f6 681 int retry_count = 0;
RobMeades 0:5cffef3371f6 682 bool done = false;
RobMeades 0:5cffef3371f6 683 LOCK();
RobMeades 0:5cffef3371f6 684
RobMeades 0:5cffef3371f6 685 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 686
RobMeades 0:5cffef3371f6 687 /* SIM initialisation may take a significant amount, so an error is
RobMeades 0:5cffef3371f6 688 * kind of expected. We should retry 10 times until we succeed or timeout. */
RobMeades 0:5cffef3371f6 689 for (retry_count = 0; !done && (retry_count < 10); retry_count++) {
RobMeades 0:5cffef3371f6 690 char pinstr[16];
RobMeades 0:5cffef3371f6 691
RobMeades 0:5cffef3371f6 692 if (_at->send("AT+CPIN?") && _at->recv("+CPIN: %15[^\n]\n", pinstr) &&
RobMeades 0:5cffef3371f6 693 _at->recv("OK")) {
RobMeades 0:5cffef3371f6 694 done = true;
RobMeades 0:5cffef3371f6 695 if (strcmp(pinstr, "SIM PIN") == 0) {
RobMeades 0:5cffef3371f6 696 _sim_pin_check_enabled = true;
RobMeades 0:5cffef3371f6 697 if (_at->send("AT+CPIN=\"%s\"", _pin)) {
RobMeades 0:5cffef3371f6 698 if (_at->recv("OK")) {
RobMeades 0:5cffef3371f6 699 tr_info("PIN correct");
RobMeades 0:5cffef3371f6 700 success = true;
RobMeades 0:5cffef3371f6 701 } else {
RobMeades 0:5cffef3371f6 702 tr_error("Incorrect PIN");
RobMeades 0:5cffef3371f6 703 }
RobMeades 0:5cffef3371f6 704 }
RobMeades 0:5cffef3371f6 705 } else if (strcmp(pinstr, "READY") == 0) {
RobMeades 0:5cffef3371f6 706 _sim_pin_check_enabled = false;
RobMeades 0:5cffef3371f6 707 tr_info("No PIN required");
RobMeades 0:5cffef3371f6 708 success = true;
RobMeades 0:5cffef3371f6 709 } else {
RobMeades 0:5cffef3371f6 710 tr_debug("Unexpected response from SIM: \"%s\"", pinstr);
RobMeades 0:5cffef3371f6 711 }
RobMeades 0:5cffef3371f6 712 }
RobMeades 0:5cffef3371f6 713
RobMeades 0:5cffef3371f6 714 /* wait for a second before retry */
RobMeades 0:5cffef3371f6 715 wait_ms(1000);
RobMeades 0:5cffef3371f6 716 }
RobMeades 0:5cffef3371f6 717
RobMeades 0:5cffef3371f6 718 if (done) {
RobMeades 0:5cffef3371f6 719 tr_info("SIM Ready.");
RobMeades 0:5cffef3371f6 720 } else {
RobMeades 0:5cffef3371f6 721 tr_error("SIM not ready.");
RobMeades 0:5cffef3371f6 722 }
RobMeades 0:5cffef3371f6 723
RobMeades 0:5cffef3371f6 724 UNLOCK();
RobMeades 0:5cffef3371f6 725 return success;
RobMeades 0:5cffef3371f6 726 }
RobMeades 0:5cffef3371f6 727
RobMeades 0:5cffef3371f6 728 /**********************************************************************
RobMeades 0:5cffef3371f6 729 * PUBLIC METHODS
RobMeades 0:5cffef3371f6 730 **********************************************************************/
RobMeades 0:5cffef3371f6 731
RobMeades 0:5cffef3371f6 732 // Initialise the modem.
RobMeades 0:5cffef3371f6 733 bool UbloxCellularBase::init(const char *pin)
RobMeades 0:5cffef3371f6 734 {
RobMeades 8:a15349fcab25 735 int x;
RobMeades 0:5cffef3371f6 736 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 737
RobMeades 0:5cffef3371f6 738 if (!_modem_initialised) {
RobMeades 0:5cffef3371f6 739 if (power_up()) {
RobMeades 0:5cffef3371f6 740 tr_info("Modem Ready.");
RobMeades 0:5cffef3371f6 741 if (pin != NULL) {
RobMeades 0:5cffef3371f6 742 _pin = pin;
RobMeades 0:5cffef3371f6 743 }
RobMeades 0:5cffef3371f6 744 if (initialise_sim_card()) {
RobMeades 0:5cffef3371f6 745 if (set_device_identity(&_dev_info.dev) && // Set up device identity
rob.meades@u-blox.com 6:8fadf1e49487 746 device_init(_dev_info.dev)) {// Initialise this device
rob.meades@u-blox.com 6:8fadf1e49487 747 // Get the integrated circuit ID of the SIM
rob.meades@u-blox.com 6:8fadf1e49487 748 if (get_iccid()) {
rob.meades@u-blox.com 6:8fadf1e49487 749 // Try a few times to get the IMSI (since on some modems this can
rob.meades@u-blox.com 6:8fadf1e49487 750 // take a while to be retrieved, especially if a SIM PIN
rob.meades@u-blox.com 6:8fadf1e49487 751 // was set)
RobMeades 8:a15349fcab25 752 for (x = 0; (x < 3) && !get_imsi(); x++) {
rob.meades@u-blox.com 6:8fadf1e49487 753 wait_ms(1000);
rob.meades@u-blox.com 6:8fadf1e49487 754 }
rob.meades@u-blox.com 6:8fadf1e49487 755
RobMeades 8:a15349fcab25 756 if (x < 3) { // If we got the IMSI, can get the others
rob.meades@u-blox.com 6:8fadf1e49487 757 if (get_imei() && // Get international mobile equipment identifier
rob.meades@u-blox.com 6:8fadf1e49487 758 get_meid() && // Probably the same as the IMEI
rob.meades@u-blox.com 6:8fadf1e49487 759 set_sms()) { // And set up SMS
rob.meades@u-blox.com 6:8fadf1e49487 760 // The modem is initialised.
rob.meades@u-blox.com 6:8fadf1e49487 761 _modem_initialised = true;
rob.meades@u-blox.com 6:8fadf1e49487 762 }
rob.meades@u-blox.com 6:8fadf1e49487 763 }
rob.meades@u-blox.com 6:8fadf1e49487 764 }
RobMeades 0:5cffef3371f6 765 }
RobMeades 0:5cffef3371f6 766 }
RobMeades 0:5cffef3371f6 767 }
RobMeades 0:5cffef3371f6 768 }
RobMeades 0:5cffef3371f6 769
RobMeades 0:5cffef3371f6 770 return _modem_initialised;
RobMeades 0:5cffef3371f6 771 }
RobMeades 0:5cffef3371f6 772
RobMeades 0:5cffef3371f6 773 // Perform registration.
RobMeades 0:5cffef3371f6 774 bool UbloxCellularBase::nwk_registration()
RobMeades 0:5cffef3371f6 775 {
RobMeades 0:5cffef3371f6 776 bool atSuccess = false;
RobMeades 0:5cffef3371f6 777 bool registered = false;
RobMeades 0:5cffef3371f6 778 int status;
RobMeades 0:5cffef3371f6 779 int at_timeout;
RobMeades 0:5cffef3371f6 780 LOCK();
RobMeades 0:5cffef3371f6 781
RobMeades 0:5cffef3371f6 782 at_timeout = _at_timeout; // Has to be inside LOCK()s
RobMeades 0:5cffef3371f6 783
RobMeades 0:5cffef3371f6 784 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 785
RobMeades 0:5cffef3371f6 786 if (!is_registered_psd() && !is_registered_csd() && !is_registered_eps()) {
RobMeades 0:5cffef3371f6 787 tr_info("Searching Network...");
RobMeades 0:5cffef3371f6 788 // Enable the packet switched and network registration unsolicited result codes
RobMeades 0:5cffef3371f6 789 if (_at->send("AT+CREG=1") && _at->recv("OK") &&
RobMeades 0:5cffef3371f6 790 _at->send("AT+CGREG=1") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 791 atSuccess = true;
RobMeades 0:5cffef3371f6 792 if (_at->send("AT+CEREG=1")) {
RobMeades 0:5cffef3371f6 793 _at->recv("OK");
RobMeades 0:5cffef3371f6 794 // Don't check return value as this works for LTE only
RobMeades 0:5cffef3371f6 795 }
RobMeades 0:5cffef3371f6 796
RobMeades 0:5cffef3371f6 797 if (atSuccess) {
RobMeades 0:5cffef3371f6 798 // See if we are already in automatic mode
RobMeades 0:5cffef3371f6 799 if (_at->send("AT+COPS?") && _at->recv("+COPS: %d", &status) &&
RobMeades 0:5cffef3371f6 800 _at->recv("OK")) {
RobMeades 0:5cffef3371f6 801 // If not, set it
RobMeades 0:5cffef3371f6 802 if (status != 0) {
RobMeades 0:5cffef3371f6 803 // Don't check return code here as there's not much
RobMeades 0:5cffef3371f6 804 // we can do if this fails.
RobMeades 0:5cffef3371f6 805 _at->send("AT+COPS=0") && _at->recv("OK");
RobMeades 0:5cffef3371f6 806 }
RobMeades 0:5cffef3371f6 807 }
RobMeades 0:5cffef3371f6 808
RobMeades 0:5cffef3371f6 809 // Query the registration status directly as well,
RobMeades 0:5cffef3371f6 810 // just in case
RobMeades 0:5cffef3371f6 811 if (_at->send("AT+CREG?") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 812 // Answer will be processed by URC
RobMeades 0:5cffef3371f6 813 }
RobMeades 0:5cffef3371f6 814 if (_at->send("AT+CGREG?") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 815 // Answer will be processed by URC
RobMeades 0:5cffef3371f6 816 }
RobMeades 0:5cffef3371f6 817 if (_at->send("AT+CEREG?")) {
RobMeades 0:5cffef3371f6 818 _at->recv("OK");
RobMeades 0:5cffef3371f6 819 // Don't check return value as this works for LTE only
RobMeades 0:5cffef3371f6 820 }
RobMeades 0:5cffef3371f6 821 }
RobMeades 0:5cffef3371f6 822 }
RobMeades 0:5cffef3371f6 823 // Wait for registration to succeed
RobMeades 0:5cffef3371f6 824 at_set_timeout(1000);
RobMeades 0:5cffef3371f6 825 for (int waitSeconds = 0; !registered && (waitSeconds < 180); waitSeconds++) {
RobMeades 0:5cffef3371f6 826 registered = is_registered_psd() || is_registered_csd() || is_registered_eps();
RobMeades 0:5cffef3371f6 827 _at->recv(UNNATURAL_STRING);
RobMeades 0:5cffef3371f6 828 }
RobMeades 0:5cffef3371f6 829 at_set_timeout(at_timeout);
RobMeades 0:5cffef3371f6 830
RobMeades 0:5cffef3371f6 831 if (registered) {
RobMeades 0:5cffef3371f6 832 // This should return quickly but sometimes the status field is not returned
RobMeades 0:5cffef3371f6 833 // so make the timeout short
RobMeades 0:5cffef3371f6 834 at_set_timeout(1000);
RobMeades 0:5cffef3371f6 835 if (_at->send("AT+COPS?") && _at->recv("+COPS: %*d,%*d,\"%*[^\"]\",%d\n", &status)) {
RobMeades 0:5cffef3371f6 836 set_rat(status);
RobMeades 0:5cffef3371f6 837 }
RobMeades 0:5cffef3371f6 838 at_set_timeout(at_timeout);
RobMeades 0:5cffef3371f6 839 }
RobMeades 0:5cffef3371f6 840 } else {
RobMeades 0:5cffef3371f6 841 registered = true;
RobMeades 0:5cffef3371f6 842 }
RobMeades 0:5cffef3371f6 843
RobMeades 0:5cffef3371f6 844 UNLOCK();
RobMeades 0:5cffef3371f6 845 return registered;
RobMeades 0:5cffef3371f6 846 }
RobMeades 0:5cffef3371f6 847
RobMeades 0:5cffef3371f6 848 bool UbloxCellularBase::is_registered_csd()
RobMeades 0:5cffef3371f6 849 {
RobMeades 0:5cffef3371f6 850 return (_dev_info.reg_status_csd == CSD_REGISTERED) ||
RobMeades 0:5cffef3371f6 851 (_dev_info.reg_status_csd == CSD_REGISTERED_ROAMING) ||
RobMeades 0:5cffef3371f6 852 (_dev_info.reg_status_csd == CSD_CSFB_NOT_PREFERRED);
RobMeades 0:5cffef3371f6 853 }
RobMeades 0:5cffef3371f6 854
RobMeades 0:5cffef3371f6 855 bool UbloxCellularBase::is_registered_psd()
RobMeades 0:5cffef3371f6 856 {
RobMeades 0:5cffef3371f6 857 return (_dev_info.reg_status_psd == PSD_REGISTERED) ||
RobMeades 0:5cffef3371f6 858 (_dev_info.reg_status_psd == PSD_REGISTERED_ROAMING);
RobMeades 0:5cffef3371f6 859 }
RobMeades 0:5cffef3371f6 860
RobMeades 0:5cffef3371f6 861 bool UbloxCellularBase::is_registered_eps()
RobMeades 0:5cffef3371f6 862 {
RobMeades 0:5cffef3371f6 863 return (_dev_info.reg_status_eps == EPS_REGISTERED) ||
RobMeades 0:5cffef3371f6 864 (_dev_info.reg_status_eps == EPS_REGISTERED_ROAMING);
RobMeades 0:5cffef3371f6 865 }
RobMeades 0:5cffef3371f6 866
RobMeades 0:5cffef3371f6 867 // Perform deregistration.
RobMeades 0:5cffef3371f6 868 bool UbloxCellularBase::nwk_deregistration()
RobMeades 0:5cffef3371f6 869 {
RobMeades 0:5cffef3371f6 870 bool success = false;
RobMeades 0:5cffef3371f6 871 LOCK();
RobMeades 0:5cffef3371f6 872
RobMeades 0:5cffef3371f6 873 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 874
RobMeades 0:5cffef3371f6 875 if (_at->send("AT+COPS=2") && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 876 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 877 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 878 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
RobMeades 0:5cffef3371f6 879 success = true;
RobMeades 0:5cffef3371f6 880 }
RobMeades 0:5cffef3371f6 881
RobMeades 0:5cffef3371f6 882 UNLOCK();
RobMeades 0:5cffef3371f6 883 return success;
RobMeades 0:5cffef3371f6 884 }
RobMeades 0:5cffef3371f6 885
RobMeades 0:5cffef3371f6 886 // Put the modem into its lowest power state.
RobMeades 0:5cffef3371f6 887 void UbloxCellularBase::deinit()
RobMeades 0:5cffef3371f6 888 {
RobMeades 0:5cffef3371f6 889 power_down();
RobMeades 0:5cffef3371f6 890 _modem_initialised = false;
RobMeades 0:5cffef3371f6 891 }
RobMeades 0:5cffef3371f6 892
RobMeades 0:5cffef3371f6 893 // Set the PIN.
RobMeades 0:5cffef3371f6 894 void UbloxCellularBase::set_pin(const char *pin) {
RobMeades 0:5cffef3371f6 895 _pin = pin;
RobMeades 0:5cffef3371f6 896 }
RobMeades 0:5cffef3371f6 897
RobMeades 0:5cffef3371f6 898 // Enable or disable SIM pin checking.
rob.meades@u-blox.com 4:2e640a101db1 899 bool UbloxCellularBase::sim_pin_check_enable(bool enableNotDisable)
RobMeades 0:5cffef3371f6 900 {
RobMeades 0:5cffef3371f6 901 bool success = false;;
RobMeades 0:5cffef3371f6 902 LOCK();
RobMeades 0:5cffef3371f6 903
RobMeades 0:5cffef3371f6 904 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 905
RobMeades 0:5cffef3371f6 906 if (_pin != NULL) {
RobMeades 0:5cffef3371f6 907 if (_sim_pin_check_enabled && !enableNotDisable) {
RobMeades 0:5cffef3371f6 908 // Disable the SIM lock
RobMeades 0:5cffef3371f6 909 if (_at->send("AT+CLCK=\"SC\",0,\"%s\"", _pin) && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 910 _sim_pin_check_enabled = false;
RobMeades 0:5cffef3371f6 911 success = true;
RobMeades 0:5cffef3371f6 912 }
RobMeades 0:5cffef3371f6 913 } else if (!_sim_pin_check_enabled && enableNotDisable) {
RobMeades 0:5cffef3371f6 914 // Enable the SIM lock
RobMeades 0:5cffef3371f6 915 if (_at->send("AT+CLCK=\"SC\",1,\"%s\"", _pin) && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 916 _sim_pin_check_enabled = true;
RobMeades 0:5cffef3371f6 917 success = true;
RobMeades 0:5cffef3371f6 918 }
RobMeades 0:5cffef3371f6 919 } else {
RobMeades 0:5cffef3371f6 920 success = true;
RobMeades 0:5cffef3371f6 921 }
RobMeades 0:5cffef3371f6 922 }
RobMeades 0:5cffef3371f6 923
RobMeades 0:5cffef3371f6 924 UNLOCK();
RobMeades 0:5cffef3371f6 925 return success;
RobMeades 0:5cffef3371f6 926 }
RobMeades 0:5cffef3371f6 927
RobMeades 0:5cffef3371f6 928 // Change the pin code for the SIM card.
RobMeades 0:5cffef3371f6 929 bool UbloxCellularBase::change_sim_pin(const char *pin)
RobMeades 0:5cffef3371f6 930 {
RobMeades 0:5cffef3371f6 931 bool success = false;;
RobMeades 0:5cffef3371f6 932 LOCK();
RobMeades 0:5cffef3371f6 933
RobMeades 0:5cffef3371f6 934 MBED_ASSERT(_at != NULL);
RobMeades 0:5cffef3371f6 935
RobMeades 0:5cffef3371f6 936 // Change the SIM pin
RobMeades 0:5cffef3371f6 937 if ((pin != NULL) && (_pin != NULL)) {
RobMeades 0:5cffef3371f6 938 if (_at->send("AT+CPWD=\"SC\",\"%s\",\"%s\"", _pin, pin) && _at->recv("OK")) {
RobMeades 0:5cffef3371f6 939 _pin = pin;
RobMeades 0:5cffef3371f6 940 success = true;
RobMeades 0:5cffef3371f6 941 }
RobMeades 0:5cffef3371f6 942 }
RobMeades 0:5cffef3371f6 943
RobMeades 0:5cffef3371f6 944 UNLOCK();
RobMeades 0:5cffef3371f6 945 return success;
RobMeades 0:5cffef3371f6 946 }
RobMeades 0:5cffef3371f6 947
RobMeades 14:e420232ee4e7 948 // Get the IMEI.
fahim alavi 13:158a035b1b50 949 bool UbloxCellularBase::get_imei(char *imei_to_send, int size)
fahim alavi 13:158a035b1b50 950 {
fahim alavi 13:158a035b1b50 951 bool success;
fahim alavi 13:158a035b1b50 952 LOCK();
fahim alavi 13:158a035b1b50 953
fahim alavi 13:158a035b1b50 954 MBED_ASSERT(_at != NULL);
fahim alavi 13:158a035b1b50 955
fahim alavi 13:158a035b1b50 956 // International mobile equipment identifier
fahim alavi 13:158a035b1b50 957 // AT Command Manual UBX-13002752, section 4.7
fahim alavi 13:158a035b1b50 958 success = _at->send("AT+CGSN") && _at->recv("%15[^\n]\nOK\n", _dev_info.imei);
fahim alavi 13:158a035b1b50 959 tr_info("DevInfo: IMEI=%s", _dev_info.imei);
fahim alavi 13:158a035b1b50 960
fahim alavi 13:158a035b1b50 961 if (success) {
fahim alavi 13:158a035b1b50 962 memcpy(imei_to_send,_dev_info.imei,size);
fahim alavi 13:158a035b1b50 963 imei_to_send[size-1] = '\0';
fahim alavi 13:158a035b1b50 964 }
fahim alavi 13:158a035b1b50 965
fahim alavi 13:158a035b1b50 966 UNLOCK();
fahim alavi 13:158a035b1b50 967 return success;
fahim alavi 13:158a035b1b50 968 }
fahim alavi 13:158a035b1b50 969
RobMeades 14:e420232ee4e7 970 // Get the IMEI of the module.
RobMeades 14:e420232ee4e7 971 const char *UbloxCellularBase::imei()
RobMeades 14:e420232ee4e7 972 {
RobMeades 14:e420232ee4e7 973 return _dev_info.imei;
RobMeades 14:e420232ee4e7 974 }
RobMeades 14:e420232ee4e7 975
RobMeades 14:e420232ee4e7 976 // Get the Mobile Equipment ID (which may be the same as the IMEI).
RobMeades 14:e420232ee4e7 977 const char *UbloxCellularBase::meid()
RobMeades 14:e420232ee4e7 978 {
RobMeades 14:e420232ee4e7 979 return _dev_info.meid;
RobMeades 14:e420232ee4e7 980 }
RobMeades 14:e420232ee4e7 981
RobMeades 14:e420232ee4e7 982 // Get the IMSI of the SIM.
RobMeades 14:e420232ee4e7 983 const char *UbloxCellularBase::imsi()
RobMeades 14:e420232ee4e7 984 {
RobMeades 14:e420232ee4e7 985 // (try) to update the IMSI, just in case the SIM has changed
RobMeades 14:e420232ee4e7 986 get_imsi();
RobMeades 14:e420232ee4e7 987
RobMeades 14:e420232ee4e7 988 return _dev_info.imsi;
RobMeades 14:e420232ee4e7 989 }
RobMeades 14:e420232ee4e7 990
RobMeades 14:e420232ee4e7 991 // Get the ICCID of the SIM.
RobMeades 14:e420232ee4e7 992 const char *UbloxCellularBase::iccid()
RobMeades 14:e420232ee4e7 993 {
RobMeades 14:e420232ee4e7 994 // (try) to update the ICCID, just in case the SIM has changed
RobMeades 14:e420232ee4e7 995 get_iccid();
RobMeades 14:e420232ee4e7 996
RobMeades 14:e420232ee4e7 997 return _dev_info.iccid;
RobMeades 14:e420232ee4e7 998 }
RobMeades 14:e420232ee4e7 999
RobMeades 14:e420232ee4e7 1000 // Get the RSSI in dBm.
RobMeades 14:e420232ee4e7 1001 int UbloxCellularBase::rssi()
RobMeades 14:e420232ee4e7 1002 {
RobMeades 14:e420232ee4e7 1003 char buf[7] = {0};
RobMeades 14:e420232ee4e7 1004 int rssi = 0;
RobMeades 14:e420232ee4e7 1005 int qual = 0;
RobMeades 14:e420232ee4e7 1006 int rssiRet = 0;
RobMeades 14:e420232ee4e7 1007 bool success;
RobMeades 14:e420232ee4e7 1008 LOCK();
RobMeades 14:e420232ee4e7 1009
RobMeades 14:e420232ee4e7 1010 MBED_ASSERT(_at != NULL);
RobMeades 14:e420232ee4e7 1011
RobMeades 14:e420232ee4e7 1012 success = _at->send("AT+CSQ") && _at->recv("+CSQ: %6[^\n]\nOK\n", buf);
RobMeades 14:e420232ee4e7 1013
RobMeades 14:e420232ee4e7 1014 if (success) {
RobMeades 14:e420232ee4e7 1015 if (sscanf(buf, "%d,%d", &rssi, &qual) == 2) {
RobMeades 14:e420232ee4e7 1016 // AT+CSQ returns a coded RSSI value and an RxQual value
RobMeades 14:e420232ee4e7 1017 // For 2G an RSSI of 0 corresponds to -113 dBm or less,
RobMeades 14:e420232ee4e7 1018 // an RSSI of 31 corresponds to -51 dBm or less and hence
RobMeades 14:e420232ee4e7 1019 // each value is a 2 dB step.
RobMeades 14:e420232ee4e7 1020 // For LTE the mapping is defined in the array rssiConvertLte[].
RobMeades 14:e420232ee4e7 1021 // For 3G the mapping to RSCP is defined in the array rscpConvert3G[]
RobMeades 14:e420232ee4e7 1022 // and the RSSI value is then RSCP - the EC_NO_LEV number derived
RobMeades 14:e420232ee4e7 1023 // by putting the qual number through qualConvert3G[].
RobMeades 14:e420232ee4e7 1024 if ((rssi >= 0) && (rssi <= 31)) {
RobMeades 14:e420232ee4e7 1025 switch (_dev_info.rat) {
RobMeades 14:e420232ee4e7 1026 case UTRAN:
RobMeades 14:e420232ee4e7 1027 case HSDPA:
RobMeades 14:e420232ee4e7 1028 case HSUPA:
RobMeades 14:e420232ee4e7 1029 case HSDPA_HSUPA:
RobMeades 14:e420232ee4e7 1030 // 3G
RobMeades 14:e420232ee4e7 1031 if ((qual >= 0) && (qual <= 7)) {
RobMeades 14:e420232ee4e7 1032 qual = qualConvert3G[qual];
fahim.alavi@u-blox.com 15:93b157a47b8d 1033 rssiRet = rscpConvert3G[rssi];
fahim.alavi@u-blox.com 15:93b157a47b8d 1034 rssiRet -= qual;
RobMeades 14:e420232ee4e7 1035 }
fahim.alavi@u-blox.com 15:93b157a47b8d 1036
RobMeades 14:e420232ee4e7 1037 break;
RobMeades 14:e420232ee4e7 1038 case LTE:
RobMeades 14:e420232ee4e7 1039 // LTE
RobMeades 14:e420232ee4e7 1040 rssiRet = rssiConvertLte[rssi];
RobMeades 14:e420232ee4e7 1041 break;
RobMeades 14:e420232ee4e7 1042 case GSM:
RobMeades 14:e420232ee4e7 1043 case COMPACT_GSM:
RobMeades 14:e420232ee4e7 1044 case EDGE:
RobMeades 14:e420232ee4e7 1045 default:
RobMeades 14:e420232ee4e7 1046 // GSM or assumed GSM if the RAT is not known
RobMeades 14:e420232ee4e7 1047 rssiRet = -(113 - (rssi << 2));
RobMeades 14:e420232ee4e7 1048 break;
RobMeades 14:e420232ee4e7 1049 }
RobMeades 14:e420232ee4e7 1050 }
RobMeades 14:e420232ee4e7 1051 }
RobMeades 14:e420232ee4e7 1052 }
RobMeades 14:e420232ee4e7 1053
RobMeades 14:e420232ee4e7 1054 UNLOCK();
RobMeades 14:e420232ee4e7 1055 return rssiRet;
RobMeades 14:e420232ee4e7 1056 }
RobMeades 14:e420232ee4e7 1057
RobMeades 0:5cffef3371f6 1058 // End of File
RobMeades 0:5cffef3371f6 1059