This class provides SMS, USSD and modem file system support for u-blox modules on the C027 and C030 boards (excepting the C030 N2xx flavour) from mbed 5.5 onwards.

Dependents:   example-ublox-at-cellular-interface-ext example-ublox-cellular-driver-gen HelloMQTT ublox_new_driver_test ... more

Committer:
rob.meades@u-blox.com
Date:
Tue Jun 13 00:29:44 2017 +0100
Revision:
3:027c9eaec52c
Parent:
2:08302b9cd519
Child:
4:4f2c12992e17
Update to work with external libraries, not yet fully working on C027 though, watch this space.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RobMeades 0:bb5fabac67ab 1 /* Copyright (c) 2017 ublox Limited
RobMeades 0:bb5fabac67ab 2 *
RobMeades 0:bb5fabac67ab 3 * Licensed under the Apache License, Version 2.0 (the "License");
RobMeades 0:bb5fabac67ab 4 * you may not use this file except in compliance with the License.
RobMeades 0:bb5fabac67ab 5 * You may obtain a copy of the License at
RobMeades 0:bb5fabac67ab 6 *
RobMeades 0:bb5fabac67ab 7 * http://www.apache.org/licenses/LICENSE-2.0
RobMeades 0:bb5fabac67ab 8 *
RobMeades 0:bb5fabac67ab 9 * Unless required by applicable law or agreed to in writing, software
RobMeades 0:bb5fabac67ab 10 * distributed under the License is distributed on an "AS IS" BASIS,
RobMeades 0:bb5fabac67ab 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
RobMeades 0:bb5fabac67ab 12 * See the License for the specific language governing permissions and
RobMeades 0:bb5fabac67ab 13 * limitations under the License.
RobMeades 0:bb5fabac67ab 14 */
RobMeades 0:bb5fabac67ab 15
RobMeades 0:bb5fabac67ab 16 #include "UbloxCellularDriverGen.h"
RobMeades 0:bb5fabac67ab 17 #include "string.h"
RobMeades 0:bb5fabac67ab 18 #if defined(FEATURE_COMMON_PAL)
RobMeades 0:bb5fabac67ab 19 #include "mbed_trace.h"
RobMeades 0:bb5fabac67ab 20 #define TRACE_GROUP "UCID"
RobMeades 0:bb5fabac67ab 21 #else
RobMeades 0:bb5fabac67ab 22 #define debug_if(_debug_trace_on, ...) (void(0)) // dummies if feature common pal is not added
RobMeades 0:bb5fabac67ab 23 #define tr_info(...) (void(0)) // dummies if feature common pal is not added
RobMeades 0:bb5fabac67ab 24 #define tr_error(...) (void(0)) // dummies if feature common pal is not added
RobMeades 0:bb5fabac67ab 25 #endif
RobMeades 0:bb5fabac67ab 26
RobMeades 0:bb5fabac67ab 27 /**********************************************************************
RobMeades 0:bb5fabac67ab 28 * PROTECTED METHODS: Short Message Service
RobMeades 0:bb5fabac67ab 29 **********************************************************************/
RobMeades 0:bb5fabac67ab 30
RobMeades 0:bb5fabac67ab 31 // URC for Short Message listing.
RobMeades 0:bb5fabac67ab 32 void UbloxCellularDriverGen::CMGL_URC()
RobMeades 0:bb5fabac67ab 33 {
RobMeades 0:bb5fabac67ab 34 char buf[64];
RobMeades 0:bb5fabac67ab 35 int index;
RobMeades 0:bb5fabac67ab 36
RobMeades 0:bb5fabac67ab 37 // Note: not calling _at->recv() from here as we're
RobMeades 0:bb5fabac67ab 38 // already in an _at->recv()
RobMeades 0:bb5fabac67ab 39 // +CMGL: <ix>,...
RobMeades 0:bb5fabac67ab 40 *buf = 0;
RobMeades 0:bb5fabac67ab 41 if (read_at_to_char(buf, sizeof(buf), '\n') > 0) {
RobMeades 0:bb5fabac67ab 42 // Now also read out the text message, so that we don't
RobMeades 0:bb5fabac67ab 43 // accidentally trigger URCs or the like on any of
RobMeades 0:bb5fabac67ab 44 // its contents
RobMeades 0:bb5fabac67ab 45 *_smsBuf = 0;
RobMeades 0:bb5fabac67ab 46 read_at_to_char(_smsBuf, sizeof(_smsBuf), '\n');
RobMeades 0:bb5fabac67ab 47 // Note: don't put any debug in here, this URC is being
RobMeades 0:bb5fabac67ab 48 // called multiple times and debug may cause it to
RobMeades 0:bb5fabac67ab 49 // miss characters
RobMeades 0:bb5fabac67ab 50 if (sscanf(buf, ": %d,", &index) == 1) {
RobMeades 0:bb5fabac67ab 51 _smsCount++;
RobMeades 0:bb5fabac67ab 52 if ((_userSmsIndex != NULL) && (_userSmsNum > 0)) {
RobMeades 0:bb5fabac67ab 53 *_userSmsIndex = index;
RobMeades 0:bb5fabac67ab 54 _userSmsIndex++;
RobMeades 0:bb5fabac67ab 55 _userSmsNum--;
RobMeades 0:bb5fabac67ab 56 }
RobMeades 0:bb5fabac67ab 57 }
RobMeades 0:bb5fabac67ab 58 }
RobMeades 0:bb5fabac67ab 59 }
RobMeades 0:bb5fabac67ab 60
RobMeades 0:bb5fabac67ab 61 // URC for new SMS messages.
RobMeades 0:bb5fabac67ab 62 void UbloxCellularDriverGen::CMTI_URC()
RobMeades 0:bb5fabac67ab 63 {
RobMeades 0:bb5fabac67ab 64 char buf[32];
RobMeades 0:bb5fabac67ab 65
RobMeades 0:bb5fabac67ab 66 // Note: not calling _at->recv() from here as we're
RobMeades 0:bb5fabac67ab 67 // already in an _at->recv()
RobMeades 0:bb5fabac67ab 68 *buf = 0;
RobMeades 0:bb5fabac67ab 69 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 0:bb5fabac67ab 70 // No need to parse, any content is good
RobMeades 0:bb5fabac67ab 71 tr_info("New SMS received");
RobMeades 0:bb5fabac67ab 72 }
RobMeades 0:bb5fabac67ab 73 }
RobMeades 0:bb5fabac67ab 74
RobMeades 0:bb5fabac67ab 75 /**********************************************************************
RobMeades 0:bb5fabac67ab 76 * PROTECTED METHODS: Unstructured Supplementary Service Data
RobMeades 0:bb5fabac67ab 77 **********************************************************************/
RobMeades 0:bb5fabac67ab 78
RobMeades 0:bb5fabac67ab 79 // URC for call waiting.
RobMeades 0:bb5fabac67ab 80 void UbloxCellularDriverGen::CCWA_URC()
RobMeades 0:bb5fabac67ab 81 {
RobMeades 0:bb5fabac67ab 82 char buf[32];
RobMeades 0:bb5fabac67ab 83 int numChars;
RobMeades 0:bb5fabac67ab 84 int a;
RobMeades 0:bb5fabac67ab 85 int b = 0;
RobMeades 0:bb5fabac67ab 86
RobMeades 0:bb5fabac67ab 87 // Note: not calling _at->recv() from here as we're
RobMeades 0:bb5fabac67ab 88 // already in an _at->recv()
RobMeades 0:bb5fabac67ab 89 // +CCWA: <status>[, <class>]
RobMeades 0:bb5fabac67ab 90 numChars = read_at_to_char(buf, sizeof (buf), '\n');
RobMeades 0:bb5fabac67ab 91 if (numChars > 0) {
RobMeades 0:bb5fabac67ab 92 if (sscanf(buf, ": %d, %d", &a, &b) > 0) {
RobMeades 0:bb5fabac67ab 93 if (_ssUrcBuf == NULL) {
RobMeades 0:bb5fabac67ab 94 _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
RobMeades 0:bb5fabac67ab 95 if (_ssUrcBuf != NULL) {
RobMeades 0:bb5fabac67ab 96 memcpy (_ssUrcBuf, "+CCWA", 5);
RobMeades 0:bb5fabac67ab 97 memcpy (_ssUrcBuf + 5, buf, numChars);
RobMeades 0:bb5fabac67ab 98 *(_ssUrcBuf + numChars + 5) = 0;
RobMeades 0:bb5fabac67ab 99 if (a > 0) {
RobMeades 0:bb5fabac67ab 100 debug_if(_debug_trace_on, "Calling Waiting is active");
RobMeades 0:bb5fabac67ab 101 } else {
RobMeades 0:bb5fabac67ab 102 debug_if(_debug_trace_on, "Calling Waiting is not active");
RobMeades 0:bb5fabac67ab 103 }
RobMeades 0:bb5fabac67ab 104 if (b > 0) {
RobMeades 0:bb5fabac67ab 105 if (b & 0x01) {
RobMeades 0:bb5fabac67ab 106 debug_if(_debug_trace_on, " for voice\n");
RobMeades 0:bb5fabac67ab 107 }
RobMeades 0:bb5fabac67ab 108 if (b & 0x02) {
RobMeades 0:bb5fabac67ab 109 debug_if(_debug_trace_on, " for data\n");
RobMeades 0:bb5fabac67ab 110 }
RobMeades 0:bb5fabac67ab 111 if (b & 0x04) {
RobMeades 0:bb5fabac67ab 112 debug_if(_debug_trace_on, " for fax\n");
RobMeades 0:bb5fabac67ab 113 }
RobMeades 0:bb5fabac67ab 114 if (b & 0x08) {
RobMeades 0:bb5fabac67ab 115 debug_if(_debug_trace_on, " for SMS\n");
RobMeades 0:bb5fabac67ab 116 }
RobMeades 0:bb5fabac67ab 117 if (b & 0x10) {
RobMeades 0:bb5fabac67ab 118 debug_if(_debug_trace_on, " for data circuit sync\n");
RobMeades 0:bb5fabac67ab 119 }
RobMeades 0:bb5fabac67ab 120 if (b & 0x20) {
RobMeades 0:bb5fabac67ab 121 debug_if(_debug_trace_on, " for data circuit async\n");
RobMeades 0:bb5fabac67ab 122 }
RobMeades 0:bb5fabac67ab 123 if (b & 0x40) {
RobMeades 0:bb5fabac67ab 124 debug_if(_debug_trace_on, " for dedicated packet access\n");
RobMeades 0:bb5fabac67ab 125 }
RobMeades 0:bb5fabac67ab 126 if (b & 0x80) {
RobMeades 0:bb5fabac67ab 127 debug_if(_debug_trace_on, " for dedicated PAD access\n");
RobMeades 0:bb5fabac67ab 128 }
RobMeades 0:bb5fabac67ab 129 }
RobMeades 0:bb5fabac67ab 130 }
RobMeades 0:bb5fabac67ab 131 }
RobMeades 0:bb5fabac67ab 132 }
RobMeades 0:bb5fabac67ab 133 }
RobMeades 0:bb5fabac67ab 134 }
RobMeades 0:bb5fabac67ab 135
RobMeades 0:bb5fabac67ab 136 // URC for call forwarding.
RobMeades 0:bb5fabac67ab 137 void UbloxCellularDriverGen::CCFC_URC()
RobMeades 0:bb5fabac67ab 138 {
RobMeades 0:bb5fabac67ab 139 char buf[32];
RobMeades 0:bb5fabac67ab 140 int numChars;
RobMeades 0:bb5fabac67ab 141 char num[32];
RobMeades 0:bb5fabac67ab 142 int a, b;
RobMeades 0:bb5fabac67ab 143 int numValues;
RobMeades 0:bb5fabac67ab 144
RobMeades 0:bb5fabac67ab 145 // Note: not calling _at->recv() from here as we're
RobMeades 0:bb5fabac67ab 146 // already in an _at->recv()
RobMeades 0:bb5fabac67ab 147 // +CCFC: <status>[, <class>]
RobMeades 0:bb5fabac67ab 148 numChars = read_at_to_char(buf, sizeof (buf), '\n');
RobMeades 0:bb5fabac67ab 149 if (numChars > 0) {
RobMeades 0:bb5fabac67ab 150 memset (num, 0, sizeof (num));
RobMeades 0:bb5fabac67ab 151 numValues = sscanf(buf, ": %d,%d,\"%32[^\"][\"]", &a, &b, num);
RobMeades 0:bb5fabac67ab 152 if (numValues > 0) {
RobMeades 0:bb5fabac67ab 153 if (_ssUrcBuf == NULL) {
RobMeades 0:bb5fabac67ab 154 _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
RobMeades 0:bb5fabac67ab 155 if (_ssUrcBuf != NULL) {
RobMeades 0:bb5fabac67ab 156 memcpy (_ssUrcBuf, "+CCFC", 5);
RobMeades 0:bb5fabac67ab 157 memcpy (_ssUrcBuf + 5, buf, numChars);
RobMeades 0:bb5fabac67ab 158 *(_ssUrcBuf + numChars + 5) = 0;
RobMeades 0:bb5fabac67ab 159 if (a > 0) {
RobMeades 0:bb5fabac67ab 160 debug_if(_debug_trace_on, "Calling Forwarding is active ");
RobMeades 0:bb5fabac67ab 161 } else {
RobMeades 0:bb5fabac67ab 162 debug_if(_debug_trace_on, "Calling Forwarding is not active ");
RobMeades 0:bb5fabac67ab 163 }
RobMeades 0:bb5fabac67ab 164 if (numValues > 1) {
RobMeades 0:bb5fabac67ab 165 if (b > 0) {
RobMeades 0:bb5fabac67ab 166 if (b & 0x01) {
RobMeades 0:bb5fabac67ab 167 debug_if(_debug_trace_on, " for voice");
RobMeades 0:bb5fabac67ab 168 }
RobMeades 0:bb5fabac67ab 169 if (b & 0x02) {
RobMeades 0:bb5fabac67ab 170 debug_if(_debug_trace_on, " for data");
RobMeades 0:bb5fabac67ab 171 }
RobMeades 0:bb5fabac67ab 172 if (b & 0x04) {
RobMeades 0:bb5fabac67ab 173 debug_if(_debug_trace_on, " for fax");
RobMeades 0:bb5fabac67ab 174 }
RobMeades 0:bb5fabac67ab 175 if (b & 0x08) {
RobMeades 0:bb5fabac67ab 176 debug_if(_debug_trace_on, " for SMS");
RobMeades 0:bb5fabac67ab 177 }
RobMeades 0:bb5fabac67ab 178 if (b & 0x10) {
RobMeades 0:bb5fabac67ab 179 debug_if(_debug_trace_on, " for data circuit sync");
RobMeades 0:bb5fabac67ab 180 }
RobMeades 0:bb5fabac67ab 181 if (b & 0x20) {
RobMeades 0:bb5fabac67ab 182 debug_if(_debug_trace_on, " for data circuit async");
RobMeades 0:bb5fabac67ab 183 }
RobMeades 0:bb5fabac67ab 184 if (b & 0x40) {
RobMeades 0:bb5fabac67ab 185 debug_if(_debug_trace_on, " for dedicated packet access");
RobMeades 0:bb5fabac67ab 186 }
RobMeades 0:bb5fabac67ab 187 if (b & 0x80) {
RobMeades 0:bb5fabac67ab 188 debug_if(_debug_trace_on, " for dedicated PAD access");
RobMeades 0:bb5fabac67ab 189 }
RobMeades 0:bb5fabac67ab 190 }
RobMeades 0:bb5fabac67ab 191 }
RobMeades 0:bb5fabac67ab 192 if (numValues > 2) {
RobMeades 0:bb5fabac67ab 193 debug_if(_debug_trace_on, " for %s\n", num);
RobMeades 0:bb5fabac67ab 194 } else {
RobMeades 0:bb5fabac67ab 195 debug_if(_debug_trace_on, "\n");
RobMeades 0:bb5fabac67ab 196 }
RobMeades 0:bb5fabac67ab 197 }
RobMeades 0:bb5fabac67ab 198 }
RobMeades 0:bb5fabac67ab 199 }
RobMeades 0:bb5fabac67ab 200 }
RobMeades 0:bb5fabac67ab 201 }
RobMeades 0:bb5fabac67ab 202
RobMeades 0:bb5fabac67ab 203
RobMeades 0:bb5fabac67ab 204 // URC for calling line ID restriction.
RobMeades 0:bb5fabac67ab 205 void UbloxCellularDriverGen::CLIR_URC()
RobMeades 0:bb5fabac67ab 206 {
RobMeades 0:bb5fabac67ab 207 char buf[32];
RobMeades 0:bb5fabac67ab 208 int numChars;
RobMeades 0:bb5fabac67ab 209 int a, b;
RobMeades 0:bb5fabac67ab 210 int numValues;
RobMeades 0:bb5fabac67ab 211
RobMeades 0:bb5fabac67ab 212 // Note: not calling _at->recv() from here as we're
RobMeades 0:bb5fabac67ab 213 // already in an _at->recv()
RobMeades 0:bb5fabac67ab 214 // +CLIR: <n>[, <m>]
RobMeades 0:bb5fabac67ab 215 numChars = read_at_to_char(buf, sizeof (buf), '\n');
RobMeades 0:bb5fabac67ab 216 if (numChars > 0) {
RobMeades 0:bb5fabac67ab 217 numValues = sscanf(buf, ": %d,%d", &a, &b);
RobMeades 0:bb5fabac67ab 218 if (numValues > 0) {
RobMeades 0:bb5fabac67ab 219 if (_ssUrcBuf == NULL) {
RobMeades 0:bb5fabac67ab 220 _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
RobMeades 0:bb5fabac67ab 221 if (_ssUrcBuf != NULL) {
RobMeades 0:bb5fabac67ab 222 memcpy (_ssUrcBuf, "+CLIR", 5);
RobMeades 0:bb5fabac67ab 223 memcpy (_ssUrcBuf + 5, buf, numChars);
RobMeades 0:bb5fabac67ab 224 *(_ssUrcBuf + numChars + 5) = 0;
RobMeades 0:bb5fabac67ab 225 switch (a) {
RobMeades 0:bb5fabac67ab 226 case 0:
RobMeades 0:bb5fabac67ab 227 debug_if(_debug_trace_on, "Calling Line ID restriction is as subscribed\n");
RobMeades 0:bb5fabac67ab 228 break;
RobMeades 0:bb5fabac67ab 229 case 1:
RobMeades 0:bb5fabac67ab 230 debug_if(_debug_trace_on, "Calling Line ID invocation ");
RobMeades 0:bb5fabac67ab 231 break;
RobMeades 0:bb5fabac67ab 232 case 2:
RobMeades 0:bb5fabac67ab 233 debug_if(_debug_trace_on, "Calling Line ID suppression ");
RobMeades 0:bb5fabac67ab 234 break;
RobMeades 0:bb5fabac67ab 235 }
RobMeades 0:bb5fabac67ab 236 if (numValues > 2) {
RobMeades 0:bb5fabac67ab 237 switch (b) {
RobMeades 0:bb5fabac67ab 238 case 0:
RobMeades 0:bb5fabac67ab 239 debug_if(_debug_trace_on, " is not provisioned\n");
RobMeades 0:bb5fabac67ab 240 break;
RobMeades 0:bb5fabac67ab 241 case 1:
RobMeades 0:bb5fabac67ab 242 debug_if(_debug_trace_on, " is provisioned permanently\n");
RobMeades 0:bb5fabac67ab 243 break;
RobMeades 0:bb5fabac67ab 244 case 2:
RobMeades 0:bb5fabac67ab 245 debug_if(_debug_trace_on, " is unknown\n");
RobMeades 0:bb5fabac67ab 246 break;
RobMeades 0:bb5fabac67ab 247 case 3:
RobMeades 0:bb5fabac67ab 248 debug_if(_debug_trace_on, " is in temporary mode, presentation restricted\n");
RobMeades 0:bb5fabac67ab 249 break;
RobMeades 0:bb5fabac67ab 250 case 4:
RobMeades 0:bb5fabac67ab 251 debug_if(_debug_trace_on, " is in temporary mode, presentation allowed\n");
RobMeades 0:bb5fabac67ab 252 break;
RobMeades 0:bb5fabac67ab 253 }
RobMeades 0:bb5fabac67ab 254 }
RobMeades 0:bb5fabac67ab 255 }
RobMeades 0:bb5fabac67ab 256 }
RobMeades 0:bb5fabac67ab 257 }
RobMeades 0:bb5fabac67ab 258 }
RobMeades 0:bb5fabac67ab 259 }
RobMeades 0:bb5fabac67ab 260
RobMeades 0:bb5fabac67ab 261 // URC for calling line ID presentation.
RobMeades 0:bb5fabac67ab 262 void UbloxCellularDriverGen::CLIP_URC()
RobMeades 0:bb5fabac67ab 263 {
RobMeades 0:bb5fabac67ab 264 char buf[32];
RobMeades 0:bb5fabac67ab 265 int numChars;
RobMeades 0:bb5fabac67ab 266 int a, b;
RobMeades 0:bb5fabac67ab 267 int numValues;
RobMeades 0:bb5fabac67ab 268
RobMeades 0:bb5fabac67ab 269 // Note: not calling _at->recv() from here as we're
RobMeades 0:bb5fabac67ab 270 // already in an _at->recv()
RobMeades 0:bb5fabac67ab 271 // +CLIP: <n>[, <m>]
RobMeades 0:bb5fabac67ab 272 numChars = read_at_to_char(buf, sizeof (buf), '\n');
RobMeades 0:bb5fabac67ab 273 if (numChars > 0) {
RobMeades 0:bb5fabac67ab 274 numValues = sscanf(buf, ": %d,%d", &a, &b);
RobMeades 0:bb5fabac67ab 275 if (numValues > 0) {
RobMeades 0:bb5fabac67ab 276 if (_ssUrcBuf == NULL) {
RobMeades 0:bb5fabac67ab 277 _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
RobMeades 0:bb5fabac67ab 278 if (_ssUrcBuf != NULL) {
RobMeades 0:bb5fabac67ab 279 memcpy (_ssUrcBuf, "+CLIP", 5);
RobMeades 0:bb5fabac67ab 280 memcpy (_ssUrcBuf + 5, buf, numChars);
RobMeades 0:bb5fabac67ab 281 *(_ssUrcBuf + numChars + 5) = 0;
RobMeades 0:bb5fabac67ab 282 switch (a) {
RobMeades 0:bb5fabac67ab 283 case 0:
RobMeades 0:bb5fabac67ab 284 debug_if(_debug_trace_on, "Calling Line ID disable ");
RobMeades 0:bb5fabac67ab 285 break;
RobMeades 0:bb5fabac67ab 286 case 1:
RobMeades 0:bb5fabac67ab 287 debug_if(_debug_trace_on, "Calling Line ID enable ");
RobMeades 0:bb5fabac67ab 288 break;
RobMeades 0:bb5fabac67ab 289 }
RobMeades 0:bb5fabac67ab 290 if (numValues > 1) {
RobMeades 0:bb5fabac67ab 291 switch (b) {
RobMeades 0:bb5fabac67ab 292 case 0:
RobMeades 0:bb5fabac67ab 293 debug_if(_debug_trace_on, " is not provisioned\n");
RobMeades 0:bb5fabac67ab 294 break;
RobMeades 0:bb5fabac67ab 295 case 1:
RobMeades 0:bb5fabac67ab 296 debug_if(_debug_trace_on, " is provisioned\n");
RobMeades 0:bb5fabac67ab 297 break;
RobMeades 0:bb5fabac67ab 298 case 2:
RobMeades 0:bb5fabac67ab 299 debug_if(_debug_trace_on, " is unknown\n");
RobMeades 0:bb5fabac67ab 300 break;
RobMeades 0:bb5fabac67ab 301 }
RobMeades 0:bb5fabac67ab 302 }
RobMeades 0:bb5fabac67ab 303 }
RobMeades 0:bb5fabac67ab 304 }
RobMeades 0:bb5fabac67ab 305 }
RobMeades 0:bb5fabac67ab 306 }
RobMeades 0:bb5fabac67ab 307 }
RobMeades 0:bb5fabac67ab 308
RobMeades 0:bb5fabac67ab 309 // URC for connected line ID presentation.
RobMeades 0:bb5fabac67ab 310 void UbloxCellularDriverGen::COLP_URC()
RobMeades 0:bb5fabac67ab 311 {
RobMeades 0:bb5fabac67ab 312 char buf[32];
RobMeades 0:bb5fabac67ab 313 int numChars;
RobMeades 0:bb5fabac67ab 314 int a, b;
RobMeades 0:bb5fabac67ab 315 int numValues;
RobMeades 0:bb5fabac67ab 316
RobMeades 0:bb5fabac67ab 317 // Note: not calling _at->recv() from here as we're
RobMeades 0:bb5fabac67ab 318 // already in an _at->recv()
RobMeades 0:bb5fabac67ab 319 // +COLP: <n>[, <m>]
RobMeades 0:bb5fabac67ab 320 numChars = read_at_to_char(buf, sizeof (buf), '\n');
RobMeades 0:bb5fabac67ab 321 if (numChars > 0) {
RobMeades 0:bb5fabac67ab 322 numValues = sscanf(buf, ": %d,%d", &a, &b);
RobMeades 0:bb5fabac67ab 323 if (numValues > 0) {
RobMeades 0:bb5fabac67ab 324 if (_ssUrcBuf == NULL) {
RobMeades 0:bb5fabac67ab 325 _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
RobMeades 0:bb5fabac67ab 326 if (_ssUrcBuf != NULL) {
RobMeades 0:bb5fabac67ab 327 memcpy (_ssUrcBuf, "+COLP", 5);
RobMeades 0:bb5fabac67ab 328 memcpy (_ssUrcBuf + 5, buf, numChars);
RobMeades 0:bb5fabac67ab 329 *(_ssUrcBuf + numChars + 5) = 0;
RobMeades 0:bb5fabac67ab 330 switch (a) {
RobMeades 0:bb5fabac67ab 331 case 0:
RobMeades 0:bb5fabac67ab 332 debug_if(_debug_trace_on, "Connected Line ID disable ");
RobMeades 0:bb5fabac67ab 333 break;
RobMeades 0:bb5fabac67ab 334 case 1:
RobMeades 0:bb5fabac67ab 335 debug_if(_debug_trace_on, "Connected Line ID enable ");
RobMeades 0:bb5fabac67ab 336 break;
RobMeades 0:bb5fabac67ab 337 }
RobMeades 0:bb5fabac67ab 338 if (numValues > 1) {
RobMeades 0:bb5fabac67ab 339 switch (b) {
RobMeades 0:bb5fabac67ab 340 case 0:
RobMeades 0:bb5fabac67ab 341 debug_if(_debug_trace_on, " is not provisioned\n");
RobMeades 0:bb5fabac67ab 342 break;
RobMeades 0:bb5fabac67ab 343 case 1:
RobMeades 0:bb5fabac67ab 344 debug_if(_debug_trace_on, " is provisioned\n");
RobMeades 0:bb5fabac67ab 345 break;
RobMeades 0:bb5fabac67ab 346 case 2:
RobMeades 0:bb5fabac67ab 347 debug_if(_debug_trace_on, " is unknown\n");
RobMeades 0:bb5fabac67ab 348 break;
RobMeades 0:bb5fabac67ab 349 }
RobMeades 0:bb5fabac67ab 350 }
RobMeades 0:bb5fabac67ab 351 }
RobMeades 0:bb5fabac67ab 352 }
RobMeades 0:bb5fabac67ab 353 }
RobMeades 0:bb5fabac67ab 354 }
RobMeades 0:bb5fabac67ab 355 }
RobMeades 0:bb5fabac67ab 356
RobMeades 0:bb5fabac67ab 357 // URC for connected line ID restriction.
RobMeades 0:bb5fabac67ab 358 void UbloxCellularDriverGen::COLR_URC()
RobMeades 0:bb5fabac67ab 359 {
RobMeades 0:bb5fabac67ab 360 char buf[32];
RobMeades 0:bb5fabac67ab 361 int numChars;
RobMeades 0:bb5fabac67ab 362 int a;
RobMeades 0:bb5fabac67ab 363
RobMeades 0:bb5fabac67ab 364 // Note: not calling _at->recv() from here as we're
RobMeades 0:bb5fabac67ab 365 // already in an _at->recv()
RobMeades 0:bb5fabac67ab 366 // +COLR: <status>
RobMeades 0:bb5fabac67ab 367 numChars = read_at_to_char(buf, sizeof (buf), '\n');
RobMeades 0:bb5fabac67ab 368 if (numChars > 0) {
RobMeades 0:bb5fabac67ab 369 if (sscanf(buf, ": %d", &a) > 0) {
RobMeades 0:bb5fabac67ab 370 if (_ssUrcBuf == NULL) {
RobMeades 0:bb5fabac67ab 371 _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
RobMeades 0:bb5fabac67ab 372 if (_ssUrcBuf != NULL) {
RobMeades 0:bb5fabac67ab 373 memcpy (_ssUrcBuf, "+COLR", 5);
RobMeades 0:bb5fabac67ab 374 memcpy (_ssUrcBuf + 5, buf, numChars);
RobMeades 0:bb5fabac67ab 375 *(_ssUrcBuf + numChars + 5) = 0;
RobMeades 0:bb5fabac67ab 376 switch (a) {
RobMeades 0:bb5fabac67ab 377 case 0:
RobMeades 0:bb5fabac67ab 378 debug_if(_debug_trace_on, "Connected Line ID restriction is not provisioned\n");
RobMeades 0:bb5fabac67ab 379 break;
RobMeades 0:bb5fabac67ab 380 case 1:
RobMeades 0:bb5fabac67ab 381 debug_if(_debug_trace_on, "Connected Line ID restriction is provisioned\n");
RobMeades 0:bb5fabac67ab 382 break;
RobMeades 0:bb5fabac67ab 383 case 2:
RobMeades 0:bb5fabac67ab 384 debug_if(_debug_trace_on, "Connected Line ID restriction is unknown\n");
RobMeades 0:bb5fabac67ab 385 break;
RobMeades 0:bb5fabac67ab 386 }
RobMeades 0:bb5fabac67ab 387 }
RobMeades 0:bb5fabac67ab 388 }
RobMeades 0:bb5fabac67ab 389 }
RobMeades 0:bb5fabac67ab 390 }
RobMeades 0:bb5fabac67ab 391 }
RobMeades 0:bb5fabac67ab 392
RobMeades 0:bb5fabac67ab 393 /**********************************************************************
RobMeades 0:bb5fabac67ab 394 * PUBLIC METHODS: Generic
RobMeades 0:bb5fabac67ab 395 **********************************************************************/
RobMeades 0:bb5fabac67ab 396
RobMeades 0:bb5fabac67ab 397 // Constructor.
RobMeades 0:bb5fabac67ab 398 UbloxCellularDriverGen::UbloxCellularDriverGen(PinName tx, PinName rx,
RobMeades 0:bb5fabac67ab 399 int baud, bool debug_on)
RobMeades 0:bb5fabac67ab 400 {
RobMeades 0:bb5fabac67ab 401 _userSmsIndex = NULL;
RobMeades 0:bb5fabac67ab 402 _userSmsNum = 0;
RobMeades 0:bb5fabac67ab 403 _smsCount = 0;
RobMeades 0:bb5fabac67ab 404 _ssUrcBuf = NULL;
RobMeades 0:bb5fabac67ab 405
RobMeades 0:bb5fabac67ab 406 // Initialise the base class, which starts the AT parser
RobMeades 0:bb5fabac67ab 407 baseClassInit(tx, rx, baud, debug_on);
RobMeades 0:bb5fabac67ab 408
RobMeades 0:bb5fabac67ab 409 // URCs related to SMS
RobMeades 0:bb5fabac67ab 410 _at->oob("+CMGL", callback(this, &UbloxCellularDriverGen::CMGL_URC));
RobMeades 0:bb5fabac67ab 411 // Include the colon with this one as otherwise it could be found
RobMeades 0:bb5fabac67ab 412 // by +CMT, should it ever occur
RobMeades 0:bb5fabac67ab 413 _at->oob("+CMTI:", callback(this, &UbloxCellularDriverGen::CMTI_URC));
RobMeades 0:bb5fabac67ab 414
RobMeades 0:bb5fabac67ab 415 // URCs relater to supplementary services
RobMeades 0:bb5fabac67ab 416 _at->oob("+CCWA", callback(this, &UbloxCellularDriverGen::CCWA_URC));
RobMeades 0:bb5fabac67ab 417 _at->oob("+CCFC", callback(this, &UbloxCellularDriverGen::CCFC_URC));
RobMeades 0:bb5fabac67ab 418 _at->oob("+CLIR", callback(this, &UbloxCellularDriverGen::CLIR_URC));
RobMeades 0:bb5fabac67ab 419 _at->oob("+CLIP", callback(this, &UbloxCellularDriverGen::CLIP_URC));
RobMeades 0:bb5fabac67ab 420 _at->oob("+COLP", callback(this, &UbloxCellularDriverGen::COLP_URC));
RobMeades 0:bb5fabac67ab 421 _at->oob("+COLR", callback(this, &UbloxCellularDriverGen::COLR_URC));
RobMeades 0:bb5fabac67ab 422 }
RobMeades 0:bb5fabac67ab 423
RobMeades 0:bb5fabac67ab 424 // Destructor.
RobMeades 0:bb5fabac67ab 425 UbloxCellularDriverGen::~UbloxCellularDriverGen()
RobMeades 0:bb5fabac67ab 426 {
RobMeades 0:bb5fabac67ab 427 }
RobMeades 0:bb5fabac67ab 428
RobMeades 0:bb5fabac67ab 429 /**********************************************************************
RobMeades 0:bb5fabac67ab 430 * PUBLIC METHODS: Short Message Service
RobMeades 0:bb5fabac67ab 431 **********************************************************************/
RobMeades 0:bb5fabac67ab 432
RobMeades 0:bb5fabac67ab 433 // Count the number of messages on the module.
RobMeades 0:bb5fabac67ab 434 int UbloxCellularDriverGen::smsList(const char* stat, int* index, int num)
RobMeades 0:bb5fabac67ab 435 {
RobMeades 0:bb5fabac67ab 436 int numMessages = -1;
RobMeades 0:bb5fabac67ab 437 LOCK();
RobMeades 0:bb5fabac67ab 438
RobMeades 0:bb5fabac67ab 439 _userSmsIndex = index;
RobMeades 0:bb5fabac67ab 440 _userSmsNum = num;
RobMeades 0:bb5fabac67ab 441 _smsCount = 0;
RobMeades 0:bb5fabac67ab 442 // There is a callback to capture the result
RobMeades 0:bb5fabac67ab 443 // +CMGL: <ix>,...
RobMeades 0:bb5fabac67ab 444 _at->debug_on(false); // No time for AT interface debug
RobMeades 0:bb5fabac67ab 445 // as the list comes out in one long
RobMeades 0:bb5fabac67ab 446 // stream and we can lose characters if we
RobMeades 0:bb5fabac67ab 447 // pause to do printfs
RobMeades 0:bb5fabac67ab 448 if (_at->send("AT+CMGL=\"%s\"", stat) && _at->recv("OK\n")) {
RobMeades 0:bb5fabac67ab 449 numMessages = _smsCount;
RobMeades 0:bb5fabac67ab 450 }
RobMeades 0:bb5fabac67ab 451 _at->debug_on(_debug_trace_on);
RobMeades 0:bb5fabac67ab 452
RobMeades 0:bb5fabac67ab 453 // Set this back to null so that the URC won't trample
RobMeades 0:bb5fabac67ab 454 _userSmsIndex = NULL;
RobMeades 0:bb5fabac67ab 455
RobMeades 0:bb5fabac67ab 456 UNLOCK();
RobMeades 0:bb5fabac67ab 457 return numMessages;
RobMeades 0:bb5fabac67ab 458 }
RobMeades 0:bb5fabac67ab 459
RobMeades 0:bb5fabac67ab 460 // Send an SMS message.
RobMeades 0:bb5fabac67ab 461 bool UbloxCellularDriverGen::smsSend(const char* num, const char* buf)
RobMeades 0:bb5fabac67ab 462 {
RobMeades 0:bb5fabac67ab 463 bool success = false;
RobMeades 0:bb5fabac67ab 464 char typeOfAddress = TYPE_OF_ADDRESS_NATIONAL;
RobMeades 0:bb5fabac67ab 465 LOCK();
RobMeades 0:bb5fabac67ab 466
RobMeades 0:bb5fabac67ab 467 if ((strlen (num) > 0) && (*(num) == '+')) {
RobMeades 0:bb5fabac67ab 468 typeOfAddress = TYPE_OF_ADDRESS_INTERNATIONAL;
RobMeades 0:bb5fabac67ab 469 }
RobMeades 0:bb5fabac67ab 470 if (_at->send("AT+CMGS=\"%s\",%d", num, typeOfAddress) && _at->recv(">")) {
RobMeades 0:bb5fabac67ab 471 if ((_at->write(buf, (int) strlen(buf)) >= (int) strlen(buf)) &&
RobMeades 0:bb5fabac67ab 472 (_at->putc(0x1A) == 0) && // CTRL-Z
RobMeades 0:bb5fabac67ab 473 _at->recv("OK")) {
RobMeades 0:bb5fabac67ab 474 success = true;
RobMeades 0:bb5fabac67ab 475 }
RobMeades 0:bb5fabac67ab 476 }
RobMeades 0:bb5fabac67ab 477
RobMeades 0:bb5fabac67ab 478 UNLOCK();
RobMeades 0:bb5fabac67ab 479 return success;
RobMeades 0:bb5fabac67ab 480 }
RobMeades 0:bb5fabac67ab 481
RobMeades 0:bb5fabac67ab 482 bool UbloxCellularDriverGen::smsDelete(int index)
RobMeades 0:bb5fabac67ab 483 {
RobMeades 0:bb5fabac67ab 484 bool success;
RobMeades 0:bb5fabac67ab 485 LOCK();
RobMeades 0:bb5fabac67ab 486
RobMeades 0:bb5fabac67ab 487 success = _at->send("AT+CMGD=%d", index) && _at->recv("OK");
RobMeades 0:bb5fabac67ab 488
RobMeades 0:bb5fabac67ab 489 UNLOCK();
RobMeades 0:bb5fabac67ab 490 return success;
RobMeades 0:bb5fabac67ab 491 }
RobMeades 0:bb5fabac67ab 492
RobMeades 0:bb5fabac67ab 493 bool UbloxCellularDriverGen::smsRead(int index, char* num, char* buf, int len)
RobMeades 0:bb5fabac67ab 494 {
RobMeades 0:bb5fabac67ab 495 bool success = false;
RobMeades 0:bb5fabac67ab 496 char * endOfString;
RobMeades 0:bb5fabac67ab 497 int smsReadLength = 0;
RobMeades 0:bb5fabac67ab 498 LOCK();
RobMeades 0:bb5fabac67ab 499
RobMeades 0:bb5fabac67ab 500 if (len > 0) {
RobMeades 0:bb5fabac67ab 501 //+CMGR: "REC READ", "+393488535999",,"07/04/05,18:02:28+08",145,4,0,0,"+393492000466",145,93
RobMeades 0:bb5fabac67ab 502 // The text of the message.
RobMeades 0:bb5fabac67ab 503 // OK
RobMeades 0:bb5fabac67ab 504 memset (_smsBuf, 0, sizeof (SMS_BUFFER_SIZE)); // Ensure terminator
RobMeades 0:bb5fabac67ab 505 if (_at->send("AT+CMGR=%d", index) &&
RobMeades 0:bb5fabac67ab 506 _at->recv("+CMGR: \"%*[^\"]\",\"%15[^\"]\"%*[^\n]\n", num) &&
RobMeades 0:bb5fabac67ab 507 _at->recv("%" stringify(SMS_BUFFER_SIZE) "[^\n]\n", _smsBuf) &&
RobMeades 0:bb5fabac67ab 508 _at->recv("OK")) {
RobMeades 0:bb5fabac67ab 509 endOfString = strchr(_smsBuf, 0);
RobMeades 0:bb5fabac67ab 510 if (endOfString != NULL) {
RobMeades 0:bb5fabac67ab 511 smsReadLength = endOfString - _smsBuf;
RobMeades 0:bb5fabac67ab 512 if (smsReadLength + 1 > len) { // +1 for terminator
RobMeades 0:bb5fabac67ab 513 smsReadLength = len - 1;
RobMeades 0:bb5fabac67ab 514 }
RobMeades 0:bb5fabac67ab 515 memcpy(buf, _smsBuf, smsReadLength);
RobMeades 0:bb5fabac67ab 516 *(buf + smsReadLength) = 0; // Add terminator
RobMeades 0:bb5fabac67ab 517 success = true;
RobMeades 0:bb5fabac67ab 518 }
RobMeades 0:bb5fabac67ab 519 }
RobMeades 0:bb5fabac67ab 520 }
RobMeades 0:bb5fabac67ab 521
RobMeades 0:bb5fabac67ab 522 UNLOCK();
RobMeades 0:bb5fabac67ab 523 return success;
RobMeades 0:bb5fabac67ab 524 }
RobMeades 0:bb5fabac67ab 525
RobMeades 0:bb5fabac67ab 526 /**********************************************************************
RobMeades 0:bb5fabac67ab 527 * PUBLIC METHODS: Unstructured Supplementary Service Data
RobMeades 0:bb5fabac67ab 528 **********************************************************************/
RobMeades 0:bb5fabac67ab 529
RobMeades 0:bb5fabac67ab 530 // Perform a USSD command.
RobMeades 0:bb5fabac67ab 531 bool UbloxCellularDriverGen::ussdCommand(const char* cmd, char* buf, int len)
RobMeades 0:bb5fabac67ab 532 {
RobMeades 0:bb5fabac67ab 533 bool success = false;
RobMeades 0:bb5fabac67ab 534 char * tmpBuf;
RobMeades 0:bb5fabac67ab 535 int atTimeout;
RobMeades 0:bb5fabac67ab 536 int x;
RobMeades 0:bb5fabac67ab 537 Timer timer;
RobMeades 0:bb5fabac67ab 538 LOCK();
RobMeades 0:bb5fabac67ab 539 atTimeout = _at_timeout; // Has to be inside LOCK()s
RobMeades 0:bb5fabac67ab 540
RobMeades 0:bb5fabac67ab 541 if (len > 0) {
RobMeades 0:bb5fabac67ab 542 *buf = 0;
RobMeades 0:bb5fabac67ab 543 if (len > USSD_STRING_LENGTH + 1) {
RobMeades 0:bb5fabac67ab 544 len = USSD_STRING_LENGTH + 1;
RobMeades 0:bb5fabac67ab 545 }
RobMeades 0:bb5fabac67ab 546
RobMeades 0:bb5fabac67ab 547 tmpBuf = (char *) malloc(USSD_STRING_LENGTH + 1);
RobMeades 0:bb5fabac67ab 548
RobMeades 0:bb5fabac67ab 549 if (tmpBuf != NULL) {
RobMeades 0:bb5fabac67ab 550 memset (tmpBuf, 0, USSD_STRING_LENGTH + 1);
RobMeades 0:bb5fabac67ab 551 // +CUSD: \"%*d, \"%128[^\"]\",%*d"
RobMeades 0:bb5fabac67ab 552 if (_at->send("AT+CUSD=1,\"%s\"", cmd)) {
RobMeades 0:bb5fabac67ab 553 // Wait for either +CUSD to come back or
RobMeades 0:bb5fabac67ab 554 // one of the other SS related URCs to trigger
RobMeades 0:bb5fabac67ab 555 if (_ssUrcBuf != NULL) {
RobMeades 0:bb5fabac67ab 556 free (_ssUrcBuf);
RobMeades 0:bb5fabac67ab 557 _ssUrcBuf = NULL;
RobMeades 0:bb5fabac67ab 558 }
RobMeades 0:bb5fabac67ab 559 timer.start();
RobMeades 0:bb5fabac67ab 560 _at->set_timeout(1000);
RobMeades 0:bb5fabac67ab 561 while (!success && (timer.read_ms() < atTimeout)) {
RobMeades 0:bb5fabac67ab 562 if (_at->recv("+CUSD: %*d,\"")) {
RobMeades 0:bb5fabac67ab 563 // Note: don't wait for "OK" here as the +CUSD response may come
RobMeades 0:bb5fabac67ab 564 // before or after the OK
RobMeades 0:bb5fabac67ab 565 // Also, the return string may include newlines so can't just use
RobMeades 0:bb5fabac67ab 566 // recv() to capture it as recv() will stop capturing at a newline.
RobMeades 0:bb5fabac67ab 567 if (read_at_to_char(tmpBuf, USSD_STRING_LENGTH, '\"') > 0) {
RobMeades 0:bb5fabac67ab 568 success = true;
RobMeades 0:bb5fabac67ab 569 memcpy (buf, tmpBuf, len);
RobMeades 0:bb5fabac67ab 570 *(buf + len - 1) = 0;
RobMeades 0:bb5fabac67ab 571 }
RobMeades 0:bb5fabac67ab 572 } else {
RobMeades 0:bb5fabac67ab 573 // Some of the return values do not appear as +CUSD but
RobMeades 0:bb5fabac67ab 574 // instead as the relevant URC for call waiting, call forwarding,
RobMeades 0:bb5fabac67ab 575 // etc. Test those here.
RobMeades 0:bb5fabac67ab 576 if (_ssUrcBuf != NULL) {
RobMeades 0:bb5fabac67ab 577 success = true;
RobMeades 0:bb5fabac67ab 578 x = strlen (_ssUrcBuf);
RobMeades 0:bb5fabac67ab 579 if (x > len - 1 ) {
RobMeades 0:bb5fabac67ab 580 x = len - 1;
RobMeades 0:bb5fabac67ab 581 }
RobMeades 0:bb5fabac67ab 582 memcpy (buf, _ssUrcBuf, x);
RobMeades 0:bb5fabac67ab 583 *(buf + x) = 0;
RobMeades 0:bb5fabac67ab 584 free (_ssUrcBuf);
RobMeades 0:bb5fabac67ab 585 _ssUrcBuf = NULL;
RobMeades 0:bb5fabac67ab 586 }
RobMeades 0:bb5fabac67ab 587 }
RobMeades 0:bb5fabac67ab 588 }
RobMeades 0:bb5fabac67ab 589 at_set_timeout(atTimeout);
RobMeades 0:bb5fabac67ab 590 timer.stop();
RobMeades 0:bb5fabac67ab 591 }
RobMeades 0:bb5fabac67ab 592 }
RobMeades 0:bb5fabac67ab 593 }
RobMeades 0:bb5fabac67ab 594
RobMeades 0:bb5fabac67ab 595 UNLOCK();
RobMeades 0:bb5fabac67ab 596 return success;
RobMeades 0:bb5fabac67ab 597 }
RobMeades 0:bb5fabac67ab 598
RobMeades 0:bb5fabac67ab 599 /**********************************************************************
RobMeades 0:bb5fabac67ab 600 * PUBLIC: Module File System
RobMeades 0:bb5fabac67ab 601 **********************************************************************/
RobMeades 0:bb5fabac67ab 602
RobMeades 0:bb5fabac67ab 603 // Delete a file from the module's file system.
RobMeades 0:bb5fabac67ab 604 bool UbloxCellularDriverGen::delFile(const char* filename)
RobMeades 0:bb5fabac67ab 605 {
RobMeades 0:bb5fabac67ab 606 bool success;
RobMeades 0:bb5fabac67ab 607 LOCK();
RobMeades 0:bb5fabac67ab 608
RobMeades 0:bb5fabac67ab 609 success = _at->send("AT+UDELFILE=\"%s\"", filename) && _at->recv("OK");
RobMeades 0:bb5fabac67ab 610
RobMeades 0:bb5fabac67ab 611 UNLOCK();
RobMeades 0:bb5fabac67ab 612 return success;
RobMeades 0:bb5fabac67ab 613 }
RobMeades 0:bb5fabac67ab 614
RobMeades 0:bb5fabac67ab 615 // Write a buffer of data to a file in the module's file system.
RobMeades 0:bb5fabac67ab 616 int UbloxCellularDriverGen::writeFile(const char* filename, const char* buf, int len)
RobMeades 0:bb5fabac67ab 617 {
RobMeades 0:bb5fabac67ab 618 int bytesWritten = -1;
RobMeades 0:bb5fabac67ab 619 LOCK();
RobMeades 0:bb5fabac67ab 620
RobMeades 0:bb5fabac67ab 621 if (_at->send("AT+UDWNFILE=\"%s\",%d", filename, len) && _at->recv(">")) {
RobMeades 0:bb5fabac67ab 622 if ((_at->write(buf, len) >= len) && _at->recv("OK")) {
RobMeades 0:bb5fabac67ab 623 bytesWritten = len;
RobMeades 0:bb5fabac67ab 624 }
RobMeades 0:bb5fabac67ab 625 }
RobMeades 0:bb5fabac67ab 626
RobMeades 0:bb5fabac67ab 627 UNLOCK();
RobMeades 0:bb5fabac67ab 628 return bytesWritten;
RobMeades 0:bb5fabac67ab 629 }
RobMeades 0:bb5fabac67ab 630
RobMeades 0:bb5fabac67ab 631 // Read a file from the module's file system
RobMeades 0:bb5fabac67ab 632 // Note: this is implemented with block reads since UARTSerial
RobMeades 0:bb5fabac67ab 633 // does not currently allow flow control and there is a danger
RobMeades 0:bb5fabac67ab 634 // of character loss with large whole-file reads
RobMeades 0:bb5fabac67ab 635 int UbloxCellularDriverGen::readFile(const char* filename, char* buf, int len)
RobMeades 0:bb5fabac67ab 636 {
RobMeades 0:bb5fabac67ab 637 int countBytes = -1; // Counter for file reading (default value)
RobMeades 0:bb5fabac67ab 638 int bytesToRead = fileSize(filename); // Retrieve the size of the file
RobMeades 0:bb5fabac67ab 639 int offset = 0;
RobMeades 0:bb5fabac67ab 640 int blockSize = FILE_BUFFER_SIZE;
RobMeades 0:bb5fabac67ab 641 char respFilename[48 + 1];
RobMeades 0:bb5fabac67ab 642 int sz, sz_read;
RobMeades 0:bb5fabac67ab 643 bool success = true;
RobMeades 0:bb5fabac67ab 644 int ch = 0;
RobMeades 0:bb5fabac67ab 645 int timeLimit;
RobMeades 0:bb5fabac67ab 646 Timer timer;
RobMeades 0:bb5fabac67ab 647
RobMeades 0:bb5fabac67ab 648 debug_if(_debug_trace_on, "readFile: filename is %s; size is %d\n", filename, bytesToRead);
RobMeades 0:bb5fabac67ab 649
RobMeades 0:bb5fabac67ab 650 memset(respFilename, 0, sizeof (respFilename)); // Ensure terminator
RobMeades 0:bb5fabac67ab 651 if (bytesToRead > 0)
RobMeades 0:bb5fabac67ab 652 {
RobMeades 0:bb5fabac67ab 653 if (bytesToRead > len) {
RobMeades 0:bb5fabac67ab 654 bytesToRead = len;
RobMeades 0:bb5fabac67ab 655 }
RobMeades 0:bb5fabac67ab 656
RobMeades 0:bb5fabac67ab 657 while (success && (bytesToRead > 0)) {
RobMeades 0:bb5fabac67ab 658
RobMeades 0:bb5fabac67ab 659 if (bytesToRead < blockSize) {
RobMeades 0:bb5fabac67ab 660 blockSize = bytesToRead;
RobMeades 0:bb5fabac67ab 661 }
RobMeades 0:bb5fabac67ab 662 LOCK();
RobMeades 0:bb5fabac67ab 663
RobMeades 0:bb5fabac67ab 664 if (blockSize > 0) {
RobMeades 0:bb5fabac67ab 665 if (_at->send("AT+URDBLOCK=\"%s\",%d,%d\r\n", filename, offset, blockSize) &&
RobMeades 0:bb5fabac67ab 666 _at->recv("+URDBLOCK: \"%48[^\"]\",%d,\"", respFilename, &sz) &&
RobMeades 0:bb5fabac67ab 667 (strcmp(filename, respFilename) == 0)) {
RobMeades 0:bb5fabac67ab 668
RobMeades 0:bb5fabac67ab 669 // Would use _at->read() here, but if it runs ahead of the
RobMeades 0:bb5fabac67ab 670 // serial stream it returns -1 instead of the number of characters
RobMeades 0:bb5fabac67ab 671 // read so far, which is not very helpful so instead use _at->getc() and
rob.meades@u-blox.com 3:027c9eaec52c 672 // a time limit. The time limit is twice the amount of time it should take to
rob.meades@u-blox.com 3:027c9eaec52c 673 // read the block at the working baud rate
RobMeades 0:bb5fabac67ab 674 timer.reset();
RobMeades 0:bb5fabac67ab 675 timer.start();
rob.meades@u-blox.com 3:027c9eaec52c 676 timeLimit = blockSize * 2 / ((MBED_CONF_UBLOX_CELL_BAUD_RATE / 8) / 1000);
RobMeades 0:bb5fabac67ab 677 sz_read = 0;
RobMeades 0:bb5fabac67ab 678 while ((sz_read < blockSize) && (timer.read_ms() < timeLimit)) {
RobMeades 0:bb5fabac67ab 679 ch = _at->getc();
RobMeades 0:bb5fabac67ab 680 if (ch >= 0) {
RobMeades 0:bb5fabac67ab 681 *buf = ch;
RobMeades 0:bb5fabac67ab 682 buf++;
RobMeades 0:bb5fabac67ab 683 sz_read++;
RobMeades 0:bb5fabac67ab 684 }
RobMeades 0:bb5fabac67ab 685 }
RobMeades 0:bb5fabac67ab 686 timer.stop();
RobMeades 0:bb5fabac67ab 687
RobMeades 0:bb5fabac67ab 688 if (sz_read == blockSize) {
RobMeades 0:bb5fabac67ab 689 bytesToRead -= sz_read;
RobMeades 0:bb5fabac67ab 690 offset += sz_read;
RobMeades 0:bb5fabac67ab 691 _at->recv("OK");
RobMeades 0:bb5fabac67ab 692 } else {
rob.meades@u-blox.com 3:027c9eaec52c 693 debug_if(_debug_trace_on, "blockSize %d but only received %d bytes\n", blockSize, sz_read);
RobMeades 0:bb5fabac67ab 694 success = false;
RobMeades 0:bb5fabac67ab 695 }
RobMeades 0:bb5fabac67ab 696 } else {
RobMeades 0:bb5fabac67ab 697 success = false;
RobMeades 0:bb5fabac67ab 698 }
RobMeades 0:bb5fabac67ab 699 }
RobMeades 0:bb5fabac67ab 700
RobMeades 0:bb5fabac67ab 701 UNLOCK();
RobMeades 0:bb5fabac67ab 702 }
RobMeades 0:bb5fabac67ab 703
RobMeades 0:bb5fabac67ab 704 if (success) {
RobMeades 0:bb5fabac67ab 705 countBytes = offset;
RobMeades 0:bb5fabac67ab 706 }
RobMeades 0:bb5fabac67ab 707 }
RobMeades 0:bb5fabac67ab 708
RobMeades 0:bb5fabac67ab 709 return countBytes;
RobMeades 0:bb5fabac67ab 710 }
RobMeades 0:bb5fabac67ab 711
RobMeades 0:bb5fabac67ab 712 // Return the size of a file.
RobMeades 0:bb5fabac67ab 713 int UbloxCellularDriverGen::fileSize(const char* filename)
RobMeades 0:bb5fabac67ab 714 {
RobMeades 0:bb5fabac67ab 715 int returnValue = -1;
RobMeades 0:bb5fabac67ab 716 int fileSize;
RobMeades 0:bb5fabac67ab 717 LOCK();
RobMeades 0:bb5fabac67ab 718
RobMeades 0:bb5fabac67ab 719 if (_at->send("AT+ULSTFILE=2,\"%s\"", filename) &&
RobMeades 0:bb5fabac67ab 720 _at->recv("+ULSTFILE: %d\n", &fileSize) &&
RobMeades 0:bb5fabac67ab 721 _at->recv("OK")) {
RobMeades 0:bb5fabac67ab 722 returnValue = fileSize;
RobMeades 0:bb5fabac67ab 723 }
RobMeades 0:bb5fabac67ab 724
RobMeades 0:bb5fabac67ab 725 UNLOCK();
RobMeades 0:bb5fabac67ab 726 return returnValue;
RobMeades 0:bb5fabac67ab 727 }
RobMeades 0:bb5fabac67ab 728
RobMeades 0:bb5fabac67ab 729 // End of file
RobMeades 0:bb5fabac67ab 730