Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of ublox-cellular-base by
UbloxCellularBase.cpp@5:05fa111c1cf3, 2017-08-10 (annotated)
- Committer:
- rob.meades@u-blox.com
- Date:
- Thu Aug 10 14:27:24 2017 +0100
- Revision:
- 5:05fa111c1cf3
- Parent:
- 4:2e640a101db1
- Child:
- 6:8fadf1e49487
Remove reference to set_flow_control() since this is not yet exposed by UARTSerial.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
RobMeades | 0:5cffef3371f6 | 1 | /* Copyright (c) 2017 ublox Limited |
RobMeades | 0:5cffef3371f6 | 2 | * |
RobMeades | 0:5cffef3371f6 | 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
RobMeades | 0:5cffef3371f6 | 4 | * you may not use this file except in compliance with the License. |
RobMeades | 0:5cffef3371f6 | 5 | * You may obtain a copy of the License at |
RobMeades | 0:5cffef3371f6 | 6 | * |
RobMeades | 0:5cffef3371f6 | 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
RobMeades | 0:5cffef3371f6 | 8 | * |
RobMeades | 0:5cffef3371f6 | 9 | * Unless required by applicable law or agreed to in writing, software |
RobMeades | 0:5cffef3371f6 | 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
RobMeades | 0:5cffef3371f6 | 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
RobMeades | 0:5cffef3371f6 | 12 | * See the License for the specific language governing permissions and |
RobMeades | 0:5cffef3371f6 | 13 | * limitations under the License. |
RobMeades | 0:5cffef3371f6 | 14 | */ |
RobMeades | 0:5cffef3371f6 | 15 | |
RobMeades | 0:5cffef3371f6 | 16 | #include "UARTSerial.h" |
RobMeades | 0:5cffef3371f6 | 17 | #include "APN_db.h" |
RobMeades | 0:5cffef3371f6 | 18 | #include "UbloxCellularBase.h" |
RobMeades | 0:5cffef3371f6 | 19 | #include "onboard_modem_api.h" |
RobMeades | 0:5cffef3371f6 | 20 | #ifdef FEATURE_COMMON_PAL |
RobMeades | 0:5cffef3371f6 | 21 | #include "mbed_trace.h" |
RobMeades | 0:5cffef3371f6 | 22 | #define TRACE_GROUP "UCB" |
RobMeades | 0:5cffef3371f6 | 23 | #else |
rob.meades@u-blox.com | 2:73fcc33c9400 | 24 | #define tr_debug(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__) |
rob.meades@u-blox.com | 2:73fcc33c9400 | 25 | #define tr_info(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__) |
rob.meades@u-blox.com | 2:73fcc33c9400 | 26 | #define tr_warn(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__) |
rob.meades@u-blox.com | 2:73fcc33c9400 | 27 | #define tr_error(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__) |
RobMeades | 0:5cffef3371f6 | 28 | #endif |
RobMeades | 0:5cffef3371f6 | 29 | |
RobMeades | 0:5cffef3371f6 | 30 | /********************************************************************** |
RobMeades | 0:5cffef3371f6 | 31 | * PRIVATE METHODS |
RobMeades | 0:5cffef3371f6 | 32 | **********************************************************************/ |
RobMeades | 0:5cffef3371f6 | 33 | |
RobMeades | 0:5cffef3371f6 | 34 | void UbloxCellularBase::set_nwk_reg_status_csd(int status) |
RobMeades | 0:5cffef3371f6 | 35 | { |
RobMeades | 0:5cffef3371f6 | 36 | switch (status) { |
RobMeades | 0:5cffef3371f6 | 37 | case CSD_NOT_REGISTERED_NOT_SEARCHING: |
RobMeades | 0:5cffef3371f6 | 38 | case CSD_NOT_REGISTERED_SEARCHING: |
RobMeades | 0:5cffef3371f6 | 39 | tr_info("Not (yet) registered for circuit switched service"); |
RobMeades | 0:5cffef3371f6 | 40 | break; |
RobMeades | 0:5cffef3371f6 | 41 | case CSD_REGISTERED: |
RobMeades | 0:5cffef3371f6 | 42 | case CSD_REGISTERED_ROAMING: |
RobMeades | 0:5cffef3371f6 | 43 | tr_info("Registered for circuit switched service"); |
RobMeades | 0:5cffef3371f6 | 44 | break; |
RobMeades | 0:5cffef3371f6 | 45 | case CSD_REGISTRATION_DENIED: |
RobMeades | 0:5cffef3371f6 | 46 | tr_info("Circuit switched service denied"); |
RobMeades | 0:5cffef3371f6 | 47 | break; |
RobMeades | 0:5cffef3371f6 | 48 | case CSD_UNKNOWN_COVERAGE: |
RobMeades | 0:5cffef3371f6 | 49 | tr_info("Out of circuit switched service coverage"); |
RobMeades | 0:5cffef3371f6 | 50 | break; |
RobMeades | 0:5cffef3371f6 | 51 | case CSD_SMS_ONLY: |
RobMeades | 0:5cffef3371f6 | 52 | tr_info("SMS service only"); |
RobMeades | 0:5cffef3371f6 | 53 | break; |
RobMeades | 0:5cffef3371f6 | 54 | case CSD_SMS_ONLY_ROAMING: |
RobMeades | 0:5cffef3371f6 | 55 | tr_info("SMS service only"); |
RobMeades | 0:5cffef3371f6 | 56 | break; |
RobMeades | 0:5cffef3371f6 | 57 | case CSD_CSFB_NOT_PREFERRED: |
RobMeades | 0:5cffef3371f6 | 58 | tr_info("Registered for circuit switched service with CSFB not preferred"); |
RobMeades | 0:5cffef3371f6 | 59 | break; |
RobMeades | 0:5cffef3371f6 | 60 | default: |
RobMeades | 0:5cffef3371f6 | 61 | tr_info("Unknown circuit switched service registration status. %d", status); |
RobMeades | 0:5cffef3371f6 | 62 | break; |
RobMeades | 0:5cffef3371f6 | 63 | } |
RobMeades | 0:5cffef3371f6 | 64 | |
RobMeades | 0:5cffef3371f6 | 65 | _dev_info.reg_status_csd = static_cast<NetworkRegistrationStatusCsd>(status); |
RobMeades | 0:5cffef3371f6 | 66 | } |
RobMeades | 0:5cffef3371f6 | 67 | |
RobMeades | 0:5cffef3371f6 | 68 | void UbloxCellularBase::set_nwk_reg_status_psd(int status) |
RobMeades | 0:5cffef3371f6 | 69 | { |
RobMeades | 0:5cffef3371f6 | 70 | switch (status) { |
RobMeades | 0:5cffef3371f6 | 71 | case PSD_NOT_REGISTERED_NOT_SEARCHING: |
RobMeades | 0:5cffef3371f6 | 72 | case PSD_NOT_REGISTERED_SEARCHING: |
RobMeades | 0:5cffef3371f6 | 73 | tr_info("Not (yet) registered for packet switched service"); |
RobMeades | 0:5cffef3371f6 | 74 | break; |
RobMeades | 0:5cffef3371f6 | 75 | case PSD_REGISTERED: |
RobMeades | 0:5cffef3371f6 | 76 | case PSD_REGISTERED_ROAMING: |
RobMeades | 0:5cffef3371f6 | 77 | tr_info("Registered for packet switched service"); |
RobMeades | 0:5cffef3371f6 | 78 | break; |
RobMeades | 0:5cffef3371f6 | 79 | case PSD_REGISTRATION_DENIED: |
RobMeades | 0:5cffef3371f6 | 80 | tr_info("Packet switched service denied"); |
RobMeades | 0:5cffef3371f6 | 81 | break; |
RobMeades | 0:5cffef3371f6 | 82 | case PSD_UNKNOWN_COVERAGE: |
RobMeades | 0:5cffef3371f6 | 83 | tr_info("Out of packet switched service coverage"); |
RobMeades | 0:5cffef3371f6 | 84 | break; |
RobMeades | 0:5cffef3371f6 | 85 | case PSD_EMERGENCY_SERVICES_ONLY: |
RobMeades | 0:5cffef3371f6 | 86 | tr_info("Limited access for packet switched service. Emergency use only."); |
RobMeades | 0:5cffef3371f6 | 87 | break; |
RobMeades | 0:5cffef3371f6 | 88 | default: |
RobMeades | 0:5cffef3371f6 | 89 | tr_info("Unknown packet switched service registration status. %d", status); |
RobMeades | 0:5cffef3371f6 | 90 | break; |
RobMeades | 0:5cffef3371f6 | 91 | } |
RobMeades | 0:5cffef3371f6 | 92 | |
RobMeades | 0:5cffef3371f6 | 93 | _dev_info.reg_status_psd = static_cast<NetworkRegistrationStatusPsd>(status); |
RobMeades | 0:5cffef3371f6 | 94 | } |
RobMeades | 0:5cffef3371f6 | 95 | |
RobMeades | 0:5cffef3371f6 | 96 | void UbloxCellularBase::set_nwk_reg_status_eps(int status) |
RobMeades | 0:5cffef3371f6 | 97 | { |
RobMeades | 0:5cffef3371f6 | 98 | switch (status) { |
RobMeades | 0:5cffef3371f6 | 99 | case EPS_NOT_REGISTERED_NOT_SEARCHING: |
RobMeades | 0:5cffef3371f6 | 100 | case EPS_NOT_REGISTERED_SEARCHING: |
RobMeades | 0:5cffef3371f6 | 101 | tr_info("Not (yet) registered for EPS service"); |
RobMeades | 0:5cffef3371f6 | 102 | break; |
RobMeades | 0:5cffef3371f6 | 103 | case EPS_REGISTERED: |
RobMeades | 0:5cffef3371f6 | 104 | case EPS_REGISTERED_ROAMING: |
RobMeades | 0:5cffef3371f6 | 105 | tr_info("Registered for EPS service"); |
RobMeades | 0:5cffef3371f6 | 106 | break; |
RobMeades | 0:5cffef3371f6 | 107 | case EPS_REGISTRATION_DENIED: |
RobMeades | 0:5cffef3371f6 | 108 | tr_info("EPS service denied"); |
RobMeades | 0:5cffef3371f6 | 109 | break; |
RobMeades | 0:5cffef3371f6 | 110 | case EPS_UNKNOWN_COVERAGE: |
RobMeades | 0:5cffef3371f6 | 111 | tr_info("Out of EPS service coverage"); |
RobMeades | 0:5cffef3371f6 | 112 | break; |
RobMeades | 0:5cffef3371f6 | 113 | case EPS_EMERGENCY_SERVICES_ONLY: |
RobMeades | 0:5cffef3371f6 | 114 | tr_info("Limited access for EPS service. Emergency use only."); |
RobMeades | 0:5cffef3371f6 | 115 | break; |
RobMeades | 0:5cffef3371f6 | 116 | default: |
RobMeades | 0:5cffef3371f6 | 117 | tr_info("Unknown EPS service registration status. %d", status); |
RobMeades | 0:5cffef3371f6 | 118 | break; |
RobMeades | 0:5cffef3371f6 | 119 | } |
RobMeades | 0:5cffef3371f6 | 120 | |
RobMeades | 0:5cffef3371f6 | 121 | _dev_info.reg_status_eps = static_cast<NetworkRegistrationStatusEps>(status); |
RobMeades | 0:5cffef3371f6 | 122 | } |
RobMeades | 0:5cffef3371f6 | 123 | |
RobMeades | 0:5cffef3371f6 | 124 | void UbloxCellularBase::set_rat(int AcTStatus) |
RobMeades | 0:5cffef3371f6 | 125 | { |
RobMeades | 0:5cffef3371f6 | 126 | switch (AcTStatus) { |
RobMeades | 0:5cffef3371f6 | 127 | case GSM: |
RobMeades | 0:5cffef3371f6 | 128 | case COMPACT_GSM: |
RobMeades | 0:5cffef3371f6 | 129 | tr_info("Connected in GSM"); |
RobMeades | 0:5cffef3371f6 | 130 | break; |
RobMeades | 0:5cffef3371f6 | 131 | case UTRAN: |
RobMeades | 0:5cffef3371f6 | 132 | tr_info("Connected to UTRAN"); |
RobMeades | 0:5cffef3371f6 | 133 | break; |
RobMeades | 0:5cffef3371f6 | 134 | case EDGE: |
RobMeades | 0:5cffef3371f6 | 135 | tr_info("Connected to EDGE"); |
RobMeades | 0:5cffef3371f6 | 136 | break; |
RobMeades | 0:5cffef3371f6 | 137 | case HSDPA: |
RobMeades | 0:5cffef3371f6 | 138 | tr_info("Connected to HSDPA"); |
RobMeades | 0:5cffef3371f6 | 139 | break; |
RobMeades | 0:5cffef3371f6 | 140 | case HSUPA: |
RobMeades | 0:5cffef3371f6 | 141 | tr_info("Connected to HSPA"); |
RobMeades | 0:5cffef3371f6 | 142 | break; |
RobMeades | 0:5cffef3371f6 | 143 | case HSDPA_HSUPA: |
RobMeades | 0:5cffef3371f6 | 144 | tr_info("Connected to HDPA/HSPA"); |
RobMeades | 0:5cffef3371f6 | 145 | break; |
RobMeades | 0:5cffef3371f6 | 146 | case LTE: |
RobMeades | 0:5cffef3371f6 | 147 | tr_info("Connected to LTE"); |
RobMeades | 0:5cffef3371f6 | 148 | break; |
RobMeades | 0:5cffef3371f6 | 149 | default: |
RobMeades | 0:5cffef3371f6 | 150 | tr_info("Unknown RAT %d", AcTStatus); |
RobMeades | 0:5cffef3371f6 | 151 | break; |
RobMeades | 0:5cffef3371f6 | 152 | } |
RobMeades | 0:5cffef3371f6 | 153 | |
RobMeades | 0:5cffef3371f6 | 154 | _dev_info.rat = static_cast<RadioAccessNetworkType>(AcTStatus); |
RobMeades | 0:5cffef3371f6 | 155 | } |
RobMeades | 0:5cffef3371f6 | 156 | |
RobMeades | 0:5cffef3371f6 | 157 | bool UbloxCellularBase::get_iccid() |
RobMeades | 0:5cffef3371f6 | 158 | { |
RobMeades | 0:5cffef3371f6 | 159 | bool success; |
RobMeades | 0:5cffef3371f6 | 160 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 161 | |
RobMeades | 0:5cffef3371f6 | 162 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 163 | |
RobMeades | 0:5cffef3371f6 | 164 | // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card. |
RobMeades | 0:5cffef3371f6 | 165 | // ICCID is a serial number identifying the SIM. |
RobMeades | 0:5cffef3371f6 | 166 | // AT Command Manual UBX-13002752, section 4.12 |
RobMeades | 0:5cffef3371f6 | 167 | success = _at->send("AT+CCID") && _at->recv("+CCID: %20[^\n]\nOK\n", _dev_info.iccid); |
RobMeades | 0:5cffef3371f6 | 168 | tr_info("DevInfo: ICCID=%s", _dev_info.iccid); |
RobMeades | 0:5cffef3371f6 | 169 | |
RobMeades | 0:5cffef3371f6 | 170 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 171 | return success; |
RobMeades | 0:5cffef3371f6 | 172 | } |
RobMeades | 0:5cffef3371f6 | 173 | |
RobMeades | 0:5cffef3371f6 | 174 | bool UbloxCellularBase::get_imsi() |
RobMeades | 0:5cffef3371f6 | 175 | { |
RobMeades | 0:5cffef3371f6 | 176 | bool success; |
RobMeades | 0:5cffef3371f6 | 177 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 178 | |
RobMeades | 0:5cffef3371f6 | 179 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 180 | |
RobMeades | 0:5cffef3371f6 | 181 | // International mobile subscriber identification |
RobMeades | 0:5cffef3371f6 | 182 | // AT Command Manual UBX-13002752, section 4.11 |
RobMeades | 0:5cffef3371f6 | 183 | success = _at->send("AT+CIMI") && _at->recv("%15[^\n]\nOK\n", _dev_info.imsi); |
RobMeades | 0:5cffef3371f6 | 184 | tr_info("DevInfo: IMSI=%s", _dev_info.imsi); |
RobMeades | 0:5cffef3371f6 | 185 | |
RobMeades | 0:5cffef3371f6 | 186 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 187 | return success; |
RobMeades | 0:5cffef3371f6 | 188 | } |
RobMeades | 0:5cffef3371f6 | 189 | |
RobMeades | 0:5cffef3371f6 | 190 | bool UbloxCellularBase::get_imei() |
RobMeades | 0:5cffef3371f6 | 191 | { |
RobMeades | 0:5cffef3371f6 | 192 | bool success; |
RobMeades | 0:5cffef3371f6 | 193 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 194 | |
RobMeades | 0:5cffef3371f6 | 195 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 196 | |
RobMeades | 0:5cffef3371f6 | 197 | // International mobile equipment identifier |
RobMeades | 0:5cffef3371f6 | 198 | // AT Command Manual UBX-13002752, section 4.7 |
RobMeades | 0:5cffef3371f6 | 199 | success = _at->send("AT+CGSN") && _at->recv("%15[^\n]\nOK\n", _dev_info.imei); |
RobMeades | 0:5cffef3371f6 | 200 | tr_info("DevInfo: IMEI=%s", _dev_info.imei); |
RobMeades | 0:5cffef3371f6 | 201 | |
RobMeades | 0:5cffef3371f6 | 202 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 203 | return success; |
RobMeades | 0:5cffef3371f6 | 204 | } |
RobMeades | 0:5cffef3371f6 | 205 | |
RobMeades | 0:5cffef3371f6 | 206 | bool UbloxCellularBase::get_meid() |
RobMeades | 0:5cffef3371f6 | 207 | { |
RobMeades | 0:5cffef3371f6 | 208 | bool success; |
RobMeades | 0:5cffef3371f6 | 209 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 210 | |
RobMeades | 0:5cffef3371f6 | 211 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 212 | |
RobMeades | 0:5cffef3371f6 | 213 | // Mobile equipment identifier |
RobMeades | 0:5cffef3371f6 | 214 | // AT Command Manual UBX-13002752, section 4.8 |
RobMeades | 0:5cffef3371f6 | 215 | success = _at->send("AT+GSN") && _at->recv("%18[^\n]\nOK\n", _dev_info.meid); |
RobMeades | 0:5cffef3371f6 | 216 | tr_info("DevInfo: MEID=%s", _dev_info.meid); |
RobMeades | 0:5cffef3371f6 | 217 | |
RobMeades | 0:5cffef3371f6 | 218 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 219 | return success; |
RobMeades | 0:5cffef3371f6 | 220 | } |
RobMeades | 0:5cffef3371f6 | 221 | |
RobMeades | 0:5cffef3371f6 | 222 | bool UbloxCellularBase::set_sms() |
RobMeades | 0:5cffef3371f6 | 223 | { |
RobMeades | 0:5cffef3371f6 | 224 | bool success = false; |
RobMeades | 0:5cffef3371f6 | 225 | char buf[32]; |
RobMeades | 0:5cffef3371f6 | 226 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 227 | |
RobMeades | 0:5cffef3371f6 | 228 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 229 | |
RobMeades | 0:5cffef3371f6 | 230 | // Set up SMS format and enable URC |
RobMeades | 0:5cffef3371f6 | 231 | // AT Command Manual UBX-13002752, section 11 |
RobMeades | 0:5cffef3371f6 | 232 | if (_at->send("AT+CMGF=1") && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 233 | tr_debug("SMS in text mode"); |
RobMeades | 0:5cffef3371f6 | 234 | if (_at->send("AT+CNMI=2,1") && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 235 | tr_debug("SMS URC enabled"); |
RobMeades | 0:5cffef3371f6 | 236 | // Set to CS preferred since PS preferred doesn't work |
RobMeades | 0:5cffef3371f6 | 237 | // on some networks |
RobMeades | 0:5cffef3371f6 | 238 | if (_at->send("AT+CGSMS=1") && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 239 | tr_debug("SMS set to CS preferred"); |
RobMeades | 0:5cffef3371f6 | 240 | success = true; |
RobMeades | 0:5cffef3371f6 | 241 | memset (buf, 0, sizeof (buf)); |
RobMeades | 0:5cffef3371f6 | 242 | if (_at->send("AT+CSCA?") && |
RobMeades | 0:5cffef3371f6 | 243 | _at->recv("+CSCA: \"%31[^\"]\"", buf) && |
RobMeades | 0:5cffef3371f6 | 244 | _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 245 | tr_info("SMS Service Centre address is \"%s\"", buf); |
RobMeades | 0:5cffef3371f6 | 246 | } |
RobMeades | 0:5cffef3371f6 | 247 | } |
RobMeades | 0:5cffef3371f6 | 248 | } |
RobMeades | 0:5cffef3371f6 | 249 | } |
RobMeades | 0:5cffef3371f6 | 250 | |
RobMeades | 0:5cffef3371f6 | 251 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 252 | return success; |
RobMeades | 0:5cffef3371f6 | 253 | } |
RobMeades | 0:5cffef3371f6 | 254 | |
RobMeades | 0:5cffef3371f6 | 255 | void UbloxCellularBase::parser_abort_cb() |
RobMeades | 0:5cffef3371f6 | 256 | { |
RobMeades | 0:5cffef3371f6 | 257 | _at->abort(); |
RobMeades | 0:5cffef3371f6 | 258 | } |
RobMeades | 0:5cffef3371f6 | 259 | |
RobMeades | 0:5cffef3371f6 | 260 | // Callback for CME ERROR and CMS ERROR. |
RobMeades | 0:5cffef3371f6 | 261 | void UbloxCellularBase::CMX_ERROR_URC() |
RobMeades | 0:5cffef3371f6 | 262 | { |
RobMeades | 0:5cffef3371f6 | 263 | char buf[48]; |
RobMeades | 0:5cffef3371f6 | 264 | |
RobMeades | 0:5cffef3371f6 | 265 | if (read_at_to_char(buf, sizeof (buf), '\n') > 0) { |
RobMeades | 0:5cffef3371f6 | 266 | tr_debug("AT error %s", buf); |
RobMeades | 0:5cffef3371f6 | 267 | } |
RobMeades | 0:5cffef3371f6 | 268 | parser_abort_cb(); |
RobMeades | 0:5cffef3371f6 | 269 | } |
RobMeades | 0:5cffef3371f6 | 270 | |
RobMeades | 0:5cffef3371f6 | 271 | // Callback for circuit switched registration URC. |
RobMeades | 0:5cffef3371f6 | 272 | void UbloxCellularBase::CREG_URC() |
RobMeades | 0:5cffef3371f6 | 273 | { |
RobMeades | 0:5cffef3371f6 | 274 | char buf[10]; |
RobMeades | 0:5cffef3371f6 | 275 | int status; |
RobMeades | 0:5cffef3371f6 | 276 | |
RobMeades | 0:5cffef3371f6 | 277 | // If this is the URC it will be a single |
RobMeades | 0:5cffef3371f6 | 278 | // digit followed by \n. If it is the |
RobMeades | 0:5cffef3371f6 | 279 | // answer to a CREG query, it will be |
RobMeades | 0:5cffef3371f6 | 280 | // a ": %d,%d\n" where the second digit |
RobMeades | 0:5cffef3371f6 | 281 | // indicates the status |
RobMeades | 0:5cffef3371f6 | 282 | // Note: not calling _at->recv() from here as we're |
RobMeades | 0:5cffef3371f6 | 283 | // already in an _at->recv() |
RobMeades | 0:5cffef3371f6 | 284 | if (read_at_to_char(buf, sizeof (buf), '\n') > 0) { |
RobMeades | 0:5cffef3371f6 | 285 | if (sscanf(buf, ": %*d,%d", &status) == 1) { |
RobMeades | 0:5cffef3371f6 | 286 | set_nwk_reg_status_csd(status); |
RobMeades | 0:5cffef3371f6 | 287 | } else if (sscanf(buf, ": %d", &status) == 1) { |
RobMeades | 0:5cffef3371f6 | 288 | set_nwk_reg_status_csd(status); |
RobMeades | 0:5cffef3371f6 | 289 | } |
RobMeades | 0:5cffef3371f6 | 290 | } |
RobMeades | 0:5cffef3371f6 | 291 | } |
RobMeades | 0:5cffef3371f6 | 292 | |
RobMeades | 0:5cffef3371f6 | 293 | // Callback for packet switched registration URC. |
RobMeades | 0:5cffef3371f6 | 294 | void UbloxCellularBase::CGREG_URC() |
RobMeades | 0:5cffef3371f6 | 295 | { |
RobMeades | 0:5cffef3371f6 | 296 | char buf[10]; |
RobMeades | 0:5cffef3371f6 | 297 | int status; |
RobMeades | 0:5cffef3371f6 | 298 | |
RobMeades | 0:5cffef3371f6 | 299 | // If this is the URC it will be a single |
RobMeades | 0:5cffef3371f6 | 300 | // digit followed by \n. If it is the |
RobMeades | 0:5cffef3371f6 | 301 | // answer to a CGREG query, it will be |
RobMeades | 0:5cffef3371f6 | 302 | // a ": %d,%d\n" where the second digit |
RobMeades | 0:5cffef3371f6 | 303 | // indicates the status |
RobMeades | 0:5cffef3371f6 | 304 | // Note: not calling _at->recv() from here as we're |
RobMeades | 0:5cffef3371f6 | 305 | // already in an _at->recv() |
RobMeades | 0:5cffef3371f6 | 306 | if (read_at_to_char(buf, sizeof (buf), '\n') > 0) { |
RobMeades | 0:5cffef3371f6 | 307 | if (sscanf(buf, ": %*d,%d", &status) == 1) { |
RobMeades | 0:5cffef3371f6 | 308 | set_nwk_reg_status_psd(status); |
RobMeades | 0:5cffef3371f6 | 309 | } else if (sscanf(buf, ": %d", &status) == 1) { |
RobMeades | 0:5cffef3371f6 | 310 | set_nwk_reg_status_psd(status); |
RobMeades | 0:5cffef3371f6 | 311 | } |
RobMeades | 0:5cffef3371f6 | 312 | } |
RobMeades | 0:5cffef3371f6 | 313 | } |
RobMeades | 0:5cffef3371f6 | 314 | |
RobMeades | 0:5cffef3371f6 | 315 | // Callback for EPS registration URC. |
RobMeades | 0:5cffef3371f6 | 316 | void UbloxCellularBase::CEREG_URC() |
RobMeades | 0:5cffef3371f6 | 317 | { |
RobMeades | 0:5cffef3371f6 | 318 | char buf[10]; |
RobMeades | 0:5cffef3371f6 | 319 | int status; |
RobMeades | 0:5cffef3371f6 | 320 | |
RobMeades | 0:5cffef3371f6 | 321 | // If this is the URC it will be a single |
RobMeades | 0:5cffef3371f6 | 322 | // digit followed by \n. If it is the |
RobMeades | 0:5cffef3371f6 | 323 | // answer to a CEREG query, it will be |
RobMeades | 0:5cffef3371f6 | 324 | // a ": %d,%d\n" where the second digit |
RobMeades | 0:5cffef3371f6 | 325 | // indicates the status |
RobMeades | 0:5cffef3371f6 | 326 | // Note: not calling _at->recv() from here as we're |
RobMeades | 0:5cffef3371f6 | 327 | // already in an _at->recv() |
RobMeades | 0:5cffef3371f6 | 328 | if (read_at_to_char(buf, sizeof (buf), '\n') > 0) { |
RobMeades | 0:5cffef3371f6 | 329 | if (sscanf(buf, ": %*d,%d", &status) == 1) { |
RobMeades | 0:5cffef3371f6 | 330 | set_nwk_reg_status_eps(status); |
RobMeades | 0:5cffef3371f6 | 331 | } else if (sscanf(buf, ": %d", &status) == 1) { |
RobMeades | 0:5cffef3371f6 | 332 | set_nwk_reg_status_eps(status); |
RobMeades | 0:5cffef3371f6 | 333 | } |
RobMeades | 0:5cffef3371f6 | 334 | } |
RobMeades | 0:5cffef3371f6 | 335 | } |
RobMeades | 0:5cffef3371f6 | 336 | |
RobMeades | 0:5cffef3371f6 | 337 | // Callback UMWI, just filtering it out. |
RobMeades | 0:5cffef3371f6 | 338 | void UbloxCellularBase::UMWI_URC() |
RobMeades | 0:5cffef3371f6 | 339 | { |
RobMeades | 0:5cffef3371f6 | 340 | char buf[10]; |
RobMeades | 0:5cffef3371f6 | 341 | |
RobMeades | 0:5cffef3371f6 | 342 | // Note: not calling _at->recv() from here as we're |
RobMeades | 0:5cffef3371f6 | 343 | // already in an _at->recv() |
RobMeades | 0:5cffef3371f6 | 344 | read_at_to_char(buf, sizeof (buf), '\n'); |
RobMeades | 0:5cffef3371f6 | 345 | } |
RobMeades | 0:5cffef3371f6 | 346 | |
RobMeades | 0:5cffef3371f6 | 347 | /********************************************************************** |
RobMeades | 0:5cffef3371f6 | 348 | * PROTECTED METHODS |
RobMeades | 0:5cffef3371f6 | 349 | **********************************************************************/ |
RobMeades | 0:5cffef3371f6 | 350 | |
RobMeades | 0:5cffef3371f6 | 351 | #if MODEM_ON_BOARD |
RobMeades | 0:5cffef3371f6 | 352 | void UbloxCellularBase::modem_init() |
RobMeades | 0:5cffef3371f6 | 353 | { |
RobMeades | 0:5cffef3371f6 | 354 | ::onboard_modem_init(); |
RobMeades | 0:5cffef3371f6 | 355 | } |
RobMeades | 0:5cffef3371f6 | 356 | |
RobMeades | 0:5cffef3371f6 | 357 | void UbloxCellularBase::modem_deinit() |
RobMeades | 0:5cffef3371f6 | 358 | { |
RobMeades | 0:5cffef3371f6 | 359 | ::onboard_modem_deinit(); |
RobMeades | 0:5cffef3371f6 | 360 | } |
RobMeades | 0:5cffef3371f6 | 361 | |
RobMeades | 0:5cffef3371f6 | 362 | void UbloxCellularBase::modem_power_up() |
RobMeades | 0:5cffef3371f6 | 363 | { |
RobMeades | 0:5cffef3371f6 | 364 | ::onboard_modem_power_up(); |
RobMeades | 0:5cffef3371f6 | 365 | } |
RobMeades | 0:5cffef3371f6 | 366 | |
RobMeades | 0:5cffef3371f6 | 367 | void UbloxCellularBase::modem_power_down() |
RobMeades | 0:5cffef3371f6 | 368 | { |
RobMeades | 0:5cffef3371f6 | 369 | ::onboard_modem_power_down(); |
RobMeades | 0:5cffef3371f6 | 370 | } |
RobMeades | 0:5cffef3371f6 | 371 | #else |
RobMeades | 0:5cffef3371f6 | 372 | void UbloxCellularBase::modem_init() |
RobMeades | 0:5cffef3371f6 | 373 | { |
RobMeades | 0:5cffef3371f6 | 374 | // Meant to be overridden |
RobMeades | 0:5cffef3371f6 | 375 | } |
RobMeades | 0:5cffef3371f6 | 376 | |
RobMeades | 0:5cffef3371f6 | 377 | void UbloxCellularBase::modem_deinit() |
RobMeades | 0:5cffef3371f6 | 378 | { |
RobMeades | 0:5cffef3371f6 | 379 | // Meant to be overridden |
RobMeades | 0:5cffef3371f6 | 380 | } |
RobMeades | 0:5cffef3371f6 | 381 | |
RobMeades | 0:5cffef3371f6 | 382 | void UbloxCellularBase::modem_power_up() |
RobMeades | 0:5cffef3371f6 | 383 | { |
RobMeades | 0:5cffef3371f6 | 384 | // Meant to be overridden |
RobMeades | 0:5cffef3371f6 | 385 | } |
RobMeades | 0:5cffef3371f6 | 386 | |
RobMeades | 0:5cffef3371f6 | 387 | void UbloxCellularBase::modem_power_down() |
RobMeades | 0:5cffef3371f6 | 388 | { |
RobMeades | 0:5cffef3371f6 | 389 | // Mmeant to be overridden |
RobMeades | 0:5cffef3371f6 | 390 | } |
RobMeades | 0:5cffef3371f6 | 391 | #endif |
RobMeades | 0:5cffef3371f6 | 392 | |
RobMeades | 0:5cffef3371f6 | 393 | // Constructor. |
RobMeades | 0:5cffef3371f6 | 394 | // Note: to allow this base class to be inherited as a virtual base class |
RobMeades | 0:5cffef3371f6 | 395 | // by everyone, it takes no parameters. See also comment above classInit() |
RobMeades | 0:5cffef3371f6 | 396 | // in the header file. |
RobMeades | 0:5cffef3371f6 | 397 | UbloxCellularBase::UbloxCellularBase() |
RobMeades | 0:5cffef3371f6 | 398 | { |
RobMeades | 0:5cffef3371f6 | 399 | _pin = NULL; |
RobMeades | 0:5cffef3371f6 | 400 | _at = NULL; |
RobMeades | 0:5cffef3371f6 | 401 | _at_timeout = AT_PARSER_TIMEOUT; |
RobMeades | 0:5cffef3371f6 | 402 | _fh = NULL; |
RobMeades | 0:5cffef3371f6 | 403 | _modem_initialised = false; |
RobMeades | 0:5cffef3371f6 | 404 | _sim_pin_check_enabled = false; |
RobMeades | 0:5cffef3371f6 | 405 | _debug_trace_on = false; |
RobMeades | 0:5cffef3371f6 | 406 | |
RobMeades | 0:5cffef3371f6 | 407 | _dev_info.dev = DEV_TYPE_NONE; |
RobMeades | 0:5cffef3371f6 | 408 | _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING; |
RobMeades | 0:5cffef3371f6 | 409 | _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING; |
RobMeades | 0:5cffef3371f6 | 410 | _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING; |
RobMeades | 0:5cffef3371f6 | 411 | } |
RobMeades | 0:5cffef3371f6 | 412 | |
RobMeades | 0:5cffef3371f6 | 413 | // Destructor. |
RobMeades | 0:5cffef3371f6 | 414 | UbloxCellularBase::~UbloxCellularBase() |
RobMeades | 0:5cffef3371f6 | 415 | { |
RobMeades | 0:5cffef3371f6 | 416 | deinit(); |
RobMeades | 0:5cffef3371f6 | 417 | delete _at; |
RobMeades | 0:5cffef3371f6 | 418 | delete _fh; |
RobMeades | 0:5cffef3371f6 | 419 | } |
RobMeades | 0:5cffef3371f6 | 420 | |
RobMeades | 0:5cffef3371f6 | 421 | // Initialise the portions of this class that are parameterised. |
RobMeades | 0:5cffef3371f6 | 422 | void UbloxCellularBase::baseClassInit(PinName tx, PinName rx, |
RobMeades | 0:5cffef3371f6 | 423 | int baud, bool debug_on) |
RobMeades | 0:5cffef3371f6 | 424 | { |
RobMeades | 0:5cffef3371f6 | 425 | // Only initialise ourselves if it's not already been done |
RobMeades | 0:5cffef3371f6 | 426 | if (_at == NULL) { |
RobMeades | 0:5cffef3371f6 | 427 | if (_debug_trace_on == false) { |
RobMeades | 0:5cffef3371f6 | 428 | _debug_trace_on = debug_on; |
RobMeades | 0:5cffef3371f6 | 429 | } |
rob.meades@u-blox.com | 4:2e640a101db1 | 430 | _baud = baud; |
RobMeades | 0:5cffef3371f6 | 431 | |
RobMeades | 0:5cffef3371f6 | 432 | // Set up File Handle for buffered serial comms with cellular module |
RobMeades | 0:5cffef3371f6 | 433 | // (which will be used by the AT parser) |
rob.meades@u-blox.com | 4:2e640a101db1 | 434 | // Note: the UART is initialised to run no faster than 115200 because |
rob.meades@u-blox.com | 4:2e640a101db1 | 435 | // the modems cannot reliably auto-baud at faster rates. The faster |
rob.meades@u-blox.com | 4:2e640a101db1 | 436 | // rate is adopted later with a specific AT command and the |
rob.meades@u-blox.com | 4:2e640a101db1 | 437 | // UARTSerial rate is adjusted at that time |
rob.meades@u-blox.com | 4:2e640a101db1 | 438 | if (baud > 115200) { |
rob.meades@u-blox.com | 4:2e640a101db1 | 439 | baud = 115200; |
rob.meades@u-blox.com | 4:2e640a101db1 | 440 | } |
RobMeades | 0:5cffef3371f6 | 441 | _fh = new UARTSerial(tx, rx, baud); |
RobMeades | 0:5cffef3371f6 | 442 | |
RobMeades | 0:5cffef3371f6 | 443 | // Set up the AT parser |
RobMeades | 0:5cffef3371f6 | 444 | _at = new ATCmdParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE, |
rob.meades@u-blox.com | 3:f9b2cd6f72b1 | 445 | _at_timeout, _debug_trace_on); |
RobMeades | 0:5cffef3371f6 | 446 | |
RobMeades | 0:5cffef3371f6 | 447 | // Error cases, out of band handling |
RobMeades | 0:5cffef3371f6 | 448 | _at->oob("ERROR", callback(this, &UbloxCellularBase::parser_abort_cb)); |
RobMeades | 0:5cffef3371f6 | 449 | _at->oob("+CME ERROR", callback(this, &UbloxCellularBase::CMX_ERROR_URC)); |
RobMeades | 0:5cffef3371f6 | 450 | _at->oob("+CMS ERROR", callback(this, &UbloxCellularBase::CMX_ERROR_URC)); |
RobMeades | 0:5cffef3371f6 | 451 | |
RobMeades | 0:5cffef3371f6 | 452 | // Registration status, out of band handling |
RobMeades | 0:5cffef3371f6 | 453 | _at->oob("+CREG", callback(this, &UbloxCellularBase::CREG_URC)); |
RobMeades | 0:5cffef3371f6 | 454 | _at->oob("+CGREG", callback(this, &UbloxCellularBase::CGREG_URC)); |
RobMeades | 0:5cffef3371f6 | 455 | _at->oob("+CEREG", callback(this, &UbloxCellularBase::CEREG_URC)); |
RobMeades | 0:5cffef3371f6 | 456 | |
RobMeades | 0:5cffef3371f6 | 457 | // Capture the UMWI, just to stop it getting in the way |
RobMeades | 0:5cffef3371f6 | 458 | _at->oob("+UMWI", callback(this, &UbloxCellularBase::UMWI_URC)); |
RobMeades | 0:5cffef3371f6 | 459 | } |
RobMeades | 0:5cffef3371f6 | 460 | } |
RobMeades | 0:5cffef3371f6 | 461 | |
RobMeades | 0:5cffef3371f6 | 462 | // Set the AT parser timeout. |
RobMeades | 0:5cffef3371f6 | 463 | // Note: the AT interface should be locked before this is called. |
RobMeades | 0:5cffef3371f6 | 464 | void UbloxCellularBase::at_set_timeout(int timeout) { |
RobMeades | 0:5cffef3371f6 | 465 | |
RobMeades | 0:5cffef3371f6 | 466 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 467 | |
RobMeades | 0:5cffef3371f6 | 468 | _at_timeout = timeout; |
RobMeades | 0:5cffef3371f6 | 469 | _at->set_timeout(timeout); |
RobMeades | 0:5cffef3371f6 | 470 | } |
RobMeades | 0:5cffef3371f6 | 471 | |
RobMeades | 0:5cffef3371f6 | 472 | // Read up to size bytes from the AT interface up to a "end". |
RobMeades | 0:5cffef3371f6 | 473 | // Note: the AT interface should be locked before this is called. |
RobMeades | 0:5cffef3371f6 | 474 | int UbloxCellularBase::read_at_to_char(char * buf, int size, char end) |
RobMeades | 0:5cffef3371f6 | 475 | { |
RobMeades | 0:5cffef3371f6 | 476 | int count = 0; |
RobMeades | 0:5cffef3371f6 | 477 | int x = 0; |
RobMeades | 0:5cffef3371f6 | 478 | |
RobMeades | 0:5cffef3371f6 | 479 | if (size > 0) { |
RobMeades | 0:5cffef3371f6 | 480 | for (count = 0; (count < size) && (x >= 0) && (x != end); count++) { |
RobMeades | 0:5cffef3371f6 | 481 | x = _at->getc(); |
RobMeades | 0:5cffef3371f6 | 482 | *(buf + count) = (char) x; |
RobMeades | 0:5cffef3371f6 | 483 | } |
RobMeades | 0:5cffef3371f6 | 484 | |
RobMeades | 0:5cffef3371f6 | 485 | count--; |
RobMeades | 0:5cffef3371f6 | 486 | *(buf + count) = 0; |
RobMeades | 0:5cffef3371f6 | 487 | |
RobMeades | 0:5cffef3371f6 | 488 | // Convert line endings: |
RobMeades | 0:5cffef3371f6 | 489 | // If end was '\n' (0x0a) and the preceding character was 0x0d, then |
RobMeades | 0:5cffef3371f6 | 490 | // overwrite that with null as well. |
RobMeades | 0:5cffef3371f6 | 491 | if ((count > 0) && (end == '\n') && (*(buf + count - 1) == '\x0d')) { |
RobMeades | 0:5cffef3371f6 | 492 | count--; |
RobMeades | 0:5cffef3371f6 | 493 | *(buf + count) = 0; |
RobMeades | 0:5cffef3371f6 | 494 | } |
RobMeades | 0:5cffef3371f6 | 495 | } |
RobMeades | 0:5cffef3371f6 | 496 | |
RobMeades | 0:5cffef3371f6 | 497 | return count; |
RobMeades | 0:5cffef3371f6 | 498 | } |
RobMeades | 0:5cffef3371f6 | 499 | |
RobMeades | 0:5cffef3371f6 | 500 | // Power up the modem. |
RobMeades | 0:5cffef3371f6 | 501 | // Enables the GPIO lines to the modem and then wriggles the power line in short pulses. |
RobMeades | 0:5cffef3371f6 | 502 | bool UbloxCellularBase::power_up() |
RobMeades | 0:5cffef3371f6 | 503 | { |
RobMeades | 0:5cffef3371f6 | 504 | bool success = false; |
RobMeades | 0:5cffef3371f6 | 505 | int at_timeout; |
RobMeades | 0:5cffef3371f6 | 506 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 507 | |
RobMeades | 0:5cffef3371f6 | 508 | at_timeout = _at_timeout; // Has to be inside LOCK()s |
RobMeades | 0:5cffef3371f6 | 509 | |
RobMeades | 0:5cffef3371f6 | 510 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 511 | |
RobMeades | 0:5cffef3371f6 | 512 | /* Initialize GPIO lines */ |
RobMeades | 0:5cffef3371f6 | 513 | tr_info("Powering up modem..."); |
RobMeades | 0:5cffef3371f6 | 514 | onboard_modem_init(); |
RobMeades | 0:5cffef3371f6 | 515 | /* Give modem a little time to settle down */ |
RobMeades | 0:5cffef3371f6 | 516 | wait_ms(250); |
RobMeades | 0:5cffef3371f6 | 517 | |
RobMeades | 0:5cffef3371f6 | 518 | for (int retry_count = 0; !success && (retry_count < 20); retry_count++) { |
RobMeades | 0:5cffef3371f6 | 519 | onboard_modem_power_up(); |
RobMeades | 0:5cffef3371f6 | 520 | wait_ms(500); |
RobMeades | 0:5cffef3371f6 | 521 | // Modem tends to spit out noise during power up - don't confuse the parser |
RobMeades | 0:5cffef3371f6 | 522 | _at->flush(); |
RobMeades | 0:5cffef3371f6 | 523 | at_set_timeout(1000); |
RobMeades | 0:5cffef3371f6 | 524 | if (_at->send("AT")) { |
RobMeades | 0:5cffef3371f6 | 525 | // C027 needs a delay here |
RobMeades | 0:5cffef3371f6 | 526 | wait_ms(100); |
RobMeades | 0:5cffef3371f6 | 527 | if (_at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 528 | success = true; |
RobMeades | 0:5cffef3371f6 | 529 | } |
RobMeades | 0:5cffef3371f6 | 530 | } |
RobMeades | 0:5cffef3371f6 | 531 | at_set_timeout(at_timeout); |
RobMeades | 0:5cffef3371f6 | 532 | } |
RobMeades | 0:5cffef3371f6 | 533 | |
rob.meades@u-blox.com | 4:2e640a101db1 | 534 | if (success) { |
rob.meades@u-blox.com | 4:2e640a101db1 | 535 | // Set the final baud rate |
rob.meades@u-blox.com | 4:2e640a101db1 | 536 | if (_at->send("AT+IPR=%d", _baud) && _at->recv("OK")) { |
rob.meades@u-blox.com | 4:2e640a101db1 | 537 | // Need to wait for things to be sorted out on the modem side |
rob.meades@u-blox.com | 4:2e640a101db1 | 538 | wait_ms(100); |
rob.meades@u-blox.com | 4:2e640a101db1 | 539 | ((UARTSerial *)_fh)->set_baud(_baud); |
rob.meades@u-blox.com | 4:2e640a101db1 | 540 | } |
rob.meades@u-blox.com | 4:2e640a101db1 | 541 | |
rob.meades@u-blox.com | 4:2e640a101db1 | 542 | // Turn off modem echoing and turn on verbose responses |
rob.meades@u-blox.com | 4:2e640a101db1 | 543 | success = _at->send("ATE0;+CMEE=2") && _at->recv("OK") && |
rob.meades@u-blox.com | 4:2e640a101db1 | 544 | // The following commands are best sent separately |
rob.meades@u-blox.com | 4:2e640a101db1 | 545 | _at->send("AT&K0") && _at->recv("OK") && // Turn off RTC/CTS handshaking |
rob.meades@u-blox.com | 4:2e640a101db1 | 546 | _at->send("AT&C1") && _at->recv("OK") && // Set DCD circuit(109), changes in accordance with the carrier detect status |
rob.meades@u-blox.com | 4:2e640a101db1 | 547 | _at->send("AT&D0") && _at->recv("OK"); // Set DTR circuit, we ignore the state change of DTR |
rob.meades@u-blox.com | 4:2e640a101db1 | 548 | } |
RobMeades | 0:5cffef3371f6 | 549 | |
RobMeades | 0:5cffef3371f6 | 550 | if (!success) { |
RobMeades | 0:5cffef3371f6 | 551 | tr_error("Preliminary modem setup failed."); |
RobMeades | 0:5cffef3371f6 | 552 | } |
RobMeades | 0:5cffef3371f6 | 553 | |
RobMeades | 0:5cffef3371f6 | 554 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 555 | return success; |
RobMeades | 0:5cffef3371f6 | 556 | } |
RobMeades | 0:5cffef3371f6 | 557 | |
RobMeades | 0:5cffef3371f6 | 558 | // Power down modem via AT interface. |
RobMeades | 0:5cffef3371f6 | 559 | void UbloxCellularBase::power_down() |
RobMeades | 0:5cffef3371f6 | 560 | { |
RobMeades | 0:5cffef3371f6 | 561 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 562 | |
RobMeades | 0:5cffef3371f6 | 563 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 564 | |
RobMeades | 0:5cffef3371f6 | 565 | // If we have been running, do a soft power-off first |
RobMeades | 0:5cffef3371f6 | 566 | if (_modem_initialised && (_at != NULL)) { |
RobMeades | 0:5cffef3371f6 | 567 | _at->send("AT+CPWROFF") && _at->recv("OK"); |
RobMeades | 0:5cffef3371f6 | 568 | } |
RobMeades | 0:5cffef3371f6 | 569 | |
RobMeades | 0:5cffef3371f6 | 570 | // Now do a hard power-off |
RobMeades | 0:5cffef3371f6 | 571 | onboard_modem_power_down(); |
RobMeades | 0:5cffef3371f6 | 572 | onboard_modem_deinit(); |
RobMeades | 0:5cffef3371f6 | 573 | |
RobMeades | 0:5cffef3371f6 | 574 | _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING; |
RobMeades | 0:5cffef3371f6 | 575 | _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING; |
RobMeades | 0:5cffef3371f6 | 576 | _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING; |
RobMeades | 0:5cffef3371f6 | 577 | |
RobMeades | 0:5cffef3371f6 | 578 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 579 | } |
RobMeades | 0:5cffef3371f6 | 580 | |
RobMeades | 0:5cffef3371f6 | 581 | // Get the device ID. |
RobMeades | 0:5cffef3371f6 | 582 | bool UbloxCellularBase::set_device_identity(DeviceType *dev) |
RobMeades | 0:5cffef3371f6 | 583 | { |
RobMeades | 0:5cffef3371f6 | 584 | char buf[20]; |
RobMeades | 0:5cffef3371f6 | 585 | bool success; |
RobMeades | 0:5cffef3371f6 | 586 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 587 | |
RobMeades | 0:5cffef3371f6 | 588 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 589 | |
RobMeades | 0:5cffef3371f6 | 590 | success = _at->send("ATI") && _at->recv("%19[^\n]\nOK\n", buf); |
RobMeades | 0:5cffef3371f6 | 591 | |
RobMeades | 0:5cffef3371f6 | 592 | if (success) { |
RobMeades | 0:5cffef3371f6 | 593 | if (strstr(buf, "SARA-G35")) |
RobMeades | 0:5cffef3371f6 | 594 | *dev = DEV_SARA_G35; |
RobMeades | 0:5cffef3371f6 | 595 | else if (strstr(buf, "LISA-U200-03S")) |
RobMeades | 0:5cffef3371f6 | 596 | *dev = DEV_LISA_U2_03S; |
RobMeades | 0:5cffef3371f6 | 597 | else if (strstr(buf, "LISA-U2")) |
RobMeades | 0:5cffef3371f6 | 598 | *dev = DEV_LISA_U2; |
RobMeades | 0:5cffef3371f6 | 599 | else if (strstr(buf, "SARA-U2")) |
RobMeades | 0:5cffef3371f6 | 600 | *dev = DEV_SARA_U2; |
RobMeades | 0:5cffef3371f6 | 601 | else if (strstr(buf, "LEON-G2")) |
RobMeades | 0:5cffef3371f6 | 602 | *dev = DEV_LEON_G2; |
RobMeades | 0:5cffef3371f6 | 603 | else if (strstr(buf, "TOBY-L2")) |
RobMeades | 0:5cffef3371f6 | 604 | *dev = DEV_TOBY_L2; |
RobMeades | 0:5cffef3371f6 | 605 | else if (strstr(buf, "MPCI-L2")) |
RobMeades | 0:5cffef3371f6 | 606 | *dev = DEV_MPCI_L2; |
RobMeades | 0:5cffef3371f6 | 607 | } |
RobMeades | 0:5cffef3371f6 | 608 | |
RobMeades | 0:5cffef3371f6 | 609 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 610 | return success; |
RobMeades | 0:5cffef3371f6 | 611 | } |
RobMeades | 0:5cffef3371f6 | 612 | |
RobMeades | 0:5cffef3371f6 | 613 | // Send initialisation AT commands that are specific to the device. |
RobMeades | 0:5cffef3371f6 | 614 | bool UbloxCellularBase::device_init(DeviceType dev) |
RobMeades | 0:5cffef3371f6 | 615 | { |
RobMeades | 0:5cffef3371f6 | 616 | bool success = false; |
RobMeades | 0:5cffef3371f6 | 617 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 618 | |
RobMeades | 0:5cffef3371f6 | 619 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 620 | |
RobMeades | 0:5cffef3371f6 | 621 | if ((dev == DEV_LISA_U2) || (dev == DEV_LEON_G2) || (dev == DEV_TOBY_L2)) { |
RobMeades | 0:5cffef3371f6 | 622 | success = _at->send("AT+UGPIOC=20,2") && _at->recv("OK"); |
RobMeades | 0:5cffef3371f6 | 623 | } else if ((dev == DEV_SARA_U2) || (dev == DEV_SARA_G35)) { |
RobMeades | 0:5cffef3371f6 | 624 | success = _at->send("AT+UGPIOC=16,2") && _at->recv("OK"); |
RobMeades | 0:5cffef3371f6 | 625 | } else { |
RobMeades | 0:5cffef3371f6 | 626 | success = true; |
RobMeades | 0:5cffef3371f6 | 627 | } |
RobMeades | 0:5cffef3371f6 | 628 | |
RobMeades | 0:5cffef3371f6 | 629 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 630 | return success; |
RobMeades | 0:5cffef3371f6 | 631 | } |
RobMeades | 0:5cffef3371f6 | 632 | |
RobMeades | 0:5cffef3371f6 | 633 | // Get the SIM card going. |
RobMeades | 0:5cffef3371f6 | 634 | bool UbloxCellularBase::initialise_sim_card() |
RobMeades | 0:5cffef3371f6 | 635 | { |
RobMeades | 0:5cffef3371f6 | 636 | bool success = false; |
RobMeades | 0:5cffef3371f6 | 637 | int retry_count = 0; |
RobMeades | 0:5cffef3371f6 | 638 | bool done = false; |
RobMeades | 0:5cffef3371f6 | 639 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 640 | |
RobMeades | 0:5cffef3371f6 | 641 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 642 | |
RobMeades | 0:5cffef3371f6 | 643 | /* SIM initialisation may take a significant amount, so an error is |
RobMeades | 0:5cffef3371f6 | 644 | * kind of expected. We should retry 10 times until we succeed or timeout. */ |
RobMeades | 0:5cffef3371f6 | 645 | for (retry_count = 0; !done && (retry_count < 10); retry_count++) { |
RobMeades | 0:5cffef3371f6 | 646 | char pinstr[16]; |
RobMeades | 0:5cffef3371f6 | 647 | |
RobMeades | 0:5cffef3371f6 | 648 | if (_at->send("AT+CPIN?") && _at->recv("+CPIN: %15[^\n]\n", pinstr) && |
RobMeades | 0:5cffef3371f6 | 649 | _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 650 | done = true; |
RobMeades | 0:5cffef3371f6 | 651 | if (strcmp(pinstr, "SIM PIN") == 0) { |
RobMeades | 0:5cffef3371f6 | 652 | _sim_pin_check_enabled = true; |
RobMeades | 0:5cffef3371f6 | 653 | if (_at->send("AT+CPIN=\"%s\"", _pin)) { |
RobMeades | 0:5cffef3371f6 | 654 | if (_at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 655 | tr_info("PIN correct"); |
RobMeades | 0:5cffef3371f6 | 656 | success = true; |
RobMeades | 0:5cffef3371f6 | 657 | } else { |
RobMeades | 0:5cffef3371f6 | 658 | tr_error("Incorrect PIN"); |
RobMeades | 0:5cffef3371f6 | 659 | } |
RobMeades | 0:5cffef3371f6 | 660 | } |
RobMeades | 0:5cffef3371f6 | 661 | } else if (strcmp(pinstr, "READY") == 0) { |
RobMeades | 0:5cffef3371f6 | 662 | _sim_pin_check_enabled = false; |
RobMeades | 0:5cffef3371f6 | 663 | tr_info("No PIN required"); |
RobMeades | 0:5cffef3371f6 | 664 | success = true; |
RobMeades | 0:5cffef3371f6 | 665 | } else { |
RobMeades | 0:5cffef3371f6 | 666 | tr_debug("Unexpected response from SIM: \"%s\"", pinstr); |
RobMeades | 0:5cffef3371f6 | 667 | } |
RobMeades | 0:5cffef3371f6 | 668 | } |
RobMeades | 0:5cffef3371f6 | 669 | |
RobMeades | 0:5cffef3371f6 | 670 | /* wait for a second before retry */ |
RobMeades | 0:5cffef3371f6 | 671 | wait_ms(1000); |
RobMeades | 0:5cffef3371f6 | 672 | } |
RobMeades | 0:5cffef3371f6 | 673 | |
RobMeades | 0:5cffef3371f6 | 674 | if (done) { |
RobMeades | 0:5cffef3371f6 | 675 | tr_info("SIM Ready."); |
RobMeades | 0:5cffef3371f6 | 676 | } else { |
RobMeades | 0:5cffef3371f6 | 677 | tr_error("SIM not ready."); |
RobMeades | 0:5cffef3371f6 | 678 | } |
RobMeades | 0:5cffef3371f6 | 679 | |
RobMeades | 0:5cffef3371f6 | 680 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 681 | return success; |
RobMeades | 0:5cffef3371f6 | 682 | } |
RobMeades | 0:5cffef3371f6 | 683 | |
RobMeades | 0:5cffef3371f6 | 684 | /********************************************************************** |
RobMeades | 0:5cffef3371f6 | 685 | * PUBLIC METHODS |
RobMeades | 0:5cffef3371f6 | 686 | **********************************************************************/ |
RobMeades | 0:5cffef3371f6 | 687 | |
RobMeades | 0:5cffef3371f6 | 688 | // Initialise the modem. |
RobMeades | 0:5cffef3371f6 | 689 | bool UbloxCellularBase::init(const char *pin) |
RobMeades | 0:5cffef3371f6 | 690 | { |
RobMeades | 0:5cffef3371f6 | 691 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 692 | |
RobMeades | 0:5cffef3371f6 | 693 | if (!_modem_initialised) { |
RobMeades | 0:5cffef3371f6 | 694 | if (power_up()) { |
RobMeades | 0:5cffef3371f6 | 695 | tr_info("Modem Ready."); |
RobMeades | 0:5cffef3371f6 | 696 | if (pin != NULL) { |
RobMeades | 0:5cffef3371f6 | 697 | _pin = pin; |
RobMeades | 0:5cffef3371f6 | 698 | } |
RobMeades | 0:5cffef3371f6 | 699 | if (initialise_sim_card()) { |
RobMeades | 0:5cffef3371f6 | 700 | if (set_device_identity(&_dev_info.dev) && // Set up device identity |
RobMeades | 0:5cffef3371f6 | 701 | device_init(_dev_info.dev) && // Initialise this device |
RobMeades | 0:5cffef3371f6 | 702 | get_iccid() && // Get integrated circuit ID of the SIM |
RobMeades | 0:5cffef3371f6 | 703 | get_imsi() && // Get international mobile subscriber information |
RobMeades | 0:5cffef3371f6 | 704 | get_imei() && // Get international mobile equipment identifier |
RobMeades | 0:5cffef3371f6 | 705 | get_meid() && // Probably the same as the IMEI |
RobMeades | 0:5cffef3371f6 | 706 | set_sms()) { |
RobMeades | 0:5cffef3371f6 | 707 | |
RobMeades | 0:5cffef3371f6 | 708 | // The modem is initialised. |
RobMeades | 0:5cffef3371f6 | 709 | _modem_initialised = true; |
RobMeades | 0:5cffef3371f6 | 710 | } |
RobMeades | 0:5cffef3371f6 | 711 | } |
RobMeades | 0:5cffef3371f6 | 712 | } |
RobMeades | 0:5cffef3371f6 | 713 | } |
RobMeades | 0:5cffef3371f6 | 714 | |
RobMeades | 0:5cffef3371f6 | 715 | return _modem_initialised; |
RobMeades | 0:5cffef3371f6 | 716 | } |
RobMeades | 0:5cffef3371f6 | 717 | |
RobMeades | 0:5cffef3371f6 | 718 | // Perform registration. |
RobMeades | 0:5cffef3371f6 | 719 | bool UbloxCellularBase::nwk_registration() |
RobMeades | 0:5cffef3371f6 | 720 | { |
RobMeades | 0:5cffef3371f6 | 721 | bool atSuccess = false; |
RobMeades | 0:5cffef3371f6 | 722 | bool registered = false; |
RobMeades | 0:5cffef3371f6 | 723 | int status; |
RobMeades | 0:5cffef3371f6 | 724 | int at_timeout; |
RobMeades | 0:5cffef3371f6 | 725 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 726 | |
RobMeades | 0:5cffef3371f6 | 727 | at_timeout = _at_timeout; // Has to be inside LOCK()s |
RobMeades | 0:5cffef3371f6 | 728 | |
RobMeades | 0:5cffef3371f6 | 729 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 730 | |
RobMeades | 0:5cffef3371f6 | 731 | if (!is_registered_psd() && !is_registered_csd() && !is_registered_eps()) { |
RobMeades | 0:5cffef3371f6 | 732 | tr_info("Searching Network..."); |
RobMeades | 0:5cffef3371f6 | 733 | // Enable the packet switched and network registration unsolicited result codes |
RobMeades | 0:5cffef3371f6 | 734 | if (_at->send("AT+CREG=1") && _at->recv("OK") && |
RobMeades | 0:5cffef3371f6 | 735 | _at->send("AT+CGREG=1") && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 736 | atSuccess = true; |
RobMeades | 0:5cffef3371f6 | 737 | if (_at->send("AT+CEREG=1")) { |
RobMeades | 0:5cffef3371f6 | 738 | _at->recv("OK"); |
RobMeades | 0:5cffef3371f6 | 739 | // Don't check return value as this works for LTE only |
RobMeades | 0:5cffef3371f6 | 740 | } |
RobMeades | 0:5cffef3371f6 | 741 | |
RobMeades | 0:5cffef3371f6 | 742 | if (atSuccess) { |
RobMeades | 0:5cffef3371f6 | 743 | // See if we are already in automatic mode |
RobMeades | 0:5cffef3371f6 | 744 | if (_at->send("AT+COPS?") && _at->recv("+COPS: %d", &status) && |
RobMeades | 0:5cffef3371f6 | 745 | _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 746 | // If not, set it |
RobMeades | 0:5cffef3371f6 | 747 | if (status != 0) { |
RobMeades | 0:5cffef3371f6 | 748 | // Don't check return code here as there's not much |
RobMeades | 0:5cffef3371f6 | 749 | // we can do if this fails. |
RobMeades | 0:5cffef3371f6 | 750 | _at->send("AT+COPS=0") && _at->recv("OK"); |
RobMeades | 0:5cffef3371f6 | 751 | } |
RobMeades | 0:5cffef3371f6 | 752 | } |
RobMeades | 0:5cffef3371f6 | 753 | |
RobMeades | 0:5cffef3371f6 | 754 | // Query the registration status directly as well, |
RobMeades | 0:5cffef3371f6 | 755 | // just in case |
RobMeades | 0:5cffef3371f6 | 756 | if (_at->send("AT+CREG?") && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 757 | // Answer will be processed by URC |
RobMeades | 0:5cffef3371f6 | 758 | } |
RobMeades | 0:5cffef3371f6 | 759 | if (_at->send("AT+CGREG?") && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 760 | // Answer will be processed by URC |
RobMeades | 0:5cffef3371f6 | 761 | } |
RobMeades | 0:5cffef3371f6 | 762 | if (_at->send("AT+CEREG?")) { |
RobMeades | 0:5cffef3371f6 | 763 | _at->recv("OK"); |
RobMeades | 0:5cffef3371f6 | 764 | // Don't check return value as this works for LTE only |
RobMeades | 0:5cffef3371f6 | 765 | } |
RobMeades | 0:5cffef3371f6 | 766 | } |
RobMeades | 0:5cffef3371f6 | 767 | } |
RobMeades | 0:5cffef3371f6 | 768 | // Wait for registration to succeed |
RobMeades | 0:5cffef3371f6 | 769 | at_set_timeout(1000); |
RobMeades | 0:5cffef3371f6 | 770 | for (int waitSeconds = 0; !registered && (waitSeconds < 180); waitSeconds++) { |
RobMeades | 0:5cffef3371f6 | 771 | registered = is_registered_psd() || is_registered_csd() || is_registered_eps(); |
RobMeades | 0:5cffef3371f6 | 772 | _at->recv(UNNATURAL_STRING); |
RobMeades | 0:5cffef3371f6 | 773 | } |
RobMeades | 0:5cffef3371f6 | 774 | at_set_timeout(at_timeout); |
RobMeades | 0:5cffef3371f6 | 775 | |
RobMeades | 0:5cffef3371f6 | 776 | if (registered) { |
RobMeades | 0:5cffef3371f6 | 777 | // This should return quickly but sometimes the status field is not returned |
RobMeades | 0:5cffef3371f6 | 778 | // so make the timeout short |
RobMeades | 0:5cffef3371f6 | 779 | at_set_timeout(1000); |
RobMeades | 0:5cffef3371f6 | 780 | if (_at->send("AT+COPS?") && _at->recv("+COPS: %*d,%*d,\"%*[^\"]\",%d\n", &status)) { |
RobMeades | 0:5cffef3371f6 | 781 | set_rat(status); |
RobMeades | 0:5cffef3371f6 | 782 | } |
RobMeades | 0:5cffef3371f6 | 783 | at_set_timeout(at_timeout); |
RobMeades | 0:5cffef3371f6 | 784 | } |
RobMeades | 0:5cffef3371f6 | 785 | } else { |
RobMeades | 0:5cffef3371f6 | 786 | registered = true; |
RobMeades | 0:5cffef3371f6 | 787 | } |
RobMeades | 0:5cffef3371f6 | 788 | |
RobMeades | 0:5cffef3371f6 | 789 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 790 | return registered; |
RobMeades | 0:5cffef3371f6 | 791 | } |
RobMeades | 0:5cffef3371f6 | 792 | |
RobMeades | 0:5cffef3371f6 | 793 | bool UbloxCellularBase::is_registered_csd() |
RobMeades | 0:5cffef3371f6 | 794 | { |
RobMeades | 0:5cffef3371f6 | 795 | return (_dev_info.reg_status_csd == CSD_REGISTERED) || |
RobMeades | 0:5cffef3371f6 | 796 | (_dev_info.reg_status_csd == CSD_REGISTERED_ROAMING) || |
RobMeades | 0:5cffef3371f6 | 797 | (_dev_info.reg_status_csd == CSD_CSFB_NOT_PREFERRED); |
RobMeades | 0:5cffef3371f6 | 798 | } |
RobMeades | 0:5cffef3371f6 | 799 | |
RobMeades | 0:5cffef3371f6 | 800 | bool UbloxCellularBase::is_registered_psd() |
RobMeades | 0:5cffef3371f6 | 801 | { |
RobMeades | 0:5cffef3371f6 | 802 | return (_dev_info.reg_status_psd == PSD_REGISTERED) || |
RobMeades | 0:5cffef3371f6 | 803 | (_dev_info.reg_status_psd == PSD_REGISTERED_ROAMING); |
RobMeades | 0:5cffef3371f6 | 804 | } |
RobMeades | 0:5cffef3371f6 | 805 | |
RobMeades | 0:5cffef3371f6 | 806 | bool UbloxCellularBase::is_registered_eps() |
RobMeades | 0:5cffef3371f6 | 807 | { |
RobMeades | 0:5cffef3371f6 | 808 | return (_dev_info.reg_status_eps == EPS_REGISTERED) || |
RobMeades | 0:5cffef3371f6 | 809 | (_dev_info.reg_status_eps == EPS_REGISTERED_ROAMING); |
RobMeades | 0:5cffef3371f6 | 810 | } |
RobMeades | 0:5cffef3371f6 | 811 | |
RobMeades | 0:5cffef3371f6 | 812 | // Perform deregistration. |
RobMeades | 0:5cffef3371f6 | 813 | bool UbloxCellularBase::nwk_deregistration() |
RobMeades | 0:5cffef3371f6 | 814 | { |
RobMeades | 0:5cffef3371f6 | 815 | bool success = false; |
RobMeades | 0:5cffef3371f6 | 816 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 817 | |
RobMeades | 0:5cffef3371f6 | 818 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 819 | |
RobMeades | 0:5cffef3371f6 | 820 | if (_at->send("AT+COPS=2") && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 821 | _dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING; |
RobMeades | 0:5cffef3371f6 | 822 | _dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING; |
RobMeades | 0:5cffef3371f6 | 823 | _dev_info.reg_status_eps = EPS_NOT_REGISTERED_NOT_SEARCHING; |
RobMeades | 0:5cffef3371f6 | 824 | success = true; |
RobMeades | 0:5cffef3371f6 | 825 | } |
RobMeades | 0:5cffef3371f6 | 826 | |
RobMeades | 0:5cffef3371f6 | 827 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 828 | return success; |
RobMeades | 0:5cffef3371f6 | 829 | } |
RobMeades | 0:5cffef3371f6 | 830 | |
RobMeades | 0:5cffef3371f6 | 831 | // Put the modem into its lowest power state. |
RobMeades | 0:5cffef3371f6 | 832 | void UbloxCellularBase::deinit() |
RobMeades | 0:5cffef3371f6 | 833 | { |
RobMeades | 0:5cffef3371f6 | 834 | power_down(); |
RobMeades | 0:5cffef3371f6 | 835 | _modem_initialised = false; |
RobMeades | 0:5cffef3371f6 | 836 | } |
RobMeades | 0:5cffef3371f6 | 837 | |
RobMeades | 0:5cffef3371f6 | 838 | // Set the PIN. |
RobMeades | 0:5cffef3371f6 | 839 | void UbloxCellularBase::set_pin(const char *pin) { |
RobMeades | 0:5cffef3371f6 | 840 | _pin = pin; |
RobMeades | 0:5cffef3371f6 | 841 | } |
RobMeades | 0:5cffef3371f6 | 842 | |
RobMeades | 0:5cffef3371f6 | 843 | // Enable or disable SIM pin checking. |
rob.meades@u-blox.com | 4:2e640a101db1 | 844 | bool UbloxCellularBase::sim_pin_check_enable(bool enableNotDisable) |
RobMeades | 0:5cffef3371f6 | 845 | { |
RobMeades | 0:5cffef3371f6 | 846 | bool success = false;; |
RobMeades | 0:5cffef3371f6 | 847 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 848 | |
RobMeades | 0:5cffef3371f6 | 849 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 850 | |
RobMeades | 0:5cffef3371f6 | 851 | if (_pin != NULL) { |
RobMeades | 0:5cffef3371f6 | 852 | if (_sim_pin_check_enabled && !enableNotDisable) { |
RobMeades | 0:5cffef3371f6 | 853 | // Disable the SIM lock |
RobMeades | 0:5cffef3371f6 | 854 | if (_at->send("AT+CLCK=\"SC\",0,\"%s\"", _pin) && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 855 | _sim_pin_check_enabled = false; |
RobMeades | 0:5cffef3371f6 | 856 | success = true; |
RobMeades | 0:5cffef3371f6 | 857 | } |
RobMeades | 0:5cffef3371f6 | 858 | } else if (!_sim_pin_check_enabled && enableNotDisable) { |
RobMeades | 0:5cffef3371f6 | 859 | // Enable the SIM lock |
RobMeades | 0:5cffef3371f6 | 860 | if (_at->send("AT+CLCK=\"SC\",1,\"%s\"", _pin) && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 861 | _sim_pin_check_enabled = true; |
RobMeades | 0:5cffef3371f6 | 862 | success = true; |
RobMeades | 0:5cffef3371f6 | 863 | } |
RobMeades | 0:5cffef3371f6 | 864 | } else { |
RobMeades | 0:5cffef3371f6 | 865 | success = true; |
RobMeades | 0:5cffef3371f6 | 866 | } |
RobMeades | 0:5cffef3371f6 | 867 | } |
RobMeades | 0:5cffef3371f6 | 868 | |
RobMeades | 0:5cffef3371f6 | 869 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 870 | return success; |
RobMeades | 0:5cffef3371f6 | 871 | } |
RobMeades | 0:5cffef3371f6 | 872 | |
RobMeades | 0:5cffef3371f6 | 873 | // Change the pin code for the SIM card. |
RobMeades | 0:5cffef3371f6 | 874 | bool UbloxCellularBase::change_sim_pin(const char *pin) |
RobMeades | 0:5cffef3371f6 | 875 | { |
RobMeades | 0:5cffef3371f6 | 876 | bool success = false;; |
RobMeades | 0:5cffef3371f6 | 877 | LOCK(); |
RobMeades | 0:5cffef3371f6 | 878 | |
RobMeades | 0:5cffef3371f6 | 879 | MBED_ASSERT(_at != NULL); |
RobMeades | 0:5cffef3371f6 | 880 | |
RobMeades | 0:5cffef3371f6 | 881 | // Change the SIM pin |
RobMeades | 0:5cffef3371f6 | 882 | if ((pin != NULL) && (_pin != NULL)) { |
RobMeades | 0:5cffef3371f6 | 883 | if (_at->send("AT+CPWD=\"SC\",\"%s\",\"%s\"", _pin, pin) && _at->recv("OK")) { |
RobMeades | 0:5cffef3371f6 | 884 | _pin = pin; |
RobMeades | 0:5cffef3371f6 | 885 | success = true; |
RobMeades | 0:5cffef3371f6 | 886 | } |
RobMeades | 0:5cffef3371f6 | 887 | } |
RobMeades | 0:5cffef3371f6 | 888 | |
RobMeades | 0:5cffef3371f6 | 889 | UNLOCK(); |
RobMeades | 0:5cffef3371f6 | 890 | return success; |
RobMeades | 0:5cffef3371f6 | 891 | } |
RobMeades | 0:5cffef3371f6 | 892 | |
RobMeades | 0:5cffef3371f6 | 893 | // End of File |
RobMeades | 0:5cffef3371f6 | 894 |