ublox-cellular-base-n2xx

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