Adding ability to set priority of the Rx thread

Dependencies:   ublox-at-cellular-interface

Fork of ublox-at-cellular-interface-ext by u-blox

Committer:
amq
Date:
Tue Oct 30 18:54:19 2018 +0000
Revision:
15:6f0a1ecc8cec
Parent:
11:3631f62bb359
Add ability to set priority for the Rx thread

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RobMeades 0:0b75e22c9231 1 /* Copyright (c) 2017 ARM 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 #ifndef _UBLOX_AT_CELLULAR_INTERFACE_EXT_
RobMeades 0:0b75e22c9231 17 #define _UBLOX_AT_CELLULAR_INTERFACE_EXT_
RobMeades 0:0b75e22c9231 18
rob.meades@u-blox.com 5:9fd89567f769 19 #include "UbloxATCellularInterface.h"
RobMeades 0:0b75e22c9231 20 #include "UbloxCellularDriverGen.h"
RobMeades 0:0b75e22c9231 21
RobMeades 0:0b75e22c9231 22 /**UbloxATCellularInterfaceExt class.
RobMeades 0:0b75e22c9231 23 *
RobMeades 0:0b75e22c9231 24 * This interface extends the UbloxATCellularInterface to
RobMeades 0:0b75e22c9231 25 * include other features that use the IP stack on board the
RobMeades 0:0b75e22c9231 26 * cellular modem: HTTP, FTP and Cell Locate.
RobMeades 0:0b75e22c9231 27 *
RobMeades 0:0b75e22c9231 28 * Note: the UbloxCellularGeneric class is required because
RobMeades 0:0b75e22c9231 29 * reading a large HTTP response is performed via a modem
RobMeades 0:0b75e22c9231 30 * file system call and the UbloxCellularGeneric class is
RobMeades 0:0b75e22c9231 31 * where modem file system support is provided.
RobMeades 0:0b75e22c9231 32 */
RobMeades 0:0b75e22c9231 33 class UbloxATCellularInterfaceExt : public UbloxATCellularInterface, public UbloxCellularDriverGen {
RobMeades 0:0b75e22c9231 34
RobMeades 0:0b75e22c9231 35 public:
RobMeades 0:0b75e22c9231 36 /** Constructor.
RobMeades 0:0b75e22c9231 37 *
RobMeades 0:0b75e22c9231 38 * @param tx the UART TX data pin to which the modem is attached.
RobMeades 0:0b75e22c9231 39 * @param rx the UART RX data pin to which the modem is attached.
RobMeades 0:0b75e22c9231 40 * @param baud the UART baud rate.
RobMeades 0:0b75e22c9231 41 * @param debugOn true to switch AT interface debug on, otherwise false.
RobMeades 0:0b75e22c9231 42 */
RobMeades 0:0b75e22c9231 43 UbloxATCellularInterfaceExt(PinName tx = MDMTXD,
RobMeades 0:0b75e22c9231 44 PinName rx = MDMRXD,
RobMeades 0:0b75e22c9231 45 int baud = MBED_CONF_UBLOX_CELL_BAUD_RATE,
amq 15:6f0a1ecc8cec 46 bool debugOn = false,
amq 15:6f0a1ecc8cec 47 osPriority priority = osPriorityNormal);
RobMeades 0:0b75e22c9231 48
RobMeades 0:0b75e22c9231 49 /* Destructor.
RobMeades 0:0b75e22c9231 50 */
RobMeades 0:0b75e22c9231 51 virtual ~UbloxATCellularInterfaceExt();
RobMeades 0:0b75e22c9231 52
RobMeades 0:0b75e22c9231 53 /**********************************************************************
RobMeades 0:0b75e22c9231 54 * PUBLIC: General
RobMeades 0:0b75e22c9231 55 **********************************************************************/
RobMeades 0:0b75e22c9231 56
RobMeades 0:0b75e22c9231 57 /** Infinite timeout.
RobMeades 0:0b75e22c9231 58 */
RobMeades 0:0b75e22c9231 59 #define TIMEOUT_BLOCKING -1
RobMeades 0:0b75e22c9231 60
RobMeades 0:0b75e22c9231 61 /** A struct containing an HTTP or FTP error class and code
RobMeades 0:0b75e22c9231 62 */
RobMeades 0:0b75e22c9231 63 typedef struct {
RobMeades 0:0b75e22c9231 64 int eClass;
RobMeades 0:0b75e22c9231 65 int eCode;
RobMeades 0:0b75e22c9231 66 } Error;
RobMeades 0:0b75e22c9231 67
RobMeades 0:0b75e22c9231 68 /**********************************************************************
RobMeades 0:0b75e22c9231 69 * PUBLIC: HTTP
RobMeades 0:0b75e22c9231 70 **********************************************************************/
RobMeades 0:0b75e22c9231 71
RobMeades 0:0b75e22c9231 72 /** HTTP profile unused marker.
RobMeades 0:0b75e22c9231 73 */
RobMeades 0:0b75e22c9231 74 #define HTTP_PROF_UNUSED -1
RobMeades 0:0b75e22c9231 75
RobMeades 0:0b75e22c9231 76 /** HTTP configuration parameters (reference to HTTP control +UHTTP).
RobMeades 0:0b75e22c9231 77 */
RobMeades 0:0b75e22c9231 78 typedef enum {
RobMeades 0:0b75e22c9231 79 HTTP_IP_ADDRESS = 0,
RobMeades 0:0b75e22c9231 80 HTTP_SERVER_NAME = 1,
RobMeades 0:0b75e22c9231 81 HTTP_USER_NAME = 2,
RobMeades 0:0b75e22c9231 82 HTTP_PASSWORD = 3,
RobMeades 0:0b75e22c9231 83 HTTP_AUTH_TYPE = 4,
RobMeades 0:0b75e22c9231 84 HTTP_SERVER_PORT = 5,
RobMeades 0:0b75e22c9231 85 HTTP_SECURE = 6
RobMeades 0:0b75e22c9231 86 } HttpOpCode;
RobMeades 0:0b75e22c9231 87
RobMeades 0:0b75e22c9231 88 /** Type of HTTP Command.
RobMeades 0:0b75e22c9231 89 */
RobMeades 0:0b75e22c9231 90 typedef enum {
RobMeades 0:0b75e22c9231 91 HTTP_HEAD = 0,
RobMeades 0:0b75e22c9231 92 HTTP_GET = 1,
RobMeades 0:0b75e22c9231 93 HTTP_DELETE = 2,
RobMeades 0:0b75e22c9231 94 HTTP_PUT = 3,
RobMeades 0:0b75e22c9231 95 HTTP_POST_FILE = 4,
RobMeades 0:0b75e22c9231 96 HTTP_POST_DATA = 5
RobMeades 0:0b75e22c9231 97 } HttpCmd;
RobMeades 0:0b75e22c9231 98
RobMeades 0:0b75e22c9231 99 /** HTTP content types.
RobMeades 0:0b75e22c9231 100 */
RobMeades 0:0b75e22c9231 101 typedef enum {
RobMeades 0:0b75e22c9231 102 HTTP_CONTENT_URLENCODED = 0,
RobMeades 0:0b75e22c9231 103 HTTP_CONTENT_TEXT = 1,
RobMeades 0:0b75e22c9231 104 HTTP_CONTENT_OCTET_STREAM = 2,
RobMeades 0:0b75e22c9231 105 HTTP_CONTENT_FORM_DATA = 3,
RobMeades 0:0b75e22c9231 106 HTTP_CONTENT_JSON = 4,
RobMeades 0:0b75e22c9231 107 HTTP_CONTENT_XML = 5,
RobMeades 0:0b75e22c9231 108 HTTP_CONTENT_USER_DEFINED = 6
RobMeades 0:0b75e22c9231 109 } HttpContentType;
RobMeades 0:0b75e22c9231 110
RobMeades 0:0b75e22c9231 111 /** Find a free HTTP profile.
RobMeades 0:0b75e22c9231 112 *
RobMeades 0:0b75e22c9231 113 * A profile will be blocking when first allocated.
RobMeades 0:0b75e22c9231 114 *
RobMeades 0:0b75e22c9231 115 * @return the profile or negative if none are available.
RobMeades 0:0b75e22c9231 116 */
RobMeades 0:0b75e22c9231 117 int httpAllocProfile();
RobMeades 0:0b75e22c9231 118
RobMeades 0:0b75e22c9231 119 /** Free the HTTP profile.
RobMeades 0:0b75e22c9231 120 *
RobMeades 0:0b75e22c9231 121 * @param profile the HTTP profile handle.
RobMeades 0:0b75e22c9231 122 * @return true if successful, otherwise false.
RobMeades 0:0b75e22c9231 123 */
RobMeades 0:0b75e22c9231 124 bool httpFreeProfile(int profile);
RobMeades 0:0b75e22c9231 125
RobMeades 0:0b75e22c9231 126 /** Set the timeout for this profile.
RobMeades 0:0b75e22c9231 127 *
RobMeades 0:0b75e22c9231 128 * @param profile the HTTP profile handle.
RobMeades 0:0b75e22c9231 129 * @param timeout -1 blocking, else non-blocking timeout in milliseconds.
RobMeades 0:0b75e22c9231 130 * @return true if successful, otherwise false.
RobMeades 0:0b75e22c9231 131 */
RobMeades 0:0b75e22c9231 132 bool httpSetTimeout(int profile, int timeout);
RobMeades 0:0b75e22c9231 133
RobMeades 0:0b75e22c9231 134 /** Reset a HTTP profile back to defaults.
RobMeades 0:0b75e22c9231 135 *
RobMeades 0:0b75e22c9231 136 * This may be called if the state of a HTTP profile
RobMeades 0:0b75e22c9231 137 * during parameter setting or exchange of HTTP commands
RobMeades 0:0b75e22c9231 138 * has become confusing/unknown.
RobMeades 0:0b75e22c9231 139 *
RobMeades 0:0b75e22c9231 140 * @param httpProfile the HTTP profile to be reset.
RobMeades 0:0b75e22c9231 141 * @return true if successful, false otherwise.
RobMeades 0:0b75e22c9231 142 */
RobMeades 0:0b75e22c9231 143 bool httpResetProfile(int httpProfile);
RobMeades 0:0b75e22c9231 144
RobMeades 0:0b75e22c9231 145 /** Set HTTP parameters.
RobMeades 0:0b75e22c9231 146 *
RobMeades 0:0b75e22c9231 147 * This should be called as many times as is necessary
RobMeades 0:0b75e22c9231 148 * to set all the possible parameters (HttpOpCode).
RobMeades 0:0b75e22c9231 149 *
RobMeades 0:0b75e22c9231 150 * See section 28.1 of u-blox-ATCommands_Manual(UBX-13002752).pdf
RobMeades 0:0b75e22c9231 151 * for full details. By example:
RobMeades 0:0b75e22c9231 152 *
RobMeades 0:0b75e22c9231 153 * httpOpCode httpInPar
RobMeades 0:0b75e22c9231 154 * HTTP_IP_ADDRESS "145.33.18.10" (the target HTTP server IP address)
RobMeades 0:0b75e22c9231 155 * HTTP_SERVER_NAME "www.myhttpserver.com" (the target HTTP server name)
RobMeades 0:0b75e22c9231 156 * HTTP_USER_NAME "my_username"
RobMeades 0:0b75e22c9231 157 * HTTP_PASSWORD "my_password"
RobMeades 0:0b75e22c9231 158 * HTTP_AUTH_TYPE "0" for no authentication, "1" for username/password
RobMeades 0:0b75e22c9231 159 * authentication (the default is 0)
RobMeades 0:0b75e22c9231 160 * HTTP_SERVER_PORT "81" (default is port 80)
rob.meades@u-blox.com 11:3631f62bb359 161 * HTTP_SECURE "0" for no security, "1" for TLS (the default is 0),
rob.meades@u-blox.com 11:3631f62bb359 162 * not all modems support this parameter
RobMeades 0:0b75e22c9231 163 *
RobMeades 0:0b75e22c9231 164 * @param httpProfile the HTTP profile identifier.
RobMeades 0:0b75e22c9231 165 * @param httpOpCode the HTTP operation code.
RobMeades 0:0b75e22c9231 166 * @param httpInPar the HTTP input parameter.
RobMeades 0:0b75e22c9231 167 * @return true if successful, false otherwise.
RobMeades 0:0b75e22c9231 168 */
RobMeades 0:0b75e22c9231 169 bool httpSetPar(int httpProfile, HttpOpCode httpOpCode, const char * httpInPar);
RobMeades 0:0b75e22c9231 170
RobMeades 0:0b75e22c9231 171 /** Perform a HTTP command.
RobMeades 0:0b75e22c9231 172 *
RobMeades 0:0b75e22c9231 173 * See section 28.3 of u-blox-ATCommands_Manual(UBX-13002752).pdf
RobMeades 0:0b75e22c9231 174 * for full details. By example, it works like this:
RobMeades 0:0b75e22c9231 175 *
RobMeades 0:0b75e22c9231 176 * httpCmd httpPath rspFile sendStr httpContentType httpCustomPar
RobMeades 0:0b75e22c9231 177 * HEAD "path/file.html" NULL NULL 0 NULL
RobMeades 0:0b75e22c9231 178 * GET "path/file.html" NULL NULL 0 NULL
RobMeades 0:0b75e22c9231 179 * DELETE "path/file.html" NULL NULL 0 NULL
RobMeades 0:0b75e22c9231 180 * PUT "path/file.html" NULL "myfile.txt" 0 to 6 Note 1
RobMeades 0:0b75e22c9231 181 * POST_FILE "path/file.html" NULL "myfile.txt" 0 to 6 Note 1
RobMeades 0:0b75e22c9231 182 * POST "path/file.html" NULL "hello there!" 0 to 6 Note 1
RobMeades 0:0b75e22c9231 183 *
RobMeades 0:0b75e22c9231 184 * Note 1: httpCustomPar is only applicable when httpContentType = HTTP_CONTENT_USER_DEFINED.
RobMeades 0:0b75e22c9231 185 *
RobMeades 0:0b75e22c9231 186 * The server to which this command is directed must have previously been
RobMeades 0:0b75e22c9231 187 * set with a call to httpSetPar(). If the server requires TLS (i.e. "HTTPS"),
RobMeades 0:0b75e22c9231 188 * then set that up with httpSetPar() also (HTTP_SECURE).
RobMeades 0:0b75e22c9231 189 *
RobMeades 0:0b75e22c9231 190 * rspFile may be left as NULL as the server response will be returned in buf.
RobMeades 0:0b75e22c9231 191 * Alternatively, a rspFile may be given (e.g. "myresponse.txt") and this can
RobMeades 0:0b75e22c9231 192 * later be read from the modem file system using readFile().
RobMeades 0:0b75e22c9231 193 *
RobMeades 0:0b75e22c9231 194 * @param httpProfile the HTTP profile identifier.
RobMeades 0:0b75e22c9231 195 * @param httpCmd the HTTP command.
RobMeades 0:0b75e22c9231 196 * @param httpPath the path of resource on the HTTP server.
RobMeades 0:0b75e22c9231 197 * @param rspFile the local modem file where the server
RobMeades 0:0b75e22c9231 198 * response will be stored, use NULL for
RobMeades 0:0b75e22c9231 199 * don't care.
RobMeades 0:0b75e22c9231 200 * @param sendStr the filename or string to be sent
RobMeades 0:0b75e22c9231 201 * to the HTTP server with the command request.
RobMeades 0:0b75e22c9231 202 * @param httpContentType the HTTP Content-Type identifier.
RobMeades 0:0b75e22c9231 203 * @param httpCustomPar the parameter for a user defined HTTP Content-Type.
RobMeades 0:0b75e22c9231 204 * @param buf the buffer to read into.
RobMeades 0:0b75e22c9231 205 * @param len the size of the buffer to read into.
RobMeades 0:0b75e22c9231 206 * @return NULL if successful, otherwise a pointer to
RobMeades 0:0b75e22c9231 207 * a Error struct containing the error class and error
RobMeades 0:0b75e22c9231 208 * code, see section Appendix A.B of
RobMeades 0:0b75e22c9231 209 * u-blox-ATCommands_Manual(UBX-13002752).pdf for details.
RobMeades 0:0b75e22c9231 210 */
RobMeades 0:0b75e22c9231 211 Error * httpCommand(int httpProfile, HttpCmd httpCmd, const char* httpPath,
RobMeades 0:0b75e22c9231 212 const char* rspFile, const char* sendStr,
RobMeades 0:0b75e22c9231 213 int httpContentType, const char* httpCustomPar,
RobMeades 0:0b75e22c9231 214 char* buf, int len);
RobMeades 0:0b75e22c9231 215
RobMeades 0:0b75e22c9231 216 /**********************************************************************
RobMeades 0:0b75e22c9231 217 * PUBLIC: FTP
RobMeades 0:0b75e22c9231 218 **********************************************************************/
RobMeades 0:0b75e22c9231 219
RobMeades 0:0b75e22c9231 220 /** FTP configuration parameters (reference to FTP control +UFTP).
RobMeades 0:0b75e22c9231 221 */
RobMeades 0:0b75e22c9231 222 typedef enum {
RobMeades 0:0b75e22c9231 223 FTP_IP_ADDRESS = 0,
RobMeades 0:0b75e22c9231 224 FTP_SERVER_NAME = 1,
RobMeades 0:0b75e22c9231 225 FTP_USER_NAME = 2,
RobMeades 0:0b75e22c9231 226 FTP_PASSWORD = 3,
RobMeades 0:0b75e22c9231 227 FTP_ACCOUNT = 4,
RobMeades 0:0b75e22c9231 228 FTP_INACTIVITY_TIMEOUT = 5,
RobMeades 0:0b75e22c9231 229 FTP_MODE = 6,
RobMeades 0:0b75e22c9231 230 FTP_SERVER_PORT = 7,
RobMeades 0:0b75e22c9231 231 FTP_SECURE = 8,
RobMeades 0:0b75e22c9231 232 NUM_FTP_OP_CODES
RobMeades 0:0b75e22c9231 233 } FtpOpCode;
RobMeades 0:0b75e22c9231 234
RobMeades 0:0b75e22c9231 235 /** Type of FTP Command.
RobMeades 0:0b75e22c9231 236 */
RobMeades 0:0b75e22c9231 237 typedef enum {
RobMeades 0:0b75e22c9231 238 FTP_LOGOUT = 0,
RobMeades 0:0b75e22c9231 239 FTP_LOGIN = 1,
RobMeades 0:0b75e22c9231 240 FTP_DELETE_FILE = 2,
RobMeades 0:0b75e22c9231 241 FTP_RENAME_FILE = 3,
RobMeades 0:0b75e22c9231 242 FTP_GET_FILE = 4,
RobMeades 0:0b75e22c9231 243 FTP_PUT_FILE = 5,
RobMeades 0:0b75e22c9231 244 FTP_GET_DIRECT = 6,
RobMeades 0:0b75e22c9231 245 FTP_PUT_DIRECT = 7,
RobMeades 0:0b75e22c9231 246 FTP_CD = 8,
RobMeades 0:0b75e22c9231 247 FTP_MKDIR = 10,
RobMeades 0:0b75e22c9231 248 FTP_RMDIR = 11,
RobMeades 0:0b75e22c9231 249 FTP_FILE_INFO = 13,
RobMeades 0:0b75e22c9231 250 FTP_LS = 14,
RobMeades 0:0b75e22c9231 251 FTP_FOTA_FILE = 100
RobMeades 0:0b75e22c9231 252 } FtpCmd;
RobMeades 0:0b75e22c9231 253
RobMeades 0:0b75e22c9231 254 /** Set the timeout for FTP operations.
RobMeades 0:0b75e22c9231 255 *
RobMeades 0:0b75e22c9231 256 * @param timeout -1 blocking, else non-blocking timeout in milliseconds.
RobMeades 0:0b75e22c9231 257 * @return true if successful, otherwise false.
RobMeades 0:0b75e22c9231 258 */
RobMeades 0:0b75e22c9231 259 bool ftpSetTimeout(int timeout);
RobMeades 0:0b75e22c9231 260
RobMeades 0:0b75e22c9231 261 /** Reset the FTP configuration back to defaults.
RobMeades 0:0b75e22c9231 262 */
rob.meades@u-blox.com 11:3631f62bb359 263 void ftpResetPar();
RobMeades 0:0b75e22c9231 264
RobMeades 0:0b75e22c9231 265 /** Set FTP parameters.
RobMeades 0:0b75e22c9231 266 *
RobMeades 0:0b75e22c9231 267 * This should be called as many times as is necessary
RobMeades 0:0b75e22c9231 268 * to set all the possible parameters (FtpOpCode).
RobMeades 0:0b75e22c9231 269 *
RobMeades 0:0b75e22c9231 270 * See section 27.1 of u-blox-ATCommands_Manual(UBX-13002752).pdf
RobMeades 0:0b75e22c9231 271 * for full details. By example:
RobMeades 0:0b75e22c9231 272 *
RobMeades 0:0b75e22c9231 273 * ftpOpCode ftpInPar
RobMeades 0:0b75e22c9231 274 * FTP_IP_ADDRESS "145.33.18.10" (the target FTP server IP address)
RobMeades 0:0b75e22c9231 275 * FTP_SERVER_NAME "www.ftpserver.com" (the target FTP server name)
RobMeades 0:0b75e22c9231 276 * FTP_USER_NAME "my_username"
RobMeades 0:0b75e22c9231 277 * FTP_PASSWORD "my_password"
RobMeades 0:0b75e22c9231 278 * FTP_ACCOUNT "my_account" (not required by most FTP servers)
RobMeades 0:0b75e22c9231 279 * FTP_INACTIVITY_TIMEOUT "60" (the default is 0, which means no timeout)
RobMeades 0:0b75e22c9231 280 * FTP_MODE "0" for active, "1" for passive (the default is 0)
RobMeades 0:0b75e22c9231 281 * FTP_SERVER_PORT "25" (default is port 21)
RobMeades 0:0b75e22c9231 282 * FTP_SECURE "0" for no security, "1" for SFTP (the default is 0)
RobMeades 0:0b75e22c9231 283 *
RobMeades 0:0b75e22c9231 284 * @param ftpOpCode the FTP operation code.
RobMeades 0:0b75e22c9231 285 * @param ftpInPar the FTP input parameter.
RobMeades 0:0b75e22c9231 286 * @return true if successful, false otherwise.
RobMeades 0:0b75e22c9231 287 */
RobMeades 0:0b75e22c9231 288 bool ftpSetPar(FtpOpCode ftpOpCode, const char * ftpInPar);
RobMeades 0:0b75e22c9231 289
RobMeades 0:0b75e22c9231 290 /** Perform an FTP command.
RobMeades 0:0b75e22c9231 291 *
RobMeades 0:0b75e22c9231 292 * Connect() must have been called previously to establish a data
RobMeades 0:0b75e22c9231 293 * connection.
RobMeades 0:0b75e22c9231 294 *
RobMeades 0:0b75e22c9231 295 * See section 27.2 of u-blox-ATCommands_Manual(UBX-13002752).pdf
RobMeades 0:0b75e22c9231 296 * for full details. By example, it works like this:
RobMeades 0:0b75e22c9231 297 *
rob.meades@u-blox.com 11:3631f62bb359 298 * ftpCmd file1 file2 buf len offset
rob.meades@u-blox.com 11:3631f62bb359 299 * FTP_LOGOUT N/A N/A N/A N/A N/A
rob.meades@u-blox.com 11:3631f62bb359 300 * FTP_LOGIN N/A N/A N/A N/A N/A
rob.meades@u-blox.com 11:3631f62bb359 301 * FTP_DELETE_FILE "the_file" N/A N/A N/A N/A
rob.meades@u-blox.com 11:3631f62bb359 302 * FTP_RENAME_FILE "old_name" "new_name" N/A N/A N/A
rob.meades@u-blox.com 11:3631f62bb359 303 * FTP_GET_FILE "the_file" Note 1 N/A N/A 0 - 1 (Notes 2 & 3)
rob.meades@u-blox.com 11:3631f62bb359 304 * FTP_PUT_FILE "the_file" Note 1 N/A N/A 0 - 65535 (Notes 2 & 4 & 5)
rob.meades@u-blox.com 11:3631f62bb359 305 * FTP_CD "dir1\dir2" N/A N/A N/A N/A
rob.meades@u-blox.com 11:3631f62bb359 306 * FTP_MKDIR "newdir" N/A N/A N/A N/A
rob.meades@u-blox.com 11:3631f62bb359 307 * FTP_RMDIR "dir" N/A N/A N/A N/A
rob.meades@u-blox.com 11:3631f62bb359 308 * FTP_FILE_INFO "the_path" N/A Note 6 N/A
rob.meades@u-blox.com 11:3631f62bb359 309 * FTP_LS "the_path" N/A Note 6 N/A
rob.meades@u-blox.com 11:3631f62bb359 310 * FTP_FOTA_FILE "the_file" N/A Note 7 N/A
RobMeades 0:0b75e22c9231 311 *
RobMeades 0:0b75e22c9231 312 * Note 1: for this case, file2 is the name that the file should be
RobMeades 0:0b75e22c9231 313 * given when it arrives (in the modem file system for a GET, at the FTP
RobMeades 0:0b75e22c9231 314 * server for a PUT); if set to NULL then file1 is used.
RobMeades 0:0b75e22c9231 315 * Note 2: the file will placed into the modem file system for the
RobMeades 0:0b75e22c9231 316 * GET case (and can be read with readFile()), or must already be in the
RobMeades 0:0b75e22c9231 317 * modem file system, (can be written using writeFile()) for the PUT case.
rob.meades@u-blox.com 11:3631f62bb359 318 * Note 3: if offset is 1 then, where supported, the FTP GET
rob.meades@u-blox.com 11:3631f62bb359 319 * will be continued from the point it previously stopped.
rob.meades@u-blox.com 11:3631f62bb359 320 * Note 4: if the file already exists in the modem file system some
rob.meades@u-blox.com 11:3631f62bb359 321 * modems will return an error. It is up to the caller to ensure that
rob.meades@u-blox.com 11:3631f62bb359 322 * the file does not exist before the FTP PUT operation.
rob.meades@u-blox.com 11:3631f62bb359 323 * Note 5: where supported, offset is the position in the file to continue
rob.meades@u-blox.com 11:3631f62bb359 324 * the FTP PUT from.
rob.meades@u-blox.com 11:3631f62bb359 325 * Note 6: buf should point to the location where the file info
RobMeades 0:0b75e22c9231 326 * or directory listing is to be stored and len should be the maximum
RobMeades 0:0b75e22c9231 327 * length that can be stored.
rob.meades@u-blox.com 11:3631f62bb359 328 * Note 7: a hex string representing the MD5 sum of the FOTA file will be
RobMeades 0:0b75e22c9231 329 * stored at buf; len must be at least 32 as an MD5 sum is 16 bytes.
RobMeades 0:0b75e22c9231 330 * FTP_FOTA_FILE is not supported on SARA-U2.
rob.meades@u-blox.com 11:3631f62bb359 331 * Note 8: FTP_GET_DIRECT and FTP_PUT_DIRECT are not supported by
RobMeades 0:0b75e22c9231 332 * this driver.
RobMeades 0:0b75e22c9231 333 *
RobMeades 0:0b75e22c9231 334 * @param ftpCmd the FTP command.
RobMeades 0:0b75e22c9231 335 * @param file1 the first file name if required (NULL otherwise).
RobMeades 0:0b75e22c9231 336 * @param file2 the second file name if required (NULL otherwise).
RobMeades 0:0b75e22c9231 337 * @param buf pointer to a buffer, required for FTP_DIRECT mode
RobMeades 0:0b75e22c9231 338 * and FTP_LS only.
RobMeades 0:0b75e22c9231 339 * @param len the size of buf.
rob.meades@u-blox.com 11:3631f62bb359 340 * @param continue if true then attempt to continue a download that
rob.meades@u-blox.com 11:3631f62bb359 341 * was previously interrupted.
RobMeades 0:0b75e22c9231 342 * @return NULL if successful, otherwise a pointer to
RobMeades 0:0b75e22c9231 343 * a Error struct containing the error class and error
RobMeades 0:0b75e22c9231 344 * code, see section Appendix A.B of
RobMeades 0:0b75e22c9231 345 * u-blox-ATCommands_Manual(UBX-13002752).pdf for details.
RobMeades 0:0b75e22c9231 346 */
RobMeades 0:0b75e22c9231 347 Error *ftpCommand(FtpCmd ftpCmd, const char* file1 = NULL, const char* file2 = NULL,
rob.meades@u-blox.com 11:3631f62bb359 348 char* buf = NULL, int len = 0, int offset = 0);
RobMeades 0:0b75e22c9231 349
RobMeades 0:0b75e22c9231 350 /**********************************************************************
RobMeades 0:0b75e22c9231 351 * PUBLIC: Cell Locate
RobMeades 0:0b75e22c9231 352 **********************************************************************/
RobMeades 0:0b75e22c9231 353
RobMeades 0:0b75e22c9231 354 /** Which form of Cell Locate sensing to use.
RobMeades 0:0b75e22c9231 355 */
RobMeades 0:0b75e22c9231 356 typedef enum {
RobMeades 0:0b75e22c9231 357 CELL_LAST,
RobMeades 0:0b75e22c9231 358 CELL_GNSS,
RobMeades 0:0b75e22c9231 359 CELL_LOCATE,
RobMeades 0:0b75e22c9231 360 CELL_HYBRID
RobMeades 0:0b75e22c9231 361 } CellSensType;
RobMeades 0:0b75e22c9231 362
RobMeades 0:0b75e22c9231 363 /** Types of Cell Locate response.
RobMeades 0:0b75e22c9231 364 */
RobMeades 0:0b75e22c9231 365 typedef enum {
RobMeades 0:0b75e22c9231 366 CELL_DETAILED = 1,
RobMeades 0:0b75e22c9231 367 CELL_MULTIHYP = 2
RobMeades 0:0b75e22c9231 368 } CellRespType;
RobMeades 0:0b75e22c9231 369
RobMeades 0:0b75e22c9231 370 /** Cell Locate data.
RobMeades 0:0b75e22c9231 371 */
RobMeades 0:0b75e22c9231 372 typedef struct {
RobMeades 0:0b75e22c9231 373 volatile bool validData; //!< Flag for indicating if data is valid.
RobMeades 0:0b75e22c9231 374 volatile struct tm time; //!< GPS Timestamp.
RobMeades 0:0b75e22c9231 375 volatile float longitude; //!< Estimated longitude, in degrees.
RobMeades 0:0b75e22c9231 376 volatile float latitude; //!< Estimated latitude, in degrees.
RobMeades 0:0b75e22c9231 377 volatile int altitude; //!< Estimated altitude, in meters^2.
RobMeades 0:0b75e22c9231 378 volatile int uncertainty; //!< Maximum possible error, in meters.
RobMeades 0:0b75e22c9231 379 volatile int speed; //!< Speed over ground m/s^2.
RobMeades 0:0b75e22c9231 380 volatile int direction; //!< Course over ground in degrees.
RobMeades 0:0b75e22c9231 381 volatile int verticalAcc; //!< Vertical accuracy, in meters^2.
RobMeades 0:0b75e22c9231 382 volatile CellSensType sensor; //!< Sensor used for last calculation.
RobMeades 0:0b75e22c9231 383 volatile int svUsed; //!< number of satellite used.
RobMeades 0:0b75e22c9231 384 } CellLocData;
RobMeades 0:0b75e22c9231 385
RobMeades 0:0b75e22c9231 386 /** Configure the Cell Locate TCP aiding server.
RobMeades 0:0b75e22c9231 387 *
RobMeades 0:0b75e22c9231 388 * Connect() must have been called previously to establish
RobMeades 0:0b75e22c9231 389 * a data connection.
RobMeades 0:0b75e22c9231 390 *
RobMeades 0:0b75e22c9231 391 * @param server_1 host name of the primary MGA server.
RobMeades 0:0b75e22c9231 392 * @param server_2 host name of the secondary MGA server.
RobMeades 0:0b75e22c9231 393 * @param token authentication token for MGA server access.
RobMeades 0:0b75e22c9231 394 * @param days the number of days into the future the off-line
RobMeades 0:0b75e22c9231 395 * data for the u-blox 7.
RobMeades 0:0b75e22c9231 396 * @param period the number of weeks into the future the off-line
RobMeades 0:0b75e22c9231 397 * data for u-blox M8.
RobMeades 0:0b75e22c9231 398 * @param resolution resolution of off-line data for u-blox M8: 1 every
RobMeades 0:0b75e22c9231 399 * day, 0 every other day.
RobMeades 0:0b75e22c9231 400 * @return true if the request is successful, otherwise false.
RobMeades 0:0b75e22c9231 401 */
RobMeades 0:0b75e22c9231 402 bool cellLocSrvTcp(const char* token, const char* server_1 = "cell-live1.services.u-blox.com",
RobMeades 0:0b75e22c9231 403 const char* server_2 = "cell-live2.services.u-blox.com",
RobMeades 0:0b75e22c9231 404 int days = 14, int period = 4, int resolution = 1);
RobMeades 0:0b75e22c9231 405
RobMeades 0:0b75e22c9231 406 /** Configure Cell Locate UDP aiding server.
RobMeades 0:0b75e22c9231 407 *
RobMeades 0:0b75e22c9231 408 * Connect() must have been called previously to establish
RobMeades 0:0b75e22c9231 409 * a data connection.
RobMeades 0:0b75e22c9231 410 *
RobMeades 0:0b75e22c9231 411 * @param server_1 host name of the primary MGA server.
RobMeades 0:0b75e22c9231 412 * @param port server port.
RobMeades 0:0b75e22c9231 413 * @param latency expected network latency in seconds from 0 to 10000 milliseconds.
RobMeades 0:0b75e22c9231 414 * @param mode Assist Now management, mode of operation:
RobMeades 0:0b75e22c9231 415 * 0 data downloaded at GNSS power up,
RobMeades 0:0b75e22c9231 416 * 1 automatically kept alive, manual download.
RobMeades 0:0b75e22c9231 417 * @return true if the request is successful, otherwise false.
RobMeades 0:0b75e22c9231 418 */
RobMeades 0:0b75e22c9231 419 bool cellLocSrvUdp(const char* server_1 = "cell-live1.services.u-blox.com",
RobMeades 0:0b75e22c9231 420 int port = 46434, int latency = 1000, int mode = 0);
RobMeades 0:0b75e22c9231 421
RobMeades 0:0b75e22c9231 422 /** Configure Cell Locate location sensor.
RobMeades 0:0b75e22c9231 423 *
RobMeades 0:0b75e22c9231 424 * @param scanMode network scan mode: 0 normal, 1 deep scan.
RobMeades 0:0b75e22c9231 425 * @return true if the request is successful, otherwise false.
RobMeades 0:0b75e22c9231 426 */
RobMeades 0:0b75e22c9231 427 bool cellLocConfig(int scanMode);
RobMeades 0:0b75e22c9231 428
RobMeades 0:0b75e22c9231 429 /** Request a one-shot Cell Locate.
RobMeades 0:0b75e22c9231 430 *
RobMeades 0:0b75e22c9231 431 * This function is non-blocking, the result is retrieved using cellLocGetxxx.
RobMeades 0:0b75e22c9231 432 *
rob.meades@u-blox.com 1:26a67ab07275 433 * Note: none of the CellLocate methods switch on the GNSS receiver chip.
rob.meades@u-blox.com 1:26a67ab07275 434 * That should be done by instantiating the GnssSerial or GnssI2C classes and
rob.meades@u-blox.com 1:26a67ab07275 435 * calling the init() method.
rob.meades@u-blox.com 1:26a67ab07275 436 *
RobMeades 0:0b75e22c9231 437 * Note: during the location process, unsolicited result codes will be returned
RobMeades 0:0b75e22c9231 438 * by the modem indicating progress and potentially flagging interesting errors.
RobMeades 0:0b75e22c9231 439 * In order to see these errors, instantiate this class with debugOn set to true.
RobMeades 0:0b75e22c9231 440 *
RobMeades 0:0b75e22c9231 441 * @param sensor sensor selection.
RobMeades 0:0b75e22c9231 442 * @param timeout timeout period in seconds (1 - 999).
RobMeades 0:0b75e22c9231 443 * @param accuracy target accuracy in meters (1 - 999999).
RobMeades 0:0b75e22c9231 444 * @param type detailed or multi-hypothesis.
RobMeades 0:0b75e22c9231 445 * @param hypothesis maximum desired number of responses from CellLocate (up to 16),
RobMeades 0:0b75e22c9231 446 * must be 1 if type is CELL_DETAILED.
RobMeades 0:0b75e22c9231 447 * @return true if the request is successful, otherwise false.
RobMeades 0:0b75e22c9231 448 */
RobMeades 0:0b75e22c9231 449 bool cellLocRequest(CellSensType sensor, int timeout, int accuracy,
RobMeades 0:0b75e22c9231 450 CellRespType type = CELL_DETAILED, int hypothesis = 1);
RobMeades 0:0b75e22c9231 451
RobMeades 0:0b75e22c9231 452 /** Get a position record.
RobMeades 0:0b75e22c9231 453 *
RobMeades 0:0b75e22c9231 454 * @param data pointer to a CellLocData structure where the location will be put.
RobMeades 0:0b75e22c9231 455 * @param index of the position to retrieve.
RobMeades 0:0b75e22c9231 456 * @return true if data has been retrieved and copied, false otherwise.
RobMeades 0:0b75e22c9231 457 */
RobMeades 0:0b75e22c9231 458 bool cellLocGetData(CellLocData *data, int index = 0);
RobMeades 0:0b75e22c9231 459
RobMeades 0:0b75e22c9231 460 /** Get the number of position records received.
RobMeades 0:0b75e22c9231 461 *
RobMeades 0:0b75e22c9231 462 * @return number of position records received.
RobMeades 0:0b75e22c9231 463 */
RobMeades 0:0b75e22c9231 464 int cellLocGetRes();
RobMeades 0:0b75e22c9231 465
RobMeades 0:0b75e22c9231 466 /** Get the number of position records expected to be received.
RobMeades 0:0b75e22c9231 467 *
RobMeades 0:0b75e22c9231 468 * @return number of position records expected to be received.
RobMeades 0:0b75e22c9231 469 */
RobMeades 0:0b75e22c9231 470 int cellLocGetExpRes();
RobMeades 0:0b75e22c9231 471
RobMeades 0:0b75e22c9231 472 protected:
RobMeades 0:0b75e22c9231 473
RobMeades 0:0b75e22c9231 474 /**********************************************************************
RobMeades 0:0b75e22c9231 475 * PROTECTED: HTTP
RobMeades 0:0b75e22c9231 476 **********************************************************************/
RobMeades 0:0b75e22c9231 477
RobMeades 0:0b75e22c9231 478 /** Check for timeout.
RobMeades 0:0b75e22c9231 479 */
RobMeades 0:0b75e22c9231 480 #define TIMEOUT(t, ms) ((ms != TIMEOUT_BLOCKING) && (ms < t.read_ms()))
RobMeades 0:0b75e22c9231 481
RobMeades 0:0b75e22c9231 482 /** Check for a valid profile.
RobMeades 0:0b75e22c9231 483 */
RobMeades 0:0b75e22c9231 484 #define IS_PROFILE(p) (((p) >= 0) && (((unsigned int) p) < (sizeof(_httpProfiles)/sizeof(_httpProfiles[0]))) \
RobMeades 0:0b75e22c9231 485 && (_httpProfiles[p].modemHandle != HTTP_PROF_UNUSED))
RobMeades 0:0b75e22c9231 486
RobMeades 0:0b75e22c9231 487 /** Management structure for HTTP profiles.
RobMeades 0:0b75e22c9231 488 *
RobMeades 0:0b75e22c9231 489 * It is possible to have up to 4 different HTTP profiles (LISA-C200, LISA-U200 and SARA-G350) having:
RobMeades 0:0b75e22c9231 490 *
RobMeades 0:0b75e22c9231 491 * @param handle the current HTTP profile is in handling state or not (default value is HTTP_ERROR).
RobMeades 0:0b75e22c9231 492 * @param timeout the timeout for the current HTTP command.
RobMeades 0:0b75e22c9231 493 * @param pending the status for the current HTTP command (in processing state or not).
RobMeades 0:0b75e22c9231 494 * @param cmd the code for the current HTTP command.
RobMeades 0:0b75e22c9231 495 * @param result the result for the current HTTP command once processed.
RobMeades 0:0b75e22c9231 496 */
RobMeades 0:0b75e22c9231 497 typedef struct {
RobMeades 0:0b75e22c9231 498 int modemHandle;
RobMeades 0:0b75e22c9231 499 int timeout;
RobMeades 0:0b75e22c9231 500 volatile bool pending;
RobMeades 0:0b75e22c9231 501 volatile int cmd;
RobMeades 0:0b75e22c9231 502 volatile int result;
RobMeades 0:0b75e22c9231 503 Error httpError;
RobMeades 0:0b75e22c9231 504 } HttpProfCtrl;
RobMeades 0:0b75e22c9231 505
RobMeades 0:0b75e22c9231 506 /** The HTTP profile storage.
RobMeades 0:0b75e22c9231 507 */
RobMeades 0:0b75e22c9231 508 HttpProfCtrl _httpProfiles[4];
RobMeades 0:0b75e22c9231 509
RobMeades 0:0b75e22c9231 510 /** Callback to capture the response to an HTTP command.
RobMeades 0:0b75e22c9231 511 */
RobMeades 0:0b75e22c9231 512 void UUHTTPCR_URC();
RobMeades 0:0b75e22c9231 513
RobMeades 0:0b75e22c9231 514 /** Find a profile with a given handle. If no handle is given, find the next
RobMeades 0:0b75e22c9231 515 * free profile.
RobMeades 0:0b75e22c9231 516 *
RobMeades 0:0b75e22c9231 517 * @param modemHandle the handle of the profile to find.
RobMeades 0:0b75e22c9231 518 * @return the profile handle or negative if not found/created.
RobMeades 0:0b75e22c9231 519 */
RobMeades 0:0b75e22c9231 520 int findProfile(int modemHandle = HTTP_PROF_UNUSED);
RobMeades 0:0b75e22c9231 521
RobMeades 0:0b75e22c9231 522 /** Helper function to get a HTTP command as a text string, useful
RobMeades 0:0b75e22c9231 523 * for debug purposes.
RobMeades 0:0b75e22c9231 524 *
RobMeades 0:0b75e22c9231 525 * @param httpCmdCode the HTTP command.
RobMeades 0:0b75e22c9231 526 * @return HTTP command in string format.
RobMeades 0:0b75e22c9231 527 */
RobMeades 0:0b75e22c9231 528 const char* getHttpCmd(HttpCmd httpCmd);
RobMeades 0:0b75e22c9231 529
RobMeades 0:0b75e22c9231 530 /**********************************************************************
RobMeades 0:0b75e22c9231 531 * PROTECTED: FTP
RobMeades 0:0b75e22c9231 532 **********************************************************************/
RobMeades 0:0b75e22c9231 533
RobMeades 0:0b75e22c9231 534 /** Unused FTP op code marker.
RobMeades 0:0b75e22c9231 535 */
RobMeades 0:0b75e22c9231 536 #define FTP_OP_CODE_UNUSED -1
RobMeades 0:0b75e22c9231 537
RobMeades 0:0b75e22c9231 538 /** The FTP timeout in milliseconds.
RobMeades 0:0b75e22c9231 539 */
RobMeades 0:0b75e22c9231 540 int _ftpTimeout;
RobMeades 0:0b75e22c9231 541
RobMeades 0:0b75e22c9231 542 /** A place to store the FTP op code for the last result.
RobMeades 0:0b75e22c9231 543 */
RobMeades 0:0b75e22c9231 544 volatile int _lastFtpOpCodeResult;
RobMeades 0:0b75e22c9231 545
RobMeades 0:0b75e22c9231 546 /** A place to store the last FTP result.
RobMeades 0:0b75e22c9231 547 */
RobMeades 0:0b75e22c9231 548 volatile int _lastFtpResult;
RobMeades 0:0b75e22c9231 549
RobMeades 0:0b75e22c9231 550 /** A place to store the last FTP op code for data response.
RobMeades 0:0b75e22c9231 551 */
RobMeades 0:0b75e22c9231 552 volatile int _lastFtpOpCodeData;
RobMeades 0:0b75e22c9231 553
RobMeades 0:0b75e22c9231 554 /** A place to store data returns from an FTP operation.
RobMeades 0:0b75e22c9231 555 */
RobMeades 0:0b75e22c9231 556 char * _ftpBuf;
RobMeades 0:0b75e22c9231 557
RobMeades 0:0b75e22c9231 558 /** The length of FTP data that can be stored (at _ftpBuf).
RobMeades 0:0b75e22c9231 559 */
RobMeades 0:0b75e22c9231 560 int _ftpBufLen;
RobMeades 0:0b75e22c9231 561
RobMeades 0:0b75e22c9231 562 /** storage for the last FTP error
RobMeades 0:0b75e22c9231 563 */
RobMeades 0:0b75e22c9231 564 Error _ftpError;
RobMeades 0:0b75e22c9231 565
RobMeades 0:0b75e22c9231 566 /** Callback to capture the result of an FTP command.
RobMeades 0:0b75e22c9231 567 */
RobMeades 0:0b75e22c9231 568 void UUFTPCR_URC();
RobMeades 0:0b75e22c9231 569
RobMeades 0:0b75e22c9231 570 /** Callback to capture data returned from an FTP command.
RobMeades 0:0b75e22c9231 571 */
RobMeades 0:0b75e22c9231 572 void UUFTPCD_URC();
RobMeades 0:0b75e22c9231 573
RobMeades 0:0b75e22c9231 574 /** Helper function to get an FTP command as a text string, useful
RobMeades 0:0b75e22c9231 575 * for debug purposes.
RobMeades 0:0b75e22c9231 576 *
RobMeades 0:0b75e22c9231 577 * @param ftpCmdCode the FTP command.
RobMeades 0:0b75e22c9231 578 * @return FTP command in string format.
RobMeades 0:0b75e22c9231 579 */
RobMeades 0:0b75e22c9231 580 const char * getFtpCmd(FtpCmd ftpCmd);
RobMeades 0:0b75e22c9231 581
RobMeades 0:0b75e22c9231 582 /**********************************************************************
RobMeades 0:0b75e22c9231 583 * PROTECTED: Cell Locate
RobMeades 0:0b75e22c9231 584 **********************************************************************/
RobMeades 0:0b75e22c9231 585
RobMeades 0:0b75e22c9231 586 /** The maximum number of hypotheses
RobMeades 0:0b75e22c9231 587 */
RobMeades 0:0b75e22c9231 588 #define CELL_MAX_HYP (16 + 1)
RobMeades 0:0b75e22c9231 589
RobMeades 0:0b75e22c9231 590 /** Received positions.
RobMeades 0:0b75e22c9231 591 */
RobMeades 0:0b75e22c9231 592 volatile int _locRcvPos;
RobMeades 0:0b75e22c9231 593
RobMeades 0:0b75e22c9231 594 /** Expected positions.
RobMeades 0:0b75e22c9231 595 */
RobMeades 0:0b75e22c9231 596 volatile int _locExpPos;
RobMeades 0:0b75e22c9231 597
RobMeades 0:0b75e22c9231 598 /** The Cell Locate data.
RobMeades 0:0b75e22c9231 599 */
RobMeades 0:0b75e22c9231 600 CellLocData _loc[CELL_MAX_HYP];
RobMeades 0:0b75e22c9231 601
RobMeades 0:0b75e22c9231 602 /** Buffer for the URC to work with
RobMeades 0:0b75e22c9231 603 */
RobMeades 0:0b75e22c9231 604 char urcBuf[128];
RobMeades 0:0b75e22c9231 605
RobMeades 0:0b75e22c9231 606 /** Callback to capture +UULOCIND.
RobMeades 0:0b75e22c9231 607 */
RobMeades 0:0b75e22c9231 608 void UULOCIND_URC();
RobMeades 0:0b75e22c9231 609
RobMeades 0:0b75e22c9231 610 /** Callback to capture +UULOC.
RobMeades 0:0b75e22c9231 611 */
RobMeades 0:0b75e22c9231 612 void UULOC_URC();
RobMeades 0:0b75e22c9231 613 };
RobMeades 0:0b75e22c9231 614
RobMeades 0:0b75e22c9231 615 #endif // _UBLOX_AT_CELLULAR_INTERFACE_EXT_
RobMeades 0:0b75e22c9231 616