ublox-cellular-base-n2xx

Committer:
fahim alavi
Date:
Tue Jan 09 12:46:00 2018 +0500
Revision:
8:72412b28c93f
Parent:
7:f1c3373e4ff5
Child:
9:4368e434de4e
Code updated according to convention

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
fahim alavi 8:72412b28c93f 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
fahim alavi 8:72412b28c93f 405 if (success) {
mudassar0121 7:f1c3373e4ff5 406 memcpy(buffer,_dev_info.imei,size);
mudassar0121 7:f1c3373e4ff5 407 buffer[size-1] = '\0';
mudassar0121 7:f1c3373e4ff5 408 }
mudassar0121 7:f1c3373e4ff5 409
mudassar0121 7:f1c3373e4ff5 410 return success;
mudassar0121 7:f1c3373e4ff5 411 }
mudassar0121 7:f1c3373e4ff5 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