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