This class adds HTTP, FTP and CellLocate client support for u-blox modules for the C027 and C030 boards (excepting the C030 N2xx flavour) from mbed 5.5 onwards. The HTTP, FTP and CellLocate operations are all hosted on the module, minimizing RAM consumption in the mbed MCU. It also sub-classes ublox-cellular-driver-gen to bring in SMS, USSD and modem file system support if you need to use these functions at the same time as the cellular interface.

Dependencies:   ublox-at-cellular-interface

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

Committer:
RobMeades
Date:
Fri Jun 09 22:23:28 2017 +0000
Revision:
4:39acbc0111eb
Parent:
1:26a67ab07275
Child:
5:9fd89567f769
Handle case where uncertainty is "-1".  Differentiate between +UULOC and +UULOCIND URCs.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RobMeades 0:0b75e22c9231 1 /* Copyright (c) 2017 ublox Limited
RobMeades 0:0b75e22c9231 2 *
RobMeades 0:0b75e22c9231 3 * Licensed under the Apache License, Version 2.0 (the "License");
RobMeades 0:0b75e22c9231 4 * you may not use this file except in compliance with the License.
RobMeades 0:0b75e22c9231 5 * You may obtain a copy of the License at
RobMeades 0:0b75e22c9231 6 *
RobMeades 0:0b75e22c9231 7 * http://www.apache.org/licenses/LICENSE-2.0
RobMeades 0:0b75e22c9231 8 *
RobMeades 0:0b75e22c9231 9 * Unless required by applicable law or agreed to in writing, software
RobMeades 0:0b75e22c9231 10 * distributed under the License is distributed on an "AS IS" BASIS,
RobMeades 0:0b75e22c9231 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
RobMeades 0:0b75e22c9231 12 * See the License for the specific language governing permissions and
RobMeades 0:0b75e22c9231 13 * limitations under the License.
RobMeades 0:0b75e22c9231 14 */
RobMeades 0:0b75e22c9231 15
RobMeades 0:0b75e22c9231 16 #include "UbloxATCellularInterfaceExt.h"
RobMeades 0:0b75e22c9231 17 #include "APN_db.h"
RobMeades 0:0b75e22c9231 18 #if defined(FEATURE_COMMON_PAL)
RobMeades 0:0b75e22c9231 19 #include "mbed_trace.h"
RobMeades 0:0b75e22c9231 20 #define TRACE_GROUP "UCAD"
RobMeades 0:0b75e22c9231 21 #else
RobMeades 0:0b75e22c9231 22 #define debug_if(_debug_trace_on, ...) (void(0)) // dummies if feature common pal is not added
RobMeades 0:0b75e22c9231 23 #define tr_info(...) (void(0)) // dummies if feature common pal is not added
RobMeades 0:0b75e22c9231 24 #define tr_error(...) (void(0)) // dummies if feature common pal is not added
RobMeades 0:0b75e22c9231 25 #endif
RobMeades 0:0b75e22c9231 26
RobMeades 0:0b75e22c9231 27 /**********************************************************************
RobMeades 0:0b75e22c9231 28 * PROTECTED METHODS: HTTP
RobMeades 0:0b75e22c9231 29 **********************************************************************/
RobMeades 0:0b75e22c9231 30
RobMeades 0:0b75e22c9231 31 // Callback for HTTP result code handling.
RobMeades 0:0b75e22c9231 32 void UbloxATCellularInterfaceExt::UUHTTPCR_URC()
RobMeades 0:0b75e22c9231 33 {
RobMeades 0:0b75e22c9231 34 char buf[32];
RobMeades 0:0b75e22c9231 35 int a, b, c;
RobMeades 0:0b75e22c9231 36
RobMeades 0:0b75e22c9231 37 // Note: not calling _at->recv() from here as we're
RobMeades 0:0b75e22c9231 38 // already in an _at->recv()
RobMeades 0:0b75e22c9231 39 // +UUHTTPCR: <profile_id>,<op_code>,<param_val>
RobMeades 0:0b75e22c9231 40 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 0:0b75e22c9231 41 if (sscanf(buf, ": %d,%d,%d", &a, &b, &c) == 3) {
RobMeades 0:0b75e22c9231 42 _httpProfiles[a].cmd = b; // Command
RobMeades 0:0b75e22c9231 43 _httpProfiles[a].result = c; // Result
RobMeades 0:0b75e22c9231 44 debug_if(_debug_trace_on, "%s on profile %d, result code is %d\n", getHttpCmd((HttpCmd) b), a, c);
RobMeades 0:0b75e22c9231 45 }
RobMeades 0:0b75e22c9231 46 }
RobMeades 0:0b75e22c9231 47 }
RobMeades 0:0b75e22c9231 48
RobMeades 0:0b75e22c9231 49 // Find a given profile. NOTE: LOCK() before calling.
RobMeades 0:0b75e22c9231 50 int UbloxATCellularInterfaceExt::findProfile(int modemHandle)
RobMeades 0:0b75e22c9231 51 {
RobMeades 0:0b75e22c9231 52 for (unsigned int profile = 0; profile < (sizeof(_httpProfiles)/sizeof(_httpProfiles[0]));
RobMeades 0:0b75e22c9231 53 profile++) {
RobMeades 0:0b75e22c9231 54 if (_httpProfiles[profile].modemHandle == modemHandle) {
RobMeades 0:0b75e22c9231 55 return profile;
RobMeades 0:0b75e22c9231 56 }
RobMeades 0:0b75e22c9231 57 }
RobMeades 0:0b75e22c9231 58
RobMeades 0:0b75e22c9231 59 return HTTP_PROF_UNUSED;
RobMeades 0:0b75e22c9231 60 }
RobMeades 0:0b75e22c9231 61
RobMeades 0:0b75e22c9231 62 // Return a string representing an HTTP AT command.
RobMeades 0:0b75e22c9231 63 const char *UbloxATCellularInterfaceExt::getHttpCmd(HttpCmd httpCmd)
RobMeades 0:0b75e22c9231 64 {
RobMeades 0:0b75e22c9231 65 const char * str = "HTTP command not recognised";
RobMeades 0:0b75e22c9231 66
RobMeades 0:0b75e22c9231 67 switch (httpCmd) {
RobMeades 0:0b75e22c9231 68 case HTTP_HEAD:
RobMeades 0:0b75e22c9231 69 str = "HTTP HEAD command";
RobMeades 0:0b75e22c9231 70 break;
RobMeades 0:0b75e22c9231 71 case HTTP_GET:
RobMeades 0:0b75e22c9231 72 str = "HTTP GET command";
RobMeades 0:0b75e22c9231 73 break;
RobMeades 0:0b75e22c9231 74 case HTTP_DELETE:
RobMeades 0:0b75e22c9231 75 str = "HTTP DELETE command";
RobMeades 0:0b75e22c9231 76 break;
RobMeades 0:0b75e22c9231 77 case HTTP_PUT:
RobMeades 0:0b75e22c9231 78 str = "HTTP PUT command";
RobMeades 0:0b75e22c9231 79 break;
RobMeades 0:0b75e22c9231 80 case HTTP_POST_FILE:
RobMeades 0:0b75e22c9231 81 str = "HTTP POST file command";
RobMeades 0:0b75e22c9231 82 break;
RobMeades 0:0b75e22c9231 83 case HTTP_POST_DATA:
RobMeades 0:0b75e22c9231 84 str = "HTTP POST data command";
RobMeades 0:0b75e22c9231 85 break;
RobMeades 0:0b75e22c9231 86 default:
RobMeades 0:0b75e22c9231 87 break;
RobMeades 0:0b75e22c9231 88 }
RobMeades 0:0b75e22c9231 89
RobMeades 0:0b75e22c9231 90 return str;
RobMeades 0:0b75e22c9231 91 }
RobMeades 0:0b75e22c9231 92
RobMeades 0:0b75e22c9231 93 /**********************************************************************
RobMeades 0:0b75e22c9231 94 * PROTECTED METHODS: FTP
RobMeades 0:0b75e22c9231 95 **********************************************************************/
RobMeades 0:0b75e22c9231 96
RobMeades 0:0b75e22c9231 97 // Callback for FTP result code handling.
RobMeades 0:0b75e22c9231 98 void UbloxATCellularInterfaceExt::UUFTPCR_URC()
RobMeades 0:0b75e22c9231 99 {
RobMeades 0:0b75e22c9231 100 char buf[64];
RobMeades 0:0b75e22c9231 101 char md5[32];
RobMeades 0:0b75e22c9231 102
RobMeades 0:0b75e22c9231 103 // Note: not calling _at->recv() from here as we're
RobMeades 0:0b75e22c9231 104 // already in an _at->recv()
RobMeades 0:0b75e22c9231 105 // +UUFTPCR: <op_code>,<ftp_result>[,<md5_sum>]
RobMeades 0:0b75e22c9231 106 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 0:0b75e22c9231 107 if (sscanf(buf, ": %d,%d,%32[^\n]\n", &_lastFtpOpCodeResult, &_lastFtpResult, md5) == 3) {
RobMeades 0:0b75e22c9231 108 // Store the MD5 sum if we can
RobMeades 0:0b75e22c9231 109 if ((_ftpBuf != NULL) && (_ftpBufLen >= 32)) {
RobMeades 0:0b75e22c9231 110 memcpy (_ftpBuf, md5, 32);
RobMeades 0:0b75e22c9231 111 if (_ftpBufLen == 33) {
RobMeades 0:0b75e22c9231 112 *(buf + 32) = 0; // Add a terminator if there's room
RobMeades 0:0b75e22c9231 113 }
RobMeades 0:0b75e22c9231 114 }
RobMeades 0:0b75e22c9231 115 }
RobMeades 0:0b75e22c9231 116 debug_if(_debug_trace_on, "%s result code is %d\n",
RobMeades 0:0b75e22c9231 117 getFtpCmd((FtpCmd) _lastFtpOpCodeResult), _lastFtpResult);
RobMeades 0:0b75e22c9231 118 }
RobMeades 0:0b75e22c9231 119 }
RobMeades 0:0b75e22c9231 120
RobMeades 0:0b75e22c9231 121 // Callback for FTP data handling.
RobMeades 0:0b75e22c9231 122 void UbloxATCellularInterfaceExt::UUFTPCD_URC()
RobMeades 0:0b75e22c9231 123 {
RobMeades 0:0b75e22c9231 124 char buf[32];
RobMeades 0:0b75e22c9231 125 char *ftpBufPtr = _ftpBuf;
RobMeades 0:0b75e22c9231 126 int ftpDataLen;
RobMeades 0:0b75e22c9231 127
RobMeades 0:0b75e22c9231 128 // Note: not calling _at->recv() from here as we're
RobMeades 0:0b75e22c9231 129 // already in an _at->recv()
RobMeades 0:0b75e22c9231 130 // +UUFTPCD: <op_code>,<ftp_data_len>,<ftp_data_in_quotes>
RobMeades 0:0b75e22c9231 131 if (read_at_to_char(buf, sizeof(buf), '\"') > 0) {
RobMeades 0:0b75e22c9231 132 if (sscanf(buf, ": %d,%d,\"", &_lastFtpOpCodeData, &ftpDataLen) == 2) {
RobMeades 0:0b75e22c9231 133 if ((ftpBufPtr != NULL) && (_ftpBufLen > 0)) {
RobMeades 0:0b75e22c9231 134 if (ftpDataLen + 1 > _ftpBufLen) { // +1 for terminator
RobMeades 0:0b75e22c9231 135 ftpDataLen = _ftpBufLen - 1;
RobMeades 0:0b75e22c9231 136 }
RobMeades 0:0b75e22c9231 137 ftpBufPtr += _at->read(ftpBufPtr, ftpDataLen);
RobMeades 0:0b75e22c9231 138 *ftpBufPtr = 0; // Add terminator
RobMeades 0:0b75e22c9231 139 }
RobMeades 0:0b75e22c9231 140 }
RobMeades 0:0b75e22c9231 141 }
RobMeades 0:0b75e22c9231 142 }
RobMeades 0:0b75e22c9231 143
RobMeades 0:0b75e22c9231 144 // Return a string representing an FTP AT command.
RobMeades 0:0b75e22c9231 145 const char *UbloxATCellularInterfaceExt::getFtpCmd(FtpCmd ftpCmd)
RobMeades 0:0b75e22c9231 146 {
RobMeades 0:0b75e22c9231 147 const char * str = "FTP command not recognised";
RobMeades 0:0b75e22c9231 148
RobMeades 0:0b75e22c9231 149 switch (ftpCmd) {
RobMeades 0:0b75e22c9231 150 case FTP_LOGOUT:
RobMeades 0:0b75e22c9231 151 str = "FTP log out command";
RobMeades 0:0b75e22c9231 152 break;
RobMeades 0:0b75e22c9231 153 case FTP_LOGIN:
RobMeades 0:0b75e22c9231 154 str = "FTP log in command";
RobMeades 0:0b75e22c9231 155 break;
RobMeades 0:0b75e22c9231 156 case FTP_DELETE_FILE:
RobMeades 0:0b75e22c9231 157 str = "FTP delete file command";
RobMeades 0:0b75e22c9231 158 break;
RobMeades 0:0b75e22c9231 159 case FTP_RENAME_FILE:
RobMeades 0:0b75e22c9231 160 str = "FTP rename file command";
RobMeades 0:0b75e22c9231 161 break;
RobMeades 0:0b75e22c9231 162 case FTP_GET_FILE:
RobMeades 0:0b75e22c9231 163 str = "FTP get file command";
RobMeades 0:0b75e22c9231 164 break;
RobMeades 0:0b75e22c9231 165 case FTP_PUT_FILE:
RobMeades 0:0b75e22c9231 166 str = "FTP put file command";
RobMeades 0:0b75e22c9231 167 break;
RobMeades 0:0b75e22c9231 168 case FTP_CD:
RobMeades 0:0b75e22c9231 169 str = "FTP change directory command";
RobMeades 0:0b75e22c9231 170 break;
RobMeades 0:0b75e22c9231 171 case FTP_MKDIR:
RobMeades 0:0b75e22c9231 172 str = "FTP make directory command";
RobMeades 0:0b75e22c9231 173 break;
RobMeades 0:0b75e22c9231 174 case FTP_RMDIR:
RobMeades 0:0b75e22c9231 175 str = "FTP remove directory command";
RobMeades 0:0b75e22c9231 176 break;
RobMeades 0:0b75e22c9231 177 case FTP_FILE_INFO:
RobMeades 0:0b75e22c9231 178 str = "FTP file info command";
RobMeades 0:0b75e22c9231 179 break;
RobMeades 0:0b75e22c9231 180 case FTP_LS:
RobMeades 0:0b75e22c9231 181 str = "FTP directory list command";
RobMeades 0:0b75e22c9231 182 break;
RobMeades 0:0b75e22c9231 183 case FTP_FOTA_FILE:
RobMeades 0:0b75e22c9231 184 str = "FTP FOTA file command";
RobMeades 0:0b75e22c9231 185 break;
RobMeades 0:0b75e22c9231 186 default:
RobMeades 0:0b75e22c9231 187 break;
RobMeades 0:0b75e22c9231 188 }
RobMeades 0:0b75e22c9231 189
RobMeades 0:0b75e22c9231 190 return str;
RobMeades 0:0b75e22c9231 191 }
RobMeades 0:0b75e22c9231 192
RobMeades 0:0b75e22c9231 193 /**********************************************************************
RobMeades 0:0b75e22c9231 194 * PROTECTED METHODS: Cell Locate
RobMeades 0:0b75e22c9231 195 **********************************************************************/
RobMeades 0:0b75e22c9231 196
RobMeades 0:0b75e22c9231 197 // Callback for UULOCIND handling.
RobMeades 0:0b75e22c9231 198 void UbloxATCellularInterfaceExt::UULOCIND_URC()
RobMeades 0:0b75e22c9231 199 {
RobMeades 0:0b75e22c9231 200 char buf[32];
RobMeades 0:0b75e22c9231 201 int a, b;
RobMeades 0:0b75e22c9231 202
RobMeades 0:0b75e22c9231 203 // Note: not calling _at->recv() from here as we're
RobMeades 0:0b75e22c9231 204 // already in an _at->recv()
RobMeades 0:0b75e22c9231 205 // +UULOCIND: <step>,<result>
RobMeades 0:0b75e22c9231 206 if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
RobMeades 0:0b75e22c9231 207 if (sscanf(buf, " %d,%d", &a, &b) == 2) {
RobMeades 0:0b75e22c9231 208 switch (a) {
RobMeades 0:0b75e22c9231 209 case 0:
RobMeades 0:0b75e22c9231 210 debug_if(_debug_trace_on, "Network scan start\n");
RobMeades 0:0b75e22c9231 211 break;
RobMeades 0:0b75e22c9231 212 case 1:
RobMeades 0:0b75e22c9231 213 debug_if(_debug_trace_on, "Network scan end\n");
RobMeades 0:0b75e22c9231 214 break;
RobMeades 0:0b75e22c9231 215 case 2:
RobMeades 0:0b75e22c9231 216 debug_if(_debug_trace_on, "Requesting data from server\n");
RobMeades 0:0b75e22c9231 217 break;
RobMeades 0:0b75e22c9231 218 case 3:
RobMeades 0:0b75e22c9231 219 debug_if(_debug_trace_on, "Received data from server\n");
RobMeades 0:0b75e22c9231 220 break;
RobMeades 0:0b75e22c9231 221 case 4:
RobMeades 0:0b75e22c9231 222 debug_if(_debug_trace_on, "Sending feedback to server\n");
RobMeades 0:0b75e22c9231 223 break;
RobMeades 0:0b75e22c9231 224 default:
RobMeades 0:0b75e22c9231 225 debug_if(_debug_trace_on, "Unknown step\n");
RobMeades 0:0b75e22c9231 226 break;
RobMeades 0:0b75e22c9231 227 }
RobMeades 0:0b75e22c9231 228 switch (b) {
RobMeades 0:0b75e22c9231 229 case 0:
RobMeades 0:0b75e22c9231 230 // No error
RobMeades 0:0b75e22c9231 231 break;
RobMeades 0:0b75e22c9231 232 case 1:
RobMeades 0:0b75e22c9231 233 debug_if(_debug_trace_on, "Wrong URL!\n");
RobMeades 0:0b75e22c9231 234 break;
RobMeades 0:0b75e22c9231 235 case 2:
RobMeades 0:0b75e22c9231 236 debug_if(_debug_trace_on, "HTTP error!\n");
RobMeades 0:0b75e22c9231 237 break;
RobMeades 0:0b75e22c9231 238 case 3:
RobMeades 0:0b75e22c9231 239 debug_if(_debug_trace_on, "Create socket error!\n");
RobMeades 0:0b75e22c9231 240 break;
RobMeades 0:0b75e22c9231 241 case 4:
RobMeades 0:0b75e22c9231 242 debug_if(_debug_trace_on, "Close socket error!\n");
RobMeades 0:0b75e22c9231 243 break;
RobMeades 0:0b75e22c9231 244 case 5:
RobMeades 0:0b75e22c9231 245 debug_if(_debug_trace_on, "Write to socket error!\n");
RobMeades 0:0b75e22c9231 246 break;
RobMeades 0:0b75e22c9231 247 case 6:
RobMeades 0:0b75e22c9231 248 debug_if(_debug_trace_on, "Read from socket error!\n");
RobMeades 0:0b75e22c9231 249 break;
RobMeades 0:0b75e22c9231 250 case 7:
RobMeades 0:0b75e22c9231 251 debug_if(_debug_trace_on, "Connection/DNS error!\n");
RobMeades 0:0b75e22c9231 252 break;
RobMeades 0:0b75e22c9231 253 case 8:
RobMeades 0:0b75e22c9231 254 debug_if(_debug_trace_on, "Authentication token problem!\n");
RobMeades 0:0b75e22c9231 255 break;
RobMeades 0:0b75e22c9231 256 case 9:
RobMeades 0:0b75e22c9231 257 debug_if(_debug_trace_on, "Generic error!\n");
RobMeades 0:0b75e22c9231 258 break;
RobMeades 0:0b75e22c9231 259 case 10:
RobMeades 0:0b75e22c9231 260 debug_if(_debug_trace_on, "User terminated!\n");
RobMeades 0:0b75e22c9231 261 break;
RobMeades 0:0b75e22c9231 262 case 11:
RobMeades 0:0b75e22c9231 263 debug_if(_debug_trace_on, "No data from server!\n");
RobMeades 0:0b75e22c9231 264 break;
RobMeades 0:0b75e22c9231 265 default:
RobMeades 0:0b75e22c9231 266 debug_if(_debug_trace_on, "Unknown result!\n");
RobMeades 0:0b75e22c9231 267 break;
RobMeades 0:0b75e22c9231 268 }
RobMeades 0:0b75e22c9231 269 }
RobMeades 0:0b75e22c9231 270 }
RobMeades 0:0b75e22c9231 271 }
RobMeades 0:0b75e22c9231 272
RobMeades 0:0b75e22c9231 273 // Callback for UULOC URC handling.
RobMeades 0:0b75e22c9231 274 void UbloxATCellularInterfaceExt::UULOC_URC()
RobMeades 0:0b75e22c9231 275 {
RobMeades 0:0b75e22c9231 276 int a, b;
RobMeades 0:0b75e22c9231 277
RobMeades 0:0b75e22c9231 278 // Note: not calling _at->recv() from here as we're
RobMeades 0:0b75e22c9231 279 // already in an _at->recv()
RobMeades 0:0b75e22c9231 280
RobMeades 0:0b75e22c9231 281 // +UHTTPCR: <profile_id>,<op_code>,<param_val>
RobMeades 0:0b75e22c9231 282 if (read_at_to_char(urcBuf, sizeof (urcBuf), '\n') > 0) {
rob.meades@u-blox.com 1:26a67ab07275 283 // Response type 1
RobMeades 0:0b75e22c9231 284 // +UULOC: <date>,<time>,<lat>,<long>,<alt>,<uncertainty>,<speed>, <direction>,<vertical_acc>,<sensor_used>,<SV_used>,<antenna_status>, <jamming_status>
RobMeades 4:39acbc0111eb 285 if (sscanf(urcBuf, " %d/%d/%d,%d:%d:%d.%*d,%f,%f,%d,%d,%d,%d,%d,%d,%d,%*d,%*d",
RobMeades 0:0b75e22c9231 286 &_loc[0].time.tm_mday, &_loc[0].time.tm_mon,
RobMeades 0:0b75e22c9231 287 &_loc[0].time.tm_year, &_loc[0].time.tm_hour,
RobMeades 0:0b75e22c9231 288 &_loc[0].time.tm_min, &_loc[0].time.tm_sec,
RobMeades 0:0b75e22c9231 289 &_loc[0].latitude, &_loc[0].longitude, &_loc[0].altitude,
RobMeades 0:0b75e22c9231 290 &_loc[0].uncertainty, &_loc[0].speed, &_loc[0].direction,
RobMeades 0:0b75e22c9231 291 &_loc[0].verticalAcc,
RobMeades 0:0b75e22c9231 292 &b, &_loc[0].svUsed) == 15) {
RobMeades 0:0b75e22c9231 293 debug_if(_debug_trace_on, "Position found at index 0\n");
RobMeades 0:0b75e22c9231 294 _loc[0].sensor = (b == 0) ? CELL_LAST : (b == 1) ? CELL_GNSS :
RobMeades 0:0b75e22c9231 295 (b == 2) ? CELL_LOCATE : (b == 3) ? CELL_HYBRID : CELL_LAST;
rob.meades@u-blox.com 1:26a67ab07275 296 _loc[0].time.tm_year -= 1900;
RobMeades 0:0b75e22c9231 297 _loc[0].time.tm_mon -= 1;
RobMeades 0:0b75e22c9231 298 _loc[0].time.tm_wday = 0;
RobMeades 0:0b75e22c9231 299 _loc[0].time.tm_yday = 0;
RobMeades 0:0b75e22c9231 300 _loc[0].validData = true;
RobMeades 4:39acbc0111eb 301 // Uncertainty can appear as 4294967, which is
RobMeades 4:39acbc0111eb 302 // (2^32 - 1) / 1000, or -1. Since it is confusing
RobMeades 4:39acbc0111eb 303 // for the user to get a large positive number instead
RobMeades 4:39acbc0111eb 304 // of 0 -1, set it to -1 in th1s case.
RobMeades 4:39acbc0111eb 305 if (_loc[0].uncertainty == 4294967) {
RobMeades 4:39acbc0111eb 306 _loc[0].uncertainty = -1;
RobMeades 4:39acbc0111eb 307 }
RobMeades 4:39acbc0111eb 308 _locExpPos = 1;
RobMeades 0:0b75e22c9231 309 _locRcvPos++;
rob.meades@u-blox.com 1:26a67ab07275 310 // Response type 2, sensor used 1
RobMeades 0:0b75e22c9231 311 // +UULOC: <sol>,<num>,<sensor_used>,<date>,<time>,<lat>,<long>,<alt>,<uncertainty>,<speed>, <direction>,<vertical_acc>,,<SV_used>,<antenna_status>, <jamming_status>
RobMeades 4:39acbc0111eb 312 } else if (sscanf(urcBuf, " %d,%d,%d,%d/%d/%d,%d:%d:%d.%*d,%f,%f,%d,%d,%d,%d,%d,%d,%*d,%*d",
RobMeades 0:0b75e22c9231 313 &a, &_locExpPos, &b,
RobMeades 0:0b75e22c9231 314 &_loc[CELL_MAX_HYP - 1].time.tm_mday,
RobMeades 0:0b75e22c9231 315 &_loc[CELL_MAX_HYP - 1].time.tm_mon,
RobMeades 0:0b75e22c9231 316 &_loc[CELL_MAX_HYP - 1].time.tm_year,
RobMeades 0:0b75e22c9231 317 &_loc[CELL_MAX_HYP - 1].time.tm_hour,
RobMeades 0:0b75e22c9231 318 &_loc[CELL_MAX_HYP - 1].time.tm_min,
RobMeades 0:0b75e22c9231 319 &_loc[CELL_MAX_HYP - 1].time.tm_sec,
RobMeades 0:0b75e22c9231 320 &_loc[CELL_MAX_HYP - 1].latitude,
RobMeades 0:0b75e22c9231 321 &_loc[CELL_MAX_HYP - 1].longitude,
RobMeades 0:0b75e22c9231 322 &_loc[CELL_MAX_HYP - 1].altitude,
RobMeades 0:0b75e22c9231 323 &_loc[CELL_MAX_HYP - 1].uncertainty,
RobMeades 0:0b75e22c9231 324 &_loc[CELL_MAX_HYP - 1].speed,
RobMeades 0:0b75e22c9231 325 &_loc[CELL_MAX_HYP - 1].direction,
RobMeades 0:0b75e22c9231 326 &_loc[CELL_MAX_HYP - 1].verticalAcc,
RobMeades 0:0b75e22c9231 327 &_loc[CELL_MAX_HYP - 1].svUsed) == 17) {
RobMeades 0:0b75e22c9231 328 if (--a >= 0) {
RobMeades 0:0b75e22c9231 329 debug_if(_debug_trace_on, "Position found at index %d\n", a);
RobMeades 0:0b75e22c9231 330
RobMeades 0:0b75e22c9231 331 memcpy(&_loc[a], &_loc[CELL_MAX_HYP - 1], sizeof(*_loc));
RobMeades 0:0b75e22c9231 332
RobMeades 0:0b75e22c9231 333 _loc[a].sensor = (b == 0) ? CELL_LAST : (b == 1) ? CELL_GNSS :
RobMeades 0:0b75e22c9231 334 (b == 2) ? CELL_LOCATE : (b == 3) ? CELL_HYBRID : CELL_LAST;
rob.meades@u-blox.com 1:26a67ab07275 335 _loc[a].time.tm_year -= 1900;
RobMeades 0:0b75e22c9231 336 _loc[a].time.tm_mon -= 1;
RobMeades 0:0b75e22c9231 337 _loc[a].time.tm_wday = 0;
RobMeades 0:0b75e22c9231 338 _loc[a].time.tm_yday = 0;
RobMeades 4:39acbc0111eb 339 // Uncertainty can appear as 4294967, which is
RobMeades 4:39acbc0111eb 340 // (2^32 - 1) / 1000, or -1. Since it is confusing
RobMeades 4:39acbc0111eb 341 // for the user to get a large positive number instead
RobMeades 4:39acbc0111eb 342 // of 0 -1, set it to -1 in th1s case.
RobMeades 4:39acbc0111eb 343 if (_loc[a].uncertainty == 4294967) {
RobMeades 4:39acbc0111eb 344 _loc[a].uncertainty = -1;
RobMeades 4:39acbc0111eb 345 }
RobMeades 0:0b75e22c9231 346 _loc[a].validData = true;
RobMeades 0:0b75e22c9231 347 _locRcvPos++;
RobMeades 0:0b75e22c9231 348 }
rob.meades@u-blox.com 1:26a67ab07275 349 // Response type 2, sensor used 2
RobMeades 0:0b75e22c9231 350 //+UULOC: <sol>,<num>,<sensor_used>,<date>,<time>,<lat>,<long>,<alt>,<lat50>,<long50>,<major50>,<minor50>,<orientation50>,<confidence50>[,<lat95>,<long95>,<major95>,<minor95>,<orientation95>,<confidence95>]
RobMeades 4:39acbc0111eb 351 } else if (sscanf(urcBuf, " %d,%d,%d,%d/%d/%d,%d:%d:%d.%*d,%f,%f,%d,%*f,%*f,%d,%*d,%*d,%*d",
RobMeades 0:0b75e22c9231 352 &a, &_locExpPos, &b,
RobMeades 0:0b75e22c9231 353 &_loc[CELL_MAX_HYP - 1].time.tm_mday,
RobMeades 0:0b75e22c9231 354 &_loc[CELL_MAX_HYP - 1].time.tm_mon,
RobMeades 0:0b75e22c9231 355 &_loc[CELL_MAX_HYP - 1].time.tm_year,
RobMeades 0:0b75e22c9231 356 &_loc[CELL_MAX_HYP - 1].time.tm_hour,
RobMeades 0:0b75e22c9231 357 &_loc[CELL_MAX_HYP - 1].time.tm_min,
RobMeades 0:0b75e22c9231 358 &_loc[CELL_MAX_HYP - 1].time.tm_sec,
RobMeades 0:0b75e22c9231 359 &_loc[CELL_MAX_HYP - 1].latitude,
RobMeades 0:0b75e22c9231 360 &_loc[CELL_MAX_HYP - 1].longitude,
RobMeades 0:0b75e22c9231 361 &_loc[CELL_MAX_HYP - 1].altitude,
RobMeades 0:0b75e22c9231 362 &_loc[CELL_MAX_HYP - 1].uncertainty) == 13) {
RobMeades 0:0b75e22c9231 363 if (--a >= 0) {
RobMeades 0:0b75e22c9231 364
RobMeades 0:0b75e22c9231 365 debug_if(_debug_trace_on, "Position found at index %d\n", a);
RobMeades 0:0b75e22c9231 366
RobMeades 0:0b75e22c9231 367 memcpy(&_loc[a], &_loc[CELL_MAX_HYP - 1], sizeof(*_loc));
RobMeades 0:0b75e22c9231 368
RobMeades 0:0b75e22c9231 369 _loc[a].sensor = (b == 0) ? CELL_LAST : (b == 1) ? CELL_GNSS :
RobMeades 0:0b75e22c9231 370 (b == 2) ? CELL_LOCATE : (b == 3) ? CELL_HYBRID : CELL_LAST;
rob.meades@u-blox.com 1:26a67ab07275 371 _loc[a].time.tm_year -= 1900;
RobMeades 0:0b75e22c9231 372 _loc[a].time.tm_mon -= 1;
RobMeades 0:0b75e22c9231 373 _loc[a].time.tm_wday = 0;
RobMeades 0:0b75e22c9231 374 _loc[a].time.tm_yday = 0;
rob.meades@u-blox.com 1:26a67ab07275 375 _loc[a].speed = 0;
rob.meades@u-blox.com 1:26a67ab07275 376 _loc[a].direction = 0;
rob.meades@u-blox.com 1:26a67ab07275 377 _loc[a].verticalAcc = 0;
rob.meades@u-blox.com 1:26a67ab07275 378 _loc[a].svUsed = 0;
RobMeades 4:39acbc0111eb 379 // Uncertainty can appear as 4294967, which is
RobMeades 4:39acbc0111eb 380 // (2^32 - 1) / 1000, or -1. Since it is confusing
RobMeades 4:39acbc0111eb 381 // for the user to get a large positive number instead
RobMeades 4:39acbc0111eb 382 // of 0 -1, set it to -1 in th1s case.
RobMeades 4:39acbc0111eb 383 if (_loc[a].uncertainty == 4294967) {
RobMeades 4:39acbc0111eb 384 _loc[a].uncertainty = -1;
RobMeades 4:39acbc0111eb 385 }
rob.meades@u-blox.com 1:26a67ab07275 386 _loc[a].validData = true;
rob.meades@u-blox.com 1:26a67ab07275 387 _locRcvPos++;
rob.meades@u-blox.com 1:26a67ab07275 388 }
rob.meades@u-blox.com 1:26a67ab07275 389 // Response type 2, sensor used 0
rob.meades@u-blox.com 1:26a67ab07275 390 //+UULOC: <sol>,<num>,<sensor_used>,<date>,<time>,<lat>,<long>,<alt>,<uncertainty>
RobMeades 4:39acbc0111eb 391 } else if (sscanf(urcBuf, " %d,%d,%d,%d/%d/%d,%d:%d:%d.%*d,%f,%f,%d,%d",
rob.meades@u-blox.com 1:26a67ab07275 392 &a, &_locExpPos, &b,
rob.meades@u-blox.com 1:26a67ab07275 393 &_loc[CELL_MAX_HYP - 1].time.tm_mday,
rob.meades@u-blox.com 1:26a67ab07275 394 &_loc[CELL_MAX_HYP - 1].time.tm_mon,
rob.meades@u-blox.com 1:26a67ab07275 395 &_loc[CELL_MAX_HYP - 1].time.tm_year,
rob.meades@u-blox.com 1:26a67ab07275 396 &_loc[CELL_MAX_HYP - 1].time.tm_hour,
rob.meades@u-blox.com 1:26a67ab07275 397 &_loc[CELL_MAX_HYP - 1].time.tm_min,
rob.meades@u-blox.com 1:26a67ab07275 398 &_loc[CELL_MAX_HYP - 1].time.tm_sec,
rob.meades@u-blox.com 1:26a67ab07275 399 &_loc[CELL_MAX_HYP - 1].latitude,
rob.meades@u-blox.com 1:26a67ab07275 400 &_loc[CELL_MAX_HYP - 1].longitude,
rob.meades@u-blox.com 1:26a67ab07275 401 &_loc[CELL_MAX_HYP - 1].altitude,
rob.meades@u-blox.com 1:26a67ab07275 402 &_loc[CELL_MAX_HYP - 1].uncertainty) == 13) {
rob.meades@u-blox.com 1:26a67ab07275 403 if (--a >= 0) {
rob.meades@u-blox.com 1:26a67ab07275 404
rob.meades@u-blox.com 1:26a67ab07275 405 debug_if(_debug_trace_on, "Position found at index %d\n", a);
rob.meades@u-blox.com 1:26a67ab07275 406
rob.meades@u-blox.com 1:26a67ab07275 407 memcpy(&_loc[a], &_loc[CELL_MAX_HYP - 1], sizeof(*_loc));
rob.meades@u-blox.com 1:26a67ab07275 408
rob.meades@u-blox.com 1:26a67ab07275 409 _loc[a].sensor = (b == 0) ? CELL_LAST : (b == 1) ? CELL_GNSS :
rob.meades@u-blox.com 1:26a67ab07275 410 (b == 2) ? CELL_LOCATE : (b == 3) ? CELL_HYBRID : CELL_LAST;
rob.meades@u-blox.com 1:26a67ab07275 411 _loc[a].time.tm_year -= 1900;
rob.meades@u-blox.com 1:26a67ab07275 412 _loc[a].time.tm_mon -= 1;
rob.meades@u-blox.com 1:26a67ab07275 413 _loc[a].time.tm_wday = 0;
rob.meades@u-blox.com 1:26a67ab07275 414 _loc[a].time.tm_yday = 0;
rob.meades@u-blox.com 1:26a67ab07275 415 _loc[a].speed = 0;
rob.meades@u-blox.com 1:26a67ab07275 416 _loc[a].direction = 0;
rob.meades@u-blox.com 1:26a67ab07275 417 _loc[a].verticalAcc = 0;
rob.meades@u-blox.com 1:26a67ab07275 418 _loc[a].svUsed = 0;
RobMeades 4:39acbc0111eb 419 // Uncertainty can appear as 4294967, which is
RobMeades 4:39acbc0111eb 420 // (2^32 - 1) / 1000, or -1. Since it is confusing
RobMeades 4:39acbc0111eb 421 // for the user to get a large positive number instead
RobMeades 4:39acbc0111eb 422 // of 0 -1, set it to -1 in th1s case.
RobMeades 4:39acbc0111eb 423 if (_loc[a].uncertainty == 4294967) {
RobMeades 4:39acbc0111eb 424 _loc[a].uncertainty = -1;
RobMeades 4:39acbc0111eb 425 }
RobMeades 0:0b75e22c9231 426 _loc[a].validData = true;
RobMeades 0:0b75e22c9231 427 _locRcvPos++;
RobMeades 0:0b75e22c9231 428 }
RobMeades 0:0b75e22c9231 429 }
RobMeades 0:0b75e22c9231 430 }
RobMeades 0:0b75e22c9231 431 }
RobMeades 0:0b75e22c9231 432
RobMeades 0:0b75e22c9231 433 /**********************************************************************
RobMeades 0:0b75e22c9231 434 * PUBLIC METHODS: GENERAL
RobMeades 0:0b75e22c9231 435 **********************************************************************/
RobMeades 0:0b75e22c9231 436
RobMeades 0:0b75e22c9231 437 // Constructor.
RobMeades 0:0b75e22c9231 438 UbloxATCellularInterfaceExt::UbloxATCellularInterfaceExt(PinName tx,
RobMeades 0:0b75e22c9231 439 PinName rx,
RobMeades 0:0b75e22c9231 440 int baud,
RobMeades 0:0b75e22c9231 441 bool debugOn):
RobMeades 0:0b75e22c9231 442 UbloxATCellularInterface(tx, rx, baud, debugOn)
RobMeades 0:0b75e22c9231 443 {
RobMeades 0:0b75e22c9231 444 // Zero HTTP stuff
RobMeades 0:0b75e22c9231 445 memset(_httpProfiles, 0, sizeof(_httpProfiles));
RobMeades 0:0b75e22c9231 446 for (unsigned int profile = 0; profile < sizeof(_httpProfiles) / sizeof(_httpProfiles[0]);
RobMeades 0:0b75e22c9231 447 profile++) {
RobMeades 0:0b75e22c9231 448 _httpProfiles[profile].modemHandle = HTTP_PROF_UNUSED;
RobMeades 0:0b75e22c9231 449 }
RobMeades 0:0b75e22c9231 450
RobMeades 0:0b75e22c9231 451 // Zero FTP stuff
RobMeades 0:0b75e22c9231 452 _ftpTimeout = TIMEOUT_BLOCKING;
RobMeades 0:0b75e22c9231 453 _lastFtpOpCodeResult = FTP_OP_CODE_UNUSED;
RobMeades 0:0b75e22c9231 454 _lastFtpResult = 0;
RobMeades 0:0b75e22c9231 455 _lastFtpOpCodeData = FTP_OP_CODE_UNUSED;
RobMeades 0:0b75e22c9231 456 _ftpBuf = NULL;
RobMeades 0:0b75e22c9231 457 _ftpBufLen = 0;
RobMeades 0:0b75e22c9231 458 _ftpError.eClass = 0;
RobMeades 0:0b75e22c9231 459 _ftpError.eCode = 0;
RobMeades 0:0b75e22c9231 460
RobMeades 0:0b75e22c9231 461 // Zero Cell Locate stuff
RobMeades 0:0b75e22c9231 462 _locRcvPos = 0;
RobMeades 0:0b75e22c9231 463 _locExpPos = 0;
RobMeades 0:0b75e22c9231 464
RobMeades 0:0b75e22c9231 465 // URC handler for HTTP
RobMeades 0:0b75e22c9231 466 _at->oob("+UUHTTPCR", callback(this, &UbloxATCellularInterfaceExt::UUHTTPCR_URC));
RobMeades 0:0b75e22c9231 467
RobMeades 0:0b75e22c9231 468 // URC handlers for FTP
RobMeades 0:0b75e22c9231 469 _at->oob("+UUFTPCR", callback(this, &UbloxATCellularInterfaceExt::UUFTPCR_URC));
RobMeades 0:0b75e22c9231 470 _at->oob("+UUFTPCD", callback(this, &UbloxATCellularInterfaceExt::UUFTPCD_URC));
RobMeades 0:0b75e22c9231 471
RobMeades 0:0b75e22c9231 472 // URC handlers for Cell Locate
RobMeades 4:39acbc0111eb 473 _at->oob("+UULOCIND:", callback(this, &UbloxATCellularInterfaceExt::UULOCIND_URC));
RobMeades 4:39acbc0111eb 474 _at->oob("+UULOC:", callback(this, &UbloxATCellularInterfaceExt::UULOC_URC));
RobMeades 0:0b75e22c9231 475 }
RobMeades 0:0b75e22c9231 476
RobMeades 0:0b75e22c9231 477 // Destructor.
RobMeades 0:0b75e22c9231 478 UbloxATCellularInterfaceExt::~UbloxATCellularInterfaceExt()
RobMeades 0:0b75e22c9231 479 {
RobMeades 0:0b75e22c9231 480 }
RobMeades 0:0b75e22c9231 481
RobMeades 0:0b75e22c9231 482 /**********************************************************************
RobMeades 0:0b75e22c9231 483 * PUBLIC METHODS: HTTP
RobMeades 0:0b75e22c9231 484 **********************************************************************/
RobMeades 0:0b75e22c9231 485
RobMeades 0:0b75e22c9231 486 // Find a free profile.
RobMeades 0:0b75e22c9231 487 int UbloxATCellularInterfaceExt::httpAllocProfile()
RobMeades 0:0b75e22c9231 488 {
RobMeades 0:0b75e22c9231 489 int profile = HTTP_PROF_UNUSED;
RobMeades 0:0b75e22c9231 490 LOCK();
RobMeades 0:0b75e22c9231 491
RobMeades 0:0b75e22c9231 492 // Find a free HTTP profile
RobMeades 0:0b75e22c9231 493 profile = findProfile();
RobMeades 0:0b75e22c9231 494 debug_if(_debug_trace_on, "httpFindProfile: profile is %d\n", profile);
RobMeades 0:0b75e22c9231 495
RobMeades 0:0b75e22c9231 496 if (profile != HTTP_PROF_UNUSED) {
RobMeades 0:0b75e22c9231 497 _httpProfiles[profile].modemHandle = 1;
RobMeades 0:0b75e22c9231 498 _httpProfiles[profile].timeout = TIMEOUT_BLOCKING;
RobMeades 0:0b75e22c9231 499 _httpProfiles[profile].pending = false;
RobMeades 0:0b75e22c9231 500 _httpProfiles[profile].cmd = -1;
RobMeades 0:0b75e22c9231 501 _httpProfiles[profile].result = -1;
RobMeades 0:0b75e22c9231 502 }
RobMeades 0:0b75e22c9231 503
RobMeades 0:0b75e22c9231 504 UNLOCK();
RobMeades 0:0b75e22c9231 505 return profile;
RobMeades 0:0b75e22c9231 506 }
RobMeades 0:0b75e22c9231 507
RobMeades 0:0b75e22c9231 508 // Free a profile.
RobMeades 0:0b75e22c9231 509 bool UbloxATCellularInterfaceExt::httpFreeProfile(int profile)
RobMeades 0:0b75e22c9231 510 {
RobMeades 0:0b75e22c9231 511 bool success = false;
RobMeades 0:0b75e22c9231 512 LOCK();
RobMeades 0:0b75e22c9231 513
RobMeades 0:0b75e22c9231 514 if (IS_PROFILE(profile)) {
RobMeades 0:0b75e22c9231 515 debug_if(_debug_trace_on, "httpFreeProfile(%d)\n", profile);
RobMeades 0:0b75e22c9231 516 _httpProfiles[profile].modemHandle = HTTP_PROF_UNUSED;
RobMeades 0:0b75e22c9231 517 _httpProfiles[profile].timeout = TIMEOUT_BLOCKING;
RobMeades 0:0b75e22c9231 518 _httpProfiles[profile].pending = false;
RobMeades 0:0b75e22c9231 519 _httpProfiles[profile].cmd = -1;
RobMeades 0:0b75e22c9231 520 _httpProfiles[profile].result = -1;
RobMeades 0:0b75e22c9231 521 success = _at->send("AT+UHTTP=%d", profile) && _at->recv("OK");
RobMeades 0:0b75e22c9231 522 }
RobMeades 0:0b75e22c9231 523
RobMeades 0:0b75e22c9231 524 UNLOCK();
RobMeades 0:0b75e22c9231 525 return success;
RobMeades 0:0b75e22c9231 526 }
RobMeades 0:0b75e22c9231 527
RobMeades 0:0b75e22c9231 528 // Set the blocking/timeout state of a profile.
RobMeades 0:0b75e22c9231 529 bool UbloxATCellularInterfaceExt::httpSetTimeout(int profile, int timeout)
RobMeades 0:0b75e22c9231 530 {
RobMeades 0:0b75e22c9231 531 bool success = false;
RobMeades 0:0b75e22c9231 532 LOCK();
RobMeades 0:0b75e22c9231 533
RobMeades 0:0b75e22c9231 534 debug_if(_debug_trace_on, "httpSetTimeout(%d, %d)\n", profile, timeout);
RobMeades 0:0b75e22c9231 535
RobMeades 0:0b75e22c9231 536 if (IS_PROFILE(profile)) {
RobMeades 0:0b75e22c9231 537 _httpProfiles[profile].timeout = timeout;
RobMeades 0:0b75e22c9231 538 success = true;
RobMeades 0:0b75e22c9231 539 }
RobMeades 0:0b75e22c9231 540
RobMeades 0:0b75e22c9231 541 UNLOCK();
RobMeades 0:0b75e22c9231 542 return success;
RobMeades 0:0b75e22c9231 543 }
RobMeades 0:0b75e22c9231 544
RobMeades 0:0b75e22c9231 545 // Set a profile back to defaults.
RobMeades 0:0b75e22c9231 546 bool UbloxATCellularInterfaceExt::httpResetProfile(int httpProfile)
RobMeades 0:0b75e22c9231 547 {
RobMeades 0:0b75e22c9231 548 bool success = false;
RobMeades 0:0b75e22c9231 549 LOCK();
RobMeades 0:0b75e22c9231 550
RobMeades 0:0b75e22c9231 551 debug_if(_debug_trace_on, "httpResetProfile(%d)\n", httpProfile);
RobMeades 0:0b75e22c9231 552 success = _at->send("AT+UHTTP=%d", httpProfile) && _at->recv("OK");
RobMeades 0:0b75e22c9231 553
RobMeades 0:0b75e22c9231 554 UNLOCK();
RobMeades 0:0b75e22c9231 555 return success;
RobMeades 0:0b75e22c9231 556 }
RobMeades 0:0b75e22c9231 557
RobMeades 0:0b75e22c9231 558 // Set HTTP parameters.
RobMeades 0:0b75e22c9231 559 bool UbloxATCellularInterfaceExt::httpSetPar(int httpProfile,
RobMeades 0:0b75e22c9231 560 HttpOpCode httpOpCode,
RobMeades 0:0b75e22c9231 561 const char * httpInPar)
RobMeades 0:0b75e22c9231 562 {
RobMeades 0:0b75e22c9231 563 bool success = false;
RobMeades 0:0b75e22c9231 564 int httpInParNum = 0;
RobMeades 0:0b75e22c9231 565 SocketAddress address;
RobMeades 0:0b75e22c9231 566
RobMeades 0:0b75e22c9231 567 debug_if(_debug_trace_on, "httpSetPar(%d, %d, \"%s\")\n", httpProfile, httpOpCode, httpInPar);
RobMeades 0:0b75e22c9231 568 if (IS_PROFILE(httpProfile)) {
RobMeades 0:0b75e22c9231 569 LOCK();
RobMeades 0:0b75e22c9231 570
RobMeades 0:0b75e22c9231 571 switch(httpOpCode) {
RobMeades 0:0b75e22c9231 572 case HTTP_IP_ADDRESS: // 0
RobMeades 0:0b75e22c9231 573 if (gethostbyname(httpInPar, &address) == NSAPI_ERROR_OK) {
RobMeades 0:0b75e22c9231 574 success = _at->send("AT+UHTTP=%d,%d,\"%s\"",
RobMeades 0:0b75e22c9231 575 httpProfile, httpOpCode, address.get_ip_address()) &&
RobMeades 0:0b75e22c9231 576 _at->recv("OK");
RobMeades 0:0b75e22c9231 577 }
RobMeades 0:0b75e22c9231 578 break;
RobMeades 0:0b75e22c9231 579 case HTTP_SERVER_NAME: // 1
RobMeades 0:0b75e22c9231 580 case HTTP_USER_NAME: // 2
RobMeades 0:0b75e22c9231 581 case HTTP_PASSWORD: // 3
RobMeades 0:0b75e22c9231 582 success = _at->send("AT+UHTTP=%d,%d,\"%s\"", httpProfile, httpOpCode, httpInPar) &&
RobMeades 0:0b75e22c9231 583 _at->recv("OK");
RobMeades 0:0b75e22c9231 584 break;
RobMeades 0:0b75e22c9231 585
RobMeades 0:0b75e22c9231 586 case HTTP_AUTH_TYPE: // 4
RobMeades 0:0b75e22c9231 587 case HTTP_SERVER_PORT: // 5
RobMeades 0:0b75e22c9231 588 httpInParNum = atoi(httpInPar);
RobMeades 0:0b75e22c9231 589 success = _at->send("AT+UHTTP=%d,%d,%d", httpProfile, httpOpCode, httpInParNum) &&
RobMeades 0:0b75e22c9231 590 _at->recv("OK");
RobMeades 0:0b75e22c9231 591 break;
RobMeades 0:0b75e22c9231 592
RobMeades 0:0b75e22c9231 593 case HTTP_SECURE: // 6
RobMeades 0:0b75e22c9231 594 httpInParNum = atoi(httpInPar);
RobMeades 0:0b75e22c9231 595 success = _at->send("AT+UHTTP=%d,%d,%d", httpProfile, httpOpCode, httpInParNum) &&
RobMeades 0:0b75e22c9231 596 _at->recv("OK");
RobMeades 0:0b75e22c9231 597 break;
RobMeades 0:0b75e22c9231 598
RobMeades 0:0b75e22c9231 599 default:
RobMeades 0:0b75e22c9231 600 debug_if(_debug_trace_on, "httpSetPar: unknown httpOpCode %d\n", httpOpCode);
RobMeades 0:0b75e22c9231 601 break;
RobMeades 0:0b75e22c9231 602 }
RobMeades 0:0b75e22c9231 603
RobMeades 0:0b75e22c9231 604 UNLOCK();
RobMeades 0:0b75e22c9231 605 }
RobMeades 0:0b75e22c9231 606
RobMeades 0:0b75e22c9231 607 return success;
RobMeades 0:0b75e22c9231 608 }
RobMeades 0:0b75e22c9231 609
RobMeades 0:0b75e22c9231 610 // Perform an HTTP command.
RobMeades 0:0b75e22c9231 611 UbloxATCellularInterfaceExt::Error * UbloxATCellularInterfaceExt::httpCommand(int httpProfile,
RobMeades 0:0b75e22c9231 612 HttpCmd httpCmd,
RobMeades 0:0b75e22c9231 613 const char *httpPath,
RobMeades 0:0b75e22c9231 614 const char *rspFile,
RobMeades 0:0b75e22c9231 615 const char *sendStr,
RobMeades 0:0b75e22c9231 616 int httpContentType,
RobMeades 0:0b75e22c9231 617 const char *httpCustomPar,
RobMeades 0:0b75e22c9231 618 char *buf, int len)
RobMeades 0:0b75e22c9231 619 {
RobMeades 0:0b75e22c9231 620 bool atSuccess = false;
RobMeades 0:0b75e22c9231 621 bool success = false;
RobMeades 0:0b75e22c9231 622 int at_timeout;
RobMeades 0:0b75e22c9231 623 char defaultFilename[] = "http_last_response_x";
RobMeades 0:0b75e22c9231 624
RobMeades 0:0b75e22c9231 625 debug_if(_debug_trace_on, "%s\n", getHttpCmd(httpCmd));
RobMeades 0:0b75e22c9231 626
RobMeades 0:0b75e22c9231 627 if (IS_PROFILE(httpProfile)) {
RobMeades 0:0b75e22c9231 628 LOCK();
RobMeades 0:0b75e22c9231 629 at_timeout = _at_timeout; // Has to be inside LOCK()s
RobMeades 0:0b75e22c9231 630
RobMeades 0:0b75e22c9231 631 if (rspFile == NULL) {
RobMeades 0:0b75e22c9231 632 sprintf(defaultFilename + sizeof (defaultFilename) - 2, "%1d", httpProfile);
RobMeades 0:0b75e22c9231 633 rspFile = defaultFilename;
RobMeades 0:0b75e22c9231 634 }
RobMeades 0:0b75e22c9231 635
RobMeades 0:0b75e22c9231 636 switch (httpCmd) {
RobMeades 0:0b75e22c9231 637 case HTTP_HEAD:
RobMeades 0:0b75e22c9231 638 atSuccess = _at->send("AT+UHTTPC=%d,%d,\"%s\",\"%s\"", httpProfile, httpCmd,
RobMeades 0:0b75e22c9231 639 httpPath, rspFile) &&
RobMeades 0:0b75e22c9231 640 _at->recv("OK");
RobMeades 0:0b75e22c9231 641 break;
RobMeades 0:0b75e22c9231 642 case HTTP_GET:
RobMeades 0:0b75e22c9231 643 atSuccess = _at->send("AT+UHTTPC=%d,%d,\"%s\",\"%s\"", httpProfile, httpCmd,
RobMeades 0:0b75e22c9231 644 httpPath, rspFile) &&
RobMeades 0:0b75e22c9231 645 _at->recv("OK");
RobMeades 0:0b75e22c9231 646 break;
RobMeades 0:0b75e22c9231 647 case HTTP_DELETE:
RobMeades 0:0b75e22c9231 648 atSuccess = _at->send("AT+UHTTPC=%d,%d,\"%s\",\"%s\"", httpProfile, httpCmd,
RobMeades 0:0b75e22c9231 649 httpPath, rspFile) &&
RobMeades 0:0b75e22c9231 650 _at->recv("OK");
RobMeades 0:0b75e22c9231 651 break;
RobMeades 0:0b75e22c9231 652 case HTTP_PUT:
RobMeades 0:0b75e22c9231 653 // In this case the parameter sendStr is a filename
RobMeades 0:0b75e22c9231 654 atSuccess = _at->send("AT+UHTTPC=%d,%d,\"%s\",\"%s\",\"%s\"", httpProfile, httpCmd,
RobMeades 0:0b75e22c9231 655 httpPath, rspFile, sendStr) &&
RobMeades 0:0b75e22c9231 656 _at->recv("OK");
RobMeades 0:0b75e22c9231 657 break;
RobMeades 0:0b75e22c9231 658 case HTTP_POST_FILE:
RobMeades 0:0b75e22c9231 659 // In this case the parameter sendStr is a filename
RobMeades 0:0b75e22c9231 660 if (httpContentType != 6) {
RobMeades 0:0b75e22c9231 661 atSuccess = _at->send("AT+UHTTPC=%d,%d,\"%s\",\"%s\",\"%s\",%d",
RobMeades 0:0b75e22c9231 662 httpProfile, httpCmd, httpPath, rspFile, sendStr,
RobMeades 0:0b75e22c9231 663 httpContentType) &&
RobMeades 0:0b75e22c9231 664 _at->recv("OK");
RobMeades 0:0b75e22c9231 665 } else {
RobMeades 0:0b75e22c9231 666 atSuccess = _at->send("AT+UHTTPC=%d,%d,\"%s\",\"%s\",\"%s\",%d,%s",
RobMeades 0:0b75e22c9231 667 httpProfile, httpCmd, httpPath, rspFile, sendStr,
RobMeades 0:0b75e22c9231 668 httpContentType,
RobMeades 0:0b75e22c9231 669 httpCustomPar) &&
RobMeades 0:0b75e22c9231 670 _at->recv("OK");
RobMeades 0:0b75e22c9231 671 }
RobMeades 0:0b75e22c9231 672 break;
RobMeades 0:0b75e22c9231 673 case HTTP_POST_DATA:
RobMeades 0:0b75e22c9231 674 // In this case the parameter sendStr is a string containing data
RobMeades 0:0b75e22c9231 675 if (httpContentType != 6) {
RobMeades 0:0b75e22c9231 676 atSuccess = _at->send("AT+UHTTPC=%d,%d,\"%s\",\"%s\",\"%s\",%d",
RobMeades 0:0b75e22c9231 677 httpProfile, httpCmd, httpPath, rspFile, sendStr,
RobMeades 0:0b75e22c9231 678 httpContentType) &&
RobMeades 0:0b75e22c9231 679 _at->recv("OK");
RobMeades 0:0b75e22c9231 680 } else {
RobMeades 0:0b75e22c9231 681 atSuccess = _at->send("AT+UHTTPC=%d,%d,\"%s\",\"%s\",\"%s\",%d,%s",
RobMeades 0:0b75e22c9231 682 httpProfile, httpCmd, httpPath, rspFile, sendStr,
RobMeades 0:0b75e22c9231 683 httpContentType,
RobMeades 0:0b75e22c9231 684 httpCustomPar) &&
RobMeades 0:0b75e22c9231 685 _at->recv("OK");
RobMeades 0:0b75e22c9231 686 }
RobMeades 0:0b75e22c9231 687 break;
RobMeades 0:0b75e22c9231 688 default:
RobMeades 0:0b75e22c9231 689 debug_if(_debug_trace_on, "HTTP command not recognised\n");
RobMeades 0:0b75e22c9231 690 break;
RobMeades 0:0b75e22c9231 691 }
RobMeades 0:0b75e22c9231 692
RobMeades 0:0b75e22c9231 693 if (atSuccess) {
RobMeades 0:0b75e22c9231 694 Timer timer;
RobMeades 0:0b75e22c9231 695
RobMeades 0:0b75e22c9231 696 at_set_timeout(1000);
RobMeades 0:0b75e22c9231 697 _httpProfiles[httpProfile].pending = true;
RobMeades 0:0b75e22c9231 698 _httpProfiles[httpProfile].result = -1;
RobMeades 0:0b75e22c9231 699
RobMeades 0:0b75e22c9231 700 // Waiting for unsolicited result code
RobMeades 0:0b75e22c9231 701 timer.start();
RobMeades 0:0b75e22c9231 702 while (_httpProfiles[httpProfile].pending) {
RobMeades 0:0b75e22c9231 703 if (_httpProfiles[httpProfile].result != -1) {
RobMeades 0:0b75e22c9231 704 // Received unsolicited: starting its analysis
RobMeades 0:0b75e22c9231 705 _httpProfiles[httpProfile].pending = false;
RobMeades 0:0b75e22c9231 706 if (_httpProfiles[httpProfile].result == 1) {
RobMeades 0:0b75e22c9231 707 // HTTP command successfully executed
RobMeades 0:0b75e22c9231 708 if (readFile(rspFile, buf, len) >= 0) {
RobMeades 0:0b75e22c9231 709 success = true;
RobMeades 0:0b75e22c9231 710 }
RobMeades 0:0b75e22c9231 711 } else {
RobMeades 0:0b75e22c9231 712 // Retrieve the error class and code
RobMeades 0:0b75e22c9231 713 if (_at->send("AT+UHTTPER=%d", httpProfile) &&
RobMeades 0:0b75e22c9231 714 _at->recv("AT+UHTTPER=%*d,%d,%d",
RobMeades 0:0b75e22c9231 715 &(_httpProfiles[httpProfile].httpError.eClass),
RobMeades 0:0b75e22c9231 716 &(_httpProfiles[httpProfile].httpError.eCode)) &&
RobMeades 0:0b75e22c9231 717 _at->recv("OK")) {
RobMeades 0:0b75e22c9231 718 debug_if(_debug_trace_on, "HTTP error class %d, code %d\n",
RobMeades 0:0b75e22c9231 719 _httpProfiles[httpProfile].httpError.eClass,
RobMeades 0:0b75e22c9231 720 _httpProfiles[httpProfile].httpError.eCode);
RobMeades 0:0b75e22c9231 721 }
RobMeades 0:0b75e22c9231 722 }
RobMeades 0:0b75e22c9231 723 } else if (!TIMEOUT(timer, _httpProfiles[httpProfile].timeout)) {
RobMeades 0:0b75e22c9231 724 // Wait for URCs
RobMeades 0:0b75e22c9231 725 _at->recv(UNNATURAL_STRING);
RobMeades 0:0b75e22c9231 726 } else {
RobMeades 0:0b75e22c9231 727 _httpProfiles[httpProfile].pending = false;
RobMeades 0:0b75e22c9231 728 }
RobMeades 0:0b75e22c9231 729 }
RobMeades 0:0b75e22c9231 730 timer.stop();
RobMeades 0:0b75e22c9231 731
RobMeades 0:0b75e22c9231 732 at_set_timeout(at_timeout);
RobMeades 0:0b75e22c9231 733
RobMeades 0:0b75e22c9231 734 if (!success) {
RobMeades 0:0b75e22c9231 735 debug_if(_debug_trace_on, "%s: ERROR\n", getHttpCmd(httpCmd));
RobMeades 0:0b75e22c9231 736 }
RobMeades 0:0b75e22c9231 737
RobMeades 0:0b75e22c9231 738 }
RobMeades 0:0b75e22c9231 739
RobMeades 0:0b75e22c9231 740 UNLOCK();
RobMeades 0:0b75e22c9231 741 }
RobMeades 0:0b75e22c9231 742
RobMeades 0:0b75e22c9231 743 return success ? NULL : &(_httpProfiles[httpProfile].httpError);
RobMeades 0:0b75e22c9231 744 }
RobMeades 0:0b75e22c9231 745
RobMeades 0:0b75e22c9231 746 /**********************************************************************
RobMeades 0:0b75e22c9231 747 * PUBLIC METHODS: FTP
RobMeades 0:0b75e22c9231 748 **********************************************************************/
RobMeades 0:0b75e22c9231 749
RobMeades 0:0b75e22c9231 750 // Set the blocking/timeout for FTP.
RobMeades 0:0b75e22c9231 751 bool UbloxATCellularInterfaceExt::ftpSetTimeout(int timeout)
RobMeades 0:0b75e22c9231 752 {
RobMeades 0:0b75e22c9231 753 LOCK();
RobMeades 0:0b75e22c9231 754 debug_if(_debug_trace_on, "ftpSetTimeout(%d)\n", timeout);
RobMeades 0:0b75e22c9231 755 _ftpTimeout = timeout;
RobMeades 0:0b75e22c9231 756 UNLOCK();
RobMeades 0:0b75e22c9231 757
RobMeades 0:0b75e22c9231 758 return true;
RobMeades 0:0b75e22c9231 759 }
RobMeades 0:0b75e22c9231 760
RobMeades 0:0b75e22c9231 761 // Reset the FTP configuration back to defaults.
RobMeades 0:0b75e22c9231 762 bool UbloxATCellularInterfaceExt::ftpResetPar()
RobMeades 0:0b75e22c9231 763 {
RobMeades 0:0b75e22c9231 764 bool success = true;
RobMeades 0:0b75e22c9231 765 LOCK();
RobMeades 0:0b75e22c9231 766
RobMeades 0:0b75e22c9231 767 debug_if(_debug_trace_on, "ftpResetPar()\n");
RobMeades 0:0b75e22c9231 768 for (int x = 0; success && (x < NUM_FTP_OP_CODES); x++) {
RobMeades 0:0b75e22c9231 769 success = _at->send("AT+UFTP=%d", x) && _at->recv("OK");
RobMeades 0:0b75e22c9231 770 }
RobMeades 0:0b75e22c9231 771
RobMeades 0:0b75e22c9231 772 UNLOCK();
RobMeades 0:0b75e22c9231 773 return success;
RobMeades 0:0b75e22c9231 774 }
RobMeades 0:0b75e22c9231 775
RobMeades 0:0b75e22c9231 776 // Set FTP parameters.
RobMeades 0:0b75e22c9231 777 bool UbloxATCellularInterfaceExt::ftpSetPar(FtpOpCode ftpOpCode,
RobMeades 0:0b75e22c9231 778 const char * ftpInPar)
RobMeades 0:0b75e22c9231 779 {
RobMeades 0:0b75e22c9231 780 bool success = false;
RobMeades 0:0b75e22c9231 781 int ftpInParNum = 0;
RobMeades 0:0b75e22c9231 782 LOCK();
RobMeades 0:0b75e22c9231 783
RobMeades 0:0b75e22c9231 784 debug_if(_debug_trace_on, "ftpSetPar(%d, %s)\n", ftpOpCode, ftpInPar);
RobMeades 0:0b75e22c9231 785 switch (ftpOpCode) {
RobMeades 0:0b75e22c9231 786 case FTP_IP_ADDRESS: // 0
RobMeades 0:0b75e22c9231 787 case FTP_SERVER_NAME: // 1
RobMeades 0:0b75e22c9231 788 case FTP_USER_NAME: // 2
RobMeades 0:0b75e22c9231 789 case FTP_PASSWORD: // 3
RobMeades 0:0b75e22c9231 790 case FTP_ACCOUNT: // 4
RobMeades 0:0b75e22c9231 791 success = _at->send("AT+UFTP=%d,\"%s\"", ftpOpCode, ftpInPar) &&
RobMeades 0:0b75e22c9231 792 _at->recv("OK");
RobMeades 0:0b75e22c9231 793 break;
RobMeades 0:0b75e22c9231 794 case FTP_INACTIVITY_TIMEOUT: // 5
RobMeades 0:0b75e22c9231 795 case FTP_MODE: // 6
RobMeades 0:0b75e22c9231 796 case FTP_SERVER_PORT: // 7
RobMeades 0:0b75e22c9231 797 case FTP_SECURE: // 8
RobMeades 0:0b75e22c9231 798 ftpInParNum = atoi(ftpInPar);
RobMeades 0:0b75e22c9231 799 success = _at->send("AT+UFTP=%d,%d", ftpOpCode, ftpInParNum) &&
RobMeades 0:0b75e22c9231 800 _at->recv("OK");
RobMeades 0:0b75e22c9231 801 break;
RobMeades 0:0b75e22c9231 802 default:
RobMeades 0:0b75e22c9231 803 debug_if(_debug_trace_on, "ftpSetPar: unknown ftpOpCode %d\n", ftpOpCode);
RobMeades 0:0b75e22c9231 804 break;
RobMeades 0:0b75e22c9231 805 }
RobMeades 0:0b75e22c9231 806
RobMeades 0:0b75e22c9231 807 UNLOCK();
RobMeades 0:0b75e22c9231 808 return success;
RobMeades 0:0b75e22c9231 809 }
RobMeades 0:0b75e22c9231 810
RobMeades 0:0b75e22c9231 811 // Perform an FTP command.
RobMeades 0:0b75e22c9231 812 UbloxATCellularInterfaceExt::Error * UbloxATCellularInterfaceExt::ftpCommand(FtpCmd ftpCmd,
RobMeades 0:0b75e22c9231 813 const char* file1,
RobMeades 0:0b75e22c9231 814 const char* file2,
RobMeades 0:0b75e22c9231 815 int offset,
RobMeades 0:0b75e22c9231 816 char* buf, int len)
RobMeades 0:0b75e22c9231 817 {
RobMeades 0:0b75e22c9231 818 bool atSuccess = false;
RobMeades 0:0b75e22c9231 819 bool success = false;
RobMeades 0:0b75e22c9231 820 int at_timeout;
RobMeades 0:0b75e22c9231 821 LOCK();
RobMeades 0:0b75e22c9231 822 at_timeout = _at_timeout; // Has to be inside LOCK()s
RobMeades 0:0b75e22c9231 823
RobMeades 0:0b75e22c9231 824 debug_if(_debug_trace_on, "%s\n", getFtpCmd(ftpCmd));
RobMeades 0:0b75e22c9231 825 switch (ftpCmd) {
RobMeades 0:0b75e22c9231 826 case FTP_LOGOUT:
RobMeades 0:0b75e22c9231 827 case FTP_LOGIN:
RobMeades 0:0b75e22c9231 828 atSuccess = _at->send("AT+UFTPC=%d", ftpCmd) && _at->recv("OK");
RobMeades 0:0b75e22c9231 829 break;
RobMeades 0:0b75e22c9231 830 case FTP_DELETE_FILE:
RobMeades 0:0b75e22c9231 831 case FTP_CD:
RobMeades 0:0b75e22c9231 832 case FTP_MKDIR:
RobMeades 0:0b75e22c9231 833 case FTP_RMDIR:
RobMeades 0:0b75e22c9231 834 case FTP_FOTA_FILE:
RobMeades 0:0b75e22c9231 835 atSuccess = _at->send("AT+UFTPC=%d,\"%s\"", ftpCmd, file1) &&
RobMeades 0:0b75e22c9231 836 _at->recv("OK");
RobMeades 0:0b75e22c9231 837 break;
RobMeades 0:0b75e22c9231 838 case FTP_RENAME_FILE:
RobMeades 0:0b75e22c9231 839 atSuccess = _at->send("AT+UFTPC=%d,\"%s\",\"%s\"",
RobMeades 0:0b75e22c9231 840 ftpCmd, file1, file2) &&
RobMeades 0:0b75e22c9231 841 _at->recv("OK");
RobMeades 0:0b75e22c9231 842 break;
RobMeades 0:0b75e22c9231 843 case FTP_GET_FILE:
RobMeades 0:0b75e22c9231 844 case FTP_PUT_FILE:
RobMeades 0:0b75e22c9231 845 if (file2 == NULL) {
RobMeades 0:0b75e22c9231 846 file2 = file1;
RobMeades 0:0b75e22c9231 847 }
RobMeades 0:0b75e22c9231 848 atSuccess = _at->send("AT+UFTPC=%d,\"%s\",\"%s\",%d",
RobMeades 0:0b75e22c9231 849 ftpCmd, file1, file2, offset) &&
RobMeades 0:0b75e22c9231 850 _at->recv("OK");
RobMeades 0:0b75e22c9231 851 break;
RobMeades 0:0b75e22c9231 852 case FTP_FILE_INFO:
RobMeades 0:0b75e22c9231 853 case FTP_LS:
RobMeades 0:0b75e22c9231 854 _ftpBuf = buf;
RobMeades 0:0b75e22c9231 855 _ftpBufLen = len;
RobMeades 0:0b75e22c9231 856 // Add a terminator in case nothing comes back
RobMeades 0:0b75e22c9231 857 if (_ftpBufLen > 0) {
RobMeades 0:0b75e22c9231 858 *_ftpBuf = 0;
RobMeades 0:0b75e22c9231 859 }
RobMeades 0:0b75e22c9231 860 if (file1 == NULL) {
RobMeades 0:0b75e22c9231 861 atSuccess = _at->send("AT+UFTPC=%d", ftpCmd) &&
RobMeades 0:0b75e22c9231 862 _at->recv("OK");
RobMeades 0:0b75e22c9231 863 } else {
RobMeades 0:0b75e22c9231 864 atSuccess = _at->send("AT+UFTPC=%d,\"%s\"", ftpCmd, file1) &&
RobMeades 0:0b75e22c9231 865 _at->recv("OK");
RobMeades 0:0b75e22c9231 866 }
RobMeades 0:0b75e22c9231 867 break;
RobMeades 0:0b75e22c9231 868 default:
RobMeades 0:0b75e22c9231 869 debug_if(_debug_trace_on, "FTP command not recognised/supported\n");
RobMeades 0:0b75e22c9231 870 break;
RobMeades 0:0b75e22c9231 871 }
RobMeades 0:0b75e22c9231 872
RobMeades 0:0b75e22c9231 873 // Wait for the result to arrive back
RobMeades 0:0b75e22c9231 874 if (atSuccess) {
RobMeades 0:0b75e22c9231 875 Timer timer;
RobMeades 0:0b75e22c9231 876
RobMeades 0:0b75e22c9231 877 at_set_timeout(1000);
RobMeades 0:0b75e22c9231 878 _lastFtpOpCodeData = FTP_OP_CODE_UNUSED;
RobMeades 0:0b75e22c9231 879 _lastFtpOpCodeResult = FTP_OP_CODE_UNUSED;
RobMeades 0:0b75e22c9231 880 _lastFtpResult = -1; // just for safety
RobMeades 0:0b75e22c9231 881 // Waiting for result to arrive
RobMeades 0:0b75e22c9231 882 timer.start();
RobMeades 0:0b75e22c9231 883 while ((_lastFtpOpCodeResult == FTP_OP_CODE_UNUSED) &&
RobMeades 0:0b75e22c9231 884 !TIMEOUT(timer, _ftpTimeout)) {
RobMeades 0:0b75e22c9231 885 _at->recv(UNNATURAL_STRING);
RobMeades 0:0b75e22c9231 886 }
RobMeades 0:0b75e22c9231 887 timer.stop();
RobMeades 0:0b75e22c9231 888
RobMeades 0:0b75e22c9231 889 if ((_lastFtpOpCodeResult == ftpCmd) && (_lastFtpResult == 1)) {
RobMeades 0:0b75e22c9231 890 // Got a result for our FTP op code and it is good
RobMeades 0:0b75e22c9231 891 success = true;
RobMeades 0:0b75e22c9231 892 } else {
RobMeades 0:0b75e22c9231 893 // Retrieve the error class and code
RobMeades 0:0b75e22c9231 894 if (_at->send("AT+UFTPER") &&
RobMeades 0:0b75e22c9231 895 _at->recv("+UFTPER:%d,%d", &(_ftpError.eClass), &(_ftpError.eCode)) &&
RobMeades 0:0b75e22c9231 896 _at->recv("OK")) {
RobMeades 0:0b75e22c9231 897 debug_if(_debug_trace_on, "FTP Error class %d, code %d\n",
RobMeades 0:0b75e22c9231 898 _ftpError.eClass, _ftpError.eCode);
RobMeades 0:0b75e22c9231 899 }
RobMeades 0:0b75e22c9231 900 }
RobMeades 0:0b75e22c9231 901
RobMeades 0:0b75e22c9231 902 at_set_timeout(at_timeout);
RobMeades 0:0b75e22c9231 903
RobMeades 0:0b75e22c9231 904 if (!success) {
RobMeades 0:0b75e22c9231 905 debug_if(_debug_trace_on, "%s: ERROR\n", getFtpCmd(ftpCmd));
RobMeades 0:0b75e22c9231 906 }
RobMeades 0:0b75e22c9231 907 }
RobMeades 0:0b75e22c9231 908
RobMeades 0:0b75e22c9231 909 // Set these back to nothing to stop the URC splatting
RobMeades 0:0b75e22c9231 910 _ftpBuf = NULL;
RobMeades 0:0b75e22c9231 911 _ftpBufLen = 0;
RobMeades 0:0b75e22c9231 912
RobMeades 0:0b75e22c9231 913 UNLOCK();
RobMeades 0:0b75e22c9231 914 return success ? NULL : &_ftpError;
RobMeades 0:0b75e22c9231 915 }
RobMeades 0:0b75e22c9231 916
RobMeades 0:0b75e22c9231 917 /**********************************************************************
RobMeades 0:0b75e22c9231 918 * PUBLIC METHODS: Cell Locate
RobMeades 0:0b75e22c9231 919 **********************************************************************/
RobMeades 0:0b75e22c9231 920
RobMeades 0:0b75e22c9231 921 // Configure CellLocate TCP Aiding server.
RobMeades 0:0b75e22c9231 922 bool UbloxATCellularInterfaceExt::cellLocSrvTcp(const char* token,
RobMeades 0:0b75e22c9231 923 const char* server_1,
RobMeades 0:0b75e22c9231 924 const char* server_2,
RobMeades 0:0b75e22c9231 925 int days, int period,
RobMeades 0:0b75e22c9231 926 int resolution)
RobMeades 0:0b75e22c9231 927 {
RobMeades 0:0b75e22c9231 928 bool success = false;
RobMeades 0:0b75e22c9231 929 LOCK();
RobMeades 0:0b75e22c9231 930
RobMeades 0:0b75e22c9231 931 if ((_dev_info.dev == DEV_LISA_U2_03S) || (_dev_info.dev == DEV_SARA_U2)){
RobMeades 0:0b75e22c9231 932 success = _at->send("AT+UGSRV=\"%s\",\"%s\",\"%s\",%d,%d,%d",
RobMeades 0:0b75e22c9231 933 server_1, server_2, token, days, period, resolution) &&
RobMeades 0:0b75e22c9231 934 _at->recv("OK");
RobMeades 0:0b75e22c9231 935 }
RobMeades 0:0b75e22c9231 936
RobMeades 0:0b75e22c9231 937 UNLOCK();
RobMeades 0:0b75e22c9231 938 return success;
RobMeades 0:0b75e22c9231 939 }
RobMeades 0:0b75e22c9231 940
RobMeades 0:0b75e22c9231 941 // Configure CellLocate UDP Aiding server.
RobMeades 0:0b75e22c9231 942 bool UbloxATCellularInterfaceExt::cellLocSrvUdp(const char* server_1,
RobMeades 0:0b75e22c9231 943 int port, int latency,
RobMeades 0:0b75e22c9231 944 int mode)
RobMeades 0:0b75e22c9231 945 {
RobMeades 0:0b75e22c9231 946
RobMeades 0:0b75e22c9231 947 bool success = false;
RobMeades 0:0b75e22c9231 948 LOCK();
RobMeades 0:0b75e22c9231 949
RobMeades 0:0b75e22c9231 950 if (_dev_info.dev != DEV_TOBY_L2) {
RobMeades 0:0b75e22c9231 951 success = _at->send("AT+UGAOP=\"%s\",%d,%d,%d", server_1, port, latency, mode) &&
RobMeades 0:0b75e22c9231 952 _at->recv("OK");
RobMeades 0:0b75e22c9231 953 }
RobMeades 0:0b75e22c9231 954
RobMeades 0:0b75e22c9231 955 UNLOCK();
RobMeades 0:0b75e22c9231 956 return success;
RobMeades 0:0b75e22c9231 957 }
RobMeades 0:0b75e22c9231 958
RobMeades 0:0b75e22c9231 959 // Configure Cell Locate location sensor.
RobMeades 0:0b75e22c9231 960 bool UbloxATCellularInterfaceExt::cellLocConfig(int scanMode)
RobMeades 0:0b75e22c9231 961 {
RobMeades 0:0b75e22c9231 962 bool success;
RobMeades 0:0b75e22c9231 963 LOCK();
RobMeades 0:0b75e22c9231 964
RobMeades 0:0b75e22c9231 965 success = _at->send("AT+ULOCCELL=%d", scanMode) &&
RobMeades 0:0b75e22c9231 966 _at->recv("OK");
RobMeades 0:0b75e22c9231 967
RobMeades 0:0b75e22c9231 968 UNLOCK();
RobMeades 0:0b75e22c9231 969 return success;
RobMeades 0:0b75e22c9231 970 }
RobMeades 0:0b75e22c9231 971
RobMeades 0:0b75e22c9231 972 // Request CellLocate.
RobMeades 0:0b75e22c9231 973 bool UbloxATCellularInterfaceExt::cellLocRequest(CellSensType sensor,
RobMeades 0:0b75e22c9231 974 int timeout,
RobMeades 0:0b75e22c9231 975 int accuracy,
RobMeades 0:0b75e22c9231 976 CellRespType type,
RobMeades 0:0b75e22c9231 977 int hypothesis)
RobMeades 0:0b75e22c9231 978 {
RobMeades 0:0b75e22c9231 979 bool success = false;
RobMeades 0:0b75e22c9231 980
RobMeades 0:0b75e22c9231 981 if ((hypothesis <= CELL_MAX_HYP) &&
RobMeades 0:0b75e22c9231 982 !((hypothesis > 1) && (type != CELL_MULTIHYP))) {
RobMeades 0:0b75e22c9231 983
RobMeades 0:0b75e22c9231 984 LOCK();
RobMeades 0:0b75e22c9231 985
RobMeades 0:0b75e22c9231 986 _locRcvPos = 0;
RobMeades 0:0b75e22c9231 987 _locExpPos = 0;
RobMeades 0:0b75e22c9231 988
RobMeades 0:0b75e22c9231 989 for (int i = 0; i < hypothesis; i++) {
RobMeades 0:0b75e22c9231 990 _loc[i].validData = false;
RobMeades 0:0b75e22c9231 991 }
RobMeades 0:0b75e22c9231 992
RobMeades 0:0b75e22c9231 993 // Switch on the URC
RobMeades 0:0b75e22c9231 994 if (_at->send("AT+ULOCIND=1") && _at->recv("OK")) {
RobMeades 0:0b75e22c9231 995 // Switch on Cell Locate
RobMeades 0:0b75e22c9231 996 success = _at->send("AT+ULOC=2,%d,%d,%d,%d,%d", sensor, type, timeout, accuracy, hypothesis) &&
RobMeades 0:0b75e22c9231 997 _at->recv("OK");
RobMeades 0:0b75e22c9231 998 // Answers are picked up by the URC
RobMeades 0:0b75e22c9231 999 }
RobMeades 0:0b75e22c9231 1000
RobMeades 0:0b75e22c9231 1001 UNLOCK();
RobMeades 0:0b75e22c9231 1002 }
RobMeades 0:0b75e22c9231 1003
RobMeades 0:0b75e22c9231 1004 return success;
RobMeades 0:0b75e22c9231 1005 }
RobMeades 0:0b75e22c9231 1006
RobMeades 0:0b75e22c9231 1007 // Get a position record.
RobMeades 0:0b75e22c9231 1008 bool UbloxATCellularInterfaceExt::cellLocGetData(CellLocData *data, int index)
RobMeades 0:0b75e22c9231 1009 {
RobMeades 0:0b75e22c9231 1010 bool success = false;
RobMeades 0:0b75e22c9231 1011
RobMeades 0:0b75e22c9231 1012 if (_loc[index].validData) {
RobMeades 0:0b75e22c9231 1013 LOCK();
RobMeades 0:0b75e22c9231 1014 memcpy(data, &_loc[index], sizeof(*_loc));
RobMeades 0:0b75e22c9231 1015 success = true;
RobMeades 0:0b75e22c9231 1016 UNLOCK();
RobMeades 0:0b75e22c9231 1017 }
RobMeades 0:0b75e22c9231 1018
RobMeades 0:0b75e22c9231 1019 return success;
RobMeades 0:0b75e22c9231 1020 }
RobMeades 0:0b75e22c9231 1021
RobMeades 0:0b75e22c9231 1022 // Get number of position records received.
RobMeades 0:0b75e22c9231 1023 int UbloxATCellularInterfaceExt::cellLocGetRes()
RobMeades 0:0b75e22c9231 1024 {
RobMeades 0:0b75e22c9231 1025 int at_timeout;
RobMeades 0:0b75e22c9231 1026 LOCK();
RobMeades 0:0b75e22c9231 1027
RobMeades 0:0b75e22c9231 1028 at_timeout = _at_timeout; // Has to be inside LOCK()s
RobMeades 0:0b75e22c9231 1029 at_set_timeout(1000);
RobMeades 0:0b75e22c9231 1030 // Wait for URCs
RobMeades 0:0b75e22c9231 1031 _at->recv(UNNATURAL_STRING);
RobMeades 0:0b75e22c9231 1032 at_set_timeout(at_timeout);
RobMeades 0:0b75e22c9231 1033
RobMeades 0:0b75e22c9231 1034 UNLOCK();
RobMeades 0:0b75e22c9231 1035 return _locRcvPos;
RobMeades 0:0b75e22c9231 1036 }
RobMeades 0:0b75e22c9231 1037
RobMeades 0:0b75e22c9231 1038 // Get number of positions records expected to be received.
RobMeades 0:0b75e22c9231 1039 int UbloxATCellularInterfaceExt::cellLocGetExpRes()
RobMeades 0:0b75e22c9231 1040 {
RobMeades 0:0b75e22c9231 1041 int numRecords = 0;
RobMeades 0:0b75e22c9231 1042 LOCK();
RobMeades 0:0b75e22c9231 1043
RobMeades 0:0b75e22c9231 1044 _at->recv("OK");
RobMeades 0:0b75e22c9231 1045
RobMeades 0:0b75e22c9231 1046 if (_locRcvPos > 0) {
RobMeades 0:0b75e22c9231 1047 numRecords = _locExpPos;
RobMeades 0:0b75e22c9231 1048 }
RobMeades 0:0b75e22c9231 1049
RobMeades 0:0b75e22c9231 1050 UNLOCK();
RobMeades 0:0b75e22c9231 1051 return numRecords;
RobMeades 0:0b75e22c9231 1052 }
RobMeades 0:0b75e22c9231 1053
RobMeades 0:0b75e22c9231 1054 // End of file
RobMeades 0:0b75e22c9231 1055