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:
fahim alavi
Date:
Tue Jan 09 15:25:11 2018 +0500
Revision:
9:4368e434de4e
Parent:
8:72412b28c93f
Child:
10:1afe5ed24f0c
Method moved with protected functions

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
fahim alavi 9:4368e434de4e 367 bool UbloxCellularBaseN2xx::get_imei(char *buffer, int size)
fahim alavi 9:4368e434de4e 368 {
fahim alavi 9:4368e434de4e 369 // International mobile equipment identifier
fahim alavi 9:4368e434de4e 370 // AT Command Manual UBX-13002752, section 4.7
fahim alavi 9:4368e434de4e 371 bool success = cgsn(1, _dev_info.imei);
fahim alavi 9:4368e434de4e 372 tr_info("DevInfo: IMEI=%s", _dev_info.imei);
fahim alavi 9:4368e434de4e 373
fahim alavi 9:4368e434de4e 374 if (success) {
fahim alavi 9:4368e434de4e 375 memcpy(buffer,_dev_info.imei,size);
fahim alavi 9:4368e434de4e 376 buffer[size-1] = '\0';
fahim alavi 9:4368e434de4e 377 }
fahim alavi 9:4368e434de4e 378
fahim alavi 9:4368e434de4e 379 return success;
fahim alavi 9:4368e434de4e 380 }
fahim alavi 9:4368e434de4e 381
philware 1:d4ff95ab40ae 382 bool UbloxCellularBaseN2xx::get_iccid()
philware 1:d4ff95ab40ae 383 {
philware 1:d4ff95ab40ae 384 // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
philware 1:d4ff95ab40ae 385 // ICCID is a serial number identifying the SIM.
philware 1:d4ff95ab40ae 386 // AT Command Manual UBX-13002752, section 4.12
philware 1:d4ff95ab40ae 387 bool success = ccid(_dev_info.iccid);
philware 1:d4ff95ab40ae 388 tr_info("DevInfo: ICCID=%s", _dev_info.iccid);
philware 1:d4ff95ab40ae 389
philware 1:d4ff95ab40ae 390 return success;
philware 1:d4ff95ab40ae 391 }
philware 1:d4ff95ab40ae 392
philware 1:d4ff95ab40ae 393 bool UbloxCellularBaseN2xx::get_imsi()
philware 1:d4ff95ab40ae 394 {
philware 1:d4ff95ab40ae 395 // International mobile subscriber identification
philware 1:d4ff95ab40ae 396 // AT Command Manual UBX-13002752, section 4.11
philware 1:d4ff95ab40ae 397 bool success = cimi(_dev_info.imsi);
philware 1:d4ff95ab40ae 398 tr_info("DevInfo: IMSI=%s", _dev_info.imsi);
philware 1:d4ff95ab40ae 399
philware 1:d4ff95ab40ae 400 return success;
philware 1:d4ff95ab40ae 401 }
philware 1:d4ff95ab40ae 402
philware 1:d4ff95ab40ae 403 bool UbloxCellularBaseN2xx::get_imei()
philware 1:d4ff95ab40ae 404 {
philware 1:d4ff95ab40ae 405 // International mobile equipment identifier
philware 1:d4ff95ab40ae 406 // AT Command Manual UBX-13002752, section 4.7
philware 1:d4ff95ab40ae 407 bool success = cgsn(1, _dev_info.imei);
philware 1:d4ff95ab40ae 408 tr_info("DevInfo: IMEI=%s", _dev_info.imei);
philware 1:d4ff95ab40ae 409
philware 1:d4ff95ab40ae 410 return success;
philware 1:d4ff95ab40ae 411 }
philware 1:d4ff95ab40ae 412
philware 1:d4ff95ab40ae 413 bool UbloxCellularBaseN2xx::get_meid()
philware 1:d4ff95ab40ae 414 {
Rob Meades 6:377997119ef1 415 // *** NOT IMPLEMENTED on SARA-N2XX
philware 1:d4ff95ab40ae 416 return false;
philware 1:d4ff95ab40ae 417 }
philware 1:d4ff95ab40ae 418
philware 1:d4ff95ab40ae 419 bool UbloxCellularBaseN2xx::set_sms()
philware 1:d4ff95ab40ae 420 {
Rob Meades 6:377997119ef1 421 // *** NOT IMPLEMENTED on SARA-N2XX
Rob Meades 6:377997119ef1 422 return false;
philware 1:d4ff95ab40ae 423 }
philware 1:d4ff95ab40ae 424
philware 1:d4ff95ab40ae 425 void UbloxCellularBaseN2xx::parser_abort_cb()
philware 1:d4ff95ab40ae 426 {
philware 1:d4ff95ab40ae 427 _at->abort();
philware 1:d4ff95ab40ae 428 }
philware 1:d4ff95ab40ae 429
philware 1:d4ff95ab40ae 430 // Callback for CME ERROR and CMS ERROR.
philware 1:d4ff95ab40ae 431 void UbloxCellularBaseN2xx::CMX_ERROR_URC()
philware 1:d4ff95ab40ae 432 {
philware 1:d4ff95ab40ae 433 char buf[48];
philware 1:d4ff95ab40ae 434
philware 1:d4ff95ab40ae 435 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
philware 1:d4ff95ab40ae 436 tr_debug("AT error %s", buf);
philware 1:d4ff95ab40ae 437 }
philware 1:d4ff95ab40ae 438 parser_abort_cb();
philware 1:d4ff95ab40ae 439 }
philware 1:d4ff95ab40ae 440
philware 1:d4ff95ab40ae 441 // Callback for EPS registration URC.
philware 1:d4ff95ab40ae 442 void UbloxCellularBaseN2xx::CEREG_URC()
philware 1:d4ff95ab40ae 443 {
philware 1:d4ff95ab40ae 444 char buf[20];
philware 1:d4ff95ab40ae 445 int status;
philware 1:d4ff95ab40ae 446 int n, AcT;
philware 1:d4ff95ab40ae 447 char tac[4], ci[4];
philware 1:d4ff95ab40ae 448
philware 1:d4ff95ab40ae 449 // If this is the URC it will be a single
philware 1:d4ff95ab40ae 450 // digit followed by \n. If it is the
philware 1:d4ff95ab40ae 451 // answer to a CEREG query, it will be
philware 1:d4ff95ab40ae 452 // a ": %d,%d\n" where the second digit
philware 1:d4ff95ab40ae 453 // indicates the status
philware 1:d4ff95ab40ae 454 // Note: not calling _at->recv() from here as we're
philware 1:d4ff95ab40ae 455 // already in an _at->recv()
philware 1:d4ff95ab40ae 456 // We also hanlde the extended 4 or 5 argument
philware 1:d4ff95ab40ae 457 // response if cereg is set to 2.
philware 1:d4ff95ab40ae 458 if (read_at_to_newline(buf, sizeof (buf)) > 0) {
philware 1:d4ff95ab40ae 459 if (sscanf(buf, ":%d,%d,%[0123456789abcdef],%[0123456789abcdef],%d\n", &n, &status, tac, ci, &AcT) == 5) {
philware 1:d4ff95ab40ae 460 set_nwk_reg_status_eps(status);
philware 1:d4ff95ab40ae 461 } else if (sscanf(buf, ":%d,%[0123456789abcdef],%[0123456789abcdef],%d\n`", &status, tac, ci, &AcT) == 4) {
philware 1:d4ff95ab40ae 462 set_nwk_reg_status_eps(status);
philware 1:d4ff95ab40ae 463 } else if (sscanf(buf, ":%d,%d\n", &n, &status) == 2) {
philware 1:d4ff95ab40ae 464 set_nwk_reg_status_eps(status);
philware 1:d4ff95ab40ae 465 } else if (sscanf(buf, ":%d\n", &status) == 1) {
philware 1:d4ff95ab40ae 466 set_nwk_reg_status_eps(status);
philware 1:d4ff95ab40ae 467 }
philware 1:d4ff95ab40ae 468 }
philware 1:d4ff95ab40ae 469 }
philware 1:d4ff95ab40ae 470
philware 1:d4ff95ab40ae 471 /**********************************************************************
philware 1:d4ff95ab40ae 472 * PROTECTED METHODS
philware 1:d4ff95ab40ae 473 **********************************************************************/
philware 1:d4ff95ab40ae 474
philware 1:d4ff95ab40ae 475 #if MODEM_ON_BOARD
philware 1:d4ff95ab40ae 476 void UbloxCellularBaseN2xx::modem_init()
philware 1:d4ff95ab40ae 477 {
philware 1:d4ff95ab40ae 478 ::onboard_modem_init();
philware 1:d4ff95ab40ae 479 }
philware 1:d4ff95ab40ae 480
philware 1:d4ff95ab40ae 481 void UbloxCellularBaseN2xx::modem_deinit()
philware 1:d4ff95ab40ae 482 {
philware 1:d4ff95ab40ae 483 ::onboard_modem_deinit();
philware 1:d4ff95ab40ae 484 }
philware 1:d4ff95ab40ae 485
philware 1:d4ff95ab40ae 486 void UbloxCellularBaseN2xx::modem_power_up()
philware 1:d4ff95ab40ae 487 {
philware 1:d4ff95ab40ae 488 ::onboard_modem_power_up();
philware 1:d4ff95ab40ae 489 }
philware 1:d4ff95ab40ae 490
philware 1:d4ff95ab40ae 491 void UbloxCellularBaseN2xx::modem_power_down()
philware 1:d4ff95ab40ae 492 {
philware 1:d4ff95ab40ae 493 ::onboard_modem_power_down();
philware 1:d4ff95ab40ae 494 }
philware 1:d4ff95ab40ae 495 #else
philware 1:d4ff95ab40ae 496 void UbloxCellularBaseN2xx::modem_init()
philware 1:d4ff95ab40ae 497 {
philware 1:d4ff95ab40ae 498 // Meant to be overridden
philware 1:d4ff95ab40ae 499 #error need to do something here!
philware 1:d4ff95ab40ae 500 }
philware 1:d4ff95ab40ae 501
philware 1:d4ff95ab40ae 502 void UbloxCellularBaseN2xx::modem_deinit()
philware 1:d4ff95ab40ae 503 {
philware 1:d4ff95ab40ae 504 // Meant to be overridden
philware 1:d4ff95ab40ae 505 }
philware 1:d4ff95ab40ae 506
philware 1:d4ff95ab40ae 507 void UbloxCellularBaseN2xx::modem_power_up()
philware 1:d4ff95ab40ae 508 {
philware 1:d4ff95ab40ae 509 // Meant to be overridden
philware 1:d4ff95ab40ae 510 }
philware 1:d4ff95ab40ae 511
philware 1:d4ff95ab40ae 512 void UbloxCellularBaseN2xx::modem_power_down()
philware 1:d4ff95ab40ae 513 {
philware 1:d4ff95ab40ae 514 // Mmeant to be overridden
philware 1:d4ff95ab40ae 515 }
philware 1:d4ff95ab40ae 516 #endif
philware 1:d4ff95ab40ae 517
philware 1:d4ff95ab40ae 518 // Constructor.
philware 1:d4ff95ab40ae 519 // Note: to allow this base class to be inherited as a virtual base class
philware 1:d4ff95ab40ae 520 // by everyone, it takes no parameters. See also comment above classInit()
philware 1:d4ff95ab40ae 521 // in the header file.
philware 1:d4ff95ab40ae 522 UbloxCellularBaseN2xx::UbloxCellularBaseN2xx()
philware 1:d4ff95ab40ae 523 {
philware 1:d4ff95ab40ae 524 tr_debug("UbloxATCellularBaseN2xx Constructor");
philware 1:d4ff95ab40ae 525
philware 1:d4ff95ab40ae 526 _pin = NULL;
philware 1:d4ff95ab40ae 527 _at = NULL;
philware 1:d4ff95ab40ae 528 _at_timeout = AT_PARSER_TIMEOUT;
philware 1:d4ff95ab40ae 529 _fh = NULL;
philware 1:d4ff95ab40ae 530 _modem_initialised = false;
philware 1:d4ff95ab40ae 531 _sim_pin_check_enabled = false;
philware 1:d4ff95ab40ae 532 _debug_trace_on = false;
philware 1:d4ff95ab40ae 533
philware 1:d4ff95ab40ae 534 _dev_info.dev = DEV_TYPE_NONE;
philware 1:d4ff95ab40ae 535 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 536 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 537 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 538 }
philware 1:d4ff95ab40ae 539
philware 1:d4ff95ab40ae 540 // Destructor.
philware 1:d4ff95ab40ae 541 UbloxCellularBaseN2xx::~UbloxCellularBaseN2xx()
philware 1:d4ff95ab40ae 542 {
philware 1:d4ff95ab40ae 543 deinit();
philware 1:d4ff95ab40ae 544 delete _at;
philware 1:d4ff95ab40ae 545 delete _fh;
philware 1:d4ff95ab40ae 546 }
philware 1:d4ff95ab40ae 547
philware 1:d4ff95ab40ae 548 // Initialise the portions of this class that are parameterised.
philware 1:d4ff95ab40ae 549 void UbloxCellularBaseN2xx::baseClassInit(PinName tx, PinName rx,
philware 1:d4ff95ab40ae 550 int baud, bool debug_on)
philware 1:d4ff95ab40ae 551 {
philware 1:d4ff95ab40ae 552 // Only initialise ourselves if it's not already been done
philware 1:d4ff95ab40ae 553 if (_at == NULL) {
philware 1:d4ff95ab40ae 554 if (_debug_trace_on == false) {
philware 1:d4ff95ab40ae 555 _debug_trace_on = debug_on;
philware 1:d4ff95ab40ae 556 }
philware 1:d4ff95ab40ae 557
philware 1:d4ff95ab40ae 558 // Set up File Handle for buffered serial comms with cellular module
philware 1:d4ff95ab40ae 559 // (which will be used by the AT parser)
philware 1:d4ff95ab40ae 560 _fh = new UARTSerial(tx, rx, baud);
philware 1:d4ff95ab40ae 561
philware 1:d4ff95ab40ae 562 // Set up the AT parser
philware 1:d4ff95ab40ae 563 _at = new ATCmdParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE,
philware 1:d4ff95ab40ae 564 _at_timeout, _debug_trace_on);
philware 1:d4ff95ab40ae 565
philware 1:d4ff95ab40ae 566 // Error cases, out of band handling
philware 1:d4ff95ab40ae 567 _at->oob("ERROR", callback(this, &UbloxCellularBaseN2xx::parser_abort_cb));
philware 1:d4ff95ab40ae 568 _at->oob("+CME ERROR", callback(this, &UbloxCellularBaseN2xx::CMX_ERROR_URC));
philware 1:d4ff95ab40ae 569 _at->oob("+CMS ERROR", callback(this, &UbloxCellularBaseN2xx::CMX_ERROR_URC));
philware 1:d4ff95ab40ae 570
philware 1:d4ff95ab40ae 571 // Registration status, out of band handling
philware 1:d4ff95ab40ae 572 _at->oob("+CEREG", callback(this, &UbloxCellularBaseN2xx::CEREG_URC));
philware 1:d4ff95ab40ae 573 }
philware 1:d4ff95ab40ae 574 }
philware 1:d4ff95ab40ae 575
philware 1:d4ff95ab40ae 576 // Set the AT parser timeout.
philware 1:d4ff95ab40ae 577 // Note: the AT interface should be locked before this is called.
philware 1:d4ff95ab40ae 578 void UbloxCellularBaseN2xx::at_set_timeout(int timeout) {
philware 1:d4ff95ab40ae 579
philware 1:d4ff95ab40ae 580 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 581
philware 1:d4ff95ab40ae 582 _at_timeout = timeout;
philware 1:d4ff95ab40ae 583 _at->set_timeout(timeout);
philware 1:d4ff95ab40ae 584 }
philware 1:d4ff95ab40ae 585
philware 1:d4ff95ab40ae 586 // Read up to size bytes from the AT interface up to a "end".
philware 1:d4ff95ab40ae 587 // Note: the AT interface should be locked before this is called.
philware 1:d4ff95ab40ae 588 int UbloxCellularBaseN2xx::read_at_to_char(char * buf, int size, char end)
philware 1:d4ff95ab40ae 589 {
philware 1:d4ff95ab40ae 590 int count = 0;
philware 1:d4ff95ab40ae 591 int x = 0;
philware 1:d4ff95ab40ae 592
philware 1:d4ff95ab40ae 593 if (size > 0) {
philware 1:d4ff95ab40ae 594 for (count = 0; (count < size) && (x >= 0) && (x != end); count++) {
philware 1:d4ff95ab40ae 595 x = _at->getc();
philware 1:d4ff95ab40ae 596 *(buf + count) = (char) x;
philware 1:d4ff95ab40ae 597 }
philware 1:d4ff95ab40ae 598
philware 1:d4ff95ab40ae 599 count--;
philware 1:d4ff95ab40ae 600 *(buf + count) = 0;
philware 1:d4ff95ab40ae 601
philware 1:d4ff95ab40ae 602 // Convert line endings:
philware 1:d4ff95ab40ae 603 // If end was '\n' (0x0a) and the preceding character was 0x0d, then
philware 1:d4ff95ab40ae 604 // overwrite that with null as well.
philware 1:d4ff95ab40ae 605 if ((count > 0) && (end == '\n') && (*(buf + count - 1) == '\x0d')) {
philware 1:d4ff95ab40ae 606 count--;
philware 1:d4ff95ab40ae 607 *(buf + count) = 0;
philware 1:d4ff95ab40ae 608 }
philware 1:d4ff95ab40ae 609 }
philware 1:d4ff95ab40ae 610
philware 1:d4ff95ab40ae 611 return count;
philware 1:d4ff95ab40ae 612 }
philware 1:d4ff95ab40ae 613
philware 1:d4ff95ab40ae 614 // Power up the modem.
philware 1:d4ff95ab40ae 615 // Enables the GPIO lines to the modem and then wriggles the power line in short pulses.
philware 1:d4ff95ab40ae 616 bool UbloxCellularBaseN2xx::power_up()
philware 1:d4ff95ab40ae 617 {
philware 1:d4ff95ab40ae 618 bool success = false;
philware 1:d4ff95ab40ae 619 int at_timeout;
philware 1:d4ff95ab40ae 620 LOCK();
philware 1:d4ff95ab40ae 621
philware 1:d4ff95ab40ae 622 at_timeout = _at_timeout; // Has to be inside LOCK()s
philware 1:d4ff95ab40ae 623
philware 1:d4ff95ab40ae 624 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 625
philware 1:d4ff95ab40ae 626 /* Initialize GPIO lines */
philware 1:d4ff95ab40ae 627 tr_info("Powering up modem...");
philware 1:d4ff95ab40ae 628 onboard_modem_init();
philware 1:d4ff95ab40ae 629 /* Give SARA-N2XX time to reset */
philware 1:d4ff95ab40ae 630 tr_debug("Waiting for 5 seconds (booting SARA-N2xx)...");
philware 1:d4ff95ab40ae 631 wait_ms(5000);
philware 1:d4ff95ab40ae 632
philware 1:d4ff95ab40ae 633 at_set_timeout(1000);
philware 1:d4ff95ab40ae 634 for (int retry_count = 0; !success && (retry_count < 20); retry_count++) {
philware 1:d4ff95ab40ae 635 _at->flush();
philware 1:d4ff95ab40ae 636 if (at_send("AT")) {
philware 1:d4ff95ab40ae 637 success = true;
philware 1:d4ff95ab40ae 638 }
philware 1:d4ff95ab40ae 639 }
philware 1:d4ff95ab40ae 640 at_set_timeout(at_timeout);
philware 1:d4ff95ab40ae 641
philware 1:d4ff95ab40ae 642 // perform any initialisation AT commands here
philware 1:d4ff95ab40ae 643 if (success) {
philware 1:d4ff95ab40ae 644 success = at_send("AT+CMEE=1"); // Turn on verbose responses
philware 1:d4ff95ab40ae 645 }
philware 1:d4ff95ab40ae 646
philware 1:d4ff95ab40ae 647 if (!success) {
philware 1:d4ff95ab40ae 648 tr_error("Preliminary modem setup failed.");
philware 1:d4ff95ab40ae 649 }
philware 1:d4ff95ab40ae 650
philware 1:d4ff95ab40ae 651 UNLOCK();
philware 1:d4ff95ab40ae 652 return success;
philware 1:d4ff95ab40ae 653 }
philware 1:d4ff95ab40ae 654
philware 1:d4ff95ab40ae 655 // Power down modem via AT interface.
philware 1:d4ff95ab40ae 656 void UbloxCellularBaseN2xx::power_down()
philware 1:d4ff95ab40ae 657 {
philware 1:d4ff95ab40ae 658 LOCK();
philware 1:d4ff95ab40ae 659
philware 1:d4ff95ab40ae 660 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 661
philware 1:d4ff95ab40ae 662 // If we have been running, do a soft power-off first
philware 1:d4ff95ab40ae 663 if (_modem_initialised && (_at != NULL)) {
philware 1:d4ff95ab40ae 664 // NOT IMPLEMENTED in B656 firmware
philware 1:d4ff95ab40ae 665 // at_send("AT+CPWROFF");
philware 1:d4ff95ab40ae 666 }
philware 1:d4ff95ab40ae 667
philware 1:d4ff95ab40ae 668 // Now do a hard power-off
philware 1:d4ff95ab40ae 669 onboard_modem_power_down();
philware 1:d4ff95ab40ae 670 onboard_modem_deinit();
philware 1:d4ff95ab40ae 671
philware 1:d4ff95ab40ae 672 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 673 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 674 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 675
philware 1:d4ff95ab40ae 676 UNLOCK();
philware 1:d4ff95ab40ae 677 }
philware 1:d4ff95ab40ae 678
philware 1:d4ff95ab40ae 679 // Get the device ID.
philware 1:d4ff95ab40ae 680 bool UbloxCellularBaseN2xx::set_device_identity(DeviceType *dev)
philware 1:d4ff95ab40ae 681 {
philware 1:d4ff95ab40ae 682 char buf[20];
philware 1:d4ff95ab40ae 683 bool success;
philware 1:d4ff95ab40ae 684 LOCK();
philware 1:d4ff95ab40ae 685
philware 1:d4ff95ab40ae 686 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 687
philware 1:d4ff95ab40ae 688 success = at_req("AT+CGMM", "%19[^\n]\n", buf);
philware 1:d4ff95ab40ae 689
philware 1:d4ff95ab40ae 690 if (success) {
philware 1:d4ff95ab40ae 691 if (strstr(buf, "Neul Hi2110"))
philware 1:d4ff95ab40ae 692 *dev = DEV_SARA_N2;
philware 1:d4ff95ab40ae 693 }
philware 1:d4ff95ab40ae 694
philware 1:d4ff95ab40ae 695 UNLOCK();
philware 1:d4ff95ab40ae 696 return success;
philware 1:d4ff95ab40ae 697 }
philware 1:d4ff95ab40ae 698
philware 1:d4ff95ab40ae 699 // Send initialisation AT commands that are specific to the device.
philware 1:d4ff95ab40ae 700 bool UbloxCellularBaseN2xx::device_init(DeviceType dev)
philware 1:d4ff95ab40ae 701 {
philware 1:d4ff95ab40ae 702 // SARA-N2xx doesn't have anything to initialise
philware 1:d4ff95ab40ae 703 return true;
philware 1:d4ff95ab40ae 704 }
philware 1:d4ff95ab40ae 705
philware 1:d4ff95ab40ae 706 // Get the SIM card going.
philware 1:d4ff95ab40ae 707 bool UbloxCellularBaseN2xx::initialise_sim_card()
philware 1:d4ff95ab40ae 708 {
philware 1:d4ff95ab40ae 709 // SARA-N2XX doesn't have any SIM AT Commands for now.
philware 1:d4ff95ab40ae 710 return true;
philware 1:d4ff95ab40ae 711 }
philware 1:d4ff95ab40ae 712
philware 1:d4ff95ab40ae 713 /**********************************************************************
philware 1:d4ff95ab40ae 714 * PUBLIC METHODS
philware 1:d4ff95ab40ae 715 **********************************************************************/
philware 1:d4ff95ab40ae 716
philware 1:d4ff95ab40ae 717 // Initialise the modem.
philware 1:d4ff95ab40ae 718 bool UbloxCellularBaseN2xx::init(const char *pin)
philware 1:d4ff95ab40ae 719 {
philware 1:d4ff95ab40ae 720 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 721
philware 1:d4ff95ab40ae 722 if (!_modem_initialised) {
philware 3:39eadc84c5ac 723 tr_warn("Modem not initialised, initialising...");
philware 1:d4ff95ab40ae 724 if (power_up()) {
philware 3:39eadc84c5ac 725 tr_info("Modem Powered Up.");
philware 1:d4ff95ab40ae 726 if (pin != NULL) {
philware 1:d4ff95ab40ae 727 _pin = pin;
philware 1:d4ff95ab40ae 728 }
philware 1:d4ff95ab40ae 729
philware 1:d4ff95ab40ae 730 if (initialise_sim_card()) {
philware 3:39eadc84c5ac 731 tr_info("Sim ready...");
philware 1:d4ff95ab40ae 732 if (set_device_identity(&_dev_info.dev) && // Set up device identity
philware 1:d4ff95ab40ae 733 device_init(_dev_info.dev) &&
philware 1:d4ff95ab40ae 734 get_sara_n2xx_info())
philware 1:d4ff95ab40ae 735 {
philware 1:d4ff95ab40ae 736 tr_debug("CGMM: %s", _sara_n2xx_info.cgmm);
philware 1:d4ff95ab40ae 737 tr_debug("CGMI: %s", _sara_n2xx_info.cgmi);
philware 1:d4ff95ab40ae 738 tr_debug("CGMR: %s", _sara_n2xx_info.cgmr);
philware 1:d4ff95ab40ae 739 tr_debug("CGSN: %s", _sara_n2xx_info.cgsn);
philware 1:d4ff95ab40ae 740
philware 1:d4ff95ab40ae 741 // The modem is initialised. The following checks my still fail,
philware 1:d4ff95ab40ae 742 // of course, but they are all of a "fatal" nature and so we wouldn't
philware 1:d4ff95ab40ae 743 // want to retry them anyway
philware 1:d4ff95ab40ae 744 _modem_initialised = true;
philware 1:d4ff95ab40ae 745 }
philware 1:d4ff95ab40ae 746 }
philware 3:39eadc84c5ac 747 } else {
philware 3:39eadc84c5ac 748 tr_error("Couldn't power up modem.");
philware 1:d4ff95ab40ae 749 }
philware 1:d4ff95ab40ae 750 }
philware 3:39eadc84c5ac 751 else {
philware 3:39eadc84c5ac 752 tr_info("Modem already initialised.");
philware 3:39eadc84c5ac 753 }
philware 1:d4ff95ab40ae 754
philware 1:d4ff95ab40ae 755 return _modem_initialised;
philware 1:d4ff95ab40ae 756 }
philware 1:d4ff95ab40ae 757
philware 1:d4ff95ab40ae 758 // Perform registration.
philware 1:d4ff95ab40ae 759 bool UbloxCellularBaseN2xx::nwk_registration()
philware 1:d4ff95ab40ae 760 {
philware 1:d4ff95ab40ae 761 bool registered = false;
philware 1:d4ff95ab40ae 762 int status;
philware 1:d4ff95ab40ae 763 int at_timeout;
philware 1:d4ff95ab40ae 764 LOCK();
philware 1:d4ff95ab40ae 765
philware 1:d4ff95ab40ae 766 at_timeout = _at_timeout; // Has to be inside LOCK()s
philware 1:d4ff95ab40ae 767
philware 1:d4ff95ab40ae 768 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 769
philware 1:d4ff95ab40ae 770 // Enable the packet switched and network registration unsolicited result codes
philware 1:d4ff95ab40ae 771 if (cereg(1)) {
philware 1:d4ff95ab40ae 772 // See if we are already in automatic mode
philware 1:d4ff95ab40ae 773 if (get_cops(&status)) {
philware 1:d4ff95ab40ae 774 if (status != 0) {
philware 1:d4ff95ab40ae 775 // Don't check return code here as there's not much
philware 1:d4ff95ab40ae 776 // we can do if this fails.
philware 1:d4ff95ab40ae 777 cops(0);
philware 1:d4ff95ab40ae 778 }
philware 1:d4ff95ab40ae 779 }
philware 1:d4ff95ab40ae 780
philware 1:d4ff95ab40ae 781 // query cereg just in case
philware 1:d4ff95ab40ae 782 get_cereg();
philware 1:d4ff95ab40ae 783 registered = is_registered_eps();
philware 1:d4ff95ab40ae 784
philware 1:d4ff95ab40ae 785 at_set_timeout(1000);
philware 1:d4ff95ab40ae 786 for (int waitSeconds = 0; !registered && (waitSeconds < 180); waitSeconds++) {
philware 1:d4ff95ab40ae 787 _at->recv(UNNATURAL_STRING);
philware 1:d4ff95ab40ae 788 registered = is_registered_eps();
philware 1:d4ff95ab40ae 789 }
philware 1:d4ff95ab40ae 790 at_set_timeout(at_timeout);
philware 1:d4ff95ab40ae 791 } else {
philware 1:d4ff95ab40ae 792 tr_error("Failed to set CEREG=1");
philware 1:d4ff95ab40ae 793 }
philware 1:d4ff95ab40ae 794
philware 1:d4ff95ab40ae 795 UNLOCK();
philware 1:d4ff95ab40ae 796 return registered;
philware 1:d4ff95ab40ae 797 }
philware 1:d4ff95ab40ae 798
philware 1:d4ff95ab40ae 799 bool UbloxCellularBaseN2xx::is_registered_csd()
philware 1:d4ff95ab40ae 800 {
philware 1:d4ff95ab40ae 801 return (_dev_info.reg_status_csd == CSD_REGISTERED) ||
philware 1:d4ff95ab40ae 802 (_dev_info.reg_status_csd == CSD_REGISTERED_ROAMING) ||
philware 1:d4ff95ab40ae 803 (_dev_info.reg_status_csd == CSD_CSFB_NOT_PREFERRED);
philware 1:d4ff95ab40ae 804 }
philware 1:d4ff95ab40ae 805
philware 1:d4ff95ab40ae 806 bool UbloxCellularBaseN2xx::is_registered_psd()
philware 1:d4ff95ab40ae 807 {
philware 1:d4ff95ab40ae 808 return (_dev_info.reg_status_psd == PSD_REGISTERED) ||
philware 1:d4ff95ab40ae 809 (_dev_info.reg_status_psd == PSD_REGISTERED_ROAMING);
philware 1:d4ff95ab40ae 810 }
philware 1:d4ff95ab40ae 811
philware 1:d4ff95ab40ae 812 bool UbloxCellularBaseN2xx::is_registered_eps()
philware 1:d4ff95ab40ae 813 {
philware 1:d4ff95ab40ae 814 return (_dev_info.reg_status_eps == EPS_REGISTERED) ||
philware 1:d4ff95ab40ae 815 (_dev_info.reg_status_eps == EPS_REGISTERED_ROAMING);
philware 1:d4ff95ab40ae 816 }
philware 1:d4ff95ab40ae 817
philware 1:d4ff95ab40ae 818 // Perform deregistration.
philware 1:d4ff95ab40ae 819 bool UbloxCellularBaseN2xx::nwk_deregistration()
philware 1:d4ff95ab40ae 820 {
philware 1:d4ff95ab40ae 821 bool success = false;
philware 1:d4ff95ab40ae 822
philware 1:d4ff95ab40ae 823 MBED_ASSERT(_at != NULL);
philware 1:d4ff95ab40ae 824
philware 1:d4ff95ab40ae 825 if (cops(2)) {
philware 1:d4ff95ab40ae 826 // we need to wait here so that the internal status of the module
philware 1:d4ff95ab40ae 827 wait_ms(1000);
philware 1:d4ff95ab40ae 828
philware 1:d4ff95ab40ae 829 _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 830 _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 831 _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING;
philware 1:d4ff95ab40ae 832
philware 1:d4ff95ab40ae 833 success = true;
philware 1:d4ff95ab40ae 834 } else {
philware 1:d4ff95ab40ae 835 tr_error("Failed to set COPS=2");
philware 1:d4ff95ab40ae 836 }
philware 1:d4ff95ab40ae 837
philware 1:d4ff95ab40ae 838 return success;
philware 1:d4ff95ab40ae 839 }
philware 1:d4ff95ab40ae 840
philware 1:d4ff95ab40ae 841 // Put the modem into its lowest power state.
philware 1:d4ff95ab40ae 842 void UbloxCellularBaseN2xx::deinit()
philware 1:d4ff95ab40ae 843 {
philware 1:d4ff95ab40ae 844 power_down();
philware 1:d4ff95ab40ae 845 _modem_initialised = false;
philware 1:d4ff95ab40ae 846 }
philware 1:d4ff95ab40ae 847
philware 1:d4ff95ab40ae 848 // Set the PIN.
philware 1:d4ff95ab40ae 849 void UbloxCellularBaseN2xx::set_pin(const char *pin) {
philware 1:d4ff95ab40ae 850 _pin = pin;
philware 1:d4ff95ab40ae 851 }
philware 1:d4ff95ab40ae 852
philware 1:d4ff95ab40ae 853 // Enable or disable SIM pin checking.
philware 1:d4ff95ab40ae 854 bool UbloxCellularBaseN2xx:: sim_pin_check_enable(bool enableNotDisable)
philware 1:d4ff95ab40ae 855 {
philware 1:d4ff95ab40ae 856 // *** NOT IMPLEMENTED on SARA-N2XX
philware 1:d4ff95ab40ae 857 return false;
philware 1:d4ff95ab40ae 858 }
philware 1:d4ff95ab40ae 859
philware 1:d4ff95ab40ae 860 // Change the pin code for the SIM card.
philware 1:d4ff95ab40ae 861 bool UbloxCellularBaseN2xx::change_sim_pin(const char *pin)
philware 1:d4ff95ab40ae 862 {
philware 1:d4ff95ab40ae 863 // *** NOT IMPLEMENTED on SARA-N2XX
philware 1:d4ff95ab40ae 864 return false;
philware 1:d4ff95ab40ae 865 }
philware 1:d4ff95ab40ae 866
philware 1:d4ff95ab40ae 867 // Read up to size bytes from the AT interface up to a newline.
philware 1:d4ff95ab40ae 868 // This doesn't need a LOCK() UNLOCK() Wrapping as it's only called
philware 1:d4ff95ab40ae 869 // from the URC function, which are already in a lock
philware 1:d4ff95ab40ae 870 int UbloxCellularBaseN2xx::read_at_to_newline(char * buf, int size)
philware 1:d4ff95ab40ae 871 {
philware 1:d4ff95ab40ae 872 int count = 0;
philware 1:d4ff95ab40ae 873 int x = 0;
philware 1:d4ff95ab40ae 874
philware 1:d4ff95ab40ae 875 if (size > 0) {
philware 1:d4ff95ab40ae 876 for (count = 0; (count < size) && (x >= 0) && (x != '\n'); count++) {
philware 1:d4ff95ab40ae 877 x = _at->getc();
philware 1:d4ff95ab40ae 878 *(buf + count) = (char) x;
philware 1:d4ff95ab40ae 879 }
philware 1:d4ff95ab40ae 880
philware 1:d4ff95ab40ae 881 *(buf + count - 1) = 0;
philware 1:d4ff95ab40ae 882 count--;
philware 1:d4ff95ab40ae 883 }
philware 1:d4ff95ab40ae 884
philware 1:d4ff95ab40ae 885 return count;
philware 1:d4ff95ab40ae 886 }
philware 1:d4ff95ab40ae 887 // End of File
philware 1:d4ff95ab40ae 888