Base class for the u-blox N2xx modems. Cannot be used standalone, only inherited by classes that do properly useful stuff. Or, to put it another way, if you are using any of the classes ending with 'n2xx', you will need this class also. Note: requires the N211 module firmware to be at least 06.57 A01.02.

Dependents:   example-ublox-cellular-interface HelloMQTT example-ublox-cellular-interface_r410M example-ublox-mbed-client ... more

Committer:
mudassar0121
Date:
Wed Jan 03 05:50:31 2018 +0000
Revision:
7:f1c3373e4ff5
Parent:
6:377997119ef1
Child:
8:72412b28c93f
Copy imei function added for SARA R410M support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
philware 1:d4ff95ab40ae 1 /* Copyright (c) 2017 ublox Limited
philware 1:d4ff95ab40ae 2 *
philware 1:d4ff95ab40ae 3 * Licensed under the Apache License, Version 2.0 (the "License");
philware 1:d4ff95ab40ae 4 * you may not use this file except in compliance with the License.
philware 1:d4ff95ab40ae 5 * You may obtain a copy of the License at
philware 1:d4ff95ab40ae 6 *
philware 1:d4ff95ab40ae 7 * http://www.apache.org/licenses/LICENSE-2.0
philware 1:d4ff95ab40ae 8 *
philware 1:d4ff95ab40ae 9 * Unless required by applicable law or agreed to in writing, software
philware 1:d4ff95ab40ae 10 * distributed under the License is distributed on an "AS IS" BASIS,
philware 1:d4ff95ab40ae 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
philware 1:d4ff95ab40ae 12 * See the License for the specific language governing permissions and
philware 1:d4ff95ab40ae 13 * limitations under the License.
philware 1:d4ff95ab40ae 14 */
philware 1:d4ff95ab40ae 15
philware 1:d4ff95ab40ae 16 #include "UARTSerial.h"
philware 1:d4ff95ab40ae 17 #include "APN_db.h"
philware 1:d4ff95ab40ae 18 #include "UbloxCellularBaseN2xx.h"
philware 1:d4ff95ab40ae 19 #include "onboard_modem_api.h"
philware 1:d4ff95ab40ae 20 #ifdef FEATURE_COMMON_PAL
philware 1:d4ff95ab40ae 21 #include "mbed_trace.h"
philware 1:d4ff95ab40ae 22 #define TRACE_GROUP "UCB"
philware 1:d4ff95ab40ae 23 #else
philware 1:d4ff95ab40ae 24 #define tr_debug(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
philware 1:d4ff95ab40ae 25 #define tr_info(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
philware 1:d4ff95ab40ae 26 #define tr_warn(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
philware 1:d4ff95ab40ae 27 #define tr_error(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
philware 1:d4ff95ab40ae 28 #endif
philware 1:d4ff95ab40ae 29
philware 1:d4ff95ab40ae 30 #define ATOK _at->recv("OK")
philware 1:d4ff95ab40ae 31
philware 1:d4ff95ab40ae 32 /**********************************************************************
philware 1:d4ff95ab40ae 33 * PRIVATE METHODS
philware 1:d4ff95ab40ae 34 **********************************************************************/
philware 1:d4ff95ab40ae 35
philware 1:d4ff95ab40ae 36 void UbloxCellularBaseN2xx::set_nwk_reg_status_csd(int status)
philware 1:d4ff95ab40ae 37 {
philware 1:d4ff95ab40ae 38 switch (status) {
philware 1:d4ff95ab40ae 39 case CSD_NOT_REGISTERED_NOT_SEARCHING:
philware 1:d4ff95ab40ae 40 case CSD_NOT_REGISTERED_SEARCHING:
philware 1:d4ff95ab40ae 41 tr_info("Not (yet) registered for circuit switched service");
philware 1:d4ff95ab40ae 42 break;
philware 1:d4ff95ab40ae 43 case CSD_REGISTERED:
philware 1:d4ff95ab40ae 44 case CSD_REGISTERED_ROAMING:
philware 1:d4ff95ab40ae 45 tr_info("Registered for circuit switched service");
philware 1:d4ff95ab40ae 46 break;
philware 1:d4ff95ab40ae 47 case CSD_REGISTRATION_DENIED:
philware 1:d4ff95ab40ae 48 tr_info("Circuit switched service denied");
philware 1:d4ff95ab40ae 49 break;
philware 1:d4ff95ab40ae 50 case CSD_UNKNOWN_COVERAGE:
philware 1:d4ff95ab40ae 51 tr_info("Out of circuit switched service coverage");
philware 1:d4ff95ab40ae 52 break;
philware 1:d4ff95ab40ae 53 case CSD_SMS_ONLY:
philware 1:d4ff95ab40ae 54 tr_info("SMS service only");
philware 1:d4ff95ab40ae 55 break;
philware 1:d4ff95ab40ae 56 case CSD_SMS_ONLY_ROAMING:
philware 1:d4ff95ab40ae 57 tr_info("SMS service only");
philware 1:d4ff95ab40ae 58 break;
philware 1:d4ff95ab40ae 59 case CSD_CSFB_NOT_PREFERRED:
philware 1:d4ff95ab40ae 60 tr_info("Registered for circuit switched service with CSFB not preferred");
philware 1:d4ff95ab40ae 61 break;
philware 1:d4ff95ab40ae 62 default:
philware 1:d4ff95ab40ae 63 tr_info("Unknown circuit switched service registration status. %d", status);
philware 1:d4ff95ab40ae 64 break;
philware 1:d4ff95ab40ae 65 }
philware 1:d4ff95ab40ae 66
philware 1:d4ff95ab40ae 67 _dev_info.reg_status_csd = static_cast<NetworkRegistrationStatusCsd>(status);
philware 1:d4ff95ab40ae 68 }
philware 1:d4ff95ab40ae 69
philware 1:d4ff95ab40ae 70 void UbloxCellularBaseN2xx::set_nwk_reg_status_psd(int status)
philware 1:d4ff95ab40ae 71 {
philware 1:d4ff95ab40ae 72 switch (status) {
philware 1:d4ff95ab40ae 73 case PSD_NOT_REGISTERED_NOT_SEARCHING:
philware 1:d4ff95ab40ae 74 case PSD_NOT_REGISTERED_SEARCHING:
philware 1:d4ff95ab40ae 75 tr_info("Not (yet) registered for packet switched service");
philware 1:d4ff95ab40ae 76 break;
philware 1:d4ff95ab40ae 77 case PSD_REGISTERED:
philware 1:d4ff95ab40ae 78 case PSD_REGISTERED_ROAMING:
philware 1:d4ff95ab40ae 79 tr_info("Registered for packet switched service");
philware 1:d4ff95ab40ae 80 break;
philware 1:d4ff95ab40ae 81 case PSD_REGISTRATION_DENIED:
philware 1:d4ff95ab40ae 82 tr_info("Packet switched service denied");
philware 1:d4ff95ab40ae 83 break;
philware 1:d4ff95ab40ae 84 case PSD_UNKNOWN_COVERAGE:
philware 1:d4ff95ab40ae 85 tr_info("Out of packet switched service coverage");
philware 1:d4ff95ab40ae 86 break;
philware 1:d4ff95ab40ae 87 case PSD_EMERGENCY_SERVICES_ONLY:
philware 1:d4ff95ab40ae 88 tr_info("Limited access for packet switched service. Emergency use only.");
philware 1:d4ff95ab40ae 89 break;
philware 1:d4ff95ab40ae 90 default:
philware 1:d4ff95ab40ae 91 tr_info("Unknown packet switched service registration status. %d", status);
philware 1:d4ff95ab40ae 92 break;
philware 1:d4ff95ab40ae 93 }
philware 1:d4ff95ab40ae 94
philware 1:d4ff95ab40ae 95 _dev_info.reg_status_psd = static_cast<NetworkRegistrationStatusPsd>(status);
philware 1:d4ff95ab40ae 96 }
philware 1:d4ff95ab40ae 97
philware 1:d4ff95ab40ae 98 void UbloxCellularBaseN2xx::set_nwk_reg_status_eps(int status)
philware 1:d4ff95ab40ae 99 {
philware 1:d4ff95ab40ae 100 switch (status) {
philware 1:d4ff95ab40ae 101 case EPS_NOT_REGISTERED_NOT_SEARCHING:
philware 1:d4ff95ab40ae 102 case EPS_NOT_REGISTERED_SEARCHING:
philware 1:d4ff95ab40ae 103 tr_info("Not (yet) registered for EPS service");
philware 1:d4ff95ab40ae 104 break;
philware 1:d4ff95ab40ae 105 case EPS_REGISTERED:
philware 1:d4ff95ab40ae 106 case EPS_REGISTERED_ROAMING:
philware 1:d4ff95ab40ae 107 tr_info("Registered for EPS service");
philware 1:d4ff95ab40ae 108 break;
philware 1:d4ff95ab40ae 109 case EPS_REGISTRATION_DENIED:
philware 1:d4ff95ab40ae 110 tr_info("EPS service denied");
philware 1:d4ff95ab40ae 111 break;
philware 1:d4ff95ab40ae 112 case EPS_UNKNOWN_COVERAGE:
philware 1:d4ff95ab40ae 113 tr_info("Out of EPS service coverage");
philware 1:d4ff95ab40ae 114 break;
philware 1:d4ff95ab40ae 115 case EPS_EMERGENCY_SERVICES_ONLY:
philware 1:d4ff95ab40ae 116 tr_info("Limited access for EPS service. Emergency use only.");
philware 1:d4ff95ab40ae 117 break;
philware 1:d4ff95ab40ae 118 default:
philware 1:d4ff95ab40ae 119 tr_info("Unknown EPS service registration status. %d", status);
philware 1:d4ff95ab40ae 120 break;
philware 1:d4ff95ab40ae 121 }
philware 1:d4ff95ab40ae 122
philware 1:d4ff95ab40ae 123 _dev_info.reg_status_eps = static_cast<NetworkRegistrationStatusEps>(status);
philware 1:d4ff95ab40ae 124 }
philware 1:d4ff95ab40ae 125
philware 1:d4ff95ab40ae 126 void UbloxCellularBaseN2xx::set_rat(int AcTStatus)
philware 1:d4ff95ab40ae 127 {
philware 1:d4ff95ab40ae 128 switch (AcTStatus) {
philware 1:d4ff95ab40ae 129 case GSM:
philware 1:d4ff95ab40ae 130 case COMPACT_GSM:
philware 1:d4ff95ab40ae 131 tr_info("Connected in GSM");
philware 1:d4ff95ab40ae 132 break;
philware 1:d4ff95ab40ae 133 case UTRAN:
philware 1:d4ff95ab40ae 134 tr_info("Connected to UTRAN");
philware 1:d4ff95ab40ae 135 break;
philware 1:d4ff95ab40ae 136 case EDGE:
philware 1:d4ff95ab40ae 137 tr_info("Connected to EDGE");
philware 1:d4ff95ab40ae 138 break;
philware 1:d4ff95ab40ae 139 case HSDPA:
philware 1:d4ff95ab40ae 140 tr_info("Connected to HSDPA");
philware 1:d4ff95ab40ae 141 break;
philware 1:d4ff95ab40ae 142 case HSUPA:
philware 1:d4ff95ab40ae 143 tr_info("Connected to HSPA");
philware 1:d4ff95ab40ae 144 break;
philware 1:d4ff95ab40ae 145 case HSDPA_HSUPA:
philware 1:d4ff95ab40ae 146 tr_info("Connected to HDPA/HSPA");
philware 1:d4ff95ab40ae 147 break;
philware 1:d4ff95ab40ae 148 case LTE:
philware 1:d4ff95ab40ae 149 tr_info("Connected to LTE");
philware 1:d4ff95ab40ae 150 break;
philware 1:d4ff95ab40ae 151 default:
philware 1:d4ff95ab40ae 152 tr_info("Unknown RAT %d", AcTStatus);
philware 1:d4ff95ab40ae 153 break;
philware 1:d4ff95ab40ae 154 }
philware 1:d4ff95ab40ae 155
philware 1:d4ff95ab40ae 156 _dev_info.rat = static_cast<RadioAccessNetworkType>(AcTStatus);
philware 1:d4ff95ab40ae 157 }
philware 1:d4ff95ab40ae 158
philware 1:d4ff95ab40ae 159 bool UbloxCellularBaseN2xx::get_sara_n2xx_info()
philware 1:d4ff95ab40ae 160 {
philware 1:d4ff95ab40ae 161 return (
philware 1:d4ff95ab40ae 162 cgmi(_sara_n2xx_info.cgmi) &&
philware 1:d4ff95ab40ae 163 cgmm(_sara_n2xx_info.cgmm) &&
philware 1:d4ff95ab40ae 164 cgmr(_sara_n2xx_info.cgmr) &&
philware 1:d4ff95ab40ae 165 cgsn(1, _sara_n2xx_info.cgsn)
philware 1:d4ff95ab40ae 166 );
philware 1:d4ff95ab40ae 167 }
philware 1:d4ff95ab40ae 168
philware 1:d4ff95ab40ae 169 bool UbloxCellularBaseN2xx::at_req(const char *cmd, const char *recvFormat, const char *response) {
philware 1:d4ff95ab40ae 170 bool success = false;
philware 1:d4ff95ab40ae 171 LOCK();
philware 1:d4ff95ab40ae 172
philware 1:d4ff95ab40ae 173 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 174
philware 1:d4ff95ab40ae 175 tr_debug("ATREQ: %s => %s", cmd, recvFormat);
philware 1:d4ff95ab40ae 176 if(_at->send(cmd) && _at->recv(recvFormat, response) && ATOK) {
philware 1:d4ff95ab40ae 177 tr_debug("ATRESULT: %s", response);
philware 1:d4ff95ab40ae 178 success = true;
philware 1:d4ff95ab40ae 179 } else {
philware 1:d4ff95ab40ae 180 tr_error("ATRESULT: No Answer!");
philware 1:d4ff95ab40ae 181 }
philware 1:d4ff95ab40ae 182
philware 1:d4ff95ab40ae 183 UNLOCK();
philware 1:d4ff95ab40ae 184 return success;
philware 1:d4ff95ab40ae 185 }
philware 1:d4ff95ab40ae 186
philware 1:d4ff95ab40ae 187 bool UbloxCellularBaseN2xx::at_req(const char *cmd, const char *recvFormat, int *response) {
philware 1:d4ff95ab40ae 188 bool success = false;
philware 1:d4ff95ab40ae 189 LOCK();
philware 1:d4ff95ab40ae 190
philware 1:d4ff95ab40ae 191 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 192
philware 1:d4ff95ab40ae 193 tr_debug("ATREQ: %s => %s", cmd, recvFormat);
philware 1:d4ff95ab40ae 194 if(_at->send(cmd) && _at->recv(recvFormat, response) && ATOK) {
philware 1:d4ff95ab40ae 195 tr_debug("ATRESULT: %d", *response);
philware 1:d4ff95ab40ae 196 success = true;
philware 1:d4ff95ab40ae 197 } else {
philware 1:d4ff95ab40ae 198 tr_error("ATRESULT: No Answer!");
philware 1:d4ff95ab40ae 199 }
philware 1:d4ff95ab40ae 200
philware 1:d4ff95ab40ae 201 UNLOCK();
philware 1:d4ff95ab40ae 202 return success;
philware 1:d4ff95ab40ae 203 }
philware 1:d4ff95ab40ae 204
philware 1:d4ff95ab40ae 205 bool UbloxCellularBaseN2xx::at_send(const char *cmd) {
philware 1:d4ff95ab40ae 206 bool success = false;
philware 1:d4ff95ab40ae 207 LOCK();
philware 1:d4ff95ab40ae 208
philware 1:d4ff95ab40ae 209 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 210
philware 1:d4ff95ab40ae 211 tr_debug("ATSEND: %s", cmd);
philware 1:d4ff95ab40ae 212 if(_at->send(cmd) && ATOK) {
philware 1:d4ff95ab40ae 213 success = true;
philware 1:d4ff95ab40ae 214 } else {
philware 1:d4ff95ab40ae 215 tr_error("Failed to send %s", cmd);
philware 1:d4ff95ab40ae 216 }
philware 1:d4ff95ab40ae 217
philware 1:d4ff95ab40ae 218 UNLOCK();
philware 1:d4ff95ab40ae 219 return success;
philware 1:d4ff95ab40ae 220 }
philware 1:d4ff95ab40ae 221
philware 1:d4ff95ab40ae 222 bool UbloxCellularBaseN2xx::at_send(const char *cmd, int n) {
philware 1:d4ff95ab40ae 223 bool success = false;
philware 1:d4ff95ab40ae 224 LOCK();
philware 1:d4ff95ab40ae 225
philware 1:d4ff95ab40ae 226 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 227
philware 1:d4ff95ab40ae 228 tr_debug("ATSEND: %s, %d", cmd, n);
philware 1:d4ff95ab40ae 229 if(_at->send(cmd, n) && ATOK) {
philware 1:d4ff95ab40ae 230 success = true;
philware 1:d4ff95ab40ae 231 } else {
philware 1:d4ff95ab40ae 232 tr_error("Failed to send %s,%d", cmd, n);
philware 1:d4ff95ab40ae 233 }
philware 1:d4ff95ab40ae 234
philware 1:d4ff95ab40ae 235 UNLOCK();
philware 1:d4ff95ab40ae 236 return success;
philware 1:d4ff95ab40ae 237 }
philware 1:d4ff95ab40ae 238
philware 1:d4ff95ab40ae 239 bool UbloxCellularBaseN2xx::at_send(const char *cmd, const char *arg) {
philware 1:d4ff95ab40ae 240 bool success = false;
philware 1:d4ff95ab40ae 241 LOCK();
philware 1:d4ff95ab40ae 242
philware 1:d4ff95ab40ae 243 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 244
philware 1:d4ff95ab40ae 245 tr_debug("ATSEND: %s,%s", cmd, arg);
philware 1:d4ff95ab40ae 246 if(_at->send(cmd, arg) && ATOK) {
philware 1:d4ff95ab40ae 247 success = true;
philware 1:d4ff95ab40ae 248 } else {
philware 1:d4ff95ab40ae 249 tr_error("Failed to send %s,%s", cmd, arg);
philware 1:d4ff95ab40ae 250 }
philware 1:d4ff95ab40ae 251
philware 1:d4ff95ab40ae 252 UNLOCK();
philware 1:d4ff95ab40ae 253 return success;
philware 1:d4ff95ab40ae 254 }
philware 1:d4ff95ab40ae 255
philware 1:d4ff95ab40ae 256 bool UbloxCellularBaseN2xx::cgmi(const char *response)
philware 1:d4ff95ab40ae 257 {
philware 1:d4ff95ab40ae 258 return at_req("AT+CGMI", "%32[^\n]\n", response);
philware 1:d4ff95ab40ae 259 }
philware 1:d4ff95ab40ae 260
philware 1:d4ff95ab40ae 261 bool UbloxCellularBaseN2xx::cgmm(const char *response) {
philware 1:d4ff95ab40ae 262 return at_req("AT+CGMM", "%32[^\n]\n", response);
philware 1:d4ff95ab40ae 263 }
philware 1:d4ff95ab40ae 264
philware 1:d4ff95ab40ae 265 bool UbloxCellularBaseN2xx::cimi(const char *response) {
philware 1:d4ff95ab40ae 266 return at_req("AT+CIMI", "%32[^\n]\n", response);
philware 1:d4ff95ab40ae 267 }
philware 1:d4ff95ab40ae 268
philware 1:d4ff95ab40ae 269 bool UbloxCellularBaseN2xx::ccid(const char *response) {
philware 1:d4ff95ab40ae 270 return at_req("AT+NCCID", "+NCCID:%32[^\n]\n", response);
philware 1:d4ff95ab40ae 271 }
philware 1:d4ff95ab40ae 272
philware 1:d4ff95ab40ae 273 bool UbloxCellularBaseN2xx::cgmr(const char *response) {
philware 1:d4ff95ab40ae 274 return at_req("AT+CGMR", "%32[^\n]\n", response);
philware 1:d4ff95ab40ae 275 }
philware 1:d4ff95ab40ae 276
philware 1:d4ff95ab40ae 277 bool UbloxCellularBaseN2xx::cgsn(int snt, const char *response) {
philware 1:d4ff95ab40ae 278 char cmd[10];
philware 1:d4ff95ab40ae 279 sprintf(cmd, "AT+CGSN=%d", snt);
philware 1:d4ff95ab40ae 280
philware 1:d4ff95ab40ae 281 return at_req(cmd, "+CGSN:%32[^\n]\n", response);
philware 1:d4ff95ab40ae 282 }
philware 1:d4ff95ab40ae 283
philware 1:d4ff95ab40ae 284 bool UbloxCellularBaseN2xx::cereg(int n) {
philware 1:d4ff95ab40ae 285 return at_send("AT+CEREG=%d", n);
philware 1:d4ff95ab40ae 286 }
philware 1:d4ff95ab40ae 287
philware 1:d4ff95ab40ae 288 nsapi_error_t UbloxCellularBaseN2xx::get_cereg() {
philware 1:d4ff95ab40ae 289 nsapi_error_t r = NSAPI_ERROR_DEVICE_ERROR;
philware 1:d4ff95ab40ae 290 LOCK();
philware 1:d4ff95ab40ae 291
philware 1:d4ff95ab40ae 292 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 293
philware 1:d4ff95ab40ae 294 // The response will be handled by the CEREG URC, by waiting for the OK we know it has been serviced.
philware 1:d4ff95ab40ae 295 if (at_send("AT+CEREG?")){
philware 1:d4ff95ab40ae 296 r = _dev_info.reg_status_eps;
philware 1:d4ff95ab40ae 297 }
philware 1:d4ff95ab40ae 298
philware 1:d4ff95ab40ae 299 UNLOCK();
philware 1:d4ff95ab40ae 300 return r;
philware 1:d4ff95ab40ae 301 }
philware 1:d4ff95ab40ae 302
philware 1:d4ff95ab40ae 303 nsapi_error_t UbloxCellularBaseN2xx::get_cscon() {
philware 1:d4ff95ab40ae 304 char resp[3+1];
philware 1:d4ff95ab40ae 305
philware 1:d4ff95ab40ae 306 int n, stat;
philware 1:d4ff95ab40ae 307
philware 1:d4ff95ab40ae 308 if (at_req("AT+CSCON?", "+CSCON:%3[^\n]\n", resp) &&
philware 1:d4ff95ab40ae 309 sscanf(resp, "%d,%d", &n, &stat)) {
philware 1:d4ff95ab40ae 310 return stat;
philware 1:d4ff95ab40ae 311 }
philware 1:d4ff95ab40ae 312
philware 1:d4ff95ab40ae 313 return NSAPI_ERROR_DEVICE_ERROR;
philware 1:d4ff95ab40ae 314 }
philware 1:d4ff95ab40ae 315
philware 1:d4ff95ab40ae 316 nsapi_error_t UbloxCellularBaseN2xx::get_csq() {
philware 1:d4ff95ab40ae 317 char resp[5+1];
philware 1:d4ff95ab40ae 318 nsapi_error_t rssi = NSAPI_ERROR_DEVICE_ERROR;
philware 1:d4ff95ab40ae 319
philware 1:d4ff95ab40ae 320 LOCK();
philware 1:d4ff95ab40ae 321 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 322
philware 1:d4ff95ab40ae 323 if (at_req("AT+CSQ", "+CSQ:%5[^\n]\n", resp) &&
philware 1:d4ff95ab40ae 324 sscanf(resp, "%d,%*d", &rssi)) {
philware 1:d4ff95ab40ae 325 return rssi;
philware 1:d4ff95ab40ae 326 }
philware 1:d4ff95ab40ae 327
philware 1:d4ff95ab40ae 328 UNLOCK();
philware 1:d4ff95ab40ae 329 return rssi;
philware 1:d4ff95ab40ae 330 }
philware 1:d4ff95ab40ae 331
philware 1:d4ff95ab40ae 332 bool UbloxCellularBaseN2xx::cops(const char *plmn) {
philware 1:d4ff95ab40ae 333 return at_send("AT+COPS=1,2,\"%s\"", plmn);
philware 1:d4ff95ab40ae 334 }
philware 1:d4ff95ab40ae 335
philware 1:d4ff95ab40ae 336 bool UbloxCellularBaseN2xx::cops(int mode) {
philware 1:d4ff95ab40ae 337 return at_send("AT+COPS=%d", mode);
philware 1:d4ff95ab40ae 338 }
philware 1:d4ff95ab40ae 339
philware 1:d4ff95ab40ae 340 bool UbloxCellularBaseN2xx::get_cops(int *status) {
philware 1:d4ff95ab40ae 341 return at_req("AT+COPS?", "+COPS: %d", status);
philware 1:d4ff95ab40ae 342 }
philware 1:d4ff95ab40ae 343
philware 1:d4ff95ab40ae 344 bool UbloxCellularBaseN2xx::cfun(int mode) {
philware 1:d4ff95ab40ae 345 return at_send("AT+CFUN=%d", mode);
philware 1:d4ff95ab40ae 346 }
philware 1:d4ff95ab40ae 347
philware 1:d4ff95ab40ae 348 bool UbloxCellularBaseN2xx::reboot() {
philware 1:d4ff95ab40ae 349 return at_send("AT+NRB");
philware 1:d4ff95ab40ae 350 }
philware 1:d4ff95ab40ae 351
philware 1:d4ff95ab40ae 352 bool UbloxCellularBaseN2xx::auto_connect(bool state) {
philware 1:d4ff95ab40ae 353 return nconfig("AUTOCONNECT", state);
philware 1:d4ff95ab40ae 354 }
philware 1:d4ff95ab40ae 355
philware 1:d4ff95ab40ae 356 bool UbloxCellularBaseN2xx::nconfig(const char *name, bool state) {
philware 1:d4ff95ab40ae 357 char n[50];
philware 1:d4ff95ab40ae 358
philware 1:d4ff95ab40ae 359 if (state)
philware 5:66451d314225 360 sprintf(n, "AT+NCONFIG=\"%s\",\"TRUE\"", name);
philware 1:d4ff95ab40ae 361 else
philware 5:66451d314225 362 sprintf(n, "AT+NCONFIG=\"%s\",\"FALSE\"", name);
philware 1:d4ff95ab40ae 363
philware 1:d4ff95ab40ae 364 return at_send(n);
philware 1:d4ff95ab40ae 365 }
philware 1:d4ff95ab40ae 366
philware 1:d4ff95ab40ae 367 bool UbloxCellularBaseN2xx::get_iccid()
philware 1:d4ff95ab40ae 368 {
philware 1:d4ff95ab40ae 369 // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
philware 1:d4ff95ab40ae 370 // ICCID is a serial number identifying the SIM.
philware 1:d4ff95ab40ae 371 // AT Command Manual UBX-13002752, section 4.12
philware 1:d4ff95ab40ae 372 bool success = ccid(_dev_info.iccid);
philware 1:d4ff95ab40ae 373 tr_info("DevInfo: ICCID=%s", _dev_info.iccid);
philware 1:d4ff95ab40ae 374
philware 1:d4ff95ab40ae 375 return success;
philware 1:d4ff95ab40ae 376 }
philware 1:d4ff95ab40ae 377
philware 1:d4ff95ab40ae 378 bool UbloxCellularBaseN2xx::get_imsi()
philware 1:d4ff95ab40ae 379 {
philware 1:d4ff95ab40ae 380 // International mobile subscriber identification
philware 1:d4ff95ab40ae 381 // AT Command Manual UBX-13002752, section 4.11
philware 1:d4ff95ab40ae 382 bool success = cimi(_dev_info.imsi);
philware 1:d4ff95ab40ae 383 tr_info("DevInfo: IMSI=%s", _dev_info.imsi);
philware 1:d4ff95ab40ae 384
philware 1:d4ff95ab40ae 385 return success;
philware 1:d4ff95ab40ae 386 }
philware 1:d4ff95ab40ae 387
philware 1:d4ff95ab40ae 388 bool UbloxCellularBaseN2xx::get_imei()
philware 1:d4ff95ab40ae 389 {
philware 1:d4ff95ab40ae 390 // International mobile equipment identifier
philware 1:d4ff95ab40ae 391 // AT Command Manual UBX-13002752, section 4.7
philware 1:d4ff95ab40ae 392 bool success = cgsn(1, _dev_info.imei);
philware 1:d4ff95ab40ae 393 tr_info("DevInfo: IMEI=%s", _dev_info.imei);
philware 1:d4ff95ab40ae 394
philware 1:d4ff95ab40ae 395 return success;
philware 1:d4ff95ab40ae 396 }
philware 1:d4ff95ab40ae 397
mudassar0121 7:f1c3373e4ff5 398 bool UbloxCellularBaseN2xx::get_imei(char *buffer,int size)
mudassar0121 7:f1c3373e4ff5 399 {
mudassar0121 7:f1c3373e4ff5 400 // International mobile equipment identifier
mudassar0121 7:f1c3373e4ff5 401 // AT Command Manual UBX-13002752, section 4.7
mudassar0121 7:f1c3373e4ff5 402 bool success = cgsn(1, _dev_info.imei);
mudassar0121 7:f1c3373e4ff5 403 tr_info("DevInfo: IMEI=%s", _dev_info.imei);
mudassar0121 7:f1c3373e4ff5 404
mudassar0121 7:f1c3373e4ff5 405 if(success)
mudassar0121 7:f1c3373e4ff5 406 {
mudassar0121 7:f1c3373e4ff5 407 memcpy(buffer,_dev_info.imei,size);
mudassar0121 7:f1c3373e4ff5 408 buffer[size-1] = '\0';
mudassar0121 7:f1c3373e4ff5 409 }
mudassar0121 7:f1c3373e4ff5 410
mudassar0121 7:f1c3373e4ff5 411 return success;
mudassar0121 7:f1c3373e4ff5 412 }
mudassar0121 7:f1c3373e4ff5 413
philware 1:d4ff95ab40ae 414 bool UbloxCellularBaseN2xx::get_meid()
philware 1:d4ff95ab40ae 415 {
Rob Meades 6:377997119ef1 416 // *** NOT IMPLEMENTED on SARA-N2XX
philware 1:d4ff95ab40ae 417 return false;
philware 1:d4ff95ab40ae 418 }
philware 1:d4ff95ab40ae 419
philware 1:d4ff95ab40ae 420 bool UbloxCellularBaseN2xx::set_sms()
philware 1:d4ff95ab40ae 421 {
Rob Meades 6:377997119ef1 422 // *** NOT IMPLEMENTED on SARA-N2XX
Rob Meades 6:377997119ef1 423 return false;
philware 1:d4ff95ab40ae 424 }
philware 1:d4ff95ab40ae 425
philware 1:d4ff95ab40ae 426 void UbloxCellularBaseN2xx::parser_abort_cb()
philware 1:d4ff95ab40ae 427 {
philware 1:d4ff95ab40ae 428 _at->abort();
philware 1:d4ff95ab40ae 429 }
philware 1:d4ff95ab40ae 430
philware 1:d4ff95ab40ae 431 // Callback for CME ERROR and CMS ERROR.
philware 1:d4ff95ab40ae 432 void UbloxCellularBaseN2xx::CMX_ERROR_URC()
philware 1:d4ff95ab40ae 433 {
philware 1:d4ff95ab40ae 434 char buf[48];
philware 1:d4ff95ab40ae 435
philware 1:d4ff95ab40ae 436 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
philware 1:d4ff95ab40ae 437 tr_debug("AT error %s", buf);
philware 1:d4ff95ab40ae 438 }
philware 1:d4ff95ab40ae 439 parser_abort_cb();
philware 1:d4ff95ab40ae 440 }
philware 1:d4ff95ab40ae 441
philware 1:d4ff95ab40ae 442 // Callback for EPS registration URC.
philware 1:d4ff95ab40ae 443 void UbloxCellularBaseN2xx::CEREG_URC()
philware 1:d4ff95ab40ae 444 {
philware 1:d4ff95ab40ae 445 char buf[20];
philware 1:d4ff95ab40ae 446 int status;
philware 1:d4ff95ab40ae 447 int n, AcT;
philware 1:d4ff95ab40ae 448 char tac[4], ci[4];
philware 1:d4ff95ab40ae 449
philware 1:d4ff95ab40ae 450 // If this is the URC it will be a single
philware 1:d4ff95ab40ae 451 // digit followed by \n. If it is the
philware 1:d4ff95ab40ae 452 // answer to a CEREG query, it will be
philware 1:d4ff95ab40ae 453 // a ": %d,%d\n" where the second digit
philware 1:d4ff95ab40ae 454 // indicates the status
philware 1:d4ff95ab40ae 455 // Note: not calling _at->recv() from here as we're
philware 1:d4ff95ab40ae 456 // already in an _at->recv()
philware 1:d4ff95ab40ae 457 // We also hanlde the extended 4 or 5 argument
philware 1:d4ff95ab40ae 458 // response if cereg is set to 2.
philware 1:d4ff95ab40ae 459 if (read_at_to_newline(buf, sizeof (buf)) > 0) {
philware 1:d4ff95ab40ae 460 if (sscanf(buf, ":%d,%d,%[0123456789abcdef],%[0123456789abcdef],%d\n", &n, &status, tac, ci, &AcT) == 5) {
philware 1:d4ff95ab40ae 461 set_nwk_reg_status_eps(status);
philware 1:d4ff95ab40ae 462 } else if (sscanf(buf, ":%d,%[0123456789abcdef],%[0123456789abcdef],%d\n`", &status, tac, ci, &AcT) == 4) {
philware 1:d4ff95ab40ae 463 set_nwk_reg_status_eps(status);
philware 1:d4ff95ab40ae 464 } else if (sscanf(buf, ":%d,%d\n", &n, &status) == 2) {
philware 1:d4ff95ab40ae 465 set_nwk_reg_status_eps(status);
philware 1:d4ff95ab40ae 466 } else if (sscanf(buf, ":%d\n", &status) == 1) {
philware 1:d4ff95ab40ae 467 set_nwk_reg_status_eps(status);
philware 1:d4ff95ab40ae 468 }
philware 1:d4ff95ab40ae 469 }
philware 1:d4ff95ab40ae 470 }
philware 1:d4ff95ab40ae 471
philware 1:d4ff95ab40ae 472 /**********************************************************************
philware 1:d4ff95ab40ae 473 * PROTECTED METHODS
philware 1:d4ff95ab40ae 474 **********************************************************************/
philware 1:d4ff95ab40ae 475
philware 1:d4ff95ab40ae 476 #if MODEM_ON_BOARD
philware 1:d4ff95ab40ae 477 void UbloxCellularBaseN2xx::modem_init()
philware 1:d4ff95ab40ae 478 {
philware 1:d4ff95ab40ae 479 ::onboard_modem_init();
philware 1:d4ff95ab40ae 480 }
philware 1:d4ff95ab40ae 481
philware 1:d4ff95ab40ae 482 void UbloxCellularBaseN2xx::modem_deinit()
philware 1:d4ff95ab40ae 483 {
philware 1:d4ff95ab40ae 484 ::onboard_modem_deinit();
philware 1:d4ff95ab40ae 485 }
philware 1:d4ff95ab40ae 486
philware 1:d4ff95ab40ae 487 void UbloxCellularBaseN2xx::modem_power_up()
philware 1:d4ff95ab40ae 488 {
philware 1:d4ff95ab40ae 489 ::onboard_modem_power_up();
philware 1:d4ff95ab40ae 490 }
philware 1:d4ff95ab40ae 491
philware 1:d4ff95ab40ae 492 void UbloxCellularBaseN2xx::modem_power_down()
philware 1:d4ff95ab40ae 493 {
philware 1:d4ff95ab40ae 494 ::onboard_modem_power_down();
philware 1:d4ff95ab40ae 495 }
philware 1:d4ff95ab40ae 496 #else
philware 1:d4ff95ab40ae 497 void UbloxCellularBaseN2xx::modem_init()
philware 1:d4ff95ab40ae 498 {
philware 1:d4ff95ab40ae 499 // Meant to be overridden
philware 1:d4ff95ab40ae 500 #error need to do something here!
philware 1:d4ff95ab40ae 501 }
philware 1:d4ff95ab40ae 502
philware 1:d4ff95ab40ae 503 void UbloxCellularBaseN2xx::modem_deinit()
philware 1:d4ff95ab40ae 504 {
philware 1:d4ff95ab40ae 505 // Meant to be overridden
philware 1:d4ff95ab40ae 506 }
philware 1:d4ff95ab40ae 507
philware 1:d4ff95ab40ae 508 void UbloxCellularBaseN2xx::modem_power_up()
philware 1:d4ff95ab40ae 509 {
philware 1:d4ff95ab40ae 510 // Meant to be overridden
philware 1:d4ff95ab40ae 511 }
philware 1:d4ff95ab40ae 512
philware 1:d4ff95ab40ae 513 void UbloxCellularBaseN2xx::modem_power_down()
philware 1:d4ff95ab40ae 514 {
philware 1:d4ff95ab40ae 515 // Mmeant to be overridden
philware 1:d4ff95ab40ae 516 }
philware 1:d4ff95ab40ae 517 #endif
philware 1:d4ff95ab40ae 518
philware 1:d4ff95ab40ae 519 // Constructor.
philware 1:d4ff95ab40ae 520 // Note: to allow this base class to be inherited as a virtual base class
philware 1:d4ff95ab40ae 521 // by everyone, it takes no parameters. See also comment above classInit()
philware 1:d4ff95ab40ae 522 // in the header file.
philware 1:d4ff95ab40ae 523 UbloxCellularBaseN2xx::UbloxCellularBaseN2xx()
philware 1:d4ff95ab40ae 524 {
philware 1:d4ff95ab40ae 525 tr_debug("UbloxATCellularBaseN2xx Constructor");
philware 1:d4ff95ab40ae 526
philware 1:d4ff95ab40ae 527 _pin = NULL;
philware 1:d4ff95ab40ae 528 _at = NULL;
philware 1:d4ff95ab40ae 529 _at_timeout = AT_PARSER_TIMEOUT;
philware 1:d4ff95ab40ae 530 _fh = NULL;
philware 1:d4ff95ab40ae 531 _modem_initialised = false;
philware 1:d4ff95ab40ae 532 _sim_pin_check_enabled = false;
philware 1:d4ff95ab40ae 533 _debug_trace_on = false;
philware 1:d4ff95ab40ae 534
philware 1:d4ff95ab40ae 535 _dev_info.dev = DEV_TYPE_NONE;
philware 1:d4ff95ab40ae 536 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 537 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 538 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 539 }
philware 1:d4ff95ab40ae 540
philware 1:d4ff95ab40ae 541 // Destructor.
philware 1:d4ff95ab40ae 542 UbloxCellularBaseN2xx::~UbloxCellularBaseN2xx()
philware 1:d4ff95ab40ae 543 {
philware 1:d4ff95ab40ae 544 deinit();
philware 1:d4ff95ab40ae 545 delete _at;
philware 1:d4ff95ab40ae 546 delete _fh;
philware 1:d4ff95ab40ae 547 }
philware 1:d4ff95ab40ae 548
philware 1:d4ff95ab40ae 549 // Initialise the portions of this class that are parameterised.
philware 1:d4ff95ab40ae 550 void UbloxCellularBaseN2xx::baseClassInit(PinName tx, PinName rx,
philware 1:d4ff95ab40ae 551 int baud, bool debug_on)
philware 1:d4ff95ab40ae 552 {
philware 1:d4ff95ab40ae 553 // Only initialise ourselves if it's not already been done
philware 1:d4ff95ab40ae 554 if (_at == NULL) {
philware 1:d4ff95ab40ae 555 if (_debug_trace_on == false) {
philware 1:d4ff95ab40ae 556 _debug_trace_on = debug_on;
philware 1:d4ff95ab40ae 557 }
philware 1:d4ff95ab40ae 558
philware 1:d4ff95ab40ae 559 // Set up File Handle for buffered serial comms with cellular module
philware 1:d4ff95ab40ae 560 // (which will be used by the AT parser)
philware 1:d4ff95ab40ae 561 _fh = new UARTSerial(tx, rx, baud);
philware 1:d4ff95ab40ae 562
philware 1:d4ff95ab40ae 563 // Set up the AT parser
philware 1:d4ff95ab40ae 564 _at = new ATCmdParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE,
philware 1:d4ff95ab40ae 565 _at_timeout, _debug_trace_on);
philware 1:d4ff95ab40ae 566
philware 1:d4ff95ab40ae 567 // Error cases, out of band handling
philware 1:d4ff95ab40ae 568 _at->oob("ERROR", callback(this, &UbloxCellularBaseN2xx::parser_abort_cb));
philware 1:d4ff95ab40ae 569 _at->oob("+CME ERROR", callback(this, &UbloxCellularBaseN2xx::CMX_ERROR_URC));
philware 1:d4ff95ab40ae 570 _at->oob("+CMS ERROR", callback(this, &UbloxCellularBaseN2xx::CMX_ERROR_URC));
philware 1:d4ff95ab40ae 571
philware 1:d4ff95ab40ae 572 // Registration status, out of band handling
philware 1:d4ff95ab40ae 573 _at->oob("+CEREG", callback(this, &UbloxCellularBaseN2xx::CEREG_URC));
philware 1:d4ff95ab40ae 574 }
philware 1:d4ff95ab40ae 575 }
philware 1:d4ff95ab40ae 576
philware 1:d4ff95ab40ae 577 // Set the AT parser timeout.
philware 1:d4ff95ab40ae 578 // Note: the AT interface should be locked before this is called.
philware 1:d4ff95ab40ae 579 void UbloxCellularBaseN2xx::at_set_timeout(int timeout) {
philware 1:d4ff95ab40ae 580
philware 1:d4ff95ab40ae 581 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 582
philware 1:d4ff95ab40ae 583 _at_timeout = timeout;
philware 1:d4ff95ab40ae 584 _at->set_timeout(timeout);
philware 1:d4ff95ab40ae 585 }
philware 1:d4ff95ab40ae 586
philware 1:d4ff95ab40ae 587 // Read up to size bytes from the AT interface up to a "end".
philware 1:d4ff95ab40ae 588 // Note: the AT interface should be locked before this is called.
philware 1:d4ff95ab40ae 589 int UbloxCellularBaseN2xx::read_at_to_char(char * buf, int size, char end)
philware 1:d4ff95ab40ae 590 {
philware 1:d4ff95ab40ae 591 int count = 0;
philware 1:d4ff95ab40ae 592 int x = 0;
philware 1:d4ff95ab40ae 593
philware 1:d4ff95ab40ae 594 if (size > 0) {
philware 1:d4ff95ab40ae 595 for (count = 0; (count < size) && (x >= 0) && (x != end); count++) {
philware 1:d4ff95ab40ae 596 x = _at->getc();
philware 1:d4ff95ab40ae 597 *(buf + count) = (char) x;
philware 1:d4ff95ab40ae 598 }
philware 1:d4ff95ab40ae 599
philware 1:d4ff95ab40ae 600 count--;
philware 1:d4ff95ab40ae 601 *(buf + count) = 0;
philware 1:d4ff95ab40ae 602
philware 1:d4ff95ab40ae 603 // Convert line endings:
philware 1:d4ff95ab40ae 604 // If end was '\n' (0x0a) and the preceding character was 0x0d, then
philware 1:d4ff95ab40ae 605 // overwrite that with null as well.
philware 1:d4ff95ab40ae 606 if ((count > 0) && (end == '\n') && (*(buf + count - 1) == '\x0d')) {
philware 1:d4ff95ab40ae 607 count--;
philware 1:d4ff95ab40ae 608 *(buf + count) = 0;
philware 1:d4ff95ab40ae 609 }
philware 1:d4ff95ab40ae 610 }
philware 1:d4ff95ab40ae 611
philware 1:d4ff95ab40ae 612 return count;
philware 1:d4ff95ab40ae 613 }
philware 1:d4ff95ab40ae 614
philware 1:d4ff95ab40ae 615 // Power up the modem.
philware 1:d4ff95ab40ae 616 // Enables the GPIO lines to the modem and then wriggles the power line in short pulses.
philware 1:d4ff95ab40ae 617 bool UbloxCellularBaseN2xx::power_up()
philware 1:d4ff95ab40ae 618 {
philware 1:d4ff95ab40ae 619 bool success = false;
philware 1:d4ff95ab40ae 620 int at_timeout;
philware 1:d4ff95ab40ae 621 LOCK();
philware 1:d4ff95ab40ae 622
philware 1:d4ff95ab40ae 623 at_timeout = _at_timeout; // Has to be inside LOCK()s
philware 1:d4ff95ab40ae 624
philware 1:d4ff95ab40ae 625 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 626
philware 1:d4ff95ab40ae 627 /* Initialize GPIO lines */
philware 1:d4ff95ab40ae 628 tr_info("Powering up modem...");
philware 1:d4ff95ab40ae 629 onboard_modem_init();
philware 1:d4ff95ab40ae 630 /* Give SARA-N2XX time to reset */
philware 1:d4ff95ab40ae 631 tr_debug("Waiting for 5 seconds (booting SARA-N2xx)...");
philware 1:d4ff95ab40ae 632 wait_ms(5000);
philware 1:d4ff95ab40ae 633
philware 1:d4ff95ab40ae 634 at_set_timeout(1000);
philware 1:d4ff95ab40ae 635 for (int retry_count = 0; !success && (retry_count < 20); retry_count++) {
philware 1:d4ff95ab40ae 636 _at->flush();
philware 1:d4ff95ab40ae 637 if (at_send("AT")) {
philware 1:d4ff95ab40ae 638 success = true;
philware 1:d4ff95ab40ae 639 }
philware 1:d4ff95ab40ae 640 }
philware 1:d4ff95ab40ae 641 at_set_timeout(at_timeout);
philware 1:d4ff95ab40ae 642
philware 1:d4ff95ab40ae 643 // perform any initialisation AT commands here
philware 1:d4ff95ab40ae 644 if (success) {
philware 1:d4ff95ab40ae 645 success = at_send("AT+CMEE=1"); // Turn on verbose responses
philware 1:d4ff95ab40ae 646 }
philware 1:d4ff95ab40ae 647
philware 1:d4ff95ab40ae 648 if (!success) {
philware 1:d4ff95ab40ae 649 tr_error("Preliminary modem setup failed.");
philware 1:d4ff95ab40ae 650 }
philware 1:d4ff95ab40ae 651
philware 1:d4ff95ab40ae 652 UNLOCK();
philware 1:d4ff95ab40ae 653 return success;
philware 1:d4ff95ab40ae 654 }
philware 1:d4ff95ab40ae 655
philware 1:d4ff95ab40ae 656 // Power down modem via AT interface.
philware 1:d4ff95ab40ae 657 void UbloxCellularBaseN2xx::power_down()
philware 1:d4ff95ab40ae 658 {
philware 1:d4ff95ab40ae 659 LOCK();
philware 1:d4ff95ab40ae 660
philware 1:d4ff95ab40ae 661 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 662
philware 1:d4ff95ab40ae 663 // If we have been running, do a soft power-off first
philware 1:d4ff95ab40ae 664 if (_modem_initialised && (_at != NULL)) {
philware 1:d4ff95ab40ae 665 // NOT IMPLEMENTED in B656 firmware
philware 1:d4ff95ab40ae 666 // at_send("AT+CPWROFF");
philware 1:d4ff95ab40ae 667 }
philware 1:d4ff95ab40ae 668
philware 1:d4ff95ab40ae 669 // Now do a hard power-off
philware 1:d4ff95ab40ae 670 onboard_modem_power_down();
philware 1:d4ff95ab40ae 671 onboard_modem_deinit();
philware 1:d4ff95ab40ae 672
philware 1:d4ff95ab40ae 673 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 674 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 675 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 676
philware 1:d4ff95ab40ae 677 UNLOCK();
philware 1:d4ff95ab40ae 678 }
philware 1:d4ff95ab40ae 679
philware 1:d4ff95ab40ae 680 // Get the device ID.
philware 1:d4ff95ab40ae 681 bool UbloxCellularBaseN2xx::set_device_identity(DeviceType *dev)
philware 1:d4ff95ab40ae 682 {
philware 1:d4ff95ab40ae 683 char buf[20];
philware 1:d4ff95ab40ae 684 bool success;
philware 1:d4ff95ab40ae 685 LOCK();
philware 1:d4ff95ab40ae 686
philware 1:d4ff95ab40ae 687 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 688
philware 1:d4ff95ab40ae 689 success = at_req("AT+CGMM", "%19[^\n]\n", buf);
philware 1:d4ff95ab40ae 690
philware 1:d4ff95ab40ae 691 if (success) {
philware 1:d4ff95ab40ae 692 if (strstr(buf, "Neul Hi2110"))
philware 1:d4ff95ab40ae 693 *dev = DEV_SARA_N2;
philware 1:d4ff95ab40ae 694 }
philware 1:d4ff95ab40ae 695
philware 1:d4ff95ab40ae 696 UNLOCK();
philware 1:d4ff95ab40ae 697 return success;
philware 1:d4ff95ab40ae 698 }
philware 1:d4ff95ab40ae 699
philware 1:d4ff95ab40ae 700 // Send initialisation AT commands that are specific to the device.
philware 1:d4ff95ab40ae 701 bool UbloxCellularBaseN2xx::device_init(DeviceType dev)
philware 1:d4ff95ab40ae 702 {
philware 1:d4ff95ab40ae 703 // SARA-N2xx doesn't have anything to initialise
philware 1:d4ff95ab40ae 704 return true;
philware 1:d4ff95ab40ae 705 }
philware 1:d4ff95ab40ae 706
philware 1:d4ff95ab40ae 707 // Get the SIM card going.
philware 1:d4ff95ab40ae 708 bool UbloxCellularBaseN2xx::initialise_sim_card()
philware 1:d4ff95ab40ae 709 {
philware 1:d4ff95ab40ae 710 // SARA-N2XX doesn't have any SIM AT Commands for now.
philware 1:d4ff95ab40ae 711 return true;
philware 1:d4ff95ab40ae 712 }
philware 1:d4ff95ab40ae 713
philware 1:d4ff95ab40ae 714 /**********************************************************************
philware 1:d4ff95ab40ae 715 * PUBLIC METHODS
philware 1:d4ff95ab40ae 716 **********************************************************************/
philware 1:d4ff95ab40ae 717
philware 1:d4ff95ab40ae 718 // Initialise the modem.
philware 1:d4ff95ab40ae 719 bool UbloxCellularBaseN2xx::init(const char *pin)
philware 1:d4ff95ab40ae 720 {
philware 1:d4ff95ab40ae 721 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 722
philware 1:d4ff95ab40ae 723 if (!_modem_initialised) {
philware 3:39eadc84c5ac 724 tr_warn("Modem not initialised, initialising...");
philware 1:d4ff95ab40ae 725 if (power_up()) {
philware 3:39eadc84c5ac 726 tr_info("Modem Powered Up.");
philware 1:d4ff95ab40ae 727 if (pin != NULL) {
philware 1:d4ff95ab40ae 728 _pin = pin;
philware 1:d4ff95ab40ae 729 }
philware 1:d4ff95ab40ae 730
philware 1:d4ff95ab40ae 731 if (initialise_sim_card()) {
philware 3:39eadc84c5ac 732 tr_info("Sim ready...");
philware 1:d4ff95ab40ae 733 if (set_device_identity(&_dev_info.dev) && // Set up device identity
philware 1:d4ff95ab40ae 734 device_init(_dev_info.dev) &&
philware 1:d4ff95ab40ae 735 get_sara_n2xx_info())
philware 1:d4ff95ab40ae 736 {
philware 1:d4ff95ab40ae 737 tr_debug("CGMM: %s", _sara_n2xx_info.cgmm);
philware 1:d4ff95ab40ae 738 tr_debug("CGMI: %s", _sara_n2xx_info.cgmi);
philware 1:d4ff95ab40ae 739 tr_debug("CGMR: %s", _sara_n2xx_info.cgmr);
philware 1:d4ff95ab40ae 740 tr_debug("CGSN: %s", _sara_n2xx_info.cgsn);
philware 1:d4ff95ab40ae 741
philware 1:d4ff95ab40ae 742 // The modem is initialised. The following checks my still fail,
philware 1:d4ff95ab40ae 743 // of course, but they are all of a "fatal" nature and so we wouldn't
philware 1:d4ff95ab40ae 744 // want to retry them anyway
philware 1:d4ff95ab40ae 745 _modem_initialised = true;
philware 1:d4ff95ab40ae 746 }
philware 1:d4ff95ab40ae 747 }
philware 3:39eadc84c5ac 748 } else {
philware 3:39eadc84c5ac 749 tr_error("Couldn't power up modem.");
philware 1:d4ff95ab40ae 750 }
philware 1:d4ff95ab40ae 751 }
philware 3:39eadc84c5ac 752 else {
philware 3:39eadc84c5ac 753 tr_info("Modem already initialised.");
philware 3:39eadc84c5ac 754 }
philware 1:d4ff95ab40ae 755
philware 1:d4ff95ab40ae 756 return _modem_initialised;
philware 1:d4ff95ab40ae 757 }
philware 1:d4ff95ab40ae 758
philware 1:d4ff95ab40ae 759 // Perform registration.
philware 1:d4ff95ab40ae 760 bool UbloxCellularBaseN2xx::nwk_registration()
philware 1:d4ff95ab40ae 761 {
philware 1:d4ff95ab40ae 762 bool registered = false;
philware 1:d4ff95ab40ae 763 int status;
philware 1:d4ff95ab40ae 764 int at_timeout;
philware 1:d4ff95ab40ae 765 LOCK();
philware 1:d4ff95ab40ae 766
philware 1:d4ff95ab40ae 767 at_timeout = _at_timeout; // Has to be inside LOCK()s
philware 1:d4ff95ab40ae 768
philware 1:d4ff95ab40ae 769 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 770
philware 1:d4ff95ab40ae 771 // Enable the packet switched and network registration unsolicited result codes
philware 1:d4ff95ab40ae 772 if (cereg(1)) {
philware 1:d4ff95ab40ae 773 // See if we are already in automatic mode
philware 1:d4ff95ab40ae 774 if (get_cops(&status)) {
philware 1:d4ff95ab40ae 775 if (status != 0) {
philware 1:d4ff95ab40ae 776 // Don't check return code here as there's not much
philware 1:d4ff95ab40ae 777 // we can do if this fails.
philware 1:d4ff95ab40ae 778 cops(0);
philware 1:d4ff95ab40ae 779 }
philware 1:d4ff95ab40ae 780 }
philware 1:d4ff95ab40ae 781
philware 1:d4ff95ab40ae 782 // query cereg just in case
philware 1:d4ff95ab40ae 783 get_cereg();
philware 1:d4ff95ab40ae 784 registered = is_registered_eps();
philware 1:d4ff95ab40ae 785
philware 1:d4ff95ab40ae 786 at_set_timeout(1000);
philware 1:d4ff95ab40ae 787 for (int waitSeconds = 0; !registered && (waitSeconds < 180); waitSeconds++) {
philware 1:d4ff95ab40ae 788 _at->recv(UNNATURAL_STRING);
philware 1:d4ff95ab40ae 789 registered = is_registered_eps();
philware 1:d4ff95ab40ae 790 }
philware 1:d4ff95ab40ae 791 at_set_timeout(at_timeout);
philware 1:d4ff95ab40ae 792 } else {
philware 1:d4ff95ab40ae 793 tr_error("Failed to set CEREG=1");
philware 1:d4ff95ab40ae 794 }
philware 1:d4ff95ab40ae 795
philware 1:d4ff95ab40ae 796 UNLOCK();
philware 1:d4ff95ab40ae 797 return registered;
philware 1:d4ff95ab40ae 798 }
philware 1:d4ff95ab40ae 799
philware 1:d4ff95ab40ae 800 bool UbloxCellularBaseN2xx::is_registered_csd()
philware 1:d4ff95ab40ae 801 {
philware 1:d4ff95ab40ae 802 return (_dev_info.reg_status_csd == CSD_REGISTERED) ||
philware 1:d4ff95ab40ae 803 (_dev_info.reg_status_csd == CSD_REGISTERED_ROAMING) ||
philware 1:d4ff95ab40ae 804 (_dev_info.reg_status_csd == CSD_CSFB_NOT_PREFERRED);
philware 1:d4ff95ab40ae 805 }
philware 1:d4ff95ab40ae 806
philware 1:d4ff95ab40ae 807 bool UbloxCellularBaseN2xx::is_registered_psd()
philware 1:d4ff95ab40ae 808 {
philware 1:d4ff95ab40ae 809 return (_dev_info.reg_status_psd == PSD_REGISTERED) ||
philware 1:d4ff95ab40ae 810 (_dev_info.reg_status_psd == PSD_REGISTERED_ROAMING);
philware 1:d4ff95ab40ae 811 }
philware 1:d4ff95ab40ae 812
philware 1:d4ff95ab40ae 813 bool UbloxCellularBaseN2xx::is_registered_eps()
philware 1:d4ff95ab40ae 814 {
philware 1:d4ff95ab40ae 815 return (_dev_info.reg_status_eps == EPS_REGISTERED) ||
philware 1:d4ff95ab40ae 816 (_dev_info.reg_status_eps == EPS_REGISTERED_ROAMING);
philware 1:d4ff95ab40ae 817 }
philware 1:d4ff95ab40ae 818
philware 1:d4ff95ab40ae 819 // Perform deregistration.
philware 1:d4ff95ab40ae 820 bool UbloxCellularBaseN2xx::nwk_deregistration()
philware 1:d4ff95ab40ae 821 {
philware 1:d4ff95ab40ae 822 bool success = false;
philware 1:d4ff95ab40ae 823
philware 1:d4ff95ab40ae 824 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 825
philware 1:d4ff95ab40ae 826 if (cops(2)) {
philware 1:d4ff95ab40ae 827 // we need to wait here so that the internal status of the module
philware 1:d4ff95ab40ae 828 wait_ms(1000);
philware 1:d4ff95ab40ae 829
philware 1:d4ff95ab40ae 830 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 831 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 832 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 833
philware 1:d4ff95ab40ae 834 success = true;
philware 1:d4ff95ab40ae 835 } else {
philware 1:d4ff95ab40ae 836 tr_error("Failed to set COPS=2");
philware 1:d4ff95ab40ae 837 }
philware 1:d4ff95ab40ae 838
philware 1:d4ff95ab40ae 839 return success;
philware 1:d4ff95ab40ae 840 }
philware 1:d4ff95ab40ae 841
philware 1:d4ff95ab40ae 842 // Put the modem into its lowest power state.
philware 1:d4ff95ab40ae 843 void UbloxCellularBaseN2xx::deinit()
philware 1:d4ff95ab40ae 844 {
philware 1:d4ff95ab40ae 845 power_down();
philware 1:d4ff95ab40ae 846 _modem_initialised = false;
philware 1:d4ff95ab40ae 847 }
philware 1:d4ff95ab40ae 848
philware 1:d4ff95ab40ae 849 // Set the PIN.
philware 1:d4ff95ab40ae 850 void UbloxCellularBaseN2xx::set_pin(const char *pin) {
philware 1:d4ff95ab40ae 851 _pin = pin;
philware 1:d4ff95ab40ae 852 }
philware 1:d4ff95ab40ae 853
philware 1:d4ff95ab40ae 854 // Enable or disable SIM pin checking.
philware 1:d4ff95ab40ae 855 bool UbloxCellularBaseN2xx:: sim_pin_check_enable(bool enableNotDisable)
philware 1:d4ff95ab40ae 856 {
philware 1:d4ff95ab40ae 857 // *** NOT IMPLEMENTED on SARA-N2XX
philware 1:d4ff95ab40ae 858 return false;
philware 1:d4ff95ab40ae 859 }
philware 1:d4ff95ab40ae 860
philware 1:d4ff95ab40ae 861 // Change the pin code for the SIM card.
philware 1:d4ff95ab40ae 862 bool UbloxCellularBaseN2xx::change_sim_pin(const char *pin)
philware 1:d4ff95ab40ae 863 {
philware 1:d4ff95ab40ae 864 // *** NOT IMPLEMENTED on SARA-N2XX
philware 1:d4ff95ab40ae 865 return false;
philware 1:d4ff95ab40ae 866 }
philware 1:d4ff95ab40ae 867
philware 1:d4ff95ab40ae 868 // Read up to size bytes from the AT interface up to a newline.
philware 1:d4ff95ab40ae 869 // This doesn't need a LOCK() UNLOCK() Wrapping as it's only called
philware 1:d4ff95ab40ae 870 // from the URC function, which are already in a lock
philware 1:d4ff95ab40ae 871 int UbloxCellularBaseN2xx::read_at_to_newline(char * buf, int size)
philware 1:d4ff95ab40ae 872 {
philware 1:d4ff95ab40ae 873 int count = 0;
philware 1:d4ff95ab40ae 874 int x = 0;
philware 1:d4ff95ab40ae 875
philware 1:d4ff95ab40ae 876 if (size > 0) {
philware 1:d4ff95ab40ae 877 for (count = 0; (count < size) && (x >= 0) && (x != '\n'); count++) {
philware 1:d4ff95ab40ae 878 x = _at->getc();
philware 1:d4ff95ab40ae 879 *(buf + count) = (char) x;
philware 1:d4ff95ab40ae 880 }
philware 1:d4ff95ab40ae 881
philware 1:d4ff95ab40ae 882 *(buf + count - 1) = 0;
philware 1:d4ff95ab40ae 883 count--;
philware 1:d4ff95ab40ae 884 }
philware 1:d4ff95ab40ae 885
philware 1:d4ff95ab40ae 886 return count;
philware 1:d4ff95ab40ae 887 }
philware 1:d4ff95ab40ae 888 // End of File
philware 1:d4ff95ab40ae 889