ublox-cellular-base-n2xx

Committer:
Rob Meades
Date:
Mon Oct 30 14:44:36 2017 +0000
Revision:
6:377997119ef1
Parent:
5:66451d314225
Child:
7:f1c3373e4ff5
Remove unreachable code.

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