From 31eb61649d6acb88cf9a5c25df1758e3ee5033f1 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 15 Nov 2023 11:55:46 -0700 Subject: [PATCH 01/52] Create library.properties --- library.properties | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 library.properties diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..95e1087 --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=SparkFun u-blox AT Commands Arduino Library +version=1.0.0 +author=SparkFun Electronics +maintainer=SparkFun Electronics +sentence=Library for u-blox modules supporting AT commands +paragraph= +category=Communication +url=https://github.com/sparkfun/SparkFun_u-blox_AT_Commands_Arduino_Library +architectures=* From 216d2572d86a043e625de0aafe4cfb964a3a0017 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 15 Nov 2023 11:59:25 -0700 Subject: [PATCH 02/52] Add base class files Copied from SAAR-R5 library, replaced `SARA_R5` with `UBLOX_AT` for now --- src/sfe_ublox_at_commands.cpp | 6932 +++++++++++++++++++++++++++++++++ src/sfe_ublox_at_commands.h | 1131 ++++++ 2 files changed, 8063 insertions(+) create mode 100644 src/sfe_ublox_at_commands.cpp create mode 100644 src/sfe_ublox_at_commands.h diff --git a/src/sfe_ublox_at_commands.cpp b/src/sfe_ublox_at_commands.cpp new file mode 100644 index 0000000..1499bee --- /dev/null +++ b/src/sfe_ublox_at_commands.cpp @@ -0,0 +1,6932 @@ +/* + Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod Asset Tracker + By: Paul Clark + October 19th 2020 + + Based extensively on the: + Arduino Library for the SparkFun LTE CAT M1/NB-IoT Shield - SARA-R4 + Written by Jim Lindblom @ SparkFun Electronics, September 5, 2018 + + This Arduino library provides mechanisms to initialize and use + the SARA-R5 module over either a SoftwareSerial or hardware serial port. + + Please see LICENSE.md for the license information + +*/ + +#include "sfe_ublox_at_commands.h" + +UBLOX_AT::UBLOX_AT(int powerPin, int resetPin, uint8_t maxInitTries) +{ +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + _softSerial = nullptr; +#endif + _hardSerial = nullptr; + _baud = 0; + _resetPin = resetPin; + _powerPin = powerPin; + _invertPowerPin = false; + _maxInitTries = maxInitTries; + _socketListenCallback = nullptr; + _socketReadCallback = nullptr; + _socketReadCallbackPlus = nullptr; + _socketCloseCallback = nullptr; + _gpsRequestCallback = nullptr; + _simStateReportCallback = nullptr; + _psdActionRequestCallback = nullptr; + _pingRequestCallback = nullptr; + _httpCommandRequestCallback = nullptr; + _mqttCommandRequestCallback = nullptr; + _registrationCallback = nullptr; + _epsRegistrationCallback = nullptr; + _debugAtPort = nullptr; + _debugPort = nullptr; + _printDebug = false; + _lastRemoteIP = {0, 0, 0, 0}; + _lastLocalIP = {0, 0, 0, 0}; + for (int i = 0; i < UBLOX_AT_NUM_SOCKETS; i++) + _lastSocketProtocol[i] = 0; // Set to zero initially. Will be set to TCP/UDP by socketOpen etc. + _autoTimeZoneForBegin = true; + _bufferedPollReentrant = false; + _pollReentrant = false; + _saraResponseBacklogLength = 0; + _saraRXBuffer = nullptr; + _pruneBuffer = nullptr; + _saraResponseBacklog = nullptr; +} + +UBLOX_AT::~UBLOX_AT(void) { + if (nullptr != _saraRXBuffer) { + delete[] _saraRXBuffer; + _saraRXBuffer = nullptr; + } + if (nullptr != _pruneBuffer) { + delete[] _pruneBuffer; + _pruneBuffer = nullptr; + } + if (nullptr != _saraResponseBacklog) { + delete[] _saraResponseBacklog; + _saraResponseBacklog = nullptr; + } +} + +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +bool UBLOX_AT::begin(SoftwareSerial &softSerial, unsigned long baud) +{ + if (nullptr == _saraRXBuffer) + { + _saraRXBuffer = new char[_RXBuffSize]; + if (nullptr == _saraRXBuffer) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _saraRXBuffer!")); + return false; + } + } + memset(_saraRXBuffer, 0, _RXBuffSize); + + if (nullptr == _pruneBuffer) + { + _pruneBuffer = new char[_RXBuffSize]; + if (nullptr == _pruneBuffer) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _pruneBuffer!")); + return false; + } + } + memset(_pruneBuffer, 0, _RXBuffSize); + + if (nullptr == _saraResponseBacklog) + { + _saraResponseBacklog = new char[_RXBuffSize]; + if (nullptr == _saraResponseBacklog) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _saraResponseBacklog!")); + return false; + } + } + memset(_saraResponseBacklog, 0, _RXBuffSize); + + UBLOX_AT_error_t err; + + _softSerial = &softSerial; + + err = init(baud); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + return true; + } + return false; +} +#endif + +bool UBLOX_AT::begin(HardwareSerial &hardSerial, unsigned long baud) +{ + if (nullptr == _saraRXBuffer) + { + _saraRXBuffer = new char[_RXBuffSize]; + if (nullptr == _saraRXBuffer) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _saraRXBuffer!")); + return false; + } + } + memset(_saraRXBuffer, 0, _RXBuffSize); + + if (nullptr == _pruneBuffer) + { + _pruneBuffer = new char[_RXBuffSize]; + if (nullptr == _pruneBuffer) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _pruneBuffer!")); + return false; + } + } + memset(_pruneBuffer, 0, _RXBuffSize); + + if (nullptr == _saraResponseBacklog) + { + _saraResponseBacklog = new char[_RXBuffSize]; + if (nullptr == _saraResponseBacklog) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _saraResponseBacklog!")); + return false; + } + } + memset(_saraResponseBacklog, 0, _RXBuffSize); + + UBLOX_AT_error_t err; + + _hardSerial = &hardSerial; + + err = init(baud); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + return true; + } + return false; +} + +//Calling this function with nothing sets the debug port to Serial +//You can also call it with other streams like Serial1, SerialUSB, etc. +void UBLOX_AT::enableDebugging(Print &debugPort) +{ + _debugPort = &debugPort; + _printDebug = true; +} + +//Calling this function with nothing sets the debug port to Serial +//You can also call it with other streams like Serial1, SerialUSB, etc. +void UBLOX_AT::enableAtDebugging(Print &debugPort) +{ + _debugAtPort = &debugPort; + _printAtDebug = true; +} + +// This function was originally written by Matthew Menze for the LTE Shield (SARA-R4) library +// See: https://github.com/sparkfun/SparkFun_LTE_Shield_Arduino_Library/pull/8 +// It does the same job as ::poll but also processed any 'old' data stored in the backlog first +// It also has a built-in timeout - which ::poll does not +bool UBLOX_AT::bufferedPoll(void) +{ + if (_bufferedPollReentrant == true) // Check for reentry (i.e. bufferedPoll has been called from inside a callback) + return false; + + _bufferedPollReentrant = true; + + int avail = 0; + char c = 0; + bool handled = false; + unsigned long timeIn = millis(); + char *event; + int backlogLen = _saraResponseBacklogLength; + + memset(_saraRXBuffer, 0, _RXBuffSize); // Clear _saraRXBuffer + + // Does the backlog contain any data? If it does, copy it into _saraRXBuffer and then clear the backlog + if (_saraResponseBacklogLength > 0) + { + //The backlog also logs reads from other tasks like transmitting. + if (_printDebug == true) + { + _debugPort->print(F("bufferedPoll: backlog found! backlogLen is ")); + _debugPort->println(_saraResponseBacklogLength); + } + memcpy(_saraRXBuffer + avail, _saraResponseBacklog, _saraResponseBacklogLength); + avail += _saraResponseBacklogLength; + memset(_saraResponseBacklog, 0, _RXBuffSize); // Clear the backlog making sure it is NULL-terminated + _saraResponseBacklogLength = 0; + } + + if ((hwAvailable() > 0) || (backlogLen > 0)) // If either new data is available, or backlog had data. + { + //Check for incoming serial data. Copy it into the backlog + + // Important note: + // On ESP32, Serial.available only provides an update every ~120 bytes during the reception of long messages: + // https://gitter.im/espressif/arduino-esp32?at=5e25d6370a1cf54144909c85 + // Be aware that if a long message is being received, the code below will timeout after _rxWindowMillis = 2 millis. + // At 115200 baud, hwAvailable takes ~120 * 10 / 115200 = 10.4 millis before it indicates that data is being received. + + while (((millis() - timeIn) < _rxWindowMillis) && (avail < _RXBuffSize)) + { + if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL + { + c = readChar(); + // bufferedPoll is only interested in the URCs. + // The URCs are all readable. + // strtok does not like NULL characters. + // So we need to make sure no NULL characters are added to _saraRXBuffer + if (c == '\0') + c = '0'; // Convert any NULLs to ASCII Zeros + _saraRXBuffer[avail++] = c; + timeIn = millis(); + } else { + yield(); + } + } + + // _saraRXBuffer now contains the backlog (if any) and the new serial data (if any) + + // A health warning about strtok: + // strtok will convert any delimiters it finds ("\r\n" in our case) into NULL characters. + // Also, be very careful that you do not use strtok within an strtok while loop. + // The next call of strtok(NULL, ...) in the outer loop will use the pointer saved from the inner loop! + // In our case, strtok is also used in pruneBacklog, which is called by waitForRespone or sendCommandWithResponse, + // which is called by the parse functions called by processURCEvent... + // The solution is to use strtok_r - the reentrant version of strtok + + char *preservedEvent; + event = strtok_r(_saraRXBuffer, "\r\n", &preservedEvent); // Look for an 'event' (_saraRXBuffer contains something ending in \r\n) + + if (event != nullptr) + if (_printDebug == true) + _debugPort->println(F("bufferedPoll: event(s) found! ===>")); + + while (event != nullptr) // Keep going until all events have been processed + { + if (_printDebug == true) + { + _debugPort->print(F("bufferedPoll: start of event: ")); + _debugPort->println(event); + } + + //Process the event + bool latestHandled = processURCEvent((const char *)event); + if (latestHandled) { + if ((true == _printAtDebug) && (nullptr != event)) { + _debugAtPort->print(event); + } + handled = true; // handled will be true if latestHandled has ever been true + } + if ((_saraResponseBacklogLength > 0) && ((avail + _saraResponseBacklogLength) < _RXBuffSize)) // Has any new data been added to the backlog? + { + if (_printDebug == true) + { + _debugPort->println(F("bufferedPoll: new backlog added!")); + } + memcpy(_saraRXBuffer + avail, _saraResponseBacklog, _saraResponseBacklogLength); + avail += _saraResponseBacklogLength; + memset(_saraResponseBacklog, 0, _RXBuffSize); //Clear out the backlog buffer again. + _saraResponseBacklogLength = 0; + } + + //Walk through any remaining events + event = strtok_r(nullptr, "\r\n", &preservedEvent); + + if (_printDebug == true) + _debugPort->println(F("bufferedPoll: end of event")); //Just to denote end of processing event. + + if (event == nullptr) + if (_printDebug == true) + _debugPort->println(F("bufferedPoll: <=== end of event(s)!")); + } + } + + _bufferedPollReentrant = false; + + return handled; +} // /bufferedPoll + +// Parse incoming URC's - the associated parse functions pass the data to the user via the callbacks (if defined) +bool UBLOX_AT::processURCEvent(const char *event) +{ + { // URC: +UUSORD (Read Socket Data) + int socket, length; + char *searchPtr = strstr(event, UBLOX_AT_READ_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_READ_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // Skip spaces + int ret = sscanf(searchPtr, "%d,%d", &socket, &length); + if (ret == 2) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: read socket data")); + // From the UBLOX_AT AT Commands Manual: + // "For the UDP socket type the URC +UUSORD: , notifies that a UDP packet has been received, + // either when buffer is empty or after a UDP packet has been read and one or more packets are stored in the + // buffer." + // So we need to check if this is a TCP socket or a UDP socket: + // If UDP, we call parseSocketReadIndicationUDP. + // Otherwise, we call parseSocketReadIndication. + if (_lastSocketProtocol[socket] == UBLOX_AT_UDP) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: received +UUSORD but socket is UDP. Calling parseSocketReadIndicationUDP")); + parseSocketReadIndicationUDP(socket, length); + } + else + parseSocketReadIndication(socket, length); + return true; + } + } + } + { // URC: +UUSORF (Receive From command (UDP only)) + int socket, length; + char *searchPtr = strstr(event, UBLOX_AT_READ_UDP_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_READ_UDP_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int ret = sscanf(searchPtr, "%d,%d", &socket, &length); + if (ret == 2) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: UDP receive")); + parseSocketReadIndicationUDP(socket, length); + return true; + } + } + } + { // URC: +UUSOLI (Set Listening Socket) + int socket = 0; + int listenSocket = 0; + unsigned int port = 0; + unsigned int listenPort = 0; + IPAddress remoteIP = {0,0,0,0}; + IPAddress localIP = {0,0,0,0}; + int remoteIPstore[4] = {0,0,0,0}; + int localIPstore[4] = {0,0,0,0}; + + char *searchPtr = strstr(event, UBLOX_AT_LISTEN_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_LISTEN_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int ret = sscanf(searchPtr, + "%d,\"%d.%d.%d.%d\",%u,%d,\"%d.%d.%d.%d\",%u", + &socket, + &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], + &port, &listenSocket, + &localIPstore[0], &localIPstore[1], &localIPstore[2], &localIPstore[3], + &listenPort); + for (int i = 0; i <= 3; i++) + { + if (ret >= 5) + remoteIP[i] = (uint8_t)remoteIPstore[i]; + if (ret >= 11) + localIP[i] = (uint8_t)localIPstore[i]; + } + if (ret >= 5) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: socket listen")); + parseSocketListenIndication(listenSocket, localIP, listenPort, socket, remoteIP, port); + return true; + } + } + } + { // URC: +UUSOCL (Close Socket) + int socket; + char *searchPtr = strstr(event, UBLOX_AT_CLOSE_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_CLOSE_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int ret = sscanf(searchPtr, "%d", &socket); + if (ret == 1) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: socket close")); + if ((socket >= 0) && (socket <= 6)) + { + if (_socketCloseCallback != nullptr) + { + _socketCloseCallback(socket); + } + } + return true; + } + } + } + { // URC: +UULOC (Localization information - CellLocate and hybrid positioning) + ClockData clck; + PositionData gps; + SpeedData spd; + unsigned long uncertainty; + int scanNum; + int latH, lonH, alt; + unsigned int speedU, cogU; + char latL[10], lonL[10]; + int dateStore[5]; + + // Maybe we should also scan for +UUGIND and extract the activated gnss system? + + // This assumes the ULOC response type is "0" or "1" - as selected by gpsRequest detailed + char *searchPtr = strstr(event, UBLOX_AT_GNSS_REQUEST_LOCATION_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_GNSS_REQUEST_LOCATION_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, + "%d/%d/%d,%d:%d:%d.%d,%d.%[^,],%d.%[^,],%d,%lu,%u,%u,%*s", + &dateStore[0], &dateStore[1], &clck.date.year, + &dateStore[2], &dateStore[3], &dateStore[4], &clck.time.ms, + &latH, latL, &lonH, lonL, &alt, &uncertainty, + &speedU, &cogU); + clck.date.day = dateStore[0]; + clck.date.month = dateStore[1]; + clck.time.hour = dateStore[2]; + clck.time.minute = dateStore[3]; + clck.time.second = dateStore[4]; + + if (scanNum >= 13) + { + // Found a Location string! + if (_printDebug == true) + { + _debugPort->println(F("processReadEvent: location")); + } + + if (latH >= 0) + gps.lat = (float)latH + ((float)atol(latL) / pow(10, strlen(latL))); + else + gps.lat = (float)latH - ((float)atol(latL) / pow(10, strlen(latL))); + if (lonH >= 0) + gps.lon = (float)lonH + ((float)atol(lonL) / pow(10, strlen(lonL))); + else + gps.lon = (float)lonH - ((float)atol(lonL) / pow(10, strlen(lonL))); + gps.alt = (float)alt; + if (scanNum >= 15) // If detailed response, get speed data + { + spd.speed = (float)speedU; + spd.cog = (float)cogU; + } + + // if (_printDebug == true) + // { + // _debugPort->print(F("processReadEvent: location: lat: ")); + // _debugPort->print(gps.lat, 7); + // _debugPort->print(F(" lon: ")); + // _debugPort->print(gps.lon, 7); + // _debugPort->print(F(" alt: ")); + // _debugPort->print(gps.alt, 2); + // _debugPort->print(F(" speed: ")); + // _debugPort->print(spd.speed, 2); + // _debugPort->print(F(" cog: ")); + // _debugPort->println(spd.cog, 2); + // } + + if (_gpsRequestCallback != nullptr) + { + _gpsRequestCallback(clck, gps, spd, uncertainty); + } + + return true; + } + } + } + { // URC: +UUSIMSTAT (SIM Status) + UBLOX_AT_sim_states_t state; + int scanNum; + int stateStore; + + char *searchPtr = strstr(event, UBLOX_AT_SIM_STATE_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_SIM_STATE_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d", &stateStore); + + if (scanNum == 1) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: SIM status")); + + state = (UBLOX_AT_sim_states_t)stateStore; + + if (_simStateReportCallback != nullptr) + { + _simStateReportCallback(state); + } + + return true; + } + } + } + { // URC: +UUPSDA (Packet Switched Data Action) + int result; + IPAddress remoteIP = {0, 0, 0, 0}; + int scanNum; + int remoteIPstore[4]; + + char *searchPtr = strstr(event, UBLOX_AT_MESSAGE_PDP_ACTION_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\"", + &result, &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); + + if (scanNum == 5) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: packet switched data action")); + + for (int i = 0; i <= 3; i++) + { + remoteIP[i] = (uint8_t)remoteIPstore[i]; + } + + if (_psdActionRequestCallback != nullptr) + { + _psdActionRequestCallback(result, remoteIP); + } + + return true; + } + } + } + { // URC: +UUHTTPCR (HTTP Command Result) + int profile, command, result; + int scanNum; + + char *searchPtr = strstr(event, UBLOX_AT_HTTP_COMMAND_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_HTTP_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,%d", &profile, &command, &result); + + if (scanNum == 3) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: HTTP command result")); + + if ((profile >= 0) && (profile < UBLOX_AT_NUM_HTTP_PROFILES)) + { + if (_httpCommandRequestCallback != nullptr) + { + _httpCommandRequestCallback(profile, command, result); + } + } + + return true; + } + } + } + { // URC: +UUMQTTC (MQTT Command Result) + int command, result; + int scanNum; + int qos = -1; + String topic; + + char *searchPtr = strstr(event, UBLOX_AT_MQTT_COMMAND_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_MQTT_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + { + searchPtr++; // skip spaces + } + + scanNum = sscanf(searchPtr, "%d,%d", &command, &result); + if ((scanNum == 2) && (command == UBLOX_AT_MQTT_COMMAND_SUBSCRIBE)) + { + char topicC[100] = ""; + scanNum = sscanf(searchPtr, "%*d,%*d,%d,\"%[^\"]\"", &qos, topicC); + topic = topicC; + } + if ((scanNum == 2) || (scanNum == 4)) + { + if (_printDebug == true) + { + _debugPort->println(F("processReadEvent: MQTT command result")); + } + + if (_mqttCommandRequestCallback != nullptr) + { + _mqttCommandRequestCallback(command, result); + } + + return true; + } + } + } + { // URC: +UUFTPCR (FTP Command Result) + int ftpCmd; + int ftpResult; + int scanNum; + char *searchPtr = strstr(event, UBLOX_AT_FTP_COMMAND_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_FTP_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + { + searchPtr++; // skip spaces + } + + scanNum = sscanf(searchPtr, "%d,%d", &ftpCmd, &ftpResult); + if (scanNum == 2 && _ftpCommandRequestCallback != nullptr) + { + _ftpCommandRequestCallback(ftpCmd, ftpResult); + return true; + } + } + } + { // URC: +UUPING (Ping Result) + int retry = 0; + int p_size = 0; + int ttl = 0; + String remote_host = ""; + IPAddress remoteIP = {0, 0, 0, 0}; + long rtt = 0; + int scanNum; + + // Try to extract the UUPING retries and payload size + char *searchPtr = strstr(event, UBLOX_AT_PING_COMMAND_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_PING_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,", &retry, &p_size); + + if (scanNum == 2) + { + if (_printDebug == true) + { + _debugPort->println(F("processReadEvent: ping")); + } + + searchPtr = strchr(++searchPtr, '\"'); // Search to the first quote + + // Extract the remote host name, stop at the next quote + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0')) + { + remote_host.concat(*(searchPtr)); + } + + if (*searchPtr != '\0') // Make sure we found a quote + { + int remoteIPstore[4]; + scanNum = sscanf(searchPtr, "\",\"%d.%d.%d.%d\",%d,%ld", + &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], &ttl, &rtt); + for (int i = 0; i <= 3; i++) + { + remoteIP[i] = (uint8_t)remoteIPstore[i]; + } + + if (scanNum == 6) // Make sure we extracted enough data + { + if (_pingRequestCallback != nullptr) + { + _pingRequestCallback(retry, p_size, remote_host, remoteIP, ttl, rtt); + } + } + } + return true; + } + } + } + { // URC: +CREG + int status = 0; + unsigned int lac = 0, ci = 0, Act = 0; + char *searchPtr = strstr(event, UBLOX_AT_REGISTRATION_STATUS_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_REGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &lac, &ci, &Act); + if (scanNum == 4) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: CREG")); + + if (_registrationCallback != nullptr) + { + _registrationCallback((UBLOX_AT_registration_status_t)status, lac, ci, Act); + } + + return true; + } + } + } + { // URC: +CEREG + int status = 0; + unsigned int tac = 0, ci = 0, Act = 0; + char *searchPtr = strstr(event, UBLOX_AT_EPSREGISTRATION_STATUS_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBLOX_AT_EPSREGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &tac, &ci, &Act); + if (scanNum == 4) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: CEREG")); + + if (_epsRegistrationCallback != nullptr) + { + _epsRegistrationCallback((UBLOX_AT_registration_status_t)status, tac, ci, Act); + } + + return true; + } + } + } + // NOTE: When adding new URC messages, remember to update pruneBacklog too! + + return false; +} + +// This is the original poll function. +// It is 'blocking' - it does not return when serial data is available until it receives a `\n`. +// ::bufferedPoll is the new improved version. It processes any data in the backlog and includes a timeout. +bool UBLOX_AT::poll(void) +{ + if (_pollReentrant == true) // Check for reentry (i.e. poll has been called from inside a callback) + return false; + + _pollReentrant = true; + + int avail = 0; + char c = 0; + bool handled = false; + + memset(_saraRXBuffer, 0, _RXBuffSize); // Clear _saraRXBuffer + + if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL + { + while (c != '\n') // Copy characters into _saraRXBuffer. Stop at the first new line + { + if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL + { + c = readChar(); + _saraRXBuffer[avail++] = c; + } else { + yield(); + } + } + + // Now search for all supported URC's + handled = processURCEvent(_saraRXBuffer); + if (handled && (true == _printAtDebug)) { + _debugAtPort->write(_saraRXBuffer, avail); + } + if ((handled == false) && (strlen(_saraRXBuffer) > 2)) + { + if (_printDebug == true) + { + _debugPort->print(F("poll: ")); + _debugPort->println(_saraRXBuffer); + } + } + else + { + } + } + + _pollReentrant = false; + + return handled; +} + +void UBLOX_AT::setSocketListenCallback(void (*socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int)) +{ + _socketListenCallback = socketListenCallback; +} + +void UBLOX_AT::setSocketReadCallback(void (*socketReadCallback)(int, String)) +{ + _socketReadCallback = socketReadCallback; +} + +void UBLOX_AT::setSocketReadCallbackPlus(void (*socketReadCallbackPlus)(int, const char *, int, IPAddress, int)) // socket, data, length, remoteAddress, remotePort +{ + _socketReadCallbackPlus = socketReadCallbackPlus; +} + +void UBLOX_AT::setSocketCloseCallback(void (*socketCloseCallback)(int)) +{ + _socketCloseCallback = socketCloseCallback; +} + +void UBLOX_AT::setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, + PositionData gps, SpeedData spd, unsigned long uncertainty)) +{ + _gpsRequestCallback = gpsRequestCallback; +} + +void UBLOX_AT::setSIMstateReportCallback(void (*simStateReportCallback)(UBLOX_AT_sim_states_t state)) +{ + _simStateReportCallback = simStateReportCallback; +} + +void UBLOX_AT::setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)) +{ + _psdActionRequestCallback = psdActionRequestCallback; +} + +void UBLOX_AT::setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)) +{ + _pingRequestCallback = pingRequestCallback; +} + +void UBLOX_AT::setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)) +{ + _httpCommandRequestCallback = httpCommandRequestCallback; +} + +void UBLOX_AT::setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)) +{ + _mqttCommandRequestCallback = mqttCommandRequestCallback; +} + +void UBLOX_AT::setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)) +{ + _ftpCommandRequestCallback = ftpCommandRequestCallback; +} + +UBLOX_AT_error_t UBLOX_AT::setRegistrationCallback(void (*registrationCallback)(UBLOX_AT_registration_status_t status, unsigned int lac, unsigned int ci, int Act)) +{ + _registrationCallback = registrationCallback; + + char *command = ublox_at_calloc_char(strlen(UBLOX_AT_REGISTRATION_STATUS) + 3); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_REGISTRATION_STATUS, 2/*enable URC with location*/); + UBLOX_AT_error_t err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setEpsRegistrationCallback(void (*registrationCallback)(UBLOX_AT_registration_status_t status, unsigned int tac, unsigned int ci, int Act)) +{ + _epsRegistrationCallback = registrationCallback; + + char *command = ublox_at_calloc_char(strlen(UBLOX_AT_EPSREGISTRATION_STATUS) + 3); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_EPSREGISTRATION_STATUS, 2/*enable URC with location*/); + UBLOX_AT_error_t err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +size_t UBLOX_AT::write(uint8_t c) +{ + return hwWrite(c); +} + +size_t UBLOX_AT::write(const char *str) +{ + return hwPrint(str); +} + +size_t UBLOX_AT::write(const char *buffer, size_t size) +{ + return hwWriteData(buffer, size); +} + +UBLOX_AT_error_t UBLOX_AT::at(void) +{ + UBLOX_AT_error_t err; + + err = sendCommandWithResponse(nullptr, UBLOX_AT_RESPONSE_OK, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::enableEcho(bool enable) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_ECHO) + 2); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s%d", UBLOX_AT_COMMAND_ECHO, enable ? 1 : 0); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +String UBLOX_AT::getManufacturerID(void) +{ + char *response; + char idResponse[16] = {0x00}; // E.g. u-blox + UBLOX_AT_error_t err; + + response = ublox_at_calloc_char(minimumResponseAllocation); + + err = sendCommandWithResponse(UBLOX_AT_COMMAND_MANU_ID, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + if (sscanf(response, "\r\n%15s\r\n", idResponse) != 1) + { + memset(idResponse, 0, 16); + } + } + free(response); + return String(idResponse); +} + +String UBLOX_AT::getModelID(void) +{ + char *response; + char idResponse[32] = {0x00}; // E.g. SARA-R510M8Q + UBLOX_AT_error_t err; + + response = ublox_at_calloc_char(minimumResponseAllocation); + + err = sendCommandWithResponse(UBLOX_AT_COMMAND_MODEL_ID, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + if (sscanf(response, "\r\n%31s\r\n", idResponse) != 1) + { + memset(idResponse, 0, 16); + } + } + free(response); + return String(idResponse); +} + +String UBLOX_AT::getFirmwareVersion(void) +{ + char *response; + char idResponse[16] = {0x00}; // E.g. 11.40 + UBLOX_AT_error_t err; + + response = ublox_at_calloc_char(minimumResponseAllocation); + + err = sendCommandWithResponse(UBLOX_AT_COMMAND_FW_VER_ID, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + if (sscanf(response, "\r\n%15s\r\n", idResponse) != 1) + { + memset(idResponse, 0, 16); + } + } + free(response); + return String(idResponse); +} + +String UBLOX_AT::getSerialNo(void) +{ + char *response; + char idResponse[32] = {0x00}; // E.g. 357520070120767 + UBLOX_AT_error_t err; + + response = ublox_at_calloc_char(minimumResponseAllocation); + + err = sendCommandWithResponse(UBLOX_AT_COMMAND_SERIAL_NO, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + if (sscanf(response, "\r\n%31s\r\n", idResponse) != 1) + { + memset(idResponse, 0, 16); + } + } + free(response); + return String(idResponse); +} + +String UBLOX_AT::getIMEI(void) +{ + char *response; + char imeiResponse[32] = {0x00}; // E.g. 004999010640000 + UBLOX_AT_error_t err; + + response = ublox_at_calloc_char(minimumResponseAllocation); + + err = sendCommandWithResponse(UBLOX_AT_COMMAND_IMEI, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + if (sscanf(response, "\r\n%31s\r\n", imeiResponse) != 1) + { + memset(imeiResponse, 0, 16); + } + } + free(response); + return String(imeiResponse); +} + +String UBLOX_AT::getIMSI(void) +{ + char *response; + char imsiResponse[32] = {0x00}; // E.g. 222107701772423 + UBLOX_AT_error_t err; + + response = ublox_at_calloc_char(minimumResponseAllocation); + + err = sendCommandWithResponse(UBLOX_AT_COMMAND_IMSI, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + if (sscanf(response, "\r\n%31s\r\n", imsiResponse) != 1) + { + memset(imsiResponse, 0, 16); + } + } + free(response); + return String(imsiResponse); +} + +String UBLOX_AT::getCCID(void) +{ + char *response; + char ccidResponse[32] = {0x00}; // E.g. +CCID: 8939107900010087330 + UBLOX_AT_error_t err; + + response = ublox_at_calloc_char(minimumResponseAllocation); + + err = sendCommandWithResponse(UBLOX_AT_COMMAND_CCID, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "\r\n+CCID:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("\r\n+CCID:"); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + if (sscanf(searchPtr, "%31s", ccidResponse) != 1) + { + ccidResponse[0] = 0; + } + } + } + free(response); + return String(ccidResponse); +} + +String UBLOX_AT::getSubscriberNo(void) +{ + char *response; + char idResponse[128] = {0x00}; // E.g. +CNUM: "ABCD . AAA","123456789012",129 + UBLOX_AT_error_t err; + + response = ublox_at_calloc_char(minimumResponseAllocation); + + err = sendCommandWithResponse(UBLOX_AT_COMMAND_CNUM, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_10_SEC_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "\r\n+CNUM:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("\r\n+CNUM:"); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + if (sscanf(searchPtr, "%127s", idResponse) != 1) + { + idResponse[0] = 0; + } + } + } + free(response); + return String(idResponse); +} + +String UBLOX_AT::getCapabilities(void) +{ + char *response; + char idResponse[128] = {0x00}; // E.g. +GCAP: +FCLASS, +CGSM + UBLOX_AT_error_t err; + + response = ublox_at_calloc_char(minimumResponseAllocation); + + err = sendCommandWithResponse(UBLOX_AT_COMMAND_REQ_CAP, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "\r\n+GCAP:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("\r\n+GCAP:"); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + if (sscanf(searchPtr, "%127s", idResponse) != 1) + { + idResponse[0] = 0; + } + } + } + free(response); + return String(idResponse); +} + +UBLOX_AT_error_t UBLOX_AT::reset(void) +{ + UBLOX_AT_error_t err; + + err = functionality(SILENT_RESET_WITH_SIM); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + // Reset will set the baud rate back to 115200 + //beginSerial(9600); + err = UBLOX_AT_ERROR_INVALID; + while (err != UBLOX_AT_ERROR_SUCCESS) + { + beginSerial(UBLOX_AT_DEFAULT_BAUD_RATE); + setBaud(_baud); + beginSerial(_baud); + err = at(); + } + return init(_baud); + } + return err; +} + +String UBLOX_AT::clock(void) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + char *clockBegin; + char *clockEnd; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_CLOCK) + 2); + if (command == nullptr) + return ""; + sprintf(command, "%s?", UBLOX_AT_COMMAND_CLOCK); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return ""; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + free(command); + free(response); + return ""; + } + + // Response format: \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n + clockBegin = strchr(response, '\"'); // Find first quote + if (clockBegin == nullptr) + { + free(command); + free(response); + return ""; + } + clockBegin += 1; // Increment pointer to begin at first number + clockEnd = strchr(clockBegin, '\"'); // Find last quote + if (clockEnd == nullptr) + { + free(command); + free(response); + return ""; + } + *(clockEnd) = '\0'; // Set last quote to null char -- end string + + String clock = String(clockBegin); // Extract the clock as a String _before_ freeing response + + free(command); + free(response); + + return (clock); +} + +UBLOX_AT_error_t UBLOX_AT::clock(uint8_t *y, uint8_t *mo, uint8_t *d, + uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + char tzPlusMinus; + int scanNum = 0; + + int iy, imo, id, ih, imin, is, itz; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_CLOCK) + 2); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_COMMAND_CLOCK); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + // Response format (if TZ is negative): \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+CCLK:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+CCLK:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "\"%d/%d/%d,%d:%d:%d%c%d\"\r\n", + &iy, &imo, &id, &ih, &imin, &is, &tzPlusMinus, &itz); + } + if (scanNum == 8) + { + *y = iy; + *mo = imo; + *d = id; + *h = ih; + *min = imin; + *s = is; + if (tzPlusMinus == '-') + *tz = 0 - itz; + else + *tz = itz; + } + else + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setClock(uint8_t y, uint8_t mo, uint8_t d, + uint8_t h, uint8_t min, uint8_t s, int8_t tz) +{ + //Convert y,mo,d,h,min,s,tz into a String + //Some platforms don't support sprintf correctly (for %02d or %+02d) so we need to build the String manually + //Format is "yy/MM/dd,hh:mm:ss+TZ" + //TZ can be +/- and is in increments of 15 minutes (not hours) + + String theTime = ""; + + theTime.concat(y / 10); + theTime.concat(y % 10); + theTime.concat('/'); + theTime.concat(mo / 10); + theTime.concat(mo % 10); + theTime.concat('/'); + theTime.concat(d / 10); + theTime.concat(d % 10); + theTime.concat(','); + theTime.concat(h / 10); + theTime.concat(h % 10); + theTime.concat(':'); + theTime.concat(min / 10); + theTime.concat(min % 10); + theTime.concat(':'); + theTime.concat(s / 10); + theTime.concat(s % 10); + if (tz < 0) + { + theTime.concat('-'); + tz = 0 - tz; + } + else + theTime.concat('+'); + theTime.concat(tz / 10); + theTime.concat(tz % 10); + + return (setClock(theTime)); +} + +UBLOX_AT_error_t UBLOX_AT::setClock(String theTime) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_CLOCK) + theTime.length() + 8); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBLOX_AT_COMMAND_CLOCK, theTime.c_str()); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +void UBLOX_AT::autoTimeZoneForBegin(bool tz) +{ + _autoTimeZoneForBegin = tz; +} + +UBLOX_AT_error_t UBLOX_AT::setUtimeMode(UBLOX_AT_utime_mode_t mode, UBLOX_AT_utime_sensor_t sensor) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_REQUEST_TIME) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + if (mode == UBLOX_AT_UTIME_MODE_STOP) // stop UTIME does not require a sensor + sprintf(command, "%s=%d", UBLOX_AT_GNSS_REQUEST_TIME, mode); + else + sprintf(command, "%s=%d,%d", UBLOX_AT_GNSS_REQUEST_TIME, mode, sensor); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_10_SEC_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getUtimeMode(UBLOX_AT_utime_mode_t *mode, UBLOX_AT_utime_sensor_t *sensor) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + UBLOX_AT_utime_mode_t m; + UBLOX_AT_utime_sensor_t s; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_REQUEST_TIME) + 2); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_GNSS_REQUEST_TIME); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_10_SEC_TIMEOUT); + + // Response format: \r\n+UTIME: [,]\r\n\r\nOK\r\n + if (err == UBLOX_AT_ERROR_SUCCESS) + { + int mStore, sStore, scanned = 0; + char *searchPtr = strstr(response, "+UTIME:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UTIME:"); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d\r\n", &mStore, &sStore); + } + m = (UBLOX_AT_utime_mode_t)mStore; + s = (UBLOX_AT_utime_sensor_t)sStore; + if (scanned == 2) + { + *mode = m; + *sensor = s; + } + else if (scanned == 1) + { + *mode = m; + *sensor = UBLOX_AT_UTIME_SENSOR_NONE; + } + else + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setUtimeIndication(UBLOX_AT_utime_urc_configuration_t config) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_TIME_INDICATION) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_GNSS_TIME_INDICATION, config); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getUtimeIndication(UBLOX_AT_utime_urc_configuration_t *config) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + UBLOX_AT_utime_urc_configuration_t c; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_TIME_INDICATION) + 2); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_GNSS_TIME_INDICATION); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + // Response format: \r\n+UTIMEIND: \r\n\r\nOK\r\n + if (err == UBLOX_AT_ERROR_SUCCESS) + { + int cStore, scanned = 0; + char *searchPtr = strstr(response, "+UTIMEIND:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UTIMEIND:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d\r\n", &cStore); + } + c = (UBLOX_AT_utime_urc_configuration_t)cStore; + if (scanned == 1) + { + *config = c; + } + else + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_TIME_CONFIGURATION) + 48); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; +#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) + sprintf(command, "%s=%d,%d", UBLOX_AT_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); +#else + sprintf(command, "%s=%ld,%ld", UBLOX_AT_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); +#endif + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + int32_t ons; + int32_t os; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_TIME_CONFIGURATION) + 2); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_GNSS_TIME_CONFIGURATION); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + // Response format: \r\n+UTIMECFG: ,\r\n\r\nOK\r\n + if (err == UBLOX_AT_ERROR_SUCCESS) + { + int scanned = 0; + char *searchPtr = strstr(response, "+UTIMECFG:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UTIMECFG:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces +#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) + scanned = sscanf(searchPtr, "%d,%d\r\n", &ons, &os); +#else + scanned = sscanf(searchPtr, "%ld,%ld\r\n", &ons, &os); +#endif + } + if (scanned == 2) + { + *offsetNanoseconds = ons; + *offsetSeconds = os; + } + else + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::autoTimeZone(bool enable) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_AUTO_TZ) + 3); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_COMMAND_AUTO_TZ, enable ? 1 : 0); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +int8_t UBLOX_AT::rssi(void) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int rssi; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SIGNAL_QUALITY) + 1); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s", UBLOX_AT_SIGNAL_QUALITY); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, 10000, + minimumResponseAllocation, AT_COMMAND); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + free(command); + free(response); + return -1; + } + + int scanned = 0; + char *searchPtr = strstr(response, "+CSQ:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+CSQ:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%*d", &rssi); + } + if (scanned != 1) + { + rssi = -1; + } + + free(command); + free(response); + return rssi; +} + +UBLOX_AT_error_t UBLOX_AT::getExtSignalQuality(signal_quality& signal_quality) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_EXT_SIGNAL_QUALITY) + 1); + if (command == nullptr) + { + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s", UBLOX_AT_EXT_SIGNAL_QUALITY); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, + UBLOX_AT_RESPONSE_OK_OR_ERROR, response, 10000, + minimumResponseAllocation, AT_COMMAND); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + free(command); + free(response); + return UBLOX_AT_ERROR_ERROR; + } + + int scanned = 0; + const char * responseStr = "+CESQ:"; + char *searchPtr = strstr(response, responseStr); + if (searchPtr != nullptr) + { + searchPtr += strlen(responseStr); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%u,%u,%u,%u,%u,%u", &signal_quality.rxlev, &signal_quality.ber, + &signal_quality.rscp, &signal_quality.enc0, &signal_quality.rsrq, &signal_quality.rsrp); + } + + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + if (scanned == 6) + { + err = UBLOX_AT_ERROR_SUCCESS; + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_registration_status_t UBLOX_AT::registration(bool eps) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int status; + const char* tag = eps ? UBLOX_AT_EPSREGISTRATION_STATUS : UBLOX_AT_REGISTRATION_STATUS; + command = ublox_at_calloc_char(strlen(tag) + 3); + if (command == nullptr) + return UBLOX_AT_REGISTRATION_INVALID; + sprintf(command, "%s?", tag); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_REGISTRATION_INVALID; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, + minimumResponseAllocation, AT_COMMAND); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + free(command); + free(response); + return UBLOX_AT_REGISTRATION_INVALID; + } + + int scanned = 0; + const char *startTag = eps ? UBLOX_AT_EPSREGISTRATION_STATUS_URC : UBLOX_AT_REGISTRATION_STATUS_URC; + char *searchPtr = strstr(response, startTag); + if (searchPtr != nullptr) + { + searchPtr += eps ? strlen(UBLOX_AT_EPSREGISTRATION_STATUS_URC) : strlen(UBLOX_AT_REGISTRATION_STATUS_URC); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%*d,%d", &status); + } + if (scanned != 1) + status = UBLOX_AT_REGISTRATION_INVALID; + + free(command); + free(response); + return (UBLOX_AT_registration_status_t)status; +} + +bool UBLOX_AT::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) +{ + mobile_network_operator_t currentMno; + + // Check currently set MNO profile + if (getMNOprofile(¤tMno) != UBLOX_AT_ERROR_SUCCESS) + { + return false; + } + + if (currentMno == mno) + { + return true; + } + + // Disable transmit and receive so we can change operator + if (functionality(MINIMUM_FUNCTIONALITY) != UBLOX_AT_ERROR_SUCCESS) + { + return false; + } + + if (setMNOprofile(mno, autoReset, urcNotification) != UBLOX_AT_ERROR_SUCCESS) + { + return false; + } + + if (reset() != UBLOX_AT_ERROR_SUCCESS) + { + return false; + } + + return true; +} + +mobile_network_operator_t UBLOX_AT::getNetworkProfile(void) +{ + mobile_network_operator_t mno; + UBLOX_AT_error_t err; + + err = getMNOprofile(&mno); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + return MNO_INVALID; + } + return mno; +} + +UBLOX_AT_error_t UBLOX_AT::setAPN(String apn, uint8_t cid, UBLOX_AT_pdp_type pdpType) +{ + UBLOX_AT_error_t err; + char *command; + char pdpStr[8]; + + memset(pdpStr, 0, 8); + + if (cid >= 8) + return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_DEF) + strlen(apn.c_str()) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + switch (pdpType) + { + case PDP_TYPE_INVALID: + free(command); + return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + break; + case PDP_TYPE_IP: + memcpy(pdpStr, "IP", 2); + break; + case PDP_TYPE_NONIP: + memcpy(pdpStr, "NONIP", 5); + break; + case PDP_TYPE_IPV4V6: + memcpy(pdpStr, "IPV4V6", 6); + break; + case PDP_TYPE_IPV6: + memcpy(pdpStr, "IPV6", 4); + break; + default: + free(command); + return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + break; + } + if (apn == nullptr) + { + if (_printDebug == true) + _debugPort->println(F("setAPN: nullptr")); + sprintf(command, "%s=%d,\"%s\",\"\"", UBLOX_AT_MESSAGE_PDP_DEF, + cid, pdpStr); + } + else + { + if (_printDebug == true) + { + _debugPort->print(F("setAPN: ")); + _debugPort->println(apn); + } + sprintf(command, "%s=%d,\"%s\",\"%s\"", UBLOX_AT_MESSAGE_PDP_DEF, + cid, pdpStr, apn.c_str()); + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + + return err; +} + +// Return the Access Point Name and IP address for the chosen context identifier +UBLOX_AT_error_t UBLOX_AT::getAPN(int cid, String *apn, IPAddress *ip, UBLOX_AT_pdp_type* pdpType) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + if (cid > UBLOX_AT_NUM_PDP_CONTEXT_IDENTIFIERS) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_DEF) + 3); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_MESSAGE_PDP_DEF); + + response = ublox_at_calloc_char(1024); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, 1024); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + // Example: + // +CGDCONT: 0,"IP","payandgo.o2.co.uk","0.0.0.0",0,0,0,0,0,0,0,0,0,0 + // +CGDCONT: 1,"IP","payandgo.o2.co.uk.mnc010.mcc234.gprs","10.160.182.234",0,0,0,2,0,0,0,0,0,0 + int rcid = -1; + char *searchPtr = response; + + bool keepGoing = true; + while (keepGoing == true) + { + int scanned = 0; + // Find the first/next occurrence of +CGDCONT: + searchPtr = strstr(searchPtr, "+CGDCONT:"); + if (searchPtr != nullptr) + { + char strPdpType[10]; + char strApn[128]; + int ipOct[4]; + + searchPtr += strlen("+CGDCONT:"); // Point to the cid + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,\"%[^\"]\",\"%[^\"]\",\"%d.%d.%d.%d", + &rcid, strPdpType, strApn, + &ipOct[0], &ipOct[1], &ipOct[2], &ipOct[3]); + if ((scanned == 7) && (rcid == cid)) { + if (apn) *apn = strApn; + for (int o = 0; ip && (o < 4); o++) + { + (*ip)[o] = (uint8_t)ipOct[o]; + } + if (pdpType) { + *pdpType = (0 == strcmp(strPdpType, "IPV4V6")) ? PDP_TYPE_IPV4V6 : + (0 == strcmp(strPdpType, "IPV6")) ? PDP_TYPE_IPV6 : + (0 == strcmp(strPdpType, "IP")) ? PDP_TYPE_IP : + PDP_TYPE_INVALID; + } + keepGoing = false; + } + } + else // We don't have a match so let's clear the APN and IP address + { + if (apn) *apn = ""; + if (pdpType) *pdpType = PDP_TYPE_INVALID; + if (ip) *ip = {0, 0, 0, 0}; + keepGoing = false; + } + } + } + else + { + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getSimStatus(String* code) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_SIMPIN) + 2); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_COMMAND_SIMPIN); + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + int scanned = 0; + char c[16]; + char *searchPtr = strstr(response, "+CPIN:"); + if (searchPtr != nullptr) { + searchPtr += strlen("+CPIN:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%15s\r\n", c); + } + if (scanned == 1) + { + if(code) + *code = c; + } + else + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setSimPin(String pin) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_SIMPIN) + 4 + pin.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBLOX_AT_COMMAND_SIMPIN, pin.c_str()); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setSIMstateReportingMode(int mode) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SIM_STATE) + 4); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_SIM_STATE, mode); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getSIMstateReportingMode(int *mode) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + int m; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SIM_STATE) + 3); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_SIM_STATE); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + int scanned = 0; + char *searchPtr = strstr(response, "+USIMSTAT:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USIMSTAT:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d\r\n", &m); + } + if (scanned == 1) + { + *mode = m; + } + else + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +const char *PPP_L2P[5] = { + "", + "PPP", + "M-HEX", + "M-RAW_IP", + "M-OPT-PPP", +}; + +UBLOX_AT_error_t UBLOX_AT::enterPPP(uint8_t cid, char dialing_type_char, + unsigned long dialNumber, UBLOX_AT::UBLOX_AT_l2p_t l2p) +{ + UBLOX_AT_error_t err; + char *command; + + if ((dialing_type_char != 0) && (dialing_type_char != 'T') && + (dialing_type_char != 'P')) + { + return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + } + + command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_ENTER_PPP) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + if (dialing_type_char != 0) + { + sprintf(command, "%s%c*%lu**%s*%u#", UBLOX_AT_MESSAGE_ENTER_PPP, dialing_type_char, + dialNumber, PPP_L2P[l2p], (unsigned int)cid); + } + else + { + sprintf(command, "%s*%lu**%s*%u#", UBLOX_AT_MESSAGE_ENTER_PPP, + dialNumber, PPP_L2P[l2p], (unsigned int)cid); + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_CONNECT, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +uint8_t UBLOX_AT::getOperators(struct operator_stats *opRet, int maxOps) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + uint8_t opsSeen = 0; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 3); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=?", UBLOX_AT_OPERATOR_SELECTION); + + int responseSize = (maxOps + 1) * 48; + response = ublox_at_calloc_char(responseSize); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + // AT+COPS maximum response time is 3 minutes (180000 ms) + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_3_MIN_TIMEOUT, responseSize); + + // Sample responses: + // +COPS: (3,"Verizon Wireless","VzW","311480",8),,(0,1,2,3,4),(0,1,2) + // +COPS: (1,"313 100","313 100","313100",8),(2,"AT&T","AT&T","310410",8),(3,"311 480","311 480","311480",8),,(0,1,2,3,4),(0,1,2) + + if (_printDebug == true) + { + _debugPort->print(F("getOperators: Response: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *opBegin; + char *opEnd; + int op = 0; + int stat; + char longOp[26]; + char shortOp[11]; + int act; + unsigned long numOp; + + opBegin = response; + + for (; op < maxOps; op++) + { + opBegin = strchr(opBegin, '('); + if (opBegin == nullptr) + break; + opEnd = strchr(opBegin, ')'); + if (opEnd == nullptr) + break; + + int sscanRead = sscanf(opBegin, "(%d,\"%[^\"]\",\"%[^\"]\",\"%lu\",%d)%*s", + &stat, longOp, shortOp, &numOp, &act); + if (sscanRead == 5) + { + opRet[op].stat = stat; + opRet[op].longOp = (String)(longOp); + opRet[op].shortOp = (String)(shortOp); + opRet[op].numOp = numOp; + opRet[op].act = act; + opsSeen += 1; + } + // TODO: Search for other possible patterns here + else + { + break; // Break out if pattern doesn't match. + } + opBegin = opEnd + 1; // Move opBegin to beginning of next value + } + } + + free(command); + free(response); + + return opsSeen; +} + +UBLOX_AT_error_t UBLOX_AT::registerOperator(struct operator_stats oper) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 24); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=1,2,\"%lu\"", UBLOX_AT_OPERATOR_SELECTION, oper.numOp); + + // AT+COPS maximum response time is 3 minutes (180000 ms) + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_3_MIN_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::automaticOperatorSelection() +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 6); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=0,0", UBLOX_AT_OPERATOR_SELECTION); + + // AT+COPS maximum response time is 3 minutes (180000 ms) + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_3_MIN_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getOperator(String *oper) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + char *searchPtr; + char mode; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 3); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_OPERATOR_SELECTION); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + // AT+COPS maximum response time is 3 minutes (180000 ms) + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_3_MIN_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + searchPtr = strstr(response, "+COPS:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+COPS:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + mode = *searchPtr; // Read first char -- should be mode + if (mode == '2') // Check for de-register + { + err = UBLOX_AT_ERROR_DEREGISTERED; + } + // Otherwise if it's default, manual, set-only, or automatic + else if ((mode == '0') || (mode == '1') || (mode == '3') || (mode == '4')) + { + *oper = ""; + searchPtr = strchr(searchPtr, '\"'); // Move to first quote + if (searchPtr == nullptr) + { + err = UBLOX_AT_ERROR_DEREGISTERED; + } + else + { + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0')) + { + oper->concat(*(searchPtr)); + } + } + if (_printDebug == true) + { + _debugPort->print(F("getOperator: ")); + _debugPort->println(*oper); + } + } + } + } + + free(response); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::deregisterOperator(void) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 4); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=2", UBLOX_AT_OPERATOR_SELECTION); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_3_MIN_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setSMSMessageFormat(UBLOX_AT_message_format_t textMode) +{ + char *command; + UBLOX_AT_error_t err; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_FORMAT) + 4); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_MESSAGE_FORMAT, + (textMode == UBLOX_AT_MESSAGE_FORMAT_TEXT) ? 1 : 0); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::sendSMS(String number, String message) +{ + char *command; + char *messageCStr; + char *numberCStr; + UBLOX_AT_error_t err; + + numberCStr = ublox_at_calloc_char(number.length() + 2); + if (numberCStr == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + number.toCharArray(numberCStr, number.length() + 1); + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SEND_TEXT) + strlen(numberCStr) + 8); + if (command != nullptr) + { + sprintf(command, "%s=\"%s\"", UBLOX_AT_SEND_TEXT, numberCStr); + + err = sendCommandWithResponse(command, ">", nullptr, + UBLOX_AT_10_SEC_TIMEOUT); + free(command); + free(numberCStr); + if (err != UBLOX_AT_ERROR_SUCCESS) + return err; + + messageCStr = ublox_at_calloc_char(message.length() + 1); + if (messageCStr == nullptr) + { + hwWrite(ASCII_CTRL_Z); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + message.toCharArray(messageCStr, message.length() + 1); + messageCStr[message.length()] = ASCII_CTRL_Z; + + err = sendCommandWithResponse(messageCStr, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_10_SEC_TIMEOUT, minimumResponseAllocation, NOT_AT_COMMAND); + + free(messageCStr); + } + else + { + free(numberCStr); + err = UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getPreferredMessageStorage(int *used, int *total, String memory) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + int u; + int t; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_PREF_MESSAGE_STORE) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBLOX_AT_PREF_MESSAGE_STORE, memory.c_str()); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_3_MIN_TIMEOUT); + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + free(command); + free(response); + return err; + } + + int scanned = 0; + char *searchPtr = strstr(response, "+CPMS:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+CPMS:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d", &u, &t); + } + if (scanned == 2) + { + if (_printDebug == true) + { + _debugPort->print(F("getPreferredMessageStorage: memory1 (read and delete): ")); + _debugPort->print(memory); + _debugPort->print(F(" used: ")); + _debugPort->print(u); + _debugPort->print(F(" total: ")); + _debugPort->println(t); + } + *used = u; + *total = t; + } + else + { + err = UBLOX_AT_ERROR_INVALID; + } + + free(response); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_TEXT_MESSAGE) + 5); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_READ_TEXT_MESSAGE, location); + + response = ublox_at_calloc_char(1024); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_10_SEC_TIMEOUT, 1024); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = response; + + // Find the first occurrence of +CMGR: + searchPtr = strstr(searchPtr, "+CMGR:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+CMGR:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + int pointer = 0; + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0') && (pointer < 12)) + { + unread->concat(*(searchPtr)); + pointer++; + } + if ((*searchPtr == '\0') || (pointer == 12)) + { + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + // Search to the next quote + searchPtr = strchr(++searchPtr, '\"'); + pointer = 0; + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0') && (pointer < 24)) + { + from->concat(*(searchPtr)); + pointer++; + } + if ((*searchPtr == '\0') || (pointer == 24)) + { + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + // Skip two commas + searchPtr = strchr(++searchPtr, ','); + searchPtr = strchr(++searchPtr, ','); + // Search to the next quote + searchPtr = strchr(++searchPtr, '\"'); + pointer = 0; + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0') && (pointer < 24)) + { + dateTime->concat(*(searchPtr)); + pointer++; + } + if ((*searchPtr == '\0') || (pointer == 24)) + { + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + // Search to the next new line + searchPtr = strchr(++searchPtr, '\n'); + pointer = 0; + while ((*(++searchPtr) != '\r') && (*searchPtr != '\n') && (*searchPtr != '\0') && (pointer < 512)) + { + message->concat(*(searchPtr)); + pointer++; + } + if ((*searchPtr == '\0') || (pointer == 512)) + { + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + } + else + { + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + } + else + { + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::deleteSMSmessage(int location, int deleteFlag) +{ + char *command; + UBLOX_AT_error_t err; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_DELETE_MESSAGE) + 12); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + if (deleteFlag == 0) + sprintf(command, "%s=%d", UBLOX_AT_DELETE_MESSAGE, location); + else + sprintf(command, "%s=%d,%d", UBLOX_AT_DELETE_MESSAGE, location, deleteFlag); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_55_SECS_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setBaud(unsigned long baud) +{ + UBLOX_AT_error_t err; + char *command; + int b = 0; + + // Error check -- ensure supported baud + for (; b < NUM_SUPPORTED_BAUD; b++) + { + if (UBLOX_AT_SUPPORTED_BAUD[b] == baud) + { + break; + } + } + if (b >= NUM_SUPPORTED_BAUD) + { + return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + } + + // Construct command + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_BAUD) + 7 + 12); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%lu", UBLOX_AT_COMMAND_BAUD, baud); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_SET_BAUD_TIMEOUT); + + free(command); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setFlowControl(UBLOX_AT_flow_control_t value) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_FLOW_CONTROL) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s%d", UBLOX_AT_FLOW_CONTROL, value); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setGpioMode(UBLOX_AT_gpio_t gpio, + UBLOX_AT_gpio_mode_t mode, int value) +{ + UBLOX_AT_error_t err; + char *command; + + // Example command: AT+UGPIOC=16,2 + // Example command: AT+UGPIOC=23,0,1 + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_GPIO) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + if (mode == GPIO_OUTPUT) + sprintf(command, "%s=%d,%d,%d", UBLOX_AT_COMMAND_GPIO, gpio, mode, value); + else + sprintf(command, "%s=%d,%d", UBLOX_AT_COMMAND_GPIO, gpio, mode); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_10_SEC_TIMEOUT); + + free(command); + + return err; +} + +UBLOX_AT::UBLOX_AT_gpio_mode_t UBLOX_AT::getGpioMode(UBLOX_AT_gpio_t gpio) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + char gpioChar[4]; + char *gpioStart; + int gpioMode; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_GPIO) + 2); + if (command == nullptr) + return GPIO_MODE_INVALID; + sprintf(command, "%s?", UBLOX_AT_COMMAND_GPIO); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return GPIO_MODE_INVALID; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + free(command); + free(response); + return GPIO_MODE_INVALID; + } + + sprintf(gpioChar, "%d", gpio); // Convert GPIO to char array + gpioStart = strstr(response, gpioChar); // Find first occurence of GPIO in response + + free(command); + free(response); + + if (gpioStart == nullptr) + return GPIO_MODE_INVALID; // If not found return invalid + sscanf(gpioStart, "%*d,%d\r\n", &gpioMode); + + return (UBLOX_AT_gpio_mode_t)gpioMode; +} + +int UBLOX_AT::socketOpen(UBLOX_AT_socket_protocol_t protocol, unsigned int localPort) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + int sockId = -1; + char *responseStart; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_CREATE_SOCKET) + 10); + if (command == nullptr) + return -1; + if (localPort == 0) + sprintf(command, "%s=%d", UBLOX_AT_CREATE_SOCKET, (int)protocol); + else + sprintf(command, "%s=%d,%d", UBLOX_AT_CREATE_SOCKET, (int)protocol, localPort); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + if (_printDebug == true) + _debugPort->println(F("socketOpen: Fail: nullptr response")); + free(command); + return -1; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("socketOpen: Fail: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" Response: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + free(command); + free(response); + return -1; + } + + responseStart = strstr(response, "+USOCR:"); + if (responseStart == nullptr) + { + if (_printDebug == true) + { + _debugPort->print(F("socketOpen: Failure: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + free(command); + free(response); + return -1; + } + + responseStart += strlen("+USOCR:"); // Move searchPtr to first char + while (*responseStart == ' ') responseStart++; // skip spaces + sscanf(responseStart, "%d", &sockId); + _lastSocketProtocol[sockId] = (int)protocol; + + free(command); + free(response); + + return sockId; +} + +UBLOX_AT_error_t UBLOX_AT::socketClose(int socket, unsigned long timeout) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_CLOSE_SOCKET) + 10); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + // if timeout is short, close asynchronously and don't wait for socket closure (we will get the URC later) + // this will make sure the AT command parser is not confused during init() + const char* format = (UBLOX_AT_STANDARD_RESPONSE_TIMEOUT == timeout) ? "%s=%d,1" : "%s=%d"; + sprintf(command, format, UBLOX_AT_CLOSE_SOCKET, socket); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, timeout); + + if ((err != UBLOX_AT_ERROR_SUCCESS) && (_printDebug == true)) + { + _debugPort->print(F("socketClose: Error: ")); + _debugPort->println(socketGetLastError()); + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketConnect(int socket, const char *address, + unsigned int port) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_CONNECT_SOCKET) + strlen(address) + 11); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\",%d", UBLOX_AT_CONNECT_SOCKET, socket, address, port); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_IP_CONNECT_TIMEOUT); + + free(command); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketConnect(int socket, IPAddress address, + unsigned int port) +{ + char *charAddress = ublox_at_calloc_char(16); + if (charAddress == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + memset(charAddress, 0, 16); + sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); + + return (socketConnect(socket, (const char *)charAddress, port)); +} + +UBLOX_AT_error_t UBLOX_AT::socketWrite(int socket, const char *str, int len) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_WRITE_SOCKET) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + int dataLen = len == -1 ? strlen(str) : len; + sprintf(command, "%s=%d,%d", UBLOX_AT_WRITE_SOCKET, socket, dataLen); + + err = sendCommandWithResponse(command, "@", response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT * 5); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + unsigned long writeDelay = millis(); + while (millis() < (writeDelay + 50)) + delay(1); //u-blox specification says to wait 50ms after receiving "@" to write data. + + if (len == -1) + { + if (_printDebug == true) + { + _debugPort->print(F("socketWrite: writing: ")); + _debugPort->println(str); + } + hwPrint(str); + } + else + { + if (_printDebug == true) + { + _debugPort->print(F("socketWrite: writing ")); + _debugPort->print(len); + _debugPort->println(F(" bytes")); + } + hwWriteData(str, len); + } + + err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_SOCKET_WRITE_TIMEOUT); + } + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("socketWrite: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" => {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketWrite(int socket, String str) +{ + return socketWrite(socket, str.c_str(), str.length()); +} + +UBLOX_AT_error_t UBLOX_AT::socketWriteUDP(int socket, const char *address, int port, const char *str, int len) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int dataLen = len == -1 ? strlen(str) : len; + + command = ublox_at_calloc_char(64); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s=%d,\"%s\",%d,%d", UBLOX_AT_WRITE_UDP_SOCKET, + socket, address, port, dataLen); + err = sendCommandWithResponse(command, "@", response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT * 5); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + if (len == -1) //If binary data we need to send a length. + { + hwPrint(str); + } + else + { + hwWriteData(str, len); + } + err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_SOCKET_WRITE_TIMEOUT); + } + else + { + if (_printDebug == true) + _debugPort->print(F("socketWriteUDP: Error: ")); + if (_printDebug == true) + _debugPort->println(socketGetLastError()); + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len) +{ + char *charAddress = ublox_at_calloc_char(16); + if (charAddress == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + memset(charAddress, 0, 16); + sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); + + return (socketWriteUDP(socket, (const char *)charAddress, port, str, len)); +} + +UBLOX_AT_error_t UBLOX_AT::socketWriteUDP(int socket, String address, int port, String str) +{ + return socketWriteUDP(socket, address.c_str(), port, str.c_str(), str.length()); +} + +UBLOX_AT_error_t UBLOX_AT::socketRead(int socket, int length, char *readDest, int *bytesRead) +{ + char *command; + char *response; + char *strBegin; + int readIndexTotal = 0; + int readIndexThisRead = 0; + UBLOX_AT_error_t err; + int scanNum = 0; + int readLength = 0; + int socketStore = 0; + int bytesLeftToRead = length; + int bytesToRead; + + // Set *bytesRead to zero + if (bytesRead != nullptr) + *bytesRead = 0; + + // Check if length is zero + if (length == 0) + { + if (_printDebug == true) + _debugPort->print(F("socketRead: length is 0! Call socketReadAvailable?")); + return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + } + + // Allocate memory for the command + command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_SOCKET) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + + // Allocate memory for the response + // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing + int responseLength = _saraR5maxSocketRead + strlen(UBLOX_AT_READ_SOCKET) + minimumResponseAllocation; + response = ublox_at_calloc_char(responseLength); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + // If there are more than _saraR5maxSocketRead (1024) bytes to be read, + // we need to do multiple reads to get all the data + + while (bytesLeftToRead > 0) + { + if (bytesLeftToRead > _saraR5maxSocketRead) // Limit a single read to _saraR5maxSocketRead + bytesToRead = _saraR5maxSocketRead; + else + bytesToRead = bytesLeftToRead; + + sprintf(command, "%s=%d,%d", UBLOX_AT_READ_SOCKET, socket, bytesToRead); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, responseLength); + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("socketRead: sendCommandWithResponse err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } + + // Extract the data + char *searchPtr = strstr(response, "+USORD:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USORD:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d", + &socketStore, &readLength); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("socketRead: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + // Check that readLength == bytesToRead + if (readLength != bytesToRead) + { + if (_printDebug == true) + { + _debugPort->print(F("socketRead: length mismatch! bytesToRead=")); + _debugPort->print(bytesToRead); + _debugPort->print(F(" readLength=")); + _debugPort->println(readLength); + } + } + + // Check that readLength > 0 + if (readLength == 0) + { + if (_printDebug == true) + { + _debugPort->println(F("socketRead: zero length!")); + } + free(command); + free(response); + return UBLOX_AT_ERROR_ZERO_READ_LENGTH; + } + + // Find the first double-quote: + strBegin = strchr(searchPtr, '\"'); + + if (strBegin == nullptr) + { + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + // Now copy the data into readDest + readIndexThisRead = 1; // Start after the quote + while (readIndexThisRead < (readLength + 1)) + { + readDest[readIndexTotal] = strBegin[readIndexThisRead]; + readIndexTotal++; + readIndexThisRead++; + } + + if (_printDebug == true) + _debugPort->println(F("socketRead: success")); + + // Update *bytesRead + if (bytesRead != nullptr) + *bytesRead = readIndexTotal; + + // How many bytes are left to read? + // This would have been bytesLeftToRead -= bytesToRead + // Except the SARA can potentially return less data than requested... + // So we need to subtract readLength instead. + bytesLeftToRead -= readLength; + if (_printDebug == true) + { + if (bytesLeftToRead > 0) + { + _debugPort->print(F("socketRead: multiple read. bytesLeftToRead: ")); + _debugPort->println(bytesLeftToRead); + } + } + } // /while (bytesLeftToRead > 0) + + free(command); + free(response); + + return UBLOX_AT_ERROR_SUCCESS; +} + +UBLOX_AT_error_t UBLOX_AT::socketReadAvailable(int socket, int *length) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int readLength = 0; + int socketStore = 0; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_SOCKET) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,0", UBLOX_AT_READ_SOCKET, socket); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USORD:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USORD:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d", + &socketStore, &readLength); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadAvailable: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + *length = readLength; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketReadUDP(int socket, int length, char *readDest, + IPAddress *remoteIPAddress, int *remotePort, int *bytesRead) +{ + char *command; + char *response; + char *strBegin; + int readIndexTotal = 0; + int readIndexThisRead = 0; + UBLOX_AT_error_t err; + int scanNum = 0; + int remoteIPstore[4] = { 0, 0, 0, 0 }; + int portStore = 0; + int readLength = 0; + int socketStore = 0; + int bytesLeftToRead = length; + int bytesToRead; + + // Set *bytesRead to zero + if (bytesRead != nullptr) + *bytesRead = 0; + + // Check if length is zero + if (length == 0) + { + if (_printDebug == true) + _debugPort->print(F("socketReadUDP: length is 0! Call socketReadAvailableUDP?")); + return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + } + + // Allocate memory for the command + command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_UDP_SOCKET) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + + // Allocate memory for the response + // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing + int responseLength = _saraR5maxSocketRead + strlen(UBLOX_AT_READ_UDP_SOCKET) + minimumResponseAllocation; + response = ublox_at_calloc_char(responseLength); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + // If there are more than _saraR5maxSocketRead (1024) bytes to be read, + // we need to do multiple reads to get all the data + + while (bytesLeftToRead > 0) + { + if (bytesLeftToRead > _saraR5maxSocketRead) // Limit a single read to _saraR5maxSocketRead + bytesToRead = _saraR5maxSocketRead; + else + bytesToRead = bytesLeftToRead; + + sprintf(command, "%s=%d,%d", UBLOX_AT_READ_UDP_SOCKET, socket, bytesToRead); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, responseLength); + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadUDP: sendCommandWithResponse err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } + + // Extract the data + char *searchPtr = strstr(response, "+USORF:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USORF:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\",%d,%d", + &socketStore, &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], + &portStore, &readLength); + } + if (scanNum != 7) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadUDP: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + // Check that readLength == bytesToRead + if (readLength != bytesToRead) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadUDP: length mismatch! bytesToRead=")); + _debugPort->print(bytesToRead); + _debugPort->print(F(" readLength=")); + _debugPort->println(readLength); + } + } + + // Check that readLength > 0 + if (readLength == 0) + { + if (_printDebug == true) + { + _debugPort->println(F("socketRead: zero length!")); + } + free(command); + free(response); + return UBLOX_AT_ERROR_ZERO_READ_LENGTH; + } + + // Find the third double-quote + strBegin = strchr(searchPtr, '\"'); + strBegin = strchr(strBegin + 1, '\"'); + strBegin = strchr(strBegin + 1, '\"'); + + if (strBegin == nullptr) + { + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + // Now copy the data into readDest + readIndexThisRead = 1; // Start after the quote + while (readIndexThisRead < (readLength + 1)) + { + readDest[readIndexTotal] = strBegin[readIndexThisRead]; + readIndexTotal++; + readIndexThisRead++; + } + + // If remoteIPaddress is not nullptr, copy the remote IP address + if (remoteIPAddress != nullptr) + { + IPAddress tempAddress; + for (int i = 0; i <= 3; i++) + { + tempAddress[i] = (uint8_t)remoteIPstore[i]; + } + *remoteIPAddress = tempAddress; + } + + // If remotePort is not nullptr, copy the remote port + if (remotePort != nullptr) + { + *remotePort = portStore; + } + + if (_printDebug == true) + _debugPort->println(F("socketReadUDP: success")); + + // Update *bytesRead + if (bytesRead != nullptr) + *bytesRead = readIndexTotal; + + // How many bytes are left to read? + // This would have been bytesLeftToRead -= bytesToRead + // Except the SARA can potentially return less data than requested... + // So we need to subtract readLength instead. + bytesLeftToRead -= readLength; + if (_printDebug == true) + { + if (bytesLeftToRead > 0) + { + _debugPort->print(F("socketReadUDP: multiple read. bytesLeftToRead: ")); + _debugPort->println(bytesLeftToRead); + } + } + } // /while (bytesLeftToRead > 0) + + free(command); + free(response); + + return UBLOX_AT_ERROR_SUCCESS; +} + +UBLOX_AT_error_t UBLOX_AT::socketReadAvailableUDP(int socket, int *length) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int readLength = 0; + int socketStore = 0; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_UDP_SOCKET) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,0", UBLOX_AT_READ_UDP_SOCKET, socket); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USORF:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USORF:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d", + &socketStore, &readLength); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadAvailableUDP: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + *length = readLength; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketListen(int socket, unsigned int port) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_LISTEN_SOCKET) + 9); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", UBLOX_AT_LISTEN_SOCKET, socket, port); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketDirectLinkMode(int socket) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_DIRECT_LINK) + 8); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_SOCKET_DIRECT_LINK, socket); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_CONNECT, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger) +{ + // valid range is 0 (trigger disabled), 100-120000 + if (!((timerTrigger == 0) || ((timerTrigger >= 100) && (timerTrigger <= 120000)))) + return UBLOX_AT_ERROR_ERROR; + + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_UD_CONFIGURATION) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=5,%d,%ld", UBLOX_AT_UD_CONFIGURATION, socket, timerTrigger); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger) +{ + // valid range is 0, 3-1472 for UDP + if (!((dataLengthTrigger == 0) || ((dataLengthTrigger >= 3) && (dataLengthTrigger <= 1472)))) + return UBLOX_AT_ERROR_ERROR; + + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_UD_CONFIGURATION) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=6,%d,%d", UBLOX_AT_UD_CONFIGURATION, socket, dataLengthTrigger); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketDirectLinkCharacterTrigger(int socket, int characterTrigger) +{ + // The allowed range is -1, 0-255, the factory-programmed value is -1; -1 means trigger disabled. + if (!((characterTrigger >= -1) && (characterTrigger <= 255))) + return UBLOX_AT_ERROR_ERROR; + + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_UD_CONFIGURATION) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=7,%d,%d", UBLOX_AT_UD_CONFIGURATION, socket, characterTrigger); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer) +{ + // valid range is 0, 1000-72000 + if (!((congestionTimer == 0) || ((congestionTimer >= 1000) && (congestionTimer <= 72000)))) + return UBLOX_AT_ERROR_ERROR; + + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_UD_CONFIGURATION) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=8,%d,%ld", UBLOX_AT_UD_CONFIGURATION, socket, congestionTimer); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::querySocketType(int socket, UBLOX_AT_socket_protocol_t *protocol) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int socketStore = 0; + int paramVal; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,0", UBLOX_AT_SOCKET_CONTROL, socket); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,0,%d", + &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketType: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + *protocol = (UBLOX_AT_socket_protocol_t)paramVal; + _lastSocketProtocol[socketStore] = paramVal; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::querySocketLastError(int socket, int *error) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int socketStore = 0; + int paramVal; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,1", UBLOX_AT_SOCKET_CONTROL, socket); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,1,%d", + &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketLastError: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + *error = paramVal; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::querySocketTotalBytesSent(int socket, uint32_t *total) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int socketStore = 0; + long unsigned int paramVal; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,2", UBLOX_AT_SOCKET_CONTROL, socket); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,2,%lu", + &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketTotalBytesSent: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + *total = (uint32_t)paramVal; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::querySocketTotalBytesReceived(int socket, uint32_t *total) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int socketStore = 0; + long unsigned int paramVal; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,3", UBLOX_AT_SOCKET_CONTROL, socket); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,3,%lu", + &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketTotalBytesReceived: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + *total = (uint32_t)paramVal; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::querySocketRemoteIPAddress(int socket, IPAddress *address, int *port) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int socketStore = 0; + int paramVals[5]; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,4", UBLOX_AT_SOCKET_CONTROL, socket); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,4,\"%d.%d.%d.%d\",%d", + &socketStore, + ¶mVals[0], ¶mVals[1], ¶mVals[2], ¶mVals[3], + ¶mVals[4]); + } + if (scanNum != 6) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketRemoteIPAddress: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + IPAddress tempAddress = { (uint8_t)paramVals[0], (uint8_t)paramVals[1], + (uint8_t)paramVals[2], (uint8_t)paramVals[3] }; + *address = tempAddress; + *port = paramVals[4]; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::querySocketStatusTCP(int socket, UBLOX_AT_tcp_socket_status_t *status) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int socketStore = 0; + int paramVal; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,10", UBLOX_AT_SOCKET_CONTROL, socket); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,10,%d", + &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketStatusTCP: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + *status = (UBLOX_AT_tcp_socket_status_t)paramVal; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::querySocketOutUnackData(int socket, uint32_t *total) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int socketStore = 0; + long unsigned int paramVal; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,11", UBLOX_AT_SOCKET_CONTROL, socket); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,11,%lu", + &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketOutUnackData: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + *total = (uint32_t)paramVal; + } + + free(command); + free(response); + + return err; +} + +//Issues command to get last socket error, then prints to serial. Also updates rx/backlog buffers. +int UBLOX_AT::socketGetLastError() +{ + UBLOX_AT_error_t err; + char *command; + char *response; + int errorCode = -1; + + command = ublox_at_calloc_char(64); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s", UBLOX_AT_GET_ERROR); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOER:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOER:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + sscanf(searchPtr, "%d", &errorCode); + } + } + + free(command); + free(response); + + return errorCode; +} + +IPAddress UBLOX_AT::lastRemoteIP(void) +{ + return _lastRemoteIP; +} + +UBLOX_AT_error_t UBLOX_AT::resetHTTPprofile(int profile) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_HTTP_PROFILE, profile); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setHTTPserverIPaddress(int profile, IPAddress address) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 64); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SERVER_IP, + address[0], address[1], address[2], address[3]); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setHTTPserverName(int profile, String server) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 12 + server.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SERVER_NAME, + server.c_str()); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setHTTPusername(int profile, String username) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 12 + username.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_USERNAME, + username.c_str()); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setHTTPpassword(int profile, String password) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 12 + password.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_PASSWORD, + password.c_str()); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setHTTPauthentication(int profile, bool authenticate) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_AUTHENTICATION, + authenticate); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setHTTPserverPort(int profile, int port) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SERVER_PORT, + port); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setHTTPcustomHeader(int profile, String header) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 12 + header.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_ADD_CUSTOM_HEADERS, + header.c_str()); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setHTTPsecure(int profile, bool secure, int secprofile) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + if (secprofile == -1) + sprintf(command, "%s=%d,%d,%d", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SECURE, + secure); + else sprintf(command, "%s=%d,%d,%d,%d", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SECURE, + secure, secprofile); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::ping(String remote_host, int retry, int p_size, + unsigned long timeout, int ttl) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_PING_COMMAND) + 48 + + remote_host.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\",%d,%d,%ld,%d", UBLOX_AT_PING_COMMAND, + remote_host.c_str(), retry, p_size, timeout, ttl); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::sendHTTPGET(int profile, String path, String responseFilename) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_COMMAND) + 24 + + path.length() + responseFilename.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\",\"%s\"", UBLOX_AT_HTTP_COMMAND, profile, UBLOX_AT_HTTP_COMMAND_GET, + path.c_str(), responseFilename.c_str()); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::sendHTTPPOSTdata(int profile, String path, String responseFilename, + String data, UBLOX_AT_http_content_types_t httpContentType) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_COMMAND) + 24 + + path.length() + responseFilename.length() + data.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBLOX_AT_HTTP_COMMAND, profile, UBLOX_AT_HTTP_COMMAND_POST_DATA, + path.c_str(), responseFilename.c_str(), data.c_str(), httpContentType); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::sendHTTPPOSTfile(int profile, String path, String responseFilename, + String requestFile, UBLOX_AT_http_content_types_t httpContentType) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_COMMAND) + 24 + + path.length() + responseFilename.length() + requestFile.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBLOX_AT_HTTP_COMMAND, profile, UBLOX_AT_HTTP_COMMAND_POST_FILE, + path.c_str(), responseFilename.c_str(), requestFile.c_str(), httpContentType); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getHTTPprotocolError(int profile, int *error_class, int *error_code) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + int rprofile, eclass, ecode; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROTOCOL_ERROR) + 4); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_HTTP_PROTOCOL_ERROR, profile); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + int scanned = 0; + char *searchPtr = strstr(response, "+UHTTPER:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UHTTPER:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d,%d\r\n", + &rprofile, &eclass, &ecode); + } + if (scanned == 3) + { + *error_class = eclass; + *error_code = ecode; + } + else + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::nvMQTT(UBLOX_AT_mqtt_nv_parameter_t parameter) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_NVM) + 10); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_MQTT_NVM, parameter); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setMQTTclientId(const String& clientId) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_PROFILE) + clientId.length() + 10); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\"", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_CLIENT_ID, clientId.c_str()); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setMQTTserver(const String& serverName, int port) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_PROFILE) + serverName.length() + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\",%d", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_SERVERNAME, serverName.c_str(), port); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setMQTTcredentials(const String& userName, const String& pwd) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_PROFILE) + userName.length() + pwd.length() + 16); + if (command == nullptr) { + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + sprintf(command, "%s=%d,\"%s\",\"%s\"", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_USERNAMEPWD, userName.c_str(), pwd.c_str()); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setMQTTsecure(bool secure, int secprofile) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_PROFILE) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + if (secprofile == -1) sprintf(command, "%s=%d,%d", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_SECURE, secure); + else sprintf(command, "%s=%d,%d,%d", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_SECURE, secure, secprofile); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::connectMQTT(void) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 10); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_LOGIN); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::disconnectMQTT(void) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 10); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_LOGOUT); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::subscribeMQTTtopic(int max_Qos, const String& topic) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 16 + topic.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_SUBSCRIBE, max_Qos, topic.c_str()); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::unsubscribeMQTTtopic(const String& topic) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 16 + topic.length()); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\"", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_UNSUBSCRIBE, topic.c_str()); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::readMQTT(int* pQos, String* pTopic, uint8_t *readDest, int readLength, int *bytesRead) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int total_length, topic_length, data_length; + + // Set *bytesRead to zero + if (bytesRead != nullptr) + *bytesRead = 0; + + // Allocate memory for the command + command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 10); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + + // Allocate memory for the response + int responseLength = readLength + minimumResponseAllocation; + response = ublox_at_calloc_char(responseLength); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... + // To try and avoid this, look for \"\r\n\r\nOK\r\n there is a extra \r\n beetween " and the the standard \r\nOK\r\n + const char mqttReadTerm[] = "\"\r\n\r\nOK\r\n"; + sprintf(command, "%s=%d,%d", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_READ, 1); + err = sendCommandWithResponse(command, mqttReadTerm, response, + (5 * UBLOX_AT_STANDARD_RESPONSE_TIMEOUT), responseLength); + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("readMQTT: sendCommandWithResponse err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } + + // Extract the data + char *searchPtr = strstr(response, "+UMQTTC:"); + int cmd = 0; + if (searchPtr != nullptr) + { + searchPtr += strlen("+UMQTTC:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,%d,%d,\"%*[^\"]\",%d,\"", &cmd, pQos, &total_length, &topic_length, &data_length); + } + if ((scanNum != 5) || (cmd != UBLOX_AT_MQTT_COMMAND_READ)) + { + if (_printDebug == true) + { + _debugPort->print(F("readMQTT: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + err = UBLOX_AT_ERROR_SUCCESS; + searchPtr = strstr(searchPtr, "\""); + if (searchPtr!= nullptr) { + if (pTopic) { + searchPtr[topic_length + 1] = '\0'; // zero terminate + *pTopic = searchPtr + 1; + searchPtr[topic_length + 1] = '\"'; // restore + } + searchPtr = strstr(searchPtr + topic_length + 2, "\""); + if (readDest && (searchPtr != nullptr) && (response + responseLength >= searchPtr + data_length + 1) && (searchPtr[data_length + 1] == '"')) { + if (data_length > readLength) { + data_length = readLength; + if (_printDebug == true) { + _debugPort->print(F("readMQTT: error: trucate message")); + } + err = UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + memcpy(readDest, searchPtr+1, data_length); + *bytesRead = data_length; + } else { + if (_printDebug == true) { + _debugPort->print(F("readMQTT: error: message end ")); + } + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + } + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::mqttPublishTextMsg(const String& topic, const char * const msg, uint8_t qos, bool retain) +{ + if (topic.length() < 1 || msg == nullptr) + { + return UBLOX_AT_ERROR_INVALID; + } + + UBLOX_AT_error_t err; + + char sanitized_msg[MAX_MQTT_DIRECT_MSG_LEN + 1]; + memset(sanitized_msg, 0, sizeof(sanitized_msg)); + + // Check the message length and truncate if necessary. + size_t msg_len = strnlen(msg, MAX_MQTT_DIRECT_MSG_LEN); + if (msg_len > MAX_MQTT_DIRECT_MSG_LEN) + { + msg_len = MAX_MQTT_DIRECT_MSG_LEN; + } + + strncpy(sanitized_msg, msg, msg_len); + char * msg_ptr = sanitized_msg; + while (*msg_ptr != 0) + { + if (*msg_ptr == '"') + { + *msg_ptr = ' '; + } + + msg_ptr++; + } + + char *command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 20 + topic.length() + msg_len); + if (command == nullptr) + { + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s=%d,%u,%u,0,\"%s\",\"%s\"", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_PUBLISH, qos, (retain ? 1:0), topic.c_str(), sanitized_msg); + + sendCommand(command, true); + err = waitForResponse(UBLOX_AT_RESPONSE_MORE, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + sendCommand(msg, false); + err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + } + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::mqttPublishBinaryMsg(const String& topic, const char * const msg, size_t msg_len, uint8_t qos, bool retain) +{ + /* + * The modem prints the '>' as the signal to send the binary message content. + * at+umqttc=9,0,0,"topic",4 + * + * >"xY" + * OK + * + * +UUMQTTC: 9,1 + */ + if (topic.length() < 1|| msg == nullptr || msg_len > MAX_MQTT_DIRECT_MSG_LEN) + { + return UBLOX_AT_ERROR_INVALID; + } + + UBLOX_AT_error_t err; + char *command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 20 + topic.length()); + if (command == nullptr) + { + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s=%d,%u,%u,\"%s\",%u", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_PUBLISHBINARY, qos, (retain ? 1:0), topic.c_str(), msg_len); + + sendCommand(command, true); + err = waitForResponse(UBLOX_AT_RESPONSE_MORE, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + sendCommand(msg, false); + err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + } + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::mqttPublishFromFile(const String& topic, const String& filename, uint8_t qos, bool retain) +{ + if (topic.length() < 1|| filename.length() < 1) + { + return UBLOX_AT_ERROR_INVALID; + } + + UBLOX_AT_error_t err; + char *command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 20 + topic.length() + filename.length()); + if (command == nullptr) + { + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s=%d,%u,%u,\"%s\",\"%s\"", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_PUBLISHFILE, qos, (retain ? 1:0), topic.c_str(), filename.c_str()); + + sendCommand(command, true); + err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getMQTTprotocolError(int *error_code, int *error_code2) +{ + UBLOX_AT_error_t err; + char *response; + + int code, code2; + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(UBLOX_AT_MQTT_PROTOCOL_ERROR, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + int scanned = 0; + char *searchPtr = strstr(response, "+UMQTTER:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UMQTTER:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d\r\n", + &code, &code2); + } + if (scanned == 2) + { + *error_code = code; + *error_code2 = code2; + } + else + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setFTPserver(const String& serverName) +{ + constexpr size_t cmd_len = 145; + char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> + + snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBLOX_AT_FTP_PROFILE, UBLOX_AT_FTP_PROFILE_SERVERNAME, serverName.c_str()); + return sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); +} + +UBLOX_AT_error_t UBLOX_AT::setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger) +{ + constexpr size_t cmd_len = 64; + char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> + + snprintf(command, cmd_len - 1, "%s=%d,%u,%u,%u", UBLOX_AT_FTP_PROFILE, UBLOX_AT_FTP_PROFILE_TIMEOUT, timeout, cmd_linger, data_linger); + return sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); +} + +UBLOX_AT_error_t UBLOX_AT::setFTPcredentials(const String& userName, const String& pwd) +{ + UBLOX_AT_error_t err; + constexpr size_t cmd_len = 48; + char command[cmd_len]; // long enough for AT+UFTP=n,<30 bytes> + + snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBLOX_AT_FTP_PROFILE, UBLOX_AT_FTP_PROFILE_USERNAME, userName.c_str()); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + return err; + } + + snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBLOX_AT_FTP_PROFILE, UBLOX_AT_FTP_PROFILE_PWD, pwd.c_str()); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::connectFTP(void) +{ + constexpr size_t cmd_len = 16; + char command[cmd_len]; // long enough for AT+UFTPC=n + + snprintf(command, cmd_len - 1, "%s=%d", UBLOX_AT_FTP_COMMAND, UBLOX_AT_FTP_COMMAND_LOGIN); + return sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); +} + +UBLOX_AT_error_t UBLOX_AT::disconnectFTP(void) +{ + constexpr size_t cmd_len = 16; + char command[cmd_len]; // long enough for AT+UFTPC=n + + snprintf(command, cmd_len - 1, "%s=%d", UBLOX_AT_FTP_COMMAND, UBLOX_AT_FTP_COMMAND_LOGOUT); + return sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); +} + +UBLOX_AT_error_t UBLOX_AT::ftpGetFile(const String& filename) +{ + char * command = ublox_at_calloc_char(strlen(UBLOX_AT_FTP_COMMAND) + (2 * filename.length()) + 16); + if (command == nullptr) + { + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s=%d,\"%s\",\"%s\"", UBLOX_AT_FTP_COMMAND, UBLOX_AT_FTP_COMMAND_GET_FILE, filename.c_str(), filename.c_str()); + //memset(response, 0, sizeof(response)); + //sendCommandWithResponse(command, UBLOX_AT_RESPONSE_CONNECT, response, 8000 /* ms */, response_len); + UBLOX_AT_error_t err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getFTPprotocolError(int *error_code, int *error_code2) +{ + UBLOX_AT_error_t err; + char *response; + + int code, code2; + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(UBLOX_AT_FTP_PROTOCOL_ERROR, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + int scanned = 0; + char *searchPtr = strstr(response, "+UFTPER:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UFTPER:"); // Move searchPtr to first char + while (*searchPtr == ' ') + { + searchPtr++; // skip spaces + } + scanned = sscanf(searchPtr, "%d,%d\r\n", &code, &code2); + } + + if (scanned == 2) + { + *error_code = code; + *error_code2 = code2; + } + else + { + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + } + + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::resetSecurityProfile(int secprofile) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SEC_PROFILE) + 6); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + + sprintf(command, "%s=%d", UBLOX_AT_SEC_PROFILE, secprofile); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::configSecurityProfile(int secprofile, UBLOX_AT_sec_profile_parameter_t parameter, int value) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SEC_PROFILE) + 10); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBLOX_AT_SEC_PROFILE, secprofile,parameter,value); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::configSecurityProfileString(int secprofile, UBLOX_AT_sec_profile_parameter_t parameter, String value) +{ + UBLOX_AT_error_t err; + char *command; + command = ublox_at_calloc_char(strlen(UBLOX_AT_SEC_PROFILE) + value.length() + 10); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_SEC_PROFILE, secprofile,parameter,value.c_str()); + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setSecurityManager(UBLOX_AT_sec_manager_opcode_t opcode, UBLOX_AT_sec_manager_parameter_t parameter, String name, String data) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_SEC_MANAGER) + name.length() + 20); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + int dataLen = data.length(); + sprintf(command, "%s=%d,%d,\"%s\",%d", UBLOX_AT_SEC_MANAGER, opcode, parameter, name.c_str(), dataLen); + + err = sendCommandWithResponse(command, ">", response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("dataDownload: writing ")); + _debugPort->print(dataLen); + _debugPort->println(F(" bytes")); + } + hwWriteData(data.c_str(), dataLen); + err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT*3); + } + + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("dataDownload: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" => {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, int value) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_PSD_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_CONFIG) + 24); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBLOX_AT_MESSAGE_PDP_CONFIG, profile, parameter, + value); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, UBLOX_AT_pdp_protocol_type_t value) +{ + return (setPDPconfiguration(profile, parameter, (int)value)); +} + +UBLOX_AT_error_t UBLOX_AT::setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, String value) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_PSD_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_CONFIG) + 64); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_MESSAGE_PDP_CONFIG, profile, parameter, + value.c_str()); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, IPAddress value) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_PSD_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_CONFIG) + 64); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBLOX_AT_MESSAGE_PDP_CONFIG, profile, parameter, + value[0], value[1], value[2], value[3]); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::performPDPaction(int profile, UBLOX_AT_pdp_actions_t action) +{ + UBLOX_AT_error_t err; + char *command; + + if (profile >= UBLOX_AT_NUM_PSD_PROFILES) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_ACTION) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", UBLOX_AT_MESSAGE_PDP_ACTION, profile, action); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::activatePDPcontext(bool status, int cid) +{ + UBLOX_AT_error_t err; + char *command; + + if (cid >= UBLOX_AT_NUM_PDP_CONTEXT_IDENTIFIERS) + return UBLOX_AT_ERROR_ERROR; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_CONTEXT_ACTIVATE) + 32); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + if (cid == -1) + sprintf(command, "%s=%d", UBLOX_AT_MESSAGE_PDP_CONTEXT_ACTIVATE, status); + else + sprintf(command, "%s=%d,%d", UBLOX_AT_MESSAGE_PDP_CONTEXT_ACTIVATE, status, cid); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getNetworkAssignedIPAddress(int profile, IPAddress *address) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + int scanNum = 0; + int profileStore = 0; + int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation + int paramVals[4]; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_NETWORK_ASSIGNED_DATA) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", UBLOX_AT_NETWORK_ASSIGNED_DATA, profile, paramTag); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+UPSND:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UPSND:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,\"%d.%d.%d.%d\"", + &profileStore, ¶mTag, + ¶mVals[0], ¶mVals[1], ¶mVals[2], ¶mVals[3]); + } + if (scanNum != 6) + { + if (_printDebug == true) + { + _debugPort->print(F("getNetworkAssignedIPAddress: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + IPAddress tempAddress = { (uint8_t)paramVals[0], (uint8_t)paramVals[1], + (uint8_t)paramVals[2], (uint8_t)paramVals[3] }; + *address = tempAddress; + } + + free(command); + free(response); + + return err; +} + +bool UBLOX_AT::isGPSon(void) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + bool on = false; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_POWER) + 2); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_GNSS_POWER); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, + UBLOX_AT_10_SEC_TIMEOUT); + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + // Example response: "+UGPS: 0" for off "+UGPS: 1,0,1" for on + // Search for a ':' followed by a '1' or ' 1' + char *pch1 = strchr(response, ':'); + if (pch1 != nullptr) + { + char *pch2 = strchr(response, '1'); + if ((pch2 != nullptr) && ((pch2 == pch1 + 1) || (pch2 == pch1 + 2))) + on = true; + } + } + + free(command); + free(response); + + return on; +} + +UBLOX_AT_error_t UBLOX_AT::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_aiding_mode_t gnss_aiding) +{ + UBLOX_AT_error_t err; + char *command; + bool gpsState; + + // Don't turn GPS on/off if it's already on/off + gpsState = isGPSon(); + if ((enable && gpsState) || (!enable && !gpsState)) + { + return UBLOX_AT_ERROR_SUCCESS; + } + + // GPS power management + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_POWER) + 32); // gnss_sys could be up to three digits + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + if (enable) + { + sprintf(command, "%s=1,%d,%d", UBLOX_AT_GNSS_POWER, gnss_aiding, gnss_sys); + } + else + { + sprintf(command, "%s=0", UBLOX_AT_GNSS_POWER); + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, 10000); + + free(command); + return err; +} + +/* +UBLOX_AT_error_t UBLOX_AT::gpsEnableClock(bool enable) +{ + // AT+UGZDA=<0,1> + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsGetClock(struct ClockData *clock) +{ + // AT+UGZDA? + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsEnableFix(bool enable) +{ + // AT+UGGGA=<0,1> + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsGetFix(struct PositionData *pos) +{ + // AT+UGGGA? + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsEnablePos(bool enable) +{ + // AT+UGGLL=<0,1> + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsGetPos(struct PositionData *pos) +{ + // AT+UGGLL? + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsEnableSat(bool enable) +{ + // AT+UGGSV=<0,1> + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsGetSat(uint8_t *sats) +{ + // AT+UGGSV? + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} +*/ + +UBLOX_AT_error_t UBLOX_AT::gpsEnableRmc(bool enable) +{ + // AT+UGRMC=<0,1> + UBLOX_AT_error_t err; + char *command; + + // ** Don't call gpsPower here. It causes problems for +UTIME and the PPS signal ** + // ** Call isGPSon and gpsPower externally if required ** + // if (!isGPSon()) + // { + // err = gpsPower(true); + // if (err != UBLOX_AT_ERROR_SUCCESS) + // { + // return err; + // } + // } + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_GPRMC) + 3); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_GNSS_GPRMC, enable ? 1 : 0); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_10_SEC_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsGetRmc(struct PositionData *pos, struct SpeedData *spd, + struct ClockData *clk, bool *valid) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + char *rmcBegin; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_GPRMC) + 2); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_GNSS_GPRMC); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_10_SEC_TIMEOUT); + if (err == UBLOX_AT_ERROR_SUCCESS) + { + // Fast-forward response string to $GPRMC starter + rmcBegin = strstr(response, "$GPRMC"); + if (rmcBegin == nullptr) + { + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + else + { + *valid = parseGPRMCString(rmcBegin, pos, clk, spd); + } + } + + free(command); + free(response); + return err; +} + +/* +UBLOX_AT_error_t UBLOX_AT::gpsEnableSpeed(bool enable) +{ + // AT+UGVTG=<0,1> + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsGetSpeed(struct SpeedData *speed) +{ + // AT+UGVTG? + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + return err; +} +*/ + +UBLOX_AT_error_t UBLOX_AT::gpsRequest(unsigned int timeout, uint32_t accuracy, + bool detailed, unsigned int sensor) +{ + // AT+ULOC=2,,,, + UBLOX_AT_error_t err; + char *command; + + // This function will only work if the GPS module is initially turned off. + if (isGPSon()) + { + gpsPower(false); + } + + if (timeout > 999) + timeout = 999; + if (accuracy > 999999) + accuracy = 999999; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_REQUEST_LOCATION) + 24); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; +#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) + sprintf(command, "%s=2,%d,%d,%d,%d", UBLOX_AT_GNSS_REQUEST_LOCATION, + sensor, detailed ? 1 : 0, timeout, accuracy); +#else + sprintf(command, "%s=2,%d,%d,%d,%ld", UBLOX_AT_GNSS_REQUEST_LOCATION, + sensor, detailed ? 1 : 0, timeout, accuracy); +#endif + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_10_SEC_TIMEOUT); + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, + unsigned int days, unsigned int period, unsigned int resolution, + unsigned int gnssTypes, unsigned int mode, unsigned int dataType) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_AIDING_SERVER_CONFIGURATION) + 256); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + + sprintf(command, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBLOX_AT_AIDING_SERVER_CONFIGURATION, + primaryServer, secondaryServer, authToken, + days, period, resolution, gnssTypes, mode, dataType); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + + +// OK for text files. But will fail with binary files (containing \0) on some platforms. +UBLOX_AT_error_t UBLOX_AT::appendFileContents(String filename, const char *str, int len) +{ + char *command; + char *response; + UBLOX_AT_error_t err; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_DOWNLOAD_FILE) + filename.length() + 10); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + int dataLen = len == -1 ? strlen(str) : len; + sprintf(command, "%s=\"%s\",%d", UBLOX_AT_FILE_SYSTEM_DOWNLOAD_FILE, filename.c_str(), dataLen); + + err = sendCommandWithResponse(command, ">", response, + UBLOX_AT_STANDARD_RESPONSE_TIMEOUT*2); + + unsigned long writeDelay = millis(); + while (millis() < (writeDelay + 50)) + delay(1); //uBlox specification says to wait 50ms after receiving "@" to write data. + + if (err == UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("fileDownload: writing ")); + _debugPort->print(dataLen); + _debugPort->println(F(" bytes")); + } + hwWriteData(str, dataLen); + + err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT*5); + } + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("fileDownload: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" => {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::appendFileContents(String filename, String str) +{ + return appendFileContents(filename, str.c_str(), str.length()); +} + + +// OK for text files. But will fail with binary files (containing \0) on some platforms. +UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, String *contents) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + // Start by getting the file size so we know in advance how much data to expect + int fileSize = 0; + err = getFileSize(filename, &fileSize); + if (err != UBLOX_AT_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: getFileSize returned err ")); + _debugPort->println(err); + } + return err; + } + + command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_READ_FILE) + filename.length() + 8); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBLOX_AT_FILE_SYSTEM_READ_FILE, filename.c_str()); + + response = ublox_at_calloc_char(fileSize + minimumResponseAllocation); + if (response == nullptr) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: response alloc failed: ")); + _debugPort->println(fileSize + minimumResponseAllocation); + } + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + // A large file will completely fill the backlog buffer - but it will be pruned afterwards + // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... + // To try and avoid this, look for \"\r\nOK\r\n + const char fileReadTerm[] = "\r\nOK\r\n"; //LARA-R6 returns "\"\r\n\r\nOK\r\n" while SARA-R5 return "\"\r\nOK\r\n"; + err = sendCommandWithResponse(command, fileReadTerm, + response, (5 * UBLOX_AT_STANDARD_RESPONSE_TIMEOUT), + (fileSize + minimumResponseAllocation)); + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: sendCommandWithResponse returned err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } + + // Response format: \r\n+URDFILE: "filename",36,"these bytes are the data of the file"\r\n\r\nOK\r\n + int scanned = 0; + int readFileSize = 0; + char *searchPtr = strstr(response, "+URDFILE:"); + if (searchPtr != nullptr) + { + searchPtr = strchr(searchPtr, '\"'); // Find the first quote + searchPtr = strchr(++searchPtr, '\"'); // Find the second quote + + scanned = sscanf(searchPtr, "\",%d,", &readFileSize); // Get the file size (again) + if (scanned == 1) + { + searchPtr = strchr(++searchPtr, '\"'); // Find the third quote + + if (searchPtr == nullptr) + { + if (_printDebug == true) + { + _debugPort->println(F("getFileContents: third quote not found!")); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + int bytesRead = 0; + + while (bytesRead < readFileSize) + { + searchPtr++; // Increment searchPtr then copy file char into contents + // Important Note: some implementations of concat, like the one on ESP32, are binary-compatible. + // But some, like SAMD, are not. They use strlen or strcpy internally - which don't like \0's. + // The only true binary-compatible solution is to use getFileContents(String filename, char *contents)... + contents->concat(*(searchPtr)); // Append file char to contents + bytesRead++; + } + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: total bytes read: ")); + _debugPort->println(bytesRead); + } + err = UBLOX_AT_ERROR_SUCCESS; + } + else + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: sscanf failed! scanned is ")); + _debugPort->println(scanned); + } + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + } + else + { + if (_printDebug == true) + _debugPort->println(F("getFileContents: strstr failed!")); + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +// OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. +UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, char *contents) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + // Start by getting the file size so we know in advance how much data to expect + int fileSize = 0; + err = getFileSize(filename, &fileSize); + if (err != UBLOX_AT_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: getFileSize returned err ")); + _debugPort->println(err); + } + return err; + } + + command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_READ_FILE) + filename.length() + 8); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBLOX_AT_FILE_SYSTEM_READ_FILE, filename.c_str()); + + response = ublox_at_calloc_char(fileSize + minimumResponseAllocation); + if (response == nullptr) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: response alloc failed: ")); + _debugPort->println(fileSize + minimumResponseAllocation); + } + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + // A large file will completely fill the backlog buffer - but it will be pruned afterwards + // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... + // To try and avoid this, look for \"\r\nOK\r\n + const char fileReadTerm[] = "\"\r\nOK\r\n"; + err = sendCommandWithResponse(command, fileReadTerm, + response, (5 * UBLOX_AT_STANDARD_RESPONSE_TIMEOUT), + (fileSize + minimumResponseAllocation)); + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: sendCommandWithResponse returned err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } + + // Response format: \r\n+URDFILE: "filename",36,"these bytes are the data of the file"\r\n\r\nOK\r\n + int scanned = 0; + int readFileSize = 0; + char *searchPtr = strstr(response, "+URDFILE:"); + if (searchPtr != nullptr) + { + searchPtr = strchr(searchPtr, '\"'); // Find the first quote + searchPtr = strchr(++searchPtr, '\"'); // Find the second quote + + scanned = sscanf(searchPtr, "\",%d,", &readFileSize); // Get the file size (again) + if (scanned == 1) + { + searchPtr = strchr(++searchPtr, '\"'); // Find the third quote + + if (searchPtr == nullptr) + { + if (_printDebug == true) + { + _debugPort->println(F("getFileContents: third quote not found!")); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + int bytesRead = 0; + + while (bytesRead < readFileSize) + { + searchPtr++; // Increment searchPtr then copy file char into contents + contents[bytesRead] = *searchPtr; // Append file char to contents + bytesRead++; + } + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: total bytes read: ")); + _debugPort->println(bytesRead); + } + err = UBLOX_AT_ERROR_SUCCESS; + } + else + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: sscanf failed! scanned is ")); + _debugPort->println(scanned); + } + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + } + else + { + if (_printDebug == true) + _debugPort->println(F("getFileContents: strstr failed!")); + err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getFileBlock(const String& filename, char* buffer, size_t offset, size_t requested_length, size_t& bytes_read) +{ + bytes_read = 0; + if (filename.length() < 1 || buffer == nullptr || requested_length < 1) + { + return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + } + + // trying to get a byte at a time does not seem to be reliable so this method must use + // a real UART. + if (_hardSerial == nullptr) + { + if (_printDebug == true) + { + _debugPort->println(F("getFileBlock: only works with a hardware UART")); + } + return UBLOX_AT_ERROR_INVALID; + } + + size_t cmd_len = filename.length() + 32; + char* cmd = ublox_at_calloc_char(cmd_len); + sprintf(cmd, "at+urdblock=\"%s\",%zu,%zu\r\n", filename.c_str(), offset, requested_length); + sendCommand(cmd, false); + + int ich; + char ch; + int quote_count = 0; + size_t comma_idx = 0; + + while (quote_count < 3) + { + ich = _hardSerial->read(); + if (ich < 0) + { + continue; + } + ch = (char)(ich & 0xFF); + cmd[bytes_read++] = ch; + if (ch == '"') + { + quote_count++; + } + else if (ch == ',' && comma_idx == 0) + { + comma_idx = bytes_read; + } + } + + cmd[bytes_read] = 0; + cmd[bytes_read - 2] = 0; + + // Example response: + // +URDBLOCK: "wombat.bin",64000,"... " + size_t data_length = strtoul(&cmd[comma_idx], nullptr, 10); + free(cmd); + + bytes_read = 0; + size_t bytes_remaining = data_length; + while (bytes_read < data_length) + { + // This method seems more reliable than reading a byte at a time. + size_t rc = _hardSerial->readBytes(&buffer[bytes_read], bytes_remaining); + bytes_read += rc; + bytes_remaining -= rc; + } + + return UBLOX_AT_ERROR_SUCCESS; +} + +UBLOX_AT_error_t UBLOX_AT::getFileSize(String filename, int *size) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_LIST_FILES) + filename.length() + 8); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=2,\"%s\"", UBLOX_AT_FILE_SYSTEM_LIST_FILES, filename.c_str()); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileSize: Fail: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" Response: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + free(command); + free(response); + return err; + } + + char *responseStart = strstr(response, "+ULSTFILE:"); + if (responseStart == nullptr) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileSize: Failure: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + free(command); + free(response); + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + int fileSize; + responseStart += strlen("+ULSTFILE:"); // Move searchPtr to first char + while (*responseStart == ' ') responseStart++; // skip spaces + sscanf(responseStart, "%d", &fileSize); + *size = fileSize; + + free(command); + free(response); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::deleteFile(String filename) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_DELETE_FILE) + filename.length() + 8); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBLOX_AT_FILE_SYSTEM_DELETE_FILE, filename.c_str()); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("deleteFile: Fail: Error: ")); + _debugPort->println(err); + } + } + + free(command); + return err; +} + +UBLOX_AT_error_t UBLOX_AT::modulePowerOff(void) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_POWER_OFF) + 6); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + + sprintf(command, "%s", UBLOX_AT_COMMAND_POWER_OFF); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, + UBLOX_AT_POWER_OFF_TIMEOUT); + + free(command); + return err; +} + +void UBLOX_AT::modulePowerOn(void) +{ + if (_powerPin >= 0) + { + powerOn(); + } + else + { + if (_printDebug == true) + _debugPort->println(F("modulePowerOn: not supported. _powerPin not defined.")); + } +} + +///////////// +// Private // +///////////// + +UBLOX_AT_error_t UBLOX_AT::init(unsigned long baud, + UBLOX_AT::UBLOX_AT_init_type_t initType) +{ + int retries = _maxInitTries; + UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + + beginSerial(baud); + + do + { + if (_printDebug == true) + _debugPort->println(F("init: Begin module init.")); + + if (initType == UBLOX_AT_INIT_AUTOBAUD) + { + if (_printDebug == true) + _debugPort->println(F("init: Attempting autobaud connection to module.")); + + err = autobaud(baud); + + if (err != UBLOX_AT_ERROR_SUCCESS) { + initType = UBLOX_AT_INIT_RESET; + } + } + else if (initType == UBLOX_AT_INIT_RESET) + { + if (_printDebug == true) + _debugPort->println(F("init: Power cycling module.")); + + powerOff(); + delay(UBLOX_AT_POWER_OFF_PULSE_PERIOD); + powerOn(); + beginSerial(baud); + delay(2000); + + err = at(); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + initType = UBLOX_AT_INIT_AUTOBAUD; + } + } + if (err == UBLOX_AT_ERROR_SUCCESS) + { + err = enableEcho(false); // = disableEcho + if (err != UBLOX_AT_ERROR_SUCCESS) + { + if (_printDebug == true) + _debugPort->println(F("init: Module failed echo test.")); + initType = UBLOX_AT_INIT_AUTOBAUD; + } + } + } + while ((retries --) && (err != UBLOX_AT_ERROR_SUCCESS)); + + // we tried but seems failed + if (err != UBLOX_AT_ERROR_SUCCESS) { + if (_printDebug == true) + _debugPort->println(F("init: Module failed to init. Exiting.")); + return (UBLOX_AT_ERROR_NO_RESPONSE); + } + + if (_printDebug == true) + _debugPort->println(F("init: Module responded successfully.")); + + _baud = baud; + setGpioMode(GPIO1, NETWORK_STATUS); + //setGpioMode(GPIO2, GNSS_SUPPLY_ENABLE); + setGpioMode(GPIO6, TIME_PULSE_OUTPUT); + setSMSMessageFormat(UBLOX_AT_MESSAGE_FORMAT_TEXT); + autoTimeZone(_autoTimeZoneForBegin); + for (int i = 0; i < UBLOX_AT_NUM_SOCKETS; i++) + { + socketClose(i, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + } + + return UBLOX_AT_ERROR_SUCCESS; +} + +void UBLOX_AT::invertPowerPin(bool invert) +{ + _invertPowerPin = invert; +} + +// Do a graceful power off. Hold the PWR_ON pin low for UBLOX_AT_POWER_OFF_PULSE_PERIOD +// Note: +CPWROFF () is preferred to this. +void UBLOX_AT::powerOff(void) +{ + if (_powerPin >= 0) + { + if (_invertPowerPin) // Set the pin state before making it an output + digitalWrite(_powerPin, HIGH); + else + digitalWrite(_powerPin, LOW); + pinMode(_powerPin, OUTPUT); + if (_invertPowerPin) // Set the pin state + digitalWrite(_powerPin, HIGH); + else + digitalWrite(_powerPin, LOW); + delay(UBLOX_AT_POWER_OFF_PULSE_PERIOD); + pinMode(_powerPin, INPUT); // Return to high-impedance, rely on (e.g.) SARA module internal pull-up + if (_printDebug == true) + _debugPort->println(F("powerOff: complete")); + } +} + +void UBLOX_AT::powerOn(void) +{ + if (_powerPin >= 0) + { + if (_invertPowerPin) // Set the pin state before making it an output + digitalWrite(_powerPin, HIGH); + else + digitalWrite(_powerPin, LOW); + pinMode(_powerPin, OUTPUT); + if (_invertPowerPin) // Set the pin state + digitalWrite(_powerPin, HIGH); + else + digitalWrite(_powerPin, LOW); + delay(UBLOX_AT_POWER_ON_PULSE_PERIOD); + pinMode(_powerPin, INPUT); // Return to high-impedance, rely on (e.g.) SARA module internal pull-up + //delay(2000); // Do this in init. Wait before sending AT commands to module. 100 is too short. + if (_printDebug == true) + _debugPort->println(F("powerOn: complete")); + } +} + +//This does an abrupt emergency hardware shutdown of the SARA-R5 series modules. +//It only works if you have access to both the RESET_N and PWR_ON pins. +//You cannot use this function on the SparkFun Asset Tracker and RESET_N is tied to the MicroMod processor !RESET!... +void UBLOX_AT::hwReset(void) +{ + if ((_resetPin >= 0) && (_powerPin >= 0)) + { + digitalWrite(_resetPin, HIGH); // Start by making sure the RESET_N pin is high + pinMode(_resetPin, OUTPUT); + digitalWrite(_resetPin, HIGH); + + if (_invertPowerPin) // Now pull PWR_ON low - invert as necessary (on the Asset Tracker) + { + digitalWrite(_powerPin, HIGH); // Inverted - Asset Tracker + pinMode(_powerPin, OUTPUT); + digitalWrite(_powerPin, HIGH); + } + else + { + digitalWrite(_powerPin, LOW); // Not inverted + pinMode(_powerPin, OUTPUT); + digitalWrite(_powerPin, LOW); + } + + delay(UBLOX_AT_RESET_PULSE_PERIOD); // Wait 23 seconds... (Yes, really!) + + digitalWrite(_resetPin, LOW); // Now pull RESET_N low + + delay(100); // Wait a little... (The data sheet doesn't say how long for) + + if (_invertPowerPin) // Now pull PWR_ON high - invert as necessary (on the Asset Tracker) + { + digitalWrite(_powerPin, LOW); // Inverted - Asset Tracker + } + else + { + digitalWrite(_powerPin, HIGH); // Not inverted + } + + delay(1500); // Wait 1.5 seconds + + digitalWrite(_resetPin, HIGH); // Now pull RESET_N high again + + pinMode(_resetPin, INPUT); // Return to high-impedance, rely on SARA module internal pull-up + pinMode(_powerPin, INPUT); // Return to high-impedance, rely on SARA module internal pull-up + } +} + +UBLOX_AT_error_t UBLOX_AT::functionality(UBLOX_AT_functionality_t function) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_FUNC) + 16); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBLOX_AT_COMMAND_FUNC, function); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_3_MIN_TIMEOUT); + + free(command); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::setMNOprofile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) +{ + UBLOX_AT_error_t err; + char *command; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_MNO) + 9); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + if (mno == MNO_SIM_ICCID) // Only add autoReset and urcNotification if mno is MNO_SIM_ICCID + sprintf(command, "%s=%d,%d,%d", UBLOX_AT_COMMAND_MNO, (uint8_t)mno, (uint8_t)autoReset, (uint8_t)urcNotification); + else + sprintf(command, "%s=%d", UBLOX_AT_COMMAND_MNO, (uint8_t)mno); + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + + free(command); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::getMNOprofile(mobile_network_operator_t *mno) +{ + UBLOX_AT_error_t err; + char *command; + char *response; + mobile_network_operator_t o; + int d; + int r; + int u; + int oStore; + + command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_MNO) + 2); + if (command == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBLOX_AT_COMMAND_MNO); + + response = ublox_at_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, + response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + free(command); + free(response); + return err; + } + + int scanned = 0; + char *searchPtr = strstr(response, "+UMNOPROF:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UMNOPROF:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d,%d,%d", &oStore, &d, &r, &u); + } + o = (mobile_network_operator_t)oStore; + + if (scanned >= 1) + { + if (_printDebug == true) + { + _debugPort->print(F("getMNOprofile: MNO is: ")); + _debugPort->println(o); + } + *mno = o; + } + else + { + err = UBLOX_AT_ERROR_INVALID; + } + + free(command); + free(response); + + return err; +} + +UBLOX_AT_error_t UBLOX_AT::waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout) +{ + unsigned long timeIn; + bool found = false; + bool error = false; + int responseIndex = 0, errorIndex = 0; + // bool printedSomething = false; + + timeIn = millis(); + + int responseLen = (int)strlen(expectedResponse); + int errorLen = (int)strlen(expectedError); + + while ((!found) && ((timeIn + timeout) > millis())) + { + if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is nullptr + { + char c = readChar(); + // if (_printDebug == true) + // { + // if (printedSomething == false) + // _debugPort->print(F("waitForResponse: ")); + // _debugPort->write(c); + // printedSomething = true; + // } + if ((responseIndex < responseLen) && (c == expectedResponse[responseIndex])) + { + if (++responseIndex == responseLen) + { + found = true; + } + } + else + { + responseIndex = ((responseIndex < responseLen) && (c == expectedResponse[0])) ? 1 : 0; + } + if ((errorIndex < errorLen) && (c == expectedError[errorIndex])) + { + if (++errorIndex == errorLen) + { + error = true; + found = true; + } + } + else + { + errorIndex = ((errorIndex < errorLen) && (c == expectedError[0])) ? 1 : 0; + } + //_saraResponseBacklog is a global array that holds the backlog of any events + //that came in while waiting for response. To be processed later within bufferedPoll(). + //Note: the expectedResponse or expectedError will also be added to the backlog. + //The backlog is only used by bufferedPoll to process the URCs - which are all readable. + //bufferedPoll uses strtok - which does not like nullptr characters. + //So let's make sure no NULLs end up in the backlog! + if (_saraResponseBacklogLength < _RXBuffSize) // Don't overflow the buffer + { + if (c == '\0') + _saraResponseBacklog[_saraResponseBacklogLength++] = '0'; // Change NULLs to ASCII Zeros + else + _saraResponseBacklog[_saraResponseBacklogLength++] = c; + } + } else { + yield(); + } + } + + // if (_printDebug == true) + // if (printedSomething) + // _debugPort->println(); + + pruneBacklog(); // Prune any incoming non-actionable URC's and responses/errors from the backlog + + if (found == true) + { + if (true == _printAtDebug) { + _debugAtPort->print((error == true) ? expectedError : expectedResponse); + } + + return (error == true) ? UBLOX_AT_ERROR_ERROR : UBLOX_AT_ERROR_SUCCESS; + } + + return UBLOX_AT_ERROR_NO_RESPONSE; +} + +UBLOX_AT_error_t UBLOX_AT::sendCommandWithResponse( + const char *command, const char *expectedResponse, char *responseDest, + unsigned long commandTimeout, int destSize, bool at) +{ + bool found = false; + bool error = false; + int responseIndex = 0; + int errorIndex = 0; + int destIndex = 0; + unsigned int charsRead = 0; + int responseLen = 0; + int errorLen = 0; + const char* expectedError= nullptr; + bool printResponse = false; // Change to true to print the full response + bool printedSomething = false; + + if (_printDebug == true) + { + _debugPort->print(F("sendCommandWithResponse: Command: ")); + _debugPort->println(String(command)); + } + + sendCommand(command, at); //Sending command needs to dump data to backlog buffer as well. + unsigned long timeIn = millis(); + if (UBLOX_AT_RESPONSE_OK_OR_ERROR == expectedResponse) { + expectedResponse = UBLOX_AT_RESPONSE_OK; + expectedError = UBLOX_AT_RESPONSE_ERROR; + responseLen = sizeof(UBLOX_AT_RESPONSE_OK)-1; + errorLen = sizeof(UBLOX_AT_RESPONSE_ERROR)-1; + } else { + responseLen = (int)strlen(expectedResponse); + } + + while ((!found) && ((timeIn + commandTimeout) > millis())) + { + if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is nullptr + { + char c = readChar(); + if ((printResponse = true) && (_printDebug == true)) + { + if (printedSomething == false) + { + _debugPort->print(F("sendCommandWithResponse: Response: ")); + printedSomething = true; + } + _debugPort->write(c); + } + if (responseDest != nullptr) + { + if (destIndex < destSize) // Only add this char to response if there is room for it + responseDest[destIndex] = c; + destIndex++; + if (destIndex == destSize) + { + if (_printDebug == true) + { + if ((printResponse = true) && (printedSomething)) + _debugPort->println(); + _debugPort->print(F("sendCommandWithResponse: Panic! responseDest is full!")); + if ((printResponse = true) && (printedSomething)) + _debugPort->print(F("sendCommandWithResponse: Ignored response: ")); + } + } + } + charsRead++; + if ((errorIndex < errorLen) && (c == expectedError[errorIndex])) + { + if (++errorIndex == errorLen) + { + error = true; + found = true; + } + } + else + { + errorIndex = ((errorIndex < errorLen) && (c == expectedError[0])) ? 1 : 0; + } + if ((responseIndex < responseLen) && (c == expectedResponse[responseIndex])) + { + if (++responseIndex == responseLen) + { + found = true; + } + } + else + { + responseIndex = ((responseIndex < responseLen) && (c == expectedResponse[0])) ? 1 : 0; + } + //_saraResponseBacklog is a global array that holds the backlog of any events + //that came in while waiting for response. To be processed later within bufferedPoll(). + //Note: the expectedResponse or expectedError will also be added to the backlog + //The backlog is only used by bufferedPoll to process the URCs - which are all readable. + //bufferedPoll uses strtok - which does not like NULL characters. + //So let's make sure no NULLs end up in the backlog! + if (_saraResponseBacklogLength < _RXBuffSize) // Don't overflow the buffer + { + if (c == '\0') + _saraResponseBacklog[_saraResponseBacklogLength++] = '0'; // Change NULLs to ASCII Zeros + else + _saraResponseBacklog[_saraResponseBacklogLength++] = c; + } + } else { + yield(); + } + } + + if (_printDebug == true) + if ((printResponse = true) && (printedSomething)) + _debugPort->println(); + + pruneBacklog(); // Prune any incoming non-actionable URC's and responses/errors from the backlog + + if (found) + { + if ((true == _printAtDebug) && ((nullptr != responseDest) || (nullptr != expectedResponse))) { + _debugAtPort->print((nullptr != responseDest) ? responseDest : expectedResponse); + } + return error ? UBLOX_AT_ERROR_ERROR : UBLOX_AT_ERROR_SUCCESS; + } + else if (charsRead == 0) + { + return UBLOX_AT_ERROR_NO_RESPONSE; + } + else + { + if ((true == _printAtDebug) && (nullptr != responseDest)) { + _debugAtPort->print(responseDest); + } + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } +} + +// Send a custom command with an expected (potentially partial) response, store entire response +UBLOX_AT_error_t UBLOX_AT::sendCustomCommandWithResponse(const char *command, const char *expectedResponse, + char *responseDest, unsigned long commandTimeout, bool at) +{ + // Assume the user has allocated enough storage for any response. Set destSize to 32766. + return sendCommandWithResponse(command, expectedResponse, responseDest, commandTimeout, 32766, at); +} + +void UBLOX_AT::sendCommand(const char *command, bool at) +{ + //Check for incoming serial data. Copy it into the backlog + + // Important note: + // On ESP32, Serial.available only provides an update every ~120 bytes during the reception of long messages: + // https://gitter.im/espressif/arduino-esp32?at=5e25d6370a1cf54144909c85 + // Be aware that if a long message is being received, the code below will timeout after _rxWindowMillis = 2 millis. + // At 115200 baud, hwAvailable takes ~120 * 10 / 115200 = 10.4 millis before it indicates that data is being received. + + unsigned long timeIn = millis(); + if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL + { + while (((millis() - timeIn) < _rxWindowMillis) && (_saraResponseBacklogLength < _RXBuffSize)) //May need to escape on newline? + { + if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL + { + //_saraResponseBacklog is a global array that holds the backlog of any events + //that came in while waiting for response. To be processed later within bufferedPoll(). + //Note: the expectedResponse or expectedError will also be added to the backlog + //The backlog is only used by bufferedPoll to process the URCs - which are all readable. + //bufferedPoll uses strtok - which does not like NULL characters. + //So let's make sure no NULLs end up in the backlog! + char c = readChar(); + if (c == '\0') // Make sure no NULL characters end up in the backlog! Change them to ASCII Zeros + c = '0'; + _saraResponseBacklog[_saraResponseBacklogLength++] = c; + timeIn = millis(); + } else { + yield(); + } + } + } + + //Now send the command + if (at) + { + hwPrint(UBLOX_AT_COMMAND_AT); + hwPrint(command); + hwPrint("\r\n"); + } + else + { + hwPrint(command); + } +} + +UBLOX_AT_error_t UBLOX_AT::parseSocketReadIndication(int socket, int length) +{ + UBLOX_AT_error_t err; + char *readDest; + + if ((socket < 0) || (length < 0)) + { + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + // Return now if both callbacks pointers are nullptr - otherwise the data will be read and lost! + if ((_socketReadCallback == nullptr) && (_socketReadCallbackPlus == nullptr)) + return UBLOX_AT_ERROR_INVALID; + + readDest = ublox_at_calloc_char(length + 1); + if (readDest == nullptr) + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + + int bytesRead; + err = socketRead(socket, length, readDest, &bytesRead); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + free(readDest); + return err; + } + + if (_socketReadCallback != nullptr) + { + String dataAsString = ""; // Create an empty string + // Copy the data from readDest into the String in a binary-compatible way + // Important Note: some implementations of concat, like the one on ESP32, are binary-compatible. + // But some, like SAMD, are not. They use strlen or strcpy internally - which don't like \0's. + // The only true binary-compatible solution is to use socketReadCallbackPlus... + for (int i = 0; i < bytesRead; i++) + dataAsString.concat(readDest[i]); + _socketReadCallback(socket, dataAsString); + } + + if (_socketReadCallbackPlus != nullptr) + { + IPAddress dummyAddress = { 0, 0, 0, 0 }; + int dummyPort = 0; + _socketReadCallbackPlus(socket, (const char *)readDest, bytesRead, dummyAddress, dummyPort); + } + + free(readDest); + return UBLOX_AT_ERROR_SUCCESS; +} + +UBLOX_AT_error_t UBLOX_AT::parseSocketReadIndicationUDP(int socket, int length) +{ + UBLOX_AT_error_t err; + char *readDest; + IPAddress remoteAddress = { 0, 0, 0, 0 }; + int remotePort = 0; + + if ((socket < 0) || (length < 0)) + { + return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + } + + // Return now if both callbacks pointers are nullptr - otherwise the data will be read and lost! + if ((_socketReadCallback == nullptr) && (_socketReadCallbackPlus == nullptr)) + return UBLOX_AT_ERROR_INVALID; + + readDest = ublox_at_calloc_char(length + 1); + if (readDest == nullptr) + { + return UBLOX_AT_ERROR_OUT_OF_MEMORY; + } + + int bytesRead; + err = socketReadUDP(socket, length, readDest, &remoteAddress, &remotePort, &bytesRead); + if (err != UBLOX_AT_ERROR_SUCCESS) + { + free(readDest); + return err; + } + + if (_socketReadCallback != nullptr) + { + String dataAsString = ""; // Create an empty string + // Important Note: some implementations of concat, like the one on ESP32, are binary-compatible. + // But some, like SAMD, are not. They use strlen or strcpy internally - which don't like \0's. + // The only true binary-compatible solution is to use socketReadCallbackPlus... + for (int i = 0; i < bytesRead; i++) // Copy the data from readDest into the String in a binary-compatible way + dataAsString.concat(readDest[i]); + _socketReadCallback(socket, dataAsString); + } + + if (_socketReadCallbackPlus != nullptr) + { + _socketReadCallbackPlus(socket, (const char *)readDest, bytesRead, remoteAddress, remotePort); + } + + free(readDest); + return UBLOX_AT_ERROR_SUCCESS; +} + +UBLOX_AT_error_t UBLOX_AT::parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, int socket, IPAddress remoteIP, unsigned int port) +{ + _lastLocalIP = localIP; + _lastRemoteIP = remoteIP; + + if (_socketListenCallback != nullptr) + { + _socketListenCallback(listeningSocket, localIP, listeningPort, socket, remoteIP, port); + } + + return UBLOX_AT_ERROR_SUCCESS; +} + +UBLOX_AT_error_t UBLOX_AT::parseSocketCloseIndication(String *closeIndication) +{ + int search; + int socket; + + search = closeIndication->indexOf(UBLOX_AT_CLOSE_SOCKET_URC); + search += strlen(UBLOX_AT_CLOSE_SOCKET_URC); + while (closeIndication->charAt(search) == ' ') search ++; // skip spaces + + // Socket will be first integer, should be single-digit number between 0-6: + socket = closeIndication->substring(search, search + 1).toInt(); + + if (_socketCloseCallback != nullptr) + { + _socketCloseCallback(socket); + } + + return UBLOX_AT_ERROR_SUCCESS; +} + +size_t UBLOX_AT::hwPrint(const char *s) +{ + if ((true == _printAtDebug) && (nullptr != s)) { + _debugAtPort->print(s); + } + if (_hardSerial != nullptr) + { + return _hardSerial->print(s); + } +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + else if (_softSerial != nullptr) + { + return _softSerial->print(s); + } +#endif + + return (size_t)0; +} + +size_t UBLOX_AT::hwWriteData(const char *buff, int len) +{ + if ((true == _printAtDebug) && (nullptr != buff) && (0 < len) ) { + _debugAtPort->write(buff,len); + } + if (_hardSerial != nullptr) + { + return _hardSerial->write((const uint8_t *)buff, len); + } +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + else if (_softSerial != nullptr) + { + return _softSerial->write((const uint8_t *)buff, len); + } +#endif + return (size_t)0; +} + +size_t UBLOX_AT::hwWrite(const char c) +{ + if (true == _printAtDebug) { + _debugAtPort->write(c); + } + if (_hardSerial != nullptr) + { + return _hardSerial->write(c); + } +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + else if (_softSerial != nullptr) + { + return _softSerial->write(c); + } +#endif + + return (size_t)0; +} + +int UBLOX_AT::readAvailable(char *inString) +{ + int len = 0; + + if (_hardSerial != nullptr) + { + while (_hardSerial->available()) + { + char c = (char)_hardSerial->read(); + if (inString != nullptr) + { + inString[len++] = c; + } + } + if (inString != nullptr) + { + inString[len] = 0; + } + //if (_printDebug == true) + // _debugPort->println(inString); + } +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + else if (_softSerial != nullptr) + { + while (_softSerial->available()) + { + char c = (char)_softSerial->read(); + if (inString != nullptr) + { + inString[len++] = c; + } + } + if (inString != nullptr) + { + inString[len] = 0; + } + } +#endif + + return len; +} + +char UBLOX_AT::readChar(void) +{ + char ret = 0; + + if (_hardSerial != nullptr) + { + ret = (char)_hardSerial->read(); + } +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + else if (_softSerial != nullptr) + { + ret = (char)_softSerial->read(); + } +#endif + + return ret; +} + +int UBLOX_AT::hwAvailable(void) +{ + if (_hardSerial != nullptr) + { + return _hardSerial->available(); + } +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + else if (_softSerial != nullptr) + { + return _softSerial->available(); + } +#endif + + return -1; +} + +void UBLOX_AT::beginSerial(unsigned long baud) +{ + delay(100); + if (_hardSerial != nullptr) + { + _hardSerial->end(); + _hardSerial->begin(baud); + } +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + else if (_softSerial != nullptr) + { + _softSerial->end(); + _softSerial->begin(baud); + } +#endif + delay(100); +} + +void UBLOX_AT::setTimeout(unsigned long timeout) +{ + if (_hardSerial != nullptr) + { + _hardSerial->setTimeout(timeout); + } +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + else if (_softSerial != nullptr) + { + _softSerial->setTimeout(timeout); + } +#endif +} + +bool UBLOX_AT::find(char *target) +{ + bool found = false; + if (_hardSerial != nullptr) + { + found = _hardSerial->find(target); + } +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + else if (_softSerial != nullptr) + { + found = _softSerial->find(target); + } +#endif + return found; +} + +UBLOX_AT_error_t UBLOX_AT::autobaud(unsigned long desiredBaud) +{ + UBLOX_AT_error_t err = UBLOX_AT_ERROR_INVALID; + int b = 0; + + while ((err != UBLOX_AT_ERROR_SUCCESS) && (b < NUM_SUPPORTED_BAUD)) + { + beginSerial(UBLOX_AT_SUPPORTED_BAUD[b++]); + setBaud(desiredBaud); + beginSerial(desiredBaud); + err = at(); + } + if (err == UBLOX_AT_ERROR_SUCCESS) + { + beginSerial(desiredBaud); + } + return err; +} + +char *UBLOX_AT::ublox_at_calloc_char(size_t num) +{ + return (char *)calloc(num, sizeof(char)); +} + +//This prunes the backlog of non-actionable events. If new actionable events are added, you must modify the if statement. +void UBLOX_AT::pruneBacklog() +{ + char *event; + + // if (_printDebug == true) + // { + // if (_saraResponseBacklogLength > 0) //Handy for debugging new parsing. + // { + // _debugPort->println(F("pruneBacklog: before pruning, backlog was:")); + // _debugPort->println(_saraResponseBacklog); + // _debugPort->println(F("pruneBacklog: end of backlog")); + // } + // else + // { + // _debugPort->println(F("pruneBacklog: backlog was empty")); + // } + // } + + memset(_pruneBuffer, 0, _RXBuffSize); // Clear the _pruneBuffer + + _saraResponseBacklogLength = 0; // Zero the backlog length + + char *preservedEvent; + event = strtok_r(_saraResponseBacklog, "\r\n", &preservedEvent); // Look for an 'event' - something ending in \r\n + + while (event != nullptr) //If event is actionable, add it to pruneBuffer. + { + // These are the events we want to keep so they can be processed by poll / bufferedPoll + if ((strstr(event, UBLOX_AT_READ_SOCKET_URC) != nullptr) + || (strstr(event, UBLOX_AT_READ_UDP_SOCKET_URC) != nullptr) + || (strstr(event, UBLOX_AT_LISTEN_SOCKET_URC) != nullptr) + || (strstr(event, UBLOX_AT_CLOSE_SOCKET_URC) != nullptr) + || (strstr(event, UBLOX_AT_GNSS_REQUEST_LOCATION_URC) != nullptr) + || (strstr(event, UBLOX_AT_SIM_STATE_URC) != nullptr) + || (strstr(event, UBLOX_AT_MESSAGE_PDP_ACTION_URC) != nullptr) + || (strstr(event, UBLOX_AT_HTTP_COMMAND_URC) != nullptr) + || (strstr(event, UBLOX_AT_MQTT_COMMAND_URC) != nullptr) + || (strstr(event, UBLOX_AT_PING_COMMAND_URC) != nullptr) + || (strstr(event, UBLOX_AT_REGISTRATION_STATUS_URC) != nullptr) + || (strstr(event, UBLOX_AT_EPSREGISTRATION_STATUS_URC) != nullptr) + || (strstr(event, UBLOX_AT_FTP_COMMAND_URC) != nullptr)) + { + strcat(_pruneBuffer, event); // The URCs are all readable text so using strcat is OK + strcat(_pruneBuffer, "\r\n"); // strtok blows away delimiter, but we want that for later. + _saraResponseBacklogLength += strlen(event) + 2; // Add the length of this event to _saraResponseBacklogLength + } + + event = strtok_r(nullptr, "\r\n", &preservedEvent); // Walk though any remaining events + } + + memset(_saraResponseBacklog, 0, _RXBuffSize); //Clear out backlog buffer. + memcpy(_saraResponseBacklog, _pruneBuffer, _saraResponseBacklogLength); //Copy the pruned buffer back into the backlog + + // if (_printDebug == true) + // { + // if (_saraResponseBacklogLength > 0) //Handy for debugging new parsing. + // { + // _debugPort->println(F("pruneBacklog: after pruning, backlog is now:")); + // _debugPort->println(_saraResponseBacklog); + // _debugPort->println(F("pruneBacklog: end of backlog")); + // } + // else + // { + // _debugPort->println(F("pruneBacklog: backlog is now empty")); + // } + // } +} + +// GPS Helper Functions: + +// Read a source string until a delimiter is hit, store the result in destination +char *UBLOX_AT::readDataUntil(char *destination, unsigned int destSize, + char *source, char delimiter) +{ + + char *strEnd; + size_t len; + + strEnd = strchr(source, delimiter); + + if (strEnd != nullptr) + { + len = strEnd - source; + memset(destination, 0, destSize); + memcpy(destination, source, len); + } + + return strEnd; +} + +bool UBLOX_AT::parseGPRMCString(char *rmcString, PositionData *pos, + ClockData *clk, SpeedData *spd) +{ + char *ptr, *search; + unsigned long tTemp; + char tempData[TEMP_NMEA_DATA_SIZE]; + + // if (_printDebug == true) + // { + // _debugPort->println(F("parseGPRMCString: rmcString: ")); + // _debugPort->println(rmcString); + // } + + // Fast-forward test to first value: + ptr = strchr(rmcString, ','); + ptr++; // Move ptr past first comma + + // If the next character is another comma, there's no time data + // Find time: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + // Next comma should be present and not the next position + if ((search != nullptr) && (search != ptr)) + { + pos->utc = atof(tempData); // Extract hhmmss.ss as float + tTemp = pos->utc; // Convert to unsigned long (discard the digits beyond the decimal point) + clk->time.ms = ((unsigned int)(pos->utc * 100)) % 100; // Extract the milliseconds + clk->time.hour = tTemp / 10000; + tTemp -= ((unsigned long)clk->time.hour * 10000); + clk->time.minute = tTemp / 100; + tTemp -= ((unsigned long)clk->time.minute * 100); + clk->time.second = tTemp; + } + else + { + pos->utc = 0.0; + clk->time.hour = 0; + clk->time.minute = 0; + clk->time.second = 0; + } + ptr = search + 1; // Move pointer to next value + + // Find status character: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + // Should be a single character: V = Data invalid, A = Data valid + if ((search != nullptr) && (search == ptr + 1)) + { + pos->status = *ptr; // Assign char at ptr to status + } + else + { + pos->status = 'X'; // Made up very bad status + } + ptr = search + 1; + + // Find latitude: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + pos->lat = atof(tempData); // Extract ddmm.mmmmm as float + unsigned long lat_deg = pos->lat / 100; // Extract the degrees + pos->lat -= (float)lat_deg * 100.0; // Subtract the degrees leaving only the minutes + pos->lat /= 60.0; // Convert minutes into degrees + pos->lat += (float)lat_deg; // Finally add the degrees back on again + } + else + { + pos->lat = 0.0; + } + ptr = search + 1; + + // Find latitude hemishpere + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search == ptr + 1)) + { + if (*ptr == 'S') // Is the latitude South + pos->lat *= -1.0; // Make lat negative + } + ptr = search + 1; + + // Find longitude: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + pos->lon = atof(tempData); // Extract dddmm.mmmmm as float + unsigned long lon_deg = pos->lon / 100; // Extract the degrees + pos->lon -= (float)lon_deg * 100.0; // Subtract the degrees leaving only the minutes + pos->lon /= 60.0; // Convert minutes into degrees + pos->lon += (float)lon_deg; // Finally add the degrees back on again + } + else + { + pos->lon = 0.0; + } + ptr = search + 1; + + // Find longitude hemishpere + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search == ptr + 1)) + { + if (*ptr == 'W') // Is the longitude West + pos->lon *= -1.0; // Make lon negative + } + ptr = search + 1; + + // Find speed + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + spd->speed = atof(tempData); // Extract speed over ground in knots + spd->speed *= 0.514444; // Convert to m/s + } + else + { + spd->speed = 0.0; + } + ptr = search + 1; + + // Find course over ground + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + spd->cog = atof(tempData); + } + else + { + spd->cog = 0.0; + } + ptr = search + 1; + + // Find date + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + tTemp = atol(tempData); + clk->date.day = tTemp / 10000; + tTemp -= ((unsigned long)clk->date.day * 10000); + clk->date.month = tTemp / 100; + tTemp -= ((unsigned long)clk->date.month * 100); + clk->date.year = tTemp; + } + else + { + clk->date.day = 0; + clk->date.month = 0; + clk->date.year = 0; + } + ptr = search + 1; + + // Find magnetic variation in degrees: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + spd->magVar = atof(tempData); + } + else + { + spd->magVar = 0.0; + } + ptr = search + 1; + + // Find magnetic variation direction + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search == ptr + 1)) + { + if (*ptr == 'W') // Is the magnetic variation West + spd->magVar *= -1.0; // Make magnetic variation negative + } + ptr = search + 1; + + // Find position system mode + // Possible values for posMode: N = No fix, E = Estimated/Dead reckoning fix, A = Autonomous GNSS fix, + // D = Differential GNSS fix, F = RTK float, R = RTK fixed + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, '*'); + if ((search != nullptr) && (search = ptr + 1)) + { + pos->mode = *ptr; + } + else + { + pos->mode = 'X'; + } + ptr = search + 1; + + if (pos->status == 'A') + { + return true; + } + return false; +} diff --git a/src/sfe_ublox_at_commands.h b/src/sfe_ublox_at_commands.h new file mode 100644 index 0000000..05e1a62 --- /dev/null +++ b/src/sfe_ublox_at_commands.h @@ -0,0 +1,1131 @@ +/* + Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod Asset Tracker + By: Paul Clark + October 19th 2020 + + Based extensively on the: + Arduino Library for the SparkFun LTE CAT M1/NB-IoT Shield - SARA-R4 + Written by Jim Lindblom @ SparkFun Electronics, September 5, 2018 + + This Arduino library provides mechanisms to initialize and use + the SARA-R5 module over either a SoftwareSerial or hardware serial port. + + Please see LICENSE.md for the license information + +*/ + +#ifndef SPARKFUN_UBLOX_AT_ARDUINO_LIBRARY_H +#define SPARKFUN_UBLOX_AT_ARDUINO_LIBRARY_H + +#if (ARDUINO >= 100) +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#ifdef ARDUINO_ARCH_AVR // Arduino AVR boards (Uno, Pro Micro, etc.) +#define UBLOX_AT_SOFTWARE_SERIAL_ENABLED // Enable software serial +#endif + +#ifdef ARDUINO_ARCH_SAMD // Arduino SAMD boards (SAMD21, etc.) +#define UBLOX_AT_SOFTWARE_SERIAL_ENABLEDx // Disable software serial +#endif + +#ifdef ARDUINO_ARCH_APOLLO3 // Arduino Apollo boards (Artemis module, RedBoard Artemis, etc) +#define UBLOX_AT_SOFTWARE_SERIAL_ENABLEDx // Disable software serial (no longer supported with v2 of Apollo3) +// Note: paulvha has provided software serial support for v2 of the Apollo3 / Artemis core. +// Further details are available at: +// https://github.com/paulvha/apollo3/tree/master/SoftwareSerial +#endif + +#ifdef ARDUINO_ARCH_STM32 // STM32 based boards (Disco, Nucleo, etc) +#define UBLOX_AT_SOFTWARE_SERIAL_ENABLED // Enable software serial +#endif + +#ifdef ARDUINO_ARCH_ESP32 // ESP32 based boards +// Check to see if ESP Software Serial has been included +// Note: you need to #include at the very start of your script, +// _before_ the #include , for this to work. +// See SARA-R5_Example2_Identification_ESPSoftwareSerial for more details. +#if __has_include( ) +#define UBLOX_AT_SOFTWARE_SERIAL_ENABLED // Enable software serial +#else +#define UBLOX_AT_SOFTWARE_SERIAL_ENABLEDx // Disable software serial +#endif +#endif + +#ifdef ARDUINO_ARCH_ESP8266 // ESP8266 based boards +// Check to see if ESP Software Serial has been included +// Note: you need to #include at the very start of your script, +// _before_ the #include , for this to work. +// See SARA-R5_Example2_Identification_ESPSoftwareSerial for more details. +#if __has_include( ) +#define UBLOX_AT_SOFTWARE_SERIAL_ENABLED // Enable software serial +#else +#define UBLOX_AT_SOFTWARE_SERIAL_ENABLEDx // Disable software serial +#endif +#endif + +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#include // SoftwareSerial.h is guarded. It is OK to include it twice. +#endif + +#include + +#define UBLOX_AT_POWER_PIN -1 // Default to no pin +#define UBLOX_AT_RESET_PIN -1 + +// Timing +#define UBLOX_AT_STANDARD_RESPONSE_TIMEOUT 1000 +#define UBLOX_AT_10_SEC_TIMEOUT 10000 +#define UBLOX_AT_55_SECS_TIMEOUT 55000 +#define UBLOX_AT_2_MIN_TIMEOUT 120000 +#define UBLOX_AT_3_MIN_TIMEOUT 180000 +#define UBLOX_AT_SET_BAUD_TIMEOUT 500 +#define UBLOX_AT_POWER_OFF_PULSE_PERIOD 3200 // Hold PWR_ON low for this long to power the module off +#define UBLOX_AT_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) +#define UBLOX_AT_RESET_PULSE_PERIOD 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) +#define UBLOX_AT_POWER_OFF_TIMEOUT 40000 // Datasheet says 40 seconds... +#define UBLOX_AT_IP_CONNECT_TIMEOUT 130000 +#define UBLOX_AT_POLL_DELAY 1 +#define UBLOX_AT_SOCKET_WRITE_TIMEOUT 10000 + +// ## Suported AT Commands +// ### General +const char UBLOX_AT_COMMAND_AT[] = "AT"; // AT "Test" +const char UBLOX_AT_COMMAND_ECHO[] = "E"; // Local Echo +const char UBLOX_AT_COMMAND_MANU_ID[] = "+CGMI"; // Manufacturer identification +const char UBLOX_AT_COMMAND_MODEL_ID[] = "+CGMM"; // Model identification +const char UBLOX_AT_COMMAND_FW_VER_ID[] = "+CGMR"; // Firmware version identification +const char UBLOX_AT_COMMAND_SERIAL_NO[] = "+CGSN"; // Product serial number +const char UBLOX_AT_COMMAND_IMEI[] = "+GSN"; // IMEI identification +const char UBLOX_AT_COMMAND_IMSI[] = "+CIMI"; // IMSI identification +const char UBLOX_AT_COMMAND_CCID[] = "+CCID"; // SIM CCID +const char UBLOX_AT_COMMAND_REQ_CAP[] = "+GCAP"; // Request capabilities list +// ### Control and status +const char UBLOX_AT_COMMAND_POWER_OFF[] = "+CPWROFF"; // Module switch off +const char UBLOX_AT_COMMAND_FUNC[] = "+CFUN"; // Functionality (reset, etc.) +const char UBLOX_AT_COMMAND_CLOCK[] = "+CCLK"; // Real-time clock +const char UBLOX_AT_COMMAND_AUTO_TZ[] = "+CTZU"; // Automatic time zone update +const char UBLOX_AT_COMMAND_TZ_REPORT[] = "+CTZR"; // Time zone reporting +// ### Network service +const char UBLOX_AT_COMMAND_CNUM[] = "+CNUM"; // Subscriber number +const char UBLOX_AT_SIGNAL_QUALITY[] = "+CSQ"; +const char UBLOX_AT_EXT_SIGNAL_QUALITY[] = "+CESQ"; +const char UBLOX_AT_OPERATOR_SELECTION[] = "+COPS"; +const char UBLOX_AT_REGISTRATION_STATUS[] = "+CREG"; +const char UBLOX_AT_EPSREGISTRATION_STATUS[] = "+CEREG"; +const char UBLOX_AT_READ_OPERATOR_NAMES[] = "+COPN"; +const char UBLOX_AT_COMMAND_MNO[] = "+UMNOPROF"; // MNO (mobile network operator) Profile +// ### SIM +const char UBLOX_AT_SIM_STATE[] = "+USIMSTAT"; +const char UBLOX_AT_COMMAND_SIMPIN[] = "+CPIN"; // SIM PIN +// ### SMS +const char UBLOX_AT_MESSAGE_FORMAT[] = "+CMGF"; // Set SMS message format +const char UBLOX_AT_SEND_TEXT[] = "+CMGS"; // Send SMS message +const char UBLOX_AT_NEW_MESSAGE_IND[] = "+CNMI"; // New [SMS] message indication +const char UBLOX_AT_PREF_MESSAGE_STORE[] = "+CPMS"; // Preferred message storage +const char UBLOX_AT_READ_TEXT_MESSAGE[] = "+CMGR"; // Read message +const char UBLOX_AT_DELETE_MESSAGE[] = "+CMGD"; // Delete message +// V24 control and V25ter (UART interface) +const char UBLOX_AT_FLOW_CONTROL[] = "&K"; // Flow control +const char UBLOX_AT_COMMAND_BAUD[] = "+IPR"; // Baud rate +// ### Packet switched data services +const char UBLOX_AT_MESSAGE_PDP_DEF[] = "+CGDCONT"; // Packet switched Data Profile context definition +const char UBLOX_AT_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration +const char UBLOX_AT_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile +const char UBLOX_AT_MESSAGE_PDP_CONTEXT_ACTIVATE[] = "+CGACT"; // Activates or deactivates the specified PDP context +const char UBLOX_AT_MESSAGE_ENTER_PPP[] = "D"; +const char UBLOX_AT_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data +// ### GPIO +const char UBLOX_AT_COMMAND_GPIO[] = "+UGPIOC"; // GPIO Configuration +// ### IP +const char UBLOX_AT_CREATE_SOCKET[] = "+USOCR"; // Create a new socket +const char UBLOX_AT_CLOSE_SOCKET[] = "+USOCL"; // Close a socket +const char UBLOX_AT_CONNECT_SOCKET[] = "+USOCO"; // Connect to server on socket +const char UBLOX_AT_WRITE_SOCKET[] = "+USOWR"; // Write data to a socket +const char UBLOX_AT_WRITE_UDP_SOCKET[] = "+USOST"; // Write data to a UDP socket +const char UBLOX_AT_READ_SOCKET[] = "+USORD"; // Read from a socket +const char UBLOX_AT_READ_UDP_SOCKET[] = "+USORF"; // Read UDP data from a socket +const char UBLOX_AT_LISTEN_SOCKET[] = "+USOLI"; // Listen for connection on socket +const char UBLOX_AT_GET_ERROR[] = "+USOER"; // Get last socket error. +const char UBLOX_AT_SOCKET_DIRECT_LINK[] = "+USODL"; // Set socket in Direct Link mode +const char UBLOX_AT_SOCKET_CONTROL[] = "+USOCTL"; // Query the socket parameters +const char UBLOX_AT_UD_CONFIGURATION[] = "+UDCONF"; // User Datagram Configuration +// ### Ping +const char UBLOX_AT_PING_COMMAND[] = "+UPING"; // Ping +// ### HTTP +const char UBLOX_AT_HTTP_PROFILE[] = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined +const char UBLOX_AT_HTTP_COMMAND[] = "+UHTTPC"; // Trigger the specified HTTP command +const char UBLOX_AT_HTTP_PROTOCOL_ERROR[] = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. + +const char UBLOX_AT_MQTT_NVM[] = "+UMQTTNV"; +const char UBLOX_AT_MQTT_PROFILE[] = "+UMQTT"; +const char UBLOX_AT_MQTT_COMMAND[] = "+UMQTTC"; +const char UBLOX_AT_MQTT_PROTOCOL_ERROR[] = "+UMQTTER"; +// ### FTP +const char UBLOX_AT_FTP_PROFILE[] = "+UFTP"; +const char UBLOX_AT_FTP_COMMAND[] = "+UFTPC"; +const char UBLOX_AT_FTP_PROTOCOL_ERROR[] = "+UFTPER"; +// ### GNSS +const char UBLOX_AT_GNSS_POWER[] = "+UGPS"; // GNSS power management configuration +const char UBLOX_AT_GNSS_ASSISTED_IND[] = "+UGIND"; // Assisted GNSS unsolicited indication +const char UBLOX_AT_GNSS_REQUEST_LOCATION[] = "+ULOC"; // Ask for localization information +const char UBLOX_AT_GNSS_GPRMC[] = "+UGRMC"; // Ask for localization information +const char UBLOX_AT_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) +const char UBLOX_AT_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication +const char UBLOX_AT_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration +const char UBLOX_AT_GNSS_CONFIGURE_SENSOR[] = "+ULOCGNSS"; // Configure GNSS sensor +const char UBLOX_AT_GNSS_CONFIGURE_LOCATION[] = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) +const char UBLOX_AT_AIDING_SERVER_CONFIGURATION[] = "+UGSRV"; // Configure aiding server (CellLocate®) +// ### File System +// TO DO: Add support for file tags. Default tag to USER +const char UBLOX_AT_FILE_SYSTEM_READ_FILE[] = "+URDFILE"; // Read a file +const char UBLOX_AT_FILE_SYSTEM_READ_BLOCK[] = "+URDBLOCK"; // Read a block from a file +const char UBLOX_AT_FILE_SYSTEM_DOWNLOAD_FILE[] = "+UDWNFILE"; // Download a file into the module +const char UBLOX_AT_FILE_SYSTEM_LIST_FILES[] = "+ULSTFILE"; // List of files, size of file, etc. +const char UBLOX_AT_FILE_SYSTEM_DELETE_FILE[] = "+UDELFILE"; // Delete a file +// ### File System +// TO DO: Add support for file tags. Default tag to USER +const char UBLOX_AT_SEC_PROFILE[] = "+USECPRF"; +const char UBLOX_AT_SEC_MANAGER[] = "+USECMNG"; + + +// ### URC strings +const char UBLOX_AT_READ_SOCKET_URC[] = "+UUSORD:"; +const char UBLOX_AT_READ_UDP_SOCKET_URC[] = "+UUSORF:"; +const char UBLOX_AT_LISTEN_SOCKET_URC[] = "+UUSOLI:"; +const char UBLOX_AT_CLOSE_SOCKET_URC[] = "+UUSOCL:"; +const char UBLOX_AT_GNSS_REQUEST_LOCATION_URC[] = "+UULOC:"; +const char UBLOX_AT_SIM_STATE_URC[] = "+UUSIMSTAT:"; +const char UBLOX_AT_MESSAGE_PDP_ACTION_URC[] = "+UUPSDA:"; +const char UBLOX_AT_HTTP_COMMAND_URC[] = "+UUHTTPCR:"; +const char UBLOX_AT_MQTT_COMMAND_URC[] = "+UUMQTTC:"; +const char UBLOX_AT_PING_COMMAND_URC[] = "+UUPING:"; +const char UBLOX_AT_REGISTRATION_STATUS_URC[] = "+CREG:"; +const char UBLOX_AT_EPSREGISTRATION_STATUS_URC[] = "+CEREG:"; +const char UBLOX_AT_FTP_COMMAND_URC[] = "+UUFTPCR:"; + +// ### Response +const char UBLOX_AT_RESPONSE_MORE[] = "\n>"; +const char UBLOX_AT_RESPONSE_OK[] = "\nOK\r\n"; +const char UBLOX_AT_RESPONSE_ERROR[] = "\nERROR\r\n"; +const char UBLOX_AT_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; +#define UBLOX_AT_RESPONSE_OK_OR_ERROR nullptr + +// CTRL+Z and ESC ASCII codes for SMS message sends +const char ASCII_CTRL_Z = 0x1A; +const char ASCII_ESC = 0x1B; + +// NMEA data size - used by parseGPRMCString +#define TEMP_NMEA_DATA_SIZE 16 + +#define NOT_AT_COMMAND false +#define AT_COMMAND true + +// The minimum memory allocation for responses from sendCommandWithResponse +// This needs to be large enough to hold the response you're expecting plus and URC's that may arrive during the timeout +#define minimumResponseAllocation 128 + +#define UBLOX_AT_NUM_SOCKETS 6 + +#define NUM_SUPPORTED_BAUD 6 +const unsigned long UBLOX_AT_SUPPORTED_BAUD[NUM_SUPPORTED_BAUD] = + { + 115200, + 9600, + 19200, + 38400, + 57600, + 230400}; +#define UBLOX_AT_DEFAULT_BAUD_RATE 115200 + +// Flow control definitions for AT&K +// Note: SW (XON/XOFF) flow control is not supported on the UBLOX_AT +typedef enum +{ + UBLOX_AT_DISABLE_FLOW_CONTROL = 0, + UBLOX_AT_ENABLE_FLOW_CONTROL = 3 +} UBLOX_AT_flow_control_t; + +// The standard Europe profile should be used as the basis for all other MNOs in Europe outside of Vodafone +// and Deutsche Telekom. However, there may be changes that need to be applied to the module for proper +// operation with any given European MNO such as attach type, RAT preference, band selection, etc. Please +// consult with the preferred network provider. +typedef enum +{ + MNO_INVALID = -1, + MNO_SW_DEFAULT = 0, // Undefined / regulatory + MNO_SIM_ICCID = 1, + MNO_ATT = 2, // AT&T + MNO_VERIZON = 3, + MNO_TELSTRA = 4, + MNO_TMO = 5, // T-Mobile US + MNO_CT = 6, // China Telecom + MNO_SPRINT = 8, + MNO_VODAFONE = 19, + MNO_NTT_DOCOMO = 20, + MNO_TELUS = 21, + MNO_SOFTBANK = 28, + MNO_DT = 31, // Deutsche Telekom + MNO_US_CELLULAR = 32, + MNO_SKT = 39, + MNO_GLOBAL = 90, + MNO_STD_EUROPE = 100, + MNO_STD_EU_NOEPCO = 101 +} mobile_network_operator_t; + +typedef enum +{ + UBLOX_AT_ERROR_INVALID = -1, // -1 + UBLOX_AT_ERROR_SUCCESS = 0, // 0 + UBLOX_AT_ERROR_OUT_OF_MEMORY, // 1 + UBLOX_AT_ERROR_TIMEOUT, // 2 + UBLOX_AT_ERROR_UNEXPECTED_PARAM, // 3 + UBLOX_AT_ERROR_UNEXPECTED_RESPONSE, // 4 + UBLOX_AT_ERROR_NO_RESPONSE, // 5 + UBLOX_AT_ERROR_DEREGISTERED, // 6 + UBLOX_AT_ERROR_ZERO_READ_LENGTH, // 7 + UBLOX_AT_ERROR_ERROR // 8 +} UBLOX_AT_error_t; +#define UBLOX_AT_SUCCESS UBLOX_AT_ERROR_SUCCESS + +typedef enum +{ + UBLOX_AT_REGISTRATION_INVALID = -1, + UBLOX_AT_REGISTRATION_NOT_REGISTERED = 0, + UBLOX_AT_REGISTRATION_HOME = 1, + UBLOX_AT_REGISTRATION_SEARCHING = 2, + UBLOX_AT_REGISTRATION_DENIED = 3, + UBLOX_AT_REGISTRATION_UNKNOWN = 4, + UBLOX_AT_REGISTRATION_ROAMING = 5, + UBLOX_AT_REGISTRATION_HOME_SMS_ONLY = 6, + UBLOX_AT_REGISTRATION_ROAMING_SMS_ONLY = 7, + UBLOX_AT_REGISTRATION_EMERGENCY_SERV_ONLY = 8, + UBLOX_AT_REGISTRATION_HOME_CSFB_NOT_PREFERRED = 9, + UBLOX_AT_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED = 10 +} UBLOX_AT_registration_status_t; + +struct DateData +{ + uint8_t day; + uint8_t month; + unsigned int year; +}; + +struct TimeData +{ + uint8_t hour; + uint8_t minute; + uint8_t second; + unsigned int ms; + uint8_t tzh; + uint8_t tzm; +}; + +struct ClockData +{ + struct DateData date; + struct TimeData time; +}; + +struct PositionData +{ + float utc; + float lat; // Degrees: +/- 90 + float lon; // Degrees: +/- 180 + float alt; + char mode; + char status; +}; + +struct SpeedData +{ + float speed; // m/s + float cog; // Degrees + float magVar; // Degrees +}; + +struct operator_stats +{ + uint8_t stat; + String shortOp; + String longOp; + unsigned long numOp; + uint8_t act; +}; + +typedef struct ext_signal_quality_ { + unsigned int rxlev; + unsigned int ber; + unsigned int rscp; + unsigned int enc0; + unsigned int rsrq; + unsigned int rsrp; +} signal_quality; + +typedef enum +{ + UBLOX_AT_TCP = 6, + UBLOX_AT_UDP = 17 +} UBLOX_AT_socket_protocol_t; + +typedef enum +{ + UBLOX_AT_TCP_SOCKET_STATUS_INACTIVE, + UBLOX_AT_TCP_SOCKET_STATUS_LISTEN, + UBLOX_AT_TCP_SOCKET_STATUS_SYN_SENT, + UBLOX_AT_TCP_SOCKET_STATUS_SYN_RCVD, + UBLOX_AT_TCP_SOCKET_STATUS_ESTABLISHED, + UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_1, + UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_2, + UBLOX_AT_TCP_SOCKET_STATUS_CLOSE_WAIT, + UBLOX_AT_TCP_SOCKET_STATUS_CLOSING, + UBLOX_AT_TCP_SOCKET_STATUS_LAST_ACK, + UBLOX_AT_TCP_SOCKET_STATUS_TIME_WAIT +} UBLOX_AT_tcp_socket_status_t; + +typedef enum +{ + UBLOX_AT_MESSAGE_FORMAT_PDU = 0, + UBLOX_AT_MESSAGE_FORMAT_TEXT = 1 +} UBLOX_AT_message_format_t; + +typedef enum +{ + UBLOX_AT_UTIME_MODE_STOP = 0, + UBLOX_AT_UTIME_MODE_PPS, + UBLOX_AT_UTIME_MODE_ONE_SHOT, + UBLOX_AT_UTIME_MODE_EXT_INT +} UBLOX_AT_utime_mode_t; + +typedef enum +{ + UBLOX_AT_UTIME_SENSOR_NONE = 0, + UBLOX_AT_UTIME_SENSOR_GNSS_LTE = 1, + UBLOX_AT_UTIME_SENSOR_LTE +} UBLOX_AT_utime_sensor_t; + +typedef enum +{ + UBLOX_AT_UTIME_URC_CONFIGURATION_DISABLED = 0, + UBLOX_AT_UTIME_URC_CONFIGURATION_ENABLED +} UBLOX_AT_utime_urc_configuration_t; + +typedef enum +{ + UBLOX_AT_SIM_NOT_PRESENT = 0, + UBLOX_AT_SIM_PIN_NEEDED, + UBLOX_AT_SIM_PIN_BLOCKED, + UBLOX_AT_SIM_PUK_BLOCKED, + UBLOX_AT_SIM_NOT_OPERATIONAL, + UBLOX_AT_SIM_RESTRICTED, + UBLOX_AT_SIM_OPERATIONAL + //UBLOX_AT_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 + //UBLOX_AT_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 + //UBLOX_AT_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 + //UBLOX_AT_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 + //UBLOX_AT_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 + //UBLOX_AT_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 + //UBLOX_AT_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 +} UBLOX_AT_sim_states_t; + +#define UBLOX_AT_NUM_PSD_PROFILES 6 // Number of supported PSD profiles +#define UBLOX_AT_NUM_PDP_CONTEXT_IDENTIFIERS 11 // Number of supported PDP context identifiers +#define UBLOX_AT_NUM_HTTP_PROFILES 4 // Number of supported HTTP profiles + +typedef enum +{ + UBLOX_AT_HTTP_OP_CODE_SERVER_IP = 0, + UBLOX_AT_HTTP_OP_CODE_SERVER_NAME, + UBLOX_AT_HTTP_OP_CODE_USERNAME, + UBLOX_AT_HTTP_OP_CODE_PASSWORD, + UBLOX_AT_HTTP_OP_CODE_AUTHENTICATION, + UBLOX_AT_HTTP_OP_CODE_SERVER_PORT, + UBLOX_AT_HTTP_OP_CODE_SECURE, + UBLOX_AT_HTTP_OP_CODE_REQUEST_TIMEOUT, + UBLOX_AT_HTTP_OP_CODE_ADD_CUSTOM_HEADERS = 9 +} UBLOX_AT_http_op_codes_t; + +typedef enum +{ + UBLOX_AT_HTTP_COMMAND_HEAD = 0, + UBLOX_AT_HTTP_COMMAND_GET, + UBLOX_AT_HTTP_COMMAND_DELETE, + UBLOX_AT_HTTP_COMMAND_PUT, + UBLOX_AT_HTTP_COMMAND_POST_FILE, + UBLOX_AT_HTTP_COMMAND_POST_DATA, + UBLOX_AT_HTTP_COMMAND_GET_FOTA = 100 +} UBLOX_AT_http_commands_t; + +typedef enum +{ + UBLOX_AT_HTTP_CONTENT_APPLICATION_X_WWW = 0, + UBLOX_AT_HTTP_CONTENT_TEXT_PLAIN, + UBLOX_AT_HTTP_CONTENT_APPLICATION_OCTET, + UBLOX_AT_HTTP_CONTENT_MULTIPART_FORM, + UBLOX_AT_HTTP_CONTENT_APPLICATION_JSON, + UBLOX_AT_HTTP_CONTENT_APPLICATION_XML, + UBLOX_AT_HTTP_CONTENT_USER_DEFINED +} UBLOX_AT_http_content_types_t; + +typedef enum +{ + UBLOX_AT_MQTT_NV_RESTORE = 0, + UBLOX_AT_MQTT_NV_SET, + UBLOX_AT_MQTT_NV_STORE, +} UBLOX_AT_mqtt_nv_parameter_t; + +typedef enum +{ + UBLOX_AT_MQTT_PROFILE_CLIENT_ID = 0, + UBLOX_AT_MQTT_PROFILE_SERVERNAME = 2, + UBLOX_AT_MQTT_PROFILE_IPADDRESS, + UBLOX_AT_MQTT_PROFILE_USERNAMEPWD, + UBLOX_AT_MQTT_PROFILE_QOS = 6, + UBLOX_AT_MQTT_PROFILE_RETAIN, + UBLOX_AT_MQTT_PROFILE_TOPIC, + UBLOX_AT_MQTT_PROFILE_MESSAGE, + UBLOX_AT_MQTT_PROFILE_INACTIVITYTIMEOUT, + UBLOX_AT_MQTT_PROFILE_SECURE, +} UBLOX_AT_mqtt_profile_opcode_t; + +typedef enum +{ + UBLOX_AT_MQTT_COMMAND_INVALID = -1, + UBLOX_AT_MQTT_COMMAND_LOGOUT = 0, + UBLOX_AT_MQTT_COMMAND_LOGIN, + UBLOX_AT_MQTT_COMMAND_PUBLISH, + UBLOX_AT_MQTT_COMMAND_PUBLISHFILE, + UBLOX_AT_MQTT_COMMAND_SUBSCRIBE, + UBLOX_AT_MQTT_COMMAND_UNSUBSCRIBE, + UBLOX_AT_MQTT_COMMAND_READ, + UBLOX_AT_MQTT_COMMAND_RCVMSGFORMAT, + UBLOX_AT_MQTT_COMMAND_PING, + UBLOX_AT_MQTT_COMMAND_PUBLISHBINARY, +} UBLOX_AT_mqtt_command_opcode_t; + +constexpr uint16_t MAX_MQTT_HEX_MSG_LEN = 512; +constexpr uint16_t MAX_MQTT_DIRECT_MSG_LEN = 1024; + +typedef enum +{ + UBLOX_AT_FTP_PROFILE_IPADDRESS = 0, + UBLOX_AT_FTP_PROFILE_SERVERNAME, + UBLOX_AT_FTP_PROFILE_USERNAME, + UBLOX_AT_FTP_PROFILE_PWD, + UBLOX_AT_FTP_PROFILE_ACCOUNT, + UBLOX_AT_FTP_PROFILE_TIMEOUT, + UBLOX_AT_FTP_PROFILE_MODE +} UBLOX_AT_ftp_profile_opcode_t; + +typedef enum +{ + UBLOX_AT_FTP_COMMAND_INVALID = -1, + UBLOX_AT_FTP_COMMAND_LOGOUT = 0, + UBLOX_AT_FTP_COMMAND_LOGIN, + UBLOX_AT_FTP_COMMAND_DELETE_FILE, + UBLOX_AT_FTP_COMMAND_RENAME_FILE, + UBLOX_AT_FTP_COMMAND_GET_FILE, + UBLOX_AT_FTP_COMMAND_PUT_FILE, + UBLOX_AT_FTP_COMMAND_GET_FILE_DIRECT, + UBLOX_AT_FTP_COMMAND_PUT_FILE_DIRECT, + UBLOX_AT_FTP_COMMAND_CHANGE_DIR, + UBLOX_AT_FTP_COMMAND_MKDIR = 10, + UBLOX_AT_FTP_COMMAND_RMDIR, + UBLOX_AT_FTP_COMMAND_DIR_INFO = 13, + UBLOX_AT_FTP_COMMAND_LS, + UBLOX_AT_FTP_COMMAND_GET_FOTA_FILE = 100 +} UBLOX_AT_ftp_command_opcode_t; + +typedef enum +{ + UBLOX_AT_PSD_CONFIG_PARAM_PROTOCOL = 0, + UBLOX_AT_PSD_CONFIG_PARAM_APN, + //UBLOX_AT_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 + //UBLOX_AT_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 + UBLOX_AT_PSD_CONFIG_PARAM_DNS1 = 4, + UBLOX_AT_PSD_CONFIG_PARAM_DNS2, + //UBLOX_AT_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 + //UBLOX_AT_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 + //UBLOX_AT_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 + //UBLOX_AT_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 + UBLOX_AT_PSD_CONFIG_PARAM_MAP_TO_CID = 100 +} UBLOX_AT_pdp_configuration_parameter_t; + +typedef enum +{ + UBLOX_AT_PSD_PROTOCOL_IPV4 = 0, + UBLOX_AT_PSD_PROTOCOL_IPV6, + UBLOX_AT_PSD_PROTOCOL_IPV4V6_V4_PREF, + UBLOX_AT_PSD_PROTOCOL_IPV4V6_V6_PREF +} UBLOX_AT_pdp_protocol_type_t; + +typedef enum +{ + UBLOX_AT_PSD_ACTION_RESET = 0, + UBLOX_AT_PSD_ACTION_STORE, + UBLOX_AT_PSD_ACTION_LOAD, + UBLOX_AT_PSD_ACTION_ACTIVATE, + UBLOX_AT_PSD_ACTION_DEACTIVATE +} UBLOX_AT_pdp_actions_t; + +typedef enum +{ + UBLOX_AT_SEC_PROFILE_PARAM_CERT_VAL_LEVEL = 0, + UBLOX_AT_SEC_PROFILE_PARAM_TLS_VER, + UBLOX_AT_SEC_PROFILE_PARAM_CYPHER_SUITE, + UBLOX_AT_SEC_PROFILE_PARAM_ROOT_CA, + UBLOX_AT_SEC_PROFILE_PARAM_HOSTNAME, + UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_CERT, + UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY, + UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY_PWD, + UBLOX_AT_SEC_PROFILE_PARAM_PSK, + UBLOX_AT_SEC_PROFILE_PARAM_PSK_IDENT, + UBLOX_AT_SEC_PROFILE_PARAM_SNI, +} UBLOX_AT_sec_profile_parameter_t; + +typedef enum +{ + UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_NO = 0, + UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL, + UBLOX_AT_SEC_PROFILE_CERVTAL_OPCODE_YESURL, + UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE, +} UBLOX_AT_sec_profile_certval_op_code_t; + +typedef enum +{ + UBLOX_AT_SEC_PROFILE_TLS_OPCODE_ANYVER = 0, + UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_0, + UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_1, + UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_2, + UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_3, +} UBLOX_AT_sec_profile_tls_op_code_t; + +typedef enum +{ + UBLOX_AT_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT = 0, +} UBLOX_AT_sec_profile_suite_op_code_t; + +typedef enum +{ + UBLOX_AT_SEC_MANAGER_OPCODE_IMPORT = 0, +} UBLOX_AT_sec_manager_opcode_t; + +typedef enum +{ + UBLOX_AT_SEC_MANAGER_ROOTCA = 0, + UBLOX_AT_SEC_MANAGER_CLIENT_CERT, + UBLOX_AT_SEC_MANAGER_CLIENT_KEY, + UBLOX_AT_SEC_MANAGER_SERVER_CERT +} UBLOX_AT_sec_manager_parameter_t; + +typedef enum +{ + MINIMUM_FUNCTIONALITY = 0, // (disable both transmit and receive RF circuits by deactivating both CS and PS services) + FULL_FUNCTIONALITY = 1, + AIRPLANE_MODE = 4, + SIM_TOOLKIT_ENABLE_DEDICATED = 6, + SIM_TOOLKIT_DISABLE_DEDICATED = 7, + SIM_TOOLKIT_ENABLE_RAW = 9, + FAST_SAFE_POWER_OFF = 10, + //SILENT_RESET_WITHOUT_SIM = 15, // Not supported on SARA-R5 + SILENT_RESET_WITH_SIM = 16 + //MINIMUM_FUNCTIONALITY = 19, // Not supported on SARA-R5 + //DEEP_LOW_POWER_STATE = 127 // Not supported on SARA-R5 +} UBLOX_AT_functionality_t; + +class UBLOX_AT : public Print +{ +public: + // Constructor + // The library will use the powerPin and resetPin (if provided) to power the module off/on and perform an emergency reset + // maxInitTries sets the maximum number of initialization attempts. .init is called by .begin. + UBLOX_AT(int powerPin = UBLOX_AT_POWER_PIN, int resetPin = UBLOX_AT_RESET_PIN, uint8_t maxInitTries = 9); + + ~UBLOX_AT(); + // Begin -- initialize module and ensure it's connected +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + bool begin(SoftwareSerial &softSerial, unsigned long baud = 9600); +#endif + bool begin(HardwareSerial &hardSerial, unsigned long baud = 9600); + + // Debug prints + void enableDebugging(Print &debugPort = Serial); //Turn on debug printing. If user doesn't specify then Serial will be used. + void enableAtDebugging(Print &debugPort = Serial); //Turn on AT debug printing. If user doesn't specify then Serial will be used. + + // Invert the polarity of the power pin - if required + // Normally the SARA's power pin is pulled low and released to toggle the power + // But the Asset Tracker needs this to be pulled high and released instead + void invertPowerPin(bool invert = false); + + UBLOX_AT_error_t modulePowerOff(void); // Graceful disconnect and shutdown using +CPWROFF. + void modulePowerOn(void); // Requires access to the PWR_ON pin + + // Loop polling and polling setup - process URC's etc. from the module + + // This function was originally written by Matthew Menze for the LTE Shield (SARA-R4) library + // See: https://github.com/sparkfun/SparkFun_LTE_Shield_Arduino_Library/pull/8 + // It does the same job as ::poll but also processes any 'old' data stored in the backlog first + // It also has a built-in timeout - which ::poll does not + // Use this - it is way better than ::poll. Thank you Matthew! + bool bufferedPoll(void); + + // This is the original poll function. + // It is 'blocking' - it does not return when serial data is available until it receives a `\n`. + // ::bufferedPoll is the new improved version. It processes any data in the backlog and includes a timeout. + // Retained for backward-compatibility and just in case you do want to (temporarily) ignore any data in the backlog + bool poll(void); + + // Callbacks (called during polling) + void setSocketListenCallback(void (*socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int)); // listen Socket, local IP Address, listen Port, socket, remote IP Address, port + // This is the original read socket callback - called when a +UUSORD or +UUSORF URC is received + // It works - and handles binary data correctly - but the remote IP Address and Port are lost for UDP connections + // setSocketReadCallbackPlus is preferred! + void setSocketReadCallback(void (*socketReadCallback)(int, String)); // socket, read data + void setSocketReadCallbackPlus(void (*socketReadCallbackPlus)(int, const char *, int, IPAddress, int)); // socket, read data, length, remoteAddress, remotePort + void setSocketCloseCallback(void (*socketCloseCallback)(int)); // socket + void setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, + PositionData gps, SpeedData spd, unsigned long uncertainty)); + void setSIMstateReportCallback(void (*simStateRequestCallback)(UBLOX_AT_sim_states_t state)); + void setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)); + void setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)); + void setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)); + void setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)); + void setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)); + + UBLOX_AT_error_t setRegistrationCallback(void (*registrationCallback)(UBLOX_AT_registration_status_t status, + unsigned int lac, unsigned int ci, int Act)); + UBLOX_AT_error_t setEpsRegistrationCallback(void (*epsRegistrationCallback)(UBLOX_AT_registration_status_t status, + unsigned int tac, unsigned int ci, int Act)); + + // Direct write/print to cell serial port + virtual size_t write(uint8_t c); + virtual size_t write(const char *str); + virtual size_t write(const char *buffer, size_t size); + + // General AT Commands + UBLOX_AT_error_t at(void); + UBLOX_AT_error_t enableEcho(bool enable = true); + String getManufacturerID(void); + String getModelID(void); + String getFirmwareVersion(void); + String getSerialNo(void); + String getIMEI(void); + String getIMSI(void); + String getCCID(void); + String getSubscriberNo(void); + String getCapabilities(void); + + // Control and status AT commands + UBLOX_AT_error_t reset(void); + String clock(void); + // TODO: Return a clock struct + UBLOX_AT_error_t clock(uint8_t *y, uint8_t *mo, uint8_t *d, + uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz); // TZ can be +/- and is in increments of 15 minutes. -28 == 7 hours behind UTC/GMT + UBLOX_AT_error_t setClock(String theTime); + UBLOX_AT_error_t setClock(uint8_t y, uint8_t mo, uint8_t d, + uint8_t h, uint8_t min, uint8_t s, int8_t tz); // TZ can be +/- and is in increments of 15 minutes. -28 == 7 hours behind UTC/GMT + void autoTimeZoneForBegin(bool enable = true); // Call autoTimeZoneForBegin(false) _before_ .begin if you want to disable the automatic time zone + UBLOX_AT_error_t autoTimeZone(bool enable); // Enable/disable automatic time zone adjustment + UBLOX_AT_error_t setUtimeMode(UBLOX_AT_utime_mode_t mode = UBLOX_AT_UTIME_MODE_PPS, UBLOX_AT_utime_sensor_t sensor = UBLOX_AT_UTIME_SENSOR_GNSS_LTE); // Time mode, source etc. (+UTIME) + UBLOX_AT_error_t getUtimeMode(UBLOX_AT_utime_mode_t *mode, UBLOX_AT_utime_sensor_t *sensor); + UBLOX_AT_error_t setUtimeIndication(UBLOX_AT_utime_urc_configuration_t config = UBLOX_AT_UTIME_URC_CONFIGURATION_ENABLED); // +UTIMEIND + UBLOX_AT_error_t getUtimeIndication(UBLOX_AT_utime_urc_configuration_t *config); + UBLOX_AT_error_t setUtimeConfiguration(int32_t offsetNanoseconds = 0, int32_t offsetSeconds = 0); // +UTIMECFG + UBLOX_AT_error_t getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds); + + // Network service AT commands + int8_t rssi(void); // Receive signal strength + UBLOX_AT_error_t getExtSignalQuality(signal_quality& signal_quality); + + UBLOX_AT_registration_status_t registration(bool eps = true); + bool setNetworkProfile(mobile_network_operator_t mno, bool autoReset = false, bool urcNotification = false); + mobile_network_operator_t getNetworkProfile(void); + typedef enum + { + PDP_TYPE_INVALID = -1, + PDP_TYPE_IP = 0, + PDP_TYPE_NONIP = 1, + PDP_TYPE_IPV4V6 = 2, + PDP_TYPE_IPV6 = 3 + } UBLOX_AT_pdp_type; + UBLOX_AT_error_t setAPN(String apn, uint8_t cid = 1, UBLOX_AT_pdp_type pdpType = PDP_TYPE_IP); // Set the Access Point Name + UBLOX_AT_error_t getAPN(int cid, String *apn, IPAddress *ip, UBLOX_AT_pdp_type* pdpType = nullptr); // Return the apn and IP address for the chosen context identifier + + UBLOX_AT_error_t getSimStatus(String* code); + UBLOX_AT_error_t setSimPin(String pin); + + // SIM + // Status report Mode: + // Bit States reported + // 0 Reports the (U)SIM initialization status ('s from 0 to 6 may be reported) + // 1 Reports the (U)SIM phonebook initialization status ('s from 7 to 8 may be reported) + // 2 Reports the (U)SIM toolkit REFRESH proactive command execution result ('s from 9 to 13 may be reported) + // Note: For the SARA-R5: =7, 8, 9, 10, 11, 12 and 13 are not reported. + UBLOX_AT_error_t setSIMstateReportingMode(int mode); + UBLOX_AT_error_t getSIMstateReportingMode(int *mode); + + typedef enum + { + L2P_DEFAULT, + L2P_PPP, + L2P_M_HEX, + L2P_M_RAW_IP, + L2P_M_OPT_PPP + } UBLOX_AT_l2p_t; + UBLOX_AT_error_t enterPPP(uint8_t cid = 1, char dialing_type_char = 0, + unsigned long dialNumber = 99, UBLOX_AT_l2p_t l2p = L2P_DEFAULT); + + uint8_t getOperators(struct operator_stats *op, int maxOps = 3); + UBLOX_AT_error_t registerOperator(struct operator_stats oper); + UBLOX_AT_error_t automaticOperatorSelection(); + UBLOX_AT_error_t getOperator(String *oper); + UBLOX_AT_error_t deregisterOperator(void); + + // SMS -- Short Messages Service + UBLOX_AT_error_t setSMSMessageFormat(UBLOX_AT_message_format_t textMode = UBLOX_AT_MESSAGE_FORMAT_TEXT); + UBLOX_AT_error_t sendSMS(String number, String message); + UBLOX_AT_error_t getPreferredMessageStorage(int *used, int *total, String memory = "ME"); + UBLOX_AT_error_t readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message); + UBLOX_AT_error_t deleteSMSmessage(int location, int deleteFlag = 0); // Default to deleting the single message at the specified location + UBLOX_AT_error_t deleteReadSMSmessages(void) { return (deleteSMSmessage( 1, 1 )); }; // Delete all the read messages from preferred storage + UBLOX_AT_error_t deleteReadSentSMSmessages(void) { return (deleteSMSmessage( 1, 2 )); }; // Delete the read and sent messages from preferred storage + UBLOX_AT_error_t deleteReadSentUnsentSMSmessages(void) { return (deleteSMSmessage( 1, 3 )); }; // Delete the read, sent and unsent messages from preferred storage + UBLOX_AT_error_t deleteAllSMSmessages(void) { return (deleteSMSmessage( 1, 4 )); }; // Delete the read, sent, unsent and unread messages from preferred storage + + // V24 Control and V25ter (UART interface) AT commands + UBLOX_AT_error_t setBaud(unsigned long baud); + UBLOX_AT_error_t setFlowControl(UBLOX_AT_flow_control_t value = UBLOX_AT_ENABLE_FLOW_CONTROL); + + // GPIO + // GPIO pin map + typedef enum + { + GPIO1 = 16, + GPIO2 = 23, + GPIO3 = 24, + GPIO4 = 25, + GPIO5 = 42, + GPIO6 = 19 + } UBLOX_AT_gpio_t; + // GPIO pin modes + typedef enum + { + GPIO_MODE_INVALID = -1, + GPIO_OUTPUT = 0, + GPIO_INPUT, + NETWORK_STATUS, + GNSS_SUPPLY_ENABLE, + GNSS_DATA_READY, + GNSS_RTC_SHARING, + JAMMING_DETECTION, + SIM_CARD_DETECTION, + HEADSET_DETECTION, + GSM_TX_BURST_INDICATION, + MODULE_STATUS_INDICATION, + MODULE_OPERATING_MODE_INDICATION, + I2S_DIGITAL_AUDIO_INTERFACE, + SPI_SERIAL_INTERFACE, + MASTER_CLOCK_GENRATION, + UART_INTERFACE, + WIFI_ENABLE, + RING_INDICATION = 18, + LAST_GASP_ENABLE, + EXTERNAL_GNSS_ANTENNA, + TIME_PULSE_GNSS, + TIME_PULSE_OUTPUT, + TIMESTAMP, + FAST_POWER_OFF, + LWM2M_PULSE, + HARDWARE_FLOW_CONTROL, + ANTENNA_TUNING, + EXT_GNSS_TIME_PULSE, + EXT_GNSS_TIMESTAMP, + DTR_MODE, + KHZ_32768_OUT = 32, + PAD_DISABLED = 255 + } UBLOX_AT_gpio_mode_t; + UBLOX_AT_error_t setGpioMode(UBLOX_AT_gpio_t gpio, UBLOX_AT_gpio_mode_t mode, int value = 0); + UBLOX_AT_gpio_mode_t getGpioMode(UBLOX_AT_gpio_t gpio); + + // IP Transport Layer + int socketOpen(UBLOX_AT_socket_protocol_t protocol, unsigned int localPort = 0); // Open a socket. Returns the socket number. + UBLOX_AT_error_t socketClose(int socket, unsigned long timeout = UBLOX_AT_2_MIN_TIMEOUT); // Close the socket + UBLOX_AT_error_t socketConnect(int socket, const char *address, unsigned int port); // TCP - connect to a remote IP Address using the specified port. Not required for UDP sockets. + UBLOX_AT_error_t socketConnect(int socket, IPAddress address, unsigned int port); + // Write data to the specified socket. Works with binary data - but you must specify the data length when using the const char * version + // Works with both TCP and UDP sockets - but socketWriteUDP is preferred for UDP and doesn't require socketOpen to be called first + UBLOX_AT_error_t socketWrite(int socket, const char *str, int len = -1); + UBLOX_AT_error_t socketWrite(int socket, String str); // OK for binary data + // Write UDP data to the specified IP Address and port. + // Works with binary data - but you must specify the data length when using the const char * versions + // If you let len default to -1, strlen is used to calculate the data length - and will be incorrect for binary data + UBLOX_AT_error_t socketWriteUDP(int socket, const char *address, int port, const char *str, int len = -1); + UBLOX_AT_error_t socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len = -1); + UBLOX_AT_error_t socketWriteUDP(int socket, String address, int port, String str); + // Read data from the specified socket + // Call socketReadAvailable first to determine how much data is available - or use the callbacks (triggered by URC's) + // Works for both TCP and UDP - but socketReadUDP is preferred for UDP as it records the remote IP Address and port + // bytesRead - if provided - will be updated with the number of bytes actually read. This could be less than length! + UBLOX_AT_error_t socketRead(int socket, int length, char *readDest, int *bytesRead = nullptr); + // Return the number of bytes available (waiting to be read) on the chosen socket + // Uses +USORD. Valid for both TCP and UDP sockets - but socketReadAvailableUDP is preferred for UDP + UBLOX_AT_error_t socketReadAvailable(int socket, int *length); + // Read data from the specified UDP port + // Call socketReadAvailableUDP first to determine how much data is available - or use the callbacks (triggered by URC's) + // The remote IP Address and port are returned via *remoteIPAddress and *remotePort (if not nullptr) + // bytesRead - if provided - will be updated with the number of bytes actually read. This could be less than length! + UBLOX_AT_error_t socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress = nullptr, int *remotePort = nullptr, int *bytesRead = nullptr); + // Return the number of bytes available (waiting to be read) on the chosen UDP socket + UBLOX_AT_error_t socketReadAvailableUDP(int socket, int *length); + // Start listening for a connection on the specified port. The connection is reported via the socket listen callback + UBLOX_AT_error_t socketListen(int socket, unsigned int port); + // Place the socket into direct link mode - making it easy to transfer binary data. Wait two seconds and then send +++ to exit the link. + UBLOX_AT_error_t socketDirectLinkMode(int socket); + // Configure when direct link data is sent + UBLOX_AT_error_t socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger); + UBLOX_AT_error_t socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger); + UBLOX_AT_error_t socketDirectLinkCharacterTrigger(int socket, int characterTrigger); + UBLOX_AT_error_t socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer); + // Use +USOCTL (Socket control) to query the socket parameters + UBLOX_AT_error_t querySocketType(int socket, UBLOX_AT_socket_protocol_t *protocol); + UBLOX_AT_error_t querySocketLastError(int socket, int *error); + UBLOX_AT_error_t querySocketTotalBytesSent(int socket, uint32_t *total); + UBLOX_AT_error_t querySocketTotalBytesReceived(int socket, uint32_t *total); + UBLOX_AT_error_t querySocketRemoteIPAddress(int socket, IPAddress *address, int *port); + UBLOX_AT_error_t querySocketStatusTCP(int socket, UBLOX_AT_tcp_socket_status_t *status); + UBLOX_AT_error_t querySocketOutUnackData(int socket, uint32_t *total); + // Return the most recent socket error + int socketGetLastError(); + // Return the remote IP Address from the most recent socket listen indication (socket connection) + // Use the socket listen callback to get the full address and port information + IPAddress lastRemoteIP(void); + + // Ping + UBLOX_AT_error_t ping(String remote_host, int retry = 4, int p_size = 32, unsigned long timeout = 5000, int ttl = 32); + + // HTTP + UBLOX_AT_error_t resetHTTPprofile(int profile); // Reset the HTTP profile. Note: The configured HTTP profile parameters are not saved in the non volatile memory. + UBLOX_AT_error_t setHTTPserverIPaddress(int profile, IPAddress address); // Default: empty string + UBLOX_AT_error_t setHTTPserverName(int profile, String server); // Default: empty string + UBLOX_AT_error_t setHTTPusername(int profile, String username); // Default: empty string + UBLOX_AT_error_t setHTTPpassword(int profile, String password); // Default: empty string + UBLOX_AT_error_t setHTTPauthentication(int profile, bool authenticate); // Default: no authentication + UBLOX_AT_error_t setHTTPserverPort(int profile, int port); // Default: 80 + UBLOX_AT_error_t setHTTPcustomHeader(int profile, String header); // Default: format 0:Content-Type:application/json" + UBLOX_AT_error_t setHTTPsecure(int profile, bool secure, int secprofile = -1); // Default: disabled (HTTP on port 80). Set to true for HTTPS on port 443 + // TO DO: Add custom request headers + UBLOX_AT_error_t getHTTPprotocolError(int profile, int *error_class, int *error_code); // Read the most recent HTTP protocol error for this profile + UBLOX_AT_error_t sendHTTPGET(int profile, String path, String responseFilename); + UBLOX_AT_error_t sendHTTPPOSTdata(int profile, String path, String responseFilename, String data, UBLOX_AT_http_content_types_t httpContentType); + UBLOX_AT_error_t sendHTTPPOSTfile(int profile, String path, String responseFilename, String requestFile, UBLOX_AT_http_content_types_t httpContentType); + + UBLOX_AT_error_t nvMQTT(UBLOX_AT_mqtt_nv_parameter_t parameter); + UBLOX_AT_error_t setMQTTclientId(const String& clientId); + UBLOX_AT_error_t setMQTTserver(const String& serverName, int port); + UBLOX_AT_error_t setMQTTcredentials(const String& userName, const String& pwd); + UBLOX_AT_error_t setMQTTsecure(bool secure, int secprofile = -1); + UBLOX_AT_error_t connectMQTT(void); + UBLOX_AT_error_t disconnectMQTT(void); + UBLOX_AT_error_t subscribeMQTTtopic(int max_Qos, const String& topic); + UBLOX_AT_error_t unsubscribeMQTTtopic(const String& topic); + UBLOX_AT_error_t readMQTT(int* pQos, String* pTopic, uint8_t *readDest, int readLength, int *bytesRead); + UBLOX_AT_error_t mqttPublishTextMsg(const String& topic, const char * const msg, uint8_t qos = 0, bool retain = false); + UBLOX_AT_error_t mqttPublishBinaryMsg(const String& topic, const char * const msg, size_t msg_len, uint8_t qos = 0, bool retain = false); + UBLOX_AT_error_t mqttPublishFromFile(const String& topic, const String& filename, uint8_t qos = 0, bool retain = false); + UBLOX_AT_error_t getMQTTprotocolError(int *error_code, int *error_code2); + + // FTP + UBLOX_AT_error_t setFTPserver(const String& serverName); + UBLOX_AT_error_t setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger); + UBLOX_AT_error_t setFTPcredentials(const String& userName, const String& pwd); + UBLOX_AT_error_t connectFTP(void); + UBLOX_AT_error_t disconnectFTP(void); + UBLOX_AT_error_t ftpGetFile(const String& filename); + UBLOX_AT_error_t getFTPprotocolError(int *error_code, int *error_code2); + + // Configure security profiles + UBLOX_AT_error_t resetSecurityProfile(int secprofile); + UBLOX_AT_error_t configSecurityProfileString(int secprofile, UBLOX_AT_sec_profile_parameter_t parameter, String value); + UBLOX_AT_error_t configSecurityProfile(int secprofile, UBLOX_AT_sec_profile_parameter_t parameter, int value); + UBLOX_AT_error_t setSecurityManager(UBLOX_AT_sec_manager_opcode_t opcode, UBLOX_AT_sec_manager_parameter_t parameter, String name, String data); + + // Packet Switched Data + // Configure the PDP using +UPSD. See UBLOX_AT_pdp_configuration_parameter_t for the list of parameters: protocol, APN, username, DNS, etc. + UBLOX_AT_error_t setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, int value); // Set parameters in the chosen PSD profile + UBLOX_AT_error_t setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, UBLOX_AT_pdp_protocol_type_t value); // Set parameters in the chosen PSD profile + UBLOX_AT_error_t setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, String value); // Set parameters in the chosen PSD profile + UBLOX_AT_error_t setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, IPAddress value); // Set parameters in the chosen PSD profile + UBLOX_AT_error_t performPDPaction(int profile, UBLOX_AT_pdp_actions_t action); // Performs the requested action for the specified PSD profile: reset, store, load, activate, deactivate + UBLOX_AT_error_t activatePDPcontext(bool status, int cid = -1); // Activates or deactivates the specified PDP context. Default to all (cid = -1) + UBLOX_AT_error_t getNetworkAssignedIPAddress(int profile, IPAddress *address); // Get the dynamic IP address assigned during PDP context activation + + // GPS + typedef enum + { + GNSS_SYSTEM_GPS = 1, + GNSS_SYSTEM_SBAS = 2, + GNSS_SYSTEM_GALILEO = 4, + GNSS_SYSTEM_BEIDOU = 8, + GNSS_SYSTEM_IMES = 16, + GNSS_SYSTEM_QZSS = 32, + GNSS_SYSTEM_GLONASS = 64 + } gnss_system_t; + typedef enum + { + GNSS_AIDING_MODE_NONE = 0, + GNSS_AIDING_MODE_AUTOMATIC = 1, + GNSS_AIDING_MODE_ASSISTNOW_OFFLINE = 2, + GNSS_AIDING_MODE_ASSISTNOW_ONLINE = 4, + GNSS_AIDING_MODE_ASSISTNOW_AUTONOMOUS = 8 + } gnss_aiding_mode_t; + bool isGPSon(void); + UBLOX_AT_error_t gpsPower(bool enable = true, + gnss_system_t gnss_sys = GNSS_SYSTEM_GPS, + gnss_aiding_mode_t gnss_aiding = GNSS_AIDING_MODE_AUTOMATIC); + //UBLOX_AT_error_t gpsEnableClock(bool enable = true); + //UBLOX_AT_error_t gpsGetClock(struct ClockData *clock); + //UBLOX_AT_error_t gpsEnableFix(bool enable = true); + //UBLOX_AT_error_t gpsGetFix(float *lat, float *lon, unsigned int *alt, uint8_t *quality, uint8_t *sat); + //UBLOX_AT_error_t gpsGetFix(struct PositionData *pos); + //UBLOX_AT_error_t gpsEnablePos(bool enable = true); + //UBLOX_AT_error_t gpsGetPos(struct PositionData *pos); + //UBLOX_AT_error_t gpsEnableSat(bool enable = true); + //UBLOX_AT_error_t gpsGetSat(uint8_t *sats); + UBLOX_AT_error_t gpsEnableRmc(bool enable = true); // Enable GPRMC messages + UBLOX_AT_error_t gpsGetRmc(struct PositionData *pos, struct SpeedData *speed, struct ClockData *clk, bool *valid); //Parse a GPRMC message + //UBLOX_AT_error_t gpsEnableSpeed(bool enable = true); + //UBLOX_AT_error_t gpsGetSpeed(struct SpeedData *speed); + + UBLOX_AT_error_t gpsRequest(unsigned int timeout, uint32_t accuracy, bool detailed = true, unsigned int sensor = 3); + + //CellLocate + UBLOX_AT_error_t gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, + unsigned int days = 14, unsigned int period = 4, unsigned int resolution = 1, + unsigned int gnssTypes = 65, unsigned int mode = 0, unsigned int dataType = 15); + + // File system + // TO DO: add full support for file tags. Default tag to USER + UBLOX_AT_error_t getFileContents(String filename, String *contents); // OK for text files. But will fail with binary files (containing \0) on some platforms. + UBLOX_AT_error_t getFileContents(String filename, char *contents); // OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. + UBLOX_AT_error_t getFileBlock(const String& filename, char* buffer, size_t offset, size_t length, size_t& bytes_read); // OK for binary files. Make sure buffer can hold the requested block size. + + // Append data to a file, delete file first to not appends the data. + UBLOX_AT_error_t appendFileContents(String filename, String str); + UBLOX_AT_error_t appendFileContents(String filename, const char *str, int len); + UBLOX_AT_error_t getFileSize(String filename, int *size); + UBLOX_AT_error_t deleteFile(String filename); + + // Functionality + UBLOX_AT_error_t functionality(UBLOX_AT_functionality_t function = FULL_FUNCTIONALITY); + + // Send a custom command with an expected (potentially partial) response, store entire response + UBLOX_AT_error_t sendCustomCommandWithResponse(const char *command, const char *expectedResponse, + char *responseDest, unsigned long commandTimeout = UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, bool at = true); + +private: + HardwareSerial *_hardSerial; +#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED + SoftwareSerial *_softSerial; +#endif + + Print *_debugPort; //The stream to send debug messages to if enabled. Usually Serial. + bool _printDebug = false; //Flag to print debugging variables + Print *_debugAtPort; //The stream to send debug messages to if enabled. Usually Serial. + bool _printAtDebug = false; //Flag to print debugging variables + + int _powerPin; + int _resetPin; + bool _invertPowerPin = false; + + unsigned long _baud; + IPAddress _lastRemoteIP; + IPAddress _lastLocalIP; + uint8_t _maxInitTries; + bool _autoTimeZoneForBegin = true; + bool _bufferedPollReentrant = false; // Prevent reentry of bufferedPoll - just in case it gets called from a callback + bool _pollReentrant = false; // Prevent reentry of poll - just in case it gets called from a callback + + #define _RXBuffSize 2056 + const unsigned long _rxWindowMillis = 2; // 1ms is not quite long enough for a single char at 9600 baud. millis roll over much less often than micros. See notes in .cpp re. ESP32! + char *_saraRXBuffer; // Allocated in UBLOX_AT::begin + char *_pruneBuffer; + char *_saraResponseBacklog; + int _saraResponseBacklogLength = 0; // The backlog could contain binary data so we can't use strlen to find its length + + void (*_socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int); + void (*_socketReadCallback)(int, String); + void (*_socketReadCallbackPlus)(int, const char *, int, IPAddress, int); // socket, data, length, remoteAddress, remotePort + void (*_socketCloseCallback)(int); + void (*_gpsRequestCallback)(ClockData, PositionData, SpeedData, unsigned long); + void (*_simStateReportCallback)(UBLOX_AT_sim_states_t); + void (*_psdActionRequestCallback)(int, IPAddress); + void (*_pingRequestCallback)(int, int, String, IPAddress, int, long); + void (*_httpCommandRequestCallback)(int, int, int); + void (*_mqttCommandRequestCallback)(int, int); + void (*_ftpCommandRequestCallback)(int, int); + void (*_registrationCallback)(UBLOX_AT_registration_status_t status, unsigned int lac, unsigned int ci, int Act); + void (*_epsRegistrationCallback)(UBLOX_AT_registration_status_t status, unsigned int tac, unsigned int ci, int Act); + + + int _lastSocketProtocol[UBLOX_AT_NUM_SOCKETS]; // Record the protocol for each socket to avoid having to call querySocketType in parseSocketReadIndication + + typedef enum + { + UBLOX_AT_INIT_STANDARD, + UBLOX_AT_INIT_AUTOBAUD, + UBLOX_AT_INIT_RESET + } UBLOX_AT_init_type_t; + + UBLOX_AT_error_t init(unsigned long baud, UBLOX_AT_init_type_t initType = UBLOX_AT_INIT_STANDARD); + + void powerOn(void); // Brief pulse on PWR_ON to turn module back on + void powerOff(void); // Long pulse on PWR_ON to do a graceful shutdown. Note modulePowerOff (+CPWROFF) is preferred. + + void hwReset(void); + + UBLOX_AT_error_t setMNOprofile(mobile_network_operator_t mno, bool autoReset = false, bool urcNotification = false); + UBLOX_AT_error_t getMNOprofile(mobile_network_operator_t *mno); + + // Wait for an expected response (don't send a command) + UBLOX_AT_error_t waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout); + + // Send command with an expected (potentially partial) response, store entire response + UBLOX_AT_error_t sendCommandWithResponse(const char *command, const char *expectedResponse, + char *responseDest, unsigned long commandTimeout, int destSize = minimumResponseAllocation, bool at = true); + + // Send a command -- prepend AT if at is true + void sendCommand(const char *command, bool at); + + const int _saraR5maxSocketRead = 1024; // The limit on bytes that can be read in a single read + + UBLOX_AT_error_t parseSocketReadIndication(int socket, int length); + UBLOX_AT_error_t parseSocketReadIndicationUDP(int socket, int length); + UBLOX_AT_error_t parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, int socket, IPAddress remoteIP, unsigned int port); + UBLOX_AT_error_t parseSocketCloseIndication(String *closeIndication); + + // UART Functions + size_t hwPrint(const char *s); + size_t hwWriteData(const char *buff, int len); + size_t hwWrite(const char c); + int readAvailable(char *inString); + char readChar(void); + int hwAvailable(void); + virtual void beginSerial(unsigned long baud); + void setTimeout(unsigned long timeout); + bool find(char *target); + + UBLOX_AT_error_t autobaud(unsigned long desiredBaud); + + char *ublox_at_calloc_char(size_t num); + + bool processURCEvent(const char *event); + void pruneBacklog(void); + + // GPS Helper functions + char *readDataUntil(char *destination, unsigned int destSize, char *source, char delimiter); + bool parseGPRMCString(char *rmcString, PositionData *pos, ClockData *clk, SpeedData *spd); +}; + +#endif //SPARKFUN_UBLOX_AT_ARDUINO_LIBRARY_H From 9aade77b6e51cf7bcccea9122571029ec79ce65d Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 15 Nov 2023 11:59:53 -0700 Subject: [PATCH 03/52] Add SARA-R5 and LARA-R6 class files Placeholders for now --- src/sfe_lara_r6.cpp | 0 src/sfe_lara_r6.h | 42 ++++++++++++++++++++++++++++++++++++++++++ src/sfe_sara_r5.cpp | 0 src/sfe_sara_r5.h | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 src/sfe_lara_r6.cpp create mode 100644 src/sfe_lara_r6.h create mode 100644 src/sfe_sara_r5.cpp create mode 100644 src/sfe_sara_r5.h diff --git a/src/sfe_lara_r6.cpp b/src/sfe_lara_r6.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/sfe_lara_r6.h b/src/sfe_lara_r6.h new file mode 100644 index 0000000..438edff --- /dev/null +++ b/src/sfe_lara_r6.h @@ -0,0 +1,42 @@ +#ifndef SFE_LARA_R6_LIBRARY_H +#define SFE_LARA_R6_LIBRARY_H + +#include "sfe_ublox_at_commands.h" + +// Base LARA-R6 class +class LARA_R6: public UBLOX_AT +{ + +}; + +class LARA_R6001: public LARA_R6 +{ + +}; + +class LARA_R6001D: public LARA_R6 +{ + +}; + +class LARA_R6401: public LARA_R6 +{ + +}; + +class LARA_R6401D: public LARA_R6 +{ + +}; + +class LARA_R6801_00B: public LARA_R6 +{ + +}; + +class LARA_R6801D: public LARA_R6 +{ + +}; + +#endif \ No newline at end of file diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h new file mode 100644 index 0000000..c43b412 --- /dev/null +++ b/src/sfe_sara_r5.h @@ -0,0 +1,37 @@ +#ifndef SFE_SARA_R5_LIBRARY_H +#define SFE_SARA_R5_LIBRARY_H + +#include "sfe_ublox_at_commands.h" + +// Base SARA-R5 class +class SARA_R5: public UBLOX_AT +{ + +}; + +class SARA_R500S: public SARA_R5 +{ + +}; + +class SARA_R500S_01B: public SARA_R5 +{ + +}; + +class SARA_R500S_61B: public SARA_R5 +{ + +}; + +class SARA_R510M8S_61B: public SARA_R5 +{ + +}; + +class SARA_R510S: public SARA_R5 +{ + +}; + +#endif \ No newline at end of file From d247a1743e9e0401ae154ceae41edbef608aca7d Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 15 Nov 2023 12:00:51 -0700 Subject: [PATCH 04/52] Add main library header files Just includes all other headers in library --- src/SparkFun_u-blox_AT_Commands_Arduino_Library.h | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/SparkFun_u-blox_AT_Commands_Arduino_Library.h diff --git a/src/SparkFun_u-blox_AT_Commands_Arduino_Library.h b/src/SparkFun_u-blox_AT_Commands_Arduino_Library.h new file mode 100644 index 0000000..0ebb8e3 --- /dev/null +++ b/src/SparkFun_u-blox_AT_Commands_Arduino_Library.h @@ -0,0 +1,3 @@ +#include "sfe_ublox_at_commands.h" +#include "sfe_sara_r5.h" +#include "sfe_lara_r6.h" From 904a1c8421660f4140b0c4521471179956f8adfb Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 15 Nov 2023 12:02:28 -0700 Subject: [PATCH 05/52] Add original SARA-R5 header This is purely for backwards compatibility with the original library, mainly macros and constants. Some are duplicates in base class header, need to remove those --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 587 ++++++++++++++++++ 1 file changed, 587 insertions(+) create mode 100644 src/SparkFun_u-blox_SARA-R5_Arduino_Library.h diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h new file mode 100644 index 0000000..8d4d995 --- /dev/null +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -0,0 +1,587 @@ +// This file is purely for backwards compatibility with the original SARA-R5 library + +/* + Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod Asset Tracker + By: Paul Clark + October 19th 2020 + + Based extensively on the: + Arduino Library for the SparkFun LTE CAT M1/NB-IoT Shield - SARA-R4 + Written by Jim Lindblom @ SparkFun Electronics, September 5, 2018 + + This Arduino library provides mechanisms to initialize and use + the SARA-R5 module over either a SoftwareSerial or hardware serial port. + + Please see LICENSE.md for the license information + +*/ + +#ifndef SPARKFUN_SARA_R5_ARDUINO_LIBRARY_H +#define SPARKFUN_SARA_R5_ARDUINO_LIBRARY_H + +#include "sfe_sara_r5.h" + +#define SARA_R5_POWER_PIN -1 // Default to no pin +#define SARA_R5_RESET_PIN -1 + +// Timing +#define SARA_R5_STANDARD_RESPONSE_TIMEOUT 1000 +#define SARA_R5_10_SEC_TIMEOUT 10000 +#define SARA_R5_55_SECS_TIMEOUT 55000 +#define SARA_R5_2_MIN_TIMEOUT 120000 +#define SARA_R5_3_MIN_TIMEOUT 180000 +#define SARA_R5_SET_BAUD_TIMEOUT 500 +#define SARA_R5_POWER_OFF_PULSE_PERIOD 3200 // Hold PWR_ON low for this long to power the module off +#define SARA_R5_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) +#define SARA_R5_RESET_PULSE_PERIOD 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) +#define SARA_R5_POWER_OFF_TIMEOUT 40000 // Datasheet says 40 seconds... +#define SARA_R5_IP_CONNECT_TIMEOUT 130000 +#define SARA_R5_POLL_DELAY 1 +#define SARA_R5_SOCKET_WRITE_TIMEOUT 10000 + +// ## Suported AT Commands +// ### General +const char SARA_R5_COMMAND_AT[] = "AT"; // AT "Test" +const char SARA_R5_COMMAND_ECHO[] = "E"; // Local Echo +const char SARA_R5_COMMAND_MANU_ID[] = "+CGMI"; // Manufacturer identification +const char SARA_R5_COMMAND_MODEL_ID[] = "+CGMM"; // Model identification +const char SARA_R5_COMMAND_FW_VER_ID[] = "+CGMR"; // Firmware version identification +const char SARA_R5_COMMAND_SERIAL_NO[] = "+CGSN"; // Product serial number +const char SARA_R5_COMMAND_IMEI[] = "+GSN"; // IMEI identification +const char SARA_R5_COMMAND_IMSI[] = "+CIMI"; // IMSI identification +const char SARA_R5_COMMAND_CCID[] = "+CCID"; // SIM CCID +const char SARA_R5_COMMAND_REQ_CAP[] = "+GCAP"; // Request capabilities list +// ### Control and status +const char SARA_R5_COMMAND_POWER_OFF[] = "+CPWROFF"; // Module switch off +const char SARA_R5_COMMAND_FUNC[] = "+CFUN"; // Functionality (reset, etc.) +const char SARA_R5_COMMAND_CLOCK[] = "+CCLK"; // Real-time clock +const char SARA_R5_COMMAND_AUTO_TZ[] = "+CTZU"; // Automatic time zone update +const char SARA_R5_COMMAND_TZ_REPORT[] = "+CTZR"; // Time zone reporting +// ### Network service +const char SARA_R5_COMMAND_CNUM[] = "+CNUM"; // Subscriber number +const char SARA_R5_SIGNAL_QUALITY[] = "+CSQ"; +const char SARA_R5_EXT_SIGNAL_QUALITY[] = "+CESQ"; +const char SARA_R5_OPERATOR_SELECTION[] = "+COPS"; +const char SARA_R5_REGISTRATION_STATUS[] = "+CREG"; +const char SARA_R5_EPSREGISTRATION_STATUS[] = "+CEREG"; +const char SARA_R5_READ_OPERATOR_NAMES[] = "+COPN"; +const char SARA_R5_COMMAND_MNO[] = "+UMNOPROF"; // MNO (mobile network operator) Profile +// ### SIM +const char SARA_R5_SIM_STATE[] = "+USIMSTAT"; +const char SARA_R5_COMMAND_SIMPIN[] = "+CPIN"; // SIM PIN +// ### SMS +const char SARA_R5_MESSAGE_FORMAT[] = "+CMGF"; // Set SMS message format +const char SARA_R5_SEND_TEXT[] = "+CMGS"; // Send SMS message +const char SARA_R5_NEW_MESSAGE_IND[] = "+CNMI"; // New [SMS] message indication +const char SARA_R5_PREF_MESSAGE_STORE[] = "+CPMS"; // Preferred message storage +const char SARA_R5_READ_TEXT_MESSAGE[] = "+CMGR"; // Read message +const char SARA_R5_DELETE_MESSAGE[] = "+CMGD"; // Delete message +// V24 control and V25ter (UART interface) +const char SARA_R5_FLOW_CONTROL[] = "&K"; // Flow control +const char SARA_R5_COMMAND_BAUD[] = "+IPR"; // Baud rate +// ### Packet switched data services +const char SARA_R5_MESSAGE_PDP_DEF[] = "+CGDCONT"; // Packet switched Data Profile context definition +const char SARA_R5_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration +const char SARA_R5_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile +const char SARA_R5_MESSAGE_PDP_CONTEXT_ACTIVATE[] = "+CGACT"; // Activates or deactivates the specified PDP context +const char SARA_R5_MESSAGE_ENTER_PPP[] = "D"; +const char SARA_R5_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data +// ### GPIO +const char SARA_R5_COMMAND_GPIO[] = "+UGPIOC"; // GPIO Configuration +// ### IP +const char SARA_R5_CREATE_SOCKET[] = "+USOCR"; // Create a new socket +const char SARA_R5_CLOSE_SOCKET[] = "+USOCL"; // Close a socket +const char SARA_R5_CONNECT_SOCKET[] = "+USOCO"; // Connect to server on socket +const char SARA_R5_WRITE_SOCKET[] = "+USOWR"; // Write data to a socket +const char SARA_R5_WRITE_UDP_SOCKET[] = "+USOST"; // Write data to a UDP socket +const char SARA_R5_READ_SOCKET[] = "+USORD"; // Read from a socket +const char SARA_R5_READ_UDP_SOCKET[] = "+USORF"; // Read UDP data from a socket +const char SARA_R5_LISTEN_SOCKET[] = "+USOLI"; // Listen for connection on socket +const char SARA_R5_GET_ERROR[] = "+USOER"; // Get last socket error. +const char SARA_R5_SOCKET_DIRECT_LINK[] = "+USODL"; // Set socket in Direct Link mode +const char SARA_R5_SOCKET_CONTROL[] = "+USOCTL"; // Query the socket parameters +const char SARA_R5_UD_CONFIGURATION[] = "+UDCONF"; // User Datagram Configuration +// ### Ping +const char SARA_R5_PING_COMMAND[] = "+UPING"; // Ping +// ### HTTP +const char SARA_R5_HTTP_PROFILE[] = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined +const char SARA_R5_HTTP_COMMAND[] = "+UHTTPC"; // Trigger the specified HTTP command +const char SARA_R5_HTTP_PROTOCOL_ERROR[] = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. + +const char SARA_R5_MQTT_NVM[] = "+UMQTTNV"; +const char SARA_R5_MQTT_PROFILE[] = "+UMQTT"; +const char SARA_R5_MQTT_COMMAND[] = "+UMQTTC"; +const char SARA_R5_MQTT_PROTOCOL_ERROR[] = "+UMQTTER"; +// ### FTP +const char SARA_R5_FTP_PROFILE[] = "+UFTP"; +const char SARA_R5_FTP_COMMAND[] = "+UFTPC"; +const char SARA_R5_FTP_PROTOCOL_ERROR[] = "+UFTPER"; +// ### GNSS +const char SARA_R5_GNSS_POWER[] = "+UGPS"; // GNSS power management configuration +const char SARA_R5_GNSS_ASSISTED_IND[] = "+UGIND"; // Assisted GNSS unsolicited indication +const char SARA_R5_GNSS_REQUEST_LOCATION[] = "+ULOC"; // Ask for localization information +const char SARA_R5_GNSS_GPRMC[] = "+UGRMC"; // Ask for localization information +const char SARA_R5_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) +const char SARA_R5_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication +const char SARA_R5_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration +const char SARA_R5_GNSS_CONFIGURE_SENSOR[] = "+ULOCGNSS"; // Configure GNSS sensor +const char SARA_R5_GNSS_CONFIGURE_LOCATION[] = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) +const char SARA_R5_AIDING_SERVER_CONFIGURATION[] = "+UGSRV"; // Configure aiding server (CellLocate®) +// ### File System +// TO DO: Add support for file tags. Default tag to USER +const char SARA_R5_FILE_SYSTEM_READ_FILE[] = "+URDFILE"; // Read a file +const char SARA_R5_FILE_SYSTEM_READ_BLOCK[] = "+URDBLOCK"; // Read a block from a file +const char SARA_R5_FILE_SYSTEM_DOWNLOAD_FILE[] = "+UDWNFILE"; // Download a file into the module +const char SARA_R5_FILE_SYSTEM_LIST_FILES[] = "+ULSTFILE"; // List of files, size of file, etc. +const char SARA_R5_FILE_SYSTEM_DELETE_FILE[] = "+UDELFILE"; // Delete a file +// ### File System +// TO DO: Add support for file tags. Default tag to USER +const char SARA_R5_SEC_PROFILE[] = "+USECPRF"; +const char SARA_R5_SEC_MANAGER[] = "+USECMNG"; + + +// ### URC strings +const char SARA_R5_READ_SOCKET_URC[] = "+UUSORD:"; +const char SARA_R5_READ_UDP_SOCKET_URC[] = "+UUSORF:"; +const char SARA_R5_LISTEN_SOCKET_URC[] = "+UUSOLI:"; +const char SARA_R5_CLOSE_SOCKET_URC[] = "+UUSOCL:"; +const char SARA_R5_GNSS_REQUEST_LOCATION_URC[] = "+UULOC:"; +const char SARA_R5_SIM_STATE_URC[] = "+UUSIMSTAT:"; +const char SARA_R5_MESSAGE_PDP_ACTION_URC[] = "+UUPSDA:"; +const char SARA_R5_HTTP_COMMAND_URC[] = "+UUHTTPCR:"; +const char SARA_R5_MQTT_COMMAND_URC[] = "+UUMQTTC:"; +const char SARA_R5_PING_COMMAND_URC[] = "+UUPING:"; +const char SARA_R5_REGISTRATION_STATUS_URC[] = "+CREG:"; +const char SARA_R5_EPSREGISTRATION_STATUS_URC[] = "+CEREG:"; +const char SARA_R5_FTP_COMMAND_URC[] = "+UUFTPCR:"; + +// ### Response +const char SARA_R5_RESPONSE_MORE[] = "\n>"; +const char SARA_R5_RESPONSE_OK[] = "\nOK\r\n"; +const char SARA_R5_RESPONSE_ERROR[] = "\nERROR\r\n"; +const char SARA_R5_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; +#define SARA_R5_RESPONSE_OK_OR_ERROR nullptr + +// CTRL+Z and ESC ASCII codes for SMS message sends +const char ASCII_CTRL_Z = 0x1A; +const char ASCII_ESC = 0x1B; + +// NMEA data size - used by parseGPRMCString +#define TEMP_NMEA_DATA_SIZE 16 + +#define NOT_AT_COMMAND false +#define AT_COMMAND true + +// The minimum memory allocation for responses from sendCommandWithResponse +// This needs to be large enough to hold the response you're expecting plus and URC's that may arrive during the timeout +#define minimumResponseAllocation 128 + +#define SARA_R5_NUM_SOCKETS 6 + +#define NUM_SUPPORTED_BAUD 6 +const unsigned long SARA_R5_SUPPORTED_BAUD[NUM_SUPPORTED_BAUD] = + { + 115200, + 9600, + 19200, + 38400, + 57600, + 230400}; +#define SARA_R5_DEFAULT_BAUD_RATE 115200 + +// Flow control definitions for AT&K +// Note: SW (XON/XOFF) flow control is not supported on the SARA_R5 +typedef enum +{ + SARA_R5_DISABLE_FLOW_CONTROL = 0, + SARA_R5_ENABLE_FLOW_CONTROL = 3 +} SARA_R5_flow_control_t; + +// The standard Europe profile should be used as the basis for all other MNOs in Europe outside of Vodafone +// and Deutsche Telekom. However, there may be changes that need to be applied to the module for proper +// operation with any given European MNO such as attach type, RAT preference, band selection, etc. Please +// consult with the preferred network provider. +typedef enum +{ + MNO_INVALID = -1, + MNO_SW_DEFAULT = 0, // Undefined / regulatory + MNO_SIM_ICCID = 1, + MNO_ATT = 2, // AT&T + MNO_VERIZON = 3, + MNO_TELSTRA = 4, + MNO_TMO = 5, // T-Mobile US + MNO_CT = 6, // China Telecom + MNO_SPRINT = 8, + MNO_VODAFONE = 19, + MNO_NTT_DOCOMO = 20, + MNO_TELUS = 21, + MNO_SOFTBANK = 28, + MNO_DT = 31, // Deutsche Telekom + MNO_US_CELLULAR = 32, + MNO_SKT = 39, + MNO_GLOBAL = 90, + MNO_STD_EUROPE = 100, + MNO_STD_EU_NOEPCO = 101 +} mobile_network_operator_t; + +typedef enum +{ + SARA_R5_ERROR_INVALID = -1, // -1 + SARA_R5_ERROR_SUCCESS = 0, // 0 + SARA_R5_ERROR_OUT_OF_MEMORY, // 1 + SARA_R5_ERROR_TIMEOUT, // 2 + SARA_R5_ERROR_UNEXPECTED_PARAM, // 3 + SARA_R5_ERROR_UNEXPECTED_RESPONSE, // 4 + SARA_R5_ERROR_NO_RESPONSE, // 5 + SARA_R5_ERROR_DEREGISTERED, // 6 + SARA_R5_ERROR_ZERO_READ_LENGTH, // 7 + SARA_R5_ERROR_ERROR // 8 +} SARA_R5_error_t; +#define SARA_R5_SUCCESS SARA_R5_ERROR_SUCCESS + +typedef enum +{ + SARA_R5_REGISTRATION_INVALID = -1, + SARA_R5_REGISTRATION_NOT_REGISTERED = 0, + SARA_R5_REGISTRATION_HOME = 1, + SARA_R5_REGISTRATION_SEARCHING = 2, + SARA_R5_REGISTRATION_DENIED = 3, + SARA_R5_REGISTRATION_UNKNOWN = 4, + SARA_R5_REGISTRATION_ROAMING = 5, + SARA_R5_REGISTRATION_HOME_SMS_ONLY = 6, + SARA_R5_REGISTRATION_ROAMING_SMS_ONLY = 7, + SARA_R5_REGISTRATION_EMERGENCY_SERV_ONLY = 8, + SARA_R5_REGISTRATION_HOME_CSFB_NOT_PREFERRED = 9, + SARA_R5_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED = 10 +} SARA_R5_registration_status_t; + +struct DateData +{ + uint8_t day; + uint8_t month; + unsigned int year; +}; + +struct TimeData +{ + uint8_t hour; + uint8_t minute; + uint8_t second; + unsigned int ms; + uint8_t tzh; + uint8_t tzm; +}; + +struct ClockData +{ + struct DateData date; + struct TimeData time; +}; + +struct PositionData +{ + float utc; + float lat; // Degrees: +/- 90 + float lon; // Degrees: +/- 180 + float alt; + char mode; + char status; +}; + +struct SpeedData +{ + float speed; // m/s + float cog; // Degrees + float magVar; // Degrees +}; + +struct operator_stats +{ + uint8_t stat; + String shortOp; + String longOp; + unsigned long numOp; + uint8_t act; +}; + +typedef struct ext_signal_quality_ { + unsigned int rxlev; + unsigned int ber; + unsigned int rscp; + unsigned int enc0; + unsigned int rsrq; + unsigned int rsrp; +} signal_quality; + +typedef enum +{ + SARA_R5_TCP = 6, + SARA_R5_UDP = 17 +} SARA_R5_socket_protocol_t; + +typedef enum +{ + SARA_R5_TCP_SOCKET_STATUS_INACTIVE, + SARA_R5_TCP_SOCKET_STATUS_LISTEN, + SARA_R5_TCP_SOCKET_STATUS_SYN_SENT, + SARA_R5_TCP_SOCKET_STATUS_SYN_RCVD, + SARA_R5_TCP_SOCKET_STATUS_ESTABLISHED, + SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_1, + SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_2, + SARA_R5_TCP_SOCKET_STATUS_CLOSE_WAIT, + SARA_R5_TCP_SOCKET_STATUS_CLOSING, + SARA_R5_TCP_SOCKET_STATUS_LAST_ACK, + SARA_R5_TCP_SOCKET_STATUS_TIME_WAIT +} SARA_R5_tcp_socket_status_t; + +typedef enum +{ + SARA_R5_MESSAGE_FORMAT_PDU = 0, + SARA_R5_MESSAGE_FORMAT_TEXT = 1 +} SARA_R5_message_format_t; + +typedef enum +{ + SARA_R5_UTIME_MODE_STOP = 0, + SARA_R5_UTIME_MODE_PPS, + SARA_R5_UTIME_MODE_ONE_SHOT, + SARA_R5_UTIME_MODE_EXT_INT +} SARA_R5_utime_mode_t; + +typedef enum +{ + SARA_R5_UTIME_SENSOR_NONE = 0, + SARA_R5_UTIME_SENSOR_GNSS_LTE = 1, + SARA_R5_UTIME_SENSOR_LTE +} SARA_R5_utime_sensor_t; + +typedef enum +{ + SARA_R5_UTIME_URC_CONFIGURATION_DISABLED = 0, + SARA_R5_UTIME_URC_CONFIGURATION_ENABLED +} SARA_R5_utime_urc_configuration_t; + +typedef enum +{ + SARA_R5_SIM_NOT_PRESENT = 0, + SARA_R5_SIM_PIN_NEEDED, + SARA_R5_SIM_PIN_BLOCKED, + SARA_R5_SIM_PUK_BLOCKED, + SARA_R5_SIM_NOT_OPERATIONAL, + SARA_R5_SIM_RESTRICTED, + SARA_R5_SIM_OPERATIONAL + //SARA_R5_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 + //SARA_R5_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 + //SARA_R5_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 + //SARA_R5_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 + //SARA_R5_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 + //SARA_R5_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 + //SARA_R5_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 +} SARA_R5_sim_states_t; + +#define SARA_R5_NUM_PSD_PROFILES 6 // Number of supported PSD profiles +#define SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS 11 // Number of supported PDP context identifiers +#define SARA_R5_NUM_HTTP_PROFILES 4 // Number of supported HTTP profiles + +typedef enum +{ + SARA_R5_HTTP_OP_CODE_SERVER_IP = 0, + SARA_R5_HTTP_OP_CODE_SERVER_NAME, + SARA_R5_HTTP_OP_CODE_USERNAME, + SARA_R5_HTTP_OP_CODE_PASSWORD, + SARA_R5_HTTP_OP_CODE_AUTHENTICATION, + SARA_R5_HTTP_OP_CODE_SERVER_PORT, + SARA_R5_HTTP_OP_CODE_SECURE, + SARA_R5_HTTP_OP_CODE_REQUEST_TIMEOUT, + SARA_R5_HTTP_OP_CODE_ADD_CUSTOM_HEADERS = 9 +} SARA_R5_http_op_codes_t; + +typedef enum +{ + SARA_R5_HTTP_COMMAND_HEAD = 0, + SARA_R5_HTTP_COMMAND_GET, + SARA_R5_HTTP_COMMAND_DELETE, + SARA_R5_HTTP_COMMAND_PUT, + SARA_R5_HTTP_COMMAND_POST_FILE, + SARA_R5_HTTP_COMMAND_POST_DATA, + SARA_R5_HTTP_COMMAND_GET_FOTA = 100 +} SARA_R5_http_commands_t; + +typedef enum +{ + SARA_R5_HTTP_CONTENT_APPLICATION_X_WWW = 0, + SARA_R5_HTTP_CONTENT_TEXT_PLAIN, + SARA_R5_HTTP_CONTENT_APPLICATION_OCTET, + SARA_R5_HTTP_CONTENT_MULTIPART_FORM, + SARA_R5_HTTP_CONTENT_APPLICATION_JSON, + SARA_R5_HTTP_CONTENT_APPLICATION_XML, + SARA_R5_HTTP_CONTENT_USER_DEFINED +} SARA_R5_http_content_types_t; + +typedef enum +{ + SARA_R5_MQTT_NV_RESTORE = 0, + SARA_R5_MQTT_NV_SET, + SARA_R5_MQTT_NV_STORE, +} SARA_R5_mqtt_nv_parameter_t; + +typedef enum +{ + SARA_R5_MQTT_PROFILE_CLIENT_ID = 0, + SARA_R5_MQTT_PROFILE_SERVERNAME = 2, + SARA_R5_MQTT_PROFILE_IPADDRESS, + SARA_R5_MQTT_PROFILE_USERNAMEPWD, + SARA_R5_MQTT_PROFILE_QOS = 6, + SARA_R5_MQTT_PROFILE_RETAIN, + SARA_R5_MQTT_PROFILE_TOPIC, + SARA_R5_MQTT_PROFILE_MESSAGE, + SARA_R5_MQTT_PROFILE_INACTIVITYTIMEOUT, + SARA_R5_MQTT_PROFILE_SECURE, +} SARA_R5_mqtt_profile_opcode_t; + +typedef enum +{ + SARA_R5_MQTT_COMMAND_INVALID = -1, + SARA_R5_MQTT_COMMAND_LOGOUT = 0, + SARA_R5_MQTT_COMMAND_LOGIN, + SARA_R5_MQTT_COMMAND_PUBLISH, + SARA_R5_MQTT_COMMAND_PUBLISHFILE, + SARA_R5_MQTT_COMMAND_SUBSCRIBE, + SARA_R5_MQTT_COMMAND_UNSUBSCRIBE, + SARA_R5_MQTT_COMMAND_READ, + SARA_R5_MQTT_COMMAND_RCVMSGFORMAT, + SARA_R5_MQTT_COMMAND_PING, + SARA_R5_MQTT_COMMAND_PUBLISHBINARY, +} SARA_R5_mqtt_command_opcode_t; + +constexpr uint16_t MAX_MQTT_HEX_MSG_LEN = 512; +constexpr uint16_t MAX_MQTT_DIRECT_MSG_LEN = 1024; + +typedef enum +{ + SARA_R5_FTP_PROFILE_IPADDRESS = 0, + SARA_R5_FTP_PROFILE_SERVERNAME, + SARA_R5_FTP_PROFILE_USERNAME, + SARA_R5_FTP_PROFILE_PWD, + SARA_R5_FTP_PROFILE_ACCOUNT, + SARA_R5_FTP_PROFILE_TIMEOUT, + SARA_R5_FTP_PROFILE_MODE +} SARA_R5_ftp_profile_opcode_t; + +typedef enum +{ + SARA_R5_FTP_COMMAND_INVALID = -1, + SARA_R5_FTP_COMMAND_LOGOUT = 0, + SARA_R5_FTP_COMMAND_LOGIN, + SARA_R5_FTP_COMMAND_DELETE_FILE, + SARA_R5_FTP_COMMAND_RENAME_FILE, + SARA_R5_FTP_COMMAND_GET_FILE, + SARA_R5_FTP_COMMAND_PUT_FILE, + SARA_R5_FTP_COMMAND_GET_FILE_DIRECT, + SARA_R5_FTP_COMMAND_PUT_FILE_DIRECT, + SARA_R5_FTP_COMMAND_CHANGE_DIR, + SARA_R5_FTP_COMMAND_MKDIR = 10, + SARA_R5_FTP_COMMAND_RMDIR, + SARA_R5_FTP_COMMAND_DIR_INFO = 13, + SARA_R5_FTP_COMMAND_LS, + SARA_R5_FTP_COMMAND_GET_FOTA_FILE = 100 +} SARA_R5_ftp_command_opcode_t; + +typedef enum +{ + SARA_R5_PSD_CONFIG_PARAM_PROTOCOL = 0, + SARA_R5_PSD_CONFIG_PARAM_APN, + //SARA_R5_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 + //SARA_R5_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 + SARA_R5_PSD_CONFIG_PARAM_DNS1 = 4, + SARA_R5_PSD_CONFIG_PARAM_DNS2, + //SARA_R5_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 + //SARA_R5_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 + //SARA_R5_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 + //SARA_R5_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 + SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID = 100 +} SARA_R5_pdp_configuration_parameter_t; + +typedef enum +{ + SARA_R5_PSD_PROTOCOL_IPV4 = 0, + SARA_R5_PSD_PROTOCOL_IPV6, + SARA_R5_PSD_PROTOCOL_IPV4V6_V4_PREF, + SARA_R5_PSD_PROTOCOL_IPV4V6_V6_PREF +} SARA_R5_pdp_protocol_type_t; + +typedef enum +{ + SARA_R5_PSD_ACTION_RESET = 0, + SARA_R5_PSD_ACTION_STORE, + SARA_R5_PSD_ACTION_LOAD, + SARA_R5_PSD_ACTION_ACTIVATE, + SARA_R5_PSD_ACTION_DEACTIVATE +} SARA_R5_pdp_actions_t; + +typedef enum +{ + SARA_R5_SEC_PROFILE_PARAM_CERT_VAL_LEVEL = 0, + SARA_R5_SEC_PROFILE_PARAM_TLS_VER, + SARA_R5_SEC_PROFILE_PARAM_CYPHER_SUITE, + SARA_R5_SEC_PROFILE_PARAM_ROOT_CA, + SARA_R5_SEC_PROFILE_PARAM_HOSTNAME, + SARA_R5_SEC_PROFILE_PARAM_CLIENT_CERT, + SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY, + SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY_PWD, + SARA_R5_SEC_PROFILE_PARAM_PSK, + SARA_R5_SEC_PROFILE_PARAM_PSK_IDENT, + SARA_R5_SEC_PROFILE_PARAM_SNI, +} SARA_R5_sec_profile_parameter_t; + +typedef enum +{ + SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_NO = 0, + SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL, + SARA_R5_SEC_PROFILE_CERVTAL_OPCODE_YESURL, + SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE, +} SARA_R5_sec_profile_certval_op_code_t; + +typedef enum +{ + SARA_R5_SEC_PROFILE_TLS_OPCODE_ANYVER = 0, + SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_0, + SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_1, + SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_2, + SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_3, +} SARA_R5_sec_profile_tls_op_code_t; + +typedef enum +{ + SARA_R5_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT = 0, +} SARA_R5_sec_profile_suite_op_code_t; + +typedef enum +{ + SARA_R5_SEC_MANAGER_OPCODE_IMPORT = 0, +} SARA_R5_sec_manager_opcode_t; + +typedef enum +{ + SARA_R5_SEC_MANAGER_ROOTCA = 0, + SARA_R5_SEC_MANAGER_CLIENT_CERT, + SARA_R5_SEC_MANAGER_CLIENT_KEY, + SARA_R5_SEC_MANAGER_SERVER_CERT +} SARA_R5_sec_manager_parameter_t; + +typedef enum +{ + MINIMUM_FUNCTIONALITY = 0, // (disable both transmit and receive RF circuits by deactivating both CS and PS services) + FULL_FUNCTIONALITY = 1, + AIRPLANE_MODE = 4, + SIM_TOOLKIT_ENABLE_DEDICATED = 6, + SIM_TOOLKIT_DISABLE_DEDICATED = 7, + SIM_TOOLKIT_ENABLE_RAW = 9, + FAST_SAFE_POWER_OFF = 10, + //SILENT_RESET_WITHOUT_SIM = 15, // Not supported on SARA-R5 + SILENT_RESET_WITH_SIM = 16 + //MINIMUM_FUNCTIONALITY = 19, // Not supported on SARA-R5 + //DEEP_LOW_POWER_STATE = 127 // Not supported on SARA-R5 +} SARA_R5_functionality_t; + +#endif //SPARKFUN_SARA_R5_ARDUINO_LIBRARY_H From a175f61b69a525fcfbabef8cbc85e07a49106839 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 15 Nov 2023 12:03:05 -0700 Subject: [PATCH 06/52] Add Example 1 - Device Identification Copied from original SARA-R5 library, and modified to work with new library. --- .../Example1_DeviceIdentification.ino | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino diff --git a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino new file mode 100644 index 0000000..5d223dc --- /dev/null +++ b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino @@ -0,0 +1,99 @@ +#include "SparkFun_u-blox_AT_Commands_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBLOX_AT myModule; // This example works with all modules, so the base class can be used +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +// Map SIM states to more readable strings +String simStateString[] = +{ + "Not present", // 0 + "PIN needed", // 1 + "PIN blocked", // 2 + "PUK blocked", // 3 + "Not operational", // 4 + "Restricted", // 5 + "Operational" // 6 +}; + +// processSIMstate is provided to the SARA-R5 library via a +// callback setter -- setSIMstateReadCallback. (See setup()) +void processSIMstate(UBLOX_AT_sim_states_t state) +{ + Serial.println(); + Serial.print(F("SIM state: ")); + Serial.print(String(state)); + Serial.println(); +} + +void begin() +{ + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("SARA-R5 Example")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + //myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Comment the next line if required + myModule.invertPowerPin(true); + + // Initialize the SARA + if (myModule.begin(mySerial, 9600) ) + { + Serial.println(F("SARA-R5 connected!")); + } + else + { + Serial.println(F("Unable to communicate with the SARA.")); + Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + Serial.println("Manufacturer ID: " + String(myModule.getManufacturerID())); + Serial.println("Model ID: " + String(myModule.getModelID())); + Serial.println("Firmware Version: " + String(myModule.getFirmwareVersion())); + Serial.println("Product Serial No.: " + String(myModule.getSerialNo())); + Serial.println("IMEI: " + String(myModule.getIMEI())); + Serial.println("IMSI: " + String(myModule.getIMSI())); + Serial.println("SIM CCID: " + String(myModule.getCCID())); + Serial.println("Subscriber No.: " + String(myModule.getSubscriberNo())); + Serial.println("Capabilities: " + String(myModule.getCapabilities())); + + // Set a callback to return the SIM state once requested + myModule.setSIMstateReportCallback(&processSIMstate); + // Now enable SIM state reporting for states 0 to 6 (by setting the reporting mode LSb) + if (myModule.setSIMstateReportingMode(1) == UBLOX_AT_SUCCESS) + Serial.println("SIM state reports requested..."); + // You can disable the SIM staus reports again by calling assetTracker.setSIMstateReportingMode(0) +} + +void loop() +{ + myModule.poll(); // Keep processing data from the SARA so we can extract the SIM status +} \ No newline at end of file From 40e4d0c9bcb314fc5cbf229ea877b278ce1d4593 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 15 Nov 2023 12:29:53 -0700 Subject: [PATCH 07/52] Remove duplicate items from original SARA-R5 header --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 117 ------------------ 1 file changed, 117 deletions(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h index 8d4d995..2ead05c 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -162,20 +162,6 @@ const char SARA_R5_RESPONSE_ERROR[] = "\nERROR\r\n"; const char SARA_R5_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; #define SARA_R5_RESPONSE_OK_OR_ERROR nullptr -// CTRL+Z and ESC ASCII codes for SMS message sends -const char ASCII_CTRL_Z = 0x1A; -const char ASCII_ESC = 0x1B; - -// NMEA data size - used by parseGPRMCString -#define TEMP_NMEA_DATA_SIZE 16 - -#define NOT_AT_COMMAND false -#define AT_COMMAND true - -// The minimum memory allocation for responses from sendCommandWithResponse -// This needs to be large enough to hold the response you're expecting plus and URC's that may arrive during the timeout -#define minimumResponseAllocation 128 - #define SARA_R5_NUM_SOCKETS 6 #define NUM_SUPPORTED_BAUD 6 @@ -197,33 +183,6 @@ typedef enum SARA_R5_ENABLE_FLOW_CONTROL = 3 } SARA_R5_flow_control_t; -// The standard Europe profile should be used as the basis for all other MNOs in Europe outside of Vodafone -// and Deutsche Telekom. However, there may be changes that need to be applied to the module for proper -// operation with any given European MNO such as attach type, RAT preference, band selection, etc. Please -// consult with the preferred network provider. -typedef enum -{ - MNO_INVALID = -1, - MNO_SW_DEFAULT = 0, // Undefined / regulatory - MNO_SIM_ICCID = 1, - MNO_ATT = 2, // AT&T - MNO_VERIZON = 3, - MNO_TELSTRA = 4, - MNO_TMO = 5, // T-Mobile US - MNO_CT = 6, // China Telecom - MNO_SPRINT = 8, - MNO_VODAFONE = 19, - MNO_NTT_DOCOMO = 20, - MNO_TELUS = 21, - MNO_SOFTBANK = 28, - MNO_DT = 31, // Deutsche Telekom - MNO_US_CELLULAR = 32, - MNO_SKT = 39, - MNO_GLOBAL = 90, - MNO_STD_EUROPE = 100, - MNO_STD_EU_NOEPCO = 101 -} mobile_network_operator_t; - typedef enum { SARA_R5_ERROR_INVALID = -1, // -1 @@ -255,64 +214,6 @@ typedef enum SARA_R5_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED = 10 } SARA_R5_registration_status_t; -struct DateData -{ - uint8_t day; - uint8_t month; - unsigned int year; -}; - -struct TimeData -{ - uint8_t hour; - uint8_t minute; - uint8_t second; - unsigned int ms; - uint8_t tzh; - uint8_t tzm; -}; - -struct ClockData -{ - struct DateData date; - struct TimeData time; -}; - -struct PositionData -{ - float utc; - float lat; // Degrees: +/- 90 - float lon; // Degrees: +/- 180 - float alt; - char mode; - char status; -}; - -struct SpeedData -{ - float speed; // m/s - float cog; // Degrees - float magVar; // Degrees -}; - -struct operator_stats -{ - uint8_t stat; - String shortOp; - String longOp; - unsigned long numOp; - uint8_t act; -}; - -typedef struct ext_signal_quality_ { - unsigned int rxlev; - unsigned int ber; - unsigned int rscp; - unsigned int enc0; - unsigned int rsrq; - unsigned int rsrp; -} signal_quality; - typedef enum { SARA_R5_TCP = 6, @@ -454,9 +355,6 @@ typedef enum SARA_R5_MQTT_COMMAND_PUBLISHBINARY, } SARA_R5_mqtt_command_opcode_t; -constexpr uint16_t MAX_MQTT_HEX_MSG_LEN = 512; -constexpr uint16_t MAX_MQTT_DIRECT_MSG_LEN = 1024; - typedef enum { SARA_R5_FTP_PROFILE_IPADDRESS = 0, @@ -569,19 +467,4 @@ typedef enum SARA_R5_SEC_MANAGER_SERVER_CERT } SARA_R5_sec_manager_parameter_t; -typedef enum -{ - MINIMUM_FUNCTIONALITY = 0, // (disable both transmit and receive RF circuits by deactivating both CS and PS services) - FULL_FUNCTIONALITY = 1, - AIRPLANE_MODE = 4, - SIM_TOOLKIT_ENABLE_DEDICATED = 6, - SIM_TOOLKIT_DISABLE_DEDICATED = 7, - SIM_TOOLKIT_ENABLE_RAW = 9, - FAST_SAFE_POWER_OFF = 10, - //SILENT_RESET_WITHOUT_SIM = 15, // Not supported on SARA-R5 - SILENT_RESET_WITH_SIM = 16 - //MINIMUM_FUNCTIONALITY = 19, // Not supported on SARA-R5 - //DEEP_LOW_POWER_STATE = 127 // Not supported on SARA-R5 -} SARA_R5_functionality_t; - #endif //SPARKFUN_SARA_R5_ARDUINO_LIBRARY_H From d87f14b8c4992841b6645f700050d6bff6deda2e Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 15 Nov 2023 12:56:18 -0700 Subject: [PATCH 08/52] Fix typo in Example 1 --- .../Example1_DeviceIdentification.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino index 5d223dc..6af0225 100644 --- a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino +++ b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino @@ -43,7 +43,7 @@ void processSIMstate(UBLOX_AT_sim_states_t state) Serial.println(); } -void begin() +void setup() { Serial.begin(115200); // Start the serial console From 37db6a8333ade98c89385b8078f5a00d126e9064 Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 17 Nov 2023 11:06:15 +0000 Subject: [PATCH 09/52] Update sfe_sara_r5.h --- src/sfe_sara_r5.h | 368 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 368 insertions(+) diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index c43b412..02626b4 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -3,6 +3,374 @@ #include "sfe_ublox_at_commands.h" +// RegEx Replace: \#define\sSARA\_R5\_([A-Z0-9_]+).* \#define SARA\_R5\_$+ UBLOX\_AT\_$+ + +#define SARA_R5_POWER_PIN -1 // Default to no pin +#define SARA_R5_RESET_PIN -1 + +// Timing +#define SARA_R5_STANDARD_RESPONSE_TIMEOUT 1000 +#define SARA_R5_10_SEC_TIMEOUT 10000 +#define SARA_R5_55_SECS_TIMEOUT 55000 +#define SARA_R5_2_MIN_TIMEOUT 120000 +#define SARA_R5_3_MIN_TIMEOUT 180000 +#define SARA_R5_SET_BAUD_TIMEOUT 500 +#define SARA_R5_POWER_OFF_PULSE_PERIOD 3200 // Hold PWR_ON low for this long to power the module off +#define SARA_R5_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) +#define SARA_R5_RESET_PULSE_PERIOD 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) +#define SARA_R5_POWER_OFF_TIMEOUT 40000 // Datasheet says 40 seconds... +#define SARA_R5_IP_CONNECT_TIMEOUT 130000 +#define SARA_R5_POLL_DELAY 1 +#define SARA_R5_SOCKET_WRITE_TIMEOUT 10000 + +// ## Suported AT Commands +// ### General +const char SARA_R5_COMMAND_AT[] = "AT"; // AT "Test" +const char SARA_R5_COMMAND_ECHO[] = "E"; // Local Echo +const char SARA_R5_COMMAND_MANU_ID[] = "+CGMI"; // Manufacturer identification +const char SARA_R5_COMMAND_MODEL_ID[] = "+CGMM"; // Model identification +const char SARA_R5_COMMAND_FW_VER_ID[] = "+CGMR"; // Firmware version identification +const char SARA_R5_COMMAND_SERIAL_NO[] = "+CGSN"; // Product serial number +const char SARA_R5_COMMAND_IMEI[] = "+GSN"; // IMEI identification +const char SARA_R5_COMMAND_IMSI[] = "+CIMI"; // IMSI identification +const char SARA_R5_COMMAND_CCID[] = "+CCID"; // SIM CCID +const char SARA_R5_COMMAND_REQ_CAP[] = "+GCAP"; // Request capabilities list +// ### Control and status +const char SARA_R5_COMMAND_POWER_OFF[] = "+CPWROFF"; // Module switch off +const char SARA_R5_COMMAND_FUNC[] = "+CFUN"; // Functionality (reset, etc.) +const char SARA_R5_COMMAND_CLOCK[] = "+CCLK"; // Real-time clock +const char SARA_R5_COMMAND_AUTO_TZ[] = "+CTZU"; // Automatic time zone update +const char SARA_R5_COMMAND_TZ_REPORT[] = "+CTZR"; // Time zone reporting +// ### Network service +const char SARA_R5_COMMAND_CNUM[] = "+CNUM"; // Subscriber number +const char SARA_R5_SIGNAL_QUALITY[] = "+CSQ"; +const char SARA_R5_EXT_SIGNAL_QUALITY[] = "+CESQ"; +const char SARA_R5_OPERATOR_SELECTION[] = "+COPS"; +const char SARA_R5_REGISTRATION_STATUS[] = "+CREG"; +const char SARA_R5_EPSREGISTRATION_STATUS[] = "+CEREG"; +const char SARA_R5_READ_OPERATOR_NAMES[] = "+COPN"; +const char SARA_R5_COMMAND_MNO[] = "+UMNOPROF"; // MNO (mobile network operator) Profile +// ### SIM +const char SARA_R5_SIM_STATE[] = "+USIMSTAT"; +const char SARA_R5_COMMAND_SIMPIN[] = "+CPIN"; // SIM PIN +// ### SMS +const char SARA_R5_MESSAGE_FORMAT[] = "+CMGF"; // Set SMS message format +const char SARA_R5_SEND_TEXT[] = "+CMGS"; // Send SMS message +const char SARA_R5_NEW_MESSAGE_IND[] = "+CNMI"; // New [SMS] message indication +const char SARA_R5_PREF_MESSAGE_STORE[] = "+CPMS"; // Preferred message storage +const char SARA_R5_READ_TEXT_MESSAGE[] = "+CMGR"; // Read message +const char SARA_R5_DELETE_MESSAGE[] = "+CMGD"; // Delete message +// V24 control and V25ter (UART interface) +const char SARA_R5_FLOW_CONTROL[] = "&K"; // Flow control +const char SARA_R5_COMMAND_BAUD[] = "+IPR"; // Baud rate +// ### Packet switched data services +const char SARA_R5_MESSAGE_PDP_DEF[] = "+CGDCONT"; // Packet switched Data Profile context definition +const char SARA_R5_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration +const char SARA_R5_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile +const char SARA_R5_MESSAGE_PDP_CONTEXT_ACTIVATE[] = "+CGACT"; // Activates or deactivates the specified PDP context +const char SARA_R5_MESSAGE_ENTER_PPP[] = "D"; +const char SARA_R5_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data +// ### GPIO +const char SARA_R5_COMMAND_GPIO[] = "+UGPIOC"; // GPIO Configuration +// ### IP +const char SARA_R5_CREATE_SOCKET[] = "+USOCR"; // Create a new socket +const char SARA_R5_CLOSE_SOCKET[] = "+USOCL"; // Close a socket +const char SARA_R5_CONNECT_SOCKET[] = "+USOCO"; // Connect to server on socket +const char SARA_R5_WRITE_SOCKET[] = "+USOWR"; // Write data to a socket +const char SARA_R5_WRITE_UDP_SOCKET[] = "+USOST"; // Write data to a UDP socket +const char SARA_R5_READ_SOCKET[] = "+USORD"; // Read from a socket +const char SARA_R5_READ_UDP_SOCKET[] = "+USORF"; // Read UDP data from a socket +const char SARA_R5_LISTEN_SOCKET[] = "+USOLI"; // Listen for connection on socket +const char SARA_R5_GET_ERROR[] = "+USOER"; // Get last socket error. +const char SARA_R5_SOCKET_DIRECT_LINK[] = "+USODL"; // Set socket in Direct Link mode +const char SARA_R5_SOCKET_CONTROL[] = "+USOCTL"; // Query the socket parameters +const char SARA_R5_UD_CONFIGURATION[] = "+UDCONF"; // User Datagram Configuration +// ### Ping +const char SARA_R5_PING_COMMAND[] = "+UPING"; // Ping +// ### HTTP +const char SARA_R5_HTTP_PROFILE[] = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined +const char SARA_R5_HTTP_COMMAND[] = "+UHTTPC"; // Trigger the specified HTTP command +const char SARA_R5_HTTP_PROTOCOL_ERROR[] = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. + +const char SARA_R5_MQTT_NVM[] = "+UMQTTNV"; +const char SARA_R5_MQTT_PROFILE[] = "+UMQTT"; +const char SARA_R5_MQTT_COMMAND[] = "+UMQTTC"; +const char SARA_R5_MQTT_PROTOCOL_ERROR[] = "+UMQTTER"; +// ### FTP +const char SARA_R5_FTP_PROFILE[] = "+UFTP"; +const char SARA_R5_FTP_COMMAND[] = "+UFTPC"; +const char SARA_R5_FTP_PROTOCOL_ERROR[] = "+UFTPER"; +// ### GNSS +const char SARA_R5_GNSS_POWER[] = "+UGPS"; // GNSS power management configuration +const char SARA_R5_GNSS_ASSISTED_IND[] = "+UGIND"; // Assisted GNSS unsolicited indication +const char SARA_R5_GNSS_REQUEST_LOCATION[] = "+ULOC"; // Ask for localization information +const char SARA_R5_GNSS_GPRMC[] = "+UGRMC"; // Ask for localization information +const char SARA_R5_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) +const char SARA_R5_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication +const char SARA_R5_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration +const char SARA_R5_GNSS_CONFIGURE_SENSOR[] = "+ULOCGNSS"; // Configure GNSS sensor +const char SARA_R5_GNSS_CONFIGURE_LOCATION[] = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) +const char SARA_R5_AIDING_SERVER_CONFIGURATION[] = "+UGSRV"; // Configure aiding server (CellLocate®) +// ### File System +// TO DO: Add support for file tags. Default tag to USER +const char SARA_R5_FILE_SYSTEM_READ_FILE[] = "+URDFILE"; // Read a file +const char SARA_R5_FILE_SYSTEM_READ_BLOCK[] = "+URDBLOCK"; // Read a block from a file +const char SARA_R5_FILE_SYSTEM_DOWNLOAD_FILE[] = "+UDWNFILE"; // Download a file into the module +const char SARA_R5_FILE_SYSTEM_LIST_FILES[] = "+ULSTFILE"; // List of files, size of file, etc. +const char SARA_R5_FILE_SYSTEM_DELETE_FILE[] = "+UDELFILE"; // Delete a file +// ### File System +// TO DO: Add support for file tags. Default tag to USER +const char SARA_R5_SEC_PROFILE[] = "+USECPRF"; +const char SARA_R5_SEC_MANAGER[] = "+USECMNG"; + + +// ### URC strings +const char SARA_R5_READ_SOCKET_URC[] = "+UUSORD:"; +const char SARA_R5_READ_UDP_SOCKET_URC[] = "+UUSORF:"; +const char SARA_R5_LISTEN_SOCKET_URC[] = "+UUSOLI:"; +const char SARA_R5_CLOSE_SOCKET_URC[] = "+UUSOCL:"; +const char SARA_R5_GNSS_REQUEST_LOCATION_URC[] = "+UULOC:"; +const char SARA_R5_SIM_STATE_URC[] = "+UUSIMSTAT:"; +const char SARA_R5_MESSAGE_PDP_ACTION_URC[] = "+UUPSDA:"; +const char SARA_R5_HTTP_COMMAND_URC[] = "+UUHTTPCR:"; +const char SARA_R5_MQTT_COMMAND_URC[] = "+UUMQTTC:"; +const char SARA_R5_PING_COMMAND_URC[] = "+UUPING:"; +const char SARA_R5_REGISTRATION_STATUS_URC[] = "+CREG:"; +const char SARA_R5_EPSREGISTRATION_STATUS_URC[] = "+CEREG:"; +const char SARA_R5_FTP_COMMAND_URC[] = "+UUFTPCR:"; + +// ### Response +const char SARA_R5_RESPONSE_MORE[] = "\n>"; +const char SARA_R5_RESPONSE_OK[] = "\nOK\r\n"; +const char SARA_R5_RESPONSE_ERROR[] = "\nERROR\r\n"; +const char SARA_R5_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; +#define SARA_R5_RESPONSE_OK_OR_ERROR nullptr + +#define SARA_R5_NUM_SOCKETS 6 + +#define SARA_R5_NUM_SUPPORTED_BAUD 6 +const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = + { + 115200, + 9600, + 19200, + 38400, + 57600, + 230400}; +#define SARA_R5_DEFAULT_BAUD_RATE 115200 + +// Flow control definitions for AT&K +// Note: SW (XON/XOFF) flow control is not supported on the SARA_R5 +#define SARA_R5_DISABLE_FLOW_CONTROL UBLOX_AT_DISABLE_FLOW_CONTROL +#define SARA_R5_ENABLE_FLOW_CONTROL UBLOX_AT_ENABLE_FLOW_CONTROL + +#define SARA_R5_ERROR_INVALID UBLOX_AT_ERROR_INVALID +#define SARA_R5_ERROR_SUCCESS UBLOX_AT_ERROR_SUCCESS +#define SARA_R5_ERROR_OUT_OF_MEMORY UBLOX_AT_ERROR_OUT_OF_MEMORY +#define SARA_R5_ERROR_TIMEOUT UBLOX_AT_ERROR_TIMEOUT +#define SARA_R5_ERROR_UNEXPECTED_PARAM UBLOX_AT_ERROR_UNEXPECTED_PARAM +#define SARA_R5_ERROR_UNEXPECTED_RESPONSE UBLOX_AT_ERROR_UNEXPECTED_RESPONSE +#define SARA_R5_ERROR_NO_RESPONSE UBLOX_AT_ERROR_NO_RESPONSE +#define SARA_R5_ERROR_DEREGISTERED UBLOX_AT_ERROR_DEREGISTERED +#define SARA_R5_ERROR_ZERO_READ_LENGTH UBLOX_AT_ERROR_ZERO_READ_LENGTH +#define SARA_R5_ERROR_ERROR UBLOX_AT_ERROR_ERROR +#define SARA_R5_SUCCESS SARA_R5_ERROR_SUCCESS + +#define SARA_R5_REGISTRATION_INVALID UBLOX_AT_REGISTRATION_INVALID +#define SARA_R5_REGISTRATION_NOT_REGISTERED UBLOX_AT_REGISTRATION_NOT_REGISTERED +#define SARA_R5_REGISTRATION_HOME UBLOX_AT_REGISTRATION_HOME +#define SARA_R5_REGISTRATION_SEARCHING UBLOX_AT_REGISTRATION_SEARCHING +#define SARA_R5_REGISTRATION_DENIED UBLOX_AT_REGISTRATION_DENIED +#define SARA_R5_REGISTRATION_UNKNOWN UBLOX_AT_REGISTRATION_UNKNOWN +#define SARA_R5_REGISTRATION_ROAMING UBLOX_AT_REGISTRATION_ROAMING +#define SARA_R5_REGISTRATION_HOME_SMS_ONLY UBLOX_AT_REGISTRATION_HOME_SMS_ONLY +#define SARA_R5_REGISTRATION_ROAMING_SMS_ONLY UBLOX_AT_REGISTRATION_ROAMING_SMS_ONLY +#define SARA_R5_REGISTRATION_EMERGENCY_SERV_ONLY UBLOX_AT_REGISTRATION_EMERGENCY_SERV_ONLY +#define SARA_R5_REGISTRATION_HOME_CSFB_NOT_PREFERRED UBLOX_AT_REGISTRATION_HOME_CSFB_NOT_PREFERRED +#define SARA_R5_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED UBLOX_AT_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED + +#define SARA_R5_TCP UBLOX_AT_TCP +#define SARA_R5_UDP UBLOX_AT_UDP + +#define SARA_R5_TCP_SOCKET_STATUS_INACTIVE UBLOX_AT_TCP_SOCKET_STATUS_INACTIVE +#define SARA_R5_TCP_SOCKET_STATUS_LISTEN UBLOX_AT_TCP_SOCKET_STATUS_LISTEN +#define SARA_R5_TCP_SOCKET_STATUS_SYN_SENT UBLOX_AT_TCP_SOCKET_STATUS_SYN_SENT +#define SARA_R5_TCP_SOCKET_STATUS_SYN_RCVD UBLOX_AT_TCP_SOCKET_STATUS_SYN_RCVD +#define SARA_R5_TCP_SOCKET_STATUS_ESTABLISHED UBLOX_AT_TCP_SOCKET_STATUS_ESTABLISHED +#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_1 UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_1 +#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_2 UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_2 +#define SARA_R5_TCP_SOCKET_STATUS_CLOSE_WAIT UBLOX_AT_TCP_SOCKET_STATUS_CLOSE_WAIT +#define SARA_R5_TCP_SOCKET_STATUS_CLOSING UBLOX_AT_TCP_SOCKET_STATUS_CLOSING +#define SARA_R5_TCP_SOCKET_STATUS_LAST_ACK UBLOX_AT_TCP_SOCKET_STATUS_LAST_ACK +#define SARA_R5_TCP_SOCKET_STATUS_TIME_WAIT UBLOX_AT_TCP_SOCKET_STATUS_TIME_WAIT + +#define SARA_R5_MESSAGE_FORMAT_PDU UBLOX_AT_MESSAGE_FORMAT_PDU +#define SARA_R5_MESSAGE_FORMAT_TEXT UBLOX_AT_MESSAGE_FORMAT_TEXT + +#define SARA_R5_UTIME_MODE_STOP UBLOX_AT_UTIME_MODE_STOP +#define SARA_R5_UTIME_MODE_PPS UBLOX_AT_UTIME_MODE_PPS +#define SARA_R5_UTIME_MODE_ONE_SHOT UBLOX_AT_UTIME_MODE_ONE_SHOT +#define SARA_R5_UTIME_MODE_EXT_INT UBLOX_AT_UTIME_MODE_EXT_INT + +#define SARA_R5_UTIME_SENSOR_NONE UBLOX_AT_UTIME_SENSOR_NONE +#define SARA_R5_UTIME_SENSOR_GNSS_LTE UBLOX_AT_UTIME_SENSOR_GNSS_LTE +#define SARA_R5_UTIME_SENSOR_LTE UBLOX_AT_UTIME_SENSOR_LTE + +#define SARA_R5_UTIME_URC_CONFIGURATION_DISABLED UBLOX_AT_UTIME_URC_CONFIGURATION_DISABLED +#define SARA_R5_UTIME_URC_CONFIGURATION_ENABLED UBLOX_AT_UTIME_URC_CONFIGURATION_ENABLED + +#define SARA_R5_SIM_NOT_PRESENT UBLOX_AT_SIM_NOT_PRESENT +#define SARA_R5_SIM_PIN_NEEDED UBLOX_AT_SIM_PIN_NEEDED +#define SARA_R5_SIM_PIN_BLOCKED UBLOX_AT_SIM_PIN_BLOCKED +#define SARA_R5_SIM_PUK_BLOCKED UBLOX_AT_SIM_PUK_BLOCKED +#define SARA_R5_SIM_NOT_OPERATIONAL UBLOX_AT_SIM_NOT_OPERATIONAL +#define SARA_R5_SIM_RESTRICTED UBLOX_AT_SIM_RESTRICTED +#define SARA_R5_SIM_OPERATIONAL UBLOX_AT_SIM_OPERATIONAL +//SARA_R5_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 +//SARA_R5_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 +//SARA_R5_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 +//SARA_R5_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 +//SARA_R5_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 +//SARA_R5_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 +//SARA_R5_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 + +#define SARA_R5_NUM_PSD_PROFILES 6 // Number of supported PSD profiles +#define SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS 11 // Number of supported PDP context identifiers +#define SARA_R5_NUM_HTTP_PROFILES 4 // Number of supported HTTP profiles + +#define SARA_R5_HTTP_OP_CODE_SERVER_IP UBLOX_AT_HTTP_OP_CODE_SERVER_IP +#define SARA_R5_HTTP_OP_CODE_SERVER_NAME UBLOX_AT_HTTP_OP_CODE_SERVER_NAME +#define SARA_R5_HTTP_OP_CODE_USERNAME UBLOX_AT_HTTP_OP_CODE_USERNAME +#define SARA_R5_HTTP_OP_CODE_PASSWORD UBLOX_AT_HTTP_OP_CODE_PASSWORD +#define SARA_R5_HTTP_OP_CODE_AUTHENTICATION UBLOX_AT_HTTP_OP_CODE_AUTHENTICATION +#define SARA_R5_HTTP_OP_CODE_SERVER_PORT UBLOX_AT_HTTP_OP_CODE_SERVER_PORT +#define SARA_R5_HTTP_OP_CODE_SECURE UBLOX_AT_HTTP_OP_CODE_SECURE +#define SARA_R5_HTTP_OP_CODE_REQUEST_TIMEOUT UBLOX_AT_HTTP_OP_CODE_REQUEST_TIMEOUT +#define SARA_R5_HTTP_OP_CODE_ADD_CUSTOM_HEADERS UBLOX_AT_HTTP_OP_CODE_ADD_CUSTOM_HEADERS + +#define SARA_R5_HTTP_COMMAND_HEAD UBLOX_AT_HTTP_COMMAND_HEAD +#define SARA_R5_HTTP_COMMAND_GET UBLOX_AT_HTTP_COMMAND_GET +#define SARA_R5_HTTP_COMMAND_DELETE UBLOX_AT_HTTP_COMMAND_DELETE +#define SARA_R5_HTTP_COMMAND_PUT UBLOX_AT_HTTP_COMMAND_PUT +#define SARA_R5_HTTP_COMMAND_POST_FILE UBLOX_AT_HTTP_COMMAND_POST_FILE +#define SARA_R5_HTTP_COMMAND_POST_DATA UBLOX_AT_HTTP_COMMAND_POST_DATA +#define SARA_R5_HTTP_COMMAND_GET_FOTA UBLOX_AT_HTTP_COMMAND_GET_FOTA + +#define SARA_R5_HTTP_CONTENT_APPLICATION_X_WWW UBLOX_AT_HTTP_CONTENT_APPLICATION_X_WWW +#define SARA_R5_HTTP_CONTENT_TEXT_PLAIN UBLOX_AT_HTTP_CONTENT_TEXT_PLAIN +#define SARA_R5_HTTP_CONTENT_APPLICATION_OCTET UBLOX_AT_HTTP_CONTENT_APPLICATION_OCTET +#define SARA_R5_HTTP_CONTENT_MULTIPART_FORM UBLOX_AT_HTTP_CONTENT_MULTIPART_FORM +#define SARA_R5_HTTP_CONTENT_APPLICATION_JSON UBLOX_AT_HTTP_CONTENT_APPLICATION_JSON +#define SARA_R5_HTTP_CONTENT_APPLICATION_XML UBLOX_AT_HTTP_CONTENT_APPLICATION_XML +#define SARA_R5_HTTP_CONTENT_USER_DEFINED UBLOX_AT_HTTP_CONTENT_USER_DEFINED + +#define SARA_R5_MQTT_NV_RESTORE UBLOX_AT_MQTT_NV_RESTORE +#define SARA_R5_MQTT_NV_SET UBLOX_AT_MQTT_NV_SET +#define SARA_R5_MQTT_NV_STORE UBLOX_AT_MQTT_NV_STORE + +#define SARA_R5_MQTT_PROFILE_CLIENT_ID UBLOX_AT_MQTT_PROFILE_CLIENT_ID +#define SARA_R5_MQTT_PROFILE_SERVERNAME UBLOX_AT_MQTT_PROFILE_SERVERNAME +#define SARA_R5_MQTT_PROFILE_IPADDRESS UBLOX_AT_MQTT_PROFILE_IPADDRESS +#define SARA_R5_MQTT_PROFILE_USERNAMEPWD UBLOX_AT_MQTT_PROFILE_USERNAMEPWD +#define SARA_R5_MQTT_PROFILE_QOS UBLOX_AT_MQTT_PROFILE_QOS +#define SARA_R5_MQTT_PROFILE_RETAIN UBLOX_AT_MQTT_PROFILE_RETAIN +#define SARA_R5_MQTT_PROFILE_TOPIC UBLOX_AT_MQTT_PROFILE_TOPIC +#define SARA_R5_MQTT_PROFILE_MESSAGE UBLOX_AT_MQTT_PROFILE_MESSAGE +#define SARA_R5_MQTT_PROFILE_INACTIVITYTIMEOUT UBLOX_AT_MQTT_PROFILE_INACTIVITYTIMEOUT +#define SARA_R5_MQTT_PROFILE_SECURE UBLOX_AT_MQTT_PROFILE_SECURE + +#define SARA_R5_MQTT_COMMAND_INVALID UBLOX_AT_MQTT_COMMAND_INVALID +#define SARA_R5_MQTT_COMMAND_LOGOUT UBLOX_AT_MQTT_COMMAND_LOGOUT +#define SARA_R5_MQTT_COMMAND_LOGIN UBLOX_AT_MQTT_COMMAND_LOGIN +#define SARA_R5_MQTT_COMMAND_PUBLISH UBLOX_AT_MQTT_COMMAND_PUBLISH +#define SARA_R5_MQTT_COMMAND_PUBLISHFILE UBLOX_AT_MQTT_COMMAND_PUBLISHFILE +#define SARA_R5_MQTT_COMMAND_SUBSCRIBE UBLOX_AT_MQTT_COMMAND_SUBSCRIBE +#define SARA_R5_MQTT_COMMAND_UNSUBSCRIBE UBLOX_AT_MQTT_COMMAND_UNSUBSCRIBE +#define SARA_R5_MQTT_COMMAND_READ UBLOX_AT_MQTT_COMMAND_READ +#define SARA_R5_MQTT_COMMAND_RCVMSGFORMAT UBLOX_AT_MQTT_COMMAND_RCVMSGFORMAT +#define SARA_R5_MQTT_COMMAND_PING UBLOX_AT_MQTT_COMMAND_PING +#define SARA_R5_MQTT_COMMAND_PUBLISHBINARY UBLOX_AT_MQTT_COMMAND_PUBLISHBINARY + +#define SARA_R5_FTP_PROFILE_IPADDRESS UBLOX_AT_FTP_PROFILE_IPADDRESS +#define SARA_R5_FTP_PROFILE_SERVERNAME UBLOX_AT_FTP_PROFILE_SERVERNAME +#define SARA_R5_FTP_PROFILE_USERNAME UBLOX_AT_FTP_PROFILE_USERNAME +#define SARA_R5_FTP_PROFILE_PWD UBLOX_AT_FTP_PROFILE_PWD +#define SARA_R5_FTP_PROFILE_ACCOUNT UBLOX_AT_FTP_PROFILE_ACCOUNT +#define SARA_R5_FTP_PROFILE_TIMEOUT UBLOX_AT_FTP_PROFILE_TIMEOUT +#define SARA_R5_FTP_PROFILE_MODE UBLOX_AT_FTP_PROFILE_MODE + +#define SARA_R5_FTP_COMMAND_INVALID UBLOX_AT_FTP_COMMAND_INVALID +#define SARA_R5_FTP_COMMAND_LOGOUT UBLOX_AT_FTP_COMMAND_LOGOUT +#define SARA_R5_FTP_COMMAND_LOGIN UBLOX_AT_FTP_COMMAND_LOGIN +#define SARA_R5_FTP_COMMAND_DELETE_FILE UBLOX_AT_FTP_COMMAND_DELETE_FILE +#define SARA_R5_FTP_COMMAND_RENAME_FILE UBLOX_AT_FTP_COMMAND_RENAME_FILE +#define SARA_R5_FTP_COMMAND_GET_FILE UBLOX_AT_FTP_COMMAND_GET_FILE +#define SARA_R5_FTP_COMMAND_PUT_FILE UBLOX_AT_FTP_COMMAND_PUT_FILE +#define SARA_R5_FTP_COMMAND_GET_FILE_DIRECT UBLOX_AT_FTP_COMMAND_GET_FILE_DIRECT +#define SARA_R5_FTP_COMMAND_PUT_FILE_DIRECT UBLOX_AT_FTP_COMMAND_PUT_FILE_DIRECT +#define SARA_R5_FTP_COMMAND_CHANGE_DIR UBLOX_AT_FTP_COMMAND_CHANGE_DIR +#define SARA_R5_FTP_COMMAND_MKDIR UBLOX_AT_FTP_COMMAND_MKDIR +#define SARA_R5_FTP_COMMAND_RMDIR UBLOX_AT_FTP_COMMAND_RMDIR +#define SARA_R5_FTP_COMMAND_DIR_INFO UBLOX_AT_FTP_COMMAND_DIR_INFO +#define SARA_R5_FTP_COMMAND_LS UBLOX_AT_FTP_COMMAND_LS +#define SARA_R5_FTP_COMMAND_GET_FOTA_FILE UBLOX_AT_FTP_COMMAND_GET_FOTA_FILE + +#define SARA_R5_PSD_CONFIG_PARAM_PROTOCOL UBLOX_AT_PSD_CONFIG_PARAM_PROTOCOL +#define SARA_R5_PSD_CONFIG_PARAM_APN UBLOX_AT_PSD_CONFIG_PARAM_APN +//SARA_R5_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 +//SARA_R5_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 +#define SARA_R5_PSD_CONFIG_PARAM_DNS1 UBLOX_AT_PSD_CONFIG_PARAM_DNS1 +#define SARA_R5_PSD_CONFIG_PARAM_DNS2 UBLOX_AT_PSD_CONFIG_PARAM_DNS2 +//SARA_R5_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 +//SARA_R5_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 +//SARA_R5_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 +//SARA_R5_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 +#define SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID UBLOX_AT_PSD_CONFIG_PARAM_MAP_TO_CID + +#define SARA_R5_PSD_PROTOCOL_IPV4 UBLOX_AT_PSD_PROTOCOL_IPV4 +#define SARA_R5_PSD_PROTOCOL_IPV6 UBLOX_AT_PSD_PROTOCOL_IPV6 +#define SARA_R5_PSD_PROTOCOL_IPV4V6_V4_PREF UBLOX_AT_PSD_PROTOCOL_IPV4V6_V4_PREF +#define SARA_R5_PSD_PROTOCOL_IPV4V6_V6_PREF UBLOX_AT_PSD_PROTOCOL_IPV4V6_V6_PREF + +#define SARA_R5_PSD_ACTION_RESET UBLOX_AT_PSD_ACTION_RESET +#define SARA_R5_PSD_ACTION_STORE UBLOX_AT_PSD_ACTION_STORE +#define SARA_R5_PSD_ACTION_LOAD UBLOX_AT_PSD_ACTION_LOAD +#define SARA_R5_PSD_ACTION_ACTIVATE UBLOX_AT_PSD_ACTION_ACTIVATE +#define SARA_R5_PSD_ACTION_DEACTIVATE UBLOX_AT_PSD_ACTION_DEACTIVATE + +#define SARA_R5_SEC_PROFILE_PARAM_CERT_VAL_LEVEL UBLOX_AT_SEC_PROFILE_PARAM_CERT_VAL_LEVEL +#define SARA_R5_SEC_PROFILE_PARAM_TLS_VER UBLOX_AT_SEC_PROFILE_PARAM_TLS_VER +#define SARA_R5_SEC_PROFILE_PARAM_CYPHER_SUITE UBLOX_AT_SEC_PROFILE_PARAM_CYPHER_SUITE +#define SARA_R5_SEC_PROFILE_PARAM_ROOT_CA UBLOX_AT_SEC_PROFILE_PARAM_ROOT_CA +#define SARA_R5_SEC_PROFILE_PARAM_HOSTNAME UBLOX_AT_SEC_PROFILE_PARAM_HOSTNAME +#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_CERT UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_CERT +#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY +#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY_PWD UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY_PWD +#define SARA_R5_SEC_PROFILE_PARAM_PSK UBLOX_AT_SEC_PROFILE_PARAM_PSK +#define SARA_R5_SEC_PROFILE_PARAM_PSK_IDENT UBLOX_AT_SEC_PROFILE_PARAM_PSK_IDENT +#define SARA_R5_SEC_PROFILE_PARAM_SNI UBLOX_AT_SEC_PROFILE_PARAM_SNI + +#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_NO UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_NO +#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL +#define SARA_R5_SEC_PROFILE_CERVTAL_OPCODE_YESURL UBLOX_AT_SEC_PROFILE_CERVTAL_OPCODE_YESURL +#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE + +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_ANYVER UBLOX_AT_SEC_PROFILE_TLS_OPCODE_ANYVER +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_0 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_0 +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_1 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_1 +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_2 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_2 +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_3 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_3 + +#define SARA_R5_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT UBLOX_AT_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT + +#define SARA_R5_SEC_MANAGER_OPCODE_IMPORT UBLOX_AT_SEC_MANAGER_OPCODE_IMPORT + +#define SARA_R5_SEC_MANAGER_ROOTCA UBLOX_AT_SEC_MANAGER_ROOTCA +#define SARA_R5_SEC_MANAGER_CLIENT_CERT UBLOX_AT_SEC_MANAGER_CLIENT_CERT +#define SARA_R5_SEC_MANAGER_CLIENT_KEY UBLOX_AT_SEC_MANAGER_CLIENT_KEY +#define SARA_R5_SEC_MANAGER_SERVER_CERT UBLOX_AT_SEC_MANAGER_SERVER_CERT + + // Base SARA-R5 class class SARA_R5: public UBLOX_AT { From 058c38a236c7a2e8f024a53ab9c6cc159c2ce50b Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Fri, 17 Nov 2023 10:59:58 -0700 Subject: [PATCH 10/52] Rename files from "AT Commands" to "Cellular" --- .../Example1_DeviceIdentification.ino | 2 +- ...ino_Library.h => SparkFun_u-blox_Cellular_Arduino_Library.h} | 2 +- src/sfe_lara_r6.h | 2 +- src/sfe_sara_r5.h | 2 +- src/{sfe_ublox_at_commands.cpp => sfe_ublox_cellular.cpp} | 2 +- src/{sfe_ublox_at_commands.h => sfe_ublox_cellular.h} | 0 6 files changed, 5 insertions(+), 5 deletions(-) rename src/{SparkFun_u-blox_AT_Commands_Arduino_Library.h => SparkFun_u-blox_Cellular_Arduino_Library.h} (58%) rename src/{sfe_ublox_at_commands.cpp => sfe_ublox_cellular.cpp} (99%) rename src/{sfe_ublox_at_commands.h => sfe_ublox_cellular.h} (100%) diff --git a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino index 6af0225..a33751a 100644 --- a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino +++ b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino @@ -1,4 +1,4 @@ -#include "SparkFun_u-blox_AT_Commands_Arduino_Library.h" +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" // Uncomment the line below that you need for Serial on your platform #define mySerial Serial1 diff --git a/src/SparkFun_u-blox_AT_Commands_Arduino_Library.h b/src/SparkFun_u-blox_Cellular_Arduino_Library.h similarity index 58% rename from src/SparkFun_u-blox_AT_Commands_Arduino_Library.h rename to src/SparkFun_u-blox_Cellular_Arduino_Library.h index 0ebb8e3..a5b2243 100644 --- a/src/SparkFun_u-blox_AT_Commands_Arduino_Library.h +++ b/src/SparkFun_u-blox_Cellular_Arduino_Library.h @@ -1,3 +1,3 @@ -#include "sfe_ublox_at_commands.h" +#include "sfe_ublox_cellular.h" #include "sfe_sara_r5.h" #include "sfe_lara_r6.h" diff --git a/src/sfe_lara_r6.h b/src/sfe_lara_r6.h index 438edff..548583d 100644 --- a/src/sfe_lara_r6.h +++ b/src/sfe_lara_r6.h @@ -1,7 +1,7 @@ #ifndef SFE_LARA_R6_LIBRARY_H #define SFE_LARA_R6_LIBRARY_H -#include "sfe_ublox_at_commands.h" +#include "sfe_ublox_cellular.h" // Base LARA-R6 class class LARA_R6: public UBLOX_AT diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index c43b412..cba6df8 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -1,7 +1,7 @@ #ifndef SFE_SARA_R5_LIBRARY_H #define SFE_SARA_R5_LIBRARY_H -#include "sfe_ublox_at_commands.h" +#include "sfe_ublox_cellular.h" // Base SARA-R5 class class SARA_R5: public UBLOX_AT diff --git a/src/sfe_ublox_at_commands.cpp b/src/sfe_ublox_cellular.cpp similarity index 99% rename from src/sfe_ublox_at_commands.cpp rename to src/sfe_ublox_cellular.cpp index 1499bee..a6646aa 100644 --- a/src/sfe_ublox_at_commands.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -14,7 +14,7 @@ */ -#include "sfe_ublox_at_commands.h" +#include "sfe_ublox_cellular.h" UBLOX_AT::UBLOX_AT(int powerPin, int resetPin, uint8_t maxInitTries) { diff --git a/src/sfe_ublox_at_commands.h b/src/sfe_ublox_cellular.h similarity index 100% rename from src/sfe_ublox_at_commands.h rename to src/sfe_ublox_cellular.h From e5b369340dd851b96dd3d8eed8b65f6483360f23 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Fri, 17 Nov 2023 11:08:54 -0700 Subject: [PATCH 11/52] Change prefixes from UBLOX_AT to UBX_CELL More consistent with the new library name, and more consistent with the GNSS library (UBX_GNSS is a common prefix there; probably not important to have parity between this and that, but hey, you never know when little things like that will help in big ways...) --- .../Example1_DeviceIdentification.ino | 6 +- src/sfe_lara_r6.h | 2 +- src/sfe_sara_r5.h | 2 +- src/sfe_ublox_cellular.cpp | 2752 ++++++++--------- src/sfe_ublox_cellular.h | 1028 +++--- 5 files changed, 1895 insertions(+), 1895 deletions(-) diff --git a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino index a33751a..a09ac87 100644 --- a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino +++ b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino @@ -6,7 +6,7 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBLOX_AT myModule; // This example works with all modules, so the base class can be used +UBX_CELL myModule; // This example works with all modules, so the base class can be used // SARA_R5 myModule; // Base SARA-R5 class // SARA_R500S myModule; // SARA_R500S_01B myModule; @@ -35,7 +35,7 @@ String simStateString[] = // processSIMstate is provided to the SARA-R5 library via a // callback setter -- setSIMstateReadCallback. (See setup()) -void processSIMstate(UBLOX_AT_sim_states_t state) +void processSIMstate(UBX_CELL_sim_states_t state) { Serial.println(); Serial.print(F("SIM state: ")); @@ -88,7 +88,7 @@ void setup() // Set a callback to return the SIM state once requested myModule.setSIMstateReportCallback(&processSIMstate); // Now enable SIM state reporting for states 0 to 6 (by setting the reporting mode LSb) - if (myModule.setSIMstateReportingMode(1) == UBLOX_AT_SUCCESS) + if (myModule.setSIMstateReportingMode(1) == UBX_CELL_SUCCESS) Serial.println("SIM state reports requested..."); // You can disable the SIM staus reports again by calling assetTracker.setSIMstateReportingMode(0) } diff --git a/src/sfe_lara_r6.h b/src/sfe_lara_r6.h index 548583d..3177346 100644 --- a/src/sfe_lara_r6.h +++ b/src/sfe_lara_r6.h @@ -4,7 +4,7 @@ #include "sfe_ublox_cellular.h" // Base LARA-R6 class -class LARA_R6: public UBLOX_AT +class LARA_R6: public UBX_CELL { }; diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index cba6df8..688aa54 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -4,7 +4,7 @@ #include "sfe_ublox_cellular.h" // Base SARA-R5 class -class SARA_R5: public UBLOX_AT +class SARA_R5: public UBX_CELL { }; diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index a6646aa..3dd79c8 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -16,9 +16,9 @@ #include "sfe_ublox_cellular.h" -UBLOX_AT::UBLOX_AT(int powerPin, int resetPin, uint8_t maxInitTries) +UBX_CELL::UBX_CELL(int powerPin, int resetPin, uint8_t maxInitTries) { -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED _softSerial = nullptr; #endif _hardSerial = nullptr; @@ -44,7 +44,7 @@ UBLOX_AT::UBLOX_AT(int powerPin, int resetPin, uint8_t maxInitTries) _printDebug = false; _lastRemoteIP = {0, 0, 0, 0}; _lastLocalIP = {0, 0, 0, 0}; - for (int i = 0; i < UBLOX_AT_NUM_SOCKETS; i++) + for (int i = 0; i < UBX_CELL_NUM_SOCKETS; i++) _lastSocketProtocol[i] = 0; // Set to zero initially. Will be set to TCP/UDP by socketOpen etc. _autoTimeZoneForBegin = true; _bufferedPollReentrant = false; @@ -55,7 +55,7 @@ UBLOX_AT::UBLOX_AT(int powerPin, int resetPin, uint8_t maxInitTries) _saraResponseBacklog = nullptr; } -UBLOX_AT::~UBLOX_AT(void) { +UBX_CELL::~UBX_CELL(void) { if (nullptr != _saraRXBuffer) { delete[] _saraRXBuffer; _saraRXBuffer = nullptr; @@ -70,8 +70,8 @@ UBLOX_AT::~UBLOX_AT(void) { } } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED -bool UBLOX_AT::begin(SoftwareSerial &softSerial, unsigned long baud) +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED +bool UBX_CELL::begin(SoftwareSerial &softSerial, unsigned long baud) { if (nullptr == _saraRXBuffer) { @@ -109,12 +109,12 @@ bool UBLOX_AT::begin(SoftwareSerial &softSerial, unsigned long baud) } memset(_saraResponseBacklog, 0, _RXBuffSize); - UBLOX_AT_error_t err; + UBX_CELL_error_t err; _softSerial = &softSerial; err = init(baud); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { return true; } @@ -122,7 +122,7 @@ bool UBLOX_AT::begin(SoftwareSerial &softSerial, unsigned long baud) } #endif -bool UBLOX_AT::begin(HardwareSerial &hardSerial, unsigned long baud) +bool UBX_CELL::begin(HardwareSerial &hardSerial, unsigned long baud) { if (nullptr == _saraRXBuffer) { @@ -160,12 +160,12 @@ bool UBLOX_AT::begin(HardwareSerial &hardSerial, unsigned long baud) } memset(_saraResponseBacklog, 0, _RXBuffSize); - UBLOX_AT_error_t err; + UBX_CELL_error_t err; _hardSerial = &hardSerial; err = init(baud); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { return true; } @@ -174,7 +174,7 @@ bool UBLOX_AT::begin(HardwareSerial &hardSerial, unsigned long baud) //Calling this function with nothing sets the debug port to Serial //You can also call it with other streams like Serial1, SerialUSB, etc. -void UBLOX_AT::enableDebugging(Print &debugPort) +void UBX_CELL::enableDebugging(Print &debugPort) { _debugPort = &debugPort; _printDebug = true; @@ -182,7 +182,7 @@ void UBLOX_AT::enableDebugging(Print &debugPort) //Calling this function with nothing sets the debug port to Serial //You can also call it with other streams like Serial1, SerialUSB, etc. -void UBLOX_AT::enableAtDebugging(Print &debugPort) +void UBX_CELL::enableAtDebugging(Print &debugPort) { _debugAtPort = &debugPort; _printAtDebug = true; @@ -192,7 +192,7 @@ void UBLOX_AT::enableAtDebugging(Print &debugPort) // See: https://github.com/sparkfun/SparkFun_LTE_Shield_Arduino_Library/pull/8 // It does the same job as ::poll but also processed any 'old' data stored in the backlog first // It also has a built-in timeout - which ::poll does not -bool UBLOX_AT::bufferedPoll(void) +bool UBX_CELL::bufferedPoll(void) { if (_bufferedPollReentrant == true) // Check for reentry (i.e. bufferedPoll has been called from inside a callback) return false; @@ -314,28 +314,28 @@ bool UBLOX_AT::bufferedPoll(void) } // /bufferedPoll // Parse incoming URC's - the associated parse functions pass the data to the user via the callbacks (if defined) -bool UBLOX_AT::processURCEvent(const char *event) +bool UBX_CELL::processURCEvent(const char *event) { { // URC: +UUSORD (Read Socket Data) int socket, length; - char *searchPtr = strstr(event, UBLOX_AT_READ_SOCKET_URC); + char *searchPtr = strstr(event, UBX_CELL_READ_SOCKET_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_READ_SOCKET_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_READ_SOCKET_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // Skip spaces int ret = sscanf(searchPtr, "%d,%d", &socket, &length); if (ret == 2) { if (_printDebug == true) _debugPort->println(F("processReadEvent: read socket data")); - // From the UBLOX_AT AT Commands Manual: + // From the UBX_CELL AT Commands Manual: // "For the UDP socket type the URC +UUSORD: , notifies that a UDP packet has been received, // either when buffer is empty or after a UDP packet has been read and one or more packets are stored in the // buffer." // So we need to check if this is a TCP socket or a UDP socket: // If UDP, we call parseSocketReadIndicationUDP. // Otherwise, we call parseSocketReadIndication. - if (_lastSocketProtocol[socket] == UBLOX_AT_UDP) + if (_lastSocketProtocol[socket] == UBX_CELL_UDP) { if (_printDebug == true) _debugPort->println(F("processReadEvent: received +UUSORD but socket is UDP. Calling parseSocketReadIndicationUDP")); @@ -349,10 +349,10 @@ bool UBLOX_AT::processURCEvent(const char *event) } { // URC: +UUSORF (Receive From command (UDP only)) int socket, length; - char *searchPtr = strstr(event, UBLOX_AT_READ_UDP_SOCKET_URC); + char *searchPtr = strstr(event, UBX_CELL_READ_UDP_SOCKET_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_READ_UDP_SOCKET_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_READ_UDP_SOCKET_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces int ret = sscanf(searchPtr, "%d,%d", &socket, &length); if (ret == 2) @@ -374,10 +374,10 @@ bool UBLOX_AT::processURCEvent(const char *event) int remoteIPstore[4] = {0,0,0,0}; int localIPstore[4] = {0,0,0,0}; - char *searchPtr = strstr(event, UBLOX_AT_LISTEN_SOCKET_URC); + char *searchPtr = strstr(event, UBX_CELL_LISTEN_SOCKET_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_LISTEN_SOCKET_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_LISTEN_SOCKET_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces int ret = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\",%u,%d,\"%d.%d.%d.%d\",%u", @@ -404,10 +404,10 @@ bool UBLOX_AT::processURCEvent(const char *event) } { // URC: +UUSOCL (Close Socket) int socket; - char *searchPtr = strstr(event, UBLOX_AT_CLOSE_SOCKET_URC); + char *searchPtr = strstr(event, UBX_CELL_CLOSE_SOCKET_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_CLOSE_SOCKET_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_CLOSE_SOCKET_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces int ret = sscanf(searchPtr, "%d", &socket); if (ret == 1) @@ -439,10 +439,10 @@ bool UBLOX_AT::processURCEvent(const char *event) // Maybe we should also scan for +UUGIND and extract the activated gnss system? // This assumes the ULOC response type is "0" or "1" - as selected by gpsRequest detailed - char *searchPtr = strstr(event, UBLOX_AT_GNSS_REQUEST_LOCATION_URC); + char *searchPtr = strstr(event, UBX_CELL_GNSS_REQUEST_LOCATION_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_GNSS_REQUEST_LOCATION_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_GNSS_REQUEST_LOCATION_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces scanNum = sscanf(searchPtr, "%d/%d/%d,%d:%d:%d.%d,%d.%[^,],%d.%[^,],%d,%lu,%u,%u,%*s", @@ -503,14 +503,14 @@ bool UBLOX_AT::processURCEvent(const char *event) } } { // URC: +UUSIMSTAT (SIM Status) - UBLOX_AT_sim_states_t state; + UBX_CELL_sim_states_t state; int scanNum; int stateStore; - char *searchPtr = strstr(event, UBLOX_AT_SIM_STATE_URC); + char *searchPtr = strstr(event, UBX_CELL_SIM_STATE_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_SIM_STATE_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_SIM_STATE_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces scanNum = sscanf(searchPtr, "%d", &stateStore); @@ -519,7 +519,7 @@ bool UBLOX_AT::processURCEvent(const char *event) if (_printDebug == true) _debugPort->println(F("processReadEvent: SIM status")); - state = (UBLOX_AT_sim_states_t)stateStore; + state = (UBX_CELL_sim_states_t)stateStore; if (_simStateReportCallback != nullptr) { @@ -536,10 +536,10 @@ bool UBLOX_AT::processURCEvent(const char *event) int scanNum; int remoteIPstore[4]; - char *searchPtr = strstr(event, UBLOX_AT_MESSAGE_PDP_ACTION_URC); + char *searchPtr = strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\"", &result, &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); @@ -567,10 +567,10 @@ bool UBLOX_AT::processURCEvent(const char *event) int profile, command, result; int scanNum; - char *searchPtr = strstr(event, UBLOX_AT_HTTP_COMMAND_URC); + char *searchPtr = strstr(event, UBX_CELL_HTTP_COMMAND_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_HTTP_COMMAND_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_HTTP_COMMAND_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces scanNum = sscanf(searchPtr, "%d,%d,%d", &profile, &command, &result); @@ -579,7 +579,7 @@ bool UBLOX_AT::processURCEvent(const char *event) if (_printDebug == true) _debugPort->println(F("processReadEvent: HTTP command result")); - if ((profile >= 0) && (profile < UBLOX_AT_NUM_HTTP_PROFILES)) + if ((profile >= 0) && (profile < UBX_CELL_NUM_HTTP_PROFILES)) { if (_httpCommandRequestCallback != nullptr) { @@ -597,17 +597,17 @@ bool UBLOX_AT::processURCEvent(const char *event) int qos = -1; String topic; - char *searchPtr = strstr(event, UBLOX_AT_MQTT_COMMAND_URC); + char *searchPtr = strstr(event, UBX_CELL_MQTT_COMMAND_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_MQTT_COMMAND_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_MQTT_COMMAND_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') { searchPtr++; // skip spaces } scanNum = sscanf(searchPtr, "%d,%d", &command, &result); - if ((scanNum == 2) && (command == UBLOX_AT_MQTT_COMMAND_SUBSCRIBE)) + if ((scanNum == 2) && (command == UBX_CELL_MQTT_COMMAND_SUBSCRIBE)) { char topicC[100] = ""; scanNum = sscanf(searchPtr, "%*d,%*d,%d,\"%[^\"]\"", &qos, topicC); @@ -633,10 +633,10 @@ bool UBLOX_AT::processURCEvent(const char *event) int ftpCmd; int ftpResult; int scanNum; - char *searchPtr = strstr(event, UBLOX_AT_FTP_COMMAND_URC); + char *searchPtr = strstr(event, UBX_CELL_FTP_COMMAND_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_FTP_COMMAND_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_FTP_COMMAND_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') { searchPtr++; // skip spaces @@ -660,10 +660,10 @@ bool UBLOX_AT::processURCEvent(const char *event) int scanNum; // Try to extract the UUPING retries and payload size - char *searchPtr = strstr(event, UBLOX_AT_PING_COMMAND_URC); + char *searchPtr = strstr(event, UBX_CELL_PING_COMMAND_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_PING_COMMAND_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_PING_COMMAND_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces scanNum = sscanf(searchPtr, "%d,%d,", &retry, &p_size); @@ -707,10 +707,10 @@ bool UBLOX_AT::processURCEvent(const char *event) { // URC: +CREG int status = 0; unsigned int lac = 0, ci = 0, Act = 0; - char *searchPtr = strstr(event, UBLOX_AT_REGISTRATION_STATUS_URC); + char *searchPtr = strstr(event, UBX_CELL_REGISTRATION_STATUS_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_REGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_REGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &lac, &ci, &Act); if (scanNum == 4) @@ -720,7 +720,7 @@ bool UBLOX_AT::processURCEvent(const char *event) if (_registrationCallback != nullptr) { - _registrationCallback((UBLOX_AT_registration_status_t)status, lac, ci, Act); + _registrationCallback((UBX_CELL_registration_status_t)status, lac, ci, Act); } return true; @@ -730,10 +730,10 @@ bool UBLOX_AT::processURCEvent(const char *event) { // URC: +CEREG int status = 0; unsigned int tac = 0, ci = 0, Act = 0; - char *searchPtr = strstr(event, UBLOX_AT_EPSREGISTRATION_STATUS_URC); + char *searchPtr = strstr(event, UBX_CELL_EPSREGISTRATION_STATUS_URC); if (searchPtr != nullptr) { - searchPtr += strlen(UBLOX_AT_EPSREGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space + searchPtr += strlen(UBX_CELL_EPSREGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space while (*searchPtr == ' ') searchPtr++; // skip spaces int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &tac, &ci, &Act); if (scanNum == 4) @@ -743,7 +743,7 @@ bool UBLOX_AT::processURCEvent(const char *event) if (_epsRegistrationCallback != nullptr) { - _epsRegistrationCallback((UBLOX_AT_registration_status_t)status, tac, ci, Act); + _epsRegistrationCallback((UBX_CELL_registration_status_t)status, tac, ci, Act); } return true; @@ -758,7 +758,7 @@ bool UBLOX_AT::processURCEvent(const char *event) // This is the original poll function. // It is 'blocking' - it does not return when serial data is available until it receives a `\n`. // ::bufferedPoll is the new improved version. It processes any data in the backlog and includes a timeout. -bool UBLOX_AT::poll(void) +bool UBX_CELL::poll(void) { if (_pollReentrant == true) // Check for reentry (i.e. poll has been called from inside a callback) return false; @@ -807,141 +807,141 @@ bool UBLOX_AT::poll(void) return handled; } -void UBLOX_AT::setSocketListenCallback(void (*socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int)) +void UBX_CELL::setSocketListenCallback(void (*socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int)) { _socketListenCallback = socketListenCallback; } -void UBLOX_AT::setSocketReadCallback(void (*socketReadCallback)(int, String)) +void UBX_CELL::setSocketReadCallback(void (*socketReadCallback)(int, String)) { _socketReadCallback = socketReadCallback; } -void UBLOX_AT::setSocketReadCallbackPlus(void (*socketReadCallbackPlus)(int, const char *, int, IPAddress, int)) // socket, data, length, remoteAddress, remotePort +void UBX_CELL::setSocketReadCallbackPlus(void (*socketReadCallbackPlus)(int, const char *, int, IPAddress, int)) // socket, data, length, remoteAddress, remotePort { _socketReadCallbackPlus = socketReadCallbackPlus; } -void UBLOX_AT::setSocketCloseCallback(void (*socketCloseCallback)(int)) +void UBX_CELL::setSocketCloseCallback(void (*socketCloseCallback)(int)) { _socketCloseCallback = socketCloseCallback; } -void UBLOX_AT::setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, +void UBX_CELL::setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, PositionData gps, SpeedData spd, unsigned long uncertainty)) { _gpsRequestCallback = gpsRequestCallback; } -void UBLOX_AT::setSIMstateReportCallback(void (*simStateReportCallback)(UBLOX_AT_sim_states_t state)) +void UBX_CELL::setSIMstateReportCallback(void (*simStateReportCallback)(UBX_CELL_sim_states_t state)) { _simStateReportCallback = simStateReportCallback; } -void UBLOX_AT::setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)) +void UBX_CELL::setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)) { _psdActionRequestCallback = psdActionRequestCallback; } -void UBLOX_AT::setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)) +void UBX_CELL::setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)) { _pingRequestCallback = pingRequestCallback; } -void UBLOX_AT::setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)) +void UBX_CELL::setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)) { _httpCommandRequestCallback = httpCommandRequestCallback; } -void UBLOX_AT::setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)) +void UBX_CELL::setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)) { _mqttCommandRequestCallback = mqttCommandRequestCallback; } -void UBLOX_AT::setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)) +void UBX_CELL::setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)) { _ftpCommandRequestCallback = ftpCommandRequestCallback; } -UBLOX_AT_error_t UBLOX_AT::setRegistrationCallback(void (*registrationCallback)(UBLOX_AT_registration_status_t status, unsigned int lac, unsigned int ci, int Act)) +UBX_CELL_error_t UBX_CELL::setRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, unsigned int lac, unsigned int ci, int Act)) { _registrationCallback = registrationCallback; - char *command = ublox_at_calloc_char(strlen(UBLOX_AT_REGISTRATION_STATUS) + 3); + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_REGISTRATION_STATUS) + 3); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_REGISTRATION_STATUS, 2/*enable URC with location*/); - UBLOX_AT_error_t err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_REGISTRATION_STATUS, 2/*enable URC with location*/); + UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setEpsRegistrationCallback(void (*registrationCallback)(UBLOX_AT_registration_status_t status, unsigned int tac, unsigned int ci, int Act)) +UBX_CELL_error_t UBX_CELL::setEpsRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, unsigned int tac, unsigned int ci, int Act)) { _epsRegistrationCallback = registrationCallback; - char *command = ublox_at_calloc_char(strlen(UBLOX_AT_EPSREGISTRATION_STATUS) + 3); + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_EPSREGISTRATION_STATUS) + 3); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_EPSREGISTRATION_STATUS, 2/*enable URC with location*/); - UBLOX_AT_error_t err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_EPSREGISTRATION_STATUS, 2/*enable URC with location*/); + UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -size_t UBLOX_AT::write(uint8_t c) +size_t UBX_CELL::write(uint8_t c) { return hwWrite(c); } -size_t UBLOX_AT::write(const char *str) +size_t UBX_CELL::write(const char *str) { return hwPrint(str); } -size_t UBLOX_AT::write(const char *buffer, size_t size) +size_t UBX_CELL::write(const char *buffer, size_t size) { return hwWriteData(buffer, size); } -UBLOX_AT_error_t UBLOX_AT::at(void) +UBX_CELL_error_t UBX_CELL::at(void) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - err = sendCommandWithResponse(nullptr, UBLOX_AT_RESPONSE_OK, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(nullptr, UBX_CELL_RESPONSE_OK, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); return err; } -UBLOX_AT_error_t UBLOX_AT::enableEcho(bool enable) +UBX_CELL_error_t UBX_CELL::enableEcho(bool enable) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_ECHO) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_ECHO) + 2); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s%d", UBLOX_AT_COMMAND_ECHO, enable ? 1 : 0); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s%d", UBX_CELL_COMMAND_ECHO, enable ? 1 : 0); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -String UBLOX_AT::getManufacturerID(void) +String UBX_CELL::getManufacturerID(void) { char *response; char idResponse[16] = {0x00}; // E.g. u-blox - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBLOX_AT_COMMAND_MANU_ID, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(UBX_CELL_COMMAND_MANU_ID, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { if (sscanf(response, "\r\n%15s\r\n", idResponse) != 1) { @@ -952,17 +952,17 @@ String UBLOX_AT::getManufacturerID(void) return String(idResponse); } -String UBLOX_AT::getModelID(void) +String UBX_CELL::getModelID(void) { char *response; char idResponse[32] = {0x00}; // E.g. SARA-R510M8Q - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBLOX_AT_COMMAND_MODEL_ID, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(UBX_CELL_COMMAND_MODEL_ID, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { if (sscanf(response, "\r\n%31s\r\n", idResponse) != 1) { @@ -973,17 +973,17 @@ String UBLOX_AT::getModelID(void) return String(idResponse); } -String UBLOX_AT::getFirmwareVersion(void) +String UBX_CELL::getFirmwareVersion(void) { char *response; char idResponse[16] = {0x00}; // E.g. 11.40 - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBLOX_AT_COMMAND_FW_VER_ID, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(UBX_CELL_COMMAND_FW_VER_ID, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { if (sscanf(response, "\r\n%15s\r\n", idResponse) != 1) { @@ -994,17 +994,17 @@ String UBLOX_AT::getFirmwareVersion(void) return String(idResponse); } -String UBLOX_AT::getSerialNo(void) +String UBX_CELL::getSerialNo(void) { char *response; char idResponse[32] = {0x00}; // E.g. 357520070120767 - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBLOX_AT_COMMAND_SERIAL_NO, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(UBX_CELL_COMMAND_SERIAL_NO, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { if (sscanf(response, "\r\n%31s\r\n", idResponse) != 1) { @@ -1015,17 +1015,17 @@ String UBLOX_AT::getSerialNo(void) return String(idResponse); } -String UBLOX_AT::getIMEI(void) +String UBX_CELL::getIMEI(void) { char *response; char imeiResponse[32] = {0x00}; // E.g. 004999010640000 - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBLOX_AT_COMMAND_IMEI, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(UBX_CELL_COMMAND_IMEI, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { if (sscanf(response, "\r\n%31s\r\n", imeiResponse) != 1) { @@ -1036,17 +1036,17 @@ String UBLOX_AT::getIMEI(void) return String(imeiResponse); } -String UBLOX_AT::getIMSI(void) +String UBX_CELL::getIMSI(void) { char *response; char imsiResponse[32] = {0x00}; // E.g. 222107701772423 - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBLOX_AT_COMMAND_IMSI, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(UBX_CELL_COMMAND_IMSI, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { if (sscanf(response, "\r\n%31s\r\n", imsiResponse) != 1) { @@ -1057,17 +1057,17 @@ String UBLOX_AT::getIMSI(void) return String(imsiResponse); } -String UBLOX_AT::getCCID(void) +String UBX_CELL::getCCID(void) { char *response; char ccidResponse[32] = {0x00}; // E.g. +CCID: 8939107900010087330 - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBLOX_AT_COMMAND_CCID, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(UBX_CELL_COMMAND_CCID, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "\r\n+CCID:"); if (searchPtr != nullptr) @@ -1084,17 +1084,17 @@ String UBLOX_AT::getCCID(void) return String(ccidResponse); } -String UBLOX_AT::getSubscriberNo(void) +String UBX_CELL::getSubscriberNo(void) { char *response; char idResponse[128] = {0x00}; // E.g. +CNUM: "ABCD . AAA","123456789012",129 - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBLOX_AT_COMMAND_CNUM, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_10_SEC_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(UBX_CELL_COMMAND_CNUM, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "\r\n+CNUM:"); if (searchPtr != nullptr) @@ -1111,17 +1111,17 @@ String UBLOX_AT::getSubscriberNo(void) return String(idResponse); } -String UBLOX_AT::getCapabilities(void) +String UBX_CELL::getCapabilities(void) { char *response; char idResponse[128] = {0x00}; // E.g. +GCAP: +FCLASS, +CGSM - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBLOX_AT_COMMAND_REQ_CAP, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(UBX_CELL_COMMAND_REQ_CAP, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "\r\n+GCAP:"); if (searchPtr != nullptr) @@ -1138,19 +1138,19 @@ String UBLOX_AT::getCapabilities(void) return String(idResponse); } -UBLOX_AT_error_t UBLOX_AT::reset(void) +UBX_CELL_error_t UBX_CELL::reset(void) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; err = functionality(SILENT_RESET_WITH_SIM); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { // Reset will set the baud rate back to 115200 //beginSerial(9600); - err = UBLOX_AT_ERROR_INVALID; - while (err != UBLOX_AT_ERROR_SUCCESS) + err = UBX_CELL_ERROR_INVALID; + while (err != UBX_CELL_ERROR_SUCCESS) { - beginSerial(UBLOX_AT_DEFAULT_BAUD_RATE); + beginSerial(UBX_CELL_DEFAULT_BAUD_RATE); setBaud(_baud); beginSerial(_baud); err = at(); @@ -1160,29 +1160,29 @@ UBLOX_AT_error_t UBLOX_AT::reset(void) return err; } -String UBLOX_AT::clock(void) +String UBX_CELL::clock(void) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; char *clockBegin; char *clockEnd; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_CLOCK) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + 2); if (command == nullptr) return ""; - sprintf(command, "%s?", UBLOX_AT_COMMAND_CLOCK); + sprintf(command, "%s?", UBX_CELL_COMMAND_CLOCK); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); return ""; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err != UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err != UBX_CELL_ERROR_SUCCESS) { free(command); free(response); @@ -1215,10 +1215,10 @@ String UBLOX_AT::clock(void) return (clock); } -UBLOX_AT_error_t UBLOX_AT::clock(uint8_t *y, uint8_t *mo, uint8_t *d, +UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; char tzPlusMinus; @@ -1226,23 +1226,23 @@ UBLOX_AT_error_t UBLOX_AT::clock(uint8_t *y, uint8_t *mo, uint8_t *d, int iy, imo, id, ih, imin, is, itz; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_CLOCK) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + 2); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_COMMAND_CLOCK); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_COMMAND_CLOCK); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); // Response format (if TZ is negative): \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+CCLK:"); if (searchPtr != nullptr) @@ -1266,7 +1266,7 @@ UBLOX_AT_error_t UBLOX_AT::clock(uint8_t *y, uint8_t *mo, uint8_t *d, *tz = itz; } else - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -1274,7 +1274,7 @@ UBLOX_AT_error_t UBLOX_AT::clock(uint8_t *y, uint8_t *mo, uint8_t *d, return err; } -UBLOX_AT_error_t UBLOX_AT::setClock(uint8_t y, uint8_t mo, uint8_t d, +UBX_CELL_error_t UBX_CELL::setClock(uint8_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t min, uint8_t s, int8_t tz) { //Convert y,mo,d,h,min,s,tz into a String @@ -1314,73 +1314,73 @@ UBLOX_AT_error_t UBLOX_AT::setClock(uint8_t y, uint8_t mo, uint8_t d, return (setClock(theTime)); } -UBLOX_AT_error_t UBLOX_AT::setClock(String theTime) +UBX_CELL_error_t UBX_CELL::setClock(String theTime) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_CLOCK) + theTime.length() + 8); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + theTime.length() + 8); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBLOX_AT_COMMAND_CLOCK, theTime.c_str()); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_COMMAND_CLOCK, theTime.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -void UBLOX_AT::autoTimeZoneForBegin(bool tz) +void UBX_CELL::autoTimeZoneForBegin(bool tz) { _autoTimeZoneForBegin = tz; } -UBLOX_AT_error_t UBLOX_AT::setUtimeMode(UBLOX_AT_utime_mode_t mode, UBLOX_AT_utime_sensor_t sensor) +UBX_CELL_error_t UBX_CELL::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utime_sensor_t sensor) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_REQUEST_TIME) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - if (mode == UBLOX_AT_UTIME_MODE_STOP) // stop UTIME does not require a sensor - sprintf(command, "%s=%d", UBLOX_AT_GNSS_REQUEST_TIME, mode); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (mode == UBX_CELL_UTIME_MODE_STOP) // stop UTIME does not require a sensor + sprintf(command, "%s=%d", UBX_CELL_GNSS_REQUEST_TIME, mode); else - sprintf(command, "%s=%d,%d", UBLOX_AT_GNSS_REQUEST_TIME, mode, sensor); + sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_REQUEST_TIME, mode, sensor); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_10_SEC_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_10_SEC_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getUtimeMode(UBLOX_AT_utime_mode_t *mode, UBLOX_AT_utime_sensor_t *sensor) +UBX_CELL_error_t UBX_CELL::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; - UBLOX_AT_utime_mode_t m; - UBLOX_AT_utime_sensor_t s; + UBX_CELL_utime_mode_t m; + UBX_CELL_utime_sensor_t s; - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_REQUEST_TIME) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_GNSS_REQUEST_TIME); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_REQUEST_TIME); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_10_SEC_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_10_SEC_TIMEOUT); // Response format: \r\n+UTIME: [,]\r\n\r\nOK\r\n - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { int mStore, sStore, scanned = 0; char *searchPtr = strstr(response, "+UTIME:"); @@ -1390,8 +1390,8 @@ UBLOX_AT_error_t UBLOX_AT::getUtimeMode(UBLOX_AT_utime_mode_t *mode, UBLOX_AT_ut while (*searchPtr == ' ') searchPtr++; // skip spaces scanned = sscanf(searchPtr, "%d,%d\r\n", &mStore, &sStore); } - m = (UBLOX_AT_utime_mode_t)mStore; - s = (UBLOX_AT_utime_sensor_t)sStore; + m = (UBX_CELL_utime_mode_t)mStore; + s = (UBX_CELL_utime_sensor_t)sStore; if (scanned == 2) { *mode = m; @@ -1400,10 +1400,10 @@ UBLOX_AT_error_t UBLOX_AT::getUtimeMode(UBLOX_AT_utime_mode_t *mode, UBLOX_AT_ut else if (scanned == 1) { *mode = m; - *sensor = UBLOX_AT_UTIME_SENSOR_NONE; + *sensor = UBX_CELL_UTIME_SENSOR_NONE; } else - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -1411,47 +1411,47 @@ UBLOX_AT_error_t UBLOX_AT::getUtimeMode(UBLOX_AT_utime_mode_t *mode, UBLOX_AT_ut return err; } -UBLOX_AT_error_t UBLOX_AT::setUtimeIndication(UBLOX_AT_utime_urc_configuration_t config) +UBX_CELL_error_t UBX_CELL::setUtimeIndication(UBX_CELL_utime_urc_configuration_t config) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_TIME_INDICATION) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_GNSS_TIME_INDICATION, config); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_GNSS_TIME_INDICATION, config); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getUtimeIndication(UBLOX_AT_utime_urc_configuration_t *config) +UBX_CELL_error_t UBX_CELL::getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; - UBLOX_AT_utime_urc_configuration_t c; + UBX_CELL_utime_urc_configuration_t c; - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_TIME_INDICATION) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_GNSS_TIME_INDICATION); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_TIME_INDICATION); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); // Response format: \r\n+UTIMEIND: \r\n\r\nOK\r\n - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { int cStore, scanned = 0; char *searchPtr = strstr(response, "+UTIMEIND:"); @@ -1461,13 +1461,13 @@ UBLOX_AT_error_t UBLOX_AT::getUtimeIndication(UBLOX_AT_utime_urc_configuration_t while (*searchPtr == ' ') searchPtr++; // skip spaces scanned = sscanf(searchPtr, "%d\r\n", &cStore); } - c = (UBLOX_AT_utime_urc_configuration_t)cStore; + c = (UBX_CELL_utime_urc_configuration_t)cStore; if (scanned == 1) { *config = c; } else - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -1475,52 +1475,52 @@ UBLOX_AT_error_t UBLOX_AT::getUtimeIndication(UBLOX_AT_utime_urc_configuration_t return err; } -UBLOX_AT_error_t UBLOX_AT::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds) +UBX_CELL_error_t UBX_CELL::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_TIME_CONFIGURATION) + 48); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - sprintf(command, "%s=%d,%d", UBLOX_AT_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); + sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); #else - sprintf(command, "%s=%ld,%ld", UBLOX_AT_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); + sprintf(command, "%s=%ld,%ld", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); #endif - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds) +UBX_CELL_error_t UBX_CELL::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; int32_t ons; int32_t os; - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_TIME_CONFIGURATION) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_GNSS_TIME_CONFIGURATION); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_TIME_CONFIGURATION); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); // Response format: \r\n+UTIMECFG: ,\r\n\r\nOK\r\n - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; char *searchPtr = strstr(response, "+UTIMECFG:"); @@ -1540,7 +1540,7 @@ UBLOX_AT_error_t UBLOX_AT::getUtimeConfiguration(int32_t *offsetNanoseconds, int *offsetSeconds = os; } else - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -1548,45 +1548,45 @@ UBLOX_AT_error_t UBLOX_AT::getUtimeConfiguration(int32_t *offsetNanoseconds, int return err; } -UBLOX_AT_error_t UBLOX_AT::autoTimeZone(bool enable) +UBX_CELL_error_t UBX_CELL::autoTimeZone(bool enable) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_AUTO_TZ) + 3); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_AUTO_TZ) + 3); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_COMMAND_AUTO_TZ, enable ? 1 : 0); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_COMMAND_AUTO_TZ, enable ? 1 : 0); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -int8_t UBLOX_AT::rssi(void) +int8_t UBX_CELL::rssi(void) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int rssi; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SIGNAL_QUALITY) + 1); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SIGNAL_QUALITY) + 1); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s", UBLOX_AT_SIGNAL_QUALITY); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s", UBX_CELL_SIGNAL_QUALITY); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } err = sendCommandWithResponse(command, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, 10000, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, 10000, minimumResponseAllocation, AT_COMMAND); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { free(command); free(response); @@ -1611,35 +1611,35 @@ int8_t UBLOX_AT::rssi(void) return rssi; } -UBLOX_AT_error_t UBLOX_AT::getExtSignalQuality(signal_quality& signal_quality) +UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality& signal_quality) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - command = ublox_at_calloc_char(strlen(UBLOX_AT_EXT_SIGNAL_QUALITY) + 1); + command = ubx_cell_calloc_char(strlen(UBX_CELL_EXT_SIGNAL_QUALITY) + 1); if (command == nullptr) { - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s", UBLOX_AT_EXT_SIGNAL_QUALITY); + sprintf(command, "%s", UBX_CELL_EXT_SIGNAL_QUALITY); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } err = sendCommandWithResponse(command, - UBLOX_AT_RESPONSE_OK_OR_ERROR, response, 10000, + UBX_CELL_RESPONSE_OK_OR_ERROR, response, 10000, minimumResponseAllocation, AT_COMMAND); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { free(command); free(response); - return UBLOX_AT_ERROR_ERROR; + return UBX_CELL_ERROR_ERROR; } int scanned = 0; @@ -1653,10 +1653,10 @@ UBLOX_AT_error_t UBLOX_AT::getExtSignalQuality(signal_quality& signal_quality) &signal_quality.rscp, &signal_quality.enc0, &signal_quality.rsrq, &signal_quality.rsrp); } - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; if (scanned == 6) { - err = UBLOX_AT_ERROR_SUCCESS; + err = UBX_CELL_ERROR_SUCCESS; } free(command); @@ -1664,58 +1664,58 @@ UBLOX_AT_error_t UBLOX_AT::getExtSignalQuality(signal_quality& signal_quality) return err; } -UBLOX_AT_registration_status_t UBLOX_AT::registration(bool eps) +UBX_CELL_registration_status_t UBX_CELL::registration(bool eps) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int status; - const char* tag = eps ? UBLOX_AT_EPSREGISTRATION_STATUS : UBLOX_AT_REGISTRATION_STATUS; - command = ublox_at_calloc_char(strlen(tag) + 3); + const char* tag = eps ? UBX_CELL_EPSREGISTRATION_STATUS : UBX_CELL_REGISTRATION_STATUS; + command = ubx_cell_calloc_char(strlen(tag) + 3); if (command == nullptr) - return UBLOX_AT_REGISTRATION_INVALID; + return UBX_CELL_REGISTRATION_INVALID; sprintf(command, "%s?", tag); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_REGISTRATION_INVALID; + return UBX_CELL_REGISTRATION_INVALID; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT, minimumResponseAllocation, AT_COMMAND); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { free(command); free(response); - return UBLOX_AT_REGISTRATION_INVALID; + return UBX_CELL_REGISTRATION_INVALID; } int scanned = 0; - const char *startTag = eps ? UBLOX_AT_EPSREGISTRATION_STATUS_URC : UBLOX_AT_REGISTRATION_STATUS_URC; + const char *startTag = eps ? UBX_CELL_EPSREGISTRATION_STATUS_URC : UBX_CELL_REGISTRATION_STATUS_URC; char *searchPtr = strstr(response, startTag); if (searchPtr != nullptr) { - searchPtr += eps ? strlen(UBLOX_AT_EPSREGISTRATION_STATUS_URC) : strlen(UBLOX_AT_REGISTRATION_STATUS_URC); // Move searchPtr to first char + searchPtr += eps ? strlen(UBX_CELL_EPSREGISTRATION_STATUS_URC) : strlen(UBX_CELL_REGISTRATION_STATUS_URC); // Move searchPtr to first char while (*searchPtr == ' ') searchPtr++; // skip spaces scanned = sscanf(searchPtr, "%*d,%d", &status); } if (scanned != 1) - status = UBLOX_AT_REGISTRATION_INVALID; + status = UBX_CELL_REGISTRATION_INVALID; free(command); free(response); - return (UBLOX_AT_registration_status_t)status; + return (UBX_CELL_registration_status_t)status; } -bool UBLOX_AT::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) +bool UBX_CELL::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) { mobile_network_operator_t currentMno; // Check currently set MNO profile - if (getMNOprofile(¤tMno) != UBLOX_AT_ERROR_SUCCESS) + if (getMNOprofile(¤tMno) != UBX_CELL_ERROR_SUCCESS) { return false; } @@ -1726,17 +1726,17 @@ bool UBLOX_AT::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, } // Disable transmit and receive so we can change operator - if (functionality(MINIMUM_FUNCTIONALITY) != UBLOX_AT_ERROR_SUCCESS) + if (functionality(MINIMUM_FUNCTIONALITY) != UBX_CELL_ERROR_SUCCESS) { return false; } - if (setMNOprofile(mno, autoReset, urcNotification) != UBLOX_AT_ERROR_SUCCESS) + if (setMNOprofile(mno, autoReset, urcNotification) != UBX_CELL_ERROR_SUCCESS) { return false; } - if (reset() != UBLOX_AT_ERROR_SUCCESS) + if (reset() != UBX_CELL_ERROR_SUCCESS) { return false; } @@ -1744,38 +1744,38 @@ bool UBLOX_AT::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, return true; } -mobile_network_operator_t UBLOX_AT::getNetworkProfile(void) +mobile_network_operator_t UBX_CELL::getNetworkProfile(void) { mobile_network_operator_t mno; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; err = getMNOprofile(&mno); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { return MNO_INVALID; } return mno; } -UBLOX_AT_error_t UBLOX_AT::setAPN(String apn, uint8_t cid, UBLOX_AT_pdp_type pdpType) +UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdpType) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char pdpStr[8]; memset(pdpStr, 0, 8); if (cid >= 8) - return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + return UBX_CELL_ERROR_UNEXPECTED_PARAM; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_DEF) + strlen(apn.c_str()) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_DEF) + strlen(apn.c_str()) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; switch (pdpType) { case PDP_TYPE_INVALID: free(command); - return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + return UBX_CELL_ERROR_UNEXPECTED_PARAM; break; case PDP_TYPE_IP: memcpy(pdpStr, "IP", 2); @@ -1791,14 +1791,14 @@ UBLOX_AT_error_t UBLOX_AT::setAPN(String apn, uint8_t cid, UBLOX_AT_pdp_type pdp break; default: free(command); - return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + return UBX_CELL_ERROR_UNEXPECTED_PARAM; break; } if (apn == nullptr) { if (_printDebug == true) _debugPort->println(F("setAPN: nullptr")); - sprintf(command, "%s=%d,\"%s\",\"\"", UBLOX_AT_MESSAGE_PDP_DEF, + sprintf(command, "%s=%d,\"%s\",\"\"", UBX_CELL_MESSAGE_PDP_DEF, cid, pdpStr); } else @@ -1808,12 +1808,12 @@ UBLOX_AT_error_t UBLOX_AT::setAPN(String apn, uint8_t cid, UBLOX_AT_pdp_type pdp _debugPort->print(F("setAPN: ")); _debugPort->println(apn); } - sprintf(command, "%s=%d,\"%s\",\"%s\"", UBLOX_AT_MESSAGE_PDP_DEF, + sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MESSAGE_PDP_DEF, cid, pdpStr, apn.c_str()); } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); @@ -1821,31 +1821,31 @@ UBLOX_AT_error_t UBLOX_AT::setAPN(String apn, uint8_t cid, UBLOX_AT_pdp_type pdp } // Return the Access Point Name and IP address for the chosen context identifier -UBLOX_AT_error_t UBLOX_AT::getAPN(int cid, String *apn, IPAddress *ip, UBLOX_AT_pdp_type* pdpType) +UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_pdp_type* pdpType) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; - if (cid > UBLOX_AT_NUM_PDP_CONTEXT_IDENTIFIERS) - return UBLOX_AT_ERROR_ERROR; + if (cid > UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_DEF) + 3); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_DEF) + 3); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_MESSAGE_PDP_DEF); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_MESSAGE_PDP_DEF); - response = ublox_at_calloc_char(1024); + response = ubx_cell_calloc_char(1024); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, 1024); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT, 1024); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { // Example: // +CGDCONT: 0,"IP","payandgo.o2.co.uk","0.0.0.0",0,0,0,0,0,0,0,0,0,0 @@ -1896,7 +1896,7 @@ UBLOX_AT_error_t UBLOX_AT::getAPN(int cid, String *apn, IPAddress *ip, UBLOX_AT_ } else { - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -1905,25 +1905,25 @@ UBLOX_AT_error_t UBLOX_AT::getAPN(int cid, String *apn, IPAddress *ip, UBLOX_AT_ return err; } -UBLOX_AT_error_t UBLOX_AT::getSimStatus(String* code) +UBX_CELL_error_t UBX_CELL::getSimStatus(String* code) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_SIMPIN) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_SIMPIN) + 2); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_COMMAND_SIMPIN); - response = ublox_at_calloc_char(minimumResponseAllocation); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_COMMAND_SIMPIN); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; char c[16]; @@ -1939,7 +1939,7 @@ UBLOX_AT_error_t UBLOX_AT::getSimStatus(String* code) *code = c; } else - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -1948,60 +1948,60 @@ UBLOX_AT_error_t UBLOX_AT::getSimStatus(String* code) return err; } -UBLOX_AT_error_t UBLOX_AT::setSimPin(String pin) +UBX_CELL_error_t UBX_CELL::setSimPin(String pin) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_SIMPIN) + 4 + pin.length()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_SIMPIN) + 4 + pin.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBLOX_AT_COMMAND_SIMPIN, pin.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_COMMAND_SIMPIN, pin.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setSIMstateReportingMode(int mode) +UBX_CELL_error_t UBX_CELL::setSIMstateReportingMode(int mode) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SIM_STATE) + 4); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SIM_STATE) + 4); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_SIM_STATE, mode); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_SIM_STATE, mode); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getSIMstateReportingMode(int *mode) +UBX_CELL_error_t UBX_CELL::getSIMstateReportingMode(int *mode) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; int m; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SIM_STATE) + 3); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SIM_STATE) + 3); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_SIM_STATE); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_SIM_STATE); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; char *searchPtr = strstr(response, "+USIMSTAT:"); @@ -2016,7 +2016,7 @@ UBLOX_AT_error_t UBLOX_AT::getSIMstateReportingMode(int *mode) *mode = m; } else - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -2032,62 +2032,62 @@ const char *PPP_L2P[5] = { "M-OPT-PPP", }; -UBLOX_AT_error_t UBLOX_AT::enterPPP(uint8_t cid, char dialing_type_char, - unsigned long dialNumber, UBLOX_AT::UBLOX_AT_l2p_t l2p) +UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, + unsigned long dialNumber, UBX_CELL::UBX_CELL_l2p_t l2p) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; if ((dialing_type_char != 0) && (dialing_type_char != 'T') && (dialing_type_char != 'P')) { - return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + return UBX_CELL_ERROR_UNEXPECTED_PARAM; } - command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_ENTER_PPP) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_ENTER_PPP) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; if (dialing_type_char != 0) { - sprintf(command, "%s%c*%lu**%s*%u#", UBLOX_AT_MESSAGE_ENTER_PPP, dialing_type_char, + sprintf(command, "%s%c*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialing_type_char, dialNumber, PPP_L2P[l2p], (unsigned int)cid); } else { - sprintf(command, "%s*%lu**%s*%u#", UBLOX_AT_MESSAGE_ENTER_PPP, + sprintf(command, "%s*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialNumber, PPP_L2P[l2p], (unsigned int)cid); } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_CONNECT, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -uint8_t UBLOX_AT::getOperators(struct operator_stats *opRet, int maxOps) +uint8_t UBX_CELL::getOperators(struct operator_stats *opRet, int maxOps) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; uint8_t opsSeen = 0; - command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 3); + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 3); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=?", UBLOX_AT_OPERATOR_SELECTION); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=?", UBX_CELL_OPERATOR_SELECTION); int responseSize = (maxOps + 1) * 48; - response = ublox_at_calloc_char(responseSize); + response = ubx_cell_calloc_char(responseSize); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } // AT+COPS maximum response time is 3 minutes (180000 ms) - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_3_MIN_TIMEOUT, responseSize); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_3_MIN_TIMEOUT, responseSize); // Sample responses: // +COPS: (3,"Verizon Wireless","VzW","311480",8),,(0,1,2,3,4),(0,1,2) @@ -2100,7 +2100,7 @@ uint8_t UBLOX_AT::getOperators(struct operator_stats *opRet, int maxOps) _debugPort->println(F("}")); } - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *opBegin; char *opEnd; @@ -2148,67 +2148,67 @@ uint8_t UBLOX_AT::getOperators(struct operator_stats *opRet, int maxOps) return opsSeen; } -UBLOX_AT_error_t UBLOX_AT::registerOperator(struct operator_stats oper) +UBX_CELL_error_t UBX_CELL::registerOperator(struct operator_stats oper) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 24); + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 24); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=1,2,\"%lu\"", UBLOX_AT_OPERATOR_SELECTION, oper.numOp); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=1,2,\"%lu\"", UBX_CELL_OPERATOR_SELECTION, oper.numOp); // AT+COPS maximum response time is 3 minutes (180000 ms) - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_3_MIN_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_3_MIN_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::automaticOperatorSelection() +UBX_CELL_error_t UBX_CELL::automaticOperatorSelection() { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 6); + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 6); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=0,0", UBLOX_AT_OPERATOR_SELECTION); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=0,0", UBX_CELL_OPERATOR_SELECTION); // AT+COPS maximum response time is 3 minutes (180000 ms) - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_3_MIN_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_3_MIN_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getOperator(String *oper) +UBX_CELL_error_t UBX_CELL::getOperator(String *oper) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; char *searchPtr; char mode; - command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 3); + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 3); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_OPERATOR_SELECTION); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_OPERATOR_SELECTION); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } // AT+COPS maximum response time is 3 minutes (180000 ms) - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_3_MIN_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_3_MIN_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { searchPtr = strstr(response, "+COPS:"); if (searchPtr != nullptr) @@ -2218,7 +2218,7 @@ UBLOX_AT_error_t UBLOX_AT::getOperator(String *oper) mode = *searchPtr; // Read first char -- should be mode if (mode == '2') // Check for de-register { - err = UBLOX_AT_ERROR_DEREGISTERED; + err = UBX_CELL_ERROR_DEREGISTERED; } // Otherwise if it's default, manual, set-only, or automatic else if ((mode == '0') || (mode == '1') || (mode == '3') || (mode == '4')) @@ -2227,7 +2227,7 @@ UBLOX_AT_error_t UBLOX_AT::getOperator(String *oper) searchPtr = strchr(searchPtr, '\"'); // Move to first quote if (searchPtr == nullptr) { - err = UBLOX_AT_ERROR_DEREGISTERED; + err = UBX_CELL_ERROR_DEREGISTERED; } else { @@ -2250,112 +2250,112 @@ UBLOX_AT_error_t UBLOX_AT::getOperator(String *oper) return err; } -UBLOX_AT_error_t UBLOX_AT::deregisterOperator(void) +UBX_CELL_error_t UBX_CELL::deregisterOperator(void) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_OPERATOR_SELECTION) + 4); + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 4); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=2", UBLOX_AT_OPERATOR_SELECTION); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=2", UBX_CELL_OPERATOR_SELECTION); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_3_MIN_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_3_MIN_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setSMSMessageFormat(UBLOX_AT_message_format_t textMode) +UBX_CELL_error_t UBX_CELL::setSMSMessageFormat(UBX_CELL_message_format_t textMode) { char *command; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_FORMAT) + 4); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_FORMAT) + 4); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_MESSAGE_FORMAT, - (textMode == UBLOX_AT_MESSAGE_FORMAT_TEXT) ? 1 : 0); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_MESSAGE_FORMAT, + (textMode == UBX_CELL_MESSAGE_FORMAT_TEXT) ? 1 : 0); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::sendSMS(String number, String message) +UBX_CELL_error_t UBX_CELL::sendSMS(String number, String message) { char *command; char *messageCStr; char *numberCStr; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - numberCStr = ublox_at_calloc_char(number.length() + 2); + numberCStr = ubx_cell_calloc_char(number.length() + 2); if (numberCStr == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; number.toCharArray(numberCStr, number.length() + 1); - command = ublox_at_calloc_char(strlen(UBLOX_AT_SEND_TEXT) + strlen(numberCStr) + 8); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEND_TEXT) + strlen(numberCStr) + 8); if (command != nullptr) { - sprintf(command, "%s=\"%s\"", UBLOX_AT_SEND_TEXT, numberCStr); + sprintf(command, "%s=\"%s\"", UBX_CELL_SEND_TEXT, numberCStr); err = sendCommandWithResponse(command, ">", nullptr, - UBLOX_AT_10_SEC_TIMEOUT); + UBX_CELL_10_SEC_TIMEOUT); free(command); free(numberCStr); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) return err; - messageCStr = ublox_at_calloc_char(message.length() + 1); + messageCStr = ubx_cell_calloc_char(message.length() + 1); if (messageCStr == nullptr) { hwWrite(ASCII_CTRL_Z); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } message.toCharArray(messageCStr, message.length() + 1); messageCStr[message.length()] = ASCII_CTRL_Z; - err = sendCommandWithResponse(messageCStr, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_10_SEC_TIMEOUT, minimumResponseAllocation, NOT_AT_COMMAND); + err = sendCommandWithResponse(messageCStr, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_10_SEC_TIMEOUT, minimumResponseAllocation, NOT_AT_COMMAND); free(messageCStr); } else { free(numberCStr); - err = UBLOX_AT_ERROR_OUT_OF_MEMORY; + err = UBX_CELL_ERROR_OUT_OF_MEMORY; } return err; } -UBLOX_AT_error_t UBLOX_AT::getPreferredMessageStorage(int *used, int *total, String memory) +UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, String memory) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; int u; int t; - command = ublox_at_calloc_char(strlen(UBLOX_AT_PREF_MESSAGE_STORE) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_PREF_MESSAGE_STORE) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBLOX_AT_PREF_MESSAGE_STORE, memory.c_str()); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_PREF_MESSAGE_STORE, memory.c_str()); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_3_MIN_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_3_MIN_TIMEOUT); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { free(command); free(response); @@ -2386,7 +2386,7 @@ UBLOX_AT_error_t UBLOX_AT::getPreferredMessageStorage(int *used, int *total, Str } else { - err = UBLOX_AT_ERROR_INVALID; + err = UBX_CELL_ERROR_INVALID; } free(response); @@ -2394,28 +2394,28 @@ UBLOX_AT_error_t UBLOX_AT::getPreferredMessageStorage(int *used, int *total, Str return err; } -UBLOX_AT_error_t UBLOX_AT::readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message) +UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; - command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_TEXT_MESSAGE) + 5); + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_TEXT_MESSAGE) + 5); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_READ_TEXT_MESSAGE, location); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_READ_TEXT_MESSAGE, location); - response = ublox_at_calloc_char(1024); + response = ubx_cell_calloc_char(1024); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_10_SEC_TIMEOUT, 1024); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_10_SEC_TIMEOUT, 1024); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = response; @@ -2435,7 +2435,7 @@ UBLOX_AT_error_t UBLOX_AT::readSMSmessage(int location, String *unread, String * { free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Search to the next quote searchPtr = strchr(++searchPtr, '\"'); @@ -2449,7 +2449,7 @@ UBLOX_AT_error_t UBLOX_AT::readSMSmessage(int location, String *unread, String * { free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Skip two commas searchPtr = strchr(++searchPtr, ','); @@ -2466,7 +2466,7 @@ UBLOX_AT_error_t UBLOX_AT::readSMSmessage(int location, String *unread, String * { free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Search to the next new line searchPtr = strchr(++searchPtr, '\n'); @@ -2480,17 +2480,17 @@ UBLOX_AT_error_t UBLOX_AT::readSMSmessage(int location, String *unread, String * { free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } } else { - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } } else { - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -2499,125 +2499,125 @@ UBLOX_AT_error_t UBLOX_AT::readSMSmessage(int location, String *unread, String * return err; } -UBLOX_AT_error_t UBLOX_AT::deleteSMSmessage(int location, int deleteFlag) +UBX_CELL_error_t UBX_CELL::deleteSMSmessage(int location, int deleteFlag) { char *command; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - command = ublox_at_calloc_char(strlen(UBLOX_AT_DELETE_MESSAGE) + 12); + command = ubx_cell_calloc_char(strlen(UBX_CELL_DELETE_MESSAGE) + 12); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; if (deleteFlag == 0) - sprintf(command, "%s=%d", UBLOX_AT_DELETE_MESSAGE, location); + sprintf(command, "%s=%d", UBX_CELL_DELETE_MESSAGE, location); else - sprintf(command, "%s=%d,%d", UBLOX_AT_DELETE_MESSAGE, location, deleteFlag); + sprintf(command, "%s=%d,%d", UBX_CELL_DELETE_MESSAGE, location, deleteFlag); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_55_SECS_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_55_SECS_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setBaud(unsigned long baud) +UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; int b = 0; // Error check -- ensure supported baud for (; b < NUM_SUPPORTED_BAUD; b++) { - if (UBLOX_AT_SUPPORTED_BAUD[b] == baud) + if (UBX_CELL_SUPPORTED_BAUD[b] == baud) { break; } } if (b >= NUM_SUPPORTED_BAUD) { - return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + return UBX_CELL_ERROR_UNEXPECTED_PARAM; } // Construct command - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_BAUD) + 7 + 12); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_BAUD) + 7 + 12); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%lu", UBLOX_AT_COMMAND_BAUD, baud); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%lu", UBX_CELL_COMMAND_BAUD, baud); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_SET_BAUD_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_SET_BAUD_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setFlowControl(UBLOX_AT_flow_control_t value) +UBX_CELL_error_t UBX_CELL::setFlowControl(UBX_CELL_flow_control_t value) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_FLOW_CONTROL) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_FLOW_CONTROL) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s%d", UBLOX_AT_FLOW_CONTROL, value); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s%d", UBX_CELL_FLOW_CONTROL, value); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setGpioMode(UBLOX_AT_gpio_t gpio, - UBLOX_AT_gpio_mode_t mode, int value) +UBX_CELL_error_t UBX_CELL::setGpioMode(UBX_CELL_gpio_t gpio, + UBX_CELL_gpio_mode_t mode, int value) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; // Example command: AT+UGPIOC=16,2 // Example command: AT+UGPIOC=23,0,1 - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_GPIO) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GPIO) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; if (mode == GPIO_OUTPUT) - sprintf(command, "%s=%d,%d,%d", UBLOX_AT_COMMAND_GPIO, gpio, mode, value); + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode, value); else - sprintf(command, "%s=%d,%d", UBLOX_AT_COMMAND_GPIO, gpio, mode); + sprintf(command, "%s=%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_10_SEC_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_10_SEC_TIMEOUT); free(command); return err; } -UBLOX_AT::UBLOX_AT_gpio_mode_t UBLOX_AT::getGpioMode(UBLOX_AT_gpio_t gpio) +UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; char gpioChar[4]; char *gpioStart; int gpioMode; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_GPIO) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GPIO) + 2); if (command == nullptr) return GPIO_MODE_INVALID; - sprintf(command, "%s?", UBLOX_AT_COMMAND_GPIO); + sprintf(command, "%s?", UBX_CELL_COMMAND_GPIO); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); return GPIO_MODE_INVALID; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { free(command); free(response); @@ -2634,26 +2634,26 @@ UBLOX_AT::UBLOX_AT_gpio_mode_t UBLOX_AT::getGpioMode(UBLOX_AT_gpio_t gpio) return GPIO_MODE_INVALID; // If not found return invalid sscanf(gpioStart, "%*d,%d\r\n", &gpioMode); - return (UBLOX_AT_gpio_mode_t)gpioMode; + return (UBX_CELL_gpio_mode_t)gpioMode; } -int UBLOX_AT::socketOpen(UBLOX_AT_socket_protocol_t protocol, unsigned int localPort) +int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int localPort) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; int sockId = -1; char *responseStart; - command = ublox_at_calloc_char(strlen(UBLOX_AT_CREATE_SOCKET) + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_CREATE_SOCKET) + 10); if (command == nullptr) return -1; if (localPort == 0) - sprintf(command, "%s=%d", UBLOX_AT_CREATE_SOCKET, (int)protocol); + sprintf(command, "%s=%d", UBX_CELL_CREATE_SOCKET, (int)protocol); else - sprintf(command, "%s=%d,%d", UBLOX_AT_CREATE_SOCKET, (int)protocol, localPort); + sprintf(command, "%s=%d,%d", UBX_CELL_CREATE_SOCKET, (int)protocol, localPort); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { if (_printDebug == true) @@ -2662,10 +2662,10 @@ int UBLOX_AT::socketOpen(UBLOX_AT_socket_protocol_t protocol, unsigned int local return -1; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -2705,29 +2705,29 @@ int UBLOX_AT::socketOpen(UBLOX_AT_socket_protocol_t protocol, unsigned int local return sockId; } -UBLOX_AT_error_t UBLOX_AT::socketClose(int socket, unsigned long timeout) +UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; - command = ublox_at_calloc_char(strlen(UBLOX_AT_CLOSE_SOCKET) + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_CLOSE_SOCKET) + 10); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - response = ublox_at_calloc_char(minimumResponseAllocation); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } // if timeout is short, close asynchronously and don't wait for socket closure (we will get the URC later) // this will make sure the AT command parser is not confused during init() - const char* format = (UBLOX_AT_STANDARD_RESPONSE_TIMEOUT == timeout) ? "%s=%d,1" : "%s=%d"; - sprintf(command, format, UBLOX_AT_CLOSE_SOCKET, socket); + const char* format = (UBX_CELL_STANDARD_RESPONSE_TIMEOUT == timeout) ? "%s=%d,1" : "%s=%d"; + sprintf(command, format, UBX_CELL_CLOSE_SOCKET, socket); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, timeout); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, timeout); - if ((err != UBLOX_AT_ERROR_SUCCESS) && (_printDebug == true)) + if ((err != UBX_CELL_ERROR_SUCCESS) && (_printDebug == true)) { _debugPort->print(F("socketClose: Error: ")); _debugPort->println(socketGetLastError()); @@ -2739,58 +2739,58 @@ UBLOX_AT_error_t UBLOX_AT::socketClose(int socket, unsigned long timeout) return err; } -UBLOX_AT_error_t UBLOX_AT::socketConnect(int socket, const char *address, +UBX_CELL_error_t UBX_CELL::socketConnect(int socket, const char *address, unsigned int port) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_CONNECT_SOCKET) + strlen(address) + 11); + command = ubx_cell_calloc_char(strlen(UBX_CELL_CONNECT_SOCKET) + strlen(address) + 11); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\",%d", UBLOX_AT_CONNECT_SOCKET, socket, address, port); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\",%d", UBX_CELL_CONNECT_SOCKET, socket, address, port); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_IP_CONNECT_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_IP_CONNECT_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::socketConnect(int socket, IPAddress address, +UBX_CELL_error_t UBX_CELL::socketConnect(int socket, IPAddress address, unsigned int port) { - char *charAddress = ublox_at_calloc_char(16); + char *charAddress = ubx_cell_calloc_char(16); if (charAddress == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; memset(charAddress, 0, 16); sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); return (socketConnect(socket, (const char *)charAddress, port)); } -UBLOX_AT_error_t UBLOX_AT::socketWrite(int socket, const char *str, int len) +UBX_CELL_error_t UBX_CELL::socketWrite(int socket, const char *str, int len) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - command = ublox_at_calloc_char(strlen(UBLOX_AT_WRITE_SOCKET) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_WRITE_SOCKET) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - response = ublox_at_calloc_char(minimumResponseAllocation); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } int dataLen = len == -1 ? strlen(str) : len; - sprintf(command, "%s=%d,%d", UBLOX_AT_WRITE_SOCKET, socket, dataLen); + sprintf(command, "%s=%d,%d", UBX_CELL_WRITE_SOCKET, socket, dataLen); err = sendCommandWithResponse(command, "@", response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT * 5); + UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { unsigned long writeDelay = millis(); while (millis() < (writeDelay + 50)) @@ -2816,10 +2816,10 @@ UBLOX_AT_error_t UBLOX_AT::socketWrite(int socket, const char *str, int len) hwWriteData(str, len); } - err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_SOCKET_WRITE_TIMEOUT); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_SOCKET_WRITE_TIMEOUT); } - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -2836,33 +2836,33 @@ UBLOX_AT_error_t UBLOX_AT::socketWrite(int socket, const char *str, int len) return err; } -UBLOX_AT_error_t UBLOX_AT::socketWrite(int socket, String str) +UBX_CELL_error_t UBX_CELL::socketWrite(int socket, String str) { return socketWrite(socket, str.c_str(), str.length()); } -UBLOX_AT_error_t UBLOX_AT::socketWriteUDP(int socket, const char *address, int port, const char *str, int len) +UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int port, const char *str, int len) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int dataLen = len == -1 ? strlen(str) : len; - command = ublox_at_calloc_char(64); + command = ubx_cell_calloc_char(64); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - response = ublox_at_calloc_char(minimumResponseAllocation); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,\"%s\",%d,%d", UBLOX_AT_WRITE_UDP_SOCKET, + sprintf(command, "%s=%d,\"%s\",%d,%d", UBX_CELL_WRITE_UDP_SOCKET, socket, address, port, dataLen); - err = sendCommandWithResponse(command, "@", response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT * 5); + err = sendCommandWithResponse(command, "@", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { if (len == -1) //If binary data we need to send a length. { @@ -2872,7 +2872,7 @@ UBLOX_AT_error_t UBLOX_AT::socketWriteUDP(int socket, const char *address, int p { hwWriteData(str, len); } - err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_SOCKET_WRITE_TIMEOUT); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_SOCKET_WRITE_TIMEOUT); } else { @@ -2887,30 +2887,30 @@ UBLOX_AT_error_t UBLOX_AT::socketWriteUDP(int socket, const char *address, int p return err; } -UBLOX_AT_error_t UBLOX_AT::socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len) +UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len) { - char *charAddress = ublox_at_calloc_char(16); + char *charAddress = ubx_cell_calloc_char(16); if (charAddress == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; memset(charAddress, 0, 16); sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); return (socketWriteUDP(socket, (const char *)charAddress, port, str, len)); } -UBLOX_AT_error_t UBLOX_AT::socketWriteUDP(int socket, String address, int port, String str) +UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, String address, int port, String str) { return socketWriteUDP(socket, address.c_str(), port, str.c_str(), str.length()); } -UBLOX_AT_error_t UBLOX_AT::socketRead(int socket, int length, char *readDest, int *bytesRead) +UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, int *bytesRead) { char *command; char *response; char *strBegin; int readIndexTotal = 0; int readIndexThisRead = 0; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int readLength = 0; int socketStore = 0; @@ -2926,22 +2926,22 @@ UBLOX_AT_error_t UBLOX_AT::socketRead(int socket, int length, char *readDest, in { if (_printDebug == true) _debugPort->print(F("socketRead: length is 0! Call socketReadAvailable?")); - return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + return UBX_CELL_ERROR_UNEXPECTED_PARAM; } // Allocate memory for the command - command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_SOCKET) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_SOCKET) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; // Allocate memory for the response // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing - int responseLength = _saraR5maxSocketRead + strlen(UBLOX_AT_READ_SOCKET) + minimumResponseAllocation; - response = ublox_at_calloc_char(responseLength); + int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_SOCKET) + minimumResponseAllocation; + response = ubx_cell_calloc_char(responseLength); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } // If there are more than _saraR5maxSocketRead (1024) bytes to be read, @@ -2954,12 +2954,12 @@ UBLOX_AT_error_t UBLOX_AT::socketRead(int socket, int length, char *readDest, in else bytesToRead = bytesLeftToRead; - sprintf(command, "%s=%d,%d", UBLOX_AT_READ_SOCKET, socket, bytesToRead); + sprintf(command, "%s=%d,%d", UBX_CELL_READ_SOCKET, socket, bytesToRead); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, responseLength); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT, responseLength); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -2989,7 +2989,7 @@ UBLOX_AT_error_t UBLOX_AT::socketRead(int socket, int length, char *readDest, in } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Check that readLength == bytesToRead @@ -3013,7 +3013,7 @@ UBLOX_AT_error_t UBLOX_AT::socketRead(int socket, int length, char *readDest, in } free(command); free(response); - return UBLOX_AT_ERROR_ZERO_READ_LENGTH; + return UBX_CELL_ERROR_ZERO_READ_LENGTH; } // Find the first double-quote: @@ -3023,7 +3023,7 @@ UBLOX_AT_error_t UBLOX_AT::socketRead(int socket, int length, char *readDest, in { free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Now copy the data into readDest @@ -3060,34 +3060,34 @@ UBLOX_AT_error_t UBLOX_AT::socketRead(int socket, int length, char *readDest, in free(command); free(response); - return UBLOX_AT_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } -UBLOX_AT_error_t UBLOX_AT::socketReadAvailable(int socket, int *length) +UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int readLength = 0; int socketStore = 0; - command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_SOCKET) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_SOCKET) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,0", UBLOX_AT_READ_SOCKET, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,0", UBX_CELL_READ_SOCKET, socket); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USORD:"); if (searchPtr != nullptr) @@ -3106,7 +3106,7 @@ UBLOX_AT_error_t UBLOX_AT::socketReadAvailable(int socket, int *length) } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *length = readLength; @@ -3118,7 +3118,7 @@ UBLOX_AT_error_t UBLOX_AT::socketReadAvailable(int socket, int *length) return err; } -UBLOX_AT_error_t UBLOX_AT::socketReadUDP(int socket, int length, char *readDest, +UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress, int *remotePort, int *bytesRead) { char *command; @@ -3126,7 +3126,7 @@ UBLOX_AT_error_t UBLOX_AT::socketReadUDP(int socket, int length, char *readDest, char *strBegin; int readIndexTotal = 0; int readIndexThisRead = 0; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int remoteIPstore[4] = { 0, 0, 0, 0 }; int portStore = 0; @@ -3144,22 +3144,22 @@ UBLOX_AT_error_t UBLOX_AT::socketReadUDP(int socket, int length, char *readDest, { if (_printDebug == true) _debugPort->print(F("socketReadUDP: length is 0! Call socketReadAvailableUDP?")); - return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + return UBX_CELL_ERROR_UNEXPECTED_PARAM; } // Allocate memory for the command - command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_UDP_SOCKET) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_UDP_SOCKET) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; // Allocate memory for the response // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing - int responseLength = _saraR5maxSocketRead + strlen(UBLOX_AT_READ_UDP_SOCKET) + minimumResponseAllocation; - response = ublox_at_calloc_char(responseLength); + int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_UDP_SOCKET) + minimumResponseAllocation; + response = ubx_cell_calloc_char(responseLength); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } // If there are more than _saraR5maxSocketRead (1024) bytes to be read, @@ -3172,12 +3172,12 @@ UBLOX_AT_error_t UBLOX_AT::socketReadUDP(int socket, int length, char *readDest, else bytesToRead = bytesLeftToRead; - sprintf(command, "%s=%d,%d", UBLOX_AT_READ_UDP_SOCKET, socket, bytesToRead); + sprintf(command, "%s=%d,%d", UBX_CELL_READ_UDP_SOCKET, socket, bytesToRead); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, responseLength); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT, responseLength); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -3208,7 +3208,7 @@ UBLOX_AT_error_t UBLOX_AT::socketReadUDP(int socket, int length, char *readDest, } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Check that readLength == bytesToRead @@ -3232,7 +3232,7 @@ UBLOX_AT_error_t UBLOX_AT::socketReadUDP(int socket, int length, char *readDest, } free(command); free(response); - return UBLOX_AT_ERROR_ZERO_READ_LENGTH; + return UBX_CELL_ERROR_ZERO_READ_LENGTH; } // Find the third double-quote @@ -3244,7 +3244,7 @@ UBLOX_AT_error_t UBLOX_AT::socketReadUDP(int socket, int length, char *readDest, { free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Now copy the data into readDest @@ -3298,34 +3298,34 @@ UBLOX_AT_error_t UBLOX_AT::socketReadUDP(int socket, int length, char *readDest, free(command); free(response); - return UBLOX_AT_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } -UBLOX_AT_error_t UBLOX_AT::socketReadAvailableUDP(int socket, int *length) +UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int readLength = 0; int socketStore = 0; - command = ublox_at_calloc_char(strlen(UBLOX_AT_READ_UDP_SOCKET) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_UDP_SOCKET) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,0", UBLOX_AT_READ_UDP_SOCKET, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,0", UBX_CELL_READ_UDP_SOCKET, socket); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USORF:"); if (searchPtr != nullptr) @@ -3344,7 +3344,7 @@ UBLOX_AT_error_t UBLOX_AT::socketReadAvailableUDP(int socket, int *length) } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *length = readLength; @@ -3356,149 +3356,149 @@ UBLOX_AT_error_t UBLOX_AT::socketReadAvailableUDP(int socket, int *length) return err; } -UBLOX_AT_error_t UBLOX_AT::socketListen(int socket, unsigned int port) +UBX_CELL_error_t UBX_CELL::socketListen(int socket, unsigned int port) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_LISTEN_SOCKET) + 9); + command = ubx_cell_calloc_char(strlen(UBX_CELL_LISTEN_SOCKET) + 9); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBLOX_AT_LISTEN_SOCKET, socket, port); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", UBX_CELL_LISTEN_SOCKET, socket, port); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::socketDirectLinkMode(int socket) +UBX_CELL_error_t UBX_CELL::socketDirectLinkMode(int socket) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_DIRECT_LINK) + 8); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_DIRECT_LINK) + 8); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_SOCKET_DIRECT_LINK, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_SOCKET_DIRECT_LINK, socket); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_CONNECT, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger) +UBX_CELL_error_t UBX_CELL::socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger) { // valid range is 0 (trigger disabled), 100-120000 if (!((timerTrigger == 0) || ((timerTrigger >= 100) && (timerTrigger <= 120000)))) - return UBLOX_AT_ERROR_ERROR; + return UBX_CELL_ERROR_ERROR; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_UD_CONFIGURATION) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=5,%d,%ld", UBLOX_AT_UD_CONFIGURATION, socket, timerTrigger); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=5,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, timerTrigger); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger) +UBX_CELL_error_t UBX_CELL::socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger) { // valid range is 0, 3-1472 for UDP if (!((dataLengthTrigger == 0) || ((dataLengthTrigger >= 3) && (dataLengthTrigger <= 1472)))) - return UBLOX_AT_ERROR_ERROR; + return UBX_CELL_ERROR_ERROR; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_UD_CONFIGURATION) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=6,%d,%d", UBLOX_AT_UD_CONFIGURATION, socket, dataLengthTrigger); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=6,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, dataLengthTrigger); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::socketDirectLinkCharacterTrigger(int socket, int characterTrigger) +UBX_CELL_error_t UBX_CELL::socketDirectLinkCharacterTrigger(int socket, int characterTrigger) { // The allowed range is -1, 0-255, the factory-programmed value is -1; -1 means trigger disabled. if (!((characterTrigger >= -1) && (characterTrigger <= 255))) - return UBLOX_AT_ERROR_ERROR; + return UBX_CELL_ERROR_ERROR; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_UD_CONFIGURATION) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=7,%d,%d", UBLOX_AT_UD_CONFIGURATION, socket, characterTrigger); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=7,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, characterTrigger); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer) +UBX_CELL_error_t UBX_CELL::socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer) { // valid range is 0, 1000-72000 if (!((congestionTimer == 0) || ((congestionTimer >= 1000) && (congestionTimer <= 72000)))) - return UBLOX_AT_ERROR_ERROR; + return UBX_CELL_ERROR_ERROR; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_UD_CONFIGURATION) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=8,%d,%ld", UBLOX_AT_UD_CONFIGURATION, socket, congestionTimer); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=8,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, congestionTimer); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::querySocketType(int socket, UBLOX_AT_socket_protocol_t *protocol) +UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; int paramVal; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,0", UBLOX_AT_SOCKET_CONTROL, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,0", UBX_CELL_SOCKET_CONTROL, socket); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USOCTL:"); if (searchPtr != nullptr) @@ -3517,10 +3517,10 @@ UBLOX_AT_error_t UBLOX_AT::querySocketType(int socket, UBLOX_AT_socket_protocol_ } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - *protocol = (UBLOX_AT_socket_protocol_t)paramVal; + *protocol = (UBX_CELL_socket_protocol_t)paramVal; _lastSocketProtocol[socketStore] = paramVal; } @@ -3530,31 +3530,31 @@ UBLOX_AT_error_t UBLOX_AT::querySocketType(int socket, UBLOX_AT_socket_protocol_ return err; } -UBLOX_AT_error_t UBLOX_AT::querySocketLastError(int socket, int *error) +UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; int paramVal; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,1", UBLOX_AT_SOCKET_CONTROL, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,1", UBX_CELL_SOCKET_CONTROL, socket); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USOCTL:"); if (searchPtr != nullptr) @@ -3573,7 +3573,7 @@ UBLOX_AT_error_t UBLOX_AT::querySocketLastError(int socket, int *error) } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *error = paramVal; @@ -3585,31 +3585,31 @@ UBLOX_AT_error_t UBLOX_AT::querySocketLastError(int socket, int *error) return err; } -UBLOX_AT_error_t UBLOX_AT::querySocketTotalBytesSent(int socket, uint32_t *total) +UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; long unsigned int paramVal; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,2", UBLOX_AT_SOCKET_CONTROL, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,2", UBX_CELL_SOCKET_CONTROL, socket); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USOCTL:"); if (searchPtr != nullptr) @@ -3628,7 +3628,7 @@ UBLOX_AT_error_t UBLOX_AT::querySocketTotalBytesSent(int socket, uint32_t *total } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *total = (uint32_t)paramVal; @@ -3640,31 +3640,31 @@ UBLOX_AT_error_t UBLOX_AT::querySocketTotalBytesSent(int socket, uint32_t *total return err; } -UBLOX_AT_error_t UBLOX_AT::querySocketTotalBytesReceived(int socket, uint32_t *total) +UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *total) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; long unsigned int paramVal; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,3", UBLOX_AT_SOCKET_CONTROL, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,3", UBX_CELL_SOCKET_CONTROL, socket); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USOCTL:"); if (searchPtr != nullptr) @@ -3683,7 +3683,7 @@ UBLOX_AT_error_t UBLOX_AT::querySocketTotalBytesReceived(int socket, uint32_t *t } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *total = (uint32_t)paramVal; @@ -3695,31 +3695,31 @@ UBLOX_AT_error_t UBLOX_AT::querySocketTotalBytesReceived(int socket, uint32_t *t return err; } -UBLOX_AT_error_t UBLOX_AT::querySocketRemoteIPAddress(int socket, IPAddress *address, int *port) +UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *address, int *port) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; int paramVals[5]; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,4", UBLOX_AT_SOCKET_CONTROL, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,4", UBX_CELL_SOCKET_CONTROL, socket); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USOCTL:"); if (searchPtr != nullptr) @@ -3740,7 +3740,7 @@ UBLOX_AT_error_t UBLOX_AT::querySocketRemoteIPAddress(int socket, IPAddress *add } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } IPAddress tempAddress = { (uint8_t)paramVals[0], (uint8_t)paramVals[1], @@ -3755,31 +3755,31 @@ UBLOX_AT_error_t UBLOX_AT::querySocketRemoteIPAddress(int socket, IPAddress *add return err; } -UBLOX_AT_error_t UBLOX_AT::querySocketStatusTCP(int socket, UBLOX_AT_tcp_socket_status_t *status) +UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; int paramVal; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,10", UBLOX_AT_SOCKET_CONTROL, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,10", UBX_CELL_SOCKET_CONTROL, socket); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USOCTL:"); if (searchPtr != nullptr) @@ -3798,10 +3798,10 @@ UBLOX_AT_error_t UBLOX_AT::querySocketStatusTCP(int socket, UBLOX_AT_tcp_socket_ } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - *status = (UBLOX_AT_tcp_socket_status_t)paramVal; + *status = (UBX_CELL_tcp_socket_status_t)paramVal; } free(command); @@ -3810,31 +3810,31 @@ UBLOX_AT_error_t UBLOX_AT::querySocketStatusTCP(int socket, UBLOX_AT_tcp_socket_ return err; } -UBLOX_AT_error_t UBLOX_AT::querySocketOutUnackData(int socket, uint32_t *total) +UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; long unsigned int paramVal; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,11", UBLOX_AT_SOCKET_CONTROL, socket); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,11", UBX_CELL_SOCKET_CONTROL, socket); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USOCTL:"); if (searchPtr != nullptr) @@ -3853,7 +3853,7 @@ UBLOX_AT_error_t UBLOX_AT::querySocketOutUnackData(int socket, uint32_t *total) } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *total = (uint32_t)paramVal; @@ -3866,30 +3866,30 @@ UBLOX_AT_error_t UBLOX_AT::querySocketOutUnackData(int socket, uint32_t *total) } //Issues command to get last socket error, then prints to serial. Also updates rx/backlog buffers. -int UBLOX_AT::socketGetLastError() +int UBX_CELL::socketGetLastError() { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; int errorCode = -1; - command = ublox_at_calloc_char(64); + command = ubx_cell_calloc_char(64); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s", UBLOX_AT_GET_ERROR); + sprintf(command, "%s", UBX_CELL_GET_ERROR); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+USOER:"); if (searchPtr != nullptr) @@ -3906,314 +3906,314 @@ int UBLOX_AT::socketGetLastError() return errorCode; } -IPAddress UBLOX_AT::lastRemoteIP(void) +IPAddress UBX_CELL::lastRemoteIP(void) { return _lastRemoteIP; } -UBLOX_AT_error_t UBLOX_AT::resetHTTPprofile(int profile) +UBX_CELL_error_t UBX_CELL::resetHTTPprofile(int profile) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_HTTP_PROFILE, profile); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_HTTP_PROFILE, profile); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setHTTPserverIPaddress(int profile, IPAddress address) +UBX_CELL_error_t UBX_CELL::setHTTPserverIPaddress(int profile, IPAddress address) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 64); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 64); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SERVER_IP, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_IP, address[0], address[1], address[2], address[3]); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setHTTPserverName(int profile, String server) +UBX_CELL_error_t UBX_CELL::setHTTPserverName(int profile, String server) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 12 + server.length()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + server.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SERVER_NAME, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_NAME, server.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setHTTPusername(int profile, String username) +UBX_CELL_error_t UBX_CELL::setHTTPusername(int profile, String username) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 12 + username.length()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + username.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_USERNAME, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_USERNAME, username.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setHTTPpassword(int profile, String password) +UBX_CELL_error_t UBX_CELL::setHTTPpassword(int profile, String password) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 12 + password.length()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + password.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_PASSWORD, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_PASSWORD, password.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setHTTPauthentication(int profile, bool authenticate) +UBX_CELL_error_t UBX_CELL::setHTTPauthentication(int profile, bool authenticate) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_AUTHENTICATION, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, authenticate); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setHTTPserverPort(int profile, int port) +UBX_CELL_error_t UBX_CELL::setHTTPserverPort(int profile, int port) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SERVER_PORT, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_PORT, port); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setHTTPcustomHeader(int profile, String header) +UBX_CELL_error_t UBX_CELL::setHTTPcustomHeader(int profile, String header) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 12 + header.length()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + header.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_ADD_CUSTOM_HEADERS, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS, header.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setHTTPsecure(int profile, bool secure, int secprofile) +UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofile) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROFILE) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; if (secprofile == -1) - sprintf(command, "%s=%d,%d,%d", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SECURE, + sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure); - else sprintf(command, "%s=%d,%d,%d,%d", UBLOX_AT_HTTP_PROFILE, profile, UBLOX_AT_HTTP_OP_CODE_SECURE, + else sprintf(command, "%s=%d,%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure, secprofile); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::ping(String remote_host, int retry, int p_size, +UBX_CELL_error_t UBX_CELL::ping(String remote_host, int retry, int p_size, unsigned long timeout, int ttl) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_PING_COMMAND) + 48 + + command = ubx_cell_calloc_char(strlen(UBX_CELL_PING_COMMAND) + 48 + remote_host.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\",%d,%d,%ld,%d", UBLOX_AT_PING_COMMAND, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\",%d,%d,%ld,%d", UBX_CELL_PING_COMMAND, remote_host.c_str(), retry, p_size, timeout, ttl); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::sendHTTPGET(int profile, String path, String responseFilename) +UBX_CELL_error_t UBX_CELL::sendHTTPGET(int profile, String path, String responseFilename) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_COMMAND) + 24 + + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\",\"%s\"", UBLOX_AT_HTTP_COMMAND, profile, UBLOX_AT_HTTP_COMMAND_GET, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\",\"%s\"", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_GET, path.c_str(), responseFilename.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::sendHTTPPOSTdata(int profile, String path, String responseFilename, - String data, UBLOX_AT_http_content_types_t httpContentType) +UBX_CELL_error_t UBX_CELL::sendHTTPPOSTdata(int profile, String path, String responseFilename, + String data, UBX_CELL_http_content_types_t httpContentType) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_COMMAND) + 24 + + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length() + data.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBLOX_AT_HTTP_COMMAND, profile, UBLOX_AT_HTTP_COMMAND_POST_DATA, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_POST_DATA, path.c_str(), responseFilename.c_str(), data.c_str(), httpContentType); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::sendHTTPPOSTfile(int profile, String path, String responseFilename, - String requestFile, UBLOX_AT_http_content_types_t httpContentType) +UBX_CELL_error_t UBX_CELL::sendHTTPPOSTfile(int profile, String path, String responseFilename, + String requestFile, UBX_CELL_http_content_types_t httpContentType) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_HTTP_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_COMMAND) + 24 + + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length() + requestFile.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBLOX_AT_HTTP_COMMAND, profile, UBLOX_AT_HTTP_COMMAND_POST_FILE, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_POST_FILE, path.c_str(), responseFilename.c_str(), requestFile.c_str(), httpContentType); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getHTTPprotocolError(int profile, int *error_class, int *error_code) +UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, int *error_code) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; int rprofile, eclass, ecode; - command = ublox_at_calloc_char(strlen(UBLOX_AT_HTTP_PROTOCOL_ERROR) + 4); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROTOCOL_ERROR) + 4); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_HTTP_PROTOCOL_ERROR, profile); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_HTTP_PROTOCOL_ERROR, profile); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; char *searchPtr = strstr(response, "+UHTTPER:"); @@ -4230,7 +4230,7 @@ UBLOX_AT_error_t UBLOX_AT::getHTTPprotocolError(int profile, int *error_class, i *error_code = ecode; } else - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -4238,139 +4238,139 @@ UBLOX_AT_error_t UBLOX_AT::getHTTPprotocolError(int profile, int *error_class, i return err; } -UBLOX_AT_error_t UBLOX_AT::nvMQTT(UBLOX_AT_mqtt_nv_parameter_t parameter) +UBX_CELL_error_t UBX_CELL::nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_NVM) + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_NVM) + 10); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_MQTT_NVM, parameter); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_MQTT_NVM, parameter); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setMQTTclientId(const String& clientId) +UBX_CELL_error_t UBX_CELL::setMQTTclientId(const String& clientId) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_PROFILE) + clientId.length() + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + clientId.length() + 10); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\"", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_CLIENT_ID, clientId.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_CLIENT_ID, clientId.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setMQTTserver(const String& serverName, int port) +UBX_CELL_error_t UBX_CELL::setMQTTserver(const String& serverName, int port) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_PROFILE) + serverName.length() + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + serverName.length() + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\",%d", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_SERVERNAME, serverName.c_str(), port); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\",%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SERVERNAME, serverName.c_str(), port); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setMQTTcredentials(const String& userName, const String& pwd) +UBX_CELL_error_t UBX_CELL::setMQTTcredentials(const String& userName, const String& pwd) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_PROFILE) + userName.length() + pwd.length() + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + userName.length() + pwd.length() + 16); if (command == nullptr) { - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,\"%s\",\"%s\"", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_USERNAMEPWD, userName.c_str(), pwd.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_USERNAMEPWD, userName.c_str(), pwd.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setMQTTsecure(bool secure, int secprofile) +UBX_CELL_error_t UBX_CELL::setMQTTsecure(bool secure, int secprofile) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_PROFILE) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - if (secprofile == -1) sprintf(command, "%s=%d,%d", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_SECURE, secure); - else sprintf(command, "%s=%d,%d,%d", UBLOX_AT_MQTT_PROFILE, UBLOX_AT_MQTT_PROFILE_SECURE, secure, secprofile); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (secprofile == -1) sprintf(command, "%s=%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure); + else sprintf(command, "%s=%d,%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure, secprofile); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::connectMQTT(void) +UBX_CELL_error_t UBX_CELL::connectMQTT(void) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_LOGIN); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGIN); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::disconnectMQTT(void) +UBX_CELL_error_t UBX_CELL::disconnectMQTT(void) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_LOGOUT); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::subscribeMQTTtopic(int max_Qos, const String& topic) +UBX_CELL_error_t UBX_CELL::subscribeMQTTtopic(int max_Qos, const String& topic) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 16 + topic.length()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_SUBSCRIBE, max_Qos, topic.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_SUBSCRIBE, max_Qos, topic.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::unsubscribeMQTTtopic(const String& topic) +UBX_CELL_error_t UBX_CELL::unsubscribeMQTTtopic(const String& topic) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 16 + topic.length()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length()); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\"", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_UNSUBSCRIBE, topic.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_UNSUBSCRIBE, topic.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::readMQTT(int* pQos, String* pTopic, uint8_t *readDest, int readLength, int *bytesRead) +UBX_CELL_error_t UBX_CELL::readMQTT(int* pQos, String* pTopic, uint8_t *readDest, int readLength, int *bytesRead) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int total_length, topic_length, data_length; @@ -4379,27 +4379,27 @@ UBLOX_AT_error_t UBLOX_AT::readMQTT(int* pQos, String* pTopic, uint8_t *readDest *bytesRead = 0; // Allocate memory for the command - command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; // Allocate memory for the response int responseLength = readLength + minimumResponseAllocation; - response = ublox_at_calloc_char(responseLength); + response = ubx_cell_calloc_char(responseLength); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... // To try and avoid this, look for \"\r\n\r\nOK\r\n there is a extra \r\n beetween " and the the standard \r\nOK\r\n const char mqttReadTerm[] = "\"\r\n\r\nOK\r\n"; - sprintf(command, "%s=%d,%d", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_READ, 1); + sprintf(command, "%s=%d,%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_READ, 1); err = sendCommandWithResponse(command, mqttReadTerm, response, - (5 * UBLOX_AT_STANDARD_RESPONSE_TIMEOUT), responseLength); + (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), responseLength); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -4420,7 +4420,7 @@ UBLOX_AT_error_t UBLOX_AT::readMQTT(int* pQos, String* pTopic, uint8_t *readDest while (*searchPtr == ' ') searchPtr++; // skip spaces scanNum = sscanf(searchPtr, "%d,%d,%d,%d,\"%*[^\"]\",%d,\"", &cmd, pQos, &total_length, &topic_length, &data_length); } - if ((scanNum != 5) || (cmd != UBLOX_AT_MQTT_COMMAND_READ)) + if ((scanNum != 5) || (cmd != UBX_CELL_MQTT_COMMAND_READ)) { if (_printDebug == true) { @@ -4429,10 +4429,10 @@ UBLOX_AT_error_t UBLOX_AT::readMQTT(int* pQos, String* pTopic, uint8_t *readDest } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - err = UBLOX_AT_ERROR_SUCCESS; + err = UBX_CELL_ERROR_SUCCESS; searchPtr = strstr(searchPtr, "\""); if (searchPtr!= nullptr) { if (pTopic) { @@ -4447,7 +4447,7 @@ UBLOX_AT_error_t UBLOX_AT::readMQTT(int* pQos, String* pTopic, uint8_t *readDest if (_printDebug == true) { _debugPort->print(F("readMQTT: error: trucate message")); } - err = UBLOX_AT_ERROR_OUT_OF_MEMORY; + err = UBX_CELL_ERROR_OUT_OF_MEMORY; } memcpy(readDest, searchPtr+1, data_length); *bytesRead = data_length; @@ -4455,7 +4455,7 @@ UBLOX_AT_error_t UBLOX_AT::readMQTT(int* pQos, String* pTopic, uint8_t *readDest if (_printDebug == true) { _debugPort->print(F("readMQTT: error: message end ")); } - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } } free(command); @@ -4464,14 +4464,14 @@ UBLOX_AT_error_t UBLOX_AT::readMQTT(int* pQos, String* pTopic, uint8_t *readDest return err; } -UBLOX_AT_error_t UBLOX_AT::mqttPublishTextMsg(const String& topic, const char * const msg, uint8_t qos, bool retain) +UBX_CELL_error_t UBX_CELL::mqttPublishTextMsg(const String& topic, const char * const msg, uint8_t qos, bool retain) { if (topic.length() < 1 || msg == nullptr) { - return UBLOX_AT_ERROR_INVALID; + return UBX_CELL_ERROR_INVALID; } - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char sanitized_msg[MAX_MQTT_DIRECT_MSG_LEN + 1]; memset(sanitized_msg, 0, sizeof(sanitized_msg)); @@ -4495,27 +4495,27 @@ UBLOX_AT_error_t UBLOX_AT::mqttPublishTextMsg(const String& topic, const char * msg_ptr++; } - char *command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 20 + topic.length() + msg_len); + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + msg_len); if (command == nullptr) { - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,%u,%u,0,\"%s\",\"%s\"", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_PUBLISH, qos, (retain ? 1:0), topic.c_str(), sanitized_msg); + sprintf(command, "%s=%d,%u,%u,0,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISH, qos, (retain ? 1:0), topic.c_str(), sanitized_msg); sendCommand(command, true); - err = waitForResponse(UBLOX_AT_RESPONSE_MORE, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = waitForResponse(UBX_CELL_RESPONSE_MORE, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { sendCommand(msg, false); - err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::mqttPublishBinaryMsg(const String& topic, const char * const msg, size_t msg_len, uint8_t qos, bool retain) +UBX_CELL_error_t UBX_CELL::mqttPublishBinaryMsg(const String& topic, const char * const msg, size_t msg_len, uint8_t qos, bool retain) { /* * The modem prints the '>' as the signal to send the binary message content. @@ -4528,70 +4528,70 @@ UBLOX_AT_error_t UBLOX_AT::mqttPublishBinaryMsg(const String& topic, const char */ if (topic.length() < 1|| msg == nullptr || msg_len > MAX_MQTT_DIRECT_MSG_LEN) { - return UBLOX_AT_ERROR_INVALID; + return UBX_CELL_ERROR_INVALID; } - UBLOX_AT_error_t err; - char *command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 20 + topic.length()); + UBX_CELL_error_t err; + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length()); if (command == nullptr) { - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,%u,%u,\"%s\",%u", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_PUBLISHBINARY, qos, (retain ? 1:0), topic.c_str(), msg_len); + sprintf(command, "%s=%d,%u,%u,\"%s\",%u", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, qos, (retain ? 1:0), topic.c_str(), msg_len); sendCommand(command, true); - err = waitForResponse(UBLOX_AT_RESPONSE_MORE, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = waitForResponse(UBX_CELL_RESPONSE_MORE, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { sendCommand(msg, false); - err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::mqttPublishFromFile(const String& topic, const String& filename, uint8_t qos, bool retain) +UBX_CELL_error_t UBX_CELL::mqttPublishFromFile(const String& topic, const String& filename, uint8_t qos, bool retain) { if (topic.length() < 1|| filename.length() < 1) { - return UBLOX_AT_ERROR_INVALID; + return UBX_CELL_ERROR_INVALID; } - UBLOX_AT_error_t err; - char *command = ublox_at_calloc_char(strlen(UBLOX_AT_MQTT_COMMAND) + 20 + topic.length() + filename.length()); + UBX_CELL_error_t err; + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + filename.length()); if (command == nullptr) { - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,%u,%u,\"%s\",\"%s\"", UBLOX_AT_MQTT_COMMAND, UBLOX_AT_MQTT_COMMAND_PUBLISHFILE, qos, (retain ? 1:0), topic.c_str(), filename.c_str()); + sprintf(command, "%s=%d,%u,%u,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHFILE, qos, (retain ? 1:0), topic.c_str(), filename.c_str()); sendCommand(command, true); - err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getMQTTprotocolError(int *error_code, int *error_code2) +UBX_CELL_error_t UBX_CELL::getMQTTprotocolError(int *error_code, int *error_code2) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *response; int code, code2; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(UBLOX_AT_MQTT_PROTOCOL_ERROR, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(UBX_CELL_MQTT_PROTOCOL_ERROR, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; char *searchPtr = strstr(response, "+UMQTTER:"); @@ -4608,109 +4608,109 @@ UBLOX_AT_error_t UBLOX_AT::getMQTTprotocolError(int *error_code, int *error_code *error_code2 = code2; } else - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(response); return err; } -UBLOX_AT_error_t UBLOX_AT::setFTPserver(const String& serverName) +UBX_CELL_error_t UBX_CELL::setFTPserver(const String& serverName) { constexpr size_t cmd_len = 145; char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> - snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBLOX_AT_FTP_PROFILE, UBLOX_AT_FTP_PROFILE_SERVERNAME, serverName.c_str()); - return sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_SERVERNAME, serverName.c_str()); + return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } -UBLOX_AT_error_t UBLOX_AT::setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger) +UBX_CELL_error_t UBX_CELL::setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger) { constexpr size_t cmd_len = 64; char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> - snprintf(command, cmd_len - 1, "%s=%d,%u,%u,%u", UBLOX_AT_FTP_PROFILE, UBLOX_AT_FTP_PROFILE_TIMEOUT, timeout, cmd_linger, data_linger); - return sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + snprintf(command, cmd_len - 1, "%s=%d,%u,%u,%u", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_TIMEOUT, timeout, cmd_linger, data_linger); + return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } -UBLOX_AT_error_t UBLOX_AT::setFTPcredentials(const String& userName, const String& pwd) +UBX_CELL_error_t UBX_CELL::setFTPcredentials(const String& userName, const String& pwd) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; constexpr size_t cmd_len = 48; char command[cmd_len]; // long enough for AT+UFTP=n,<30 bytes> - snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBLOX_AT_FTP_PROFILE, UBLOX_AT_FTP_PROFILE_USERNAME, userName.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err != UBLOX_AT_ERROR_SUCCESS) + snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_USERNAME, userName.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err != UBX_CELL_ERROR_SUCCESS) { return err; } - snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBLOX_AT_FTP_PROFILE, UBLOX_AT_FTP_PROFILE_PWD, pwd.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_PWD, pwd.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); return err; } -UBLOX_AT_error_t UBLOX_AT::connectFTP(void) +UBX_CELL_error_t UBX_CELL::connectFTP(void) { constexpr size_t cmd_len = 16; char command[cmd_len]; // long enough for AT+UFTPC=n - snprintf(command, cmd_len - 1, "%s=%d", UBLOX_AT_FTP_COMMAND, UBLOX_AT_FTP_COMMAND_LOGIN); - return sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + snprintf(command, cmd_len - 1, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGIN); + return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } -UBLOX_AT_error_t UBLOX_AT::disconnectFTP(void) +UBX_CELL_error_t UBX_CELL::disconnectFTP(void) { constexpr size_t cmd_len = 16; char command[cmd_len]; // long enough for AT+UFTPC=n - snprintf(command, cmd_len - 1, "%s=%d", UBLOX_AT_FTP_COMMAND, UBLOX_AT_FTP_COMMAND_LOGOUT); - return sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + snprintf(command, cmd_len - 1, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGOUT); + return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } -UBLOX_AT_error_t UBLOX_AT::ftpGetFile(const String& filename) +UBX_CELL_error_t UBX_CELL::ftpGetFile(const String& filename) { - char * command = ublox_at_calloc_char(strlen(UBLOX_AT_FTP_COMMAND) + (2 * filename.length()) + 16); + char * command = ubx_cell_calloc_char(strlen(UBX_CELL_FTP_COMMAND) + (2 * filename.length()) + 16); if (command == nullptr) { - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,\"%s\",\"%s\"", UBLOX_AT_FTP_COMMAND, UBLOX_AT_FTP_COMMAND_GET_FILE, filename.c_str(), filename.c_str()); + sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_GET_FILE, filename.c_str(), filename.c_str()); //memset(response, 0, sizeof(response)); - //sendCommandWithResponse(command, UBLOX_AT_RESPONSE_CONNECT, response, 8000 /* ms */, response_len); - UBLOX_AT_error_t err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + //sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, response, 8000 /* ms */, response_len); + UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getFTPprotocolError(int *error_code, int *error_code2) +UBX_CELL_error_t UBX_CELL::getFTPprotocolError(int *error_code, int *error_code2) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *response; int code, code2; - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(UBLOX_AT_FTP_PROTOCOL_ERROR, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(UBX_CELL_FTP_PROTOCOL_ERROR, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; char *searchPtr = strstr(response, "+UFTPER:"); @@ -4731,7 +4731,7 @@ UBLOX_AT_error_t UBLOX_AT::getFTPprotocolError(int *error_code, int *error_code2 } else { - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } } @@ -4739,73 +4739,73 @@ UBLOX_AT_error_t UBLOX_AT::getFTPprotocolError(int *error_code, int *error_code2 return err; } -UBLOX_AT_error_t UBLOX_AT::resetSecurityProfile(int secprofile) +UBX_CELL_error_t UBX_CELL::resetSecurityProfile(int secprofile) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SEC_PROFILE) + 6); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + 6); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_SEC_PROFILE, secprofile); + sprintf(command, "%s=%d", UBX_CELL_SEC_PROFILE, secprofile); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::configSecurityProfile(int secprofile, UBLOX_AT_sec_profile_parameter_t parameter, int value) +UBX_CELL_error_t UBX_CELL::configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SEC_PROFILE) + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + 10); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBLOX_AT_SEC_PROFILE, secprofile,parameter,value); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_SEC_PROFILE, secprofile,parameter,value); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::configSecurityProfileString(int secprofile, UBLOX_AT_sec_profile_parameter_t parameter, String value) +UBX_CELL_error_t UBX_CELL::configSecurityProfileString(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, String value) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SEC_PROFILE) + value.length() + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + value.length() + 10); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_SEC_PROFILE, secprofile,parameter,value.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_SEC_PROFILE, secprofile,parameter,value.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setSecurityManager(UBLOX_AT_sec_manager_opcode_t opcode, UBLOX_AT_sec_manager_parameter_t parameter, String name, String data) +UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, UBX_CELL_sec_manager_parameter_t parameter, String name, String data) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - command = ublox_at_calloc_char(strlen(UBLOX_AT_SEC_MANAGER) + name.length() + 20); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_MANAGER) + name.length() + 20); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - response = ublox_at_calloc_char(minimumResponseAllocation); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } int dataLen = data.length(); - sprintf(command, "%s=%d,%d,\"%s\",%d", UBLOX_AT_SEC_MANAGER, opcode, parameter, name.c_str(), dataLen); + sprintf(command, "%s=%d,%d,\"%s\",%d", UBX_CELL_SEC_MANAGER, opcode, parameter, name.c_str(), dataLen); - err = sendCommandWithResponse(command, ">", response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(command, ">", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -4814,11 +4814,11 @@ UBLOX_AT_error_t UBLOX_AT::setSecurityManager(UBLOX_AT_sec_manager_opcode_t opco _debugPort->println(F(" bytes")); } hwWriteData(data.c_str(), dataLen); - err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT*3); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT*3); } - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -4835,143 +4835,143 @@ UBLOX_AT_error_t UBLOX_AT::setSecurityManager(UBLOX_AT_sec_manager_opcode_t opco return err; } -UBLOX_AT_error_t UBLOX_AT::setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, int value) +UBX_CELL_error_t UBX_CELL::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_PSD_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_CONFIG) + 24); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBLOX_AT_MESSAGE_PDP_CONFIG, profile, parameter, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, UBLOX_AT_pdp_protocol_type_t value) +UBX_CELL_error_t UBX_CELL::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, UBX_CELL_pdp_protocol_type_t value) { return (setPDPconfiguration(profile, parameter, (int)value)); } -UBLOX_AT_error_t UBLOX_AT::setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, String value) +UBX_CELL_error_t UBX_CELL::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, String value) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_PSD_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_CONFIG) + 64); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBLOX_AT_MESSAGE_PDP_CONFIG, profile, parameter, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, IPAddress value) +UBX_CELL_error_t UBX_CELL::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_PSD_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_CONFIG) + 64); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBLOX_AT_MESSAGE_PDP_CONFIG, profile, parameter, + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value[0], value[1], value[2], value[3]); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::performPDPaction(int profile, UBLOX_AT_pdp_actions_t action) +UBX_CELL_error_t UBX_CELL::performPDPaction(int profile, UBX_CELL_pdp_actions_t action) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (profile >= UBLOX_AT_NUM_PSD_PROFILES) - return UBLOX_AT_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_ACTION) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBLOX_AT_MESSAGE_PDP_ACTION, profile, action); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_ACTION, profile, action); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::activatePDPcontext(bool status, int cid) +UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - if (cid >= UBLOX_AT_NUM_PDP_CONTEXT_IDENTIFIERS) - return UBLOX_AT_ERROR_ERROR; + if (cid >= UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) + return UBX_CELL_ERROR_ERROR; - command = ublox_at_calloc_char(strlen(UBLOX_AT_MESSAGE_PDP_CONTEXT_ACTIVATE) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE) + 32); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; if (cid == -1) - sprintf(command, "%s=%d", UBLOX_AT_MESSAGE_PDP_CONTEXT_ACTIVATE, status); + sprintf(command, "%s=%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status); else - sprintf(command, "%s=%d,%d", UBLOX_AT_MESSAGE_PDP_CONTEXT_ACTIVATE, status, cid); + sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status, cid); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getNetworkAssignedIPAddress(int profile, IPAddress *address) +UBX_CELL_error_t UBX_CELL::getNetworkAssignedIPAddress(int profile, IPAddress *address) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; int scanNum = 0; int profileStore = 0; int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation int paramVals[4]; - command = ublox_at_calloc_char(strlen(UBLOX_AT_NETWORK_ASSIGNED_DATA) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBLOX_AT_NETWORK_ASSIGNED_DATA, profile, paramTag); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", UBX_CELL_NETWORK_ASSIGNED_DATA, profile, paramTag); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { char *searchPtr = strstr(response, "+UPSND:"); if (searchPtr != nullptr) @@ -4991,7 +4991,7 @@ UBLOX_AT_error_t UBLOX_AT::getNetworkAssignedIPAddress(int profile, IPAddress *a } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } IPAddress tempAddress = { (uint8_t)paramVals[0], (uint8_t)paramVals[1], @@ -5005,29 +5005,29 @@ UBLOX_AT_error_t UBLOX_AT::getNetworkAssignedIPAddress(int profile, IPAddress *a return err; } -bool UBLOX_AT::isGPSon(void) +bool UBX_CELL::isGPSon(void) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; bool on = false; - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_POWER) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_POWER) + 2); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_GNSS_POWER); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_POWER); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, - UBLOX_AT_10_SEC_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_10_SEC_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { // Example response: "+UGPS: 0" for off "+UGPS: 1,0,1" for on // Search for a ':' followed by a '1' or ' 1' @@ -5046,9 +5046,9 @@ bool UBLOX_AT::isGPSon(void) return on; } -UBLOX_AT_error_t UBLOX_AT::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_aiding_mode_t gnss_aiding) +UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_aiding_mode_t gnss_aiding) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; bool gpsState; @@ -5056,90 +5056,90 @@ UBLOX_AT_error_t UBLOX_AT::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_ai gpsState = isGPSon(); if ((enable && gpsState) || (!enable && !gpsState)) { - return UBLOX_AT_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } // GPS power management - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_POWER) + 32); // gnss_sys could be up to three digits + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_POWER) + 32); // gnss_sys could be up to three digits if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; if (enable) { - sprintf(command, "%s=1,%d,%d", UBLOX_AT_GNSS_POWER, gnss_aiding, gnss_sys); + sprintf(command, "%s=1,%d,%d", UBX_CELL_GNSS_POWER, gnss_aiding, gnss_sys); } else { - sprintf(command, "%s=0", UBLOX_AT_GNSS_POWER); + sprintf(command, "%s=0", UBX_CELL_GNSS_POWER); } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, 10000); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, 10000); free(command); return err; } /* -UBLOX_AT_error_t UBLOX_AT::gpsEnableClock(bool enable) +UBX_CELL_error_t UBX_CELL::gpsEnableClock(bool enable) { // AT+UGZDA=<0,1> - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBLOX_AT_error_t UBLOX_AT::gpsGetClock(struct ClockData *clock) +UBX_CELL_error_t UBX_CELL::gpsGetClock(struct ClockData *clock) { // AT+UGZDA? - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBLOX_AT_error_t UBLOX_AT::gpsEnableFix(bool enable) +UBX_CELL_error_t UBX_CELL::gpsEnableFix(bool enable) { // AT+UGGGA=<0,1> - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBLOX_AT_error_t UBLOX_AT::gpsGetFix(struct PositionData *pos) +UBX_CELL_error_t UBX_CELL::gpsGetFix(struct PositionData *pos) { // AT+UGGGA? - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBLOX_AT_error_t UBLOX_AT::gpsEnablePos(bool enable) +UBX_CELL_error_t UBX_CELL::gpsEnablePos(bool enable) { // AT+UGGLL=<0,1> - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBLOX_AT_error_t UBLOX_AT::gpsGetPos(struct PositionData *pos) +UBX_CELL_error_t UBX_CELL::gpsGetPos(struct PositionData *pos) { // AT+UGGLL? - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBLOX_AT_error_t UBLOX_AT::gpsEnableSat(bool enable) +UBX_CELL_error_t UBX_CELL::gpsEnableSat(bool enable) { // AT+UGGSV=<0,1> - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBLOX_AT_error_t UBLOX_AT::gpsGetSat(uint8_t *sats) +UBX_CELL_error_t UBX_CELL::gpsGetSat(uint8_t *sats) { // AT+UGGSV? - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } */ -UBLOX_AT_error_t UBLOX_AT::gpsEnableRmc(bool enable) +UBX_CELL_error_t UBX_CELL::gpsEnableRmc(bool enable) { // AT+UGRMC=<0,1> - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; // ** Don't call gpsPower here. It causes problems for +UTIME and the PPS signal ** @@ -5147,51 +5147,51 @@ UBLOX_AT_error_t UBLOX_AT::gpsEnableRmc(bool enable) // if (!isGPSon()) // { // err = gpsPower(true); - // if (err != UBLOX_AT_ERROR_SUCCESS) + // if (err != UBX_CELL_ERROR_SUCCESS) // { // return err; // } // } - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_GPRMC) + 3); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_GPRMC) + 3); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_GNSS_GPRMC, enable ? 1 : 0); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_GNSS_GPRMC, enable ? 1 : 0); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_10_SEC_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::gpsGetRmc(struct PositionData *pos, struct SpeedData *spd, +UBX_CELL_error_t UBX_CELL::gpsGetRmc(struct PositionData *pos, struct SpeedData *spd, struct ClockData *clk, bool *valid) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; char *rmcBegin; - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_GPRMC) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_GPRMC) + 2); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_GNSS_GPRMC); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_GPRMC); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_10_SEC_TIMEOUT); - if (err == UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { // Fast-forward response string to $GPRMC starter rmcBegin = strstr(response, "$GPRMC"); if (rmcBegin == nullptr) { - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } else { @@ -5205,26 +5205,26 @@ UBLOX_AT_error_t UBLOX_AT::gpsGetRmc(struct PositionData *pos, struct SpeedData } /* -UBLOX_AT_error_t UBLOX_AT::gpsEnableSpeed(bool enable) +UBX_CELL_error_t UBX_CELL::gpsEnableSpeed(bool enable) { // AT+UGVTG=<0,1> - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBLOX_AT_error_t UBLOX_AT::gpsGetSpeed(struct SpeedData *speed) +UBX_CELL_error_t UBX_CELL::gpsGetSpeed(struct SpeedData *speed) { // AT+UGVTG? - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } */ -UBLOX_AT_error_t UBLOX_AT::gpsRequest(unsigned int timeout, uint32_t accuracy, +UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, bool detailed, unsigned int sensor) { // AT+ULOC=2,,,, - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; // This function will only work if the GPS module is initially turned off. @@ -5238,40 +5238,40 @@ UBLOX_AT_error_t UBLOX_AT::gpsRequest(unsigned int timeout, uint32_t accuracy, if (accuracy > 999999) accuracy = 999999; - command = ublox_at_calloc_char(strlen(UBLOX_AT_GNSS_REQUEST_LOCATION) + 24); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_LOCATION) + 24); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - sprintf(command, "%s=2,%d,%d,%d,%d", UBLOX_AT_GNSS_REQUEST_LOCATION, + sprintf(command, "%s=2,%d,%d,%d,%d", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); #else - sprintf(command, "%s=2,%d,%d,%d,%ld", UBLOX_AT_GNSS_REQUEST_LOCATION, + sprintf(command, "%s=2,%d,%d,%d,%ld", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); #endif - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_10_SEC_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, +UBX_CELL_error_t UBX_CELL::gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, unsigned int days, unsigned int period, unsigned int resolution, unsigned int gnssTypes, unsigned int mode, unsigned int dataType) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_AIDING_SERVER_CONFIGURATION) + 256); + command = ubx_cell_calloc_char(strlen(UBX_CELL_AIDING_SERVER_CONFIGURATION) + 256); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBLOX_AT_AIDING_SERVER_CONFIGURATION, + sprintf(command, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBX_CELL_AIDING_SERVER_CONFIGURATION, primaryServer, secondaryServer, authToken, days, period, resolution, gnssTypes, mode, dataType); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -5279,32 +5279,32 @@ UBLOX_AT_error_t UBLOX_AT::gpsAidingServerConf(const char *primaryServer, const // OK for text files. But will fail with binary files (containing \0) on some platforms. -UBLOX_AT_error_t UBLOX_AT::appendFileContents(String filename, const char *str, int len) +UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, const char *str, int len) { char *command; char *response; - UBLOX_AT_error_t err; + UBX_CELL_error_t err; - command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_DOWNLOAD_FILE) + filename.length() + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE) + filename.length() + 10); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - response = ublox_at_calloc_char(minimumResponseAllocation); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } int dataLen = len == -1 ? strlen(str) : len; - sprintf(command, "%s=\"%s\",%d", UBLOX_AT_FILE_SYSTEM_DOWNLOAD_FILE, filename.c_str(), dataLen); + sprintf(command, "%s=\"%s\",%d", UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE, filename.c_str(), dataLen); err = sendCommandWithResponse(command, ">", response, - UBLOX_AT_STANDARD_RESPONSE_TIMEOUT*2); + UBX_CELL_STANDARD_RESPONSE_TIMEOUT*2); unsigned long writeDelay = millis(); while (millis() < (writeDelay + 50)) delay(1); //uBlox specification says to wait 50ms after receiving "@" to write data. - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -5314,9 +5314,9 @@ UBLOX_AT_error_t UBLOX_AT::appendFileContents(String filename, const char *str, } hwWriteData(str, dataLen); - err = waitForResponse(UBLOX_AT_RESPONSE_OK, UBLOX_AT_RESPONSE_ERROR, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT*5); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT*5); } - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -5333,23 +5333,23 @@ UBLOX_AT_error_t UBLOX_AT::appendFileContents(String filename, const char *str, return err; } -UBLOX_AT_error_t UBLOX_AT::appendFileContents(String filename, String str) +UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, String str) { return appendFileContents(filename, str.c_str(), str.length()); } // OK for text files. But will fail with binary files (containing \0) on some platforms. -UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, String *contents) +UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; // Start by getting the file size so we know in advance how much data to expect int fileSize = 0; err = getFileSize(filename, &fileSize); - if (err != UBLOX_AT_SUCCESS) + if (err != UBX_CELL_SUCCESS) { if (_printDebug == true) { @@ -5359,12 +5359,12 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, String *contents) return err; } - command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_READ_FILE) + filename.length() + 8); + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBLOX_AT_FILE_SYSTEM_READ_FILE, filename.c_str()); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); - response = ublox_at_calloc_char(fileSize + minimumResponseAllocation); + response = ubx_cell_calloc_char(fileSize + minimumResponseAllocation); if (response == nullptr) { if (_printDebug == true) @@ -5373,7 +5373,7 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, String *contents) _debugPort->println(fileSize + minimumResponseAllocation); } free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } // A large file will completely fill the backlog buffer - but it will be pruned afterwards @@ -5381,10 +5381,10 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, String *contents) // To try and avoid this, look for \"\r\nOK\r\n const char fileReadTerm[] = "\r\nOK\r\n"; //LARA-R6 returns "\"\r\n\r\nOK\r\n" while SARA-R5 return "\"\r\nOK\r\n"; err = sendCommandWithResponse(command, fileReadTerm, - response, (5 * UBLOX_AT_STANDARD_RESPONSE_TIMEOUT), + response, (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), (fileSize + minimumResponseAllocation)); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -5418,7 +5418,7 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, String *contents) } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } int bytesRead = 0; @@ -5437,7 +5437,7 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, String *contents) _debugPort->print(F("getFileContents: total bytes read: ")); _debugPort->println(bytesRead); } - err = UBLOX_AT_ERROR_SUCCESS; + err = UBX_CELL_ERROR_SUCCESS; } else { @@ -5446,14 +5446,14 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, String *contents) _debugPort->print(F("getFileContents: sscanf failed! scanned is ")); _debugPort->println(scanned); } - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } } else { if (_printDebug == true) _debugPort->println(F("getFileContents: strstr failed!")); - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -5462,16 +5462,16 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, String *contents) } // OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. -UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, char *contents) +UBX_CELL_error_t UBX_CELL::getFileContents(String filename, char *contents) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; // Start by getting the file size so we know in advance how much data to expect int fileSize = 0; err = getFileSize(filename, &fileSize); - if (err != UBLOX_AT_SUCCESS) + if (err != UBX_CELL_SUCCESS) { if (_printDebug == true) { @@ -5481,12 +5481,12 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, char *contents) return err; } - command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_READ_FILE) + filename.length() + 8); + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBLOX_AT_FILE_SYSTEM_READ_FILE, filename.c_str()); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); - response = ublox_at_calloc_char(fileSize + minimumResponseAllocation); + response = ubx_cell_calloc_char(fileSize + minimumResponseAllocation); if (response == nullptr) { if (_printDebug == true) @@ -5495,7 +5495,7 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, char *contents) _debugPort->println(fileSize + minimumResponseAllocation); } free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } // A large file will completely fill the backlog buffer - but it will be pruned afterwards @@ -5503,10 +5503,10 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, char *contents) // To try and avoid this, look for \"\r\nOK\r\n const char fileReadTerm[] = "\"\r\nOK\r\n"; err = sendCommandWithResponse(command, fileReadTerm, - response, (5 * UBLOX_AT_STANDARD_RESPONSE_TIMEOUT), + response, (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), (fileSize + minimumResponseAllocation)); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -5540,7 +5540,7 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, char *contents) } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } int bytesRead = 0; @@ -5556,7 +5556,7 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, char *contents) _debugPort->print(F("getFileContents: total bytes read: ")); _debugPort->println(bytesRead); } - err = UBLOX_AT_ERROR_SUCCESS; + err = UBX_CELL_ERROR_SUCCESS; } else { @@ -5565,14 +5565,14 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, char *contents) _debugPort->print(F("getFileContents: sscanf failed! scanned is ")); _debugPort->println(scanned); } - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } } else { if (_printDebug == true) _debugPort->println(F("getFileContents: strstr failed!")); - err = UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } free(command); @@ -5580,12 +5580,12 @@ UBLOX_AT_error_t UBLOX_AT::getFileContents(String filename, char *contents) return err; } -UBLOX_AT_error_t UBLOX_AT::getFileBlock(const String& filename, char* buffer, size_t offset, size_t requested_length, size_t& bytes_read) +UBX_CELL_error_t UBX_CELL::getFileBlock(const String& filename, char* buffer, size_t offset, size_t requested_length, size_t& bytes_read) { bytes_read = 0; if (filename.length() < 1 || buffer == nullptr || requested_length < 1) { - return UBLOX_AT_ERROR_UNEXPECTED_PARAM; + return UBX_CELL_ERROR_UNEXPECTED_PARAM; } // trying to get a byte at a time does not seem to be reliable so this method must use @@ -5596,11 +5596,11 @@ UBLOX_AT_error_t UBLOX_AT::getFileBlock(const String& filename, char* buffer, si { _debugPort->println(F("getFileBlock: only works with a hardware UART")); } - return UBLOX_AT_ERROR_INVALID; + return UBX_CELL_ERROR_INVALID; } size_t cmd_len = filename.length() + 32; - char* cmd = ublox_at_calloc_char(cmd_len); + char* cmd = ubx_cell_calloc_char(cmd_len); sprintf(cmd, "at+urdblock=\"%s\",%zu,%zu\r\n", filename.c_str(), offset, requested_length); sendCommand(cmd, false); @@ -5646,29 +5646,29 @@ UBLOX_AT_error_t UBLOX_AT::getFileBlock(const String& filename, char* buffer, si bytes_remaining -= rc; } - return UBLOX_AT_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } -UBLOX_AT_error_t UBLOX_AT::getFileSize(String filename, int *size) +UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; - command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_LIST_FILES) + filename.length() + 8); + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_LIST_FILES) + filename.length() + 8); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=2,\"%s\"", UBLOX_AT_FILE_SYSTEM_LIST_FILES, filename.c_str()); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=2,\"%s\"", UBX_CELL_FILE_SYSTEM_LIST_FILES, filename.c_str()); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err != UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -5694,7 +5694,7 @@ UBLOX_AT_error_t UBLOX_AT::getFileSize(String filename, int *size) } free(command); free(response); - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } int fileSize; @@ -5708,19 +5708,19 @@ UBLOX_AT_error_t UBLOX_AT::getFileSize(String filename, int *size) return err; } -UBLOX_AT_error_t UBLOX_AT::deleteFile(String filename) +UBX_CELL_error_t UBX_CELL::deleteFile(String filename) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_FILE_SYSTEM_DELETE_FILE) + filename.length() + 8); + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_DELETE_FILE) + filename.length() + 8); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBLOX_AT_FILE_SYSTEM_DELETE_FILE, filename.c_str()); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_DELETE_FILE, filename.c_str()); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) { @@ -5733,25 +5733,25 @@ UBLOX_AT_error_t UBLOX_AT::deleteFile(String filename) return err; } -UBLOX_AT_error_t UBLOX_AT::modulePowerOff(void) +UBX_CELL_error_t UBX_CELL::modulePowerOff(void) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_POWER_OFF) + 6); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_POWER_OFF) + 6); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s", UBLOX_AT_COMMAND_POWER_OFF); + sprintf(command, "%s", UBX_CELL_COMMAND_POWER_OFF); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, nullptr, - UBLOX_AT_POWER_OFF_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_POWER_OFF_TIMEOUT); free(command); return err; } -void UBLOX_AT::modulePowerOn(void) +void UBX_CELL::modulePowerOn(void) { if (_powerPin >= 0) { @@ -5768,11 +5768,11 @@ void UBLOX_AT::modulePowerOn(void) // Private // ///////////// -UBLOX_AT_error_t UBLOX_AT::init(unsigned long baud, - UBLOX_AT::UBLOX_AT_init_type_t initType) +UBX_CELL_error_t UBX_CELL::init(unsigned long baud, + UBX_CELL::UBX_CELL_init_type_t initType) { int retries = _maxInitTries; - UBLOX_AT_error_t err = UBLOX_AT_ERROR_SUCCESS; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; beginSerial(baud); @@ -5781,52 +5781,52 @@ UBLOX_AT_error_t UBLOX_AT::init(unsigned long baud, if (_printDebug == true) _debugPort->println(F("init: Begin module init.")); - if (initType == UBLOX_AT_INIT_AUTOBAUD) + if (initType == UBX_CELL_INIT_AUTOBAUD) { if (_printDebug == true) _debugPort->println(F("init: Attempting autobaud connection to module.")); err = autobaud(baud); - if (err != UBLOX_AT_ERROR_SUCCESS) { - initType = UBLOX_AT_INIT_RESET; + if (err != UBX_CELL_ERROR_SUCCESS) { + initType = UBX_CELL_INIT_RESET; } } - else if (initType == UBLOX_AT_INIT_RESET) + else if (initType == UBX_CELL_INIT_RESET) { if (_printDebug == true) _debugPort->println(F("init: Power cycling module.")); powerOff(); - delay(UBLOX_AT_POWER_OFF_PULSE_PERIOD); + delay(UBX_CELL_POWER_OFF_PULSE_PERIOD); powerOn(); beginSerial(baud); delay(2000); err = at(); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { - initType = UBLOX_AT_INIT_AUTOBAUD; + initType = UBX_CELL_INIT_AUTOBAUD; } } - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { err = enableEcho(false); // = disableEcho - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) _debugPort->println(F("init: Module failed echo test.")); - initType = UBLOX_AT_INIT_AUTOBAUD; + initType = UBX_CELL_INIT_AUTOBAUD; } } } - while ((retries --) && (err != UBLOX_AT_ERROR_SUCCESS)); + while ((retries --) && (err != UBX_CELL_ERROR_SUCCESS)); // we tried but seems failed - if (err != UBLOX_AT_ERROR_SUCCESS) { + if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) _debugPort->println(F("init: Module failed to init. Exiting.")); - return (UBLOX_AT_ERROR_NO_RESPONSE); + return (UBX_CELL_ERROR_NO_RESPONSE); } if (_printDebug == true) @@ -5836,24 +5836,24 @@ UBLOX_AT_error_t UBLOX_AT::init(unsigned long baud, setGpioMode(GPIO1, NETWORK_STATUS); //setGpioMode(GPIO2, GNSS_SUPPLY_ENABLE); setGpioMode(GPIO6, TIME_PULSE_OUTPUT); - setSMSMessageFormat(UBLOX_AT_MESSAGE_FORMAT_TEXT); + setSMSMessageFormat(UBX_CELL_MESSAGE_FORMAT_TEXT); autoTimeZone(_autoTimeZoneForBegin); - for (int i = 0; i < UBLOX_AT_NUM_SOCKETS; i++) + for (int i = 0; i < UBX_CELL_NUM_SOCKETS; i++) { - socketClose(i, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + socketClose(i, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } - return UBLOX_AT_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } -void UBLOX_AT::invertPowerPin(bool invert) +void UBX_CELL::invertPowerPin(bool invert) { _invertPowerPin = invert; } -// Do a graceful power off. Hold the PWR_ON pin low for UBLOX_AT_POWER_OFF_PULSE_PERIOD +// Do a graceful power off. Hold the PWR_ON pin low for UBX_CELL_POWER_OFF_PULSE_PERIOD // Note: +CPWROFF () is preferred to this. -void UBLOX_AT::powerOff(void) +void UBX_CELL::powerOff(void) { if (_powerPin >= 0) { @@ -5866,14 +5866,14 @@ void UBLOX_AT::powerOff(void) digitalWrite(_powerPin, HIGH); else digitalWrite(_powerPin, LOW); - delay(UBLOX_AT_POWER_OFF_PULSE_PERIOD); + delay(UBX_CELL_POWER_OFF_PULSE_PERIOD); pinMode(_powerPin, INPUT); // Return to high-impedance, rely on (e.g.) SARA module internal pull-up if (_printDebug == true) _debugPort->println(F("powerOff: complete")); } } -void UBLOX_AT::powerOn(void) +void UBX_CELL::powerOn(void) { if (_powerPin >= 0) { @@ -5886,7 +5886,7 @@ void UBLOX_AT::powerOn(void) digitalWrite(_powerPin, HIGH); else digitalWrite(_powerPin, LOW); - delay(UBLOX_AT_POWER_ON_PULSE_PERIOD); + delay(UBX_CELL_POWER_ON_PULSE_PERIOD); pinMode(_powerPin, INPUT); // Return to high-impedance, rely on (e.g.) SARA module internal pull-up //delay(2000); // Do this in init. Wait before sending AT commands to module. 100 is too short. if (_printDebug == true) @@ -5897,7 +5897,7 @@ void UBLOX_AT::powerOn(void) //This does an abrupt emergency hardware shutdown of the SARA-R5 series modules. //It only works if you have access to both the RESET_N and PWR_ON pins. //You cannot use this function on the SparkFun Asset Tracker and RESET_N is tied to the MicroMod processor !RESET!... -void UBLOX_AT::hwReset(void) +void UBX_CELL::hwReset(void) { if ((_resetPin >= 0) && (_powerPin >= 0)) { @@ -5918,7 +5918,7 @@ void UBLOX_AT::hwReset(void) digitalWrite(_powerPin, LOW); } - delay(UBLOX_AT_RESET_PULSE_PERIOD); // Wait 23 seconds... (Yes, really!) + delay(UBX_CELL_RESET_PULSE_PERIOD); // Wait 23 seconds... (Yes, really!) digitalWrite(_resetPin, LOW); // Now pull RESET_N low @@ -5942,48 +5942,48 @@ void UBLOX_AT::hwReset(void) } } -UBLOX_AT_error_t UBLOX_AT::functionality(UBLOX_AT_functionality_t function) +UBX_CELL_error_t UBX_CELL::functionality(UBX_CELL_functionality_t function) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_FUNC) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_FUNC) + 16); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBLOX_AT_COMMAND_FUNC, function); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_COMMAND_FUNC, function); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_3_MIN_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_3_MIN_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::setMNOprofile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) +UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_MNO) + 9); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_MNO) + 9); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; if (mno == MNO_SIM_ICCID) // Only add autoReset and urcNotification if mno is MNO_SIM_ICCID - sprintf(command, "%s=%d,%d,%d", UBLOX_AT_COMMAND_MNO, (uint8_t)mno, (uint8_t)autoReset, (uint8_t)urcNotification); + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno, (uint8_t)autoReset, (uint8_t)urcNotification); else - sprintf(command, "%s=%d", UBLOX_AT_COMMAND_MNO, (uint8_t)mno); + sprintf(command, "%s=%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno); - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - nullptr, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; } -UBLOX_AT_error_t UBLOX_AT::getMNOprofile(mobile_network_operator_t *mno) +UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *command; char *response; mobile_network_operator_t o; @@ -5992,21 +5992,21 @@ UBLOX_AT_error_t UBLOX_AT::getMNOprofile(mobile_network_operator_t *mno) int u; int oStore; - command = ublox_at_calloc_char(strlen(UBLOX_AT_COMMAND_MNO) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_MNO) + 2); if (command == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBLOX_AT_COMMAND_MNO); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_COMMAND_MNO); - response = ublox_at_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { free(command); - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - err = sendCommandWithResponse(command, UBLOX_AT_RESPONSE_OK_OR_ERROR, - response, UBLOX_AT_STANDARD_RESPONSE_TIMEOUT); - if (err != UBLOX_AT_ERROR_SUCCESS) + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err != UBX_CELL_ERROR_SUCCESS) { free(command); free(response); @@ -6034,7 +6034,7 @@ UBLOX_AT_error_t UBLOX_AT::getMNOprofile(mobile_network_operator_t *mno) } else { - err = UBLOX_AT_ERROR_INVALID; + err = UBX_CELL_ERROR_INVALID; } free(command); @@ -6043,7 +6043,7 @@ UBLOX_AT_error_t UBLOX_AT::getMNOprofile(mobile_network_operator_t *mno) return err; } -UBLOX_AT_error_t UBLOX_AT::waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout) +UBX_CELL_error_t UBX_CELL::waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout) { unsigned long timeIn; bool found = false; @@ -6121,13 +6121,13 @@ UBLOX_AT_error_t UBLOX_AT::waitForResponse(const char *expectedResponse, const c _debugAtPort->print((error == true) ? expectedError : expectedResponse); } - return (error == true) ? UBLOX_AT_ERROR_ERROR : UBLOX_AT_ERROR_SUCCESS; + return (error == true) ? UBX_CELL_ERROR_ERROR : UBX_CELL_ERROR_SUCCESS; } - return UBLOX_AT_ERROR_NO_RESPONSE; + return UBX_CELL_ERROR_NO_RESPONSE; } -UBLOX_AT_error_t UBLOX_AT::sendCommandWithResponse( +UBX_CELL_error_t UBX_CELL::sendCommandWithResponse( const char *command, const char *expectedResponse, char *responseDest, unsigned long commandTimeout, int destSize, bool at) { @@ -6151,11 +6151,11 @@ UBLOX_AT_error_t UBLOX_AT::sendCommandWithResponse( sendCommand(command, at); //Sending command needs to dump data to backlog buffer as well. unsigned long timeIn = millis(); - if (UBLOX_AT_RESPONSE_OK_OR_ERROR == expectedResponse) { - expectedResponse = UBLOX_AT_RESPONSE_OK; - expectedError = UBLOX_AT_RESPONSE_ERROR; - responseLen = sizeof(UBLOX_AT_RESPONSE_OK)-1; - errorLen = sizeof(UBLOX_AT_RESPONSE_ERROR)-1; + if (UBX_CELL_RESPONSE_OK_OR_ERROR == expectedResponse) { + expectedResponse = UBX_CELL_RESPONSE_OK; + expectedError = UBX_CELL_RESPONSE_ERROR; + responseLen = sizeof(UBX_CELL_RESPONSE_OK)-1; + errorLen = sizeof(UBX_CELL_RESPONSE_ERROR)-1; } else { responseLen = (int)strlen(expectedResponse); } @@ -6244,30 +6244,30 @@ UBLOX_AT_error_t UBLOX_AT::sendCommandWithResponse( if ((true == _printAtDebug) && ((nullptr != responseDest) || (nullptr != expectedResponse))) { _debugAtPort->print((nullptr != responseDest) ? responseDest : expectedResponse); } - return error ? UBLOX_AT_ERROR_ERROR : UBLOX_AT_ERROR_SUCCESS; + return error ? UBX_CELL_ERROR_ERROR : UBX_CELL_ERROR_SUCCESS; } else if (charsRead == 0) { - return UBLOX_AT_ERROR_NO_RESPONSE; + return UBX_CELL_ERROR_NO_RESPONSE; } else { if ((true == _printAtDebug) && (nullptr != responseDest)) { _debugAtPort->print(responseDest); } - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } } // Send a custom command with an expected (potentially partial) response, store entire response -UBLOX_AT_error_t UBLOX_AT::sendCustomCommandWithResponse(const char *command, const char *expectedResponse, +UBX_CELL_error_t UBX_CELL::sendCustomCommandWithResponse(const char *command, const char *expectedResponse, char *responseDest, unsigned long commandTimeout, bool at) { // Assume the user has allocated enough storage for any response. Set destSize to 32766. return sendCommandWithResponse(command, expectedResponse, responseDest, commandTimeout, 32766, at); } -void UBLOX_AT::sendCommand(const char *command, bool at) +void UBX_CELL::sendCommand(const char *command, bool at) { //Check for incoming serial data. Copy it into the backlog @@ -6304,7 +6304,7 @@ void UBLOX_AT::sendCommand(const char *command, bool at) //Now send the command if (at) { - hwPrint(UBLOX_AT_COMMAND_AT); + hwPrint(UBX_CELL_COMMAND_AT); hwPrint(command); hwPrint("\r\n"); } @@ -6314,27 +6314,27 @@ void UBLOX_AT::sendCommand(const char *command, bool at) } } -UBLOX_AT_error_t UBLOX_AT::parseSocketReadIndication(int socket, int length) +UBX_CELL_error_t UBX_CELL::parseSocketReadIndication(int socket, int length) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *readDest; if ((socket < 0) || (length < 0)) { - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Return now if both callbacks pointers are nullptr - otherwise the data will be read and lost! if ((_socketReadCallback == nullptr) && (_socketReadCallbackPlus == nullptr)) - return UBLOX_AT_ERROR_INVALID; + return UBX_CELL_ERROR_INVALID; - readDest = ublox_at_calloc_char(length + 1); + readDest = ubx_cell_calloc_char(length + 1); if (readDest == nullptr) - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; int bytesRead; err = socketRead(socket, length, readDest, &bytesRead); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { free(readDest); return err; @@ -6360,34 +6360,34 @@ UBLOX_AT_error_t UBLOX_AT::parseSocketReadIndication(int socket, int length) } free(readDest); - return UBLOX_AT_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } -UBLOX_AT_error_t UBLOX_AT::parseSocketReadIndicationUDP(int socket, int length) +UBX_CELL_error_t UBX_CELL::parseSocketReadIndicationUDP(int socket, int length) { - UBLOX_AT_error_t err; + UBX_CELL_error_t err; char *readDest; IPAddress remoteAddress = { 0, 0, 0, 0 }; int remotePort = 0; if ((socket < 0) || (length < 0)) { - return UBLOX_AT_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Return now if both callbacks pointers are nullptr - otherwise the data will be read and lost! if ((_socketReadCallback == nullptr) && (_socketReadCallbackPlus == nullptr)) - return UBLOX_AT_ERROR_INVALID; + return UBX_CELL_ERROR_INVALID; - readDest = ublox_at_calloc_char(length + 1); + readDest = ubx_cell_calloc_char(length + 1); if (readDest == nullptr) { - return UBLOX_AT_ERROR_OUT_OF_MEMORY; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } int bytesRead; err = socketReadUDP(socket, length, readDest, &remoteAddress, &remotePort, &bytesRead); - if (err != UBLOX_AT_ERROR_SUCCESS) + if (err != UBX_CELL_ERROR_SUCCESS) { free(readDest); return err; @@ -6410,10 +6410,10 @@ UBLOX_AT_error_t UBLOX_AT::parseSocketReadIndicationUDP(int socket, int length) } free(readDest); - return UBLOX_AT_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } -UBLOX_AT_error_t UBLOX_AT::parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, int socket, IPAddress remoteIP, unsigned int port) +UBX_CELL_error_t UBX_CELL::parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, int socket, IPAddress remoteIP, unsigned int port) { _lastLocalIP = localIP; _lastRemoteIP = remoteIP; @@ -6423,16 +6423,16 @@ UBLOX_AT_error_t UBLOX_AT::parseSocketListenIndication(int listeningSocket, IPAd _socketListenCallback(listeningSocket, localIP, listeningPort, socket, remoteIP, port); } - return UBLOX_AT_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } -UBLOX_AT_error_t UBLOX_AT::parseSocketCloseIndication(String *closeIndication) +UBX_CELL_error_t UBX_CELL::parseSocketCloseIndication(String *closeIndication) { int search; int socket; - search = closeIndication->indexOf(UBLOX_AT_CLOSE_SOCKET_URC); - search += strlen(UBLOX_AT_CLOSE_SOCKET_URC); + search = closeIndication->indexOf(UBX_CELL_CLOSE_SOCKET_URC); + search += strlen(UBX_CELL_CLOSE_SOCKET_URC); while (closeIndication->charAt(search) == ' ') search ++; // skip spaces // Socket will be first integer, should be single-digit number between 0-6: @@ -6443,10 +6443,10 @@ UBLOX_AT_error_t UBLOX_AT::parseSocketCloseIndication(String *closeIndication) _socketCloseCallback(socket); } - return UBLOX_AT_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } -size_t UBLOX_AT::hwPrint(const char *s) +size_t UBX_CELL::hwPrint(const char *s) { if ((true == _printAtDebug) && (nullptr != s)) { _debugAtPort->print(s); @@ -6455,7 +6455,7 @@ size_t UBLOX_AT::hwPrint(const char *s) { return _hardSerial->print(s); } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED else if (_softSerial != nullptr) { return _softSerial->print(s); @@ -6465,7 +6465,7 @@ size_t UBLOX_AT::hwPrint(const char *s) return (size_t)0; } -size_t UBLOX_AT::hwWriteData(const char *buff, int len) +size_t UBX_CELL::hwWriteData(const char *buff, int len) { if ((true == _printAtDebug) && (nullptr != buff) && (0 < len) ) { _debugAtPort->write(buff,len); @@ -6474,7 +6474,7 @@ size_t UBLOX_AT::hwWriteData(const char *buff, int len) { return _hardSerial->write((const uint8_t *)buff, len); } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED else if (_softSerial != nullptr) { return _softSerial->write((const uint8_t *)buff, len); @@ -6483,7 +6483,7 @@ size_t UBLOX_AT::hwWriteData(const char *buff, int len) return (size_t)0; } -size_t UBLOX_AT::hwWrite(const char c) +size_t UBX_CELL::hwWrite(const char c) { if (true == _printAtDebug) { _debugAtPort->write(c); @@ -6492,7 +6492,7 @@ size_t UBLOX_AT::hwWrite(const char c) { return _hardSerial->write(c); } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED else if (_softSerial != nullptr) { return _softSerial->write(c); @@ -6502,7 +6502,7 @@ size_t UBLOX_AT::hwWrite(const char c) return (size_t)0; } -int UBLOX_AT::readAvailable(char *inString) +int UBX_CELL::readAvailable(char *inString) { int len = 0; @@ -6523,7 +6523,7 @@ int UBLOX_AT::readAvailable(char *inString) //if (_printDebug == true) // _debugPort->println(inString); } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED else if (_softSerial != nullptr) { while (_softSerial->available()) @@ -6544,7 +6544,7 @@ int UBLOX_AT::readAvailable(char *inString) return len; } -char UBLOX_AT::readChar(void) +char UBX_CELL::readChar(void) { char ret = 0; @@ -6552,7 +6552,7 @@ char UBLOX_AT::readChar(void) { ret = (char)_hardSerial->read(); } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED else if (_softSerial != nullptr) { ret = (char)_softSerial->read(); @@ -6562,13 +6562,13 @@ char UBLOX_AT::readChar(void) return ret; } -int UBLOX_AT::hwAvailable(void) +int UBX_CELL::hwAvailable(void) { if (_hardSerial != nullptr) { return _hardSerial->available(); } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED else if (_softSerial != nullptr) { return _softSerial->available(); @@ -6578,7 +6578,7 @@ int UBLOX_AT::hwAvailable(void) return -1; } -void UBLOX_AT::beginSerial(unsigned long baud) +void UBX_CELL::beginSerial(unsigned long baud) { delay(100); if (_hardSerial != nullptr) @@ -6586,7 +6586,7 @@ void UBLOX_AT::beginSerial(unsigned long baud) _hardSerial->end(); _hardSerial->begin(baud); } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED else if (_softSerial != nullptr) { _softSerial->end(); @@ -6596,13 +6596,13 @@ void UBLOX_AT::beginSerial(unsigned long baud) delay(100); } -void UBLOX_AT::setTimeout(unsigned long timeout) +void UBX_CELL::setTimeout(unsigned long timeout) { if (_hardSerial != nullptr) { _hardSerial->setTimeout(timeout); } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED else if (_softSerial != nullptr) { _softSerial->setTimeout(timeout); @@ -6610,14 +6610,14 @@ void UBLOX_AT::setTimeout(unsigned long timeout) #endif } -bool UBLOX_AT::find(char *target) +bool UBX_CELL::find(char *target) { bool found = false; if (_hardSerial != nullptr) { found = _hardSerial->find(target); } -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED else if (_softSerial != nullptr) { found = _softSerial->find(target); @@ -6626,32 +6626,32 @@ bool UBLOX_AT::find(char *target) return found; } -UBLOX_AT_error_t UBLOX_AT::autobaud(unsigned long desiredBaud) +UBX_CELL_error_t UBX_CELL::autobaud(unsigned long desiredBaud) { - UBLOX_AT_error_t err = UBLOX_AT_ERROR_INVALID; + UBX_CELL_error_t err = UBX_CELL_ERROR_INVALID; int b = 0; - while ((err != UBLOX_AT_ERROR_SUCCESS) && (b < NUM_SUPPORTED_BAUD)) + while ((err != UBX_CELL_ERROR_SUCCESS) && (b < NUM_SUPPORTED_BAUD)) { - beginSerial(UBLOX_AT_SUPPORTED_BAUD[b++]); + beginSerial(UBX_CELL_SUPPORTED_BAUD[b++]); setBaud(desiredBaud); beginSerial(desiredBaud); err = at(); } - if (err == UBLOX_AT_ERROR_SUCCESS) + if (err == UBX_CELL_ERROR_SUCCESS) { beginSerial(desiredBaud); } return err; } -char *UBLOX_AT::ublox_at_calloc_char(size_t num) +char *UBX_CELL::ubx_cell_calloc_char(size_t num) { return (char *)calloc(num, sizeof(char)); } //This prunes the backlog of non-actionable events. If new actionable events are added, you must modify the if statement. -void UBLOX_AT::pruneBacklog() +void UBX_CELL::pruneBacklog() { char *event; @@ -6679,19 +6679,19 @@ void UBLOX_AT::pruneBacklog() while (event != nullptr) //If event is actionable, add it to pruneBuffer. { // These are the events we want to keep so they can be processed by poll / bufferedPoll - if ((strstr(event, UBLOX_AT_READ_SOCKET_URC) != nullptr) - || (strstr(event, UBLOX_AT_READ_UDP_SOCKET_URC) != nullptr) - || (strstr(event, UBLOX_AT_LISTEN_SOCKET_URC) != nullptr) - || (strstr(event, UBLOX_AT_CLOSE_SOCKET_URC) != nullptr) - || (strstr(event, UBLOX_AT_GNSS_REQUEST_LOCATION_URC) != nullptr) - || (strstr(event, UBLOX_AT_SIM_STATE_URC) != nullptr) - || (strstr(event, UBLOX_AT_MESSAGE_PDP_ACTION_URC) != nullptr) - || (strstr(event, UBLOX_AT_HTTP_COMMAND_URC) != nullptr) - || (strstr(event, UBLOX_AT_MQTT_COMMAND_URC) != nullptr) - || (strstr(event, UBLOX_AT_PING_COMMAND_URC) != nullptr) - || (strstr(event, UBLOX_AT_REGISTRATION_STATUS_URC) != nullptr) - || (strstr(event, UBLOX_AT_EPSREGISTRATION_STATUS_URC) != nullptr) - || (strstr(event, UBLOX_AT_FTP_COMMAND_URC) != nullptr)) + if ((strstr(event, UBX_CELL_READ_SOCKET_URC) != nullptr) + || (strstr(event, UBX_CELL_READ_UDP_SOCKET_URC) != nullptr) + || (strstr(event, UBX_CELL_LISTEN_SOCKET_URC) != nullptr) + || (strstr(event, UBX_CELL_CLOSE_SOCKET_URC) != nullptr) + || (strstr(event, UBX_CELL_GNSS_REQUEST_LOCATION_URC) != nullptr) + || (strstr(event, UBX_CELL_SIM_STATE_URC) != nullptr) + || (strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC) != nullptr) + || (strstr(event, UBX_CELL_HTTP_COMMAND_URC) != nullptr) + || (strstr(event, UBX_CELL_MQTT_COMMAND_URC) != nullptr) + || (strstr(event, UBX_CELL_PING_COMMAND_URC) != nullptr) + || (strstr(event, UBX_CELL_REGISTRATION_STATUS_URC) != nullptr) + || (strstr(event, UBX_CELL_EPSREGISTRATION_STATUS_URC) != nullptr) + || (strstr(event, UBX_CELL_FTP_COMMAND_URC) != nullptr)) { strcat(_pruneBuffer, event); // The URCs are all readable text so using strcat is OK strcat(_pruneBuffer, "\r\n"); // strtok blows away delimiter, but we want that for later. @@ -6722,7 +6722,7 @@ void UBLOX_AT::pruneBacklog() // GPS Helper Functions: // Read a source string until a delimiter is hit, store the result in destination -char *UBLOX_AT::readDataUntil(char *destination, unsigned int destSize, +char *UBX_CELL::readDataUntil(char *destination, unsigned int destSize, char *source, char delimiter) { @@ -6741,7 +6741,7 @@ char *UBLOX_AT::readDataUntil(char *destination, unsigned int destSize, return strEnd; } -bool UBLOX_AT::parseGPRMCString(char *rmcString, PositionData *pos, +bool UBX_CELL::parseGPRMCString(char *rmcString, PositionData *pos, ClockData *clk, SpeedData *spd) { char *ptr, *search; diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index 05e1a62..a16bfa6 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -14,8 +14,8 @@ */ -#ifndef SPARKFUN_UBLOX_AT_ARDUINO_LIBRARY_H -#define SPARKFUN_UBLOX_AT_ARDUINO_LIBRARY_H +#ifndef SPARKFUN_UBX_CELL_ARDUINO_LIBRARY_H +#define SPARKFUN_UBX_CELL_ARDUINO_LIBRARY_H #if (ARDUINO >= 100) #include "Arduino.h" @@ -24,22 +24,22 @@ #endif #ifdef ARDUINO_ARCH_AVR // Arduino AVR boards (Uno, Pro Micro, etc.) -#define UBLOX_AT_SOFTWARE_SERIAL_ENABLED // Enable software serial +#define UBX_CELL_SOFTWARE_SERIAL_ENABLED // Enable software serial #endif #ifdef ARDUINO_ARCH_SAMD // Arduino SAMD boards (SAMD21, etc.) -#define UBLOX_AT_SOFTWARE_SERIAL_ENABLEDx // Disable software serial +#define UBX_CELL_SOFTWARE_SERIAL_ENABLEDx // Disable software serial #endif #ifdef ARDUINO_ARCH_APOLLO3 // Arduino Apollo boards (Artemis module, RedBoard Artemis, etc) -#define UBLOX_AT_SOFTWARE_SERIAL_ENABLEDx // Disable software serial (no longer supported with v2 of Apollo3) +#define UBX_CELL_SOFTWARE_SERIAL_ENABLEDx // Disable software serial (no longer supported with v2 of Apollo3) // Note: paulvha has provided software serial support for v2 of the Apollo3 / Artemis core. // Further details are available at: // https://github.com/paulvha/apollo3/tree/master/SoftwareSerial #endif #ifdef ARDUINO_ARCH_STM32 // STM32 based boards (Disco, Nucleo, etc) -#define UBLOX_AT_SOFTWARE_SERIAL_ENABLED // Enable software serial +#define UBX_CELL_SOFTWARE_SERIAL_ENABLED // Enable software serial #endif #ifdef ARDUINO_ARCH_ESP32 // ESP32 based boards @@ -48,9 +48,9 @@ // _before_ the #include , for this to work. // See SARA-R5_Example2_Identification_ESPSoftwareSerial for more details. #if __has_include( ) -#define UBLOX_AT_SOFTWARE_SERIAL_ENABLED // Enable software serial +#define UBX_CELL_SOFTWARE_SERIAL_ENABLED // Enable software serial #else -#define UBLOX_AT_SOFTWARE_SERIAL_ENABLEDx // Disable software serial +#define UBX_CELL_SOFTWARE_SERIAL_ENABLEDx // Disable software serial #endif #endif @@ -60,158 +60,158 @@ // _before_ the #include , for this to work. // See SARA-R5_Example2_Identification_ESPSoftwareSerial for more details. #if __has_include( ) -#define UBLOX_AT_SOFTWARE_SERIAL_ENABLED // Enable software serial +#define UBX_CELL_SOFTWARE_SERIAL_ENABLED // Enable software serial #else -#define UBLOX_AT_SOFTWARE_SERIAL_ENABLEDx // Disable software serial +#define UBX_CELL_SOFTWARE_SERIAL_ENABLEDx // Disable software serial #endif #endif -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED #include // SoftwareSerial.h is guarded. It is OK to include it twice. #endif #include -#define UBLOX_AT_POWER_PIN -1 // Default to no pin -#define UBLOX_AT_RESET_PIN -1 +#define UBX_CELL_POWER_PIN -1 // Default to no pin +#define UBX_CELL_RESET_PIN -1 // Timing -#define UBLOX_AT_STANDARD_RESPONSE_TIMEOUT 1000 -#define UBLOX_AT_10_SEC_TIMEOUT 10000 -#define UBLOX_AT_55_SECS_TIMEOUT 55000 -#define UBLOX_AT_2_MIN_TIMEOUT 120000 -#define UBLOX_AT_3_MIN_TIMEOUT 180000 -#define UBLOX_AT_SET_BAUD_TIMEOUT 500 -#define UBLOX_AT_POWER_OFF_PULSE_PERIOD 3200 // Hold PWR_ON low for this long to power the module off -#define UBLOX_AT_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) -#define UBLOX_AT_RESET_PULSE_PERIOD 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) -#define UBLOX_AT_POWER_OFF_TIMEOUT 40000 // Datasheet says 40 seconds... -#define UBLOX_AT_IP_CONNECT_TIMEOUT 130000 -#define UBLOX_AT_POLL_DELAY 1 -#define UBLOX_AT_SOCKET_WRITE_TIMEOUT 10000 +#define UBX_CELL_STANDARD_RESPONSE_TIMEOUT 1000 +#define UBX_CELL_10_SEC_TIMEOUT 10000 +#define UBX_CELL_55_SECS_TIMEOUT 55000 +#define UBX_CELL_2_MIN_TIMEOUT 120000 +#define UBX_CELL_3_MIN_TIMEOUT 180000 +#define UBX_CELL_SET_BAUD_TIMEOUT 500 +#define UBX_CELL_POWER_OFF_PULSE_PERIOD 3200 // Hold PWR_ON low for this long to power the module off +#define UBX_CELL_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) +#define UBX_CELL_RESET_PULSE_PERIOD 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) +#define UBX_CELL_POWER_OFF_TIMEOUT 40000 // Datasheet says 40 seconds... +#define UBX_CELL_IP_CONNECT_TIMEOUT 130000 +#define UBX_CELL_POLL_DELAY 1 +#define UBX_CELL_SOCKET_WRITE_TIMEOUT 10000 // ## Suported AT Commands // ### General -const char UBLOX_AT_COMMAND_AT[] = "AT"; // AT "Test" -const char UBLOX_AT_COMMAND_ECHO[] = "E"; // Local Echo -const char UBLOX_AT_COMMAND_MANU_ID[] = "+CGMI"; // Manufacturer identification -const char UBLOX_AT_COMMAND_MODEL_ID[] = "+CGMM"; // Model identification -const char UBLOX_AT_COMMAND_FW_VER_ID[] = "+CGMR"; // Firmware version identification -const char UBLOX_AT_COMMAND_SERIAL_NO[] = "+CGSN"; // Product serial number -const char UBLOX_AT_COMMAND_IMEI[] = "+GSN"; // IMEI identification -const char UBLOX_AT_COMMAND_IMSI[] = "+CIMI"; // IMSI identification -const char UBLOX_AT_COMMAND_CCID[] = "+CCID"; // SIM CCID -const char UBLOX_AT_COMMAND_REQ_CAP[] = "+GCAP"; // Request capabilities list +const char UBX_CELL_COMMAND_AT[] = "AT"; // AT "Test" +const char UBX_CELL_COMMAND_ECHO[] = "E"; // Local Echo +const char UBX_CELL_COMMAND_MANU_ID[] = "+CGMI"; // Manufacturer identification +const char UBX_CELL_COMMAND_MODEL_ID[] = "+CGMM"; // Model identification +const char UBX_CELL_COMMAND_FW_VER_ID[] = "+CGMR"; // Firmware version identification +const char UBX_CELL_COMMAND_SERIAL_NO[] = "+CGSN"; // Product serial number +const char UBX_CELL_COMMAND_IMEI[] = "+GSN"; // IMEI identification +const char UBX_CELL_COMMAND_IMSI[] = "+CIMI"; // IMSI identification +const char UBX_CELL_COMMAND_CCID[] = "+CCID"; // SIM CCID +const char UBX_CELL_COMMAND_REQ_CAP[] = "+GCAP"; // Request capabilities list // ### Control and status -const char UBLOX_AT_COMMAND_POWER_OFF[] = "+CPWROFF"; // Module switch off -const char UBLOX_AT_COMMAND_FUNC[] = "+CFUN"; // Functionality (reset, etc.) -const char UBLOX_AT_COMMAND_CLOCK[] = "+CCLK"; // Real-time clock -const char UBLOX_AT_COMMAND_AUTO_TZ[] = "+CTZU"; // Automatic time zone update -const char UBLOX_AT_COMMAND_TZ_REPORT[] = "+CTZR"; // Time zone reporting +const char UBX_CELL_COMMAND_POWER_OFF[] = "+CPWROFF"; // Module switch off +const char UBX_CELL_COMMAND_FUNC[] = "+CFUN"; // Functionality (reset, etc.) +const char UBX_CELL_COMMAND_CLOCK[] = "+CCLK"; // Real-time clock +const char UBX_CELL_COMMAND_AUTO_TZ[] = "+CTZU"; // Automatic time zone update +const char UBX_CELL_COMMAND_TZ_REPORT[] = "+CTZR"; // Time zone reporting // ### Network service -const char UBLOX_AT_COMMAND_CNUM[] = "+CNUM"; // Subscriber number -const char UBLOX_AT_SIGNAL_QUALITY[] = "+CSQ"; -const char UBLOX_AT_EXT_SIGNAL_QUALITY[] = "+CESQ"; -const char UBLOX_AT_OPERATOR_SELECTION[] = "+COPS"; -const char UBLOX_AT_REGISTRATION_STATUS[] = "+CREG"; -const char UBLOX_AT_EPSREGISTRATION_STATUS[] = "+CEREG"; -const char UBLOX_AT_READ_OPERATOR_NAMES[] = "+COPN"; -const char UBLOX_AT_COMMAND_MNO[] = "+UMNOPROF"; // MNO (mobile network operator) Profile +const char UBX_CELL_COMMAND_CNUM[] = "+CNUM"; // Subscriber number +const char UBX_CELL_SIGNAL_QUALITY[] = "+CSQ"; +const char UBX_CELL_EXT_SIGNAL_QUALITY[] = "+CESQ"; +const char UBX_CELL_OPERATOR_SELECTION[] = "+COPS"; +const char UBX_CELL_REGISTRATION_STATUS[] = "+CREG"; +const char UBX_CELL_EPSREGISTRATION_STATUS[] = "+CEREG"; +const char UBX_CELL_READ_OPERATOR_NAMES[] = "+COPN"; +const char UBX_CELL_COMMAND_MNO[] = "+UMNOPROF"; // MNO (mobile network operator) Profile // ### SIM -const char UBLOX_AT_SIM_STATE[] = "+USIMSTAT"; -const char UBLOX_AT_COMMAND_SIMPIN[] = "+CPIN"; // SIM PIN +const char UBX_CELL_SIM_STATE[] = "+USIMSTAT"; +const char UBX_CELL_COMMAND_SIMPIN[] = "+CPIN"; // SIM PIN // ### SMS -const char UBLOX_AT_MESSAGE_FORMAT[] = "+CMGF"; // Set SMS message format -const char UBLOX_AT_SEND_TEXT[] = "+CMGS"; // Send SMS message -const char UBLOX_AT_NEW_MESSAGE_IND[] = "+CNMI"; // New [SMS] message indication -const char UBLOX_AT_PREF_MESSAGE_STORE[] = "+CPMS"; // Preferred message storage -const char UBLOX_AT_READ_TEXT_MESSAGE[] = "+CMGR"; // Read message -const char UBLOX_AT_DELETE_MESSAGE[] = "+CMGD"; // Delete message +const char UBX_CELL_MESSAGE_FORMAT[] = "+CMGF"; // Set SMS message format +const char UBX_CELL_SEND_TEXT[] = "+CMGS"; // Send SMS message +const char UBX_CELL_NEW_MESSAGE_IND[] = "+CNMI"; // New [SMS] message indication +const char UBX_CELL_PREF_MESSAGE_STORE[] = "+CPMS"; // Preferred message storage +const char UBX_CELL_READ_TEXT_MESSAGE[] = "+CMGR"; // Read message +const char UBX_CELL_DELETE_MESSAGE[] = "+CMGD"; // Delete message // V24 control and V25ter (UART interface) -const char UBLOX_AT_FLOW_CONTROL[] = "&K"; // Flow control -const char UBLOX_AT_COMMAND_BAUD[] = "+IPR"; // Baud rate +const char UBX_CELL_FLOW_CONTROL[] = "&K"; // Flow control +const char UBX_CELL_COMMAND_BAUD[] = "+IPR"; // Baud rate // ### Packet switched data services -const char UBLOX_AT_MESSAGE_PDP_DEF[] = "+CGDCONT"; // Packet switched Data Profile context definition -const char UBLOX_AT_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration -const char UBLOX_AT_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile -const char UBLOX_AT_MESSAGE_PDP_CONTEXT_ACTIVATE[] = "+CGACT"; // Activates or deactivates the specified PDP context -const char UBLOX_AT_MESSAGE_ENTER_PPP[] = "D"; -const char UBLOX_AT_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data +const char UBX_CELL_MESSAGE_PDP_DEF[] = "+CGDCONT"; // Packet switched Data Profile context definition +const char UBX_CELL_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration +const char UBX_CELL_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile +const char UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE[] = "+CGACT"; // Activates or deactivates the specified PDP context +const char UBX_CELL_MESSAGE_ENTER_PPP[] = "D"; +const char UBX_CELL_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data // ### GPIO -const char UBLOX_AT_COMMAND_GPIO[] = "+UGPIOC"; // GPIO Configuration +const char UBX_CELL_COMMAND_GPIO[] = "+UGPIOC"; // GPIO Configuration // ### IP -const char UBLOX_AT_CREATE_SOCKET[] = "+USOCR"; // Create a new socket -const char UBLOX_AT_CLOSE_SOCKET[] = "+USOCL"; // Close a socket -const char UBLOX_AT_CONNECT_SOCKET[] = "+USOCO"; // Connect to server on socket -const char UBLOX_AT_WRITE_SOCKET[] = "+USOWR"; // Write data to a socket -const char UBLOX_AT_WRITE_UDP_SOCKET[] = "+USOST"; // Write data to a UDP socket -const char UBLOX_AT_READ_SOCKET[] = "+USORD"; // Read from a socket -const char UBLOX_AT_READ_UDP_SOCKET[] = "+USORF"; // Read UDP data from a socket -const char UBLOX_AT_LISTEN_SOCKET[] = "+USOLI"; // Listen for connection on socket -const char UBLOX_AT_GET_ERROR[] = "+USOER"; // Get last socket error. -const char UBLOX_AT_SOCKET_DIRECT_LINK[] = "+USODL"; // Set socket in Direct Link mode -const char UBLOX_AT_SOCKET_CONTROL[] = "+USOCTL"; // Query the socket parameters -const char UBLOX_AT_UD_CONFIGURATION[] = "+UDCONF"; // User Datagram Configuration +const char UBX_CELL_CREATE_SOCKET[] = "+USOCR"; // Create a new socket +const char UBX_CELL_CLOSE_SOCKET[] = "+USOCL"; // Close a socket +const char UBX_CELL_CONNECT_SOCKET[] = "+USOCO"; // Connect to server on socket +const char UBX_CELL_WRITE_SOCKET[] = "+USOWR"; // Write data to a socket +const char UBX_CELL_WRITE_UDP_SOCKET[] = "+USOST"; // Write data to a UDP socket +const char UBX_CELL_READ_SOCKET[] = "+USORD"; // Read from a socket +const char UBX_CELL_READ_UDP_SOCKET[] = "+USORF"; // Read UDP data from a socket +const char UBX_CELL_LISTEN_SOCKET[] = "+USOLI"; // Listen for connection on socket +const char UBX_CELL_GET_ERROR[] = "+USOER"; // Get last socket error. +const char UBX_CELL_SOCKET_DIRECT_LINK[] = "+USODL"; // Set socket in Direct Link mode +const char UBX_CELL_SOCKET_CONTROL[] = "+USOCTL"; // Query the socket parameters +const char UBX_CELL_UD_CONFIGURATION[] = "+UDCONF"; // User Datagram Configuration // ### Ping -const char UBLOX_AT_PING_COMMAND[] = "+UPING"; // Ping +const char UBX_CELL_PING_COMMAND[] = "+UPING"; // Ping // ### HTTP -const char UBLOX_AT_HTTP_PROFILE[] = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined -const char UBLOX_AT_HTTP_COMMAND[] = "+UHTTPC"; // Trigger the specified HTTP command -const char UBLOX_AT_HTTP_PROTOCOL_ERROR[] = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. - -const char UBLOX_AT_MQTT_NVM[] = "+UMQTTNV"; -const char UBLOX_AT_MQTT_PROFILE[] = "+UMQTT"; -const char UBLOX_AT_MQTT_COMMAND[] = "+UMQTTC"; -const char UBLOX_AT_MQTT_PROTOCOL_ERROR[] = "+UMQTTER"; +const char UBX_CELL_HTTP_PROFILE[] = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined +const char UBX_CELL_HTTP_COMMAND[] = "+UHTTPC"; // Trigger the specified HTTP command +const char UBX_CELL_HTTP_PROTOCOL_ERROR[] = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. + +const char UBX_CELL_MQTT_NVM[] = "+UMQTTNV"; +const char UBX_CELL_MQTT_PROFILE[] = "+UMQTT"; +const char UBX_CELL_MQTT_COMMAND[] = "+UMQTTC"; +const char UBX_CELL_MQTT_PROTOCOL_ERROR[] = "+UMQTTER"; // ### FTP -const char UBLOX_AT_FTP_PROFILE[] = "+UFTP"; -const char UBLOX_AT_FTP_COMMAND[] = "+UFTPC"; -const char UBLOX_AT_FTP_PROTOCOL_ERROR[] = "+UFTPER"; +const char UBX_CELL_FTP_PROFILE[] = "+UFTP"; +const char UBX_CELL_FTP_COMMAND[] = "+UFTPC"; +const char UBX_CELL_FTP_PROTOCOL_ERROR[] = "+UFTPER"; // ### GNSS -const char UBLOX_AT_GNSS_POWER[] = "+UGPS"; // GNSS power management configuration -const char UBLOX_AT_GNSS_ASSISTED_IND[] = "+UGIND"; // Assisted GNSS unsolicited indication -const char UBLOX_AT_GNSS_REQUEST_LOCATION[] = "+ULOC"; // Ask for localization information -const char UBLOX_AT_GNSS_GPRMC[] = "+UGRMC"; // Ask for localization information -const char UBLOX_AT_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) -const char UBLOX_AT_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication -const char UBLOX_AT_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration -const char UBLOX_AT_GNSS_CONFIGURE_SENSOR[] = "+ULOCGNSS"; // Configure GNSS sensor -const char UBLOX_AT_GNSS_CONFIGURE_LOCATION[] = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) -const char UBLOX_AT_AIDING_SERVER_CONFIGURATION[] = "+UGSRV"; // Configure aiding server (CellLocate®) +const char UBX_CELL_GNSS_POWER[] = "+UGPS"; // GNSS power management configuration +const char UBX_CELL_GNSS_ASSISTED_IND[] = "+UGIND"; // Assisted GNSS unsolicited indication +const char UBX_CELL_GNSS_REQUEST_LOCATION[] = "+ULOC"; // Ask for localization information +const char UBX_CELL_GNSS_GPRMC[] = "+UGRMC"; // Ask for localization information +const char UBX_CELL_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) +const char UBX_CELL_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication +const char UBX_CELL_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration +const char UBX_CELL_GNSS_CONFIGURE_SENSOR[] = "+ULOCGNSS"; // Configure GNSS sensor +const char UBX_CELL_GNSS_CONFIGURE_LOCATION[] = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) +const char UBX_CELL_AIDING_SERVER_CONFIGURATION[] = "+UGSRV"; // Configure aiding server (CellLocate®) // ### File System // TO DO: Add support for file tags. Default tag to USER -const char UBLOX_AT_FILE_SYSTEM_READ_FILE[] = "+URDFILE"; // Read a file -const char UBLOX_AT_FILE_SYSTEM_READ_BLOCK[] = "+URDBLOCK"; // Read a block from a file -const char UBLOX_AT_FILE_SYSTEM_DOWNLOAD_FILE[] = "+UDWNFILE"; // Download a file into the module -const char UBLOX_AT_FILE_SYSTEM_LIST_FILES[] = "+ULSTFILE"; // List of files, size of file, etc. -const char UBLOX_AT_FILE_SYSTEM_DELETE_FILE[] = "+UDELFILE"; // Delete a file +const char UBX_CELL_FILE_SYSTEM_READ_FILE[] = "+URDFILE"; // Read a file +const char UBX_CELL_FILE_SYSTEM_READ_BLOCK[] = "+URDBLOCK"; // Read a block from a file +const char UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE[] = "+UDWNFILE"; // Download a file into the module +const char UBX_CELL_FILE_SYSTEM_LIST_FILES[] = "+ULSTFILE"; // List of files, size of file, etc. +const char UBX_CELL_FILE_SYSTEM_DELETE_FILE[] = "+UDELFILE"; // Delete a file // ### File System // TO DO: Add support for file tags. Default tag to USER -const char UBLOX_AT_SEC_PROFILE[] = "+USECPRF"; -const char UBLOX_AT_SEC_MANAGER[] = "+USECMNG"; +const char UBX_CELL_SEC_PROFILE[] = "+USECPRF"; +const char UBX_CELL_SEC_MANAGER[] = "+USECMNG"; // ### URC strings -const char UBLOX_AT_READ_SOCKET_URC[] = "+UUSORD:"; -const char UBLOX_AT_READ_UDP_SOCKET_URC[] = "+UUSORF:"; -const char UBLOX_AT_LISTEN_SOCKET_URC[] = "+UUSOLI:"; -const char UBLOX_AT_CLOSE_SOCKET_URC[] = "+UUSOCL:"; -const char UBLOX_AT_GNSS_REQUEST_LOCATION_URC[] = "+UULOC:"; -const char UBLOX_AT_SIM_STATE_URC[] = "+UUSIMSTAT:"; -const char UBLOX_AT_MESSAGE_PDP_ACTION_URC[] = "+UUPSDA:"; -const char UBLOX_AT_HTTP_COMMAND_URC[] = "+UUHTTPCR:"; -const char UBLOX_AT_MQTT_COMMAND_URC[] = "+UUMQTTC:"; -const char UBLOX_AT_PING_COMMAND_URC[] = "+UUPING:"; -const char UBLOX_AT_REGISTRATION_STATUS_URC[] = "+CREG:"; -const char UBLOX_AT_EPSREGISTRATION_STATUS_URC[] = "+CEREG:"; -const char UBLOX_AT_FTP_COMMAND_URC[] = "+UUFTPCR:"; +const char UBX_CELL_READ_SOCKET_URC[] = "+UUSORD:"; +const char UBX_CELL_READ_UDP_SOCKET_URC[] = "+UUSORF:"; +const char UBX_CELL_LISTEN_SOCKET_URC[] = "+UUSOLI:"; +const char UBX_CELL_CLOSE_SOCKET_URC[] = "+UUSOCL:"; +const char UBX_CELL_GNSS_REQUEST_LOCATION_URC[] = "+UULOC:"; +const char UBX_CELL_SIM_STATE_URC[] = "+UUSIMSTAT:"; +const char UBX_CELL_MESSAGE_PDP_ACTION_URC[] = "+UUPSDA:"; +const char UBX_CELL_HTTP_COMMAND_URC[] = "+UUHTTPCR:"; +const char UBX_CELL_MQTT_COMMAND_URC[] = "+UUMQTTC:"; +const char UBX_CELL_PING_COMMAND_URC[] = "+UUPING:"; +const char UBX_CELL_REGISTRATION_STATUS_URC[] = "+CREG:"; +const char UBX_CELL_EPSREGISTRATION_STATUS_URC[] = "+CEREG:"; +const char UBX_CELL_FTP_COMMAND_URC[] = "+UUFTPCR:"; // ### Response -const char UBLOX_AT_RESPONSE_MORE[] = "\n>"; -const char UBLOX_AT_RESPONSE_OK[] = "\nOK\r\n"; -const char UBLOX_AT_RESPONSE_ERROR[] = "\nERROR\r\n"; -const char UBLOX_AT_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; -#define UBLOX_AT_RESPONSE_OK_OR_ERROR nullptr +const char UBX_CELL_RESPONSE_MORE[] = "\n>"; +const char UBX_CELL_RESPONSE_OK[] = "\nOK\r\n"; +const char UBX_CELL_RESPONSE_ERROR[] = "\nERROR\r\n"; +const char UBX_CELL_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; +#define UBX_CELL_RESPONSE_OK_OR_ERROR nullptr // CTRL+Z and ESC ASCII codes for SMS message sends const char ASCII_CTRL_Z = 0x1A; @@ -227,10 +227,10 @@ const char ASCII_ESC = 0x1B; // This needs to be large enough to hold the response you're expecting plus and URC's that may arrive during the timeout #define minimumResponseAllocation 128 -#define UBLOX_AT_NUM_SOCKETS 6 +#define UBX_CELL_NUM_SOCKETS 6 #define NUM_SUPPORTED_BAUD 6 -const unsigned long UBLOX_AT_SUPPORTED_BAUD[NUM_SUPPORTED_BAUD] = +const unsigned long UBX_CELL_SUPPORTED_BAUD[NUM_SUPPORTED_BAUD] = { 115200, 9600, @@ -238,15 +238,15 @@ const unsigned long UBLOX_AT_SUPPORTED_BAUD[NUM_SUPPORTED_BAUD] = 38400, 57600, 230400}; -#define UBLOX_AT_DEFAULT_BAUD_RATE 115200 +#define UBX_CELL_DEFAULT_BAUD_RATE 115200 // Flow control definitions for AT&K -// Note: SW (XON/XOFF) flow control is not supported on the UBLOX_AT +// Note: SW (XON/XOFF) flow control is not supported on the UBX_CELL typedef enum { - UBLOX_AT_DISABLE_FLOW_CONTROL = 0, - UBLOX_AT_ENABLE_FLOW_CONTROL = 3 -} UBLOX_AT_flow_control_t; + UBX_CELL_DISABLE_FLOW_CONTROL = 0, + UBX_CELL_ENABLE_FLOW_CONTROL = 3 +} UBX_CELL_flow_control_t; // The standard Europe profile should be used as the basis for all other MNOs in Europe outside of Vodafone // and Deutsche Telekom. However, there may be changes that need to be applied to the module for proper @@ -277,34 +277,34 @@ typedef enum typedef enum { - UBLOX_AT_ERROR_INVALID = -1, // -1 - UBLOX_AT_ERROR_SUCCESS = 0, // 0 - UBLOX_AT_ERROR_OUT_OF_MEMORY, // 1 - UBLOX_AT_ERROR_TIMEOUT, // 2 - UBLOX_AT_ERROR_UNEXPECTED_PARAM, // 3 - UBLOX_AT_ERROR_UNEXPECTED_RESPONSE, // 4 - UBLOX_AT_ERROR_NO_RESPONSE, // 5 - UBLOX_AT_ERROR_DEREGISTERED, // 6 - UBLOX_AT_ERROR_ZERO_READ_LENGTH, // 7 - UBLOX_AT_ERROR_ERROR // 8 -} UBLOX_AT_error_t; -#define UBLOX_AT_SUCCESS UBLOX_AT_ERROR_SUCCESS + UBX_CELL_ERROR_INVALID = -1, // -1 + UBX_CELL_ERROR_SUCCESS = 0, // 0 + UBX_CELL_ERROR_OUT_OF_MEMORY, // 1 + UBX_CELL_ERROR_TIMEOUT, // 2 + UBX_CELL_ERROR_UNEXPECTED_PARAM, // 3 + UBX_CELL_ERROR_UNEXPECTED_RESPONSE, // 4 + UBX_CELL_ERROR_NO_RESPONSE, // 5 + UBX_CELL_ERROR_DEREGISTERED, // 6 + UBX_CELL_ERROR_ZERO_READ_LENGTH, // 7 + UBX_CELL_ERROR_ERROR // 8 +} UBX_CELL_error_t; +#define UBX_CELL_SUCCESS UBX_CELL_ERROR_SUCCESS typedef enum { - UBLOX_AT_REGISTRATION_INVALID = -1, - UBLOX_AT_REGISTRATION_NOT_REGISTERED = 0, - UBLOX_AT_REGISTRATION_HOME = 1, - UBLOX_AT_REGISTRATION_SEARCHING = 2, - UBLOX_AT_REGISTRATION_DENIED = 3, - UBLOX_AT_REGISTRATION_UNKNOWN = 4, - UBLOX_AT_REGISTRATION_ROAMING = 5, - UBLOX_AT_REGISTRATION_HOME_SMS_ONLY = 6, - UBLOX_AT_REGISTRATION_ROAMING_SMS_ONLY = 7, - UBLOX_AT_REGISTRATION_EMERGENCY_SERV_ONLY = 8, - UBLOX_AT_REGISTRATION_HOME_CSFB_NOT_PREFERRED = 9, - UBLOX_AT_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED = 10 -} UBLOX_AT_registration_status_t; + UBX_CELL_REGISTRATION_INVALID = -1, + UBX_CELL_REGISTRATION_NOT_REGISTERED = 0, + UBX_CELL_REGISTRATION_HOME = 1, + UBX_CELL_REGISTRATION_SEARCHING = 2, + UBX_CELL_REGISTRATION_DENIED = 3, + UBX_CELL_REGISTRATION_UNKNOWN = 4, + UBX_CELL_REGISTRATION_ROAMING = 5, + UBX_CELL_REGISTRATION_HOME_SMS_ONLY = 6, + UBX_CELL_REGISTRATION_ROAMING_SMS_ONLY = 7, + UBX_CELL_REGISTRATION_EMERGENCY_SERV_ONLY = 8, + UBX_CELL_REGISTRATION_HOME_CSFB_NOT_PREFERRED = 9, + UBX_CELL_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED = 10 +} UBX_CELL_registration_status_t; struct DateData { @@ -366,259 +366,259 @@ typedef struct ext_signal_quality_ { typedef enum { - UBLOX_AT_TCP = 6, - UBLOX_AT_UDP = 17 -} UBLOX_AT_socket_protocol_t; + UBX_CELL_TCP = 6, + UBX_CELL_UDP = 17 +} UBX_CELL_socket_protocol_t; typedef enum { - UBLOX_AT_TCP_SOCKET_STATUS_INACTIVE, - UBLOX_AT_TCP_SOCKET_STATUS_LISTEN, - UBLOX_AT_TCP_SOCKET_STATUS_SYN_SENT, - UBLOX_AT_TCP_SOCKET_STATUS_SYN_RCVD, - UBLOX_AT_TCP_SOCKET_STATUS_ESTABLISHED, - UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_1, - UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_2, - UBLOX_AT_TCP_SOCKET_STATUS_CLOSE_WAIT, - UBLOX_AT_TCP_SOCKET_STATUS_CLOSING, - UBLOX_AT_TCP_SOCKET_STATUS_LAST_ACK, - UBLOX_AT_TCP_SOCKET_STATUS_TIME_WAIT -} UBLOX_AT_tcp_socket_status_t; + UBX_CELL_TCP_SOCKET_STATUS_INACTIVE, + UBX_CELL_TCP_SOCKET_STATUS_LISTEN, + UBX_CELL_TCP_SOCKET_STATUS_SYN_SENT, + UBX_CELL_TCP_SOCKET_STATUS_SYN_RCVD, + UBX_CELL_TCP_SOCKET_STATUS_ESTABLISHED, + UBX_CELL_TCP_SOCKET_STATUS_FIN_WAIT_1, + UBX_CELL_TCP_SOCKET_STATUS_FIN_WAIT_2, + UBX_CELL_TCP_SOCKET_STATUS_CLOSE_WAIT, + UBX_CELL_TCP_SOCKET_STATUS_CLOSING, + UBX_CELL_TCP_SOCKET_STATUS_LAST_ACK, + UBX_CELL_TCP_SOCKET_STATUS_TIME_WAIT +} UBX_CELL_tcp_socket_status_t; typedef enum { - UBLOX_AT_MESSAGE_FORMAT_PDU = 0, - UBLOX_AT_MESSAGE_FORMAT_TEXT = 1 -} UBLOX_AT_message_format_t; + UBX_CELL_MESSAGE_FORMAT_PDU = 0, + UBX_CELL_MESSAGE_FORMAT_TEXT = 1 +} UBX_CELL_message_format_t; typedef enum { - UBLOX_AT_UTIME_MODE_STOP = 0, - UBLOX_AT_UTIME_MODE_PPS, - UBLOX_AT_UTIME_MODE_ONE_SHOT, - UBLOX_AT_UTIME_MODE_EXT_INT -} UBLOX_AT_utime_mode_t; + UBX_CELL_UTIME_MODE_STOP = 0, + UBX_CELL_UTIME_MODE_PPS, + UBX_CELL_UTIME_MODE_ONE_SHOT, + UBX_CELL_UTIME_MODE_EXT_INT +} UBX_CELL_utime_mode_t; typedef enum { - UBLOX_AT_UTIME_SENSOR_NONE = 0, - UBLOX_AT_UTIME_SENSOR_GNSS_LTE = 1, - UBLOX_AT_UTIME_SENSOR_LTE -} UBLOX_AT_utime_sensor_t; + UBX_CELL_UTIME_SENSOR_NONE = 0, + UBX_CELL_UTIME_SENSOR_GNSS_LTE = 1, + UBX_CELL_UTIME_SENSOR_LTE +} UBX_CELL_utime_sensor_t; typedef enum { - UBLOX_AT_UTIME_URC_CONFIGURATION_DISABLED = 0, - UBLOX_AT_UTIME_URC_CONFIGURATION_ENABLED -} UBLOX_AT_utime_urc_configuration_t; + UBX_CELL_UTIME_URC_CONFIGURATION_DISABLED = 0, + UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED +} UBX_CELL_utime_urc_configuration_t; typedef enum { - UBLOX_AT_SIM_NOT_PRESENT = 0, - UBLOX_AT_SIM_PIN_NEEDED, - UBLOX_AT_SIM_PIN_BLOCKED, - UBLOX_AT_SIM_PUK_BLOCKED, - UBLOX_AT_SIM_NOT_OPERATIONAL, - UBLOX_AT_SIM_RESTRICTED, - UBLOX_AT_SIM_OPERATIONAL - //UBLOX_AT_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 - //UBLOX_AT_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 - //UBLOX_AT_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 - //UBLOX_AT_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 - //UBLOX_AT_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 - //UBLOX_AT_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 - //UBLOX_AT_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 -} UBLOX_AT_sim_states_t; - -#define UBLOX_AT_NUM_PSD_PROFILES 6 // Number of supported PSD profiles -#define UBLOX_AT_NUM_PDP_CONTEXT_IDENTIFIERS 11 // Number of supported PDP context identifiers -#define UBLOX_AT_NUM_HTTP_PROFILES 4 // Number of supported HTTP profiles + UBX_CELL_SIM_NOT_PRESENT = 0, + UBX_CELL_SIM_PIN_NEEDED, + UBX_CELL_SIM_PIN_BLOCKED, + UBX_CELL_SIM_PUK_BLOCKED, + UBX_CELL_SIM_NOT_OPERATIONAL, + UBX_CELL_SIM_RESTRICTED, + UBX_CELL_SIM_OPERATIONAL + //UBX_CELL_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 + //UBX_CELL_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 + //UBX_CELL_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 + //UBX_CELL_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 + //UBX_CELL_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 + //UBX_CELL_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 + //UBX_CELL_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 +} UBX_CELL_sim_states_t; + +#define UBX_CELL_NUM_PSD_PROFILES 6 // Number of supported PSD profiles +#define UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS 11 // Number of supported PDP context identifiers +#define UBX_CELL_NUM_HTTP_PROFILES 4 // Number of supported HTTP profiles typedef enum { - UBLOX_AT_HTTP_OP_CODE_SERVER_IP = 0, - UBLOX_AT_HTTP_OP_CODE_SERVER_NAME, - UBLOX_AT_HTTP_OP_CODE_USERNAME, - UBLOX_AT_HTTP_OP_CODE_PASSWORD, - UBLOX_AT_HTTP_OP_CODE_AUTHENTICATION, - UBLOX_AT_HTTP_OP_CODE_SERVER_PORT, - UBLOX_AT_HTTP_OP_CODE_SECURE, - UBLOX_AT_HTTP_OP_CODE_REQUEST_TIMEOUT, - UBLOX_AT_HTTP_OP_CODE_ADD_CUSTOM_HEADERS = 9 -} UBLOX_AT_http_op_codes_t; + UBX_CELL_HTTP_OP_CODE_SERVER_IP = 0, + UBX_CELL_HTTP_OP_CODE_SERVER_NAME, + UBX_CELL_HTTP_OP_CODE_USERNAME, + UBX_CELL_HTTP_OP_CODE_PASSWORD, + UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, + UBX_CELL_HTTP_OP_CODE_SERVER_PORT, + UBX_CELL_HTTP_OP_CODE_SECURE, + UBX_CELL_HTTP_OP_CODE_REQUEST_TIMEOUT, + UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS = 9 +} UBX_CELL_http_op_codes_t; typedef enum { - UBLOX_AT_HTTP_COMMAND_HEAD = 0, - UBLOX_AT_HTTP_COMMAND_GET, - UBLOX_AT_HTTP_COMMAND_DELETE, - UBLOX_AT_HTTP_COMMAND_PUT, - UBLOX_AT_HTTP_COMMAND_POST_FILE, - UBLOX_AT_HTTP_COMMAND_POST_DATA, - UBLOX_AT_HTTP_COMMAND_GET_FOTA = 100 -} UBLOX_AT_http_commands_t; + UBX_CELL_HTTP_COMMAND_HEAD = 0, + UBX_CELL_HTTP_COMMAND_GET, + UBX_CELL_HTTP_COMMAND_DELETE, + UBX_CELL_HTTP_COMMAND_PUT, + UBX_CELL_HTTP_COMMAND_POST_FILE, + UBX_CELL_HTTP_COMMAND_POST_DATA, + UBX_CELL_HTTP_COMMAND_GET_FOTA = 100 +} UBX_CELL_http_commands_t; typedef enum { - UBLOX_AT_HTTP_CONTENT_APPLICATION_X_WWW = 0, - UBLOX_AT_HTTP_CONTENT_TEXT_PLAIN, - UBLOX_AT_HTTP_CONTENT_APPLICATION_OCTET, - UBLOX_AT_HTTP_CONTENT_MULTIPART_FORM, - UBLOX_AT_HTTP_CONTENT_APPLICATION_JSON, - UBLOX_AT_HTTP_CONTENT_APPLICATION_XML, - UBLOX_AT_HTTP_CONTENT_USER_DEFINED -} UBLOX_AT_http_content_types_t; + UBX_CELL_HTTP_CONTENT_APPLICATION_X_WWW = 0, + UBX_CELL_HTTP_CONTENT_TEXT_PLAIN, + UBX_CELL_HTTP_CONTENT_APPLICATION_OCTET, + UBX_CELL_HTTP_CONTENT_MULTIPART_FORM, + UBX_CELL_HTTP_CONTENT_APPLICATION_JSON, + UBX_CELL_HTTP_CONTENT_APPLICATION_XML, + UBX_CELL_HTTP_CONTENT_USER_DEFINED +} UBX_CELL_http_content_types_t; typedef enum { - UBLOX_AT_MQTT_NV_RESTORE = 0, - UBLOX_AT_MQTT_NV_SET, - UBLOX_AT_MQTT_NV_STORE, -} UBLOX_AT_mqtt_nv_parameter_t; + UBX_CELL_MQTT_NV_RESTORE = 0, + UBX_CELL_MQTT_NV_SET, + UBX_CELL_MQTT_NV_STORE, +} UBX_CELL_mqtt_nv_parameter_t; typedef enum { - UBLOX_AT_MQTT_PROFILE_CLIENT_ID = 0, - UBLOX_AT_MQTT_PROFILE_SERVERNAME = 2, - UBLOX_AT_MQTT_PROFILE_IPADDRESS, - UBLOX_AT_MQTT_PROFILE_USERNAMEPWD, - UBLOX_AT_MQTT_PROFILE_QOS = 6, - UBLOX_AT_MQTT_PROFILE_RETAIN, - UBLOX_AT_MQTT_PROFILE_TOPIC, - UBLOX_AT_MQTT_PROFILE_MESSAGE, - UBLOX_AT_MQTT_PROFILE_INACTIVITYTIMEOUT, - UBLOX_AT_MQTT_PROFILE_SECURE, -} UBLOX_AT_mqtt_profile_opcode_t; + UBX_CELL_MQTT_PROFILE_CLIENT_ID = 0, + UBX_CELL_MQTT_PROFILE_SERVERNAME = 2, + UBX_CELL_MQTT_PROFILE_IPADDRESS, + UBX_CELL_MQTT_PROFILE_USERNAMEPWD, + UBX_CELL_MQTT_PROFILE_QOS = 6, + UBX_CELL_MQTT_PROFILE_RETAIN, + UBX_CELL_MQTT_PROFILE_TOPIC, + UBX_CELL_MQTT_PROFILE_MESSAGE, + UBX_CELL_MQTT_PROFILE_INACTIVITYTIMEOUT, + UBX_CELL_MQTT_PROFILE_SECURE, +} UBX_CELL_mqtt_profile_opcode_t; typedef enum { - UBLOX_AT_MQTT_COMMAND_INVALID = -1, - UBLOX_AT_MQTT_COMMAND_LOGOUT = 0, - UBLOX_AT_MQTT_COMMAND_LOGIN, - UBLOX_AT_MQTT_COMMAND_PUBLISH, - UBLOX_AT_MQTT_COMMAND_PUBLISHFILE, - UBLOX_AT_MQTT_COMMAND_SUBSCRIBE, - UBLOX_AT_MQTT_COMMAND_UNSUBSCRIBE, - UBLOX_AT_MQTT_COMMAND_READ, - UBLOX_AT_MQTT_COMMAND_RCVMSGFORMAT, - UBLOX_AT_MQTT_COMMAND_PING, - UBLOX_AT_MQTT_COMMAND_PUBLISHBINARY, -} UBLOX_AT_mqtt_command_opcode_t; + UBX_CELL_MQTT_COMMAND_INVALID = -1, + UBX_CELL_MQTT_COMMAND_LOGOUT = 0, + UBX_CELL_MQTT_COMMAND_LOGIN, + UBX_CELL_MQTT_COMMAND_PUBLISH, + UBX_CELL_MQTT_COMMAND_PUBLISHFILE, + UBX_CELL_MQTT_COMMAND_SUBSCRIBE, + UBX_CELL_MQTT_COMMAND_UNSUBSCRIBE, + UBX_CELL_MQTT_COMMAND_READ, + UBX_CELL_MQTT_COMMAND_RCVMSGFORMAT, + UBX_CELL_MQTT_COMMAND_PING, + UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, +} UBX_CELL_mqtt_command_opcode_t; constexpr uint16_t MAX_MQTT_HEX_MSG_LEN = 512; constexpr uint16_t MAX_MQTT_DIRECT_MSG_LEN = 1024; typedef enum { - UBLOX_AT_FTP_PROFILE_IPADDRESS = 0, - UBLOX_AT_FTP_PROFILE_SERVERNAME, - UBLOX_AT_FTP_PROFILE_USERNAME, - UBLOX_AT_FTP_PROFILE_PWD, - UBLOX_AT_FTP_PROFILE_ACCOUNT, - UBLOX_AT_FTP_PROFILE_TIMEOUT, - UBLOX_AT_FTP_PROFILE_MODE -} UBLOX_AT_ftp_profile_opcode_t; + UBX_CELL_FTP_PROFILE_IPADDRESS = 0, + UBX_CELL_FTP_PROFILE_SERVERNAME, + UBX_CELL_FTP_PROFILE_USERNAME, + UBX_CELL_FTP_PROFILE_PWD, + UBX_CELL_FTP_PROFILE_ACCOUNT, + UBX_CELL_FTP_PROFILE_TIMEOUT, + UBX_CELL_FTP_PROFILE_MODE +} UBX_CELL_ftp_profile_opcode_t; typedef enum { - UBLOX_AT_FTP_COMMAND_INVALID = -1, - UBLOX_AT_FTP_COMMAND_LOGOUT = 0, - UBLOX_AT_FTP_COMMAND_LOGIN, - UBLOX_AT_FTP_COMMAND_DELETE_FILE, - UBLOX_AT_FTP_COMMAND_RENAME_FILE, - UBLOX_AT_FTP_COMMAND_GET_FILE, - UBLOX_AT_FTP_COMMAND_PUT_FILE, - UBLOX_AT_FTP_COMMAND_GET_FILE_DIRECT, - UBLOX_AT_FTP_COMMAND_PUT_FILE_DIRECT, - UBLOX_AT_FTP_COMMAND_CHANGE_DIR, - UBLOX_AT_FTP_COMMAND_MKDIR = 10, - UBLOX_AT_FTP_COMMAND_RMDIR, - UBLOX_AT_FTP_COMMAND_DIR_INFO = 13, - UBLOX_AT_FTP_COMMAND_LS, - UBLOX_AT_FTP_COMMAND_GET_FOTA_FILE = 100 -} UBLOX_AT_ftp_command_opcode_t; + UBX_CELL_FTP_COMMAND_INVALID = -1, + UBX_CELL_FTP_COMMAND_LOGOUT = 0, + UBX_CELL_FTP_COMMAND_LOGIN, + UBX_CELL_FTP_COMMAND_DELETE_FILE, + UBX_CELL_FTP_COMMAND_RENAME_FILE, + UBX_CELL_FTP_COMMAND_GET_FILE, + UBX_CELL_FTP_COMMAND_PUT_FILE, + UBX_CELL_FTP_COMMAND_GET_FILE_DIRECT, + UBX_CELL_FTP_COMMAND_PUT_FILE_DIRECT, + UBX_CELL_FTP_COMMAND_CHANGE_DIR, + UBX_CELL_FTP_COMMAND_MKDIR = 10, + UBX_CELL_FTP_COMMAND_RMDIR, + UBX_CELL_FTP_COMMAND_DIR_INFO = 13, + UBX_CELL_FTP_COMMAND_LS, + UBX_CELL_FTP_COMMAND_GET_FOTA_FILE = 100 +} UBX_CELL_ftp_command_opcode_t; typedef enum { - UBLOX_AT_PSD_CONFIG_PARAM_PROTOCOL = 0, - UBLOX_AT_PSD_CONFIG_PARAM_APN, - //UBLOX_AT_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 - //UBLOX_AT_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 - UBLOX_AT_PSD_CONFIG_PARAM_DNS1 = 4, - UBLOX_AT_PSD_CONFIG_PARAM_DNS2, - //UBLOX_AT_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 - //UBLOX_AT_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 - //UBLOX_AT_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 - //UBLOX_AT_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 - UBLOX_AT_PSD_CONFIG_PARAM_MAP_TO_CID = 100 -} UBLOX_AT_pdp_configuration_parameter_t; + UBX_CELL_PSD_CONFIG_PARAM_PROTOCOL = 0, + UBX_CELL_PSD_CONFIG_PARAM_APN, + //UBX_CELL_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 + //UBX_CELL_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 + UBX_CELL_PSD_CONFIG_PARAM_DNS1 = 4, + UBX_CELL_PSD_CONFIG_PARAM_DNS2, + //UBX_CELL_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 + //UBX_CELL_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 + //UBX_CELL_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 + //UBX_CELL_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 + UBX_CELL_PSD_CONFIG_PARAM_MAP_TO_CID = 100 +} UBX_CELL_pdp_configuration_parameter_t; typedef enum { - UBLOX_AT_PSD_PROTOCOL_IPV4 = 0, - UBLOX_AT_PSD_PROTOCOL_IPV6, - UBLOX_AT_PSD_PROTOCOL_IPV4V6_V4_PREF, - UBLOX_AT_PSD_PROTOCOL_IPV4V6_V6_PREF -} UBLOX_AT_pdp_protocol_type_t; + UBX_CELL_PSD_PROTOCOL_IPV4 = 0, + UBX_CELL_PSD_PROTOCOL_IPV6, + UBX_CELL_PSD_PROTOCOL_IPV4V6_V4_PREF, + UBX_CELL_PSD_PROTOCOL_IPV4V6_V6_PREF +} UBX_CELL_pdp_protocol_type_t; typedef enum { - UBLOX_AT_PSD_ACTION_RESET = 0, - UBLOX_AT_PSD_ACTION_STORE, - UBLOX_AT_PSD_ACTION_LOAD, - UBLOX_AT_PSD_ACTION_ACTIVATE, - UBLOX_AT_PSD_ACTION_DEACTIVATE -} UBLOX_AT_pdp_actions_t; + UBX_CELL_PSD_ACTION_RESET = 0, + UBX_CELL_PSD_ACTION_STORE, + UBX_CELL_PSD_ACTION_LOAD, + UBX_CELL_PSD_ACTION_ACTIVATE, + UBX_CELL_PSD_ACTION_DEACTIVATE +} UBX_CELL_pdp_actions_t; typedef enum { - UBLOX_AT_SEC_PROFILE_PARAM_CERT_VAL_LEVEL = 0, - UBLOX_AT_SEC_PROFILE_PARAM_TLS_VER, - UBLOX_AT_SEC_PROFILE_PARAM_CYPHER_SUITE, - UBLOX_AT_SEC_PROFILE_PARAM_ROOT_CA, - UBLOX_AT_SEC_PROFILE_PARAM_HOSTNAME, - UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_CERT, - UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY, - UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY_PWD, - UBLOX_AT_SEC_PROFILE_PARAM_PSK, - UBLOX_AT_SEC_PROFILE_PARAM_PSK_IDENT, - UBLOX_AT_SEC_PROFILE_PARAM_SNI, -} UBLOX_AT_sec_profile_parameter_t; + UBX_CELL_SEC_PROFILE_PARAM_CERT_VAL_LEVEL = 0, + UBX_CELL_SEC_PROFILE_PARAM_TLS_VER, + UBX_CELL_SEC_PROFILE_PARAM_CYPHER_SUITE, + UBX_CELL_SEC_PROFILE_PARAM_ROOT_CA, + UBX_CELL_SEC_PROFILE_PARAM_HOSTNAME, + UBX_CELL_SEC_PROFILE_PARAM_CLIENT_CERT, + UBX_CELL_SEC_PROFILE_PARAM_CLIENT_KEY, + UBX_CELL_SEC_PROFILE_PARAM_CLIENT_KEY_PWD, + UBX_CELL_SEC_PROFILE_PARAM_PSK, + UBX_CELL_SEC_PROFILE_PARAM_PSK_IDENT, + UBX_CELL_SEC_PROFILE_PARAM_SNI, +} UBX_CELL_sec_profile_parameter_t; typedef enum { - UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_NO = 0, - UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL, - UBLOX_AT_SEC_PROFILE_CERVTAL_OPCODE_YESURL, - UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE, -} UBLOX_AT_sec_profile_certval_op_code_t; + UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_NO = 0, + UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL, + UBX_CELL_SEC_PROFILE_CERVTAL_OPCODE_YESURL, + UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE, +} UBX_CELL_sec_profile_certval_op_code_t; typedef enum { - UBLOX_AT_SEC_PROFILE_TLS_OPCODE_ANYVER = 0, - UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_0, - UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_1, - UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_2, - UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_3, -} UBLOX_AT_sec_profile_tls_op_code_t; + UBX_CELL_SEC_PROFILE_TLS_OPCODE_ANYVER = 0, + UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_0, + UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_1, + UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_2, + UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_3, +} UBX_CELL_sec_profile_tls_op_code_t; typedef enum { - UBLOX_AT_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT = 0, -} UBLOX_AT_sec_profile_suite_op_code_t; + UBX_CELL_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT = 0, +} UBX_CELL_sec_profile_suite_op_code_t; typedef enum { - UBLOX_AT_SEC_MANAGER_OPCODE_IMPORT = 0, -} UBLOX_AT_sec_manager_opcode_t; + UBX_CELL_SEC_MANAGER_OPCODE_IMPORT = 0, +} UBX_CELL_sec_manager_opcode_t; typedef enum { - UBLOX_AT_SEC_MANAGER_ROOTCA = 0, - UBLOX_AT_SEC_MANAGER_CLIENT_CERT, - UBLOX_AT_SEC_MANAGER_CLIENT_KEY, - UBLOX_AT_SEC_MANAGER_SERVER_CERT -} UBLOX_AT_sec_manager_parameter_t; + UBX_CELL_SEC_MANAGER_ROOTCA = 0, + UBX_CELL_SEC_MANAGER_CLIENT_CERT, + UBX_CELL_SEC_MANAGER_CLIENT_KEY, + UBX_CELL_SEC_MANAGER_SERVER_CERT +} UBX_CELL_sec_manager_parameter_t; typedef enum { @@ -633,19 +633,19 @@ typedef enum SILENT_RESET_WITH_SIM = 16 //MINIMUM_FUNCTIONALITY = 19, // Not supported on SARA-R5 //DEEP_LOW_POWER_STATE = 127 // Not supported on SARA-R5 -} UBLOX_AT_functionality_t; +} UBX_CELL_functionality_t; -class UBLOX_AT : public Print +class UBX_CELL : public Print { public: // Constructor // The library will use the powerPin and resetPin (if provided) to power the module off/on and perform an emergency reset // maxInitTries sets the maximum number of initialization attempts. .init is called by .begin. - UBLOX_AT(int powerPin = UBLOX_AT_POWER_PIN, int resetPin = UBLOX_AT_RESET_PIN, uint8_t maxInitTries = 9); + UBX_CELL(int powerPin = UBX_CELL_POWER_PIN, int resetPin = UBX_CELL_RESET_PIN, uint8_t maxInitTries = 9); - ~UBLOX_AT(); + ~UBX_CELL(); // Begin -- initialize module and ensure it's connected -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED bool begin(SoftwareSerial &softSerial, unsigned long baud = 9600); #endif bool begin(HardwareSerial &hardSerial, unsigned long baud = 9600); @@ -659,7 +659,7 @@ class UBLOX_AT : public Print // But the Asset Tracker needs this to be pulled high and released instead void invertPowerPin(bool invert = false); - UBLOX_AT_error_t modulePowerOff(void); // Graceful disconnect and shutdown using +CPWROFF. + UBX_CELL_error_t modulePowerOff(void); // Graceful disconnect and shutdown using +CPWROFF. void modulePowerOn(void); // Requires access to the PWR_ON pin // Loop polling and polling setup - process URC's etc. from the module @@ -687,16 +687,16 @@ class UBLOX_AT : public Print void setSocketCloseCallback(void (*socketCloseCallback)(int)); // socket void setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, PositionData gps, SpeedData spd, unsigned long uncertainty)); - void setSIMstateReportCallback(void (*simStateRequestCallback)(UBLOX_AT_sim_states_t state)); + void setSIMstateReportCallback(void (*simStateRequestCallback)(UBX_CELL_sim_states_t state)); void setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)); void setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)); void setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)); void setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)); void setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)); - UBLOX_AT_error_t setRegistrationCallback(void (*registrationCallback)(UBLOX_AT_registration_status_t status, + UBX_CELL_error_t setRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, unsigned int lac, unsigned int ci, int Act)); - UBLOX_AT_error_t setEpsRegistrationCallback(void (*epsRegistrationCallback)(UBLOX_AT_registration_status_t status, + UBX_CELL_error_t setEpsRegistrationCallback(void (*epsRegistrationCallback)(UBX_CELL_registration_status_t status, unsigned int tac, unsigned int ci, int Act)); // Direct write/print to cell serial port @@ -705,8 +705,8 @@ class UBLOX_AT : public Print virtual size_t write(const char *buffer, size_t size); // General AT Commands - UBLOX_AT_error_t at(void); - UBLOX_AT_error_t enableEcho(bool enable = true); + UBX_CELL_error_t at(void); + UBX_CELL_error_t enableEcho(bool enable = true); String getManufacturerID(void); String getModelID(void); String getFirmwareVersion(void); @@ -718,28 +718,28 @@ class UBLOX_AT : public Print String getCapabilities(void); // Control and status AT commands - UBLOX_AT_error_t reset(void); + UBX_CELL_error_t reset(void); String clock(void); // TODO: Return a clock struct - UBLOX_AT_error_t clock(uint8_t *y, uint8_t *mo, uint8_t *d, + UBX_CELL_error_t clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz); // TZ can be +/- and is in increments of 15 minutes. -28 == 7 hours behind UTC/GMT - UBLOX_AT_error_t setClock(String theTime); - UBLOX_AT_error_t setClock(uint8_t y, uint8_t mo, uint8_t d, + UBX_CELL_error_t setClock(String theTime); + UBX_CELL_error_t setClock(uint8_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t min, uint8_t s, int8_t tz); // TZ can be +/- and is in increments of 15 minutes. -28 == 7 hours behind UTC/GMT void autoTimeZoneForBegin(bool enable = true); // Call autoTimeZoneForBegin(false) _before_ .begin if you want to disable the automatic time zone - UBLOX_AT_error_t autoTimeZone(bool enable); // Enable/disable automatic time zone adjustment - UBLOX_AT_error_t setUtimeMode(UBLOX_AT_utime_mode_t mode = UBLOX_AT_UTIME_MODE_PPS, UBLOX_AT_utime_sensor_t sensor = UBLOX_AT_UTIME_SENSOR_GNSS_LTE); // Time mode, source etc. (+UTIME) - UBLOX_AT_error_t getUtimeMode(UBLOX_AT_utime_mode_t *mode, UBLOX_AT_utime_sensor_t *sensor); - UBLOX_AT_error_t setUtimeIndication(UBLOX_AT_utime_urc_configuration_t config = UBLOX_AT_UTIME_URC_CONFIGURATION_ENABLED); // +UTIMEIND - UBLOX_AT_error_t getUtimeIndication(UBLOX_AT_utime_urc_configuration_t *config); - UBLOX_AT_error_t setUtimeConfiguration(int32_t offsetNanoseconds = 0, int32_t offsetSeconds = 0); // +UTIMECFG - UBLOX_AT_error_t getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds); + UBX_CELL_error_t autoTimeZone(bool enable); // Enable/disable automatic time zone adjustment + UBX_CELL_error_t setUtimeMode(UBX_CELL_utime_mode_t mode = UBX_CELL_UTIME_MODE_PPS, UBX_CELL_utime_sensor_t sensor = UBX_CELL_UTIME_SENSOR_GNSS_LTE); // Time mode, source etc. (+UTIME) + UBX_CELL_error_t getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor); + UBX_CELL_error_t setUtimeIndication(UBX_CELL_utime_urc_configuration_t config = UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED); // +UTIMEIND + UBX_CELL_error_t getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config); + UBX_CELL_error_t setUtimeConfiguration(int32_t offsetNanoseconds = 0, int32_t offsetSeconds = 0); // +UTIMECFG + UBX_CELL_error_t getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds); // Network service AT commands int8_t rssi(void); // Receive signal strength - UBLOX_AT_error_t getExtSignalQuality(signal_quality& signal_quality); + UBX_CELL_error_t getExtSignalQuality(signal_quality& signal_quality); - UBLOX_AT_registration_status_t registration(bool eps = true); + UBX_CELL_registration_status_t registration(bool eps = true); bool setNetworkProfile(mobile_network_operator_t mno, bool autoReset = false, bool urcNotification = false); mobile_network_operator_t getNetworkProfile(void); typedef enum @@ -749,12 +749,12 @@ class UBLOX_AT : public Print PDP_TYPE_NONIP = 1, PDP_TYPE_IPV4V6 = 2, PDP_TYPE_IPV6 = 3 - } UBLOX_AT_pdp_type; - UBLOX_AT_error_t setAPN(String apn, uint8_t cid = 1, UBLOX_AT_pdp_type pdpType = PDP_TYPE_IP); // Set the Access Point Name - UBLOX_AT_error_t getAPN(int cid, String *apn, IPAddress *ip, UBLOX_AT_pdp_type* pdpType = nullptr); // Return the apn and IP address for the chosen context identifier + } UBX_CELL_pdp_type; + UBX_CELL_error_t setAPN(String apn, uint8_t cid = 1, UBX_CELL_pdp_type pdpType = PDP_TYPE_IP); // Set the Access Point Name + UBX_CELL_error_t getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_pdp_type* pdpType = nullptr); // Return the apn and IP address for the chosen context identifier - UBLOX_AT_error_t getSimStatus(String* code); - UBLOX_AT_error_t setSimPin(String pin); + UBX_CELL_error_t getSimStatus(String* code); + UBX_CELL_error_t setSimPin(String pin); // SIM // Status report Mode: @@ -763,8 +763,8 @@ class UBLOX_AT : public Print // 1 Reports the (U)SIM phonebook initialization status ('s from 7 to 8 may be reported) // 2 Reports the (U)SIM toolkit REFRESH proactive command execution result ('s from 9 to 13 may be reported) // Note: For the SARA-R5: =7, 8, 9, 10, 11, 12 and 13 are not reported. - UBLOX_AT_error_t setSIMstateReportingMode(int mode); - UBLOX_AT_error_t getSIMstateReportingMode(int *mode); + UBX_CELL_error_t setSIMstateReportingMode(int mode); + UBX_CELL_error_t getSIMstateReportingMode(int *mode); typedef enum { @@ -773,30 +773,30 @@ class UBLOX_AT : public Print L2P_M_HEX, L2P_M_RAW_IP, L2P_M_OPT_PPP - } UBLOX_AT_l2p_t; - UBLOX_AT_error_t enterPPP(uint8_t cid = 1, char dialing_type_char = 0, - unsigned long dialNumber = 99, UBLOX_AT_l2p_t l2p = L2P_DEFAULT); + } UBX_CELL_l2p_t; + UBX_CELL_error_t enterPPP(uint8_t cid = 1, char dialing_type_char = 0, + unsigned long dialNumber = 99, UBX_CELL_l2p_t l2p = L2P_DEFAULT); uint8_t getOperators(struct operator_stats *op, int maxOps = 3); - UBLOX_AT_error_t registerOperator(struct operator_stats oper); - UBLOX_AT_error_t automaticOperatorSelection(); - UBLOX_AT_error_t getOperator(String *oper); - UBLOX_AT_error_t deregisterOperator(void); + UBX_CELL_error_t registerOperator(struct operator_stats oper); + UBX_CELL_error_t automaticOperatorSelection(); + UBX_CELL_error_t getOperator(String *oper); + UBX_CELL_error_t deregisterOperator(void); // SMS -- Short Messages Service - UBLOX_AT_error_t setSMSMessageFormat(UBLOX_AT_message_format_t textMode = UBLOX_AT_MESSAGE_FORMAT_TEXT); - UBLOX_AT_error_t sendSMS(String number, String message); - UBLOX_AT_error_t getPreferredMessageStorage(int *used, int *total, String memory = "ME"); - UBLOX_AT_error_t readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message); - UBLOX_AT_error_t deleteSMSmessage(int location, int deleteFlag = 0); // Default to deleting the single message at the specified location - UBLOX_AT_error_t deleteReadSMSmessages(void) { return (deleteSMSmessage( 1, 1 )); }; // Delete all the read messages from preferred storage - UBLOX_AT_error_t deleteReadSentSMSmessages(void) { return (deleteSMSmessage( 1, 2 )); }; // Delete the read and sent messages from preferred storage - UBLOX_AT_error_t deleteReadSentUnsentSMSmessages(void) { return (deleteSMSmessage( 1, 3 )); }; // Delete the read, sent and unsent messages from preferred storage - UBLOX_AT_error_t deleteAllSMSmessages(void) { return (deleteSMSmessage( 1, 4 )); }; // Delete the read, sent, unsent and unread messages from preferred storage + UBX_CELL_error_t setSMSMessageFormat(UBX_CELL_message_format_t textMode = UBX_CELL_MESSAGE_FORMAT_TEXT); + UBX_CELL_error_t sendSMS(String number, String message); + UBX_CELL_error_t getPreferredMessageStorage(int *used, int *total, String memory = "ME"); + UBX_CELL_error_t readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message); + UBX_CELL_error_t deleteSMSmessage(int location, int deleteFlag = 0); // Default to deleting the single message at the specified location + UBX_CELL_error_t deleteReadSMSmessages(void) { return (deleteSMSmessage( 1, 1 )); }; // Delete all the read messages from preferred storage + UBX_CELL_error_t deleteReadSentSMSmessages(void) { return (deleteSMSmessage( 1, 2 )); }; // Delete the read and sent messages from preferred storage + UBX_CELL_error_t deleteReadSentUnsentSMSmessages(void) { return (deleteSMSmessage( 1, 3 )); }; // Delete the read, sent and unsent messages from preferred storage + UBX_CELL_error_t deleteAllSMSmessages(void) { return (deleteSMSmessage( 1, 4 )); }; // Delete the read, sent, unsent and unread messages from preferred storage // V24 Control and V25ter (UART interface) AT commands - UBLOX_AT_error_t setBaud(unsigned long baud); - UBLOX_AT_error_t setFlowControl(UBLOX_AT_flow_control_t value = UBLOX_AT_ENABLE_FLOW_CONTROL); + UBX_CELL_error_t setBaud(unsigned long baud); + UBX_CELL_error_t setFlowControl(UBX_CELL_flow_control_t value = UBX_CELL_ENABLE_FLOW_CONTROL); // GPIO // GPIO pin map @@ -808,7 +808,7 @@ class UBLOX_AT : public Print GPIO4 = 25, GPIO5 = 42, GPIO6 = 19 - } UBLOX_AT_gpio_t; + } UBX_CELL_gpio_t; // GPIO pin modes typedef enum { @@ -845,57 +845,57 @@ class UBLOX_AT : public Print DTR_MODE, KHZ_32768_OUT = 32, PAD_DISABLED = 255 - } UBLOX_AT_gpio_mode_t; - UBLOX_AT_error_t setGpioMode(UBLOX_AT_gpio_t gpio, UBLOX_AT_gpio_mode_t mode, int value = 0); - UBLOX_AT_gpio_mode_t getGpioMode(UBLOX_AT_gpio_t gpio); + } UBX_CELL_gpio_mode_t; + UBX_CELL_error_t setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_t mode, int value = 0); + UBX_CELL_gpio_mode_t getGpioMode(UBX_CELL_gpio_t gpio); // IP Transport Layer - int socketOpen(UBLOX_AT_socket_protocol_t protocol, unsigned int localPort = 0); // Open a socket. Returns the socket number. - UBLOX_AT_error_t socketClose(int socket, unsigned long timeout = UBLOX_AT_2_MIN_TIMEOUT); // Close the socket - UBLOX_AT_error_t socketConnect(int socket, const char *address, unsigned int port); // TCP - connect to a remote IP Address using the specified port. Not required for UDP sockets. - UBLOX_AT_error_t socketConnect(int socket, IPAddress address, unsigned int port); + int socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int localPort = 0); // Open a socket. Returns the socket number. + UBX_CELL_error_t socketClose(int socket, unsigned long timeout = UBX_CELL_2_MIN_TIMEOUT); // Close the socket + UBX_CELL_error_t socketConnect(int socket, const char *address, unsigned int port); // TCP - connect to a remote IP Address using the specified port. Not required for UDP sockets. + UBX_CELL_error_t socketConnect(int socket, IPAddress address, unsigned int port); // Write data to the specified socket. Works with binary data - but you must specify the data length when using the const char * version // Works with both TCP and UDP sockets - but socketWriteUDP is preferred for UDP and doesn't require socketOpen to be called first - UBLOX_AT_error_t socketWrite(int socket, const char *str, int len = -1); - UBLOX_AT_error_t socketWrite(int socket, String str); // OK for binary data + UBX_CELL_error_t socketWrite(int socket, const char *str, int len = -1); + UBX_CELL_error_t socketWrite(int socket, String str); // OK for binary data // Write UDP data to the specified IP Address and port. // Works with binary data - but you must specify the data length when using the const char * versions // If you let len default to -1, strlen is used to calculate the data length - and will be incorrect for binary data - UBLOX_AT_error_t socketWriteUDP(int socket, const char *address, int port, const char *str, int len = -1); - UBLOX_AT_error_t socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len = -1); - UBLOX_AT_error_t socketWriteUDP(int socket, String address, int port, String str); + UBX_CELL_error_t socketWriteUDP(int socket, const char *address, int port, const char *str, int len = -1); + UBX_CELL_error_t socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len = -1); + UBX_CELL_error_t socketWriteUDP(int socket, String address, int port, String str); // Read data from the specified socket // Call socketReadAvailable first to determine how much data is available - or use the callbacks (triggered by URC's) // Works for both TCP and UDP - but socketReadUDP is preferred for UDP as it records the remote IP Address and port // bytesRead - if provided - will be updated with the number of bytes actually read. This could be less than length! - UBLOX_AT_error_t socketRead(int socket, int length, char *readDest, int *bytesRead = nullptr); + UBX_CELL_error_t socketRead(int socket, int length, char *readDest, int *bytesRead = nullptr); // Return the number of bytes available (waiting to be read) on the chosen socket // Uses +USORD. Valid for both TCP and UDP sockets - but socketReadAvailableUDP is preferred for UDP - UBLOX_AT_error_t socketReadAvailable(int socket, int *length); + UBX_CELL_error_t socketReadAvailable(int socket, int *length); // Read data from the specified UDP port // Call socketReadAvailableUDP first to determine how much data is available - or use the callbacks (triggered by URC's) // The remote IP Address and port are returned via *remoteIPAddress and *remotePort (if not nullptr) // bytesRead - if provided - will be updated with the number of bytes actually read. This could be less than length! - UBLOX_AT_error_t socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress = nullptr, int *remotePort = nullptr, int *bytesRead = nullptr); + UBX_CELL_error_t socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress = nullptr, int *remotePort = nullptr, int *bytesRead = nullptr); // Return the number of bytes available (waiting to be read) on the chosen UDP socket - UBLOX_AT_error_t socketReadAvailableUDP(int socket, int *length); + UBX_CELL_error_t socketReadAvailableUDP(int socket, int *length); // Start listening for a connection on the specified port. The connection is reported via the socket listen callback - UBLOX_AT_error_t socketListen(int socket, unsigned int port); + UBX_CELL_error_t socketListen(int socket, unsigned int port); // Place the socket into direct link mode - making it easy to transfer binary data. Wait two seconds and then send +++ to exit the link. - UBLOX_AT_error_t socketDirectLinkMode(int socket); + UBX_CELL_error_t socketDirectLinkMode(int socket); // Configure when direct link data is sent - UBLOX_AT_error_t socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger); - UBLOX_AT_error_t socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger); - UBLOX_AT_error_t socketDirectLinkCharacterTrigger(int socket, int characterTrigger); - UBLOX_AT_error_t socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer); + UBX_CELL_error_t socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger); + UBX_CELL_error_t socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger); + UBX_CELL_error_t socketDirectLinkCharacterTrigger(int socket, int characterTrigger); + UBX_CELL_error_t socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer); // Use +USOCTL (Socket control) to query the socket parameters - UBLOX_AT_error_t querySocketType(int socket, UBLOX_AT_socket_protocol_t *protocol); - UBLOX_AT_error_t querySocketLastError(int socket, int *error); - UBLOX_AT_error_t querySocketTotalBytesSent(int socket, uint32_t *total); - UBLOX_AT_error_t querySocketTotalBytesReceived(int socket, uint32_t *total); - UBLOX_AT_error_t querySocketRemoteIPAddress(int socket, IPAddress *address, int *port); - UBLOX_AT_error_t querySocketStatusTCP(int socket, UBLOX_AT_tcp_socket_status_t *status); - UBLOX_AT_error_t querySocketOutUnackData(int socket, uint32_t *total); + UBX_CELL_error_t querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol); + UBX_CELL_error_t querySocketLastError(int socket, int *error); + UBX_CELL_error_t querySocketTotalBytesSent(int socket, uint32_t *total); + UBX_CELL_error_t querySocketTotalBytesReceived(int socket, uint32_t *total); + UBX_CELL_error_t querySocketRemoteIPAddress(int socket, IPAddress *address, int *port); + UBX_CELL_error_t querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status); + UBX_CELL_error_t querySocketOutUnackData(int socket, uint32_t *total); // Return the most recent socket error int socketGetLastError(); // Return the remote IP Address from the most recent socket listen indication (socket connection) @@ -903,63 +903,63 @@ class UBLOX_AT : public Print IPAddress lastRemoteIP(void); // Ping - UBLOX_AT_error_t ping(String remote_host, int retry = 4, int p_size = 32, unsigned long timeout = 5000, int ttl = 32); + UBX_CELL_error_t ping(String remote_host, int retry = 4, int p_size = 32, unsigned long timeout = 5000, int ttl = 32); // HTTP - UBLOX_AT_error_t resetHTTPprofile(int profile); // Reset the HTTP profile. Note: The configured HTTP profile parameters are not saved in the non volatile memory. - UBLOX_AT_error_t setHTTPserverIPaddress(int profile, IPAddress address); // Default: empty string - UBLOX_AT_error_t setHTTPserverName(int profile, String server); // Default: empty string - UBLOX_AT_error_t setHTTPusername(int profile, String username); // Default: empty string - UBLOX_AT_error_t setHTTPpassword(int profile, String password); // Default: empty string - UBLOX_AT_error_t setHTTPauthentication(int profile, bool authenticate); // Default: no authentication - UBLOX_AT_error_t setHTTPserverPort(int profile, int port); // Default: 80 - UBLOX_AT_error_t setHTTPcustomHeader(int profile, String header); // Default: format 0:Content-Type:application/json" - UBLOX_AT_error_t setHTTPsecure(int profile, bool secure, int secprofile = -1); // Default: disabled (HTTP on port 80). Set to true for HTTPS on port 443 + UBX_CELL_error_t resetHTTPprofile(int profile); // Reset the HTTP profile. Note: The configured HTTP profile parameters are not saved in the non volatile memory. + UBX_CELL_error_t setHTTPserverIPaddress(int profile, IPAddress address); // Default: empty string + UBX_CELL_error_t setHTTPserverName(int profile, String server); // Default: empty string + UBX_CELL_error_t setHTTPusername(int profile, String username); // Default: empty string + UBX_CELL_error_t setHTTPpassword(int profile, String password); // Default: empty string + UBX_CELL_error_t setHTTPauthentication(int profile, bool authenticate); // Default: no authentication + UBX_CELL_error_t setHTTPserverPort(int profile, int port); // Default: 80 + UBX_CELL_error_t setHTTPcustomHeader(int profile, String header); // Default: format 0:Content-Type:application/json" + UBX_CELL_error_t setHTTPsecure(int profile, bool secure, int secprofile = -1); // Default: disabled (HTTP on port 80). Set to true for HTTPS on port 443 // TO DO: Add custom request headers - UBLOX_AT_error_t getHTTPprotocolError(int profile, int *error_class, int *error_code); // Read the most recent HTTP protocol error for this profile - UBLOX_AT_error_t sendHTTPGET(int profile, String path, String responseFilename); - UBLOX_AT_error_t sendHTTPPOSTdata(int profile, String path, String responseFilename, String data, UBLOX_AT_http_content_types_t httpContentType); - UBLOX_AT_error_t sendHTTPPOSTfile(int profile, String path, String responseFilename, String requestFile, UBLOX_AT_http_content_types_t httpContentType); - - UBLOX_AT_error_t nvMQTT(UBLOX_AT_mqtt_nv_parameter_t parameter); - UBLOX_AT_error_t setMQTTclientId(const String& clientId); - UBLOX_AT_error_t setMQTTserver(const String& serverName, int port); - UBLOX_AT_error_t setMQTTcredentials(const String& userName, const String& pwd); - UBLOX_AT_error_t setMQTTsecure(bool secure, int secprofile = -1); - UBLOX_AT_error_t connectMQTT(void); - UBLOX_AT_error_t disconnectMQTT(void); - UBLOX_AT_error_t subscribeMQTTtopic(int max_Qos, const String& topic); - UBLOX_AT_error_t unsubscribeMQTTtopic(const String& topic); - UBLOX_AT_error_t readMQTT(int* pQos, String* pTopic, uint8_t *readDest, int readLength, int *bytesRead); - UBLOX_AT_error_t mqttPublishTextMsg(const String& topic, const char * const msg, uint8_t qos = 0, bool retain = false); - UBLOX_AT_error_t mqttPublishBinaryMsg(const String& topic, const char * const msg, size_t msg_len, uint8_t qos = 0, bool retain = false); - UBLOX_AT_error_t mqttPublishFromFile(const String& topic, const String& filename, uint8_t qos = 0, bool retain = false); - UBLOX_AT_error_t getMQTTprotocolError(int *error_code, int *error_code2); + UBX_CELL_error_t getHTTPprotocolError(int profile, int *error_class, int *error_code); // Read the most recent HTTP protocol error for this profile + UBX_CELL_error_t sendHTTPGET(int profile, String path, String responseFilename); + UBX_CELL_error_t sendHTTPPOSTdata(int profile, String path, String responseFilename, String data, UBX_CELL_http_content_types_t httpContentType); + UBX_CELL_error_t sendHTTPPOSTfile(int profile, String path, String responseFilename, String requestFile, UBX_CELL_http_content_types_t httpContentType); + + UBX_CELL_error_t nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter); + UBX_CELL_error_t setMQTTclientId(const String& clientId); + UBX_CELL_error_t setMQTTserver(const String& serverName, int port); + UBX_CELL_error_t setMQTTcredentials(const String& userName, const String& pwd); + UBX_CELL_error_t setMQTTsecure(bool secure, int secprofile = -1); + UBX_CELL_error_t connectMQTT(void); + UBX_CELL_error_t disconnectMQTT(void); + UBX_CELL_error_t subscribeMQTTtopic(int max_Qos, const String& topic); + UBX_CELL_error_t unsubscribeMQTTtopic(const String& topic); + UBX_CELL_error_t readMQTT(int* pQos, String* pTopic, uint8_t *readDest, int readLength, int *bytesRead); + UBX_CELL_error_t mqttPublishTextMsg(const String& topic, const char * const msg, uint8_t qos = 0, bool retain = false); + UBX_CELL_error_t mqttPublishBinaryMsg(const String& topic, const char * const msg, size_t msg_len, uint8_t qos = 0, bool retain = false); + UBX_CELL_error_t mqttPublishFromFile(const String& topic, const String& filename, uint8_t qos = 0, bool retain = false); + UBX_CELL_error_t getMQTTprotocolError(int *error_code, int *error_code2); // FTP - UBLOX_AT_error_t setFTPserver(const String& serverName); - UBLOX_AT_error_t setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger); - UBLOX_AT_error_t setFTPcredentials(const String& userName, const String& pwd); - UBLOX_AT_error_t connectFTP(void); - UBLOX_AT_error_t disconnectFTP(void); - UBLOX_AT_error_t ftpGetFile(const String& filename); - UBLOX_AT_error_t getFTPprotocolError(int *error_code, int *error_code2); + UBX_CELL_error_t setFTPserver(const String& serverName); + UBX_CELL_error_t setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger); + UBX_CELL_error_t setFTPcredentials(const String& userName, const String& pwd); + UBX_CELL_error_t connectFTP(void); + UBX_CELL_error_t disconnectFTP(void); + UBX_CELL_error_t ftpGetFile(const String& filename); + UBX_CELL_error_t getFTPprotocolError(int *error_code, int *error_code2); // Configure security profiles - UBLOX_AT_error_t resetSecurityProfile(int secprofile); - UBLOX_AT_error_t configSecurityProfileString(int secprofile, UBLOX_AT_sec_profile_parameter_t parameter, String value); - UBLOX_AT_error_t configSecurityProfile(int secprofile, UBLOX_AT_sec_profile_parameter_t parameter, int value); - UBLOX_AT_error_t setSecurityManager(UBLOX_AT_sec_manager_opcode_t opcode, UBLOX_AT_sec_manager_parameter_t parameter, String name, String data); + UBX_CELL_error_t resetSecurityProfile(int secprofile); + UBX_CELL_error_t configSecurityProfileString(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, String value); + UBX_CELL_error_t configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value); + UBX_CELL_error_t setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, UBX_CELL_sec_manager_parameter_t parameter, String name, String data); // Packet Switched Data - // Configure the PDP using +UPSD. See UBLOX_AT_pdp_configuration_parameter_t for the list of parameters: protocol, APN, username, DNS, etc. - UBLOX_AT_error_t setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, int value); // Set parameters in the chosen PSD profile - UBLOX_AT_error_t setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, UBLOX_AT_pdp_protocol_type_t value); // Set parameters in the chosen PSD profile - UBLOX_AT_error_t setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, String value); // Set parameters in the chosen PSD profile - UBLOX_AT_error_t setPDPconfiguration(int profile, UBLOX_AT_pdp_configuration_parameter_t parameter, IPAddress value); // Set parameters in the chosen PSD profile - UBLOX_AT_error_t performPDPaction(int profile, UBLOX_AT_pdp_actions_t action); // Performs the requested action for the specified PSD profile: reset, store, load, activate, deactivate - UBLOX_AT_error_t activatePDPcontext(bool status, int cid = -1); // Activates or deactivates the specified PDP context. Default to all (cid = -1) - UBLOX_AT_error_t getNetworkAssignedIPAddress(int profile, IPAddress *address); // Get the dynamic IP address assigned during PDP context activation + // Configure the PDP using +UPSD. See UBX_CELL_pdp_configuration_parameter_t for the list of parameters: protocol, APN, username, DNS, etc. + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, UBX_CELL_pdp_protocol_type_t value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, String value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t performPDPaction(int profile, UBX_CELL_pdp_actions_t action); // Performs the requested action for the specified PSD profile: reset, store, load, activate, deactivate + UBX_CELL_error_t activatePDPcontext(bool status, int cid = -1); // Activates or deactivates the specified PDP context. Default to all (cid = -1) + UBX_CELL_error_t getNetworkAssignedIPAddress(int profile, IPAddress *address); // Get the dynamic IP address assigned during PDP context activation // GPS typedef enum @@ -981,52 +981,52 @@ class UBLOX_AT : public Print GNSS_AIDING_MODE_ASSISTNOW_AUTONOMOUS = 8 } gnss_aiding_mode_t; bool isGPSon(void); - UBLOX_AT_error_t gpsPower(bool enable = true, + UBX_CELL_error_t gpsPower(bool enable = true, gnss_system_t gnss_sys = GNSS_SYSTEM_GPS, gnss_aiding_mode_t gnss_aiding = GNSS_AIDING_MODE_AUTOMATIC); - //UBLOX_AT_error_t gpsEnableClock(bool enable = true); - //UBLOX_AT_error_t gpsGetClock(struct ClockData *clock); - //UBLOX_AT_error_t gpsEnableFix(bool enable = true); - //UBLOX_AT_error_t gpsGetFix(float *lat, float *lon, unsigned int *alt, uint8_t *quality, uint8_t *sat); - //UBLOX_AT_error_t gpsGetFix(struct PositionData *pos); - //UBLOX_AT_error_t gpsEnablePos(bool enable = true); - //UBLOX_AT_error_t gpsGetPos(struct PositionData *pos); - //UBLOX_AT_error_t gpsEnableSat(bool enable = true); - //UBLOX_AT_error_t gpsGetSat(uint8_t *sats); - UBLOX_AT_error_t gpsEnableRmc(bool enable = true); // Enable GPRMC messages - UBLOX_AT_error_t gpsGetRmc(struct PositionData *pos, struct SpeedData *speed, struct ClockData *clk, bool *valid); //Parse a GPRMC message - //UBLOX_AT_error_t gpsEnableSpeed(bool enable = true); - //UBLOX_AT_error_t gpsGetSpeed(struct SpeedData *speed); - - UBLOX_AT_error_t gpsRequest(unsigned int timeout, uint32_t accuracy, bool detailed = true, unsigned int sensor = 3); + //UBX_CELL_error_t gpsEnableClock(bool enable = true); + //UBX_CELL_error_t gpsGetClock(struct ClockData *clock); + //UBX_CELL_error_t gpsEnableFix(bool enable = true); + //UBX_CELL_error_t gpsGetFix(float *lat, float *lon, unsigned int *alt, uint8_t *quality, uint8_t *sat); + //UBX_CELL_error_t gpsGetFix(struct PositionData *pos); + //UBX_CELL_error_t gpsEnablePos(bool enable = true); + //UBX_CELL_error_t gpsGetPos(struct PositionData *pos); + //UBX_CELL_error_t gpsEnableSat(bool enable = true); + //UBX_CELL_error_t gpsGetSat(uint8_t *sats); + UBX_CELL_error_t gpsEnableRmc(bool enable = true); // Enable GPRMC messages + UBX_CELL_error_t gpsGetRmc(struct PositionData *pos, struct SpeedData *speed, struct ClockData *clk, bool *valid); //Parse a GPRMC message + //UBX_CELL_error_t gpsEnableSpeed(bool enable = true); + //UBX_CELL_error_t gpsGetSpeed(struct SpeedData *speed); + + UBX_CELL_error_t gpsRequest(unsigned int timeout, uint32_t accuracy, bool detailed = true, unsigned int sensor = 3); //CellLocate - UBLOX_AT_error_t gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, + UBX_CELL_error_t gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, unsigned int days = 14, unsigned int period = 4, unsigned int resolution = 1, unsigned int gnssTypes = 65, unsigned int mode = 0, unsigned int dataType = 15); // File system // TO DO: add full support for file tags. Default tag to USER - UBLOX_AT_error_t getFileContents(String filename, String *contents); // OK for text files. But will fail with binary files (containing \0) on some platforms. - UBLOX_AT_error_t getFileContents(String filename, char *contents); // OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. - UBLOX_AT_error_t getFileBlock(const String& filename, char* buffer, size_t offset, size_t length, size_t& bytes_read); // OK for binary files. Make sure buffer can hold the requested block size. + UBX_CELL_error_t getFileContents(String filename, String *contents); // OK for text files. But will fail with binary files (containing \0) on some platforms. + UBX_CELL_error_t getFileContents(String filename, char *contents); // OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. + UBX_CELL_error_t getFileBlock(const String& filename, char* buffer, size_t offset, size_t length, size_t& bytes_read); // OK for binary files. Make sure buffer can hold the requested block size. // Append data to a file, delete file first to not appends the data. - UBLOX_AT_error_t appendFileContents(String filename, String str); - UBLOX_AT_error_t appendFileContents(String filename, const char *str, int len); - UBLOX_AT_error_t getFileSize(String filename, int *size); - UBLOX_AT_error_t deleteFile(String filename); + UBX_CELL_error_t appendFileContents(String filename, String str); + UBX_CELL_error_t appendFileContents(String filename, const char *str, int len); + UBX_CELL_error_t getFileSize(String filename, int *size); + UBX_CELL_error_t deleteFile(String filename); // Functionality - UBLOX_AT_error_t functionality(UBLOX_AT_functionality_t function = FULL_FUNCTIONALITY); + UBX_CELL_error_t functionality(UBX_CELL_functionality_t function = FULL_FUNCTIONALITY); // Send a custom command with an expected (potentially partial) response, store entire response - UBLOX_AT_error_t sendCustomCommandWithResponse(const char *command, const char *expectedResponse, - char *responseDest, unsigned long commandTimeout = UBLOX_AT_STANDARD_RESPONSE_TIMEOUT, bool at = true); + UBX_CELL_error_t sendCustomCommandWithResponse(const char *command, const char *expectedResponse, + char *responseDest, unsigned long commandTimeout = UBX_CELL_STANDARD_RESPONSE_TIMEOUT, bool at = true); private: HardwareSerial *_hardSerial; -#ifdef UBLOX_AT_SOFTWARE_SERIAL_ENABLED +#ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED SoftwareSerial *_softSerial; #endif @@ -1049,7 +1049,7 @@ class UBLOX_AT : public Print #define _RXBuffSize 2056 const unsigned long _rxWindowMillis = 2; // 1ms is not quite long enough for a single char at 9600 baud. millis roll over much less often than micros. See notes in .cpp re. ESP32! - char *_saraRXBuffer; // Allocated in UBLOX_AT::begin + char *_saraRXBuffer; // Allocated in UBX_CELL::begin char *_pruneBuffer; char *_saraResponseBacklog; int _saraResponseBacklogLength = 0; // The backlog could contain binary data so we can't use strlen to find its length @@ -1059,40 +1059,40 @@ class UBLOX_AT : public Print void (*_socketReadCallbackPlus)(int, const char *, int, IPAddress, int); // socket, data, length, remoteAddress, remotePort void (*_socketCloseCallback)(int); void (*_gpsRequestCallback)(ClockData, PositionData, SpeedData, unsigned long); - void (*_simStateReportCallback)(UBLOX_AT_sim_states_t); + void (*_simStateReportCallback)(UBX_CELL_sim_states_t); void (*_psdActionRequestCallback)(int, IPAddress); void (*_pingRequestCallback)(int, int, String, IPAddress, int, long); void (*_httpCommandRequestCallback)(int, int, int); void (*_mqttCommandRequestCallback)(int, int); void (*_ftpCommandRequestCallback)(int, int); - void (*_registrationCallback)(UBLOX_AT_registration_status_t status, unsigned int lac, unsigned int ci, int Act); - void (*_epsRegistrationCallback)(UBLOX_AT_registration_status_t status, unsigned int tac, unsigned int ci, int Act); + void (*_registrationCallback)(UBX_CELL_registration_status_t status, unsigned int lac, unsigned int ci, int Act); + void (*_epsRegistrationCallback)(UBX_CELL_registration_status_t status, unsigned int tac, unsigned int ci, int Act); - int _lastSocketProtocol[UBLOX_AT_NUM_SOCKETS]; // Record the protocol for each socket to avoid having to call querySocketType in parseSocketReadIndication + int _lastSocketProtocol[UBX_CELL_NUM_SOCKETS]; // Record the protocol for each socket to avoid having to call querySocketType in parseSocketReadIndication typedef enum { - UBLOX_AT_INIT_STANDARD, - UBLOX_AT_INIT_AUTOBAUD, - UBLOX_AT_INIT_RESET - } UBLOX_AT_init_type_t; + UBX_CELL_INIT_STANDARD, + UBX_CELL_INIT_AUTOBAUD, + UBX_CELL_INIT_RESET + } UBX_CELL_init_type_t; - UBLOX_AT_error_t init(unsigned long baud, UBLOX_AT_init_type_t initType = UBLOX_AT_INIT_STANDARD); + UBX_CELL_error_t init(unsigned long baud, UBX_CELL_init_type_t initType = UBX_CELL_INIT_STANDARD); void powerOn(void); // Brief pulse on PWR_ON to turn module back on void powerOff(void); // Long pulse on PWR_ON to do a graceful shutdown. Note modulePowerOff (+CPWROFF) is preferred. void hwReset(void); - UBLOX_AT_error_t setMNOprofile(mobile_network_operator_t mno, bool autoReset = false, bool urcNotification = false); - UBLOX_AT_error_t getMNOprofile(mobile_network_operator_t *mno); + UBX_CELL_error_t setMNOprofile(mobile_network_operator_t mno, bool autoReset = false, bool urcNotification = false); + UBX_CELL_error_t getMNOprofile(mobile_network_operator_t *mno); // Wait for an expected response (don't send a command) - UBLOX_AT_error_t waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout); + UBX_CELL_error_t waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout); // Send command with an expected (potentially partial) response, store entire response - UBLOX_AT_error_t sendCommandWithResponse(const char *command, const char *expectedResponse, + UBX_CELL_error_t sendCommandWithResponse(const char *command, const char *expectedResponse, char *responseDest, unsigned long commandTimeout, int destSize = minimumResponseAllocation, bool at = true); // Send a command -- prepend AT if at is true @@ -1100,10 +1100,10 @@ class UBLOX_AT : public Print const int _saraR5maxSocketRead = 1024; // The limit on bytes that can be read in a single read - UBLOX_AT_error_t parseSocketReadIndication(int socket, int length); - UBLOX_AT_error_t parseSocketReadIndicationUDP(int socket, int length); - UBLOX_AT_error_t parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, int socket, IPAddress remoteIP, unsigned int port); - UBLOX_AT_error_t parseSocketCloseIndication(String *closeIndication); + UBX_CELL_error_t parseSocketReadIndication(int socket, int length); + UBX_CELL_error_t parseSocketReadIndicationUDP(int socket, int length); + UBX_CELL_error_t parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, int socket, IPAddress remoteIP, unsigned int port); + UBX_CELL_error_t parseSocketCloseIndication(String *closeIndication); // UART Functions size_t hwPrint(const char *s); @@ -1116,9 +1116,9 @@ class UBLOX_AT : public Print void setTimeout(unsigned long timeout); bool find(char *target); - UBLOX_AT_error_t autobaud(unsigned long desiredBaud); + UBX_CELL_error_t autobaud(unsigned long desiredBaud); - char *ublox_at_calloc_char(size_t num); + char *ubx_cell_calloc_char(size_t num); bool processURCEvent(const char *event); void pruneBacklog(void); @@ -1128,4 +1128,4 @@ class UBLOX_AT : public Print bool parseGPRMCString(char *rmcString, PositionData *pos, ClockData *clk, SpeedData *spd); }; -#endif //SPARKFUN_UBLOX_AT_ARDUINO_LIBRARY_H +#endif //SPARKFUN_UBX_CELL_ARDUINO_LIBRARY_H From 20beede048d49fc3fda5f54d87f89258aa63157d Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Fri, 17 Nov 2023 12:37:12 -0700 Subject: [PATCH 12/52] Fix SARA-R5 backwards compatibility Only in SparkFun_u-blox_SARA-R5_Arduino_Library.h --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 488 ++++++++---------- src/sfe_sara_r5.h | 368 ------------- 2 files changed, 204 insertions(+), 652 deletions(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h index 2ead05c..841b71b 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -1,4 +1,5 @@ // This file is purely for backwards compatibility with the original SARA-R5 library +// RegEx Replace: \#define\sSARA\_R5\_([A-Z0-9_]+).* \#define SARA\_R5\_$+ UBLOX\_AT\_$+ /* Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod Asset Tracker @@ -164,8 +165,8 @@ const char SARA_R5_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; #define SARA_R5_NUM_SOCKETS 6 -#define NUM_SUPPORTED_BAUD 6 -const unsigned long SARA_R5_SUPPORTED_BAUD[NUM_SUPPORTED_BAUD] = +#define SARA_R5_NUM_SUPPORTED_BAUD 6 +const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = { 115200, 9600, @@ -177,294 +178,213 @@ const unsigned long SARA_R5_SUPPORTED_BAUD[NUM_SUPPORTED_BAUD] = // Flow control definitions for AT&K // Note: SW (XON/XOFF) flow control is not supported on the SARA_R5 -typedef enum -{ - SARA_R5_DISABLE_FLOW_CONTROL = 0, - SARA_R5_ENABLE_FLOW_CONTROL = 3 -} SARA_R5_flow_control_t; - -typedef enum -{ - SARA_R5_ERROR_INVALID = -1, // -1 - SARA_R5_ERROR_SUCCESS = 0, // 0 - SARA_R5_ERROR_OUT_OF_MEMORY, // 1 - SARA_R5_ERROR_TIMEOUT, // 2 - SARA_R5_ERROR_UNEXPECTED_PARAM, // 3 - SARA_R5_ERROR_UNEXPECTED_RESPONSE, // 4 - SARA_R5_ERROR_NO_RESPONSE, // 5 - SARA_R5_ERROR_DEREGISTERED, // 6 - SARA_R5_ERROR_ZERO_READ_LENGTH, // 7 - SARA_R5_ERROR_ERROR // 8 -} SARA_R5_error_t; +#define SARA_R5_DISABLE_FLOW_CONTROL UBLOX_AT_DISABLE_FLOW_CONTROL +#define SARA_R5_ENABLE_FLOW_CONTROL UBLOX_AT_ENABLE_FLOW_CONTROL + +#define SARA_R5_ERROR_INVALID UBLOX_AT_ERROR_INVALID +#define SARA_R5_ERROR_SUCCESS UBLOX_AT_ERROR_SUCCESS +#define SARA_R5_ERROR_OUT_OF_MEMORY UBLOX_AT_ERROR_OUT_OF_MEMORY +#define SARA_R5_ERROR_TIMEOUT UBLOX_AT_ERROR_TIMEOUT +#define SARA_R5_ERROR_UNEXPECTED_PARAM UBLOX_AT_ERROR_UNEXPECTED_PARAM +#define SARA_R5_ERROR_UNEXPECTED_RESPONSE UBLOX_AT_ERROR_UNEXPECTED_RESPONSE +#define SARA_R5_ERROR_NO_RESPONSE UBLOX_AT_ERROR_NO_RESPONSE +#define SARA_R5_ERROR_DEREGISTERED UBLOX_AT_ERROR_DEREGISTERED +#define SARA_R5_ERROR_ZERO_READ_LENGTH UBLOX_AT_ERROR_ZERO_READ_LENGTH +#define SARA_R5_ERROR_ERROR UBLOX_AT_ERROR_ERROR #define SARA_R5_SUCCESS SARA_R5_ERROR_SUCCESS -typedef enum -{ - SARA_R5_REGISTRATION_INVALID = -1, - SARA_R5_REGISTRATION_NOT_REGISTERED = 0, - SARA_R5_REGISTRATION_HOME = 1, - SARA_R5_REGISTRATION_SEARCHING = 2, - SARA_R5_REGISTRATION_DENIED = 3, - SARA_R5_REGISTRATION_UNKNOWN = 4, - SARA_R5_REGISTRATION_ROAMING = 5, - SARA_R5_REGISTRATION_HOME_SMS_ONLY = 6, - SARA_R5_REGISTRATION_ROAMING_SMS_ONLY = 7, - SARA_R5_REGISTRATION_EMERGENCY_SERV_ONLY = 8, - SARA_R5_REGISTRATION_HOME_CSFB_NOT_PREFERRED = 9, - SARA_R5_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED = 10 -} SARA_R5_registration_status_t; - -typedef enum -{ - SARA_R5_TCP = 6, - SARA_R5_UDP = 17 -} SARA_R5_socket_protocol_t; - -typedef enum -{ - SARA_R5_TCP_SOCKET_STATUS_INACTIVE, - SARA_R5_TCP_SOCKET_STATUS_LISTEN, - SARA_R5_TCP_SOCKET_STATUS_SYN_SENT, - SARA_R5_TCP_SOCKET_STATUS_SYN_RCVD, - SARA_R5_TCP_SOCKET_STATUS_ESTABLISHED, - SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_1, - SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_2, - SARA_R5_TCP_SOCKET_STATUS_CLOSE_WAIT, - SARA_R5_TCP_SOCKET_STATUS_CLOSING, - SARA_R5_TCP_SOCKET_STATUS_LAST_ACK, - SARA_R5_TCP_SOCKET_STATUS_TIME_WAIT -} SARA_R5_tcp_socket_status_t; - -typedef enum -{ - SARA_R5_MESSAGE_FORMAT_PDU = 0, - SARA_R5_MESSAGE_FORMAT_TEXT = 1 -} SARA_R5_message_format_t; - -typedef enum -{ - SARA_R5_UTIME_MODE_STOP = 0, - SARA_R5_UTIME_MODE_PPS, - SARA_R5_UTIME_MODE_ONE_SHOT, - SARA_R5_UTIME_MODE_EXT_INT -} SARA_R5_utime_mode_t; - -typedef enum -{ - SARA_R5_UTIME_SENSOR_NONE = 0, - SARA_R5_UTIME_SENSOR_GNSS_LTE = 1, - SARA_R5_UTIME_SENSOR_LTE -} SARA_R5_utime_sensor_t; - -typedef enum -{ - SARA_R5_UTIME_URC_CONFIGURATION_DISABLED = 0, - SARA_R5_UTIME_URC_CONFIGURATION_ENABLED -} SARA_R5_utime_urc_configuration_t; - -typedef enum -{ - SARA_R5_SIM_NOT_PRESENT = 0, - SARA_R5_SIM_PIN_NEEDED, - SARA_R5_SIM_PIN_BLOCKED, - SARA_R5_SIM_PUK_BLOCKED, - SARA_R5_SIM_NOT_OPERATIONAL, - SARA_R5_SIM_RESTRICTED, - SARA_R5_SIM_OPERATIONAL - //SARA_R5_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 - //SARA_R5_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 - //SARA_R5_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 - //SARA_R5_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 - //SARA_R5_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 - //SARA_R5_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 - //SARA_R5_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 -} SARA_R5_sim_states_t; +#define SARA_R5_REGISTRATION_INVALID UBLOX_AT_REGISTRATION_INVALID +#define SARA_R5_REGISTRATION_NOT_REGISTERED UBLOX_AT_REGISTRATION_NOT_REGISTERED +#define SARA_R5_REGISTRATION_HOME UBLOX_AT_REGISTRATION_HOME +#define SARA_R5_REGISTRATION_SEARCHING UBLOX_AT_REGISTRATION_SEARCHING +#define SARA_R5_REGISTRATION_DENIED UBLOX_AT_REGISTRATION_DENIED +#define SARA_R5_REGISTRATION_UNKNOWN UBLOX_AT_REGISTRATION_UNKNOWN +#define SARA_R5_REGISTRATION_ROAMING UBLOX_AT_REGISTRATION_ROAMING +#define SARA_R5_REGISTRATION_HOME_SMS_ONLY UBLOX_AT_REGISTRATION_HOME_SMS_ONLY +#define SARA_R5_REGISTRATION_ROAMING_SMS_ONLY UBLOX_AT_REGISTRATION_ROAMING_SMS_ONLY +#define SARA_R5_REGISTRATION_EMERGENCY_SERV_ONLY UBLOX_AT_REGISTRATION_EMERGENCY_SERV_ONLY +#define SARA_R5_REGISTRATION_HOME_CSFB_NOT_PREFERRED UBLOX_AT_REGISTRATION_HOME_CSFB_NOT_PREFERRED +#define SARA_R5_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED UBLOX_AT_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED + +#define SARA_R5_TCP UBLOX_AT_TCP +#define SARA_R5_UDP UBLOX_AT_UDP + +#define SARA_R5_TCP_SOCKET_STATUS_INACTIVE UBLOX_AT_TCP_SOCKET_STATUS_INACTIVE +#define SARA_R5_TCP_SOCKET_STATUS_LISTEN UBLOX_AT_TCP_SOCKET_STATUS_LISTEN +#define SARA_R5_TCP_SOCKET_STATUS_SYN_SENT UBLOX_AT_TCP_SOCKET_STATUS_SYN_SENT +#define SARA_R5_TCP_SOCKET_STATUS_SYN_RCVD UBLOX_AT_TCP_SOCKET_STATUS_SYN_RCVD +#define SARA_R5_TCP_SOCKET_STATUS_ESTABLISHED UBLOX_AT_TCP_SOCKET_STATUS_ESTABLISHED +#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_1 UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_1 +#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_2 UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_2 +#define SARA_R5_TCP_SOCKET_STATUS_CLOSE_WAIT UBLOX_AT_TCP_SOCKET_STATUS_CLOSE_WAIT +#define SARA_R5_TCP_SOCKET_STATUS_CLOSING UBLOX_AT_TCP_SOCKET_STATUS_CLOSING +#define SARA_R5_TCP_SOCKET_STATUS_LAST_ACK UBLOX_AT_TCP_SOCKET_STATUS_LAST_ACK +#define SARA_R5_TCP_SOCKET_STATUS_TIME_WAIT UBLOX_AT_TCP_SOCKET_STATUS_TIME_WAIT + +#define SARA_R5_MESSAGE_FORMAT_PDU UBLOX_AT_MESSAGE_FORMAT_PDU +#define SARA_R5_MESSAGE_FORMAT_TEXT UBLOX_AT_MESSAGE_FORMAT_TEXT + +#define SARA_R5_UTIME_MODE_STOP UBLOX_AT_UTIME_MODE_STOP +#define SARA_R5_UTIME_MODE_PPS UBLOX_AT_UTIME_MODE_PPS +#define SARA_R5_UTIME_MODE_ONE_SHOT UBLOX_AT_UTIME_MODE_ONE_SHOT +#define SARA_R5_UTIME_MODE_EXT_INT UBLOX_AT_UTIME_MODE_EXT_INT + +#define SARA_R5_UTIME_SENSOR_NONE UBLOX_AT_UTIME_SENSOR_NONE +#define SARA_R5_UTIME_SENSOR_GNSS_LTE UBLOX_AT_UTIME_SENSOR_GNSS_LTE +#define SARA_R5_UTIME_SENSOR_LTE UBLOX_AT_UTIME_SENSOR_LTE + +#define SARA_R5_UTIME_URC_CONFIGURATION_DISABLED UBLOX_AT_UTIME_URC_CONFIGURATION_DISABLED +#define SARA_R5_UTIME_URC_CONFIGURATION_ENABLED UBLOX_AT_UTIME_URC_CONFIGURATION_ENABLED + +#define SARA_R5_SIM_NOT_PRESENT UBLOX_AT_SIM_NOT_PRESENT +#define SARA_R5_SIM_PIN_NEEDED UBLOX_AT_SIM_PIN_NEEDED +#define SARA_R5_SIM_PIN_BLOCKED UBLOX_AT_SIM_PIN_BLOCKED +#define SARA_R5_SIM_PUK_BLOCKED UBLOX_AT_SIM_PUK_BLOCKED +#define SARA_R5_SIM_NOT_OPERATIONAL UBLOX_AT_SIM_NOT_OPERATIONAL +#define SARA_R5_SIM_RESTRICTED UBLOX_AT_SIM_RESTRICTED +#define SARA_R5_SIM_OPERATIONAL UBLOX_AT_SIM_OPERATIONAL +//SARA_R5_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 +//SARA_R5_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 +//SARA_R5_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 +//SARA_R5_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 +//SARA_R5_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 +//SARA_R5_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 +//SARA_R5_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 #define SARA_R5_NUM_PSD_PROFILES 6 // Number of supported PSD profiles #define SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS 11 // Number of supported PDP context identifiers #define SARA_R5_NUM_HTTP_PROFILES 4 // Number of supported HTTP profiles -typedef enum -{ - SARA_R5_HTTP_OP_CODE_SERVER_IP = 0, - SARA_R5_HTTP_OP_CODE_SERVER_NAME, - SARA_R5_HTTP_OP_CODE_USERNAME, - SARA_R5_HTTP_OP_CODE_PASSWORD, - SARA_R5_HTTP_OP_CODE_AUTHENTICATION, - SARA_R5_HTTP_OP_CODE_SERVER_PORT, - SARA_R5_HTTP_OP_CODE_SECURE, - SARA_R5_HTTP_OP_CODE_REQUEST_TIMEOUT, - SARA_R5_HTTP_OP_CODE_ADD_CUSTOM_HEADERS = 9 -} SARA_R5_http_op_codes_t; - -typedef enum -{ - SARA_R5_HTTP_COMMAND_HEAD = 0, - SARA_R5_HTTP_COMMAND_GET, - SARA_R5_HTTP_COMMAND_DELETE, - SARA_R5_HTTP_COMMAND_PUT, - SARA_R5_HTTP_COMMAND_POST_FILE, - SARA_R5_HTTP_COMMAND_POST_DATA, - SARA_R5_HTTP_COMMAND_GET_FOTA = 100 -} SARA_R5_http_commands_t; - -typedef enum -{ - SARA_R5_HTTP_CONTENT_APPLICATION_X_WWW = 0, - SARA_R5_HTTP_CONTENT_TEXT_PLAIN, - SARA_R5_HTTP_CONTENT_APPLICATION_OCTET, - SARA_R5_HTTP_CONTENT_MULTIPART_FORM, - SARA_R5_HTTP_CONTENT_APPLICATION_JSON, - SARA_R5_HTTP_CONTENT_APPLICATION_XML, - SARA_R5_HTTP_CONTENT_USER_DEFINED -} SARA_R5_http_content_types_t; - -typedef enum -{ - SARA_R5_MQTT_NV_RESTORE = 0, - SARA_R5_MQTT_NV_SET, - SARA_R5_MQTT_NV_STORE, -} SARA_R5_mqtt_nv_parameter_t; - -typedef enum -{ - SARA_R5_MQTT_PROFILE_CLIENT_ID = 0, - SARA_R5_MQTT_PROFILE_SERVERNAME = 2, - SARA_R5_MQTT_PROFILE_IPADDRESS, - SARA_R5_MQTT_PROFILE_USERNAMEPWD, - SARA_R5_MQTT_PROFILE_QOS = 6, - SARA_R5_MQTT_PROFILE_RETAIN, - SARA_R5_MQTT_PROFILE_TOPIC, - SARA_R5_MQTT_PROFILE_MESSAGE, - SARA_R5_MQTT_PROFILE_INACTIVITYTIMEOUT, - SARA_R5_MQTT_PROFILE_SECURE, -} SARA_R5_mqtt_profile_opcode_t; - -typedef enum -{ - SARA_R5_MQTT_COMMAND_INVALID = -1, - SARA_R5_MQTT_COMMAND_LOGOUT = 0, - SARA_R5_MQTT_COMMAND_LOGIN, - SARA_R5_MQTT_COMMAND_PUBLISH, - SARA_R5_MQTT_COMMAND_PUBLISHFILE, - SARA_R5_MQTT_COMMAND_SUBSCRIBE, - SARA_R5_MQTT_COMMAND_UNSUBSCRIBE, - SARA_R5_MQTT_COMMAND_READ, - SARA_R5_MQTT_COMMAND_RCVMSGFORMAT, - SARA_R5_MQTT_COMMAND_PING, - SARA_R5_MQTT_COMMAND_PUBLISHBINARY, -} SARA_R5_mqtt_command_opcode_t; - -typedef enum -{ - SARA_R5_FTP_PROFILE_IPADDRESS = 0, - SARA_R5_FTP_PROFILE_SERVERNAME, - SARA_R5_FTP_PROFILE_USERNAME, - SARA_R5_FTP_PROFILE_PWD, - SARA_R5_FTP_PROFILE_ACCOUNT, - SARA_R5_FTP_PROFILE_TIMEOUT, - SARA_R5_FTP_PROFILE_MODE -} SARA_R5_ftp_profile_opcode_t; - -typedef enum -{ - SARA_R5_FTP_COMMAND_INVALID = -1, - SARA_R5_FTP_COMMAND_LOGOUT = 0, - SARA_R5_FTP_COMMAND_LOGIN, - SARA_R5_FTP_COMMAND_DELETE_FILE, - SARA_R5_FTP_COMMAND_RENAME_FILE, - SARA_R5_FTP_COMMAND_GET_FILE, - SARA_R5_FTP_COMMAND_PUT_FILE, - SARA_R5_FTP_COMMAND_GET_FILE_DIRECT, - SARA_R5_FTP_COMMAND_PUT_FILE_DIRECT, - SARA_R5_FTP_COMMAND_CHANGE_DIR, - SARA_R5_FTP_COMMAND_MKDIR = 10, - SARA_R5_FTP_COMMAND_RMDIR, - SARA_R5_FTP_COMMAND_DIR_INFO = 13, - SARA_R5_FTP_COMMAND_LS, - SARA_R5_FTP_COMMAND_GET_FOTA_FILE = 100 -} SARA_R5_ftp_command_opcode_t; - -typedef enum -{ - SARA_R5_PSD_CONFIG_PARAM_PROTOCOL = 0, - SARA_R5_PSD_CONFIG_PARAM_APN, - //SARA_R5_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 - //SARA_R5_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 - SARA_R5_PSD_CONFIG_PARAM_DNS1 = 4, - SARA_R5_PSD_CONFIG_PARAM_DNS2, - //SARA_R5_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 - //SARA_R5_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 - //SARA_R5_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 - //SARA_R5_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 - SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID = 100 -} SARA_R5_pdp_configuration_parameter_t; - -typedef enum -{ - SARA_R5_PSD_PROTOCOL_IPV4 = 0, - SARA_R5_PSD_PROTOCOL_IPV6, - SARA_R5_PSD_PROTOCOL_IPV4V6_V4_PREF, - SARA_R5_PSD_PROTOCOL_IPV4V6_V6_PREF -} SARA_R5_pdp_protocol_type_t; - -typedef enum -{ - SARA_R5_PSD_ACTION_RESET = 0, - SARA_R5_PSD_ACTION_STORE, - SARA_R5_PSD_ACTION_LOAD, - SARA_R5_PSD_ACTION_ACTIVATE, - SARA_R5_PSD_ACTION_DEACTIVATE -} SARA_R5_pdp_actions_t; - -typedef enum -{ - SARA_R5_SEC_PROFILE_PARAM_CERT_VAL_LEVEL = 0, - SARA_R5_SEC_PROFILE_PARAM_TLS_VER, - SARA_R5_SEC_PROFILE_PARAM_CYPHER_SUITE, - SARA_R5_SEC_PROFILE_PARAM_ROOT_CA, - SARA_R5_SEC_PROFILE_PARAM_HOSTNAME, - SARA_R5_SEC_PROFILE_PARAM_CLIENT_CERT, - SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY, - SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY_PWD, - SARA_R5_SEC_PROFILE_PARAM_PSK, - SARA_R5_SEC_PROFILE_PARAM_PSK_IDENT, - SARA_R5_SEC_PROFILE_PARAM_SNI, -} SARA_R5_sec_profile_parameter_t; - -typedef enum -{ - SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_NO = 0, - SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL, - SARA_R5_SEC_PROFILE_CERVTAL_OPCODE_YESURL, - SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE, -} SARA_R5_sec_profile_certval_op_code_t; - -typedef enum -{ - SARA_R5_SEC_PROFILE_TLS_OPCODE_ANYVER = 0, - SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_0, - SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_1, - SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_2, - SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_3, -} SARA_R5_sec_profile_tls_op_code_t; - -typedef enum -{ - SARA_R5_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT = 0, -} SARA_R5_sec_profile_suite_op_code_t; - -typedef enum -{ - SARA_R5_SEC_MANAGER_OPCODE_IMPORT = 0, -} SARA_R5_sec_manager_opcode_t; - -typedef enum -{ - SARA_R5_SEC_MANAGER_ROOTCA = 0, - SARA_R5_SEC_MANAGER_CLIENT_CERT, - SARA_R5_SEC_MANAGER_CLIENT_KEY, - SARA_R5_SEC_MANAGER_SERVER_CERT -} SARA_R5_sec_manager_parameter_t; +#define SARA_R5_HTTP_OP_CODE_SERVER_IP UBLOX_AT_HTTP_OP_CODE_SERVER_IP +#define SARA_R5_HTTP_OP_CODE_SERVER_NAME UBLOX_AT_HTTP_OP_CODE_SERVER_NAME +#define SARA_R5_HTTP_OP_CODE_USERNAME UBLOX_AT_HTTP_OP_CODE_USERNAME +#define SARA_R5_HTTP_OP_CODE_PASSWORD UBLOX_AT_HTTP_OP_CODE_PASSWORD +#define SARA_R5_HTTP_OP_CODE_AUTHENTICATION UBLOX_AT_HTTP_OP_CODE_AUTHENTICATION +#define SARA_R5_HTTP_OP_CODE_SERVER_PORT UBLOX_AT_HTTP_OP_CODE_SERVER_PORT +#define SARA_R5_HTTP_OP_CODE_SECURE UBLOX_AT_HTTP_OP_CODE_SECURE +#define SARA_R5_HTTP_OP_CODE_REQUEST_TIMEOUT UBLOX_AT_HTTP_OP_CODE_REQUEST_TIMEOUT +#define SARA_R5_HTTP_OP_CODE_ADD_CUSTOM_HEADERS UBLOX_AT_HTTP_OP_CODE_ADD_CUSTOM_HEADERS + +#define SARA_R5_HTTP_COMMAND_HEAD UBLOX_AT_HTTP_COMMAND_HEAD +#define SARA_R5_HTTP_COMMAND_GET UBLOX_AT_HTTP_COMMAND_GET +#define SARA_R5_HTTP_COMMAND_DELETE UBLOX_AT_HTTP_COMMAND_DELETE +#define SARA_R5_HTTP_COMMAND_PUT UBLOX_AT_HTTP_COMMAND_PUT +#define SARA_R5_HTTP_COMMAND_POST_FILE UBLOX_AT_HTTP_COMMAND_POST_FILE +#define SARA_R5_HTTP_COMMAND_POST_DATA UBLOX_AT_HTTP_COMMAND_POST_DATA +#define SARA_R5_HTTP_COMMAND_GET_FOTA UBLOX_AT_HTTP_COMMAND_GET_FOTA + +#define SARA_R5_HTTP_CONTENT_APPLICATION_X_WWW UBLOX_AT_HTTP_CONTENT_APPLICATION_X_WWW +#define SARA_R5_HTTP_CONTENT_TEXT_PLAIN UBLOX_AT_HTTP_CONTENT_TEXT_PLAIN +#define SARA_R5_HTTP_CONTENT_APPLICATION_OCTET UBLOX_AT_HTTP_CONTENT_APPLICATION_OCTET +#define SARA_R5_HTTP_CONTENT_MULTIPART_FORM UBLOX_AT_HTTP_CONTENT_MULTIPART_FORM +#define SARA_R5_HTTP_CONTENT_APPLICATION_JSON UBLOX_AT_HTTP_CONTENT_APPLICATION_JSON +#define SARA_R5_HTTP_CONTENT_APPLICATION_XML UBLOX_AT_HTTP_CONTENT_APPLICATION_XML +#define SARA_R5_HTTP_CONTENT_USER_DEFINED UBLOX_AT_HTTP_CONTENT_USER_DEFINED + +#define SARA_R5_MQTT_NV_RESTORE UBLOX_AT_MQTT_NV_RESTORE +#define SARA_R5_MQTT_NV_SET UBLOX_AT_MQTT_NV_SET +#define SARA_R5_MQTT_NV_STORE UBLOX_AT_MQTT_NV_STORE + +#define SARA_R5_MQTT_PROFILE_CLIENT_ID UBLOX_AT_MQTT_PROFILE_CLIENT_ID +#define SARA_R5_MQTT_PROFILE_SERVERNAME UBLOX_AT_MQTT_PROFILE_SERVERNAME +#define SARA_R5_MQTT_PROFILE_IPADDRESS UBLOX_AT_MQTT_PROFILE_IPADDRESS +#define SARA_R5_MQTT_PROFILE_USERNAMEPWD UBLOX_AT_MQTT_PROFILE_USERNAMEPWD +#define SARA_R5_MQTT_PROFILE_QOS UBLOX_AT_MQTT_PROFILE_QOS +#define SARA_R5_MQTT_PROFILE_RETAIN UBLOX_AT_MQTT_PROFILE_RETAIN +#define SARA_R5_MQTT_PROFILE_TOPIC UBLOX_AT_MQTT_PROFILE_TOPIC +#define SARA_R5_MQTT_PROFILE_MESSAGE UBLOX_AT_MQTT_PROFILE_MESSAGE +#define SARA_R5_MQTT_PROFILE_INACTIVITYTIMEOUT UBLOX_AT_MQTT_PROFILE_INACTIVITYTIMEOUT +#define SARA_R5_MQTT_PROFILE_SECURE UBLOX_AT_MQTT_PROFILE_SECURE + +#define SARA_R5_MQTT_COMMAND_INVALID UBLOX_AT_MQTT_COMMAND_INVALID +#define SARA_R5_MQTT_COMMAND_LOGOUT UBLOX_AT_MQTT_COMMAND_LOGOUT +#define SARA_R5_MQTT_COMMAND_LOGIN UBLOX_AT_MQTT_COMMAND_LOGIN +#define SARA_R5_MQTT_COMMAND_PUBLISH UBLOX_AT_MQTT_COMMAND_PUBLISH +#define SARA_R5_MQTT_COMMAND_PUBLISHFILE UBLOX_AT_MQTT_COMMAND_PUBLISHFILE +#define SARA_R5_MQTT_COMMAND_SUBSCRIBE UBLOX_AT_MQTT_COMMAND_SUBSCRIBE +#define SARA_R5_MQTT_COMMAND_UNSUBSCRIBE UBLOX_AT_MQTT_COMMAND_UNSUBSCRIBE +#define SARA_R5_MQTT_COMMAND_READ UBLOX_AT_MQTT_COMMAND_READ +#define SARA_R5_MQTT_COMMAND_RCVMSGFORMAT UBLOX_AT_MQTT_COMMAND_RCVMSGFORMAT +#define SARA_R5_MQTT_COMMAND_PING UBLOX_AT_MQTT_COMMAND_PING +#define SARA_R5_MQTT_COMMAND_PUBLISHBINARY UBLOX_AT_MQTT_COMMAND_PUBLISHBINARY + +#define SARA_R5_FTP_PROFILE_IPADDRESS UBLOX_AT_FTP_PROFILE_IPADDRESS +#define SARA_R5_FTP_PROFILE_SERVERNAME UBLOX_AT_FTP_PROFILE_SERVERNAME +#define SARA_R5_FTP_PROFILE_USERNAME UBLOX_AT_FTP_PROFILE_USERNAME +#define SARA_R5_FTP_PROFILE_PWD UBLOX_AT_FTP_PROFILE_PWD +#define SARA_R5_FTP_PROFILE_ACCOUNT UBLOX_AT_FTP_PROFILE_ACCOUNT +#define SARA_R5_FTP_PROFILE_TIMEOUT UBLOX_AT_FTP_PROFILE_TIMEOUT +#define SARA_R5_FTP_PROFILE_MODE UBLOX_AT_FTP_PROFILE_MODE + +#define SARA_R5_FTP_COMMAND_INVALID UBLOX_AT_FTP_COMMAND_INVALID +#define SARA_R5_FTP_COMMAND_LOGOUT UBLOX_AT_FTP_COMMAND_LOGOUT +#define SARA_R5_FTP_COMMAND_LOGIN UBLOX_AT_FTP_COMMAND_LOGIN +#define SARA_R5_FTP_COMMAND_DELETE_FILE UBLOX_AT_FTP_COMMAND_DELETE_FILE +#define SARA_R5_FTP_COMMAND_RENAME_FILE UBLOX_AT_FTP_COMMAND_RENAME_FILE +#define SARA_R5_FTP_COMMAND_GET_FILE UBLOX_AT_FTP_COMMAND_GET_FILE +#define SARA_R5_FTP_COMMAND_PUT_FILE UBLOX_AT_FTP_COMMAND_PUT_FILE +#define SARA_R5_FTP_COMMAND_GET_FILE_DIRECT UBLOX_AT_FTP_COMMAND_GET_FILE_DIRECT +#define SARA_R5_FTP_COMMAND_PUT_FILE_DIRECT UBLOX_AT_FTP_COMMAND_PUT_FILE_DIRECT +#define SARA_R5_FTP_COMMAND_CHANGE_DIR UBLOX_AT_FTP_COMMAND_CHANGE_DIR +#define SARA_R5_FTP_COMMAND_MKDIR UBLOX_AT_FTP_COMMAND_MKDIR +#define SARA_R5_FTP_COMMAND_RMDIR UBLOX_AT_FTP_COMMAND_RMDIR +#define SARA_R5_FTP_COMMAND_DIR_INFO UBLOX_AT_FTP_COMMAND_DIR_INFO +#define SARA_R5_FTP_COMMAND_LS UBLOX_AT_FTP_COMMAND_LS +#define SARA_R5_FTP_COMMAND_GET_FOTA_FILE UBLOX_AT_FTP_COMMAND_GET_FOTA_FILE + +#define SARA_R5_PSD_CONFIG_PARAM_PROTOCOL UBLOX_AT_PSD_CONFIG_PARAM_PROTOCOL +#define SARA_R5_PSD_CONFIG_PARAM_APN UBLOX_AT_PSD_CONFIG_PARAM_APN +//SARA_R5_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 +//SARA_R5_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 +#define SARA_R5_PSD_CONFIG_PARAM_DNS1 UBLOX_AT_PSD_CONFIG_PARAM_DNS1 +#define SARA_R5_PSD_CONFIG_PARAM_DNS2 UBLOX_AT_PSD_CONFIG_PARAM_DNS2 +//SARA_R5_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 +//SARA_R5_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 +//SARA_R5_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 +//SARA_R5_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 +#define SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID UBLOX_AT_PSD_CONFIG_PARAM_MAP_TO_CID + +#define SARA_R5_PSD_PROTOCOL_IPV4 UBLOX_AT_PSD_PROTOCOL_IPV4 +#define SARA_R5_PSD_PROTOCOL_IPV6 UBLOX_AT_PSD_PROTOCOL_IPV6 +#define SARA_R5_PSD_PROTOCOL_IPV4V6_V4_PREF UBLOX_AT_PSD_PROTOCOL_IPV4V6_V4_PREF +#define SARA_R5_PSD_PROTOCOL_IPV4V6_V6_PREF UBLOX_AT_PSD_PROTOCOL_IPV4V6_V6_PREF + +#define SARA_R5_PSD_ACTION_RESET UBLOX_AT_PSD_ACTION_RESET +#define SARA_R5_PSD_ACTION_STORE UBLOX_AT_PSD_ACTION_STORE +#define SARA_R5_PSD_ACTION_LOAD UBLOX_AT_PSD_ACTION_LOAD +#define SARA_R5_PSD_ACTION_ACTIVATE UBLOX_AT_PSD_ACTION_ACTIVATE +#define SARA_R5_PSD_ACTION_DEACTIVATE UBLOX_AT_PSD_ACTION_DEACTIVATE + +#define SARA_R5_SEC_PROFILE_PARAM_CERT_VAL_LEVEL UBLOX_AT_SEC_PROFILE_PARAM_CERT_VAL_LEVEL +#define SARA_R5_SEC_PROFILE_PARAM_TLS_VER UBLOX_AT_SEC_PROFILE_PARAM_TLS_VER +#define SARA_R5_SEC_PROFILE_PARAM_CYPHER_SUITE UBLOX_AT_SEC_PROFILE_PARAM_CYPHER_SUITE +#define SARA_R5_SEC_PROFILE_PARAM_ROOT_CA UBLOX_AT_SEC_PROFILE_PARAM_ROOT_CA +#define SARA_R5_SEC_PROFILE_PARAM_HOSTNAME UBLOX_AT_SEC_PROFILE_PARAM_HOSTNAME +#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_CERT UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_CERT +#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY +#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY_PWD UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY_PWD +#define SARA_R5_SEC_PROFILE_PARAM_PSK UBLOX_AT_SEC_PROFILE_PARAM_PSK +#define SARA_R5_SEC_PROFILE_PARAM_PSK_IDENT UBLOX_AT_SEC_PROFILE_PARAM_PSK_IDENT +#define SARA_R5_SEC_PROFILE_PARAM_SNI UBLOX_AT_SEC_PROFILE_PARAM_SNI + +#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_NO UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_NO +#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL +#define SARA_R5_SEC_PROFILE_CERVTAL_OPCODE_YESURL UBLOX_AT_SEC_PROFILE_CERVTAL_OPCODE_YESURL +#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE + +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_ANYVER UBLOX_AT_SEC_PROFILE_TLS_OPCODE_ANYVER +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_0 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_0 +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_1 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_1 +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_2 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_2 +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_3 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_3 + +#define SARA_R5_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT UBLOX_AT_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT + +#define SARA_R5_SEC_MANAGER_OPCODE_IMPORT UBLOX_AT_SEC_MANAGER_OPCODE_IMPORT + +#define SARA_R5_SEC_MANAGER_ROOTCA UBLOX_AT_SEC_MANAGER_ROOTCA +#define SARA_R5_SEC_MANAGER_CLIENT_CERT UBLOX_AT_SEC_MANAGER_CLIENT_CERT +#define SARA_R5_SEC_MANAGER_CLIENT_KEY UBLOX_AT_SEC_MANAGER_CLIENT_KEY +#define SARA_R5_SEC_MANAGER_SERVER_CERT UBLOX_AT_SEC_MANAGER_SERVER_CERT #endif //SPARKFUN_SARA_R5_ARDUINO_LIBRARY_H diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index 02626b4..c43b412 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -3,374 +3,6 @@ #include "sfe_ublox_at_commands.h" -// RegEx Replace: \#define\sSARA\_R5\_([A-Z0-9_]+).* \#define SARA\_R5\_$+ UBLOX\_AT\_$+ - -#define SARA_R5_POWER_PIN -1 // Default to no pin -#define SARA_R5_RESET_PIN -1 - -// Timing -#define SARA_R5_STANDARD_RESPONSE_TIMEOUT 1000 -#define SARA_R5_10_SEC_TIMEOUT 10000 -#define SARA_R5_55_SECS_TIMEOUT 55000 -#define SARA_R5_2_MIN_TIMEOUT 120000 -#define SARA_R5_3_MIN_TIMEOUT 180000 -#define SARA_R5_SET_BAUD_TIMEOUT 500 -#define SARA_R5_POWER_OFF_PULSE_PERIOD 3200 // Hold PWR_ON low for this long to power the module off -#define SARA_R5_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) -#define SARA_R5_RESET_PULSE_PERIOD 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) -#define SARA_R5_POWER_OFF_TIMEOUT 40000 // Datasheet says 40 seconds... -#define SARA_R5_IP_CONNECT_TIMEOUT 130000 -#define SARA_R5_POLL_DELAY 1 -#define SARA_R5_SOCKET_WRITE_TIMEOUT 10000 - -// ## Suported AT Commands -// ### General -const char SARA_R5_COMMAND_AT[] = "AT"; // AT "Test" -const char SARA_R5_COMMAND_ECHO[] = "E"; // Local Echo -const char SARA_R5_COMMAND_MANU_ID[] = "+CGMI"; // Manufacturer identification -const char SARA_R5_COMMAND_MODEL_ID[] = "+CGMM"; // Model identification -const char SARA_R5_COMMAND_FW_VER_ID[] = "+CGMR"; // Firmware version identification -const char SARA_R5_COMMAND_SERIAL_NO[] = "+CGSN"; // Product serial number -const char SARA_R5_COMMAND_IMEI[] = "+GSN"; // IMEI identification -const char SARA_R5_COMMAND_IMSI[] = "+CIMI"; // IMSI identification -const char SARA_R5_COMMAND_CCID[] = "+CCID"; // SIM CCID -const char SARA_R5_COMMAND_REQ_CAP[] = "+GCAP"; // Request capabilities list -// ### Control and status -const char SARA_R5_COMMAND_POWER_OFF[] = "+CPWROFF"; // Module switch off -const char SARA_R5_COMMAND_FUNC[] = "+CFUN"; // Functionality (reset, etc.) -const char SARA_R5_COMMAND_CLOCK[] = "+CCLK"; // Real-time clock -const char SARA_R5_COMMAND_AUTO_TZ[] = "+CTZU"; // Automatic time zone update -const char SARA_R5_COMMAND_TZ_REPORT[] = "+CTZR"; // Time zone reporting -// ### Network service -const char SARA_R5_COMMAND_CNUM[] = "+CNUM"; // Subscriber number -const char SARA_R5_SIGNAL_QUALITY[] = "+CSQ"; -const char SARA_R5_EXT_SIGNAL_QUALITY[] = "+CESQ"; -const char SARA_R5_OPERATOR_SELECTION[] = "+COPS"; -const char SARA_R5_REGISTRATION_STATUS[] = "+CREG"; -const char SARA_R5_EPSREGISTRATION_STATUS[] = "+CEREG"; -const char SARA_R5_READ_OPERATOR_NAMES[] = "+COPN"; -const char SARA_R5_COMMAND_MNO[] = "+UMNOPROF"; // MNO (mobile network operator) Profile -// ### SIM -const char SARA_R5_SIM_STATE[] = "+USIMSTAT"; -const char SARA_R5_COMMAND_SIMPIN[] = "+CPIN"; // SIM PIN -// ### SMS -const char SARA_R5_MESSAGE_FORMAT[] = "+CMGF"; // Set SMS message format -const char SARA_R5_SEND_TEXT[] = "+CMGS"; // Send SMS message -const char SARA_R5_NEW_MESSAGE_IND[] = "+CNMI"; // New [SMS] message indication -const char SARA_R5_PREF_MESSAGE_STORE[] = "+CPMS"; // Preferred message storage -const char SARA_R5_READ_TEXT_MESSAGE[] = "+CMGR"; // Read message -const char SARA_R5_DELETE_MESSAGE[] = "+CMGD"; // Delete message -// V24 control and V25ter (UART interface) -const char SARA_R5_FLOW_CONTROL[] = "&K"; // Flow control -const char SARA_R5_COMMAND_BAUD[] = "+IPR"; // Baud rate -// ### Packet switched data services -const char SARA_R5_MESSAGE_PDP_DEF[] = "+CGDCONT"; // Packet switched Data Profile context definition -const char SARA_R5_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration -const char SARA_R5_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile -const char SARA_R5_MESSAGE_PDP_CONTEXT_ACTIVATE[] = "+CGACT"; // Activates or deactivates the specified PDP context -const char SARA_R5_MESSAGE_ENTER_PPP[] = "D"; -const char SARA_R5_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data -// ### GPIO -const char SARA_R5_COMMAND_GPIO[] = "+UGPIOC"; // GPIO Configuration -// ### IP -const char SARA_R5_CREATE_SOCKET[] = "+USOCR"; // Create a new socket -const char SARA_R5_CLOSE_SOCKET[] = "+USOCL"; // Close a socket -const char SARA_R5_CONNECT_SOCKET[] = "+USOCO"; // Connect to server on socket -const char SARA_R5_WRITE_SOCKET[] = "+USOWR"; // Write data to a socket -const char SARA_R5_WRITE_UDP_SOCKET[] = "+USOST"; // Write data to a UDP socket -const char SARA_R5_READ_SOCKET[] = "+USORD"; // Read from a socket -const char SARA_R5_READ_UDP_SOCKET[] = "+USORF"; // Read UDP data from a socket -const char SARA_R5_LISTEN_SOCKET[] = "+USOLI"; // Listen for connection on socket -const char SARA_R5_GET_ERROR[] = "+USOER"; // Get last socket error. -const char SARA_R5_SOCKET_DIRECT_LINK[] = "+USODL"; // Set socket in Direct Link mode -const char SARA_R5_SOCKET_CONTROL[] = "+USOCTL"; // Query the socket parameters -const char SARA_R5_UD_CONFIGURATION[] = "+UDCONF"; // User Datagram Configuration -// ### Ping -const char SARA_R5_PING_COMMAND[] = "+UPING"; // Ping -// ### HTTP -const char SARA_R5_HTTP_PROFILE[] = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined -const char SARA_R5_HTTP_COMMAND[] = "+UHTTPC"; // Trigger the specified HTTP command -const char SARA_R5_HTTP_PROTOCOL_ERROR[] = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. - -const char SARA_R5_MQTT_NVM[] = "+UMQTTNV"; -const char SARA_R5_MQTT_PROFILE[] = "+UMQTT"; -const char SARA_R5_MQTT_COMMAND[] = "+UMQTTC"; -const char SARA_R5_MQTT_PROTOCOL_ERROR[] = "+UMQTTER"; -// ### FTP -const char SARA_R5_FTP_PROFILE[] = "+UFTP"; -const char SARA_R5_FTP_COMMAND[] = "+UFTPC"; -const char SARA_R5_FTP_PROTOCOL_ERROR[] = "+UFTPER"; -// ### GNSS -const char SARA_R5_GNSS_POWER[] = "+UGPS"; // GNSS power management configuration -const char SARA_R5_GNSS_ASSISTED_IND[] = "+UGIND"; // Assisted GNSS unsolicited indication -const char SARA_R5_GNSS_REQUEST_LOCATION[] = "+ULOC"; // Ask for localization information -const char SARA_R5_GNSS_GPRMC[] = "+UGRMC"; // Ask for localization information -const char SARA_R5_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) -const char SARA_R5_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication -const char SARA_R5_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration -const char SARA_R5_GNSS_CONFIGURE_SENSOR[] = "+ULOCGNSS"; // Configure GNSS sensor -const char SARA_R5_GNSS_CONFIGURE_LOCATION[] = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) -const char SARA_R5_AIDING_SERVER_CONFIGURATION[] = "+UGSRV"; // Configure aiding server (CellLocate®) -// ### File System -// TO DO: Add support for file tags. Default tag to USER -const char SARA_R5_FILE_SYSTEM_READ_FILE[] = "+URDFILE"; // Read a file -const char SARA_R5_FILE_SYSTEM_READ_BLOCK[] = "+URDBLOCK"; // Read a block from a file -const char SARA_R5_FILE_SYSTEM_DOWNLOAD_FILE[] = "+UDWNFILE"; // Download a file into the module -const char SARA_R5_FILE_SYSTEM_LIST_FILES[] = "+ULSTFILE"; // List of files, size of file, etc. -const char SARA_R5_FILE_SYSTEM_DELETE_FILE[] = "+UDELFILE"; // Delete a file -// ### File System -// TO DO: Add support for file tags. Default tag to USER -const char SARA_R5_SEC_PROFILE[] = "+USECPRF"; -const char SARA_R5_SEC_MANAGER[] = "+USECMNG"; - - -// ### URC strings -const char SARA_R5_READ_SOCKET_URC[] = "+UUSORD:"; -const char SARA_R5_READ_UDP_SOCKET_URC[] = "+UUSORF:"; -const char SARA_R5_LISTEN_SOCKET_URC[] = "+UUSOLI:"; -const char SARA_R5_CLOSE_SOCKET_URC[] = "+UUSOCL:"; -const char SARA_R5_GNSS_REQUEST_LOCATION_URC[] = "+UULOC:"; -const char SARA_R5_SIM_STATE_URC[] = "+UUSIMSTAT:"; -const char SARA_R5_MESSAGE_PDP_ACTION_URC[] = "+UUPSDA:"; -const char SARA_R5_HTTP_COMMAND_URC[] = "+UUHTTPCR:"; -const char SARA_R5_MQTT_COMMAND_URC[] = "+UUMQTTC:"; -const char SARA_R5_PING_COMMAND_URC[] = "+UUPING:"; -const char SARA_R5_REGISTRATION_STATUS_URC[] = "+CREG:"; -const char SARA_R5_EPSREGISTRATION_STATUS_URC[] = "+CEREG:"; -const char SARA_R5_FTP_COMMAND_URC[] = "+UUFTPCR:"; - -// ### Response -const char SARA_R5_RESPONSE_MORE[] = "\n>"; -const char SARA_R5_RESPONSE_OK[] = "\nOK\r\n"; -const char SARA_R5_RESPONSE_ERROR[] = "\nERROR\r\n"; -const char SARA_R5_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; -#define SARA_R5_RESPONSE_OK_OR_ERROR nullptr - -#define SARA_R5_NUM_SOCKETS 6 - -#define SARA_R5_NUM_SUPPORTED_BAUD 6 -const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = - { - 115200, - 9600, - 19200, - 38400, - 57600, - 230400}; -#define SARA_R5_DEFAULT_BAUD_RATE 115200 - -// Flow control definitions for AT&K -// Note: SW (XON/XOFF) flow control is not supported on the SARA_R5 -#define SARA_R5_DISABLE_FLOW_CONTROL UBLOX_AT_DISABLE_FLOW_CONTROL -#define SARA_R5_ENABLE_FLOW_CONTROL UBLOX_AT_ENABLE_FLOW_CONTROL - -#define SARA_R5_ERROR_INVALID UBLOX_AT_ERROR_INVALID -#define SARA_R5_ERROR_SUCCESS UBLOX_AT_ERROR_SUCCESS -#define SARA_R5_ERROR_OUT_OF_MEMORY UBLOX_AT_ERROR_OUT_OF_MEMORY -#define SARA_R5_ERROR_TIMEOUT UBLOX_AT_ERROR_TIMEOUT -#define SARA_R5_ERROR_UNEXPECTED_PARAM UBLOX_AT_ERROR_UNEXPECTED_PARAM -#define SARA_R5_ERROR_UNEXPECTED_RESPONSE UBLOX_AT_ERROR_UNEXPECTED_RESPONSE -#define SARA_R5_ERROR_NO_RESPONSE UBLOX_AT_ERROR_NO_RESPONSE -#define SARA_R5_ERROR_DEREGISTERED UBLOX_AT_ERROR_DEREGISTERED -#define SARA_R5_ERROR_ZERO_READ_LENGTH UBLOX_AT_ERROR_ZERO_READ_LENGTH -#define SARA_R5_ERROR_ERROR UBLOX_AT_ERROR_ERROR -#define SARA_R5_SUCCESS SARA_R5_ERROR_SUCCESS - -#define SARA_R5_REGISTRATION_INVALID UBLOX_AT_REGISTRATION_INVALID -#define SARA_R5_REGISTRATION_NOT_REGISTERED UBLOX_AT_REGISTRATION_NOT_REGISTERED -#define SARA_R5_REGISTRATION_HOME UBLOX_AT_REGISTRATION_HOME -#define SARA_R5_REGISTRATION_SEARCHING UBLOX_AT_REGISTRATION_SEARCHING -#define SARA_R5_REGISTRATION_DENIED UBLOX_AT_REGISTRATION_DENIED -#define SARA_R5_REGISTRATION_UNKNOWN UBLOX_AT_REGISTRATION_UNKNOWN -#define SARA_R5_REGISTRATION_ROAMING UBLOX_AT_REGISTRATION_ROAMING -#define SARA_R5_REGISTRATION_HOME_SMS_ONLY UBLOX_AT_REGISTRATION_HOME_SMS_ONLY -#define SARA_R5_REGISTRATION_ROAMING_SMS_ONLY UBLOX_AT_REGISTRATION_ROAMING_SMS_ONLY -#define SARA_R5_REGISTRATION_EMERGENCY_SERV_ONLY UBLOX_AT_REGISTRATION_EMERGENCY_SERV_ONLY -#define SARA_R5_REGISTRATION_HOME_CSFB_NOT_PREFERRED UBLOX_AT_REGISTRATION_HOME_CSFB_NOT_PREFERRED -#define SARA_R5_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED UBLOX_AT_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED - -#define SARA_R5_TCP UBLOX_AT_TCP -#define SARA_R5_UDP UBLOX_AT_UDP - -#define SARA_R5_TCP_SOCKET_STATUS_INACTIVE UBLOX_AT_TCP_SOCKET_STATUS_INACTIVE -#define SARA_R5_TCP_SOCKET_STATUS_LISTEN UBLOX_AT_TCP_SOCKET_STATUS_LISTEN -#define SARA_R5_TCP_SOCKET_STATUS_SYN_SENT UBLOX_AT_TCP_SOCKET_STATUS_SYN_SENT -#define SARA_R5_TCP_SOCKET_STATUS_SYN_RCVD UBLOX_AT_TCP_SOCKET_STATUS_SYN_RCVD -#define SARA_R5_TCP_SOCKET_STATUS_ESTABLISHED UBLOX_AT_TCP_SOCKET_STATUS_ESTABLISHED -#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_1 UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_1 -#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_2 UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_2 -#define SARA_R5_TCP_SOCKET_STATUS_CLOSE_WAIT UBLOX_AT_TCP_SOCKET_STATUS_CLOSE_WAIT -#define SARA_R5_TCP_SOCKET_STATUS_CLOSING UBLOX_AT_TCP_SOCKET_STATUS_CLOSING -#define SARA_R5_TCP_SOCKET_STATUS_LAST_ACK UBLOX_AT_TCP_SOCKET_STATUS_LAST_ACK -#define SARA_R5_TCP_SOCKET_STATUS_TIME_WAIT UBLOX_AT_TCP_SOCKET_STATUS_TIME_WAIT - -#define SARA_R5_MESSAGE_FORMAT_PDU UBLOX_AT_MESSAGE_FORMAT_PDU -#define SARA_R5_MESSAGE_FORMAT_TEXT UBLOX_AT_MESSAGE_FORMAT_TEXT - -#define SARA_R5_UTIME_MODE_STOP UBLOX_AT_UTIME_MODE_STOP -#define SARA_R5_UTIME_MODE_PPS UBLOX_AT_UTIME_MODE_PPS -#define SARA_R5_UTIME_MODE_ONE_SHOT UBLOX_AT_UTIME_MODE_ONE_SHOT -#define SARA_R5_UTIME_MODE_EXT_INT UBLOX_AT_UTIME_MODE_EXT_INT - -#define SARA_R5_UTIME_SENSOR_NONE UBLOX_AT_UTIME_SENSOR_NONE -#define SARA_R5_UTIME_SENSOR_GNSS_LTE UBLOX_AT_UTIME_SENSOR_GNSS_LTE -#define SARA_R5_UTIME_SENSOR_LTE UBLOX_AT_UTIME_SENSOR_LTE - -#define SARA_R5_UTIME_URC_CONFIGURATION_DISABLED UBLOX_AT_UTIME_URC_CONFIGURATION_DISABLED -#define SARA_R5_UTIME_URC_CONFIGURATION_ENABLED UBLOX_AT_UTIME_URC_CONFIGURATION_ENABLED - -#define SARA_R5_SIM_NOT_PRESENT UBLOX_AT_SIM_NOT_PRESENT -#define SARA_R5_SIM_PIN_NEEDED UBLOX_AT_SIM_PIN_NEEDED -#define SARA_R5_SIM_PIN_BLOCKED UBLOX_AT_SIM_PIN_BLOCKED -#define SARA_R5_SIM_PUK_BLOCKED UBLOX_AT_SIM_PUK_BLOCKED -#define SARA_R5_SIM_NOT_OPERATIONAL UBLOX_AT_SIM_NOT_OPERATIONAL -#define SARA_R5_SIM_RESTRICTED UBLOX_AT_SIM_RESTRICTED -#define SARA_R5_SIM_OPERATIONAL UBLOX_AT_SIM_OPERATIONAL -//SARA_R5_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 -//SARA_R5_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 -//SARA_R5_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 -//SARA_R5_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 -//SARA_R5_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 -//SARA_R5_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 -//SARA_R5_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 - -#define SARA_R5_NUM_PSD_PROFILES 6 // Number of supported PSD profiles -#define SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS 11 // Number of supported PDP context identifiers -#define SARA_R5_NUM_HTTP_PROFILES 4 // Number of supported HTTP profiles - -#define SARA_R5_HTTP_OP_CODE_SERVER_IP UBLOX_AT_HTTP_OP_CODE_SERVER_IP -#define SARA_R5_HTTP_OP_CODE_SERVER_NAME UBLOX_AT_HTTP_OP_CODE_SERVER_NAME -#define SARA_R5_HTTP_OP_CODE_USERNAME UBLOX_AT_HTTP_OP_CODE_USERNAME -#define SARA_R5_HTTP_OP_CODE_PASSWORD UBLOX_AT_HTTP_OP_CODE_PASSWORD -#define SARA_R5_HTTP_OP_CODE_AUTHENTICATION UBLOX_AT_HTTP_OP_CODE_AUTHENTICATION -#define SARA_R5_HTTP_OP_CODE_SERVER_PORT UBLOX_AT_HTTP_OP_CODE_SERVER_PORT -#define SARA_R5_HTTP_OP_CODE_SECURE UBLOX_AT_HTTP_OP_CODE_SECURE -#define SARA_R5_HTTP_OP_CODE_REQUEST_TIMEOUT UBLOX_AT_HTTP_OP_CODE_REQUEST_TIMEOUT -#define SARA_R5_HTTP_OP_CODE_ADD_CUSTOM_HEADERS UBLOX_AT_HTTP_OP_CODE_ADD_CUSTOM_HEADERS - -#define SARA_R5_HTTP_COMMAND_HEAD UBLOX_AT_HTTP_COMMAND_HEAD -#define SARA_R5_HTTP_COMMAND_GET UBLOX_AT_HTTP_COMMAND_GET -#define SARA_R5_HTTP_COMMAND_DELETE UBLOX_AT_HTTP_COMMAND_DELETE -#define SARA_R5_HTTP_COMMAND_PUT UBLOX_AT_HTTP_COMMAND_PUT -#define SARA_R5_HTTP_COMMAND_POST_FILE UBLOX_AT_HTTP_COMMAND_POST_FILE -#define SARA_R5_HTTP_COMMAND_POST_DATA UBLOX_AT_HTTP_COMMAND_POST_DATA -#define SARA_R5_HTTP_COMMAND_GET_FOTA UBLOX_AT_HTTP_COMMAND_GET_FOTA - -#define SARA_R5_HTTP_CONTENT_APPLICATION_X_WWW UBLOX_AT_HTTP_CONTENT_APPLICATION_X_WWW -#define SARA_R5_HTTP_CONTENT_TEXT_PLAIN UBLOX_AT_HTTP_CONTENT_TEXT_PLAIN -#define SARA_R5_HTTP_CONTENT_APPLICATION_OCTET UBLOX_AT_HTTP_CONTENT_APPLICATION_OCTET -#define SARA_R5_HTTP_CONTENT_MULTIPART_FORM UBLOX_AT_HTTP_CONTENT_MULTIPART_FORM -#define SARA_R5_HTTP_CONTENT_APPLICATION_JSON UBLOX_AT_HTTP_CONTENT_APPLICATION_JSON -#define SARA_R5_HTTP_CONTENT_APPLICATION_XML UBLOX_AT_HTTP_CONTENT_APPLICATION_XML -#define SARA_R5_HTTP_CONTENT_USER_DEFINED UBLOX_AT_HTTP_CONTENT_USER_DEFINED - -#define SARA_R5_MQTT_NV_RESTORE UBLOX_AT_MQTT_NV_RESTORE -#define SARA_R5_MQTT_NV_SET UBLOX_AT_MQTT_NV_SET -#define SARA_R5_MQTT_NV_STORE UBLOX_AT_MQTT_NV_STORE - -#define SARA_R5_MQTT_PROFILE_CLIENT_ID UBLOX_AT_MQTT_PROFILE_CLIENT_ID -#define SARA_R5_MQTT_PROFILE_SERVERNAME UBLOX_AT_MQTT_PROFILE_SERVERNAME -#define SARA_R5_MQTT_PROFILE_IPADDRESS UBLOX_AT_MQTT_PROFILE_IPADDRESS -#define SARA_R5_MQTT_PROFILE_USERNAMEPWD UBLOX_AT_MQTT_PROFILE_USERNAMEPWD -#define SARA_R5_MQTT_PROFILE_QOS UBLOX_AT_MQTT_PROFILE_QOS -#define SARA_R5_MQTT_PROFILE_RETAIN UBLOX_AT_MQTT_PROFILE_RETAIN -#define SARA_R5_MQTT_PROFILE_TOPIC UBLOX_AT_MQTT_PROFILE_TOPIC -#define SARA_R5_MQTT_PROFILE_MESSAGE UBLOX_AT_MQTT_PROFILE_MESSAGE -#define SARA_R5_MQTT_PROFILE_INACTIVITYTIMEOUT UBLOX_AT_MQTT_PROFILE_INACTIVITYTIMEOUT -#define SARA_R5_MQTT_PROFILE_SECURE UBLOX_AT_MQTT_PROFILE_SECURE - -#define SARA_R5_MQTT_COMMAND_INVALID UBLOX_AT_MQTT_COMMAND_INVALID -#define SARA_R5_MQTT_COMMAND_LOGOUT UBLOX_AT_MQTT_COMMAND_LOGOUT -#define SARA_R5_MQTT_COMMAND_LOGIN UBLOX_AT_MQTT_COMMAND_LOGIN -#define SARA_R5_MQTT_COMMAND_PUBLISH UBLOX_AT_MQTT_COMMAND_PUBLISH -#define SARA_R5_MQTT_COMMAND_PUBLISHFILE UBLOX_AT_MQTT_COMMAND_PUBLISHFILE -#define SARA_R5_MQTT_COMMAND_SUBSCRIBE UBLOX_AT_MQTT_COMMAND_SUBSCRIBE -#define SARA_R5_MQTT_COMMAND_UNSUBSCRIBE UBLOX_AT_MQTT_COMMAND_UNSUBSCRIBE -#define SARA_R5_MQTT_COMMAND_READ UBLOX_AT_MQTT_COMMAND_READ -#define SARA_R5_MQTT_COMMAND_RCVMSGFORMAT UBLOX_AT_MQTT_COMMAND_RCVMSGFORMAT -#define SARA_R5_MQTT_COMMAND_PING UBLOX_AT_MQTT_COMMAND_PING -#define SARA_R5_MQTT_COMMAND_PUBLISHBINARY UBLOX_AT_MQTT_COMMAND_PUBLISHBINARY - -#define SARA_R5_FTP_PROFILE_IPADDRESS UBLOX_AT_FTP_PROFILE_IPADDRESS -#define SARA_R5_FTP_PROFILE_SERVERNAME UBLOX_AT_FTP_PROFILE_SERVERNAME -#define SARA_R5_FTP_PROFILE_USERNAME UBLOX_AT_FTP_PROFILE_USERNAME -#define SARA_R5_FTP_PROFILE_PWD UBLOX_AT_FTP_PROFILE_PWD -#define SARA_R5_FTP_PROFILE_ACCOUNT UBLOX_AT_FTP_PROFILE_ACCOUNT -#define SARA_R5_FTP_PROFILE_TIMEOUT UBLOX_AT_FTP_PROFILE_TIMEOUT -#define SARA_R5_FTP_PROFILE_MODE UBLOX_AT_FTP_PROFILE_MODE - -#define SARA_R5_FTP_COMMAND_INVALID UBLOX_AT_FTP_COMMAND_INVALID -#define SARA_R5_FTP_COMMAND_LOGOUT UBLOX_AT_FTP_COMMAND_LOGOUT -#define SARA_R5_FTP_COMMAND_LOGIN UBLOX_AT_FTP_COMMAND_LOGIN -#define SARA_R5_FTP_COMMAND_DELETE_FILE UBLOX_AT_FTP_COMMAND_DELETE_FILE -#define SARA_R5_FTP_COMMAND_RENAME_FILE UBLOX_AT_FTP_COMMAND_RENAME_FILE -#define SARA_R5_FTP_COMMAND_GET_FILE UBLOX_AT_FTP_COMMAND_GET_FILE -#define SARA_R5_FTP_COMMAND_PUT_FILE UBLOX_AT_FTP_COMMAND_PUT_FILE -#define SARA_R5_FTP_COMMAND_GET_FILE_DIRECT UBLOX_AT_FTP_COMMAND_GET_FILE_DIRECT -#define SARA_R5_FTP_COMMAND_PUT_FILE_DIRECT UBLOX_AT_FTP_COMMAND_PUT_FILE_DIRECT -#define SARA_R5_FTP_COMMAND_CHANGE_DIR UBLOX_AT_FTP_COMMAND_CHANGE_DIR -#define SARA_R5_FTP_COMMAND_MKDIR UBLOX_AT_FTP_COMMAND_MKDIR -#define SARA_R5_FTP_COMMAND_RMDIR UBLOX_AT_FTP_COMMAND_RMDIR -#define SARA_R5_FTP_COMMAND_DIR_INFO UBLOX_AT_FTP_COMMAND_DIR_INFO -#define SARA_R5_FTP_COMMAND_LS UBLOX_AT_FTP_COMMAND_LS -#define SARA_R5_FTP_COMMAND_GET_FOTA_FILE UBLOX_AT_FTP_COMMAND_GET_FOTA_FILE - -#define SARA_R5_PSD_CONFIG_PARAM_PROTOCOL UBLOX_AT_PSD_CONFIG_PARAM_PROTOCOL -#define SARA_R5_PSD_CONFIG_PARAM_APN UBLOX_AT_PSD_CONFIG_PARAM_APN -//SARA_R5_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 -//SARA_R5_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 -#define SARA_R5_PSD_CONFIG_PARAM_DNS1 UBLOX_AT_PSD_CONFIG_PARAM_DNS1 -#define SARA_R5_PSD_CONFIG_PARAM_DNS2 UBLOX_AT_PSD_CONFIG_PARAM_DNS2 -//SARA_R5_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 -//SARA_R5_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 -//SARA_R5_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 -//SARA_R5_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 -#define SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID UBLOX_AT_PSD_CONFIG_PARAM_MAP_TO_CID - -#define SARA_R5_PSD_PROTOCOL_IPV4 UBLOX_AT_PSD_PROTOCOL_IPV4 -#define SARA_R5_PSD_PROTOCOL_IPV6 UBLOX_AT_PSD_PROTOCOL_IPV6 -#define SARA_R5_PSD_PROTOCOL_IPV4V6_V4_PREF UBLOX_AT_PSD_PROTOCOL_IPV4V6_V4_PREF -#define SARA_R5_PSD_PROTOCOL_IPV4V6_V6_PREF UBLOX_AT_PSD_PROTOCOL_IPV4V6_V6_PREF - -#define SARA_R5_PSD_ACTION_RESET UBLOX_AT_PSD_ACTION_RESET -#define SARA_R5_PSD_ACTION_STORE UBLOX_AT_PSD_ACTION_STORE -#define SARA_R5_PSD_ACTION_LOAD UBLOX_AT_PSD_ACTION_LOAD -#define SARA_R5_PSD_ACTION_ACTIVATE UBLOX_AT_PSD_ACTION_ACTIVATE -#define SARA_R5_PSD_ACTION_DEACTIVATE UBLOX_AT_PSD_ACTION_DEACTIVATE - -#define SARA_R5_SEC_PROFILE_PARAM_CERT_VAL_LEVEL UBLOX_AT_SEC_PROFILE_PARAM_CERT_VAL_LEVEL -#define SARA_R5_SEC_PROFILE_PARAM_TLS_VER UBLOX_AT_SEC_PROFILE_PARAM_TLS_VER -#define SARA_R5_SEC_PROFILE_PARAM_CYPHER_SUITE UBLOX_AT_SEC_PROFILE_PARAM_CYPHER_SUITE -#define SARA_R5_SEC_PROFILE_PARAM_ROOT_CA UBLOX_AT_SEC_PROFILE_PARAM_ROOT_CA -#define SARA_R5_SEC_PROFILE_PARAM_HOSTNAME UBLOX_AT_SEC_PROFILE_PARAM_HOSTNAME -#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_CERT UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_CERT -#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY -#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY_PWD UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY_PWD -#define SARA_R5_SEC_PROFILE_PARAM_PSK UBLOX_AT_SEC_PROFILE_PARAM_PSK -#define SARA_R5_SEC_PROFILE_PARAM_PSK_IDENT UBLOX_AT_SEC_PROFILE_PARAM_PSK_IDENT -#define SARA_R5_SEC_PROFILE_PARAM_SNI UBLOX_AT_SEC_PROFILE_PARAM_SNI - -#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_NO UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_NO -#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL -#define SARA_R5_SEC_PROFILE_CERVTAL_OPCODE_YESURL UBLOX_AT_SEC_PROFILE_CERVTAL_OPCODE_YESURL -#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE - -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_ANYVER UBLOX_AT_SEC_PROFILE_TLS_OPCODE_ANYVER -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_0 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_0 -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_1 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_1 -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_2 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_2 -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_3 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_3 - -#define SARA_R5_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT UBLOX_AT_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT - -#define SARA_R5_SEC_MANAGER_OPCODE_IMPORT UBLOX_AT_SEC_MANAGER_OPCODE_IMPORT - -#define SARA_R5_SEC_MANAGER_ROOTCA UBLOX_AT_SEC_MANAGER_ROOTCA -#define SARA_R5_SEC_MANAGER_CLIENT_CERT UBLOX_AT_SEC_MANAGER_CLIENT_CERT -#define SARA_R5_SEC_MANAGER_CLIENT_KEY UBLOX_AT_SEC_MANAGER_CLIENT_KEY -#define SARA_R5_SEC_MANAGER_SERVER_CERT UBLOX_AT_SEC_MANAGER_SERVER_CERT - - // Base SARA-R5 class class SARA_R5: public UBLOX_AT { From 84cb26a067be2b19f8e4e152c117019517259b8e Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Fri, 17 Nov 2023 12:52:42 -0700 Subject: [PATCH 13/52] Update UBLOX_AT to UBX_CELL prefixes Prepping for merge --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 376 +++++++++--------- 1 file changed, 188 insertions(+), 188 deletions(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h index 841b71b..0887158 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -178,71 +178,71 @@ const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = // Flow control definitions for AT&K // Note: SW (XON/XOFF) flow control is not supported on the SARA_R5 -#define SARA_R5_DISABLE_FLOW_CONTROL UBLOX_AT_DISABLE_FLOW_CONTROL -#define SARA_R5_ENABLE_FLOW_CONTROL UBLOX_AT_ENABLE_FLOW_CONTROL - -#define SARA_R5_ERROR_INVALID UBLOX_AT_ERROR_INVALID -#define SARA_R5_ERROR_SUCCESS UBLOX_AT_ERROR_SUCCESS -#define SARA_R5_ERROR_OUT_OF_MEMORY UBLOX_AT_ERROR_OUT_OF_MEMORY -#define SARA_R5_ERROR_TIMEOUT UBLOX_AT_ERROR_TIMEOUT -#define SARA_R5_ERROR_UNEXPECTED_PARAM UBLOX_AT_ERROR_UNEXPECTED_PARAM -#define SARA_R5_ERROR_UNEXPECTED_RESPONSE UBLOX_AT_ERROR_UNEXPECTED_RESPONSE -#define SARA_R5_ERROR_NO_RESPONSE UBLOX_AT_ERROR_NO_RESPONSE -#define SARA_R5_ERROR_DEREGISTERED UBLOX_AT_ERROR_DEREGISTERED -#define SARA_R5_ERROR_ZERO_READ_LENGTH UBLOX_AT_ERROR_ZERO_READ_LENGTH -#define SARA_R5_ERROR_ERROR UBLOX_AT_ERROR_ERROR +#define SARA_R5_DISABLE_FLOW_CONTROL UBX_CELL_DISABLE_FLOW_CONTROL +#define SARA_R5_ENABLE_FLOW_CONTROL UBX_CELL_ENABLE_FLOW_CONTROL + +#define SARA_R5_ERROR_INVALID UBX_CELL_ERROR_INVALID +#define SARA_R5_ERROR_SUCCESS UBX_CELL_ERROR_SUCCESS +#define SARA_R5_ERROR_OUT_OF_MEMORY UBX_CELL_ERROR_OUT_OF_MEMORY +#define SARA_R5_ERROR_TIMEOUT UBX_CELL_ERROR_TIMEOUT +#define SARA_R5_ERROR_UNEXPECTED_PARAM UBX_CELL_ERROR_UNEXPECTED_PARAM +#define SARA_R5_ERROR_UNEXPECTED_RESPONSE UBX_CELL_ERROR_UNEXPECTED_RESPONSE +#define SARA_R5_ERROR_NO_RESPONSE UBX_CELL_ERROR_NO_RESPONSE +#define SARA_R5_ERROR_DEREGISTERED UBX_CELL_ERROR_DEREGISTERED +#define SARA_R5_ERROR_ZERO_READ_LENGTH UBX_CELL_ERROR_ZERO_READ_LENGTH +#define SARA_R5_ERROR_ERROR UBX_CELL_ERROR_ERROR #define SARA_R5_SUCCESS SARA_R5_ERROR_SUCCESS -#define SARA_R5_REGISTRATION_INVALID UBLOX_AT_REGISTRATION_INVALID -#define SARA_R5_REGISTRATION_NOT_REGISTERED UBLOX_AT_REGISTRATION_NOT_REGISTERED -#define SARA_R5_REGISTRATION_HOME UBLOX_AT_REGISTRATION_HOME -#define SARA_R5_REGISTRATION_SEARCHING UBLOX_AT_REGISTRATION_SEARCHING -#define SARA_R5_REGISTRATION_DENIED UBLOX_AT_REGISTRATION_DENIED -#define SARA_R5_REGISTRATION_UNKNOWN UBLOX_AT_REGISTRATION_UNKNOWN -#define SARA_R5_REGISTRATION_ROAMING UBLOX_AT_REGISTRATION_ROAMING -#define SARA_R5_REGISTRATION_HOME_SMS_ONLY UBLOX_AT_REGISTRATION_HOME_SMS_ONLY -#define SARA_R5_REGISTRATION_ROAMING_SMS_ONLY UBLOX_AT_REGISTRATION_ROAMING_SMS_ONLY -#define SARA_R5_REGISTRATION_EMERGENCY_SERV_ONLY UBLOX_AT_REGISTRATION_EMERGENCY_SERV_ONLY -#define SARA_R5_REGISTRATION_HOME_CSFB_NOT_PREFERRED UBLOX_AT_REGISTRATION_HOME_CSFB_NOT_PREFERRED -#define SARA_R5_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED UBLOX_AT_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED - -#define SARA_R5_TCP UBLOX_AT_TCP -#define SARA_R5_UDP UBLOX_AT_UDP - -#define SARA_R5_TCP_SOCKET_STATUS_INACTIVE UBLOX_AT_TCP_SOCKET_STATUS_INACTIVE -#define SARA_R5_TCP_SOCKET_STATUS_LISTEN UBLOX_AT_TCP_SOCKET_STATUS_LISTEN -#define SARA_R5_TCP_SOCKET_STATUS_SYN_SENT UBLOX_AT_TCP_SOCKET_STATUS_SYN_SENT -#define SARA_R5_TCP_SOCKET_STATUS_SYN_RCVD UBLOX_AT_TCP_SOCKET_STATUS_SYN_RCVD -#define SARA_R5_TCP_SOCKET_STATUS_ESTABLISHED UBLOX_AT_TCP_SOCKET_STATUS_ESTABLISHED -#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_1 UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_1 -#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_2 UBLOX_AT_TCP_SOCKET_STATUS_FIN_WAIT_2 -#define SARA_R5_TCP_SOCKET_STATUS_CLOSE_WAIT UBLOX_AT_TCP_SOCKET_STATUS_CLOSE_WAIT -#define SARA_R5_TCP_SOCKET_STATUS_CLOSING UBLOX_AT_TCP_SOCKET_STATUS_CLOSING -#define SARA_R5_TCP_SOCKET_STATUS_LAST_ACK UBLOX_AT_TCP_SOCKET_STATUS_LAST_ACK -#define SARA_R5_TCP_SOCKET_STATUS_TIME_WAIT UBLOX_AT_TCP_SOCKET_STATUS_TIME_WAIT - -#define SARA_R5_MESSAGE_FORMAT_PDU UBLOX_AT_MESSAGE_FORMAT_PDU -#define SARA_R5_MESSAGE_FORMAT_TEXT UBLOX_AT_MESSAGE_FORMAT_TEXT - -#define SARA_R5_UTIME_MODE_STOP UBLOX_AT_UTIME_MODE_STOP -#define SARA_R5_UTIME_MODE_PPS UBLOX_AT_UTIME_MODE_PPS -#define SARA_R5_UTIME_MODE_ONE_SHOT UBLOX_AT_UTIME_MODE_ONE_SHOT -#define SARA_R5_UTIME_MODE_EXT_INT UBLOX_AT_UTIME_MODE_EXT_INT - -#define SARA_R5_UTIME_SENSOR_NONE UBLOX_AT_UTIME_SENSOR_NONE -#define SARA_R5_UTIME_SENSOR_GNSS_LTE UBLOX_AT_UTIME_SENSOR_GNSS_LTE -#define SARA_R5_UTIME_SENSOR_LTE UBLOX_AT_UTIME_SENSOR_LTE - -#define SARA_R5_UTIME_URC_CONFIGURATION_DISABLED UBLOX_AT_UTIME_URC_CONFIGURATION_DISABLED -#define SARA_R5_UTIME_URC_CONFIGURATION_ENABLED UBLOX_AT_UTIME_URC_CONFIGURATION_ENABLED - -#define SARA_R5_SIM_NOT_PRESENT UBLOX_AT_SIM_NOT_PRESENT -#define SARA_R5_SIM_PIN_NEEDED UBLOX_AT_SIM_PIN_NEEDED -#define SARA_R5_SIM_PIN_BLOCKED UBLOX_AT_SIM_PIN_BLOCKED -#define SARA_R5_SIM_PUK_BLOCKED UBLOX_AT_SIM_PUK_BLOCKED -#define SARA_R5_SIM_NOT_OPERATIONAL UBLOX_AT_SIM_NOT_OPERATIONAL -#define SARA_R5_SIM_RESTRICTED UBLOX_AT_SIM_RESTRICTED -#define SARA_R5_SIM_OPERATIONAL UBLOX_AT_SIM_OPERATIONAL +#define SARA_R5_REGISTRATION_INVALID UBX_CELL_REGISTRATION_INVALID +#define SARA_R5_REGISTRATION_NOT_REGISTERED UBX_CELL_REGISTRATION_NOT_REGISTERED +#define SARA_R5_REGISTRATION_HOME UBX_CELL_REGISTRATION_HOME +#define SARA_R5_REGISTRATION_SEARCHING UBX_CELL_REGISTRATION_SEARCHING +#define SARA_R5_REGISTRATION_DENIED UBX_CELL_REGISTRATION_DENIED +#define SARA_R5_REGISTRATION_UNKNOWN UBX_CELL_REGISTRATION_UNKNOWN +#define SARA_R5_REGISTRATION_ROAMING UBX_CELL_REGISTRATION_ROAMING +#define SARA_R5_REGISTRATION_HOME_SMS_ONLY UBX_CELL_REGISTRATION_HOME_SMS_ONLY +#define SARA_R5_REGISTRATION_ROAMING_SMS_ONLY UBX_CELL_REGISTRATION_ROAMING_SMS_ONLY +#define SARA_R5_REGISTRATION_EMERGENCY_SERV_ONLY UBX_CELL_REGISTRATION_EMERGENCY_SERV_ONLY +#define SARA_R5_REGISTRATION_HOME_CSFB_NOT_PREFERRED UBX_CELL_REGISTRATION_HOME_CSFB_NOT_PREFERRED +#define SARA_R5_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED UBX_CELL_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED + +#define SARA_R5_TCP UBX_CELL_TCP +#define SARA_R5_UDP UBX_CELL_UDP + +#define SARA_R5_TCP_SOCKET_STATUS_INACTIVE UBX_CELL_TCP_SOCKET_STATUS_INACTIVE +#define SARA_R5_TCP_SOCKET_STATUS_LISTEN UBX_CELL_TCP_SOCKET_STATUS_LISTEN +#define SARA_R5_TCP_SOCKET_STATUS_SYN_SENT UBX_CELL_TCP_SOCKET_STATUS_SYN_SENT +#define SARA_R5_TCP_SOCKET_STATUS_SYN_RCVD UBX_CELL_TCP_SOCKET_STATUS_SYN_RCVD +#define SARA_R5_TCP_SOCKET_STATUS_ESTABLISHED UBX_CELL_TCP_SOCKET_STATUS_ESTABLISHED +#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_1 UBX_CELL_TCP_SOCKET_STATUS_FIN_WAIT_1 +#define SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_2 UBX_CELL_TCP_SOCKET_STATUS_FIN_WAIT_2 +#define SARA_R5_TCP_SOCKET_STATUS_CLOSE_WAIT UBX_CELL_TCP_SOCKET_STATUS_CLOSE_WAIT +#define SARA_R5_TCP_SOCKET_STATUS_CLOSING UBX_CELL_TCP_SOCKET_STATUS_CLOSING +#define SARA_R5_TCP_SOCKET_STATUS_LAST_ACK UBX_CELL_TCP_SOCKET_STATUS_LAST_ACK +#define SARA_R5_TCP_SOCKET_STATUS_TIME_WAIT UBX_CELL_TCP_SOCKET_STATUS_TIME_WAIT + +#define SARA_R5_MESSAGE_FORMAT_PDU UBX_CELL_MESSAGE_FORMAT_PDU +#define SARA_R5_MESSAGE_FORMAT_TEXT UBX_CELL_MESSAGE_FORMAT_TEXT + +#define SARA_R5_UTIME_MODE_STOP UBX_CELL_UTIME_MODE_STOP +#define SARA_R5_UTIME_MODE_PPS UBX_CELL_UTIME_MODE_PPS +#define SARA_R5_UTIME_MODE_ONE_SHOT UBX_CELL_UTIME_MODE_ONE_SHOT +#define SARA_R5_UTIME_MODE_EXT_INT UBX_CELL_UTIME_MODE_EXT_INT + +#define SARA_R5_UTIME_SENSOR_NONE UBX_CELL_UTIME_SENSOR_NONE +#define SARA_R5_UTIME_SENSOR_GNSS_LTE UBX_CELL_UTIME_SENSOR_GNSS_LTE +#define SARA_R5_UTIME_SENSOR_LTE UBX_CELL_UTIME_SENSOR_LTE + +#define SARA_R5_UTIME_URC_CONFIGURATION_DISABLED UBX_CELL_UTIME_URC_CONFIGURATION_DISABLED +#define SARA_R5_UTIME_URC_CONFIGURATION_ENABLED UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED + +#define SARA_R5_SIM_NOT_PRESENT UBX_CELL_SIM_NOT_PRESENT +#define SARA_R5_SIM_PIN_NEEDED UBX_CELL_SIM_PIN_NEEDED +#define SARA_R5_SIM_PIN_BLOCKED UBX_CELL_SIM_PIN_BLOCKED +#define SARA_R5_SIM_PUK_BLOCKED UBX_CELL_SIM_PUK_BLOCKED +#define SARA_R5_SIM_NOT_OPERATIONAL UBX_CELL_SIM_NOT_OPERATIONAL +#define SARA_R5_SIM_RESTRICTED UBX_CELL_SIM_RESTRICTED +#define SARA_R5_SIM_OPERATIONAL UBX_CELL_SIM_OPERATIONAL //SARA_R5_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 //SARA_R5_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 //SARA_R5_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 @@ -255,136 +255,136 @@ const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = #define SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS 11 // Number of supported PDP context identifiers #define SARA_R5_NUM_HTTP_PROFILES 4 // Number of supported HTTP profiles -#define SARA_R5_HTTP_OP_CODE_SERVER_IP UBLOX_AT_HTTP_OP_CODE_SERVER_IP -#define SARA_R5_HTTP_OP_CODE_SERVER_NAME UBLOX_AT_HTTP_OP_CODE_SERVER_NAME -#define SARA_R5_HTTP_OP_CODE_USERNAME UBLOX_AT_HTTP_OP_CODE_USERNAME -#define SARA_R5_HTTP_OP_CODE_PASSWORD UBLOX_AT_HTTP_OP_CODE_PASSWORD -#define SARA_R5_HTTP_OP_CODE_AUTHENTICATION UBLOX_AT_HTTP_OP_CODE_AUTHENTICATION -#define SARA_R5_HTTP_OP_CODE_SERVER_PORT UBLOX_AT_HTTP_OP_CODE_SERVER_PORT -#define SARA_R5_HTTP_OP_CODE_SECURE UBLOX_AT_HTTP_OP_CODE_SECURE -#define SARA_R5_HTTP_OP_CODE_REQUEST_TIMEOUT UBLOX_AT_HTTP_OP_CODE_REQUEST_TIMEOUT -#define SARA_R5_HTTP_OP_CODE_ADD_CUSTOM_HEADERS UBLOX_AT_HTTP_OP_CODE_ADD_CUSTOM_HEADERS - -#define SARA_R5_HTTP_COMMAND_HEAD UBLOX_AT_HTTP_COMMAND_HEAD -#define SARA_R5_HTTP_COMMAND_GET UBLOX_AT_HTTP_COMMAND_GET -#define SARA_R5_HTTP_COMMAND_DELETE UBLOX_AT_HTTP_COMMAND_DELETE -#define SARA_R5_HTTP_COMMAND_PUT UBLOX_AT_HTTP_COMMAND_PUT -#define SARA_R5_HTTP_COMMAND_POST_FILE UBLOX_AT_HTTP_COMMAND_POST_FILE -#define SARA_R5_HTTP_COMMAND_POST_DATA UBLOX_AT_HTTP_COMMAND_POST_DATA -#define SARA_R5_HTTP_COMMAND_GET_FOTA UBLOX_AT_HTTP_COMMAND_GET_FOTA - -#define SARA_R5_HTTP_CONTENT_APPLICATION_X_WWW UBLOX_AT_HTTP_CONTENT_APPLICATION_X_WWW -#define SARA_R5_HTTP_CONTENT_TEXT_PLAIN UBLOX_AT_HTTP_CONTENT_TEXT_PLAIN -#define SARA_R5_HTTP_CONTENT_APPLICATION_OCTET UBLOX_AT_HTTP_CONTENT_APPLICATION_OCTET -#define SARA_R5_HTTP_CONTENT_MULTIPART_FORM UBLOX_AT_HTTP_CONTENT_MULTIPART_FORM -#define SARA_R5_HTTP_CONTENT_APPLICATION_JSON UBLOX_AT_HTTP_CONTENT_APPLICATION_JSON -#define SARA_R5_HTTP_CONTENT_APPLICATION_XML UBLOX_AT_HTTP_CONTENT_APPLICATION_XML -#define SARA_R5_HTTP_CONTENT_USER_DEFINED UBLOX_AT_HTTP_CONTENT_USER_DEFINED - -#define SARA_R5_MQTT_NV_RESTORE UBLOX_AT_MQTT_NV_RESTORE -#define SARA_R5_MQTT_NV_SET UBLOX_AT_MQTT_NV_SET -#define SARA_R5_MQTT_NV_STORE UBLOX_AT_MQTT_NV_STORE - -#define SARA_R5_MQTT_PROFILE_CLIENT_ID UBLOX_AT_MQTT_PROFILE_CLIENT_ID -#define SARA_R5_MQTT_PROFILE_SERVERNAME UBLOX_AT_MQTT_PROFILE_SERVERNAME -#define SARA_R5_MQTT_PROFILE_IPADDRESS UBLOX_AT_MQTT_PROFILE_IPADDRESS -#define SARA_R5_MQTT_PROFILE_USERNAMEPWD UBLOX_AT_MQTT_PROFILE_USERNAMEPWD -#define SARA_R5_MQTT_PROFILE_QOS UBLOX_AT_MQTT_PROFILE_QOS -#define SARA_R5_MQTT_PROFILE_RETAIN UBLOX_AT_MQTT_PROFILE_RETAIN -#define SARA_R5_MQTT_PROFILE_TOPIC UBLOX_AT_MQTT_PROFILE_TOPIC -#define SARA_R5_MQTT_PROFILE_MESSAGE UBLOX_AT_MQTT_PROFILE_MESSAGE -#define SARA_R5_MQTT_PROFILE_INACTIVITYTIMEOUT UBLOX_AT_MQTT_PROFILE_INACTIVITYTIMEOUT -#define SARA_R5_MQTT_PROFILE_SECURE UBLOX_AT_MQTT_PROFILE_SECURE - -#define SARA_R5_MQTT_COMMAND_INVALID UBLOX_AT_MQTT_COMMAND_INVALID -#define SARA_R5_MQTT_COMMAND_LOGOUT UBLOX_AT_MQTT_COMMAND_LOGOUT -#define SARA_R5_MQTT_COMMAND_LOGIN UBLOX_AT_MQTT_COMMAND_LOGIN -#define SARA_R5_MQTT_COMMAND_PUBLISH UBLOX_AT_MQTT_COMMAND_PUBLISH -#define SARA_R5_MQTT_COMMAND_PUBLISHFILE UBLOX_AT_MQTT_COMMAND_PUBLISHFILE -#define SARA_R5_MQTT_COMMAND_SUBSCRIBE UBLOX_AT_MQTT_COMMAND_SUBSCRIBE -#define SARA_R5_MQTT_COMMAND_UNSUBSCRIBE UBLOX_AT_MQTT_COMMAND_UNSUBSCRIBE -#define SARA_R5_MQTT_COMMAND_READ UBLOX_AT_MQTT_COMMAND_READ -#define SARA_R5_MQTT_COMMAND_RCVMSGFORMAT UBLOX_AT_MQTT_COMMAND_RCVMSGFORMAT -#define SARA_R5_MQTT_COMMAND_PING UBLOX_AT_MQTT_COMMAND_PING -#define SARA_R5_MQTT_COMMAND_PUBLISHBINARY UBLOX_AT_MQTT_COMMAND_PUBLISHBINARY - -#define SARA_R5_FTP_PROFILE_IPADDRESS UBLOX_AT_FTP_PROFILE_IPADDRESS -#define SARA_R5_FTP_PROFILE_SERVERNAME UBLOX_AT_FTP_PROFILE_SERVERNAME -#define SARA_R5_FTP_PROFILE_USERNAME UBLOX_AT_FTP_PROFILE_USERNAME -#define SARA_R5_FTP_PROFILE_PWD UBLOX_AT_FTP_PROFILE_PWD -#define SARA_R5_FTP_PROFILE_ACCOUNT UBLOX_AT_FTP_PROFILE_ACCOUNT -#define SARA_R5_FTP_PROFILE_TIMEOUT UBLOX_AT_FTP_PROFILE_TIMEOUT -#define SARA_R5_FTP_PROFILE_MODE UBLOX_AT_FTP_PROFILE_MODE - -#define SARA_R5_FTP_COMMAND_INVALID UBLOX_AT_FTP_COMMAND_INVALID -#define SARA_R5_FTP_COMMAND_LOGOUT UBLOX_AT_FTP_COMMAND_LOGOUT -#define SARA_R5_FTP_COMMAND_LOGIN UBLOX_AT_FTP_COMMAND_LOGIN -#define SARA_R5_FTP_COMMAND_DELETE_FILE UBLOX_AT_FTP_COMMAND_DELETE_FILE -#define SARA_R5_FTP_COMMAND_RENAME_FILE UBLOX_AT_FTP_COMMAND_RENAME_FILE -#define SARA_R5_FTP_COMMAND_GET_FILE UBLOX_AT_FTP_COMMAND_GET_FILE -#define SARA_R5_FTP_COMMAND_PUT_FILE UBLOX_AT_FTP_COMMAND_PUT_FILE -#define SARA_R5_FTP_COMMAND_GET_FILE_DIRECT UBLOX_AT_FTP_COMMAND_GET_FILE_DIRECT -#define SARA_R5_FTP_COMMAND_PUT_FILE_DIRECT UBLOX_AT_FTP_COMMAND_PUT_FILE_DIRECT -#define SARA_R5_FTP_COMMAND_CHANGE_DIR UBLOX_AT_FTP_COMMAND_CHANGE_DIR -#define SARA_R5_FTP_COMMAND_MKDIR UBLOX_AT_FTP_COMMAND_MKDIR -#define SARA_R5_FTP_COMMAND_RMDIR UBLOX_AT_FTP_COMMAND_RMDIR -#define SARA_R5_FTP_COMMAND_DIR_INFO UBLOX_AT_FTP_COMMAND_DIR_INFO -#define SARA_R5_FTP_COMMAND_LS UBLOX_AT_FTP_COMMAND_LS -#define SARA_R5_FTP_COMMAND_GET_FOTA_FILE UBLOX_AT_FTP_COMMAND_GET_FOTA_FILE - -#define SARA_R5_PSD_CONFIG_PARAM_PROTOCOL UBLOX_AT_PSD_CONFIG_PARAM_PROTOCOL -#define SARA_R5_PSD_CONFIG_PARAM_APN UBLOX_AT_PSD_CONFIG_PARAM_APN +#define SARA_R5_HTTP_OP_CODE_SERVER_IP UBX_CELL_HTTP_OP_CODE_SERVER_IP +#define SARA_R5_HTTP_OP_CODE_SERVER_NAME UBX_CELL_HTTP_OP_CODE_SERVER_NAME +#define SARA_R5_HTTP_OP_CODE_USERNAME UBX_CELL_HTTP_OP_CODE_USERNAME +#define SARA_R5_HTTP_OP_CODE_PASSWORD UBX_CELL_HTTP_OP_CODE_PASSWORD +#define SARA_R5_HTTP_OP_CODE_AUTHENTICATION UBX_CELL_HTTP_OP_CODE_AUTHENTICATION +#define SARA_R5_HTTP_OP_CODE_SERVER_PORT UBX_CELL_HTTP_OP_CODE_SERVER_PORT +#define SARA_R5_HTTP_OP_CODE_SECURE UBX_CELL_HTTP_OP_CODE_SECURE +#define SARA_R5_HTTP_OP_CODE_REQUEST_TIMEOUT UBX_CELL_HTTP_OP_CODE_REQUEST_TIMEOUT +#define SARA_R5_HTTP_OP_CODE_ADD_CUSTOM_HEADERS UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS + +#define SARA_R5_HTTP_COMMAND_HEAD UBX_CELL_HTTP_COMMAND_HEAD +#define SARA_R5_HTTP_COMMAND_GET UBX_CELL_HTTP_COMMAND_GET +#define SARA_R5_HTTP_COMMAND_DELETE UBX_CELL_HTTP_COMMAND_DELETE +#define SARA_R5_HTTP_COMMAND_PUT UBX_CELL_HTTP_COMMAND_PUT +#define SARA_R5_HTTP_COMMAND_POST_FILE UBX_CELL_HTTP_COMMAND_POST_FILE +#define SARA_R5_HTTP_COMMAND_POST_DATA UBX_CELL_HTTP_COMMAND_POST_DATA +#define SARA_R5_HTTP_COMMAND_GET_FOTA UBX_CELL_HTTP_COMMAND_GET_FOTA + +#define SARA_R5_HTTP_CONTENT_APPLICATION_X_WWW UBX_CELL_HTTP_CONTENT_APPLICATION_X_WWW +#define SARA_R5_HTTP_CONTENT_TEXT_PLAIN UBX_CELL_HTTP_CONTENT_TEXT_PLAIN +#define SARA_R5_HTTP_CONTENT_APPLICATION_OCTET UBX_CELL_HTTP_CONTENT_APPLICATION_OCTET +#define SARA_R5_HTTP_CONTENT_MULTIPART_FORM UBX_CELL_HTTP_CONTENT_MULTIPART_FORM +#define SARA_R5_HTTP_CONTENT_APPLICATION_JSON UBX_CELL_HTTP_CONTENT_APPLICATION_JSON +#define SARA_R5_HTTP_CONTENT_APPLICATION_XML UBX_CELL_HTTP_CONTENT_APPLICATION_XML +#define SARA_R5_HTTP_CONTENT_USER_DEFINED UBX_CELL_HTTP_CONTENT_USER_DEFINED + +#define SARA_R5_MQTT_NV_RESTORE UBX_CELL_MQTT_NV_RESTORE +#define SARA_R5_MQTT_NV_SET UBX_CELL_MQTT_NV_SET +#define SARA_R5_MQTT_NV_STORE UBX_CELL_MQTT_NV_STORE + +#define SARA_R5_MQTT_PROFILE_CLIENT_ID UBX_CELL_MQTT_PROFILE_CLIENT_ID +#define SARA_R5_MQTT_PROFILE_SERVERNAME UBX_CELL_MQTT_PROFILE_SERVERNAME +#define SARA_R5_MQTT_PROFILE_IPADDRESS UBX_CELL_MQTT_PROFILE_IPADDRESS +#define SARA_R5_MQTT_PROFILE_USERNAMEPWD UBX_CELL_MQTT_PROFILE_USERNAMEPWD +#define SARA_R5_MQTT_PROFILE_QOS UBX_CELL_MQTT_PROFILE_QOS +#define SARA_R5_MQTT_PROFILE_RETAIN UBX_CELL_MQTT_PROFILE_RETAIN +#define SARA_R5_MQTT_PROFILE_TOPIC UBX_CELL_MQTT_PROFILE_TOPIC +#define SARA_R5_MQTT_PROFILE_MESSAGE UBX_CELL_MQTT_PROFILE_MESSAGE +#define SARA_R5_MQTT_PROFILE_INACTIVITYTIMEOUT UBX_CELL_MQTT_PROFILE_INACTIVITYTIMEOUT +#define SARA_R5_MQTT_PROFILE_SECURE UBX_CELL_MQTT_PROFILE_SECURE + +#define SARA_R5_MQTT_COMMAND_INVALID UBX_CELL_MQTT_COMMAND_INVALID +#define SARA_R5_MQTT_COMMAND_LOGOUT UBX_CELL_MQTT_COMMAND_LOGOUT +#define SARA_R5_MQTT_COMMAND_LOGIN UBX_CELL_MQTT_COMMAND_LOGIN +#define SARA_R5_MQTT_COMMAND_PUBLISH UBX_CELL_MQTT_COMMAND_PUBLISH +#define SARA_R5_MQTT_COMMAND_PUBLISHFILE UBX_CELL_MQTT_COMMAND_PUBLISHFILE +#define SARA_R5_MQTT_COMMAND_SUBSCRIBE UBX_CELL_MQTT_COMMAND_SUBSCRIBE +#define SARA_R5_MQTT_COMMAND_UNSUBSCRIBE UBX_CELL_MQTT_COMMAND_UNSUBSCRIBE +#define SARA_R5_MQTT_COMMAND_READ UBX_CELL_MQTT_COMMAND_READ +#define SARA_R5_MQTT_COMMAND_RCVMSGFORMAT UBX_CELL_MQTT_COMMAND_RCVMSGFORMAT +#define SARA_R5_MQTT_COMMAND_PING UBX_CELL_MQTT_COMMAND_PING +#define SARA_R5_MQTT_COMMAND_PUBLISHBINARY UBX_CELL_MQTT_COMMAND_PUBLISHBINARY + +#define SARA_R5_FTP_PROFILE_IPADDRESS UBX_CELL_FTP_PROFILE_IPADDRESS +#define SARA_R5_FTP_PROFILE_SERVERNAME UBX_CELL_FTP_PROFILE_SERVERNAME +#define SARA_R5_FTP_PROFILE_USERNAME UBX_CELL_FTP_PROFILE_USERNAME +#define SARA_R5_FTP_PROFILE_PWD UBX_CELL_FTP_PROFILE_PWD +#define SARA_R5_FTP_PROFILE_ACCOUNT UBX_CELL_FTP_PROFILE_ACCOUNT +#define SARA_R5_FTP_PROFILE_TIMEOUT UBX_CELL_FTP_PROFILE_TIMEOUT +#define SARA_R5_FTP_PROFILE_MODE UBX_CELL_FTP_PROFILE_MODE + +#define SARA_R5_FTP_COMMAND_INVALID UBX_CELL_FTP_COMMAND_INVALID +#define SARA_R5_FTP_COMMAND_LOGOUT UBX_CELL_FTP_COMMAND_LOGOUT +#define SARA_R5_FTP_COMMAND_LOGIN UBX_CELL_FTP_COMMAND_LOGIN +#define SARA_R5_FTP_COMMAND_DELETE_FILE UBX_CELL_FTP_COMMAND_DELETE_FILE +#define SARA_R5_FTP_COMMAND_RENAME_FILE UBX_CELL_FTP_COMMAND_RENAME_FILE +#define SARA_R5_FTP_COMMAND_GET_FILE UBX_CELL_FTP_COMMAND_GET_FILE +#define SARA_R5_FTP_COMMAND_PUT_FILE UBX_CELL_FTP_COMMAND_PUT_FILE +#define SARA_R5_FTP_COMMAND_GET_FILE_DIRECT UBX_CELL_FTP_COMMAND_GET_FILE_DIRECT +#define SARA_R5_FTP_COMMAND_PUT_FILE_DIRECT UBX_CELL_FTP_COMMAND_PUT_FILE_DIRECT +#define SARA_R5_FTP_COMMAND_CHANGE_DIR UBX_CELL_FTP_COMMAND_CHANGE_DIR +#define SARA_R5_FTP_COMMAND_MKDIR UBX_CELL_FTP_COMMAND_MKDIR +#define SARA_R5_FTP_COMMAND_RMDIR UBX_CELL_FTP_COMMAND_RMDIR +#define SARA_R5_FTP_COMMAND_DIR_INFO UBX_CELL_FTP_COMMAND_DIR_INFO +#define SARA_R5_FTP_COMMAND_LS UBX_CELL_FTP_COMMAND_LS +#define SARA_R5_FTP_COMMAND_GET_FOTA_FILE UBX_CELL_FTP_COMMAND_GET_FOTA_FILE + +#define SARA_R5_PSD_CONFIG_PARAM_PROTOCOL UBX_CELL_PSD_CONFIG_PARAM_PROTOCOL +#define SARA_R5_PSD_CONFIG_PARAM_APN UBX_CELL_PSD_CONFIG_PARAM_APN //SARA_R5_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 //SARA_R5_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 -#define SARA_R5_PSD_CONFIG_PARAM_DNS1 UBLOX_AT_PSD_CONFIG_PARAM_DNS1 -#define SARA_R5_PSD_CONFIG_PARAM_DNS2 UBLOX_AT_PSD_CONFIG_PARAM_DNS2 +#define SARA_R5_PSD_CONFIG_PARAM_DNS1 UBX_CELL_PSD_CONFIG_PARAM_DNS1 +#define SARA_R5_PSD_CONFIG_PARAM_DNS2 UBX_CELL_PSD_CONFIG_PARAM_DNS2 //SARA_R5_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 //SARA_R5_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 //SARA_R5_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 //SARA_R5_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 -#define SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID UBLOX_AT_PSD_CONFIG_PARAM_MAP_TO_CID - -#define SARA_R5_PSD_PROTOCOL_IPV4 UBLOX_AT_PSD_PROTOCOL_IPV4 -#define SARA_R5_PSD_PROTOCOL_IPV6 UBLOX_AT_PSD_PROTOCOL_IPV6 -#define SARA_R5_PSD_PROTOCOL_IPV4V6_V4_PREF UBLOX_AT_PSD_PROTOCOL_IPV4V6_V4_PREF -#define SARA_R5_PSD_PROTOCOL_IPV4V6_V6_PREF UBLOX_AT_PSD_PROTOCOL_IPV4V6_V6_PREF - -#define SARA_R5_PSD_ACTION_RESET UBLOX_AT_PSD_ACTION_RESET -#define SARA_R5_PSD_ACTION_STORE UBLOX_AT_PSD_ACTION_STORE -#define SARA_R5_PSD_ACTION_LOAD UBLOX_AT_PSD_ACTION_LOAD -#define SARA_R5_PSD_ACTION_ACTIVATE UBLOX_AT_PSD_ACTION_ACTIVATE -#define SARA_R5_PSD_ACTION_DEACTIVATE UBLOX_AT_PSD_ACTION_DEACTIVATE - -#define SARA_R5_SEC_PROFILE_PARAM_CERT_VAL_LEVEL UBLOX_AT_SEC_PROFILE_PARAM_CERT_VAL_LEVEL -#define SARA_R5_SEC_PROFILE_PARAM_TLS_VER UBLOX_AT_SEC_PROFILE_PARAM_TLS_VER -#define SARA_R5_SEC_PROFILE_PARAM_CYPHER_SUITE UBLOX_AT_SEC_PROFILE_PARAM_CYPHER_SUITE -#define SARA_R5_SEC_PROFILE_PARAM_ROOT_CA UBLOX_AT_SEC_PROFILE_PARAM_ROOT_CA -#define SARA_R5_SEC_PROFILE_PARAM_HOSTNAME UBLOX_AT_SEC_PROFILE_PARAM_HOSTNAME -#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_CERT UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_CERT -#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY -#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY_PWD UBLOX_AT_SEC_PROFILE_PARAM_CLIENT_KEY_PWD -#define SARA_R5_SEC_PROFILE_PARAM_PSK UBLOX_AT_SEC_PROFILE_PARAM_PSK -#define SARA_R5_SEC_PROFILE_PARAM_PSK_IDENT UBLOX_AT_SEC_PROFILE_PARAM_PSK_IDENT -#define SARA_R5_SEC_PROFILE_PARAM_SNI UBLOX_AT_SEC_PROFILE_PARAM_SNI - -#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_NO UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_NO -#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL -#define SARA_R5_SEC_PROFILE_CERVTAL_OPCODE_YESURL UBLOX_AT_SEC_PROFILE_CERVTAL_OPCODE_YESURL -#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE UBLOX_AT_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE - -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_ANYVER UBLOX_AT_SEC_PROFILE_TLS_OPCODE_ANYVER -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_0 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_0 -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_1 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_1 -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_2 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_2 -#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_3 UBLOX_AT_SEC_PROFILE_TLS_OPCODE_VER1_3 - -#define SARA_R5_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT UBLOX_AT_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT - -#define SARA_R5_SEC_MANAGER_OPCODE_IMPORT UBLOX_AT_SEC_MANAGER_OPCODE_IMPORT - -#define SARA_R5_SEC_MANAGER_ROOTCA UBLOX_AT_SEC_MANAGER_ROOTCA -#define SARA_R5_SEC_MANAGER_CLIENT_CERT UBLOX_AT_SEC_MANAGER_CLIENT_CERT -#define SARA_R5_SEC_MANAGER_CLIENT_KEY UBLOX_AT_SEC_MANAGER_CLIENT_KEY -#define SARA_R5_SEC_MANAGER_SERVER_CERT UBLOX_AT_SEC_MANAGER_SERVER_CERT +#define SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID UBX_CELL_PSD_CONFIG_PARAM_MAP_TO_CID + +#define SARA_R5_PSD_PROTOCOL_IPV4 UBX_CELL_PSD_PROTOCOL_IPV4 +#define SARA_R5_PSD_PROTOCOL_IPV6 UBX_CELL_PSD_PROTOCOL_IPV6 +#define SARA_R5_PSD_PROTOCOL_IPV4V6_V4_PREF UBX_CELL_PSD_PROTOCOL_IPV4V6_V4_PREF +#define SARA_R5_PSD_PROTOCOL_IPV4V6_V6_PREF UBX_CELL_PSD_PROTOCOL_IPV4V6_V6_PREF + +#define SARA_R5_PSD_ACTION_RESET UBX_CELL_PSD_ACTION_RESET +#define SARA_R5_PSD_ACTION_STORE UBX_CELL_PSD_ACTION_STORE +#define SARA_R5_PSD_ACTION_LOAD UBX_CELL_PSD_ACTION_LOAD +#define SARA_R5_PSD_ACTION_ACTIVATE UBX_CELL_PSD_ACTION_ACTIVATE +#define SARA_R5_PSD_ACTION_DEACTIVATE UBX_CELL_PSD_ACTION_DEACTIVATE + +#define SARA_R5_SEC_PROFILE_PARAM_CERT_VAL_LEVEL UBX_CELL_SEC_PROFILE_PARAM_CERT_VAL_LEVEL +#define SARA_R5_SEC_PROFILE_PARAM_TLS_VER UBX_CELL_SEC_PROFILE_PARAM_TLS_VER +#define SARA_R5_SEC_PROFILE_PARAM_CYPHER_SUITE UBX_CELL_SEC_PROFILE_PARAM_CYPHER_SUITE +#define SARA_R5_SEC_PROFILE_PARAM_ROOT_CA UBX_CELL_SEC_PROFILE_PARAM_ROOT_CA +#define SARA_R5_SEC_PROFILE_PARAM_HOSTNAME UBX_CELL_SEC_PROFILE_PARAM_HOSTNAME +#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_CERT UBX_CELL_SEC_PROFILE_PARAM_CLIENT_CERT +#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY UBX_CELL_SEC_PROFILE_PARAM_CLIENT_KEY +#define SARA_R5_SEC_PROFILE_PARAM_CLIENT_KEY_PWD UBX_CELL_SEC_PROFILE_PARAM_CLIENT_KEY_PWD +#define SARA_R5_SEC_PROFILE_PARAM_PSK UBX_CELL_SEC_PROFILE_PARAM_PSK +#define SARA_R5_SEC_PROFILE_PARAM_PSK_IDENT UBX_CELL_SEC_PROFILE_PARAM_PSK_IDENT +#define SARA_R5_SEC_PROFILE_PARAM_SNI UBX_CELL_SEC_PROFILE_PARAM_SNI + +#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_NO UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_NO +#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL +#define SARA_R5_SEC_PROFILE_CERVTAL_OPCODE_YESURL UBX_CELL_SEC_PROFILE_CERVTAL_OPCODE_YESURL +#define SARA_R5_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE + +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_ANYVER UBX_CELL_SEC_PROFILE_TLS_OPCODE_ANYVER +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_0 UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_0 +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_1 UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_1 +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_2 UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_2 +#define SARA_R5_SEC_PROFILE_TLS_OPCODE_VER1_3 UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_3 + +#define SARA_R5_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT UBX_CELL_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT + +#define SARA_R5_SEC_MANAGER_OPCODE_IMPORT UBX_CELL_SEC_MANAGER_OPCODE_IMPORT + +#define SARA_R5_SEC_MANAGER_ROOTCA UBX_CELL_SEC_MANAGER_ROOTCA +#define SARA_R5_SEC_MANAGER_CLIENT_CERT UBX_CELL_SEC_MANAGER_CLIENT_CERT +#define SARA_R5_SEC_MANAGER_CLIENT_KEY UBX_CELL_SEC_MANAGER_CLIENT_KEY +#define SARA_R5_SEC_MANAGER_SERVER_CERT UBX_CELL_SEC_MANAGER_SERVER_CERT #endif //SPARKFUN_SARA_R5_ARDUINO_LIBRARY_H From 0f2b97e55f14ca65cb2ce44ad8d8145e158349d4 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Fri, 17 Nov 2023 13:08:53 -0700 Subject: [PATCH 14/52] Change base class private members to protected Sub classes will need these things --- src/sfe_ublox_cellular.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index a16bfa6..032add5 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -1024,7 +1024,7 @@ class UBX_CELL : public Print UBX_CELL_error_t sendCustomCommandWithResponse(const char *command, const char *expectedResponse, char *responseDest, unsigned long commandTimeout = UBX_CELL_STANDARD_RESPONSE_TIMEOUT, bool at = true); -private: +protected: HardwareSerial *_hardSerial; #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED SoftwareSerial *_softSerial; From 71c39a95269f3f25698bf6fb42776c1778dfa5ae Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Fri, 17 Nov 2023 16:20:24 -0700 Subject: [PATCH 15/52] Add voice class --- src/sfe_lara_r6.h | 9 +-- src/sfe_ublox_cellular_voice.cpp | 112 +++++++++++++++++++++++++++++++ src/sfe_ublox_cellular_voice.h | 26 +++++++ 3 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 src/sfe_ublox_cellular_voice.cpp create mode 100644 src/sfe_ublox_cellular_voice.h diff --git a/src/sfe_lara_r6.h b/src/sfe_lara_r6.h index 3177346..8349645 100644 --- a/src/sfe_lara_r6.h +++ b/src/sfe_lara_r6.h @@ -2,14 +2,15 @@ #define SFE_LARA_R6_LIBRARY_H #include "sfe_ublox_cellular.h" +#include "sfe_ublox_cellular_voice.h" // Base LARA-R6 class -class LARA_R6: public UBX_CELL +class LARA_R6: virtual public UBX_CELL { }; -class LARA_R6001: public LARA_R6 +class LARA_R6001: public LARA_R6, public UBX_CELL_VOICE { }; @@ -19,7 +20,7 @@ class LARA_R6001D: public LARA_R6 }; -class LARA_R6401: public LARA_R6 +class LARA_R6401: public LARA_R6, public UBX_CELL_VOICE { }; @@ -29,7 +30,7 @@ class LARA_R6401D: public LARA_R6 }; -class LARA_R6801_00B: public LARA_R6 +class LARA_R6801_00B: public LARA_R6, public UBX_CELL_VOICE { }; diff --git a/src/sfe_ublox_cellular_voice.cpp b/src/sfe_ublox_cellular_voice.cpp new file mode 100644 index 0000000..951dc98 --- /dev/null +++ b/src/sfe_ublox_cellular_voice.cpp @@ -0,0 +1,112 @@ +#include "sfe_ublox_cellular_voice.h" + +UBX_CELL_error_t UBX_CELL_VOICE::dial(String number) +{ + char *command; + char *numberCStr; + UBX_CELL_error_t err; + + numberCStr = ubx_cell_calloc_char(number.length() + 1); + if (numberCStr == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + number.toCharArray(numberCStr, number.length() + 1); + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_DIAL) + strlen(numberCStr) + 3); + if (command != nullptr) + { + // Heads up! The dial command is one of the only commands that requires a + // semicolon at the end of it! + sprintf(command, "%s=%s;", UBX_CELL_COMMAND_DIAL, numberCStr); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, + nullptr, UBX_CELL_10_SEC_TIMEOUT); + + free(command); + } + else + { + err = UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + free(numberCStr); + + return err; +} + +UBX_CELL_error_t UBX_CELL_VOICE::answer(void) +{ + return sendCommandWithResponse(UBX_CELL_COMMAND_ANSWER, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); +} + +UBX_CELL_error_t UBX_CELL_VOICE::hangUp(void) +{ + return sendCommandWithResponse(UBX_CELL_COMMAND_HANG_UP, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); +} + +UBX_CELL_error_t UBX_CELL_VOICE::playAudioResource(uint8_t audio_resource, uint8_t tone_id, uint8_t nof_repeat) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL_VOICE::stopAudioResource(uint8_t audio_resource) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL_VOICE::generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume) +{ + UBX_CELL_error_t err; + char *command; + char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume); + + err = sendCommandWithResponse(command, response, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL_VOICE::generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume) +{ + UBX_CELL_error_t err; + char *command; + char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume); + + err = sendCommandWithResponse(command, response, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} \ No newline at end of file diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h new file mode 100644 index 0000000..7b605e1 --- /dev/null +++ b/src/sfe_ublox_cellular_voice.h @@ -0,0 +1,26 @@ +#ifndef SPARKFUN_UBX_CELL_VOICE_ARDUINO_LIBRARY_H +#define SPARKFUN_UBX_CELL_VOICE_ARDUINO_LIBRARY_H + +#include "sfe_ublox_cellular.h" + +const char UBX_CELL_COMMAND_DIAL[] = "D"; // Dial command +const char UBX_CELL_COMMAND_ANSWER[] = "A"; // Answer call +const char UBX_CELL_COMMAND_HANG_UP[] = "+CHUP"; // Hang up call +const char UBX_CELL_COMMAND_PLAY_AUDIO[] = "+UPAR"; // Play audio resource +const char UBX_CELL_COMMAND_STOP_AUDIO[] = "+USAR"; // Stop audio resource +const char UBX_CELL_COMMAND_GENERATE_TONE[] = "+UTGN"; // Tone generator + +// Base class for any modules supporting voice calls +class UBX_CELL_VOICE: virtual public UBX_CELL +{ +public: + UBX_CELL_error_t dial(String number); + UBX_CELL_error_t answer(void); + UBX_CELL_error_t hangUp(void); + UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id, uint8_t nof_repeat); + UBX_CELL_error_t stopAudioResource(uint8_t audio_resource); + UBX_CELL_error_t generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume); + UBX_CELL_error_t generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume); +}; + +#endif \ No newline at end of file From f271ac7935bb8604cc87f4a7ccbad91a7e411152 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 29 Nov 2023 10:36:25 -0700 Subject: [PATCH 16/52] Change to template structure Audio class (and other feature sets) now uses templating instead of virtual inheritance --- src/sfe_lara_r6.h | 8 +-- src/sfe_ublox_cellular.h | 12 ++-- src/sfe_ublox_cellular_voice.cpp | 111 ---------------------------- src/sfe_ublox_cellular_voice.h | 120 ++++++++++++++++++++++++++++--- 4 files changed, 122 insertions(+), 129 deletions(-) diff --git a/src/sfe_lara_r6.h b/src/sfe_lara_r6.h index 8349645..08e9736 100644 --- a/src/sfe_lara_r6.h +++ b/src/sfe_lara_r6.h @@ -5,12 +5,12 @@ #include "sfe_ublox_cellular_voice.h" // Base LARA-R6 class -class LARA_R6: virtual public UBX_CELL +class LARA_R6: public UBX_CELL { }; -class LARA_R6001: public LARA_R6, public UBX_CELL_VOICE +class LARA_R6001: public LARA_R6, public UBX_CELL_VOICE { }; @@ -20,7 +20,7 @@ class LARA_R6001D: public LARA_R6 }; -class LARA_R6401: public LARA_R6, public UBX_CELL_VOICE +class LARA_R6401: public LARA_R6, public UBX_CELL_VOICE { }; @@ -30,7 +30,7 @@ class LARA_R6401D: public LARA_R6 }; -class LARA_R6801_00B: public LARA_R6, public UBX_CELL_VOICE +class LARA_R6801_00B: public LARA_R6, public UBX_CELL_VOICE { }; diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index 032add5..f59062d 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -1024,6 +1024,12 @@ class UBX_CELL : public Print UBX_CELL_error_t sendCustomCommandWithResponse(const char *command, const char *expectedResponse, char *responseDest, unsigned long commandTimeout = UBX_CELL_STANDARD_RESPONSE_TIMEOUT, bool at = true); + // Send command with an expected (potentially partial) response, store entire response + UBX_CELL_error_t sendCommandWithResponse(const char *command, const char *expectedResponse, + char *responseDest, unsigned long commandTimeout, int destSize = minimumResponseAllocation, bool at = true); + + char *ubx_cell_calloc_char(size_t num); + protected: HardwareSerial *_hardSerial; #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED @@ -1091,10 +1097,6 @@ class UBX_CELL : public Print // Wait for an expected response (don't send a command) UBX_CELL_error_t waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout); - // Send command with an expected (potentially partial) response, store entire response - UBX_CELL_error_t sendCommandWithResponse(const char *command, const char *expectedResponse, - char *responseDest, unsigned long commandTimeout, int destSize = minimumResponseAllocation, bool at = true); - // Send a command -- prepend AT if at is true void sendCommand(const char *command, bool at); @@ -1118,8 +1120,6 @@ class UBX_CELL : public Print UBX_CELL_error_t autobaud(unsigned long desiredBaud); - char *ubx_cell_calloc_char(size_t num); - bool processURCEvent(const char *event); void pruneBacklog(void); diff --git a/src/sfe_ublox_cellular_voice.cpp b/src/sfe_ublox_cellular_voice.cpp index 951dc98..db6e4a7 100644 --- a/src/sfe_ublox_cellular_voice.cpp +++ b/src/sfe_ublox_cellular_voice.cpp @@ -1,112 +1 @@ #include "sfe_ublox_cellular_voice.h" - -UBX_CELL_error_t UBX_CELL_VOICE::dial(String number) -{ - char *command; - char *numberCStr; - UBX_CELL_error_t err; - - numberCStr = ubx_cell_calloc_char(number.length() + 1); - if (numberCStr == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - number.toCharArray(numberCStr, number.length() + 1); - - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_DIAL) + strlen(numberCStr) + 3); - if (command != nullptr) - { - // Heads up! The dial command is one of the only commands that requires a - // semicolon at the end of it! - sprintf(command, "%s=%s;", UBX_CELL_COMMAND_DIAL, numberCStr); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, - nullptr, UBX_CELL_10_SEC_TIMEOUT); - - free(command); - } - else - { - err = UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - free(numberCStr); - - return err; -} - -UBX_CELL_error_t UBX_CELL_VOICE::answer(void) -{ - return sendCommandWithResponse(UBX_CELL_COMMAND_ANSWER, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); -} - -UBX_CELL_error_t UBX_CELL_VOICE::hangUp(void) -{ - return sendCommandWithResponse(UBX_CELL_COMMAND_HANG_UP, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); -} - -UBX_CELL_error_t UBX_CELL_VOICE::playAudioResource(uint8_t audio_resource, uint8_t tone_id, uint8_t nof_repeat) -{ - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL_VOICE::stopAudioResource(uint8_t audio_resource) -{ - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL_VOICE::generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume) -{ - UBX_CELL_error_t err; - char *command; - char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume); - - err = sendCommandWithResponse(command, response, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL_VOICE::generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume) -{ - UBX_CELL_error_t err; - char *command; - char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume); - - err = sendCommandWithResponse(command, response, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} \ No newline at end of file diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index 7b605e1..46caa65 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -11,16 +11,120 @@ const char UBX_CELL_COMMAND_STOP_AUDIO[] = "+USAR"; // Stop audio resource const char UBX_CELL_COMMAND_GENERATE_TONE[] = "+UTGN"; // Tone generator // Base class for any modules supporting voice calls -class UBX_CELL_VOICE: virtual public UBX_CELL +template +class UBX_CELL_VOICE { public: - UBX_CELL_error_t dial(String number); - UBX_CELL_error_t answer(void); - UBX_CELL_error_t hangUp(void); - UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id, uint8_t nof_repeat); - UBX_CELL_error_t stopAudioResource(uint8_t audio_resource); - UBX_CELL_error_t generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume); - UBX_CELL_error_t generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume); + UBX_CELL_error_t dial(String number) + { + char *command; + char *numberCStr; + UBX_CELL_error_t err; + + numberCStr = static_cast(this)->ubx_cell_calloc_char(number.length() + 1); + if (numberCStr == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + number.toCharArray(numberCStr, number.length() + 1); + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_DIAL) + strlen(numberCStr) + 3); + if (command != nullptr) + { + // Heads up! The dial command is one of the only commands that requires a + // semicolon at the end of it! + sprintf(command, "%s=%s;", UBX_CELL_COMMAND_DIAL, numberCStr); + + err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, + nullptr, UBX_CELL_10_SEC_TIMEOUT); + + free(command); + } + else + { + err = UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + free(numberCStr); + + return err; + } + + UBX_CELL_error_t answer(void) + { + return static_cast(this)->sendCommandWithResponse(UBX_CELL_COMMAND_ANSWER, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + } + + UBX_CELL_error_t hangUp(void) + { + return static_cast(this)->sendCommandWithResponse(UBX_CELL_COMMAND_HANG_UP, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + } + + UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id, uint8_t nof_repeat) + { + UBX_CELL_error_t err; + char *command; + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat); + + err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; + } + + UBX_CELL_error_t stopAudioResource(uint8_t audio_resource) + { + UBX_CELL_error_t err; + char *command; + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource); + + err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; + } + + UBX_CELL_error_t generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume) + { + UBX_CELL_error_t err; + char *command; + char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume); + + err = static_cast(this)->sendCommandWithResponse(command, response, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; + } + + UBX_CELL_error_t generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume) + { + UBX_CELL_error_t err; + char *command; + char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume); + + err = static_cast(this)->sendCommandWithResponse(command, response, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; + } }; #endif \ No newline at end of file From 920bc7bc2b59bcb03330affcdaf110eba7676733 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 09:53:47 -0700 Subject: [PATCH 17/52] Remove unused .cpp files --- src/sfe_lara_r6.cpp | 0 src/sfe_sara_r5.cpp | 0 src/sfe_ublox_cellular_voice.cpp | 1 - 3 files changed, 1 deletion(-) delete mode 100644 src/sfe_lara_r6.cpp delete mode 100644 src/sfe_sara_r5.cpp delete mode 100644 src/sfe_ublox_cellular_voice.cpp diff --git a/src/sfe_lara_r6.cpp b/src/sfe_lara_r6.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/sfe_ublox_cellular_voice.cpp b/src/sfe_ublox_cellular_voice.cpp deleted file mode 100644 index db6e4a7..0000000 --- a/src/sfe_ublox_cellular_voice.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "sfe_ublox_cellular_voice.h" From 8fbe23f7e4696287d31a6812379a90ca5ec474af Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 10:14:39 -0700 Subject: [PATCH 18/52] Change default baud rate Not all modules support 9600, 115200 is a better default --- .../Example1_DeviceIdentification.ino | 2 +- src/sfe_ublox_cellular.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino index a09ac87..74dd2df 100644 --- a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino +++ b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino @@ -63,7 +63,7 @@ void setup() myModule.invertPowerPin(true); // Initialize the SARA - if (myModule.begin(mySerial, 9600) ) + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) { Serial.println(F("SARA-R5 connected!")); } diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index f59062d..c361865 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -646,9 +646,9 @@ class UBX_CELL : public Print ~UBX_CELL(); // Begin -- initialize module and ensure it's connected #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - bool begin(SoftwareSerial &softSerial, unsigned long baud = 9600); + bool begin(SoftwareSerial &softSerial, unsigned long baud = UBX_CELL_DEFAULT_BAUD_RATE); #endif - bool begin(HardwareSerial &hardSerial, unsigned long baud = 9600); + bool begin(HardwareSerial &hardSerial, unsigned long baud = UBX_CELL_DEFAULT_BAUD_RATE); // Debug prints void enableDebugging(Print &debugPort = Serial); //Turn on debug printing. If user doesn't specify then Serial will be used. From d26ede01422b6ce9efea0fcf0239d6a4002246d3 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 10:16:01 -0700 Subject: [PATCH 19/52] Update Example 1 Remove "SARA" references to keep it generic Add "Beginning..." print message to aid user in case module doesn't connect, which results in no messages for a long time --- .../Example1_DeviceIdentification.ino | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino index 74dd2df..ba5591c 100644 --- a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino +++ b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino @@ -33,7 +33,7 @@ String simStateString[] = "Operational" // 6 }; -// processSIMstate is provided to the SARA-R5 library via a +// processSIMstate is provided to the u-blox cellular library via a // callback setter -- setSIMstateReadCallback. (See setup()) void processSIMstate(UBX_CELL_sim_states_t state) { @@ -48,7 +48,7 @@ void setup() Serial.begin(115200); // Start the serial console // Wait for user to press key to begin - Serial.println(F("SARA-R5 Example")); + Serial.println(F("u-blox Cellular Example 1 - Device Identification")); Serial.println(F("Press any key to begin")); while (!Serial.available()) // Wait for the user to press a key (send any serial character) @@ -56,21 +56,23 @@ void setup() while (Serial.available()) // Empty the serial RX buffer Serial.read(); - //myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Comment the next line if required - myModule.invertPowerPin(true); + // Uncomment the next line if required + // myModule.invertPowerPin(true); - // Initialize the SARA + // Initialize the module if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) { - Serial.println(F("SARA-R5 connected!")); + Serial.println(F("Module connected!")); } else { - Serial.println(F("Unable to communicate with the SARA.")); - Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again.")); + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); while (1) ; // Loop forever on fail } Serial.println(); @@ -95,5 +97,5 @@ void setup() void loop() { - myModule.poll(); // Keep processing data from the SARA so we can extract the SIM status + myModule.poll(); // Keep processing data from the module so we can extract the SIM status } \ No newline at end of file From 4b2fc8c302e04c80416c006e13e0a8e0195b54ee Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 10:38:42 -0700 Subject: [PATCH 20/52] Move SARA-R5 features out of base class LARA_R6 does not support these AT commands, as per #4 Moved into SARA-R5 class for now, but if other modules support these, they should be moved into a sub-class that can be inherited like the voice class --- src/sfe_sara_r5.cpp | 360 +++++++++++++++++++++++++++++++++++++ src/sfe_sara_r5.h | 24 ++- src/sfe_ublox_cellular.cpp | 359 ------------------------------------ src/sfe_ublox_cellular.h | 20 --- 4 files changed, 383 insertions(+), 380 deletions(-) create mode 100644 src/sfe_sara_r5.cpp diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp new file mode 100644 index 0000000..ddff46b --- /dev/null +++ b/src/sfe_sara_r5.cpp @@ -0,0 +1,360 @@ +#include "sfe_sara_r5.h" + +UBX_CELL_error_t SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utime_sensor_t sensor) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_REQUEST_TIME) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (mode == UBX_CELL_UTIME_MODE_STOP) // stop UTIME does not require a sensor + sprintf(command, "%s=%d", SARA_R5_GNSS_REQUEST_TIME, mode); + else + sprintf(command, "%s=%d,%d", SARA_R5_GNSS_REQUEST_TIME, mode, sensor); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_10_SEC_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor) +{ + UBX_CELL_error_t err; + char *command; + char *response; + + UBX_CELL_utime_mode_t m; + UBX_CELL_utime_sensor_t s; + + command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_REQUEST_TIME) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", SARA_R5_GNSS_REQUEST_TIME); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_10_SEC_TIMEOUT); + + // Response format: \r\n+UTIME: [,]\r\n\r\nOK\r\n + if (err == UBX_CELL_ERROR_SUCCESS) + { + int mStore, sStore, scanned = 0; + char *searchPtr = strstr(response, "+UTIME:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UTIME:"); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d\r\n", &mStore, &sStore); + } + m = (UBX_CELL_utime_mode_t)mStore; + s = (UBX_CELL_utime_sensor_t)sStore; + if (scanned == 2) + { + *mode = m; + *sensor = s; + } + else if (scanned == 1) + { + *mode = m; + *sensor = UBX_CELL_UTIME_SENSOR_NONE; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBX_CELL_error_t SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t config) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_TIME_INDICATION) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", SARA_R5_GNSS_TIME_INDICATION, config); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config) +{ + UBX_CELL_error_t err; + char *command; + char *response; + + UBX_CELL_utime_urc_configuration_t c; + + command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_TIME_INDICATION) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", SARA_R5_GNSS_TIME_INDICATION); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + // Response format: \r\n+UTIMEIND: \r\n\r\nOK\r\n + if (err == UBX_CELL_ERROR_SUCCESS) + { + int cStore, scanned = 0; + char *searchPtr = strstr(response, "+UTIMEIND:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UTIMEIND:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d\r\n", &cStore); + } + c = (UBX_CELL_utime_urc_configuration_t)cStore; + if (scanned == 1) + { + *config = c; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBX_CELL_error_t SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_TIME_CONFIGURATION) + 48); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; +#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) + sprintf(command, "%s=%d,%d", SARA_R5_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); +#else + sprintf(command, "%s=%ld,%ld", SARA_R5_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); +#endif + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds) +{ + UBX_CELL_error_t err; + char *command; + char *response; + + int32_t ons; + int32_t os; + + command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_TIME_CONFIGURATION) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", SARA_R5_GNSS_TIME_CONFIGURATION); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, + response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + // Response format: \r\n+UTIMECFG: ,\r\n\r\nOK\r\n + if (err == UBX_CELL_ERROR_SUCCESS) + { + int scanned = 0; + char *searchPtr = strstr(response, "+UTIMECFG:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UTIMECFG:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces +#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) + scanned = sscanf(searchPtr, "%d,%d\r\n", &ons, &os); +#else + scanned = sscanf(searchPtr, "%ld,%ld\r\n", &ons, &os); +#endif + } + if (scanned == 2) + { + *offsetNanoseconds = ons; + *offsetSeconds = os; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value) +{ + UBX_CELL_error_t err; + char *command; + + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; + + command = ubx_cell_calloc_char(strlen(SARA_R5_MESSAGE_PDP_CONFIG) + 24); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", SARA_R5_MESSAGE_PDP_CONFIG, profile, parameter, + value); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, UBX_CELL_pdp_protocol_type_t value) +{ + return (setPDPconfiguration(profile, parameter, (int)value)); +} + +UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, String value) +{ + UBX_CELL_error_t err; + char *command; + + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; + + command = ubx_cell_calloc_char(strlen(SARA_R5_MESSAGE_PDP_CONFIG) + 64); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", SARA_R5_MESSAGE_PDP_CONFIG, profile, parameter, + value.c_str()); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value) +{ + UBX_CELL_error_t err; + char *command; + + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; + + command = ubx_cell_calloc_char(strlen(SARA_R5_MESSAGE_PDP_CONFIG) + 64); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", SARA_R5_MESSAGE_PDP_CONFIG, profile, parameter, + value[0], value[1], value[2], value[3]); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBX_CELL_error_t SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t action) +{ + UBX_CELL_error_t err; + char *command; + + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; + + command = ubx_cell_calloc_char(strlen(SARA_R5_MESSAGE_PDP_ACTION) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", SARA_R5_MESSAGE_PDP_ACTION, profile, action); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *address) +{ + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int profileStore = 0; + int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation + int paramVals[4]; + + command = ubx_cell_calloc_char(strlen(SARA_R5_NETWORK_ASSIGNED_DATA) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", SARA_R5_NETWORK_ASSIGNED_DATA, profile, paramTag); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+UPSND:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UPSND:"); // Move searchPtr to first char + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,\"%d.%d.%d.%d\"", + &profileStore, ¶mTag, + ¶mVals[0], ¶mVals[1], ¶mVals[2], ¶mVals[3]); + } + if (scanNum != 6) + { + if (_printDebug == true) + { + _debugPort->print(F("getNetworkAssignedIPAddress: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + IPAddress tempAddress = { (uint8_t)paramVals[0], (uint8_t)paramVals[1], + (uint8_t)paramVals[2], (uint8_t)paramVals[3] }; + *address = tempAddress; + } + + free(command); + free(response); + + return err; +} diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index 688aa54..6896950 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -3,10 +3,32 @@ #include "sfe_ublox_cellular.h" +const char SARA_R5_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration +const char SARA_R5_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile +const char SARA_R5_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data +const char SARA_R5_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) +const char SARA_R5_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication +const char SARA_R5_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration + // Base SARA-R5 class class SARA_R5: public UBX_CELL { - +public: + UBX_CELL_error_t setUtimeMode(UBX_CELL_utime_mode_t mode = UBX_CELL_UTIME_MODE_PPS, UBX_CELL_utime_sensor_t sensor = UBX_CELL_UTIME_SENSOR_GNSS_LTE); // Time mode, source etc. (+UTIME) + UBX_CELL_error_t getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor); + UBX_CELL_error_t setUtimeIndication(UBX_CELL_utime_urc_configuration_t config = UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED); // +UTIMEIND + UBX_CELL_error_t getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config); + UBX_CELL_error_t setUtimeConfiguration(int32_t offsetNanoseconds = 0, int32_t offsetSeconds = 0); // +UTIMECFG + UBX_CELL_error_t getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds); + + // Packet Switched Data + // Configure the PDP using +UPSD. See UBX_CELL_pdp_configuration_parameter_t for the list of parameters: protocol, APN, username, DNS, etc. + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, UBX_CELL_pdp_protocol_type_t value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, String value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t performPDPaction(int profile, UBX_CELL_pdp_actions_t action); // Performs the requested action for the specified PSD profile: reset, store, load, activate, deactivate + UBX_CELL_error_t getNetworkAssignedIPAddress(int profile, IPAddress *address); // Get the dynamic IP address assigned during PDP context activation }; class SARA_R500S: public SARA_R5 diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index 3dd79c8..484973c 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -1336,218 +1336,6 @@ void UBX_CELL::autoTimeZoneForBegin(bool tz) _autoTimeZoneForBegin = tz; } -UBX_CELL_error_t UBX_CELL::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utime_sensor_t sensor) -{ - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (mode == UBX_CELL_UTIME_MODE_STOP) // stop UTIME does not require a sensor - sprintf(command, "%s=%d", UBX_CELL_GNSS_REQUEST_TIME, mode); - else - sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_REQUEST_TIME, mode, sensor); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_10_SEC_TIMEOUT); - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor) -{ - UBX_CELL_error_t err; - char *command; - char *response; - - UBX_CELL_utime_mode_t m; - UBX_CELL_utime_sensor_t s; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_REQUEST_TIME); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_10_SEC_TIMEOUT); - - // Response format: \r\n+UTIME: [,]\r\n\r\nOK\r\n - if (err == UBX_CELL_ERROR_SUCCESS) - { - int mStore, sStore, scanned = 0; - char *searchPtr = strstr(response, "+UTIME:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+UTIME:"); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d,%d\r\n", &mStore, &sStore); - } - m = (UBX_CELL_utime_mode_t)mStore; - s = (UBX_CELL_utime_sensor_t)sStore; - if (scanned == 2) - { - *mode = m; - *sensor = s; - } - else if (scanned == 1) - { - *mode = m; - *sensor = UBX_CELL_UTIME_SENSOR_NONE; - } - else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - free(command); - free(response); - return err; -} - -UBX_CELL_error_t UBX_CELL::setUtimeIndication(UBX_CELL_utime_urc_configuration_t config) -{ - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_GNSS_TIME_INDICATION, config); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config) -{ - UBX_CELL_error_t err; - char *command; - char *response; - - UBX_CELL_utime_urc_configuration_t c; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_TIME_INDICATION); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - // Response format: \r\n+UTIMEIND: \r\n\r\nOK\r\n - if (err == UBX_CELL_ERROR_SUCCESS) - { - int cStore, scanned = 0; - char *searchPtr = strstr(response, "+UTIMEIND:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+UTIMEIND:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d\r\n", &cStore); - } - c = (UBX_CELL_utime_urc_configuration_t)cStore; - if (scanned == 1) - { - *config = c; - } - else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - free(command); - free(response); - return err; -} - -UBX_CELL_error_t UBX_CELL::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds) -{ - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); -#else - sprintf(command, "%s=%ld,%ld", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); -#endif - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds) -{ - UBX_CELL_error_t err; - char *command; - char *response; - - int32_t ons; - int32_t os; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_TIME_CONFIGURATION); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - // Response format: \r\n+UTIMECFG: ,\r\n\r\nOK\r\n - if (err == UBX_CELL_ERROR_SUCCESS) - { - int scanned = 0; - char *searchPtr = strstr(response, "+UTIMECFG:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+UTIMECFG:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - scanned = sscanf(searchPtr, "%d,%d\r\n", &ons, &os); -#else - scanned = sscanf(searchPtr, "%ld,%ld\r\n", &ons, &os); -#endif - } - if (scanned == 2) - { - *offsetNanoseconds = ons; - *offsetSeconds = os; - } - else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - free(command); - free(response); - return err; -} - UBX_CELL_error_t UBX_CELL::autoTimeZone(bool enable) { UBX_CELL_error_t err; @@ -4835,94 +4623,6 @@ UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opco return err; } -UBX_CELL_error_t UBX_CELL::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value) -{ - UBX_CELL_error_t err; - char *command; - - if (profile >= UBX_CELL_NUM_PSD_PROFILES) - return UBX_CELL_ERROR_ERROR; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, - value); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, UBX_CELL_pdp_protocol_type_t value) -{ - return (setPDPconfiguration(profile, parameter, (int)value)); -} - -UBX_CELL_error_t UBX_CELL::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, String value) -{ - UBX_CELL_error_t err; - char *command; - - if (profile >= UBX_CELL_NUM_PSD_PROFILES) - return UBX_CELL_ERROR_ERROR; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, - value.c_str()); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value) -{ - UBX_CELL_error_t err; - char *command; - - if (profile >= UBX_CELL_NUM_PSD_PROFILES) - return UBX_CELL_ERROR_ERROR; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, - value[0], value[1], value[2], value[3]); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::performPDPaction(int profile, UBX_CELL_pdp_actions_t action) -{ - UBX_CELL_error_t err; - char *command; - - if (profile >= UBX_CELL_NUM_PSD_PROFILES) - return UBX_CELL_ERROR_ERROR; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_ACTION, profile, action); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - free(command); - return err; -} - UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) { UBX_CELL_error_t err; @@ -4946,65 +4646,6 @@ UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) return err; } -UBX_CELL_error_t UBX_CELL::getNetworkAssignedIPAddress(int profile, IPAddress *address) -{ - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int profileStore = 0; - int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation - int paramVals[4]; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBX_CELL_NETWORK_ASSIGNED_DATA, profile, paramTag); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+UPSND:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+UPSND:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d,\"%d.%d.%d.%d\"", - &profileStore, ¶mTag, - ¶mVals[0], ¶mVals[1], ¶mVals[2], ¶mVals[3]); - } - if (scanNum != 6) - { - if (_printDebug == true) - { - _debugPort->print(F("getNetworkAssignedIPAddress: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - IPAddress tempAddress = { (uint8_t)paramVals[0], (uint8_t)paramVals[1], - (uint8_t)paramVals[2], (uint8_t)paramVals[3] }; - *address = tempAddress; - } - - free(command); - free(response); - - return err; -} - bool UBX_CELL::isGPSon(void) { UBX_CELL_error_t err; diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index c361865..b2f74d9 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -132,11 +132,8 @@ const char UBX_CELL_FLOW_CONTROL[] = "&K"; // Flow control const char UBX_CELL_COMMAND_BAUD[] = "+IPR"; // Baud rate // ### Packet switched data services const char UBX_CELL_MESSAGE_PDP_DEF[] = "+CGDCONT"; // Packet switched Data Profile context definition -const char UBX_CELL_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration -const char UBX_CELL_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile const char UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE[] = "+CGACT"; // Activates or deactivates the specified PDP context const char UBX_CELL_MESSAGE_ENTER_PPP[] = "D"; -const char UBX_CELL_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data // ### GPIO const char UBX_CELL_COMMAND_GPIO[] = "+UGPIOC"; // GPIO Configuration // ### IP @@ -172,9 +169,6 @@ const char UBX_CELL_GNSS_POWER[] = "+UGPS"; // GNSS power mana const char UBX_CELL_GNSS_ASSISTED_IND[] = "+UGIND"; // Assisted GNSS unsolicited indication const char UBX_CELL_GNSS_REQUEST_LOCATION[] = "+ULOC"; // Ask for localization information const char UBX_CELL_GNSS_GPRMC[] = "+UGRMC"; // Ask for localization information -const char UBX_CELL_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) -const char UBX_CELL_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication -const char UBX_CELL_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration const char UBX_CELL_GNSS_CONFIGURE_SENSOR[] = "+ULOCGNSS"; // Configure GNSS sensor const char UBX_CELL_GNSS_CONFIGURE_LOCATION[] = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) const char UBX_CELL_AIDING_SERVER_CONFIGURATION[] = "+UGSRV"; // Configure aiding server (CellLocate®) @@ -728,12 +722,6 @@ class UBX_CELL : public Print uint8_t h, uint8_t min, uint8_t s, int8_t tz); // TZ can be +/- and is in increments of 15 minutes. -28 == 7 hours behind UTC/GMT void autoTimeZoneForBegin(bool enable = true); // Call autoTimeZoneForBegin(false) _before_ .begin if you want to disable the automatic time zone UBX_CELL_error_t autoTimeZone(bool enable); // Enable/disable automatic time zone adjustment - UBX_CELL_error_t setUtimeMode(UBX_CELL_utime_mode_t mode = UBX_CELL_UTIME_MODE_PPS, UBX_CELL_utime_sensor_t sensor = UBX_CELL_UTIME_SENSOR_GNSS_LTE); // Time mode, source etc. (+UTIME) - UBX_CELL_error_t getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor); - UBX_CELL_error_t setUtimeIndication(UBX_CELL_utime_urc_configuration_t config = UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED); // +UTIMEIND - UBX_CELL_error_t getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config); - UBX_CELL_error_t setUtimeConfiguration(int32_t offsetNanoseconds = 0, int32_t offsetSeconds = 0); // +UTIMECFG - UBX_CELL_error_t getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds); // Network service AT commands int8_t rssi(void); // Receive signal strength @@ -951,15 +939,7 @@ class UBX_CELL : public Print UBX_CELL_error_t configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value); UBX_CELL_error_t setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, UBX_CELL_sec_manager_parameter_t parameter, String name, String data); - // Packet Switched Data - // Configure the PDP using +UPSD. See UBX_CELL_pdp_configuration_parameter_t for the list of parameters: protocol, APN, username, DNS, etc. - UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value); // Set parameters in the chosen PSD profile - UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, UBX_CELL_pdp_protocol_type_t value); // Set parameters in the chosen PSD profile - UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, String value); // Set parameters in the chosen PSD profile - UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value); // Set parameters in the chosen PSD profile - UBX_CELL_error_t performPDPaction(int profile, UBX_CELL_pdp_actions_t action); // Performs the requested action for the specified PSD profile: reset, store, load, activate, deactivate UBX_CELL_error_t activatePDPcontext(bool status, int cid = -1); // Activates or deactivates the specified PDP context. Default to all (cid = -1) - UBX_CELL_error_t getNetworkAssignedIPAddress(int profile, IPAddress *address); // Get the dynamic IP address assigned during PDP context activation // GPS typedef enum From 59e9aa7ca5ccdb77b98eec4db46d2cc49c29b199 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 11:02:02 -0700 Subject: [PATCH 21/52] Update definitions of SARA-R5_Arduino_Library.h Should just use macros to not have duplicate definitions Also remove PSD and UTIME definitions due to existence in sara_r5.h --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 191 +++++++++--------- 1 file changed, 93 insertions(+), 98 deletions(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h index 0887158..47e58a4 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -21,6 +21,7 @@ #define SPARKFUN_SARA_R5_ARDUINO_LIBRARY_H #include "sfe_sara_r5.h" +#include "sfe_ublox_cellular.h" #define SARA_R5_POWER_PIN -1 // Default to no pin #define SARA_R5_RESET_PIN -1 @@ -42,125 +43,119 @@ // ## Suported AT Commands // ### General -const char SARA_R5_COMMAND_AT[] = "AT"; // AT "Test" -const char SARA_R5_COMMAND_ECHO[] = "E"; // Local Echo -const char SARA_R5_COMMAND_MANU_ID[] = "+CGMI"; // Manufacturer identification -const char SARA_R5_COMMAND_MODEL_ID[] = "+CGMM"; // Model identification -const char SARA_R5_COMMAND_FW_VER_ID[] = "+CGMR"; // Firmware version identification -const char SARA_R5_COMMAND_SERIAL_NO[] = "+CGSN"; // Product serial number -const char SARA_R5_COMMAND_IMEI[] = "+GSN"; // IMEI identification -const char SARA_R5_COMMAND_IMSI[] = "+CIMI"; // IMSI identification -const char SARA_R5_COMMAND_CCID[] = "+CCID"; // SIM CCID -const char SARA_R5_COMMAND_REQ_CAP[] = "+GCAP"; // Request capabilities list +#define SARA_R5_COMMAND_AT UBX_CELL_COMMAND_AT +#define SARA_R5_COMMAND_ECHO UBX_CELL_COMMAND_ECHO +#define SARA_R5_COMMAND_MANU_ID UBX_CELL_COMMAND_MANU_ID +#define SARA_R5_COMMAND_MODEL_ID UBX_CELL_COMMAND_MODEL_ID +#define SARA_R5_COMMAND_FW_VER_ID UBX_CELL_COMMAND_FW_VER_ID +#define SARA_R5_COMMAND_SERIAL_NO UBX_CELL_COMMAND_SERIAL_NO +#define SARA_R5_COMMAND_IMEI UBX_CELL_COMMAND_IMEI +#define SARA_R5_COMMAND_IMSI UBX_CELL_COMMAND_IMSI +#define SARA_R5_COMMAND_CCID UBX_CELL_COMMAND_CCID +#define SARA_R5_COMMAND_REQ_CAP UBX_CELL_COMMAND_REQ_CAP // ### Control and status -const char SARA_R5_COMMAND_POWER_OFF[] = "+CPWROFF"; // Module switch off -const char SARA_R5_COMMAND_FUNC[] = "+CFUN"; // Functionality (reset, etc.) -const char SARA_R5_COMMAND_CLOCK[] = "+CCLK"; // Real-time clock -const char SARA_R5_COMMAND_AUTO_TZ[] = "+CTZU"; // Automatic time zone update -const char SARA_R5_COMMAND_TZ_REPORT[] = "+CTZR"; // Time zone reporting +#define SARA_R5_COMMAND_POWER_OFF UBX_CELL_COMMAND_POWER_OFF +#define SARA_R5_COMMAND_FUNC UBX_CELL_COMMAND_FUNC +#define SARA_R5_COMMAND_CLOCK UBX_CELL_COMMAND_CLOCK +#define SARA_R5_COMMAND_AUTO_TZ UBX_CELL_COMMAND_AUTO_TZ +#define SARA_R5_COMMAND_TZ_REPORT UBX_CELL_COMMAND_TZ_REPORT // ### Network service -const char SARA_R5_COMMAND_CNUM[] = "+CNUM"; // Subscriber number -const char SARA_R5_SIGNAL_QUALITY[] = "+CSQ"; -const char SARA_R5_EXT_SIGNAL_QUALITY[] = "+CESQ"; -const char SARA_R5_OPERATOR_SELECTION[] = "+COPS"; -const char SARA_R5_REGISTRATION_STATUS[] = "+CREG"; -const char SARA_R5_EPSREGISTRATION_STATUS[] = "+CEREG"; -const char SARA_R5_READ_OPERATOR_NAMES[] = "+COPN"; -const char SARA_R5_COMMAND_MNO[] = "+UMNOPROF"; // MNO (mobile network operator) Profile +#define SARA_R5_COMMAND_CNUM UBX_CELL_COMMAND_CNUM +#define SARA_R5_SIGNAL_QUALITY UBX_CELL_SIGNAL_QUALITY +#define SARA_R5_EXT_SIGNAL_QUALITY UBX_CELL_EXT_SIGNAL_QUALITY +#define SARA_R5_OPERATOR_SELECTION UBX_CELL_OPERATOR_SELECTION +#define SARA_R5_REGISTRATION_STATUS UBX_CELL_REGISTRATION_STATUS +#define SARA_R5_EPSREGISTRATION_STATUS UBX_CELL_EPSREGISTRATION_STATUS +#define SARA_R5_READ_OPERATOR_NAMES UBX_CELL_READ_OPERATOR_NAMES +#define SARA_R5_COMMAND_MNO UBX_CELL_COMMAND_MNO // ### SIM -const char SARA_R5_SIM_STATE[] = "+USIMSTAT"; -const char SARA_R5_COMMAND_SIMPIN[] = "+CPIN"; // SIM PIN +#define SARA_R5_SIM_STATE UBX_CELL_SIM_STATE +#define SARA_R5_COMMAND_SIMPIN UBX_CELL_COMMAND_SIMPIN // ### SMS -const char SARA_R5_MESSAGE_FORMAT[] = "+CMGF"; // Set SMS message format -const char SARA_R5_SEND_TEXT[] = "+CMGS"; // Send SMS message -const char SARA_R5_NEW_MESSAGE_IND[] = "+CNMI"; // New [SMS] message indication -const char SARA_R5_PREF_MESSAGE_STORE[] = "+CPMS"; // Preferred message storage -const char SARA_R5_READ_TEXT_MESSAGE[] = "+CMGR"; // Read message -const char SARA_R5_DELETE_MESSAGE[] = "+CMGD"; // Delete message +#define SARA_R5_MESSAGE_FORMAT UBX_CELL_MESSAGE_FORMAT +#define SARA_R5_SEND_TEXT UBX_CELL_SEND_TEXT +#define SARA_R5_NEW_MESSAGE_IND UBX_CELL_NEW_MESSAGE_IND +#define SARA_R5_PREF_MESSAGE_STORE UBX_CELL_PREF_MESSAGE_STORE +#define SARA_R5_READ_TEXT_MESSAGE UBX_CELL_READ_TEXT_MESSAGE +#define SARA_R5_DELETE_MESSAGE UBX_CELL_DELETE_MESSAGE // V24 control and V25ter (UART interface) -const char SARA_R5_FLOW_CONTROL[] = "&K"; // Flow control -const char SARA_R5_COMMAND_BAUD[] = "+IPR"; // Baud rate +#define SARA_R5_FLOW_CONTROL UBX_CELL_FLOW_CONTROL +#define SARA_R5_COMMAND_BAUD UBX_CELL_COMMAND_BAUD // ### Packet switched data services -const char SARA_R5_MESSAGE_PDP_DEF[] = "+CGDCONT"; // Packet switched Data Profile context definition -const char SARA_R5_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration -const char SARA_R5_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile -const char SARA_R5_MESSAGE_PDP_CONTEXT_ACTIVATE[] = "+CGACT"; // Activates or deactivates the specified PDP context -const char SARA_R5_MESSAGE_ENTER_PPP[] = "D"; -const char SARA_R5_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data +#define SARA_R5_MESSAGE_PDP_DEF UBX_CELL_MESSAGE_PDP_DEF +#define SARA_R5_MESSAGE_PDP_CONTEXT_ACTIVATE UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE +#define SARA_R5_MESSAGE_ENTER_PPP UBX_CELL_MESSAGE_ENTER_PPP // ### GPIO -const char SARA_R5_COMMAND_GPIO[] = "+UGPIOC"; // GPIO Configuration +#define SARA_R5_COMMAND_GPIO UBX_CELL_COMMAND_GPIO // ### IP -const char SARA_R5_CREATE_SOCKET[] = "+USOCR"; // Create a new socket -const char SARA_R5_CLOSE_SOCKET[] = "+USOCL"; // Close a socket -const char SARA_R5_CONNECT_SOCKET[] = "+USOCO"; // Connect to server on socket -const char SARA_R5_WRITE_SOCKET[] = "+USOWR"; // Write data to a socket -const char SARA_R5_WRITE_UDP_SOCKET[] = "+USOST"; // Write data to a UDP socket -const char SARA_R5_READ_SOCKET[] = "+USORD"; // Read from a socket -const char SARA_R5_READ_UDP_SOCKET[] = "+USORF"; // Read UDP data from a socket -const char SARA_R5_LISTEN_SOCKET[] = "+USOLI"; // Listen for connection on socket -const char SARA_R5_GET_ERROR[] = "+USOER"; // Get last socket error. -const char SARA_R5_SOCKET_DIRECT_LINK[] = "+USODL"; // Set socket in Direct Link mode -const char SARA_R5_SOCKET_CONTROL[] = "+USOCTL"; // Query the socket parameters -const char SARA_R5_UD_CONFIGURATION[] = "+UDCONF"; // User Datagram Configuration +#define SARA_R5_CREATE_SOCKET UBX_CELL_CREATE_SOCKET +#define SARA_R5_CLOSE_SOCKET UBX_CELL_CLOSE_SOCKET +#define SARA_R5_CONNECT_SOCKET UBX_CELL_CONNECT_SOCKET +#define SARA_R5_WRITE_SOCKET UBX_CELL_WRITE_SOCKET +#define SARA_R5_WRITE_UDP_SOCKET UBX_CELL_WRITE_UDP_SOCKET +#define SARA_R5_READ_SOCKET UBX_CELL_READ_SOCKET +#define SARA_R5_READ_UDP_SOCKET UBX_CELL_READ_UDP_SOCKET +#define SARA_R5_LISTEN_SOCKET UBX_CELL_LISTEN_SOCKET +#define SARA_R5_GET_ERROR UBX_CELL_GET_ERROR +#define SARA_R5_SOCKET_DIRECT_LINK UBX_CELL_SOCKET_DIRECT_LINK +#define SARA_R5_SOCKET_CONTROL UBX_CELL_SOCKET_CONTROL +#define SARA_R5_UD_CONFIGURATION UBX_CELL_UD_CONFIGURATION // ### Ping -const char SARA_R5_PING_COMMAND[] = "+UPING"; // Ping +#define SARA_R5_PING_COMMAND UBX_CELL_PING_COMMAND // ### HTTP -const char SARA_R5_HTTP_PROFILE[] = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined -const char SARA_R5_HTTP_COMMAND[] = "+UHTTPC"; // Trigger the specified HTTP command -const char SARA_R5_HTTP_PROTOCOL_ERROR[] = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. - -const char SARA_R5_MQTT_NVM[] = "+UMQTTNV"; -const char SARA_R5_MQTT_PROFILE[] = "+UMQTT"; -const char SARA_R5_MQTT_COMMAND[] = "+UMQTTC"; -const char SARA_R5_MQTT_PROTOCOL_ERROR[] = "+UMQTTER"; +#define SARA_R5_HTTP_PROFILE UBX_CELL_HTTP_PROFILE +#define SARA_R5_HTTP_COMMAND UBX_CELL_HTTP_COMMAND +#define SARA_R5_HTTP_PROTOCOL_ERROR UBX_CELL_HTTP_PROTOCOL_ERROR + +#define SARA_R5_MQTT_NVM UBX_CELL_MQTT_NVM +#define SARA_R5_MQTT_PROFILE UBX_CELL_MQTT_PROFILE +#define SARA_R5_MQTT_COMMAND UBX_CELL_MQTT_COMMAND +#define SARA_R5_MQTT_PROTOCOL_ERROR UBX_CELL_MQTT_PROTOCOL_ERROR // ### FTP -const char SARA_R5_FTP_PROFILE[] = "+UFTP"; -const char SARA_R5_FTP_COMMAND[] = "+UFTPC"; -const char SARA_R5_FTP_PROTOCOL_ERROR[] = "+UFTPER"; +#define SARA_R5_FTP_PROFILE UBX_CELL_FTP_PROFILE +#define SARA_R5_FTP_COMMAND UBX_CELL_FTP_COMMAND +#define SARA_R5_FTP_PROTOCOL_ERROR UBX_CELL_FTP_PROTOCOL_ERROR // ### GNSS -const char SARA_R5_GNSS_POWER[] = "+UGPS"; // GNSS power management configuration -const char SARA_R5_GNSS_ASSISTED_IND[] = "+UGIND"; // Assisted GNSS unsolicited indication -const char SARA_R5_GNSS_REQUEST_LOCATION[] = "+ULOC"; // Ask for localization information -const char SARA_R5_GNSS_GPRMC[] = "+UGRMC"; // Ask for localization information -const char SARA_R5_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) -const char SARA_R5_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication -const char SARA_R5_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration -const char SARA_R5_GNSS_CONFIGURE_SENSOR[] = "+ULOCGNSS"; // Configure GNSS sensor -const char SARA_R5_GNSS_CONFIGURE_LOCATION[] = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) -const char SARA_R5_AIDING_SERVER_CONFIGURATION[] = "+UGSRV"; // Configure aiding server (CellLocate®) +#define SARA_R5_GNSS_POWER UBX_CELL_GNSS_POWER +#define SARA_R5_GNSS_ASSISTED_IND UBX_CELL_GNSS_ASSISTED_IND +#define SARA_R5_GNSS_REQUEST_LOCATION UBX_CELL_GNSS_REQUEST_LOCATION +#define SARA_R5_GNSS_GPRMC UBX_CELL_GNSS_GPRMC +#define SARA_R5_GNSS_CONFIGURE_SENSOR UBX_CELL_GNSS_CONFIGURE_SENSOR +#define SARA_R5_GNSS_CONFIGURE_LOCATION UBX_CELL_GNSS_CONFIGURE_LOCATION +#define SARA_R5_AIDING_SERVER_CONFIGURATION UBX_CELL_AIDING_SERVER_CONFIGURATION // ### File System // TO DO: Add support for file tags. Default tag to USER -const char SARA_R5_FILE_SYSTEM_READ_FILE[] = "+URDFILE"; // Read a file -const char SARA_R5_FILE_SYSTEM_READ_BLOCK[] = "+URDBLOCK"; // Read a block from a file -const char SARA_R5_FILE_SYSTEM_DOWNLOAD_FILE[] = "+UDWNFILE"; // Download a file into the module -const char SARA_R5_FILE_SYSTEM_LIST_FILES[] = "+ULSTFILE"; // List of files, size of file, etc. -const char SARA_R5_FILE_SYSTEM_DELETE_FILE[] = "+UDELFILE"; // Delete a file +#define SARA_R5_FILE_SYSTEM_READ_FILE UBX_CELL_FILE_SYSTEM_READ_FILE +#define SARA_R5_FILE_SYSTEM_READ_BLOCK UBX_CELL_FILE_SYSTEM_READ_BLOCK +#define SARA_R5_FILE_SYSTEM_DOWNLOAD_FILE UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE +#define SARA_R5_FILE_SYSTEM_LIST_FILES UBX_CELL_FILE_SYSTEM_LIST_FILES +#define SARA_R5_FILE_SYSTEM_DELETE_FILE UBX_CELL_FILE_SYSTEM_DELETE_FILE // ### File System // TO DO: Add support for file tags. Default tag to USER -const char SARA_R5_SEC_PROFILE[] = "+USECPRF"; -const char SARA_R5_SEC_MANAGER[] = "+USECMNG"; +#define SARA_R5_SEC_PROFILE UBX_CELL_SEC_PROFILE +#define SARA_R5_SEC_MANAGER UBX_CELL_SEC_MANAGER // ### URC strings -const char SARA_R5_READ_SOCKET_URC[] = "+UUSORD:"; -const char SARA_R5_READ_UDP_SOCKET_URC[] = "+UUSORF:"; -const char SARA_R5_LISTEN_SOCKET_URC[] = "+UUSOLI:"; -const char SARA_R5_CLOSE_SOCKET_URC[] = "+UUSOCL:"; -const char SARA_R5_GNSS_REQUEST_LOCATION_URC[] = "+UULOC:"; -const char SARA_R5_SIM_STATE_URC[] = "+UUSIMSTAT:"; -const char SARA_R5_MESSAGE_PDP_ACTION_URC[] = "+UUPSDA:"; -const char SARA_R5_HTTP_COMMAND_URC[] = "+UUHTTPCR:"; -const char SARA_R5_MQTT_COMMAND_URC[] = "+UUMQTTC:"; -const char SARA_R5_PING_COMMAND_URC[] = "+UUPING:"; -const char SARA_R5_REGISTRATION_STATUS_URC[] = "+CREG:"; -const char SARA_R5_EPSREGISTRATION_STATUS_URC[] = "+CEREG:"; -const char SARA_R5_FTP_COMMAND_URC[] = "+UUFTPCR:"; +#define SARA_R5_READ_SOCKET_URC UBX_CELL_READ_SOCKET_URC +#define SARA_R5_READ_UDP_SOCKET_URC UBX_CELL_READ_UDP_SOCKET_URC +#define SARA_R5_LISTEN_SOCKET_URC UBX_CELL_LISTEN_SOCKET_URC +#define SARA_R5_CLOSE_SOCKET_URC UBX_CELL_CLOSE_SOCKET_URC +#define SARA_R5_GNSS_REQUEST_LOCATION_URC UBX_CELL_GNSS_REQUEST_LOCATION_URC +#define SARA_R5_SIM_STATE_URC UBX_CELL_SIM_STATE_URC +#define SARA_R5_MESSAGE_PDP_ACTION_URC UBX_CELL_MESSAGE_PDP_ACTION_URC +#define SARA_R5_HTTP_COMMAND_URC UBX_CELL_HTTP_COMMAND_URC +#define SARA_R5_MQTT_COMMAND_URC UBX_CELL_MQTT_COMMAND_URC +#define SARA_R5_PING_COMMAND_URC UBX_CELL_PING_COMMAND_URC +#define SARA_R5_REGISTRATION_STATUS_URC UBX_CELL_REGISTRATION_STATUS_URC +#define SARA_R5_EPSREGISTRATION_STATUS_URC UBX_CELL_EPSREGISTRATION_STATUS_URC +#define SARA_R5_FTP_COMMAND_URC UBX_CELL_FTP_COMMAND_URC // ### Response -const char SARA_R5_RESPONSE_MORE[] = "\n>"; -const char SARA_R5_RESPONSE_OK[] = "\nOK\r\n"; -const char SARA_R5_RESPONSE_ERROR[] = "\nERROR\r\n"; -const char SARA_R5_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; +#define SARA_R5_RESPONSE_MORE UBX_CELL_RESPONSE_MORE +#define SARA_R5_RESPONSE_OK UBX_CELL_RESPONSE_OK +#define SARA_R5_RESPONSE_ERROR UBX_CELL_RESPONSE_ERROR +#define SARA_R5_RESPONSE_CONNECT UBX_CELL_RESPONSE_CONNECT #define SARA_R5_RESPONSE_OK_OR_ERROR nullptr #define SARA_R5_NUM_SOCKETS 6 From 3c780cd2de379c505975768ed5002edc9de1bdf0 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 15:35:23 -0700 Subject: [PATCH 22/52] Add network and operator examples --- .../Example2_NetworkInfo.ino | 123 +++++++ .../Example3_RegisterOperator.ino | 339 ++++++++++++++++++ 2 files changed, 462 insertions(+) create mode 100644 examples/Example2_NetworkInfo/Example2_NetworkInfo.ino create mode 100644 examples/Example3_RegisterOperator/Example3_RegisterOperator.ino diff --git a/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino b/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino new file mode 100644 index 0000000..6b62f57 --- /dev/null +++ b/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino @@ -0,0 +1,123 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +// Map registration status messages to more readable strings +String registrationString[] = +{ + "Not registered", // 0 + "Registered, home", // 1 + "Searching for operator", // 2 + "Registration denied", // 3 + "Registration unknown", // 4 + "Registered, roaming", // 5 + "Registered, home (SMS only)", // 6 + "Registered, roaming (SMS only)", // 7 + "Registered, emergency service only", // 8 + "Registered, home, CSFB not preferred", // 9 + "Registered, roaming, CSFB not prefered" // 10 +}; + +// If you are based in Europe, you will (probably) need to select MNO_STD_EUROPE +const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL; + +void setup() +{ + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 2 - Network Info")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + if (!myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR)) + { + Serial.println(F("Error setting network. Try cycling the power.")); + while (1) ; + } + + Serial.println(F("Network profile set. Ready to go!")); + + // RSSI: Received signal strength: + Serial.println("RSSI: " + String(myModule.rssi())); + // Registration Status + int regStatus = myModule.registration(); + if ((regStatus >= 0) && (regStatus <= 10)) + { + Serial.println("Network registration: " + registrationString[regStatus]); + } + + // Print the Context IDs, Access Point Names and IP Addresses + Serial.println(F("Available PDP (Packet Data Protocol) APNs (Access Point Names) and IP Addresses:")); + Serial.println(F("Context ID:\tAPN Name:\tIP Address:")); + for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++) + { + String apn = ""; + IPAddress ip(0, 0, 0, 0); + myModule.getAPN(cid, &apn, &ip); + if (apn.length() > 0) + { + Serial.print(cid); + Serial.print(F("\t\t")); + Serial.print(apn); + Serial.print(F("\t")); + Serial.println(ip); + } + } + + Serial.println(); + + if (regStatus > 0) + { + Serial.println(F("All set. Go to the next example!")); + } +} + +void loop() +{ + // Do nothing. Now that we're registered move on to the next example. +} \ No newline at end of file diff --git a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino new file mode 100644 index 0000000..be17034 --- /dev/null +++ b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino @@ -0,0 +1,339 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// UBX_CELL myModule; // Base SARA-R5 class +// UBX_CELL00S myModule; +// UBX_CELL00S_01B myModule; +// UBX_CELL00S_61B myModule; +// UBX_CELL10M8S_61B myModule; +// UBX_CELL10S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +// Map registration status messages to more readable strings +String registrationString[] = +{ + "Not registered", // 0 + "Registered, home", // 1 + "Searching for operator", // 2 + "Registration denied", // 3 + "Registration unknown", // 4 + "Registered, roaming", // 5 + "Registered, home (SMS only)", // 6 + "Registered, roaming (SMS only)", // 7 + "Registered, emergency service only", // 8 + "Registered, home, CSFB not preferred", // 9 + "Registered, roaming, CSFB not prefered" // 10 +}; + +// If you are based in Europe, you will (probably) need to select MNO_STD_EUROPE +const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL; + +const String MOBILE_NETWORK_STRINGS[] = {"default (Undefined/Regulatory)", "SIM ICCID", "AT&T", "Verizon", + "Telstra", "T-Mobile US", "China Telecom", "Sprint", "Vodafone", "NTT DoCoMo", "Telus", "SoftBank", + "Deutsche Telekom", "US Cellular", "SKT", "global (factory default)", "standard Europe", + "standard Europe No-ePCO", "NOT RECOGNIZED"}; + +// Convert the operator number into an index for MOBILE_NETWORK_STRINGS +int convertOperatorNumber( mobile_network_operator_t mno) +{ + switch (mno) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + return ((int)mno); + break; + case 8: + return 7; + break; + case 19: + return 8; + break; + case 20: + return 9; + break; + case 21: + return 10; + break; + case 28: + return 11; + break; + case 31: + return 12; + break; + case 32: + return 13; + break; + case 39: + return 14; + break; + case 90: + return 15; + break; + case 100: + return 16; + break; + case 101: + return 17; + break; + default: // NOT RECOGNIZED + return 18; + break; + } +} + +// This defines the size of the ops struct array. To narrow the operator +// list, set MOBILE_NETWORK_OPERATOR to AT&T, Verizon etc. instead +// of MNO_SW_DEFAULT. +#define MAX_OPERATORS 10 + +// Uncomment this line if you want to be able to communicate directly with the SARA in the main loop +//#define DEBUG_PASSTHROUGH_ENABLED + +void setup() +{ + int opsAvailable; + struct operator_stats ops[MAX_OPERATORS]; + String currentOperator = ""; + bool newConnection = true; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 3 - Register Operator")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're already connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) { + Serial.print(F("Already connected to: ")); + Serial.println(currentOperator); + // If already connected provide the option to type y to connect to new operator + Serial.println(F("Press y to connect to a new operator, or any other key to continue.\r\n")); + while (!Serial.available()) ; + if (Serial.read() != 'y') + { + newConnection = false; + } + else + { + myModule.deregisterOperator(); // Deregister from the current operator so we can connect to a new one + } + while (Serial.available()) Serial.read(); + } + + if (newConnection) { + // Set MNO to either Verizon, T-Mobile, AT&T, Telstra, etc. + // This will narrow the operator options during our scan later + Serial.println(F("Setting mobile-network operator")); + if (myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR)) + { + Serial.print(F("Set mobile network operator to ")); + Serial.println(MOBILE_NETWORK_STRINGS[convertOperatorNumber(MOBILE_NETWORK_OPERATOR)] + "\r\n"); + } + else + { + Serial.println(F("Error setting MNO. Try cycling the power. Freezing...")); + while (1) ; + } + + // Wait for user to press button before initiating network scan. + Serial.println(F("Press any key scan for networks..")); + serialWait(); + + Serial.println(F("Scanning for networks...this may take up to 3 minutes\r\n")); + // myModule.getOperators takes in a operator_stats struct pointer and max number of + // structs to scan for, then fills up those objects with operator names and numbers + opsAvailable = myModule.getOperators(ops, MAX_OPERATORS); // This will block for up to 3 minutes + + if (opsAvailable > 0) + { + // Pretty-print operators we found: + Serial.println("Found " + String(opsAvailable) + " operators:"); + printOperators(ops, opsAvailable); + Serial.println(String(opsAvailable + 1) + ": use automatic selection"); + Serial.println(); + + // Wait until the user presses a key to initiate an operator connection + Serial.println("Press 1-" + String(opsAvailable + 1) + " to select an operator."); + char c = 0; + bool selected = false; + while (!selected) { + while (!Serial.available()) ; + c = Serial.read(); + int selection = c - '0'; + if ((selection >= 1) && (selection <= (opsAvailable + 1))) { + selected = true; + Serial.println("Connecting to option " + String(selection)); + if (selection == (opsAvailable + 1)) + { + if (myModule.automaticOperatorSelection() == UBX_CELL_SUCCESS) + { + Serial.println("Automatic operator selection: successful\r\n"); + } + else + { + Serial.println(F("Automatic operator selection: error. Reset and try again, or try another network.")); + } + } + else + { + if (myModule.registerOperator(ops[selection - 1]) == UBX_CELL_SUCCESS) + { + Serial.println("Network " + ops[selection - 1].longOp + " registered\r\n"); + } + else + { + Serial.println(F("Error connecting to operator. Reset and try again, or try another network.")); + } + } + } + } + } + else + { + Serial.println(F("Did not find an operator. Double-check SIM and antenna, reset and try again, or try another network.")); + while (1) ; + } + } + + // At the very end print connection information + printInfo(); +} + +void loop() +{ + // Loop provides a debugging interface. + if (mySerial.available()) { + Serial.write((char) mySerial.read()); + } +#ifdef DEBUG_PASSTHROUGH_ENABLED + if (Serial.available()) { + mySerial.write((char) Serial.read()); + } +#endif +} + +void printInfo(void) { + String currentApn = ""; + IPAddress ip(0, 0, 0, 0); + String currentOperator = ""; + + Serial.println(F("Connection info:")); + Serial.println(F("Context ID:\tAPN Name:\tIP Address:")); + for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++) + { + String apn = ""; + IPAddress ip(0, 0, 0, 0); + myModule.getAPN(cid, &apn, &ip); + if (apn.length() > 0) + { + Serial.print(cid); + Serial.print(F("\t\t")); + Serial.print(apn); + Serial.print(F("\t")); + Serial.println(ip); + } + } + + // Operator name or number + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Operator: ")); + Serial.println(currentOperator); + } + + // Received signal strength + Serial.println("RSSI: " + String(myModule.rssi())); + Serial.println(); +} + +void printOperators(struct operator_stats * ops, int operatorsAvailable) +{ + for (int i = 0; i < operatorsAvailable; i++) + { + Serial.print(String(i + 1) + ": "); + Serial.print(ops[i].longOp + " (" + String(ops[i].numOp) + ") - "); + switch (ops[i].stat) + { + case 0: + Serial.print(F("UNKNOWN")); + break; + case 1: + Serial.print(F("AVAILABLE")); + break; + case 2: + Serial.print(F("CURRENT")); + break; + case 3: + Serial.print(F("FORBIDDEN")); + break; + } + switch (ops[i].act) + { + case 0: + Serial.print(F(" - GSM")); + break; + case 2: + Serial.print(F(" - UTRAN")); + break; + case 3: + Serial.print(F(" - GSM/GPRS with EDGE")); + break; + case 7: + Serial.print(F(" - LTE")); // SARA-R5 only supports LTE + break; + } + Serial.println(); + } + Serial.println(); +} + +void serialWait() +{ + while (Serial.available()) Serial.read(); + while (!Serial.available()) ; + delay(100); + while (Serial.available()) Serial.read(); +} \ No newline at end of file From 318b3052fcb16eea509c9e249fb7bf515e305de3 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 15:35:58 -0700 Subject: [PATCH 23/52] Add ping example Had to modify ping() from the base class due to LARA-R6 not providing a TTL value --- examples/Example4_Ping/Example4_Ping.ino | 140 +++++++++++++++++++++++ src/sfe_ublox_cellular.cpp | 28 ++++- 2 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 examples/Example4_Ping/Example4_Ping.ino diff --git a/examples/Example4_Ping/Example4_Ping.ino b/examples/Example4_Ping/Example4_Ping.ino new file mode 100644 index 0000000..21cee5d --- /dev/null +++ b/examples/Example4_Ping/Example4_Ping.ino @@ -0,0 +1,140 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// UBX_CELL myModule; // Base SARA-R5 class +// UBX_CELL00S myModule; +// UBX_CELL00S_01B myModule; +// UBX_CELL00S_61B myModule; +// UBX_CELL10M8S_61B myModule; +// UBX_CELL10S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +String pingMe = ""; // The name of the server we are going to ping + +// processPingResult is provided to the SARA-R5 library via a +// callback setter -- setPingCallback. (See the end of setup()) +void processPingResult(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt) +{ + Serial.println(); + Serial.print(F("Ping Result: Retry #:")); + Serial.print(retry); + Serial.print(F(" Ping Size (Bytes):")); + Serial.print(p_size); + Serial.print(F(" Remote Host:\"")); + Serial.print(remote_hostname); + Serial.print(F("\" IP Address:\"")); + Serial.print(String(ip[0])); + Serial.print(F(".")); + Serial.print(String(ip[1])); + Serial.print(F(".")); + Serial.print(String(ip[2])); + Serial.print(F(".")); + Serial.print(String(ip[3])); + Serial.print(F("\" Time To Live (hops):")); + Serial.print(ttl); + Serial.print(F(" Round Trip (ms):")); + Serial.print(rtt); + Serial.println(); +} + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 4 - Ping")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + Serial.println(); + Serial.println(F("*** Set the Serial Monitor line ending to Newline ***")); + + Serial.println(); + Serial.println(F("Enter the name of the server you want to ping (followed by LF / Newline): ")); + Serial.println(F("Example: \"www.google.com\"")); + + // Set a callback to process the Ping result + myModule.setPingCallback(&processPingResult); +} + +void loop() +{ + if (Serial.available()) + { + char c = Serial.read(); + if (c == '\n') + { + // Newline received so let's do that ping! + Serial.println("Pinging " + pingMe + "..."); + myModule.ping(pingMe); // Use the default parameters + + // Use custom parameters + //int retries = 4; // number of retries + //int p_size = 32; // packet size (bytes) + //unsigned long timeout = 5000; // timeout (ms) + //int ttl = 32; // Time To Live + //myModule.ping(pingMe, retries, p_size, timeout, ttl); + + pingMe = ""; // Clear the server name for the next try + } + else + { + // Add serial characters to the server address + pingMe += c; + } + } + + myModule.poll(); // Keep processing data from the SARA so we can catch the Ping result +} \ No newline at end of file diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index 3dd79c8..808244f 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -684,19 +684,37 @@ bool UBX_CELL::processURCEvent(const char *event) if (*searchPtr != '\0') // Make sure we found a quote { + // Extract IP address int remoteIPstore[4]; - scanNum = sscanf(searchPtr, "\",\"%d.%d.%d.%d\",%d,%ld", - &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], &ttl, &rtt); + scanNum = sscanf(searchPtr, "\",\"%d.%d.%d.%d", + &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); for (int i = 0; i <= 3; i++) { remoteIP[i] = (uint8_t)remoteIPstore[i]; } - if (scanNum == 6) // Make sure we extracted enough data + if (scanNum == 4) // Make sure we extracted enough data { - if (_pingRequestCallback != nullptr) + // Extract TTL, should be immediately after IP address + searchPtr = strchr(searchPtr + 2, ','); // +2 to skip the quote and comma + if(searchPtr != nullptr) { - _pingRequestCallback(retry, p_size, remote_host, remoteIP, ttl, rtt); + // It's possible the TTL is not present (eg. on LARA-R6), so we + // can ignore scanNum since ttl defaults to 0 anyways + scanNum = sscanf(searchPtr, ",%d", &ttl); + + // Extract RTT, should be immediately after TTL + searchPtr = strchr(searchPtr + 1, ','); // +1 to skip the comma + if(searchPtr != nullptr) + { + scanNum = sscanf(searchPtr, ",%ld", &rtt); + + // Callback, if it exists + if (_pingRequestCallback != nullptr) + { + _pingRequestCallback(retry, p_size, remote_host, remoteIP, ttl, rtt); + } + } } } } From dc56f1087bc78cb247ff9732352163f8b3dd668e Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 15:36:04 -0700 Subject: [PATCH 24/52] Add SMS examples --- .../Example5_ReceiveSMS.ino | 256 ++++++++++++++++++ .../Example6_SendSMS/Example6_SendSMS.ino | 129 +++++++++ 2 files changed, 385 insertions(+) create mode 100644 examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino create mode 100644 examples/Example6_SendSMS/Example6_SendSMS.ino diff --git a/examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino b/examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino new file mode 100644 index 0000000..88ca78d --- /dev/null +++ b/examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino @@ -0,0 +1,256 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// UBX_CELL myModule; // Base SARA-R5 class +// UBX_CELL00S myModule; +// UBX_CELL00S_01B myModule; +// UBX_CELL00S_61B myModule; +// UBX_CELL10M8S_61B myModule; +// UBX_CELL10S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 5 - Receive SMS")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); +} + +void loop() +{ + static bool printReadMessages = true; // Print all messages once. Then only print new messages. Unless a message is deleted. + static int previousUsed = -1; // Store the previous number of used memory locations + + // Read the number of used and total messages + int used; + int total; + if (myModule.getPreferredMessageStorage(&used, &total) != UBX_CELL_SUCCESS) + { + Serial.println(F("An error occurred when trying to read ME memory!")); + } + else + { + if ((used != previousUsed) || printReadMessages) // Has a new message arrived? Or was the delete menu opened? + { + Serial.print(F("\r\nNumber of used memory locations: ")); + Serial.println(used); + Serial.print(F("Total number of memory locations: ")); + Serial.println(total); + Serial.println(); + + int memoryLocation = 0; + int foundMessages = 0; + // Keep reading until we find all the messages or we reach the end of the memory + while ((foundMessages < used) && (memoryLocation <= total)) + { + String unread = ""; + String from = ""; + String dateTime = ""; + String message = ""; + // Read the message from this location. Reading from empty message locations returns an ERROR + // unread can be: "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT" + // If the location is empty, readSMSmessage will return a UBX_CELL_ERROR_UNEXPECTED_RESPONSE + if (myModule.readSMSmessage(memoryLocation, &unread, &from, &dateTime, &message) == UBX_CELL_SUCCESS) + { + if (printReadMessages || (unread == "REC UNREAD")) + { + Serial.print(F("Message location: ")); + Serial.println(memoryLocation); + Serial.print(F("Status: ")); + Serial.println(unread); + Serial.print(F("Originator: ")); + Serial.println(from); + Serial.print(F("Date and time: ")); + Serial.println(dateTime); + Serial.println(message); + Serial.println(); + } + foundMessages++; // We found a message + } + memoryLocation++; // Move on to the next memory location + } + + printReadMessages = false; + previousUsed = used; // Update previousUsed + + Serial.println(F("Waiting for a new message...")); + Serial.println(); + Serial.println(F("Hit any key to delete a message...")); + Serial.println(); + } + } + + int delayCount = 0; + while (delayCount < 5000) + { + delay(1); // Delay for five seconds, unless the user presses a key + delayCount++; + + if (Serial.available()) + { + Serial.println(F("To delete a single message: enter its location followed by LF / Newline")); + Serial.println(F("To delete all read messages: enter r followed by LF / Newline")); + Serial.println(F("To delete all read and sent messages: enter s followed by LF / Newline")); + Serial.println(F("To delete all read, sent and unsent messages: enter u followed by LF / Newline")); + Serial.println(F("To delete all messages, including unread messages: enter a followed by LF / Newline")); + Serial.println(F("To exit: enter LF / Newline")); + + Serial.read(); // Read and discard the char that opened the menu + + int location = 0; + bool selected = false; + while (!selected) + { + while (!Serial.available()) ; // Wait for a character to arrive + char c = Serial.read(); // Read it + if (c == '\n') // Is it a LF? + { + if ((location >= 1) && (location <= total)) // Delete a single message at location + { + if (myModule.deleteSMSmessage(location) == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nMessage deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessage not deleted!\r\n")); + } + } + else if (location == 1001) // r + { + if (myModule.deleteReadSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nRead messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else if (location == 1002) // s + { + if (myModule.deleteReadSentSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nRead and sent messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else if (location == 1003) // u + { + if (myModule.deleteReadSentUnsentSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nRead, sent and unsent messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else if (location == 1004) // a + { + if (myModule.deleteAllSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nAll messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else + Serial.println(F("\r\nExit...\r\n")); + selected = true; + } + else if ((c >= '0') && (c <= '9')) + { + location *= 10; // Multiply by 10 + location += c - '0'; // Add the digit + } + else if (c == 'r') + { + location = 1001; + } + else if (c == 's') + { + location = 1002; + } + else if (c == 'u') + { + location = 1003; + } + else if (c == 'a') + { + location = 1004; + } + } + + delayCount = 5000; + } + } +} \ No newline at end of file diff --git a/examples/Example6_SendSMS/Example6_SendSMS.ino b/examples/Example6_SendSMS/Example6_SendSMS.ino new file mode 100644 index 0000000..0365c84 --- /dev/null +++ b/examples/Example6_SendSMS/Example6_SendSMS.ino @@ -0,0 +1,129 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// UBX_CELL myModule; // Base SARA-R5 class +// UBX_CELL00S myModule; +// UBX_CELL00S_01B myModule; +// UBX_CELL00S_61B myModule; +// UBX_CELL10M8S_61B myModule; +// UBX_CELL10S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 6 - Send SMS")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + Serial.println(); + Serial.println(F("*** Set the Serial Monitor line ending to Newline ***")); +} + +void loop() +{ + String destinationNumber = ""; + String message = ""; + boolean keepGoing = true; + + Serial.println(); + Serial.println(F("Enter the destination number (followed by LF / Newline): ")); + + while (keepGoing) + { + if (Serial.available()) + { + char c = Serial.read(); + if (c == '\n') + { + keepGoing = false; // Stop if we receive a newline + } + else + { + destinationNumber += c; // Add serial characters to the destination number + } + } + } + + keepGoing = true; + Serial.println(); + Serial.println(F("Enter the message (followed by LF): ")); + + while (keepGoing) + { + if (Serial.available()) + { + char c = Serial.read(); + if (c == '\n') + { + keepGoing = false; // Stop if we receive a newline + } + else + { + message += c; // Add serial characters to the destination number + } + } + } + + // Once we receive a newline, send the text. + Serial.println("Sending: \"" + message + "\" to " + destinationNumber); + // Call myModule.sendSMS(String number, String message) to send an SMS message. + if (myModule.sendSMS(destinationNumber, message) == UBX_CELL_SUCCESS) + { + Serial.println(F("sendSMS was successful")); + } +} \ No newline at end of file From bd91c64605a909573ab347f2c35d0c06c3ec997d Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 15:44:48 -0700 Subject: [PATCH 25/52] Add clock example --- examples/Example7_Clock/Example7_Clock.ino | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 examples/Example7_Clock/Example7_Clock.ino diff --git a/examples/Example7_Clock/Example7_Clock.ino b/examples/Example7_Clock/Example7_Clock.ino new file mode 100644 index 0000000..77eb144 --- /dev/null +++ b/examples/Example7_Clock/Example7_Clock.ino @@ -0,0 +1,80 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// UBX_CELL myModule; // Base SARA-R5 class +// UBX_CELL00S myModule; +// UBX_CELL00S_01B myModule; +// UBX_CELL00S_61B myModule; +// UBX_CELL10M8S_61B myModule; +// UBX_CELL10S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 7 - Clock")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // Make sure automatic time zone updates are enabled + if (myModule.autoTimeZone(true) != UBX_CELL_SUCCESS) + Serial.println(F("Enable autoTimeZone failed!")); + + // Read and print the clock as a String + String theTime = myModule.clock(); + Serial.println(theTime); + + // Read and print the hour, minute, etc. separately + uint8_t year, month, day, hour, minute, second; + int8_t timeZone; + if (myModule.clock( &year, &month, &day, &hour, &minute, &second, &timeZone ) == UBX_CELL_SUCCESS) + // Note: not all Arduino boards implement printf correctly. The formatting may not be correct on some boards. + // Note: the timeZone is defined in 15 minute increments, not hours. -28 indicates the time zone is 7 hours behind UTC/GMT. + Serial.printf("%02d/%02d/%02d %02d:%02d:%02d %+d\r\n", year, month, day, hour, minute, second, timeZone); +} + +void loop() +{ + // Nothing to do here +} \ No newline at end of file From 06a6097d5d98413ef47965801ae72e99c1333cee Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 15:48:42 -0700 Subject: [PATCH 26/52] Fix SARA references in examples --- .../Example3_RegisterOperator.ino | 14 +++++++------- examples/Example4_Ping/Example4_Ping.ino | 18 +++++++++--------- .../Example5_ReceiveSMS.ino | 14 +++++++------- examples/Example6_SendSMS/Example6_SendSMS.ino | 14 +++++++------- examples/Example7_Clock/Example7_Clock.ino | 12 ++++++------ 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino index be17034..df8385b 100644 --- a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino +++ b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino @@ -7,12 +7,12 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example UBX_CELL myModule; // This example works with all modules, so the base class can be used -// UBX_CELL myModule; // Base SARA-R5 class -// UBX_CELL00S myModule; -// UBX_CELL00S_01B myModule; -// UBX_CELL00S_61B myModule; -// UBX_CELL10M8S_61B myModule; -// UBX_CELL10S myModule; +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; // LARA_R6 myModule; // Base LARA-R6 class // LARA_R6001 myModule; // LARA_R6001D myModule; @@ -103,7 +103,7 @@ int convertOperatorNumber( mobile_network_operator_t mno) // of MNO_SW_DEFAULT. #define MAX_OPERATORS 10 -// Uncomment this line if you want to be able to communicate directly with the SARA in the main loop +// Uncomment this line if you want to be able to communicate directly with the module in the main loop //#define DEBUG_PASSTHROUGH_ENABLED void setup() diff --git a/examples/Example4_Ping/Example4_Ping.ino b/examples/Example4_Ping/Example4_Ping.ino index 21cee5d..378fa65 100644 --- a/examples/Example4_Ping/Example4_Ping.ino +++ b/examples/Example4_Ping/Example4_Ping.ino @@ -7,12 +7,12 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example UBX_CELL myModule; // This example works with all modules, so the base class can be used -// UBX_CELL myModule; // Base SARA-R5 class -// UBX_CELL00S myModule; -// UBX_CELL00S_01B myModule; -// UBX_CELL00S_61B myModule; -// UBX_CELL10M8S_61B myModule; -// UBX_CELL10S myModule; +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; // LARA_R6 myModule; // Base LARA-R6 class // LARA_R6001 myModule; // LARA_R6001D myModule; @@ -23,7 +23,7 @@ UBX_CELL myModule; // This example works with all modules, so the base class can String pingMe = ""; // The name of the server we are going to ping -// processPingResult is provided to the SARA-R5 library via a +// processPingResult is provided to the u-blox cellular library via a // callback setter -- setPingCallback. (See the end of setup()) void processPingResult(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt) { @@ -93,7 +93,7 @@ void setup() } else { - Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); while (1) ; // Do nothing more } @@ -136,5 +136,5 @@ void loop() } } - myModule.poll(); // Keep processing data from the SARA so we can catch the Ping result + myModule.poll(); // Keep processing data from the module so we can catch the Ping result } \ No newline at end of file diff --git a/examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino b/examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino index 88ca78d..ca0db60 100644 --- a/examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino +++ b/examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino @@ -7,12 +7,12 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example UBX_CELL myModule; // This example works with all modules, so the base class can be used -// UBX_CELL myModule; // Base SARA-R5 class -// UBX_CELL00S myModule; -// UBX_CELL00S_01B myModule; -// UBX_CELL00S_61B myModule; -// UBX_CELL10M8S_61B myModule; -// UBX_CELL10S myModule; +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; // LARA_R6 myModule; // Base LARA-R6 class // LARA_R6001 myModule; // LARA_R6001D myModule; @@ -65,7 +65,7 @@ void setup() } else { - Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); while (1) ; // Do nothing more } diff --git a/examples/Example6_SendSMS/Example6_SendSMS.ino b/examples/Example6_SendSMS/Example6_SendSMS.ino index 0365c84..b6a0332 100644 --- a/examples/Example6_SendSMS/Example6_SendSMS.ino +++ b/examples/Example6_SendSMS/Example6_SendSMS.ino @@ -7,12 +7,12 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example UBX_CELL myModule; // This example works with all modules, so the base class can be used -// UBX_CELL myModule; // Base SARA-R5 class -// UBX_CELL00S myModule; -// UBX_CELL00S_01B myModule; -// UBX_CELL00S_61B myModule; -// UBX_CELL10M8S_61B myModule; -// UBX_CELL10S myModule; +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; // LARA_R6 myModule; // Base LARA-R6 class // LARA_R6001 myModule; // LARA_R6001D myModule; @@ -65,7 +65,7 @@ void setup() } else { - Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); while (1) ; // Do nothing more } diff --git a/examples/Example7_Clock/Example7_Clock.ino b/examples/Example7_Clock/Example7_Clock.ino index 77eb144..e801981 100644 --- a/examples/Example7_Clock/Example7_Clock.ino +++ b/examples/Example7_Clock/Example7_Clock.ino @@ -7,12 +7,12 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example UBX_CELL myModule; // This example works with all modules, so the base class can be used -// UBX_CELL myModule; // Base SARA-R5 class -// UBX_CELL00S myModule; -// UBX_CELL00S_01B myModule; -// UBX_CELL00S_61B myModule; -// UBX_CELL10M8S_61B myModule; -// UBX_CELL10S myModule; +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; // LARA_R6 myModule; // Base LARA-R6 class // LARA_R6001 myModule; // LARA_R6001D myModule; From c1243bdbaec2c76b05d23b99b799aaaa8dcb0603 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 4 Dec 2023 15:52:45 -0700 Subject: [PATCH 27/52] Renumber examples Clock is very simple, should be before Ping and SMS examples --- .../Example7_Clock.ino => Example4_Clock/Example4_Clock.ino} | 2 +- .../Example4_Ping.ino => Example5_Ping/Example5_Ping.ino} | 2 +- .../Example6_ReceiveSMS.ino} | 2 +- .../Example7_SendSMS.ino} | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename examples/{Example7_Clock/Example7_Clock.ino => Example4_Clock/Example4_Clock.ino} (97%) rename examples/{Example4_Ping/Example4_Ping.ino => Example5_Ping/Example5_Ping.ino} (98%) rename examples/{Example5_ReceiveSMS/Example5_ReceiveSMS.ino => Example6_ReceiveSMS/Example6_ReceiveSMS.ino} (99%) rename examples/{Example6_SendSMS/Example6_SendSMS.ino => Example7_SendSMS/Example7_SendSMS.ino} (98%) diff --git a/examples/Example7_Clock/Example7_Clock.ino b/examples/Example4_Clock/Example4_Clock.ino similarity index 97% rename from examples/Example7_Clock/Example7_Clock.ino rename to examples/Example4_Clock/Example4_Clock.ino index e801981..a7a1b25 100644 --- a/examples/Example7_Clock/Example7_Clock.ino +++ b/examples/Example4_Clock/Example4_Clock.ino @@ -28,7 +28,7 @@ void setup() Serial.begin(115200); // Start the serial console // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 7 - Clock")); + Serial.println(F("u-blox Cellular Example 4 - Clock")); Serial.println(F("Press any key to begin")); while (!Serial.available()) // Wait for the user to press a key (send any serial character) diff --git a/examples/Example4_Ping/Example4_Ping.ino b/examples/Example5_Ping/Example5_Ping.ino similarity index 98% rename from examples/Example4_Ping/Example4_Ping.ino rename to examples/Example5_Ping/Example5_Ping.ino index 378fa65..1de835c 100644 --- a/examples/Example4_Ping/Example4_Ping.ino +++ b/examples/Example5_Ping/Example5_Ping.ino @@ -56,7 +56,7 @@ void setup() Serial.begin(115200); // Start the serial console // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 4 - Ping")); + Serial.println(F("u-blox Cellular Example 5 - Ping")); Serial.println(F("Press any key to begin")); while (!Serial.available()) // Wait for the user to press a key (send any serial character) diff --git a/examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino b/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino similarity index 99% rename from examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino rename to examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino index ca0db60..ae5a336 100644 --- a/examples/Example5_ReceiveSMS/Example5_ReceiveSMS.ino +++ b/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino @@ -28,7 +28,7 @@ void setup() Serial.begin(115200); // Start the serial console // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 5 - Receive SMS")); + Serial.println(F("u-blox Cellular Example 6 - Receive SMS")); Serial.println(F("Press any key to begin")); while (!Serial.available()) // Wait for the user to press a key (send any serial character) diff --git a/examples/Example6_SendSMS/Example6_SendSMS.ino b/examples/Example7_SendSMS/Example7_SendSMS.ino similarity index 98% rename from examples/Example6_SendSMS/Example6_SendSMS.ino rename to examples/Example7_SendSMS/Example7_SendSMS.ino index b6a0332..79bda44 100644 --- a/examples/Example6_SendSMS/Example6_SendSMS.ino +++ b/examples/Example7_SendSMS/Example7_SendSMS.ino @@ -28,7 +28,7 @@ void setup() Serial.begin(115200); // Start the serial console // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 6 - Send SMS")); + Serial.println(F("u-blox Cellular Example 7 - Send SMS")); Serial.println(F("Press any key to begin")); while (!Serial.available()) // Wait for the user to press a key (send any serial character) From 006d2c02523898788310b25491ae003efe75853f Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 11 Dec 2023 15:55:12 -0700 Subject: [PATCH 28/52] Fix PDP and UTIME command prefixes --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 3 ++ src/sfe_sara_r5.cpp | 48 +++++++++---------- src/sfe_sara_r5.h | 12 ++--- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h index 47e58a4..d20383c 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -83,8 +83,11 @@ #define SARA_R5_COMMAND_BAUD UBX_CELL_COMMAND_BAUD // ### Packet switched data services #define SARA_R5_MESSAGE_PDP_DEF UBX_CELL_MESSAGE_PDP_DEF +#define SARA_R5_MESSAGE_PDP_CONFIG UBX_CELL_MESSAGE_PDP_CONFIG +#define SARA_R5_MESSAGE_PDP_ACTION UBX_CELL_MESSAGE_PDP_ACTION #define SARA_R5_MESSAGE_PDP_CONTEXT_ACTIVATE UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE #define SARA_R5_MESSAGE_ENTER_PPP UBX_CELL_MESSAGE_ENTER_PPP +#define SARA_R5_NETWORK_ASSIGNED_DATA UBX_CELL_NETWORK_ASSIGNED_DATA // ### GPIO #define SARA_R5_COMMAND_GPIO UBX_CELL_COMMAND_GPIO // ### IP diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp index ddff46b..0e704b4 100644 --- a/src/sfe_sara_r5.cpp +++ b/src/sfe_sara_r5.cpp @@ -5,13 +5,13 @@ UBX_CELL_error_t SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utim UBX_CELL_error_t err; char *command; - command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_REQUEST_TIME) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (mode == UBX_CELL_UTIME_MODE_STOP) // stop UTIME does not require a sensor - sprintf(command, "%s=%d", SARA_R5_GNSS_REQUEST_TIME, mode); + sprintf(command, "%s=%d", UBX_CELL_GNSS_REQUEST_TIME, mode); else - sprintf(command, "%s=%d,%d", SARA_R5_GNSS_REQUEST_TIME, mode, sensor); + sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_REQUEST_TIME, mode, sensor); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); @@ -28,10 +28,10 @@ UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_uti UBX_CELL_utime_mode_t m; UBX_CELL_utime_sensor_t s; - command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_REQUEST_TIME) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", SARA_R5_GNSS_REQUEST_TIME); + sprintf(command, "%s?", UBX_CELL_GNSS_REQUEST_TIME); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -80,10 +80,10 @@ UBX_CELL_error_t SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t UBX_CELL_error_t err; char *command; - command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_TIME_INDICATION) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", SARA_R5_GNSS_TIME_INDICATION, config); + sprintf(command, "%s=%d", UBX_CELL_GNSS_TIME_INDICATION, config); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -99,10 +99,10 @@ UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t UBX_CELL_utime_urc_configuration_t c; - command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_TIME_INDICATION) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", SARA_R5_GNSS_TIME_INDICATION); + sprintf(command, "%s?", UBX_CELL_GNSS_TIME_INDICATION); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -144,13 +144,13 @@ UBX_CELL_error_t SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32 UBX_CELL_error_t err; char *command; - command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_TIME_CONFIGURATION) + 48); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - sprintf(command, "%s=%d,%d", SARA_R5_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); + sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); #else - sprintf(command, "%s=%ld,%ld", SARA_R5_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); + sprintf(command, "%s=%ld,%ld", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); #endif err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, @@ -168,10 +168,10 @@ UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int3 int32_t ons; int32_t os; - command = ubx_cell_calloc_char(strlen(SARA_R5_GNSS_TIME_CONFIGURATION) + 2); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", SARA_R5_GNSS_TIME_CONFIGURATION); + sprintf(command, "%s?", UBX_CELL_GNSS_TIME_CONFIGURATION); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -220,10 +220,10 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(SARA_R5_MESSAGE_PDP_CONFIG) + 24); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", SARA_R5_MESSAGE_PDP_CONFIG, profile, parameter, + sprintf(command, "%s=%d,%d,%d", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, @@ -246,10 +246,10 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(SARA_R5_MESSAGE_PDP_CONFIG) + 64); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", SARA_R5_MESSAGE_PDP_CONFIG, profile, parameter, + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, @@ -267,10 +267,10 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(SARA_R5_MESSAGE_PDP_CONFIG) + 64); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", SARA_R5_MESSAGE_PDP_CONFIG, profile, parameter, + sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value[0], value[1], value[2], value[3]); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, @@ -288,10 +288,10 @@ UBX_CELL_error_t SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t a if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(SARA_R5_MESSAGE_PDP_ACTION) + 32); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", SARA_R5_MESSAGE_PDP_ACTION, profile, action); + sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_ACTION, profile, action); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -310,10 +310,10 @@ UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *ad int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation int paramVals[4]; - command = ubx_cell_calloc_char(strlen(SARA_R5_NETWORK_ASSIGNED_DATA) + 16); + command = ubx_cell_calloc_char(strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", SARA_R5_NETWORK_ASSIGNED_DATA, profile, paramTag); + sprintf(command, "%s=%d,%d", UBX_CELL_NETWORK_ASSIGNED_DATA, profile, paramTag); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index 6896950..87cec80 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -3,12 +3,12 @@ #include "sfe_ublox_cellular.h" -const char SARA_R5_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration -const char SARA_R5_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile -const char SARA_R5_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data -const char SARA_R5_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) -const char SARA_R5_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication -const char SARA_R5_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration +const char UBX_CELL_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration +const char UBX_CELL_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile +const char UBX_CELL_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data +const char UBX_CELL_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) +const char UBX_CELL_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication +const char UBX_CELL_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration // Base SARA-R5 class class SARA_R5: public UBX_CELL From 8161600f0aba81322ee8e36169e3f3359daafe1b Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 11 Dec 2023 15:58:46 -0700 Subject: [PATCH 29/52] Add missing AT commands from SARA-R5 old lib --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h index d20383c..eb9a620 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -123,6 +123,9 @@ #define SARA_R5_GNSS_ASSISTED_IND UBX_CELL_GNSS_ASSISTED_IND #define SARA_R5_GNSS_REQUEST_LOCATION UBX_CELL_GNSS_REQUEST_LOCATION #define SARA_R5_GNSS_GPRMC UBX_CELL_GNSS_GPRMC +#define SARA_R5_GNSS_REQUEST_TIME UBX_CELL_GNSS_REQUEST_TIME +#define SARA_R5_GNSS_TIME_INDICATION UBX_CELL_GNSS_TIME_INDICATION +#define SARA_R5_GNSS_TIME_CONFIGURATION UBX_CELL_GNSS_TIME_CONFIGURATION #define SARA_R5_GNSS_CONFIGURE_SENSOR UBX_CELL_GNSS_CONFIGURE_SENSOR #define SARA_R5_GNSS_CONFIGURE_LOCATION UBX_CELL_GNSS_CONFIGURE_LOCATION #define SARA_R5_AIDING_SERVER_CONFIGURATION UBX_CELL_AIDING_SERVER_CONFIGURATION From 888284d74b121a3b3d3a595aedf190f4700039c3 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 11 Dec 2023 16:10:01 -0700 Subject: [PATCH 30/52] Redefine string pointers for AT commands and such --- src/sfe_sara_r5.h | 12 +-- src/sfe_ublox_cellular.h | 184 ++++++++++++++++----------------- src/sfe_ublox_cellular_voice.h | 12 +-- 3 files changed, 104 insertions(+), 104 deletions(-) diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index 87cec80..c719227 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -3,12 +3,12 @@ #include "sfe_ublox_cellular.h" -const char UBX_CELL_MESSAGE_PDP_CONFIG[] = "+UPSD"; // Packet switched Data Profile configuration -const char UBX_CELL_MESSAGE_PDP_ACTION[] = "+UPSDA"; // Perform the action for the specified PSD profile -const char UBX_CELL_NETWORK_ASSIGNED_DATA[] = "+UPSND"; // Packet switched network-assigned data -const char UBX_CELL_GNSS_REQUEST_TIME[] = "+UTIME"; // Ask for time information from cellular modem (CellTime) -const char UBX_CELL_GNSS_TIME_INDICATION[] = "+UTIMEIND"; // Time information request status unsolicited indication -const char UBX_CELL_GNSS_TIME_CONFIGURATION[] = "+UTIMECFG"; // Sets time configuration +const char* const UBX_CELL_MESSAGE_PDP_CONFIG = "+UPSD"; // Packet switched Data Profile configuration +const char* const UBX_CELL_MESSAGE_PDP_ACTION = "+UPSDA"; // Perform the action for the specified PSD profile +const char* const UBX_CELL_NETWORK_ASSIGNED_DATA = "+UPSND"; // Packet switched network-assigned data +const char* const UBX_CELL_GNSS_REQUEST_TIME = "+UTIME"; // Ask for time information from cellular modem (CellTime) +const char* const UBX_CELL_GNSS_TIME_INDICATION = "+UTIMEIND"; // Time information request status unsolicited indication +const char* const UBX_CELL_GNSS_TIME_CONFIGURATION = "+UTIMECFG"; // Sets time configuration // Base SARA-R5 class class SARA_R5: public UBX_CELL diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index b2f74d9..8f2f224 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -92,119 +92,119 @@ // ## Suported AT Commands // ### General -const char UBX_CELL_COMMAND_AT[] = "AT"; // AT "Test" -const char UBX_CELL_COMMAND_ECHO[] = "E"; // Local Echo -const char UBX_CELL_COMMAND_MANU_ID[] = "+CGMI"; // Manufacturer identification -const char UBX_CELL_COMMAND_MODEL_ID[] = "+CGMM"; // Model identification -const char UBX_CELL_COMMAND_FW_VER_ID[] = "+CGMR"; // Firmware version identification -const char UBX_CELL_COMMAND_SERIAL_NO[] = "+CGSN"; // Product serial number -const char UBX_CELL_COMMAND_IMEI[] = "+GSN"; // IMEI identification -const char UBX_CELL_COMMAND_IMSI[] = "+CIMI"; // IMSI identification -const char UBX_CELL_COMMAND_CCID[] = "+CCID"; // SIM CCID -const char UBX_CELL_COMMAND_REQ_CAP[] = "+GCAP"; // Request capabilities list +const char* const UBX_CELL_COMMAND_AT = "AT"; // AT "Test" +const char* const UBX_CELL_COMMAND_ECHO = "E"; // Local Echo +const char* const UBX_CELL_COMMAND_MANU_ID = "+CGMI"; // Manufacturer identification +const char* const UBX_CELL_COMMAND_MODEL_ID = "+CGMM"; // Model identification +const char* const UBX_CELL_COMMAND_FW_VER_ID = "+CGMR"; // Firmware version identification +const char* const UBX_CELL_COMMAND_SERIAL_NO = "+CGSN"; // Product serial number +const char* const UBX_CELL_COMMAND_IMEI = "+GSN"; // IMEI identification +const char* const UBX_CELL_COMMAND_IMSI = "+CIMI"; // IMSI identification +const char* const UBX_CELL_COMMAND_CCID = "+CCID"; // SIM CCID +const char* const UBX_CELL_COMMAND_REQ_CAP = "+GCAP"; // Request capabilities list // ### Control and status -const char UBX_CELL_COMMAND_POWER_OFF[] = "+CPWROFF"; // Module switch off -const char UBX_CELL_COMMAND_FUNC[] = "+CFUN"; // Functionality (reset, etc.) -const char UBX_CELL_COMMAND_CLOCK[] = "+CCLK"; // Real-time clock -const char UBX_CELL_COMMAND_AUTO_TZ[] = "+CTZU"; // Automatic time zone update -const char UBX_CELL_COMMAND_TZ_REPORT[] = "+CTZR"; // Time zone reporting +const char* const UBX_CELL_COMMAND_POWER_OFF = "+CPWROFF"; // Module switch off +const char* const UBX_CELL_COMMAND_FUNC = "+CFUN"; // Functionality (reset, etc.) +const char* const UBX_CELL_COMMAND_CLOCK = "+CCLK"; // Real-time clock +const char* const UBX_CELL_COMMAND_AUTO_TZ = "+CTZU"; // Automatic time zone update +const char* const UBX_CELL_COMMAND_TZ_REPORT = "+CTZR"; // Time zone reporting // ### Network service -const char UBX_CELL_COMMAND_CNUM[] = "+CNUM"; // Subscriber number -const char UBX_CELL_SIGNAL_QUALITY[] = "+CSQ"; -const char UBX_CELL_EXT_SIGNAL_QUALITY[] = "+CESQ"; -const char UBX_CELL_OPERATOR_SELECTION[] = "+COPS"; -const char UBX_CELL_REGISTRATION_STATUS[] = "+CREG"; -const char UBX_CELL_EPSREGISTRATION_STATUS[] = "+CEREG"; -const char UBX_CELL_READ_OPERATOR_NAMES[] = "+COPN"; -const char UBX_CELL_COMMAND_MNO[] = "+UMNOPROF"; // MNO (mobile network operator) Profile +const char* const UBX_CELL_COMMAND_CNUM = "+CNUM"; // Subscriber number +const char* const UBX_CELL_SIGNAL_QUALITY = "+CSQ"; +const char* const UBX_CELL_EXT_SIGNAL_QUALITY = "+CESQ"; +const char* const UBX_CELL_OPERATOR_SELECTION = "+COPS"; +const char* const UBX_CELL_REGISTRATION_STATUS = "+CREG"; +const char* const UBX_CELL_EPSREGISTRATION_STATUS = "+CEREG"; +const char* const UBX_CELL_READ_OPERATOR_NAMES = "+COPN"; +const char* const UBX_CELL_COMMAND_MNO = "+UMNOPROF"; // MNO (mobile network operator) Profile // ### SIM -const char UBX_CELL_SIM_STATE[] = "+USIMSTAT"; -const char UBX_CELL_COMMAND_SIMPIN[] = "+CPIN"; // SIM PIN +const char* const UBX_CELL_SIM_STATE = "+USIMSTAT"; +const char* const UBX_CELL_COMMAND_SIMPIN = "+CPIN"; // SIM PIN // ### SMS -const char UBX_CELL_MESSAGE_FORMAT[] = "+CMGF"; // Set SMS message format -const char UBX_CELL_SEND_TEXT[] = "+CMGS"; // Send SMS message -const char UBX_CELL_NEW_MESSAGE_IND[] = "+CNMI"; // New [SMS] message indication -const char UBX_CELL_PREF_MESSAGE_STORE[] = "+CPMS"; // Preferred message storage -const char UBX_CELL_READ_TEXT_MESSAGE[] = "+CMGR"; // Read message -const char UBX_CELL_DELETE_MESSAGE[] = "+CMGD"; // Delete message +const char* const UBX_CELL_MESSAGE_FORMAT = "+CMGF"; // Set SMS message format +const char* const UBX_CELL_SEND_TEXT = "+CMGS"; // Send SMS message +const char* const UBX_CELL_NEW_MESSAGE_IND = "+CNMI"; // New [SMS] message indication +const char* const UBX_CELL_PREF_MESSAGE_STORE = "+CPMS"; // Preferred message storage +const char* const UBX_CELL_READ_TEXT_MESSAGE = "+CMGR"; // Read message +const char* const UBX_CELL_DELETE_MESSAGE = "+CMGD"; // Delete message // V24 control and V25ter (UART interface) -const char UBX_CELL_FLOW_CONTROL[] = "&K"; // Flow control -const char UBX_CELL_COMMAND_BAUD[] = "+IPR"; // Baud rate +const char* const UBX_CELL_FLOW_CONTROL = "&K"; // Flow control +const char* const UBX_CELL_COMMAND_BAUD = "+IPR"; // Baud rate // ### Packet switched data services -const char UBX_CELL_MESSAGE_PDP_DEF[] = "+CGDCONT"; // Packet switched Data Profile context definition -const char UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE[] = "+CGACT"; // Activates or deactivates the specified PDP context -const char UBX_CELL_MESSAGE_ENTER_PPP[] = "D"; +const char* const UBX_CELL_MESSAGE_PDP_DEF = "+CGDCONT"; // Packet switched Data Profile context definition +const char* const UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE = "+CGACT"; // Activates or deactivates the specified PDP context +const char* const UBX_CELL_MESSAGE_ENTER_PPP = "D"; // ### GPIO -const char UBX_CELL_COMMAND_GPIO[] = "+UGPIOC"; // GPIO Configuration +const char* const UBX_CELL_COMMAND_GPIO = "+UGPIOC"; // GPIO Configuration // ### IP -const char UBX_CELL_CREATE_SOCKET[] = "+USOCR"; // Create a new socket -const char UBX_CELL_CLOSE_SOCKET[] = "+USOCL"; // Close a socket -const char UBX_CELL_CONNECT_SOCKET[] = "+USOCO"; // Connect to server on socket -const char UBX_CELL_WRITE_SOCKET[] = "+USOWR"; // Write data to a socket -const char UBX_CELL_WRITE_UDP_SOCKET[] = "+USOST"; // Write data to a UDP socket -const char UBX_CELL_READ_SOCKET[] = "+USORD"; // Read from a socket -const char UBX_CELL_READ_UDP_SOCKET[] = "+USORF"; // Read UDP data from a socket -const char UBX_CELL_LISTEN_SOCKET[] = "+USOLI"; // Listen for connection on socket -const char UBX_CELL_GET_ERROR[] = "+USOER"; // Get last socket error. -const char UBX_CELL_SOCKET_DIRECT_LINK[] = "+USODL"; // Set socket in Direct Link mode -const char UBX_CELL_SOCKET_CONTROL[] = "+USOCTL"; // Query the socket parameters -const char UBX_CELL_UD_CONFIGURATION[] = "+UDCONF"; // User Datagram Configuration +const char* const UBX_CELL_CREATE_SOCKET = "+USOCR"; // Create a new socket +const char* const UBX_CELL_CLOSE_SOCKET = "+USOCL"; // Close a socket +const char* const UBX_CELL_CONNECT_SOCKET = "+USOCO"; // Connect to server on socket +const char* const UBX_CELL_WRITE_SOCKET = "+USOWR"; // Write data to a socket +const char* const UBX_CELL_WRITE_UDP_SOCKET = "+USOST"; // Write data to a UDP socket +const char* const UBX_CELL_READ_SOCKET = "+USORD"; // Read from a socket +const char* const UBX_CELL_READ_UDP_SOCKET = "+USORF"; // Read UDP data from a socket +const char* const UBX_CELL_LISTEN_SOCKET = "+USOLI"; // Listen for connection on socket +const char* const UBX_CELL_GET_ERROR = "+USOER"; // Get last socket error. +const char* const UBX_CELL_SOCKET_DIRECT_LINK = "+USODL"; // Set socket in Direct Link mode +const char* const UBX_CELL_SOCKET_CONTROL = "+USOCTL"; // Query the socket parameters +const char* const UBX_CELL_UD_CONFIGURATION = "+UDCONF"; // User Datagram Configuration // ### Ping -const char UBX_CELL_PING_COMMAND[] = "+UPING"; // Ping +const char* const UBX_CELL_PING_COMMAND = "+UPING"; // Ping // ### HTTP -const char UBX_CELL_HTTP_PROFILE[] = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined -const char UBX_CELL_HTTP_COMMAND[] = "+UHTTPC"; // Trigger the specified HTTP command -const char UBX_CELL_HTTP_PROTOCOL_ERROR[] = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. - -const char UBX_CELL_MQTT_NVM[] = "+UMQTTNV"; -const char UBX_CELL_MQTT_PROFILE[] = "+UMQTT"; -const char UBX_CELL_MQTT_COMMAND[] = "+UMQTTC"; -const char UBX_CELL_MQTT_PROTOCOL_ERROR[] = "+UMQTTER"; +const char* const UBX_CELL_HTTP_PROFILE = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined +const char* const UBX_CELL_HTTP_COMMAND = "+UHTTPC"; // Trigger the specified HTTP command +const char* const UBX_CELL_HTTP_PROTOCOL_ERROR = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. + +const char* const UBX_CELL_MQTT_NVM = "+UMQTTNV"; +const char* const UBX_CELL_MQTT_PROFILE = "+UMQTT"; +const char* const UBX_CELL_MQTT_COMMAND = "+UMQTTC"; +const char* const UBX_CELL_MQTT_PROTOCOL_ERROR = "+UMQTTER"; // ### FTP -const char UBX_CELL_FTP_PROFILE[] = "+UFTP"; -const char UBX_CELL_FTP_COMMAND[] = "+UFTPC"; -const char UBX_CELL_FTP_PROTOCOL_ERROR[] = "+UFTPER"; +const char* const UBX_CELL_FTP_PROFILE = "+UFTP"; +const char* const UBX_CELL_FTP_COMMAND = "+UFTPC"; +const char* const UBX_CELL_FTP_PROTOCOL_ERROR = "+UFTPER"; // ### GNSS -const char UBX_CELL_GNSS_POWER[] = "+UGPS"; // GNSS power management configuration -const char UBX_CELL_GNSS_ASSISTED_IND[] = "+UGIND"; // Assisted GNSS unsolicited indication -const char UBX_CELL_GNSS_REQUEST_LOCATION[] = "+ULOC"; // Ask for localization information -const char UBX_CELL_GNSS_GPRMC[] = "+UGRMC"; // Ask for localization information -const char UBX_CELL_GNSS_CONFIGURE_SENSOR[] = "+ULOCGNSS"; // Configure GNSS sensor -const char UBX_CELL_GNSS_CONFIGURE_LOCATION[] = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) -const char UBX_CELL_AIDING_SERVER_CONFIGURATION[] = "+UGSRV"; // Configure aiding server (CellLocate®) +const char* const UBX_CELL_GNSS_POWER = "+UGPS"; // GNSS power management configuration +const char* const UBX_CELL_GNSS_ASSISTED_IND = "+UGIND"; // Assisted GNSS unsolicited indication +const char* const UBX_CELL_GNSS_REQUEST_LOCATION = "+ULOC"; // Ask for localization information +const char* const UBX_CELL_GNSS_GPRMC = "+UGRMC"; // Ask for localization information +const char* const UBX_CELL_GNSS_CONFIGURE_SENSOR = "+ULOCGNSS"; // Configure GNSS sensor +const char* const UBX_CELL_GNSS_CONFIGURE_LOCATION = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) +const char* const UBX_CELL_AIDING_SERVER_CONFIGURATION = "+UGSRV"; // Configure aiding server (CellLocate®) // ### File System // TO DO: Add support for file tags. Default tag to USER -const char UBX_CELL_FILE_SYSTEM_READ_FILE[] = "+URDFILE"; // Read a file -const char UBX_CELL_FILE_SYSTEM_READ_BLOCK[] = "+URDBLOCK"; // Read a block from a file -const char UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE[] = "+UDWNFILE"; // Download a file into the module -const char UBX_CELL_FILE_SYSTEM_LIST_FILES[] = "+ULSTFILE"; // List of files, size of file, etc. -const char UBX_CELL_FILE_SYSTEM_DELETE_FILE[] = "+UDELFILE"; // Delete a file +const char* const UBX_CELL_FILE_SYSTEM_READ_FILE = "+URDFILE"; // Read a file +const char* const UBX_CELL_FILE_SYSTEM_READ_BLOCK = "+URDBLOCK"; // Read a block from a file +const char* const UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE = "+UDWNFILE"; // Download a file into the module +const char* const UBX_CELL_FILE_SYSTEM_LIST_FILES = "+ULSTFILE"; // List of files, size of file, etc. +const char* const UBX_CELL_FILE_SYSTEM_DELETE_FILE = "+UDELFILE"; // Delete a file // ### File System // TO DO: Add support for file tags. Default tag to USER -const char UBX_CELL_SEC_PROFILE[] = "+USECPRF"; -const char UBX_CELL_SEC_MANAGER[] = "+USECMNG"; +const char* const UBX_CELL_SEC_PROFILE = "+USECPRF"; +const char* const UBX_CELL_SEC_MANAGER = "+USECMNG"; // ### URC strings -const char UBX_CELL_READ_SOCKET_URC[] = "+UUSORD:"; -const char UBX_CELL_READ_UDP_SOCKET_URC[] = "+UUSORF:"; -const char UBX_CELL_LISTEN_SOCKET_URC[] = "+UUSOLI:"; -const char UBX_CELL_CLOSE_SOCKET_URC[] = "+UUSOCL:"; -const char UBX_CELL_GNSS_REQUEST_LOCATION_URC[] = "+UULOC:"; -const char UBX_CELL_SIM_STATE_URC[] = "+UUSIMSTAT:"; -const char UBX_CELL_MESSAGE_PDP_ACTION_URC[] = "+UUPSDA:"; -const char UBX_CELL_HTTP_COMMAND_URC[] = "+UUHTTPCR:"; -const char UBX_CELL_MQTT_COMMAND_URC[] = "+UUMQTTC:"; -const char UBX_CELL_PING_COMMAND_URC[] = "+UUPING:"; -const char UBX_CELL_REGISTRATION_STATUS_URC[] = "+CREG:"; -const char UBX_CELL_EPSREGISTRATION_STATUS_URC[] = "+CEREG:"; -const char UBX_CELL_FTP_COMMAND_URC[] = "+UUFTPCR:"; +const char* const UBX_CELL_READ_SOCKET_URC = "+UUSORD:"; +const char* const UBX_CELL_READ_UDP_SOCKET_URC = "+UUSORF:"; +const char* const UBX_CELL_LISTEN_SOCKET_URC = "+UUSOLI:"; +const char* const UBX_CELL_CLOSE_SOCKET_URC = "+UUSOCL:"; +const char* const UBX_CELL_GNSS_REQUEST_LOCATION_URC = "+UULOC:"; +const char* const UBX_CELL_SIM_STATE_URC = "+UUSIMSTAT:"; +const char* const UBX_CELL_MESSAGE_PDP_ACTION_URC = "+UUPSDA:"; +const char* const UBX_CELL_HTTP_COMMAND_URC = "+UUHTTPCR:"; +const char* const UBX_CELL_MQTT_COMMAND_URC = "+UUMQTTC:"; +const char* const UBX_CELL_PING_COMMAND_URC = "+UUPING:"; +const char* const UBX_CELL_REGISTRATION_STATUS_URC = "+CREG:"; +const char* const UBX_CELL_EPSREGISTRATION_STATUS_URC = "+CEREG:"; +const char* const UBX_CELL_FTP_COMMAND_URC = "+UUFTPCR:"; // ### Response -const char UBX_CELL_RESPONSE_MORE[] = "\n>"; -const char UBX_CELL_RESPONSE_OK[] = "\nOK\r\n"; -const char UBX_CELL_RESPONSE_ERROR[] = "\nERROR\r\n"; -const char UBX_CELL_RESPONSE_CONNECT[] = "\r\nCONNECT\r\n"; +const char* const UBX_CELL_RESPONSE_MORE = "\n>"; +const char* const UBX_CELL_RESPONSE_OK = "\nOK\r\n"; +const char* const UBX_CELL_RESPONSE_ERROR = "\nERROR\r\n"; +const char* const UBX_CELL_RESPONSE_CONNECT = "\r\nCONNECT\r\n"; #define UBX_CELL_RESPONSE_OK_OR_ERROR nullptr // CTRL+Z and ESC ASCII codes for SMS message sends diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index 46caa65..0e291dd 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -3,12 +3,12 @@ #include "sfe_ublox_cellular.h" -const char UBX_CELL_COMMAND_DIAL[] = "D"; // Dial command -const char UBX_CELL_COMMAND_ANSWER[] = "A"; // Answer call -const char UBX_CELL_COMMAND_HANG_UP[] = "+CHUP"; // Hang up call -const char UBX_CELL_COMMAND_PLAY_AUDIO[] = "+UPAR"; // Play audio resource -const char UBX_CELL_COMMAND_STOP_AUDIO[] = "+USAR"; // Stop audio resource -const char UBX_CELL_COMMAND_GENERATE_TONE[] = "+UTGN"; // Tone generator +const char* const UBX_CELL_COMMAND_DIAL = "D"; // Dial command +const char* const UBX_CELL_COMMAND_ANSWER = "A"; // Answer call +const char* const UBX_CELL_COMMAND_HANG_UP = "+CHUP"; // Hang up call +const char* const UBX_CELL_COMMAND_PLAY_AUDIO = "+UPAR"; // Play audio resource +const char* const UBX_CELL_COMMAND_STOP_AUDIO = "+USAR"; // Stop audio resource +const char* const UBX_CELL_COMMAND_GENERATE_TONE = "+UTGN"; // Tone generator // Base class for any modules supporting voice calls template From 8ea8b8476721b929bf1575e3636dc83721eb75a3 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 11 Dec 2023 17:05:18 -0700 Subject: [PATCH 31/52] Create base voice class Allows us to use a single base class in audio examples instead of a specific module Need to update name at some point as part of #9, it's not clear if UBX_CELL_VOICE or UBX_CELL_VOICE_BASE should be used based on the names alone --- src/SparkFun_u-blox_Cellular_Arduino_Library.h | 1 + src/sfe_ublox_cellular_voice.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/SparkFun_u-blox_Cellular_Arduino_Library.h b/src/SparkFun_u-blox_Cellular_Arduino_Library.h index a5b2243..96e8cd8 100644 --- a/src/SparkFun_u-blox_Cellular_Arduino_Library.h +++ b/src/SparkFun_u-blox_Cellular_Arduino_Library.h @@ -1,3 +1,4 @@ #include "sfe_ublox_cellular.h" +#include "sfe_ublox_cellular_voice.h" #include "sfe_sara_r5.h" #include "sfe_lara_r6.h" diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index 0e291dd..01b7627 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -127,4 +127,9 @@ class UBX_CELL_VOICE } }; +class UBX_CELL_VOICE_BASE : public UBX_CELL, public UBX_CELL_VOICE +{ + +}; + #endif \ No newline at end of file From 80ee412641359679ecc6a7a58f6a260c981887fe Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 11 Dec 2023 17:06:21 -0700 Subject: [PATCH 32/52] Create audio example 1 --- .../Audio_Example1_Play_Tone.ino | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino diff --git a/examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino b/examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino new file mode 100644 index 0000000..df08d23 --- /dev/null +++ b/examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino @@ -0,0 +1,120 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL_VOICE_BASE myModule; // This example works with all voice-enabled modules, so this base class can be used +// LARA_R6001 myModule; +// LARA_R6401 myModule; +// LARA_R6801_00B myModule; + +void setup() +{ + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Audio Example 1 - Play Tone")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); +} + +void loop() +{ + String inputString; + char dtmfChar = 0; + uint16_t frequency = 0; + uint16_t duration = 0; + uint8_t volume = 0; + + while(true) + { + while(Serial.available() != 0){Serial.read();} + Serial.println(F("Enter a frequency in Hz (300-3400) or a DTMF character (0-9, *, #)")); + while(Serial.available() == 0){} + + inputString = Serial.readStringUntil('\n'); + + if(inputString.length() == 1) + { + dtmfChar = inputString.charAt(0); + if((dtmfChar >= '0' && dtmfChar <= '9') || dtmfChar == '*' || dtmfChar == '#') + { + break; + } + } + else + { + frequency = inputString.toInt(); + if(frequency >= 300 && frequency <= 3400) + { + dtmfChar == 0; + break; + } + } + } + + while(true) + { + while(Serial.available() != 0){Serial.read();} + Serial.println(F("Enter a duration in ms (50-1360)")); + while(Serial.available() == 0){} + + inputString = Serial.readStringUntil('\n'); + duration = inputString.toInt(); + if(duration >= 50 && duration <= 1360) + { + break; + } + } + + while(true) + { + while(Serial.available() != 0){Serial.read();} + Serial.println(F("Enter a volume (0-100)")); + while(Serial.available() == 0){} + + inputString = Serial.readStringUntil('\n'); + volume = inputString.toInt(); + if(volume <= 100) + { + break; + } + } + + if(dtmfChar == 0) + { + myModule.generateToneFreq(frequency, duration, volume); + } + else + { + myModule.generateToneDTMF(dtmfChar, duration, volume); + } +} \ No newline at end of file From 9b7a8bc05990b97a1fa6d3c33c37f24b8f45d5be Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 11 Dec 2023 17:13:53 -0700 Subject: [PATCH 33/52] Add note to audio example about needing a codec --- .../Audio_Example1_Play_Tone.ino | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino b/examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino index df08d23..a6cc09c 100644 --- a/examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino +++ b/examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino @@ -17,6 +17,15 @@ void setup() // Wait for user to press key to begin Serial.println(F("u-blox Cellular Audio Example 1 - Play Tone")); + + Serial.println(); + Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(F("This example requires an audio codec attached to the I2S interface")); + Serial.println(F("of the cellular modem. Please add one and update this example as")); + Serial.println(F("needed to configure your audio codec!")); + Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(); + Serial.println(F("Press any key to begin")); while (!Serial.available()) // Wait for the user to press a key (send any serial character) From 1c0007ae7fda882a725008741f1a5ad9fff450c4 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Tue, 12 Dec 2023 09:54:27 -0700 Subject: [PATCH 34/52] Rename audio example 1 to match conventions --- .../AudioExample1_PlayTone.ino} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/Audio_Examples/{Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino => AudioExample1_PlayTone/AudioExample1_PlayTone.ino} (100%) diff --git a/examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino b/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino similarity index 100% rename from examples/Audio_Examples/Audio_Example1_Play_Tone/Audio_Example1_Play_Tone.ino rename to examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino From 38c935a659a8fc6c0656e643eff717d428980b96 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Tue, 12 Dec 2023 10:04:22 -0700 Subject: [PATCH 35/52] Add audio resource enum Also default tone_id and nof_repeat to 0 in playAudioResource() --- src/sfe_ublox_cellular_voice.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index 01b7627..952e778 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -10,6 +10,13 @@ const char* const UBX_CELL_COMMAND_PLAY_AUDIO = "+UPAR"; // Play audio resour const char* const UBX_CELL_COMMAND_STOP_AUDIO = "+USAR"; // Stop audio resource const char* const UBX_CELL_COMMAND_GENERATE_TONE = "+UTGN"; // Tone generator +typedef enum +{ + UBX_CELL_AUDIO_RESOURCE_TONE = 0, + UBX_CELL_AUDIO_RESOURCE_MIDI = 1, + UBX_CELL_AUDIO_RESOURCE_LOOPBACK = 2 +} UBX_CELL_audio_resource_t; + // Base class for any modules supporting voice calls template class UBX_CELL_VOICE @@ -60,7 +67,7 @@ class UBX_CELL_VOICE nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } - UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id, uint8_t nof_repeat) + UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id = 0, uint8_t nof_repeat = 0) { UBX_CELL_error_t err; char *command; From e109e63b39f66d4a720f17e61821b558d1f897da Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Tue, 12 Dec 2023 10:04:34 -0700 Subject: [PATCH 36/52] Add audio example 2 (loopback) --- .../AudioExample2_Loopback.ino | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino diff --git a/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino b/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino new file mode 100644 index 0000000..f328587 --- /dev/null +++ b/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino @@ -0,0 +1,71 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL_VOICE_BASE myModule; // This example works with all voice-enabled modules, so this base class can be used +// LARA_R6001 myModule; +// LARA_R6401 myModule; +// LARA_R6801_00B myModule; + +void setup() +{ + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Audio Example 2 - Loopback")); + + Serial.println(); + Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(F("This example requires an audio codec attached to the I2S interface")); + Serial.println(F("of the cellular modem. Please add one and update this example as")); + Serial.println(F("needed to configure your audio codec!")); + Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(); + + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); +} + +void loop() +{ + while(Serial.available() != 0){Serial.read();} + Serial.println(F("Enter any key to begin loopback")); + while(Serial.available() == 0){} + + myModule.playAudioResource(UBX_CELL_AUDIO_RESOURCE_LOOPBACK); + + while(Serial.available() != 0){Serial.read();} + Serial.println(F("Enter any key to stop loopback")); + while(Serial.available() == 0){} + + myModule.stopAudioResource(UBX_CELL_AUDIO_RESOURCE_LOOPBACK); +} \ No newline at end of file From d51cae1d00bce032be4d731d366e6689586b85f3 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Tue, 12 Dec 2023 17:18:02 -0700 Subject: [PATCH 37/52] Refactor URC handling Now uses a vector to store individual URC handlers, and iterate through each one by one Also uses a separate vector for the URC strings within pruneBacklog This should make the URCs easier to maintain and expand, particularly within derived classes --- src/sfe_ublox_cellular.cpp | 805 ++++++++++++++++++++----------------- src/sfe_ublox_cellular.h | 24 ++ 2 files changed, 470 insertions(+), 359 deletions(-) diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index 484973c..6d61078 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -53,6 +53,21 @@ UBX_CELL::UBX_CELL(int powerPin, int resetPin, uint8_t maxInitTries) _saraRXBuffer = nullptr; _pruneBuffer = nullptr; _saraResponseBacklog = nullptr; + + // Add base URC handlers + addURCHandler(UBX_CELL_READ_SOCKET_URC, [this](const char* event){return this->urcHandlerReadSocket(event);}); + addURCHandler(UBX_CELL_READ_UDP_SOCKET_URC, [this](const char* event){return this->urcHandlerReadUDPSocket(event);}); + addURCHandler(UBX_CELL_LISTEN_SOCKET_URC, [this](const char* event){return this->urcHandlerListeningSocket(event);}); + addURCHandler(UBX_CELL_CLOSE_SOCKET_URC, [this](const char* event){return this->urcHandlerCloseSocket(event);}); + addURCHandler(UBX_CELL_GNSS_REQUEST_LOCATION_URC, [this](const char* event){return this->urcHandlerGNSSRequestLocation(event);}); + addURCHandler(UBX_CELL_SIM_STATE_URC, [this](const char* event){return this->urcHandlerSIMState(event);}); + addURCHandler(UBX_CELL_MESSAGE_PDP_ACTION_URC, [this](const char* event){return this->urcHandlerPDPAction(event);}); + addURCHandler(UBX_CELL_HTTP_COMMAND_URC, [this](const char* event){return this->urcHandlerHTTPCommand(event);}); + addURCHandler(UBX_CELL_MQTT_COMMAND_URC, [this](const char* event){return this->urcHandlerMQTTCommand(event);}); + addURCHandler(UBX_CELL_PING_COMMAND_URC, [this](const char* event){return this->urcHandlerPingCommand(event);}); + addURCHandler(UBX_CELL_FTP_COMMAND_URC, [this](const char* event){return this->urcHandlerFTPCommand(event);}); + addURCHandler(UBX_CELL_REGISTRATION_STATUS_URC, [this](const char* event){return this->urcHandlerRegistrationStatus(event);}); + addURCHandler(UBX_CELL_EPSREGISTRATION_STATUS_URC, [this](const char* event){return this->urcHandlerEPSRegistrationStatus(event);}); } UBX_CELL::~UBX_CELL(void) { @@ -313,445 +328,525 @@ bool UBX_CELL::bufferedPoll(void) return handled; } // /bufferedPoll -// Parse incoming URC's - the associated parse functions pass the data to the user via the callbacks (if defined) -bool UBX_CELL::processURCEvent(const char *event) +bool UBX_CELL::urcHandlerReadSocket(const char* event) { - { // URC: +UUSORD (Read Socket Data) - int socket, length; - char *searchPtr = strstr(event, UBX_CELL_READ_SOCKET_URC); - if (searchPtr != nullptr) + // URC: +UUSORD (Read Socket Data) + int socket, length; + char *searchPtr = strstr(event, UBX_CELL_READ_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_READ_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // Skip spaces + int ret = sscanf(searchPtr, "%d,%d", &socket, &length); + if (ret == 2) { - searchPtr += strlen(UBX_CELL_READ_SOCKET_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // Skip spaces - int ret = sscanf(searchPtr, "%d,%d", &socket, &length); - if (ret == 2) + if (_printDebug == true) + _debugPort->println(F("processReadEvent: read socket data")); + // From the UBX_CELL AT Commands Manual: + // "For the UDP socket type the URC +UUSORD: , notifies that a UDP packet has been received, + // either when buffer is empty or after a UDP packet has been read and one or more packets are stored in the + // buffer." + // So we need to check if this is a TCP socket or a UDP socket: + // If UDP, we call parseSocketReadIndicationUDP. + // Otherwise, we call parseSocketReadIndication. + if (_lastSocketProtocol[socket] == UBX_CELL_UDP) { if (_printDebug == true) - _debugPort->println(F("processReadEvent: read socket data")); - // From the UBX_CELL AT Commands Manual: - // "For the UDP socket type the URC +UUSORD: , notifies that a UDP packet has been received, - // either when buffer is empty or after a UDP packet has been read and one or more packets are stored in the - // buffer." - // So we need to check if this is a TCP socket or a UDP socket: - // If UDP, we call parseSocketReadIndicationUDP. - // Otherwise, we call parseSocketReadIndication. - if (_lastSocketProtocol[socket] == UBX_CELL_UDP) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: received +UUSORD but socket is UDP. Calling parseSocketReadIndicationUDP")); - parseSocketReadIndicationUDP(socket, length); - } - else - parseSocketReadIndication(socket, length); - return true; + _debugPort->println(F("processReadEvent: received +UUSORD but socket is UDP. Calling parseSocketReadIndicationUDP")); + parseSocketReadIndicationUDP(socket, length); } + else + parseSocketReadIndication(socket, length); + return true; } } - { // URC: +UUSORF (Receive From command (UDP only)) - int socket, length; - char *searchPtr = strstr(event, UBX_CELL_READ_UDP_SOCKET_URC); - if (searchPtr != nullptr) + + return false; +} + +bool UBX_CELL::urcHandlerReadUDPSocket(const char* event) +{ + // URC: +UUSORF (Receive From command (UDP only)) + int socket, length; + char *searchPtr = strstr(event, UBX_CELL_READ_UDP_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_READ_UDP_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int ret = sscanf(searchPtr, "%d,%d", &socket, &length); + if (ret == 2) { - searchPtr += strlen(UBX_CELL_READ_UDP_SOCKET_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int ret = sscanf(searchPtr, "%d,%d", &socket, &length); - if (ret == 2) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: UDP receive")); - parseSocketReadIndicationUDP(socket, length); - return true; - } + if (_printDebug == true) + _debugPort->println(F("processReadEvent: UDP receive")); + parseSocketReadIndicationUDP(socket, length); + return true; } } - { // URC: +UUSOLI (Set Listening Socket) - int socket = 0; - int listenSocket = 0; - unsigned int port = 0; - unsigned int listenPort = 0; - IPAddress remoteIP = {0,0,0,0}; - IPAddress localIP = {0,0,0,0}; - int remoteIPstore[4] = {0,0,0,0}; - int localIPstore[4] = {0,0,0,0}; - char *searchPtr = strstr(event, UBX_CELL_LISTEN_SOCKET_URC); - if (searchPtr != nullptr) + return false; +} + +bool UBX_CELL::urcHandlerListeningSocket(const char* event) +{ + // URC: +UUSOLI (Set Listening Socket) + int socket = 0; + int listenSocket = 0; + unsigned int port = 0; + unsigned int listenPort = 0; + IPAddress remoteIP = {0,0,0,0}; + IPAddress localIP = {0,0,0,0}; + int remoteIPstore[4] = {0,0,0,0}; + int localIPstore[4] = {0,0,0,0}; + + char *searchPtr = strstr(event, UBX_CELL_LISTEN_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_LISTEN_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int ret = sscanf(searchPtr, + "%d,\"%d.%d.%d.%d\",%u,%d,\"%d.%d.%d.%d\",%u", + &socket, + &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], + &port, &listenSocket, + &localIPstore[0], &localIPstore[1], &localIPstore[2], &localIPstore[3], + &listenPort); + for (int i = 0; i <= 3; i++) { - searchPtr += strlen(UBX_CELL_LISTEN_SOCKET_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int ret = sscanf(searchPtr, - "%d,\"%d.%d.%d.%d\",%u,%d,\"%d.%d.%d.%d\",%u", - &socket, - &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], - &port, &listenSocket, - &localIPstore[0], &localIPstore[1], &localIPstore[2], &localIPstore[3], - &listenPort); - for (int i = 0; i <= 3; i++) - { - if (ret >= 5) - remoteIP[i] = (uint8_t)remoteIPstore[i]; - if (ret >= 11) - localIP[i] = (uint8_t)localIPstore[i]; - } if (ret >= 5) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: socket listen")); - parseSocketListenIndication(listenSocket, localIP, listenPort, socket, remoteIP, port); - return true; - } + remoteIP[i] = (uint8_t)remoteIPstore[i]; + if (ret >= 11) + localIP[i] = (uint8_t)localIPstore[i]; + } + if (ret >= 5) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: socket listen")); + parseSocketListenIndication(listenSocket, localIP, listenPort, socket, remoteIP, port); + return true; } } - { // URC: +UUSOCL (Close Socket) - int socket; - char *searchPtr = strstr(event, UBX_CELL_CLOSE_SOCKET_URC); - if (searchPtr != nullptr) + + return false; +} + +bool UBX_CELL::urcHandlerCloseSocket(const char* event) +{ + // URC: +UUSOCL (Close Socket) + int socket; + char *searchPtr = strstr(event, UBX_CELL_CLOSE_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_CLOSE_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int ret = sscanf(searchPtr, "%d", &socket); + if (ret == 1) { - searchPtr += strlen(UBX_CELL_CLOSE_SOCKET_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int ret = sscanf(searchPtr, "%d", &socket); - if (ret == 1) + if (_printDebug == true) + _debugPort->println(F("processReadEvent: socket close")); + if ((socket >= 0) && (socket <= 6)) { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: socket close")); - if ((socket >= 0) && (socket <= 6)) + if (_socketCloseCallback != nullptr) { - if (_socketCloseCallback != nullptr) - { - _socketCloseCallback(socket); - } + _socketCloseCallback(socket); } - return true; } + return true; } } - { // URC: +UULOC (Localization information - CellLocate and hybrid positioning) - ClockData clck; - PositionData gps; - SpeedData spd; - unsigned long uncertainty; - int scanNum; - int latH, lonH, alt; - unsigned int speedU, cogU; - char latL[10], lonL[10]; - int dateStore[5]; - // Maybe we should also scan for +UUGIND and extract the activated gnss system? + return false; +} - // This assumes the ULOC response type is "0" or "1" - as selected by gpsRequest detailed - char *searchPtr = strstr(event, UBX_CELL_GNSS_REQUEST_LOCATION_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_GNSS_REQUEST_LOCATION_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, - "%d/%d/%d,%d:%d:%d.%d,%d.%[^,],%d.%[^,],%d,%lu,%u,%u,%*s", - &dateStore[0], &dateStore[1], &clck.date.year, - &dateStore[2], &dateStore[3], &dateStore[4], &clck.time.ms, - &latH, latL, &lonH, lonL, &alt, &uncertainty, - &speedU, &cogU); - clck.date.day = dateStore[0]; - clck.date.month = dateStore[1]; - clck.time.hour = dateStore[2]; - clck.time.minute = dateStore[3]; - clck.time.second = dateStore[4]; - - if (scanNum >= 13) +bool UBX_CELL::urcHandlerGNSSRequestLocation(const char* event) +{ + // URC: +UULOC (Localization information - CellLocate and hybrid positioning) + ClockData clck; + PositionData gps; + SpeedData spd; + unsigned long uncertainty; + int scanNum; + int latH, lonH, alt; + unsigned int speedU, cogU; + char latL[10], lonL[10]; + int dateStore[5]; + + // Maybe we should also scan for +UUGIND and extract the activated gnss system? + + // This assumes the ULOC response type is "0" or "1" - as selected by gpsRequest detailed + char *searchPtr = strstr(event, UBX_CELL_GNSS_REQUEST_LOCATION_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_GNSS_REQUEST_LOCATION_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, + "%d/%d/%d,%d:%d:%d.%d,%d.%[^,],%d.%[^,],%d,%lu,%u,%u,%*s", + &dateStore[0], &dateStore[1], &clck.date.year, + &dateStore[2], &dateStore[3], &dateStore[4], &clck.time.ms, + &latH, latL, &lonH, lonL, &alt, &uncertainty, + &speedU, &cogU); + clck.date.day = dateStore[0]; + clck.date.month = dateStore[1]; + clck.time.hour = dateStore[2]; + clck.time.minute = dateStore[3]; + clck.time.second = dateStore[4]; + + if (scanNum >= 13) + { + // Found a Location string! + if (_printDebug == true) { - // Found a Location string! - if (_printDebug == true) - { - _debugPort->println(F("processReadEvent: location")); - } + _debugPort->println(F("processReadEvent: location")); + } - if (latH >= 0) - gps.lat = (float)latH + ((float)atol(latL) / pow(10, strlen(latL))); - else - gps.lat = (float)latH - ((float)atol(latL) / pow(10, strlen(latL))); - if (lonH >= 0) - gps.lon = (float)lonH + ((float)atol(lonL) / pow(10, strlen(lonL))); - else - gps.lon = (float)lonH - ((float)atol(lonL) / pow(10, strlen(lonL))); - gps.alt = (float)alt; - if (scanNum >= 15) // If detailed response, get speed data - { - spd.speed = (float)speedU; - spd.cog = (float)cogU; - } + if (latH >= 0) + gps.lat = (float)latH + ((float)atol(latL) / pow(10, strlen(latL))); + else + gps.lat = (float)latH - ((float)atol(latL) / pow(10, strlen(latL))); + if (lonH >= 0) + gps.lon = (float)lonH + ((float)atol(lonL) / pow(10, strlen(lonL))); + else + gps.lon = (float)lonH - ((float)atol(lonL) / pow(10, strlen(lonL))); + gps.alt = (float)alt; + if (scanNum >= 15) // If detailed response, get speed data + { + spd.speed = (float)speedU; + spd.cog = (float)cogU; + } - // if (_printDebug == true) - // { - // _debugPort->print(F("processReadEvent: location: lat: ")); - // _debugPort->print(gps.lat, 7); - // _debugPort->print(F(" lon: ")); - // _debugPort->print(gps.lon, 7); - // _debugPort->print(F(" alt: ")); - // _debugPort->print(gps.alt, 2); - // _debugPort->print(F(" speed: ")); - // _debugPort->print(spd.speed, 2); - // _debugPort->print(F(" cog: ")); - // _debugPort->println(spd.cog, 2); - // } - - if (_gpsRequestCallback != nullptr) - { - _gpsRequestCallback(clck, gps, spd, uncertainty); - } + // if (_printDebug == true) + // { + // _debugPort->print(F("processReadEvent: location: lat: ")); + // _debugPort->print(gps.lat, 7); + // _debugPort->print(F(" lon: ")); + // _debugPort->print(gps.lon, 7); + // _debugPort->print(F(" alt: ")); + // _debugPort->print(gps.alt, 2); + // _debugPort->print(F(" speed: ")); + // _debugPort->print(spd.speed, 2); + // _debugPort->print(F(" cog: ")); + // _debugPort->println(spd.cog, 2); + // } - return true; + if (_gpsRequestCallback != nullptr) + { + _gpsRequestCallback(clck, gps, spd, uncertainty); } + + return true; } } - { // URC: +UUSIMSTAT (SIM Status) - UBX_CELL_sim_states_t state; - int scanNum; - int stateStore; - char *searchPtr = strstr(event, UBX_CELL_SIM_STATE_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_SIM_STATE_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d", &stateStore); + return false; +} - if (scanNum == 1) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: SIM status")); +bool UBX_CELL::urcHandlerSIMState(const char* event) +{ + // URC: +UUSIMSTAT (SIM Status) + UBX_CELL_sim_states_t state; + int scanNum; + int stateStore; - state = (UBX_CELL_sim_states_t)stateStore; + char *searchPtr = strstr(event, UBX_CELL_SIM_STATE_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_SIM_STATE_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d", &stateStore); - if (_simStateReportCallback != nullptr) - { - _simStateReportCallback(state); - } + if (scanNum == 1) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: SIM status")); - return true; + state = (UBX_CELL_sim_states_t)stateStore; + + if (_simStateReportCallback != nullptr) + { + _simStateReportCallback(state); } + + return true; } } - { // URC: +UUPSDA (Packet Switched Data Action) - int result; - IPAddress remoteIP = {0, 0, 0, 0}; - int scanNum; - int remoteIPstore[4]; - char *searchPtr = strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\"", - &result, &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); + return false; +} - if (scanNum == 5) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: packet switched data action")); +bool UBX_CELL::urcHandlerPDPAction(const char* event) +{ + // URC: +UUPSDA (Packet Switched Data Action) + int result; + IPAddress remoteIP = {0, 0, 0, 0}; + int scanNum; + int remoteIPstore[4]; - for (int i = 0; i <= 3; i++) - { - remoteIP[i] = (uint8_t)remoteIPstore[i]; - } + char *searchPtr = strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\"", + &result, &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); - if (_psdActionRequestCallback != nullptr) - { - _psdActionRequestCallback(result, remoteIP); - } + if (scanNum == 5) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: packet switched data action")); + + for (int i = 0; i <= 3; i++) + { + remoteIP[i] = (uint8_t)remoteIPstore[i]; + } - return true; + if (_psdActionRequestCallback != nullptr) + { + _psdActionRequestCallback(result, remoteIP); } + + return true; } } - { // URC: +UUHTTPCR (HTTP Command Result) - int profile, command, result; - int scanNum; - char *searchPtr = strstr(event, UBX_CELL_HTTP_COMMAND_URC); - if (searchPtr != nullptr) + return false; +} + +bool UBX_CELL::urcHandlerHTTPCommand(const char* event) +{ + // URC: +UUHTTPCR (HTTP Command Result) + int profile, command, result; + int scanNum; + + char *searchPtr = strstr(event, UBX_CELL_HTTP_COMMAND_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_HTTP_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,%d", &profile, &command, &result); + + if (scanNum == 3) { - searchPtr += strlen(UBX_CELL_HTTP_COMMAND_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d,%d", &profile, &command, &result); + if (_printDebug == true) + _debugPort->println(F("processReadEvent: HTTP command result")); - if (scanNum == 3) + if ((profile >= 0) && (profile < UBX_CELL_NUM_HTTP_PROFILES)) { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: HTTP command result")); - - if ((profile >= 0) && (profile < UBX_CELL_NUM_HTTP_PROFILES)) + if (_httpCommandRequestCallback != nullptr) { - if (_httpCommandRequestCallback != nullptr) - { - _httpCommandRequestCallback(profile, command, result); - } + _httpCommandRequestCallback(profile, command, result); } - - return true; } + + return true; } } - { // URC: +UUMQTTC (MQTT Command Result) - int command, result; - int scanNum; - int qos = -1; - String topic; - char *searchPtr = strstr(event, UBX_CELL_MQTT_COMMAND_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_MQTT_COMMAND_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') - { - searchPtr++; // skip spaces - } + return false; +} - scanNum = sscanf(searchPtr, "%d,%d", &command, &result); - if ((scanNum == 2) && (command == UBX_CELL_MQTT_COMMAND_SUBSCRIBE)) - { - char topicC[100] = ""; - scanNum = sscanf(searchPtr, "%*d,%*d,%d,\"%[^\"]\"", &qos, topicC); - topic = topicC; - } - if ((scanNum == 2) || (scanNum == 4)) - { - if (_printDebug == true) - { - _debugPort->println(F("processReadEvent: MQTT command result")); - } +bool UBX_CELL::urcHandlerMQTTCommand(const char* event) +{ + // URC: +UUMQTTC (MQTT Command Result) + int command, result; + int scanNum; + int qos = -1; + String topic; - if (_mqttCommandRequestCallback != nullptr) - { - _mqttCommandRequestCallback(command, result); - } + char *searchPtr = strstr(event, UBX_CELL_MQTT_COMMAND_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_MQTT_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + { + searchPtr++; // skip spaces + } - return true; - } + scanNum = sscanf(searchPtr, "%d,%d", &command, &result); + if ((scanNum == 2) && (command == UBX_CELL_MQTT_COMMAND_SUBSCRIBE)) + { + char topicC[100] = ""; + scanNum = sscanf(searchPtr, "%*d,%*d,%d,\"%[^\"]\"", &qos, topicC); + topic = topicC; } - } - { // URC: +UUFTPCR (FTP Command Result) - int ftpCmd; - int ftpResult; - int scanNum; - char *searchPtr = strstr(event, UBX_CELL_FTP_COMMAND_URC); - if (searchPtr != nullptr) + if ((scanNum == 2) || (scanNum == 4)) { - searchPtr += strlen(UBX_CELL_FTP_COMMAND_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') + if (_printDebug == true) { - searchPtr++; // skip spaces + _debugPort->println(F("processReadEvent: MQTT command result")); } - scanNum = sscanf(searchPtr, "%d,%d", &ftpCmd, &ftpResult); - if (scanNum == 2 && _ftpCommandRequestCallback != nullptr) + if (_mqttCommandRequestCallback != nullptr) { - _ftpCommandRequestCallback(ftpCmd, ftpResult); - return true; + _mqttCommandRequestCallback(command, result); } + + return true; } } - { // URC: +UUPING (Ping Result) - int retry = 0; - int p_size = 0; - int ttl = 0; - String remote_host = ""; - IPAddress remoteIP = {0, 0, 0, 0}; - long rtt = 0; - int scanNum; - // Try to extract the UUPING retries and payload size - char *searchPtr = strstr(event, UBX_CELL_PING_COMMAND_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_PING_COMMAND_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d,", &retry, &p_size); + return false; +} - if (scanNum == 2) +bool UBX_CELL::urcHandlerPingCommand(const char* event) +{ + // URC: +UUPING (Ping Result) + int retry = 0; + int p_size = 0; + int ttl = 0; + String remote_host = ""; + IPAddress remoteIP = {0, 0, 0, 0}; + long rtt = 0; + int scanNum; + + // Try to extract the UUPING retries and payload size + char *searchPtr = strstr(event, UBX_CELL_PING_COMMAND_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_PING_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,", &retry, &p_size); + + if (scanNum == 2) + { + if (_printDebug == true) { - if (_printDebug == true) - { - _debugPort->println(F("processReadEvent: ping")); - } + _debugPort->println(F("processReadEvent: ping")); + } + + searchPtr = strchr(++searchPtr, '\"'); // Search to the first quote - searchPtr = strchr(++searchPtr, '\"'); // Search to the first quote + // Extract the remote host name, stop at the next quote + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0')) + { + remote_host.concat(*(searchPtr)); + } - // Extract the remote host name, stop at the next quote - while ((*(++searchPtr) != '\"') && (*searchPtr != '\0')) + if (*searchPtr != '\0') // Make sure we found a quote + { + int remoteIPstore[4]; + scanNum = sscanf(searchPtr, "\",\"%d.%d.%d.%d\",%d,%ld", + &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], &ttl, &rtt); + for (int i = 0; i <= 3; i++) { - remote_host.concat(*(searchPtr)); + remoteIP[i] = (uint8_t)remoteIPstore[i]; } - if (*searchPtr != '\0') // Make sure we found a quote + if (scanNum == 6) // Make sure we extracted enough data { - int remoteIPstore[4]; - scanNum = sscanf(searchPtr, "\",\"%d.%d.%d.%d\",%d,%ld", - &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], &ttl, &rtt); - for (int i = 0; i <= 3; i++) + if (_pingRequestCallback != nullptr) { - remoteIP[i] = (uint8_t)remoteIPstore[i]; - } - - if (scanNum == 6) // Make sure we extracted enough data - { - if (_pingRequestCallback != nullptr) - { - _pingRequestCallback(retry, p_size, remote_host, remoteIP, ttl, rtt); - } + _pingRequestCallback(retry, p_size, remote_host, remoteIP, ttl, rtt); } } - return true; } + return true; } } - { // URC: +CREG - int status = 0; - unsigned int lac = 0, ci = 0, Act = 0; - char *searchPtr = strstr(event, UBX_CELL_REGISTRATION_STATUS_URC); - if (searchPtr != nullptr) + + return false; +} + +bool UBX_CELL::urcHandlerFTPCommand(const char* event) +{ + // URC: +UUFTPCR (FTP Command Result) + int ftpCmd; + int ftpResult; + int scanNum; + char *searchPtr = strstr(event, UBX_CELL_FTP_COMMAND_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_FTP_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') { - searchPtr += strlen(UBX_CELL_REGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &lac, &ci, &Act); - if (scanNum == 4) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: CREG")); + searchPtr++; // skip spaces + } - if (_registrationCallback != nullptr) - { - _registrationCallback((UBX_CELL_registration_status_t)status, lac, ci, Act); - } + scanNum = sscanf(searchPtr, "%d,%d", &ftpCmd, &ftpResult); + if (scanNum == 2 && _ftpCommandRequestCallback != nullptr) + { + _ftpCommandRequestCallback(ftpCmd, ftpResult); + return true; + } + } + + return false; +} - return true; +bool UBX_CELL::urcHandlerRegistrationStatus(const char* event) +{ + // URC: +CREG + int status = 0; + unsigned int lac = 0, ci = 0, Act = 0; + char *searchPtr = strstr(event, UBX_CELL_REGISTRATION_STATUS_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_REGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &lac, &ci, &Act); + if (scanNum == 4) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: CREG")); + + if (_registrationCallback != nullptr) + { + _registrationCallback((UBX_CELL_registration_status_t)status, lac, ci, Act); } + + return true; } } - { // URC: +CEREG - int status = 0; - unsigned int tac = 0, ci = 0, Act = 0; - char *searchPtr = strstr(event, UBX_CELL_EPSREGISTRATION_STATUS_URC); - if (searchPtr != nullptr) + + return false; +} + +bool UBX_CELL::urcHandlerEPSRegistrationStatus(const char* event) +{ + // URC: +CEREG + int status = 0; + unsigned int tac = 0, ci = 0, Act = 0; + char *searchPtr = strstr(event, UBX_CELL_EPSREGISTRATION_STATUS_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_EPSREGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &tac, &ci, &Act); + if (scanNum == 4) { - searchPtr += strlen(UBX_CELL_EPSREGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &tac, &ci, &Act); - if (scanNum == 4) + if (_printDebug == true) + _debugPort->println(F("processReadEvent: CEREG")); + + if (_epsRegistrationCallback != nullptr) { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: CEREG")); + _epsRegistrationCallback((UBX_CELL_registration_status_t)status, tac, ci, Act); + } - if (_epsRegistrationCallback != nullptr) - { - _epsRegistrationCallback((UBX_CELL_registration_status_t)status, tac, ci, Act); - } + return true; + } + } - return true; - } + return false; +} + +void UBX_CELL::addURCHandler(const char* urcString, UBX_CELL_urc_handler_t urcHandler) +{ + _urcStrings.push_back(urcString); + _urcHandlers.push_back(urcHandler); +} + +// Parse incoming URC's - the associated parse functions pass the data to the user via the callbacks (if defined) +bool UBX_CELL::processURCEvent(const char *event) +{ + // Iterate through each URC handler to see if it can handle this message + for(auto urcHandler : _urcHandlers) + { + if (urcHandler(event)) + { + // This handler took care of it, so we're done! + return true; } } - // NOTE: When adding new URC messages, remember to update pruneBacklog too! + // None of the handlers took care of it return false; } @@ -6320,23 +6415,15 @@ void UBX_CELL::pruneBacklog() while (event != nullptr) //If event is actionable, add it to pruneBuffer. { // These are the events we want to keep so they can be processed by poll / bufferedPoll - if ((strstr(event, UBX_CELL_READ_SOCKET_URC) != nullptr) - || (strstr(event, UBX_CELL_READ_UDP_SOCKET_URC) != nullptr) - || (strstr(event, UBX_CELL_LISTEN_SOCKET_URC) != nullptr) - || (strstr(event, UBX_CELL_CLOSE_SOCKET_URC) != nullptr) - || (strstr(event, UBX_CELL_GNSS_REQUEST_LOCATION_URC) != nullptr) - || (strstr(event, UBX_CELL_SIM_STATE_URC) != nullptr) - || (strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC) != nullptr) - || (strstr(event, UBX_CELL_HTTP_COMMAND_URC) != nullptr) - || (strstr(event, UBX_CELL_MQTT_COMMAND_URC) != nullptr) - || (strstr(event, UBX_CELL_PING_COMMAND_URC) != nullptr) - || (strstr(event, UBX_CELL_REGISTRATION_STATUS_URC) != nullptr) - || (strstr(event, UBX_CELL_EPSREGISTRATION_STATUS_URC) != nullptr) - || (strstr(event, UBX_CELL_FTP_COMMAND_URC) != nullptr)) - { - strcat(_pruneBuffer, event); // The URCs are all readable text so using strcat is OK - strcat(_pruneBuffer, "\r\n"); // strtok blows away delimiter, but we want that for later. - _saraResponseBacklogLength += strlen(event) + 2; // Add the length of this event to _saraResponseBacklogLength + for(auto urcString : _urcStrings) + { + if(strstr(event, urcString) != nullptr) + { + strcat(_pruneBuffer, event); // The URCs are all readable text so using strcat is OK + strcat(_pruneBuffer, "\r\n"); // strtok blows away delimiter, but we want that for later. + _saraResponseBacklogLength += strlen(event) + 2; // Add the length of this event to _saraResponseBacklogLength + break; // No need to check any other events + } } event = strtok_r(nullptr, "\r\n", &preservedEvent); // Walk though any remaining events diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index 8f2f224..3b32bff 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -71,6 +71,7 @@ #endif #include +#include #define UBX_CELL_POWER_PIN -1 // Default to no pin #define UBX_CELL_RESET_PIN -1 @@ -207,6 +208,9 @@ const char* const UBX_CELL_RESPONSE_ERROR = "\nERROR\r\n"; const char* const UBX_CELL_RESPONSE_CONNECT = "\r\nCONNECT\r\n"; #define UBX_CELL_RESPONSE_OK_OR_ERROR nullptr +// URC handler type definition +typedef std::function UBX_CELL_urc_handler_t; + // CTRL+Z and ESC ASCII codes for SMS message sends const char ASCII_CTRL_Z = 0x1A; const char ASCII_ESC = 0x1B; @@ -1010,6 +1014,9 @@ class UBX_CELL : public Print char *ubx_cell_calloc_char(size_t num); + // Add a URC handler + void addURCHandler(const char* urcString, UBX_CELL_urc_handler_t urcHandler); + protected: HardwareSerial *_hardSerial; #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED @@ -1054,6 +1061,9 @@ class UBX_CELL : public Print void (*_registrationCallback)(UBX_CELL_registration_status_t status, unsigned int lac, unsigned int ci, int Act); void (*_epsRegistrationCallback)(UBX_CELL_registration_status_t status, unsigned int tac, unsigned int ci, int Act); + // Vectors of URC strings and handlers + std::vector _urcStrings; + std::vector _urcHandlers; int _lastSocketProtocol[UBX_CELL_NUM_SOCKETS]; // Record the protocol for each socket to avoid having to call querySocketType in parseSocketReadIndication @@ -1100,6 +1110,20 @@ class UBX_CELL : public Print UBX_CELL_error_t autobaud(unsigned long desiredBaud); + bool urcHandlerReadSocket(const char* event); + bool urcHandlerReadUDPSocket(const char* event); + bool urcHandlerListeningSocket(const char* event); + bool urcHandlerCloseSocket(const char* event); + bool urcHandlerGNSSRequestLocation(const char* event); + bool urcHandlerSIMState(const char* event); + bool urcHandlerPDPAction(const char* event); + bool urcHandlerHTTPCommand(const char* event); + bool urcHandlerMQTTCommand(const char* event); + bool urcHandlerPingCommand(const char* event); + bool urcHandlerFTPCommand(const char* event); + bool urcHandlerRegistrationStatus(const char* event); + bool urcHandlerEPSRegistrationStatus(const char* event); + bool processURCEvent(const char *event); void pruneBacklog(void); From 7efffde75d7d2d9ed64a38e052e23d429c3e56fb Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Tue, 12 Dec 2023 17:45:59 -0700 Subject: [PATCH 38/52] Add RING URC handler Pending #16, this should work after that gets merged --- src/sfe_ublox_cellular_voice.h | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index 952e778..9ceee64 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -10,6 +10,8 @@ const char* const UBX_CELL_COMMAND_PLAY_AUDIO = "+UPAR"; // Play audio resour const char* const UBX_CELL_COMMAND_STOP_AUDIO = "+USAR"; // Stop audio resource const char* const UBX_CELL_COMMAND_GENERATE_TONE = "+UTGN"; // Tone generator +const char* const UBX_CELL_RING_URC = "RING"; + typedef enum { UBX_CELL_AUDIO_RESOURCE_TONE = 0, @@ -22,6 +24,15 @@ template class UBX_CELL_VOICE { public: + UBX_CELL_VOICE(void) + { + // Set ring URC callback to nullptr + _ringCallback = nullptr; + + // Add handler for ring URC + static_cast(this)->addURCHandler(UBX_CELL_RING_URC, [this](const char* event){return this->urcCheckRing(event);}); + } + UBX_CELL_error_t dial(String number) { char *command; @@ -132,6 +143,31 @@ class UBX_CELL_VOICE free(command); return err; } + + void setRingCallback(void (*callback)(void)) + { + _ringCallback = callback; + } + +protected: + // Callback for incoming calls + void (*_ringCallback)(void); + + bool urcCheckRing(const char *event) + { + int socket, length; + char *searchPtr = strstr(event, UBX_CELL_RING_URC); + if (searchPtr != nullptr) + { + if(_ringCallback != nullptr) + { + _ringCallback(); + } + return true; + } + + return false; + } }; class UBX_CELL_VOICE_BASE : public UBX_CELL, public UBX_CELL_VOICE From 6c2da8c0511bd5c3e2bec6ea31a53817725fb134 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Tue, 12 Dec 2023 17:46:23 -0700 Subject: [PATCH 39/52] Add audio example 3 (call control) --- .../AudioExample3_CallControl.ino | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino diff --git a/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino b/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino new file mode 100644 index 0000000..ae6ab47 --- /dev/null +++ b/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino @@ -0,0 +1,129 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL_VOICE_BASE myModule; // This example works with all voice-enabled modules, so this base class can be used +// LARA_R6001 myModule; +// LARA_R6401 myModule; +// LARA_R6801_00B myModule; + +bool callInProgress = false; +bool incomingCall = false; + +void ringCallback() +{ + Serial.println(F("Incoming call! Enter \"A\" to answer, or anything else to reject")); + incomingCall = true; +} + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Audio Example 3 - Call Control")); + + Serial.println(); + Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(F("This example requires an audio codec attached to the I2S interface")); + Serial.println(F("of the cellular modem. Please add one and update this example as")); + Serial.println(F("needed to configure your audio codec!")); + Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(); + + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + // Set callback function for when a new call is received + myModule.setRingCallback(&ringCallback); + + Serial.println(F("Enter a number to dial")); + + // Clear any input + while(Serial.available()){Serial.read();} +} + +void loop() +{ + String inputString; + + myModule.bufferedPoll(); + + if(Serial.available()) + { + inputString = Serial.readStringUntil('\n'); + while(Serial.available()){Serial.read();} + + if(incomingCall) + { + if(inputString == "A" || inputString == "a") + { + Serial.println(F("Answering call, enter any key to hang up")); + myModule.answer(); + callInProgress = true; + } + else + { + Serial.println(F("Rejecting call")); + myModule.hangUp(); + } + incomingCall = false; + } + else if(callInProgress == false) + { + Serial.println("Dialing " + inputString + ", enter any key to hang up"); + myModule.dial(inputString); + callInProgress = true; + } + else + { + Serial.println(F("Hanging up, enter a new number to dial")); + myModule.hangUp(); + callInProgress = false; + } + } +} \ No newline at end of file From 83d58c8a4b93a695213c229e70576fa05cec9b78 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 13 Dec 2023 10:52:52 -0700 Subject: [PATCH 40/52] Space out exclamation marks in audio examples Just for the rare chance that someone is using the ATMega2560 with the original bootloader, triple exclamation marks would cause bad things. Easy enough to avoid by spacing them out! --- .../AudioExample1_PlayTone/AudioExample1_PlayTone.ino | 4 ++-- .../AudioExample2_Loopback/AudioExample2_Loopback.ino | 4 ++-- .../AudioExample3_CallControl/AudioExample3_CallControl.ino | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino b/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino index a6cc09c..60f802d 100644 --- a/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino +++ b/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino @@ -19,11 +19,11 @@ void setup() Serial.println(F("u-blox Cellular Audio Example 1 - Play Tone")); Serial.println(); - Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); Serial.println(F("This example requires an audio codec attached to the I2S interface")); Serial.println(F("of the cellular modem. Please add one and update this example as")); Serial.println(F("needed to configure your audio codec!")); - Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); Serial.println(); Serial.println(F("Press any key to begin")); diff --git a/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino b/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino index f328587..b07ce47 100644 --- a/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino +++ b/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino @@ -19,11 +19,11 @@ void setup() Serial.println(F("u-blox Cellular Audio Example 2 - Loopback")); Serial.println(); - Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); Serial.println(F("This example requires an audio codec attached to the I2S interface")); Serial.println(F("of the cellular modem. Please add one and update this example as")); Serial.println(F("needed to configure your audio codec!")); - Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); Serial.println(); Serial.println(F("Press any key to begin")); diff --git a/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino b/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino index ae6ab47..47f407f 100644 --- a/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino +++ b/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino @@ -30,11 +30,11 @@ void setup() Serial.println(F("u-blox Cellular Audio Example 3 - Call Control")); Serial.println(); - Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); Serial.println(F("This example requires an audio codec attached to the I2S interface")); Serial.println(F("of the cellular modem. Please add one and update this example as")); Serial.println(F("needed to configure your audio codec!")); - Serial.println(F("!!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!! ATTENTION !!!!!!!!")); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); Serial.println(); Serial.println(F("Press any key to begin")); From 2dd478ef55272a0fc1409f67463eff135923777c Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 13 Dec 2023 10:58:21 -0700 Subject: [PATCH 41/52] Remove unnecessary breaks from Example 3 --- .../Example3_RegisterOperator.ino | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino index df8385b..6532dc8 100644 --- a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino +++ b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino @@ -58,43 +58,30 @@ int convertOperatorNumber( mobile_network_operator_t mno) case 5: case 6: return ((int)mno); - break; case 8: return 7; - break; case 19: return 8; - break; case 20: return 9; - break; case 21: return 10; - break; case 28: return 11; - break; case 31: return 12; - break; case 32: return 13; - break; case 39: return 14; - break; case 90: return 15; - break; case 100: return 16; - break; case 101: return 17; - break; default: // NOT RECOGNIZED return 18; - break; } } From a04496494e4bc96a8525643a8b6a16193a6441b2 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 13 Dec 2023 11:28:39 -0700 Subject: [PATCH 42/52] Update library.properties --- library.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library.properties b/library.properties index 95e1087..6719043 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ -name=SparkFun u-blox AT Commands Arduino Library +name=SparkFun u-blox Cellular Arduino Library version=1.0.0 author=SparkFun Electronics maintainer=SparkFun Electronics -sentence=Library for u-blox modules supporting AT commands +sentence=Library for u-blox cellular modules paragraph= category=Communication -url=https://github.com/sparkfun/SparkFun_u-blox_AT_Commands_Arduino_Library +url=https://github.com/sparkfun/SparkFun_u-blox_Cellular_Arduino_Library architectures=* From 3445bdf62808f46d35db4997e65831fdbe471c83 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 13 Dec 2023 12:53:02 -0700 Subject: [PATCH 43/52] Moved PDP Action URC out of base class Resolves #3 --- src/sfe_sara_r5.cpp | 43 ++++++++++++++++++++++++++++++++++++++ src/sfe_sara_r5.h | 7 +++++++ src/sfe_ublox_cellular.cpp | 39 ---------------------------------- src/sfe_ublox_cellular.h | 2 -- 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp index 0e704b4..2478862 100644 --- a/src/sfe_sara_r5.cpp +++ b/src/sfe_sara_r5.cpp @@ -1,5 +1,10 @@ #include "sfe_sara_r5.h" +SARA_R5::SARA_R5() +{ + addURCHandler(UBX_CELL_MESSAGE_PDP_ACTION_URC, [this](const char* event){return this->urcHandlerPDPAction(event);}); +} + UBX_CELL_error_t SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utime_sensor_t sensor) { UBX_CELL_error_t err; @@ -358,3 +363,41 @@ UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *ad return err; } + +bool SARA_R5::urcHandlerPDPAction(const char* event) +{ + // URC: +UUPSDA (Packet Switched Data Action) + int result; + IPAddress remoteIP = {0, 0, 0, 0}; + int scanNum; + int remoteIPstore[4]; + + char *searchPtr = strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\"", + &result, &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); + + if (scanNum == 5) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: packet switched data action")); + + for (int i = 0; i <= 3; i++) + { + remoteIP[i] = (uint8_t)remoteIPstore[i]; + } + + if (_psdActionRequestCallback != nullptr) + { + _psdActionRequestCallback(result, remoteIP); + } + + return true; + } + } + + return false; +} diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index c719227..ffa060c 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -10,10 +10,14 @@ const char* const UBX_CELL_GNSS_REQUEST_TIME = "+UTIME"; // Ask for tim const char* const UBX_CELL_GNSS_TIME_INDICATION = "+UTIMEIND"; // Time information request status unsolicited indication const char* const UBX_CELL_GNSS_TIME_CONFIGURATION = "+UTIMECFG"; // Sets time configuration +const char* const UBX_CELL_MESSAGE_PDP_ACTION_URC = "+UUPSDA:"; + // Base SARA-R5 class class SARA_R5: public UBX_CELL { public: + SARA_R5(); + UBX_CELL_error_t setUtimeMode(UBX_CELL_utime_mode_t mode = UBX_CELL_UTIME_MODE_PPS, UBX_CELL_utime_sensor_t sensor = UBX_CELL_UTIME_SENSOR_GNSS_LTE); // Time mode, source etc. (+UTIME) UBX_CELL_error_t getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor); UBX_CELL_error_t setUtimeIndication(UBX_CELL_utime_urc_configuration_t config = UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED); // +UTIMEIND @@ -29,6 +33,9 @@ class SARA_R5: public UBX_CELL UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value); // Set parameters in the chosen PSD profile UBX_CELL_error_t performPDPaction(int profile, UBX_CELL_pdp_actions_t action); // Performs the requested action for the specified PSD profile: reset, store, load, activate, deactivate UBX_CELL_error_t getNetworkAssignedIPAddress(int profile, IPAddress *address); // Get the dynamic IP address assigned during PDP context activation + +protected: + bool urcHandlerPDPAction(const char* event); }; class SARA_R500S: public SARA_R5 diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index 7d95875..9a9ae0a 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -61,7 +61,6 @@ UBX_CELL::UBX_CELL(int powerPin, int resetPin, uint8_t maxInitTries) addURCHandler(UBX_CELL_CLOSE_SOCKET_URC, [this](const char* event){return this->urcHandlerCloseSocket(event);}); addURCHandler(UBX_CELL_GNSS_REQUEST_LOCATION_URC, [this](const char* event){return this->urcHandlerGNSSRequestLocation(event);}); addURCHandler(UBX_CELL_SIM_STATE_URC, [this](const char* event){return this->urcHandlerSIMState(event);}); - addURCHandler(UBX_CELL_MESSAGE_PDP_ACTION_URC, [this](const char* event){return this->urcHandlerPDPAction(event);}); addURCHandler(UBX_CELL_HTTP_COMMAND_URC, [this](const char* event){return this->urcHandlerHTTPCommand(event);}); addURCHandler(UBX_CELL_MQTT_COMMAND_URC, [this](const char* event){return this->urcHandlerMQTTCommand(event);}); addURCHandler(UBX_CELL_PING_COMMAND_URC, [this](const char* event){return this->urcHandlerPingCommand(event);}); @@ -572,44 +571,6 @@ bool UBX_CELL::urcHandlerSIMState(const char* event) return false; } -bool UBX_CELL::urcHandlerPDPAction(const char* event) -{ - // URC: +UUPSDA (Packet Switched Data Action) - int result; - IPAddress remoteIP = {0, 0, 0, 0}; - int scanNum; - int remoteIPstore[4]; - - char *searchPtr = strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\"", - &result, &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); - - if (scanNum == 5) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: packet switched data action")); - - for (int i = 0; i <= 3; i++) - { - remoteIP[i] = (uint8_t)remoteIPstore[i]; - } - - if (_psdActionRequestCallback != nullptr) - { - _psdActionRequestCallback(result, remoteIP); - } - - return true; - } - } - - return false; -} - bool UBX_CELL::urcHandlerHTTPCommand(const char* event) { // URC: +UUHTTPCR (HTTP Command Result) diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index 3b32bff..c3540d8 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -193,7 +193,6 @@ const char* const UBX_CELL_LISTEN_SOCKET_URC = "+UUSOLI:"; const char* const UBX_CELL_CLOSE_SOCKET_URC = "+UUSOCL:"; const char* const UBX_CELL_GNSS_REQUEST_LOCATION_URC = "+UULOC:"; const char* const UBX_CELL_SIM_STATE_URC = "+UUSIMSTAT:"; -const char* const UBX_CELL_MESSAGE_PDP_ACTION_URC = "+UUPSDA:"; const char* const UBX_CELL_HTTP_COMMAND_URC = "+UUHTTPCR:"; const char* const UBX_CELL_MQTT_COMMAND_URC = "+UUMQTTC:"; const char* const UBX_CELL_PING_COMMAND_URC = "+UUPING:"; @@ -1116,7 +1115,6 @@ class UBX_CELL : public Print bool urcHandlerCloseSocket(const char* event); bool urcHandlerGNSSRequestLocation(const char* event); bool urcHandlerSIMState(const char* event); - bool urcHandlerPDPAction(const char* event); bool urcHandlerHTTPCommand(const char* event); bool urcHandlerMQTTCommand(const char* event); bool urcHandlerPingCommand(const char* event); From c0214de24bbdc0a92999fddff92d212bc4dc0175 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 13 Dec 2023 13:01:39 -0700 Subject: [PATCH 44/52] Run library source through formatter Clang formatter in VS Code set to Microsoft style --- ...SparkFun_u-blox_Cellular_Arduino_Library.h | 4 +- src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 48 +- src/sfe_lara_r6.h | 21 +- src/sfe_sara_r5.cpp | 581 +- src/sfe_sara_r5.h | 85 +- src/sfe_ublox_cellular.cpp | 10697 ++++++++-------- src/sfe_ublox_cellular.h | 1677 +-- src/sfe_ublox_cellular_voice.h | 299 +- 8 files changed, 6725 insertions(+), 6687 deletions(-) diff --git a/src/SparkFun_u-blox_Cellular_Arduino_Library.h b/src/SparkFun_u-blox_Cellular_Arduino_Library.h index 96e8cd8..b69171c 100644 --- a/src/SparkFun_u-blox_Cellular_Arduino_Library.h +++ b/src/SparkFun_u-blox_Cellular_Arduino_Library.h @@ -1,4 +1,4 @@ +#include "sfe_lara_r6.h" +#include "sfe_sara_r5.h" #include "sfe_ublox_cellular.h" #include "sfe_ublox_cellular_voice.h" -#include "sfe_sara_r5.h" -#include "sfe_lara_r6.h" diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h index eb9a620..a5fff86 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -2,9 +2,8 @@ // RegEx Replace: \#define\sSARA\_R5\_([A-Z0-9_]+).* \#define SARA\_R5\_$+ UBLOX\_AT\_$+ /* - Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod Asset Tracker - By: Paul Clark - October 19th 2020 + Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod + Asset Tracker By: Paul Clark October 19th 2020 Based extensively on the: Arduino Library for the SparkFun LTE CAT M1/NB-IoT Shield - SARA-R4 @@ -34,8 +33,9 @@ #define SARA_R5_3_MIN_TIMEOUT 180000 #define SARA_R5_SET_BAUD_TIMEOUT 500 #define SARA_R5_POWER_OFF_PULSE_PERIOD 3200 // Hold PWR_ON low for this long to power the module off -#define SARA_R5_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) -#define SARA_R5_RESET_PULSE_PERIOD 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) +#define SARA_R5_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) +#define SARA_R5_RESET_PULSE_PERIOD \ + 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) #define SARA_R5_POWER_OFF_TIMEOUT 40000 // Datasheet says 40 seconds... #define SARA_R5_IP_CONNECT_TIMEOUT 130000 #define SARA_R5_POLL_DELAY 1 @@ -141,7 +141,6 @@ #define SARA_R5_SEC_PROFILE UBX_CELL_SEC_PROFILE #define SARA_R5_SEC_MANAGER UBX_CELL_SEC_MANAGER - // ### URC strings #define SARA_R5_READ_SOCKET_URC UBX_CELL_READ_SOCKET_URC #define SARA_R5_READ_UDP_SOCKET_URC UBX_CELL_READ_UDP_SOCKET_URC @@ -167,14 +166,7 @@ #define SARA_R5_NUM_SOCKETS 6 #define SARA_R5_NUM_SUPPORTED_BAUD 6 -const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = - { - 115200, - 9600, - 19200, - 38400, - 57600, - 230400}; +const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = {115200, 9600, 19200, 38400, 57600, 230400}; #define SARA_R5_DEFAULT_BAUD_RATE 115200 // Flow control definitions for AT&K @@ -244,13 +236,13 @@ const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = #define SARA_R5_SIM_NOT_OPERATIONAL UBX_CELL_SIM_NOT_OPERATIONAL #define SARA_R5_SIM_RESTRICTED UBX_CELL_SIM_RESTRICTED #define SARA_R5_SIM_OPERATIONAL UBX_CELL_SIM_OPERATIONAL -//SARA_R5_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 -//SARA_R5_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 -//SARA_R5_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 -//SARA_R5_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 -//SARA_R5_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 -//SARA_R5_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 -//SARA_R5_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 +// SARA_R5_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 +// SARA_R5_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 +// SARA_R5_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 +// SARA_R5_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 +// SARA_R5_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 +// SARA_R5_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 +// SARA_R5_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 #define SARA_R5_NUM_PSD_PROFILES 6 // Number of supported PSD profiles #define SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS 11 // Number of supported PDP context identifiers @@ -335,14 +327,14 @@ const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = #define SARA_R5_PSD_CONFIG_PARAM_PROTOCOL UBX_CELL_PSD_CONFIG_PARAM_PROTOCOL #define SARA_R5_PSD_CONFIG_PARAM_APN UBX_CELL_PSD_CONFIG_PARAM_APN -//SARA_R5_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 -//SARA_R5_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 +// SARA_R5_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 +// SARA_R5_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 #define SARA_R5_PSD_CONFIG_PARAM_DNS1 UBX_CELL_PSD_CONFIG_PARAM_DNS1 #define SARA_R5_PSD_CONFIG_PARAM_DNS2 UBX_CELL_PSD_CONFIG_PARAM_DNS2 -//SARA_R5_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 -//SARA_R5_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 -//SARA_R5_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 -//SARA_R5_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 +// SARA_R5_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 +// SARA_R5_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 +// SARA_R5_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 +// SARA_R5_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 #define SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID UBX_CELL_PSD_CONFIG_PARAM_MAP_TO_CID #define SARA_R5_PSD_PROTOCOL_IPV4 UBX_CELL_PSD_PROTOCOL_IPV4 @@ -388,4 +380,4 @@ const unsigned long SARA_R5_SUPPORTED_BAUD[SARA_R5_NUM_SUPPORTED_BAUD] = #define SARA_R5_SEC_MANAGER_CLIENT_KEY UBX_CELL_SEC_MANAGER_CLIENT_KEY #define SARA_R5_SEC_MANAGER_SERVER_CERT UBX_CELL_SEC_MANAGER_SERVER_CERT -#endif //SPARKFUN_SARA_R5_ARDUINO_LIBRARY_H +#endif // SPARKFUN_SARA_R5_ARDUINO_LIBRARY_H diff --git a/src/sfe_lara_r6.h b/src/sfe_lara_r6.h index 08e9736..40fc862 100644 --- a/src/sfe_lara_r6.h +++ b/src/sfe_lara_r6.h @@ -5,39 +5,32 @@ #include "sfe_ublox_cellular_voice.h" // Base LARA-R6 class -class LARA_R6: public UBX_CELL +class LARA_R6 : public UBX_CELL { - }; -class LARA_R6001: public LARA_R6, public UBX_CELL_VOICE +class LARA_R6001 : public LARA_R6, public UBX_CELL_VOICE { - }; -class LARA_R6001D: public LARA_R6 +class LARA_R6001D : public LARA_R6 { - }; -class LARA_R6401: public LARA_R6, public UBX_CELL_VOICE +class LARA_R6401 : public LARA_R6, public UBX_CELL_VOICE { - }; -class LARA_R6401D: public LARA_R6 +class LARA_R6401D : public LARA_R6 { - }; -class LARA_R6801_00B: public LARA_R6, public UBX_CELL_VOICE +class LARA_R6801_00B : public LARA_R6, public UBX_CELL_VOICE { - }; -class LARA_R6801D: public LARA_R6 +class LARA_R6801D : public LARA_R6 { - }; #endif \ No newline at end of file diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp index 2478862..34a4992 100644 --- a/src/sfe_sara_r5.cpp +++ b/src/sfe_sara_r5.cpp @@ -2,402 +2,397 @@ SARA_R5::SARA_R5() { - addURCHandler(UBX_CELL_MESSAGE_PDP_ACTION_URC, [this](const char* event){return this->urcHandlerPDPAction(event);}); + addURCHandler(UBX_CELL_MESSAGE_PDP_ACTION_URC, + [this](const char *event) { return this->urcHandlerPDPAction(event); }); } UBX_CELL_error_t SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utime_sensor_t sensor) { - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (mode == UBX_CELL_UTIME_MODE_STOP) // stop UTIME does not require a sensor - sprintf(command, "%s=%d", UBX_CELL_GNSS_REQUEST_TIME, mode); - else - sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_REQUEST_TIME, mode, sensor); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_10_SEC_TIMEOUT); - free(command); - return err; + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (mode == UBX_CELL_UTIME_MODE_STOP) // stop UTIME does not require a sensor + sprintf(command, "%s=%d", UBX_CELL_GNSS_REQUEST_TIME, mode); + else + sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_REQUEST_TIME, mode, sensor); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); + free(command); + return err; } UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor) { - UBX_CELL_error_t err; - char *command; - char *response; + UBX_CELL_error_t err; + char *command; + char *response; - UBX_CELL_utime_mode_t m; - UBX_CELL_utime_sensor_t s; + UBX_CELL_utime_mode_t m; + UBX_CELL_utime_sensor_t s; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_REQUEST_TIME); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_REQUEST_TIME); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_10_SEC_TIMEOUT); - - // Response format: \r\n+UTIME: [,]\r\n\r\nOK\r\n - if (err == UBX_CELL_ERROR_SUCCESS) - { - int mStore, sStore, scanned = 0; - char *searchPtr = strstr(response, "+UTIME:"); - if (searchPtr != nullptr) + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - searchPtr += strlen("+UTIME:"); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d,%d\r\n", &mStore, &sStore); + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - m = (UBX_CELL_utime_mode_t)mStore; - s = (UBX_CELL_utime_sensor_t)sStore; - if (scanned == 2) - { - *mode = m; - *sensor = s; - } - else if (scanned == 1) + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); + + // Response format: \r\n+UTIME: [,]\r\n\r\nOK\r\n + if (err == UBX_CELL_ERROR_SUCCESS) { - *mode = m; - *sensor = UBX_CELL_UTIME_SENSOR_NONE; + int mStore, sStore, scanned = 0; + char *searchPtr = strstr(response, "+UTIME:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UTIME:"); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d\r\n", &mStore, &sStore); + } + m = (UBX_CELL_utime_mode_t)mStore; + s = (UBX_CELL_utime_sensor_t)sStore; + if (scanned == 2) + { + *mode = m; + *sensor = s; + } + else if (scanned == 1) + { + *mode = m; + *sensor = UBX_CELL_UTIME_SENSOR_NONE; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - free(command); - free(response); - return err; + free(command); + free(response); + return err; } UBX_CELL_error_t SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t config) { - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_GNSS_TIME_INDICATION, config); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_GNSS_TIME_INDICATION, config); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; } UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config) { - UBX_CELL_error_t err; - char *command; - char *response; + UBX_CELL_error_t err; + char *command; + char *response; - UBX_CELL_utime_urc_configuration_t c; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_TIME_INDICATION); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + UBX_CELL_utime_urc_configuration_t c; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_TIME_INDICATION); - // Response format: \r\n+UTIMEIND: \r\n\r\nOK\r\n - if (err == UBX_CELL_ERROR_SUCCESS) - { - int cStore, scanned = 0; - char *searchPtr = strstr(response, "+UTIMEIND:"); - if (searchPtr != nullptr) + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - searchPtr += strlen("+UTIMEIND:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d\r\n", &cStore); + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - c = (UBX_CELL_utime_urc_configuration_t)cStore; - if (scanned == 1) + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + // Response format: \r\n+UTIMEIND: \r\n\r\nOK\r\n + if (err == UBX_CELL_ERROR_SUCCESS) { - *config = c; + int cStore, scanned = 0; + char *searchPtr = strstr(response, "+UTIMEIND:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UTIMEIND:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d\r\n", &cStore); + } + c = (UBX_CELL_utime_urc_configuration_t)cStore; + if (scanned == 1) + { + *config = c; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - free(command); - free(response); - return err; + free(command); + free(response); + return err; } UBX_CELL_error_t SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); + sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); #else - sprintf(command, "%s=%ld,%ld", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); + sprintf(command, "%s=%ld,%ld", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); #endif - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; } UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds) { - UBX_CELL_error_t err; - char *command; - char *response; + UBX_CELL_error_t err; + char *command; + char *response; - int32_t ons; - int32_t os; + int32_t ons; + int32_t os; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_TIME_CONFIGURATION); + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_TIME_CONFIGURATION); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - // Response format: \r\n+UTIMECFG: ,\r\n\r\nOK\r\n - if (err == UBX_CELL_ERROR_SUCCESS) - { - int scanned = 0; - char *searchPtr = strstr(response, "+UTIMECFG:"); - if (searchPtr != nullptr) + // Response format: \r\n+UTIMECFG: ,\r\n\r\nOK\r\n + if (err == UBX_CELL_ERROR_SUCCESS) { - searchPtr += strlen("+UTIMECFG:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces + int scanned = 0; + char *searchPtr = strstr(response, "+UTIMECFG:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UTIMECFG:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - scanned = sscanf(searchPtr, "%d,%d\r\n", &ons, &os); + scanned = sscanf(searchPtr, "%d,%d\r\n", &ons, &os); #else - scanned = sscanf(searchPtr, "%ld,%ld\r\n", &ons, &os); + scanned = sscanf(searchPtr, "%ld,%ld\r\n", &ons, &os); #endif + } + if (scanned == 2) + { + *offsetNanoseconds = ons; + *offsetSeconds = os; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - if (scanned == 2) - { - *offsetNanoseconds = ons; - *offsetSeconds = os; - } - else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - free(command); - free(response); - return err; + free(command); + free(response); + return err; } UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - if (profile >= UBX_CELL_NUM_PSD_PROFILES) - return UBX_CELL_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, - value); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, UBX_CELL_pdp_protocol_type_t value) +UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, + UBX_CELL_pdp_protocol_type_t value) { - return (setPDPconfiguration(profile, parameter, (int)value)); + return (setPDPconfiguration(profile, parameter, (int)value)); } -UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, String value) +UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, + String value) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - if (profile >= UBX_CELL_NUM_PSD_PROFILES) - return UBX_CELL_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, - value.c_str()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value) +UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, + IPAddress value) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - if (profile >= UBX_CELL_NUM_PSD_PROFILES) - return UBX_CELL_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, - value[0], value[1], value[2], value[3]); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value[0], value[1], + value[2], value[3]); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } UBX_CELL_error_t SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t action) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - if (profile >= UBX_CELL_NUM_PSD_PROFILES) - return UBX_CELL_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_PSD_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_ACTION, profile, action); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_ACTION, profile, action); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *address) { - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int profileStore = 0; - int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation - int paramVals[4]; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBX_CELL_NETWORK_ASSIGNED_DATA, profile, paramTag); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+UPSND:"); - if (searchPtr != nullptr) + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int profileStore = 0; + int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation + int paramVals[4]; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", UBX_CELL_NETWORK_ASSIGNED_DATA, profile, paramTag); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - searchPtr += strlen("+UPSND:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d,\"%d.%d.%d.%d\"", - &profileStore, ¶mTag, - ¶mVals[0], ¶mVals[1], ¶mVals[2], ¶mVals[3]); + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - if (scanNum != 6) + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) { - if (_printDebug == true) - { - _debugPort->print(F("getNetworkAssignedIPAddress: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + char *searchPtr = strstr(response, "+UPSND:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UPSND:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,\"%d.%d.%d.%d\"", &profileStore, ¶mTag, ¶mVals[0], ¶mVals[1], + ¶mVals[2], ¶mVals[3]); + } + if (scanNum != 6) + { + if (_printDebug == true) + { + _debugPort->print(F("getNetworkAssignedIPAddress: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + IPAddress tempAddress = {(uint8_t)paramVals[0], (uint8_t)paramVals[1], (uint8_t)paramVals[2], + (uint8_t)paramVals[3]}; + *address = tempAddress; } - IPAddress tempAddress = { (uint8_t)paramVals[0], (uint8_t)paramVals[1], - (uint8_t)paramVals[2], (uint8_t)paramVals[3] }; - *address = tempAddress; - } - - free(command); - free(response); + free(command); + free(response); - return err; + return err; } -bool SARA_R5::urcHandlerPDPAction(const char* event) +bool SARA_R5::urcHandlerPDPAction(const char *event) { - // URC: +UUPSDA (Packet Switched Data Action) - int result; - IPAddress remoteIP = {0, 0, 0, 0}; - int scanNum; - int remoteIPstore[4]; - - char *searchPtr = strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\"", - &result, &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); - - if (scanNum == 5) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: packet switched data action")); - - for (int i = 0; i <= 3; i++) - { - remoteIP[i] = (uint8_t)remoteIPstore[i]; - } + // URC: +UUPSDA (Packet Switched Data Action) + int result; + IPAddress remoteIP = {0, 0, 0, 0}; + int scanNum; + int remoteIPstore[4]; - if (_psdActionRequestCallback != nullptr) - { - _psdActionRequestCallback(result, remoteIP); - } - - return true; + char *searchPtr = strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\"", &result, &remoteIPstore[0], &remoteIPstore[1], + &remoteIPstore[2], &remoteIPstore[3]); + + if (scanNum == 5) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: packet switched data action")); + + for (int i = 0; i <= 3; i++) + { + remoteIP[i] = (uint8_t)remoteIPstore[i]; + } + + if (_psdActionRequestCallback != nullptr) + { + _psdActionRequestCallback(result, remoteIP); + } + + return true; + } } - } - return false; + return false; } diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index ffa060c..a8189c7 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -3,64 +3,71 @@ #include "sfe_ublox_cellular.h" -const char* const UBX_CELL_MESSAGE_PDP_CONFIG = "+UPSD"; // Packet switched Data Profile configuration -const char* const UBX_CELL_MESSAGE_PDP_ACTION = "+UPSDA"; // Perform the action for the specified PSD profile -const char* const UBX_CELL_NETWORK_ASSIGNED_DATA = "+UPSND"; // Packet switched network-assigned data -const char* const UBX_CELL_GNSS_REQUEST_TIME = "+UTIME"; // Ask for time information from cellular modem (CellTime) -const char* const UBX_CELL_GNSS_TIME_INDICATION = "+UTIMEIND"; // Time information request status unsolicited indication -const char* const UBX_CELL_GNSS_TIME_CONFIGURATION = "+UTIMECFG"; // Sets time configuration +const char *const UBX_CELL_MESSAGE_PDP_CONFIG = "+UPSD"; // Packet switched Data Profile configuration +const char *const UBX_CELL_MESSAGE_PDP_ACTION = "+UPSDA"; // Perform the action for the specified PSD profile +const char *const UBX_CELL_NETWORK_ASSIGNED_DATA = "+UPSND"; // Packet switched network-assigned data +const char *const UBX_CELL_GNSS_REQUEST_TIME = "+UTIME"; // Ask for time information from cellular modem (CellTime) +const char *const UBX_CELL_GNSS_TIME_INDICATION = "+UTIMEIND"; // Time information request status unsolicited indication +const char *const UBX_CELL_GNSS_TIME_CONFIGURATION = "+UTIMECFG"; // Sets time configuration -const char* const UBX_CELL_MESSAGE_PDP_ACTION_URC = "+UUPSDA:"; +const char *const UBX_CELL_MESSAGE_PDP_ACTION_URC = "+UUPSDA:"; // Base SARA-R5 class -class SARA_R5: public UBX_CELL +class SARA_R5 : public UBX_CELL { -public: - SARA_R5(); - - UBX_CELL_error_t setUtimeMode(UBX_CELL_utime_mode_t mode = UBX_CELL_UTIME_MODE_PPS, UBX_CELL_utime_sensor_t sensor = UBX_CELL_UTIME_SENSOR_GNSS_LTE); // Time mode, source etc. (+UTIME) - UBX_CELL_error_t getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor); - UBX_CELL_error_t setUtimeIndication(UBX_CELL_utime_urc_configuration_t config = UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED); // +UTIMEIND - UBX_CELL_error_t getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config); - UBX_CELL_error_t setUtimeConfiguration(int32_t offsetNanoseconds = 0, int32_t offsetSeconds = 0); // +UTIMECFG - UBX_CELL_error_t getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds); - - // Packet Switched Data - // Configure the PDP using +UPSD. See UBX_CELL_pdp_configuration_parameter_t for the list of parameters: protocol, APN, username, DNS, etc. - UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value); // Set parameters in the chosen PSD profile - UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, UBX_CELL_pdp_protocol_type_t value); // Set parameters in the chosen PSD profile - UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, String value); // Set parameters in the chosen PSD profile - UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value); // Set parameters in the chosen PSD profile - UBX_CELL_error_t performPDPaction(int profile, UBX_CELL_pdp_actions_t action); // Performs the requested action for the specified PSD profile: reset, store, load, activate, deactivate - UBX_CELL_error_t getNetworkAssignedIPAddress(int profile, IPAddress *address); // Get the dynamic IP address assigned during PDP context activation - -protected: - bool urcHandlerPDPAction(const char* event); + public: + SARA_R5(); + + UBX_CELL_error_t setUtimeMode( + UBX_CELL_utime_mode_t mode = UBX_CELL_UTIME_MODE_PPS, + UBX_CELL_utime_sensor_t sensor = UBX_CELL_UTIME_SENSOR_GNSS_LTE); // Time mode, source etc. (+UTIME) + UBX_CELL_error_t getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor); + UBX_CELL_error_t setUtimeIndication( + UBX_CELL_utime_urc_configuration_t config = UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED); // +UTIMEIND + UBX_CELL_error_t getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config); + UBX_CELL_error_t setUtimeConfiguration(int32_t offsetNanoseconds = 0, int32_t offsetSeconds = 0); // +UTIMECFG + UBX_CELL_error_t getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds); + + // Packet Switched Data + // Configure the PDP using +UPSD. See UBX_CELL_pdp_configuration_parameter_t for the list of parameters: protocol, + // APN, username, DNS, etc. + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, + int value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t setPDPconfiguration( + int profile, UBX_CELL_pdp_configuration_parameter_t parameter, + UBX_CELL_pdp_protocol_type_t value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, + String value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, + IPAddress value); // Set parameters in the chosen PSD profile + UBX_CELL_error_t performPDPaction( + int profile, UBX_CELL_pdp_actions_t action); // Performs the requested action for the specified PSD profile: + // reset, store, load, activate, deactivate + UBX_CELL_error_t getNetworkAssignedIPAddress( + int profile, IPAddress *address); // Get the dynamic IP address assigned during PDP context activation + + protected: + bool urcHandlerPDPAction(const char *event); }; -class SARA_R500S: public SARA_R5 +class SARA_R500S : public SARA_R5 { - }; -class SARA_R500S_01B: public SARA_R5 +class SARA_R500S_01B : public SARA_R5 { - }; -class SARA_R500S_61B: public SARA_R5 +class SARA_R500S_61B : public SARA_R5 { - }; -class SARA_R510M8S_61B: public SARA_R5 +class SARA_R510M8S_61B : public SARA_R5 { - }; -class SARA_R510S: public SARA_R5 +class SARA_R510S : public SARA_R5 { - }; #endif \ No newline at end of file diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index 9a9ae0a..e7fbe8f 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -1,7 +1,6 @@ /* - Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod Asset Tracker - By: Paul Clark - October 19th 2020 + Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod + Asset Tracker By: Paul Clark October 19th 2020 Based extensively on the: Arduino Library for the SparkFun LTE CAT M1/NB-IoT Shield - SARA-R4 @@ -19,187 +18,196 @@ UBX_CELL::UBX_CELL(int powerPin, int resetPin, uint8_t maxInitTries) { #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - _softSerial = nullptr; + _softSerial = nullptr; #endif - _hardSerial = nullptr; - _baud = 0; - _resetPin = resetPin; - _powerPin = powerPin; - _invertPowerPin = false; - _maxInitTries = maxInitTries; - _socketListenCallback = nullptr; - _socketReadCallback = nullptr; - _socketReadCallbackPlus = nullptr; - _socketCloseCallback = nullptr; - _gpsRequestCallback = nullptr; - _simStateReportCallback = nullptr; - _psdActionRequestCallback = nullptr; - _pingRequestCallback = nullptr; - _httpCommandRequestCallback = nullptr; - _mqttCommandRequestCallback = nullptr; - _registrationCallback = nullptr; - _epsRegistrationCallback = nullptr; - _debugAtPort = nullptr; - _debugPort = nullptr; - _printDebug = false; - _lastRemoteIP = {0, 0, 0, 0}; - _lastLocalIP = {0, 0, 0, 0}; - for (int i = 0; i < UBX_CELL_NUM_SOCKETS; i++) - _lastSocketProtocol[i] = 0; // Set to zero initially. Will be set to TCP/UDP by socketOpen etc. - _autoTimeZoneForBegin = true; - _bufferedPollReentrant = false; - _pollReentrant = false; - _saraResponseBacklogLength = 0; - _saraRXBuffer = nullptr; - _pruneBuffer = nullptr; - _saraResponseBacklog = nullptr; - - // Add base URC handlers - addURCHandler(UBX_CELL_READ_SOCKET_URC, [this](const char* event){return this->urcHandlerReadSocket(event);}); - addURCHandler(UBX_CELL_READ_UDP_SOCKET_URC, [this](const char* event){return this->urcHandlerReadUDPSocket(event);}); - addURCHandler(UBX_CELL_LISTEN_SOCKET_URC, [this](const char* event){return this->urcHandlerListeningSocket(event);}); - addURCHandler(UBX_CELL_CLOSE_SOCKET_URC, [this](const char* event){return this->urcHandlerCloseSocket(event);}); - addURCHandler(UBX_CELL_GNSS_REQUEST_LOCATION_URC, [this](const char* event){return this->urcHandlerGNSSRequestLocation(event);}); - addURCHandler(UBX_CELL_SIM_STATE_URC, [this](const char* event){return this->urcHandlerSIMState(event);}); - addURCHandler(UBX_CELL_HTTP_COMMAND_URC, [this](const char* event){return this->urcHandlerHTTPCommand(event);}); - addURCHandler(UBX_CELL_MQTT_COMMAND_URC, [this](const char* event){return this->urcHandlerMQTTCommand(event);}); - addURCHandler(UBX_CELL_PING_COMMAND_URC, [this](const char* event){return this->urcHandlerPingCommand(event);}); - addURCHandler(UBX_CELL_FTP_COMMAND_URC, [this](const char* event){return this->urcHandlerFTPCommand(event);}); - addURCHandler(UBX_CELL_REGISTRATION_STATUS_URC, [this](const char* event){return this->urcHandlerRegistrationStatus(event);}); - addURCHandler(UBX_CELL_EPSREGISTRATION_STATUS_URC, [this](const char* event){return this->urcHandlerEPSRegistrationStatus(event);}); -} - -UBX_CELL::~UBX_CELL(void) { - if (nullptr != _saraRXBuffer) { - delete[] _saraRXBuffer; + _hardSerial = nullptr; + _baud = 0; + _resetPin = resetPin; + _powerPin = powerPin; + _invertPowerPin = false; + _maxInitTries = maxInitTries; + _socketListenCallback = nullptr; + _socketReadCallback = nullptr; + _socketReadCallbackPlus = nullptr; + _socketCloseCallback = nullptr; + _gpsRequestCallback = nullptr; + _simStateReportCallback = nullptr; + _psdActionRequestCallback = nullptr; + _pingRequestCallback = nullptr; + _httpCommandRequestCallback = nullptr; + _mqttCommandRequestCallback = nullptr; + _registrationCallback = nullptr; + _epsRegistrationCallback = nullptr; + _debugAtPort = nullptr; + _debugPort = nullptr; + _printDebug = false; + _lastRemoteIP = {0, 0, 0, 0}; + _lastLocalIP = {0, 0, 0, 0}; + for (int i = 0; i < UBX_CELL_NUM_SOCKETS; i++) + _lastSocketProtocol[i] = 0; // Set to zero initially. Will be set to TCP/UDP by socketOpen etc. + _autoTimeZoneForBegin = true; + _bufferedPollReentrant = false; + _pollReentrant = false; + _saraResponseBacklogLength = 0; _saraRXBuffer = nullptr; - } - if (nullptr != _pruneBuffer) { - delete[] _pruneBuffer; _pruneBuffer = nullptr; - } - if (nullptr != _saraResponseBacklog) { - delete[] _saraResponseBacklog; _saraResponseBacklog = nullptr; - } + + // Add base URC handlers + addURCHandler(UBX_CELL_READ_SOCKET_URC, [this](const char *event) { return this->urcHandlerReadSocket(event); }); + addURCHandler(UBX_CELL_READ_UDP_SOCKET_URC, + [this](const char *event) { return this->urcHandlerReadUDPSocket(event); }); + addURCHandler(UBX_CELL_LISTEN_SOCKET_URC, + [this](const char *event) { return this->urcHandlerListeningSocket(event); }); + addURCHandler(UBX_CELL_CLOSE_SOCKET_URC, [this](const char *event) { return this->urcHandlerCloseSocket(event); }); + addURCHandler(UBX_CELL_GNSS_REQUEST_LOCATION_URC, + [this](const char *event) { return this->urcHandlerGNSSRequestLocation(event); }); + addURCHandler(UBX_CELL_SIM_STATE_URC, [this](const char *event) { return this->urcHandlerSIMState(event); }); + addURCHandler(UBX_CELL_HTTP_COMMAND_URC, [this](const char *event) { return this->urcHandlerHTTPCommand(event); }); + addURCHandler(UBX_CELL_MQTT_COMMAND_URC, [this](const char *event) { return this->urcHandlerMQTTCommand(event); }); + addURCHandler(UBX_CELL_PING_COMMAND_URC, [this](const char *event) { return this->urcHandlerPingCommand(event); }); + addURCHandler(UBX_CELL_FTP_COMMAND_URC, [this](const char *event) { return this->urcHandlerFTPCommand(event); }); + addURCHandler(UBX_CELL_REGISTRATION_STATUS_URC, + [this](const char *event) { return this->urcHandlerRegistrationStatus(event); }); + addURCHandler(UBX_CELL_EPSREGISTRATION_STATUS_URC, + [this](const char *event) { return this->urcHandlerEPSRegistrationStatus(event); }); +} + +UBX_CELL::~UBX_CELL(void) +{ + if (nullptr != _saraRXBuffer) + { + delete[] _saraRXBuffer; + _saraRXBuffer = nullptr; + } + if (nullptr != _pruneBuffer) + { + delete[] _pruneBuffer; + _pruneBuffer = nullptr; + } + if (nullptr != _saraResponseBacklog) + { + delete[] _saraResponseBacklog; + _saraResponseBacklog = nullptr; + } } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED bool UBX_CELL::begin(SoftwareSerial &softSerial, unsigned long baud) { - if (nullptr == _saraRXBuffer) - { - _saraRXBuffer = new char[_RXBuffSize]; if (nullptr == _saraRXBuffer) { - if (_printDebug == true) - _debugPort->println(F("begin: not enough memory for _saraRXBuffer!")); - return false; + _saraRXBuffer = new char[_RXBuffSize]; + if (nullptr == _saraRXBuffer) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _saraRXBuffer!")); + return false; + } } - } - memset(_saraRXBuffer, 0, _RXBuffSize); + memset(_saraRXBuffer, 0, _RXBuffSize); - if (nullptr == _pruneBuffer) - { - _pruneBuffer = new char[_RXBuffSize]; if (nullptr == _pruneBuffer) { - if (_printDebug == true) - _debugPort->println(F("begin: not enough memory for _pruneBuffer!")); - return false; + _pruneBuffer = new char[_RXBuffSize]; + if (nullptr == _pruneBuffer) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _pruneBuffer!")); + return false; + } } - } - memset(_pruneBuffer, 0, _RXBuffSize); + memset(_pruneBuffer, 0, _RXBuffSize); - if (nullptr == _saraResponseBacklog) - { - _saraResponseBacklog = new char[_RXBuffSize]; if (nullptr == _saraResponseBacklog) { - if (_printDebug == true) - _debugPort->println(F("begin: not enough memory for _saraResponseBacklog!")); - return false; + _saraResponseBacklog = new char[_RXBuffSize]; + if (nullptr == _saraResponseBacklog) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _saraResponseBacklog!")); + return false; + } } - } - memset(_saraResponseBacklog, 0, _RXBuffSize); + memset(_saraResponseBacklog, 0, _RXBuffSize); - UBX_CELL_error_t err; + UBX_CELL_error_t err; - _softSerial = &softSerial; + _softSerial = &softSerial; - err = init(baud); - if (err == UBX_CELL_ERROR_SUCCESS) - { - return true; - } - return false; + err = init(baud); + if (err == UBX_CELL_ERROR_SUCCESS) + { + return true; + } + return false; } #endif bool UBX_CELL::begin(HardwareSerial &hardSerial, unsigned long baud) { - if (nullptr == _saraRXBuffer) - { - _saraRXBuffer = new char[_RXBuffSize]; if (nullptr == _saraRXBuffer) { - if (_printDebug == true) - _debugPort->println(F("begin: not enough memory for _saraRXBuffer!")); - return false; + _saraRXBuffer = new char[_RXBuffSize]; + if (nullptr == _saraRXBuffer) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _saraRXBuffer!")); + return false; + } } - } - memset(_saraRXBuffer, 0, _RXBuffSize); + memset(_saraRXBuffer, 0, _RXBuffSize); - if (nullptr == _pruneBuffer) - { - _pruneBuffer = new char[_RXBuffSize]; if (nullptr == _pruneBuffer) { - if (_printDebug == true) - _debugPort->println(F("begin: not enough memory for _pruneBuffer!")); - return false; + _pruneBuffer = new char[_RXBuffSize]; + if (nullptr == _pruneBuffer) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _pruneBuffer!")); + return false; + } } - } - memset(_pruneBuffer, 0, _RXBuffSize); + memset(_pruneBuffer, 0, _RXBuffSize); - if (nullptr == _saraResponseBacklog) - { - _saraResponseBacklog = new char[_RXBuffSize]; if (nullptr == _saraResponseBacklog) { - if (_printDebug == true) - _debugPort->println(F("begin: not enough memory for _saraResponseBacklog!")); - return false; + _saraResponseBacklog = new char[_RXBuffSize]; + if (nullptr == _saraResponseBacklog) + { + if (_printDebug == true) + _debugPort->println(F("begin: not enough memory for _saraResponseBacklog!")); + return false; + } } - } - memset(_saraResponseBacklog, 0, _RXBuffSize); + memset(_saraResponseBacklog, 0, _RXBuffSize); - UBX_CELL_error_t err; + UBX_CELL_error_t err; - _hardSerial = &hardSerial; + _hardSerial = &hardSerial; - err = init(baud); - if (err == UBX_CELL_ERROR_SUCCESS) - { - return true; - } - return false; + err = init(baud); + if (err == UBX_CELL_ERROR_SUCCESS) + { + return true; + } + return false; } -//Calling this function with nothing sets the debug port to Serial -//You can also call it with other streams like Serial1, SerialUSB, etc. +// Calling this function with nothing sets the debug port to Serial +// You can also call it with other streams like Serial1, SerialUSB, etc. void UBX_CELL::enableDebugging(Print &debugPort) { - _debugPort = &debugPort; - _printDebug = true; + _debugPort = &debugPort; + _printDebug = true; } -//Calling this function with nothing sets the debug port to Serial -//You can also call it with other streams like Serial1, SerialUSB, etc. +// Calling this function with nothing sets the debug port to Serial +// You can also call it with other streams like Serial1, SerialUSB, etc. void UBX_CELL::enableAtDebugging(Print &debugPort) { - _debugAtPort = &debugPort; - _printAtDebug = true; + _debugAtPort = &debugPort; + _printAtDebug = true; } // This function was originally written by Matthew Menze for the LTE Shield (SARA-R4) library @@ -208,625 +216,637 @@ void UBX_CELL::enableAtDebugging(Print &debugPort) // It also has a built-in timeout - which ::poll does not bool UBX_CELL::bufferedPoll(void) { - if (_bufferedPollReentrant == true) // Check for reentry (i.e. bufferedPoll has been called from inside a callback) - return false; + if (_bufferedPollReentrant == true) // Check for reentry (i.e. bufferedPoll has been called from inside a callback) + return false; - _bufferedPollReentrant = true; + _bufferedPollReentrant = true; - int avail = 0; - char c = 0; - bool handled = false; - unsigned long timeIn = millis(); - char *event; - int backlogLen = _saraResponseBacklogLength; + int avail = 0; + char c = 0; + bool handled = false; + unsigned long timeIn = millis(); + char *event; + int backlogLen = _saraResponseBacklogLength; - memset(_saraRXBuffer, 0, _RXBuffSize); // Clear _saraRXBuffer + memset(_saraRXBuffer, 0, _RXBuffSize); // Clear _saraRXBuffer - // Does the backlog contain any data? If it does, copy it into _saraRXBuffer and then clear the backlog - if (_saraResponseBacklogLength > 0) - { - //The backlog also logs reads from other tasks like transmitting. - if (_printDebug == true) + // Does the backlog contain any data? If it does, copy it into _saraRXBuffer and then clear the backlog + if (_saraResponseBacklogLength > 0) { - _debugPort->print(F("bufferedPoll: backlog found! backlogLen is ")); - _debugPort->println(_saraResponseBacklogLength); - } - memcpy(_saraRXBuffer + avail, _saraResponseBacklog, _saraResponseBacklogLength); - avail += _saraResponseBacklogLength; - memset(_saraResponseBacklog, 0, _RXBuffSize); // Clear the backlog making sure it is NULL-terminated - _saraResponseBacklogLength = 0; - } - - if ((hwAvailable() > 0) || (backlogLen > 0)) // If either new data is available, or backlog had data. - { - //Check for incoming serial data. Copy it into the backlog - - // Important note: - // On ESP32, Serial.available only provides an update every ~120 bytes during the reception of long messages: - // https://gitter.im/espressif/arduino-esp32?at=5e25d6370a1cf54144909c85 - // Be aware that if a long message is being received, the code below will timeout after _rxWindowMillis = 2 millis. - // At 115200 baud, hwAvailable takes ~120 * 10 / 115200 = 10.4 millis before it indicates that data is being received. - - while (((millis() - timeIn) < _rxWindowMillis) && (avail < _RXBuffSize)) - { - if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL - { - c = readChar(); - // bufferedPoll is only interested in the URCs. - // The URCs are all readable. - // strtok does not like NULL characters. - // So we need to make sure no NULL characters are added to _saraRXBuffer - if (c == '\0') - c = '0'; // Convert any NULLs to ASCII Zeros - _saraRXBuffer[avail++] = c; - timeIn = millis(); - } else { - yield(); - } - } - - // _saraRXBuffer now contains the backlog (if any) and the new serial data (if any) - - // A health warning about strtok: - // strtok will convert any delimiters it finds ("\r\n" in our case) into NULL characters. - // Also, be very careful that you do not use strtok within an strtok while loop. - // The next call of strtok(NULL, ...) in the outer loop will use the pointer saved from the inner loop! - // In our case, strtok is also used in pruneBacklog, which is called by waitForRespone or sendCommandWithResponse, - // which is called by the parse functions called by processURCEvent... - // The solution is to use strtok_r - the reentrant version of strtok - - char *preservedEvent; - event = strtok_r(_saraRXBuffer, "\r\n", &preservedEvent); // Look for an 'event' (_saraRXBuffer contains something ending in \r\n) - - if (event != nullptr) - if (_printDebug == true) - _debugPort->println(F("bufferedPoll: event(s) found! ===>")); - - while (event != nullptr) // Keep going until all events have been processed - { - if (_printDebug == true) - { - _debugPort->print(F("bufferedPoll: start of event: ")); - _debugPort->println(event); - } - - //Process the event - bool latestHandled = processURCEvent((const char *)event); - if (latestHandled) { - if ((true == _printAtDebug) && (nullptr != event)) { - _debugAtPort->print(event); - } - handled = true; // handled will be true if latestHandled has ever been true - } - if ((_saraResponseBacklogLength > 0) && ((avail + _saraResponseBacklogLength) < _RXBuffSize)) // Has any new data been added to the backlog? - { + // The backlog also logs reads from other tasks like transmitting. if (_printDebug == true) { - _debugPort->println(F("bufferedPoll: new backlog added!")); + _debugPort->print(F("bufferedPoll: backlog found! backlogLen is ")); + _debugPort->println(_saraResponseBacklogLength); } memcpy(_saraRXBuffer + avail, _saraResponseBacklog, _saraResponseBacklogLength); avail += _saraResponseBacklogLength; - memset(_saraResponseBacklog, 0, _RXBuffSize); //Clear out the backlog buffer again. + memset(_saraResponseBacklog, 0, _RXBuffSize); // Clear the backlog making sure it is NULL-terminated _saraResponseBacklogLength = 0; - } + } - //Walk through any remaining events - event = strtok_r(nullptr, "\r\n", &preservedEvent); + if ((hwAvailable() > 0) || (backlogLen > 0)) // If either new data is available, or backlog had data. + { + // Check for incoming serial data. Copy it into the backlog - if (_printDebug == true) - _debugPort->println(F("bufferedPoll: end of event")); //Just to denote end of processing event. + // Important note: + // On ESP32, Serial.available only provides an update every ~120 bytes during the reception of long messages: + // https://gitter.im/espressif/arduino-esp32?at=5e25d6370a1cf54144909c85 + // Be aware that if a long message is being received, the code below will timeout after _rxWindowMillis = 2 + // millis. At 115200 baud, hwAvailable takes ~120 * 10 / 115200 = 10.4 millis before it indicates that data is + // being received. - if (event == nullptr) - if (_printDebug == true) - _debugPort->println(F("bufferedPoll: <=== end of event(s)!")); + while (((millis() - timeIn) < _rxWindowMillis) && (avail < _RXBuffSize)) + { + if (hwAvailable() > 0) // hwAvailable can return -1 if the serial port is NULL + { + c = readChar(); + // bufferedPoll is only interested in the URCs. + // The URCs are all readable. + // strtok does not like NULL characters. + // So we need to make sure no NULL characters are added to _saraRXBuffer + if (c == '\0') + c = '0'; // Convert any NULLs to ASCII Zeros + _saraRXBuffer[avail++] = c; + timeIn = millis(); + } + else + { + yield(); + } + } + + // _saraRXBuffer now contains the backlog (if any) and the new serial data (if any) + + // A health warning about strtok: + // strtok will convert any delimiters it finds ("\r\n" in our case) into NULL characters. + // Also, be very careful that you do not use strtok within an strtok while loop. + // The next call of strtok(NULL, ...) in the outer loop will use the pointer saved from the inner loop! + // In our case, strtok is also used in pruneBacklog, which is called by waitForRespone or + // sendCommandWithResponse, which is called by the parse functions called by processURCEvent... The solution is + // to use strtok_r - the reentrant version of strtok + + char *preservedEvent; + event = strtok_r(_saraRXBuffer, "\r\n", + &preservedEvent); // Look for an 'event' (_saraRXBuffer contains something ending in \r\n) + + if (event != nullptr) + if (_printDebug == true) + _debugPort->println(F("bufferedPoll: event(s) found! ===>")); + + while (event != nullptr) // Keep going until all events have been processed + { + if (_printDebug == true) + { + _debugPort->print(F("bufferedPoll: start of event: ")); + _debugPort->println(event); + } + + // Process the event + bool latestHandled = processURCEvent((const char *)event); + if (latestHandled) + { + if ((true == _printAtDebug) && (nullptr != event)) + { + _debugAtPort->print(event); + } + handled = true; // handled will be true if latestHandled has ever been true + } + if ((_saraResponseBacklogLength > 0) && + ((avail + _saraResponseBacklogLength) < _RXBuffSize)) // Has any new data been added to the backlog? + { + if (_printDebug == true) + { + _debugPort->println(F("bufferedPoll: new backlog added!")); + } + memcpy(_saraRXBuffer + avail, _saraResponseBacklog, _saraResponseBacklogLength); + avail += _saraResponseBacklogLength; + memset(_saraResponseBacklog, 0, _RXBuffSize); // Clear out the backlog buffer again. + _saraResponseBacklogLength = 0; + } + + // Walk through any remaining events + event = strtok_r(nullptr, "\r\n", &preservedEvent); + + if (_printDebug == true) + _debugPort->println(F("bufferedPoll: end of event")); // Just to denote end of processing event. + + if (event == nullptr) + if (_printDebug == true) + _debugPort->println(F("bufferedPoll: <=== end of event(s)!")); + } } - } - _bufferedPollReentrant = false; + _bufferedPollReentrant = false; - return handled; + return handled; } // /bufferedPoll -bool UBX_CELL::urcHandlerReadSocket(const char* event) -{ - // URC: +UUSORD (Read Socket Data) - int socket, length; - char *searchPtr = strstr(event, UBX_CELL_READ_SOCKET_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_READ_SOCKET_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // Skip spaces - int ret = sscanf(searchPtr, "%d,%d", &socket, &length); - if (ret == 2) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: read socket data")); - // From the UBX_CELL AT Commands Manual: - // "For the UDP socket type the URC +UUSORD: , notifies that a UDP packet has been received, - // either when buffer is empty or after a UDP packet has been read and one or more packets are stored in the - // buffer." - // So we need to check if this is a TCP socket or a UDP socket: - // If UDP, we call parseSocketReadIndicationUDP. - // Otherwise, we call parseSocketReadIndication. - if (_lastSocketProtocol[socket] == UBX_CELL_UDP) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: received +UUSORD but socket is UDP. Calling parseSocketReadIndicationUDP")); - parseSocketReadIndicationUDP(socket, length); - } - else - parseSocketReadIndication(socket, length); - return true; +bool UBX_CELL::urcHandlerReadSocket(const char *event) +{ + // URC: +UUSORD (Read Socket Data) + int socket, length; + char *searchPtr = strstr(event, UBX_CELL_READ_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_READ_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // Skip spaces + int ret = sscanf(searchPtr, "%d,%d", &socket, &length); + if (ret == 2) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: read socket data")); + // From the UBX_CELL AT Commands Manual: + // "For the UDP socket type the URC +UUSORD: , notifies that a UDP packet has been received, + // either when buffer is empty or after a UDP packet has been read and one or more packets are stored in + // the buffer." + // So we need to check if this is a TCP socket or a UDP socket: + // If UDP, we call parseSocketReadIndicationUDP. + // Otherwise, we call parseSocketReadIndication. + if (_lastSocketProtocol[socket] == UBX_CELL_UDP) + { + if (_printDebug == true) + _debugPort->println(F( + "processReadEvent: received +UUSORD but socket is UDP. Calling parseSocketReadIndicationUDP")); + parseSocketReadIndicationUDP(socket, length); + } + else + parseSocketReadIndication(socket, length); + return true; + } + } + + return false; +} + +bool UBX_CELL::urcHandlerReadUDPSocket(const char *event) +{ + // URC: +UUSORF (Receive From command (UDP only)) + int socket, length; + char *searchPtr = strstr(event, UBX_CELL_READ_UDP_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_READ_UDP_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + int ret = sscanf(searchPtr, "%d,%d", &socket, &length); + if (ret == 2) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: UDP receive")); + parseSocketReadIndicationUDP(socket, length); + return true; + } } - } - return false; + return false; } -bool UBX_CELL::urcHandlerReadUDPSocket(const char* event) +bool UBX_CELL::urcHandlerListeningSocket(const char *event) { - // URC: +UUSORF (Receive From command (UDP only)) - int socket, length; - char *searchPtr = strstr(event, UBX_CELL_READ_UDP_SOCKET_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_READ_UDP_SOCKET_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int ret = sscanf(searchPtr, "%d,%d", &socket, &length); - if (ret == 2) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: UDP receive")); - parseSocketReadIndicationUDP(socket, length); - return true; - } - } - - return false; -} - -bool UBX_CELL::urcHandlerListeningSocket(const char* event) -{ - // URC: +UUSOLI (Set Listening Socket) - int socket = 0; - int listenSocket = 0; - unsigned int port = 0; - unsigned int listenPort = 0; - IPAddress remoteIP = {0,0,0,0}; - IPAddress localIP = {0,0,0,0}; - int remoteIPstore[4] = {0,0,0,0}; - int localIPstore[4] = {0,0,0,0}; - - char *searchPtr = strstr(event, UBX_CELL_LISTEN_SOCKET_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_LISTEN_SOCKET_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int ret = sscanf(searchPtr, - "%d,\"%d.%d.%d.%d\",%u,%d,\"%d.%d.%d.%d\",%u", - &socket, - &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], - &port, &listenSocket, - &localIPstore[0], &localIPstore[1], &localIPstore[2], &localIPstore[3], - &listenPort); - for (int i = 0; i <= 3; i++) - { - if (ret >= 5) - remoteIP[i] = (uint8_t)remoteIPstore[i]; - if (ret >= 11) - localIP[i] = (uint8_t)localIPstore[i]; - } - if (ret >= 5) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: socket listen")); - parseSocketListenIndication(listenSocket, localIP, listenPort, socket, remoteIP, port); - return true; - } - } - - return false; -} - -bool UBX_CELL::urcHandlerCloseSocket(const char* event) -{ - // URC: +UUSOCL (Close Socket) - int socket; - char *searchPtr = strstr(event, UBX_CELL_CLOSE_SOCKET_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_CLOSE_SOCKET_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int ret = sscanf(searchPtr, "%d", &socket); - if (ret == 1) - { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: socket close")); - if ((socket >= 0) && (socket <= 6)) - { - if (_socketCloseCallback != nullptr) - { - _socketCloseCallback(socket); - } - } - return true; - } - } - - return false; -} - -bool UBX_CELL::urcHandlerGNSSRequestLocation(const char* event) -{ - // URC: +UULOC (Localization information - CellLocate and hybrid positioning) - ClockData clck; - PositionData gps; - SpeedData spd; - unsigned long uncertainty; - int scanNum; - int latH, lonH, alt; - unsigned int speedU, cogU; - char latL[10], lonL[10]; - int dateStore[5]; - - // Maybe we should also scan for +UUGIND and extract the activated gnss system? - - // This assumes the ULOC response type is "0" or "1" - as selected by gpsRequest detailed - char *searchPtr = strstr(event, UBX_CELL_GNSS_REQUEST_LOCATION_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_GNSS_REQUEST_LOCATION_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, - "%d/%d/%d,%d:%d:%d.%d,%d.%[^,],%d.%[^,],%d,%lu,%u,%u,%*s", - &dateStore[0], &dateStore[1], &clck.date.year, - &dateStore[2], &dateStore[3], &dateStore[4], &clck.time.ms, - &latH, latL, &lonH, lonL, &alt, &uncertainty, - &speedU, &cogU); - clck.date.day = dateStore[0]; - clck.date.month = dateStore[1]; - clck.time.hour = dateStore[2]; - clck.time.minute = dateStore[3]; - clck.time.second = dateStore[4]; - - if (scanNum >= 13) - { - // Found a Location string! - if (_printDebug == true) - { - _debugPort->println(F("processReadEvent: location")); - } - - if (latH >= 0) - gps.lat = (float)latH + ((float)atol(latL) / pow(10, strlen(latL))); - else - gps.lat = (float)latH - ((float)atol(latL) / pow(10, strlen(latL))); - if (lonH >= 0) - gps.lon = (float)lonH + ((float)atol(lonL) / pow(10, strlen(lonL))); - else - gps.lon = (float)lonH - ((float)atol(lonL) / pow(10, strlen(lonL))); - gps.alt = (float)alt; - if (scanNum >= 15) // If detailed response, get speed data - { - spd.speed = (float)speedU; - spd.cog = (float)cogU; - } + // URC: +UUSOLI (Set Listening Socket) + int socket = 0; + int listenSocket = 0; + unsigned int port = 0; + unsigned int listenPort = 0; + IPAddress remoteIP = {0, 0, 0, 0}; + IPAddress localIP = {0, 0, 0, 0}; + int remoteIPstore[4] = {0, 0, 0, 0}; + int localIPstore[4] = {0, 0, 0, 0}; - // if (_printDebug == true) - // { - // _debugPort->print(F("processReadEvent: location: lat: ")); - // _debugPort->print(gps.lat, 7); - // _debugPort->print(F(" lon: ")); - // _debugPort->print(gps.lon, 7); - // _debugPort->print(F(" alt: ")); - // _debugPort->print(gps.alt, 2); - // _debugPort->print(F(" speed: ")); - // _debugPort->print(spd.speed, 2); - // _debugPort->print(F(" cog: ")); - // _debugPort->println(spd.cog, 2); - // } + char *searchPtr = strstr(event, UBX_CELL_LISTEN_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_LISTEN_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + int ret = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\",%u,%d,\"%d.%d.%d.%d\",%u", &socket, &remoteIPstore[0], + &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], &port, &listenSocket, + &localIPstore[0], &localIPstore[1], &localIPstore[2], &localIPstore[3], &listenPort); + for (int i = 0; i <= 3; i++) + { + if (ret >= 5) + remoteIP[i] = (uint8_t)remoteIPstore[i]; + if (ret >= 11) + localIP[i] = (uint8_t)localIPstore[i]; + } + if (ret >= 5) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: socket listen")); + parseSocketListenIndication(listenSocket, localIP, listenPort, socket, remoteIP, port); + return true; + } + } - if (_gpsRequestCallback != nullptr) - { - _gpsRequestCallback(clck, gps, spd, uncertainty); - } + return false; +} - return true; +bool UBX_CELL::urcHandlerCloseSocket(const char *event) +{ + // URC: +UUSOCL (Close Socket) + int socket; + char *searchPtr = strstr(event, UBX_CELL_CLOSE_SOCKET_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_CLOSE_SOCKET_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + int ret = sscanf(searchPtr, "%d", &socket); + if (ret == 1) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: socket close")); + if ((socket >= 0) && (socket <= 6)) + { + if (_socketCloseCallback != nullptr) + { + _socketCloseCallback(socket); + } + } + return true; + } } - } - return false; + return false; } -bool UBX_CELL::urcHandlerSIMState(const char* event) +bool UBX_CELL::urcHandlerGNSSRequestLocation(const char *event) { - // URC: +UUSIMSTAT (SIM Status) - UBX_CELL_sim_states_t state; - int scanNum; - int stateStore; + // URC: +UULOC (Localization information - CellLocate and hybrid positioning) + ClockData clck; + PositionData gps; + SpeedData spd; + unsigned long uncertainty; + int scanNum; + int latH, lonH, alt; + unsigned int speedU, cogU; + char latL[10], lonL[10]; + int dateStore[5]; - char *searchPtr = strstr(event, UBX_CELL_SIM_STATE_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_SIM_STATE_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d", &stateStore); + // Maybe we should also scan for +UUGIND and extract the activated gnss system? - if (scanNum == 1) + // This assumes the ULOC response type is "0" or "1" - as selected by gpsRequest detailed + char *searchPtr = strstr(event, UBX_CELL_GNSS_REQUEST_LOCATION_URC); + if (searchPtr != nullptr) { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: SIM status")); + searchPtr += strlen(UBX_CELL_GNSS_REQUEST_LOCATION_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d/%d/%d,%d:%d:%d.%d,%d.%[^,],%d.%[^,],%d,%lu,%u,%u,%*s", &dateStore[0], + &dateStore[1], &clck.date.year, &dateStore[2], &dateStore[3], &dateStore[4], &clck.time.ms, + &latH, latL, &lonH, lonL, &alt, &uncertainty, &speedU, &cogU); + clck.date.day = dateStore[0]; + clck.date.month = dateStore[1]; + clck.time.hour = dateStore[2]; + clck.time.minute = dateStore[3]; + clck.time.second = dateStore[4]; + + if (scanNum >= 13) + { + // Found a Location string! + if (_printDebug == true) + { + _debugPort->println(F("processReadEvent: location")); + } - state = (UBX_CELL_sim_states_t)stateStore; + if (latH >= 0) + gps.lat = (float)latH + ((float)atol(latL) / pow(10, strlen(latL))); + else + gps.lat = (float)latH - ((float)atol(latL) / pow(10, strlen(latL))); + if (lonH >= 0) + gps.lon = (float)lonH + ((float)atol(lonL) / pow(10, strlen(lonL))); + else + gps.lon = (float)lonH - ((float)atol(lonL) / pow(10, strlen(lonL))); + gps.alt = (float)alt; + if (scanNum >= 15) // If detailed response, get speed data + { + spd.speed = (float)speedU; + spd.cog = (float)cogU; + } - if (_simStateReportCallback != nullptr) - { - _simStateReportCallback(state); - } + // if (_printDebug == true) + // { + // _debugPort->print(F("processReadEvent: location: lat: ")); + // _debugPort->print(gps.lat, 7); + // _debugPort->print(F(" lon: ")); + // _debugPort->print(gps.lon, 7); + // _debugPort->print(F(" alt: ")); + // _debugPort->print(gps.alt, 2); + // _debugPort->print(F(" speed: ")); + // _debugPort->print(spd.speed, 2); + // _debugPort->print(F(" cog: ")); + // _debugPort->println(spd.cog, 2); + // } + + if (_gpsRequestCallback != nullptr) + { + _gpsRequestCallback(clck, gps, spd, uncertainty); + } - return true; + return true; + } } - } - return false; + return false; } -bool UBX_CELL::urcHandlerHTTPCommand(const char* event) +bool UBX_CELL::urcHandlerSIMState(const char *event) { - // URC: +UUHTTPCR (HTTP Command Result) - int profile, command, result; - int scanNum; + // URC: +UUSIMSTAT (SIM Status) + UBX_CELL_sim_states_t state; + int scanNum; + int stateStore; - char *searchPtr = strstr(event, UBX_CELL_HTTP_COMMAND_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_HTTP_COMMAND_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d,%d", &profile, &command, &result); - - if (scanNum == 3) + char *searchPtr = strstr(event, UBX_CELL_SIM_STATE_URC); + if (searchPtr != nullptr) { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: HTTP command result")); + searchPtr += strlen(UBX_CELL_SIM_STATE_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d", &stateStore); - if ((profile >= 0) && (profile < UBX_CELL_NUM_HTTP_PROFILES)) - { - if (_httpCommandRequestCallback != nullptr) + if (scanNum == 1) { - _httpCommandRequestCallback(profile, command, result); - } - } + if (_printDebug == true) + _debugPort->println(F("processReadEvent: SIM status")); + + state = (UBX_CELL_sim_states_t)stateStore; - return true; + if (_simStateReportCallback != nullptr) + { + _simStateReportCallback(state); + } + + return true; + } } - } - return false; + return false; } -bool UBX_CELL::urcHandlerMQTTCommand(const char* event) +bool UBX_CELL::urcHandlerHTTPCommand(const char *event) { - // URC: +UUMQTTC (MQTT Command Result) - int command, result; - int scanNum; - int qos = -1; - String topic; + // URC: +UUHTTPCR (HTTP Command Result) + int profile, command, result; + int scanNum; - char *searchPtr = strstr(event, UBX_CELL_MQTT_COMMAND_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_MQTT_COMMAND_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') + char *searchPtr = strstr(event, UBX_CELL_HTTP_COMMAND_URC); + if (searchPtr != nullptr) { - searchPtr++; // skip spaces - } + searchPtr += strlen(UBX_CELL_HTTP_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,%d", &profile, &command, &result); - scanNum = sscanf(searchPtr, "%d,%d", &command, &result); - if ((scanNum == 2) && (command == UBX_CELL_MQTT_COMMAND_SUBSCRIBE)) - { - char topicC[100] = ""; - scanNum = sscanf(searchPtr, "%*d,%*d,%d,\"%[^\"]\"", &qos, topicC); - topic = topicC; - } - if ((scanNum == 2) || (scanNum == 4)) - { - if (_printDebug == true) - { - _debugPort->println(F("processReadEvent: MQTT command result")); - } + if (scanNum == 3) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: HTTP command result")); - if (_mqttCommandRequestCallback != nullptr) - { - _mqttCommandRequestCallback(command, result); - } + if ((profile >= 0) && (profile < UBX_CELL_NUM_HTTP_PROFILES)) + { + if (_httpCommandRequestCallback != nullptr) + { + _httpCommandRequestCallback(profile, command, result); + } + } - return true; + return true; + } } - } - return false; + return false; } -bool UBX_CELL::urcHandlerPingCommand(const char* event) +bool UBX_CELL::urcHandlerMQTTCommand(const char *event) { - // URC: +UUPING (Ping Result) - int retry = 0; - int p_size = 0; - int ttl = 0; - String remote_host = ""; - IPAddress remoteIP = {0, 0, 0, 0}; - long rtt = 0; - int scanNum; - - // Try to extract the UUPING retries and payload size - char *searchPtr = strstr(event, UBX_CELL_PING_COMMAND_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_PING_COMMAND_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d,", &retry, &p_size); + // URC: +UUMQTTC (MQTT Command Result) + int command, result; + int scanNum; + int qos = -1; + String topic; - if (scanNum == 2) + char *searchPtr = strstr(event, UBX_CELL_MQTT_COMMAND_URC); + if (searchPtr != nullptr) { - if (_printDebug == true) - { - _debugPort->println(F("processReadEvent: ping")); - } + searchPtr += strlen(UBX_CELL_MQTT_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + { + searchPtr++; // skip spaces + } - searchPtr = strchr(++searchPtr, '\"'); // Search to the first quote + scanNum = sscanf(searchPtr, "%d,%d", &command, &result); + if ((scanNum == 2) && (command == UBX_CELL_MQTT_COMMAND_SUBSCRIBE)) + { + char topicC[100] = ""; + scanNum = sscanf(searchPtr, "%*d,%*d,%d,\"%[^\"]\"", &qos, topicC); + topic = topicC; + } + if ((scanNum == 2) || (scanNum == 4)) + { + if (_printDebug == true) + { + _debugPort->println(F("processReadEvent: MQTT command result")); + } - // Extract the remote host name, stop at the next quote - while ((*(++searchPtr) != '\"') && (*searchPtr != '\0')) - { - remote_host.concat(*(searchPtr)); - } + if (_mqttCommandRequestCallback != nullptr) + { + _mqttCommandRequestCallback(command, result); + } - if (*searchPtr != '\0') // Make sure we found a quote - { - // Extract IP address - int remoteIPstore[4]; - scanNum = sscanf(searchPtr, "\",\"%d.%d.%d.%d", - &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); - for (int i = 0; i <= 3; i++) - { - remoteIP[i] = (uint8_t)remoteIPstore[i]; + return true; } + } + + return false; +} + +bool UBX_CELL::urcHandlerPingCommand(const char *event) +{ + // URC: +UUPING (Ping Result) + int retry = 0; + int p_size = 0; + int ttl = 0; + String remote_host = ""; + IPAddress remoteIP = {0, 0, 0, 0}; + long rtt = 0; + int scanNum; + + // Try to extract the UUPING retries and payload size + char *searchPtr = strstr(event, UBX_CELL_PING_COMMAND_URC); + if (searchPtr != nullptr) + { + searchPtr += strlen(UBX_CELL_PING_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d,", &retry, &p_size); - if (scanNum == 4) // Make sure we extracted enough data + if (scanNum == 2) { - // Extract TTL, should be immediately after IP address - searchPtr = strchr(searchPtr + 2, ','); // +2 to skip the quote and comma - if(searchPtr != nullptr) - { - // It's possible the TTL is not present (eg. on LARA-R6), so we - // can ignore scanNum since ttl defaults to 0 anyways - scanNum = sscanf(searchPtr, ",%d", &ttl); + if (_printDebug == true) + { + _debugPort->println(F("processReadEvent: ping")); + } + + searchPtr = strchr(++searchPtr, '\"'); // Search to the first quote - // Extract RTT, should be immediately after TTL - searchPtr = strchr(searchPtr + 1, ','); // +1 to skip the comma - if(searchPtr != nullptr) + // Extract the remote host name, stop at the next quote + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0')) { - scanNum = sscanf(searchPtr, ",%ld", &rtt); + remote_host.concat(*(searchPtr)); + } - // Callback, if it exists - if (_pingRequestCallback != nullptr) - { - _pingRequestCallback(retry, p_size, remote_host, remoteIP, ttl, rtt); - } + if (*searchPtr != '\0') // Make sure we found a quote + { + // Extract IP address + int remoteIPstore[4]; + scanNum = sscanf(searchPtr, "\",\"%d.%d.%d.%d", &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], + &remoteIPstore[3]); + for (int i = 0; i <= 3; i++) + { + remoteIP[i] = (uint8_t)remoteIPstore[i]; + } + + if (scanNum == 4) // Make sure we extracted enough data + { + // Extract TTL, should be immediately after IP address + searchPtr = strchr(searchPtr + 2, ','); // +2 to skip the quote and comma + if (searchPtr != nullptr) + { + // It's possible the TTL is not present (eg. on LARA-R6), so we + // can ignore scanNum since ttl defaults to 0 anyways + scanNum = sscanf(searchPtr, ",%d", &ttl); + + // Extract RTT, should be immediately after TTL + searchPtr = strchr(searchPtr + 1, ','); // +1 to skip the comma + if (searchPtr != nullptr) + { + scanNum = sscanf(searchPtr, ",%ld", &rtt); + + // Callback, if it exists + if (_pingRequestCallback != nullptr) + { + _pingRequestCallback(retry, p_size, remote_host, remoteIP, ttl, rtt); + } + } + } + } } - } + return true; } - } - return true; } - } - return false; + return false; } -bool UBX_CELL::urcHandlerFTPCommand(const char* event) +bool UBX_CELL::urcHandlerFTPCommand(const char *event) { - // URC: +UUFTPCR (FTP Command Result) - int ftpCmd; - int ftpResult; - int scanNum; - char *searchPtr = strstr(event, UBX_CELL_FTP_COMMAND_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_FTP_COMMAND_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') + // URC: +UUFTPCR (FTP Command Result) + int ftpCmd; + int ftpResult; + int scanNum; + char *searchPtr = strstr(event, UBX_CELL_FTP_COMMAND_URC); + if (searchPtr != nullptr) { - searchPtr++; // skip spaces - } + searchPtr += strlen(UBX_CELL_FTP_COMMAND_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + { + searchPtr++; // skip spaces + } - scanNum = sscanf(searchPtr, "%d,%d", &ftpCmd, &ftpResult); - if (scanNum == 2 && _ftpCommandRequestCallback != nullptr) - { - _ftpCommandRequestCallback(ftpCmd, ftpResult); - return true; + scanNum = sscanf(searchPtr, "%d,%d", &ftpCmd, &ftpResult); + if (scanNum == 2 && _ftpCommandRequestCallback != nullptr) + { + _ftpCommandRequestCallback(ftpCmd, ftpResult); + return true; + } } - } - return false; + return false; } -bool UBX_CELL::urcHandlerRegistrationStatus(const char* event) +bool UBX_CELL::urcHandlerRegistrationStatus(const char *event) { - // URC: +CREG - int status = 0; - unsigned int lac = 0, ci = 0, Act = 0; - char *searchPtr = strstr(event, UBX_CELL_REGISTRATION_STATUS_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_REGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &lac, &ci, &Act); - if (scanNum == 4) + // URC: +CREG + int status = 0; + unsigned int lac = 0, ci = 0, Act = 0; + char *searchPtr = strstr(event, UBX_CELL_REGISTRATION_STATUS_URC); + if (searchPtr != nullptr) { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: CREG")); + searchPtr += strlen(UBX_CELL_REGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &lac, &ci, &Act); + if (scanNum == 4) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: CREG")); - if (_registrationCallback != nullptr) - { - _registrationCallback((UBX_CELL_registration_status_t)status, lac, ci, Act); - } + if (_registrationCallback != nullptr) + { + _registrationCallback((UBX_CELL_registration_status_t)status, lac, ci, Act); + } - return true; + return true; + } } - } - return false; + return false; } -bool UBX_CELL::urcHandlerEPSRegistrationStatus(const char* event) +bool UBX_CELL::urcHandlerEPSRegistrationStatus(const char *event) { - // URC: +CEREG - int status = 0; - unsigned int tac = 0, ci = 0, Act = 0; - char *searchPtr = strstr(event, UBX_CELL_EPSREGISTRATION_STATUS_URC); - if (searchPtr != nullptr) - { - searchPtr += strlen(UBX_CELL_EPSREGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &tac, &ci, &Act); - if (scanNum == 4) + // URC: +CEREG + int status = 0; + unsigned int tac = 0, ci = 0, Act = 0; + char *searchPtr = strstr(event, UBX_CELL_EPSREGISTRATION_STATUS_URC); + if (searchPtr != nullptr) { - if (_printDebug == true) - _debugPort->println(F("processReadEvent: CEREG")); + searchPtr += + strlen(UBX_CELL_EPSREGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + int scanNum = sscanf(searchPtr, "%d,\"%4x\",\"%4x\",%d", &status, &tac, &ci, &Act); + if (scanNum == 4) + { + if (_printDebug == true) + _debugPort->println(F("processReadEvent: CEREG")); - if (_epsRegistrationCallback != nullptr) - { - _epsRegistrationCallback((UBX_CELL_registration_status_t)status, tac, ci, Act); - } + if (_epsRegistrationCallback != nullptr) + { + _epsRegistrationCallback((UBX_CELL_registration_status_t)status, tac, ci, Act); + } - return true; + return true; + } } - } - return false; + return false; } -void UBX_CELL::addURCHandler(const char* urcString, UBX_CELL_urc_handler_t urcHandler) +void UBX_CELL::addURCHandler(const char *urcString, UBX_CELL_urc_handler_t urcHandler) { - _urcStrings.push_back(urcString); - _urcHandlers.push_back(urcHandler); + _urcStrings.push_back(urcString); + _urcHandlers.push_back(urcHandler); } // Parse incoming URC's - the associated parse functions pass the data to the user via the callbacks (if defined) bool UBX_CELL::processURCEvent(const char *event) { - // Iterate through each URC handler to see if it can handle this message - for(auto urcHandler : _urcHandlers) - { - if (urcHandler(event)) + // Iterate through each URC handler to see if it can handle this message + for (auto urcHandler : _urcHandlers) { - // This handler took care of it, so we're done! - return true; + if (urcHandler(event)) + { + // This handler took care of it, so we're done! + return true; + } } - } - // None of the handlers took care of it - return false; + // None of the handlers took care of it + return false; } // This is the original poll function. @@ -834,102 +854,108 @@ bool UBX_CELL::processURCEvent(const char *event) // ::bufferedPoll is the new improved version. It processes any data in the backlog and includes a timeout. bool UBX_CELL::poll(void) { - if (_pollReentrant == true) // Check for reentry (i.e. poll has been called from inside a callback) - return false; + if (_pollReentrant == true) // Check for reentry (i.e. poll has been called from inside a callback) + return false; - _pollReentrant = true; + _pollReentrant = true; - int avail = 0; - char c = 0; - bool handled = false; + int avail = 0; + char c = 0; + bool handled = false; - memset(_saraRXBuffer, 0, _RXBuffSize); // Clear _saraRXBuffer + memset(_saraRXBuffer, 0, _RXBuffSize); // Clear _saraRXBuffer - if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL - { - while (c != '\n') // Copy characters into _saraRXBuffer. Stop at the first new line + if (hwAvailable() > 0) // hwAvailable can return -1 if the serial port is NULL { - if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL - { - c = readChar(); - _saraRXBuffer[avail++] = c; - } else { - yield(); - } - } + while (c != '\n') // Copy characters into _saraRXBuffer. Stop at the first new line + { + if (hwAvailable() > 0) // hwAvailable can return -1 if the serial port is NULL + { + c = readChar(); + _saraRXBuffer[avail++] = c; + } + else + { + yield(); + } + } - // Now search for all supported URC's - handled = processURCEvent(_saraRXBuffer); - if (handled && (true == _printAtDebug)) { - _debugAtPort->write(_saraRXBuffer, avail); - } - if ((handled == false) && (strlen(_saraRXBuffer) > 2)) - { - if (_printDebug == true) - { - _debugPort->print(F("poll: ")); - _debugPort->println(_saraRXBuffer); - } - } - else - { + // Now search for all supported URC's + handled = processURCEvent(_saraRXBuffer); + if (handled && (true == _printAtDebug)) + { + _debugAtPort->write(_saraRXBuffer, avail); + } + if ((handled == false) && (strlen(_saraRXBuffer) > 2)) + { + if (_printDebug == true) + { + _debugPort->print(F("poll: ")); + _debugPort->println(_saraRXBuffer); + } + } + else + { + } } - } - _pollReentrant = false; + _pollReentrant = false; - return handled; + return handled; } -void UBX_CELL::setSocketListenCallback(void (*socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int)) +void UBX_CELL::setSocketListenCallback(void (*socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, + unsigned int)) { - _socketListenCallback = socketListenCallback; + _socketListenCallback = socketListenCallback; } void UBX_CELL::setSocketReadCallback(void (*socketReadCallback)(int, String)) { - _socketReadCallback = socketReadCallback; + _socketReadCallback = socketReadCallback; } -void UBX_CELL::setSocketReadCallbackPlus(void (*socketReadCallbackPlus)(int, const char *, int, IPAddress, int)) // socket, data, length, remoteAddress, remotePort +void UBX_CELL::setSocketReadCallbackPlus(void (*socketReadCallbackPlus)( + int, const char *, int, IPAddress, int)) // socket, data, length, remoteAddress, remotePort { - _socketReadCallbackPlus = socketReadCallbackPlus; + _socketReadCallbackPlus = socketReadCallbackPlus; } void UBX_CELL::setSocketCloseCallback(void (*socketCloseCallback)(int)) { - _socketCloseCallback = socketCloseCallback; + _socketCloseCallback = socketCloseCallback; } -void UBX_CELL::setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, - PositionData gps, SpeedData spd, unsigned long uncertainty)) +void UBX_CELL::setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, PositionData gps, SpeedData spd, + unsigned long uncertainty)) { - _gpsRequestCallback = gpsRequestCallback; + _gpsRequestCallback = gpsRequestCallback; } void UBX_CELL::setSIMstateReportCallback(void (*simStateReportCallback)(UBX_CELL_sim_states_t state)) { - _simStateReportCallback = simStateReportCallback; + _simStateReportCallback = simStateReportCallback; } void UBX_CELL::setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)) { - _psdActionRequestCallback = psdActionRequestCallback; + _psdActionRequestCallback = psdActionRequestCallback; } -void UBX_CELL::setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)) +void UBX_CELL::setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, + int ttl, long rtt)) { - _pingRequestCallback = pingRequestCallback; + _pingRequestCallback = pingRequestCallback; } void UBX_CELL::setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)) { - _httpCommandRequestCallback = httpCommandRequestCallback; + _httpCommandRequestCallback = httpCommandRequestCallback; } void UBX_CELL::setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)) { - _mqttCommandRequestCallback = mqttCommandRequestCallback; + _mqttCommandRequestCallback = mqttCommandRequestCallback; } void UBX_CELL::setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)) @@ -937,5703 +963,5668 @@ void UBX_CELL::setFTPCommandCallback(void (*ftpCommandRequestCallback)(int comma _ftpCommandRequestCallback = ftpCommandRequestCallback; } -UBX_CELL_error_t UBX_CELL::setRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, unsigned int lac, unsigned int ci, int Act)) +UBX_CELL_error_t UBX_CELL::setRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, + unsigned int lac, unsigned int ci, + int Act)) { - _registrationCallback = registrationCallback; + _registrationCallback = registrationCallback; - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_REGISTRATION_STATUS) + 3); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_REGISTRATION_STATUS, 2/*enable URC with location*/); - UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_REGISTRATION_STATUS) + 3); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_REGISTRATION_STATUS, 2 /*enable URC with location*/); + UBX_CELL_error_t err = + sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::setEpsRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, unsigned int tac, unsigned int ci, int Act)) +UBX_CELL_error_t UBX_CELL::setEpsRegistrationCallback( + void (*registrationCallback)(UBX_CELL_registration_status_t status, unsigned int tac, unsigned int ci, int Act)) { - _epsRegistrationCallback = registrationCallback; + _epsRegistrationCallback = registrationCallback; - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_EPSREGISTRATION_STATUS) + 3); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_EPSREGISTRATION_STATUS, 2/*enable URC with location*/); - UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_EPSREGISTRATION_STATUS) + 3); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_EPSREGISTRATION_STATUS, 2 /*enable URC with location*/); + UBX_CELL_error_t err = + sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; } size_t UBX_CELL::write(uint8_t c) { - return hwWrite(c); + return hwWrite(c); } size_t UBX_CELL::write(const char *str) { - return hwPrint(str); + return hwPrint(str); } size_t UBX_CELL::write(const char *buffer, size_t size) { - return hwWriteData(buffer, size); + return hwWriteData(buffer, size); } UBX_CELL_error_t UBX_CELL::at(void) { - UBX_CELL_error_t err; + UBX_CELL_error_t err; - err = sendCommandWithResponse(nullptr, UBX_CELL_RESPONSE_OK, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(nullptr, UBX_CELL_RESPONSE_OK, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - return err; + return err; } UBX_CELL_error_t UBX_CELL::enableEcho(bool enable) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_ECHO) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s%d", UBX_CELL_COMMAND_ECHO, enable ? 1 : 0); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_ECHO) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s%d", UBX_CELL_COMMAND_ECHO, enable ? 1 : 0); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; } String UBX_CELL::getManufacturerID(void) { - char *response; - char idResponse[16] = {0x00}; // E.g. u-blox - UBX_CELL_error_t err; + char *response; + char idResponse[16] = {0x00}; // E.g. u-blox + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_MANU_ID, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - if (sscanf(response, "\r\n%15s\r\n", idResponse) != 1) + err = sendCommandWithResponse(UBX_CELL_COMMAND_MANU_ID, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - memset(idResponse, 0, 16); + if (sscanf(response, "\r\n%15s\r\n", idResponse) != 1) + { + memset(idResponse, 0, 16); + } } - } - free(response); - return String(idResponse); + free(response); + return String(idResponse); } String UBX_CELL::getModelID(void) { - char *response; - char idResponse[32] = {0x00}; // E.g. SARA-R510M8Q - UBX_CELL_error_t err; + char *response; + char idResponse[32] = {0x00}; // E.g. SARA-R510M8Q + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_MODEL_ID, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - if (sscanf(response, "\r\n%31s\r\n", idResponse) != 1) + err = sendCommandWithResponse(UBX_CELL_COMMAND_MODEL_ID, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - memset(idResponse, 0, 16); + if (sscanf(response, "\r\n%31s\r\n", idResponse) != 1) + { + memset(idResponse, 0, 16); + } } - } - free(response); - return String(idResponse); + free(response); + return String(idResponse); } String UBX_CELL::getFirmwareVersion(void) { - char *response; - char idResponse[16] = {0x00}; // E.g. 11.40 - UBX_CELL_error_t err; + char *response; + char idResponse[16] = {0x00}; // E.g. 11.40 + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_FW_VER_ID, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - if (sscanf(response, "\r\n%15s\r\n", idResponse) != 1) + err = sendCommandWithResponse(UBX_CELL_COMMAND_FW_VER_ID, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - memset(idResponse, 0, 16); + if (sscanf(response, "\r\n%15s\r\n", idResponse) != 1) + { + memset(idResponse, 0, 16); + } } - } - free(response); - return String(idResponse); + free(response); + return String(idResponse); } String UBX_CELL::getSerialNo(void) { - char *response; - char idResponse[32] = {0x00}; // E.g. 357520070120767 - UBX_CELL_error_t err; + char *response; + char idResponse[32] = {0x00}; // E.g. 357520070120767 + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_SERIAL_NO, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - if (sscanf(response, "\r\n%31s\r\n", idResponse) != 1) + err = sendCommandWithResponse(UBX_CELL_COMMAND_SERIAL_NO, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - memset(idResponse, 0, 16); + if (sscanf(response, "\r\n%31s\r\n", idResponse) != 1) + { + memset(idResponse, 0, 16); + } } - } - free(response); - return String(idResponse); + free(response); + return String(idResponse); } String UBX_CELL::getIMEI(void) { - char *response; - char imeiResponse[32] = {0x00}; // E.g. 004999010640000 - UBX_CELL_error_t err; + char *response; + char imeiResponse[32] = {0x00}; // E.g. 004999010640000 + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_IMEI, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - if (sscanf(response, "\r\n%31s\r\n", imeiResponse) != 1) + err = sendCommandWithResponse(UBX_CELL_COMMAND_IMEI, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - memset(imeiResponse, 0, 16); - } - } - free(response); - return String(imeiResponse); + if (sscanf(response, "\r\n%31s\r\n", imeiResponse) != 1) + { + memset(imeiResponse, 0, 16); + } + } + free(response); + return String(imeiResponse); } String UBX_CELL::getIMSI(void) { - char *response; - char imsiResponse[32] = {0x00}; // E.g. 222107701772423 - UBX_CELL_error_t err; + char *response; + char imsiResponse[32] = {0x00}; // E.g. 222107701772423 + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_IMSI, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - if (sscanf(response, "\r\n%31s\r\n", imsiResponse) != 1) + err = sendCommandWithResponse(UBX_CELL_COMMAND_IMSI, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - memset(imsiResponse, 0, 16); + if (sscanf(response, "\r\n%31s\r\n", imsiResponse) != 1) + { + memset(imsiResponse, 0, 16); + } } - } - free(response); - return String(imsiResponse); + free(response); + return String(imsiResponse); } String UBX_CELL::getCCID(void) { - char *response; - char ccidResponse[32] = {0x00}; // E.g. +CCID: 8939107900010087330 - UBX_CELL_error_t err; + char *response; + char ccidResponse[32] = {0x00}; // E.g. +CCID: 8939107900010087330 + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_CCID, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "\r\n+CCID:"); - if (searchPtr != nullptr) + err = sendCommandWithResponse(UBX_CELL_COMMAND_CCID, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - searchPtr += strlen("\r\n+CCID:"); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - if (sscanf(searchPtr, "%31s", ccidResponse) != 1) - { - ccidResponse[0] = 0; - } + char *searchPtr = strstr(response, "\r\n+CCID:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("\r\n+CCID:"); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + if (sscanf(searchPtr, "%31s", ccidResponse) != 1) + { + ccidResponse[0] = 0; + } + } } - } - free(response); - return String(ccidResponse); + free(response); + return String(ccidResponse); } String UBX_CELL::getSubscriberNo(void) { - char *response; - char idResponse[128] = {0x00}; // E.g. +CNUM: "ABCD . AAA","123456789012",129 - UBX_CELL_error_t err; + char *response; + char idResponse[128] = {0x00}; // E.g. +CNUM: "ABCD . AAA","123456789012",129 + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_CNUM, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "\r\n+CNUM:"); - if (searchPtr != nullptr) + err = sendCommandWithResponse(UBX_CELL_COMMAND_CNUM, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_10_SEC_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - searchPtr += strlen("\r\n+CNUM:"); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - if (sscanf(searchPtr, "%127s", idResponse) != 1) - { - idResponse[0] = 0; - } + char *searchPtr = strstr(response, "\r\n+CNUM:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("\r\n+CNUM:"); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + if (sscanf(searchPtr, "%127s", idResponse) != 1) + { + idResponse[0] = 0; + } + } } - } - free(response); - return String(idResponse); + free(response); + return String(idResponse); } String UBX_CELL::getCapabilities(void) { - char *response; - char idResponse[128] = {0x00}; // E.g. +GCAP: +FCLASS, +CGSM - UBX_CELL_error_t err; + char *response; + char idResponse[128] = {0x00}; // E.g. +GCAP: +FCLASS, +CGSM + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); + response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_REQ_CAP, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "\r\n+GCAP:"); - if (searchPtr != nullptr) + err = sendCommandWithResponse(UBX_CELL_COMMAND_REQ_CAP, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - searchPtr += strlen("\r\n+GCAP:"); // Move searchPtr to first character - probably a space - while (*searchPtr == ' ') searchPtr++; // skip spaces - if (sscanf(searchPtr, "%127s", idResponse) != 1) - { - idResponse[0] = 0; - } + char *searchPtr = strstr(response, "\r\n+GCAP:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("\r\n+GCAP:"); // Move searchPtr to first character - probably a space + while (*searchPtr == ' ') + searchPtr++; // skip spaces + if (sscanf(searchPtr, "%127s", idResponse) != 1) + { + idResponse[0] = 0; + } + } } - } - free(response); - return String(idResponse); + free(response); + return String(idResponse); } UBX_CELL_error_t UBX_CELL::reset(void) { - UBX_CELL_error_t err; + UBX_CELL_error_t err; - err = functionality(SILENT_RESET_WITH_SIM); - if (err == UBX_CELL_ERROR_SUCCESS) - { - // Reset will set the baud rate back to 115200 - //beginSerial(9600); - err = UBX_CELL_ERROR_INVALID; - while (err != UBX_CELL_ERROR_SUCCESS) + err = functionality(SILENT_RESET_WITH_SIM); + if (err == UBX_CELL_ERROR_SUCCESS) { - beginSerial(UBX_CELL_DEFAULT_BAUD_RATE); - setBaud(_baud); - beginSerial(_baud); - err = at(); + // Reset will set the baud rate back to 115200 + // beginSerial(9600); + err = UBX_CELL_ERROR_INVALID; + while (err != UBX_CELL_ERROR_SUCCESS) + { + beginSerial(UBX_CELL_DEFAULT_BAUD_RATE); + setBaud(_baud); + beginSerial(_baud); + err = at(); + } + return init(_baud); } - return init(_baud); - } - return err; + return err; } String UBX_CELL::clock(void) { - UBX_CELL_error_t err; - char *command; - char *response; - char *clockBegin; - char *clockEnd; + UBX_CELL_error_t err; + char *command; + char *response; + char *clockBegin; + char *clockEnd; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + 2); - if (command == nullptr) - return ""; - sprintf(command, "%s?", UBX_CELL_COMMAND_CLOCK); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + 2); + if (command == nullptr) + return ""; + sprintf(command, "%s?", UBX_CELL_COMMAND_CLOCK); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return ""; - } + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return ""; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err != UBX_CELL_ERROR_SUCCESS) - { - free(command); - free(response); - return ""; - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err != UBX_CELL_ERROR_SUCCESS) + { + free(command); + free(response); + return ""; + } - // Response format: \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n - clockBegin = strchr(response, '\"'); // Find first quote - if (clockBegin == nullptr) - { - free(command); - free(response); - return ""; - } - clockBegin += 1; // Increment pointer to begin at first number - clockEnd = strchr(clockBegin, '\"'); // Find last quote - if (clockEnd == nullptr) - { - free(command); - free(response); - return ""; - } - *(clockEnd) = '\0'; // Set last quote to null char -- end string + // Response format: \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n + clockBegin = strchr(response, '\"'); // Find first quote + if (clockBegin == nullptr) + { + free(command); + free(response); + return ""; + } + clockBegin += 1; // Increment pointer to begin at first number + clockEnd = strchr(clockBegin, '\"'); // Find last quote + if (clockEnd == nullptr) + { + free(command); + free(response); + return ""; + } + *(clockEnd) = '\0'; // Set last quote to null char -- end string - String clock = String(clockBegin); // Extract the clock as a String _before_ freeing response + String clock = String(clockBegin); // Extract the clock as a String _before_ freeing response - free(command); - free(response); + free(command); + free(response); - return (clock); + return (clock); } -UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, - uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz) +UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz) { - UBX_CELL_error_t err; - char *command; - char *response; - char tzPlusMinus; - int scanNum = 0; + UBX_CELL_error_t err; + char *command; + char *response; + char tzPlusMinus; + int scanNum = 0; - int iy, imo, id, ih, imin, is, itz; + int iy, imo, id, ih, imin, is, itz; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_COMMAND_CLOCK); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_COMMAND_CLOCK); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - // Response format (if TZ is negative): \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+CCLK:"); - if (searchPtr != nullptr) + // Response format (if TZ is negative): \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n + if (err == UBX_CELL_ERROR_SUCCESS) { - searchPtr += strlen("+CCLK:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "\"%d/%d/%d,%d:%d:%d%c%d\"\r\n", - &iy, &imo, &id, &ih, &imin, &is, &tzPlusMinus, &itz); + char *searchPtr = strstr(response, "+CCLK:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+CCLK:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = + sscanf(searchPtr, "\"%d/%d/%d,%d:%d:%d%c%d\"\r\n", &iy, &imo, &id, &ih, &imin, &is, &tzPlusMinus, &itz); + } + if (scanNum == 8) + { + *y = iy; + *mo = imo; + *d = id; + *h = ih; + *min = imin; + *s = is; + if (tzPlusMinus == '-') + *tz = 0 - itz; + else + *tz = itz; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - if (scanNum == 8) - { - *y = iy; - *mo = imo; - *d = id; - *h = ih; - *min = imin; - *s = is; - if (tzPlusMinus == '-') - *tz = 0 - itz; - else - *tz = itz; + + free(command); + free(response); + return err; +} + +UBX_CELL_error_t UBX_CELL::setClock(uint8_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t min, uint8_t s, int8_t tz) +{ + // Convert y,mo,d,h,min,s,tz into a String + // Some platforms don't support sprintf correctly (for %02d or %+02d) so we need to build the String manually + // Format is "yy/MM/dd,hh:mm:ss+TZ" + // TZ can be +/- and is in increments of 15 minutes (not hours) + + String theTime = ""; + + theTime.concat(y / 10); + theTime.concat(y % 10); + theTime.concat('/'); + theTime.concat(mo / 10); + theTime.concat(mo % 10); + theTime.concat('/'); + theTime.concat(d / 10); + theTime.concat(d % 10); + theTime.concat(','); + theTime.concat(h / 10); + theTime.concat(h % 10); + theTime.concat(':'); + theTime.concat(min / 10); + theTime.concat(min % 10); + theTime.concat(':'); + theTime.concat(s / 10); + theTime.concat(s % 10); + if (tz < 0) + { + theTime.concat('-'); + tz = 0 - tz; } else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - free(command); - free(response); - return err; -} - -UBX_CELL_error_t UBX_CELL::setClock(uint8_t y, uint8_t mo, uint8_t d, - uint8_t h, uint8_t min, uint8_t s, int8_t tz) -{ - //Convert y,mo,d,h,min,s,tz into a String - //Some platforms don't support sprintf correctly (for %02d or %+02d) so we need to build the String manually - //Format is "yy/MM/dd,hh:mm:ss+TZ" - //TZ can be +/- and is in increments of 15 minutes (not hours) - - String theTime = ""; - - theTime.concat(y / 10); - theTime.concat(y % 10); - theTime.concat('/'); - theTime.concat(mo / 10); - theTime.concat(mo % 10); - theTime.concat('/'); - theTime.concat(d / 10); - theTime.concat(d % 10); - theTime.concat(','); - theTime.concat(h / 10); - theTime.concat(h % 10); - theTime.concat(':'); - theTime.concat(min / 10); - theTime.concat(min % 10); - theTime.concat(':'); - theTime.concat(s / 10); - theTime.concat(s % 10); - if (tz < 0) - { - theTime.concat('-'); - tz = 0 - tz; - } - else - theTime.concat('+'); - theTime.concat(tz / 10); - theTime.concat(tz % 10); - - return (setClock(theTime)); + theTime.concat('+'); + theTime.concat(tz / 10); + theTime.concat(tz % 10); + + return (setClock(theTime)); } UBX_CELL_error_t UBX_CELL::setClock(String theTime) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + theTime.length() + 8); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_COMMAND_CLOCK, theTime.c_str()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + theTime.length() + 8); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_COMMAND_CLOCK, theTime.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } void UBX_CELL::autoTimeZoneForBegin(bool tz) { - _autoTimeZoneForBegin = tz; + _autoTimeZoneForBegin = tz; } UBX_CELL_error_t UBX_CELL::autoTimeZone(bool enable) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_AUTO_TZ) + 3); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_COMMAND_AUTO_TZ, enable ? 1 : 0); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_AUTO_TZ) + 3); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_COMMAND_AUTO_TZ, enable ? 1 : 0); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; } int8_t UBX_CELL::rssi(void) { - char *command; - char *response; - UBX_CELL_error_t err; - int rssi; + char *command; + char *response; + UBX_CELL_error_t err; + int rssi; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SIGNAL_QUALITY) + 1); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s", UBX_CELL_SIGNAL_QUALITY); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SIGNAL_QUALITY) + 1); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s", UBX_CELL_SIGNAL_QUALITY); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, 10000, - minimumResponseAllocation, AT_COMMAND); - if (err != UBX_CELL_ERROR_SUCCESS) - { - free(command); - free(response); - return -1; - } - - int scanned = 0; - char *searchPtr = strstr(response, "+CSQ:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+CSQ:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d,%*d", &rssi); - } - if (scanned != 1) - { - rssi = -1; - } - - free(command); - free(response); - return rssi; -} - -UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality& signal_quality) -{ - char *command; - char *response; - UBX_CELL_error_t err; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_EXT_SIGNAL_QUALITY) + 1); - if (command == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - sprintf(command, "%s", UBX_CELL_EXT_SIGNAL_QUALITY); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, - UBX_CELL_RESPONSE_OK_OR_ERROR, response, 10000, - minimumResponseAllocation, AT_COMMAND); - if (err != UBX_CELL_ERROR_SUCCESS) - { - free(command); - free(response); - return UBX_CELL_ERROR_ERROR; - } - - int scanned = 0; - const char * responseStr = "+CESQ:"; - char *searchPtr = strstr(response, responseStr); - if (searchPtr != nullptr) - { - searchPtr += strlen(responseStr); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%u,%u,%u,%u,%u,%u", &signal_quality.rxlev, &signal_quality.ber, - &signal_quality.rscp, &signal_quality.enc0, &signal_quality.rsrq, &signal_quality.rsrp); - } - - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - if (scanned == 6) - { - err = UBX_CELL_ERROR_SUCCESS; - } + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - free(command); - free(response); - return err; -} + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, 10000, minimumResponseAllocation, + AT_COMMAND); + if (err != UBX_CELL_ERROR_SUCCESS) + { + free(command); + free(response); + return -1; + } + + int scanned = 0; + char *searchPtr = strstr(response, "+CSQ:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+CSQ:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%*d", &rssi); + } + if (scanned != 1) + { + rssi = -1; + } -UBX_CELL_registration_status_t UBX_CELL::registration(bool eps) -{ - char *command; - char *response; - UBX_CELL_error_t err; - int status; - const char* tag = eps ? UBX_CELL_EPSREGISTRATION_STATUS : UBX_CELL_REGISTRATION_STATUS; - command = ubx_cell_calloc_char(strlen(tag) + 3); - if (command == nullptr) - return UBX_CELL_REGISTRATION_INVALID; - sprintf(command, "%s?", tag); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_REGISTRATION_INVALID; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT, - minimumResponseAllocation, AT_COMMAND); - if (err != UBX_CELL_ERROR_SUCCESS) - { free(command); free(response); - return UBX_CELL_REGISTRATION_INVALID; - } - - int scanned = 0; - const char *startTag = eps ? UBX_CELL_EPSREGISTRATION_STATUS_URC : UBX_CELL_REGISTRATION_STATUS_URC; - char *searchPtr = strstr(response, startTag); - if (searchPtr != nullptr) - { - searchPtr += eps ? strlen(UBX_CELL_EPSREGISTRATION_STATUS_URC) : strlen(UBX_CELL_REGISTRATION_STATUS_URC); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%*d,%d", &status); - } - if (scanned != 1) - status = UBX_CELL_REGISTRATION_INVALID; - - free(command); - free(response); - return (UBX_CELL_registration_status_t)status; + return rssi; } -bool UBX_CELL::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) +UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality &signal_quality) { - mobile_network_operator_t currentMno; - - // Check currently set MNO profile - if (getMNOprofile(¤tMno) != UBX_CELL_ERROR_SUCCESS) - { - return false; - } + char *command; + char *response; + UBX_CELL_error_t err; - if (currentMno == mno) - { - return true; - } + command = ubx_cell_calloc_char(strlen(UBX_CELL_EXT_SIGNAL_QUALITY) + 1); + if (command == nullptr) + { + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - // Disable transmit and receive so we can change operator - if (functionality(MINIMUM_FUNCTIONALITY) != UBX_CELL_ERROR_SUCCESS) - { - return false; - } + sprintf(command, "%s", UBX_CELL_EXT_SIGNAL_QUALITY); - if (setMNOprofile(mno, autoReset, urcNotification) != UBX_CELL_ERROR_SUCCESS) - { - return false; - } + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - if (reset() != UBX_CELL_ERROR_SUCCESS) - { - return false; - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, 10000, minimumResponseAllocation, + AT_COMMAND); + if (err != UBX_CELL_ERROR_SUCCESS) + { + free(command); + free(response); + return UBX_CELL_ERROR_ERROR; + } - return true; -} + int scanned = 0; + const char *responseStr = "+CESQ:"; + char *searchPtr = strstr(response, responseStr); + if (searchPtr != nullptr) + { + searchPtr += strlen(responseStr); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%u,%u,%u,%u,%u,%u", &signal_quality.rxlev, &signal_quality.ber, + &signal_quality.rscp, &signal_quality.enc0, &signal_quality.rsrq, &signal_quality.rsrp); + } -mobile_network_operator_t UBX_CELL::getNetworkProfile(void) -{ - mobile_network_operator_t mno; - UBX_CELL_error_t err; + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + if (scanned == 6) + { + err = UBX_CELL_ERROR_SUCCESS; + } - err = getMNOprofile(&mno); - if (err != UBX_CELL_ERROR_SUCCESS) - { - return MNO_INVALID; - } - return mno; + free(command); + free(response); + return err; } -UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdpType) +UBX_CELL_registration_status_t UBX_CELL::registration(bool eps) { - UBX_CELL_error_t err; - char *command; - char pdpStr[8]; - - memset(pdpStr, 0, 8); - - if (cid >= 8) - return UBX_CELL_ERROR_UNEXPECTED_PARAM; + char *command; + char *response; + UBX_CELL_error_t err; + int status; + const char *tag = eps ? UBX_CELL_EPSREGISTRATION_STATUS : UBX_CELL_REGISTRATION_STATUS; + command = ubx_cell_calloc_char(strlen(tag) + 3); + if (command == nullptr) + return UBX_CELL_REGISTRATION_INVALID; + sprintf(command, "%s?", tag); - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_DEF) + strlen(apn.c_str()) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - switch (pdpType) - { - case PDP_TYPE_INVALID: - free(command); - return UBX_CELL_ERROR_UNEXPECTED_PARAM; - break; - case PDP_TYPE_IP: - memcpy(pdpStr, "IP", 2); - break; - case PDP_TYPE_NONIP: - memcpy(pdpStr, "NONIP", 5); - break; - case PDP_TYPE_IPV4V6: - memcpy(pdpStr, "IPV4V6", 6); - break; - case PDP_TYPE_IPV6: - memcpy(pdpStr, "IPV6", 4); - break; - default: - free(command); - return UBX_CELL_ERROR_UNEXPECTED_PARAM; - break; - } - if (apn == nullptr) - { - if (_printDebug == true) - _debugPort->println(F("setAPN: nullptr")); - sprintf(command, "%s=%d,\"%s\",\"\"", UBX_CELL_MESSAGE_PDP_DEF, - cid, pdpStr); - } - else - { - if (_printDebug == true) + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - _debugPort->print(F("setAPN: ")); - _debugPort->println(apn); + free(command); + return UBX_CELL_REGISTRATION_INVALID; } - sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MESSAGE_PDP_DEF, - cid, pdpStr, apn.c_str()); - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - free(command); - - return err; -} - -// Return the Access Point Name and IP address for the chosen context identifier -UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_pdp_type* pdpType) -{ - UBX_CELL_error_t err; - char *command; - char *response; - if (cid > UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) - return UBX_CELL_ERROR_ERROR; + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT, + minimumResponseAllocation, AT_COMMAND); + if (err != UBX_CELL_ERROR_SUCCESS) + { + free(command); + free(response); + return UBX_CELL_REGISTRATION_INVALID; + } - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_DEF) + 3); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_MESSAGE_PDP_DEF); + int scanned = 0; + const char *startTag = eps ? UBX_CELL_EPSREGISTRATION_STATUS_URC : UBX_CELL_REGISTRATION_STATUS_URC; + char *searchPtr = strstr(response, startTag); + if (searchPtr != nullptr) + { + searchPtr += eps ? strlen(UBX_CELL_EPSREGISTRATION_STATUS_URC) + : strlen(UBX_CELL_REGISTRATION_STATUS_URC); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%*d,%d", &status); + } + if (scanned != 1) + status = UBX_CELL_REGISTRATION_INVALID; - response = ubx_cell_calloc_char(1024); - if (response == nullptr) - { free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT, 1024); - - if (err == UBX_CELL_ERROR_SUCCESS) - { - // Example: - // +CGDCONT: 0,"IP","payandgo.o2.co.uk","0.0.0.0",0,0,0,0,0,0,0,0,0,0 - // +CGDCONT: 1,"IP","payandgo.o2.co.uk.mnc010.mcc234.gprs","10.160.182.234",0,0,0,2,0,0,0,0,0,0 - int rcid = -1; - char *searchPtr = response; - - bool keepGoing = true; - while (keepGoing == true) - { - int scanned = 0; - // Find the first/next occurrence of +CGDCONT: - searchPtr = strstr(searchPtr, "+CGDCONT:"); - if (searchPtr != nullptr) - { - char strPdpType[10]; - char strApn[128]; - int ipOct[4]; - - searchPtr += strlen("+CGDCONT:"); // Point to the cid - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d,\"%[^\"]\",\"%[^\"]\",\"%d.%d.%d.%d", - &rcid, strPdpType, strApn, - &ipOct[0], &ipOct[1], &ipOct[2], &ipOct[3]); - if ((scanned == 7) && (rcid == cid)) { - if (apn) *apn = strApn; - for (int o = 0; ip && (o < 4); o++) - { - (*ip)[o] = (uint8_t)ipOct[o]; - } - if (pdpType) { - *pdpType = (0 == strcmp(strPdpType, "IPV4V6")) ? PDP_TYPE_IPV4V6 : - (0 == strcmp(strPdpType, "IPV6")) ? PDP_TYPE_IPV6 : - (0 == strcmp(strPdpType, "IP")) ? PDP_TYPE_IP : - PDP_TYPE_INVALID; - } - keepGoing = false; - } - } - else // We don't have a match so let's clear the APN and IP address - { - if (apn) *apn = ""; - if (pdpType) *pdpType = PDP_TYPE_INVALID; - if (ip) *ip = {0, 0, 0, 0}; - keepGoing = false; - } - } - } - else - { - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - free(command); - free(response); - - return err; + free(response); + return (UBX_CELL_registration_status_t)status; } -UBX_CELL_error_t UBX_CELL::getSimStatus(String* code) +bool UBX_CELL::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) { - UBX_CELL_error_t err; - char *command; - char *response; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_SIMPIN) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_COMMAND_SIMPIN); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + mobile_network_operator_t currentMno; - if (err == UBX_CELL_ERROR_SUCCESS) - { - int scanned = 0; - char c[16]; - char *searchPtr = strstr(response, "+CPIN:"); - if (searchPtr != nullptr) { - searchPtr += strlen("+CPIN:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%15s\r\n", c); + // Check currently set MNO profile + if (getMNOprofile(¤tMno) != UBX_CELL_ERROR_SUCCESS) + { + return false; } - if (scanned == 1) + + if (currentMno == mno) { - if(code) - *code = c; + return true; } - else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - free(command); - free(response); + // Disable transmit and receive so we can change operator + if (functionality(MINIMUM_FUNCTIONALITY) != UBX_CELL_ERROR_SUCCESS) + { + return false; + } - return err; -} + if (setMNOprofile(mno, autoReset, urcNotification) != UBX_CELL_ERROR_SUCCESS) + { + return false; + } -UBX_CELL_error_t UBX_CELL::setSimPin(String pin) -{ - UBX_CELL_error_t err; - char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_SIMPIN) + 4 + pin.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_COMMAND_SIMPIN, pin.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + if (reset() != UBX_CELL_ERROR_SUCCESS) + { + return false; + } + + return true; } -UBX_CELL_error_t UBX_CELL::setSIMstateReportingMode(int mode) +mobile_network_operator_t UBX_CELL::getNetworkProfile(void) { - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SIM_STATE) + 4); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_SIM_STATE, mode); + mobile_network_operator_t mno; + UBX_CELL_error_t err; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + err = getMNOprofile(&mno); + if (err != UBX_CELL_ERROR_SUCCESS) + { + return MNO_INVALID; + } + return mno; } -UBX_CELL_error_t UBX_CELL::getSIMstateReportingMode(int *mode) +UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdpType) { - UBX_CELL_error_t err; - char *command; - char *response; - - int m; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SIM_STATE) + 3); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_SIM_STATE); + UBX_CELL_error_t err; + char *command; + char pdpStr[8]; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + memset(pdpStr, 0, 8); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (cid >= 8) + return UBX_CELL_ERROR_UNEXPECTED_PARAM; - if (err == UBX_CELL_ERROR_SUCCESS) - { - int scanned = 0; - char *searchPtr = strstr(response, "+USIMSTAT:"); - if (searchPtr != nullptr) + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_DEF) + strlen(apn.c_str()) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + switch (pdpType) { - searchPtr += strlen("+USIMSTAT:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d\r\n", &m); + case PDP_TYPE_INVALID: + free(command); + return UBX_CELL_ERROR_UNEXPECTED_PARAM; + break; + case PDP_TYPE_IP: + memcpy(pdpStr, "IP", 2); + break; + case PDP_TYPE_NONIP: + memcpy(pdpStr, "NONIP", 5); + break; + case PDP_TYPE_IPV4V6: + memcpy(pdpStr, "IPV4V6", 6); + break; + case PDP_TYPE_IPV6: + memcpy(pdpStr, "IPV6", 4); + break; + default: + free(command); + return UBX_CELL_ERROR_UNEXPECTED_PARAM; + break; } - if (scanned == 1) + if (apn == nullptr) { - *mode = m; + if (_printDebug == true) + _debugPort->println(F("setAPN: nullptr")); + sprintf(command, "%s=%d,\"%s\",\"\"", UBX_CELL_MESSAGE_PDP_DEF, cid, pdpStr); } else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + { + if (_printDebug == true) + { + _debugPort->print(F("setAPN: ")); + _debugPort->println(apn); + } + sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MESSAGE_PDP_DEF, cid, pdpStr, apn.c_str()); + } - free(command); - free(response); - return err; -} + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); -const char *PPP_L2P[5] = { - "", - "PPP", - "M-HEX", - "M-RAW_IP", - "M-OPT-PPP", -}; - -UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, - unsigned long dialNumber, UBX_CELL::UBX_CELL_l2p_t l2p) -{ - UBX_CELL_error_t err; - char *command; + free(command); - if ((dialing_type_char != 0) && (dialing_type_char != 'T') && - (dialing_type_char != 'P')) - { - return UBX_CELL_ERROR_UNEXPECTED_PARAM; - } + return err; +} - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_ENTER_PPP) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (dialing_type_char != 0) - { - sprintf(command, "%s%c*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialing_type_char, - dialNumber, PPP_L2P[l2p], (unsigned int)cid); - } - else - { - sprintf(command, "%s*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, - dialNumber, PPP_L2P[l2p], (unsigned int)cid); - } +// Return the Access Point Name and IP address for the chosen context identifier +UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_pdp_type *pdpType) +{ + UBX_CELL_error_t err; + char *command; + char *response; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (cid > UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) + return UBX_CELL_ERROR_ERROR; - free(command); - return err; -} + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_DEF) + 3); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_MESSAGE_PDP_DEF); -uint8_t UBX_CELL::getOperators(struct operator_stats *opRet, int maxOps) -{ - UBX_CELL_error_t err; - char *command; - char *response; - uint8_t opsSeen = 0; + response = ubx_cell_calloc_char(1024); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 3); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=?", UBX_CELL_OPERATOR_SELECTION); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT, + 1024); - int responseSize = (maxOps + 1) * 48; - response = ubx_cell_calloc_char(responseSize); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - // AT+COPS maximum response time is 3 minutes (180000 ms) - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_3_MIN_TIMEOUT, responseSize); - - // Sample responses: - // +COPS: (3,"Verizon Wireless","VzW","311480",8),,(0,1,2,3,4),(0,1,2) - // +COPS: (1,"313 100","313 100","313100",8),(2,"AT&T","AT&T","310410",8),(3,"311 480","311 480","311480",8),,(0,1,2,3,4),(0,1,2) - - if (_printDebug == true) - { - _debugPort->print(F("getOperators: Response: {")); - _debugPort->print(response); - _debugPort->println(F("}")); - } - - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *opBegin; - char *opEnd; - int op = 0; - int stat; - char longOp[26]; - char shortOp[11]; - int act; - unsigned long numOp; - - opBegin = response; - - for (; op < maxOps; op++) - { - opBegin = strchr(opBegin, '('); - if (opBegin == nullptr) - break; - opEnd = strchr(opBegin, ')'); - if (opEnd == nullptr) - break; + if (err == UBX_CELL_ERROR_SUCCESS) + { + // Example: + // +CGDCONT: 0,"IP","payandgo.o2.co.uk","0.0.0.0",0,0,0,0,0,0,0,0,0,0 + // +CGDCONT: 1,"IP","payandgo.o2.co.uk.mnc010.mcc234.gprs","10.160.182.234",0,0,0,2,0,0,0,0,0,0 + int rcid = -1; + char *searchPtr = response; - int sscanRead = sscanf(opBegin, "(%d,\"%[^\"]\",\"%[^\"]\",\"%lu\",%d)%*s", - &stat, longOp, shortOp, &numOp, &act); - if (sscanRead == 5) - { - opRet[op].stat = stat; - opRet[op].longOp = (String)(longOp); - opRet[op].shortOp = (String)(shortOp); - opRet[op].numOp = numOp; - opRet[op].act = act; - opsSeen += 1; - } - // TODO: Search for other possible patterns here - else - { - break; // Break out if pattern doesn't match. - } - opBegin = opEnd + 1; // Move opBegin to beginning of next value + bool keepGoing = true; + while (keepGoing == true) + { + int scanned = 0; + // Find the first/next occurrence of +CGDCONT: + searchPtr = strstr(searchPtr, "+CGDCONT:"); + if (searchPtr != nullptr) + { + char strPdpType[10]; + char strApn[128]; + int ipOct[4]; + + searchPtr += strlen("+CGDCONT:"); // Point to the cid + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,\"%[^\"]\",\"%[^\"]\",\"%d.%d.%d.%d", &rcid, strPdpType, strApn, + &ipOct[0], &ipOct[1], &ipOct[2], &ipOct[3]); + if ((scanned == 7) && (rcid == cid)) + { + if (apn) + *apn = strApn; + for (int o = 0; ip && (o < 4); o++) + { + (*ip)[o] = (uint8_t)ipOct[o]; + } + if (pdpType) + { + *pdpType = (0 == strcmp(strPdpType, "IPV4V6")) ? PDP_TYPE_IPV4V6 + : (0 == strcmp(strPdpType, "IPV6")) ? PDP_TYPE_IPV6 + : (0 == strcmp(strPdpType, "IP")) ? PDP_TYPE_IP + : PDP_TYPE_INVALID; + } + keepGoing = false; + } + } + else // We don't have a match so let's clear the APN and IP address + { + if (apn) + *apn = ""; + if (pdpType) + *pdpType = PDP_TYPE_INVALID; + if (ip) + *ip = {0, 0, 0, 0}; + keepGoing = false; + } + } + } + else + { + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - } - free(command); - free(response); + free(command); + free(response); - return opsSeen; + return err; } -UBX_CELL_error_t UBX_CELL::registerOperator(struct operator_stats oper) +UBX_CELL_error_t UBX_CELL::getSimStatus(String *code) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; + char *response; + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_SIMPIN) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_COMMAND_SIMPIN); + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 24); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=1,2,\"%lu\"", UBX_CELL_OPERATOR_SELECTION, oper.numOp); + if (err == UBX_CELL_ERROR_SUCCESS) + { + int scanned = 0; + char c[16]; + char *searchPtr = strstr(response, "+CPIN:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+CPIN:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%15s\r\n", c); + } + if (scanned == 1) + { + if (code) + *code = c; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - // AT+COPS maximum response time is 3 minutes (180000 ms) - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_3_MIN_TIMEOUT); + free(command); + free(response); - free(command); - return err; + return err; } -UBX_CELL_error_t UBX_CELL::automaticOperatorSelection() +UBX_CELL_error_t UBX_CELL::setSimPin(String pin) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_SIMPIN) + 4 + pin.length()); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_COMMAND_SIMPIN, pin.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 6); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=0,0", UBX_CELL_OPERATOR_SELECTION); +UBX_CELL_error_t UBX_CELL::setSIMstateReportingMode(int mode) +{ + UBX_CELL_error_t err; + char *command; - // AT+COPS maximum response time is 3 minutes (180000 ms) - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_3_MIN_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SIM_STATE) + 4); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_SIM_STATE, mode); - free(command); - return err; + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::getOperator(String *oper) +UBX_CELL_error_t UBX_CELL::getSIMstateReportingMode(int *mode) { - UBX_CELL_error_t err; - char *command; - char *response; - char *searchPtr; - char mode; + UBX_CELL_error_t err; + char *command; + char *response; - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 3); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_OPERATOR_SELECTION); + int m; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + command = ubx_cell_calloc_char(strlen(UBX_CELL_SIM_STATE) + 3); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_SIM_STATE); - // AT+COPS maximum response time is 3 minutes (180000 ms) - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_3_MIN_TIMEOUT); + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - if (err == UBX_CELL_ERROR_SUCCESS) - { - searchPtr = strstr(response, "+COPS:"); - if (searchPtr != nullptr) + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) { - searchPtr += strlen("+COPS:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - mode = *searchPtr; // Read first char -- should be mode - if (mode == '2') // Check for de-register - { - err = UBX_CELL_ERROR_DEREGISTERED; - } - // Otherwise if it's default, manual, set-only, or automatic - else if ((mode == '0') || (mode == '1') || (mode == '3') || (mode == '4')) - { - *oper = ""; - searchPtr = strchr(searchPtr, '\"'); // Move to first quote - if (searchPtr == nullptr) - { - err = UBX_CELL_ERROR_DEREGISTERED; - } - else + int scanned = 0; + char *searchPtr = strstr(response, "+USIMSTAT:"); + if (searchPtr != nullptr) { - while ((*(++searchPtr) != '\"') && (*searchPtr != '\0')) - { - oper->concat(*(searchPtr)); - } + searchPtr += strlen("+USIMSTAT:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d\r\n", &m); } - if (_printDebug == true) + if (scanned == 1) { - _debugPort->print(F("getOperator: ")); - _debugPort->println(*oper); + *mode = m; } - } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - } - free(response); - free(command); - return err; + free(command); + free(response); + return err; } -UBX_CELL_error_t UBX_CELL::deregisterOperator(void) +const char *PPP_L2P[5] = { + "", "PPP", "M-HEX", "M-RAW_IP", "M-OPT-PPP", +}; + +UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, unsigned long dialNumber, + UBX_CELL::UBX_CELL_l2p_t l2p) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 4); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=2", UBX_CELL_OPERATOR_SELECTION); + if ((dialing_type_char != 0) && (dialing_type_char != 'T') && (dialing_type_char != 'P')) + { + return UBX_CELL_ERROR_UNEXPECTED_PARAM; + } + + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_ENTER_PPP) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (dialing_type_char != 0) + { + sprintf(command, "%s%c*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialing_type_char, dialNumber, PPP_L2P[l2p], + (unsigned int)cid); + } + else + { + sprintf(command, "%s*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialNumber, PPP_L2P[l2p], (unsigned int)cid); + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_3_MIN_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::setSMSMessageFormat(UBX_CELL_message_format_t textMode) +uint8_t UBX_CELL::getOperators(struct operator_stats *opRet, int maxOps) { - char *command; - UBX_CELL_error_t err; + UBX_CELL_error_t err; + char *command; + char *response; + uint8_t opsSeen = 0; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_FORMAT) + 4); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_MESSAGE_FORMAT, - (textMode == UBX_CELL_MESSAGE_FORMAT_TEXT) ? 1 : 0); + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 3); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=?", UBX_CELL_OPERATOR_SELECTION); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + int responseSize = (maxOps + 1) * 48; + response = ubx_cell_calloc_char(responseSize); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - free(command); - return err; -} + // AT+COPS maximum response time is 3 minutes (180000 ms) + err = + sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_3_MIN_TIMEOUT, responseSize); -UBX_CELL_error_t UBX_CELL::sendSMS(String number, String message) -{ - char *command; - char *messageCStr; - char *numberCStr; - UBX_CELL_error_t err; + // Sample responses: + // +COPS: (3,"Verizon Wireless","VzW","311480",8),,(0,1,2,3,4),(0,1,2) + // +COPS: (1,"313 100","313 100","313100",8),(2,"AT&T","AT&T","310410",8),(3,"311 480","311 + // 480","311480",8),,(0,1,2,3,4),(0,1,2) - numberCStr = ubx_cell_calloc_char(number.length() + 2); - if (numberCStr == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - number.toCharArray(numberCStr, number.length() + 1); + if (_printDebug == true) + { + _debugPort->print(F("getOperators: Response: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEND_TEXT) + strlen(numberCStr) + 8); - if (command != nullptr) - { - sprintf(command, "%s=\"%s\"", UBX_CELL_SEND_TEXT, numberCStr); + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *opBegin; + char *opEnd; + int op = 0; + int stat; + char longOp[26]; + char shortOp[11]; + int act; + unsigned long numOp; - err = sendCommandWithResponse(command, ">", nullptr, - UBX_CELL_10_SEC_TIMEOUT); - free(command); - free(numberCStr); - if (err != UBX_CELL_ERROR_SUCCESS) - return err; + opBegin = response; - messageCStr = ubx_cell_calloc_char(message.length() + 1); - if (messageCStr == nullptr) - { - hwWrite(ASCII_CTRL_Z); - return UBX_CELL_ERROR_OUT_OF_MEMORY; + for (; op < maxOps; op++) + { + opBegin = strchr(opBegin, '('); + if (opBegin == nullptr) + break; + opEnd = strchr(opBegin, ')'); + if (opEnd == nullptr) + break; + + int sscanRead = + sscanf(opBegin, "(%d,\"%[^\"]\",\"%[^\"]\",\"%lu\",%d)%*s", &stat, longOp, shortOp, &numOp, &act); + if (sscanRead == 5) + { + opRet[op].stat = stat; + opRet[op].longOp = (String)(longOp); + opRet[op].shortOp = (String)(shortOp); + opRet[op].numOp = numOp; + opRet[op].act = act; + opsSeen += 1; + } + // TODO: Search for other possible patterns here + else + { + break; // Break out if pattern doesn't match. + } + opBegin = opEnd + 1; // Move opBegin to beginning of next value + } } - message.toCharArray(messageCStr, message.length() + 1); - messageCStr[message.length()] = ASCII_CTRL_Z; - err = sendCommandWithResponse(messageCStr, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_10_SEC_TIMEOUT, minimumResponseAllocation, NOT_AT_COMMAND); - - free(messageCStr); - } - else - { - free(numberCStr); - err = UBX_CELL_ERROR_OUT_OF_MEMORY; - } + free(command); + free(response); - return err; + return opsSeen; } -UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, String memory) +UBX_CELL_error_t UBX_CELL::registerOperator(struct operator_stats oper) { - UBX_CELL_error_t err; - char *command; - char *response; - int u; - int t; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_PREF_MESSAGE_STORE) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_PREF_MESSAGE_STORE, memory.c_str()); + UBX_CELL_error_t err; + char *command; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 24); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=1,2,\"%lu\"", UBX_CELL_OPERATOR_SELECTION, oper.numOp); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_3_MIN_TIMEOUT); + // AT+COPS maximum response time is 3 minutes (180000 ms) + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); - if (err != UBX_CELL_ERROR_SUCCESS) - { free(command); - free(response); return err; - } - - int scanned = 0; - char *searchPtr = strstr(response, "+CPMS:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+CPMS:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d,%d", &u, &t); - } - if (scanned == 2) - { - if (_printDebug == true) - { - _debugPort->print(F("getPreferredMessageStorage: memory1 (read and delete): ")); - _debugPort->print(memory); - _debugPort->print(F(" used: ")); - _debugPort->print(u); - _debugPort->print(F(" total: ")); - _debugPort->println(t); - } - *used = u; - *total = t; - } - else - { - err = UBX_CELL_ERROR_INVALID; - } - - free(response); - free(command); - return err; } -UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message) +UBX_CELL_error_t UBX_CELL::automaticOperatorSelection() { - UBX_CELL_error_t err; - char *command; - char *response; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_TEXT_MESSAGE) + 5); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_READ_TEXT_MESSAGE, location); + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 6); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=0,0", UBX_CELL_OPERATOR_SELECTION); + + // AT+COPS maximum response time is 3 minutes (180000 ms) + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); - response = ubx_cell_calloc_char(1024); - if (response == nullptr) - { free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + return err; +} - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_10_SEC_TIMEOUT, 1024); +UBX_CELL_error_t UBX_CELL::getOperator(String *oper) +{ + UBX_CELL_error_t err; + char *command; + char *response; + char *searchPtr; + char mode; - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = response; + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 3); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_OPERATOR_SELECTION); - // Find the first occurrence of +CMGR: - searchPtr = strstr(searchPtr, "+CMGR:"); - if (searchPtr != nullptr) + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - searchPtr += strlen("+CMGR:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - int pointer = 0; - while ((*(++searchPtr) != '\"') && (*searchPtr != '\0') && (pointer < 12)) - { - unread->concat(*(searchPtr)); - pointer++; - } - if ((*searchPtr == '\0') || (pointer == 12)) - { - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - // Search to the next quote - searchPtr = strchr(++searchPtr, '\"'); - pointer = 0; - while ((*(++searchPtr) != '\"') && (*searchPtr != '\0') && (pointer < 24)) - { - from->concat(*(searchPtr)); - pointer++; - } - if ((*searchPtr == '\0') || (pointer == 24)) - { - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - // Skip two commas - searchPtr = strchr(++searchPtr, ','); - searchPtr = strchr(++searchPtr, ','); - // Search to the next quote - searchPtr = strchr(++searchPtr, '\"'); - pointer = 0; - while ((*(++searchPtr) != '\"') && (*searchPtr != '\0') && (pointer < 24)) - { - dateTime->concat(*(searchPtr)); - pointer++; - } - if ((*searchPtr == '\0') || (pointer == 24)) - { - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - // Search to the next new line - searchPtr = strchr(++searchPtr, '\n'); - pointer = 0; - while ((*(++searchPtr) != '\r') && (*searchPtr != '\n') && (*searchPtr != '\0') && (pointer < 512)) - { - message->concat(*(searchPtr)); - pointer++; - } - if ((*searchPtr == '\0') || (pointer == 512)) - { free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - else + + // AT+COPS maximum response time is 3 minutes (180000 ms) + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_3_MIN_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) { - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + searchPtr = strstr(response, "+COPS:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+COPS:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + mode = *searchPtr; // Read first char -- should be mode + if (mode == '2') // Check for de-register + { + err = UBX_CELL_ERROR_DEREGISTERED; + } + // Otherwise if it's default, manual, set-only, or automatic + else if ((mode == '0') || (mode == '1') || (mode == '3') || (mode == '4')) + { + *oper = ""; + searchPtr = strchr(searchPtr, '\"'); // Move to first quote + if (searchPtr == nullptr) + { + err = UBX_CELL_ERROR_DEREGISTERED; + } + else + { + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0')) + { + oper->concat(*(searchPtr)); + } + } + if (_printDebug == true) + { + _debugPort->print(F("getOperator: ")); + _debugPort->println(*oper); + } + } + } } - } - else - { - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - free(command); - free(response); - return err; + free(response); + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::deleteSMSmessage(int location, int deleteFlag) +UBX_CELL_error_t UBX_CELL::deregisterOperator(void) { - char *command; - UBX_CELL_error_t err; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_DELETE_MESSAGE) + 12); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (deleteFlag == 0) - sprintf(command, "%s=%d", UBX_CELL_DELETE_MESSAGE, location); - else - sprintf(command, "%s=%d,%d", UBX_CELL_DELETE_MESSAGE, location, deleteFlag); + command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 4); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=2", UBX_CELL_OPERATOR_SELECTION); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_55_SECS_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) +UBX_CELL_error_t UBX_CELL::setSMSMessageFormat(UBX_CELL_message_format_t textMode) { - UBX_CELL_error_t err; - char *command; - int b = 0; - - // Error check -- ensure supported baud - for (; b < NUM_SUPPORTED_BAUD; b++) - { - if (UBX_CELL_SUPPORTED_BAUD[b] == baud) - { - break; - } - } - if (b >= NUM_SUPPORTED_BAUD) - { - return UBX_CELL_ERROR_UNEXPECTED_PARAM; - } - - // Construct command - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_BAUD) + 7 + 12); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%lu", UBX_CELL_COMMAND_BAUD, baud); + char *command; + UBX_CELL_error_t err; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_SET_BAUD_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_FORMAT) + 4); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_MESSAGE_FORMAT, (textMode == UBX_CELL_MESSAGE_FORMAT_TEXT) ? 1 : 0); - free(command); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::setFlowControl(UBX_CELL_flow_control_t value) +UBX_CELL_error_t UBX_CELL::sendSMS(String number, String message) { - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_FLOW_CONTROL) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s%d", UBX_CELL_FLOW_CONTROL, value); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + char *command; + char *messageCStr; + char *numberCStr; + UBX_CELL_error_t err; - free(command); + numberCStr = ubx_cell_calloc_char(number.length() + 2); + if (numberCStr == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + number.toCharArray(numberCStr, number.length() + 1); - return err; -} + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEND_TEXT) + strlen(numberCStr) + 8); + if (command != nullptr) + { + sprintf(command, "%s=\"%s\"", UBX_CELL_SEND_TEXT, numberCStr); -UBX_CELL_error_t UBX_CELL::setGpioMode(UBX_CELL_gpio_t gpio, - UBX_CELL_gpio_mode_t mode, int value) -{ - UBX_CELL_error_t err; - char *command; + err = sendCommandWithResponse(command, ">", nullptr, UBX_CELL_10_SEC_TIMEOUT); + free(command); + free(numberCStr); + if (err != UBX_CELL_ERROR_SUCCESS) + return err; - // Example command: AT+UGPIOC=16,2 - // Example command: AT+UGPIOC=23,0,1 - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GPIO) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (mode == GPIO_OUTPUT) - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode, value); - else - sprintf(command, "%s=%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode); + messageCStr = ubx_cell_calloc_char(message.length() + 1); + if (messageCStr == nullptr) + { + hwWrite(ASCII_CTRL_Z); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + message.toCharArray(messageCStr, message.length() + 1); + messageCStr[message.length()] = ASCII_CTRL_Z; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_10_SEC_TIMEOUT); + err = sendCommandWithResponse(messageCStr, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT, + minimumResponseAllocation, NOT_AT_COMMAND); - free(command); + free(messageCStr); + } + else + { + free(numberCStr); + err = UBX_CELL_ERROR_OUT_OF_MEMORY; + } - return err; + return err; } -UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) +UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, String memory) { - UBX_CELL_error_t err; - char *command; - char *response; - char gpioChar[4]; - char *gpioStart; - int gpioMode; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GPIO) + 2); - if (command == nullptr) - return GPIO_MODE_INVALID; - sprintf(command, "%s?", UBX_CELL_COMMAND_GPIO); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return GPIO_MODE_INVALID; - } + UBX_CELL_error_t err; + char *command; + char *response; + int u; + int t; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_PREF_MESSAGE_STORE) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_PREF_MESSAGE_STORE, memory.c_str()); - if (err != UBX_CELL_ERROR_SUCCESS) - { - free(command); - free(response); - return GPIO_MODE_INVALID; - } + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - sprintf(gpioChar, "%d", gpio); // Convert GPIO to char array - gpioStart = strstr(response, gpioChar); // Find first occurence of GPIO in response + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_3_MIN_TIMEOUT); - free(command); - free(response); + if (err != UBX_CELL_ERROR_SUCCESS) + { + free(command); + free(response); + return err; + } - if (gpioStart == nullptr) - return GPIO_MODE_INVALID; // If not found return invalid - sscanf(gpioStart, "%*d,%d\r\n", &gpioMode); + int scanned = 0; + char *searchPtr = strstr(response, "+CPMS:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+CPMS:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d", &u, &t); + } + if (scanned == 2) + { + if (_printDebug == true) + { + _debugPort->print(F("getPreferredMessageStorage: memory1 (read and delete): ")); + _debugPort->print(memory); + _debugPort->print(F(" used: ")); + _debugPort->print(u); + _debugPort->print(F(" total: ")); + _debugPort->println(t); + } + *used = u; + *total = t; + } + else + { + err = UBX_CELL_ERROR_INVALID; + } - return (UBX_CELL_gpio_mode_t)gpioMode; + free(response); + free(command); + return err; } -int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int localPort) +UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message) { - UBX_CELL_error_t err; - char *command; - char *response; - int sockId = -1; - char *responseStart; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_CREATE_SOCKET) + 10); - if (command == nullptr) - return -1; - if (localPort == 0) - sprintf(command, "%s=%d", UBX_CELL_CREATE_SOCKET, (int)protocol); - else - sprintf(command, "%s=%d,%d", UBX_CELL_CREATE_SOCKET, (int)protocol, localPort); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - if (_printDebug == true) - _debugPort->println(F("socketOpen: Fail: nullptr response")); - free(command); - return -1; - } + UBX_CELL_error_t err; + char *command; + char *response; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_TEXT_MESSAGE) + 5); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_READ_TEXT_MESSAGE, location); - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) + response = ubx_cell_calloc_char(1024); + if (response == nullptr) { - _debugPort->print(F("socketOpen: Fail: Error: ")); - _debugPort->print(err); - _debugPort->print(F(" Response: {")); - _debugPort->print(response); - _debugPort->println(F("}")); + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - free(command); - free(response); - return -1; - } - responseStart = strstr(response, "+USOCR:"); - if (responseStart == nullptr) - { - if (_printDebug == true) + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT, 1024); + + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = response; + + // Find the first occurrence of +CMGR: + searchPtr = strstr(searchPtr, "+CMGR:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+CMGR:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + int pointer = 0; + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0') && (pointer < 12)) + { + unread->concat(*(searchPtr)); + pointer++; + } + if ((*searchPtr == '\0') || (pointer == 12)) + { + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + // Search to the next quote + searchPtr = strchr(++searchPtr, '\"'); + pointer = 0; + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0') && (pointer < 24)) + { + from->concat(*(searchPtr)); + pointer++; + } + if ((*searchPtr == '\0') || (pointer == 24)) + { + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + // Skip two commas + searchPtr = strchr(++searchPtr, ','); + searchPtr = strchr(++searchPtr, ','); + // Search to the next quote + searchPtr = strchr(++searchPtr, '\"'); + pointer = 0; + while ((*(++searchPtr) != '\"') && (*searchPtr != '\0') && (pointer < 24)) + { + dateTime->concat(*(searchPtr)); + pointer++; + } + if ((*searchPtr == '\0') || (pointer == 24)) + { + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + // Search to the next new line + searchPtr = strchr(++searchPtr, '\n'); + pointer = 0; + while ((*(++searchPtr) != '\r') && (*searchPtr != '\n') && (*searchPtr != '\0') && (pointer < 512)) + { + message->concat(*(searchPtr)); + pointer++; + } + if ((*searchPtr == '\0') || (pointer == 512)) + { + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + } + else + { + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + } + else { - _debugPort->print(F("socketOpen: Failure: {")); - _debugPort->print(response); - _debugPort->println(F("}")); + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } + free(command); free(response); - return -1; - } - - responseStart += strlen("+USOCR:"); // Move searchPtr to first char - while (*responseStart == ' ') responseStart++; // skip spaces - sscanf(responseStart, "%d", &sockId); - _lastSocketProtocol[sockId] = (int)protocol; - free(command); - free(response); - - return sockId; + return err; } -UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) +UBX_CELL_error_t UBX_CELL::deleteSMSmessage(int location, int deleteFlag) { - UBX_CELL_error_t err; - char *command; - char *response; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_CLOSE_SOCKET) + 10); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - // if timeout is short, close asynchronously and don't wait for socket closure (we will get the URC later) - // this will make sure the AT command parser is not confused during init() - const char* format = (UBX_CELL_STANDARD_RESPONSE_TIMEOUT == timeout) ? "%s=%d,1" : "%s=%d"; - sprintf(command, format, UBX_CELL_CLOSE_SOCKET, socket); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, timeout); + char *command; + UBX_CELL_error_t err; - if ((err != UBX_CELL_ERROR_SUCCESS) && (_printDebug == true)) - { - _debugPort->print(F("socketClose: Error: ")); - _debugPort->println(socketGetLastError()); - } + command = ubx_cell_calloc_char(strlen(UBX_CELL_DELETE_MESSAGE) + 12); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (deleteFlag == 0) + sprintf(command, "%s=%d", UBX_CELL_DELETE_MESSAGE, location); + else + sprintf(command, "%s=%d,%d", UBX_CELL_DELETE_MESSAGE, location, deleteFlag); - free(command); - free(response); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_55_SECS_TIMEOUT); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::socketConnect(int socket, const char *address, - unsigned int port) +UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; + int b = 0; + + // Error check -- ensure supported baud + for (; b < NUM_SUPPORTED_BAUD; b++) + { + if (UBX_CELL_SUPPORTED_BAUD[b] == baud) + { + break; + } + } + if (b >= NUM_SUPPORTED_BAUD) + { + return UBX_CELL_ERROR_UNEXPECTED_PARAM; + } - command = ubx_cell_calloc_char(strlen(UBX_CELL_CONNECT_SOCKET) + strlen(address) + 11); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\",%d", UBX_CELL_CONNECT_SOCKET, socket, address, port); + // Construct command + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_BAUD) + 7 + 12); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%lu", UBX_CELL_COMMAND_BAUD, baud); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_IP_CONNECT_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_SET_BAUD_TIMEOUT); - free(command); + free(command); - return err; + return err; } -UBX_CELL_error_t UBX_CELL::socketConnect(int socket, IPAddress address, - unsigned int port) +UBX_CELL_error_t UBX_CELL::setFlowControl(UBX_CELL_flow_control_t value) { - char *charAddress = ubx_cell_calloc_char(16); - if (charAddress == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - memset(charAddress, 0, 16); - sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); + UBX_CELL_error_t err; + char *command; - return (socketConnect(socket, (const char *)charAddress, port)); -} + command = ubx_cell_calloc_char(strlen(UBX_CELL_FLOW_CONTROL) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s%d", UBX_CELL_FLOW_CONTROL, value); -UBX_CELL_error_t UBX_CELL::socketWrite(int socket, const char *str, int len) -{ - char *command; - char *response; - UBX_CELL_error_t err; + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - command = ubx_cell_calloc_char(strlen(UBX_CELL_WRITE_SOCKET) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - int dataLen = len == -1 ? strlen(str) : len; - sprintf(command, "%s=%d,%d", UBX_CELL_WRITE_SOCKET, socket, dataLen); - err = sendCommandWithResponse(command, "@", response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); + return err; +} - if (err == UBX_CELL_ERROR_SUCCESS) - { - unsigned long writeDelay = millis(); - while (millis() < (writeDelay + 50)) - delay(1); //u-blox specification says to wait 50ms after receiving "@" to write data. +UBX_CELL_error_t UBX_CELL::setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_t mode, int value) +{ + UBX_CELL_error_t err; + char *command; - if (len == -1) - { - if (_printDebug == true) - { - _debugPort->print(F("socketWrite: writing: ")); - _debugPort->println(str); - } - hwPrint(str); - } + // Example command: AT+UGPIOC=16,2 + // Example command: AT+UGPIOC=23,0,1 + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GPIO) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (mode == GPIO_OUTPUT) + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode, value); else - { - if (_printDebug == true) - { - _debugPort->print(F("socketWrite: writing ")); - _debugPort->print(len); - _debugPort->println(F(" bytes")); - } - hwWriteData(str, len); - } - - err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_SOCKET_WRITE_TIMEOUT); - } + sprintf(command, "%s=%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode); - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) - { - _debugPort->print(F("socketWrite: Error: ")); - _debugPort->print(err); - _debugPort->print(F(" => {")); - _debugPort->print(response); - _debugPort->println(F("}")); - } - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); - free(command); - free(response); - return err; -} + free(command); -UBX_CELL_error_t UBX_CELL::socketWrite(int socket, String str) -{ - return socketWrite(socket, str.c_str(), str.length()); + return err; } -UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int port, const char *str, int len) +UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) { - char *command; - char *response; - UBX_CELL_error_t err; - int dataLen = len == -1 ? strlen(str) : len; - - command = ubx_cell_calloc_char(64); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + UBX_CELL_error_t err; + char *command; + char *response; + char gpioChar[4]; + char *gpioStart; + int gpioMode; - sprintf(command, "%s=%d,\"%s\",%d,%d", UBX_CELL_WRITE_UDP_SOCKET, - socket, address, port, dataLen); - err = sendCommandWithResponse(command, "@", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GPIO) + 2); + if (command == nullptr) + return GPIO_MODE_INVALID; + sprintf(command, "%s?", UBX_CELL_COMMAND_GPIO); - if (err == UBX_CELL_ERROR_SUCCESS) - { - if (len == -1) //If binary data we need to send a length. + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - hwPrint(str); + free(command); + return GPIO_MODE_INVALID; } - else + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err != UBX_CELL_ERROR_SUCCESS) { - hwWriteData(str, len); + free(command); + free(response); + return GPIO_MODE_INVALID; } - err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_SOCKET_WRITE_TIMEOUT); - } - else - { - if (_printDebug == true) - _debugPort->print(F("socketWriteUDP: Error: ")); - if (_printDebug == true) - _debugPort->println(socketGetLastError()); - } - free(command); - free(response); - return err; -} + sprintf(gpioChar, "%d", gpio); // Convert GPIO to char array + gpioStart = strstr(response, gpioChar); // Find first occurence of GPIO in response -UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len) -{ - char *charAddress = ubx_cell_calloc_char(16); - if (charAddress == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - memset(charAddress, 0, 16); - sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); + free(command); + free(response); - return (socketWriteUDP(socket, (const char *)charAddress, port, str, len)); -} + if (gpioStart == nullptr) + return GPIO_MODE_INVALID; // If not found return invalid + sscanf(gpioStart, "%*d,%d\r\n", &gpioMode); -UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, String address, int port, String str) -{ - return socketWriteUDP(socket, address.c_str(), port, str.c_str(), str.length()); + return (UBX_CELL_gpio_mode_t)gpioMode; } -UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, int *bytesRead) +int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int localPort) { - char *command; - char *response; - char *strBegin; - int readIndexTotal = 0; - int readIndexThisRead = 0; - UBX_CELL_error_t err; - int scanNum = 0; - int readLength = 0; - int socketStore = 0; - int bytesLeftToRead = length; - int bytesToRead; - - // Set *bytesRead to zero - if (bytesRead != nullptr) - *bytesRead = 0; - - // Check if length is zero - if (length == 0) - { - if (_printDebug == true) - _debugPort->print(F("socketRead: length is 0! Call socketReadAvailable?")); - return UBX_CELL_ERROR_UNEXPECTED_PARAM; - } - - // Allocate memory for the command - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_SOCKET) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - - // Allocate memory for the response - // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing - int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_SOCKET) + minimumResponseAllocation; - response = ubx_cell_calloc_char(responseLength); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - // If there are more than _saraR5maxSocketRead (1024) bytes to be read, - // we need to do multiple reads to get all the data + UBX_CELL_error_t err; + char *command; + char *response; + int sockId = -1; + char *responseStart; - while (bytesLeftToRead > 0) - { - if (bytesLeftToRead > _saraR5maxSocketRead) // Limit a single read to _saraR5maxSocketRead - bytesToRead = _saraR5maxSocketRead; + command = ubx_cell_calloc_char(strlen(UBX_CELL_CREATE_SOCKET) + 10); + if (command == nullptr) + return -1; + if (localPort == 0) + sprintf(command, "%s=%d", UBX_CELL_CREATE_SOCKET, (int)protocol); else - bytesToRead = bytesLeftToRead; + sprintf(command, "%s=%d,%d", UBX_CELL_CREATE_SOCKET, (int)protocol, localPort); - sprintf(command, "%s=%d,%d", UBX_CELL_READ_SOCKET, socket, bytesToRead); + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + if (_printDebug == true) + _debugPort->println(F("socketOpen: Fail: nullptr response")); + free(command); + return -1; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT, responseLength); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err != UBX_CELL_ERROR_SUCCESS) { - if (_printDebug == true) - { - _debugPort->print(F("socketRead: sendCommandWithResponse err ")); - _debugPort->println(err); - } - free(command); - free(response); - return err; + if (_printDebug == true) + { + _debugPort->print(F("socketOpen: Fail: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" Response: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + free(command); + free(response); + return -1; } - // Extract the data - char *searchPtr = strstr(response, "+USORD:"); - if (searchPtr != nullptr) + responseStart = strstr(response, "+USOCR:"); + if (responseStart == nullptr) { - searchPtr += strlen("+USORD:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d", - &socketStore, &readLength); - } - if (scanNum != 2) - { - if (_printDebug == true) - { - _debugPort->print(F("socketRead: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + if (_printDebug == true) + { + _debugPort->print(F("socketOpen: Failure: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + free(command); + free(response); + return -1; } - // Check that readLength == bytesToRead - if (readLength != bytesToRead) - { - if (_printDebug == true) - { - _debugPort->print(F("socketRead: length mismatch! bytesToRead=")); - _debugPort->print(bytesToRead); - _debugPort->print(F(" readLength=")); - _debugPort->println(readLength); - } - } + responseStart += strlen("+USOCR:"); // Move searchPtr to first char + while (*responseStart == ' ') + responseStart++; // skip spaces + sscanf(responseStart, "%d", &sockId); + _lastSocketProtocol[sockId] = (int)protocol; - // Check that readLength > 0 - if (readLength == 0) - { - if (_printDebug == true) - { - _debugPort->println(F("socketRead: zero length!")); - } - free(command); - free(response); - return UBX_CELL_ERROR_ZERO_READ_LENGTH; - } + free(command); + free(response); - // Find the first double-quote: - strBegin = strchr(searchPtr, '\"'); + return sockId; +} - if (strBegin == nullptr) - { - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } +UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) +{ + UBX_CELL_error_t err; + char *command; + char *response; - // Now copy the data into readDest - readIndexThisRead = 1; // Start after the quote - while (readIndexThisRead < (readLength + 1)) + command = ubx_cell_calloc_char(strlen(UBX_CELL_CLOSE_SOCKET) + 10); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - readDest[readIndexTotal] = strBegin[readIndexThisRead]; - readIndexTotal++; - readIndexThisRead++; + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } + // if timeout is short, close asynchronously and don't wait for socket closure (we will get the URC later) + // this will make sure the AT command parser is not confused during init() + const char *format = (UBX_CELL_STANDARD_RESPONSE_TIMEOUT == timeout) ? "%s=%d,1" : "%s=%d"; + sprintf(command, format, UBX_CELL_CLOSE_SOCKET, socket); - if (_printDebug == true) - _debugPort->println(F("socketRead: success")); - - // Update *bytesRead - if (bytesRead != nullptr) - *bytesRead = readIndexTotal; + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, timeout); - // How many bytes are left to read? - // This would have been bytesLeftToRead -= bytesToRead - // Except the SARA can potentially return less data than requested... - // So we need to subtract readLength instead. - bytesLeftToRead -= readLength; - if (_printDebug == true) + if ((err != UBX_CELL_ERROR_SUCCESS) && (_printDebug == true)) { - if (bytesLeftToRead > 0) - { - _debugPort->print(F("socketRead: multiple read. bytesLeftToRead: ")); - _debugPort->println(bytesLeftToRead); - } + _debugPort->print(F("socketClose: Error: ")); + _debugPort->println(socketGetLastError()); } - } // /while (bytesLeftToRead > 0) - free(command); - free(response); + free(command); + free(response); - return UBX_CELL_ERROR_SUCCESS; + return err; } -UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) +UBX_CELL_error_t UBX_CELL::socketConnect(int socket, const char *address, unsigned int port) { - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int readLength = 0; - int socketStore = 0; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_SOCKET) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,0", UBX_CELL_READ_SOCKET, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + UBX_CELL_error_t err; + char *command; - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USORD:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+USORD:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d", - &socketStore, &readLength); - } - if (scanNum != 2) - { - if (_printDebug == true) - { - _debugPort->print(F("socketReadAvailable: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + command = ubx_cell_calloc_char(strlen(UBX_CELL_CONNECT_SOCKET) + strlen(address) + 11); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\",%d", UBX_CELL_CONNECT_SOCKET, socket, address, port); - *length = readLength; - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_IP_CONNECT_TIMEOUT); - free(command); - free(response); + free(command); - return err; + return err; } -UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, - IPAddress *remoteIPAddress, int *remotePort, int *bytesRead) +UBX_CELL_error_t UBX_CELL::socketConnect(int socket, IPAddress address, unsigned int port) { - char *command; - char *response; - char *strBegin; - int readIndexTotal = 0; - int readIndexThisRead = 0; - UBX_CELL_error_t err; - int scanNum = 0; - int remoteIPstore[4] = { 0, 0, 0, 0 }; - int portStore = 0; - int readLength = 0; - int socketStore = 0; - int bytesLeftToRead = length; - int bytesToRead; - - // Set *bytesRead to zero - if (bytesRead != nullptr) - *bytesRead = 0; - - // Check if length is zero - if (length == 0) - { - if (_printDebug == true) - _debugPort->print(F("socketReadUDP: length is 0! Call socketReadAvailableUDP?")); - return UBX_CELL_ERROR_UNEXPECTED_PARAM; - } - - // Allocate memory for the command - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_UDP_SOCKET) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - - // Allocate memory for the response - // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing - int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_UDP_SOCKET) + minimumResponseAllocation; - response = ubx_cell_calloc_char(responseLength); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - // If there are more than _saraR5maxSocketRead (1024) bytes to be read, - // we need to do multiple reads to get all the data - - while (bytesLeftToRead > 0) - { - if (bytesLeftToRead > _saraR5maxSocketRead) // Limit a single read to _saraR5maxSocketRead - bytesToRead = _saraR5maxSocketRead; - else - bytesToRead = bytesLeftToRead; - - sprintf(command, "%s=%d,%d", UBX_CELL_READ_UDP_SOCKET, socket, bytesToRead); + char *charAddress = ubx_cell_calloc_char(16); + if (charAddress == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + memset(charAddress, 0, 16); + sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT, responseLength); + return (socketConnect(socket, (const char *)charAddress, port)); +} - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) - { - _debugPort->print(F("socketReadUDP: sendCommandWithResponse err ")); - _debugPort->println(err); - } - free(command); - free(response); - return err; - } +UBX_CELL_error_t UBX_CELL::socketWrite(int socket, const char *str, int len) +{ + char *command; + char *response; + UBX_CELL_error_t err; - // Extract the data - char *searchPtr = strstr(response, "+USORF:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+USORF:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\",%d,%d", - &socketStore, &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], - &portStore, &readLength); - } - if (scanNum != 7) + command = ubx_cell_calloc_char(strlen(UBX_CELL_WRITE_SOCKET) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - if (_printDebug == true) - { - _debugPort->print(F("socketReadUDP: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } + int dataLen = len == -1 ? strlen(str) : len; + sprintf(command, "%s=%d,%d", UBX_CELL_WRITE_SOCKET, socket, dataLen); - // Check that readLength == bytesToRead - if (readLength != bytesToRead) - { - if (_printDebug == true) - { - _debugPort->print(F("socketReadUDP: length mismatch! bytesToRead=")); - _debugPort->print(bytesToRead); - _debugPort->print(F(" readLength=")); - _debugPort->println(readLength); - } - } + err = sendCommandWithResponse(command, "@", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); - // Check that readLength > 0 - if (readLength == 0) + if (err == UBX_CELL_ERROR_SUCCESS) { - if (_printDebug == true) - { - _debugPort->println(F("socketRead: zero length!")); - } - free(command); - free(response); - return UBX_CELL_ERROR_ZERO_READ_LENGTH; - } + unsigned long writeDelay = millis(); + while (millis() < (writeDelay + 50)) + delay(1); // u-blox specification says to wait 50ms after receiving "@" to write data. - // Find the third double-quote - strBegin = strchr(searchPtr, '\"'); - strBegin = strchr(strBegin + 1, '\"'); - strBegin = strchr(strBegin + 1, '\"'); - - if (strBegin == nullptr) - { - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + if (len == -1) + { + if (_printDebug == true) + { + _debugPort->print(F("socketWrite: writing: ")); + _debugPort->println(str); + } + hwPrint(str); + } + else + { + if (_printDebug == true) + { + _debugPort->print(F("socketWrite: writing ")); + _debugPort->print(len); + _debugPort->println(F(" bytes")); + } + hwWriteData(str, len); + } - // Now copy the data into readDest - readIndexThisRead = 1; // Start after the quote - while (readIndexThisRead < (readLength + 1)) - { - readDest[readIndexTotal] = strBegin[readIndexThisRead]; - readIndexTotal++; - readIndexThisRead++; + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_SOCKET_WRITE_TIMEOUT); } - // If remoteIPaddress is not nullptr, copy the remote IP address - if (remoteIPAddress != nullptr) + if (err != UBX_CELL_ERROR_SUCCESS) { - IPAddress tempAddress; - for (int i = 0; i <= 3; i++) - { - tempAddress[i] = (uint8_t)remoteIPstore[i]; - } - *remoteIPAddress = tempAddress; + if (_printDebug == true) + { + _debugPort->print(F("socketWrite: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" => {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } } - // If remotePort is not nullptr, copy the remote port - if (remotePort != nullptr) - { - *remotePort = portStore; - } + free(command); + free(response); + return err; +} - if (_printDebug == true) - _debugPort->println(F("socketReadUDP: success")); +UBX_CELL_error_t UBX_CELL::socketWrite(int socket, String str) +{ + return socketWrite(socket, str.c_str(), str.length()); +} - // Update *bytesRead - if (bytesRead != nullptr) - *bytesRead = readIndexTotal; +UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int port, const char *str, int len) +{ + char *command; + char *response; + UBX_CELL_error_t err; + int dataLen = len == -1 ? strlen(str) : len; - // How many bytes are left to read? - // This would have been bytesLeftToRead -= bytesToRead - // Except the SARA can potentially return less data than requested... - // So we need to subtract readLength instead. - bytesLeftToRead -= readLength; - if (_printDebug == true) + command = ubx_cell_calloc_char(64); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - if (bytesLeftToRead > 0) - { - _debugPort->print(F("socketReadUDP: multiple read. bytesLeftToRead: ")); - _debugPort->println(bytesLeftToRead); - } + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - } // /while (bytesLeftToRead > 0) - - free(command); - free(response); - - return UBX_CELL_ERROR_SUCCESS; -} - -UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) -{ - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int readLength = 0; - int socketStore = 0; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_UDP_SOCKET) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,0", UBX_CELL_READ_UDP_SOCKET, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + sprintf(command, "%s=%d,\"%s\",%d,%d", UBX_CELL_WRITE_UDP_SOCKET, socket, address, port, dataLen); + err = sendCommandWithResponse(command, "@", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USORF:"); - if (searchPtr != nullptr) + if (err == UBX_CELL_ERROR_SUCCESS) { - searchPtr += strlen("+USORF:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d", - &socketStore, &readLength); + if (len == -1) // If binary data we need to send a length. + { + hwPrint(str); + } + else + { + hwWriteData(str, len); + } + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_SOCKET_WRITE_TIMEOUT); } - if (scanNum != 2) + else { - if (_printDebug == true) - { - _debugPort->print(F("socketReadAvailableUDP: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + if (_printDebug == true) + _debugPort->print(F("socketWriteUDP: Error: ")); + if (_printDebug == true) + _debugPort->println(socketGetLastError()); } - *length = readLength; - } - - free(command); - free(response); - - return err; + free(command); + free(response); + return err; } -UBX_CELL_error_t UBX_CELL::socketListen(int socket, unsigned int port) +UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len) { - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_LISTEN_SOCKET) + 9); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBX_CELL_LISTEN_SOCKET, socket, port); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + char *charAddress = ubx_cell_calloc_char(16); + if (charAddress == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + memset(charAddress, 0, 16); + sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); - free(command); - return err; + return (socketWriteUDP(socket, (const char *)charAddress, port, str, len)); } -UBX_CELL_error_t UBX_CELL::socketDirectLinkMode(int socket) +UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, String address, int port, String str) { - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_DIRECT_LINK) + 8); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_SOCKET_DIRECT_LINK, socket); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - free(command); - return err; + return socketWriteUDP(socket, address.c_str(), port, str.c_str(), str.length()); } -UBX_CELL_error_t UBX_CELL::socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger) +UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, int *bytesRead) { - // valid range is 0 (trigger disabled), 100-120000 - if (!((timerTrigger == 0) || ((timerTrigger >= 100) && (timerTrigger <= 120000)))) - return UBX_CELL_ERROR_ERROR; + char *command; + char *response; + char *strBegin; + int readIndexTotal = 0; + int readIndexThisRead = 0; + UBX_CELL_error_t err; + int scanNum = 0; + int readLength = 0; + int socketStore = 0; + int bytesLeftToRead = length; + int bytesToRead; - UBX_CELL_error_t err; - char *command; + // Set *bytesRead to zero + if (bytesRead != nullptr) + *bytesRead = 0; - command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=5,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, timerTrigger); + // Check if length is zero + if (length == 0) + { + if (_printDebug == true) + _debugPort->print(F("socketRead: length is 0! Call socketReadAvailable?")); + return UBX_CELL_ERROR_UNEXPECTED_PARAM; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + // Allocate memory for the command + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_SOCKET) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; - free(command); - return err; -} + // Allocate memory for the response + // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing + int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_SOCKET) + minimumResponseAllocation; + response = ubx_cell_calloc_char(responseLength); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } -UBX_CELL_error_t UBX_CELL::socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger) -{ - // valid range is 0, 3-1472 for UDP - if (!((dataLengthTrigger == 0) || ((dataLengthTrigger >= 3) && (dataLengthTrigger <= 1472)))) - return UBX_CELL_ERROR_ERROR; + // If there are more than _saraR5maxSocketRead (1024) bytes to be read, + // we need to do multiple reads to get all the data - UBX_CELL_error_t err; - char *command; + while (bytesLeftToRead > 0) + { + if (bytesLeftToRead > _saraR5maxSocketRead) // Limit a single read to _saraR5maxSocketRead + bytesToRead = _saraR5maxSocketRead; + else + bytesToRead = bytesLeftToRead; - command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=6,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, dataLengthTrigger); + sprintf(command, "%s=%d,%d", UBX_CELL_READ_SOCKET, socket, bytesToRead); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT, responseLength); - free(command); - return err; -} + if (err != UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("socketRead: sendCommandWithResponse err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } -UBX_CELL_error_t UBX_CELL::socketDirectLinkCharacterTrigger(int socket, int characterTrigger) -{ - // The allowed range is -1, 0-255, the factory-programmed value is -1; -1 means trigger disabled. - if (!((characterTrigger >= -1) && (characterTrigger <= 255))) - return UBX_CELL_ERROR_ERROR; + // Extract the data + char *searchPtr = strstr(response, "+USORD:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USORD:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d", &socketStore, &readLength); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("socketRead: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - UBX_CELL_error_t err; - char *command; + // Check that readLength == bytesToRead + if (readLength != bytesToRead) + { + if (_printDebug == true) + { + _debugPort->print(F("socketRead: length mismatch! bytesToRead=")); + _debugPort->print(bytesToRead); + _debugPort->print(F(" readLength=")); + _debugPort->println(readLength); + } + } - command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=7,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, characterTrigger); + // Check that readLength > 0 + if (readLength == 0) + { + if (_printDebug == true) + { + _debugPort->println(F("socketRead: zero length!")); + } + free(command); + free(response); + return UBX_CELL_ERROR_ZERO_READ_LENGTH; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + // Find the first double-quote: + strBegin = strchr(searchPtr, '\"'); - free(command); - return err; -} + if (strBegin == nullptr) + { + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } -UBX_CELL_error_t UBX_CELL::socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer) -{ - // valid range is 0, 1000-72000 - if (!((congestionTimer == 0) || ((congestionTimer >= 1000) && (congestionTimer <= 72000)))) - return UBX_CELL_ERROR_ERROR; + // Now copy the data into readDest + readIndexThisRead = 1; // Start after the quote + while (readIndexThisRead < (readLength + 1)) + { + readDest[readIndexTotal] = strBegin[readIndexThisRead]; + readIndexTotal++; + readIndexThisRead++; + } + + if (_printDebug == true) + _debugPort->println(F("socketRead: success")); - UBX_CELL_error_t err; - char *command; + // Update *bytesRead + if (bytesRead != nullptr) + *bytesRead = readIndexTotal; - command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=8,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, congestionTimer); + // How many bytes are left to read? + // This would have been bytesLeftToRead -= bytesToRead + // Except the SARA can potentially return less data than requested... + // So we need to subtract readLength instead. + bytesLeftToRead -= readLength; + if (_printDebug == true) + { + if (bytesLeftToRead > 0) + { + _debugPort->print(F("socketRead: multiple read. bytesLeftToRead: ")); + _debugPort->println(bytesLeftToRead); + } + } + } // /while (bytesLeftToRead > 0) - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + free(response); - free(command); - return err; + return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol) +UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) { - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int socketStore = 0; - int paramVal; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,0", UBX_CELL_SOCKET_CONTROL, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int readLength = 0; + int socketStore = 0; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_SOCKET) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,0", UBX_CELL_READ_SOCKET, socket); - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USOCTL:"); - if (searchPtr != nullptr) + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,0,%d", - &socketStore, ¶mVal); + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - if (scanNum != 2) + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) { - if (_printDebug == true) - { - _debugPort->print(F("querySocketType: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + char *searchPtr = strstr(response, "+USORD:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USORD:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d", &socketStore, &readLength); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadAvailable: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - *protocol = (UBX_CELL_socket_protocol_t)paramVal; - _lastSocketProtocol[socketStore] = paramVal; - } + *length = readLength; + } - free(command); - free(response); + free(command); + free(response); - return err; + return err; } -UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) +UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress, + int *remotePort, int *bytesRead) { - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int socketStore = 0; - int paramVal; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,1", UBX_CELL_SOCKET_CONTROL, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + char *command; + char *response; + char *strBegin; + int readIndexTotal = 0; + int readIndexThisRead = 0; + UBX_CELL_error_t err; + int scanNum = 0; + int remoteIPstore[4] = {0, 0, 0, 0}; + int portStore = 0; + int readLength = 0; + int socketStore = 0; + int bytesLeftToRead = length; + int bytesToRead; + + // Set *bytesRead to zero + if (bytesRead != nullptr) + *bytesRead = 0; - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USOCTL:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,1,%d", - &socketStore, ¶mVal); - } - if (scanNum != 2) + // Check if length is zero + if (length == 0) { - if (_printDebug == true) - { - _debugPort->print(F("querySocketLastError: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + if (_printDebug == true) + _debugPort->print(F("socketReadUDP: length is 0! Call socketReadAvailableUDP?")); + return UBX_CELL_ERROR_UNEXPECTED_PARAM; } - *error = paramVal; - } - - free(command); - free(response); - - return err; -} - -UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total) -{ - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int socketStore = 0; - long unsigned int paramVal; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,2", UBX_CELL_SOCKET_CONTROL, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + // Allocate memory for the command + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_UDP_SOCKET) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USOCTL:"); - if (searchPtr != nullptr) + // Allocate memory for the response + // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing + int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_UDP_SOCKET) + minimumResponseAllocation; + response = ubx_cell_calloc_char(responseLength); + if (response == nullptr) { - searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,2,%lu", - &socketStore, ¶mVal); + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - if (scanNum != 2) + + // If there are more than _saraR5maxSocketRead (1024) bytes to be read, + // we need to do multiple reads to get all the data + + while (bytesLeftToRead > 0) { - if (_printDebug == true) - { - _debugPort->print(F("querySocketTotalBytesSent: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + if (bytesLeftToRead > _saraR5maxSocketRead) // Limit a single read to _saraR5maxSocketRead + bytesToRead = _saraR5maxSocketRead; + else + bytesToRead = bytesLeftToRead; - *total = (uint32_t)paramVal; - } + sprintf(command, "%s=%d,%d", UBX_CELL_READ_UDP_SOCKET, socket, bytesToRead); - free(command); - free(response); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT, responseLength); - return err; -} + if (err != UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadUDP: sendCommandWithResponse err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } -UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *total) -{ - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int socketStore = 0; - long unsigned int paramVal; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,3", UBX_CELL_SOCKET_CONTROL, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + // Extract the data + char *searchPtr = strstr(response, "+USORF:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USORF:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\",%d,%d", &socketStore, &remoteIPstore[0], &remoteIPstore[1], + &remoteIPstore[2], &remoteIPstore[3], &portStore, &readLength); + } + if (scanNum != 7) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadUDP: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + // Check that readLength == bytesToRead + if (readLength != bytesToRead) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadUDP: length mismatch! bytesToRead=")); + _debugPort->print(bytesToRead); + _debugPort->print(F(" readLength=")); + _debugPort->println(readLength); + } + } - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USOCTL:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,3,%lu", - &socketStore, ¶mVal); - } - if (scanNum != 2) - { - if (_printDebug == true) - { - _debugPort->print(F("querySocketTotalBytesReceived: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + // Check that readLength > 0 + if (readLength == 0) + { + if (_printDebug == true) + { + _debugPort->println(F("socketRead: zero length!")); + } + free(command); + free(response); + return UBX_CELL_ERROR_ZERO_READ_LENGTH; + } - *total = (uint32_t)paramVal; - } + // Find the third double-quote + strBegin = strchr(searchPtr, '\"'); + strBegin = strchr(strBegin + 1, '\"'); + strBegin = strchr(strBegin + 1, '\"'); - free(command); - free(response); + if (strBegin == nullptr) + { + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - return err; -} + // Now copy the data into readDest + readIndexThisRead = 1; // Start after the quote + while (readIndexThisRead < (readLength + 1)) + { + readDest[readIndexTotal] = strBegin[readIndexThisRead]; + readIndexTotal++; + readIndexThisRead++; + } -UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *address, int *port) -{ - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int socketStore = 0; - int paramVals[5]; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,4", UBX_CELL_SOCKET_CONTROL, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + // If remoteIPaddress is not nullptr, copy the remote IP address + if (remoteIPAddress != nullptr) + { + IPAddress tempAddress; + for (int i = 0; i <= 3; i++) + { + tempAddress[i] = (uint8_t)remoteIPstore[i]; + } + *remoteIPAddress = tempAddress; + } + + // If remotePort is not nullptr, copy the remote port + if (remotePort != nullptr) + { + *remotePort = portStore; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (_printDebug == true) + _debugPort->println(F("socketReadUDP: success")); - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USOCTL:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,4,\"%d.%d.%d.%d\",%d", - &socketStore, - ¶mVals[0], ¶mVals[1], ¶mVals[2], ¶mVals[3], - ¶mVals[4]); - } - if (scanNum != 6) - { - if (_printDebug == true) - { - _debugPort->print(F("querySocketRemoteIPAddress: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + // Update *bytesRead + if (bytesRead != nullptr) + *bytesRead = readIndexTotal; - IPAddress tempAddress = { (uint8_t)paramVals[0], (uint8_t)paramVals[1], - (uint8_t)paramVals[2], (uint8_t)paramVals[3] }; - *address = tempAddress; - *port = paramVals[4]; - } + // How many bytes are left to read? + // This would have been bytesLeftToRead -= bytesToRead + // Except the SARA can potentially return less data than requested... + // So we need to subtract readLength instead. + bytesLeftToRead -= readLength; + if (_printDebug == true) + { + if (bytesLeftToRead > 0) + { + _debugPort->print(F("socketReadUDP: multiple read. bytesLeftToRead: ")); + _debugPort->println(bytesLeftToRead); + } + } + } // /while (bytesLeftToRead > 0) - free(command); - free(response); + free(command); + free(response); - return err; + return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status) +UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) { - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int socketStore = 0; - int paramVal; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,10", UBX_CELL_SOCKET_CONTROL, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int readLength = 0; + int socketStore = 0; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_UDP_SOCKET) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,0", UBX_CELL_READ_UDP_SOCKET, socket); - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USOCTL:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,10,%d", - &socketStore, ¶mVal); - } - if (scanNum != 2) + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - if (_printDebug == true) - { - _debugPort->print(F("querySocketStatusTCP: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - *status = (UBX_CELL_tcp_socket_status_t)paramVal; - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - free(response); + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USORF:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USORF:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,%d", &socketStore, &readLength); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("socketReadAvailableUDP: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - return err; -} + *length = readLength; + } -UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) -{ - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int socketStore = 0; - long unsigned int paramVal; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,11", UBX_CELL_SOCKET_CONTROL, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + free(response); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + return err; +} - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USOCTL:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,11,%lu", - &socketStore, ¶mVal); - } - if (scanNum != 2) - { - if (_printDebug == true) - { - _debugPort->print(F("querySocketOutUnackData: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } +UBX_CELL_error_t UBX_CELL::socketListen(int socket, unsigned int port) +{ + UBX_CELL_error_t err; + char *command; - *total = (uint32_t)paramVal; - } + command = ubx_cell_calloc_char(strlen(UBX_CELL_LISTEN_SOCKET) + 9); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d", UBX_CELL_LISTEN_SOCKET, socket, port); - free(command); - free(response); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - return err; + free(command); + return err; } -//Issues command to get last socket error, then prints to serial. Also updates rx/backlog buffers. -int UBX_CELL::socketGetLastError() +UBX_CELL_error_t UBX_CELL::socketDirectLinkMode(int socket) { - UBX_CELL_error_t err; - char *command; - char *response; - int errorCode = -1; - - command = ubx_cell_calloc_char(64); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - sprintf(command, "%s", UBX_CELL_GET_ERROR); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - if (err == UBX_CELL_ERROR_SUCCESS) - { - char *searchPtr = strstr(response, "+USOER:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+USOER:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - sscanf(searchPtr, "%d", &errorCode); - } - } + UBX_CELL_error_t err; + char *command; - free(command); - free(response); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_DIRECT_LINK) + 8); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_SOCKET_DIRECT_LINK, socket); - return errorCode; -} + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); -IPAddress UBX_CELL::lastRemoteIP(void) -{ - return _lastRemoteIP; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::resetHTTPprofile(int profile) +UBX_CELL_error_t UBX_CELL::socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger) { - UBX_CELL_error_t err; - char *command; + // valid range is 0 (trigger disabled), 100-120000 + if (!((timerTrigger == 0) || ((timerTrigger >= 100) && (timerTrigger <= 120000)))) + return UBX_CELL_ERROR_ERROR; - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_HTTP_PROFILE, profile); + command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=5,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, timerTrigger); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::setHTTPserverIPaddress(int profile, IPAddress address) +UBX_CELL_error_t UBX_CELL::socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger) { - UBX_CELL_error_t err; - char *command; + // valid range is 0, 3-1472 for UDP + if (!((dataLengthTrigger == 0) || ((dataLengthTrigger >= 3) && (dataLengthTrigger <= 1472)))) + return UBX_CELL_ERROR_ERROR; - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 64); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_IP, - address[0], address[1], address[2], address[3]); + command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=6,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, dataLengthTrigger); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::setHTTPserverName(int profile, String server) +UBX_CELL_error_t UBX_CELL::socketDirectLinkCharacterTrigger(int socket, int characterTrigger) { - UBX_CELL_error_t err; - char *command; + // The allowed range is -1, 0-255, the factory-programmed value is -1; -1 means trigger disabled. + if (!((characterTrigger >= -1) && (characterTrigger <= 255))) + return UBX_CELL_ERROR_ERROR; - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + server.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_NAME, - server.c_str()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=7,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, characterTrigger); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::setHTTPusername(int profile, String username) +UBX_CELL_error_t UBX_CELL::socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer) { - UBX_CELL_error_t err; - char *command; + // valid range is 0, 1000-72000 + if (!((congestionTimer == 0) || ((congestionTimer >= 1000) && (congestionTimer <= 72000)))) + return UBX_CELL_ERROR_ERROR; - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + username.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_USERNAME, - username.c_str()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=8,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, congestionTimer); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::setHTTPpassword(int profile, String password) +UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol) { - UBX_CELL_error_t err; - char *command; - - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + password.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_PASSWORD, - password.c_str()); + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int socketStore = 0; + int paramVal; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,0", UBX_CELL_SOCKET_CONTROL, socket); - free(command); - return err; -} + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } -UBX_CELL_error_t UBX_CELL::setHTTPauthentication(int profile, bool authenticate) -{ - UBX_CELL_error_t err; - char *command; + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,0,%d", &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketType: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, - authenticate); + *protocol = (UBX_CELL_socket_protocol_t)paramVal; + _lastSocketProtocol[socketStore] = paramVal; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + free(response); - free(command); - return err; + return err; } -UBX_CELL_error_t UBX_CELL::setHTTPserverPort(int profile, int port) +UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) { - UBX_CELL_error_t err; - char *command; - - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_PORT, - port); + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int socketStore = 0; + int paramVal; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,1", UBX_CELL_SOCKET_CONTROL, socket); - free(command); - return err; -} + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } -UBX_CELL_error_t UBX_CELL::setHTTPcustomHeader(int profile, String header) -{ - UBX_CELL_error_t err; - char *command; + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,1,%d", &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketLastError: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + header.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS, - header.c_str()); + *error = paramVal; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + free(response); - free(command); - return err; + return err; } -UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofile) +UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total) { - UBX_CELL_error_t err; - char *command; - - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int socketStore = 0; + long unsigned int paramVal; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (secprofile == -1) - sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, - secure); - else sprintf(command, "%s=%d,%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, - secure, secprofile); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,2", UBX_CELL_SOCKET_CONTROL, socket); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - free(command); - return err; -} + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); -UBX_CELL_error_t UBX_CELL::ping(String remote_host, int retry, int p_size, - unsigned long timeout, int ttl) -{ - UBX_CELL_error_t err; - char *command; + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,2,%lu", &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketTotalBytesSent: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - command = ubx_cell_calloc_char(strlen(UBX_CELL_PING_COMMAND) + 48 + - remote_host.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\",%d,%d,%ld,%d", UBX_CELL_PING_COMMAND, - remote_host.c_str(), retry, p_size, timeout, ttl); + *total = (uint32_t)paramVal; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + free(response); - free(command); - return err; + return err; } -UBX_CELL_error_t UBX_CELL::sendHTTPGET(int profile, String path, String responseFilename) +UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *total) { - UBX_CELL_error_t err; - char *command; - - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + - path.length() + responseFilename.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\",\"%s\"", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_GET, - path.c_str(), responseFilename.c_str()); + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int socketStore = 0; + long unsigned int paramVal; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,3", UBX_CELL_SOCKET_CONTROL, socket); - free(command); - return err; -} + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } -UBX_CELL_error_t UBX_CELL::sendHTTPPOSTdata(int profile, String path, String responseFilename, - String data, UBX_CELL_http_content_types_t httpContentType) -{ - UBX_CELL_error_t err; - char *command; + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,3,%lu", &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketTotalBytesReceived: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + - path.length() + responseFilename.length() + data.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_POST_DATA, - path.c_str(), responseFilename.c_str(), data.c_str(), httpContentType); + *total = (uint32_t)paramVal; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + free(response); - free(command); - return err; + return err; } -UBX_CELL_error_t UBX_CELL::sendHTTPPOSTfile(int profile, String path, String responseFilename, - String requestFile, UBX_CELL_http_content_types_t httpContentType) +UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *address, int *port) { - UBX_CELL_error_t err; - char *command; + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int socketStore = 0; + int paramVals[5]; - if (profile >= UBX_CELL_NUM_HTTP_PROFILES) - return UBX_CELL_ERROR_ERROR; + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,4", UBX_CELL_SOCKET_CONTROL, socket); - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + - path.length() + responseFilename.length() + requestFile.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_POST_FILE, - path.c_str(), responseFilename.c_str(), requestFile.c_str(), httpContentType); + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,4,\"%d.%d.%d.%d\",%d", &socketStore, ¶mVals[0], ¶mVals[1], + ¶mVals[2], ¶mVals[3], ¶mVals[4]); + } + if (scanNum != 6) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketRemoteIPAddress: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } -UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, int *error_code) -{ - UBX_CELL_error_t err; - char *command; - char *response; + IPAddress tempAddress = {(uint8_t)paramVals[0], (uint8_t)paramVals[1], (uint8_t)paramVals[2], + (uint8_t)paramVals[3]}; + *address = tempAddress; + *port = paramVals[4]; + } - int rprofile, eclass, ecode; + free(command); + free(response); - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROTOCOL_ERROR) + 4); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_HTTP_PROTOCOL_ERROR, profile); + return err; +} - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } +UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status) +{ + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int socketStore = 0; + int paramVal; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,10", UBX_CELL_SOCKET_CONTROL, socket); - if (err == UBX_CELL_ERROR_SUCCESS) - { - int scanned = 0; - char *searchPtr = strstr(response, "+UHTTPER:"); - if (searchPtr != nullptr) + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - searchPtr += strlen("+UHTTPER:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d,%d,%d\r\n", - &rprofile, &eclass, &ecode); + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - if (scanned == 3) + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) { - *error_class = eclass; - *error_code = ecode; - } - else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,10,%d", &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketStatusTCP: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - free(command); - free(response); - return err; -} + *status = (UBX_CELL_tcp_socket_status_t)paramVal; + } -UBX_CELL_error_t UBX_CELL::nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter) -{ - UBX_CELL_error_t err; - char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_NVM) + 10); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_MQTT_NVM, parameter); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); - return err; -} + free(response); -UBX_CELL_error_t UBX_CELL::setMQTTclientId(const String& clientId) -{ - UBX_CELL_error_t err; - char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + clientId.length() + 10); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_CLIENT_ID, clientId.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } -UBX_CELL_error_t UBX_CELL::setMQTTserver(const String& serverName, int port) +UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) { - UBX_CELL_error_t err; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + serverName.length() + 16); + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int socketStore = 0; + long unsigned int paramVal; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\",%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SERVERNAME, serverName.c_str(), port); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,11", UBX_CELL_SOCKET_CONTROL, socket); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOCTL:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = sscanf(searchPtr, "%d,11,%lu", &socketStore, ¶mVal); + } + if (scanNum != 2) + { + if (_printDebug == true) + { + _debugPort->print(F("querySocketOutUnackData: error: scanNum is ")); + _debugPort->println(scanNum); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + *total = (uint32_t)paramVal; + } + free(command); + free(response); + return err; } -UBX_CELL_error_t UBX_CELL::setMQTTcredentials(const String& userName, const String& pwd) +// Issues command to get last socket error, then prints to serial. Also updates rx/backlog buffers. +int UBX_CELL::socketGetLastError() { UBX_CELL_error_t err; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + userName.length() + pwd.length() + 16); - if (command == nullptr) { + char *response; + int errorCode = -1; + + command = ubx_cell_calloc_char(64); + if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_USERNAMEPWD, userName.c_str(), pwd.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s", UBX_CELL_GET_ERROR); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) + { + char *searchPtr = strstr(response, "+USOER:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+USOER:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + sscanf(searchPtr, "%d", &errorCode); + } + } + free(command); - return err; + free(response); + + return errorCode; } -UBX_CELL_error_t UBX_CELL::setMQTTsecure(bool secure, int secprofile) +IPAddress UBX_CELL::lastRemoteIP(void) { - UBX_CELL_error_t err; - char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (secprofile == -1) sprintf(command, "%s=%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure); - else sprintf(command, "%s=%d,%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure, secprofile); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + return _lastRemoteIP; } -UBX_CELL_error_t UBX_CELL::connectMQTT(void) +UBX_CELL_error_t UBX_CELL::resetHTTPprofile(int profile) { UBX_CELL_error_t err; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); + + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 16); if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGIN); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_HTTP_PROFILE, profile); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -UBX_CELL_error_t UBX_CELL::disconnectMQTT(void) +UBX_CELL_error_t UBX_CELL::setHTTPserverIPaddress(int profile, IPAddress address) { UBX_CELL_error_t err; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); + + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 64); if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGOUT); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_IP, + address[0], address[1], address[2], address[3]); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); -UBX_CELL_error_t UBX_CELL::subscribeMQTTtopic(int max_Qos, const String& topic) -{ - UBX_CELL_error_t err; - char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_SUBSCRIBE, max_Qos, topic.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::unsubscribeMQTTtopic(const String& topic) -{ - UBX_CELL_error_t err; - char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length()); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_UNSUBSCRIBE, topic.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::readMQTT(int* pQos, String* pTopic, uint8_t *readDest, int readLength, int *bytesRead) -{ - char *command; - char *response; - UBX_CELL_error_t err; - int scanNum = 0; - int total_length, topic_length, data_length; - - // Set *bytesRead to zero - if (bytesRead != nullptr) - *bytesRead = 0; - - // Allocate memory for the command - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - - // Allocate memory for the response - int responseLength = readLength + minimumResponseAllocation; - response = ubx_cell_calloc_char(responseLength); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... - // To try and avoid this, look for \"\r\n\r\nOK\r\n there is a extra \r\n beetween " and the the standard \r\nOK\r\n - const char mqttReadTerm[] = "\"\r\n\r\nOK\r\n"; - sprintf(command, "%s=%d,%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_READ, 1); - err = sendCommandWithResponse(command, mqttReadTerm, response, - (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), responseLength); - - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) - { - _debugPort->print(F("readMQTT: sendCommandWithResponse err ")); - _debugPort->println(err); - } free(command); - free(response); return err; - } - - // Extract the data - char *searchPtr = strstr(response, "+UMQTTC:"); - int cmd = 0; - if (searchPtr != nullptr) - { - searchPtr += strlen("+UMQTTC:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanNum = sscanf(searchPtr, "%d,%d,%d,%d,\"%*[^\"]\",%d,\"", &cmd, pQos, &total_length, &topic_length, &data_length); - } - if ((scanNum != 5) || (cmd != UBX_CELL_MQTT_COMMAND_READ)) - { - if (_printDebug == true) - { - _debugPort->print(F("readMQTT: error: scanNum is ")); - _debugPort->println(scanNum); - } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - err = UBX_CELL_ERROR_SUCCESS; - searchPtr = strstr(searchPtr, "\""); - if (searchPtr!= nullptr) { - if (pTopic) { - searchPtr[topic_length + 1] = '\0'; // zero terminate - *pTopic = searchPtr + 1; - searchPtr[topic_length + 1] = '\"'; // restore - } - searchPtr = strstr(searchPtr + topic_length + 2, "\""); - if (readDest && (searchPtr != nullptr) && (response + responseLength >= searchPtr + data_length + 1) && (searchPtr[data_length + 1] == '"')) { - if (data_length > readLength) { - data_length = readLength; - if (_printDebug == true) { - _debugPort->print(F("readMQTT: error: trucate message")); - } - err = UBX_CELL_ERROR_OUT_OF_MEMORY; - } - memcpy(readDest, searchPtr+1, data_length); - *bytesRead = data_length; - } else { - if (_printDebug == true) { - _debugPort->print(F("readMQTT: error: message end ")); - } - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - } - free(command); - free(response); - - return err; } -UBX_CELL_error_t UBX_CELL::mqttPublishTextMsg(const String& topic, const char * const msg, uint8_t qos, bool retain) +UBX_CELL_error_t UBX_CELL::setHTTPserverName(int profile, String server) { - if (topic.length() < 1 || msg == nullptr) - { - return UBX_CELL_ERROR_INVALID; - } - - UBX_CELL_error_t err; - - char sanitized_msg[MAX_MQTT_DIRECT_MSG_LEN + 1]; - memset(sanitized_msg, 0, sizeof(sanitized_msg)); - - // Check the message length and truncate if necessary. - size_t msg_len = strnlen(msg, MAX_MQTT_DIRECT_MSG_LEN); - if (msg_len > MAX_MQTT_DIRECT_MSG_LEN) - { - msg_len = MAX_MQTT_DIRECT_MSG_LEN; - } - - strncpy(sanitized_msg, msg, msg_len); - char * msg_ptr = sanitized_msg; - while (*msg_ptr != 0) - { - if (*msg_ptr == '"') - { - *msg_ptr = ' '; - } - - msg_ptr++; - } + UBX_CELL_error_t err; + char *command; - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + msg_len); - if (command == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - sprintf(command, "%s=%d,%u,%u,0,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISH, qos, (retain ? 1:0), topic.c_str(), sanitized_msg); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + server.length()); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_NAME, + server.c_str()); - sendCommand(command, true); - err = waitForResponse(UBX_CELL_RESPONSE_MORE, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - sendCommand(msg, false); - err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - } - - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::mqttPublishBinaryMsg(const String& topic, const char * const msg, size_t msg_len, uint8_t qos, bool retain) -{ - /* - * The modem prints the '>' as the signal to send the binary message content. - * at+umqttc=9,0,0,"topic",4 - * - * >"xY" - * OK - * - * +UUMQTTC: 9,1 - */ - if (topic.length() < 1|| msg == nullptr || msg_len > MAX_MQTT_DIRECT_MSG_LEN) - { - return UBX_CELL_ERROR_INVALID; - } - - UBX_CELL_error_t err; - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length()); - if (command == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - sprintf(command, "%s=%d,%u,%u,\"%s\",%u", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, qos, (retain ? 1:0), topic.c_str(), msg_len); - - sendCommand(command, true); - err = waitForResponse(UBX_CELL_RESPONSE_MORE, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - sendCommand(msg, false); - err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::mqttPublishFromFile(const String& topic, const String& filename, uint8_t qos, bool retain) +UBX_CELL_error_t UBX_CELL::setHTTPusername(int profile, String username) { - if (topic.length() < 1|| filename.length() < 1) - { - return UBX_CELL_ERROR_INVALID; - } + UBX_CELL_error_t err; + char *command; - UBX_CELL_error_t err; - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + filename.length()); - if (command == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - sprintf(command, "%s=%d,%u,%u,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHFILE, qos, (retain ? 1:0), topic.c_str(), filename.c_str()); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + username.length()); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_USERNAME, + username.c_str()); - sendCommand(command, true); - err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::getMQTTprotocolError(int *error_code, int *error_code2) +UBX_CELL_error_t UBX_CELL::setHTTPpassword(int profile, String password) { - UBX_CELL_error_t err; - char *response; - - int code, code2; + UBX_CELL_error_t err; + char *command; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - err = sendCommandWithResponse(UBX_CELL_MQTT_PROTOCOL_ERROR, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + password.length()); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_PASSWORD, + password.c_str()); - if (err == UBX_CELL_ERROR_SUCCESS) - { - int scanned = 0; - char *searchPtr = strstr(response, "+UMQTTER:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+UMQTTER:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d,%d\r\n", - &code, &code2); - } - if (scanned == 2) - { - *error_code = code; - *error_code2 = code2; - } - else - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(response); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::setFTPserver(const String& serverName) +UBX_CELL_error_t UBX_CELL::setHTTPauthentication(int profile, bool authenticate) { - constexpr size_t cmd_len = 145; - char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> - - snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_SERVERNAME, serverName.c_str()); - return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); -} + UBX_CELL_error_t err; + char *command; -UBX_CELL_error_t UBX_CELL::setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger) -{ - constexpr size_t cmd_len = 64; - char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - snprintf(command, cmd_len - 1, "%s=%d,%u,%u,%u", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_TIMEOUT, timeout, cmd_linger, data_linger); - return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); -} + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, authenticate); -UBX_CELL_error_t UBX_CELL::setFTPcredentials(const String& userName, const String& pwd) -{ - UBX_CELL_error_t err; - constexpr size_t cmd_len = 48; - char command[cmd_len]; // long enough for AT+UFTP=n,<30 bytes> + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_USERNAME, userName.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err != UBX_CELL_ERROR_SUCCESS) - { + free(command); return err; - } - - snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_PWD, pwd.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - return err; -} - -UBX_CELL_error_t UBX_CELL::connectFTP(void) -{ - constexpr size_t cmd_len = 16; - char command[cmd_len]; // long enough for AT+UFTPC=n - - snprintf(command, cmd_len - 1, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGIN); - return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } -UBX_CELL_error_t UBX_CELL::disconnectFTP(void) +UBX_CELL_error_t UBX_CELL::setHTTPserverPort(int profile, int port) { - constexpr size_t cmd_len = 16; - char command[cmd_len]; // long enough for AT+UFTPC=n + UBX_CELL_error_t err; + char *command; - snprintf(command, cmd_len - 1, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGOUT); - return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); -} + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; -UBX_CELL_error_t UBX_CELL::ftpGetFile(const String& filename) -{ - char * command = ubx_cell_calloc_char(strlen(UBX_CELL_FTP_COMMAND) + (2 * filename.length()) + 16); - if (command == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_PORT, port); - sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_GET_FILE, filename.c_str(), filename.c_str()); - //memset(response, 0, sizeof(response)); - //sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, response, 8000 /* ms */, response_len); - UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::getFTPprotocolError(int *error_code, int *error_code2) +UBX_CELL_error_t UBX_CELL::setHTTPcustomHeader(int profile, String header) { - UBX_CELL_error_t err; - char *response; - - int code, code2; - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + UBX_CELL_error_t err; + char *command; - err = sendCommandWithResponse(UBX_CELL_FTP_PROTOCOL_ERROR, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - if (err == UBX_CELL_ERROR_SUCCESS) - { - int scanned = 0; - char *searchPtr = strstr(response, "+UFTPER:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+UFTPER:"); // Move searchPtr to first char - while (*searchPtr == ' ') - { - searchPtr++; // skip spaces - } - scanned = sscanf(searchPtr, "%d,%d\r\n", &code, &code2); - } + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + header.length()); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS, + header.c_str()); - if (scanned == 2) - { - *error_code = code; - *error_code2 = code2; - } - else - { - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(response); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::resetSecurityProfile(int secprofile) +UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofile) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + 6); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - sprintf(command, "%s=%d", UBX_CELL_SEC_PROFILE, secprofile); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (secprofile == -1) + sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure); + else + sprintf(command, "%s=%d,%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure, + secprofile); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value) +UBX_CELL_error_t UBX_CELL::ping(String remote_host, int retry, int p_size, unsigned long timeout, int ttl) { UBX_CELL_error_t err; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + 10); + command = ubx_cell_calloc_char(strlen(UBX_CELL_PING_COMMAND) + 48 + remote_host.length()); if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_SEC_PROFILE, secprofile,parameter,value); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\",%d,%d,%ld,%d", UBX_CELL_PING_COMMAND, remote_host.c_str(), retry, p_size, timeout, ttl); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -UBX_CELL_error_t UBX_CELL::configSecurityProfileString(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, String value) +UBX_CELL_error_t UBX_CELL::sendHTTPGET(int profile, String path, String responseFilename) { UBX_CELL_error_t err; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + value.length() + 10); + + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length()); if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_SEC_PROFILE, secprofile,parameter,value.c_str()); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\",\"%s\"", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_GET, path.c_str(), + responseFilename.c_str()); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, UBX_CELL_sec_manager_parameter_t parameter, String name, String data) +UBX_CELL_error_t UBX_CELL::sendHTTPPOSTdata(int profile, String path, String responseFilename, String data, + UBX_CELL_http_content_types_t httpContentType) { - char *command; - char *response; - UBX_CELL_error_t err; + UBX_CELL_error_t err; + char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_MANAGER) + name.length() + 20); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - int dataLen = data.length(); - sprintf(command, "%s=%d,%d,\"%s\",%d", UBX_CELL_SEC_MANAGER, opcode, parameter, name.c_str(), dataLen); - - err = sendCommandWithResponse(command, ">", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) - { - _debugPort->print(F("dataDownload: writing ")); - _debugPort->print(dataLen); - _debugPort->println(F(" bytes")); - } - hwWriteData(data.c_str(), dataLen); - err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT*3); - } + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length() + + data.length()); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, + UBX_CELL_HTTP_COMMAND_POST_DATA, path.c_str(), responseFilename.c_str(), data.c_str(), httpContentType); - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) - { - _debugPort->print(F("dataDownload: Error: ")); - _debugPort->print(err); - _debugPort->print(F(" => {")); - _debugPort->print(response); - _debugPort->println(F("}")); - } - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - free(response); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) +UBX_CELL_error_t UBX_CELL::sendHTTPPOSTfile(int profile, String path, String responseFilename, String requestFile, + UBX_CELL_http_content_types_t httpContentType) { - UBX_CELL_error_t err; - char *command; + UBX_CELL_error_t err; + char *command; - if (cid >= UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) - return UBX_CELL_ERROR_ERROR; + if (profile >= UBX_CELL_NUM_HTTP_PROFILES) + return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE) + 32); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (cid == -1) - sprintf(command, "%s=%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status); - else - sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status, cid); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length() + + requestFile.length()); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, + UBX_CELL_HTTP_COMMAND_POST_FILE, path.c_str(), responseFilename.c_str(), requestFile.c_str(), + httpContentType); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; + free(command); + return err; } -bool UBX_CELL::isGPSon(void) +UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, int *error_code) { - UBX_CELL_error_t err; - char *command; - char *response; - bool on = false; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_POWER) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_POWER); + UBX_CELL_error_t err; + char *command; + char *response; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + int rprofile, eclass, ecode; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, - UBX_CELL_10_SEC_TIMEOUT); + command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROTOCOL_ERROR) + 4); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_HTTP_PROTOCOL_ERROR, profile); - if (err == UBX_CELL_ERROR_SUCCESS) - { - // Example response: "+UGPS: 0" for off "+UGPS: 1,0,1" for on - // Search for a ':' followed by a '1' or ' 1' - char *pch1 = strchr(response, ':'); - if (pch1 != nullptr) + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - char *pch2 = strchr(response, '1'); - if ((pch2 != nullptr) && ((pch2 == pch1 + 1) || (pch2 == pch1 + 2))) - on = true; + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - } - - free(command); - free(response); - - return on; -} - -UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_aiding_mode_t gnss_aiding) -{ - UBX_CELL_error_t err; - char *command; - bool gpsState; - - // Don't turn GPS on/off if it's already on/off - gpsState = isGPSon(); - if ((enable && gpsState) || (!enable && !gpsState)) - { - return UBX_CELL_ERROR_SUCCESS; - } - // GPS power management - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_POWER) + 32); // gnss_sys could be up to three digits - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (enable) - { - sprintf(command, "%s=1,%d,%d", UBX_CELL_GNSS_POWER, gnss_aiding, gnss_sys); - } - else - { - sprintf(command, "%s=0", UBX_CELL_GNSS_POWER); - } + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, 10000); + if (err == UBX_CELL_ERROR_SUCCESS) + { + int scanned = 0; + char *searchPtr = strstr(response, "+UHTTPER:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UHTTPER:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d,%d\r\n", &rprofile, &eclass, &ecode); + } + if (scanned == 3) + { + *error_class = eclass; + *error_code = ecode; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - free(command); - return err; + free(command); + free(response); + return err; } -/* -UBX_CELL_error_t UBX_CELL::gpsEnableClock(bool enable) +UBX_CELL_error_t UBX_CELL::nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter) { - // AT+UGZDA=<0,1> - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_NVM) + 10); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_MQTT_NVM, parameter); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -UBX_CELL_error_t UBX_CELL::gpsGetClock(struct ClockData *clock) +UBX_CELL_error_t UBX_CELL::setMQTTclientId(const String &clientId) { - // AT+UGZDA? - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + clientId.length() + 10); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_CLIENT_ID, clientId.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -UBX_CELL_error_t UBX_CELL::gpsEnableFix(bool enable) +UBX_CELL_error_t UBX_CELL::setMQTTserver(const String &serverName, int port) { - // AT+UGGGA=<0,1> - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + serverName.length() + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\",%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SERVERNAME, serverName.c_str(), + port); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -UBX_CELL_error_t UBX_CELL::gpsGetFix(struct PositionData *pos) +UBX_CELL_error_t UBX_CELL::setMQTTcredentials(const String &userName, const String &pwd) { - // AT+UGGGA? - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; - return err; -} - -UBX_CELL_error_t UBX_CELL::gpsEnablePos(bool enable) -{ - // AT+UGGLL=<0,1> - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + userName.length() + pwd.length() + 16); + if (command == nullptr) + { + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_USERNAMEPWD, userName.c_str(), + pwd.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -UBX_CELL_error_t UBX_CELL::gpsGetPos(struct PositionData *pos) +UBX_CELL_error_t UBX_CELL::setMQTTsecure(bool secure, int secprofile) { - // AT+UGGLL? - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (secprofile == -1) + sprintf(command, "%s=%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure); + else + sprintf(command, "%s=%d,%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure, secprofile); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -UBX_CELL_error_t UBX_CELL::gpsEnableSat(bool enable) +UBX_CELL_error_t UBX_CELL::connectMQTT(void) { - // AT+UGGSV=<0,1> - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGIN); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -UBX_CELL_error_t UBX_CELL::gpsGetSat(uint8_t *sats) +UBX_CELL_error_t UBX_CELL::disconnectMQTT(void) { - // AT+UGGSV? - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -*/ - -UBX_CELL_error_t UBX_CELL::gpsEnableRmc(bool enable) -{ - // AT+UGRMC=<0,1> - UBX_CELL_error_t err; - char *command; - - // ** Don't call gpsPower here. It causes problems for +UTIME and the PPS signal ** - // ** Call isGPSon and gpsPower externally if required ** - // if (!isGPSon()) - // { - // err = gpsPower(true); - // if (err != UBX_CELL_ERROR_SUCCESS) - // { - // return err; - // } - // } - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_GPRMC) + 3); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_GNSS_GPRMC, enable ? 1 : 0); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); - - free(command); - return err; -} -UBX_CELL_error_t UBX_CELL::gpsGetRmc(struct PositionData *pos, struct SpeedData *spd, - struct ClockData *clk, bool *valid) +UBX_CELL_error_t UBX_CELL::subscribeMQTTtopic(int max_Qos, const String &topic) { - UBX_CELL_error_t err; - char *command; - char *response; - char *rmcBegin; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_GPRMC) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_GPRMC); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length()); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_SUBSCRIBE, max_Qos, topic.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); - if (err == UBX_CELL_ERROR_SUCCESS) - { - // Fast-forward response string to $GPRMC starter - rmcBegin = strstr(response, "$GPRMC"); - if (rmcBegin == nullptr) - { - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - else - { - *valid = parseGPRMCString(rmcBegin, pos, clk, spd); - } - } - - free(command); - free(response); - return err; -} - -/* -UBX_CELL_error_t UBX_CELL::gpsEnableSpeed(bool enable) -{ - // AT+UGVTG=<0,1> - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBX_CELL_error_t UBX_CELL::gpsGetSpeed(struct SpeedData *speed) +UBX_CELL_error_t UBX_CELL::unsubscribeMQTTtopic(const String &topic) { - // AT+UGVTG? - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length()); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_UNSUBSCRIBE, topic.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); return err; } -*/ - -UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, - bool detailed, unsigned int sensor) -{ - // AT+ULOC=2,,,, - UBX_CELL_error_t err; - char *command; - - // This function will only work if the GPS module is initially turned off. - if (isGPSon()) - { - gpsPower(false); - } - - if (timeout > 999) - timeout = 999; - if (accuracy > 999999) - accuracy = 999999; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_LOCATION) + 24); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - sprintf(command, "%s=2,%d,%d,%d,%d", UBX_CELL_GNSS_REQUEST_LOCATION, - sensor, detailed ? 1 : 0, timeout, accuracy); -#else - sprintf(command, "%s=2,%d,%d,%d,%ld", UBX_CELL_GNSS_REQUEST_LOCATION, - sensor, detailed ? 1 : 0, timeout, accuracy); -#endif - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); - - free(command); - return err; -} - -UBX_CELL_error_t UBX_CELL::gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, - unsigned int days, unsigned int period, unsigned int resolution, - unsigned int gnssTypes, unsigned int mode, unsigned int dataType) -{ - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_AIDING_SERVER_CONFIGURATION) + 256); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - - sprintf(command, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBX_CELL_AIDING_SERVER_CONFIGURATION, - primaryServer, secondaryServer, authToken, - days, period, resolution, gnssTypes, mode, dataType); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - - free(command); - return err; -} - -// OK for text files. But will fail with binary files (containing \0) on some platforms. -UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, const char *str, int len) +UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest, int readLength, int *bytesRead) { - char *command; - char *response; - UBX_CELL_error_t err; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE) + filename.length() + 10); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - int dataLen = len == -1 ? strlen(str) : len; - sprintf(command, "%s=\"%s\",%d", UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE, filename.c_str(), dataLen); - - err = sendCommandWithResponse(command, ">", response, - UBX_CELL_STANDARD_RESPONSE_TIMEOUT*2); + char *command; + char *response; + UBX_CELL_error_t err; + int scanNum = 0; + int total_length, topic_length, data_length; - unsigned long writeDelay = millis(); - while (millis() < (writeDelay + 50)) - delay(1); //uBlox specification says to wait 50ms after receiving "@" to write data. + // Set *bytesRead to zero + if (bytesRead != nullptr) + *bytesRead = 0; - if (err == UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) - { - _debugPort->print(F("fileDownload: writing ")); - _debugPort->print(dataLen); - _debugPort->println(F(" bytes")); - } - hwWriteData(str, dataLen); + // Allocate memory for the command + command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; - err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT*5); - } - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) + // Allocate memory for the response + int responseLength = readLength + minimumResponseAllocation; + response = ubx_cell_calloc_char(responseLength); + if (response == nullptr) { - _debugPort->print(F("fileDownload: Error: ")); - _debugPort->print(err); - _debugPort->print(F(" => {")); - _debugPort->print(response); - _debugPort->println(F("}")); + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - } - - free(command); - free(response); - return err; -} - -UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, String str) -{ - return appendFileContents(filename, str.c_str(), str.length()); -} + // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... + // To try and avoid this, look for \"\r\n\r\nOK\r\n there is a extra \r\n beetween " and the the standard \r\nOK\r\n + const char mqttReadTerm[] = "\"\r\n\r\nOK\r\n"; + sprintf(command, "%s=%d,%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_READ, 1); + err = sendCommandWithResponse(command, mqttReadTerm, response, (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), + responseLength); -// OK for text files. But will fail with binary files (containing \0) on some platforms. -UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) -{ - UBX_CELL_error_t err; - char *command; - char *response; - - // Start by getting the file size so we know in advance how much data to expect - int fileSize = 0; - err = getFileSize(filename, &fileSize); - if (err != UBX_CELL_SUCCESS) - { - if (_printDebug == true) + if (err != UBX_CELL_ERROR_SUCCESS) { - _debugPort->print(F("getFileContents: getFileSize returned err ")); - _debugPort->println(err); + if (_printDebug == true) + { + _debugPort->print(F("readMQTT: sendCommandWithResponse err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; } - return err; - } - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); - - response = ubx_cell_calloc_char(fileSize + minimumResponseAllocation); - if (response == nullptr) - { - if (_printDebug == true) - { - _debugPort->print(F("getFileContents: response alloc failed: ")); - _debugPort->println(fileSize + minimumResponseAllocation); - } - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - // A large file will completely fill the backlog buffer - but it will be pruned afterwards - // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... - // To try and avoid this, look for \"\r\nOK\r\n - const char fileReadTerm[] = "\r\nOK\r\n"; //LARA-R6 returns "\"\r\n\r\nOK\r\n" while SARA-R5 return "\"\r\nOK\r\n"; - err = sendCommandWithResponse(command, fileReadTerm, - response, (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), - (fileSize + minimumResponseAllocation)); - - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) + // Extract the data + char *searchPtr = strstr(response, "+UMQTTC:"); + int cmd = 0; + if (searchPtr != nullptr) { - _debugPort->print(F("getFileContents: sendCommandWithResponse returned err ")); - _debugPort->println(err); + searchPtr += strlen("+UMQTTC:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanNum = + sscanf(searchPtr, "%d,%d,%d,%d,\"%*[^\"]\",%d,\"", &cmd, pQos, &total_length, &topic_length, &data_length); } - free(command); - free(response); - return err; - } - - // Response format: \r\n+URDFILE: "filename",36,"these bytes are the data of the file"\r\n\r\nOK\r\n - int scanned = 0; - int readFileSize = 0; - char *searchPtr = strstr(response, "+URDFILE:"); - if (searchPtr != nullptr) - { - searchPtr = strchr(searchPtr, '\"'); // Find the first quote - searchPtr = strchr(++searchPtr, '\"'); // Find the second quote - - scanned = sscanf(searchPtr, "\",%d,", &readFileSize); // Get the file size (again) - if (scanned == 1) + if ((scanNum != 5) || (cmd != UBX_CELL_MQTT_COMMAND_READ)) { - searchPtr = strchr(++searchPtr, '\"'); // Find the third quote - - if (searchPtr == nullptr) - { if (_printDebug == true) { - _debugPort->println(F("getFileContents: third quote not found!")); + _debugPort->print(F("readMQTT: error: scanNum is ")); + _debugPort->println(scanNum); } free(command); free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - int bytesRead = 0; - - while (bytesRead < readFileSize) - { - searchPtr++; // Increment searchPtr then copy file char into contents - // Important Note: some implementations of concat, like the one on ESP32, are binary-compatible. - // But some, like SAMD, are not. They use strlen or strcpy internally - which don't like \0's. - // The only true binary-compatible solution is to use getFileContents(String filename, char *contents)... - contents->concat(*(searchPtr)); // Append file char to contents - bytesRead++; - } - if (_printDebug == true) - { - _debugPort->print(F("getFileContents: total bytes read: ")); - _debugPort->println(bytesRead); - } - err = UBX_CELL_ERROR_SUCCESS; } - else + + err = UBX_CELL_ERROR_SUCCESS; + searchPtr = strstr(searchPtr, "\""); + if (searchPtr != nullptr) { - if (_printDebug == true) - { - _debugPort->print(F("getFileContents: sscanf failed! scanned is ")); - _debugPort->println(scanned); - } - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + if (pTopic) + { + searchPtr[topic_length + 1] = '\0'; // zero terminate + *pTopic = searchPtr + 1; + searchPtr[topic_length + 1] = '\"'; // restore + } + searchPtr = strstr(searchPtr + topic_length + 2, "\""); + if (readDest && (searchPtr != nullptr) && (response + responseLength >= searchPtr + data_length + 1) && + (searchPtr[data_length + 1] == '"')) + { + if (data_length > readLength) + { + data_length = readLength; + if (_printDebug == true) + { + _debugPort->print(F("readMQTT: error: trucate message")); + } + err = UBX_CELL_ERROR_OUT_OF_MEMORY; + } + memcpy(readDest, searchPtr + 1, data_length); + *bytesRead = data_length; + } + else + { + if (_printDebug == true) + { + _debugPort->print(F("readMQTT: error: message end ")); + } + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } } - } - else - { - if (_printDebug == true) - _debugPort->println(F("getFileContents: strstr failed!")); - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + free(command); + free(response); - free(command); - free(response); - return err; + return err; } -// OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. -UBX_CELL_error_t UBX_CELL::getFileContents(String filename, char *contents) +UBX_CELL_error_t UBX_CELL::mqttPublishTextMsg(const String &topic, const char *const msg, uint8_t qos, bool retain) { - UBX_CELL_error_t err; - char *command; - char *response; - - // Start by getting the file size so we know in advance how much data to expect - int fileSize = 0; - err = getFileSize(filename, &fileSize); - if (err != UBX_CELL_SUCCESS) - { - if (_printDebug == true) + if (topic.length() < 1 || msg == nullptr) { - _debugPort->print(F("getFileContents: getFileSize returned err ")); - _debugPort->println(err); + return UBX_CELL_ERROR_INVALID; } - return err; - } - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); + UBX_CELL_error_t err; - response = ubx_cell_calloc_char(fileSize + minimumResponseAllocation); - if (response == nullptr) - { - if (_printDebug == true) - { - _debugPort->print(F("getFileContents: response alloc failed: ")); - _debugPort->println(fileSize + minimumResponseAllocation); - } - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - // A large file will completely fill the backlog buffer - but it will be pruned afterwards - // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... - // To try and avoid this, look for \"\r\nOK\r\n - const char fileReadTerm[] = "\"\r\nOK\r\n"; - err = sendCommandWithResponse(command, fileReadTerm, - response, (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), - (fileSize + minimumResponseAllocation)); - - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) + char sanitized_msg[MAX_MQTT_DIRECT_MSG_LEN + 1]; + memset(sanitized_msg, 0, sizeof(sanitized_msg)); + + // Check the message length and truncate if necessary. + size_t msg_len = strnlen(msg, MAX_MQTT_DIRECT_MSG_LEN); + if (msg_len > MAX_MQTT_DIRECT_MSG_LEN) { - _debugPort->print(F("getFileContents: sendCommandWithResponse returned err ")); - _debugPort->println(err); + msg_len = MAX_MQTT_DIRECT_MSG_LEN; } - free(command); - free(response); - return err; - } - - // Response format: \r\n+URDFILE: "filename",36,"these bytes are the data of the file"\r\n\r\nOK\r\n - int scanned = 0; - int readFileSize = 0; - char *searchPtr = strstr(response, "+URDFILE:"); - if (searchPtr != nullptr) - { - searchPtr = strchr(searchPtr, '\"'); // Find the first quote - searchPtr = strchr(++searchPtr, '\"'); // Find the second quote - scanned = sscanf(searchPtr, "\",%d,", &readFileSize); // Get the file size (again) - if (scanned == 1) + strncpy(sanitized_msg, msg, msg_len); + char *msg_ptr = sanitized_msg; + while (*msg_ptr != 0) { - searchPtr = strchr(++searchPtr, '\"'); // Find the third quote - - if (searchPtr == nullptr) - { - if (_printDebug == true) + if (*msg_ptr == '"') { - _debugPort->println(F("getFileContents: third quote not found!")); + *msg_ptr = ' '; } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - int bytesRead = 0; - - while (bytesRead < readFileSize) - { - searchPtr++; // Increment searchPtr then copy file char into contents - contents[bytesRead] = *searchPtr; // Append file char to contents - bytesRead++; - } - if (_printDebug == true) - { - _debugPort->print(F("getFileContents: total bytes read: ")); - _debugPort->println(bytesRead); - } - err = UBX_CELL_ERROR_SUCCESS; + + msg_ptr++; } - else + + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + msg_len); + if (command == nullptr) { - if (_printDebug == true) - { - _debugPort->print(F("getFileContents: sscanf failed! scanned is ")); - _debugPort->println(scanned); - } - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - } - else - { - if (_printDebug == true) - _debugPort->println(F("getFileContents: strstr failed!")); - err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - free(command); - free(response); - return err; -} - -UBX_CELL_error_t UBX_CELL::getFileBlock(const String& filename, char* buffer, size_t offset, size_t requested_length, size_t& bytes_read) -{ - bytes_read = 0; - if (filename.length() < 1 || buffer == nullptr || requested_length < 1) - { - return UBX_CELL_ERROR_UNEXPECTED_PARAM; - } + sprintf(command, "%s=%d,%u,%u,0,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISH, qos, + (retain ? 1 : 0), topic.c_str(), sanitized_msg); - // trying to get a byte at a time does not seem to be reliable so this method must use - // a real UART. - if (_hardSerial == nullptr) - { - if (_printDebug == true) + sendCommand(command, true); + err = waitForResponse(UBX_CELL_RESPONSE_MORE, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) { - _debugPort->println(F("getFileBlock: only works with a hardware UART")); + sendCommand(msg, false); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } - return UBX_CELL_ERROR_INVALID; - } - - size_t cmd_len = filename.length() + 32; - char* cmd = ubx_cell_calloc_char(cmd_len); - sprintf(cmd, "at+urdblock=\"%s\",%zu,%zu\r\n", filename.c_str(), offset, requested_length); - sendCommand(cmd, false); - int ich; - char ch; - int quote_count = 0; - size_t comma_idx = 0; + free(command); + return err; +} - while (quote_count < 3) - { - ich = _hardSerial->read(); - if (ich < 0) - { - continue; - } - ch = (char)(ich & 0xFF); - cmd[bytes_read++] = ch; - if (ch == '"') +UBX_CELL_error_t UBX_CELL::mqttPublishBinaryMsg(const String &topic, const char *const msg, size_t msg_len, uint8_t qos, + bool retain) +{ + /* + * The modem prints the '>' as the signal to send the binary message content. + * at+umqttc=9,0,0,"topic",4 + * + * >"xY" + * OK + * + * +UUMQTTC: 9,1 + */ + if (topic.length() < 1 || msg == nullptr || msg_len > MAX_MQTT_DIRECT_MSG_LEN) { - quote_count++; + return UBX_CELL_ERROR_INVALID; } - else if (ch == ',' && comma_idx == 0) + + UBX_CELL_error_t err; + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length()); + if (command == nullptr) { - comma_idx = bytes_read; + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - } - cmd[bytes_read] = 0; - cmd[bytes_read - 2] = 0; + sprintf(command, "%s=%d,%u,%u,\"%s\",%u", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, qos, + (retain ? 1 : 0), topic.c_str(), msg_len); - // Example response: - // +URDBLOCK: "wombat.bin",64000,"... " - size_t data_length = strtoul(&cmd[comma_idx], nullptr, 10); - free(cmd); - - bytes_read = 0; - size_t bytes_remaining = data_length; - while (bytes_read < data_length) - { - // This method seems more reliable than reading a byte at a time. - size_t rc = _hardSerial->readBytes(&buffer[bytes_read], bytes_remaining); - bytes_read += rc; - bytes_remaining -= rc; - } + sendCommand(command, true); + err = waitForResponse(UBX_CELL_RESPONSE_MORE, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) + { + sendCommand(msg, false); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + } - return UBX_CELL_ERROR_SUCCESS; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) +UBX_CELL_error_t UBX_CELL::mqttPublishFromFile(const String &topic, const String &filename, uint8_t qos, bool retain) { - UBX_CELL_error_t err; - char *command; - char *response; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_LIST_FILES) + filename.length() + 8); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=2,\"%s\"", UBX_CELL_FILE_SYSTEM_LIST_FILES, filename.c_str()); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) + if (topic.length() < 1 || filename.length() < 1) { - _debugPort->print(F("getFileSize: Fail: Error: ")); - _debugPort->print(err); - _debugPort->print(F(" Response: {")); - _debugPort->print(response); - _debugPort->println(F("}")); + return UBX_CELL_ERROR_INVALID; } - free(command); - free(response); - return err; - } - char *responseStart = strstr(response, "+ULSTFILE:"); - if (responseStart == nullptr) - { - if (_printDebug == true) + UBX_CELL_error_t err; + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + filename.length()); + if (command == nullptr) { - _debugPort->print(F("getFileSize: Failure: {")); - _debugPort->print(response); - _debugPort->println(F("}")); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - free(command); - free(response); - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - int fileSize; - responseStart += strlen("+ULSTFILE:"); // Move searchPtr to first char - while (*responseStart == ' ') responseStart++; // skip spaces - sscanf(responseStart, "%d", &fileSize); - *size = fileSize; + sprintf(command, "%s=%d,%u,%u,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHFILE, qos, + (retain ? 1 : 0), topic.c_str(), filename.c_str()); + + sendCommand(command, true); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - free(response); - return err; + free(command); + return err; } -UBX_CELL_error_t UBX_CELL::deleteFile(String filename) +UBX_CELL_error_t UBX_CELL::getMQTTprotocolError(int *error_code, int *error_code2) { - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_DELETE_FILE) + filename.length() + 8); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_DELETE_FILE, filename.c_str()); + UBX_CELL_error_t err; + char *response; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + int code, code2; - if (err != UBX_CELL_ERROR_SUCCESS) - { - if (_printDebug == true) + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) { - _debugPort->print(F("deleteFile: Fail: Error: ")); - _debugPort->println(err); + return UBX_CELL_ERROR_OUT_OF_MEMORY; } - } - - free(command); - return err; -} -UBX_CELL_error_t UBX_CELL::modulePowerOff(void) -{ - UBX_CELL_error_t err; - char *command; + err = sendCommandWithResponse(UBX_CELL_MQTT_PROTOCOL_ERROR, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_POWER_OFF) + 6); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (err == UBX_CELL_ERROR_SUCCESS) + { + int scanned = 0; + char *searchPtr = strstr(response, "+UMQTTER:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UMQTTER:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d\r\n", &code, &code2); + } + if (scanned == 2) + { + *error_code = code; + *error_code2 = code2; + } + else + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + free(response); + return err; +} + +UBX_CELL_error_t UBX_CELL::setFTPserver(const String &serverName) +{ + constexpr size_t cmd_len = 145; + char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> + + snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_SERVERNAME, + serverName.c_str()); + return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); +} + +UBX_CELL_error_t UBX_CELL::setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, + const unsigned int data_linger) +{ + constexpr size_t cmd_len = 64; + char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> + + snprintf(command, cmd_len - 1, "%s=%d,%u,%u,%u", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_TIMEOUT, timeout, + cmd_linger, data_linger); + return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); +} + +UBX_CELL_error_t UBX_CELL::setFTPcredentials(const String &userName, const String &pwd) +{ + UBX_CELL_error_t err; + constexpr size_t cmd_len = 48; + char command[cmd_len]; // long enough for AT+UFTP=n,<30 bytes> + + snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_USERNAME, + userName.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err != UBX_CELL_ERROR_SUCCESS) + { + return err; + } + + snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_PWD, pwd.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + return err; +} + +UBX_CELL_error_t UBX_CELL::connectFTP(void) +{ + constexpr size_t cmd_len = 16; + char command[cmd_len]; // long enough for AT+UFTPC=n + + snprintf(command, cmd_len - 1, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGIN); + return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); +} + +UBX_CELL_error_t UBX_CELL::disconnectFTP(void) +{ + constexpr size_t cmd_len = 16; + char command[cmd_len]; // long enough for AT+UFTPC=n + + snprintf(command, cmd_len - 1, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGOUT); + return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); +} + +UBX_CELL_error_t UBX_CELL::ftpGetFile(const String &filename) +{ + char *command = ubx_cell_calloc_char(strlen(UBX_CELL_FTP_COMMAND) + (2 * filename.length()) + 16); + if (command == nullptr) + { + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_GET_FILE, filename.c_str(), + filename.c_str()); + // memset(response, 0, sizeof(response)); + // sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, response, 8000 /* ms */, response_len); + UBX_CELL_error_t err = + sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL::getFTPprotocolError(int *error_code, int *error_code2) +{ + UBX_CELL_error_t err; + char *response; + + int code, code2; + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(UBX_CELL_FTP_PROTOCOL_ERROR, UBX_CELL_RESPONSE_OK_OR_ERROR, response, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) + { + int scanned = 0; + char *searchPtr = strstr(response, "+UFTPER:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UFTPER:"); // Move searchPtr to first char + while (*searchPtr == ' ') + { + searchPtr++; // skip spaces + } + scanned = sscanf(searchPtr, "%d,%d\r\n", &code, &code2); + } + + if (scanned == 2) + { + *error_code = code; + *error_code2 = code2; + } + else + { + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + } + + free(response); + return err; +} + +UBX_CELL_error_t UBX_CELL::resetSecurityProfile(int secprofile) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + 6); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + + sprintf(command, "%s=%d", UBX_CELL_SEC_PROFILE, secprofile); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL::configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + 10); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_SEC_PROFILE, secprofile, parameter, value); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL::configSecurityProfileString(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, + String value) +{ + UBX_CELL_error_t err; + char *command; + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + value.length() + 10); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_SEC_PROFILE, secprofile, parameter, value.c_str()); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, + UBX_CELL_sec_manager_parameter_t parameter, String name, String data) +{ + char *command; + char *response; + UBX_CELL_error_t err; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_MANAGER) + name.length() + 20); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + int dataLen = data.length(); + sprintf(command, "%s=%d,%d,\"%s\",%d", UBX_CELL_SEC_MANAGER, opcode, parameter, name.c_str(), dataLen); + + err = sendCommandWithResponse(command, ">", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("dataDownload: writing ")); + _debugPort->print(dataLen); + _debugPort->println(F(" bytes")); + } + hwWriteData(data.c_str(), dataLen); + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 3); + } + + if (err != UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("dataDownload: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" => {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + } + + free(command); + free(response); + return err; +} + +UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) +{ + UBX_CELL_error_t err; + char *command; + + if (cid >= UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) + return UBX_CELL_ERROR_ERROR; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE) + 32); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (cid == -1) + sprintf(command, "%s=%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status); + else + sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status, cid); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +bool UBX_CELL::isGPSon(void) +{ + UBX_CELL_error_t err; + char *command; + char *response; + bool on = false; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_POWER) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_POWER); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); + + if (err == UBX_CELL_ERROR_SUCCESS) + { + // Example response: "+UGPS: 0" for off "+UGPS: 1,0,1" for on + // Search for a ':' followed by a '1' or ' 1' + char *pch1 = strchr(response, ':'); + if (pch1 != nullptr) + { + char *pch2 = strchr(response, '1'); + if ((pch2 != nullptr) && ((pch2 == pch1 + 1) || (pch2 == pch1 + 2))) + on = true; + } + } + + free(command); + free(response); + + return on; +} + +UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_aiding_mode_t gnss_aiding) +{ + UBX_CELL_error_t err; + char *command; + bool gpsState; + + // Don't turn GPS on/off if it's already on/off + gpsState = isGPSon(); + if ((enable && gpsState) || (!enable && !gpsState)) + { + return UBX_CELL_ERROR_SUCCESS; + } + + // GPS power management + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_POWER) + 32); // gnss_sys could be up to three digits + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (enable) + { + sprintf(command, "%s=1,%d,%d", UBX_CELL_GNSS_POWER, gnss_aiding, gnss_sys); + } + else + { + sprintf(command, "%s=0", UBX_CELL_GNSS_POWER); + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, 10000); + + free(command); + return err; +} + +/* +UBX_CELL_error_t UBX_CELL::gpsEnableClock(bool enable) +{ + // AT+UGZDA=<0,1> + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsGetClock(struct ClockData *clock) +{ + // AT+UGZDA? + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsEnableFix(bool enable) +{ + // AT+UGGGA=<0,1> + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsGetFix(struct PositionData *pos) +{ + // AT+UGGGA? + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsEnablePos(bool enable) +{ + // AT+UGGLL=<0,1> + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsGetPos(struct PositionData *pos) +{ + // AT+UGGLL? + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsEnableSat(bool enable) +{ + // AT+UGGSV=<0,1> + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsGetSat(uint8_t *sats) +{ + // AT+UGGSV? + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} +*/ + +UBX_CELL_error_t UBX_CELL::gpsEnableRmc(bool enable) +{ + // AT+UGRMC=<0,1> + UBX_CELL_error_t err; + char *command; + + // ** Don't call gpsPower here. It causes problems for +UTIME and the PPS signal ** + // ** Call isGPSon and gpsPower externally if required ** + // if (!isGPSon()) + // { + // err = gpsPower(true); + // if (err != UBX_CELL_ERROR_SUCCESS) + // { + // return err; + // } + // } + + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_GPRMC) + 3); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_GNSS_GPRMC, enable ? 1 : 0); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); + + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsGetRmc(struct PositionData *pos, struct SpeedData *spd, struct ClockData *clk, + bool *valid) +{ + UBX_CELL_error_t err; + char *command; + char *response; + char *rmcBegin; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_GPRMC) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_GNSS_GPRMC); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); + if (err == UBX_CELL_ERROR_SUCCESS) + { + // Fast-forward response string to $GPRMC starter + rmcBegin = strstr(response, "$GPRMC"); + if (rmcBegin == nullptr) + { + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + else + { + *valid = parseGPRMCString(rmcBegin, pos, clk, spd); + } + } + + free(command); + free(response); + return err; +} + +/* +UBX_CELL_error_t UBX_CELL::gpsEnableSpeed(bool enable) +{ + // AT+UGVTG=<0,1> + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsGetSpeed(struct SpeedData *speed) +{ + // AT+UGVTG? + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; + return err; +} +*/ + +UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, bool detailed, unsigned int sensor) +{ + // AT+ULOC=2,,,, + UBX_CELL_error_t err; + char *command; + + // This function will only work if the GPS module is initially turned off. + if (isGPSon()) + { + gpsPower(false); + } + + if (timeout > 999) + timeout = 999; + if (accuracy > 999999) + accuracy = 999999; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_LOCATION) + 24); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; +#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) + sprintf(command, "%s=2,%d,%d,%d,%d", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); +#else + sprintf(command, "%s=2,%d,%d,%d,%ld", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); +#endif + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); + + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL::gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, + const char *authToken, unsigned int days, unsigned int period, + unsigned int resolution, unsigned int gnssTypes, unsigned int mode, + unsigned int dataType) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_AIDING_SERVER_CONFIGURATION) + 256); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + + sprintf(command, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBX_CELL_AIDING_SERVER_CONFIGURATION, primaryServer, + secondaryServer, authToken, days, period, resolution, gnssTypes, mode, dataType); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + free(command); + return err; +} + +// OK for text files. But will fail with binary files (containing \0) on some platforms. +UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, const char *str, int len) +{ + char *command; + char *response; + UBX_CELL_error_t err; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE) + filename.length() + 10); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + int dataLen = len == -1 ? strlen(str) : len; + sprintf(command, "%s=\"%s\",%d", UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE, filename.c_str(), dataLen); + + err = sendCommandWithResponse(command, ">", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 2); + + unsigned long writeDelay = millis(); + while (millis() < (writeDelay + 50)) + delay(1); // uBlox specification says to wait 50ms after receiving "@" to write data. + + if (err == UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("fileDownload: writing ")); + _debugPort->print(dataLen); + _debugPort->println(F(" bytes")); + } + hwWriteData(str, dataLen); + + err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); + } + if (err != UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("fileDownload: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" => {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + } + + free(command); + free(response); + return err; +} + +UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, String str) +{ + return appendFileContents(filename, str.c_str(), str.length()); +} + +// OK for text files. But will fail with binary files (containing \0) on some platforms. +UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) +{ + UBX_CELL_error_t err; + char *command; + char *response; + + // Start by getting the file size so we know in advance how much data to expect + int fileSize = 0; + err = getFileSize(filename, &fileSize); + if (err != UBX_CELL_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: getFileSize returned err ")); + _debugPort->println(err); + } + return err; + } + + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); + + response = ubx_cell_calloc_char(fileSize + minimumResponseAllocation); + if (response == nullptr) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: response alloc failed: ")); + _debugPort->println(fileSize + minimumResponseAllocation); + } + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + // A large file will completely fill the backlog buffer - but it will be pruned afterwards + // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... + // To try and avoid this, look for \"\r\nOK\r\n + const char fileReadTerm[] = "\r\nOK\r\n"; // LARA-R6 returns "\"\r\n\r\nOK\r\n" while SARA-R5 return "\"\r\nOK\r\n"; + err = sendCommandWithResponse(command, fileReadTerm, response, (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), + (fileSize + minimumResponseAllocation)); + + if (err != UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: sendCommandWithResponse returned err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } + + // Response format: \r\n+URDFILE: "filename",36,"these bytes are the data of the file"\r\n\r\nOK\r\n + int scanned = 0; + int readFileSize = 0; + char *searchPtr = strstr(response, "+URDFILE:"); + if (searchPtr != nullptr) + { + searchPtr = strchr(searchPtr, '\"'); // Find the first quote + searchPtr = strchr(++searchPtr, '\"'); // Find the second quote + + scanned = sscanf(searchPtr, "\",%d,", &readFileSize); // Get the file size (again) + if (scanned == 1) + { + searchPtr = strchr(++searchPtr, '\"'); // Find the third quote + + if (searchPtr == nullptr) + { + if (_printDebug == true) + { + _debugPort->println(F("getFileContents: third quote not found!")); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + int bytesRead = 0; + + while (bytesRead < readFileSize) + { + searchPtr++; // Increment searchPtr then copy file char into contents + // Important Note: some implementations of concat, like the one on ESP32, are binary-compatible. + // But some, like SAMD, are not. They use strlen or strcpy internally - which don't like \0's. + // The only true binary-compatible solution is to use getFileContents(String filename, char + // *contents)... + contents->concat(*(searchPtr)); // Append file char to contents + bytesRead++; + } + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: total bytes read: ")); + _debugPort->println(bytesRead); + } + err = UBX_CELL_ERROR_SUCCESS; + } + else + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: sscanf failed! scanned is ")); + _debugPort->println(scanned); + } + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + } + else + { + if (_printDebug == true) + _debugPort->println(F("getFileContents: strstr failed!")); + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +// OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. +UBX_CELL_error_t UBX_CELL::getFileContents(String filename, char *contents) +{ + UBX_CELL_error_t err; + char *command; + char *response; + + // Start by getting the file size so we know in advance how much data to expect + int fileSize = 0; + err = getFileSize(filename, &fileSize); + if (err != UBX_CELL_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: getFileSize returned err ")); + _debugPort->println(err); + } + return err; + } + + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); + + response = ubx_cell_calloc_char(fileSize + minimumResponseAllocation); + if (response == nullptr) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: response alloc failed: ")); + _debugPort->println(fileSize + minimumResponseAllocation); + } + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + // A large file will completely fill the backlog buffer - but it will be pruned afterwards + // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... + // To try and avoid this, look for \"\r\nOK\r\n + const char fileReadTerm[] = "\"\r\nOK\r\n"; + err = sendCommandWithResponse(command, fileReadTerm, response, (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), + (fileSize + minimumResponseAllocation)); + + if (err != UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: sendCommandWithResponse returned err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } + + // Response format: \r\n+URDFILE: "filename",36,"these bytes are the data of the file"\r\n\r\nOK\r\n + int scanned = 0; + int readFileSize = 0; + char *searchPtr = strstr(response, "+URDFILE:"); + if (searchPtr != nullptr) + { + searchPtr = strchr(searchPtr, '\"'); // Find the first quote + searchPtr = strchr(++searchPtr, '\"'); // Find the second quote + + scanned = sscanf(searchPtr, "\",%d,", &readFileSize); // Get the file size (again) + if (scanned == 1) + { + searchPtr = strchr(++searchPtr, '\"'); // Find the third quote + + if (searchPtr == nullptr) + { + if (_printDebug == true) + { + _debugPort->println(F("getFileContents: third quote not found!")); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + int bytesRead = 0; + + while (bytesRead < readFileSize) + { + searchPtr++; // Increment searchPtr then copy file char into contents + contents[bytesRead] = *searchPtr; // Append file char to contents + bytesRead++; + } + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: total bytes read: ")); + _debugPort->println(bytesRead); + } + err = UBX_CELL_ERROR_SUCCESS; + } + else + { + if (_printDebug == true) + { + _debugPort->print(F("getFileContents: sscanf failed! scanned is ")); + _debugPort->println(scanned); + } + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + } + else + { + if (_printDebug == true) + _debugPort->println(F("getFileContents: strstr failed!")); + err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + free(command); + free(response); + return err; +} + +UBX_CELL_error_t UBX_CELL::getFileBlock(const String &filename, char *buffer, size_t offset, size_t requested_length, + size_t &bytes_read) +{ + bytes_read = 0; + if (filename.length() < 1 || buffer == nullptr || requested_length < 1) + { + return UBX_CELL_ERROR_UNEXPECTED_PARAM; + } + + // trying to get a byte at a time does not seem to be reliable so this method must use + // a real UART. + if (_hardSerial == nullptr) + { + if (_printDebug == true) + { + _debugPort->println(F("getFileBlock: only works with a hardware UART")); + } + return UBX_CELL_ERROR_INVALID; + } + + size_t cmd_len = filename.length() + 32; + char *cmd = ubx_cell_calloc_char(cmd_len); + sprintf(cmd, "at+urdblock=\"%s\",%zu,%zu\r\n", filename.c_str(), offset, requested_length); + sendCommand(cmd, false); + + int ich; + char ch; + int quote_count = 0; + size_t comma_idx = 0; + + while (quote_count < 3) + { + ich = _hardSerial->read(); + if (ich < 0) + { + continue; + } + ch = (char)(ich & 0xFF); + cmd[bytes_read++] = ch; + if (ch == '"') + { + quote_count++; + } + else if (ch == ',' && comma_idx == 0) + { + comma_idx = bytes_read; + } + } + + cmd[bytes_read] = 0; + cmd[bytes_read - 2] = 0; + + // Example response: + // +URDBLOCK: "wombat.bin",64000,"... " + size_t data_length = strtoul(&cmd[comma_idx], nullptr, 10); + free(cmd); + + bytes_read = 0; + size_t bytes_remaining = data_length; + while (bytes_read < data_length) + { + // This method seems more reliable than reading a byte at a time. + size_t rc = _hardSerial->readBytes(&buffer[bytes_read], bytes_remaining); + bytes_read += rc; + bytes_remaining -= rc; + } + + return UBX_CELL_ERROR_SUCCESS; +} + +UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) +{ + UBX_CELL_error_t err; + char *command; + char *response; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_LIST_FILES) + filename.length() + 8); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=2,\"%s\"", UBX_CELL_FILE_SYSTEM_LIST_FILES, filename.c_str()); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err != UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileSize: Fail: Error: ")); + _debugPort->print(err); + _debugPort->print(F(" Response: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + free(command); + free(response); + return err; + } + + char *responseStart = strstr(response, "+ULSTFILE:"); + if (responseStart == nullptr) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileSize: Failure: {")); + _debugPort->print(response); + _debugPort->println(F("}")); + } + free(command); + free(response); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } + + int fileSize; + responseStart += strlen("+ULSTFILE:"); // Move searchPtr to first char + while (*responseStart == ' ') + responseStart++; // skip spaces + sscanf(responseStart, "%d", &fileSize); + *size = fileSize; + + free(command); + free(response); + return err; +} + +UBX_CELL_error_t UBX_CELL::deleteFile(String filename) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_DELETE_FILE) + filename.length() + 8); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_DELETE_FILE, filename.c_str()); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + if (err != UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("deleteFile: Fail: Error: ")); + _debugPort->println(err); + } + } + + free(command); + return err; +} + +UBX_CELL_error_t UBX_CELL::modulePowerOff(void) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_POWER_OFF) + 6); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s", UBX_CELL_COMMAND_POWER_OFF); + sprintf(command, "%s", UBX_CELL_COMMAND_POWER_OFF); - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, - UBX_CELL_POWER_OFF_TIMEOUT); + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_POWER_OFF_TIMEOUT); - free(command); - return err; + free(command); + return err; } void UBX_CELL::modulePowerOn(void) { - if (_powerPin >= 0) - { - powerOn(); - } - else - { - if (_printDebug == true) - _debugPort->println(F("modulePowerOn: not supported. _powerPin not defined.")); - } + if (_powerPin >= 0) + { + powerOn(); + } + else + { + if (_printDebug == true) + _debugPort->println(F("modulePowerOn: not supported. _powerPin not defined.")); + } } ///////////// // Private // ///////////// -UBX_CELL_error_t UBX_CELL::init(unsigned long baud, - UBX_CELL::UBX_CELL_init_type_t initType) +UBX_CELL_error_t UBX_CELL::init(unsigned long baud, UBX_CELL::UBX_CELL_init_type_t initType) { - int retries = _maxInitTries; - UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; - - beginSerial(baud); + int retries = _maxInitTries; + UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; - do - { - if (_printDebug == true) - _debugPort->println(F("init: Begin module init.")); + beginSerial(baud); - if (initType == UBX_CELL_INIT_AUTOBAUD) + do { - if (_printDebug == true) - _debugPort->println(F("init: Attempting autobaud connection to module.")); + if (_printDebug == true) + _debugPort->println(F("init: Begin module init.")); + + if (initType == UBX_CELL_INIT_AUTOBAUD) + { + if (_printDebug == true) + _debugPort->println(F("init: Attempting autobaud connection to module.")); - err = autobaud(baud); + err = autobaud(baud); - if (err != UBX_CELL_ERROR_SUCCESS) { - initType = UBX_CELL_INIT_RESET; - } - } - else if (initType == UBX_CELL_INIT_RESET) - { - if (_printDebug == true) - _debugPort->println(F("init: Power cycling module.")); + if (err != UBX_CELL_ERROR_SUCCESS) + { + initType = UBX_CELL_INIT_RESET; + } + } + else if (initType == UBX_CELL_INIT_RESET) + { + if (_printDebug == true) + _debugPort->println(F("init: Power cycling module.")); - powerOff(); - delay(UBX_CELL_POWER_OFF_PULSE_PERIOD); - powerOn(); - beginSerial(baud); - delay(2000); + powerOff(); + delay(UBX_CELL_POWER_OFF_PULSE_PERIOD); + powerOn(); + beginSerial(baud); + delay(2000); - err = at(); - if (err != UBX_CELL_ERROR_SUCCESS) - { - initType = UBX_CELL_INIT_AUTOBAUD; - } - } - if (err == UBX_CELL_ERROR_SUCCESS) + err = at(); + if (err != UBX_CELL_ERROR_SUCCESS) + { + initType = UBX_CELL_INIT_AUTOBAUD; + } + } + if (err == UBX_CELL_ERROR_SUCCESS) + { + err = enableEcho(false); // = disableEcho + if (err != UBX_CELL_ERROR_SUCCESS) + { + if (_printDebug == true) + _debugPort->println(F("init: Module failed echo test.")); + initType = UBX_CELL_INIT_AUTOBAUD; + } + } + } while ((retries--) && (err != UBX_CELL_ERROR_SUCCESS)); + + // we tried but seems failed + if (err != UBX_CELL_ERROR_SUCCESS) { - err = enableEcho(false); // = disableEcho - if (err != UBX_CELL_ERROR_SUCCESS) - { if (_printDebug == true) - _debugPort->println(F("init: Module failed echo test.")); - initType = UBX_CELL_INIT_AUTOBAUD; - } + _debugPort->println(F("init: Module failed to init. Exiting.")); + return (UBX_CELL_ERROR_NO_RESPONSE); } - } - while ((retries --) && (err != UBX_CELL_ERROR_SUCCESS)); - // we tried but seems failed - if (err != UBX_CELL_ERROR_SUCCESS) { if (_printDebug == true) - _debugPort->println(F("init: Module failed to init. Exiting.")); - return (UBX_CELL_ERROR_NO_RESPONSE); - } + _debugPort->println(F("init: Module responded successfully.")); - if (_printDebug == true) - _debugPort->println(F("init: Module responded successfully.")); - - _baud = baud; - setGpioMode(GPIO1, NETWORK_STATUS); - //setGpioMode(GPIO2, GNSS_SUPPLY_ENABLE); - setGpioMode(GPIO6, TIME_PULSE_OUTPUT); - setSMSMessageFormat(UBX_CELL_MESSAGE_FORMAT_TEXT); - autoTimeZone(_autoTimeZoneForBegin); - for (int i = 0; i < UBX_CELL_NUM_SOCKETS; i++) - { - socketClose(i, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - } + _baud = baud; + setGpioMode(GPIO1, NETWORK_STATUS); + // setGpioMode(GPIO2, GNSS_SUPPLY_ENABLE); + setGpioMode(GPIO6, TIME_PULSE_OUTPUT); + setSMSMessageFormat(UBX_CELL_MESSAGE_FORMAT_TEXT); + autoTimeZone(_autoTimeZoneForBegin); + for (int i = 0; i < UBX_CELL_NUM_SOCKETS; i++) + { + socketClose(i, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + } - return UBX_CELL_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } void UBX_CELL::invertPowerPin(bool invert) { - _invertPowerPin = invert; + _invertPowerPin = invert; } // Do a graceful power off. Hold the PWR_ON pin low for UBX_CELL_POWER_OFF_PULSE_PERIOD // Note: +CPWROFF () is preferred to this. void UBX_CELL::powerOff(void) { - if (_powerPin >= 0) - { - if (_invertPowerPin) // Set the pin state before making it an output - digitalWrite(_powerPin, HIGH); - else - digitalWrite(_powerPin, LOW); - pinMode(_powerPin, OUTPUT); - if (_invertPowerPin) // Set the pin state - digitalWrite(_powerPin, HIGH); - else - digitalWrite(_powerPin, LOW); - delay(UBX_CELL_POWER_OFF_PULSE_PERIOD); - pinMode(_powerPin, INPUT); // Return to high-impedance, rely on (e.g.) SARA module internal pull-up - if (_printDebug == true) - _debugPort->println(F("powerOff: complete")); - } + if (_powerPin >= 0) + { + if (_invertPowerPin) // Set the pin state before making it an output + digitalWrite(_powerPin, HIGH); + else + digitalWrite(_powerPin, LOW); + pinMode(_powerPin, OUTPUT); + if (_invertPowerPin) // Set the pin state + digitalWrite(_powerPin, HIGH); + else + digitalWrite(_powerPin, LOW); + delay(UBX_CELL_POWER_OFF_PULSE_PERIOD); + pinMode(_powerPin, INPUT); // Return to high-impedance, rely on (e.g.) SARA module internal pull-up + if (_printDebug == true) + _debugPort->println(F("powerOff: complete")); + } } void UBX_CELL::powerOn(void) { - if (_powerPin >= 0) - { - if (_invertPowerPin) // Set the pin state before making it an output - digitalWrite(_powerPin, HIGH); + if (_powerPin >= 0) + { + if (_invertPowerPin) // Set the pin state before making it an output + digitalWrite(_powerPin, HIGH); + else + digitalWrite(_powerPin, LOW); + pinMode(_powerPin, OUTPUT); + if (_invertPowerPin) // Set the pin state + digitalWrite(_powerPin, HIGH); + else + digitalWrite(_powerPin, LOW); + delay(UBX_CELL_POWER_ON_PULSE_PERIOD); + pinMode(_powerPin, INPUT); // Return to high-impedance, rely on (e.g.) SARA module internal pull-up + // delay(2000); // Do this in init. Wait before sending AT commands to module. 100 is too short. + if (_printDebug == true) + _debugPort->println(F("powerOn: complete")); + } +} + +// This does an abrupt emergency hardware shutdown of the SARA-R5 series modules. +// It only works if you have access to both the RESET_N and PWR_ON pins. +// You cannot use this function on the SparkFun Asset Tracker and RESET_N is tied to the MicroMod processor !RESET!... +void UBX_CELL::hwReset(void) +{ + if ((_resetPin >= 0) && (_powerPin >= 0)) + { + digitalWrite(_resetPin, HIGH); // Start by making sure the RESET_N pin is high + pinMode(_resetPin, OUTPUT); + digitalWrite(_resetPin, HIGH); + + if (_invertPowerPin) // Now pull PWR_ON low - invert as necessary (on the Asset Tracker) + { + digitalWrite(_powerPin, HIGH); // Inverted - Asset Tracker + pinMode(_powerPin, OUTPUT); + digitalWrite(_powerPin, HIGH); + } + else + { + digitalWrite(_powerPin, LOW); // Not inverted + pinMode(_powerPin, OUTPUT); + digitalWrite(_powerPin, LOW); + } + + delay(UBX_CELL_RESET_PULSE_PERIOD); // Wait 23 seconds... (Yes, really!) + + digitalWrite(_resetPin, LOW); // Now pull RESET_N low + + delay(100); // Wait a little... (The data sheet doesn't say how long for) + + if (_invertPowerPin) // Now pull PWR_ON high - invert as necessary (on the Asset Tracker) + { + digitalWrite(_powerPin, LOW); // Inverted - Asset Tracker + } + else + { + digitalWrite(_powerPin, HIGH); // Not inverted + } + + delay(1500); // Wait 1.5 seconds + + digitalWrite(_resetPin, HIGH); // Now pull RESET_N high again + + pinMode(_resetPin, INPUT); // Return to high-impedance, rely on SARA module internal pull-up + pinMode(_powerPin, INPUT); // Return to high-impedance, rely on SARA module internal pull-up + } +} + +UBX_CELL_error_t UBX_CELL::functionality(UBX_CELL_functionality_t function) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_FUNC) + 16); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_COMMAND_FUNC, function); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); + + free(command); + + return err; +} + +UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) +{ + UBX_CELL_error_t err; + char *command; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_MNO) + 9); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + if (mno == MNO_SIM_ICCID) // Only add autoReset and urcNotification if mno is MNO_SIM_ICCID + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno, (uint8_t)autoReset, + (uint8_t)urcNotification); else - digitalWrite(_powerPin, LOW); - pinMode(_powerPin, OUTPUT); - if (_invertPowerPin) // Set the pin state - digitalWrite(_powerPin, HIGH); + sprintf(command, "%s=%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno); + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + + free(command); + + return err; +} + +UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) +{ + UBX_CELL_error_t err; + char *command; + char *response; + mobile_network_operator_t o; + int d; + int r; + int u; + int oStore; + + command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_MNO) + 2); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s?", UBX_CELL_COMMAND_MNO); + + response = ubx_cell_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + free(command); + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + if (err != UBX_CELL_ERROR_SUCCESS) + { + free(command); + free(response); + return err; + } + + int scanned = 0; + char *searchPtr = strstr(response, "+UMNOPROF:"); + if (searchPtr != nullptr) + { + searchPtr += strlen("+UMNOPROF:"); // Move searchPtr to first char + while (*searchPtr == ' ') + searchPtr++; // skip spaces + scanned = sscanf(searchPtr, "%d,%d,%d,%d", &oStore, &d, &r, &u); + } + o = (mobile_network_operator_t)oStore; + + if (scanned >= 1) + { + if (_printDebug == true) + { + _debugPort->print(F("getMNOprofile: MNO is: ")); + _debugPort->println(o); + } + *mno = o; + } else - digitalWrite(_powerPin, LOW); - delay(UBX_CELL_POWER_ON_PULSE_PERIOD); - pinMode(_powerPin, INPUT); // Return to high-impedance, rely on (e.g.) SARA module internal pull-up - //delay(2000); // Do this in init. Wait before sending AT commands to module. 100 is too short. - if (_printDebug == true) - _debugPort->println(F("powerOn: complete")); - } + { + err = UBX_CELL_ERROR_INVALID; + } + + free(command); + free(response); + + return err; } -//This does an abrupt emergency hardware shutdown of the SARA-R5 series modules. -//It only works if you have access to both the RESET_N and PWR_ON pins. -//You cannot use this function on the SparkFun Asset Tracker and RESET_N is tied to the MicroMod processor !RESET!... -void UBX_CELL::hwReset(void) +UBX_CELL_error_t UBX_CELL::waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout) +{ + unsigned long timeIn; + bool found = false; + bool error = false; + int responseIndex = 0, errorIndex = 0; + // bool printedSomething = false; + + timeIn = millis(); + + int responseLen = (int)strlen(expectedResponse); + int errorLen = (int)strlen(expectedError); + + while ((!found) && ((timeIn + timeout) > millis())) + { + if (hwAvailable() > 0) // hwAvailable can return -1 if the serial port is nullptr + { + char c = readChar(); + // if (_printDebug == true) + // { + // if (printedSomething == false) + // _debugPort->print(F("waitForResponse: ")); + // _debugPort->write(c); + // printedSomething = true; + // } + if ((responseIndex < responseLen) && (c == expectedResponse[responseIndex])) + { + if (++responseIndex == responseLen) + { + found = true; + } + } + else + { + responseIndex = ((responseIndex < responseLen) && (c == expectedResponse[0])) ? 1 : 0; + } + if ((errorIndex < errorLen) && (c == expectedError[errorIndex])) + { + if (++errorIndex == errorLen) + { + error = true; + found = true; + } + } + else + { + errorIndex = ((errorIndex < errorLen) && (c == expectedError[0])) ? 1 : 0; + } + //_saraResponseBacklog is a global array that holds the backlog of any events + // that came in while waiting for response. To be processed later within bufferedPoll(). + // Note: the expectedResponse or expectedError will also be added to the backlog. + // The backlog is only used by bufferedPoll to process the URCs - which are all readable. + // bufferedPoll uses strtok - which does not like nullptr characters. + // So let's make sure no NULLs end up in the backlog! + if (_saraResponseBacklogLength < _RXBuffSize) // Don't overflow the buffer + { + if (c == '\0') + _saraResponseBacklog[_saraResponseBacklogLength++] = '0'; // Change NULLs to ASCII Zeros + else + _saraResponseBacklog[_saraResponseBacklogLength++] = c; + } + } + else + { + yield(); + } + } + + // if (_printDebug == true) + // if (printedSomething) + // _debugPort->println(); + + pruneBacklog(); // Prune any incoming non-actionable URC's and responses/errors from the backlog + + if (found == true) + { + if (true == _printAtDebug) + { + _debugAtPort->print((error == true) ? expectedError : expectedResponse); + } + + return (error == true) ? UBX_CELL_ERROR_ERROR : UBX_CELL_ERROR_SUCCESS; + } + + return UBX_CELL_ERROR_NO_RESPONSE; +} + +UBX_CELL_error_t UBX_CELL::sendCommandWithResponse(const char *command, const char *expectedResponse, + char *responseDest, unsigned long commandTimeout, int destSize, + bool at) { - if ((_resetPin >= 0) && (_powerPin >= 0)) - { - digitalWrite(_resetPin, HIGH); // Start by making sure the RESET_N pin is high - pinMode(_resetPin, OUTPUT); - digitalWrite(_resetPin, HIGH); + bool found = false; + bool error = false; + int responseIndex = 0; + int errorIndex = 0; + int destIndex = 0; + unsigned int charsRead = 0; + int responseLen = 0; + int errorLen = 0; + const char *expectedError = nullptr; + bool printResponse = false; // Change to true to print the full response + bool printedSomething = false; + + if (_printDebug == true) + { + _debugPort->print(F("sendCommandWithResponse: Command: ")); + _debugPort->println(String(command)); + } - if (_invertPowerPin) // Now pull PWR_ON low - invert as necessary (on the Asset Tracker) + sendCommand(command, at); // Sending command needs to dump data to backlog buffer as well. + unsigned long timeIn = millis(); + if (UBX_CELL_RESPONSE_OK_OR_ERROR == expectedResponse) { - digitalWrite(_powerPin, HIGH); // Inverted - Asset Tracker - pinMode(_powerPin, OUTPUT); - digitalWrite(_powerPin, HIGH); + expectedResponse = UBX_CELL_RESPONSE_OK; + expectedError = UBX_CELL_RESPONSE_ERROR; + responseLen = sizeof(UBX_CELL_RESPONSE_OK) - 1; + errorLen = sizeof(UBX_CELL_RESPONSE_ERROR) - 1; } else { - digitalWrite(_powerPin, LOW); // Not inverted - pinMode(_powerPin, OUTPUT); - digitalWrite(_powerPin, LOW); + responseLen = (int)strlen(expectedResponse); } - delay(UBX_CELL_RESET_PULSE_PERIOD); // Wait 23 seconds... (Yes, really!) + while ((!found) && ((timeIn + commandTimeout) > millis())) + { + if (hwAvailable() > 0) // hwAvailable can return -1 if the serial port is nullptr + { + char c = readChar(); + if ((printResponse = true) && (_printDebug == true)) + { + if (printedSomething == false) + { + _debugPort->print(F("sendCommandWithResponse: Response: ")); + printedSomething = true; + } + _debugPort->write(c); + } + if (responseDest != nullptr) + { + if (destIndex < destSize) // Only add this char to response if there is room for it + responseDest[destIndex] = c; + destIndex++; + if (destIndex == destSize) + { + if (_printDebug == true) + { + if ((printResponse = true) && (printedSomething)) + _debugPort->println(); + _debugPort->print(F("sendCommandWithResponse: Panic! responseDest is full!")); + if ((printResponse = true) && (printedSomething)) + _debugPort->print(F("sendCommandWithResponse: Ignored response: ")); + } + } + } + charsRead++; + if ((errorIndex < errorLen) && (c == expectedError[errorIndex])) + { + if (++errorIndex == errorLen) + { + error = true; + found = true; + } + } + else + { + errorIndex = ((errorIndex < errorLen) && (c == expectedError[0])) ? 1 : 0; + } + if ((responseIndex < responseLen) && (c == expectedResponse[responseIndex])) + { + if (++responseIndex == responseLen) + { + found = true; + } + } + else + { + responseIndex = ((responseIndex < responseLen) && (c == expectedResponse[0])) ? 1 : 0; + } + //_saraResponseBacklog is a global array that holds the backlog of any events + // that came in while waiting for response. To be processed later within bufferedPoll(). + // Note: the expectedResponse or expectedError will also be added to the backlog + // The backlog is only used by bufferedPoll to process the URCs - which are all readable. + // bufferedPoll uses strtok - which does not like NULL characters. + // So let's make sure no NULLs end up in the backlog! + if (_saraResponseBacklogLength < _RXBuffSize) // Don't overflow the buffer + { + if (c == '\0') + _saraResponseBacklog[_saraResponseBacklogLength++] = '0'; // Change NULLs to ASCII Zeros + else + _saraResponseBacklog[_saraResponseBacklogLength++] = c; + } + } + else + { + yield(); + } + } - digitalWrite(_resetPin, LOW); // Now pull RESET_N low + if (_printDebug == true) + if ((printResponse = true) && (printedSomething)) + _debugPort->println(); - delay(100); // Wait a little... (The data sheet doesn't say how long for) + pruneBacklog(); // Prune any incoming non-actionable URC's and responses/errors from the backlog - if (_invertPowerPin) // Now pull PWR_ON high - invert as necessary (on the Asset Tracker) + if (found) + { + if ((true == _printAtDebug) && ((nullptr != responseDest) || (nullptr != expectedResponse))) + { + _debugAtPort->print((nullptr != responseDest) ? responseDest : expectedResponse); + } + return error ? UBX_CELL_ERROR_ERROR : UBX_CELL_ERROR_SUCCESS; + } + else if (charsRead == 0) { - digitalWrite(_powerPin, LOW); // Inverted - Asset Tracker + return UBX_CELL_ERROR_NO_RESPONSE; } else { - digitalWrite(_powerPin, HIGH); // Not inverted + if ((true == _printAtDebug) && (nullptr != responseDest)) + { + _debugAtPort->print(responseDest); + } + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - - delay(1500); // Wait 1.5 seconds - - digitalWrite(_resetPin, HIGH); // Now pull RESET_N high again - - pinMode(_resetPin, INPUT); // Return to high-impedance, rely on SARA module internal pull-up - pinMode(_powerPin, INPUT); // Return to high-impedance, rely on SARA module internal pull-up - } } -UBX_CELL_error_t UBX_CELL::functionality(UBX_CELL_functionality_t function) +// Send a custom command with an expected (potentially partial) response, store entire response +UBX_CELL_error_t UBX_CELL::sendCustomCommandWithResponse(const char *command, const char *expectedResponse, + char *responseDest, unsigned long commandTimeout, bool at) { - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_FUNC) + 16); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_COMMAND_FUNC, function); - - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_3_MIN_TIMEOUT); - - free(command); - - return err; + // Assume the user has allocated enough storage for any response. Set destSize to 32766. + return sendCommandWithResponse(command, expectedResponse, responseDest, commandTimeout, 32766, at); } -UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) +void UBX_CELL::sendCommand(const char *command, bool at) { - UBX_CELL_error_t err; - char *command; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_MNO) + 9); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - if (mno == MNO_SIM_ICCID) // Only add autoReset and urcNotification if mno is MNO_SIM_ICCID - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno, (uint8_t)autoReset, (uint8_t)urcNotification); - else - sprintf(command, "%s=%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno); + // Check for incoming serial data. Copy it into the backlog - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + // Important note: + // On ESP32, Serial.available only provides an update every ~120 bytes during the reception of long messages: + // https://gitter.im/espressif/arduino-esp32?at=5e25d6370a1cf54144909c85 + // Be aware that if a long message is being received, the code below will timeout after _rxWindowMillis = 2 millis. + // At 115200 baud, hwAvailable takes ~120 * 10 / 115200 = 10.4 millis before it indicates that data is being + // received. - free(command); + unsigned long timeIn = millis(); + if (hwAvailable() > 0) // hwAvailable can return -1 if the serial port is NULL + { + while (((millis() - timeIn) < _rxWindowMillis) && + (_saraResponseBacklogLength < _RXBuffSize)) // May need to escape on newline? + { + if (hwAvailable() > 0) // hwAvailable can return -1 if the serial port is NULL + { + //_saraResponseBacklog is a global array that holds the backlog of any events + // that came in while waiting for response. To be processed later within bufferedPoll(). + // Note: the expectedResponse or expectedError will also be added to the backlog + // The backlog is only used by bufferedPoll to process the URCs - which are all readable. + // bufferedPoll uses strtok - which does not like NULL characters. + // So let's make sure no NULLs end up in the backlog! + char c = readChar(); + if (c == '\0') // Make sure no NULL characters end up in the backlog! Change them to ASCII Zeros + c = '0'; + _saraResponseBacklog[_saraResponseBacklogLength++] = c; + timeIn = millis(); + } + else + { + yield(); + } + } + } - return err; + // Now send the command + if (at) + { + hwPrint(UBX_CELL_COMMAND_AT); + hwPrint(command); + hwPrint("\r\n"); + } + else + { + hwPrint(command); + } } -UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) +UBX_CELL_error_t UBX_CELL::parseSocketReadIndication(int socket, int length) { - UBX_CELL_error_t err; - char *command; - char *response; - mobile_network_operator_t o; - int d; - int r; - int u; - int oStore; - - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_MNO) + 2); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_COMMAND_MNO); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + UBX_CELL_error_t err; + char *readDest; - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - if (err != UBX_CELL_ERROR_SUCCESS) - { - free(command); - free(response); - return err; - } - - int scanned = 0; - char *searchPtr = strstr(response, "+UMNOPROF:"); - if (searchPtr != nullptr) - { - searchPtr += strlen("+UMNOPROF:"); // Move searchPtr to first char - while (*searchPtr == ' ') searchPtr++; // skip spaces - scanned = sscanf(searchPtr, "%d,%d,%d,%d", &oStore, &d, &r, &u); - } - o = (mobile_network_operator_t)oStore; - - if (scanned >= 1) - { - if (_printDebug == true) + if ((socket < 0) || (length < 0)) { - _debugPort->print(F("getMNOprofile: MNO is: ")); - _debugPort->println(o); + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - *mno = o; - } - else - { - err = UBX_CELL_ERROR_INVALID; - } - free(command); - free(response); + // Return now if both callbacks pointers are nullptr - otherwise the data will be read and lost! + if ((_socketReadCallback == nullptr) && (_socketReadCallbackPlus == nullptr)) + return UBX_CELL_ERROR_INVALID; - return err; -} + readDest = ubx_cell_calloc_char(length + 1); + if (readDest == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; -UBX_CELL_error_t UBX_CELL::waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout) -{ - unsigned long timeIn; - bool found = false; - bool error = false; - int responseIndex = 0, errorIndex = 0; - // bool printedSomething = false; - - timeIn = millis(); - - int responseLen = (int)strlen(expectedResponse); - int errorLen = (int)strlen(expectedError); - - while ((!found) && ((timeIn + timeout) > millis())) - { - if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is nullptr - { - char c = readChar(); - // if (_printDebug == true) - // { - // if (printedSomething == false) - // _debugPort->print(F("waitForResponse: ")); - // _debugPort->write(c); - // printedSomething = true; - // } - if ((responseIndex < responseLen) && (c == expectedResponse[responseIndex])) - { - if (++responseIndex == responseLen) - { - found = true; - } - } - else - { - responseIndex = ((responseIndex < responseLen) && (c == expectedResponse[0])) ? 1 : 0; - } - if ((errorIndex < errorLen) && (c == expectedError[errorIndex])) - { - if (++errorIndex == errorLen) - { - error = true; - found = true; - } - } - else - { - errorIndex = ((errorIndex < errorLen) && (c == expectedError[0])) ? 1 : 0; - } - //_saraResponseBacklog is a global array that holds the backlog of any events - //that came in while waiting for response. To be processed later within bufferedPoll(). - //Note: the expectedResponse or expectedError will also be added to the backlog. - //The backlog is only used by bufferedPoll to process the URCs - which are all readable. - //bufferedPoll uses strtok - which does not like nullptr characters. - //So let's make sure no NULLs end up in the backlog! - if (_saraResponseBacklogLength < _RXBuffSize) // Don't overflow the buffer - { - if (c == '\0') - _saraResponseBacklog[_saraResponseBacklogLength++] = '0'; // Change NULLs to ASCII Zeros - else - _saraResponseBacklog[_saraResponseBacklogLength++] = c; - } - } else { - yield(); - } - } - - // if (_printDebug == true) - // if (printedSomething) - // _debugPort->println(); - - pruneBacklog(); // Prune any incoming non-actionable URC's and responses/errors from the backlog - - if (found == true) - { - if (true == _printAtDebug) { - _debugAtPort->print((error == true) ? expectedError : expectedResponse); - } - - return (error == true) ? UBX_CELL_ERROR_ERROR : UBX_CELL_ERROR_SUCCESS; - } - - return UBX_CELL_ERROR_NO_RESPONSE; -} - -UBX_CELL_error_t UBX_CELL::sendCommandWithResponse( - const char *command, const char *expectedResponse, char *responseDest, - unsigned long commandTimeout, int destSize, bool at) -{ - bool found = false; - bool error = false; - int responseIndex = 0; - int errorIndex = 0; - int destIndex = 0; - unsigned int charsRead = 0; - int responseLen = 0; - int errorLen = 0; - const char* expectedError= nullptr; - bool printResponse = false; // Change to true to print the full response - bool printedSomething = false; - - if (_printDebug == true) - { - _debugPort->print(F("sendCommandWithResponse: Command: ")); - _debugPort->println(String(command)); - } - - sendCommand(command, at); //Sending command needs to dump data to backlog buffer as well. - unsigned long timeIn = millis(); - if (UBX_CELL_RESPONSE_OK_OR_ERROR == expectedResponse) { - expectedResponse = UBX_CELL_RESPONSE_OK; - expectedError = UBX_CELL_RESPONSE_ERROR; - responseLen = sizeof(UBX_CELL_RESPONSE_OK)-1; - errorLen = sizeof(UBX_CELL_RESPONSE_ERROR)-1; - } else { - responseLen = (int)strlen(expectedResponse); - } - - while ((!found) && ((timeIn + commandTimeout) > millis())) - { - if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is nullptr - { - char c = readChar(); - if ((printResponse = true) && (_printDebug == true)) - { - if (printedSomething == false) - { - _debugPort->print(F("sendCommandWithResponse: Response: ")); - printedSomething = true; - } - _debugPort->write(c); - } - if (responseDest != nullptr) - { - if (destIndex < destSize) // Only add this char to response if there is room for it - responseDest[destIndex] = c; - destIndex++; - if (destIndex == destSize) - { - if (_printDebug == true) - { - if ((printResponse = true) && (printedSomething)) - _debugPort->println(); - _debugPort->print(F("sendCommandWithResponse: Panic! responseDest is full!")); - if ((printResponse = true) && (printedSomething)) - _debugPort->print(F("sendCommandWithResponse: Ignored response: ")); - } - } - } - charsRead++; - if ((errorIndex < errorLen) && (c == expectedError[errorIndex])) - { - if (++errorIndex == errorLen) - { - error = true; - found = true; - } - } - else - { - errorIndex = ((errorIndex < errorLen) && (c == expectedError[0])) ? 1 : 0; - } - if ((responseIndex < responseLen) && (c == expectedResponse[responseIndex])) - { - if (++responseIndex == responseLen) - { - found = true; - } - } - else - { - responseIndex = ((responseIndex < responseLen) && (c == expectedResponse[0])) ? 1 : 0; - } - //_saraResponseBacklog is a global array that holds the backlog of any events - //that came in while waiting for response. To be processed later within bufferedPoll(). - //Note: the expectedResponse or expectedError will also be added to the backlog - //The backlog is only used by bufferedPoll to process the URCs - which are all readable. - //bufferedPoll uses strtok - which does not like NULL characters. - //So let's make sure no NULLs end up in the backlog! - if (_saraResponseBacklogLength < _RXBuffSize) // Don't overflow the buffer - { - if (c == '\0') - _saraResponseBacklog[_saraResponseBacklogLength++] = '0'; // Change NULLs to ASCII Zeros - else - _saraResponseBacklog[_saraResponseBacklogLength++] = c; - } - } else { - yield(); + int bytesRead; + err = socketRead(socket, length, readDest, &bytesRead); + if (err != UBX_CELL_ERROR_SUCCESS) + { + free(readDest); + return err; } - } - if (_printDebug == true) - if ((printResponse = true) && (printedSomething)) - _debugPort->println(); - - pruneBacklog(); // Prune any incoming non-actionable URC's and responses/errors from the backlog - - if (found) - { - if ((true == _printAtDebug) && ((nullptr != responseDest) || (nullptr != expectedResponse))) { - _debugAtPort->print((nullptr != responseDest) ? responseDest : expectedResponse); - } - return error ? UBX_CELL_ERROR_ERROR : UBX_CELL_ERROR_SUCCESS; - } - else if (charsRead == 0) - { - return UBX_CELL_ERROR_NO_RESPONSE; - } - else - { - if ((true == _printAtDebug) && (nullptr != responseDest)) { - _debugAtPort->print(responseDest); + if (_socketReadCallback != nullptr) + { + String dataAsString = ""; // Create an empty string + // Copy the data from readDest into the String in a binary-compatible way + // Important Note: some implementations of concat, like the one on ESP32, are binary-compatible. + // But some, like SAMD, are not. They use strlen or strcpy internally - which don't like \0's. + // The only true binary-compatible solution is to use socketReadCallbackPlus... + for (int i = 0; i < bytesRead; i++) + dataAsString.concat(readDest[i]); + _socketReadCallback(socket, dataAsString); } - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } -} -// Send a custom command with an expected (potentially partial) response, store entire response -UBX_CELL_error_t UBX_CELL::sendCustomCommandWithResponse(const char *command, const char *expectedResponse, - char *responseDest, unsigned long commandTimeout, bool at) -{ - // Assume the user has allocated enough storage for any response. Set destSize to 32766. - return sendCommandWithResponse(command, expectedResponse, responseDest, commandTimeout, 32766, at); -} + if (_socketReadCallbackPlus != nullptr) + { + IPAddress dummyAddress = {0, 0, 0, 0}; + int dummyPort = 0; + _socketReadCallbackPlus(socket, (const char *)readDest, bytesRead, dummyAddress, dummyPort); + } -void UBX_CELL::sendCommand(const char *command, bool at) -{ - //Check for incoming serial data. Copy it into the backlog - - // Important note: - // On ESP32, Serial.available only provides an update every ~120 bytes during the reception of long messages: - // https://gitter.im/espressif/arduino-esp32?at=5e25d6370a1cf54144909c85 - // Be aware that if a long message is being received, the code below will timeout after _rxWindowMillis = 2 millis. - // At 115200 baud, hwAvailable takes ~120 * 10 / 115200 = 10.4 millis before it indicates that data is being received. - - unsigned long timeIn = millis(); - if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL - { - while (((millis() - timeIn) < _rxWindowMillis) && (_saraResponseBacklogLength < _RXBuffSize)) //May need to escape on newline? - { - if (hwAvailable() > 0) //hwAvailable can return -1 if the serial port is NULL - { - //_saraResponseBacklog is a global array that holds the backlog of any events - //that came in while waiting for response. To be processed later within bufferedPoll(). - //Note: the expectedResponse or expectedError will also be added to the backlog - //The backlog is only used by bufferedPoll to process the URCs - which are all readable. - //bufferedPoll uses strtok - which does not like NULL characters. - //So let's make sure no NULLs end up in the backlog! - char c = readChar(); - if (c == '\0') // Make sure no NULL characters end up in the backlog! Change them to ASCII Zeros - c = '0'; - _saraResponseBacklog[_saraResponseBacklogLength++] = c; - timeIn = millis(); - } else { - yield(); - } - } - } - - //Now send the command - if (at) - { - hwPrint(UBX_CELL_COMMAND_AT); - hwPrint(command); - hwPrint("\r\n"); - } - else - { - hwPrint(command); - } + free(readDest); + return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::parseSocketReadIndication(int socket, int length) +UBX_CELL_error_t UBX_CELL::parseSocketReadIndicationUDP(int socket, int length) { - UBX_CELL_error_t err; - char *readDest; - - if ((socket < 0) || (length < 0)) - { - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } + UBX_CELL_error_t err; + char *readDest; + IPAddress remoteAddress = {0, 0, 0, 0}; + int remotePort = 0; - // Return now if both callbacks pointers are nullptr - otherwise the data will be read and lost! - if ((_socketReadCallback == nullptr) && (_socketReadCallbackPlus == nullptr)) - return UBX_CELL_ERROR_INVALID; + if ((socket < 0) || (length < 0)) + { + return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; + } - readDest = ubx_cell_calloc_char(length + 1); - if (readDest == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + // Return now if both callbacks pointers are nullptr - otherwise the data will be read and lost! + if ((_socketReadCallback == nullptr) && (_socketReadCallbackPlus == nullptr)) + return UBX_CELL_ERROR_INVALID; - int bytesRead; - err = socketRead(socket, length, readDest, &bytesRead); - if (err != UBX_CELL_ERROR_SUCCESS) - { - free(readDest); - return err; - } - - if (_socketReadCallback != nullptr) - { - String dataAsString = ""; // Create an empty string - // Copy the data from readDest into the String in a binary-compatible way - // Important Note: some implementations of concat, like the one on ESP32, are binary-compatible. - // But some, like SAMD, are not. They use strlen or strcpy internally - which don't like \0's. - // The only true binary-compatible solution is to use socketReadCallbackPlus... - for (int i = 0; i < bytesRead; i++) - dataAsString.concat(readDest[i]); - _socketReadCallback(socket, dataAsString); - } - - if (_socketReadCallbackPlus != nullptr) - { - IPAddress dummyAddress = { 0, 0, 0, 0 }; - int dummyPort = 0; - _socketReadCallbackPlus(socket, (const char *)readDest, bytesRead, dummyAddress, dummyPort); - } - - free(readDest); - return UBX_CELL_ERROR_SUCCESS; -} + readDest = ubx_cell_calloc_char(length + 1); + if (readDest == nullptr) + { + return UBX_CELL_ERROR_OUT_OF_MEMORY; + } -UBX_CELL_error_t UBX_CELL::parseSocketReadIndicationUDP(int socket, int length) -{ - UBX_CELL_error_t err; - char *readDest; - IPAddress remoteAddress = { 0, 0, 0, 0 }; - int remotePort = 0; - - if ((socket < 0) || (length < 0)) - { - return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; - } - - // Return now if both callbacks pointers are nullptr - otherwise the data will be read and lost! - if ((_socketReadCallback == nullptr) && (_socketReadCallbackPlus == nullptr)) - return UBX_CELL_ERROR_INVALID; - - readDest = ubx_cell_calloc_char(length + 1); - if (readDest == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - int bytesRead; - err = socketReadUDP(socket, length, readDest, &remoteAddress, &remotePort, &bytesRead); - if (err != UBX_CELL_ERROR_SUCCESS) - { - free(readDest); - return err; - } + int bytesRead; + err = socketReadUDP(socket, length, readDest, &remoteAddress, &remotePort, &bytesRead); + if (err != UBX_CELL_ERROR_SUCCESS) + { + free(readDest); + return err; + } - if (_socketReadCallback != nullptr) - { - String dataAsString = ""; // Create an empty string - // Important Note: some implementations of concat, like the one on ESP32, are binary-compatible. - // But some, like SAMD, are not. They use strlen or strcpy internally - which don't like \0's. - // The only true binary-compatible solution is to use socketReadCallbackPlus... - for (int i = 0; i < bytesRead; i++) // Copy the data from readDest into the String in a binary-compatible way - dataAsString.concat(readDest[i]); - _socketReadCallback(socket, dataAsString); - } + if (_socketReadCallback != nullptr) + { + String dataAsString = ""; // Create an empty string + // Important Note: some implementations of concat, like the one on ESP32, are binary-compatible. + // But some, like SAMD, are not. They use strlen or strcpy internally - which don't like \0's. + // The only true binary-compatible solution is to use socketReadCallbackPlus... + for (int i = 0; i < bytesRead; i++) // Copy the data from readDest into the String in a binary-compatible way + dataAsString.concat(readDest[i]); + _socketReadCallback(socket, dataAsString); + } - if (_socketReadCallbackPlus != nullptr) - { - _socketReadCallbackPlus(socket, (const char *)readDest, bytesRead, remoteAddress, remotePort); - } + if (_socketReadCallbackPlus != nullptr) + { + _socketReadCallbackPlus(socket, (const char *)readDest, bytesRead, remoteAddress, remotePort); + } - free(readDest); - return UBX_CELL_ERROR_SUCCESS; + free(readDest); + return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, int socket, IPAddress remoteIP, unsigned int port) +UBX_CELL_error_t UBX_CELL::parseSocketListenIndication(int listeningSocket, IPAddress localIP, + unsigned int listeningPort, int socket, IPAddress remoteIP, + unsigned int port) { - _lastLocalIP = localIP; - _lastRemoteIP = remoteIP; + _lastLocalIP = localIP; + _lastRemoteIP = remoteIP; - if (_socketListenCallback != nullptr) - { - _socketListenCallback(listeningSocket, localIP, listeningPort, socket, remoteIP, port); - } + if (_socketListenCallback != nullptr) + { + _socketListenCallback(listeningSocket, localIP, listeningPort, socket, remoteIP, port); + } - return UBX_CELL_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } UBX_CELL_error_t UBX_CELL::parseSocketCloseIndication(String *closeIndication) { - int search; - int socket; + int search; + int socket; - search = closeIndication->indexOf(UBX_CELL_CLOSE_SOCKET_URC); - search += strlen(UBX_CELL_CLOSE_SOCKET_URC); - while (closeIndication->charAt(search) == ' ') search ++; // skip spaces + search = closeIndication->indexOf(UBX_CELL_CLOSE_SOCKET_URC); + search += strlen(UBX_CELL_CLOSE_SOCKET_URC); + while (closeIndication->charAt(search) == ' ') + search++; // skip spaces - // Socket will be first integer, should be single-digit number between 0-6: - socket = closeIndication->substring(search, search + 1).toInt(); + // Socket will be first integer, should be single-digit number between 0-6: + socket = closeIndication->substring(search, search + 1).toInt(); - if (_socketCloseCallback != nullptr) - { - _socketCloseCallback(socket); - } + if (_socketCloseCallback != nullptr) + { + _socketCloseCallback(socket); + } - return UBX_CELL_ERROR_SUCCESS; + return UBX_CELL_ERROR_SUCCESS; } size_t UBX_CELL::hwPrint(const char *s) { - if ((true == _printAtDebug) && (nullptr != s)) { - _debugAtPort->print(s); - } - if (_hardSerial != nullptr) - { - return _hardSerial->print(s); - } + if ((true == _printAtDebug) && (nullptr != s)) + { + _debugAtPort->print(s); + } + if (_hardSerial != nullptr) + { + return _hardSerial->print(s); + } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - else if (_softSerial != nullptr) - { - return _softSerial->print(s); - } + else if (_softSerial != nullptr) + { + return _softSerial->print(s); + } #endif - return (size_t)0; + return (size_t)0; } size_t UBX_CELL::hwWriteData(const char *buff, int len) { - if ((true == _printAtDebug) && (nullptr != buff) && (0 < len) ) { - _debugAtPort->write(buff,len); - } - if (_hardSerial != nullptr) - { - return _hardSerial->write((const uint8_t *)buff, len); - } + if ((true == _printAtDebug) && (nullptr != buff) && (0 < len)) + { + _debugAtPort->write(buff, len); + } + if (_hardSerial != nullptr) + { + return _hardSerial->write((const uint8_t *)buff, len); + } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - else if (_softSerial != nullptr) - { - return _softSerial->write((const uint8_t *)buff, len); - } + else if (_softSerial != nullptr) + { + return _softSerial->write((const uint8_t *)buff, len); + } #endif - return (size_t)0; + return (size_t)0; } size_t UBX_CELL::hwWrite(const char c) { - if (true == _printAtDebug) { - _debugAtPort->write(c); - } - if (_hardSerial != nullptr) - { - return _hardSerial->write(c); - } + if (true == _printAtDebug) + { + _debugAtPort->write(c); + } + if (_hardSerial != nullptr) + { + return _hardSerial->write(c); + } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - else if (_softSerial != nullptr) - { - return _softSerial->write(c); - } + else if (_softSerial != nullptr) + { + return _softSerial->write(c); + } #endif - return (size_t)0; + return (size_t)0; } int UBX_CELL::readAvailable(char *inString) { - int len = 0; + int len = 0; - if (_hardSerial != nullptr) - { - while (_hardSerial->available()) - { - char c = (char)_hardSerial->read(); - if (inString != nullptr) - { - inString[len++] = c; - } - } - if (inString != nullptr) + if (_hardSerial != nullptr) { - inString[len] = 0; + while (_hardSerial->available()) + { + char c = (char)_hardSerial->read(); + if (inString != nullptr) + { + inString[len++] = c; + } + } + if (inString != nullptr) + { + inString[len] = 0; + } + // if (_printDebug == true) + // _debugPort->println(inString); } - //if (_printDebug == true) - // _debugPort->println(inString); - } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - else if (_softSerial != nullptr) - { - while (_softSerial->available()) - { - char c = (char)_softSerial->read(); - if (inString != nullptr) - { - inString[len++] = c; - } - } - if (inString != nullptr) + else if (_softSerial != nullptr) { - inString[len] = 0; + while (_softSerial->available()) + { + char c = (char)_softSerial->read(); + if (inString != nullptr) + { + inString[len++] = c; + } + } + if (inString != nullptr) + { + inString[len] = 0; + } } - } #endif - return len; + return len; } char UBX_CELL::readChar(void) { - char ret = 0; + char ret = 0; - if (_hardSerial != nullptr) - { - ret = (char)_hardSerial->read(); - } + if (_hardSerial != nullptr) + { + ret = (char)_hardSerial->read(); + } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - else if (_softSerial != nullptr) - { - ret = (char)_softSerial->read(); - } + else if (_softSerial != nullptr) + { + ret = (char)_softSerial->read(); + } #endif - return ret; + return ret; } int UBX_CELL::hwAvailable(void) { - if (_hardSerial != nullptr) - { - return _hardSerial->available(); - } + if (_hardSerial != nullptr) + { + return _hardSerial->available(); + } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - else if (_softSerial != nullptr) - { - return _softSerial->available(); - } + else if (_softSerial != nullptr) + { + return _softSerial->available(); + } #endif - return -1; + return -1; } void UBX_CELL::beginSerial(unsigned long baud) { - delay(100); - if (_hardSerial != nullptr) - { - _hardSerial->end(); - _hardSerial->begin(baud); - } + delay(100); + if (_hardSerial != nullptr) + { + _hardSerial->end(); + _hardSerial->begin(baud); + } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - else if (_softSerial != nullptr) - { - _softSerial->end(); - _softSerial->begin(baud); - } + else if (_softSerial != nullptr) + { + _softSerial->end(); + _softSerial->begin(baud); + } #endif - delay(100); + delay(100); } void UBX_CELL::setTimeout(unsigned long timeout) { - if (_hardSerial != nullptr) - { - _hardSerial->setTimeout(timeout); - } + if (_hardSerial != nullptr) + { + _hardSerial->setTimeout(timeout); + } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - else if (_softSerial != nullptr) - { - _softSerial->setTimeout(timeout); - } + else if (_softSerial != nullptr) + { + _softSerial->setTimeout(timeout); + } #endif } bool UBX_CELL::find(char *target) { - bool found = false; - if (_hardSerial != nullptr) - { - found = _hardSerial->find(target); - } + bool found = false; + if (_hardSerial != nullptr) + { + found = _hardSerial->find(target); + } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - else if (_softSerial != nullptr) - { - found = _softSerial->find(target); - } + else if (_softSerial != nullptr) + { + found = _softSerial->find(target); + } #endif - return found; + return found; } UBX_CELL_error_t UBX_CELL::autobaud(unsigned long desiredBaud) { - UBX_CELL_error_t err = UBX_CELL_ERROR_INVALID; - int b = 0; + UBX_CELL_error_t err = UBX_CELL_ERROR_INVALID; + int b = 0; - while ((err != UBX_CELL_ERROR_SUCCESS) && (b < NUM_SUPPORTED_BAUD)) - { - beginSerial(UBX_CELL_SUPPORTED_BAUD[b++]); - setBaud(desiredBaud); - beginSerial(desiredBaud); - err = at(); - } - if (err == UBX_CELL_ERROR_SUCCESS) - { - beginSerial(desiredBaud); - } - return err; + while ((err != UBX_CELL_ERROR_SUCCESS) && (b < NUM_SUPPORTED_BAUD)) + { + beginSerial(UBX_CELL_SUPPORTED_BAUD[b++]); + setBaud(desiredBaud); + beginSerial(desiredBaud); + err = at(); + } + if (err == UBX_CELL_ERROR_SUCCESS) + { + beginSerial(desiredBaud); + } + return err; } char *UBX_CELL::ubx_cell_calloc_char(size_t num) { - return (char *)calloc(num, sizeof(char)); + return (char *)calloc(num, sizeof(char)); } -//This prunes the backlog of non-actionable events. If new actionable events are added, you must modify the if statement. +// This prunes the backlog of non-actionable events. If new actionable events are added, you must modify the if +// statement. void UBX_CELL::pruneBacklog() { - char *event; - - // if (_printDebug == true) - // { - // if (_saraResponseBacklogLength > 0) //Handy for debugging new parsing. - // { - // _debugPort->println(F("pruneBacklog: before pruning, backlog was:")); - // _debugPort->println(_saraResponseBacklog); - // _debugPort->println(F("pruneBacklog: end of backlog")); - // } - // else - // { - // _debugPort->println(F("pruneBacklog: backlog was empty")); - // } - // } - - memset(_pruneBuffer, 0, _RXBuffSize); // Clear the _pruneBuffer - - _saraResponseBacklogLength = 0; // Zero the backlog length - - char *preservedEvent; - event = strtok_r(_saraResponseBacklog, "\r\n", &preservedEvent); // Look for an 'event' - something ending in \r\n - - while (event != nullptr) //If event is actionable, add it to pruneBuffer. - { - // These are the events we want to keep so they can be processed by poll / bufferedPoll - for(auto urcString : _urcStrings) - { - if(strstr(event, urcString) != nullptr) - { - strcat(_pruneBuffer, event); // The URCs are all readable text so using strcat is OK - strcat(_pruneBuffer, "\r\n"); // strtok blows away delimiter, but we want that for later. - _saraResponseBacklogLength += strlen(event) + 2; // Add the length of this event to _saraResponseBacklogLength - break; // No need to check any other events - } - } - - event = strtok_r(nullptr, "\r\n", &preservedEvent); // Walk though any remaining events - } - - memset(_saraResponseBacklog, 0, _RXBuffSize); //Clear out backlog buffer. - memcpy(_saraResponseBacklog, _pruneBuffer, _saraResponseBacklogLength); //Copy the pruned buffer back into the backlog - - // if (_printDebug == true) - // { - // if (_saraResponseBacklogLength > 0) //Handy for debugging new parsing. - // { - // _debugPort->println(F("pruneBacklog: after pruning, backlog is now:")); - // _debugPort->println(_saraResponseBacklog); - // _debugPort->println(F("pruneBacklog: end of backlog")); - // } - // else - // { - // _debugPort->println(F("pruneBacklog: backlog is now empty")); - // } - // } + char *event; + + // if (_printDebug == true) + // { + // if (_saraResponseBacklogLength > 0) //Handy for debugging new parsing. + // { + // _debugPort->println(F("pruneBacklog: before pruning, backlog was:")); + // _debugPort->println(_saraResponseBacklog); + // _debugPort->println(F("pruneBacklog: end of backlog")); + // } + // else + // { + // _debugPort->println(F("pruneBacklog: backlog was empty")); + // } + // } + + memset(_pruneBuffer, 0, _RXBuffSize); // Clear the _pruneBuffer + + _saraResponseBacklogLength = 0; // Zero the backlog length + + char *preservedEvent; + event = strtok_r(_saraResponseBacklog, "\r\n", &preservedEvent); // Look for an 'event' - something ending in \r\n + + while (event != nullptr) // If event is actionable, add it to pruneBuffer. + { + // These are the events we want to keep so they can be processed by poll / bufferedPoll + for (auto urcString : _urcStrings) + { + if (strstr(event, urcString) != nullptr) + { + strcat(_pruneBuffer, event); // The URCs are all readable text so using strcat is OK + strcat(_pruneBuffer, "\r\n"); // strtok blows away delimiter, but we want that for later. + _saraResponseBacklogLength += + strlen(event) + 2; // Add the length of this event to _saraResponseBacklogLength + break; // No need to check any other events + } + } + + event = strtok_r(nullptr, "\r\n", &preservedEvent); // Walk though any remaining events + } + + memset(_saraResponseBacklog, 0, _RXBuffSize); // Clear out backlog buffer. + memcpy(_saraResponseBacklog, _pruneBuffer, + _saraResponseBacklogLength); // Copy the pruned buffer back into the backlog + + // if (_printDebug == true) + // { + // if (_saraResponseBacklogLength > 0) //Handy for debugging new parsing. + // { + // _debugPort->println(F("pruneBacklog: after pruning, backlog is now:")); + // _debugPort->println(_saraResponseBacklog); + // _debugPort->println(F("pruneBacklog: end of backlog")); + // } + // else + // { + // _debugPort->println(F("pruneBacklog: backlog is now empty")); + // } + // } } // GPS Helper Functions: // Read a source string until a delimiter is hit, store the result in destination -char *UBX_CELL::readDataUntil(char *destination, unsigned int destSize, - char *source, char delimiter) -{ - - char *strEnd; - size_t len; - - strEnd = strchr(source, delimiter); - - if (strEnd != nullptr) - { - len = strEnd - source; - memset(destination, 0, destSize); - memcpy(destination, source, len); - } - - return strEnd; -} - -bool UBX_CELL::parseGPRMCString(char *rmcString, PositionData *pos, - ClockData *clk, SpeedData *spd) -{ - char *ptr, *search; - unsigned long tTemp; - char tempData[TEMP_NMEA_DATA_SIZE]; - - // if (_printDebug == true) - // { - // _debugPort->println(F("parseGPRMCString: rmcString: ")); - // _debugPort->println(rmcString); - // } - - // Fast-forward test to first value: - ptr = strchr(rmcString, ','); - ptr++; // Move ptr past first comma - - // If the next character is another comma, there's no time data - // Find time: - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - // Next comma should be present and not the next position - if ((search != nullptr) && (search != ptr)) - { - pos->utc = atof(tempData); // Extract hhmmss.ss as float - tTemp = pos->utc; // Convert to unsigned long (discard the digits beyond the decimal point) - clk->time.ms = ((unsigned int)(pos->utc * 100)) % 100; // Extract the milliseconds - clk->time.hour = tTemp / 10000; - tTemp -= ((unsigned long)clk->time.hour * 10000); - clk->time.minute = tTemp / 100; - tTemp -= ((unsigned long)clk->time.minute * 100); - clk->time.second = tTemp; - } - else - { - pos->utc = 0.0; - clk->time.hour = 0; - clk->time.minute = 0; - clk->time.second = 0; - } - ptr = search + 1; // Move pointer to next value - - // Find status character: - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - // Should be a single character: V = Data invalid, A = Data valid - if ((search != nullptr) && (search == ptr + 1)) - { - pos->status = *ptr; // Assign char at ptr to status - } - else - { - pos->status = 'X'; // Made up very bad status - } - ptr = search + 1; - - // Find latitude: - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - if ((search != nullptr) && (search != ptr)) - { - pos->lat = atof(tempData); // Extract ddmm.mmmmm as float - unsigned long lat_deg = pos->lat / 100; // Extract the degrees - pos->lat -= (float)lat_deg * 100.0; // Subtract the degrees leaving only the minutes - pos->lat /= 60.0; // Convert minutes into degrees - pos->lat += (float)lat_deg; // Finally add the degrees back on again - } - else - { - pos->lat = 0.0; - } - ptr = search + 1; - - // Find latitude hemishpere - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - if ((search != nullptr) && (search == ptr + 1)) - { - if (*ptr == 'S') // Is the latitude South - pos->lat *= -1.0; // Make lat negative - } - ptr = search + 1; - - // Find longitude: - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - if ((search != nullptr) && (search != ptr)) - { - pos->lon = atof(tempData); // Extract dddmm.mmmmm as float - unsigned long lon_deg = pos->lon / 100; // Extract the degrees - pos->lon -= (float)lon_deg * 100.0; // Subtract the degrees leaving only the minutes - pos->lon /= 60.0; // Convert minutes into degrees - pos->lon += (float)lon_deg; // Finally add the degrees back on again - } - else - { - pos->lon = 0.0; - } - ptr = search + 1; - - // Find longitude hemishpere - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - if ((search != nullptr) && (search == ptr + 1)) - { - if (*ptr == 'W') // Is the longitude West - pos->lon *= -1.0; // Make lon negative - } - ptr = search + 1; - - // Find speed - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - if ((search != nullptr) && (search != ptr)) - { - spd->speed = atof(tempData); // Extract speed over ground in knots - spd->speed *= 0.514444; // Convert to m/s - } - else - { - spd->speed = 0.0; - } - ptr = search + 1; - - // Find course over ground - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - if ((search != nullptr) && (search != ptr)) - { - spd->cog = atof(tempData); - } - else - { - spd->cog = 0.0; - } - ptr = search + 1; - - // Find date - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - if ((search != nullptr) && (search != ptr)) - { - tTemp = atol(tempData); - clk->date.day = tTemp / 10000; - tTemp -= ((unsigned long)clk->date.day * 10000); - clk->date.month = tTemp / 100; - tTemp -= ((unsigned long)clk->date.month * 100); - clk->date.year = tTemp; - } - else - { - clk->date.day = 0; - clk->date.month = 0; - clk->date.year = 0; - } - ptr = search + 1; - - // Find magnetic variation in degrees: - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - if ((search != nullptr) && (search != ptr)) - { - spd->magVar = atof(tempData); - } - else - { - spd->magVar = 0.0; - } - ptr = search + 1; - - // Find magnetic variation direction - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); - if ((search != nullptr) && (search == ptr + 1)) - { - if (*ptr == 'W') // Is the magnetic variation West - spd->magVar *= -1.0; // Make magnetic variation negative - } - ptr = search + 1; - - // Find position system mode - // Possible values for posMode: N = No fix, E = Estimated/Dead reckoning fix, A = Autonomous GNSS fix, - // D = Differential GNSS fix, F = RTK float, R = RTK fixed - search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, '*'); - if ((search != nullptr) && (search = ptr + 1)) - { - pos->mode = *ptr; - } - else - { - pos->mode = 'X'; - } - ptr = search + 1; - - if (pos->status == 'A') - { - return true; - } - return false; +char *UBX_CELL::readDataUntil(char *destination, unsigned int destSize, char *source, char delimiter) +{ + + char *strEnd; + size_t len; + + strEnd = strchr(source, delimiter); + + if (strEnd != nullptr) + { + len = strEnd - source; + memset(destination, 0, destSize); + memcpy(destination, source, len); + } + + return strEnd; +} + +bool UBX_CELL::parseGPRMCString(char *rmcString, PositionData *pos, ClockData *clk, SpeedData *spd) +{ + char *ptr, *search; + unsigned long tTemp; + char tempData[TEMP_NMEA_DATA_SIZE]; + + // if (_printDebug == true) + // { + // _debugPort->println(F("parseGPRMCString: rmcString: ")); + // _debugPort->println(rmcString); + // } + + // Fast-forward test to first value: + ptr = strchr(rmcString, ','); + ptr++; // Move ptr past first comma + + // If the next character is another comma, there's no time data + // Find time: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + // Next comma should be present and not the next position + if ((search != nullptr) && (search != ptr)) + { + pos->utc = atof(tempData); // Extract hhmmss.ss as float + tTemp = pos->utc; // Convert to unsigned long (discard the digits beyond the decimal point) + clk->time.ms = ((unsigned int)(pos->utc * 100)) % 100; // Extract the milliseconds + clk->time.hour = tTemp / 10000; + tTemp -= ((unsigned long)clk->time.hour * 10000); + clk->time.minute = tTemp / 100; + tTemp -= ((unsigned long)clk->time.minute * 100); + clk->time.second = tTemp; + } + else + { + pos->utc = 0.0; + clk->time.hour = 0; + clk->time.minute = 0; + clk->time.second = 0; + } + ptr = search + 1; // Move pointer to next value + + // Find status character: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + // Should be a single character: V = Data invalid, A = Data valid + if ((search != nullptr) && (search == ptr + 1)) + { + pos->status = *ptr; // Assign char at ptr to status + } + else + { + pos->status = 'X'; // Made up very bad status + } + ptr = search + 1; + + // Find latitude: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + pos->lat = atof(tempData); // Extract ddmm.mmmmm as float + unsigned long lat_deg = pos->lat / 100; // Extract the degrees + pos->lat -= (float)lat_deg * 100.0; // Subtract the degrees leaving only the minutes + pos->lat /= 60.0; // Convert minutes into degrees + pos->lat += (float)lat_deg; // Finally add the degrees back on again + } + else + { + pos->lat = 0.0; + } + ptr = search + 1; + + // Find latitude hemishpere + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search == ptr + 1)) + { + if (*ptr == 'S') // Is the latitude South + pos->lat *= -1.0; // Make lat negative + } + ptr = search + 1; + + // Find longitude: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + pos->lon = atof(tempData); // Extract dddmm.mmmmm as float + unsigned long lon_deg = pos->lon / 100; // Extract the degrees + pos->lon -= (float)lon_deg * 100.0; // Subtract the degrees leaving only the minutes + pos->lon /= 60.0; // Convert minutes into degrees + pos->lon += (float)lon_deg; // Finally add the degrees back on again + } + else + { + pos->lon = 0.0; + } + ptr = search + 1; + + // Find longitude hemishpere + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search == ptr + 1)) + { + if (*ptr == 'W') // Is the longitude West + pos->lon *= -1.0; // Make lon negative + } + ptr = search + 1; + + // Find speed + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + spd->speed = atof(tempData); // Extract speed over ground in knots + spd->speed *= 0.514444; // Convert to m/s + } + else + { + spd->speed = 0.0; + } + ptr = search + 1; + + // Find course over ground + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + spd->cog = atof(tempData); + } + else + { + spd->cog = 0.0; + } + ptr = search + 1; + + // Find date + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + tTemp = atol(tempData); + clk->date.day = tTemp / 10000; + tTemp -= ((unsigned long)clk->date.day * 10000); + clk->date.month = tTemp / 100; + tTemp -= ((unsigned long)clk->date.month * 100); + clk->date.year = tTemp; + } + else + { + clk->date.day = 0; + clk->date.month = 0; + clk->date.year = 0; + } + ptr = search + 1; + + // Find magnetic variation in degrees: + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search != ptr)) + { + spd->magVar = atof(tempData); + } + else + { + spd->magVar = 0.0; + } + ptr = search + 1; + + // Find magnetic variation direction + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, ','); + if ((search != nullptr) && (search == ptr + 1)) + { + if (*ptr == 'W') // Is the magnetic variation West + spd->magVar *= -1.0; // Make magnetic variation negative + } + ptr = search + 1; + + // Find position system mode + // Possible values for posMode: N = No fix, E = Estimated/Dead reckoning fix, A = Autonomous GNSS fix, + // D = Differential GNSS fix, F = RTK float, R = RTK fixed + search = readDataUntil(tempData, TEMP_NMEA_DATA_SIZE, ptr, '*'); + if ((search != nullptr) && (search = ptr + 1)) + { + pos->mode = *ptr; + } + else + { + pos->mode = 'X'; + } + ptr = search + 1; + + if (pos->status == 'A') + { + return true; + } + return false; } diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index c3540d8..f0a21a5 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -1,7 +1,6 @@ /* - Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod Asset Tracker - By: Paul Clark - October 19th 2020 + Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod + Asset Tracker By: Paul Clark October 19th 2020 Based extensively on the: Arduino Library for the SparkFun LTE CAT M1/NB-IoT Shield - SARA-R4 @@ -23,22 +22,22 @@ #include "WProgram.h" #endif -#ifdef ARDUINO_ARCH_AVR // Arduino AVR boards (Uno, Pro Micro, etc.) +#ifdef ARDUINO_ARCH_AVR // Arduino AVR boards (Uno, Pro Micro, etc.) #define UBX_CELL_SOFTWARE_SERIAL_ENABLED // Enable software serial #endif -#ifdef ARDUINO_ARCH_SAMD // Arduino SAMD boards (SAMD21, etc.) +#ifdef ARDUINO_ARCH_SAMD // Arduino SAMD boards (SAMD21, etc.) #define UBX_CELL_SOFTWARE_SERIAL_ENABLEDx // Disable software serial #endif -#ifdef ARDUINO_ARCH_APOLLO3 // Arduino Apollo boards (Artemis module, RedBoard Artemis, etc) +#ifdef ARDUINO_ARCH_APOLLO3 // Arduino Apollo boards (Artemis module, RedBoard Artemis, etc) #define UBX_CELL_SOFTWARE_SERIAL_ENABLEDx // Disable software serial (no longer supported with v2 of Apollo3) // Note: paulvha has provided software serial support for v2 of the Apollo3 / Artemis core. // Further details are available at: // https://github.com/paulvha/apollo3/tree/master/SoftwareSerial #endif -#ifdef ARDUINO_ARCH_STM32 // STM32 based boards (Disco, Nucleo, etc) +#ifdef ARDUINO_ARCH_STM32 // STM32 based boards (Disco, Nucleo, etc) #define UBX_CELL_SOFTWARE_SERIAL_ENABLED // Enable software serial #endif @@ -84,8 +83,9 @@ #define UBX_CELL_3_MIN_TIMEOUT 180000 #define UBX_CELL_SET_BAUD_TIMEOUT 500 #define UBX_CELL_POWER_OFF_PULSE_PERIOD 3200 // Hold PWR_ON low for this long to power the module off -#define UBX_CELL_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) -#define UBX_CELL_RESET_PULSE_PERIOD 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) +#define UBX_CELL_POWER_ON_PULSE_PERIOD 100 // Hold PWR_ON low for this long to power the module on (SARA-R510M8S) +#define UBX_CELL_RESET_PULSE_PERIOD \ + 23000 // Used to perform an abrupt emergency hardware shutdown. 23 seconds... (Yes, really!) #define UBX_CELL_POWER_OFF_TIMEOUT 40000 // Datasheet says 40 seconds... #define UBX_CELL_IP_CONNECT_TIMEOUT 130000 #define UBX_CELL_POLL_DELAY 1 @@ -93,122 +93,124 @@ // ## Suported AT Commands // ### General -const char* const UBX_CELL_COMMAND_AT = "AT"; // AT "Test" -const char* const UBX_CELL_COMMAND_ECHO = "E"; // Local Echo -const char* const UBX_CELL_COMMAND_MANU_ID = "+CGMI"; // Manufacturer identification -const char* const UBX_CELL_COMMAND_MODEL_ID = "+CGMM"; // Model identification -const char* const UBX_CELL_COMMAND_FW_VER_ID = "+CGMR"; // Firmware version identification -const char* const UBX_CELL_COMMAND_SERIAL_NO = "+CGSN"; // Product serial number -const char* const UBX_CELL_COMMAND_IMEI = "+GSN"; // IMEI identification -const char* const UBX_CELL_COMMAND_IMSI = "+CIMI"; // IMSI identification -const char* const UBX_CELL_COMMAND_CCID = "+CCID"; // SIM CCID -const char* const UBX_CELL_COMMAND_REQ_CAP = "+GCAP"; // Request capabilities list +const char *const UBX_CELL_COMMAND_AT = "AT"; // AT "Test" +const char *const UBX_CELL_COMMAND_ECHO = "E"; // Local Echo +const char *const UBX_CELL_COMMAND_MANU_ID = "+CGMI"; // Manufacturer identification +const char *const UBX_CELL_COMMAND_MODEL_ID = "+CGMM"; // Model identification +const char *const UBX_CELL_COMMAND_FW_VER_ID = "+CGMR"; // Firmware version identification +const char *const UBX_CELL_COMMAND_SERIAL_NO = "+CGSN"; // Product serial number +const char *const UBX_CELL_COMMAND_IMEI = "+GSN"; // IMEI identification +const char *const UBX_CELL_COMMAND_IMSI = "+CIMI"; // IMSI identification +const char *const UBX_CELL_COMMAND_CCID = "+CCID"; // SIM CCID +const char *const UBX_CELL_COMMAND_REQ_CAP = "+GCAP"; // Request capabilities list // ### Control and status -const char* const UBX_CELL_COMMAND_POWER_OFF = "+CPWROFF"; // Module switch off -const char* const UBX_CELL_COMMAND_FUNC = "+CFUN"; // Functionality (reset, etc.) -const char* const UBX_CELL_COMMAND_CLOCK = "+CCLK"; // Real-time clock -const char* const UBX_CELL_COMMAND_AUTO_TZ = "+CTZU"; // Automatic time zone update -const char* const UBX_CELL_COMMAND_TZ_REPORT = "+CTZR"; // Time zone reporting +const char *const UBX_CELL_COMMAND_POWER_OFF = "+CPWROFF"; // Module switch off +const char *const UBX_CELL_COMMAND_FUNC = "+CFUN"; // Functionality (reset, etc.) +const char *const UBX_CELL_COMMAND_CLOCK = "+CCLK"; // Real-time clock +const char *const UBX_CELL_COMMAND_AUTO_TZ = "+CTZU"; // Automatic time zone update +const char *const UBX_CELL_COMMAND_TZ_REPORT = "+CTZR"; // Time zone reporting // ### Network service -const char* const UBX_CELL_COMMAND_CNUM = "+CNUM"; // Subscriber number -const char* const UBX_CELL_SIGNAL_QUALITY = "+CSQ"; -const char* const UBX_CELL_EXT_SIGNAL_QUALITY = "+CESQ"; -const char* const UBX_CELL_OPERATOR_SELECTION = "+COPS"; -const char* const UBX_CELL_REGISTRATION_STATUS = "+CREG"; -const char* const UBX_CELL_EPSREGISTRATION_STATUS = "+CEREG"; -const char* const UBX_CELL_READ_OPERATOR_NAMES = "+COPN"; -const char* const UBX_CELL_COMMAND_MNO = "+UMNOPROF"; // MNO (mobile network operator) Profile +const char *const UBX_CELL_COMMAND_CNUM = "+CNUM"; // Subscriber number +const char *const UBX_CELL_SIGNAL_QUALITY = "+CSQ"; +const char *const UBX_CELL_EXT_SIGNAL_QUALITY = "+CESQ"; +const char *const UBX_CELL_OPERATOR_SELECTION = "+COPS"; +const char *const UBX_CELL_REGISTRATION_STATUS = "+CREG"; +const char *const UBX_CELL_EPSREGISTRATION_STATUS = "+CEREG"; +const char *const UBX_CELL_READ_OPERATOR_NAMES = "+COPN"; +const char *const UBX_CELL_COMMAND_MNO = "+UMNOPROF"; // MNO (mobile network operator) Profile // ### SIM -const char* const UBX_CELL_SIM_STATE = "+USIMSTAT"; -const char* const UBX_CELL_COMMAND_SIMPIN = "+CPIN"; // SIM PIN +const char *const UBX_CELL_SIM_STATE = "+USIMSTAT"; +const char *const UBX_CELL_COMMAND_SIMPIN = "+CPIN"; // SIM PIN // ### SMS -const char* const UBX_CELL_MESSAGE_FORMAT = "+CMGF"; // Set SMS message format -const char* const UBX_CELL_SEND_TEXT = "+CMGS"; // Send SMS message -const char* const UBX_CELL_NEW_MESSAGE_IND = "+CNMI"; // New [SMS] message indication -const char* const UBX_CELL_PREF_MESSAGE_STORE = "+CPMS"; // Preferred message storage -const char* const UBX_CELL_READ_TEXT_MESSAGE = "+CMGR"; // Read message -const char* const UBX_CELL_DELETE_MESSAGE = "+CMGD"; // Delete message +const char *const UBX_CELL_MESSAGE_FORMAT = "+CMGF"; // Set SMS message format +const char *const UBX_CELL_SEND_TEXT = "+CMGS"; // Send SMS message +const char *const UBX_CELL_NEW_MESSAGE_IND = "+CNMI"; // New [SMS] message indication +const char *const UBX_CELL_PREF_MESSAGE_STORE = "+CPMS"; // Preferred message storage +const char *const UBX_CELL_READ_TEXT_MESSAGE = "+CMGR"; // Read message +const char *const UBX_CELL_DELETE_MESSAGE = "+CMGD"; // Delete message // V24 control and V25ter (UART interface) -const char* const UBX_CELL_FLOW_CONTROL = "&K"; // Flow control -const char* const UBX_CELL_COMMAND_BAUD = "+IPR"; // Baud rate +const char *const UBX_CELL_FLOW_CONTROL = "&K"; // Flow control +const char *const UBX_CELL_COMMAND_BAUD = "+IPR"; // Baud rate // ### Packet switched data services -const char* const UBX_CELL_MESSAGE_PDP_DEF = "+CGDCONT"; // Packet switched Data Profile context definition -const char* const UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE = "+CGACT"; // Activates or deactivates the specified PDP context -const char* const UBX_CELL_MESSAGE_ENTER_PPP = "D"; +const char *const UBX_CELL_MESSAGE_PDP_DEF = "+CGDCONT"; // Packet switched Data Profile context definition +const char *const UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE = + "+CGACT"; // Activates or deactivates the specified PDP context +const char *const UBX_CELL_MESSAGE_ENTER_PPP = "D"; // ### GPIO -const char* const UBX_CELL_COMMAND_GPIO = "+UGPIOC"; // GPIO Configuration +const char *const UBX_CELL_COMMAND_GPIO = "+UGPIOC"; // GPIO Configuration // ### IP -const char* const UBX_CELL_CREATE_SOCKET = "+USOCR"; // Create a new socket -const char* const UBX_CELL_CLOSE_SOCKET = "+USOCL"; // Close a socket -const char* const UBX_CELL_CONNECT_SOCKET = "+USOCO"; // Connect to server on socket -const char* const UBX_CELL_WRITE_SOCKET = "+USOWR"; // Write data to a socket -const char* const UBX_CELL_WRITE_UDP_SOCKET = "+USOST"; // Write data to a UDP socket -const char* const UBX_CELL_READ_SOCKET = "+USORD"; // Read from a socket -const char* const UBX_CELL_READ_UDP_SOCKET = "+USORF"; // Read UDP data from a socket -const char* const UBX_CELL_LISTEN_SOCKET = "+USOLI"; // Listen for connection on socket -const char* const UBX_CELL_GET_ERROR = "+USOER"; // Get last socket error. -const char* const UBX_CELL_SOCKET_DIRECT_LINK = "+USODL"; // Set socket in Direct Link mode -const char* const UBX_CELL_SOCKET_CONTROL = "+USOCTL"; // Query the socket parameters -const char* const UBX_CELL_UD_CONFIGURATION = "+UDCONF"; // User Datagram Configuration +const char *const UBX_CELL_CREATE_SOCKET = "+USOCR"; // Create a new socket +const char *const UBX_CELL_CLOSE_SOCKET = "+USOCL"; // Close a socket +const char *const UBX_CELL_CONNECT_SOCKET = "+USOCO"; // Connect to server on socket +const char *const UBX_CELL_WRITE_SOCKET = "+USOWR"; // Write data to a socket +const char *const UBX_CELL_WRITE_UDP_SOCKET = "+USOST"; // Write data to a UDP socket +const char *const UBX_CELL_READ_SOCKET = "+USORD"; // Read from a socket +const char *const UBX_CELL_READ_UDP_SOCKET = "+USORF"; // Read UDP data from a socket +const char *const UBX_CELL_LISTEN_SOCKET = "+USOLI"; // Listen for connection on socket +const char *const UBX_CELL_GET_ERROR = "+USOER"; // Get last socket error. +const char *const UBX_CELL_SOCKET_DIRECT_LINK = "+USODL"; // Set socket in Direct Link mode +const char *const UBX_CELL_SOCKET_CONTROL = "+USOCTL"; // Query the socket parameters +const char *const UBX_CELL_UD_CONFIGURATION = "+UDCONF"; // User Datagram Configuration // ### Ping -const char* const UBX_CELL_PING_COMMAND = "+UPING"; // Ping +const char *const UBX_CELL_PING_COMMAND = "+UPING"; // Ping // ### HTTP -const char* const UBX_CELL_HTTP_PROFILE = "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined -const char* const UBX_CELL_HTTP_COMMAND = "+UHTTPC"; // Trigger the specified HTTP command -const char* const UBX_CELL_HTTP_PROTOCOL_ERROR = "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. - -const char* const UBX_CELL_MQTT_NVM = "+UMQTTNV"; -const char* const UBX_CELL_MQTT_PROFILE = "+UMQTT"; -const char* const UBX_CELL_MQTT_COMMAND = "+UMQTTC"; -const char* const UBX_CELL_MQTT_PROTOCOL_ERROR = "+UMQTTER"; +const char *const UBX_CELL_HTTP_PROFILE = + "+UHTTP"; // Configure the HTTP profile. Up to 4 different profiles can be defined +const char *const UBX_CELL_HTTP_COMMAND = "+UHTTPC"; // Trigger the specified HTTP command +const char *const UBX_CELL_HTTP_PROTOCOL_ERROR = + "+UHTTPER"; // Retrieves the error class and code of the latest HTTP operation on the specified HTTP profile. + +const char *const UBX_CELL_MQTT_NVM = "+UMQTTNV"; +const char *const UBX_CELL_MQTT_PROFILE = "+UMQTT"; +const char *const UBX_CELL_MQTT_COMMAND = "+UMQTTC"; +const char *const UBX_CELL_MQTT_PROTOCOL_ERROR = "+UMQTTER"; // ### FTP -const char* const UBX_CELL_FTP_PROFILE = "+UFTP"; -const char* const UBX_CELL_FTP_COMMAND = "+UFTPC"; -const char* const UBX_CELL_FTP_PROTOCOL_ERROR = "+UFTPER"; +const char *const UBX_CELL_FTP_PROFILE = "+UFTP"; +const char *const UBX_CELL_FTP_COMMAND = "+UFTPC"; +const char *const UBX_CELL_FTP_PROTOCOL_ERROR = "+UFTPER"; // ### GNSS -const char* const UBX_CELL_GNSS_POWER = "+UGPS"; // GNSS power management configuration -const char* const UBX_CELL_GNSS_ASSISTED_IND = "+UGIND"; // Assisted GNSS unsolicited indication -const char* const UBX_CELL_GNSS_REQUEST_LOCATION = "+ULOC"; // Ask for localization information -const char* const UBX_CELL_GNSS_GPRMC = "+UGRMC"; // Ask for localization information -const char* const UBX_CELL_GNSS_CONFIGURE_SENSOR = "+ULOCGNSS"; // Configure GNSS sensor -const char* const UBX_CELL_GNSS_CONFIGURE_LOCATION = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) -const char* const UBX_CELL_AIDING_SERVER_CONFIGURATION = "+UGSRV"; // Configure aiding server (CellLocate®) +const char *const UBX_CELL_GNSS_POWER = "+UGPS"; // GNSS power management configuration +const char *const UBX_CELL_GNSS_ASSISTED_IND = "+UGIND"; // Assisted GNSS unsolicited indication +const char *const UBX_CELL_GNSS_REQUEST_LOCATION = "+ULOC"; // Ask for localization information +const char *const UBX_CELL_GNSS_GPRMC = "+UGRMC"; // Ask for localization information +const char *const UBX_CELL_GNSS_CONFIGURE_SENSOR = "+ULOCGNSS"; // Configure GNSS sensor +const char *const UBX_CELL_GNSS_CONFIGURE_LOCATION = "+ULOCCELL"; // Configure cellular location sensor (CellLocate®) +const char *const UBX_CELL_AIDING_SERVER_CONFIGURATION = "+UGSRV"; // Configure aiding server (CellLocate®) // ### File System // TO DO: Add support for file tags. Default tag to USER -const char* const UBX_CELL_FILE_SYSTEM_READ_FILE = "+URDFILE"; // Read a file -const char* const UBX_CELL_FILE_SYSTEM_READ_BLOCK = "+URDBLOCK"; // Read a block from a file -const char* const UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE = "+UDWNFILE"; // Download a file into the module -const char* const UBX_CELL_FILE_SYSTEM_LIST_FILES = "+ULSTFILE"; // List of files, size of file, etc. -const char* const UBX_CELL_FILE_SYSTEM_DELETE_FILE = "+UDELFILE"; // Delete a file +const char *const UBX_CELL_FILE_SYSTEM_READ_FILE = "+URDFILE"; // Read a file +const char *const UBX_CELL_FILE_SYSTEM_READ_BLOCK = "+URDBLOCK"; // Read a block from a file +const char *const UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE = "+UDWNFILE"; // Download a file into the module +const char *const UBX_CELL_FILE_SYSTEM_LIST_FILES = "+ULSTFILE"; // List of files, size of file, etc. +const char *const UBX_CELL_FILE_SYSTEM_DELETE_FILE = "+UDELFILE"; // Delete a file // ### File System // TO DO: Add support for file tags. Default tag to USER -const char* const UBX_CELL_SEC_PROFILE = "+USECPRF"; -const char* const UBX_CELL_SEC_MANAGER = "+USECMNG"; - +const char *const UBX_CELL_SEC_PROFILE = "+USECPRF"; +const char *const UBX_CELL_SEC_MANAGER = "+USECMNG"; // ### URC strings -const char* const UBX_CELL_READ_SOCKET_URC = "+UUSORD:"; -const char* const UBX_CELL_READ_UDP_SOCKET_URC = "+UUSORF:"; -const char* const UBX_CELL_LISTEN_SOCKET_URC = "+UUSOLI:"; -const char* const UBX_CELL_CLOSE_SOCKET_URC = "+UUSOCL:"; -const char* const UBX_CELL_GNSS_REQUEST_LOCATION_URC = "+UULOC:"; -const char* const UBX_CELL_SIM_STATE_URC = "+UUSIMSTAT:"; -const char* const UBX_CELL_HTTP_COMMAND_URC = "+UUHTTPCR:"; -const char* const UBX_CELL_MQTT_COMMAND_URC = "+UUMQTTC:"; -const char* const UBX_CELL_PING_COMMAND_URC = "+UUPING:"; -const char* const UBX_CELL_REGISTRATION_STATUS_URC = "+CREG:"; -const char* const UBX_CELL_EPSREGISTRATION_STATUS_URC = "+CEREG:"; -const char* const UBX_CELL_FTP_COMMAND_URC = "+UUFTPCR:"; +const char *const UBX_CELL_READ_SOCKET_URC = "+UUSORD:"; +const char *const UBX_CELL_READ_UDP_SOCKET_URC = "+UUSORF:"; +const char *const UBX_CELL_LISTEN_SOCKET_URC = "+UUSOLI:"; +const char *const UBX_CELL_CLOSE_SOCKET_URC = "+UUSOCL:"; +const char *const UBX_CELL_GNSS_REQUEST_LOCATION_URC = "+UULOC:"; +const char *const UBX_CELL_SIM_STATE_URC = "+UUSIMSTAT:"; +const char *const UBX_CELL_HTTP_COMMAND_URC = "+UUHTTPCR:"; +const char *const UBX_CELL_MQTT_COMMAND_URC = "+UUMQTTC:"; +const char *const UBX_CELL_PING_COMMAND_URC = "+UUPING:"; +const char *const UBX_CELL_REGISTRATION_STATUS_URC = "+CREG:"; +const char *const UBX_CELL_EPSREGISTRATION_STATUS_URC = "+CEREG:"; +const char *const UBX_CELL_FTP_COMMAND_URC = "+UUFTPCR:"; // ### Response -const char* const UBX_CELL_RESPONSE_MORE = "\n>"; -const char* const UBX_CELL_RESPONSE_OK = "\nOK\r\n"; -const char* const UBX_CELL_RESPONSE_ERROR = "\nERROR\r\n"; -const char* const UBX_CELL_RESPONSE_CONNECT = "\r\nCONNECT\r\n"; +const char *const UBX_CELL_RESPONSE_MORE = "\n>"; +const char *const UBX_CELL_RESPONSE_OK = "\nOK\r\n"; +const char *const UBX_CELL_RESPONSE_ERROR = "\nERROR\r\n"; +const char *const UBX_CELL_RESPONSE_CONNECT = "\r\nCONNECT\r\n"; #define UBX_CELL_RESPONSE_OK_OR_ERROR nullptr // URC handler type definition -typedef std::function UBX_CELL_urc_handler_t; +typedef std::function UBX_CELL_urc_handler_t; // CTRL+Z and ESC ASCII codes for SMS message sends const char ASCII_CTRL_Z = 0x1A; @@ -227,22 +229,15 @@ const char ASCII_ESC = 0x1B; #define UBX_CELL_NUM_SOCKETS 6 #define NUM_SUPPORTED_BAUD 6 -const unsigned long UBX_CELL_SUPPORTED_BAUD[NUM_SUPPORTED_BAUD] = - { - 115200, - 9600, - 19200, - 38400, - 57600, - 230400}; +const unsigned long UBX_CELL_SUPPORTED_BAUD[NUM_SUPPORTED_BAUD] = {115200, 9600, 19200, 38400, 57600, 230400}; #define UBX_CELL_DEFAULT_BAUD_RATE 115200 // Flow control definitions for AT&K // Note: SW (XON/XOFF) flow control is not supported on the UBX_CELL typedef enum { - UBX_CELL_DISABLE_FLOW_CONTROL = 0, - UBX_CELL_ENABLE_FLOW_CONTROL = 3 + UBX_CELL_DISABLE_FLOW_CONTROL = 0, + UBX_CELL_ENABLE_FLOW_CONTROL = 3 } UBX_CELL_flow_control_t; // The standard Europe profile should be used as the basis for all other MNOs in Europe outside of Vodafone @@ -251,108 +246,109 @@ typedef enum // consult with the preferred network provider. typedef enum { - MNO_INVALID = -1, - MNO_SW_DEFAULT = 0, // Undefined / regulatory - MNO_SIM_ICCID = 1, - MNO_ATT = 2, // AT&T - MNO_VERIZON = 3, - MNO_TELSTRA = 4, - MNO_TMO = 5, // T-Mobile US - MNO_CT = 6, // China Telecom - MNO_SPRINT = 8, - MNO_VODAFONE = 19, - MNO_NTT_DOCOMO = 20, - MNO_TELUS = 21, - MNO_SOFTBANK = 28, - MNO_DT = 31, // Deutsche Telekom - MNO_US_CELLULAR = 32, - MNO_SKT = 39, - MNO_GLOBAL = 90, - MNO_STD_EUROPE = 100, - MNO_STD_EU_NOEPCO = 101 + MNO_INVALID = -1, + MNO_SW_DEFAULT = 0, // Undefined / regulatory + MNO_SIM_ICCID = 1, + MNO_ATT = 2, // AT&T + MNO_VERIZON = 3, + MNO_TELSTRA = 4, + MNO_TMO = 5, // T-Mobile US + MNO_CT = 6, // China Telecom + MNO_SPRINT = 8, + MNO_VODAFONE = 19, + MNO_NTT_DOCOMO = 20, + MNO_TELUS = 21, + MNO_SOFTBANK = 28, + MNO_DT = 31, // Deutsche Telekom + MNO_US_CELLULAR = 32, + MNO_SKT = 39, + MNO_GLOBAL = 90, + MNO_STD_EUROPE = 100, + MNO_STD_EU_NOEPCO = 101 } mobile_network_operator_t; typedef enum { - UBX_CELL_ERROR_INVALID = -1, // -1 - UBX_CELL_ERROR_SUCCESS = 0, // 0 - UBX_CELL_ERROR_OUT_OF_MEMORY, // 1 - UBX_CELL_ERROR_TIMEOUT, // 2 - UBX_CELL_ERROR_UNEXPECTED_PARAM, // 3 - UBX_CELL_ERROR_UNEXPECTED_RESPONSE, // 4 - UBX_CELL_ERROR_NO_RESPONSE, // 5 - UBX_CELL_ERROR_DEREGISTERED, // 6 - UBX_CELL_ERROR_ZERO_READ_LENGTH, // 7 - UBX_CELL_ERROR_ERROR // 8 + UBX_CELL_ERROR_INVALID = -1, // -1 + UBX_CELL_ERROR_SUCCESS = 0, // 0 + UBX_CELL_ERROR_OUT_OF_MEMORY, // 1 + UBX_CELL_ERROR_TIMEOUT, // 2 + UBX_CELL_ERROR_UNEXPECTED_PARAM, // 3 + UBX_CELL_ERROR_UNEXPECTED_RESPONSE, // 4 + UBX_CELL_ERROR_NO_RESPONSE, // 5 + UBX_CELL_ERROR_DEREGISTERED, // 6 + UBX_CELL_ERROR_ZERO_READ_LENGTH, // 7 + UBX_CELL_ERROR_ERROR // 8 } UBX_CELL_error_t; #define UBX_CELL_SUCCESS UBX_CELL_ERROR_SUCCESS typedef enum { - UBX_CELL_REGISTRATION_INVALID = -1, - UBX_CELL_REGISTRATION_NOT_REGISTERED = 0, - UBX_CELL_REGISTRATION_HOME = 1, - UBX_CELL_REGISTRATION_SEARCHING = 2, - UBX_CELL_REGISTRATION_DENIED = 3, - UBX_CELL_REGISTRATION_UNKNOWN = 4, - UBX_CELL_REGISTRATION_ROAMING = 5, - UBX_CELL_REGISTRATION_HOME_SMS_ONLY = 6, - UBX_CELL_REGISTRATION_ROAMING_SMS_ONLY = 7, - UBX_CELL_REGISTRATION_EMERGENCY_SERV_ONLY = 8, - UBX_CELL_REGISTRATION_HOME_CSFB_NOT_PREFERRED = 9, - UBX_CELL_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED = 10 + UBX_CELL_REGISTRATION_INVALID = -1, + UBX_CELL_REGISTRATION_NOT_REGISTERED = 0, + UBX_CELL_REGISTRATION_HOME = 1, + UBX_CELL_REGISTRATION_SEARCHING = 2, + UBX_CELL_REGISTRATION_DENIED = 3, + UBX_CELL_REGISTRATION_UNKNOWN = 4, + UBX_CELL_REGISTRATION_ROAMING = 5, + UBX_CELL_REGISTRATION_HOME_SMS_ONLY = 6, + UBX_CELL_REGISTRATION_ROAMING_SMS_ONLY = 7, + UBX_CELL_REGISTRATION_EMERGENCY_SERV_ONLY = 8, + UBX_CELL_REGISTRATION_HOME_CSFB_NOT_PREFERRED = 9, + UBX_CELL_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED = 10 } UBX_CELL_registration_status_t; struct DateData { - uint8_t day; - uint8_t month; - unsigned int year; + uint8_t day; + uint8_t month; + unsigned int year; }; struct TimeData { - uint8_t hour; - uint8_t minute; - uint8_t second; - unsigned int ms; - uint8_t tzh; - uint8_t tzm; + uint8_t hour; + uint8_t minute; + uint8_t second; + unsigned int ms; + uint8_t tzh; + uint8_t tzm; }; struct ClockData { - struct DateData date; - struct TimeData time; + struct DateData date; + struct TimeData time; }; struct PositionData { - float utc; - float lat; // Degrees: +/- 90 - float lon; // Degrees: +/- 180 - float alt; - char mode; - char status; + float utc; + float lat; // Degrees: +/- 90 + float lon; // Degrees: +/- 180 + float alt; + char mode; + char status; }; struct SpeedData { - float speed; // m/s - float cog; // Degrees - float magVar; // Degrees + float speed; // m/s + float cog; // Degrees + float magVar; // Degrees }; struct operator_stats { - uint8_t stat; - String shortOp; - String longOp; - unsigned long numOp; - uint8_t act; + uint8_t stat; + String shortOp; + String longOp; + unsigned long numOp; + uint8_t act; }; -typedef struct ext_signal_quality_ { +typedef struct ext_signal_quality_ +{ unsigned int rxlev; unsigned int ber; unsigned int rscp; @@ -363,68 +359,68 @@ typedef struct ext_signal_quality_ { typedef enum { - UBX_CELL_TCP = 6, - UBX_CELL_UDP = 17 + UBX_CELL_TCP = 6, + UBX_CELL_UDP = 17 } UBX_CELL_socket_protocol_t; typedef enum { - UBX_CELL_TCP_SOCKET_STATUS_INACTIVE, - UBX_CELL_TCP_SOCKET_STATUS_LISTEN, - UBX_CELL_TCP_SOCKET_STATUS_SYN_SENT, - UBX_CELL_TCP_SOCKET_STATUS_SYN_RCVD, - UBX_CELL_TCP_SOCKET_STATUS_ESTABLISHED, - UBX_CELL_TCP_SOCKET_STATUS_FIN_WAIT_1, - UBX_CELL_TCP_SOCKET_STATUS_FIN_WAIT_2, - UBX_CELL_TCP_SOCKET_STATUS_CLOSE_WAIT, - UBX_CELL_TCP_SOCKET_STATUS_CLOSING, - UBX_CELL_TCP_SOCKET_STATUS_LAST_ACK, - UBX_CELL_TCP_SOCKET_STATUS_TIME_WAIT + UBX_CELL_TCP_SOCKET_STATUS_INACTIVE, + UBX_CELL_TCP_SOCKET_STATUS_LISTEN, + UBX_CELL_TCP_SOCKET_STATUS_SYN_SENT, + UBX_CELL_TCP_SOCKET_STATUS_SYN_RCVD, + UBX_CELL_TCP_SOCKET_STATUS_ESTABLISHED, + UBX_CELL_TCP_SOCKET_STATUS_FIN_WAIT_1, + UBX_CELL_TCP_SOCKET_STATUS_FIN_WAIT_2, + UBX_CELL_TCP_SOCKET_STATUS_CLOSE_WAIT, + UBX_CELL_TCP_SOCKET_STATUS_CLOSING, + UBX_CELL_TCP_SOCKET_STATUS_LAST_ACK, + UBX_CELL_TCP_SOCKET_STATUS_TIME_WAIT } UBX_CELL_tcp_socket_status_t; typedef enum { - UBX_CELL_MESSAGE_FORMAT_PDU = 0, - UBX_CELL_MESSAGE_FORMAT_TEXT = 1 + UBX_CELL_MESSAGE_FORMAT_PDU = 0, + UBX_CELL_MESSAGE_FORMAT_TEXT = 1 } UBX_CELL_message_format_t; typedef enum { - UBX_CELL_UTIME_MODE_STOP = 0, - UBX_CELL_UTIME_MODE_PPS, - UBX_CELL_UTIME_MODE_ONE_SHOT, - UBX_CELL_UTIME_MODE_EXT_INT + UBX_CELL_UTIME_MODE_STOP = 0, + UBX_CELL_UTIME_MODE_PPS, + UBX_CELL_UTIME_MODE_ONE_SHOT, + UBX_CELL_UTIME_MODE_EXT_INT } UBX_CELL_utime_mode_t; typedef enum { - UBX_CELL_UTIME_SENSOR_NONE = 0, - UBX_CELL_UTIME_SENSOR_GNSS_LTE = 1, - UBX_CELL_UTIME_SENSOR_LTE + UBX_CELL_UTIME_SENSOR_NONE = 0, + UBX_CELL_UTIME_SENSOR_GNSS_LTE = 1, + UBX_CELL_UTIME_SENSOR_LTE } UBX_CELL_utime_sensor_t; typedef enum { - UBX_CELL_UTIME_URC_CONFIGURATION_DISABLED = 0, - UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED + UBX_CELL_UTIME_URC_CONFIGURATION_DISABLED = 0, + UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED } UBX_CELL_utime_urc_configuration_t; typedef enum { - UBX_CELL_SIM_NOT_PRESENT = 0, - UBX_CELL_SIM_PIN_NEEDED, - UBX_CELL_SIM_PIN_BLOCKED, - UBX_CELL_SIM_PUK_BLOCKED, - UBX_CELL_SIM_NOT_OPERATIONAL, - UBX_CELL_SIM_RESTRICTED, - UBX_CELL_SIM_OPERATIONAL - //UBX_CELL_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 - //UBX_CELL_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 - //UBX_CELL_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 - //UBX_CELL_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 - //UBX_CELL_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 - //UBX_CELL_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 - //UBX_CELL_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 + UBX_CELL_SIM_NOT_PRESENT = 0, + UBX_CELL_SIM_PIN_NEEDED, + UBX_CELL_SIM_PIN_BLOCKED, + UBX_CELL_SIM_PUK_BLOCKED, + UBX_CELL_SIM_NOT_OPERATIONAL, + UBX_CELL_SIM_RESTRICTED, + UBX_CELL_SIM_OPERATIONAL + // UBX_CELL_SIM_PHONEBOOK_READY, // Not reported by SARA-R5 + // UBX_CELL_SIM_USIM_PHONEBOOK_READY, // Not reported by SARA-R5 + // UBX_CELL_SIM_TOOLKIT_REFRESH_SUCCESSFUL, // Not reported by SARA-R5 + // UBX_CELL_SIM_TOOLKIT_REFRESH_UNSUCCESSFUL, // Not reported by SARA-R5 + // UBX_CELL_SIM_PPP_CONNECTION_ACTIVE, // Not reported by SARA-R5 + // UBX_CELL_SIM_VOICE_CALL_ACTIVE, // Not reported by SARA-R5 + // UBX_CELL_SIM_CSD_CALL_ACTIVE // Not reported by SARA-R5 } UBX_CELL_sim_states_t; #define UBX_CELL_NUM_PSD_PROFILES 6 // Number of supported PSD profiles @@ -433,37 +429,37 @@ typedef enum typedef enum { - UBX_CELL_HTTP_OP_CODE_SERVER_IP = 0, - UBX_CELL_HTTP_OP_CODE_SERVER_NAME, - UBX_CELL_HTTP_OP_CODE_USERNAME, - UBX_CELL_HTTP_OP_CODE_PASSWORD, - UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, - UBX_CELL_HTTP_OP_CODE_SERVER_PORT, - UBX_CELL_HTTP_OP_CODE_SECURE, - UBX_CELL_HTTP_OP_CODE_REQUEST_TIMEOUT, - UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS = 9 + UBX_CELL_HTTP_OP_CODE_SERVER_IP = 0, + UBX_CELL_HTTP_OP_CODE_SERVER_NAME, + UBX_CELL_HTTP_OP_CODE_USERNAME, + UBX_CELL_HTTP_OP_CODE_PASSWORD, + UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, + UBX_CELL_HTTP_OP_CODE_SERVER_PORT, + UBX_CELL_HTTP_OP_CODE_SECURE, + UBX_CELL_HTTP_OP_CODE_REQUEST_TIMEOUT, + UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS = 9 } UBX_CELL_http_op_codes_t; typedef enum { - UBX_CELL_HTTP_COMMAND_HEAD = 0, - UBX_CELL_HTTP_COMMAND_GET, - UBX_CELL_HTTP_COMMAND_DELETE, - UBX_CELL_HTTP_COMMAND_PUT, - UBX_CELL_HTTP_COMMAND_POST_FILE, - UBX_CELL_HTTP_COMMAND_POST_DATA, - UBX_CELL_HTTP_COMMAND_GET_FOTA = 100 + UBX_CELL_HTTP_COMMAND_HEAD = 0, + UBX_CELL_HTTP_COMMAND_GET, + UBX_CELL_HTTP_COMMAND_DELETE, + UBX_CELL_HTTP_COMMAND_PUT, + UBX_CELL_HTTP_COMMAND_POST_FILE, + UBX_CELL_HTTP_COMMAND_POST_DATA, + UBX_CELL_HTTP_COMMAND_GET_FOTA = 100 } UBX_CELL_http_commands_t; typedef enum { - UBX_CELL_HTTP_CONTENT_APPLICATION_X_WWW = 0, - UBX_CELL_HTTP_CONTENT_TEXT_PLAIN, - UBX_CELL_HTTP_CONTENT_APPLICATION_OCTET, - UBX_CELL_HTTP_CONTENT_MULTIPART_FORM, - UBX_CELL_HTTP_CONTENT_APPLICATION_JSON, - UBX_CELL_HTTP_CONTENT_APPLICATION_XML, - UBX_CELL_HTTP_CONTENT_USER_DEFINED + UBX_CELL_HTTP_CONTENT_APPLICATION_X_WWW = 0, + UBX_CELL_HTTP_CONTENT_TEXT_PLAIN, + UBX_CELL_HTTP_CONTENT_APPLICATION_OCTET, + UBX_CELL_HTTP_CONTENT_MULTIPART_FORM, + UBX_CELL_HTTP_CONTENT_APPLICATION_JSON, + UBX_CELL_HTTP_CONTENT_APPLICATION_XML, + UBX_CELL_HTTP_CONTENT_USER_DEFINED } UBX_CELL_http_content_types_t; typedef enum @@ -489,17 +485,17 @@ typedef enum typedef enum { - UBX_CELL_MQTT_COMMAND_INVALID = -1, - UBX_CELL_MQTT_COMMAND_LOGOUT = 0, - UBX_CELL_MQTT_COMMAND_LOGIN, - UBX_CELL_MQTT_COMMAND_PUBLISH, - UBX_CELL_MQTT_COMMAND_PUBLISHFILE, - UBX_CELL_MQTT_COMMAND_SUBSCRIBE, - UBX_CELL_MQTT_COMMAND_UNSUBSCRIBE, - UBX_CELL_MQTT_COMMAND_READ, - UBX_CELL_MQTT_COMMAND_RCVMSGFORMAT, - UBX_CELL_MQTT_COMMAND_PING, - UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, + UBX_CELL_MQTT_COMMAND_INVALID = -1, + UBX_CELL_MQTT_COMMAND_LOGOUT = 0, + UBX_CELL_MQTT_COMMAND_LOGIN, + UBX_CELL_MQTT_COMMAND_PUBLISH, + UBX_CELL_MQTT_COMMAND_PUBLISHFILE, + UBX_CELL_MQTT_COMMAND_SUBSCRIBE, + UBX_CELL_MQTT_COMMAND_UNSUBSCRIBE, + UBX_CELL_MQTT_COMMAND_READ, + UBX_CELL_MQTT_COMMAND_RCVMSGFORMAT, + UBX_CELL_MQTT_COMMAND_PING, + UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, } UBX_CELL_mqtt_command_opcode_t; constexpr uint16_t MAX_MQTT_HEX_MSG_LEN = 512; @@ -518,90 +514,90 @@ typedef enum typedef enum { - UBX_CELL_FTP_COMMAND_INVALID = -1, - UBX_CELL_FTP_COMMAND_LOGOUT = 0, - UBX_CELL_FTP_COMMAND_LOGIN, - UBX_CELL_FTP_COMMAND_DELETE_FILE, - UBX_CELL_FTP_COMMAND_RENAME_FILE, - UBX_CELL_FTP_COMMAND_GET_FILE, - UBX_CELL_FTP_COMMAND_PUT_FILE, - UBX_CELL_FTP_COMMAND_GET_FILE_DIRECT, - UBX_CELL_FTP_COMMAND_PUT_FILE_DIRECT, - UBX_CELL_FTP_COMMAND_CHANGE_DIR, - UBX_CELL_FTP_COMMAND_MKDIR = 10, - UBX_CELL_FTP_COMMAND_RMDIR, - UBX_CELL_FTP_COMMAND_DIR_INFO = 13, - UBX_CELL_FTP_COMMAND_LS, - UBX_CELL_FTP_COMMAND_GET_FOTA_FILE = 100 + UBX_CELL_FTP_COMMAND_INVALID = -1, + UBX_CELL_FTP_COMMAND_LOGOUT = 0, + UBX_CELL_FTP_COMMAND_LOGIN, + UBX_CELL_FTP_COMMAND_DELETE_FILE, + UBX_CELL_FTP_COMMAND_RENAME_FILE, + UBX_CELL_FTP_COMMAND_GET_FILE, + UBX_CELL_FTP_COMMAND_PUT_FILE, + UBX_CELL_FTP_COMMAND_GET_FILE_DIRECT, + UBX_CELL_FTP_COMMAND_PUT_FILE_DIRECT, + UBX_CELL_FTP_COMMAND_CHANGE_DIR, + UBX_CELL_FTP_COMMAND_MKDIR = 10, + UBX_CELL_FTP_COMMAND_RMDIR, + UBX_CELL_FTP_COMMAND_DIR_INFO = 13, + UBX_CELL_FTP_COMMAND_LS, + UBX_CELL_FTP_COMMAND_GET_FOTA_FILE = 100 } UBX_CELL_ftp_command_opcode_t; typedef enum { - UBX_CELL_PSD_CONFIG_PARAM_PROTOCOL = 0, - UBX_CELL_PSD_CONFIG_PARAM_APN, - //UBX_CELL_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 - //UBX_CELL_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 - UBX_CELL_PSD_CONFIG_PARAM_DNS1 = 4, - UBX_CELL_PSD_CONFIG_PARAM_DNS2, - //UBX_CELL_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 - //UBX_CELL_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 - //UBX_CELL_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 - //UBX_CELL_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 - UBX_CELL_PSD_CONFIG_PARAM_MAP_TO_CID = 100 + UBX_CELL_PSD_CONFIG_PARAM_PROTOCOL = 0, + UBX_CELL_PSD_CONFIG_PARAM_APN, + // UBX_CELL_PSD_CONFIG_PARAM_USERNAME, // Not allowed on SARA-R5 + // UBX_CELL_PSD_CONFIG_PARAM_PASSWORD, // Not allowed on SARA-R5 + UBX_CELL_PSD_CONFIG_PARAM_DNS1 = 4, + UBX_CELL_PSD_CONFIG_PARAM_DNS2, + // UBX_CELL_PSD_CONFIG_PARAM_AUTHENTICATION, // Not allowed on SARA-R5 + // UBX_CELL_PSD_CONFIG_PARAM_IP_ADDRESS, // Not allowed on SARA-R5 + // UBX_CELL_PSD_CONFIG_PARAM_DATA_COMPRESSION, // Not allowed on SARA-R5 + // UBX_CELL_PSD_CONFIG_PARAM_HEADER_COMPRESSION, // Not allowed on SARA-R5 + UBX_CELL_PSD_CONFIG_PARAM_MAP_TO_CID = 100 } UBX_CELL_pdp_configuration_parameter_t; typedef enum { - UBX_CELL_PSD_PROTOCOL_IPV4 = 0, - UBX_CELL_PSD_PROTOCOL_IPV6, - UBX_CELL_PSD_PROTOCOL_IPV4V6_V4_PREF, - UBX_CELL_PSD_PROTOCOL_IPV4V6_V6_PREF + UBX_CELL_PSD_PROTOCOL_IPV4 = 0, + UBX_CELL_PSD_PROTOCOL_IPV6, + UBX_CELL_PSD_PROTOCOL_IPV4V6_V4_PREF, + UBX_CELL_PSD_PROTOCOL_IPV4V6_V6_PREF } UBX_CELL_pdp_protocol_type_t; typedef enum { - UBX_CELL_PSD_ACTION_RESET = 0, - UBX_CELL_PSD_ACTION_STORE, - UBX_CELL_PSD_ACTION_LOAD, - UBX_CELL_PSD_ACTION_ACTIVATE, - UBX_CELL_PSD_ACTION_DEACTIVATE + UBX_CELL_PSD_ACTION_RESET = 0, + UBX_CELL_PSD_ACTION_STORE, + UBX_CELL_PSD_ACTION_LOAD, + UBX_CELL_PSD_ACTION_ACTIVATE, + UBX_CELL_PSD_ACTION_DEACTIVATE } UBX_CELL_pdp_actions_t; typedef enum { - UBX_CELL_SEC_PROFILE_PARAM_CERT_VAL_LEVEL = 0, - UBX_CELL_SEC_PROFILE_PARAM_TLS_VER, - UBX_CELL_SEC_PROFILE_PARAM_CYPHER_SUITE, - UBX_CELL_SEC_PROFILE_PARAM_ROOT_CA, - UBX_CELL_SEC_PROFILE_PARAM_HOSTNAME, - UBX_CELL_SEC_PROFILE_PARAM_CLIENT_CERT, - UBX_CELL_SEC_PROFILE_PARAM_CLIENT_KEY, - UBX_CELL_SEC_PROFILE_PARAM_CLIENT_KEY_PWD, - UBX_CELL_SEC_PROFILE_PARAM_PSK, - UBX_CELL_SEC_PROFILE_PARAM_PSK_IDENT, - UBX_CELL_SEC_PROFILE_PARAM_SNI, + UBX_CELL_SEC_PROFILE_PARAM_CERT_VAL_LEVEL = 0, + UBX_CELL_SEC_PROFILE_PARAM_TLS_VER, + UBX_CELL_SEC_PROFILE_PARAM_CYPHER_SUITE, + UBX_CELL_SEC_PROFILE_PARAM_ROOT_CA, + UBX_CELL_SEC_PROFILE_PARAM_HOSTNAME, + UBX_CELL_SEC_PROFILE_PARAM_CLIENT_CERT, + UBX_CELL_SEC_PROFILE_PARAM_CLIENT_KEY, + UBX_CELL_SEC_PROFILE_PARAM_CLIENT_KEY_PWD, + UBX_CELL_SEC_PROFILE_PARAM_PSK, + UBX_CELL_SEC_PROFILE_PARAM_PSK_IDENT, + UBX_CELL_SEC_PROFILE_PARAM_SNI, } UBX_CELL_sec_profile_parameter_t; typedef enum { - UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_NO = 0, - UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL, - UBX_CELL_SEC_PROFILE_CERVTAL_OPCODE_YESURL, - UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE, + UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_NO = 0, + UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_YESNOURL, + UBX_CELL_SEC_PROFILE_CERVTAL_OPCODE_YESURL, + UBX_CELL_SEC_PROFILE_CERTVAL_OPCODE_YESURLDATE, } UBX_CELL_sec_profile_certval_op_code_t; typedef enum { - UBX_CELL_SEC_PROFILE_TLS_OPCODE_ANYVER = 0, - UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_0, - UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_1, - UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_2, - UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_3, + UBX_CELL_SEC_PROFILE_TLS_OPCODE_ANYVER = 0, + UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_0, + UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_1, + UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_2, + UBX_CELL_SEC_PROFILE_TLS_OPCODE_VER1_3, } UBX_CELL_sec_profile_tls_op_code_t; typedef enum { - UBX_CELL_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT = 0, + UBX_CELL_SEC_PROFILE_SUITE_OPCODE_PROPOSEDDEFAULT = 0, } UBX_CELL_sec_profile_suite_op_code_t; typedef enum @@ -619,515 +615,580 @@ typedef enum typedef enum { - MINIMUM_FUNCTIONALITY = 0, // (disable both transmit and receive RF circuits by deactivating both CS and PS services) - FULL_FUNCTIONALITY = 1, - AIRPLANE_MODE = 4, - SIM_TOOLKIT_ENABLE_DEDICATED = 6, - SIM_TOOLKIT_DISABLE_DEDICATED = 7, - SIM_TOOLKIT_ENABLE_RAW = 9, - FAST_SAFE_POWER_OFF = 10, - //SILENT_RESET_WITHOUT_SIM = 15, // Not supported on SARA-R5 - SILENT_RESET_WITH_SIM = 16 - //MINIMUM_FUNCTIONALITY = 19, // Not supported on SARA-R5 - //DEEP_LOW_POWER_STATE = 127 // Not supported on SARA-R5 + MINIMUM_FUNCTIONALITY = + 0, // (disable both transmit and receive RF circuits by deactivating both CS and PS services) + FULL_FUNCTIONALITY = 1, + AIRPLANE_MODE = 4, + SIM_TOOLKIT_ENABLE_DEDICATED = 6, + SIM_TOOLKIT_DISABLE_DEDICATED = 7, + SIM_TOOLKIT_ENABLE_RAW = 9, + FAST_SAFE_POWER_OFF = 10, + // SILENT_RESET_WITHOUT_SIM = 15, // Not supported on SARA-R5 + SILENT_RESET_WITH_SIM = 16 + // MINIMUM_FUNCTIONALITY = 19, // Not supported on SARA-R5 + // DEEP_LOW_POWER_STATE = 127 // Not supported on SARA-R5 } UBX_CELL_functionality_t; class UBX_CELL : public Print { -public: - // Constructor - // The library will use the powerPin and resetPin (if provided) to power the module off/on and perform an emergency reset - // maxInitTries sets the maximum number of initialization attempts. .init is called by .begin. - UBX_CELL(int powerPin = UBX_CELL_POWER_PIN, int resetPin = UBX_CELL_RESET_PIN, uint8_t maxInitTries = 9); - - ~UBX_CELL(); - // Begin -- initialize module and ensure it's connected + public: + // Constructor + // The library will use the powerPin and resetPin (if provided) to power the module off/on and perform an emergency + // reset maxInitTries sets the maximum number of initialization attempts. .init is called by .begin. + UBX_CELL(int powerPin = UBX_CELL_POWER_PIN, int resetPin = UBX_CELL_RESET_PIN, uint8_t maxInitTries = 9); + + ~UBX_CELL(); + // Begin -- initialize module and ensure it's connected #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - bool begin(SoftwareSerial &softSerial, unsigned long baud = UBX_CELL_DEFAULT_BAUD_RATE); + bool begin(SoftwareSerial &softSerial, unsigned long baud = UBX_CELL_DEFAULT_BAUD_RATE); #endif - bool begin(HardwareSerial &hardSerial, unsigned long baud = UBX_CELL_DEFAULT_BAUD_RATE); - - // Debug prints - void enableDebugging(Print &debugPort = Serial); //Turn on debug printing. If user doesn't specify then Serial will be used. - void enableAtDebugging(Print &debugPort = Serial); //Turn on AT debug printing. If user doesn't specify then Serial will be used. - - // Invert the polarity of the power pin - if required - // Normally the SARA's power pin is pulled low and released to toggle the power - // But the Asset Tracker needs this to be pulled high and released instead - void invertPowerPin(bool invert = false); - - UBX_CELL_error_t modulePowerOff(void); // Graceful disconnect and shutdown using +CPWROFF. - void modulePowerOn(void); // Requires access to the PWR_ON pin - - // Loop polling and polling setup - process URC's etc. from the module - - // This function was originally written by Matthew Menze for the LTE Shield (SARA-R4) library - // See: https://github.com/sparkfun/SparkFun_LTE_Shield_Arduino_Library/pull/8 - // It does the same job as ::poll but also processes any 'old' data stored in the backlog first - // It also has a built-in timeout - which ::poll does not - // Use this - it is way better than ::poll. Thank you Matthew! - bool bufferedPoll(void); - - // This is the original poll function. - // It is 'blocking' - it does not return when serial data is available until it receives a `\n`. - // ::bufferedPoll is the new improved version. It processes any data in the backlog and includes a timeout. - // Retained for backward-compatibility and just in case you do want to (temporarily) ignore any data in the backlog - bool poll(void); - - // Callbacks (called during polling) - void setSocketListenCallback(void (*socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int)); // listen Socket, local IP Address, listen Port, socket, remote IP Address, port - // This is the original read socket callback - called when a +UUSORD or +UUSORF URC is received - // It works - and handles binary data correctly - but the remote IP Address and Port are lost for UDP connections - // setSocketReadCallbackPlus is preferred! - void setSocketReadCallback(void (*socketReadCallback)(int, String)); // socket, read data - void setSocketReadCallbackPlus(void (*socketReadCallbackPlus)(int, const char *, int, IPAddress, int)); // socket, read data, length, remoteAddress, remotePort - void setSocketCloseCallback(void (*socketCloseCallback)(int)); // socket - void setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, - PositionData gps, SpeedData spd, unsigned long uncertainty)); - void setSIMstateReportCallback(void (*simStateRequestCallback)(UBX_CELL_sim_states_t state)); - void setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)); - void setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)); - void setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)); - void setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)); - void setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)); - - UBX_CELL_error_t setRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, - unsigned int lac, unsigned int ci, int Act)); - UBX_CELL_error_t setEpsRegistrationCallback(void (*epsRegistrationCallback)(UBX_CELL_registration_status_t status, - unsigned int tac, unsigned int ci, int Act)); - - // Direct write/print to cell serial port - virtual size_t write(uint8_t c); - virtual size_t write(const char *str); - virtual size_t write(const char *buffer, size_t size); - - // General AT Commands - UBX_CELL_error_t at(void); - UBX_CELL_error_t enableEcho(bool enable = true); - String getManufacturerID(void); - String getModelID(void); - String getFirmwareVersion(void); - String getSerialNo(void); - String getIMEI(void); - String getIMSI(void); - String getCCID(void); - String getSubscriberNo(void); - String getCapabilities(void); - - // Control and status AT commands - UBX_CELL_error_t reset(void); - String clock(void); - // TODO: Return a clock struct - UBX_CELL_error_t clock(uint8_t *y, uint8_t *mo, uint8_t *d, - uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz); // TZ can be +/- and is in increments of 15 minutes. -28 == 7 hours behind UTC/GMT - UBX_CELL_error_t setClock(String theTime); - UBX_CELL_error_t setClock(uint8_t y, uint8_t mo, uint8_t d, - uint8_t h, uint8_t min, uint8_t s, int8_t tz); // TZ can be +/- and is in increments of 15 minutes. -28 == 7 hours behind UTC/GMT - void autoTimeZoneForBegin(bool enable = true); // Call autoTimeZoneForBegin(false) _before_ .begin if you want to disable the automatic time zone - UBX_CELL_error_t autoTimeZone(bool enable); // Enable/disable automatic time zone adjustment - - // Network service AT commands - int8_t rssi(void); // Receive signal strength - UBX_CELL_error_t getExtSignalQuality(signal_quality& signal_quality); - - UBX_CELL_registration_status_t registration(bool eps = true); - bool setNetworkProfile(mobile_network_operator_t mno, bool autoReset = false, bool urcNotification = false); - mobile_network_operator_t getNetworkProfile(void); - typedef enum - { - PDP_TYPE_INVALID = -1, - PDP_TYPE_IP = 0, - PDP_TYPE_NONIP = 1, - PDP_TYPE_IPV4V6 = 2, - PDP_TYPE_IPV6 = 3 - } UBX_CELL_pdp_type; - UBX_CELL_error_t setAPN(String apn, uint8_t cid = 1, UBX_CELL_pdp_type pdpType = PDP_TYPE_IP); // Set the Access Point Name - UBX_CELL_error_t getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_pdp_type* pdpType = nullptr); // Return the apn and IP address for the chosen context identifier - - UBX_CELL_error_t getSimStatus(String* code); - UBX_CELL_error_t setSimPin(String pin); - - // SIM - // Status report Mode: - // Bit States reported - // 0 Reports the (U)SIM initialization status ('s from 0 to 6 may be reported) - // 1 Reports the (U)SIM phonebook initialization status ('s from 7 to 8 may be reported) - // 2 Reports the (U)SIM toolkit REFRESH proactive command execution result ('s from 9 to 13 may be reported) - // Note: For the SARA-R5: =7, 8, 9, 10, 11, 12 and 13 are not reported. - UBX_CELL_error_t setSIMstateReportingMode(int mode); - UBX_CELL_error_t getSIMstateReportingMode(int *mode); - - typedef enum - { - L2P_DEFAULT, - L2P_PPP, - L2P_M_HEX, - L2P_M_RAW_IP, - L2P_M_OPT_PPP - } UBX_CELL_l2p_t; - UBX_CELL_error_t enterPPP(uint8_t cid = 1, char dialing_type_char = 0, - unsigned long dialNumber = 99, UBX_CELL_l2p_t l2p = L2P_DEFAULT); - - uint8_t getOperators(struct operator_stats *op, int maxOps = 3); - UBX_CELL_error_t registerOperator(struct operator_stats oper); - UBX_CELL_error_t automaticOperatorSelection(); - UBX_CELL_error_t getOperator(String *oper); - UBX_CELL_error_t deregisterOperator(void); - - // SMS -- Short Messages Service - UBX_CELL_error_t setSMSMessageFormat(UBX_CELL_message_format_t textMode = UBX_CELL_MESSAGE_FORMAT_TEXT); - UBX_CELL_error_t sendSMS(String number, String message); - UBX_CELL_error_t getPreferredMessageStorage(int *used, int *total, String memory = "ME"); - UBX_CELL_error_t readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message); - UBX_CELL_error_t deleteSMSmessage(int location, int deleteFlag = 0); // Default to deleting the single message at the specified location - UBX_CELL_error_t deleteReadSMSmessages(void) { return (deleteSMSmessage( 1, 1 )); }; // Delete all the read messages from preferred storage - UBX_CELL_error_t deleteReadSentSMSmessages(void) { return (deleteSMSmessage( 1, 2 )); }; // Delete the read and sent messages from preferred storage - UBX_CELL_error_t deleteReadSentUnsentSMSmessages(void) { return (deleteSMSmessage( 1, 3 )); }; // Delete the read, sent and unsent messages from preferred storage - UBX_CELL_error_t deleteAllSMSmessages(void) { return (deleteSMSmessage( 1, 4 )); }; // Delete the read, sent, unsent and unread messages from preferred storage - - // V24 Control and V25ter (UART interface) AT commands - UBX_CELL_error_t setBaud(unsigned long baud); - UBX_CELL_error_t setFlowControl(UBX_CELL_flow_control_t value = UBX_CELL_ENABLE_FLOW_CONTROL); - - // GPIO - // GPIO pin map - typedef enum - { - GPIO1 = 16, - GPIO2 = 23, - GPIO3 = 24, - GPIO4 = 25, - GPIO5 = 42, - GPIO6 = 19 - } UBX_CELL_gpio_t; - // GPIO pin modes - typedef enum - { - GPIO_MODE_INVALID = -1, - GPIO_OUTPUT = 0, - GPIO_INPUT, - NETWORK_STATUS, - GNSS_SUPPLY_ENABLE, - GNSS_DATA_READY, - GNSS_RTC_SHARING, - JAMMING_DETECTION, - SIM_CARD_DETECTION, - HEADSET_DETECTION, - GSM_TX_BURST_INDICATION, - MODULE_STATUS_INDICATION, - MODULE_OPERATING_MODE_INDICATION, - I2S_DIGITAL_AUDIO_INTERFACE, - SPI_SERIAL_INTERFACE, - MASTER_CLOCK_GENRATION, - UART_INTERFACE, - WIFI_ENABLE, - RING_INDICATION = 18, - LAST_GASP_ENABLE, - EXTERNAL_GNSS_ANTENNA, - TIME_PULSE_GNSS, - TIME_PULSE_OUTPUT, - TIMESTAMP, - FAST_POWER_OFF, - LWM2M_PULSE, - HARDWARE_FLOW_CONTROL, - ANTENNA_TUNING, - EXT_GNSS_TIME_PULSE, - EXT_GNSS_TIMESTAMP, - DTR_MODE, - KHZ_32768_OUT = 32, - PAD_DISABLED = 255 - } UBX_CELL_gpio_mode_t; - UBX_CELL_error_t setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_t mode, int value = 0); - UBX_CELL_gpio_mode_t getGpioMode(UBX_CELL_gpio_t gpio); - - // IP Transport Layer - int socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int localPort = 0); // Open a socket. Returns the socket number. - UBX_CELL_error_t socketClose(int socket, unsigned long timeout = UBX_CELL_2_MIN_TIMEOUT); // Close the socket - UBX_CELL_error_t socketConnect(int socket, const char *address, unsigned int port); // TCP - connect to a remote IP Address using the specified port. Not required for UDP sockets. - UBX_CELL_error_t socketConnect(int socket, IPAddress address, unsigned int port); - // Write data to the specified socket. Works with binary data - but you must specify the data length when using the const char * version - // Works with both TCP and UDP sockets - but socketWriteUDP is preferred for UDP and doesn't require socketOpen to be called first - UBX_CELL_error_t socketWrite(int socket, const char *str, int len = -1); - UBX_CELL_error_t socketWrite(int socket, String str); // OK for binary data - // Write UDP data to the specified IP Address and port. - // Works with binary data - but you must specify the data length when using the const char * versions - // If you let len default to -1, strlen is used to calculate the data length - and will be incorrect for binary data - UBX_CELL_error_t socketWriteUDP(int socket, const char *address, int port, const char *str, int len = -1); - UBX_CELL_error_t socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len = -1); - UBX_CELL_error_t socketWriteUDP(int socket, String address, int port, String str); - // Read data from the specified socket - // Call socketReadAvailable first to determine how much data is available - or use the callbacks (triggered by URC's) - // Works for both TCP and UDP - but socketReadUDP is preferred for UDP as it records the remote IP Address and port - // bytesRead - if provided - will be updated with the number of bytes actually read. This could be less than length! - UBX_CELL_error_t socketRead(int socket, int length, char *readDest, int *bytesRead = nullptr); - // Return the number of bytes available (waiting to be read) on the chosen socket - // Uses +USORD. Valid for both TCP and UDP sockets - but socketReadAvailableUDP is preferred for UDP - UBX_CELL_error_t socketReadAvailable(int socket, int *length); - // Read data from the specified UDP port - // Call socketReadAvailableUDP first to determine how much data is available - or use the callbacks (triggered by URC's) - // The remote IP Address and port are returned via *remoteIPAddress and *remotePort (if not nullptr) - // bytesRead - if provided - will be updated with the number of bytes actually read. This could be less than length! - UBX_CELL_error_t socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress = nullptr, int *remotePort = nullptr, int *bytesRead = nullptr); - // Return the number of bytes available (waiting to be read) on the chosen UDP socket - UBX_CELL_error_t socketReadAvailableUDP(int socket, int *length); - // Start listening for a connection on the specified port. The connection is reported via the socket listen callback - UBX_CELL_error_t socketListen(int socket, unsigned int port); - // Place the socket into direct link mode - making it easy to transfer binary data. Wait two seconds and then send +++ to exit the link. - UBX_CELL_error_t socketDirectLinkMode(int socket); - // Configure when direct link data is sent - UBX_CELL_error_t socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger); - UBX_CELL_error_t socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger); - UBX_CELL_error_t socketDirectLinkCharacterTrigger(int socket, int characterTrigger); - UBX_CELL_error_t socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer); - // Use +USOCTL (Socket control) to query the socket parameters - UBX_CELL_error_t querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol); - UBX_CELL_error_t querySocketLastError(int socket, int *error); - UBX_CELL_error_t querySocketTotalBytesSent(int socket, uint32_t *total); - UBX_CELL_error_t querySocketTotalBytesReceived(int socket, uint32_t *total); - UBX_CELL_error_t querySocketRemoteIPAddress(int socket, IPAddress *address, int *port); - UBX_CELL_error_t querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status); - UBX_CELL_error_t querySocketOutUnackData(int socket, uint32_t *total); - // Return the most recent socket error - int socketGetLastError(); - // Return the remote IP Address from the most recent socket listen indication (socket connection) - // Use the socket listen callback to get the full address and port information - IPAddress lastRemoteIP(void); - - // Ping - UBX_CELL_error_t ping(String remote_host, int retry = 4, int p_size = 32, unsigned long timeout = 5000, int ttl = 32); - - // HTTP - UBX_CELL_error_t resetHTTPprofile(int profile); // Reset the HTTP profile. Note: The configured HTTP profile parameters are not saved in the non volatile memory. - UBX_CELL_error_t setHTTPserverIPaddress(int profile, IPAddress address); // Default: empty string - UBX_CELL_error_t setHTTPserverName(int profile, String server); // Default: empty string - UBX_CELL_error_t setHTTPusername(int profile, String username); // Default: empty string - UBX_CELL_error_t setHTTPpassword(int profile, String password); // Default: empty string - UBX_CELL_error_t setHTTPauthentication(int profile, bool authenticate); // Default: no authentication - UBX_CELL_error_t setHTTPserverPort(int profile, int port); // Default: 80 - UBX_CELL_error_t setHTTPcustomHeader(int profile, String header); // Default: format 0:Content-Type:application/json" - UBX_CELL_error_t setHTTPsecure(int profile, bool secure, int secprofile = -1); // Default: disabled (HTTP on port 80). Set to true for HTTPS on port 443 - // TO DO: Add custom request headers - UBX_CELL_error_t getHTTPprotocolError(int profile, int *error_class, int *error_code); // Read the most recent HTTP protocol error for this profile - UBX_CELL_error_t sendHTTPGET(int profile, String path, String responseFilename); - UBX_CELL_error_t sendHTTPPOSTdata(int profile, String path, String responseFilename, String data, UBX_CELL_http_content_types_t httpContentType); - UBX_CELL_error_t sendHTTPPOSTfile(int profile, String path, String responseFilename, String requestFile, UBX_CELL_http_content_types_t httpContentType); - - UBX_CELL_error_t nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter); - UBX_CELL_error_t setMQTTclientId(const String& clientId); - UBX_CELL_error_t setMQTTserver(const String& serverName, int port); - UBX_CELL_error_t setMQTTcredentials(const String& userName, const String& pwd); - UBX_CELL_error_t setMQTTsecure(bool secure, int secprofile = -1); - UBX_CELL_error_t connectMQTT(void); - UBX_CELL_error_t disconnectMQTT(void); - UBX_CELL_error_t subscribeMQTTtopic(int max_Qos, const String& topic); - UBX_CELL_error_t unsubscribeMQTTtopic(const String& topic); - UBX_CELL_error_t readMQTT(int* pQos, String* pTopic, uint8_t *readDest, int readLength, int *bytesRead); - UBX_CELL_error_t mqttPublishTextMsg(const String& topic, const char * const msg, uint8_t qos = 0, bool retain = false); - UBX_CELL_error_t mqttPublishBinaryMsg(const String& topic, const char * const msg, size_t msg_len, uint8_t qos = 0, bool retain = false); - UBX_CELL_error_t mqttPublishFromFile(const String& topic, const String& filename, uint8_t qos = 0, bool retain = false); - UBX_CELL_error_t getMQTTprotocolError(int *error_code, int *error_code2); - - // FTP - UBX_CELL_error_t setFTPserver(const String& serverName); - UBX_CELL_error_t setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger); - UBX_CELL_error_t setFTPcredentials(const String& userName, const String& pwd); - UBX_CELL_error_t connectFTP(void); - UBX_CELL_error_t disconnectFTP(void); - UBX_CELL_error_t ftpGetFile(const String& filename); - UBX_CELL_error_t getFTPprotocolError(int *error_code, int *error_code2); - - // Configure security profiles - UBX_CELL_error_t resetSecurityProfile(int secprofile); - UBX_CELL_error_t configSecurityProfileString(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, String value); - UBX_CELL_error_t configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value); - UBX_CELL_error_t setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, UBX_CELL_sec_manager_parameter_t parameter, String name, String data); - - UBX_CELL_error_t activatePDPcontext(bool status, int cid = -1); // Activates or deactivates the specified PDP context. Default to all (cid = -1) - - // GPS - typedef enum - { - GNSS_SYSTEM_GPS = 1, - GNSS_SYSTEM_SBAS = 2, - GNSS_SYSTEM_GALILEO = 4, - GNSS_SYSTEM_BEIDOU = 8, - GNSS_SYSTEM_IMES = 16, - GNSS_SYSTEM_QZSS = 32, - GNSS_SYSTEM_GLONASS = 64 - } gnss_system_t; - typedef enum - { - GNSS_AIDING_MODE_NONE = 0, - GNSS_AIDING_MODE_AUTOMATIC = 1, - GNSS_AIDING_MODE_ASSISTNOW_OFFLINE = 2, - GNSS_AIDING_MODE_ASSISTNOW_ONLINE = 4, - GNSS_AIDING_MODE_ASSISTNOW_AUTONOMOUS = 8 - } gnss_aiding_mode_t; - bool isGPSon(void); - UBX_CELL_error_t gpsPower(bool enable = true, - gnss_system_t gnss_sys = GNSS_SYSTEM_GPS, - gnss_aiding_mode_t gnss_aiding = GNSS_AIDING_MODE_AUTOMATIC); - //UBX_CELL_error_t gpsEnableClock(bool enable = true); - //UBX_CELL_error_t gpsGetClock(struct ClockData *clock); - //UBX_CELL_error_t gpsEnableFix(bool enable = true); - //UBX_CELL_error_t gpsGetFix(float *lat, float *lon, unsigned int *alt, uint8_t *quality, uint8_t *sat); - //UBX_CELL_error_t gpsGetFix(struct PositionData *pos); - //UBX_CELL_error_t gpsEnablePos(bool enable = true); - //UBX_CELL_error_t gpsGetPos(struct PositionData *pos); - //UBX_CELL_error_t gpsEnableSat(bool enable = true); - //UBX_CELL_error_t gpsGetSat(uint8_t *sats); - UBX_CELL_error_t gpsEnableRmc(bool enable = true); // Enable GPRMC messages - UBX_CELL_error_t gpsGetRmc(struct PositionData *pos, struct SpeedData *speed, struct ClockData *clk, bool *valid); //Parse a GPRMC message - //UBX_CELL_error_t gpsEnableSpeed(bool enable = true); - //UBX_CELL_error_t gpsGetSpeed(struct SpeedData *speed); - - UBX_CELL_error_t gpsRequest(unsigned int timeout, uint32_t accuracy, bool detailed = true, unsigned int sensor = 3); - - //CellLocate - UBX_CELL_error_t gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, - unsigned int days = 14, unsigned int period = 4, unsigned int resolution = 1, - unsigned int gnssTypes = 65, unsigned int mode = 0, unsigned int dataType = 15); - - // File system - // TO DO: add full support for file tags. Default tag to USER - UBX_CELL_error_t getFileContents(String filename, String *contents); // OK for text files. But will fail with binary files (containing \0) on some platforms. - UBX_CELL_error_t getFileContents(String filename, char *contents); // OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. - UBX_CELL_error_t getFileBlock(const String& filename, char* buffer, size_t offset, size_t length, size_t& bytes_read); // OK for binary files. Make sure buffer can hold the requested block size. - - // Append data to a file, delete file first to not appends the data. - UBX_CELL_error_t appendFileContents(String filename, String str); - UBX_CELL_error_t appendFileContents(String filename, const char *str, int len); - UBX_CELL_error_t getFileSize(String filename, int *size); - UBX_CELL_error_t deleteFile(String filename); - - // Functionality - UBX_CELL_error_t functionality(UBX_CELL_functionality_t function = FULL_FUNCTIONALITY); - - // Send a custom command with an expected (potentially partial) response, store entire response - UBX_CELL_error_t sendCustomCommandWithResponse(const char *command, const char *expectedResponse, - char *responseDest, unsigned long commandTimeout = UBX_CELL_STANDARD_RESPONSE_TIMEOUT, bool at = true); - - // Send command with an expected (potentially partial) response, store entire response - UBX_CELL_error_t sendCommandWithResponse(const char *command, const char *expectedResponse, - char *responseDest, unsigned long commandTimeout, int destSize = minimumResponseAllocation, bool at = true); - - char *ubx_cell_calloc_char(size_t num); - - // Add a URC handler - void addURCHandler(const char* urcString, UBX_CELL_urc_handler_t urcHandler); - -protected: - HardwareSerial *_hardSerial; + bool begin(HardwareSerial &hardSerial, unsigned long baud = UBX_CELL_DEFAULT_BAUD_RATE); + + // Debug prints + void enableDebugging( + Print &debugPort = Serial); // Turn on debug printing. If user doesn't specify then Serial will be used. + void enableAtDebugging( + Print &debugPort = Serial); // Turn on AT debug printing. If user doesn't specify then Serial will be used. + + // Invert the polarity of the power pin - if required + // Normally the SARA's power pin is pulled low and released to toggle the power + // But the Asset Tracker needs this to be pulled high and released instead + void invertPowerPin(bool invert = false); + + UBX_CELL_error_t modulePowerOff(void); // Graceful disconnect and shutdown using +CPWROFF. + void modulePowerOn(void); // Requires access to the PWR_ON pin + + // Loop polling and polling setup - process URC's etc. from the module + + // This function was originally written by Matthew Menze for the LTE Shield (SARA-R4) library + // See: https://github.com/sparkfun/SparkFun_LTE_Shield_Arduino_Library/pull/8 + // It does the same job as ::poll but also processes any 'old' data stored in the backlog first + // It also has a built-in timeout - which ::poll does not + // Use this - it is way better than ::poll. Thank you Matthew! + bool bufferedPoll(void); + + // This is the original poll function. + // It is 'blocking' - it does not return when serial data is available until it receives a `\n`. + // ::bufferedPoll is the new improved version. It processes any data in the backlog and includes a timeout. + // Retained for backward-compatibility and just in case you do want to (temporarily) ignore any data in the backlog + bool poll(void); + + // Callbacks (called during polling) + void setSocketListenCallback(void (*socketListenCallback)( + int, IPAddress, unsigned int, int, IPAddress, + unsigned int)); // listen Socket, local IP Address, listen Port, socket, remote IP Address, port + // This is the original read socket callback - called when a +UUSORD or +UUSORF URC is received + // It works - and handles binary data correctly - but the remote IP Address and Port are lost for UDP connections + // setSocketReadCallbackPlus is preferred! + void setSocketReadCallback(void (*socketReadCallback)(int, String)); // socket, read data + void setSocketReadCallbackPlus(void (*socketReadCallbackPlus)( + int, const char *, int, IPAddress, int)); // socket, read data, length, remoteAddress, remotePort + void setSocketCloseCallback(void (*socketCloseCallback)(int)); // socket + void setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, PositionData gps, SpeedData spd, + unsigned long uncertainty)); + void setSIMstateReportCallback(void (*simStateRequestCallback)(UBX_CELL_sim_states_t state)); + void setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)); + void setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, + int ttl, long rtt)); + void setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)); + void setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)); + void setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)); + + UBX_CELL_error_t setRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, + unsigned int lac, unsigned int ci, int Act)); + UBX_CELL_error_t setEpsRegistrationCallback(void (*epsRegistrationCallback)(UBX_CELL_registration_status_t status, + unsigned int tac, unsigned int ci, + int Act)); + + // Direct write/print to cell serial port + virtual size_t write(uint8_t c); + virtual size_t write(const char *str); + virtual size_t write(const char *buffer, size_t size); + + // General AT Commands + UBX_CELL_error_t at(void); + UBX_CELL_error_t enableEcho(bool enable = true); + String getManufacturerID(void); + String getModelID(void); + String getFirmwareVersion(void); + String getSerialNo(void); + String getIMEI(void); + String getIMSI(void); + String getCCID(void); + String getSubscriberNo(void); + String getCapabilities(void); + + // Control and status AT commands + UBX_CELL_error_t reset(void); + String clock(void); + // TODO: Return a clock struct + UBX_CELL_error_t clock( + uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h, uint8_t *min, uint8_t *s, + int8_t *tz); // TZ can be +/- and is in increments of 15 minutes. -28 == 7 hours behind UTC/GMT + UBX_CELL_error_t setClock(String theTime); + UBX_CELL_error_t setClock( + uint8_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t min, uint8_t s, + int8_t tz); // TZ can be +/- and is in increments of 15 minutes. -28 == 7 hours behind UTC/GMT + void autoTimeZoneForBegin(bool enable = true); // Call autoTimeZoneForBegin(false) _before_ .begin if you want to + // disable the automatic time zone + UBX_CELL_error_t autoTimeZone(bool enable); // Enable/disable automatic time zone adjustment + + // Network service AT commands + int8_t rssi(void); // Receive signal strength + UBX_CELL_error_t getExtSignalQuality(signal_quality &signal_quality); + + UBX_CELL_registration_status_t registration(bool eps = true); + bool setNetworkProfile(mobile_network_operator_t mno, bool autoReset = false, bool urcNotification = false); + mobile_network_operator_t getNetworkProfile(void); + typedef enum + { + PDP_TYPE_INVALID = -1, + PDP_TYPE_IP = 0, + PDP_TYPE_NONIP = 1, + PDP_TYPE_IPV4V6 = 2, + PDP_TYPE_IPV6 = 3 + } UBX_CELL_pdp_type; + UBX_CELL_error_t setAPN(String apn, uint8_t cid = 1, + UBX_CELL_pdp_type pdpType = PDP_TYPE_IP); // Set the Access Point Name + UBX_CELL_error_t getAPN( + int cid, String *apn, IPAddress *ip, + UBX_CELL_pdp_type *pdpType = nullptr); // Return the apn and IP address for the chosen context identifier + + UBX_CELL_error_t getSimStatus(String *code); + UBX_CELL_error_t setSimPin(String pin); + + // SIM + // Status report Mode: + // Bit States reported + // 0 Reports the (U)SIM initialization status ('s from 0 to 6 may be reported) + // 1 Reports the (U)SIM phonebook initialization status ('s from 7 to 8 may be reported) + // 2 Reports the (U)SIM toolkit REFRESH proactive command execution result ('s from 9 to 13 may be + // reported) Note: For the SARA-R5: =7, 8, 9, 10, 11, 12 and 13 are not reported. + UBX_CELL_error_t setSIMstateReportingMode(int mode); + UBX_CELL_error_t getSIMstateReportingMode(int *mode); + + typedef enum + { + L2P_DEFAULT, + L2P_PPP, + L2P_M_HEX, + L2P_M_RAW_IP, + L2P_M_OPT_PPP + } UBX_CELL_l2p_t; + UBX_CELL_error_t enterPPP(uint8_t cid = 1, char dialing_type_char = 0, unsigned long dialNumber = 99, + UBX_CELL_l2p_t l2p = L2P_DEFAULT); + + uint8_t getOperators(struct operator_stats *op, int maxOps = 3); + UBX_CELL_error_t registerOperator(struct operator_stats oper); + UBX_CELL_error_t automaticOperatorSelection(); + UBX_CELL_error_t getOperator(String *oper); + UBX_CELL_error_t deregisterOperator(void); + + // SMS -- Short Messages Service + UBX_CELL_error_t setSMSMessageFormat(UBX_CELL_message_format_t textMode = UBX_CELL_MESSAGE_FORMAT_TEXT); + UBX_CELL_error_t sendSMS(String number, String message); + UBX_CELL_error_t getPreferredMessageStorage(int *used, int *total, String memory = "ME"); + UBX_CELL_error_t readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message); + UBX_CELL_error_t deleteSMSmessage( + int location, int deleteFlag = 0); // Default to deleting the single message at the specified location + UBX_CELL_error_t deleteReadSMSmessages(void) + { + return (deleteSMSmessage(1, 1)); + }; // Delete all the read messages from preferred storage + UBX_CELL_error_t deleteReadSentSMSmessages(void) + { + return (deleteSMSmessage(1, 2)); + }; // Delete the read and sent messages from preferred storage + UBX_CELL_error_t deleteReadSentUnsentSMSmessages(void) + { + return (deleteSMSmessage(1, 3)); + }; // Delete the read, sent and unsent messages from preferred storage + UBX_CELL_error_t deleteAllSMSmessages(void) + { + return (deleteSMSmessage(1, 4)); + }; // Delete the read, sent, unsent and unread messages from preferred storage + + // V24 Control and V25ter (UART interface) AT commands + UBX_CELL_error_t setBaud(unsigned long baud); + UBX_CELL_error_t setFlowControl(UBX_CELL_flow_control_t value = UBX_CELL_ENABLE_FLOW_CONTROL); + + // GPIO + // GPIO pin map + typedef enum + { + GPIO1 = 16, + GPIO2 = 23, + GPIO3 = 24, + GPIO4 = 25, + GPIO5 = 42, + GPIO6 = 19 + } UBX_CELL_gpio_t; + // GPIO pin modes + typedef enum + { + GPIO_MODE_INVALID = -1, + GPIO_OUTPUT = 0, + GPIO_INPUT, + NETWORK_STATUS, + GNSS_SUPPLY_ENABLE, + GNSS_DATA_READY, + GNSS_RTC_SHARING, + JAMMING_DETECTION, + SIM_CARD_DETECTION, + HEADSET_DETECTION, + GSM_TX_BURST_INDICATION, + MODULE_STATUS_INDICATION, + MODULE_OPERATING_MODE_INDICATION, + I2S_DIGITAL_AUDIO_INTERFACE, + SPI_SERIAL_INTERFACE, + MASTER_CLOCK_GENRATION, + UART_INTERFACE, + WIFI_ENABLE, + RING_INDICATION = 18, + LAST_GASP_ENABLE, + EXTERNAL_GNSS_ANTENNA, + TIME_PULSE_GNSS, + TIME_PULSE_OUTPUT, + TIMESTAMP, + FAST_POWER_OFF, + LWM2M_PULSE, + HARDWARE_FLOW_CONTROL, + ANTENNA_TUNING, + EXT_GNSS_TIME_PULSE, + EXT_GNSS_TIMESTAMP, + DTR_MODE, + KHZ_32768_OUT = 32, + PAD_DISABLED = 255 + } UBX_CELL_gpio_mode_t; + UBX_CELL_error_t setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_t mode, int value = 0); + UBX_CELL_gpio_mode_t getGpioMode(UBX_CELL_gpio_t gpio); + + // IP Transport Layer + int socketOpen(UBX_CELL_socket_protocol_t protocol, + unsigned int localPort = 0); // Open a socket. Returns the socket number. + UBX_CELL_error_t socketClose(int socket, unsigned long timeout = UBX_CELL_2_MIN_TIMEOUT); // Close the socket + UBX_CELL_error_t socketConnect(int socket, const char *address, + unsigned int port); // TCP - connect to a remote IP Address using the specified port. + // Not required for UDP sockets. + UBX_CELL_error_t socketConnect(int socket, IPAddress address, unsigned int port); + // Write data to the specified socket. Works with binary data - but you must specify the data length when using the + // const char * version Works with both TCP and UDP sockets - but socketWriteUDP is preferred for UDP and doesn't + // require socketOpen to be called first + UBX_CELL_error_t socketWrite(int socket, const char *str, int len = -1); + UBX_CELL_error_t socketWrite(int socket, String str); // OK for binary data + // Write UDP data to the specified IP Address and port. + // Works with binary data - but you must specify the data length when using the const char * versions + // If you let len default to -1, strlen is used to calculate the data length - and will be incorrect for binary data + UBX_CELL_error_t socketWriteUDP(int socket, const char *address, int port, const char *str, int len = -1); + UBX_CELL_error_t socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len = -1); + UBX_CELL_error_t socketWriteUDP(int socket, String address, int port, String str); + // Read data from the specified socket + // Call socketReadAvailable first to determine how much data is available - or use the callbacks (triggered by + // URC's) Works for both TCP and UDP - but socketReadUDP is preferred for UDP as it records the remote IP Address + // and port bytesRead - if provided - will be updated with the number of bytes actually read. This could be less + // than length! + UBX_CELL_error_t socketRead(int socket, int length, char *readDest, int *bytesRead = nullptr); + // Return the number of bytes available (waiting to be read) on the chosen socket + // Uses +USORD. Valid for both TCP and UDP sockets - but socketReadAvailableUDP is preferred for UDP + UBX_CELL_error_t socketReadAvailable(int socket, int *length); + // Read data from the specified UDP port + // Call socketReadAvailableUDP first to determine how much data is available - or use the callbacks (triggered by + // URC's) The remote IP Address and port are returned via *remoteIPAddress and *remotePort (if not nullptr) + // bytesRead - if provided - will be updated with the number of bytes actually read. This could be less than length! + UBX_CELL_error_t socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress = nullptr, + int *remotePort = nullptr, int *bytesRead = nullptr); + // Return the number of bytes available (waiting to be read) on the chosen UDP socket + UBX_CELL_error_t socketReadAvailableUDP(int socket, int *length); + // Start listening for a connection on the specified port. The connection is reported via the socket listen callback + UBX_CELL_error_t socketListen(int socket, unsigned int port); + // Place the socket into direct link mode - making it easy to transfer binary data. Wait two seconds and then send + // +++ to exit the link. + UBX_CELL_error_t socketDirectLinkMode(int socket); + // Configure when direct link data is sent + UBX_CELL_error_t socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger); + UBX_CELL_error_t socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger); + UBX_CELL_error_t socketDirectLinkCharacterTrigger(int socket, int characterTrigger); + UBX_CELL_error_t socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer); + // Use +USOCTL (Socket control) to query the socket parameters + UBX_CELL_error_t querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol); + UBX_CELL_error_t querySocketLastError(int socket, int *error); + UBX_CELL_error_t querySocketTotalBytesSent(int socket, uint32_t *total); + UBX_CELL_error_t querySocketTotalBytesReceived(int socket, uint32_t *total); + UBX_CELL_error_t querySocketRemoteIPAddress(int socket, IPAddress *address, int *port); + UBX_CELL_error_t querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status); + UBX_CELL_error_t querySocketOutUnackData(int socket, uint32_t *total); + // Return the most recent socket error + int socketGetLastError(); + // Return the remote IP Address from the most recent socket listen indication (socket connection) + // Use the socket listen callback to get the full address and port information + IPAddress lastRemoteIP(void); + + // Ping + UBX_CELL_error_t ping(String remote_host, int retry = 4, int p_size = 32, unsigned long timeout = 5000, + int ttl = 32); + + // HTTP + UBX_CELL_error_t resetHTTPprofile(int profile); // Reset the HTTP profile. Note: The configured HTTP profile + // parameters are not saved in the non volatile memory. + UBX_CELL_error_t setHTTPserverIPaddress(int profile, IPAddress address); // Default: empty string + UBX_CELL_error_t setHTTPserverName(int profile, String server); // Default: empty string + UBX_CELL_error_t setHTTPusername(int profile, String username); // Default: empty string + UBX_CELL_error_t setHTTPpassword(int profile, String password); // Default: empty string + UBX_CELL_error_t setHTTPauthentication(int profile, bool authenticate); // Default: no authentication + UBX_CELL_error_t setHTTPserverPort(int profile, int port); // Default: 80 + UBX_CELL_error_t setHTTPcustomHeader(int profile, + String header); // Default: format 0:Content-Type:application/json" + UBX_CELL_error_t setHTTPsecure( + int profile, bool secure, + int secprofile = -1); // Default: disabled (HTTP on port 80). Set to true for HTTPS on port 443 + // TO DO: Add custom request headers + UBX_CELL_error_t getHTTPprotocolError(int profile, int *error_class, + int *error_code); // Read the most recent HTTP protocol error for this profile + UBX_CELL_error_t sendHTTPGET(int profile, String path, String responseFilename); + UBX_CELL_error_t sendHTTPPOSTdata(int profile, String path, String responseFilename, String data, + UBX_CELL_http_content_types_t httpContentType); + UBX_CELL_error_t sendHTTPPOSTfile(int profile, String path, String responseFilename, String requestFile, + UBX_CELL_http_content_types_t httpContentType); + + UBX_CELL_error_t nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter); + UBX_CELL_error_t setMQTTclientId(const String &clientId); + UBX_CELL_error_t setMQTTserver(const String &serverName, int port); + UBX_CELL_error_t setMQTTcredentials(const String &userName, const String &pwd); + UBX_CELL_error_t setMQTTsecure(bool secure, int secprofile = -1); + UBX_CELL_error_t connectMQTT(void); + UBX_CELL_error_t disconnectMQTT(void); + UBX_CELL_error_t subscribeMQTTtopic(int max_Qos, const String &topic); + UBX_CELL_error_t unsubscribeMQTTtopic(const String &topic); + UBX_CELL_error_t readMQTT(int *pQos, String *pTopic, uint8_t *readDest, int readLength, int *bytesRead); + UBX_CELL_error_t mqttPublishTextMsg(const String &topic, const char *const msg, uint8_t qos = 0, + bool retain = false); + UBX_CELL_error_t mqttPublishBinaryMsg(const String &topic, const char *const msg, size_t msg_len, uint8_t qos = 0, + bool retain = false); + UBX_CELL_error_t mqttPublishFromFile(const String &topic, const String &filename, uint8_t qos = 0, + bool retain = false); + UBX_CELL_error_t getMQTTprotocolError(int *error_code, int *error_code2); + + // FTP + UBX_CELL_error_t setFTPserver(const String &serverName); + UBX_CELL_error_t setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, + const unsigned int data_linger); + UBX_CELL_error_t setFTPcredentials(const String &userName, const String &pwd); + UBX_CELL_error_t connectFTP(void); + UBX_CELL_error_t disconnectFTP(void); + UBX_CELL_error_t ftpGetFile(const String &filename); + UBX_CELL_error_t getFTPprotocolError(int *error_code, int *error_code2); + + // Configure security profiles + UBX_CELL_error_t resetSecurityProfile(int secprofile); + UBX_CELL_error_t configSecurityProfileString(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, + String value); + UBX_CELL_error_t configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value); + UBX_CELL_error_t setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, + UBX_CELL_sec_manager_parameter_t parameter, String name, String data); + + UBX_CELL_error_t activatePDPcontext( + bool status, int cid = -1); // Activates or deactivates the specified PDP context. Default to all (cid = -1) + + // GPS + typedef enum + { + GNSS_SYSTEM_GPS = 1, + GNSS_SYSTEM_SBAS = 2, + GNSS_SYSTEM_GALILEO = 4, + GNSS_SYSTEM_BEIDOU = 8, + GNSS_SYSTEM_IMES = 16, + GNSS_SYSTEM_QZSS = 32, + GNSS_SYSTEM_GLONASS = 64 + } gnss_system_t; + typedef enum + { + GNSS_AIDING_MODE_NONE = 0, + GNSS_AIDING_MODE_AUTOMATIC = 1, + GNSS_AIDING_MODE_ASSISTNOW_OFFLINE = 2, + GNSS_AIDING_MODE_ASSISTNOW_ONLINE = 4, + GNSS_AIDING_MODE_ASSISTNOW_AUTONOMOUS = 8 + } gnss_aiding_mode_t; + bool isGPSon(void); + UBX_CELL_error_t gpsPower(bool enable = true, gnss_system_t gnss_sys = GNSS_SYSTEM_GPS, + gnss_aiding_mode_t gnss_aiding = GNSS_AIDING_MODE_AUTOMATIC); + // UBX_CELL_error_t gpsEnableClock(bool enable = true); + // UBX_CELL_error_t gpsGetClock(struct ClockData *clock); + // UBX_CELL_error_t gpsEnableFix(bool enable = true); + // UBX_CELL_error_t gpsGetFix(float *lat, float *lon, unsigned int *alt, uint8_t *quality, uint8_t *sat); + // UBX_CELL_error_t gpsGetFix(struct PositionData *pos); + // UBX_CELL_error_t gpsEnablePos(bool enable = true); + // UBX_CELL_error_t gpsGetPos(struct PositionData *pos); + // UBX_CELL_error_t gpsEnableSat(bool enable = true); + // UBX_CELL_error_t gpsGetSat(uint8_t *sats); + UBX_CELL_error_t gpsEnableRmc(bool enable = true); // Enable GPRMC messages + UBX_CELL_error_t gpsGetRmc(struct PositionData *pos, struct SpeedData *speed, struct ClockData *clk, + bool *valid); // Parse a GPRMC message + // UBX_CELL_error_t gpsEnableSpeed(bool enable = true); + // UBX_CELL_error_t gpsGetSpeed(struct SpeedData *speed); + + UBX_CELL_error_t gpsRequest(unsigned int timeout, uint32_t accuracy, bool detailed = true, unsigned int sensor = 3); + + // CellLocate + UBX_CELL_error_t gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, + unsigned int days = 14, unsigned int period = 4, unsigned int resolution = 1, + unsigned int gnssTypes = 65, unsigned int mode = 0, + unsigned int dataType = 15); + + // File system + // TO DO: add full support for file tags. Default tag to USER + UBX_CELL_error_t getFileContents( + String filename, + String *contents); // OK for text files. But will fail with binary files (containing \0) on some platforms. + UBX_CELL_error_t getFileContents(String filename, + char *contents); // OK for binary files. Make sure contents can hold the entire + // file. Get the size first with getFileSize. + UBX_CELL_error_t getFileBlock( + const String &filename, char *buffer, size_t offset, size_t length, + size_t &bytes_read); // OK for binary files. Make sure buffer can hold the requested block size. + + // Append data to a file, delete file first to not appends the data. + UBX_CELL_error_t appendFileContents(String filename, String str); + UBX_CELL_error_t appendFileContents(String filename, const char *str, int len); + UBX_CELL_error_t getFileSize(String filename, int *size); + UBX_CELL_error_t deleteFile(String filename); + + // Functionality + UBX_CELL_error_t functionality(UBX_CELL_functionality_t function = FULL_FUNCTIONALITY); + + // Send a custom command with an expected (potentially partial) response, store entire response + UBX_CELL_error_t sendCustomCommandWithResponse(const char *command, const char *expectedResponse, + char *responseDest, + unsigned long commandTimeout = UBX_CELL_STANDARD_RESPONSE_TIMEOUT, + bool at = true); + + // Send command with an expected (potentially partial) response, store entire response + UBX_CELL_error_t sendCommandWithResponse(const char *command, const char *expectedResponse, char *responseDest, + unsigned long commandTimeout, int destSize = minimumResponseAllocation, + bool at = true); + + char *ubx_cell_calloc_char(size_t num); + + // Add a URC handler + void addURCHandler(const char *urcString, UBX_CELL_urc_handler_t urcHandler); + + protected: + HardwareSerial *_hardSerial; #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED - SoftwareSerial *_softSerial; + SoftwareSerial *_softSerial; #endif - Print *_debugPort; //The stream to send debug messages to if enabled. Usually Serial. - bool _printDebug = false; //Flag to print debugging variables - Print *_debugAtPort; //The stream to send debug messages to if enabled. Usually Serial. - bool _printAtDebug = false; //Flag to print debugging variables - - int _powerPin; - int _resetPin; - bool _invertPowerPin = false; - - unsigned long _baud; - IPAddress _lastRemoteIP; - IPAddress _lastLocalIP; - uint8_t _maxInitTries; - bool _autoTimeZoneForBegin = true; - bool _bufferedPollReentrant = false; // Prevent reentry of bufferedPoll - just in case it gets called from a callback - bool _pollReentrant = false; // Prevent reentry of poll - just in case it gets called from a callback - - #define _RXBuffSize 2056 - const unsigned long _rxWindowMillis = 2; // 1ms is not quite long enough for a single char at 9600 baud. millis roll over much less often than micros. See notes in .cpp re. ESP32! - char *_saraRXBuffer; // Allocated in UBX_CELL::begin - char *_pruneBuffer; - char *_saraResponseBacklog; - int _saraResponseBacklogLength = 0; // The backlog could contain binary data so we can't use strlen to find its length - - void (*_socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int); - void (*_socketReadCallback)(int, String); - void (*_socketReadCallbackPlus)(int, const char *, int, IPAddress, int); // socket, data, length, remoteAddress, remotePort - void (*_socketCloseCallback)(int); - void (*_gpsRequestCallback)(ClockData, PositionData, SpeedData, unsigned long); - void (*_simStateReportCallback)(UBX_CELL_sim_states_t); - void (*_psdActionRequestCallback)(int, IPAddress); - void (*_pingRequestCallback)(int, int, String, IPAddress, int, long); - void (*_httpCommandRequestCallback)(int, int, int); - void (*_mqttCommandRequestCallback)(int, int); - void (*_ftpCommandRequestCallback)(int, int); - void (*_registrationCallback)(UBX_CELL_registration_status_t status, unsigned int lac, unsigned int ci, int Act); - void (*_epsRegistrationCallback)(UBX_CELL_registration_status_t status, unsigned int tac, unsigned int ci, int Act); - - // Vectors of URC strings and handlers - std::vector _urcStrings; - std::vector _urcHandlers; - - int _lastSocketProtocol[UBX_CELL_NUM_SOCKETS]; // Record the protocol for each socket to avoid having to call querySocketType in parseSocketReadIndication - - typedef enum - { - UBX_CELL_INIT_STANDARD, - UBX_CELL_INIT_AUTOBAUD, - UBX_CELL_INIT_RESET - } UBX_CELL_init_type_t; - - UBX_CELL_error_t init(unsigned long baud, UBX_CELL_init_type_t initType = UBX_CELL_INIT_STANDARD); - - void powerOn(void); // Brief pulse on PWR_ON to turn module back on - void powerOff(void); // Long pulse on PWR_ON to do a graceful shutdown. Note modulePowerOff (+CPWROFF) is preferred. - - void hwReset(void); - - UBX_CELL_error_t setMNOprofile(mobile_network_operator_t mno, bool autoReset = false, bool urcNotification = false); - UBX_CELL_error_t getMNOprofile(mobile_network_operator_t *mno); - - // Wait for an expected response (don't send a command) - UBX_CELL_error_t waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout); - - // Send a command -- prepend AT if at is true - void sendCommand(const char *command, bool at); - - const int _saraR5maxSocketRead = 1024; // The limit on bytes that can be read in a single read - - UBX_CELL_error_t parseSocketReadIndication(int socket, int length); - UBX_CELL_error_t parseSocketReadIndicationUDP(int socket, int length); - UBX_CELL_error_t parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, int socket, IPAddress remoteIP, unsigned int port); - UBX_CELL_error_t parseSocketCloseIndication(String *closeIndication); - - // UART Functions - size_t hwPrint(const char *s); - size_t hwWriteData(const char *buff, int len); - size_t hwWrite(const char c); - int readAvailable(char *inString); - char readChar(void); - int hwAvailable(void); - virtual void beginSerial(unsigned long baud); - void setTimeout(unsigned long timeout); - bool find(char *target); - - UBX_CELL_error_t autobaud(unsigned long desiredBaud); - - bool urcHandlerReadSocket(const char* event); - bool urcHandlerReadUDPSocket(const char* event); - bool urcHandlerListeningSocket(const char* event); - bool urcHandlerCloseSocket(const char* event); - bool urcHandlerGNSSRequestLocation(const char* event); - bool urcHandlerSIMState(const char* event); - bool urcHandlerHTTPCommand(const char* event); - bool urcHandlerMQTTCommand(const char* event); - bool urcHandlerPingCommand(const char* event); - bool urcHandlerFTPCommand(const char* event); - bool urcHandlerRegistrationStatus(const char* event); - bool urcHandlerEPSRegistrationStatus(const char* event); - - bool processURCEvent(const char *event); - void pruneBacklog(void); - - // GPS Helper functions - char *readDataUntil(char *destination, unsigned int destSize, char *source, char delimiter); - bool parseGPRMCString(char *rmcString, PositionData *pos, ClockData *clk, SpeedData *spd); + Print *_debugPort; // The stream to send debug messages to if enabled. Usually Serial. + bool _printDebug = false; // Flag to print debugging variables + Print *_debugAtPort; // The stream to send debug messages to if enabled. Usually Serial. + bool _printAtDebug = false; // Flag to print debugging variables + + int _powerPin; + int _resetPin; + bool _invertPowerPin = false; + + unsigned long _baud; + IPAddress _lastRemoteIP; + IPAddress _lastLocalIP; + uint8_t _maxInitTries; + bool _autoTimeZoneForBegin = true; + bool _bufferedPollReentrant = + false; // Prevent reentry of bufferedPoll - just in case it gets called from a callback + bool _pollReentrant = false; // Prevent reentry of poll - just in case it gets called from a callback + +#define _RXBuffSize 2056 + const unsigned long _rxWindowMillis = 2; // 1ms is not quite long enough for a single char at 9600 baud. millis roll + // over much less often than micros. See notes in .cpp re. ESP32! + char *_saraRXBuffer; // Allocated in UBX_CELL::begin + char *_pruneBuffer; + char *_saraResponseBacklog; + int _saraResponseBacklogLength = + 0; // The backlog could contain binary data so we can't use strlen to find its length + + void (*_socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int); + void (*_socketReadCallback)(int, String); + void (*_socketReadCallbackPlus)(int, const char *, int, IPAddress, + int); // socket, data, length, remoteAddress, remotePort + void (*_socketCloseCallback)(int); + void (*_gpsRequestCallback)(ClockData, PositionData, SpeedData, unsigned long); + void (*_simStateReportCallback)(UBX_CELL_sim_states_t); + void (*_psdActionRequestCallback)(int, IPAddress); + void (*_pingRequestCallback)(int, int, String, IPAddress, int, long); + void (*_httpCommandRequestCallback)(int, int, int); + void (*_mqttCommandRequestCallback)(int, int); + void (*_ftpCommandRequestCallback)(int, int); + void (*_registrationCallback)(UBX_CELL_registration_status_t status, unsigned int lac, unsigned int ci, int Act); + void (*_epsRegistrationCallback)(UBX_CELL_registration_status_t status, unsigned int tac, unsigned int ci, int Act); + + // Vectors of URC strings and handlers + std::vector _urcStrings; + std::vector _urcHandlers; + + int _lastSocketProtocol[UBX_CELL_NUM_SOCKETS]; // Record the protocol for each socket to avoid having to call + // querySocketType in parseSocketReadIndication + + typedef enum + { + UBX_CELL_INIT_STANDARD, + UBX_CELL_INIT_AUTOBAUD, + UBX_CELL_INIT_RESET + } UBX_CELL_init_type_t; + + UBX_CELL_error_t init(unsigned long baud, UBX_CELL_init_type_t initType = UBX_CELL_INIT_STANDARD); + + void powerOn(void); // Brief pulse on PWR_ON to turn module back on + void powerOff(void); // Long pulse on PWR_ON to do a graceful shutdown. Note modulePowerOff (+CPWROFF) is preferred. + + void hwReset(void); + + UBX_CELL_error_t setMNOprofile(mobile_network_operator_t mno, bool autoReset = false, bool urcNotification = false); + UBX_CELL_error_t getMNOprofile(mobile_network_operator_t *mno); + + // Wait for an expected response (don't send a command) + UBX_CELL_error_t waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout); + + // Send a command -- prepend AT if at is true + void sendCommand(const char *command, bool at); + + const int _saraR5maxSocketRead = 1024; // The limit on bytes that can be read in a single read + + UBX_CELL_error_t parseSocketReadIndication(int socket, int length); + UBX_CELL_error_t parseSocketReadIndicationUDP(int socket, int length); + UBX_CELL_error_t parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, + int socket, IPAddress remoteIP, unsigned int port); + UBX_CELL_error_t parseSocketCloseIndication(String *closeIndication); + + // UART Functions + size_t hwPrint(const char *s); + size_t hwWriteData(const char *buff, int len); + size_t hwWrite(const char c); + int readAvailable(char *inString); + char readChar(void); + int hwAvailable(void); + virtual void beginSerial(unsigned long baud); + void setTimeout(unsigned long timeout); + bool find(char *target); + + UBX_CELL_error_t autobaud(unsigned long desiredBaud); + + bool urcHandlerReadSocket(const char *event); + bool urcHandlerReadUDPSocket(const char *event); + bool urcHandlerListeningSocket(const char *event); + bool urcHandlerCloseSocket(const char *event); + bool urcHandlerGNSSRequestLocation(const char *event); + bool urcHandlerSIMState(const char *event); + bool urcHandlerHTTPCommand(const char *event); + bool urcHandlerMQTTCommand(const char *event); + bool urcHandlerPingCommand(const char *event); + bool urcHandlerFTPCommand(const char *event); + bool urcHandlerRegistrationStatus(const char *event); + bool urcHandlerEPSRegistrationStatus(const char *event); + + bool processURCEvent(const char *event); + void pruneBacklog(void); + + // GPS Helper functions + char *readDataUntil(char *destination, unsigned int destSize, char *source, char delimiter); + bool parseGPRMCString(char *rmcString, PositionData *pos, ClockData *clk, SpeedData *spd); }; -#endif //SPARKFUN_UBX_CELL_ARDUINO_LIBRARY_H +#endif // SPARKFUN_UBX_CELL_ARDUINO_LIBRARY_H diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index 9ceee64..17454eb 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -3,176 +3,175 @@ #include "sfe_ublox_cellular.h" -const char* const UBX_CELL_COMMAND_DIAL = "D"; // Dial command -const char* const UBX_CELL_COMMAND_ANSWER = "A"; // Answer call -const char* const UBX_CELL_COMMAND_HANG_UP = "+CHUP"; // Hang up call -const char* const UBX_CELL_COMMAND_PLAY_AUDIO = "+UPAR"; // Play audio resource -const char* const UBX_CELL_COMMAND_STOP_AUDIO = "+USAR"; // Stop audio resource -const char* const UBX_CELL_COMMAND_GENERATE_TONE = "+UTGN"; // Tone generator +const char *const UBX_CELL_COMMAND_DIAL = "D"; // Dial command +const char *const UBX_CELL_COMMAND_ANSWER = "A"; // Answer call +const char *const UBX_CELL_COMMAND_HANG_UP = "+CHUP"; // Hang up call +const char *const UBX_CELL_COMMAND_PLAY_AUDIO = "+UPAR"; // Play audio resource +const char *const UBX_CELL_COMMAND_STOP_AUDIO = "+USAR"; // Stop audio resource +const char *const UBX_CELL_COMMAND_GENERATE_TONE = "+UTGN"; // Tone generator -const char* const UBX_CELL_RING_URC = "RING"; +const char *const UBX_CELL_RING_URC = "RING"; typedef enum { - UBX_CELL_AUDIO_RESOURCE_TONE = 0, - UBX_CELL_AUDIO_RESOURCE_MIDI = 1, - UBX_CELL_AUDIO_RESOURCE_LOOPBACK = 2 + UBX_CELL_AUDIO_RESOURCE_TONE = 0, + UBX_CELL_AUDIO_RESOURCE_MIDI = 1, + UBX_CELL_AUDIO_RESOURCE_LOOPBACK = 2 } UBX_CELL_audio_resource_t; // Base class for any modules supporting voice calls -template -class UBX_CELL_VOICE +template class UBX_CELL_VOICE { -public: - UBX_CELL_VOICE(void) - { - // Set ring URC callback to nullptr - _ringCallback = nullptr; - - // Add handler for ring URC - static_cast(this)->addURCHandler(UBX_CELL_RING_URC, [this](const char* event){return this->urcCheckRing(event);}); - } - - UBX_CELL_error_t dial(String number) - { - char *command; - char *numberCStr; - UBX_CELL_error_t err; - - numberCStr = static_cast(this)->ubx_cell_calloc_char(number.length() + 1); - if (numberCStr == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - number.toCharArray(numberCStr, number.length() + 1); - - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_DIAL) + strlen(numberCStr) + 3); - if (command != nullptr) + public: + UBX_CELL_VOICE(void) { - // Heads up! The dial command is one of the only commands that requires a - // semicolon at the end of it! - sprintf(command, "%s=%s;", UBX_CELL_COMMAND_DIAL, numberCStr); - - err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, - nullptr, UBX_CELL_10_SEC_TIMEOUT); - - free(command); + // Set ring URC callback to nullptr + _ringCallback = nullptr; + + // Add handler for ring URC + static_cast(this)->addURCHandler(UBX_CELL_RING_URC, + [this](const char *event) { return this->urcCheckRing(event); }); + } + + UBX_CELL_error_t dial(String number) + { + char *command; + char *numberCStr; + UBX_CELL_error_t err; + + numberCStr = static_cast(this)->ubx_cell_calloc_char(number.length() + 1); + if (numberCStr == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + number.toCharArray(numberCStr, number.length() + 1); + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_DIAL) + strlen(numberCStr) + 3); + if (command != nullptr) + { + // Heads up! The dial command is one of the only commands that requires a + // semicolon at the end of it! + sprintf(command, "%s=%s;", UBX_CELL_COMMAND_DIAL, numberCStr); + + err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, nullptr, + UBX_CELL_10_SEC_TIMEOUT); + + free(command); + } + else + { + err = UBX_CELL_ERROR_OUT_OF_MEMORY; + } + + free(numberCStr); + + return err; + } + + UBX_CELL_error_t answer(void) + { + return static_cast(this)->sendCommandWithResponse(UBX_CELL_COMMAND_ANSWER, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + } + + UBX_CELL_error_t hangUp(void) + { + return static_cast(this)->sendCommandWithResponse(UBX_CELL_COMMAND_HANG_UP, UBX_CELL_RESPONSE_OK_OR_ERROR, + nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + } + + UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id = 0, uint8_t nof_repeat = 0) + { + UBX_CELL_error_t err; + char *command; + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat); + + err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; + } + + UBX_CELL_error_t stopAudioResource(uint8_t audio_resource) + { + UBX_CELL_error_t err; + char *command; + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource); + + err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; + } + + UBX_CELL_error_t generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume) + { + UBX_CELL_error_t err; + char *command; + char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume); + + err = static_cast(this)->sendCommandWithResponse(command, response, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; } - else + + UBX_CELL_error_t generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume) { - err = UBX_CELL_ERROR_OUT_OF_MEMORY; + UBX_CELL_error_t err; + char *command; + char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; + + command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14); + if (command == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; + sprintf(command, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume); + + err = static_cast(this)->sendCommandWithResponse(command, response, nullptr, + UBX_CELL_STANDARD_RESPONSE_TIMEOUT); + free(command); + return err; } - free(numberCStr); - - return err; - } - - UBX_CELL_error_t answer(void) - { - return static_cast(this)->sendCommandWithResponse(UBX_CELL_COMMAND_ANSWER, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - } - - UBX_CELL_error_t hangUp(void) - { - return static_cast(this)->sendCommandWithResponse(UBX_CELL_COMMAND_HANG_UP, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - } - - UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id = 0, uint8_t nof_repeat = 0) - { - UBX_CELL_error_t err; - char *command; - - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat); - - err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; - } - - UBX_CELL_error_t stopAudioResource(uint8_t audio_resource) - { - UBX_CELL_error_t err; - char *command; - - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource); - - err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; - } - - UBX_CELL_error_t generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume) - { - UBX_CELL_error_t err; - char *command; - char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; - - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume); - - err = static_cast(this)->sendCommandWithResponse(command, response, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; - } - - UBX_CELL_error_t generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume) - { - UBX_CELL_error_t err; - char *command; - char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; - - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume); - - err = static_cast(this)->sendCommandWithResponse(command, response, - nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; - } - - void setRingCallback(void (*callback)(void)) - { - _ringCallback = callback; - } - -protected: - // Callback for incoming calls - void (*_ringCallback)(void); - - bool urcCheckRing(const char *event) - { - int socket, length; - char *searchPtr = strstr(event, UBX_CELL_RING_URC); - if (searchPtr != nullptr) + void setRingCallback(void (*callback)(void)) { - if(_ringCallback != nullptr) - { - _ringCallback(); - } - return true; + _ringCallback = callback; } - return false; - } + protected: + // Callback for incoming calls + void (*_ringCallback)(void); + + bool urcCheckRing(const char *event) + { + int socket, length; + char *searchPtr = strstr(event, UBX_CELL_RING_URC); + if (searchPtr != nullptr) + { + if (_ringCallback != nullptr) + { + _ringCallback(); + } + return true; + } + + return false; + } }; class UBX_CELL_VOICE_BASE : public UBX_CELL, public UBX_CELL_VOICE { - }; #endif \ No newline at end of file From 14c52f3bc0645ddbea7e23da7c61b7ceaf001f1d Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Wed, 13 Dec 2023 13:03:50 -0700 Subject: [PATCH 45/52] Run examples through formatter Clang formatter in VS Code set to Microsoft style --- .../AudioExample1_PlayTone.ino | 218 ++++---- .../AudioExample2_Loopback.ino | 99 ++-- .../AudioExample3_CallControl.ino | 198 ++++---- .../Example1_DeviceIdentification.ino | 112 ++--- .../Example2_NetworkInfo.ino | 171 +++---- .../Example3_RegisterOperator.ino | 465 ++++++++++-------- examples/Example4_Clock/Example4_Clock.ino | 84 ++-- examples/Example5_Ping/Example5_Ping.ino | 204 ++++---- .../Example6_ReceiveSMS.ino | 413 ++++++++-------- .../Example7_SendSMS/Example7_SendSMS.ino | 192 ++++---- 10 files changed, 1118 insertions(+), 1038 deletions(-) diff --git a/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino b/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino index 60f802d..c270e19 100644 --- a/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino +++ b/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino @@ -13,117 +13,133 @@ UBX_CELL_VOICE_BASE myModule; // This example works with all voice-enabled modul void setup() { - Serial.begin(115200); // Start the serial console - - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Audio Example 1 - Play Tone")); - - Serial.println(); - Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); - Serial.println(F("This example requires an audio codec attached to the I2S interface")); - Serial.println(F("of the cellular modem. Please add one and update this example as")); - Serial.println(F("needed to configure your audio codec!")); - Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); - Serial.println(); - - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); - - Serial.println(F("Beginning...")); - - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); - - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Audio Example 1 - Play Tone")); + + Serial.println(); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); + Serial.println(F("This example requires an audio codec attached to the I2S interface")); + Serial.println(F("of the cellular modem. Please add one and update this example as")); + Serial.println(F("needed to configure your audio codec!")); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); + Serial.println(); + + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail + } + Serial.println(); } void loop() { - String inputString; - char dtmfChar = 0; - uint16_t frequency = 0; - uint16_t duration = 0; - uint8_t volume = 0; - - while(true) - { - while(Serial.available() != 0){Serial.read();} - Serial.println(F("Enter a frequency in Hz (300-3400) or a DTMF character (0-9, *, #)")); - while(Serial.available() == 0){} - - inputString = Serial.readStringUntil('\n'); - - if(inputString.length() == 1) + String inputString; + char dtmfChar = 0; + uint16_t frequency = 0; + uint16_t duration = 0; + uint8_t volume = 0; + + while (true) { - dtmfChar = inputString.charAt(0); - if((dtmfChar >= '0' && dtmfChar <= '9') || dtmfChar == '*' || dtmfChar == '#') - { - break; - } + while (Serial.available() != 0) + { + Serial.read(); + } + Serial.println(F("Enter a frequency in Hz (300-3400) or a DTMF character (0-9, *, #)")); + while (Serial.available() == 0) + { + } + + inputString = Serial.readStringUntil('\n'); + + if (inputString.length() == 1) + { + dtmfChar = inputString.charAt(0); + if ((dtmfChar >= '0' && dtmfChar <= '9') || dtmfChar == '*' || dtmfChar == '#') + { + break; + } + } + else + { + frequency = inputString.toInt(); + if (frequency >= 300 && frequency <= 3400) + { + dtmfChar == 0; + break; + } + } } - else + + while (true) { - frequency = inputString.toInt(); - if(frequency >= 300 && frequency <= 3400) - { - dtmfChar == 0; - break; - } + while (Serial.available() != 0) + { + Serial.read(); + } + Serial.println(F("Enter a duration in ms (50-1360)")); + while (Serial.available() == 0) + { + } + + inputString = Serial.readStringUntil('\n'); + duration = inputString.toInt(); + if (duration >= 50 && duration <= 1360) + { + break; + } } - } - - while(true) - { - while(Serial.available() != 0){Serial.read();} - Serial.println(F("Enter a duration in ms (50-1360)")); - while(Serial.available() == 0){} - - inputString = Serial.readStringUntil('\n'); - duration = inputString.toInt(); - if(duration >= 50 && duration <= 1360) + + while (true) { - break; + while (Serial.available() != 0) + { + Serial.read(); + } + Serial.println(F("Enter a volume (0-100)")); + while (Serial.available() == 0) + { + } + + inputString = Serial.readStringUntil('\n'); + volume = inputString.toInt(); + if (volume <= 100) + { + break; + } } - } - - while(true) - { - while(Serial.available() != 0){Serial.read();} - Serial.println(F("Enter a volume (0-100)")); - while(Serial.available() == 0){} - - inputString = Serial.readStringUntil('\n'); - volume = inputString.toInt(); - if(volume <= 100) + + if (dtmfChar == 0) + { + myModule.generateToneFreq(frequency, duration, volume); + } + else { - break; + myModule.generateToneDTMF(dtmfChar, duration, volume); } - } - - if(dtmfChar == 0) - { - myModule.generateToneFreq(frequency, duration, volume); - } - else - { - myModule.generateToneDTMF(dtmfChar, duration, volume); - } } \ No newline at end of file diff --git a/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino b/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino index b07ce47..44aaee0 100644 --- a/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino +++ b/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino @@ -13,59 +13,70 @@ UBX_CELL_VOICE_BASE myModule; // This example works with all voice-enabled modul void setup() { - Serial.begin(115200); // Start the serial console + Serial.begin(115200); // Start the serial console - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Audio Example 2 - Loopback")); + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Audio Example 2 - Loopback")); - Serial.println(); - Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); - Serial.println(F("This example requires an audio codec attached to the I2S interface")); - Serial.println(F("of the cellular modem. Please add one and update this example as")); - Serial.println(F("needed to configure your audio codec!")); - Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); - Serial.println(); + Serial.println(); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); + Serial.println(F("This example requires an audio codec attached to the I2S interface")); + Serial.println(F("of the cellular modem. Please add one and update this example as")); + Serial.println(F("needed to configure your audio codec!")); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); + Serial.println(); - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); + Serial.println(F("Press any key to begin")); - Serial.println(F("Beginning...")); + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + Serial.println(F("Beginning...")); - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail + } + Serial.println(); } void loop() { - while(Serial.available() != 0){Serial.read();} - Serial.println(F("Enter any key to begin loopback")); - while(Serial.available() == 0){} - - myModule.playAudioResource(UBX_CELL_AUDIO_RESOURCE_LOOPBACK); - - while(Serial.available() != 0){Serial.read();} - Serial.println(F("Enter any key to stop loopback")); - while(Serial.available() == 0){} - - myModule.stopAudioResource(UBX_CELL_AUDIO_RESOURCE_LOOPBACK); + while (Serial.available() != 0) + { + Serial.read(); + } + Serial.println(F("Enter any key to begin loopback")); + while (Serial.available() == 0) + { + } + + myModule.playAudioResource(UBX_CELL_AUDIO_RESOURCE_LOOPBACK); + + while (Serial.available() != 0) + { + Serial.read(); + } + Serial.println(F("Enter any key to stop loopback")); + while (Serial.available() == 0) + { + } + + myModule.stopAudioResource(UBX_CELL_AUDIO_RESOURCE_LOOPBACK); } \ No newline at end of file diff --git a/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino b/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino index 47f407f..77f8b31 100644 --- a/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino +++ b/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino @@ -16,114 +16,122 @@ bool incomingCall = false; void ringCallback() { - Serial.println(F("Incoming call! Enter \"A\" to answer, or anything else to reject")); - incomingCall = true; + Serial.println(F("Incoming call! Enter \"A\" to answer, or anything else to reject")); + incomingCall = true; } void setup() { - String currentOperator = ""; - - Serial.begin(115200); // Start the serial console - - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Audio Example 3 - Call Control")); - - Serial.println(); - Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); - Serial.println(F("This example requires an audio codec attached to the I2S interface")); - Serial.println(F("of the cellular modem. Please add one and update this example as")); - Serial.println(F("needed to configure your audio codec!")); - Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); - Serial.println(); - - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); - - Serial.println(F("Beginning...")); - - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); - - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); - - // First check to see if we're connected to an operator: - if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) - { - Serial.print(F("Connected to: ")); - Serial.println(currentOperator); - } - else - { - Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); - while (1) - ; // Do nothing more - } - - // Set callback function for when a new call is received - myModule.setRingCallback(&ringCallback); - - Serial.println(F("Enter a number to dial")); - - // Clear any input - while(Serial.available()){Serial.read();} -} + String currentOperator = ""; -void loop() -{ - String inputString; + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Audio Example 3 - Call Control")); + + Serial.println(); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); + Serial.println(F("This example requires an audio codec attached to the I2S interface")); + Serial.println(F("of the cellular modem. Please add one and update this example as")); + Serial.println(F("needed to configure your audio codec!")); + Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !")); + Serial.println(); + + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); - myModule.bufferedPoll(); + Serial.println(F("Beginning...")); - if(Serial.available()) - { - inputString = Serial.readStringUntil('\n'); - while(Serial.available()){Serial.read();} + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - if(incomingCall) + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) + { + Serial.println(F("Module connected!")); + } + else { - if(inputString == "A" || inputString == "a") - { - Serial.println(F("Answering call, enter any key to hang up")); - myModule.answer(); - callInProgress = true; - } - else - { - Serial.println(F("Rejecting call")); - myModule.hangUp(); - } - incomingCall = false; + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail } - else if(callInProgress == false) + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) { - Serial.println("Dialing " + inputString + ", enter any key to hang up"); - myModule.dial(inputString); - callInProgress = true; + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); } else { - Serial.println(F("Hanging up, enter a new number to dial")); - myModule.hangUp(); - callInProgress = false; + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. " + "Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + // Set callback function for when a new call is received + myModule.setRingCallback(&ringCallback); + + Serial.println(F("Enter a number to dial")); + + // Clear any input + while (Serial.available()) + { + Serial.read(); + } +} + +void loop() +{ + String inputString; + + myModule.bufferedPoll(); + + if (Serial.available()) + { + inputString = Serial.readStringUntil('\n'); + while (Serial.available()) + { + Serial.read(); + } + + if (incomingCall) + { + if (inputString == "A" || inputString == "a") + { + Serial.println(F("Answering call, enter any key to hang up")); + myModule.answer(); + callInProgress = true; + } + else + { + Serial.println(F("Rejecting call")); + myModule.hangUp(); + } + incomingCall = false; + } + else if (callInProgress == false) + { + Serial.println("Dialing " + inputString + ", enter any key to hang up"); + myModule.dial(inputString); + callInProgress = true; + } + else + { + Serial.println(F("Hanging up, enter a new number to dial")); + myModule.hangUp(); + callInProgress = false; + } } - } } \ No newline at end of file diff --git a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino index ba5591c..fa50999 100644 --- a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino +++ b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino @@ -22,80 +22,80 @@ UBX_CELL myModule; // This example works with all modules, so the base class can // LARA_R6801D myModule; // Map SIM states to more readable strings -String simStateString[] = -{ - "Not present", // 0 - "PIN needed", // 1 - "PIN blocked", // 2 - "PUK blocked", // 3 - "Not operational", // 4 - "Restricted", // 5 - "Operational" // 6 +String simStateString[] = { + "Not present", // 0 + "PIN needed", // 1 + "PIN blocked", // 2 + "PUK blocked", // 3 + "Not operational", // 4 + "Restricted", // 5 + "Operational" // 6 }; -// processSIMstate is provided to the u-blox cellular library via a +// processSIMstate is provided to the u-blox cellular library via a // callback setter -- setSIMstateReadCallback. (See setup()) void processSIMstate(UBX_CELL_sim_states_t state) { - Serial.println(); - Serial.print(F("SIM state: ")); - Serial.print(String(state)); - Serial.println(); + Serial.println(); + Serial.print(F("SIM state: ")); + Serial.print(String(state)); + Serial.println(); } void setup() { - Serial.begin(115200); // Start the serial console + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 1 - Device Identification")); + Serial.println(F("Press any key to begin")); - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 1 - Device Identification")); - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); - Serial.println(F("Beginning...")); + Serial.println(F("Beginning...")); - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail + } + Serial.println(); - Serial.println("Manufacturer ID: " + String(myModule.getManufacturerID())); - Serial.println("Model ID: " + String(myModule.getModelID())); - Serial.println("Firmware Version: " + String(myModule.getFirmwareVersion())); - Serial.println("Product Serial No.: " + String(myModule.getSerialNo())); - Serial.println("IMEI: " + String(myModule.getIMEI())); - Serial.println("IMSI: " + String(myModule.getIMSI())); - Serial.println("SIM CCID: " + String(myModule.getCCID())); - Serial.println("Subscriber No.: " + String(myModule.getSubscriberNo())); - Serial.println("Capabilities: " + String(myModule.getCapabilities())); + Serial.println("Manufacturer ID: " + String(myModule.getManufacturerID())); + Serial.println("Model ID: " + String(myModule.getModelID())); + Serial.println("Firmware Version: " + String(myModule.getFirmwareVersion())); + Serial.println("Product Serial No.: " + String(myModule.getSerialNo())); + Serial.println("IMEI: " + String(myModule.getIMEI())); + Serial.println("IMSI: " + String(myModule.getIMSI())); + Serial.println("SIM CCID: " + String(myModule.getCCID())); + Serial.println("Subscriber No.: " + String(myModule.getSubscriberNo())); + Serial.println("Capabilities: " + String(myModule.getCapabilities())); - // Set a callback to return the SIM state once requested - myModule.setSIMstateReportCallback(&processSIMstate); - // Now enable SIM state reporting for states 0 to 6 (by setting the reporting mode LSb) - if (myModule.setSIMstateReportingMode(1) == UBX_CELL_SUCCESS) - Serial.println("SIM state reports requested..."); - // You can disable the SIM staus reports again by calling assetTracker.setSIMstateReportingMode(0) + // Set a callback to return the SIM state once requested + myModule.setSIMstateReportCallback(&processSIMstate); + // Now enable SIM state reporting for states 0 to 6 (by setting the reporting mode LSb) + if (myModule.setSIMstateReportingMode(1) == UBX_CELL_SUCCESS) + Serial.println("SIM state reports requested..."); + // You can disable the SIM staus reports again by calling assetTracker.setSIMstateReportingMode(0) } void loop() { - myModule.poll(); // Keep processing data from the module so we can extract the SIM status + myModule.poll(); // Keep processing data from the module so we can extract the SIM status } \ No newline at end of file diff --git a/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino b/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino index 6b62f57..cf32155 100644 --- a/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino +++ b/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino @@ -22,19 +22,18 @@ UBX_CELL myModule; // This example works with all modules, so the base class can // LARA_R6801D myModule; // Map registration status messages to more readable strings -String registrationString[] = -{ - "Not registered", // 0 - "Registered, home", // 1 - "Searching for operator", // 2 - "Registration denied", // 3 - "Registration unknown", // 4 - "Registered, roaming", // 5 - "Registered, home (SMS only)", // 6 - "Registered, roaming (SMS only)", // 7 - "Registered, emergency service only", // 8 - "Registered, home, CSFB not preferred", // 9 - "Registered, roaming, CSFB not prefered" // 10 +String registrationString[] = { + "Not registered", // 0 + "Registered, home", // 1 + "Searching for operator", // 2 + "Registration denied", // 3 + "Registration unknown", // 4 + "Registered, roaming", // 5 + "Registered, home (SMS only)", // 6 + "Registered, roaming (SMS only)", // 7 + "Registered, emergency service only", // 8 + "Registered, home, CSFB not preferred", // 9 + "Registered, roaming, CSFB not prefered" // 10 }; // If you are based in Europe, you will (probably) need to select MNO_STD_EUROPE @@ -42,82 +41,84 @@ const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL; void setup() { - Serial.begin(115200); // Start the serial console - - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 2 - Network Info")); - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); - - Serial.println(F("Beginning...")); - - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); - - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); - - if (!myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR)) - { - Serial.println(F("Error setting network. Try cycling the power.")); - while (1) ; - } - - Serial.println(F("Network profile set. Ready to go!")); - - // RSSI: Received signal strength: - Serial.println("RSSI: " + String(myModule.rssi())); - // Registration Status - int regStatus = myModule.registration(); - if ((regStatus >= 0) && (regStatus <= 10)) - { - Serial.println("Network registration: " + registrationString[regStatus]); - } - - // Print the Context IDs, Access Point Names and IP Addresses - Serial.println(F("Available PDP (Packet Data Protocol) APNs (Access Point Names) and IP Addresses:")); - Serial.println(F("Context ID:\tAPN Name:\tIP Address:")); - for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++) - { - String apn = ""; - IPAddress ip(0, 0, 0, 0); - myModule.getAPN(cid, &apn, &ip); - if (apn.length() > 0) + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 2 - Network Info")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail + } + Serial.println(); + + if (!myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR)) + { + Serial.println(F("Error setting network. Try cycling the power.")); + while (1) + ; + } + + Serial.println(F("Network profile set. Ready to go!")); + + // RSSI: Received signal strength: + Serial.println("RSSI: " + String(myModule.rssi())); + // Registration Status + int regStatus = myModule.registration(); + if ((regStatus >= 0) && (regStatus <= 10)) + { + Serial.println("Network registration: " + registrationString[regStatus]); + } + + // Print the Context IDs, Access Point Names and IP Addresses + Serial.println(F("Available PDP (Packet Data Protocol) APNs (Access Point Names) and IP Addresses:")); + Serial.println(F("Context ID:\tAPN Name:\tIP Address:")); + for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++) + { + String apn = ""; + IPAddress ip(0, 0, 0, 0); + myModule.getAPN(cid, &apn, &ip); + if (apn.length() > 0) + { + Serial.print(cid); + Serial.print(F("\t\t")); + Serial.print(apn); + Serial.print(F("\t")); + Serial.println(ip); + } + } + + Serial.println(); + + if (regStatus > 0) { - Serial.print(cid); - Serial.print(F("\t\t")); - Serial.print(apn); - Serial.print(F("\t")); - Serial.println(ip); + Serial.println(F("All set. Go to the next example!")); } - } - - Serial.println(); - - if (regStatus > 0) - { - Serial.println(F("All set. Go to the next example!")); - } } void loop() { - // Do nothing. Now that we're registered move on to the next example. + // Do nothing. Now that we're registered move on to the next example. } \ No newline at end of file diff --git a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino index 6532dc8..324b2bc 100644 --- a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino +++ b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino @@ -22,34 +22,48 @@ UBX_CELL myModule; // This example works with all modules, so the base class can // LARA_R6801D myModule; // Map registration status messages to more readable strings -String registrationString[] = -{ - "Not registered", // 0 - "Registered, home", // 1 - "Searching for operator", // 2 - "Registration denied", // 3 - "Registration unknown", // 4 - "Registered, roaming", // 5 - "Registered, home (SMS only)", // 6 - "Registered, roaming (SMS only)", // 7 - "Registered, emergency service only", // 8 - "Registered, home, CSFB not preferred", // 9 - "Registered, roaming, CSFB not prefered" // 10 +String registrationString[] = { + "Not registered", // 0 + "Registered, home", // 1 + "Searching for operator", // 2 + "Registration denied", // 3 + "Registration unknown", // 4 + "Registered, roaming", // 5 + "Registered, home (SMS only)", // 6 + "Registered, roaming (SMS only)", // 7 + "Registered, emergency service only", // 8 + "Registered, home, CSFB not preferred", // 9 + "Registered, roaming, CSFB not prefered" // 10 }; // If you are based in Europe, you will (probably) need to select MNO_STD_EUROPE const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL; -const String MOBILE_NETWORK_STRINGS[] = {"default (Undefined/Regulatory)", "SIM ICCID", "AT&T", "Verizon", - "Telstra", "T-Mobile US", "China Telecom", "Sprint", "Vodafone", "NTT DoCoMo", "Telus", "SoftBank", - "Deutsche Telekom", "US Cellular", "SKT", "global (factory default)", "standard Europe", - "standard Europe No-ePCO", "NOT RECOGNIZED"}; +const String MOBILE_NETWORK_STRINGS[] = {"default (Undefined/Regulatory)", + "SIM ICCID", + "AT&T", + "Verizon", + "Telstra", + "T-Mobile US", + "China Telecom", + "Sprint", + "Vodafone", + "NTT DoCoMo", + "Telus", + "SoftBank", + "Deutsche Telekom", + "US Cellular", + "SKT", + "global (factory default)", + "standard Europe", + "standard Europe No-ePCO", + "NOT RECOGNIZED"}; // Convert the operator number into an index for MOBILE_NETWORK_STRINGS -int convertOperatorNumber( mobile_network_operator_t mno) +int convertOperatorNumber(mobile_network_operator_t mno) { - switch (mno) - { + switch (mno) + { case 0: case 1: case 2: @@ -57,32 +71,32 @@ int convertOperatorNumber( mobile_network_operator_t mno) case 4: case 5: case 6: - return ((int)mno); + return ((int)mno); case 8: - return 7; + return 7; case 19: - return 8; + return 8; case 20: - return 9; + return 9; case 21: - return 10; + return 10; case 28: - return 11; + return 11; case 31: - return 12; + return 12; case 32: - return 13; + return 13; case 39: - return 14; + return 14; case 90: - return 15; + return 15; case 100: - return 16; + return 16; case 101: - return 17; + return 17; default: // NOT RECOGNIZED - return 18; - } + return 18; + } } // This defines the size of the ops struct array. To narrow the operator @@ -91,236 +105,255 @@ int convertOperatorNumber( mobile_network_operator_t mno) #define MAX_OPERATORS 10 // Uncomment this line if you want to be able to communicate directly with the module in the main loop -//#define DEBUG_PASSTHROUGH_ENABLED +// #define DEBUG_PASSTHROUGH_ENABLED void setup() { - int opsAvailable; - struct operator_stats ops[MAX_OPERATORS]; - String currentOperator = ""; - bool newConnection = true; + int opsAvailable; + struct operator_stats ops[MAX_OPERATORS]; + String currentOperator = ""; + bool newConnection = true; - Serial.begin(115200); // Start the serial console + Serial.begin(115200); // Start the serial console - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 3 - Register Operator")); - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 3 - Register Operator")); + Serial.println(F("Press any key to begin")); - Serial.println(F("Beginning...")); + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + Serial.println(F("Beginning...")); - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); - // First check to see if we're already connected to an operator: - if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) { - Serial.print(F("Already connected to: ")); - Serial.println(currentOperator); - // If already connected provide the option to type y to connect to new operator - Serial.println(F("Press y to connect to a new operator, or any other key to continue.\r\n")); - while (!Serial.available()) ; - if (Serial.read() != 'y') + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) { - newConnection = false; + Serial.println(F("Module connected!")); } else { - myModule.deregisterOperator(); // Deregister from the current operator so we can connect to a new one + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail } - while (Serial.available()) Serial.read(); - } + Serial.println(); - if (newConnection) { - // Set MNO to either Verizon, T-Mobile, AT&T, Telstra, etc. - // This will narrow the operator options during our scan later - Serial.println(F("Setting mobile-network operator")); - if (myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR)) + // First check to see if we're already connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) { - Serial.print(F("Set mobile network operator to ")); - Serial.println(MOBILE_NETWORK_STRINGS[convertOperatorNumber(MOBILE_NETWORK_OPERATOR)] + "\r\n"); + Serial.print(F("Already connected to: ")); + Serial.println(currentOperator); + // If already connected provide the option to type y to connect to new operator + Serial.println(F("Press y to connect to a new operator, or any other key to continue.\r\n")); + while (!Serial.available()) + ; + if (Serial.read() != 'y') + { + newConnection = false; + } + else + { + myModule.deregisterOperator(); // Deregister from the current operator so we can connect to a new one + } + while (Serial.available()) + Serial.read(); } - else + + if (newConnection) { - Serial.println(F("Error setting MNO. Try cycling the power. Freezing...")); - while (1) ; - } - - // Wait for user to press button before initiating network scan. - Serial.println(F("Press any key scan for networks..")); - serialWait(); + // Set MNO to either Verizon, T-Mobile, AT&T, Telstra, etc. + // This will narrow the operator options during our scan later + Serial.println(F("Setting mobile-network operator")); + if (myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR)) + { + Serial.print(F("Set mobile network operator to ")); + Serial.println(MOBILE_NETWORK_STRINGS[convertOperatorNumber(MOBILE_NETWORK_OPERATOR)] + "\r\n"); + } + else + { + Serial.println(F("Error setting MNO. Try cycling the power. Freezing...")); + while (1) + ; + } - Serial.println(F("Scanning for networks...this may take up to 3 minutes\r\n")); - // myModule.getOperators takes in a operator_stats struct pointer and max number of - // structs to scan for, then fills up those objects with operator names and numbers - opsAvailable = myModule.getOperators(ops, MAX_OPERATORS); // This will block for up to 3 minutes + // Wait for user to press button before initiating network scan. + Serial.println(F("Press any key scan for networks..")); + serialWait(); - if (opsAvailable > 0) - { - // Pretty-print operators we found: - Serial.println("Found " + String(opsAvailable) + " operators:"); - printOperators(ops, opsAvailable); - Serial.println(String(opsAvailable + 1) + ": use automatic selection"); - Serial.println(); + Serial.println(F("Scanning for networks...this may take up to 3 minutes\r\n")); + // myModule.getOperators takes in a operator_stats struct pointer and max number of + // structs to scan for, then fills up those objects with operator names and numbers + opsAvailable = myModule.getOperators(ops, MAX_OPERATORS); // This will block for up to 3 minutes - // Wait until the user presses a key to initiate an operator connection - Serial.println("Press 1-" + String(opsAvailable + 1) + " to select an operator."); - char c = 0; - bool selected = false; - while (!selected) { - while (!Serial.available()) ; - c = Serial.read(); - int selection = c - '0'; - if ((selection >= 1) && (selection <= (opsAvailable + 1))) { - selected = true; - Serial.println("Connecting to option " + String(selection)); - if (selection == (opsAvailable + 1)) - { - if (myModule.automaticOperatorSelection() == UBX_CELL_SUCCESS) - { - Serial.println("Automatic operator selection: successful\r\n"); - } - else - { - Serial.println(F("Automatic operator selection: error. Reset and try again, or try another network.")); - } - } - else - { - if (myModule.registerOperator(ops[selection - 1]) == UBX_CELL_SUCCESS) - { - Serial.println("Network " + ops[selection - 1].longOp + " registered\r\n"); - } - else + if (opsAvailable > 0) + { + // Pretty-print operators we found: + Serial.println("Found " + String(opsAvailable) + " operators:"); + printOperators(ops, opsAvailable); + Serial.println(String(opsAvailable + 1) + ": use automatic selection"); + Serial.println(); + + // Wait until the user presses a key to initiate an operator connection + Serial.println("Press 1-" + String(opsAvailable + 1) + " to select an operator."); + char c = 0; + bool selected = false; + while (!selected) { - Serial.println(F("Error connecting to operator. Reset and try again, or try another network.")); + while (!Serial.available()) + ; + c = Serial.read(); + int selection = c - '0'; + if ((selection >= 1) && (selection <= (opsAvailable + 1))) + { + selected = true; + Serial.println("Connecting to option " + String(selection)); + if (selection == (opsAvailable + 1)) + { + if (myModule.automaticOperatorSelection() == UBX_CELL_SUCCESS) + { + Serial.println("Automatic operator selection: successful\r\n"); + } + else + { + Serial.println( + F("Automatic operator selection: error. Reset and try again, or try another network.")); + } + } + else + { + if (myModule.registerOperator(ops[selection - 1]) == UBX_CELL_SUCCESS) + { + Serial.println("Network " + ops[selection - 1].longOp + " registered\r\n"); + } + else + { + Serial.println( + F("Error connecting to operator. Reset and try again, or try another network.")); + } + } + } } - } } - } - } - else - { - Serial.println(F("Did not find an operator. Double-check SIM and antenna, reset and try again, or try another network.")); - while (1) ; + else + { + Serial.println(F("Did not find an operator. Double-check SIM and antenna, reset and try again, or try " + "another network.")); + while (1) + ; + } } - } - // At the very end print connection information - printInfo(); + // At the very end print connection information + printInfo(); } void loop() { - // Loop provides a debugging interface. - if (mySerial.available()) { - Serial.write((char) mySerial.read()); - } + // Loop provides a debugging interface. + if (mySerial.available()) + { + Serial.write((char)mySerial.read()); + } #ifdef DEBUG_PASSTHROUGH_ENABLED - if (Serial.available()) { - mySerial.write((char) Serial.read()); - } + if (Serial.available()) + { + mySerial.write((char)Serial.read()); + } #endif } -void printInfo(void) { - String currentApn = ""; - IPAddress ip(0, 0, 0, 0); - String currentOperator = ""; - - Serial.println(F("Connection info:")); - Serial.println(F("Context ID:\tAPN Name:\tIP Address:")); - for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++) - { - String apn = ""; +void printInfo(void) +{ + String currentApn = ""; IPAddress ip(0, 0, 0, 0); - myModule.getAPN(cid, &apn, &ip); - if (apn.length() > 0) + String currentOperator = ""; + + Serial.println(F("Connection info:")); + Serial.println(F("Context ID:\tAPN Name:\tIP Address:")); + for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++) { - Serial.print(cid); - Serial.print(F("\t\t")); - Serial.print(apn); - Serial.print(F("\t")); - Serial.println(ip); + String apn = ""; + IPAddress ip(0, 0, 0, 0); + myModule.getAPN(cid, &apn, &ip); + if (apn.length() > 0) + { + Serial.print(cid); + Serial.print(F("\t\t")); + Serial.print(apn); + Serial.print(F("\t")); + Serial.println(ip); + } } - } - // Operator name or number - if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) - { - Serial.print(F("Operator: ")); - Serial.println(currentOperator); - } + // Operator name or number + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Operator: ")); + Serial.println(currentOperator); + } - // Received signal strength - Serial.println("RSSI: " + String(myModule.rssi())); - Serial.println(); + // Received signal strength + Serial.println("RSSI: " + String(myModule.rssi())); + Serial.println(); } -void printOperators(struct operator_stats * ops, int operatorsAvailable) +void printOperators(struct operator_stats *ops, int operatorsAvailable) { - for (int i = 0; i < operatorsAvailable; i++) - { - Serial.print(String(i + 1) + ": "); - Serial.print(ops[i].longOp + " (" + String(ops[i].numOp) + ") - "); - switch (ops[i].stat) + for (int i = 0; i < operatorsAvailable; i++) { - case 0: - Serial.print(F("UNKNOWN")); - break; - case 1: - Serial.print(F("AVAILABLE")); - break; - case 2: - Serial.print(F("CURRENT")); - break; - case 3: - Serial.print(F("FORBIDDEN")); - break; - } - switch (ops[i].act) - { - case 0: - Serial.print(F(" - GSM")); - break; - case 2: - Serial.print(F(" - UTRAN")); - break; - case 3: - Serial.print(F(" - GSM/GPRS with EDGE")); - break; - case 7: - Serial.print(F(" - LTE")); // SARA-R5 only supports LTE - break; + Serial.print(String(i + 1) + ": "); + Serial.print(ops[i].longOp + " (" + String(ops[i].numOp) + ") - "); + switch (ops[i].stat) + { + case 0: + Serial.print(F("UNKNOWN")); + break; + case 1: + Serial.print(F("AVAILABLE")); + break; + case 2: + Serial.print(F("CURRENT")); + break; + case 3: + Serial.print(F("FORBIDDEN")); + break; + } + switch (ops[i].act) + { + case 0: + Serial.print(F(" - GSM")); + break; + case 2: + Serial.print(F(" - UTRAN")); + break; + case 3: + Serial.print(F(" - GSM/GPRS with EDGE")); + break; + case 7: + Serial.print(F(" - LTE")); // SARA-R5 only supports LTE + break; + } + Serial.println(); } Serial.println(); - } - Serial.println(); } void serialWait() { - while (Serial.available()) Serial.read(); - while (!Serial.available()) ; - delay(100); - while (Serial.available()) Serial.read(); + while (Serial.available()) + Serial.read(); + while (!Serial.available()) + ; + delay(100); + while (Serial.available()) + Serial.read(); } \ No newline at end of file diff --git a/examples/Example4_Clock/Example4_Clock.ino b/examples/Example4_Clock/Example4_Clock.ino index a7a1b25..2e3232b 100644 --- a/examples/Example4_Clock/Example4_Clock.ino +++ b/examples/Example4_Clock/Example4_Clock.ino @@ -23,58 +23,60 @@ UBX_CELL myModule; // This example works with all modules, so the base class can void setup() { - String currentOperator = ""; + String currentOperator = ""; - Serial.begin(115200); // Start the serial console + Serial.begin(115200); // Start the serial console - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 4 - Clock")); - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 4 - Clock")); + Serial.println(F("Press any key to begin")); - Serial.println(F("Beginning...")); + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + Serial.println(F("Beginning...")); - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); - // Make sure automatic time zone updates are enabled - if (myModule.autoTimeZone(true) != UBX_CELL_SUCCESS) - Serial.println(F("Enable autoTimeZone failed!")); + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail + } + Serial.println(); - // Read and print the clock as a String - String theTime = myModule.clock(); - Serial.println(theTime); + // Make sure automatic time zone updates are enabled + if (myModule.autoTimeZone(true) != UBX_CELL_SUCCESS) + Serial.println(F("Enable autoTimeZone failed!")); - // Read and print the hour, minute, etc. separately - uint8_t year, month, day, hour, minute, second; - int8_t timeZone; - if (myModule.clock( &year, &month, &day, &hour, &minute, &second, &timeZone ) == UBX_CELL_SUCCESS) - // Note: not all Arduino boards implement printf correctly. The formatting may not be correct on some boards. - // Note: the timeZone is defined in 15 minute increments, not hours. -28 indicates the time zone is 7 hours behind UTC/GMT. - Serial.printf("%02d/%02d/%02d %02d:%02d:%02d %+d\r\n", year, month, day, hour, minute, second, timeZone); + // Read and print the clock as a String + String theTime = myModule.clock(); + Serial.println(theTime); + + // Read and print the hour, minute, etc. separately + uint8_t year, month, day, hour, minute, second; + int8_t timeZone; + if (myModule.clock(&year, &month, &day, &hour, &minute, &second, &timeZone) == UBX_CELL_SUCCESS) + // Note: not all Arduino boards implement printf correctly. The formatting may not be correct on some boards. + // Note: the timeZone is defined in 15 minute increments, not hours. -28 indicates the time zone is 7 hours + // behind UTC/GMT. + Serial.printf("%02d/%02d/%02d %02d:%02d:%02d %+d\r\n", year, month, day, hour, minute, second, timeZone); } void loop() { - // Nothing to do here + // Nothing to do here } \ No newline at end of file diff --git a/examples/Example5_Ping/Example5_Ping.ino b/examples/Example5_Ping/Example5_Ping.ino index 1de835c..3cc6678 100644 --- a/examples/Example5_Ping/Example5_Ping.ino +++ b/examples/Example5_Ping/Example5_Ping.ino @@ -23,118 +23,120 @@ UBX_CELL myModule; // This example works with all modules, so the base class can String pingMe = ""; // The name of the server we are going to ping -// processPingResult is provided to the u-blox cellular library via a +// processPingResult is provided to the u-blox cellular library via a // callback setter -- setPingCallback. (See the end of setup()) void processPingResult(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt) { - Serial.println(); - Serial.print(F("Ping Result: Retry #:")); - Serial.print(retry); - Serial.print(F(" Ping Size (Bytes):")); - Serial.print(p_size); - Serial.print(F(" Remote Host:\"")); - Serial.print(remote_hostname); - Serial.print(F("\" IP Address:\"")); - Serial.print(String(ip[0])); - Serial.print(F(".")); - Serial.print(String(ip[1])); - Serial.print(F(".")); - Serial.print(String(ip[2])); - Serial.print(F(".")); - Serial.print(String(ip[3])); - Serial.print(F("\" Time To Live (hops):")); - Serial.print(ttl); - Serial.print(F(" Round Trip (ms):")); - Serial.print(rtt); - Serial.println(); + Serial.println(); + Serial.print(F("Ping Result: Retry #:")); + Serial.print(retry); + Serial.print(F(" Ping Size (Bytes):")); + Serial.print(p_size); + Serial.print(F(" Remote Host:\"")); + Serial.print(remote_hostname); + Serial.print(F("\" IP Address:\"")); + Serial.print(String(ip[0])); + Serial.print(F(".")); + Serial.print(String(ip[1])); + Serial.print(F(".")); + Serial.print(String(ip[2])); + Serial.print(F(".")); + Serial.print(String(ip[3])); + Serial.print(F("\" Time To Live (hops):")); + Serial.print(ttl); + Serial.print(F(" Round Trip (ms):")); + Serial.print(rtt); + Serial.println(); } void setup() { - String currentOperator = ""; - - Serial.begin(115200); // Start the serial console - - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 5 - Ping")); - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); - - Serial.println(F("Beginning...")); - - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); - - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); - - // First check to see if we're connected to an operator: - if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) - { - Serial.print(F("Connected to: ")); - Serial.println(currentOperator); - } - else - { - Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); - while (1) - ; // Do nothing more - } - - Serial.println(); - Serial.println(F("*** Set the Serial Monitor line ending to Newline ***")); - - Serial.println(); - Serial.println(F("Enter the name of the server you want to ping (followed by LF / Newline): ")); - Serial.println(F("Example: \"www.google.com\"")); - - // Set a callback to process the Ping result - myModule.setPingCallback(&processPingResult); -} + String currentOperator = ""; -void loop() -{ - if (Serial.available()) - { - char c = Serial.read(); - if (c == '\n') + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 5 - Ping")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) { - // Newline received so let's do that ping! - Serial.println("Pinging " + pingMe + "..."); - myModule.ping(pingMe); // Use the default parameters - - // Use custom parameters - //int retries = 4; // number of retries - //int p_size = 32; // packet size (bytes) - //unsigned long timeout = 5000; // timeout (ms) - //int ttl = 32; // Time To Live - //myModule.ping(pingMe, retries, p_size, timeout, ttl); - - pingMe = ""; // Clear the server name for the next try + Serial.println(F("Module connected!")); } else { - // Add serial characters to the server address - pingMe += c; + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); } - } - - myModule.poll(); // Keep processing data from the module so we can catch the Ping result + else + { + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. " + "Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + Serial.println(); + Serial.println(F("*** Set the Serial Monitor line ending to Newline ***")); + + Serial.println(); + Serial.println(F("Enter the name of the server you want to ping (followed by LF / Newline): ")); + Serial.println(F("Example: \"www.google.com\"")); + + // Set a callback to process the Ping result + myModule.setPingCallback(&processPingResult); +} + +void loop() +{ + if (Serial.available()) + { + char c = Serial.read(); + if (c == '\n') + { + // Newline received so let's do that ping! + Serial.println("Pinging " + pingMe + "..."); + myModule.ping(pingMe); // Use the default parameters + + // Use custom parameters + // int retries = 4; // number of retries + // int p_size = 32; // packet size (bytes) + // unsigned long timeout = 5000; // timeout (ms) + // int ttl = 32; // Time To Live + // myModule.ping(pingMe, retries, p_size, timeout, ttl); + + pingMe = ""; // Clear the server name for the next try + } + else + { + // Add serial characters to the server address + pingMe += c; + } + } + + myModule.poll(); // Keep processing data from the module so we can catch the Ping result } \ No newline at end of file diff --git a/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino b/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino index ae5a336..416b45f 100644 --- a/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino +++ b/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino @@ -23,234 +23,239 @@ UBX_CELL myModule; // This example works with all modules, so the base class can void setup() { - String currentOperator = ""; + String currentOperator = ""; - Serial.begin(115200); // Start the serial console + Serial.begin(115200); // Start the serial console - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 6 - Receive SMS")); - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 6 - Receive SMS")); + Serial.println(F("Press any key to begin")); - Serial.println(F("Beginning...")); + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + Serial.println(F("Beginning...")); - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); - // First check to see if we're connected to an operator: - if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) - { - Serial.print(F("Connected to: ")); - Serial.println(currentOperator); - } - else - { - Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); - while (1) - ; // Do nothing more - } + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. " + "Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); } void loop() { - static bool printReadMessages = true; // Print all messages once. Then only print new messages. Unless a message is deleted. - static int previousUsed = -1; // Store the previous number of used memory locations - - // Read the number of used and total messages - int used; - int total; - if (myModule.getPreferredMessageStorage(&used, &total) != UBX_CELL_SUCCESS) - { - Serial.println(F("An error occurred when trying to read ME memory!")); - } - else - { - if ((used != previousUsed) || printReadMessages) // Has a new message arrived? Or was the delete menu opened? - { - Serial.print(F("\r\nNumber of used memory locations: ")); - Serial.println(used); - Serial.print(F("Total number of memory locations: ")); - Serial.println(total); - Serial.println(); + static bool printReadMessages = + true; // Print all messages once. Then only print new messages. Unless a message is deleted. + static int previousUsed = -1; // Store the previous number of used memory locations - int memoryLocation = 0; - int foundMessages = 0; - // Keep reading until we find all the messages or we reach the end of the memory - while ((foundMessages < used) && (memoryLocation <= total)) - { - String unread = ""; - String from = ""; - String dateTime = ""; - String message = ""; - // Read the message from this location. Reading from empty message locations returns an ERROR - // unread can be: "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT" - // If the location is empty, readSMSmessage will return a UBX_CELL_ERROR_UNEXPECTED_RESPONSE - if (myModule.readSMSmessage(memoryLocation, &unread, &from, &dateTime, &message) == UBX_CELL_SUCCESS) + // Read the number of used and total messages + int used; + int total; + if (myModule.getPreferredMessageStorage(&used, &total) != UBX_CELL_SUCCESS) + { + Serial.println(F("An error occurred when trying to read ME memory!")); + } + else + { + if ((used != previousUsed) || printReadMessages) // Has a new message arrived? Or was the delete menu opened? { - if (printReadMessages || (unread == "REC UNREAD")) - { - Serial.print(F("Message location: ")); - Serial.println(memoryLocation); - Serial.print(F("Status: ")); - Serial.println(unread); - Serial.print(F("Originator: ")); - Serial.println(from); - Serial.print(F("Date and time: ")); - Serial.println(dateTime); - Serial.println(message); + Serial.print(F("\r\nNumber of used memory locations: ")); + Serial.println(used); + Serial.print(F("Total number of memory locations: ")); + Serial.println(total); Serial.println(); - } - foundMessages++; // We found a message - } - memoryLocation++; // Move on to the next memory location - } - printReadMessages = false; - previousUsed = used; // Update previousUsed + int memoryLocation = 0; + int foundMessages = 0; + // Keep reading until we find all the messages or we reach the end of the memory + while ((foundMessages < used) && (memoryLocation <= total)) + { + String unread = ""; + String from = ""; + String dateTime = ""; + String message = ""; + // Read the message from this location. Reading from empty message locations returns an ERROR + // unread can be: "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT" + // If the location is empty, readSMSmessage will return a UBX_CELL_ERROR_UNEXPECTED_RESPONSE + if (myModule.readSMSmessage(memoryLocation, &unread, &from, &dateTime, &message) == UBX_CELL_SUCCESS) + { + if (printReadMessages || (unread == "REC UNREAD")) + { + Serial.print(F("Message location: ")); + Serial.println(memoryLocation); + Serial.print(F("Status: ")); + Serial.println(unread); + Serial.print(F("Originator: ")); + Serial.println(from); + Serial.print(F("Date and time: ")); + Serial.println(dateTime); + Serial.println(message); + Serial.println(); + } + foundMessages++; // We found a message + } + memoryLocation++; // Move on to the next memory location + } - Serial.println(F("Waiting for a new message...")); - Serial.println(); - Serial.println(F("Hit any key to delete a message...")); - Serial.println(); - } - } + printReadMessages = false; + previousUsed = used; // Update previousUsed - int delayCount = 0; - while (delayCount < 5000) - { - delay(1); // Delay for five seconds, unless the user presses a key - delayCount++; + Serial.println(F("Waiting for a new message...")); + Serial.println(); + Serial.println(F("Hit any key to delete a message...")); + Serial.println(); + } + } - if (Serial.available()) + int delayCount = 0; + while (delayCount < 5000) { - Serial.println(F("To delete a single message: enter its location followed by LF / Newline")); - Serial.println(F("To delete all read messages: enter r followed by LF / Newline")); - Serial.println(F("To delete all read and sent messages: enter s followed by LF / Newline")); - Serial.println(F("To delete all read, sent and unsent messages: enter u followed by LF / Newline")); - Serial.println(F("To delete all messages, including unread messages: enter a followed by LF / Newline")); - Serial.println(F("To exit: enter LF / Newline")); + delay(1); // Delay for five seconds, unless the user presses a key + delayCount++; - Serial.read(); // Read and discard the char that opened the menu - - int location = 0; - bool selected = false; - while (!selected) - { - while (!Serial.available()) ; // Wait for a character to arrive - char c = Serial.read(); // Read it - if (c == '\n') // Is it a LF? + if (Serial.available()) { - if ((location >= 1) && (location <= total)) // Delete a single message at location - { - if (myModule.deleteSMSmessage(location) == UBX_CELL_SUCCESS) - { - Serial.println(F("\r\nMessage deleted!\r\n")); - printReadMessages = true; - } - else - { - Serial.println(F("\r\nMessage not deleted!\r\n")); - } - } - else if (location == 1001) // r - { - if (myModule.deleteReadSMSmessages() == UBX_CELL_SUCCESS) - { - Serial.println(F("\r\nRead messages deleted!\r\n")); - printReadMessages = true; - } - else - { - Serial.println(F("\r\nMessages not deleted!\r\n")); - } - } - else if (location == 1002) // s - { - if (myModule.deleteReadSentSMSmessages() == UBX_CELL_SUCCESS) - { - Serial.println(F("\r\nRead and sent messages deleted!\r\n")); - printReadMessages = true; - } - else - { - Serial.println(F("\r\nMessages not deleted!\r\n")); - } - } - else if (location == 1003) // u - { - if (myModule.deleteReadSentUnsentSMSmessages() == UBX_CELL_SUCCESS) - { - Serial.println(F("\r\nRead, sent and unsent messages deleted!\r\n")); - printReadMessages = true; - } - else - { - Serial.println(F("\r\nMessages not deleted!\r\n")); - } - } - else if (location == 1004) // a - { - if (myModule.deleteAllSMSmessages() == UBX_CELL_SUCCESS) - { - Serial.println(F("\r\nAll messages deleted!\r\n")); - printReadMessages = true; - } - else + Serial.println( + F("To delete a single message: enter its location followed by LF / Newline")); + Serial.println(F("To delete all read messages: enter r followed by LF / Newline")); + Serial.println(F("To delete all read and sent messages: enter s followed by LF / Newline")); + Serial.println(F("To delete all read, sent and unsent messages: enter u followed by LF / Newline")); + Serial.println(F("To delete all messages, including unread messages: enter a followed by LF / Newline")); + Serial.println(F("To exit: enter LF / Newline")); + + Serial.read(); // Read and discard the char that opened the menu + + int location = 0; + bool selected = false; + while (!selected) { - Serial.println(F("\r\nMessages not deleted!\r\n")); + while (!Serial.available()) + ; // Wait for a character to arrive + char c = Serial.read(); // Read it + if (c == '\n') // Is it a LF? + { + if ((location >= 1) && (location <= total)) // Delete a single message at location + { + if (myModule.deleteSMSmessage(location) == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nMessage deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessage not deleted!\r\n")); + } + } + else if (location == 1001) // r + { + if (myModule.deleteReadSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nRead messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else if (location == 1002) // s + { + if (myModule.deleteReadSentSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nRead and sent messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else if (location == 1003) // u + { + if (myModule.deleteReadSentUnsentSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nRead, sent and unsent messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else if (location == 1004) // a + { + if (myModule.deleteAllSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nAll messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else + Serial.println(F("\r\nExit...\r\n")); + selected = true; + } + else if ((c >= '0') && (c <= '9')) + { + location *= 10; // Multiply by 10 + location += c - '0'; // Add the digit + } + else if (c == 'r') + { + location = 1001; + } + else if (c == 's') + { + location = 1002; + } + else if (c == 'u') + { + location = 1003; + } + else if (c == 'a') + { + location = 1004; + } } - } - else - Serial.println(F("\r\nExit...\r\n")); - selected = true; - } - else if ((c >= '0') && (c <= '9')) - { - location *= 10; // Multiply by 10 - location += c - '0'; // Add the digit - } - else if (c == 'r') - { - location = 1001; - } - else if (c == 's') - { - location = 1002; - } - else if (c == 'u') - { - location = 1003; - } - else if (c == 'a') - { - location = 1004; - } - } - delayCount = 5000; + delayCount = 5000; + } } - } } \ No newline at end of file diff --git a/examples/Example7_SendSMS/Example7_SendSMS.ino b/examples/Example7_SendSMS/Example7_SendSMS.ino index 79bda44..8e6e11f 100644 --- a/examples/Example7_SendSMS/Example7_SendSMS.ino +++ b/examples/Example7_SendSMS/Example7_SendSMS.ino @@ -23,107 +23,109 @@ UBX_CELL myModule; // This example works with all modules, so the base class can void setup() { - String currentOperator = ""; - - Serial.begin(115200); // Start the serial console - - // Wait for user to press key to begin - Serial.println(F("u-blox Cellular Example 7 - Send SMS")); - Serial.println(F("Press any key to begin")); - - while (!Serial.available()) // Wait for the user to press a key (send any serial character) - ; - while (Serial.available()) // Empty the serial RX buffer - Serial.read(); - - Serial.println(F("Beginning...")); - - // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial - - // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low - // Uncomment the next line if required - // myModule.invertPowerPin(true); - - // Initialize the module - if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) - { - Serial.println(F("Module connected!")); - } - else - { - Serial.println(F("Unable to communicate with the module.")); - Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); - while (1) ; // Loop forever on fail - } - Serial.println(); - - // First check to see if we're connected to an operator: - if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) - { - Serial.print(F("Connected to: ")); - Serial.println(currentOperator); - } - else - { - Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); - while (1) - ; // Do nothing more - } - - Serial.println(); - Serial.println(F("*** Set the Serial Monitor line ending to Newline ***")); + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 7 - Send SMS")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. " + "Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + Serial.println(); + Serial.println(F("*** Set the Serial Monitor line ending to Newline ***")); } void loop() { - String destinationNumber = ""; - String message = ""; - boolean keepGoing = true; - - Serial.println(); - Serial.println(F("Enter the destination number (followed by LF / Newline): ")); - - while (keepGoing) - { - if (Serial.available()) + String destinationNumber = ""; + String message = ""; + boolean keepGoing = true; + + Serial.println(); + Serial.println(F("Enter the destination number (followed by LF / Newline): ")); + + while (keepGoing) + { + if (Serial.available()) + { + char c = Serial.read(); + if (c == '\n') + { + keepGoing = false; // Stop if we receive a newline + } + else + { + destinationNumber += c; // Add serial characters to the destination number + } + } + } + + keepGoing = true; + Serial.println(); + Serial.println(F("Enter the message (followed by LF): ")); + + while (keepGoing) { - char c = Serial.read(); - if (c == '\n') - { - keepGoing = false; // Stop if we receive a newline - } - else - { - destinationNumber += c; // Add serial characters to the destination number - } + if (Serial.available()) + { + char c = Serial.read(); + if (c == '\n') + { + keepGoing = false; // Stop if we receive a newline + } + else + { + message += c; // Add serial characters to the destination number + } + } } - } - - keepGoing = true; - Serial.println(); - Serial.println(F("Enter the message (followed by LF): ")); - - while (keepGoing) - { - if (Serial.available()) + + // Once we receive a newline, send the text. + Serial.println("Sending: \"" + message + "\" to " + destinationNumber); + // Call myModule.sendSMS(String number, String message) to send an SMS message. + if (myModule.sendSMS(destinationNumber, message) == UBX_CELL_SUCCESS) { - char c = Serial.read(); - if (c == '\n') - { - keepGoing = false; // Stop if we receive a newline - } - else - { - message += c; // Add serial characters to the destination number - } + Serial.println(F("sendSMS was successful")); } - } - - // Once we receive a newline, send the text. - Serial.println("Sending: \"" + message + "\" to " + destinationNumber); - // Call myModule.sendSMS(String number, String message) to send an SMS message. - if (myModule.sendSMS(destinationNumber, message) == UBX_CELL_SUCCESS) - { - Serial.println(F("sendSMS was successful")); - } } \ No newline at end of file From 6a7ee7ff973567e1c309b954755db73d55c18dee Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 18 Dec 2023 12:55:13 -0700 Subject: [PATCH 46/52] Change sprintf to snprintf --- src/sfe_sara_r5.cpp | 59 ++-- src/sfe_ublox_cellular.cpp | 607 ++++++++++++++++++++------------- src/sfe_ublox_cellular_voice.h | 25 +- 3 files changed, 411 insertions(+), 280 deletions(-) diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp index 34a4992..ae66359 100644 --- a/src/sfe_sara_r5.cpp +++ b/src/sfe_sara_r5.cpp @@ -9,15 +9,16 @@ SARA_R5::SARA_R5() UBX_CELL_error_t SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utime_sensor_t sensor) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (mode == UBX_CELL_UTIME_MODE_STOP) // stop UTIME does not require a sensor - sprintf(command, "%s=%d", UBX_CELL_GNSS_REQUEST_TIME, mode); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_GNSS_REQUEST_TIME, mode); else - sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_REQUEST_TIME, mode, sensor); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_GNSS_REQUEST_TIME, mode, sensor); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); free(command); @@ -27,16 +28,17 @@ UBX_CELL_error_t SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utim UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2; char *command; char *response; UBX_CELL_utime_mode_t m; UBX_CELL_utime_sensor_t s; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_REQUEST_TIME); + snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_REQUEST_TIME); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -83,12 +85,13 @@ UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_uti UBX_CELL_error_t SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t config) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_GNSS_TIME_INDICATION, config); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_GNSS_TIME_INDICATION, config); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); @@ -98,15 +101,16 @@ UBX_CELL_error_t SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2; char *command; char *response; UBX_CELL_utime_urc_configuration_t c; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_TIME_INDICATION); + snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_TIME_INDICATION); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -146,15 +150,16 @@ UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t UBX_CELL_error_t SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - sprintf(command, "%s=%d,%d", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); #else - sprintf(command, "%s=%ld,%ld", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); + snprintf(command, cmdLen, "%s=%ld,%ld", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); #endif err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -165,16 +170,17 @@ UBX_CELL_error_t SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32 UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2; char *command; char *response; int32_t ons; int32_t os; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_TIME_CONFIGURATION); + snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_TIME_CONFIGURATION); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -218,15 +224,16 @@ UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int3 UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24; char *command; if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -244,15 +251,16 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur String value) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64; char *command; if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value.c_str()); + snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -264,15 +272,16 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur IPAddress value) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64; char *command; if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value[0], value[1], + snprintf(command, cmdLen, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value[0], value[1], value[2], value[3]); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -284,15 +293,16 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur UBX_CELL_error_t SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t action) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32; char *command; if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_ACTION, profile, action); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_ACTION, profile, action); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -302,6 +312,7 @@ UBX_CELL_error_t SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t a UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *address) { + size_t cmdLen = strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16; char *command; char *response; UBX_CELL_error_t err; @@ -310,10 +321,10 @@ UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *ad int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation int paramVals[4]; - command = ubx_cell_calloc_char(strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBX_CELL_NETWORK_ASSIGNED_DATA, profile, paramTag); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_NETWORK_ASSIGNED_DATA, profile, paramTag); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index e7fbe8f..1238c76 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -969,10 +969,11 @@ UBX_CELL_error_t UBX_CELL::setRegistrationCallback(void (*registrationCallback)( { _registrationCallback = registrationCallback; - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_REGISTRATION_STATUS) + 3); + size_t cmdLen = strlen(UBX_CELL_REGISTRATION_STATUS) + 3; + char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_REGISTRATION_STATUS, 2 /*enable URC with location*/); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_REGISTRATION_STATUS, 2 /*enable URC with location*/); UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); @@ -984,10 +985,11 @@ UBX_CELL_error_t UBX_CELL::setEpsRegistrationCallback( { _epsRegistrationCallback = registrationCallback; - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_EPSREGISTRATION_STATUS) + 3); + size_t cmdLen = strlen(UBX_CELL_EPSREGISTRATION_STATUS) + 3; + char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_EPSREGISTRATION_STATUS, 2 /*enable URC with location*/); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_EPSREGISTRATION_STATUS, 2 /*enable URC with location*/); UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); @@ -1021,12 +1023,13 @@ UBX_CELL_error_t UBX_CELL::at(void) UBX_CELL_error_t UBX_CELL::enableEcho(bool enable) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_ECHO) + 2; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_ECHO) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s%d", UBX_CELL_COMMAND_ECHO, enable ? 1 : 0); + snprintf(command, cmdLen, "%s%d", UBX_CELL_COMMAND_ECHO, enable ? 1 : 0); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -1267,15 +1270,16 @@ UBX_CELL_error_t UBX_CELL::reset(void) String UBX_CELL::clock(void) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_CLOCK) + 2; char *command; char *response; char *clockBegin; char *clockEnd; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return ""; - sprintf(command, "%s?", UBX_CELL_COMMAND_CLOCK); + snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_CLOCK); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -1321,6 +1325,7 @@ String UBX_CELL::clock(void) UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_CLOCK) + 2; char *command; char *response; char tzPlusMinus; @@ -1328,10 +1333,10 @@ UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h int iy, imo, id, ih, imin, is, itz; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_COMMAND_CLOCK); + snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_CLOCK); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -1379,7 +1384,7 @@ UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h UBX_CELL_error_t UBX_CELL::setClock(uint8_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t min, uint8_t s, int8_t tz) { // Convert y,mo,d,h,min,s,tz into a String - // Some platforms don't support sprintf correctly (for %02d or %+02d) so we need to build the String manually + // Some platforms don't support snprintf correctly (for %02d or %+02d) so we need to build the String manually // Format is "yy/MM/dd,hh:mm:ss+TZ" // TZ can be +/- and is in increments of 15 minutes (not hours) @@ -1418,12 +1423,13 @@ UBX_CELL_error_t UBX_CELL::setClock(uint8_t y, uint8_t mo, uint8_t d, uint8_t h, UBX_CELL_error_t UBX_CELL::setClock(String theTime) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_CLOCK) + theTime.length() + 8; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_CLOCK) + theTime.length() + 8); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_COMMAND_CLOCK, theTime.c_str()); + snprintf(command, cmdLen, "%s=\"%s\"", UBX_CELL_COMMAND_CLOCK, theTime.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -1439,12 +1445,13 @@ void UBX_CELL::autoTimeZoneForBegin(bool tz) UBX_CELL_error_t UBX_CELL::autoTimeZone(bool enable) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_AUTO_TZ) + 3; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_AUTO_TZ) + 3); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_COMMAND_AUTO_TZ, enable ? 1 : 0); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_COMMAND_AUTO_TZ, enable ? 1 : 0); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); @@ -1453,15 +1460,16 @@ UBX_CELL_error_t UBX_CELL::autoTimeZone(bool enable) int8_t UBX_CELL::rssi(void) { + size_t cmdLen = strlen(UBX_CELL_SIGNAL_QUALITY) + 1; char *command; char *response; UBX_CELL_error_t err; int rssi; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SIGNAL_QUALITY) + 1); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s", UBX_CELL_SIGNAL_QUALITY); + snprintf(command, cmdLen, "%s", UBX_CELL_SIGNAL_QUALITY); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -1500,17 +1508,15 @@ int8_t UBX_CELL::rssi(void) UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality &signal_quality) { + size_t cmdLen = strlen(UBX_CELL_EXT_SIGNAL_QUALITY) + 1; char *command; char *response; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(strlen(UBX_CELL_EXT_SIGNAL_QUALITY) + 1); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) - { return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - - sprintf(command, "%s", UBX_CELL_EXT_SIGNAL_QUALITY); + snprintf(command, cmdLen, "%s", UBX_CELL_EXT_SIGNAL_QUALITY); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -1553,15 +1559,17 @@ UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality &signal_quality) UBX_CELL_registration_status_t UBX_CELL::registration(bool eps) { + const char *tag = eps ? UBX_CELL_EPSREGISTRATION_STATUS : UBX_CELL_REGISTRATION_STATUS; + size_t cmdLen = strlen(tag) + 3; char *command; char *response; UBX_CELL_error_t err; int status; - const char *tag = eps ? UBX_CELL_EPSREGISTRATION_STATUS : UBX_CELL_REGISTRATION_STATUS; - command = ubx_cell_calloc_char(strlen(tag) + 3); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_REGISTRATION_INVALID; - sprintf(command, "%s?", tag); + snprintf(command, cmdLen, "%s?", tag); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -1648,6 +1656,7 @@ mobile_network_operator_t UBX_CELL::getNetworkProfile(void) UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdpType) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_DEF) + strlen(apn.c_str()) + 16; char *command; char pdpStr[8]; @@ -1656,7 +1665,7 @@ UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdp if (cid >= 8) return UBX_CELL_ERROR_UNEXPECTED_PARAM; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_DEF) + strlen(apn.c_str()) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; switch (pdpType) @@ -1686,7 +1695,7 @@ UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdp { if (_printDebug == true) _debugPort->println(F("setAPN: nullptr")); - sprintf(command, "%s=%d,\"%s\",\"\"", UBX_CELL_MESSAGE_PDP_DEF, cid, pdpStr); + snprintf(command, cmdLen, "%s=%d,\"%s\",\"\"", UBX_CELL_MESSAGE_PDP_DEF, cid, pdpStr); } else { @@ -1695,7 +1704,7 @@ UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdp _debugPort->print(F("setAPN: ")); _debugPort->println(apn); } - sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MESSAGE_PDP_DEF, cid, pdpStr, apn.c_str()); + snprintf(command, cmdLen, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MESSAGE_PDP_DEF, cid, pdpStr, apn.c_str()); } err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -1709,16 +1718,17 @@ UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdp UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_pdp_type *pdpType) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_DEF) + 3; char *command; char *response; if (cid > UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_DEF) + 3); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_MESSAGE_PDP_DEF); + snprintf(command, cmdLen, "%s?", UBX_CELL_MESSAGE_PDP_DEF); response = ubx_cell_calloc_char(1024); if (response == nullptr) @@ -1799,12 +1809,14 @@ UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_ UBX_CELL_error_t UBX_CELL::getSimStatus(String *code) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_SIMPIN) + 2; char *command; char *response; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_SIMPIN) + 2); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_COMMAND_SIMPIN); + snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_SIMPIN); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) { @@ -1843,11 +1855,13 @@ UBX_CELL_error_t UBX_CELL::getSimStatus(String *code) UBX_CELL_error_t UBX_CELL::setSimPin(String pin) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_SIMPIN) + 4 + pin.length(); char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_SIMPIN) + 4 + pin.length()); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_COMMAND_SIMPIN, pin.c_str()); + snprintf(command, cmdLen, "%s=\"%s\"", UBX_CELL_COMMAND_SIMPIN, pin.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -1856,12 +1870,13 @@ UBX_CELL_error_t UBX_CELL::setSimPin(String pin) UBX_CELL_error_t UBX_CELL::setSIMstateReportingMode(int mode) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_SIM_STATE) + 4; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SIM_STATE) + 4); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_SIM_STATE, mode); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_SIM_STATE, mode); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); @@ -1871,15 +1886,16 @@ UBX_CELL_error_t UBX_CELL::setSIMstateReportingMode(int mode) UBX_CELL_error_t UBX_CELL::getSIMstateReportingMode(int *mode) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_SIM_STATE) + 3; char *command; char *response; int m; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SIM_STATE) + 3); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_SIM_STATE); + snprintf(command, cmdLen, "%s?", UBX_CELL_SIM_STATE); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -1922,6 +1938,7 @@ UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, unsigne UBX_CELL::UBX_CELL_l2p_t l2p) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MESSAGE_ENTER_PPP) + 32; char *command; if ((dialing_type_char != 0) && (dialing_type_char != 'T') && (dialing_type_char != 'P')) @@ -1929,17 +1946,17 @@ UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, unsigne return UBX_CELL_ERROR_UNEXPECTED_PARAM; } - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_ENTER_PPP) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (dialing_type_char != 0) { - sprintf(command, "%s%c*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialing_type_char, dialNumber, PPP_L2P[l2p], + snprintf(command, cmdLen, "%s%c*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialing_type_char, dialNumber, PPP_L2P[l2p], (unsigned int)cid); } else { - sprintf(command, "%s*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialNumber, PPP_L2P[l2p], (unsigned int)cid); + snprintf(command, cmdLen, "%s*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialNumber, PPP_L2P[l2p], (unsigned int)cid); } err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -1951,14 +1968,15 @@ UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, unsigne uint8_t UBX_CELL::getOperators(struct operator_stats *opRet, int maxOps) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 3; char *command; char *response; uint8_t opsSeen = 0; - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 3); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=?", UBX_CELL_OPERATOR_SELECTION); + snprintf(command, cmdLen, "%s=?", UBX_CELL_OPERATOR_SELECTION); int responseSize = (maxOps + 1) * 48; response = ubx_cell_calloc_char(responseSize); @@ -2035,12 +2053,13 @@ uint8_t UBX_CELL::getOperators(struct operator_stats *opRet, int maxOps) UBX_CELL_error_t UBX_CELL::registerOperator(struct operator_stats oper) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 24; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 24); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=1,2,\"%lu\"", UBX_CELL_OPERATOR_SELECTION, oper.numOp); + snprintf(command, cmdLen, "%s=1,2,\"%lu\"", UBX_CELL_OPERATOR_SELECTION, oper.numOp); // AT+COPS maximum response time is 3 minutes (180000 ms) err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); @@ -2052,12 +2071,13 @@ UBX_CELL_error_t UBX_CELL::registerOperator(struct operator_stats oper) UBX_CELL_error_t UBX_CELL::automaticOperatorSelection() { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 6; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 6); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=0,0", UBX_CELL_OPERATOR_SELECTION); + snprintf(command, cmdLen, "%s=0,0", UBX_CELL_OPERATOR_SELECTION); // AT+COPS maximum response time is 3 minutes (180000 ms) err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); @@ -2069,15 +2089,16 @@ UBX_CELL_error_t UBX_CELL::automaticOperatorSelection() UBX_CELL_error_t UBX_CELL::getOperator(String *oper) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 3; char *command; char *response; char *searchPtr; char mode; - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 3); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_OPERATOR_SELECTION); + snprintf(command, cmdLen, "%s?", UBX_CELL_OPERATOR_SELECTION); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -2135,12 +2156,13 @@ UBX_CELL_error_t UBX_CELL::getOperator(String *oper) UBX_CELL_error_t UBX_CELL::deregisterOperator(void) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 6; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_OPERATOR_SELECTION) + 4); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=2", UBX_CELL_OPERATOR_SELECTION); + snprintf(command, cmdLen, "%s=2", UBX_CELL_OPERATOR_SELECTION); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); @@ -2150,13 +2172,14 @@ UBX_CELL_error_t UBX_CELL::deregisterOperator(void) UBX_CELL_error_t UBX_CELL::setSMSMessageFormat(UBX_CELL_message_format_t textMode) { + size_t cmdLen = strlen(UBX_CELL_MESSAGE_FORMAT) + 4; char *command; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_FORMAT) + 4); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_MESSAGE_FORMAT, (textMode == UBX_CELL_MESSAGE_FORMAT_TEXT) ? 1 : 0); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_MESSAGE_FORMAT, (textMode == UBX_CELL_MESSAGE_FORMAT_TEXT) ? 1 : 0); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -2176,10 +2199,11 @@ UBX_CELL_error_t UBX_CELL::sendSMS(String number, String message) return UBX_CELL_ERROR_OUT_OF_MEMORY; number.toCharArray(numberCStr, number.length() + 1); - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEND_TEXT) + strlen(numberCStr) + 8); + size_t cmdLen = strlen(UBX_CELL_SEND_TEXT) + strlen(numberCStr) + 8; + command = ubx_cell_calloc_char(cmdLen); if (command != nullptr) { - sprintf(command, "%s=\"%s\"", UBX_CELL_SEND_TEXT, numberCStr); + snprintf(command, cmdLen, "%s=\"%s\"", UBX_CELL_SEND_TEXT, numberCStr); err = sendCommandWithResponse(command, ">", nullptr, UBX_CELL_10_SEC_TIMEOUT); free(command); @@ -2213,15 +2237,16 @@ UBX_CELL_error_t UBX_CELL::sendSMS(String number, String message) UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, String memory) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_PREF_MESSAGE_STORE) + 32; char *command; char *response; int u; int t; - command = ubx_cell_calloc_char(strlen(UBX_CELL_PREF_MESSAGE_STORE) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_PREF_MESSAGE_STORE, memory.c_str()); + snprintf(command, cmdLen, "%s=\"%s\"", UBX_CELL_PREF_MESSAGE_STORE, memory.c_str()); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -2275,13 +2300,14 @@ UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, Str UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_READ_TEXT_MESSAGE) + 5; char *command; char *response; - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_TEXT_MESSAGE) + 5); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_READ_TEXT_MESSAGE, location); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_READ_TEXT_MESSAGE, location); response = ubx_cell_calloc_char(1024); if (response == nullptr) @@ -2379,16 +2405,17 @@ UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String * UBX_CELL_error_t UBX_CELL::deleteSMSmessage(int location, int deleteFlag) { + size_t cmdLen = strlen(UBX_CELL_DELETE_MESSAGE) + 12; char *command; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(strlen(UBX_CELL_DELETE_MESSAGE) + 12); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (deleteFlag == 0) - sprintf(command, "%s=%d", UBX_CELL_DELETE_MESSAGE, location); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_DELETE_MESSAGE, location); else - sprintf(command, "%s=%d,%d", UBX_CELL_DELETE_MESSAGE, location, deleteFlag); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_DELETE_MESSAGE, location, deleteFlag); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_55_SECS_TIMEOUT); @@ -2399,6 +2426,7 @@ UBX_CELL_error_t UBX_CELL::deleteSMSmessage(int location, int deleteFlag) UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_BAUD) + 7 + 12; char *command; int b = 0; @@ -2416,10 +2444,10 @@ UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) } // Construct command - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_BAUD) + 7 + 12); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%lu", UBX_CELL_COMMAND_BAUD, baud); + snprintf(command, cmdLen, "%s=%lu", UBX_CELL_COMMAND_BAUD, baud); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_SET_BAUD_TIMEOUT); @@ -2431,12 +2459,13 @@ UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) UBX_CELL_error_t UBX_CELL::setFlowControl(UBX_CELL_flow_control_t value) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_FLOW_CONTROL) + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_FLOW_CONTROL) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s%d", UBX_CELL_FLOW_CONTROL, value); + snprintf(command, cmdLen, "%s%d", UBX_CELL_FLOW_CONTROL, value); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -2448,17 +2477,18 @@ UBX_CELL_error_t UBX_CELL::setFlowControl(UBX_CELL_flow_control_t value) UBX_CELL_error_t UBX_CELL::setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_t mode, int value) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_GPIO) + 16; char *command; // Example command: AT+UGPIOC=16,2 // Example command: AT+UGPIOC=23,0,1 - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GPIO) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (mode == GPIO_OUTPUT) - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode, value); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode, value); else - sprintf(command, "%s=%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); @@ -2470,16 +2500,18 @@ UBX_CELL_error_t UBX_CELL::setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_ UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_GPIO) + 2; char *command; char *response; - char gpioChar[4]; + size_t charLen = 4; + char gpioChar[charLen]; char *gpioStart; int gpioMode; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GPIO) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return GPIO_MODE_INVALID; - sprintf(command, "%s?", UBX_CELL_COMMAND_GPIO); + snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_GPIO); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -2497,7 +2529,7 @@ UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) return GPIO_MODE_INVALID; } - sprintf(gpioChar, "%d", gpio); // Convert GPIO to char array + snprintf(gpioChar, charLen, "%d", gpio); // Convert GPIO to char array gpioStart = strstr(response, gpioChar); // Find first occurence of GPIO in response free(command); @@ -2513,18 +2545,19 @@ UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int localPort) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_CREATE_SOCKET) + 10; char *command; char *response; int sockId = -1; char *responseStart; - command = ubx_cell_calloc_char(strlen(UBX_CELL_CREATE_SOCKET) + 10); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return -1; if (localPort == 0) - sprintf(command, "%s=%d", UBX_CELL_CREATE_SOCKET, (int)protocol); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_CREATE_SOCKET, (int)protocol); else - sprintf(command, "%s=%d,%d", UBX_CELL_CREATE_SOCKET, (int)protocol, localPort); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_CREATE_SOCKET, (int)protocol, localPort); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -2581,10 +2614,11 @@ int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int local UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_CLOSE_SOCKET) + 10; char *command; char *response; - command = ubx_cell_calloc_char(strlen(UBX_CELL_CLOSE_SOCKET) + 10); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; response = ubx_cell_calloc_char(minimumResponseAllocation); @@ -2596,7 +2630,7 @@ UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) // if timeout is short, close asynchronously and don't wait for socket closure (we will get the URC later) // this will make sure the AT command parser is not confused during init() const char *format = (UBX_CELL_STANDARD_RESPONSE_TIMEOUT == timeout) ? "%s=%d,1" : "%s=%d"; - sprintf(command, format, UBX_CELL_CLOSE_SOCKET, socket); + snprintf(command, cmdLen, format, UBX_CELL_CLOSE_SOCKET, socket); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, timeout); @@ -2615,12 +2649,13 @@ UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) UBX_CELL_error_t UBX_CELL::socketConnect(int socket, const char *address, unsigned int port) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_CONNECT_SOCKET) + strlen(address) + 11; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_CONNECT_SOCKET) + strlen(address) + 11); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\",%d", UBX_CELL_CONNECT_SOCKET, socket, address, port); + snprintf(command, cmdLen, "%s=%d,\"%s\",%d", UBX_CELL_CONNECT_SOCKET, socket, address, port); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_IP_CONNECT_TIMEOUT); @@ -2631,22 +2666,24 @@ UBX_CELL_error_t UBX_CELL::socketConnect(int socket, const char *address, unsign UBX_CELL_error_t UBX_CELL::socketConnect(int socket, IPAddress address, unsigned int port) { - char *charAddress = ubx_cell_calloc_char(16); + size_t charLen = 16; + char *charAddress = ubx_cell_calloc_char(charLen); if (charAddress == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; memset(charAddress, 0, 16); - sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); + snprintf(charAddress, charLen, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); return (socketConnect(socket, (const char *)charAddress, port)); } UBX_CELL_error_t UBX_CELL::socketWrite(int socket, const char *str, int len) { + size_t cmdLen = strlen(UBX_CELL_WRITE_SOCKET) + 16; char *command; char *response; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(strlen(UBX_CELL_WRITE_SOCKET) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; response = ubx_cell_calloc_char(minimumResponseAllocation); @@ -2656,7 +2693,7 @@ UBX_CELL_error_t UBX_CELL::socketWrite(int socket, const char *str, int len) return UBX_CELL_ERROR_OUT_OF_MEMORY; } int dataLen = len == -1 ? strlen(str) : len; - sprintf(command, "%s=%d,%d", UBX_CELL_WRITE_SOCKET, socket, dataLen); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_WRITE_SOCKET, socket, dataLen); err = sendCommandWithResponse(command, "@", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); @@ -2713,12 +2750,13 @@ UBX_CELL_error_t UBX_CELL::socketWrite(int socket, String str) UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int port, const char *str, int len) { + size_t cmdLen = 64; char *command; char *response; UBX_CELL_error_t err; int dataLen = len == -1 ? strlen(str) : len; - command = ubx_cell_calloc_char(64); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; response = ubx_cell_calloc_char(minimumResponseAllocation); @@ -2728,7 +2766,7 @@ UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int p return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,\"%s\",%d,%d", UBX_CELL_WRITE_UDP_SOCKET, socket, address, port, dataLen); + snprintf(command, cmdLen, "%s=%d,\"%s\",%d,%d", UBX_CELL_WRITE_UDP_SOCKET, socket, address, port, dataLen); err = sendCommandWithResponse(command, "@", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); if (err == UBX_CELL_ERROR_SUCCESS) @@ -2758,11 +2796,12 @@ UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int p UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len) { + size_t charLen = 16; char *charAddress = ubx_cell_calloc_char(16); if (charAddress == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; memset(charAddress, 0, 16); - sprintf(charAddress, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); + snprintf(charAddress, charLen, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); return (socketWriteUDP(socket, (const char *)charAddress, port, str, len)); } @@ -2774,6 +2813,7 @@ UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, String address, int port, UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, int *bytesRead) { + size_t cmdLen = strlen(UBX_CELL_READ_SOCKET) + 32; char *command; char *response; char *strBegin; @@ -2799,7 +2839,7 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in } // Allocate memory for the command - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_SOCKET) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; @@ -2823,7 +2863,7 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in else bytesToRead = bytesLeftToRead; - sprintf(command, "%s=%d,%d", UBX_CELL_READ_SOCKET, socket, bytesToRead); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_READ_SOCKET, socket, bytesToRead); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT, responseLength); @@ -2934,6 +2974,7 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) { + size_t cmdLen = strlen(UBX_CELL_READ_SOCKET) + 32; char *command; char *response; UBX_CELL_error_t err; @@ -2941,10 +2982,10 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) int readLength = 0; int socketStore = 0; - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_SOCKET) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,0", UBX_CELL_READ_SOCKET, socket); + snprintf(command, cmdLen, "%s=%d,0", UBX_CELL_READ_SOCKET, socket); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -2989,6 +3030,7 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress, int *remotePort, int *bytesRead) { + size_t cmdLen = strlen(UBX_CELL_READ_UDP_SOCKET) + 32; char *command; char *response; char *strBegin; @@ -3016,7 +3058,7 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, } // Allocate memory for the command - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_UDP_SOCKET) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; @@ -3040,7 +3082,7 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, else bytesToRead = bytesLeftToRead; - sprintf(command, "%s=%d,%d", UBX_CELL_READ_UDP_SOCKET, socket, bytesToRead); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_READ_UDP_SOCKET, socket, bytesToRead); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT, responseLength); @@ -3171,6 +3213,7 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) { + size_t cmdLen = strlen(UBX_CELL_READ_UDP_SOCKET) + 32; char *command; char *response; UBX_CELL_error_t err; @@ -3178,10 +3221,10 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) int readLength = 0; int socketStore = 0; - command = ubx_cell_calloc_char(strlen(UBX_CELL_READ_UDP_SOCKET) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,0", UBX_CELL_READ_UDP_SOCKET, socket); + snprintf(command, cmdLen, "%s=%d,0", UBX_CELL_READ_UDP_SOCKET, socket); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -3226,12 +3269,13 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) UBX_CELL_error_t UBX_CELL::socketListen(int socket, unsigned int port) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_LISTEN_SOCKET) + 9; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_LISTEN_SOCKET) + 9); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d", UBX_CELL_LISTEN_SOCKET, socket, port); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_LISTEN_SOCKET, socket, port); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3242,12 +3286,13 @@ UBX_CELL_error_t UBX_CELL::socketListen(int socket, unsigned int port) UBX_CELL_error_t UBX_CELL::socketDirectLinkMode(int socket) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_SOCKET_DIRECT_LINK) + 8; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_DIRECT_LINK) + 8); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_SOCKET_DIRECT_LINK, socket); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_SOCKET_DIRECT_LINK, socket); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3262,12 +3307,13 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkTimeTrigger(int socket, unsigned long return UBX_CELL_ERROR_ERROR; UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_UD_CONFIGURATION) + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=5,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, timerTrigger); + snprintf(command, cmdLen, "%s=5,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, timerTrigger); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3282,12 +3328,13 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkDataLengthTrigger(int socket, int dat return UBX_CELL_ERROR_ERROR; UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_UD_CONFIGURATION) + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=6,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, dataLengthTrigger); + snprintf(command, cmdLen, "%s=6,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, dataLengthTrigger); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3302,12 +3349,13 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkCharacterTrigger(int socket, int char return UBX_CELL_ERROR_ERROR; UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_UD_CONFIGURATION) + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=7,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, characterTrigger); + snprintf(command, cmdLen, "%s=7,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, characterTrigger); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3322,12 +3370,13 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkCongestionTimer(int socket, unsigned return UBX_CELL_ERROR_ERROR; UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_UD_CONFIGURATION) + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_UD_CONFIGURATION) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=8,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, congestionTimer); + snprintf(command, cmdLen, "%s=8,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, congestionTimer); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3337,6 +3386,7 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkCongestionTimer(int socket, unsigned UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol) { + size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char *command; char *response; UBX_CELL_error_t err; @@ -3344,10 +3394,10 @@ UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_ int socketStore = 0; int paramVal; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,0", UBX_CELL_SOCKET_CONTROL, socket); + snprintf(command, cmdLen, "%s=%d,0", UBX_CELL_SOCKET_CONTROL, socket); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -3392,6 +3442,7 @@ UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_ UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) { + size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char *command; char *response; UBX_CELL_error_t err; @@ -3399,10 +3450,10 @@ UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) int socketStore = 0; int paramVal; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,1", UBX_CELL_SOCKET_CONTROL, socket); + snprintf(command, cmdLen, "%s=%d,1", UBX_CELL_SOCKET_CONTROL, socket); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -3446,6 +3497,7 @@ UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total) { + size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char *command; char *response; UBX_CELL_error_t err; @@ -3453,10 +3505,10 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total int socketStore = 0; long unsigned int paramVal; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,2", UBX_CELL_SOCKET_CONTROL, socket); + snprintf(command, cmdLen, "%s=%d,2", UBX_CELL_SOCKET_CONTROL, socket); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -3500,6 +3552,7 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *total) { + size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char *command; char *response; UBX_CELL_error_t err; @@ -3507,10 +3560,10 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *t int socketStore = 0; long unsigned int paramVal; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,3", UBX_CELL_SOCKET_CONTROL, socket); + snprintf(command, cmdLen, "%s=%d,3", UBX_CELL_SOCKET_CONTROL, socket); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -3554,6 +3607,7 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *t UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *address, int *port) { + size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char *command; char *response; UBX_CELL_error_t err; @@ -3561,10 +3615,10 @@ UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *add int socketStore = 0; int paramVals[5]; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,4", UBX_CELL_SOCKET_CONTROL, socket); + snprintf(command, cmdLen, "%s=%d,4", UBX_CELL_SOCKET_CONTROL, socket); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -3612,6 +3666,7 @@ UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *add UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status) { + size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char *command; char *response; UBX_CELL_error_t err; @@ -3619,10 +3674,10 @@ UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_ int socketStore = 0; int paramVal; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,10", UBX_CELL_SOCKET_CONTROL, socket); + snprintf(command, cmdLen, "%s=%d,10", UBX_CELL_SOCKET_CONTROL, socket); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -3666,6 +3721,7 @@ UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_ UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) { + size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char *command; char *response; UBX_CELL_error_t err; @@ -3673,10 +3729,10 @@ UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) int socketStore = 0; long unsigned int paramVal; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SOCKET_CONTROL) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,11", UBX_CELL_SOCKET_CONTROL, socket); + snprintf(command, cmdLen, "%s=%d,11", UBX_CELL_SOCKET_CONTROL, socket); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -3722,11 +3778,12 @@ UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) int UBX_CELL::socketGetLastError() { UBX_CELL_error_t err; + size_t cmdLen = 64; char *command; char *response; int errorCode = -1; - command = ubx_cell_calloc_char(64); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; @@ -3737,7 +3794,7 @@ int UBX_CELL::socketGetLastError() return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s", UBX_CELL_GET_ERROR); + snprintf(command, cmdLen, "%s", UBX_CELL_GET_ERROR); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3767,15 +3824,16 @@ IPAddress UBX_CELL::lastRemoteIP(void) UBX_CELL_error_t UBX_CELL::resetHTTPprofile(int profile) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 16; char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_HTTP_PROFILE, profile); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_HTTP_PROFILE, profile); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3786,15 +3844,16 @@ UBX_CELL_error_t UBX_CELL::resetHTTPprofile(int profile) UBX_CELL_error_t UBX_CELL::setHTTPserverIPaddress(int profile, IPAddress address) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 64; char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 64); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_IP, + snprintf(command, cmdLen, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_IP, address[0], address[1], address[2], address[3]); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3806,15 +3865,16 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverIPaddress(int profile, IPAddress address UBX_CELL_error_t UBX_CELL::setHTTPserverName(int profile, String server) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 12 + server.length(); char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + server.length()); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_NAME, + snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_NAME, server.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3826,15 +3886,16 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverName(int profile, String server) UBX_CELL_error_t UBX_CELL::setHTTPusername(int profile, String username) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 12 + username.length(); char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + username.length()); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_USERNAME, + snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_USERNAME, username.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3846,15 +3907,16 @@ UBX_CELL_error_t UBX_CELL::setHTTPusername(int profile, String username) UBX_CELL_error_t UBX_CELL::setHTTPpassword(int profile, String password) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 12 + password.length(); char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + password.length()); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_PASSWORD, + snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_PASSWORD, password.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3866,15 +3928,16 @@ UBX_CELL_error_t UBX_CELL::setHTTPpassword(int profile, String password) UBX_CELL_error_t UBX_CELL::setHTTPauthentication(int profile, bool authenticate) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 32; char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, authenticate); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, authenticate); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3885,15 +3948,16 @@ UBX_CELL_error_t UBX_CELL::setHTTPauthentication(int profile, bool authenticate) UBX_CELL_error_t UBX_CELL::setHTTPserverPort(int profile, int port) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 32; char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_PORT, port); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_PORT, port); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3904,15 +3968,16 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverPort(int profile, int port) UBX_CELL_error_t UBX_CELL::setHTTPcustomHeader(int profile, String header) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 12 + header.length(); char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 12 + header.length()); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS, + snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS, header.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3924,18 +3989,19 @@ UBX_CELL_error_t UBX_CELL::setHTTPcustomHeader(int profile, String header) UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofile) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 32; char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROFILE) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (secprofile == -1) - sprintf(command, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure); else - sprintf(command, "%s=%d,%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure, + snprintf(command, cmdLen, "%s=%d,%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure, secprofile); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3947,12 +4013,13 @@ UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofil UBX_CELL_error_t UBX_CELL::ping(String remote_host, int retry, int p_size, unsigned long timeout, int ttl) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_PING_COMMAND) + 48 + remote_host.length(); char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_PING_COMMAND) + 48 + remote_host.length()); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\",%d,%d,%ld,%d", UBX_CELL_PING_COMMAND, remote_host.c_str(), retry, p_size, timeout, ttl); + snprintf(command, cmdLen, "%s=\"%s\",%d,%d,%ld,%d", UBX_CELL_PING_COMMAND, remote_host.c_str(), retry, p_size, timeout, ttl); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3963,15 +4030,16 @@ UBX_CELL_error_t UBX_CELL::ping(String remote_host, int retry, int p_size, unsig UBX_CELL_error_t UBX_CELL::sendHTTPGET(int profile, String path, String responseFilename) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length(); char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length()); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\",\"%s\"", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_GET, path.c_str(), + snprintf(command, cmdLen, "%s=%d,%d,\"%s\",\"%s\"", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_GET, path.c_str(), responseFilename.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3984,16 +4052,17 @@ UBX_CELL_error_t UBX_CELL::sendHTTPPOSTdata(int profile, String path, String res UBX_CELL_http_content_types_t httpContentType) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + + responseFilename.length() + data.length(); char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length() + - data.length()); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, + snprintf(command, cmdLen, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_POST_DATA, path.c_str(), responseFilename.c_str(), data.c_str(), httpContentType); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -4006,16 +4075,17 @@ UBX_CELL_error_t UBX_CELL::sendHTTPPOSTfile(int profile, String path, String res UBX_CELL_http_content_types_t httpContentType) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + + responseFilename.length() + requestFile.length(); char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length() + - requestFile.length()); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, + snprintf(command, cmdLen, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_POST_FILE, path.c_str(), responseFilename.c_str(), requestFile.c_str(), httpContentType); @@ -4028,15 +4098,16 @@ UBX_CELL_error_t UBX_CELL::sendHTTPPOSTfile(int profile, String path, String res UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, int *error_code) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_HTTP_PROTOCOL_ERROR) + 4; char *command; char *response; int rprofile, eclass, ecode; - command = ubx_cell_calloc_char(strlen(UBX_CELL_HTTP_PROTOCOL_ERROR) + 4); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_HTTP_PROTOCOL_ERROR, profile); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_HTTP_PROTOCOL_ERROR, profile); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -4075,11 +4146,13 @@ UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, i UBX_CELL_error_t UBX_CELL::nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MQTT_NVM) + 10; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_NVM) + 10); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_MQTT_NVM, parameter); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_MQTT_NVM, parameter); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -4088,11 +4161,13 @@ UBX_CELL_error_t UBX_CELL::nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter) UBX_CELL_error_t UBX_CELL::setMQTTclientId(const String &clientId) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MQTT_PROFILE) + clientId.length() + 10; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + clientId.length() + 10); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_CLIENT_ID, clientId.c_str()); + snprintf(command, cmdLen, "%s=%d,\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_CLIENT_ID, clientId.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -4101,11 +4176,13 @@ UBX_CELL_error_t UBX_CELL::setMQTTclientId(const String &clientId) UBX_CELL_error_t UBX_CELL::setMQTTserver(const String &serverName, int port) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MQTT_PROFILE) + serverName.length() + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + serverName.length() + 16); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\",%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SERVERNAME, serverName.c_str(), + snprintf(command, cmdLen, "%s=%d,\"%s\",%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SERVERNAME, serverName.c_str(), port); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); @@ -4115,13 +4192,15 @@ UBX_CELL_error_t UBX_CELL::setMQTTserver(const String &serverName, int port) UBX_CELL_error_t UBX_CELL::setMQTTcredentials(const String &userName, const String &pwd) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MQTT_PROFILE) + userName.length() + pwd.length() + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + userName.length() + pwd.length() + 16); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) { return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_USERNAMEPWD, userName.c_str(), + snprintf(command, cmdLen, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_USERNAMEPWD, userName.c_str(), pwd.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); @@ -4131,14 +4210,16 @@ UBX_CELL_error_t UBX_CELL::setMQTTcredentials(const String &userName, const Stri UBX_CELL_error_t UBX_CELL::setMQTTsecure(bool secure, int secprofile) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MQTT_PROFILE) + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_PROFILE) + 16); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (secprofile == -1) - sprintf(command, "%s=%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure); else - sprintf(command, "%s=%d,%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure, secprofile); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure, secprofile); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -4147,11 +4228,13 @@ UBX_CELL_error_t UBX_CELL::setMQTTsecure(bool secure, int secprofile) UBX_CELL_error_t UBX_CELL::connectMQTT(void) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 10; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGIN); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGIN); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -4160,11 +4243,13 @@ UBX_CELL_error_t UBX_CELL::connectMQTT(void) UBX_CELL_error_t UBX_CELL::disconnectMQTT(void) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 10; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGOUT); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGOUT); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -4173,11 +4258,13 @@ UBX_CELL_error_t UBX_CELL::disconnectMQTT(void) UBX_CELL_error_t UBX_CELL::subscribeMQTTtopic(int max_Qos, const String &topic) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length(); char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length()); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_SUBSCRIBE, max_Qos, topic.c_str()); + snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_SUBSCRIBE, max_Qos, topic.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -4186,11 +4273,13 @@ UBX_CELL_error_t UBX_CELL::subscribeMQTTtopic(int max_Qos, const String &topic) UBX_CELL_error_t UBX_CELL::unsubscribeMQTTtopic(const String &topic) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length(); char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length()); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_UNSUBSCRIBE, topic.c_str()); + snprintf(command, cmdLen, "%s=%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_UNSUBSCRIBE, topic.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -4198,6 +4287,7 @@ UBX_CELL_error_t UBX_CELL::unsubscribeMQTTtopic(const String &topic) UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest, int readLength, int *bytesRead) { + size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 10; char *command; char *response; UBX_CELL_error_t err; @@ -4209,7 +4299,7 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest *bytesRead = 0; // Allocate memory for the command - command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 10); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; @@ -4225,7 +4315,7 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... // To try and avoid this, look for \"\r\n\r\nOK\r\n there is a extra \r\n beetween " and the the standard \r\nOK\r\n const char mqttReadTerm[] = "\"\r\n\r\nOK\r\n"; - sprintf(command, "%s=%d,%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_READ, 1); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_READ, 1); err = sendCommandWithResponse(command, mqttReadTerm, response, (5 * UBX_CELL_STANDARD_RESPONSE_TIMEOUT), responseLength); @@ -4336,13 +4426,14 @@ UBX_CELL_error_t UBX_CELL::mqttPublishTextMsg(const String &topic, const char *c msg_ptr++; } - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + msg_len); + size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + msg_len; + char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) { return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,%u,%u,0,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISH, qos, + snprintf(command, cmdLen, "%s=%d,%u,%u,0,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISH, qos, (retain ? 1 : 0), topic.c_str(), sanitized_msg); sendCommand(command, true); @@ -4375,13 +4466,14 @@ UBX_CELL_error_t UBX_CELL::mqttPublishBinaryMsg(const String &topic, const char } UBX_CELL_error_t err; - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length()); + size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length(); + char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) { return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,%u,%u,\"%s\",%u", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, qos, + snprintf(command, cmdLen, "%s=%d,%u,%u,\"%s\",%u", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, qos, (retain ? 1 : 0), topic.c_str(), msg_len); sendCommand(command, true); @@ -4404,13 +4496,14 @@ UBX_CELL_error_t UBX_CELL::mqttPublishFromFile(const String &topic, const String } UBX_CELL_error_t err; - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + filename.length()); + size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + filename.length(); + char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) { return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,%u,%u,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHFILE, qos, + snprintf(command, cmdLen, "%s=%d,%u,%u,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHFILE, qos, (retain ? 1 : 0), topic.c_str(), filename.c_str()); sendCommand(command, true); @@ -4462,10 +4555,10 @@ UBX_CELL_error_t UBX_CELL::getMQTTprotocolError(int *error_code, int *error_code UBX_CELL_error_t UBX_CELL::setFTPserver(const String &serverName) { - constexpr size_t cmd_len = 145; - char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> + constexpr size_t cmdLen = 145; + char command[cmdLen]; // long enough for AT+UFTP=1,<128 bytes> - snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_SERVERNAME, + snprintf(command, cmdLen, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_SERVERNAME, serverName.c_str()); return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } @@ -4473,10 +4566,10 @@ UBX_CELL_error_t UBX_CELL::setFTPserver(const String &serverName) UBX_CELL_error_t UBX_CELL::setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger) { - constexpr size_t cmd_len = 64; - char command[cmd_len]; // long enough for AT+UFTP=1,<128 bytes> + constexpr size_t cmdLen = 64; + char command[cmdLen]; // long enough for AT+UFTP=1,<128 bytes> - snprintf(command, cmd_len - 1, "%s=%d,%u,%u,%u", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_TIMEOUT, timeout, + snprintf(command, cmdLen, "%s=%d,%u,%u,%u", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_TIMEOUT, timeout, cmd_linger, data_linger); return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } @@ -4484,10 +4577,10 @@ UBX_CELL_error_t UBX_CELL::setFTPtimeouts(const unsigned int timeout, const unsi UBX_CELL_error_t UBX_CELL::setFTPcredentials(const String &userName, const String &pwd) { UBX_CELL_error_t err; - constexpr size_t cmd_len = 48; - char command[cmd_len]; // long enough for AT+UFTP=n,<30 bytes> + constexpr size_t cmdLen = 48; + char command[cmdLen]; // long enough for AT+UFTP=n,<30 bytes> - snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_USERNAME, + snprintf(command, cmdLen, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_USERNAME, userName.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err != UBX_CELL_ERROR_SUCCESS) @@ -4495,7 +4588,7 @@ UBX_CELL_error_t UBX_CELL::setFTPcredentials(const String &userName, const Strin return err; } - snprintf(command, cmd_len - 1, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_PWD, pwd.c_str()); + snprintf(command, cmdLen, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_PWD, pwd.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); return err; @@ -4503,31 +4596,32 @@ UBX_CELL_error_t UBX_CELL::setFTPcredentials(const String &userName, const Strin UBX_CELL_error_t UBX_CELL::connectFTP(void) { - constexpr size_t cmd_len = 16; - char command[cmd_len]; // long enough for AT+UFTPC=n + constexpr size_t cmdLen = 16; + char command[cmdLen]; // long enough for AT+UFTPC=n - snprintf(command, cmd_len - 1, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGIN); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGIN); return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } UBX_CELL_error_t UBX_CELL::disconnectFTP(void) { - constexpr size_t cmd_len = 16; - char command[cmd_len]; // long enough for AT+UFTPC=n + constexpr size_t cmdLen = 16; + char command[cmdLen]; // long enough for AT+UFTPC=n - snprintf(command, cmd_len - 1, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGOUT); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_LOGOUT); return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } UBX_CELL_error_t UBX_CELL::ftpGetFile(const String &filename) { - char *command = ubx_cell_calloc_char(strlen(UBX_CELL_FTP_COMMAND) + (2 * filename.length()) + 16); + size_t cmdLen = strlen(UBX_CELL_FTP_COMMAND) + (2 * filename.length()) + 16; + char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) { return UBX_CELL_ERROR_OUT_OF_MEMORY; } - sprintf(command, "%s=%d,\"%s\",\"%s\"", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_GET_FILE, filename.c_str(), + snprintf(command, cmdLen, "%s=%d,\"%s\",\"%s\"", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_GET_FILE, filename.c_str(), filename.c_str()); // memset(response, 0, sizeof(response)); // sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, response, 8000 /* ms */, response_len); @@ -4586,13 +4680,14 @@ UBX_CELL_error_t UBX_CELL::getFTPprotocolError(int *error_code, int *error_code2 UBX_CELL_error_t UBX_CELL::resetSecurityProfile(int secprofile) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_SEC_PROFILE) + 6; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + 6); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_SEC_PROFILE, secprofile); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_SEC_PROFILE, secprofile); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -4603,12 +4698,13 @@ UBX_CELL_error_t UBX_CELL::resetSecurityProfile(int secprofile) UBX_CELL_error_t UBX_CELL::configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_SEC_PROFILE) + 10; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + 10); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_SEC_PROFILE, secprofile, parameter, value); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_SEC_PROFILE, secprofile, parameter, value); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -4618,11 +4714,13 @@ UBX_CELL_error_t UBX_CELL::configSecurityProfileString(int secprofile, UBX_CELL_ String value) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_SEC_PROFILE) + value.length() + 10; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_PROFILE) + value.length() + 10); + + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,\"%s\"", UBX_CELL_SEC_PROFILE, secprofile, parameter, value.c_str()); + snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_SEC_PROFILE, secprofile, parameter, value.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -4631,11 +4729,12 @@ UBX_CELL_error_t UBX_CELL::configSecurityProfileString(int secprofile, UBX_CELL_ UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, UBX_CELL_sec_manager_parameter_t parameter, String name, String data) { + size_t cmdLen = strlen(UBX_CELL_SEC_MANAGER) + name.length() + 20; char *command; char *response; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(strlen(UBX_CELL_SEC_MANAGER) + name.length() + 20); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; response = ubx_cell_calloc_char(minimumResponseAllocation); @@ -4645,7 +4744,7 @@ UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opco return UBX_CELL_ERROR_OUT_OF_MEMORY; } int dataLen = data.length(); - sprintf(command, "%s=%d,%d,\"%s\",%d", UBX_CELL_SEC_MANAGER, opcode, parameter, name.c_str(), dataLen); + snprintf(command, cmdLen, "%s=%d,%d,\"%s\",%d", UBX_CELL_SEC_MANAGER, opcode, parameter, name.c_str(), dataLen); err = sendCommandWithResponse(command, ">", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -4680,18 +4779,19 @@ UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opco UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE) + 32; char *command; if (cid >= UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(strlen(UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE) + 32); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (cid == -1) - sprintf(command, "%s=%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status); else - sprintf(command, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status, cid); + snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status, cid); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -4702,14 +4802,15 @@ UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) bool UBX_CELL::isGPSon(void) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_POWER) + 2; char *command; char *response; bool on = false; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_POWER) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_POWER); + snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_POWER); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -4742,6 +4843,7 @@ bool UBX_CELL::isGPSon(void) UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_aiding_mode_t gnss_aiding) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_POWER) + 32; // gnss_sys could be up to three digits char *command; bool gpsState; @@ -4753,16 +4855,16 @@ UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_ai } // GPS power management - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_POWER) + 32); // gnss_sys could be up to three digits + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (enable) { - sprintf(command, "%s=1,%d,%d", UBX_CELL_GNSS_POWER, gnss_aiding, gnss_sys); + snprintf(command, cmdLen, "%s=1,%d,%d", UBX_CELL_GNSS_POWER, gnss_aiding, gnss_sys); } else { - sprintf(command, "%s=0", UBX_CELL_GNSS_POWER); + snprintf(command, cmdLen, "%s=0", UBX_CELL_GNSS_POWER); } err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, 10000); @@ -4833,6 +4935,7 @@ UBX_CELL_error_t UBX_CELL::gpsEnableRmc(bool enable) { // AT+UGRMC=<0,1> UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_GPRMC) + 3; char *command; // ** Don't call gpsPower here. It causes problems for +UTIME and the PPS signal ** @@ -4846,10 +4949,10 @@ UBX_CELL_error_t UBX_CELL::gpsEnableRmc(bool enable) // } // } - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_GPRMC) + 3); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_GNSS_GPRMC, enable ? 1 : 0); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_GNSS_GPRMC, enable ? 1 : 0); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); @@ -4861,14 +4964,15 @@ UBX_CELL_error_t UBX_CELL::gpsGetRmc(struct PositionData *pos, struct SpeedData bool *valid) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_GPRMC) + 2; char *command; char *response; char *rmcBegin; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_GPRMC) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_GNSS_GPRMC); + snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_GPRMC); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -4917,6 +5021,7 @@ UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, b { // AT+ULOC=2,,,, UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_LOCATION) + 24; char *command; // This function will only work if the GPS module is initially turned off. @@ -4930,13 +5035,13 @@ UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, b if (accuracy > 999999) accuracy = 999999; - command = ubx_cell_calloc_char(strlen(UBX_CELL_GNSS_REQUEST_LOCATION) + 24); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - sprintf(command, "%s=2,%d,%d,%d,%d", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); + snprintf(command, cmdLen, "%s=2,%d,%d,%d,%d", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); #else - sprintf(command, "%s=2,%d,%d,%d,%ld", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); + snprintf(command, cmdLen, "%s=2,%d,%d,%d,%ld", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); #endif err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); @@ -4951,13 +5056,14 @@ UBX_CELL_error_t UBX_CELL::gpsAidingServerConf(const char *primaryServer, const unsigned int dataType) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_AIDING_SERVER_CONFIGURATION) + 256; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_AIDING_SERVER_CONFIGURATION) + 256); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBX_CELL_AIDING_SERVER_CONFIGURATION, primaryServer, + snprintf(command, cmdLen, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBX_CELL_AIDING_SERVER_CONFIGURATION, primaryServer, secondaryServer, authToken, days, period, resolution, gnssTypes, mode, dataType); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -4969,11 +5075,12 @@ UBX_CELL_error_t UBX_CELL::gpsAidingServerConf(const char *primaryServer, const // OK for text files. But will fail with binary files (containing \0) on some platforms. UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, const char *str, int len) { + size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE) + filename.length() + 10; char *command; char *response; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE) + filename.length() + 10); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; response = ubx_cell_calloc_char(minimumResponseAllocation); @@ -4983,7 +5090,7 @@ UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, const char *str, return UBX_CELL_ERROR_OUT_OF_MEMORY; } int dataLen = len == -1 ? strlen(str) : len; - sprintf(command, "%s=\"%s\",%d", UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE, filename.c_str(), dataLen); + snprintf(command, cmdLen, "%s=\"%s\",%d", UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE, filename.c_str(), dataLen); err = sendCommandWithResponse(command, ">", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 2); @@ -5029,6 +5136,7 @@ UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, String str) UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8; char *command; char *response; @@ -5045,10 +5153,10 @@ UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) return err; } - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); + snprintf(command, cmdLen, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); response = ubx_cell_calloc_char(fileSize + minimumResponseAllocation); if (response == nullptr) @@ -5151,6 +5259,7 @@ UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) UBX_CELL_error_t UBX_CELL::getFileContents(String filename, char *contents) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8; char *command; char *response; @@ -5167,10 +5276,10 @@ UBX_CELL_error_t UBX_CELL::getFileContents(String filename, char *contents) return err; } - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); + snprintf(command, cmdLen, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_READ_FILE, filename.c_str()); response = ubx_cell_calloc_char(fileSize + minimumResponseAllocation); if (response == nullptr) @@ -5285,9 +5394,9 @@ UBX_CELL_error_t UBX_CELL::getFileBlock(const String &filename, char *buffer, si return UBX_CELL_ERROR_INVALID; } - size_t cmd_len = filename.length() + 32; - char *cmd = ubx_cell_calloc_char(cmd_len); - sprintf(cmd, "at+urdblock=\"%s\",%zu,%zu\r\n", filename.c_str(), offset, requested_length); + size_t cmdLen = filename.length() + 32; + char *cmd = ubx_cell_calloc_char(cmdLen); + snprintf(cmd, cmdLen, "at+urdblock=\"%s\",%zu,%zu\r\n", filename.c_str(), offset, requested_length); sendCommand(cmd, false); int ich; @@ -5338,13 +5447,14 @@ UBX_CELL_error_t UBX_CELL::getFileBlock(const String &filename, char *buffer, si UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_LIST_FILES) + filename.length() + 8; char *command; char *response; - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_LIST_FILES) + filename.length() + 8); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=2,\"%s\"", UBX_CELL_FILE_SYSTEM_LIST_FILES, filename.c_str()); + snprintf(command, cmdLen, "%s=2,\"%s\"", UBX_CELL_FILE_SYSTEM_LIST_FILES, filename.c_str()); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) @@ -5398,12 +5508,13 @@ UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) UBX_CELL_error_t UBX_CELL::deleteFile(String filename) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_DELETE_FILE) + filename.length() + 8; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_FILE_SYSTEM_DELETE_FILE) + filename.length() + 8); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_DELETE_FILE, filename.c_str()); + snprintf(command, cmdLen, "%s=\"%s\"", UBX_CELL_FILE_SYSTEM_DELETE_FILE, filename.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -5423,13 +5534,14 @@ UBX_CELL_error_t UBX_CELL::deleteFile(String filename) UBX_CELL_error_t UBX_CELL::modulePowerOff(void) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_POWER_OFF) + 6; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_POWER_OFF) + 6); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s", UBX_CELL_COMMAND_POWER_OFF); + snprintf(command, cmdLen, "%s", UBX_CELL_COMMAND_POWER_OFF); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_POWER_OFF_TIMEOUT); @@ -5631,12 +5743,13 @@ void UBX_CELL::hwReset(void) UBX_CELL_error_t UBX_CELL::functionality(UBX_CELL_functionality_t function) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_FUNC) + 16; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_FUNC) + 16); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_COMMAND_FUNC, function); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_COMMAND_FUNC, function); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); @@ -5648,16 +5761,17 @@ UBX_CELL_error_t UBX_CELL::functionality(UBX_CELL_functionality_t function) UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_MNO) + 9; char *command; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_MNO) + 9); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; if (mno == MNO_SIM_ICCID) // Only add autoReset and urcNotification if mno is MNO_SIM_ICCID - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno, (uint8_t)autoReset, + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno, (uint8_t)autoReset, (uint8_t)urcNotification); else - sprintf(command, "%s=%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -5669,6 +5783,7 @@ UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool aut UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_MNO) + 2; char *command; char *response; mobile_network_operator_t o; @@ -5677,10 +5792,10 @@ UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) int u; int oStore; - command = ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_MNO) + 2); + command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s?", UBX_CELL_COMMAND_MNO); + snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_MNO); response = ubx_cell_calloc_char(minimumResponseAllocation); if (response == nullptr) diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index 17454eb..98f510b 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -44,12 +44,13 @@ template class UBX_CELL_VOICE return UBX_CELL_ERROR_OUT_OF_MEMORY; number.toCharArray(numberCStr, number.length() + 1); - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_DIAL) + strlen(numberCStr) + 3); + size_t cmdLen = strlen(UBX_CELL_COMMAND_DIAL) + strlen(numberCStr) + 3; + command = static_cast(this)->ubx_cell_calloc_char(cmdLen); if (command != nullptr) { // Heads up! The dial command is one of the only commands that requires a // semicolon at the end of it! - sprintf(command, "%s=%s;", UBX_CELL_COMMAND_DIAL, numberCStr); + snprintf(command, cmdLen, "%s=%s;", UBX_CELL_COMMAND_DIAL, numberCStr); err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, nullptr, UBX_CELL_10_SEC_TIMEOUT); @@ -81,12 +82,13 @@ template class UBX_CELL_VOICE UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id = 0, uint8_t nof_repeat = 0) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13; char *command; - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13); + command = static_cast(this)->ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat); err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -97,12 +99,13 @@ template class UBX_CELL_VOICE UBX_CELL_error_t stopAudioResource(uint8_t audio_resource) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5; char *command; - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5); + command = static_cast(this)->ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource); + snprintf(command, cmdLen, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource); err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -113,13 +116,14 @@ template class UBX_CELL_VOICE UBX_CELL_error_t generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15; char *command; char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15); + command = static_cast(this)->ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume); err = static_cast(this)->sendCommandWithResponse(command, response, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -130,13 +134,14 @@ template class UBX_CELL_VOICE UBX_CELL_error_t generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume) { UBX_CELL_error_t err; + size_t cmdLen = strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14; char *command; char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; - command = static_cast(this)->ubx_cell_calloc_char(strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14); + command = static_cast(this)->ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - sprintf(command, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume); + snprintf(command, cmdLen, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume); err = static_cast(this)->sendCommandWithResponse(command, response, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); From 363ec5c2f9ec8f1ab3654f7f277e98c90556a0f8 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 18 Dec 2023 15:58:33 -0700 Subject: [PATCH 47/52] Don't use calloc for fixed length arrays Many command and response arrays are fixed length, so no need to use calloc. This helps prevent the heap from getting fragmented. --- src/sfe_sara_r5.cpp | 109 +--- src/sfe_ublox_cellular.cpp | 1001 +++++--------------------------- src/sfe_ublox_cellular_voice.h | 24 +- 3 files changed, 151 insertions(+), 983 deletions(-) diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp index ae66359..b13d056 100644 --- a/src/sfe_sara_r5.cpp +++ b/src/sfe_sara_r5.cpp @@ -10,18 +10,14 @@ UBX_CELL_error_t SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utim { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; if (mode == UBX_CELL_UTIME_MODE_STOP) // stop UTIME does not require a sensor snprintf(command, cmdLen, "%s=%d", UBX_CELL_GNSS_REQUEST_TIME, mode); else snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_GNSS_REQUEST_TIME, mode, sensor); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); - free(command); return err; } @@ -29,24 +25,14 @@ UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_uti { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_utime_mode_t m; UBX_CELL_utime_sensor_t s; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_REQUEST_TIME); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); // Response format: \r\n+UTIME: [,]\r\n\r\nOK\r\n @@ -77,8 +63,6 @@ UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_uti err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(command); - free(response); return err; } @@ -86,15 +70,11 @@ UBX_CELL_error_t SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_GNSS_TIME_INDICATION, config); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -102,23 +82,13 @@ UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_utime_urc_configuration_t c; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_TIME_INDICATION); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); // Response format: \r\n+UTIMEIND: \r\n\r\nOK\r\n @@ -142,8 +112,6 @@ UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(command); - free(response); return err; } @@ -151,11 +119,8 @@ UBX_CELL_error_t SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32 { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds); #else @@ -163,7 +128,6 @@ UBX_CELL_error_t SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32 #endif err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -171,24 +135,14 @@ UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int3 { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; int32_t ons; int32_t os; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_TIME_CONFIGURATION); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); // Response format: \r\n+UTIMECFG: ,\r\n\r\nOK\r\n @@ -216,8 +170,6 @@ UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int3 err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(command); - free(response); return err; } @@ -225,19 +177,15 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24; - char *command; + char command[cmdLen]; if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -252,19 +200,15 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64; - char *command; + char command[cmdLen]; if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -273,20 +217,16 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64; - char *command; + char command[cmdLen]; if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value[0], value[1], value[2], value[3]); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -294,45 +234,31 @@ UBX_CELL_error_t SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t a { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32; - char *command; + char command[cmdLen]; if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_ACTION, profile, action); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *address) { size_t cmdLen = strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; int profileStore = 0; int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation int paramVals[4]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_NETWORK_ASSIGNED_DATA, profile, paramTag); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -353,8 +279,6 @@ UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *ad _debugPort->print(F("getNetworkAssignedIPAddress: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -363,9 +287,6 @@ UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *ad *address = tempAddress; } - free(command); - free(response); - return err; } diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index 1238c76..e02bf0f 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -970,13 +970,10 @@ UBX_CELL_error_t UBX_CELL::setRegistrationCallback(void (*registrationCallback)( _registrationCallback = registrationCallback; size_t cmdLen = strlen(UBX_CELL_REGISTRATION_STATUS) + 3; - char *command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + char command[cmdLen]; snprintf(command, cmdLen, "%s=%d", UBX_CELL_REGISTRATION_STATUS, 2 /*enable URC with location*/); UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -986,13 +983,10 @@ UBX_CELL_error_t UBX_CELL::setEpsRegistrationCallback( _epsRegistrationCallback = registrationCallback; size_t cmdLen = strlen(UBX_CELL_EPSREGISTRATION_STATUS) + 3; - char *command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + char command[cmdLen]; snprintf(command, cmdLen, "%s=%d", UBX_CELL_EPSREGISTRATION_STATUS, 2 /*enable URC with location*/); UBX_CELL_error_t err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -1024,25 +1018,18 @@ UBX_CELL_error_t UBX_CELL::enableEcho(bool enable) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_ECHO) + 2; - char *command; - - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + char command[cmdLen]; snprintf(command, cmdLen, "%s%d", UBX_CELL_COMMAND_ECHO, enable ? 1 : 0); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } String UBX_CELL::getManufacturerID(void) { - char *response; + char response[minimumResponseAllocation]; char idResponse[16] = {0x00}; // E.g. u-blox UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_MANU_ID, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1052,18 +1039,15 @@ String UBX_CELL::getManufacturerID(void) memset(idResponse, 0, 16); } } - free(response); return String(idResponse); } String UBX_CELL::getModelID(void) { - char *response; + char response[minimumResponseAllocation]; char idResponse[32] = {0x00}; // E.g. SARA-R510M8Q UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_MODEL_ID, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1073,18 +1057,15 @@ String UBX_CELL::getModelID(void) memset(idResponse, 0, 16); } } - free(response); return String(idResponse); } String UBX_CELL::getFirmwareVersion(void) { - char *response; + char response[minimumResponseAllocation]; char idResponse[16] = {0x00}; // E.g. 11.40 UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_FW_VER_ID, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1094,18 +1075,15 @@ String UBX_CELL::getFirmwareVersion(void) memset(idResponse, 0, 16); } } - free(response); return String(idResponse); } String UBX_CELL::getSerialNo(void) { - char *response; + char response[minimumResponseAllocation]; char idResponse[32] = {0x00}; // E.g. 357520070120767 UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_SERIAL_NO, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1115,18 +1093,15 @@ String UBX_CELL::getSerialNo(void) memset(idResponse, 0, 16); } } - free(response); return String(idResponse); } String UBX_CELL::getIMEI(void) { - char *response; + char response[minimumResponseAllocation]; char imeiResponse[32] = {0x00}; // E.g. 004999010640000 UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_IMEI, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1136,18 +1111,15 @@ String UBX_CELL::getIMEI(void) memset(imeiResponse, 0, 16); } } - free(response); return String(imeiResponse); } String UBX_CELL::getIMSI(void) { - char *response; + char response[minimumResponseAllocation]; char imsiResponse[32] = {0x00}; // E.g. 222107701772423 UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_IMSI, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1157,18 +1129,15 @@ String UBX_CELL::getIMSI(void) memset(imsiResponse, 0, 16); } } - free(response); return String(imsiResponse); } String UBX_CELL::getCCID(void) { - char *response; + char response[minimumResponseAllocation]; char ccidResponse[32] = {0x00}; // E.g. +CCID: 8939107900010087330 UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_CCID, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1185,18 +1154,15 @@ String UBX_CELL::getCCID(void) } } } - free(response); return String(ccidResponse); } String UBX_CELL::getSubscriberNo(void) { - char *response; + char response[minimumResponseAllocation]; char idResponse[128] = {0x00}; // E.g. +CNUM: "ABCD . AAA","123456789012",129 UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_CNUM, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1213,18 +1179,15 @@ String UBX_CELL::getSubscriberNo(void) } } } - free(response); return String(idResponse); } String UBX_CELL::getCapabilities(void) { - char *response; + char response[minimumResponseAllocation]; char idResponse[128] = {0x00}; // E.g. +GCAP: +FCLASS, +CGSM UBX_CELL_error_t err; - response = ubx_cell_calloc_char(minimumResponseAllocation); - err = sendCommandWithResponse(UBX_CELL_COMMAND_REQ_CAP, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1241,7 +1204,6 @@ String UBX_CELL::getCapabilities(void) } } } - free(response); return String(idResponse); } @@ -1271,28 +1233,16 @@ String UBX_CELL::clock(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_CLOCK) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; char *clockBegin; char *clockEnd; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return ""; snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_CLOCK); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return ""; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err != UBX_CELL_ERROR_SUCCESS) { - free(command); - free(response); return ""; } @@ -1300,25 +1250,18 @@ String UBX_CELL::clock(void) clockBegin = strchr(response, '\"'); // Find first quote if (clockBegin == nullptr) { - free(command); - free(response); return ""; } clockBegin += 1; // Increment pointer to begin at first number clockEnd = strchr(clockBegin, '\"'); // Find last quote if (clockEnd == nullptr) { - free(command); - free(response); return ""; } *(clockEnd) = '\0'; // Set last quote to null char -- end string String clock = String(clockBegin); // Extract the clock as a String _before_ freeing response - free(command); - free(response); - return (clock); } @@ -1326,25 +1269,15 @@ UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_CLOCK) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; char tzPlusMinus; int scanNum = 0; int iy, imo, id, ih, imin, is, itz; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_CLOCK); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); // Response format (if TZ is negative): \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n @@ -1376,8 +1309,6 @@ UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(command); - free(response); return err; } @@ -1446,44 +1377,28 @@ UBX_CELL_error_t UBX_CELL::autoTimeZone(bool enable) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_AUTO_TZ) + 3; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_COMMAND_AUTO_TZ, enable ? 1 : 0); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } int8_t UBX_CELL::rssi(void) { size_t cmdLen = strlen(UBX_CELL_SIGNAL_QUALITY) + 1; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int rssi; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s", UBX_CELL_SIGNAL_QUALITY); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, 10000, minimumResponseAllocation, AT_COMMAND); if (err != UBX_CELL_ERROR_SUCCESS) { - free(command); - free(response); return -1; } @@ -1501,36 +1416,22 @@ int8_t UBX_CELL::rssi(void) rssi = -1; } - free(command); - free(response); return rssi; } UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality &signal_quality) { size_t cmdLen = strlen(UBX_CELL_EXT_SIGNAL_QUALITY) + 1; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s", UBX_CELL_EXT_SIGNAL_QUALITY); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, 10000, minimumResponseAllocation, AT_COMMAND); if (err != UBX_CELL_ERROR_SUCCESS) { - free(command); - free(response); return UBX_CELL_ERROR_ERROR; } @@ -1552,38 +1453,24 @@ UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality &signal_quality) err = UBX_CELL_ERROR_SUCCESS; } - free(command); - free(response); return err; } UBX_CELL_registration_status_t UBX_CELL::registration(bool eps) { const char *tag = eps ? UBX_CELL_EPSREGISTRATION_STATUS : UBX_CELL_REGISTRATION_STATUS; - size_t cmdLen = strlen(tag) + 3; - char *command; - char *response; + size_t cmdLen = strlen(UBX_CELL_EPSREGISTRATION_STATUS) + 3; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int status; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_REGISTRATION_INVALID; snprintf(command, cmdLen, "%s?", tag); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_REGISTRATION_INVALID; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT, minimumResponseAllocation, AT_COMMAND); if (err != UBX_CELL_ERROR_SUCCESS) { - free(command); - free(response); return UBX_CELL_REGISTRATION_INVALID; } @@ -1601,8 +1488,6 @@ UBX_CELL_registration_status_t UBX_CELL::registration(bool eps) if (scanned != 1) status = UBX_CELL_REGISTRATION_INVALID; - free(command); - free(response); return (UBX_CELL_registration_status_t)status; } @@ -1719,24 +1604,14 @@ UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_ { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_DEF) + 3; - char *command; - char *response; + char command[cmdLen]; + char response[1024]; if (cid > UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_MESSAGE_PDP_DEF); - response = ubx_cell_calloc_char(1024); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT, 1024); @@ -1800,9 +1675,6 @@ UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_ err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(command); - free(response); - return err; } @@ -1810,19 +1682,10 @@ UBX_CELL_error_t UBX_CELL::getSimStatus(String *code) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_SIMPIN) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_SIMPIN); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1846,9 +1709,6 @@ UBX_CELL_error_t UBX_CELL::getSimStatus(String *code) err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(command); - free(response); - return err; } @@ -1871,15 +1731,11 @@ UBX_CELL_error_t UBX_CELL::setSIMstateReportingMode(int mode) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SIM_STATE) + 4; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_SIM_STATE, mode); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -1887,23 +1743,13 @@ UBX_CELL_error_t UBX_CELL::getSIMstateReportingMode(int *mode) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SIM_STATE) + 3; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; int m; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_SIM_STATE); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -1925,8 +1771,6 @@ UBX_CELL_error_t UBX_CELL::getSIMstateReportingMode(int *mode) err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(command); - free(response); return err; } @@ -1939,16 +1783,13 @@ UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, unsigne { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_ENTER_PPP) + 32; - char *command; + char command[cmdLen]; if ((dialing_type_char != 0) && (dialing_type_char != 'T') && (dialing_type_char != 'P')) { return UBX_CELL_ERROR_UNEXPECTED_PARAM; } - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; if (dialing_type_char != 0) { snprintf(command, cmdLen, "%s%c*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialing_type_char, dialNumber, PPP_L2P[l2p], @@ -1961,7 +1802,6 @@ UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, unsigne err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -1969,22 +1809,16 @@ uint8_t UBX_CELL::getOperators(struct operator_stats *opRet, int maxOps) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 3; - char *command; + char command[cmdLen]; char *response; uint8_t opsSeen = 0; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=?", UBX_CELL_OPERATOR_SELECTION); int responseSize = (maxOps + 1) * 48; response = ubx_cell_calloc_char(responseSize); if (response == nullptr) - { - free(command); return UBX_CELL_ERROR_OUT_OF_MEMORY; - } // AT+COPS maximum response time is 3 minutes (180000 ms) err = @@ -2044,7 +1878,6 @@ uint8_t UBX_CELL::getOperators(struct operator_stats *opRet, int maxOps) } } - free(command); free(response); return opsSeen; @@ -2054,17 +1887,13 @@ UBX_CELL_error_t UBX_CELL::registerOperator(struct operator_stats oper) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 24; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=1,2,\"%lu\"", UBX_CELL_OPERATOR_SELECTION, oper.numOp); // AT+COPS maximum response time is 3 minutes (180000 ms) err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); - free(command); return err; } @@ -2072,17 +1901,13 @@ UBX_CELL_error_t UBX_CELL::automaticOperatorSelection() { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 6; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=0,0", UBX_CELL_OPERATOR_SELECTION); // AT+COPS maximum response time is 3 minutes (180000 ms) err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); - free(command); return err; } @@ -2090,23 +1915,13 @@ UBX_CELL_error_t UBX_CELL::getOperator(String *oper) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 3; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; char *searchPtr; char mode; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_OPERATOR_SELECTION); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - // AT+COPS maximum response time is 3 minutes (180000 ms) err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_3_MIN_TIMEOUT); @@ -2148,8 +1963,6 @@ UBX_CELL_error_t UBX_CELL::getOperator(String *oper) } } - free(response); - free(command); return err; } @@ -2157,33 +1970,25 @@ UBX_CELL_error_t UBX_CELL::deregisterOperator(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 6; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=2", UBX_CELL_OPERATOR_SELECTION); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); - free(command); return err; } UBX_CELL_error_t UBX_CELL::setSMSMessageFormat(UBX_CELL_message_format_t textMode) { size_t cmdLen = strlen(UBX_CELL_MESSAGE_FORMAT) + 4; - char *command; + char command[cmdLen]; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_MESSAGE_FORMAT, (textMode == UBX_CELL_MESSAGE_FORMAT_TEXT) ? 1 : 0); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -2238,29 +2043,17 @@ UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, Str { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_PREF_MESSAGE_STORE) + 32; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; int u; int t; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=\"%s\"", UBX_CELL_PREF_MESSAGE_STORE, memory.c_str()); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_3_MIN_TIMEOUT); if (err != UBX_CELL_ERROR_SUCCESS) { - free(command); - free(response); return err; } @@ -2292,8 +2085,6 @@ UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, Str err = UBX_CELL_ERROR_INVALID; } - free(response); - free(command); return err; } @@ -2301,21 +2092,11 @@ UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String * { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_READ_TEXT_MESSAGE) + 5; - char *command; - char *response; + char command[cmdLen]; + char response[1024]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_READ_TEXT_MESSAGE, location); - response = ubx_cell_calloc_char(1024); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT, 1024); if (err == UBX_CELL_ERROR_SUCCESS) @@ -2337,8 +2118,6 @@ UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String * } if ((*searchPtr == '\0') || (pointer == 12)) { - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Search to the next quote @@ -2351,8 +2130,6 @@ UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String * } if ((*searchPtr == '\0') || (pointer == 24)) { - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Skip two commas @@ -2368,8 +2145,6 @@ UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String * } if ((*searchPtr == '\0') || (pointer == 24)) { - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } // Search to the next new line @@ -2382,8 +2157,6 @@ UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String * } if ((*searchPtr == '\0') || (pointer == 512)) { - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } } @@ -2397,21 +2170,15 @@ UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String * err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(command); - free(response); - return err; } UBX_CELL_error_t UBX_CELL::deleteSMSmessage(int location, int deleteFlag) { size_t cmdLen = strlen(UBX_CELL_DELETE_MESSAGE) + 12; - char *command; + char command[cmdLen]; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; if (deleteFlag == 0) snprintf(command, cmdLen, "%s=%d", UBX_CELL_DELETE_MESSAGE, location); else @@ -2419,7 +2186,6 @@ UBX_CELL_error_t UBX_CELL::deleteSMSmessage(int location, int deleteFlag) err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_55_SECS_TIMEOUT); - free(command); return err; } @@ -2427,7 +2193,7 @@ UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_BAUD) + 7 + 12; - char *command; + char command[cmdLen]; int b = 0; // Error check -- ensure supported baud @@ -2444,15 +2210,10 @@ UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) } // Construct command - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%lu", UBX_CELL_COMMAND_BAUD, baud); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_SET_BAUD_TIMEOUT); - free(command); - return err; } @@ -2460,17 +2221,12 @@ UBX_CELL_error_t UBX_CELL::setFlowControl(UBX_CELL_flow_control_t value) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_FLOW_CONTROL) + 16; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s%d", UBX_CELL_FLOW_CONTROL, value); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; } @@ -2478,13 +2234,10 @@ UBX_CELL_error_t UBX_CELL::setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_ { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_GPIO) + 16; - char *command; + char command[cmdLen]; // Example command: AT+UGPIOC=16,2 // Example command: AT+UGPIOC=23,0,1 - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; if (mode == GPIO_OUTPUT) snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_GPIO, gpio, mode, value); else @@ -2492,8 +2245,6 @@ UBX_CELL_error_t UBX_CELL::setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_ err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); - free(command); - return err; } @@ -2501,40 +2252,25 @@ UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_GPIO) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; size_t charLen = 4; char gpioChar[charLen]; char *gpioStart; int gpioMode; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return GPIO_MODE_INVALID; snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_GPIO); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return GPIO_MODE_INVALID; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err != UBX_CELL_ERROR_SUCCESS) { - free(command); - free(response); return GPIO_MODE_INVALID; } snprintf(gpioChar, charLen, "%d", gpio); // Convert GPIO to char array gpioStart = strstr(response, gpioChar); // Find first occurence of GPIO in response - free(command); - free(response); - if (gpioStart == nullptr) return GPIO_MODE_INVALID; // If not found return invalid sscanf(gpioStart, "%*d,%d\r\n", &gpioMode); @@ -2546,28 +2282,16 @@ int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int local { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_CREATE_SOCKET) + 10; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; int sockId = -1; char *responseStart; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return -1; if (localPort == 0) snprintf(command, cmdLen, "%s=%d", UBX_CELL_CREATE_SOCKET, (int)protocol); else snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_CREATE_SOCKET, (int)protocol, localPort); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - if (_printDebug == true) - _debugPort->println(F("socketOpen: Fail: nullptr response")); - free(command); - return -1; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err != UBX_CELL_ERROR_SUCCESS) @@ -2580,8 +2304,6 @@ int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int local _debugPort->print(response); _debugPort->println(F("}")); } - free(command); - free(response); return -1; } @@ -2594,8 +2316,6 @@ int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int local _debugPort->print(response); _debugPort->println(F("}")); } - free(command); - free(response); return -1; } @@ -2605,9 +2325,6 @@ int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int local sscanf(responseStart, "%d", &sockId); _lastSocketProtocol[sockId] = (int)protocol; - free(command); - free(response); - return sockId; } @@ -2615,18 +2332,9 @@ UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_CLOSE_SOCKET) + 10; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } // if timeout is short, close asynchronously and don't wait for socket closure (we will get the URC later) // this will make sure the AT command parser is not confused during init() const char *format = (UBX_CELL_STANDARD_RESPONSE_TIMEOUT == timeout) ? "%s=%d,1" : "%s=%d"; @@ -2640,9 +2348,6 @@ UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) _debugPort->println(socketGetLastError()); } - free(command); - free(response); - return err; } @@ -2667,9 +2372,7 @@ UBX_CELL_error_t UBX_CELL::socketConnect(int socket, const char *address, unsign UBX_CELL_error_t UBX_CELL::socketConnect(int socket, IPAddress address, unsigned int port) { size_t charLen = 16; - char *charAddress = ubx_cell_calloc_char(charLen); - if (charAddress == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + char charAddress[charLen]; memset(charAddress, 0, 16); snprintf(charAddress, charLen, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); @@ -2679,19 +2382,10 @@ UBX_CELL_error_t UBX_CELL::socketConnect(int socket, IPAddress address, unsigned UBX_CELL_error_t UBX_CELL::socketWrite(int socket, const char *str, int len) { size_t cmdLen = strlen(UBX_CELL_WRITE_SOCKET) + 16; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } int dataLen = len == -1 ? strlen(str) : len; snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_WRITE_SOCKET, socket, dataLen); @@ -2738,8 +2432,6 @@ UBX_CELL_error_t UBX_CELL::socketWrite(int socket, const char *str, int len) } } - free(command); - free(response); return err; } @@ -2751,21 +2443,11 @@ UBX_CELL_error_t UBX_CELL::socketWrite(int socket, String str) UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int port, const char *str, int len) { size_t cmdLen = 64; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int dataLen = len == -1 ? strlen(str) : len; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - snprintf(command, cmdLen, "%s=%d,\"%s\",%d,%d", UBX_CELL_WRITE_UDP_SOCKET, socket, address, port, dataLen); err = sendCommandWithResponse(command, "@", response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT * 5); @@ -2789,17 +2471,13 @@ UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int p _debugPort->println(socketGetLastError()); } - free(command); - free(response); return err; } UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len) { size_t charLen = 16; - char *charAddress = ubx_cell_calloc_char(16); - if (charAddress == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + char charAddress[16]; memset(charAddress, 0, 16); snprintf(charAddress, charLen, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]); @@ -2814,8 +2492,10 @@ UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, String address, int port, UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, int *bytesRead) { size_t cmdLen = strlen(UBX_CELL_READ_SOCKET) + 32; - char *command; - char *response; + char command[cmdLen]; + // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing + int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_SOCKET) + minimumResponseAllocation; + char response[responseLength]; char *strBegin; int readIndexTotal = 0; int readIndexThisRead = 0; @@ -2838,21 +2518,6 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in return UBX_CELL_ERROR_UNEXPECTED_PARAM; } - // Allocate memory for the command - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - - // Allocate memory for the response - // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing - int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_SOCKET) + minimumResponseAllocation; - response = ubx_cell_calloc_char(responseLength); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - // If there are more than _saraR5maxSocketRead (1024) bytes to be read, // we need to do multiple reads to get all the data @@ -2875,8 +2540,6 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in _debugPort->print(F("socketRead: sendCommandWithResponse err ")); _debugPort->println(err); } - free(command); - free(response); return err; } @@ -2896,8 +2559,6 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in _debugPort->print(F("socketRead: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -2920,8 +2581,6 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in { _debugPort->println(F("socketRead: zero length!")); } - free(command); - free(response); return UBX_CELL_ERROR_ZERO_READ_LENGTH; } @@ -2930,8 +2589,6 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in if (strBegin == nullptr) { - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -2966,34 +2623,21 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in } } // /while (bytesLeftToRead > 0) - free(command); - free(response); - return UBX_CELL_ERROR_SUCCESS; } UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) { size_t cmdLen = strlen(UBX_CELL_READ_SOCKET) + 32; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; int readLength = 0; int socketStore = 0; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,0", UBX_CELL_READ_SOCKET, socket); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -3013,17 +2657,12 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) _debugPort->print(F("socketReadAvailable: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *length = readLength; } - free(command); - free(response); - return err; } @@ -3031,8 +2670,10 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, int *remotePort, int *bytesRead) { size_t cmdLen = strlen(UBX_CELL_READ_UDP_SOCKET) + 32; - char *command; - char *response; + char command[cmdLen]; + // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing + int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_UDP_SOCKET) + minimumResponseAllocation; + char response[responseLength]; char *strBegin; int readIndexTotal = 0; int readIndexThisRead = 0; @@ -3057,21 +2698,6 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, return UBX_CELL_ERROR_UNEXPECTED_PARAM; } - // Allocate memory for the command - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - - // Allocate memory for the response - // We only need enough to read _saraR5maxSocketRead bytes - not the whole thing - int responseLength = _saraR5maxSocketRead + strlen(UBX_CELL_READ_UDP_SOCKET) + minimumResponseAllocation; - response = ubx_cell_calloc_char(responseLength); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - // If there are more than _saraR5maxSocketRead (1024) bytes to be read, // we need to do multiple reads to get all the data @@ -3094,8 +2720,6 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, _debugPort->print(F("socketReadUDP: sendCommandWithResponse err ")); _debugPort->println(err); } - free(command); - free(response); return err; } @@ -3116,8 +2740,6 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, _debugPort->print(F("socketReadUDP: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -3140,8 +2762,6 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, { _debugPort->println(F("socketRead: zero length!")); } - free(command); - free(response); return UBX_CELL_ERROR_ZERO_READ_LENGTH; } @@ -3152,8 +2772,6 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, if (strBegin == nullptr) { - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -3205,34 +2823,21 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, } } // /while (bytesLeftToRead > 0) - free(command); - free(response); - return UBX_CELL_ERROR_SUCCESS; } UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) { size_t cmdLen = strlen(UBX_CELL_READ_UDP_SOCKET) + 32; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; int readLength = 0; int socketStore = 0; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,0", UBX_CELL_READ_UDP_SOCKET, socket); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -3252,17 +2857,12 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) _debugPort->print(F("socketReadAvailableUDP: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *length = readLength; } - free(command); - free(response); - return err; } @@ -3270,16 +2870,12 @@ UBX_CELL_error_t UBX_CELL::socketListen(int socket, unsigned int port) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_LISTEN_SOCKET) + 9; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_LISTEN_SOCKET, socket, port); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -3287,16 +2883,12 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkMode(int socket) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SOCKET_DIRECT_LINK) + 8; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_SOCKET_DIRECT_LINK, socket); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -3308,16 +2900,12 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkTimeTrigger(int socket, unsigned long UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_UD_CONFIGURATION) + 16; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=5,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, timerTrigger); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -3329,16 +2917,12 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkDataLengthTrigger(int socket, int dat UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_UD_CONFIGURATION) + 16; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=6,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, dataLengthTrigger); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -3350,16 +2934,12 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkCharacterTrigger(int socket, int char UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_UD_CONFIGURATION) + 16; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=7,%d,%d", UBX_CELL_UD_CONFIGURATION, socket, characterTrigger); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -3371,41 +2951,27 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkCongestionTimer(int socket, unsigned UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_UD_CONFIGURATION) + 16; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=8,%d,%ld", UBX_CELL_UD_CONFIGURATION, socket, congestionTimer); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; int paramVal; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,0", UBX_CELL_SOCKET_CONTROL, socket); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -3425,8 +2991,6 @@ UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_ _debugPort->print(F("querySocketType: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -3434,34 +2998,21 @@ UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_ _lastSocketProtocol[socketStore] = paramVal; } - free(command); - free(response); - return err; } UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; int paramVal; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,1", UBX_CELL_SOCKET_CONTROL, socket); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -3481,42 +3032,27 @@ UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) _debugPort->print(F("querySocketLastError: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *error = paramVal; } - free(command); - free(response); - return err; } UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; long unsigned int paramVal; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,2", UBX_CELL_SOCKET_CONTROL, socket); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -3536,42 +3072,27 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total _debugPort->print(F("querySocketTotalBytesSent: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *total = (uint32_t)paramVal; } - free(command); - free(response); - return err; } UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *total) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; long unsigned int paramVal; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,3", UBX_CELL_SOCKET_CONTROL, socket); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -3591,42 +3112,27 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *t _debugPort->print(F("querySocketTotalBytesReceived: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *total = (uint32_t)paramVal; } - free(command); - free(response); - return err; } UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *address, int *port) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; int paramVals[5]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,4", UBX_CELL_SOCKET_CONTROL, socket); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -3647,8 +3153,6 @@ UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *add _debugPort->print(F("querySocketRemoteIPAddress: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -3658,33 +3162,20 @@ UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *add *port = paramVals[4]; } - free(command); - free(response); - return err; } UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; - int socketStore = 0; - int paramVal; - - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - snprintf(command, cmdLen, "%s=%d,10", UBX_CELL_SOCKET_CONTROL, socket); - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } + int socketStore = 0; + int paramVal; + + snprintf(command, cmdLen, "%s=%d,10", UBX_CELL_SOCKET_CONTROL, socket); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3705,42 +3196,27 @@ UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_ _debugPort->print(F("querySocketStatusTCP: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *status = (UBX_CELL_tcp_socket_status_t)paramVal; } - free(command); - free(response); - return err; } UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; int scanNum = 0; int socketStore = 0; long unsigned int paramVal; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,11", UBX_CELL_SOCKET_CONTROL, socket); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -3760,17 +3236,12 @@ UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) _debugPort->print(F("querySocketOutUnackData: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } *total = (uint32_t)paramVal; } - free(command); - free(response); - return err; } @@ -3779,21 +3250,10 @@ int UBX_CELL::socketGetLastError() { UBX_CELL_error_t err; size_t cmdLen = 64; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; int errorCode = -1; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - snprintf(command, cmdLen, "%s", UBX_CELL_GET_ERROR); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3810,9 +3270,6 @@ int UBX_CELL::socketGetLastError() } } - free(command); - free(response); - return errorCode; } @@ -3825,19 +3282,15 @@ UBX_CELL_error_t UBX_CELL::resetHTTPprofile(int profile) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 16; - char *command; + char command[cmdLen]; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_HTTP_PROFILE, profile); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -3845,20 +3298,16 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverIPaddress(int profile, IPAddress address { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 64; - char *command; + char command[cmdLen]; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_IP, address[0], address[1], address[2], address[3]); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -3929,19 +3378,15 @@ UBX_CELL_error_t UBX_CELL::setHTTPauthentication(int profile, bool authenticate) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 32; - char *command; + char command[cmdLen]; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, authenticate); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -3949,19 +3394,15 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverPort(int profile, int port) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 32; - char *command; + char command[cmdLen]; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_PORT, port); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -3990,14 +3431,11 @@ UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofil { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 32; - char *command; + char command[cmdLen]; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; if (secprofile == -1) snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure); else @@ -4006,7 +3444,6 @@ UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofil err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -4099,23 +3536,13 @@ UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, i { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROTOCOL_ERROR) + 4; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; int rprofile, eclass, ecode; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_HTTP_PROTOCOL_ERROR, profile); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -4138,8 +3565,6 @@ UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, i err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(command); - free(response); return err; } @@ -4147,14 +3572,10 @@ UBX_CELL_error_t UBX_CELL::nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_NVM) + 10; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_MQTT_NVM, parameter); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -4197,9 +3618,7 @@ UBX_CELL_error_t UBX_CELL::setMQTTcredentials(const String &userName, const Stri command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) - { return UBX_CELL_ERROR_OUT_OF_MEMORY; - } snprintf(command, cmdLen, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_USERNAMEPWD, userName.c_str(), pwd.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -4211,17 +3630,13 @@ UBX_CELL_error_t UBX_CELL::setMQTTsecure(bool secure, int secprofile) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_PROFILE) + 16; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; if (secprofile == -1) snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure); else snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure, secprofile); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -4229,14 +3644,10 @@ UBX_CELL_error_t UBX_CELL::connectMQTT(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 10; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGIN); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -4244,14 +3655,10 @@ UBX_CELL_error_t UBX_CELL::disconnectMQTT(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 10; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_LOGOUT); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -4288,7 +3695,7 @@ UBX_CELL_error_t UBX_CELL::unsubscribeMQTTtopic(const String &topic) UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest, int readLength, int *bytesRead) { size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 10; - char *command; + char command[cmdLen]; char *response; UBX_CELL_error_t err; int scanNum = 0; @@ -4298,19 +3705,11 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest if (bytesRead != nullptr) *bytesRead = 0; - // Allocate memory for the command - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; - // Allocate memory for the response int responseLength = readLength + minimumResponseAllocation; response = ubx_cell_calloc_char(responseLength); if (response == nullptr) - { - free(command); return UBX_CELL_ERROR_OUT_OF_MEMORY; - } // Note to self: if the file contents contain "OK\r\n" sendCommandWithResponse will return true too early... // To try and avoid this, look for \"\r\n\r\nOK\r\n there is a extra \r\n beetween " and the the standard \r\nOK\r\n @@ -4326,7 +3725,6 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest _debugPort->print(F("readMQTT: sendCommandWithResponse err ")); _debugPort->println(err); } - free(command); free(response); return err; } @@ -4349,7 +3747,6 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest _debugPort->print(F("readMQTT: error: scanNum is ")); _debugPort->println(scanNum); } - free(command); free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -4389,7 +3786,6 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } } - free(command); free(response); return err; @@ -4429,9 +3825,7 @@ UBX_CELL_error_t UBX_CELL::mqttPublishTextMsg(const String &topic, const char *c size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + msg_len; char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) - { return UBX_CELL_ERROR_OUT_OF_MEMORY; - } snprintf(command, cmdLen, "%s=%d,%u,%u,0,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISH, qos, (retain ? 1 : 0), topic.c_str(), sanitized_msg); @@ -4469,9 +3863,7 @@ UBX_CELL_error_t UBX_CELL::mqttPublishBinaryMsg(const String &topic, const char size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length(); char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) - { return UBX_CELL_ERROR_OUT_OF_MEMORY; - } snprintf(command, cmdLen, "%s=%d,%u,%u,\"%s\",%u", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, qos, (retain ? 1 : 0), topic.c_str(), msg_len); @@ -4499,9 +3891,7 @@ UBX_CELL_error_t UBX_CELL::mqttPublishFromFile(const String &topic, const String size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 20 + topic.length() + filename.length(); char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) - { return UBX_CELL_ERROR_OUT_OF_MEMORY; - } snprintf(command, cmdLen, "%s=%d,%u,%u,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHFILE, qos, (retain ? 1 : 0), topic.c_str(), filename.c_str()); @@ -4516,16 +3906,10 @@ UBX_CELL_error_t UBX_CELL::mqttPublishFromFile(const String &topic, const String UBX_CELL_error_t UBX_CELL::getMQTTprotocolError(int *error_code, int *error_code2) { UBX_CELL_error_t err; - char *response; + char response[minimumResponseAllocation]; int code, code2; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(UBX_CELL_MQTT_PROTOCOL_ERROR, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -4549,7 +3933,6 @@ UBX_CELL_error_t UBX_CELL::getMQTTprotocolError(int *error_code, int *error_code err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } - free(response); return err; } @@ -4617,9 +4000,7 @@ UBX_CELL_error_t UBX_CELL::ftpGetFile(const String &filename) size_t cmdLen = strlen(UBX_CELL_FTP_COMMAND) + (2 * filename.length()) + 16; char *command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) - { return UBX_CELL_ERROR_OUT_OF_MEMORY; - } snprintf(command, cmdLen, "%s=%d,\"%s\",\"%s\"", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_GET_FILE, filename.c_str(), filename.c_str()); @@ -4635,16 +4016,10 @@ UBX_CELL_error_t UBX_CELL::ftpGetFile(const String &filename) UBX_CELL_error_t UBX_CELL::getFTPprotocolError(int *error_code, int *error_code2) { UBX_CELL_error_t err; - char *response; + char response[minimumResponseAllocation]; int code, code2; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(UBX_CELL_FTP_PROTOCOL_ERROR, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -4673,7 +4048,6 @@ UBX_CELL_error_t UBX_CELL::getFTPprotocolError(int *error_code, int *error_code2 } } - free(response); return err; } @@ -4681,17 +4055,12 @@ UBX_CELL_error_t UBX_CELL::resetSecurityProfile(int secprofile) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SEC_PROFILE) + 6; - char *command; - - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + char command[cmdLen]; snprintf(command, cmdLen, "%s=%d", UBX_CELL_SEC_PROFILE, secprofile); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -4699,14 +4068,10 @@ UBX_CELL_error_t UBX_CELL::configSecurityProfile(int secprofile, UBX_CELL_sec_pr { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SEC_PROFILE) + 10; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_SEC_PROFILE, secprofile, parameter, value); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -4731,18 +4096,12 @@ UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opco { size_t cmdLen = strlen(UBX_CELL_SEC_MANAGER) + name.length() + 20; char *command; - char *response; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } int dataLen = data.length(); snprintf(command, cmdLen, "%s=%d,%d,\"%s\",%d", UBX_CELL_SEC_MANAGER, opcode, parameter, name.c_str(), dataLen); @@ -4772,7 +4131,6 @@ UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opco } free(command); - free(response); return err; } @@ -4780,14 +4138,11 @@ UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE) + 32; - char *command; + char command[cmdLen]; if (cid >= UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS) return UBX_CELL_ERROR_ERROR; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; if (cid == -1) snprintf(command, cmdLen, "%s=%d", UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE, status); else @@ -4795,7 +4150,6 @@ UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -4803,22 +4157,12 @@ bool UBX_CELL::isGPSon(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_POWER) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; bool on = false; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_POWER); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) @@ -4834,9 +4178,6 @@ bool UBX_CELL::isGPSon(void) } } - free(command); - free(response); - return on; } @@ -4844,7 +4185,7 @@ UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_ai { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_POWER) + 32; // gnss_sys could be up to three digits - char *command; + char command[cmdLen]; bool gpsState; // Don't turn GPS on/off if it's already on/off @@ -4855,9 +4196,6 @@ UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_ai } // GPS power management - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; if (enable) { snprintf(command, cmdLen, "%s=1,%d,%d", UBX_CELL_GNSS_POWER, gnss_aiding, gnss_sys); @@ -4869,7 +4207,6 @@ UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_ai err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, 10000); - free(command); return err; } @@ -4936,7 +4273,7 @@ UBX_CELL_error_t UBX_CELL::gpsEnableRmc(bool enable) // AT+UGRMC=<0,1> UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_GPRMC) + 3; - char *command; + char command[cmdLen]; // ** Don't call gpsPower here. It causes problems for +UTIME and the PPS signal ** // ** Call isGPSon and gpsPower externally if required ** @@ -4949,14 +4286,10 @@ UBX_CELL_error_t UBX_CELL::gpsEnableRmc(bool enable) // } // } - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_GNSS_GPRMC, enable ? 1 : 0); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); - free(command); return err; } @@ -4965,22 +4298,12 @@ UBX_CELL_error_t UBX_CELL::gpsGetRmc(struct PositionData *pos, struct SpeedData { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_GPRMC) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; char *rmcBegin; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_GPRMC); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) { @@ -4996,8 +4319,6 @@ UBX_CELL_error_t UBX_CELL::gpsGetRmc(struct PositionData *pos, struct SpeedData } } - free(command); - free(response); return err; } @@ -5022,7 +4343,7 @@ UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, b // AT+ULOC=2,,,, UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_LOCATION) + 24; - char *command; + char command[cmdLen]; // This function will only work if the GPS module is initially turned off. if (isGPSon()) @@ -5035,9 +4356,6 @@ UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, b if (accuracy > 999999) accuracy = 999999; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) snprintf(command, cmdLen, "%s=2,%d,%d,%d,%d", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); #else @@ -5046,7 +4364,6 @@ UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, b err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); - free(command); return err; } @@ -5057,18 +4374,13 @@ UBX_CELL_error_t UBX_CELL::gpsAidingServerConf(const char *primaryServer, const { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_AIDING_SERVER_CONFIGURATION) + 256; - char *command; - - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + char command[cmdLen]; snprintf(command, cmdLen, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBX_CELL_AIDING_SERVER_CONFIGURATION, primaryServer, secondaryServer, authToken, days, period, resolution, gnssTypes, mode, dataType); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -5077,18 +4389,12 @@ UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, const char *str, { size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE) + filename.length() + 10; char *command; - char *response; + char response[minimumResponseAllocation]; UBX_CELL_error_t err; command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } int dataLen = len == -1 ? strlen(str) : len; snprintf(command, cmdLen, "%s=\"%s\",%d", UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE, filename.c_str(), dataLen); @@ -5123,7 +4429,6 @@ UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, const char *str, } free(command); - free(response); return err; } @@ -5396,6 +4701,8 @@ UBX_CELL_error_t UBX_CELL::getFileBlock(const String &filename, char *buffer, si size_t cmdLen = filename.length() + 32; char *cmd = ubx_cell_calloc_char(cmdLen); + if (cmd == nullptr) + return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(cmd, cmdLen, "at+urdblock=\"%s\",%zu,%zu\r\n", filename.c_str(), offset, requested_length); sendCommand(cmd, false); @@ -5449,20 +4756,13 @@ UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_LIST_FILES) + filename.length() + 8; char *command; - char *response; + char response[minimumResponseAllocation]; command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=2,\"%s\"", UBX_CELL_FILE_SYSTEM_LIST_FILES, filename.c_str()); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err != UBX_CELL_ERROR_SUCCESS) { @@ -5475,7 +4775,6 @@ UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) _debugPort->println(F("}")); } free(command); - free(response); return err; } @@ -5489,7 +4788,6 @@ UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) _debugPort->println(F("}")); } free(command); - free(response); return UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -5501,7 +4799,6 @@ UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) *size = fileSize; free(command); - free(response); return err; } @@ -5535,17 +4832,12 @@ UBX_CELL_error_t UBX_CELL::modulePowerOff(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_POWER_OFF) + 6; - char *command; - - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; + char command[cmdLen]; snprintf(command, cmdLen, "%s", UBX_CELL_COMMAND_POWER_OFF); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_POWER_OFF_TIMEOUT); - free(command); return err; } @@ -5744,17 +5036,12 @@ UBX_CELL_error_t UBX_CELL::functionality(UBX_CELL_functionality_t function) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_FUNC) + 16; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_COMMAND_FUNC, function); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_3_MIN_TIMEOUT); - free(command); - return err; } @@ -5762,11 +5049,8 @@ UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool aut { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_MNO) + 9; - char *command; + char command[cmdLen]; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; if (mno == MNO_SIM_ICCID) // Only add autoReset and urcNotification if mno is MNO_SIM_ICCID snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno, (uint8_t)autoReset, (uint8_t)urcNotification); @@ -5775,8 +5059,6 @@ UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool aut err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); - return err; } @@ -5784,33 +5066,19 @@ UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_MNO) + 2; - char *command; - char *response; + char command[cmdLen]; + char response[minimumResponseAllocation]; mobile_network_operator_t o; int d; int r; int u; int oStore; - command = ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s?", UBX_CELL_COMMAND_MNO); - response = ubx_cell_calloc_char(minimumResponseAllocation); - if (response == nullptr) - { - free(command); - return UBX_CELL_ERROR_OUT_OF_MEMORY; - } - err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err != UBX_CELL_ERROR_SUCCESS) - { - free(command); - free(response); return err; - } int scanned = 0; char *searchPtr = strstr(response, "+UMNOPROF:"); @@ -5837,9 +5105,6 @@ UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) err = UBX_CELL_ERROR_INVALID; } - free(command); - free(response); - return err; } @@ -6195,9 +5460,7 @@ UBX_CELL_error_t UBX_CELL::parseSocketReadIndicationUDP(int socket, int length) readDest = ubx_cell_calloc_char(length + 1); if (readDest == nullptr) - { return UBX_CELL_ERROR_OUT_OF_MEMORY; - } int bytesRead; err = socketReadUDP(socket, length, readDest, &remoteAddress, &remotePort, &bytesRead); diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index 98f510b..fde1e1e 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -83,16 +83,12 @@ template class UBX_CELL_VOICE { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13; - char *command; + char command[cmdLen]; - command = static_cast(this)->ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat); err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -100,16 +96,12 @@ template class UBX_CELL_VOICE { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5; - char *command; + char command[cmdLen]; - command = static_cast(this)->ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource); err = static_cast(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -117,17 +109,13 @@ template class UBX_CELL_VOICE { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15; - char *command; + char command[cmdLen]; char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; - command = static_cast(this)->ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume); err = static_cast(this)->sendCommandWithResponse(command, response, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } @@ -135,17 +123,13 @@ template class UBX_CELL_VOICE { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14; - char *command; + char command[cmdLen]; char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n"; - command = static_cast(this)->ubx_cell_calloc_char(cmdLen); - if (command == nullptr) - return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume); err = static_cast(this)->sendCommandWithResponse(command, response, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); - free(command); return err; } From 7dc48df6f2e54286fbd40ecbb8e9025f13f643a7 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 18 Dec 2023 16:31:10 -0700 Subject: [PATCH 48/52] Change strstr to strnstr Fixes #12 --- src/sfe_sara_r5.cpp | 10 ++-- src/sfe_ublox_cellular.cpp | 106 ++++++++++++++++----------------- src/sfe_ublox_cellular_voice.h | 2 +- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp index b13d056..d80495d 100644 --- a/src/sfe_sara_r5.cpp +++ b/src/sfe_sara_r5.cpp @@ -39,7 +39,7 @@ UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_uti if (err == UBX_CELL_ERROR_SUCCESS) { int mStore, sStore, scanned = 0; - char *searchPtr = strstr(response, "+UTIME:"); + char *searchPtr = strnstr(response, "+UTIME:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+UTIME:"); // Move searchPtr to first character - probably a space @@ -95,7 +95,7 @@ UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t if (err == UBX_CELL_ERROR_SUCCESS) { int cStore, scanned = 0; - char *searchPtr = strstr(response, "+UTIMEIND:"); + char *searchPtr = strnstr(response, "+UTIMEIND:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+UTIMEIND:"); // Move searchPtr to first char @@ -149,7 +149,7 @@ UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int3 if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; - char *searchPtr = strstr(response, "+UTIMECFG:"); + char *searchPtr = strnstr(response, "+UTIMECFG:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+UTIMECFG:"); // Move searchPtr to first char @@ -263,7 +263,7 @@ UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *ad if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+UPSND:"); + char *searchPtr = strnstr(response, "+UPSND:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+UPSND:"); // Move searchPtr to first char @@ -298,7 +298,7 @@ bool SARA_R5::urcHandlerPDPAction(const char *event) int scanNum; int remoteIPstore[4]; - char *searchPtr = strstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC); + char *searchPtr = strnstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index e02bf0f..e353a9e 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -346,7 +346,7 @@ bool UBX_CELL::urcHandlerReadSocket(const char *event) { // URC: +UUSORD (Read Socket Data) int socket, length; - char *searchPtr = strstr(event, UBX_CELL_READ_SOCKET_URC); + char *searchPtr = strnstr(event, UBX_CELL_READ_SOCKET_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_READ_SOCKET_URC); // Move searchPtr to first character - probably a space @@ -384,7 +384,7 @@ bool UBX_CELL::urcHandlerReadUDPSocket(const char *event) { // URC: +UUSORF (Receive From command (UDP only)) int socket, length; - char *searchPtr = strstr(event, UBX_CELL_READ_UDP_SOCKET_URC); + char *searchPtr = strnstr(event, UBX_CELL_READ_UDP_SOCKET_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_READ_UDP_SOCKET_URC); // Move searchPtr to first character - probably a space @@ -415,7 +415,7 @@ bool UBX_CELL::urcHandlerListeningSocket(const char *event) int remoteIPstore[4] = {0, 0, 0, 0}; int localIPstore[4] = {0, 0, 0, 0}; - char *searchPtr = strstr(event, UBX_CELL_LISTEN_SOCKET_URC); + char *searchPtr = strnstr(event, UBX_CELL_LISTEN_SOCKET_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_LISTEN_SOCKET_URC); // Move searchPtr to first character - probably a space @@ -447,7 +447,7 @@ bool UBX_CELL::urcHandlerCloseSocket(const char *event) { // URC: +UUSOCL (Close Socket) int socket; - char *searchPtr = strstr(event, UBX_CELL_CLOSE_SOCKET_URC); + char *searchPtr = strnstr(event, UBX_CELL_CLOSE_SOCKET_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_CLOSE_SOCKET_URC); // Move searchPtr to first character - probably a space @@ -488,7 +488,7 @@ bool UBX_CELL::urcHandlerGNSSRequestLocation(const char *event) // Maybe we should also scan for +UUGIND and extract the activated gnss system? // This assumes the ULOC response type is "0" or "1" - as selected by gpsRequest detailed - char *searchPtr = strstr(event, UBX_CELL_GNSS_REQUEST_LOCATION_URC); + char *searchPtr = strnstr(event, UBX_CELL_GNSS_REQUEST_LOCATION_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_GNSS_REQUEST_LOCATION_URC); // Move searchPtr to first character - probably a space @@ -559,7 +559,7 @@ bool UBX_CELL::urcHandlerSIMState(const char *event) int scanNum; int stateStore; - char *searchPtr = strstr(event, UBX_CELL_SIM_STATE_URC); + char *searchPtr = strnstr(event, UBX_CELL_SIM_STATE_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_SIM_STATE_URC); // Move searchPtr to first character - probably a space @@ -592,7 +592,7 @@ bool UBX_CELL::urcHandlerHTTPCommand(const char *event) int profile, command, result; int scanNum; - char *searchPtr = strstr(event, UBX_CELL_HTTP_COMMAND_URC); + char *searchPtr = strnstr(event, UBX_CELL_HTTP_COMMAND_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_HTTP_COMMAND_URC); // Move searchPtr to first character - probably a space @@ -628,7 +628,7 @@ bool UBX_CELL::urcHandlerMQTTCommand(const char *event) int qos = -1; String topic; - char *searchPtr = strstr(event, UBX_CELL_MQTT_COMMAND_URC); + char *searchPtr = strnstr(event, UBX_CELL_MQTT_COMMAND_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_MQTT_COMMAND_URC); // Move searchPtr to first character - probably a space @@ -675,7 +675,7 @@ bool UBX_CELL::urcHandlerPingCommand(const char *event) int scanNum; // Try to extract the UUPING retries and payload size - char *searchPtr = strstr(event, UBX_CELL_PING_COMMAND_URC); + char *searchPtr = strnstr(event, UBX_CELL_PING_COMMAND_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_PING_COMMAND_URC); // Move searchPtr to first character - probably a space @@ -747,7 +747,7 @@ bool UBX_CELL::urcHandlerFTPCommand(const char *event) int ftpCmd; int ftpResult; int scanNum; - char *searchPtr = strstr(event, UBX_CELL_FTP_COMMAND_URC); + char *searchPtr = strnstr(event, UBX_CELL_FTP_COMMAND_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_FTP_COMMAND_URC); // Move searchPtr to first character - probably a space @@ -772,7 +772,7 @@ bool UBX_CELL::urcHandlerRegistrationStatus(const char *event) // URC: +CREG int status = 0; unsigned int lac = 0, ci = 0, Act = 0; - char *searchPtr = strstr(event, UBX_CELL_REGISTRATION_STATUS_URC); + char *searchPtr = strnstr(event, UBX_CELL_REGISTRATION_STATUS_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += strlen(UBX_CELL_REGISTRATION_STATUS_URC); // Move searchPtr to first character - probably a space @@ -801,7 +801,7 @@ bool UBX_CELL::urcHandlerEPSRegistrationStatus(const char *event) // URC: +CEREG int status = 0; unsigned int tac = 0, ci = 0, Act = 0; - char *searchPtr = strstr(event, UBX_CELL_EPSREGISTRATION_STATUS_URC); + char *searchPtr = strnstr(event, UBX_CELL_EPSREGISTRATION_STATUS_URC, _RXBuffSize); if (searchPtr != nullptr) { searchPtr += @@ -1142,7 +1142,7 @@ String UBX_CELL::getCCID(void) UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "\r\n+CCID:"); + char *searchPtr = strnstr(response, "\r\n+CCID:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("\r\n+CCID:"); // Move searchPtr to first character - probably a space @@ -1167,7 +1167,7 @@ String UBX_CELL::getSubscriberNo(void) UBX_CELL_10_SEC_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "\r\n+CNUM:"); + char *searchPtr = strnstr(response, "\r\n+CNUM:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("\r\n+CNUM:"); // Move searchPtr to first character - probably a space @@ -1192,7 +1192,7 @@ String UBX_CELL::getCapabilities(void) UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "\r\n+GCAP:"); + char *searchPtr = strnstr(response, "\r\n+GCAP:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("\r\n+GCAP:"); // Move searchPtr to first character - probably a space @@ -1283,7 +1283,7 @@ UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h // Response format (if TZ is negative): \r\n+CCLK: "YY/MM/DD,HH:MM:SS-TZ"\r\n\r\nOK\r\n if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+CCLK:"); + char *searchPtr = strnstr(response, "+CCLK:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+CCLK:"); // Move searchPtr to first char @@ -1403,7 +1403,7 @@ int8_t UBX_CELL::rssi(void) } int scanned = 0; - char *searchPtr = strstr(response, "+CSQ:"); + char *searchPtr = strnstr(response, "+CSQ:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+CSQ:"); // Move searchPtr to first char @@ -1437,7 +1437,7 @@ UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality &signal_quality) int scanned = 0; const char *responseStr = "+CESQ:"; - char *searchPtr = strstr(response, responseStr); + char *searchPtr = strnstr(response, responseStr, minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen(responseStr); // Move searchPtr to first char @@ -1476,7 +1476,7 @@ UBX_CELL_registration_status_t UBX_CELL::registration(bool eps) int scanned = 0; const char *startTag = eps ? UBX_CELL_EPSREGISTRATION_STATUS_URC : UBX_CELL_REGISTRATION_STATUS_URC; - char *searchPtr = strstr(response, startTag); + char *searchPtr = strnstr(response, startTag, minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += eps ? strlen(UBX_CELL_EPSREGISTRATION_STATUS_URC) @@ -1628,7 +1628,7 @@ UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_ { int scanned = 0; // Find the first/next occurrence of +CGDCONT: - searchPtr = strstr(searchPtr, "+CGDCONT:"); + searchPtr = strnstr(searchPtr, "+CGDCONT:", 1024 - (searchPtr - response)); if (searchPtr != nullptr) { char strPdpType[10]; @@ -1692,7 +1692,7 @@ UBX_CELL_error_t UBX_CELL::getSimStatus(String *code) { int scanned = 0; char c[16]; - char *searchPtr = strstr(response, "+CPIN:"); + char *searchPtr = strnstr(response, "+CPIN:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+CPIN:"); // Move searchPtr to first char @@ -1755,7 +1755,7 @@ UBX_CELL_error_t UBX_CELL::getSIMstateReportingMode(int *mode) if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; - char *searchPtr = strstr(response, "+USIMSTAT:"); + char *searchPtr = strnstr(response, "+USIMSTAT:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USIMSTAT:"); // Move searchPtr to first char @@ -1927,7 +1927,7 @@ UBX_CELL_error_t UBX_CELL::getOperator(String *oper) if (err == UBX_CELL_ERROR_SUCCESS) { - searchPtr = strstr(response, "+COPS:"); + searchPtr = strnstr(response, "+COPS:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+COPS:"); // Move searchPtr to first char @@ -2058,7 +2058,7 @@ UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, Str } int scanned = 0; - char *searchPtr = strstr(response, "+CPMS:"); + char *searchPtr = strnstr(response, "+CPMS:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+CPMS:"); // Move searchPtr to first char @@ -2104,7 +2104,7 @@ UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String * char *searchPtr = response; // Find the first occurrence of +CMGR: - searchPtr = strstr(searchPtr, "+CMGR:"); + searchPtr = strnstr(searchPtr, "+CMGR:", 1024 - (searchPtr - response)); if (searchPtr != nullptr) { searchPtr += strlen("+CMGR:"); // Move searchPtr to first char @@ -2269,7 +2269,7 @@ UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) } snprintf(gpioChar, charLen, "%d", gpio); // Convert GPIO to char array - gpioStart = strstr(response, gpioChar); // Find first occurence of GPIO in response + gpioStart = strnstr(response, gpioChar, minimumResponseAllocation); // Find first occurence of GPIO in response if (gpioStart == nullptr) return GPIO_MODE_INVALID; // If not found return invalid @@ -2307,7 +2307,7 @@ int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int local return -1; } - responseStart = strstr(response, "+USOCR:"); + responseStart = strnstr(response, "+USOCR:", minimumResponseAllocation); if (responseStart == nullptr) { if (_printDebug == true) @@ -2544,7 +2544,7 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in } // Extract the data - char *searchPtr = strstr(response, "+USORD:"); + char *searchPtr = strnstr(response, "+USORD:", responseLength); if (searchPtr != nullptr) { searchPtr += strlen("+USORD:"); // Move searchPtr to first char @@ -2642,7 +2642,7 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USORD:"); + char *searchPtr = strnstr(response, "+USORD:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USORD:"); // Move searchPtr to first char @@ -2724,7 +2724,7 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, } // Extract the data - char *searchPtr = strstr(response, "+USORF:"); + char *searchPtr = strnstr(response, "+USORF:", responseLength); if (searchPtr != nullptr) { searchPtr += strlen("+USORF:"); // Move searchPtr to first char @@ -2842,7 +2842,7 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USORF:"); + char *searchPtr = strnstr(response, "+USORF:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USORF:"); // Move searchPtr to first char @@ -2976,7 +2976,7 @@ UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_ if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USOCTL:"); + char *searchPtr = strnstr(response, "+USOCTL:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char @@ -3017,7 +3017,7 @@ UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USOCTL:"); + char *searchPtr = strnstr(response, "+USOCTL:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char @@ -3057,7 +3057,7 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USOCTL:"); + char *searchPtr = strnstr(response, "+USOCTL:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char @@ -3097,7 +3097,7 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *t if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USOCTL:"); + char *searchPtr = strnstr(response, "+USOCTL:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char @@ -3137,7 +3137,7 @@ UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *add if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USOCTL:"); + char *searchPtr = strnstr(response, "+USOCTL:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char @@ -3181,7 +3181,7 @@ UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_ if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USOCTL:"); + char *searchPtr = strnstr(response, "+USOCTL:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char @@ -3221,7 +3221,7 @@ UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USOCTL:"); + char *searchPtr = strnstr(response, "+USOCTL:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USOCTL:"); // Move searchPtr to first char @@ -3260,7 +3260,7 @@ int UBX_CELL::socketGetLastError() if (err == UBX_CELL_ERROR_SUCCESS) { - char *searchPtr = strstr(response, "+USOER:"); + char *searchPtr = strnstr(response, "+USOER:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+USOER:"); // Move searchPtr to first char @@ -3548,7 +3548,7 @@ UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, i if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; - char *searchPtr = strstr(response, "+UHTTPER:"); + char *searchPtr = strnstr(response, "+UHTTPER:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+UHTTPER:"); // Move searchPtr to first char @@ -3730,7 +3730,7 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest } // Extract the data - char *searchPtr = strstr(response, "+UMQTTC:"); + char *searchPtr = strnstr(response, "+UMQTTC:", responseLength); int cmd = 0; if (searchPtr != nullptr) { @@ -3752,7 +3752,7 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest } err = UBX_CELL_ERROR_SUCCESS; - searchPtr = strstr(searchPtr, "\""); + searchPtr = strnstr(searchPtr, "\"", responseLength - (searchPtr - response)); if (searchPtr != nullptr) { if (pTopic) @@ -3761,7 +3761,7 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest *pTopic = searchPtr + 1; searchPtr[topic_length + 1] = '\"'; // restore } - searchPtr = strstr(searchPtr + topic_length + 2, "\""); + searchPtr = strnstr(searchPtr + topic_length + 2, "\"", responseLength - (searchPtr + topic_length + 2 - response)); if (readDest && (searchPtr != nullptr) && (response + responseLength >= searchPtr + data_length + 1) && (searchPtr[data_length + 1] == '"')) { @@ -3916,7 +3916,7 @@ UBX_CELL_error_t UBX_CELL::getMQTTprotocolError(int *error_code, int *error_code if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; - char *searchPtr = strstr(response, "+UMQTTER:"); + char *searchPtr = strnstr(response, "+UMQTTER:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+UMQTTER:"); // Move searchPtr to first char @@ -4026,7 +4026,7 @@ UBX_CELL_error_t UBX_CELL::getFTPprotocolError(int *error_code, int *error_code2 if (err == UBX_CELL_ERROR_SUCCESS) { int scanned = 0; - char *searchPtr = strstr(response, "+UFTPER:"); + char *searchPtr = strnstr(response, "+UFTPER:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+UFTPER:"); // Move searchPtr to first char @@ -4308,7 +4308,7 @@ UBX_CELL_error_t UBX_CELL::gpsGetRmc(struct PositionData *pos, struct SpeedData if (err == UBX_CELL_ERROR_SUCCESS) { // Fast-forward response string to $GPRMC starter - rmcBegin = strstr(response, "$GPRMC"); + rmcBegin = strnstr(response, "$GPRMC", minimumResponseAllocation); if (rmcBegin == nullptr) { err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; @@ -4497,7 +4497,7 @@ UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) // Response format: \r\n+URDFILE: "filename",36,"these bytes are the data of the file"\r\n\r\nOK\r\n int scanned = 0; int readFileSize = 0; - char *searchPtr = strstr(response, "+URDFILE:"); + char *searchPtr = strnstr(response, "+URDFILE:", fileSize + minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr = strchr(searchPtr, '\"'); // Find the first quote @@ -4551,7 +4551,7 @@ UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) else { if (_printDebug == true) - _debugPort->println(F("getFileContents: strstr failed!")); + _debugPort->println(F("getFileContents: strnstr failed!")); err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -4620,7 +4620,7 @@ UBX_CELL_error_t UBX_CELL::getFileContents(String filename, char *contents) // Response format: \r\n+URDFILE: "filename",36,"these bytes are the data of the file"\r\n\r\nOK\r\n int scanned = 0; int readFileSize = 0; - char *searchPtr = strstr(response, "+URDFILE:"); + char *searchPtr = strnstr(response, "+URDFILE:", fileSize + minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr = strchr(searchPtr, '\"'); // Find the first quote @@ -4670,7 +4670,7 @@ UBX_CELL_error_t UBX_CELL::getFileContents(String filename, char *contents) else { if (_printDebug == true) - _debugPort->println(F("getFileContents: strstr failed!")); + _debugPort->println(F("getFileContents: strnstr failed!")); err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE; } @@ -4778,7 +4778,7 @@ UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) return err; } - char *responseStart = strstr(response, "+ULSTFILE:"); + char *responseStart = strnstr(response, "+ULSTFILE:", minimumResponseAllocation); if (responseStart == nullptr) { if (_printDebug == true) @@ -5081,7 +5081,7 @@ UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) return err; int scanned = 0; - char *searchPtr = strstr(response, "+UMNOPROF:"); + char *searchPtr = strnstr(response, "+UMNOPROF:", minimumResponseAllocation); if (searchPtr != nullptr) { searchPtr += strlen("+UMNOPROF:"); // Move searchPtr to first char @@ -5765,7 +5765,7 @@ void UBX_CELL::pruneBacklog() // These are the events we want to keep so they can be processed by poll / bufferedPoll for (auto urcString : _urcStrings) { - if (strstr(event, urcString) != nullptr) + if (strnstr(event, urcString, _RXBuffSize - (event - _saraResponseBacklog)) != nullptr) { strcat(_pruneBuffer, event); // The URCs are all readable text so using strcat is OK strcat(_pruneBuffer, "\r\n"); // strtok blows away delimiter, but we want that for later. diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index fde1e1e..a460de7 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -145,7 +145,7 @@ template class UBX_CELL_VOICE bool urcCheckRing(const char *event) { int socket, length; - char *searchPtr = strstr(event, UBX_CELL_RING_URC); + char *searchPtr = strnstr(event, UBX_CELL_RING_URC, _RXBuffSize); if (searchPtr != nullptr) { if (_ringCallback != nullptr) From 0995691e93858326a4f928eb87212a5a42c341f0 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 18 Dec 2023 16:33:27 -0700 Subject: [PATCH 49/52] Run formatter again clang with Microsoft style --- src/sfe_sara_r5.cpp | 4 +- src/sfe_ublox_cellular.cpp | 98 ++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp index d80495d..4bb2574 100644 --- a/src/sfe_sara_r5.cpp +++ b/src/sfe_sara_r5.cpp @@ -222,8 +222,8 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur if (profile >= UBX_CELL_NUM_PSD_PROFILES) return UBX_CELL_ERROR_ERROR; - snprintf(command, cmdLen, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value[0], value[1], - value[2], value[3]); + snprintf(command, cmdLen, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value[0], + value[1], value[2], value[3]); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index e353a9e..7a07163 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -1792,12 +1792,13 @@ UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, unsigne if (dialing_type_char != 0) { - snprintf(command, cmdLen, "%s%c*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialing_type_char, dialNumber, PPP_L2P[l2p], - (unsigned int)cid); + snprintf(command, cmdLen, "%s%c*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialing_type_char, dialNumber, + PPP_L2P[l2p], (unsigned int)cid); } else { - snprintf(command, cmdLen, "%s*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialNumber, PPP_L2P[l2p], (unsigned int)cid); + snprintf(command, cmdLen, "%s*%lu**%s*%u#", UBX_CELL_MESSAGE_ENTER_PPP, dialNumber, PPP_L2P[l2p], + (unsigned int)cid); } err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -2268,7 +2269,7 @@ UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) return GPIO_MODE_INVALID; } - snprintf(gpioChar, charLen, "%d", gpio); // Convert GPIO to char array + snprintf(gpioChar, charLen, "%d", gpio); // Convert GPIO to char array gpioStart = strnstr(response, gpioChar, minimumResponseAllocation); // Find first occurence of GPIO in response if (gpioStart == nullptr) @@ -3303,8 +3304,8 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverIPaddress(int profile, IPAddress address if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - snprintf(command, cmdLen, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_IP, - address[0], address[1], address[2], address[3]); + snprintf(command, cmdLen, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_HTTP_PROFILE, profile, + UBX_CELL_HTTP_OP_CODE_SERVER_IP, address[0], address[1], address[2], address[3]); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3324,7 +3325,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverName(int profile, String server) if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SERVER_NAME, - server.c_str()); + server.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3345,7 +3346,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPusername(int profile, String username) if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_USERNAME, - username.c_str()); + username.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3366,7 +3367,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPpassword(int profile, String password) if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_PASSWORD, - password.c_str()); + password.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3383,7 +3384,8 @@ UBX_CELL_error_t UBX_CELL::setHTTPauthentication(int profile, bool authenticate) if (profile >= UBX_CELL_NUM_HTTP_PROFILES) return UBX_CELL_ERROR_ERROR; - snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, authenticate); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_AUTHENTICATION, + authenticate); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3418,8 +3420,8 @@ UBX_CELL_error_t UBX_CELL::setHTTPcustomHeader(int profile, String header) command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS, - header.c_str()); + snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_HTTP_PROFILE, profile, + UBX_CELL_HTTP_OP_CODE_ADD_CUSTOM_HEADERS, header.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3439,8 +3441,8 @@ UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofil if (secprofile == -1) snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure); else - snprintf(command, cmdLen, "%s=%d,%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, secure, - secprofile); + snprintf(command, cmdLen, "%s=%d,%d,%d,%d", UBX_CELL_HTTP_PROFILE, profile, UBX_CELL_HTTP_OP_CODE_SECURE, + secure, secprofile); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3456,7 +3458,8 @@ UBX_CELL_error_t UBX_CELL::ping(String remote_host, int retry, int p_size, unsig command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - snprintf(command, cmdLen, "%s=\"%s\",%d,%d,%ld,%d", UBX_CELL_PING_COMMAND, remote_host.c_str(), retry, p_size, timeout, ttl); + snprintf(command, cmdLen, "%s=\"%s\",%d,%d,%ld,%d", UBX_CELL_PING_COMMAND, remote_host.c_str(), retry, p_size, + timeout, ttl); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3476,8 +3479,8 @@ UBX_CELL_error_t UBX_CELL::sendHTTPGET(int profile, String path, String response command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - snprintf(command, cmdLen, "%s=%d,%d,\"%s\",\"%s\"", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_GET, path.c_str(), - responseFilename.c_str()); + snprintf(command, cmdLen, "%s=%d,%d,\"%s\",\"%s\"", UBX_CELL_HTTP_COMMAND, profile, UBX_CELL_HTTP_COMMAND_GET, + path.c_str(), responseFilename.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3489,8 +3492,7 @@ UBX_CELL_error_t UBX_CELL::sendHTTPPOSTdata(int profile, String path, String res UBX_CELL_http_content_types_t httpContentType) { UBX_CELL_error_t err; - size_t cmdLen = strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + - responseFilename.length() + data.length(); + size_t cmdLen = strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length() + data.length(); char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) @@ -3500,7 +3502,7 @@ UBX_CELL_error_t UBX_CELL::sendHTTPPOSTdata(int profile, String path, String res if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, - UBX_CELL_HTTP_COMMAND_POST_DATA, path.c_str(), responseFilename.c_str(), data.c_str(), httpContentType); + UBX_CELL_HTTP_COMMAND_POST_DATA, path.c_str(), responseFilename.c_str(), data.c_str(), httpContentType); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3512,8 +3514,8 @@ UBX_CELL_error_t UBX_CELL::sendHTTPPOSTfile(int profile, String path, String res UBX_CELL_http_content_types_t httpContentType) { UBX_CELL_error_t err; - size_t cmdLen = strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + - responseFilename.length() + requestFile.length(); + size_t cmdLen = + strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length() + requestFile.length(); char *command; if (profile >= UBX_CELL_NUM_HTTP_PROFILES) @@ -3523,8 +3525,8 @@ UBX_CELL_error_t UBX_CELL::sendHTTPPOSTfile(int profile, String path, String res if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%d,\"%s\",\"%s\",\"%s\",%d", UBX_CELL_HTTP_COMMAND, profile, - UBX_CELL_HTTP_COMMAND_POST_FILE, path.c_str(), responseFilename.c_str(), requestFile.c_str(), - httpContentType); + UBX_CELL_HTTP_COMMAND_POST_FILE, path.c_str(), responseFilename.c_str(), requestFile.c_str(), + httpContentType); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3603,8 +3605,8 @@ UBX_CELL_error_t UBX_CELL::setMQTTserver(const String &serverName, int port) command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - snprintf(command, cmdLen, "%s=%d,\"%s\",%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SERVERNAME, serverName.c_str(), - port); + snprintf(command, cmdLen, "%s=%d,\"%s\",%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SERVERNAME, + serverName.c_str(), port); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -3619,8 +3621,8 @@ UBX_CELL_error_t UBX_CELL::setMQTTcredentials(const String &userName, const Stri command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - snprintf(command, cmdLen, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_USERNAMEPWD, userName.c_str(), - pwd.c_str()); + snprintf(command, cmdLen, "%s=%d,\"%s\",\"%s\"", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_USERNAMEPWD, + userName.c_str(), pwd.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -3635,7 +3637,8 @@ UBX_CELL_error_t UBX_CELL::setMQTTsecure(bool secure, int secprofile) if (secprofile == -1) snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure); else - snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure, secprofile); + snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_MQTT_PROFILE, UBX_CELL_MQTT_PROFILE_SECURE, secure, + secprofile); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); return err; } @@ -3671,7 +3674,8 @@ UBX_CELL_error_t UBX_CELL::subscribeMQTTtopic(int max_Qos, const String &topic) command = ubx_cell_calloc_char(cmdLen); if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_SUBSCRIBE, max_Qos, topic.c_str()); + snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_SUBSCRIBE, max_Qos, + topic.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); free(command); return err; @@ -3761,7 +3765,8 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest *pTopic = searchPtr + 1; searchPtr[topic_length + 1] = '\"'; // restore } - searchPtr = strnstr(searchPtr + topic_length + 2, "\"", responseLength - (searchPtr + topic_length + 2 - response)); + searchPtr = + strnstr(searchPtr + topic_length + 2, "\"", responseLength - (searchPtr + topic_length + 2 - response)); if (readDest && (searchPtr != nullptr) && (response + responseLength >= searchPtr + data_length + 1) && (searchPtr[data_length + 1] == '"')) { @@ -3828,7 +3833,7 @@ UBX_CELL_error_t UBX_CELL::mqttPublishTextMsg(const String &topic, const char *c return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%u,%u,0,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISH, qos, - (retain ? 1 : 0), topic.c_str(), sanitized_msg); + (retain ? 1 : 0), topic.c_str(), sanitized_msg); sendCommand(command, true); err = waitForResponse(UBX_CELL_RESPONSE_MORE, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3866,7 +3871,7 @@ UBX_CELL_error_t UBX_CELL::mqttPublishBinaryMsg(const String &topic, const char return UBX_CELL_ERROR_OUT_OF_MEMORY; snprintf(command, cmdLen, "%s=%d,%u,%u,\"%s\",%u", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHBINARY, qos, - (retain ? 1 : 0), topic.c_str(), msg_len); + (retain ? 1 : 0), topic.c_str(), msg_len); sendCommand(command, true); err = waitForResponse(UBX_CELL_RESPONSE_MORE, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3893,8 +3898,8 @@ UBX_CELL_error_t UBX_CELL::mqttPublishFromFile(const String &topic, const String if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - snprintf(command, cmdLen, "%s=%d,%u,%u,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHFILE, qos, - (retain ? 1 : 0), topic.c_str(), filename.c_str()); + snprintf(command, cmdLen, "%s=%d,%u,%u,\"%s\",\"%s\"", UBX_CELL_MQTT_COMMAND, UBX_CELL_MQTT_COMMAND_PUBLISHFILE, + qos, (retain ? 1 : 0), topic.c_str(), filename.c_str()); sendCommand(command, true); err = waitForResponse(UBX_CELL_RESPONSE_OK, UBX_CELL_RESPONSE_ERROR, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -3952,8 +3957,8 @@ UBX_CELL_error_t UBX_CELL::setFTPtimeouts(const unsigned int timeout, const unsi constexpr size_t cmdLen = 64; char command[cmdLen]; // long enough for AT+UFTP=1,<128 bytes> - snprintf(command, cmdLen, "%s=%d,%u,%u,%u", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_TIMEOUT, timeout, - cmd_linger, data_linger); + snprintf(command, cmdLen, "%s=%d,%u,%u,%u", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_TIMEOUT, timeout, cmd_linger, + data_linger); return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } @@ -3963,8 +3968,7 @@ UBX_CELL_error_t UBX_CELL::setFTPcredentials(const String &userName, const Strin constexpr size_t cmdLen = 48; char command[cmdLen]; // long enough for AT+UFTP=n,<30 bytes> - snprintf(command, cmdLen, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_USERNAME, - userName.c_str()); + snprintf(command, cmdLen, "%s=%d,\"%s\"", UBX_CELL_FTP_PROFILE, UBX_CELL_FTP_PROFILE_USERNAME, userName.c_str()); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); if (err != UBX_CELL_ERROR_SUCCESS) { @@ -4002,8 +4006,8 @@ UBX_CELL_error_t UBX_CELL::ftpGetFile(const String &filename) if (command == nullptr) return UBX_CELL_ERROR_OUT_OF_MEMORY; - snprintf(command, cmdLen, "%s=%d,\"%s\",\"%s\"", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_GET_FILE, filename.c_str(), - filename.c_str()); + snprintf(command, cmdLen, "%s=%d,\"%s\",\"%s\"", UBX_CELL_FTP_COMMAND, UBX_CELL_FTP_COMMAND_GET_FILE, + filename.c_str(), filename.c_str()); // memset(response, 0, sizeof(response)); // sendCommandWithResponse(command, UBX_CELL_RESPONSE_CONNECT, response, 8000 /* ms */, response_len); UBX_CELL_error_t err = @@ -4357,9 +4361,11 @@ UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, b accuracy = 999999; #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - snprintf(command, cmdLen, "%s=2,%d,%d,%d,%d", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); + snprintf(command, cmdLen, "%s=2,%d,%d,%d,%d", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, + accuracy); #else - snprintf(command, cmdLen, "%s=2,%d,%d,%d,%ld", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, accuracy); + snprintf(command, cmdLen, "%s=2,%d,%d,%d,%ld", UBX_CELL_GNSS_REQUEST_LOCATION, sensor, detailed ? 1 : 0, timeout, + accuracy); #endif err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT); @@ -4376,8 +4382,8 @@ UBX_CELL_error_t UBX_CELL::gpsAidingServerConf(const char *primaryServer, const size_t cmdLen = strlen(UBX_CELL_AIDING_SERVER_CONFIGURATION) + 256; char command[cmdLen]; - snprintf(command, cmdLen, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBX_CELL_AIDING_SERVER_CONFIGURATION, primaryServer, - secondaryServer, authToken, days, period, resolution, gnssTypes, mode, dataType); + snprintf(command, cmdLen, "%s=\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d", UBX_CELL_AIDING_SERVER_CONFIGURATION, + primaryServer, secondaryServer, authToken, days, period, resolution, gnssTypes, mode, dataType); err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); @@ -5053,7 +5059,7 @@ UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool aut if (mno == MNO_SIM_ICCID) // Only add autoReset and urcNotification if mno is MNO_SIM_ICCID snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno, (uint8_t)autoReset, - (uint8_t)urcNotification); + (uint8_t)urcNotification); else snprintf(command, cmdLen, "%s=%d", UBX_CELL_COMMAND_MNO, (uint8_t)mno); From 92594527ce6444032d35e61f971d045fc9e749f4 Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Mon, 18 Dec 2023 16:43:24 -0700 Subject: [PATCH 50/52] Rename classes --- .../AudioExample1_PlayTone.ino | 8 +- .../AudioExample2_Loopback.ino | 8 +- .../AudioExample3_CallControl.ino | 8 +- .../Example1_DeviceIdentification.ino | 28 +- .../Example2_NetworkInfo.ino | 28 +- .../Example3_RegisterOperator.ino | 28 +- examples/Example4_Clock/Example4_Clock.ino | 28 +- examples/Example5_Ping/Example5_Ping.ino | 28 +- .../Example6_ReceiveSMS.ino | 28 +- .../Example7_SendSMS/Example7_SendSMS.ino | 28 +- src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 2 + src/sfe_lara_r6.h | 14 +- src/sfe_sara_r5.cpp | 28 +- src/sfe_sara_r5.h | 14 +- src/sfe_ublox_cellular.cpp | 412 +++++++++--------- src/sfe_ublox_cellular.h | 6 +- src/sfe_ublox_cellular_voice.h | 6 +- 17 files changed, 352 insertions(+), 350 deletions(-) diff --git a/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino b/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino index c270e19..88b093d 100644 --- a/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino +++ b/examples/Audio_Examples/AudioExample1_PlayTone/AudioExample1_PlayTone.ino @@ -6,10 +6,10 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL_VOICE_BASE myModule; // This example works with all voice-enabled modules, so this base class can be used -// LARA_R6001 myModule; -// LARA_R6401 myModule; -// LARA_R6801_00B myModule; +SparkFun_ublox_Cellular_Voice myModule; // This example works with all voice-enabled modules, so this base class can be used +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; void setup() { diff --git a/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino b/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino index 44aaee0..3adafab 100644 --- a/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino +++ b/examples/Audio_Examples/AudioExample2_Loopback/AudioExample2_Loopback.ino @@ -6,10 +6,10 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL_VOICE_BASE myModule; // This example works with all voice-enabled modules, so this base class can be used -// LARA_R6001 myModule; -// LARA_R6401 myModule; -// LARA_R6801_00B myModule; +SparkFun_ublox_Cellular_Voice myModule; // This example works with all voice-enabled modules, so this base class can be used +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; void setup() { diff --git a/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino b/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino index 77f8b31..cf6a29a 100644 --- a/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino +++ b/examples/Audio_Examples/AudioExample3_CallControl/AudioExample3_CallControl.ino @@ -6,10 +6,10 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL_VOICE_BASE myModule; // This example works with all voice-enabled modules, so this base class can be used -// LARA_R6001 myModule; -// LARA_R6401 myModule; -// LARA_R6801_00B myModule; +SparkFun_ublox_Cellular_Voice myModule; // This example works with all voice-enabled modules, so this base class can be used +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; bool callInProgress = false; bool incomingCall = false; diff --git a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino index fa50999..47089c1 100644 --- a/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino +++ b/examples/Example1_DeviceIdentification/Example1_DeviceIdentification.ino @@ -6,20 +6,20 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL myModule; // This example works with all modules, so the base class can be used -// SARA_R5 myModule; // Base SARA-R5 class -// SARA_R500S myModule; -// SARA_R500S_01B myModule; -// SARA_R500S_61B myModule; -// SARA_R510M8S_61B myModule; -// SARA_R510S myModule; -// LARA_R6 myModule; // Base LARA-R6 class -// LARA_R6001 myModule; -// LARA_R6001D myModule; -// LARA_R6401 myModule; -// LARA_R6401D myModule; -// LARA_R6801_00B myModule; -// LARA_R6801D myModule; +SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used +// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class +// SparkFun_ublox_SARA_R500S myModule; +// SparkFun_ublox_SARA_R500S_01B myModule; +// SparkFun_ublox_SARA_R500S_61B myModule; +// SparkFun_ublox_SARA_R510M8S_61B myModule; +// SparkFun_ublox_SARA_R510S myModule; +// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6001D myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6401D myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; +// SparkFun_ublox_LARA_R6801D myModule; // Map SIM states to more readable strings String simStateString[] = { diff --git a/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino b/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino index cf32155..3a851ba 100644 --- a/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino +++ b/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino @@ -6,20 +6,20 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL myModule; // This example works with all modules, so the base class can be used -// SARA_R5 myModule; // Base SARA-R5 class -// SARA_R500S myModule; -// SARA_R500S_01B myModule; -// SARA_R500S_61B myModule; -// SARA_R510M8S_61B myModule; -// SARA_R510S myModule; -// LARA_R6 myModule; // Base LARA-R6 class -// LARA_R6001 myModule; -// LARA_R6001D myModule; -// LARA_R6401 myModule; -// LARA_R6401D myModule; -// LARA_R6801_00B myModule; -// LARA_R6801D myModule; +SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used +// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class +// SparkFun_ublox_SARA_R500S myModule; +// SparkFun_ublox_SARA_R500S_01B myModule; +// SparkFun_ublox_SARA_R500S_61B myModule; +// SparkFun_ublox_SARA_R510M8S_61B myModule; +// SparkFun_ublox_SARA_R510S myModule; +// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6001D myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6401D myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; +// SparkFun_ublox_LARA_R6801D myModule; // Map registration status messages to more readable strings String registrationString[] = { diff --git a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino index 324b2bc..5a459bc 100644 --- a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino +++ b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino @@ -6,20 +6,20 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL myModule; // This example works with all modules, so the base class can be used -// SARA_R5 myModule; // Base SARA-R5 class -// SARA_R500S myModule; -// SARA_R500S_01B myModule; -// SARA_R500S_61B myModule; -// SARA_R510M8S_61B myModule; -// SARA_R510S myModule; -// LARA_R6 myModule; // Base LARA-R6 class -// LARA_R6001 myModule; -// LARA_R6001D myModule; -// LARA_R6401 myModule; -// LARA_R6401D myModule; -// LARA_R6801_00B myModule; -// LARA_R6801D myModule; +SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used +// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class +// SparkFun_ublox_SARA_R500S myModule; +// SparkFun_ublox_SARA_R500S_01B myModule; +// SparkFun_ublox_SARA_R500S_61B myModule; +// SparkFun_ublox_SARA_R510M8S_61B myModule; +// SparkFun_ublox_SARA_R510S myModule; +// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6001D myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6401D myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; +// SparkFun_ublox_LARA_R6801D myModule; // Map registration status messages to more readable strings String registrationString[] = { diff --git a/examples/Example4_Clock/Example4_Clock.ino b/examples/Example4_Clock/Example4_Clock.ino index 2e3232b..774f92c 100644 --- a/examples/Example4_Clock/Example4_Clock.ino +++ b/examples/Example4_Clock/Example4_Clock.ino @@ -6,20 +6,20 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL myModule; // This example works with all modules, so the base class can be used -// SARA_R5 myModule; // Base SARA-R5 class -// SARA_R500S myModule; -// SARA_R500S_01B myModule; -// SARA_R500S_61B myModule; -// SARA_R510M8S_61B myModule; -// SARA_R510S myModule; -// LARA_R6 myModule; // Base LARA-R6 class -// LARA_R6001 myModule; -// LARA_R6001D myModule; -// LARA_R6401 myModule; -// LARA_R6401D myModule; -// LARA_R6801_00B myModule; -// LARA_R6801D myModule; +SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used +// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class +// SparkFun_ublox_SARA_R500S myModule; +// SparkFun_ublox_SARA_R500S_01B myModule; +// SparkFun_ublox_SARA_R500S_61B myModule; +// SparkFun_ublox_SARA_R510M8S_61B myModule; +// SparkFun_ublox_SARA_R510S myModule; +// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6001D myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6401D myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; +// SparkFun_ublox_LARA_R6801D myModule; void setup() { diff --git a/examples/Example5_Ping/Example5_Ping.ino b/examples/Example5_Ping/Example5_Ping.ino index 3cc6678..8682cd5 100644 --- a/examples/Example5_Ping/Example5_Ping.ino +++ b/examples/Example5_Ping/Example5_Ping.ino @@ -6,20 +6,20 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL myModule; // This example works with all modules, so the base class can be used -// SARA_R5 myModule; // Base SARA-R5 class -// SARA_R500S myModule; -// SARA_R500S_01B myModule; -// SARA_R500S_61B myModule; -// SARA_R510M8S_61B myModule; -// SARA_R510S myModule; -// LARA_R6 myModule; // Base LARA-R6 class -// LARA_R6001 myModule; -// LARA_R6001D myModule; -// LARA_R6401 myModule; -// LARA_R6401D myModule; -// LARA_R6801_00B myModule; -// LARA_R6801D myModule; +SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used +// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class +// SparkFun_ublox_SARA_R500S myModule; +// SparkFun_ublox_SARA_R500S_01B myModule; +// SparkFun_ublox_SARA_R500S_61B myModule; +// SparkFun_ublox_SARA_R510M8S_61B myModule; +// SparkFun_ublox_SARA_R510S myModule; +// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6001D myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6401D myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; +// SparkFun_ublox_LARA_R6801D myModule; String pingMe = ""; // The name of the server we are going to ping diff --git a/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino b/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino index 416b45f..33dc6ac 100644 --- a/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino +++ b/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino @@ -6,20 +6,20 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL myModule; // This example works with all modules, so the base class can be used -// SARA_R5 myModule; // Base SARA-R5 class -// SARA_R500S myModule; -// SARA_R500S_01B myModule; -// SARA_R500S_61B myModule; -// SARA_R510M8S_61B myModule; -// SARA_R510S myModule; -// LARA_R6 myModule; // Base LARA-R6 class -// LARA_R6001 myModule; -// LARA_R6001D myModule; -// LARA_R6401 myModule; -// LARA_R6401D myModule; -// LARA_R6801_00B myModule; -// LARA_R6801D myModule; +SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used +// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class +// SparkFun_ublox_SARA_R500S myModule; +// SparkFun_ublox_SARA_R500S_01B myModule; +// SparkFun_ublox_SARA_R500S_61B myModule; +// SparkFun_ublox_SARA_R510M8S_61B myModule; +// SparkFun_ublox_SARA_R510S myModule; +// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6001D myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6401D myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; +// SparkFun_ublox_LARA_R6801D myModule; void setup() { diff --git a/examples/Example7_SendSMS/Example7_SendSMS.ino b/examples/Example7_SendSMS/Example7_SendSMS.ino index 8e6e11f..5e758cf 100644 --- a/examples/Example7_SendSMS/Example7_SendSMS.ino +++ b/examples/Example7_SendSMS/Example7_SendSMS.ino @@ -6,20 +6,20 @@ // Uncomment the module you're using. If your module is not listed below, then // it's not supported for this example -UBX_CELL myModule; // This example works with all modules, so the base class can be used -// SARA_R5 myModule; // Base SARA-R5 class -// SARA_R500S myModule; -// SARA_R500S_01B myModule; -// SARA_R500S_61B myModule; -// SARA_R510M8S_61B myModule; -// SARA_R510S myModule; -// LARA_R6 myModule; // Base LARA-R6 class -// LARA_R6001 myModule; -// LARA_R6001D myModule; -// LARA_R6401 myModule; -// LARA_R6401D myModule; -// LARA_R6801_00B myModule; -// LARA_R6801D myModule; +SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used +// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class +// SparkFun_ublox_SARA_R500S myModule; +// SparkFun_ublox_SARA_R500S_01B myModule; +// SparkFun_ublox_SARA_R500S_61B myModule; +// SparkFun_ublox_SARA_R510M8S_61B myModule; +// SparkFun_ublox_SARA_R510S myModule; +// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6001D myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6401D myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; +// SparkFun_ublox_LARA_R6801D myModule; void setup() { diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h index a5fff86..47af564 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -22,6 +22,8 @@ #include "sfe_sara_r5.h" #include "sfe_ublox_cellular.h" +#define SARA_R5 SparkFun_ublox_SARA_R5 + #define SARA_R5_POWER_PIN -1 // Default to no pin #define SARA_R5_RESET_PIN -1 diff --git a/src/sfe_lara_r6.h b/src/sfe_lara_r6.h index 40fc862..e421ae3 100644 --- a/src/sfe_lara_r6.h +++ b/src/sfe_lara_r6.h @@ -5,31 +5,31 @@ #include "sfe_ublox_cellular_voice.h" // Base LARA-R6 class -class LARA_R6 : public UBX_CELL +class SparkFun_ublox_LARA_R6 : public SparkFun_ublox_Cellular { }; -class LARA_R6001 : public LARA_R6, public UBX_CELL_VOICE +class SparkFun_ublox_LARA_R6001 : public SparkFun_ublox_LARA_R6, public SparkFun_ublox_Cellular_Voice_Base { }; -class LARA_R6001D : public LARA_R6 +class SparkFun_ublox_LARA_R6001D : public SparkFun_ublox_LARA_R6 { }; -class LARA_R6401 : public LARA_R6, public UBX_CELL_VOICE +class SparkFun_ublox_LARA_R6401 : public SparkFun_ublox_LARA_R6, public SparkFun_ublox_Cellular_Voice_Base { }; -class LARA_R6401D : public LARA_R6 +class SparkFun_ublox_LARA_R6401D : public SparkFun_ublox_LARA_R6 { }; -class LARA_R6801_00B : public LARA_R6, public UBX_CELL_VOICE +class SparkFun_ublox_LARA_R6801_00B : public SparkFun_ublox_LARA_R6, public SparkFun_ublox_Cellular_Voice_Base { }; -class LARA_R6801D : public LARA_R6 +class SparkFun_ublox_LARA_R6801D : public SparkFun_ublox_LARA_R6 { }; diff --git a/src/sfe_sara_r5.cpp b/src/sfe_sara_r5.cpp index 4bb2574..850b38f 100644 --- a/src/sfe_sara_r5.cpp +++ b/src/sfe_sara_r5.cpp @@ -1,12 +1,12 @@ #include "sfe_sara_r5.h" -SARA_R5::SARA_R5() +SparkFun_ublox_SARA_R5::SparkFun_ublox_SARA_R5() { addURCHandler(UBX_CELL_MESSAGE_PDP_ACTION_URC, [this](const char *event) { return this->urcHandlerPDPAction(event); }); } -UBX_CELL_error_t SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utime_sensor_t sensor) +UBX_CELL_error_t SparkFun_ublox_SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utime_sensor_t sensor) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16; @@ -21,7 +21,7 @@ UBX_CELL_error_t SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utim return err; } -UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor) +UBX_CELL_error_t SparkFun_ublox_SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2; @@ -66,7 +66,7 @@ UBX_CELL_error_t SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_uti return err; } -UBX_CELL_error_t SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t config) +UBX_CELL_error_t SparkFun_ublox_SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t config) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16; @@ -78,7 +78,7 @@ UBX_CELL_error_t SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t return err; } -UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config) +UBX_CELL_error_t SparkFun_ublox_SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2; @@ -115,7 +115,7 @@ UBX_CELL_error_t SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t return err; } -UBX_CELL_error_t SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds) +UBX_CELL_error_t SparkFun_ublox_SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48; @@ -131,7 +131,7 @@ UBX_CELL_error_t SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32 return err; } -UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds) +UBX_CELL_error_t SparkFun_ublox_SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2; @@ -173,7 +173,7 @@ UBX_CELL_error_t SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int3 return err; } -UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value) +UBX_CELL_error_t SparkFun_ublox_SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24; @@ -189,13 +189,13 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur return err; } -UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, +UBX_CELL_error_t SparkFun_ublox_SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, UBX_CELL_pdp_protocol_type_t value) { return (setPDPconfiguration(profile, parameter, (int)value)); } -UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, +UBX_CELL_error_t SparkFun_ublox_SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, String value) { UBX_CELL_error_t err; @@ -212,7 +212,7 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur return err; } -UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, +UBX_CELL_error_t SparkFun_ublox_SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, IPAddress value) { UBX_CELL_error_t err; @@ -230,7 +230,7 @@ UBX_CELL_error_t SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configur return err; } -UBX_CELL_error_t SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t action) +UBX_CELL_error_t SparkFun_ublox_SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t action) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32; @@ -246,7 +246,7 @@ UBX_CELL_error_t SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t a return err; } -UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *address) +UBX_CELL_error_t SparkFun_ublox_SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *address) { size_t cmdLen = strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16; char command[cmdLen]; @@ -290,7 +290,7 @@ UBX_CELL_error_t SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *ad return err; } -bool SARA_R5::urcHandlerPDPAction(const char *event) +bool SparkFun_ublox_SARA_R5::urcHandlerPDPAction(const char *event) { // URC: +UUPSDA (Packet Switched Data Action) int result; diff --git a/src/sfe_sara_r5.h b/src/sfe_sara_r5.h index a8189c7..f61a67f 100644 --- a/src/sfe_sara_r5.h +++ b/src/sfe_sara_r5.h @@ -13,10 +13,10 @@ const char *const UBX_CELL_GNSS_TIME_CONFIGURATION = "+UTIMECFG"; // Sets time c const char *const UBX_CELL_MESSAGE_PDP_ACTION_URC = "+UUPSDA:"; // Base SARA-R5 class -class SARA_R5 : public UBX_CELL +class SparkFun_ublox_SARA_R5 : public SparkFun_ublox_Cellular { public: - SARA_R5(); + SparkFun_ublox_SARA_R5(); UBX_CELL_error_t setUtimeMode( UBX_CELL_utime_mode_t mode = UBX_CELL_UTIME_MODE_PPS, @@ -50,23 +50,23 @@ class SARA_R5 : public UBX_CELL bool urcHandlerPDPAction(const char *event); }; -class SARA_R500S : public SARA_R5 +class SparkFun_ublox_SARA_R500S : public SparkFun_ublox_SARA_R5 { }; -class SARA_R500S_01B : public SARA_R5 +class SparkFun_ublox_SARA_R500S_01B : public SparkFun_ublox_SARA_R5 { }; -class SARA_R500S_61B : public SARA_R5 +class SparkFun_ublox_SARA_R500S_61B : public SparkFun_ublox_SARA_R5 { }; -class SARA_R510M8S_61B : public SARA_R5 +class SparkFun_ublox_SARA_R510M8S_61B : public SparkFun_ublox_SARA_R5 { }; -class SARA_R510S : public SARA_R5 +class SparkFun_ublox_SARA_R510S : public SparkFun_ublox_SARA_R5 { }; diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index 7a07163..418c024 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -15,7 +15,7 @@ #include "sfe_ublox_cellular.h" -UBX_CELL::UBX_CELL(int powerPin, int resetPin, uint8_t maxInitTries) +SparkFun_ublox_Cellular::SparkFun_ublox_Cellular(int powerPin, int resetPin, uint8_t maxInitTries) { #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED _softSerial = nullptr; @@ -73,7 +73,7 @@ UBX_CELL::UBX_CELL(int powerPin, int resetPin, uint8_t maxInitTries) [this](const char *event) { return this->urcHandlerEPSRegistrationStatus(event); }); } -UBX_CELL::~UBX_CELL(void) +SparkFun_ublox_Cellular::~SparkFun_ublox_Cellular(void) { if (nullptr != _saraRXBuffer) { @@ -93,7 +93,7 @@ UBX_CELL::~UBX_CELL(void) } #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED -bool UBX_CELL::begin(SoftwareSerial &softSerial, unsigned long baud) +bool SparkFun_ublox_Cellular::begin(SoftwareSerial &softSerial, unsigned long baud) { if (nullptr == _saraRXBuffer) { @@ -144,7 +144,7 @@ bool UBX_CELL::begin(SoftwareSerial &softSerial, unsigned long baud) } #endif -bool UBX_CELL::begin(HardwareSerial &hardSerial, unsigned long baud) +bool SparkFun_ublox_Cellular::begin(HardwareSerial &hardSerial, unsigned long baud) { if (nullptr == _saraRXBuffer) { @@ -196,7 +196,7 @@ bool UBX_CELL::begin(HardwareSerial &hardSerial, unsigned long baud) // Calling this function with nothing sets the debug port to Serial // You can also call it with other streams like Serial1, SerialUSB, etc. -void UBX_CELL::enableDebugging(Print &debugPort) +void SparkFun_ublox_Cellular::enableDebugging(Print &debugPort) { _debugPort = &debugPort; _printDebug = true; @@ -204,7 +204,7 @@ void UBX_CELL::enableDebugging(Print &debugPort) // Calling this function with nothing sets the debug port to Serial // You can also call it with other streams like Serial1, SerialUSB, etc. -void UBX_CELL::enableAtDebugging(Print &debugPort) +void SparkFun_ublox_Cellular::enableAtDebugging(Print &debugPort) { _debugAtPort = &debugPort; _printAtDebug = true; @@ -214,7 +214,7 @@ void UBX_CELL::enableAtDebugging(Print &debugPort) // See: https://github.com/sparkfun/SparkFun_LTE_Shield_Arduino_Library/pull/8 // It does the same job as ::poll but also processed any 'old' data stored in the backlog first // It also has a built-in timeout - which ::poll does not -bool UBX_CELL::bufferedPoll(void) +bool SparkFun_ublox_Cellular::bufferedPoll(void) { if (_bufferedPollReentrant == true) // Check for reentry (i.e. bufferedPoll has been called from inside a callback) return false; @@ -342,7 +342,7 @@ bool UBX_CELL::bufferedPoll(void) return handled; } // /bufferedPoll -bool UBX_CELL::urcHandlerReadSocket(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerReadSocket(const char *event) { // URC: +UUSORD (Read Socket Data) int socket, length; @@ -380,7 +380,7 @@ bool UBX_CELL::urcHandlerReadSocket(const char *event) return false; } -bool UBX_CELL::urcHandlerReadUDPSocket(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerReadUDPSocket(const char *event) { // URC: +UUSORF (Receive From command (UDP only)) int socket, length; @@ -403,7 +403,7 @@ bool UBX_CELL::urcHandlerReadUDPSocket(const char *event) return false; } -bool UBX_CELL::urcHandlerListeningSocket(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerListeningSocket(const char *event) { // URC: +UUSOLI (Set Listening Socket) int socket = 0; @@ -443,7 +443,7 @@ bool UBX_CELL::urcHandlerListeningSocket(const char *event) return false; } -bool UBX_CELL::urcHandlerCloseSocket(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerCloseSocket(const char *event) { // URC: +UUSOCL (Close Socket) int socket; @@ -472,7 +472,7 @@ bool UBX_CELL::urcHandlerCloseSocket(const char *event) return false; } -bool UBX_CELL::urcHandlerGNSSRequestLocation(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerGNSSRequestLocation(const char *event) { // URC: +UULOC (Localization information - CellLocate and hybrid positioning) ClockData clck; @@ -552,7 +552,7 @@ bool UBX_CELL::urcHandlerGNSSRequestLocation(const char *event) return false; } -bool UBX_CELL::urcHandlerSIMState(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerSIMState(const char *event) { // URC: +UUSIMSTAT (SIM Status) UBX_CELL_sim_states_t state; @@ -586,7 +586,7 @@ bool UBX_CELL::urcHandlerSIMState(const char *event) return false; } -bool UBX_CELL::urcHandlerHTTPCommand(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerHTTPCommand(const char *event) { // URC: +UUHTTPCR (HTTP Command Result) int profile, command, result; @@ -620,7 +620,7 @@ bool UBX_CELL::urcHandlerHTTPCommand(const char *event) return false; } -bool UBX_CELL::urcHandlerMQTTCommand(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerMQTTCommand(const char *event) { // URC: +UUMQTTC (MQTT Command Result) int command, result; @@ -663,7 +663,7 @@ bool UBX_CELL::urcHandlerMQTTCommand(const char *event) return false; } -bool UBX_CELL::urcHandlerPingCommand(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerPingCommand(const char *event) { // URC: +UUPING (Ping Result) int retry = 0; @@ -741,7 +741,7 @@ bool UBX_CELL::urcHandlerPingCommand(const char *event) return false; } -bool UBX_CELL::urcHandlerFTPCommand(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerFTPCommand(const char *event) { // URC: +UUFTPCR (FTP Command Result) int ftpCmd; @@ -767,7 +767,7 @@ bool UBX_CELL::urcHandlerFTPCommand(const char *event) return false; } -bool UBX_CELL::urcHandlerRegistrationStatus(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerRegistrationStatus(const char *event) { // URC: +CREG int status = 0; @@ -796,7 +796,7 @@ bool UBX_CELL::urcHandlerRegistrationStatus(const char *event) return false; } -bool UBX_CELL::urcHandlerEPSRegistrationStatus(const char *event) +bool SparkFun_ublox_Cellular::urcHandlerEPSRegistrationStatus(const char *event) { // URC: +CEREG int status = 0; @@ -826,14 +826,14 @@ bool UBX_CELL::urcHandlerEPSRegistrationStatus(const char *event) return false; } -void UBX_CELL::addURCHandler(const char *urcString, UBX_CELL_urc_handler_t urcHandler) +void SparkFun_ublox_Cellular::addURCHandler(const char *urcString, UBX_CELL_urc_handler_t urcHandler) { _urcStrings.push_back(urcString); _urcHandlers.push_back(urcHandler); } // Parse incoming URC's - the associated parse functions pass the data to the user via the callbacks (if defined) -bool UBX_CELL::processURCEvent(const char *event) +bool SparkFun_ublox_Cellular::processURCEvent(const char *event) { // Iterate through each URC handler to see if it can handle this message for (auto urcHandler : _urcHandlers) @@ -852,7 +852,7 @@ bool UBX_CELL::processURCEvent(const char *event) // This is the original poll function. // It is 'blocking' - it does not return when serial data is available until it receives a `\n`. // ::bufferedPoll is the new improved version. It processes any data in the backlog and includes a timeout. -bool UBX_CELL::poll(void) +bool SparkFun_ublox_Cellular::poll(void) { if (_pollReentrant == true) // Check for reentry (i.e. poll has been called from inside a callback) return false; @@ -904,66 +904,66 @@ bool UBX_CELL::poll(void) return handled; } -void UBX_CELL::setSocketListenCallback(void (*socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, +void SparkFun_ublox_Cellular::setSocketListenCallback(void (*socketListenCallback)(int, IPAddress, unsigned int, int, IPAddress, unsigned int)) { _socketListenCallback = socketListenCallback; } -void UBX_CELL::setSocketReadCallback(void (*socketReadCallback)(int, String)) +void SparkFun_ublox_Cellular::setSocketReadCallback(void (*socketReadCallback)(int, String)) { _socketReadCallback = socketReadCallback; } -void UBX_CELL::setSocketReadCallbackPlus(void (*socketReadCallbackPlus)( +void SparkFun_ublox_Cellular::setSocketReadCallbackPlus(void (*socketReadCallbackPlus)( int, const char *, int, IPAddress, int)) // socket, data, length, remoteAddress, remotePort { _socketReadCallbackPlus = socketReadCallbackPlus; } -void UBX_CELL::setSocketCloseCallback(void (*socketCloseCallback)(int)) +void SparkFun_ublox_Cellular::setSocketCloseCallback(void (*socketCloseCallback)(int)) { _socketCloseCallback = socketCloseCallback; } -void UBX_CELL::setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, PositionData gps, SpeedData spd, +void SparkFun_ublox_Cellular::setGpsReadCallback(void (*gpsRequestCallback)(ClockData time, PositionData gps, SpeedData spd, unsigned long uncertainty)) { _gpsRequestCallback = gpsRequestCallback; } -void UBX_CELL::setSIMstateReportCallback(void (*simStateReportCallback)(UBX_CELL_sim_states_t state)) +void SparkFun_ublox_Cellular::setSIMstateReportCallback(void (*simStateReportCallback)(UBX_CELL_sim_states_t state)) { _simStateReportCallback = simStateReportCallback; } -void UBX_CELL::setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)) +void SparkFun_ublox_Cellular::setPSDActionCallback(void (*psdActionRequestCallback)(int result, IPAddress ip)) { _psdActionRequestCallback = psdActionRequestCallback; } -void UBX_CELL::setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, +void SparkFun_ublox_Cellular::setPingCallback(void (*pingRequestCallback)(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)) { _pingRequestCallback = pingRequestCallback; } -void UBX_CELL::setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)) +void SparkFun_ublox_Cellular::setHTTPCommandCallback(void (*httpCommandRequestCallback)(int profile, int command, int result)) { _httpCommandRequestCallback = httpCommandRequestCallback; } -void UBX_CELL::setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)) +void SparkFun_ublox_Cellular::setMQTTCommandCallback(void (*mqttCommandRequestCallback)(int command, int result)) { _mqttCommandRequestCallback = mqttCommandRequestCallback; } -void UBX_CELL::setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)) +void SparkFun_ublox_Cellular::setFTPCommandCallback(void (*ftpCommandRequestCallback)(int command, int result)) { _ftpCommandRequestCallback = ftpCommandRequestCallback; } -UBX_CELL_error_t UBX_CELL::setRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, +UBX_CELL_error_t SparkFun_ublox_Cellular::setRegistrationCallback(void (*registrationCallback)(UBX_CELL_registration_status_t status, unsigned int lac, unsigned int ci, int Act)) { @@ -977,7 +977,7 @@ UBX_CELL_error_t UBX_CELL::setRegistrationCallback(void (*registrationCallback)( return err; } -UBX_CELL_error_t UBX_CELL::setEpsRegistrationCallback( +UBX_CELL_error_t SparkFun_ublox_Cellular::setEpsRegistrationCallback( void (*registrationCallback)(UBX_CELL_registration_status_t status, unsigned int tac, unsigned int ci, int Act)) { _epsRegistrationCallback = registrationCallback; @@ -990,22 +990,22 @@ UBX_CELL_error_t UBX_CELL::setEpsRegistrationCallback( return err; } -size_t UBX_CELL::write(uint8_t c) +size_t SparkFun_ublox_Cellular::write(uint8_t c) { return hwWrite(c); } -size_t UBX_CELL::write(const char *str) +size_t SparkFun_ublox_Cellular::write(const char *str) { return hwPrint(str); } -size_t UBX_CELL::write(const char *buffer, size_t size) +size_t SparkFun_ublox_Cellular::write(const char *buffer, size_t size) { return hwWriteData(buffer, size); } -UBX_CELL_error_t UBX_CELL::at(void) +UBX_CELL_error_t SparkFun_ublox_Cellular::at(void) { UBX_CELL_error_t err; @@ -1014,7 +1014,7 @@ UBX_CELL_error_t UBX_CELL::at(void) return err; } -UBX_CELL_error_t UBX_CELL::enableEcho(bool enable) +UBX_CELL_error_t SparkFun_ublox_Cellular::enableEcho(bool enable) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_ECHO) + 2; @@ -1024,7 +1024,7 @@ UBX_CELL_error_t UBX_CELL::enableEcho(bool enable) return err; } -String UBX_CELL::getManufacturerID(void) +String SparkFun_ublox_Cellular::getManufacturerID(void) { char response[minimumResponseAllocation]; char idResponse[16] = {0x00}; // E.g. u-blox @@ -1042,7 +1042,7 @@ String UBX_CELL::getManufacturerID(void) return String(idResponse); } -String UBX_CELL::getModelID(void) +String SparkFun_ublox_Cellular::getModelID(void) { char response[minimumResponseAllocation]; char idResponse[32] = {0x00}; // E.g. SARA-R510M8Q @@ -1060,7 +1060,7 @@ String UBX_CELL::getModelID(void) return String(idResponse); } -String UBX_CELL::getFirmwareVersion(void) +String SparkFun_ublox_Cellular::getFirmwareVersion(void) { char response[minimumResponseAllocation]; char idResponse[16] = {0x00}; // E.g. 11.40 @@ -1078,7 +1078,7 @@ String UBX_CELL::getFirmwareVersion(void) return String(idResponse); } -String UBX_CELL::getSerialNo(void) +String SparkFun_ublox_Cellular::getSerialNo(void) { char response[minimumResponseAllocation]; char idResponse[32] = {0x00}; // E.g. 357520070120767 @@ -1096,7 +1096,7 @@ String UBX_CELL::getSerialNo(void) return String(idResponse); } -String UBX_CELL::getIMEI(void) +String SparkFun_ublox_Cellular::getIMEI(void) { char response[minimumResponseAllocation]; char imeiResponse[32] = {0x00}; // E.g. 004999010640000 @@ -1114,7 +1114,7 @@ String UBX_CELL::getIMEI(void) return String(imeiResponse); } -String UBX_CELL::getIMSI(void) +String SparkFun_ublox_Cellular::getIMSI(void) { char response[minimumResponseAllocation]; char imsiResponse[32] = {0x00}; // E.g. 222107701772423 @@ -1132,7 +1132,7 @@ String UBX_CELL::getIMSI(void) return String(imsiResponse); } -String UBX_CELL::getCCID(void) +String SparkFun_ublox_Cellular::getCCID(void) { char response[minimumResponseAllocation]; char ccidResponse[32] = {0x00}; // E.g. +CCID: 8939107900010087330 @@ -1157,7 +1157,7 @@ String UBX_CELL::getCCID(void) return String(ccidResponse); } -String UBX_CELL::getSubscriberNo(void) +String SparkFun_ublox_Cellular::getSubscriberNo(void) { char response[minimumResponseAllocation]; char idResponse[128] = {0x00}; // E.g. +CNUM: "ABCD . AAA","123456789012",129 @@ -1182,7 +1182,7 @@ String UBX_CELL::getSubscriberNo(void) return String(idResponse); } -String UBX_CELL::getCapabilities(void) +String SparkFun_ublox_Cellular::getCapabilities(void) { char response[minimumResponseAllocation]; char idResponse[128] = {0x00}; // E.g. +GCAP: +FCLASS, +CGSM @@ -1207,7 +1207,7 @@ String UBX_CELL::getCapabilities(void) return String(idResponse); } -UBX_CELL_error_t UBX_CELL::reset(void) +UBX_CELL_error_t SparkFun_ublox_Cellular::reset(void) { UBX_CELL_error_t err; @@ -1229,7 +1229,7 @@ UBX_CELL_error_t UBX_CELL::reset(void) return err; } -String UBX_CELL::clock(void) +String SparkFun_ublox_Cellular::clock(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_CLOCK) + 2; @@ -1265,7 +1265,7 @@ String UBX_CELL::clock(void) return (clock); } -UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz) +UBX_CELL_error_t SparkFun_ublox_Cellular::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h, uint8_t *min, uint8_t *s, int8_t *tz) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_CLOCK) + 2; @@ -1312,7 +1312,7 @@ UBX_CELL_error_t UBX_CELL::clock(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h return err; } -UBX_CELL_error_t UBX_CELL::setClock(uint8_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t min, uint8_t s, int8_t tz) +UBX_CELL_error_t SparkFun_ublox_Cellular::setClock(uint8_t y, uint8_t mo, uint8_t d, uint8_t h, uint8_t min, uint8_t s, int8_t tz) { // Convert y,mo,d,h,min,s,tz into a String // Some platforms don't support snprintf correctly (for %02d or %+02d) so we need to build the String manually @@ -1351,7 +1351,7 @@ UBX_CELL_error_t UBX_CELL::setClock(uint8_t y, uint8_t mo, uint8_t d, uint8_t h, return (setClock(theTime)); } -UBX_CELL_error_t UBX_CELL::setClock(String theTime) +UBX_CELL_error_t SparkFun_ublox_Cellular::setClock(String theTime) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_CLOCK) + theTime.length() + 8; @@ -1368,12 +1368,12 @@ UBX_CELL_error_t UBX_CELL::setClock(String theTime) return err; } -void UBX_CELL::autoTimeZoneForBegin(bool tz) +void SparkFun_ublox_Cellular::autoTimeZoneForBegin(bool tz) { _autoTimeZoneForBegin = tz; } -UBX_CELL_error_t UBX_CELL::autoTimeZone(bool enable) +UBX_CELL_error_t SparkFun_ublox_Cellular::autoTimeZone(bool enable) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_AUTO_TZ) + 3; @@ -1385,7 +1385,7 @@ UBX_CELL_error_t UBX_CELL::autoTimeZone(bool enable) return err; } -int8_t UBX_CELL::rssi(void) +int8_t SparkFun_ublox_Cellular::rssi(void) { size_t cmdLen = strlen(UBX_CELL_SIGNAL_QUALITY) + 1; char command[cmdLen]; @@ -1419,7 +1419,7 @@ int8_t UBX_CELL::rssi(void) return rssi; } -UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality &signal_quality) +UBX_CELL_error_t SparkFun_ublox_Cellular::getExtSignalQuality(signal_quality &signal_quality) { size_t cmdLen = strlen(UBX_CELL_EXT_SIGNAL_QUALITY) + 1; char command[cmdLen]; @@ -1456,7 +1456,7 @@ UBX_CELL_error_t UBX_CELL::getExtSignalQuality(signal_quality &signal_quality) return err; } -UBX_CELL_registration_status_t UBX_CELL::registration(bool eps) +UBX_CELL_registration_status_t SparkFun_ublox_Cellular::registration(bool eps) { const char *tag = eps ? UBX_CELL_EPSREGISTRATION_STATUS : UBX_CELL_REGISTRATION_STATUS; size_t cmdLen = strlen(UBX_CELL_EPSREGISTRATION_STATUS) + 3; @@ -1491,7 +1491,7 @@ UBX_CELL_registration_status_t UBX_CELL::registration(bool eps) return (UBX_CELL_registration_status_t)status; } -bool UBX_CELL::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) +bool SparkFun_ublox_Cellular::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) { mobile_network_operator_t currentMno; @@ -1525,7 +1525,7 @@ bool UBX_CELL::setNetworkProfile(mobile_network_operator_t mno, bool autoReset, return true; } -mobile_network_operator_t UBX_CELL::getNetworkProfile(void) +mobile_network_operator_t SparkFun_ublox_Cellular::getNetworkProfile(void) { mobile_network_operator_t mno; UBX_CELL_error_t err; @@ -1538,7 +1538,7 @@ mobile_network_operator_t UBX_CELL::getNetworkProfile(void) return mno; } -UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdpType) +UBX_CELL_error_t SparkFun_ublox_Cellular::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdpType) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_DEF) + strlen(apn.c_str()) + 16; @@ -1600,7 +1600,7 @@ UBX_CELL_error_t UBX_CELL::setAPN(String apn, uint8_t cid, UBX_CELL_pdp_type pdp } // Return the Access Point Name and IP address for the chosen context identifier -UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_pdp_type *pdpType) +UBX_CELL_error_t SparkFun_ublox_Cellular::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_pdp_type *pdpType) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_DEF) + 3; @@ -1678,7 +1678,7 @@ UBX_CELL_error_t UBX_CELL::getAPN(int cid, String *apn, IPAddress *ip, UBX_CELL_ return err; } -UBX_CELL_error_t UBX_CELL::getSimStatus(String *code) +UBX_CELL_error_t SparkFun_ublox_Cellular::getSimStatus(String *code) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_SIMPIN) + 2; @@ -1712,7 +1712,7 @@ UBX_CELL_error_t UBX_CELL::getSimStatus(String *code) return err; } -UBX_CELL_error_t UBX_CELL::setSimPin(String pin) +UBX_CELL_error_t SparkFun_ublox_Cellular::setSimPin(String pin) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_SIMPIN) + 4 + pin.length(); @@ -1727,7 +1727,7 @@ UBX_CELL_error_t UBX_CELL::setSimPin(String pin) return err; } -UBX_CELL_error_t UBX_CELL::setSIMstateReportingMode(int mode) +UBX_CELL_error_t SparkFun_ublox_Cellular::setSIMstateReportingMode(int mode) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SIM_STATE) + 4; @@ -1739,7 +1739,7 @@ UBX_CELL_error_t UBX_CELL::setSIMstateReportingMode(int mode) return err; } -UBX_CELL_error_t UBX_CELL::getSIMstateReportingMode(int *mode) +UBX_CELL_error_t SparkFun_ublox_Cellular::getSIMstateReportingMode(int *mode) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SIM_STATE) + 3; @@ -1778,8 +1778,8 @@ const char *PPP_L2P[5] = { "", "PPP", "M-HEX", "M-RAW_IP", "M-OPT-PPP", }; -UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, unsigned long dialNumber, - UBX_CELL::UBX_CELL_l2p_t l2p) +UBX_CELL_error_t SparkFun_ublox_Cellular::enterPPP(uint8_t cid, char dialing_type_char, unsigned long dialNumber, + SparkFun_ublox_Cellular::UBX_CELL_l2p_t l2p) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_ENTER_PPP) + 32; @@ -1806,7 +1806,7 @@ UBX_CELL_error_t UBX_CELL::enterPPP(uint8_t cid, char dialing_type_char, unsigne return err; } -uint8_t UBX_CELL::getOperators(struct operator_stats *opRet, int maxOps) +uint8_t SparkFun_ublox_Cellular::getOperators(struct operator_stats *opRet, int maxOps) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 3; @@ -1884,7 +1884,7 @@ uint8_t UBX_CELL::getOperators(struct operator_stats *opRet, int maxOps) return opsSeen; } -UBX_CELL_error_t UBX_CELL::registerOperator(struct operator_stats oper) +UBX_CELL_error_t SparkFun_ublox_Cellular::registerOperator(struct operator_stats oper) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 24; @@ -1898,7 +1898,7 @@ UBX_CELL_error_t UBX_CELL::registerOperator(struct operator_stats oper) return err; } -UBX_CELL_error_t UBX_CELL::automaticOperatorSelection() +UBX_CELL_error_t SparkFun_ublox_Cellular::automaticOperatorSelection() { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 6; @@ -1912,7 +1912,7 @@ UBX_CELL_error_t UBX_CELL::automaticOperatorSelection() return err; } -UBX_CELL_error_t UBX_CELL::getOperator(String *oper) +UBX_CELL_error_t SparkFun_ublox_Cellular::getOperator(String *oper) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 3; @@ -1967,7 +1967,7 @@ UBX_CELL_error_t UBX_CELL::getOperator(String *oper) return err; } -UBX_CELL_error_t UBX_CELL::deregisterOperator(void) +UBX_CELL_error_t SparkFun_ublox_Cellular::deregisterOperator(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_OPERATOR_SELECTION) + 6; @@ -1980,7 +1980,7 @@ UBX_CELL_error_t UBX_CELL::deregisterOperator(void) return err; } -UBX_CELL_error_t UBX_CELL::setSMSMessageFormat(UBX_CELL_message_format_t textMode) +UBX_CELL_error_t SparkFun_ublox_Cellular::setSMSMessageFormat(UBX_CELL_message_format_t textMode) { size_t cmdLen = strlen(UBX_CELL_MESSAGE_FORMAT) + 4; char command[cmdLen]; @@ -1993,7 +1993,7 @@ UBX_CELL_error_t UBX_CELL::setSMSMessageFormat(UBX_CELL_message_format_t textMod return err; } -UBX_CELL_error_t UBX_CELL::sendSMS(String number, String message) +UBX_CELL_error_t SparkFun_ublox_Cellular::sendSMS(String number, String message) { char *command; char *messageCStr; @@ -2040,7 +2040,7 @@ UBX_CELL_error_t UBX_CELL::sendSMS(String number, String message) return err; } -UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, String memory) +UBX_CELL_error_t SparkFun_ublox_Cellular::getPreferredMessageStorage(int *used, int *total, String memory) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_PREF_MESSAGE_STORE) + 32; @@ -2089,7 +2089,7 @@ UBX_CELL_error_t UBX_CELL::getPreferredMessageStorage(int *used, int *total, Str return err; } -UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message) +UBX_CELL_error_t SparkFun_ublox_Cellular::readSMSmessage(int location, String *unread, String *from, String *dateTime, String *message) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_READ_TEXT_MESSAGE) + 5; @@ -2174,7 +2174,7 @@ UBX_CELL_error_t UBX_CELL::readSMSmessage(int location, String *unread, String * return err; } -UBX_CELL_error_t UBX_CELL::deleteSMSmessage(int location, int deleteFlag) +UBX_CELL_error_t SparkFun_ublox_Cellular::deleteSMSmessage(int location, int deleteFlag) { size_t cmdLen = strlen(UBX_CELL_DELETE_MESSAGE) + 12; char command[cmdLen]; @@ -2190,7 +2190,7 @@ UBX_CELL_error_t UBX_CELL::deleteSMSmessage(int location, int deleteFlag) return err; } -UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) +UBX_CELL_error_t SparkFun_ublox_Cellular::setBaud(unsigned long baud) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_BAUD) + 7 + 12; @@ -2218,7 +2218,7 @@ UBX_CELL_error_t UBX_CELL::setBaud(unsigned long baud) return err; } -UBX_CELL_error_t UBX_CELL::setFlowControl(UBX_CELL_flow_control_t value) +UBX_CELL_error_t SparkFun_ublox_Cellular::setFlowControl(UBX_CELL_flow_control_t value) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_FLOW_CONTROL) + 16; @@ -2231,7 +2231,7 @@ UBX_CELL_error_t UBX_CELL::setFlowControl(UBX_CELL_flow_control_t value) return err; } -UBX_CELL_error_t UBX_CELL::setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_t mode, int value) +UBX_CELL_error_t SparkFun_ublox_Cellular::setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_t mode, int value) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_GPIO) + 16; @@ -2249,7 +2249,7 @@ UBX_CELL_error_t UBX_CELL::setGpioMode(UBX_CELL_gpio_t gpio, UBX_CELL_gpio_mode_ return err; } -UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) +SparkFun_ublox_Cellular::UBX_CELL_gpio_mode_t SparkFun_ublox_Cellular::getGpioMode(UBX_CELL_gpio_t gpio) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_GPIO) + 2; @@ -2279,7 +2279,7 @@ UBX_CELL::UBX_CELL_gpio_mode_t UBX_CELL::getGpioMode(UBX_CELL_gpio_t gpio) return (UBX_CELL_gpio_mode_t)gpioMode; } -int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int localPort) +int SparkFun_ublox_Cellular::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int localPort) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_CREATE_SOCKET) + 10; @@ -2329,7 +2329,7 @@ int UBX_CELL::socketOpen(UBX_CELL_socket_protocol_t protocol, unsigned int local return sockId; } -UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketClose(int socket, unsigned long timeout) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_CLOSE_SOCKET) + 10; @@ -2352,7 +2352,7 @@ UBX_CELL_error_t UBX_CELL::socketClose(int socket, unsigned long timeout) return err; } -UBX_CELL_error_t UBX_CELL::socketConnect(int socket, const char *address, unsigned int port) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketConnect(int socket, const char *address, unsigned int port) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_CONNECT_SOCKET) + strlen(address) + 11; @@ -2370,7 +2370,7 @@ UBX_CELL_error_t UBX_CELL::socketConnect(int socket, const char *address, unsign return err; } -UBX_CELL_error_t UBX_CELL::socketConnect(int socket, IPAddress address, unsigned int port) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketConnect(int socket, IPAddress address, unsigned int port) { size_t charLen = 16; char charAddress[charLen]; @@ -2380,7 +2380,7 @@ UBX_CELL_error_t UBX_CELL::socketConnect(int socket, IPAddress address, unsigned return (socketConnect(socket, (const char *)charAddress, port)); } -UBX_CELL_error_t UBX_CELL::socketWrite(int socket, const char *str, int len) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketWrite(int socket, const char *str, int len) { size_t cmdLen = strlen(UBX_CELL_WRITE_SOCKET) + 16; char command[cmdLen]; @@ -2436,12 +2436,12 @@ UBX_CELL_error_t UBX_CELL::socketWrite(int socket, const char *str, int len) return err; } -UBX_CELL_error_t UBX_CELL::socketWrite(int socket, String str) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketWrite(int socket, String str) { return socketWrite(socket, str.c_str(), str.length()); } -UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int port, const char *str, int len) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketWriteUDP(int socket, const char *address, int port, const char *str, int len) { size_t cmdLen = 64; char command[cmdLen]; @@ -2475,7 +2475,7 @@ UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, const char *address, int p return err; } -UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketWriteUDP(int socket, IPAddress address, int port, const char *str, int len) { size_t charLen = 16; char charAddress[16]; @@ -2485,12 +2485,12 @@ UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, IPAddress address, int por return (socketWriteUDP(socket, (const char *)charAddress, port, str, len)); } -UBX_CELL_error_t UBX_CELL::socketWriteUDP(int socket, String address, int port, String str) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketWriteUDP(int socket, String address, int port, String str) { return socketWriteUDP(socket, address.c_str(), port, str.c_str(), str.length()); } -UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, int *bytesRead) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketRead(int socket, int length, char *readDest, int *bytesRead) { size_t cmdLen = strlen(UBX_CELL_READ_SOCKET) + 32; char command[cmdLen]; @@ -2627,7 +2627,7 @@ UBX_CELL_error_t UBX_CELL::socketRead(int socket, int length, char *readDest, in return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketReadAvailable(int socket, int *length) { size_t cmdLen = strlen(UBX_CELL_READ_SOCKET) + 32; char command[cmdLen]; @@ -2667,7 +2667,7 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailable(int socket, int *length) return err; } -UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress, +UBX_CELL_error_t SparkFun_ublox_Cellular::socketReadUDP(int socket, int length, char *readDest, IPAddress *remoteIPAddress, int *remotePort, int *bytesRead) { size_t cmdLen = strlen(UBX_CELL_READ_UDP_SOCKET) + 32; @@ -2827,7 +2827,7 @@ UBX_CELL_error_t UBX_CELL::socketReadUDP(int socket, int length, char *readDest, return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketReadAvailableUDP(int socket, int *length) { size_t cmdLen = strlen(UBX_CELL_READ_UDP_SOCKET) + 32; char command[cmdLen]; @@ -2867,7 +2867,7 @@ UBX_CELL_error_t UBX_CELL::socketReadAvailableUDP(int socket, int *length) return err; } -UBX_CELL_error_t UBX_CELL::socketListen(int socket, unsigned int port) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketListen(int socket, unsigned int port) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_LISTEN_SOCKET) + 9; @@ -2880,7 +2880,7 @@ UBX_CELL_error_t UBX_CELL::socketListen(int socket, unsigned int port) return err; } -UBX_CELL_error_t UBX_CELL::socketDirectLinkMode(int socket) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketDirectLinkMode(int socket) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SOCKET_DIRECT_LINK) + 8; @@ -2893,7 +2893,7 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkMode(int socket) return err; } -UBX_CELL_error_t UBX_CELL::socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketDirectLinkTimeTrigger(int socket, unsigned long timerTrigger) { // valid range is 0 (trigger disabled), 100-120000 if (!((timerTrigger == 0) || ((timerTrigger >= 100) && (timerTrigger <= 120000)))) @@ -2910,7 +2910,7 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkTimeTrigger(int socket, unsigned long return err; } -UBX_CELL_error_t UBX_CELL::socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketDirectLinkDataLengthTrigger(int socket, int dataLengthTrigger) { // valid range is 0, 3-1472 for UDP if (!((dataLengthTrigger == 0) || ((dataLengthTrigger >= 3) && (dataLengthTrigger <= 1472)))) @@ -2927,7 +2927,7 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkDataLengthTrigger(int socket, int dat return err; } -UBX_CELL_error_t UBX_CELL::socketDirectLinkCharacterTrigger(int socket, int characterTrigger) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketDirectLinkCharacterTrigger(int socket, int characterTrigger) { // The allowed range is -1, 0-255, the factory-programmed value is -1; -1 means trigger disabled. if (!((characterTrigger >= -1) && (characterTrigger <= 255))) @@ -2944,7 +2944,7 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkCharacterTrigger(int socket, int char return err; } -UBX_CELL_error_t UBX_CELL::socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer) +UBX_CELL_error_t SparkFun_ublox_Cellular::socketDirectLinkCongestionTimer(int socket, unsigned long congestionTimer) { // valid range is 0, 1000-72000 if (!((congestionTimer == 0) || ((congestionTimer >= 1000) && (congestionTimer <= 72000)))) @@ -2961,7 +2961,7 @@ UBX_CELL_error_t UBX_CELL::socketDirectLinkCongestionTimer(int socket, unsigned return err; } -UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol) +UBX_CELL_error_t SparkFun_ublox_Cellular::querySocketType(int socket, UBX_CELL_socket_protocol_t *protocol) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char command[cmdLen]; @@ -3002,7 +3002,7 @@ UBX_CELL_error_t UBX_CELL::querySocketType(int socket, UBX_CELL_socket_protocol_ return err; } -UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) +UBX_CELL_error_t SparkFun_ublox_Cellular::querySocketLastError(int socket, int *error) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char command[cmdLen]; @@ -3042,7 +3042,7 @@ UBX_CELL_error_t UBX_CELL::querySocketLastError(int socket, int *error) return err; } -UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total) +UBX_CELL_error_t SparkFun_ublox_Cellular::querySocketTotalBytesSent(int socket, uint32_t *total) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char command[cmdLen]; @@ -3082,7 +3082,7 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesSent(int socket, uint32_t *total return err; } -UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *total) +UBX_CELL_error_t SparkFun_ublox_Cellular::querySocketTotalBytesReceived(int socket, uint32_t *total) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char command[cmdLen]; @@ -3122,7 +3122,7 @@ UBX_CELL_error_t UBX_CELL::querySocketTotalBytesReceived(int socket, uint32_t *t return err; } -UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *address, int *port) +UBX_CELL_error_t SparkFun_ublox_Cellular::querySocketRemoteIPAddress(int socket, IPAddress *address, int *port) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char command[cmdLen]; @@ -3166,7 +3166,7 @@ UBX_CELL_error_t UBX_CELL::querySocketRemoteIPAddress(int socket, IPAddress *add return err; } -UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status) +UBX_CELL_error_t SparkFun_ublox_Cellular::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_status_t *status) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char command[cmdLen]; @@ -3206,7 +3206,7 @@ UBX_CELL_error_t UBX_CELL::querySocketStatusTCP(int socket, UBX_CELL_tcp_socket_ return err; } -UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) +UBX_CELL_error_t SparkFun_ublox_Cellular::querySocketOutUnackData(int socket, uint32_t *total) { size_t cmdLen = strlen(UBX_CELL_SOCKET_CONTROL) + 16; char command[cmdLen]; @@ -3247,7 +3247,7 @@ UBX_CELL_error_t UBX_CELL::querySocketOutUnackData(int socket, uint32_t *total) } // Issues command to get last socket error, then prints to serial. Also updates rx/backlog buffers. -int UBX_CELL::socketGetLastError() +int SparkFun_ublox_Cellular::socketGetLastError() { UBX_CELL_error_t err; size_t cmdLen = 64; @@ -3274,12 +3274,12 @@ int UBX_CELL::socketGetLastError() return errorCode; } -IPAddress UBX_CELL::lastRemoteIP(void) +IPAddress SparkFun_ublox_Cellular::lastRemoteIP(void) { return _lastRemoteIP; } -UBX_CELL_error_t UBX_CELL::resetHTTPprofile(int profile) +UBX_CELL_error_t SparkFun_ublox_Cellular::resetHTTPprofile(int profile) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 16; @@ -3295,7 +3295,7 @@ UBX_CELL_error_t UBX_CELL::resetHTTPprofile(int profile) return err; } -UBX_CELL_error_t UBX_CELL::setHTTPserverIPaddress(int profile, IPAddress address) +UBX_CELL_error_t SparkFun_ublox_Cellular::setHTTPserverIPaddress(int profile, IPAddress address) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 64; @@ -3312,7 +3312,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverIPaddress(int profile, IPAddress address return err; } -UBX_CELL_error_t UBX_CELL::setHTTPserverName(int profile, String server) +UBX_CELL_error_t SparkFun_ublox_Cellular::setHTTPserverName(int profile, String server) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 12 + server.length(); @@ -3333,7 +3333,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverName(int profile, String server) return err; } -UBX_CELL_error_t UBX_CELL::setHTTPusername(int profile, String username) +UBX_CELL_error_t SparkFun_ublox_Cellular::setHTTPusername(int profile, String username) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 12 + username.length(); @@ -3354,7 +3354,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPusername(int profile, String username) return err; } -UBX_CELL_error_t UBX_CELL::setHTTPpassword(int profile, String password) +UBX_CELL_error_t SparkFun_ublox_Cellular::setHTTPpassword(int profile, String password) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 12 + password.length(); @@ -3375,7 +3375,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPpassword(int profile, String password) return err; } -UBX_CELL_error_t UBX_CELL::setHTTPauthentication(int profile, bool authenticate) +UBX_CELL_error_t SparkFun_ublox_Cellular::setHTTPauthentication(int profile, bool authenticate) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 32; @@ -3392,7 +3392,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPauthentication(int profile, bool authenticate) return err; } -UBX_CELL_error_t UBX_CELL::setHTTPserverPort(int profile, int port) +UBX_CELL_error_t SparkFun_ublox_Cellular::setHTTPserverPort(int profile, int port) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 32; @@ -3408,7 +3408,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPserverPort(int profile, int port) return err; } -UBX_CELL_error_t UBX_CELL::setHTTPcustomHeader(int profile, String header) +UBX_CELL_error_t SparkFun_ublox_Cellular::setHTTPcustomHeader(int profile, String header) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 12 + header.length(); @@ -3429,7 +3429,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPcustomHeader(int profile, String header) return err; } -UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofile) +UBX_CELL_error_t SparkFun_ublox_Cellular::setHTTPsecure(int profile, bool secure, int secprofile) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROFILE) + 32; @@ -3449,7 +3449,7 @@ UBX_CELL_error_t UBX_CELL::setHTTPsecure(int profile, bool secure, int secprofil return err; } -UBX_CELL_error_t UBX_CELL::ping(String remote_host, int retry, int p_size, unsigned long timeout, int ttl) +UBX_CELL_error_t SparkFun_ublox_Cellular::ping(String remote_host, int retry, int p_size, unsigned long timeout, int ttl) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_PING_COMMAND) + 48 + remote_host.length(); @@ -3467,7 +3467,7 @@ UBX_CELL_error_t UBX_CELL::ping(String remote_host, int retry, int p_size, unsig return err; } -UBX_CELL_error_t UBX_CELL::sendHTTPGET(int profile, String path, String responseFilename) +UBX_CELL_error_t SparkFun_ublox_Cellular::sendHTTPGET(int profile, String path, String responseFilename) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_COMMAND) + 24 + path.length() + responseFilename.length(); @@ -3488,7 +3488,7 @@ UBX_CELL_error_t UBX_CELL::sendHTTPGET(int profile, String path, String response return err; } -UBX_CELL_error_t UBX_CELL::sendHTTPPOSTdata(int profile, String path, String responseFilename, String data, +UBX_CELL_error_t SparkFun_ublox_Cellular::sendHTTPPOSTdata(int profile, String path, String responseFilename, String data, UBX_CELL_http_content_types_t httpContentType) { UBX_CELL_error_t err; @@ -3510,7 +3510,7 @@ UBX_CELL_error_t UBX_CELL::sendHTTPPOSTdata(int profile, String path, String res return err; } -UBX_CELL_error_t UBX_CELL::sendHTTPPOSTfile(int profile, String path, String responseFilename, String requestFile, +UBX_CELL_error_t SparkFun_ublox_Cellular::sendHTTPPOSTfile(int profile, String path, String responseFilename, String requestFile, UBX_CELL_http_content_types_t httpContentType) { UBX_CELL_error_t err; @@ -3534,7 +3534,7 @@ UBX_CELL_error_t UBX_CELL::sendHTTPPOSTfile(int profile, String path, String res return err; } -UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, int *error_code) +UBX_CELL_error_t SparkFun_ublox_Cellular::getHTTPprotocolError(int profile, int *error_class, int *error_code) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_HTTP_PROTOCOL_ERROR) + 4; @@ -3570,7 +3570,7 @@ UBX_CELL_error_t UBX_CELL::getHTTPprotocolError(int profile, int *error_class, i return err; } -UBX_CELL_error_t UBX_CELL::nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter) +UBX_CELL_error_t SparkFun_ublox_Cellular::nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_NVM) + 10; @@ -3581,7 +3581,7 @@ UBX_CELL_error_t UBX_CELL::nvMQTT(UBX_CELL_mqtt_nv_parameter_t parameter) return err; } -UBX_CELL_error_t UBX_CELL::setMQTTclientId(const String &clientId) +UBX_CELL_error_t SparkFun_ublox_Cellular::setMQTTclientId(const String &clientId) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_PROFILE) + clientId.length() + 10; @@ -3596,7 +3596,7 @@ UBX_CELL_error_t UBX_CELL::setMQTTclientId(const String &clientId) return err; } -UBX_CELL_error_t UBX_CELL::setMQTTserver(const String &serverName, int port) +UBX_CELL_error_t SparkFun_ublox_Cellular::setMQTTserver(const String &serverName, int port) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_PROFILE) + serverName.length() + 16; @@ -3612,7 +3612,7 @@ UBX_CELL_error_t UBX_CELL::setMQTTserver(const String &serverName, int port) return err; } -UBX_CELL_error_t UBX_CELL::setMQTTcredentials(const String &userName, const String &pwd) +UBX_CELL_error_t SparkFun_ublox_Cellular::setMQTTcredentials(const String &userName, const String &pwd) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_PROFILE) + userName.length() + pwd.length() + 16; @@ -3628,7 +3628,7 @@ UBX_CELL_error_t UBX_CELL::setMQTTcredentials(const String &userName, const Stri return err; } -UBX_CELL_error_t UBX_CELL::setMQTTsecure(bool secure, int secprofile) +UBX_CELL_error_t SparkFun_ublox_Cellular::setMQTTsecure(bool secure, int secprofile) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_PROFILE) + 16; @@ -3643,7 +3643,7 @@ UBX_CELL_error_t UBX_CELL::setMQTTsecure(bool secure, int secprofile) return err; } -UBX_CELL_error_t UBX_CELL::connectMQTT(void) +UBX_CELL_error_t SparkFun_ublox_Cellular::connectMQTT(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 10; @@ -3654,7 +3654,7 @@ UBX_CELL_error_t UBX_CELL::connectMQTT(void) return err; } -UBX_CELL_error_t UBX_CELL::disconnectMQTT(void) +UBX_CELL_error_t SparkFun_ublox_Cellular::disconnectMQTT(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 10; @@ -3665,7 +3665,7 @@ UBX_CELL_error_t UBX_CELL::disconnectMQTT(void) return err; } -UBX_CELL_error_t UBX_CELL::subscribeMQTTtopic(int max_Qos, const String &topic) +UBX_CELL_error_t SparkFun_ublox_Cellular::subscribeMQTTtopic(int max_Qos, const String &topic) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length(); @@ -3681,7 +3681,7 @@ UBX_CELL_error_t UBX_CELL::subscribeMQTTtopic(int max_Qos, const String &topic) return err; } -UBX_CELL_error_t UBX_CELL::unsubscribeMQTTtopic(const String &topic) +UBX_CELL_error_t SparkFun_ublox_Cellular::unsubscribeMQTTtopic(const String &topic) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 16 + topic.length(); @@ -3696,7 +3696,7 @@ UBX_CELL_error_t UBX_CELL::unsubscribeMQTTtopic(const String &topic) return err; } -UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest, int readLength, int *bytesRead) +UBX_CELL_error_t SparkFun_ublox_Cellular::readMQTT(int *pQos, String *pTopic, uint8_t *readDest, int readLength, int *bytesRead) { size_t cmdLen = strlen(UBX_CELL_MQTT_COMMAND) + 10; char command[cmdLen]; @@ -3796,7 +3796,7 @@ UBX_CELL_error_t UBX_CELL::readMQTT(int *pQos, String *pTopic, uint8_t *readDest return err; } -UBX_CELL_error_t UBX_CELL::mqttPublishTextMsg(const String &topic, const char *const msg, uint8_t qos, bool retain) +UBX_CELL_error_t SparkFun_ublox_Cellular::mqttPublishTextMsg(const String &topic, const char *const msg, uint8_t qos, bool retain) { if (topic.length() < 1 || msg == nullptr) { @@ -3847,7 +3847,7 @@ UBX_CELL_error_t UBX_CELL::mqttPublishTextMsg(const String &topic, const char *c return err; } -UBX_CELL_error_t UBX_CELL::mqttPublishBinaryMsg(const String &topic, const char *const msg, size_t msg_len, uint8_t qos, +UBX_CELL_error_t SparkFun_ublox_Cellular::mqttPublishBinaryMsg(const String &topic, const char *const msg, size_t msg_len, uint8_t qos, bool retain) { /* @@ -3885,7 +3885,7 @@ UBX_CELL_error_t UBX_CELL::mqttPublishBinaryMsg(const String &topic, const char return err; } -UBX_CELL_error_t UBX_CELL::mqttPublishFromFile(const String &topic, const String &filename, uint8_t qos, bool retain) +UBX_CELL_error_t SparkFun_ublox_Cellular::mqttPublishFromFile(const String &topic, const String &filename, uint8_t qos, bool retain) { if (topic.length() < 1 || filename.length() < 1) { @@ -3908,7 +3908,7 @@ UBX_CELL_error_t UBX_CELL::mqttPublishFromFile(const String &topic, const String return err; } -UBX_CELL_error_t UBX_CELL::getMQTTprotocolError(int *error_code, int *error_code2) +UBX_CELL_error_t SparkFun_ublox_Cellular::getMQTTprotocolError(int *error_code, int *error_code2) { UBX_CELL_error_t err; char response[minimumResponseAllocation]; @@ -3941,7 +3941,7 @@ UBX_CELL_error_t UBX_CELL::getMQTTprotocolError(int *error_code, int *error_code return err; } -UBX_CELL_error_t UBX_CELL::setFTPserver(const String &serverName) +UBX_CELL_error_t SparkFun_ublox_Cellular::setFTPserver(const String &serverName) { constexpr size_t cmdLen = 145; char command[cmdLen]; // long enough for AT+UFTP=1,<128 bytes> @@ -3951,7 +3951,7 @@ UBX_CELL_error_t UBX_CELL::setFTPserver(const String &serverName) return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } -UBX_CELL_error_t UBX_CELL::setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, +UBX_CELL_error_t SparkFun_ublox_Cellular::setFTPtimeouts(const unsigned int timeout, const unsigned int cmd_linger, const unsigned int data_linger) { constexpr size_t cmdLen = 64; @@ -3962,7 +3962,7 @@ UBX_CELL_error_t UBX_CELL::setFTPtimeouts(const unsigned int timeout, const unsi return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } -UBX_CELL_error_t UBX_CELL::setFTPcredentials(const String &userName, const String &pwd) +UBX_CELL_error_t SparkFun_ublox_Cellular::setFTPcredentials(const String &userName, const String &pwd) { UBX_CELL_error_t err; constexpr size_t cmdLen = 48; @@ -3981,7 +3981,7 @@ UBX_CELL_error_t UBX_CELL::setFTPcredentials(const String &userName, const Strin return err; } -UBX_CELL_error_t UBX_CELL::connectFTP(void) +UBX_CELL_error_t SparkFun_ublox_Cellular::connectFTP(void) { constexpr size_t cmdLen = 16; char command[cmdLen]; // long enough for AT+UFTPC=n @@ -3990,7 +3990,7 @@ UBX_CELL_error_t UBX_CELL::connectFTP(void) return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } -UBX_CELL_error_t UBX_CELL::disconnectFTP(void) +UBX_CELL_error_t SparkFun_ublox_Cellular::disconnectFTP(void) { constexpr size_t cmdLen = 16; char command[cmdLen]; // long enough for AT+UFTPC=n @@ -3999,7 +3999,7 @@ UBX_CELL_error_t UBX_CELL::disconnectFTP(void) return sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT); } -UBX_CELL_error_t UBX_CELL::ftpGetFile(const String &filename) +UBX_CELL_error_t SparkFun_ublox_Cellular::ftpGetFile(const String &filename) { size_t cmdLen = strlen(UBX_CELL_FTP_COMMAND) + (2 * filename.length()) + 16; char *command = ubx_cell_calloc_char(cmdLen); @@ -4017,7 +4017,7 @@ UBX_CELL_error_t UBX_CELL::ftpGetFile(const String &filename) return err; } -UBX_CELL_error_t UBX_CELL::getFTPprotocolError(int *error_code, int *error_code2) +UBX_CELL_error_t SparkFun_ublox_Cellular::getFTPprotocolError(int *error_code, int *error_code2) { UBX_CELL_error_t err; char response[minimumResponseAllocation]; @@ -4055,7 +4055,7 @@ UBX_CELL_error_t UBX_CELL::getFTPprotocolError(int *error_code, int *error_code2 return err; } -UBX_CELL_error_t UBX_CELL::resetSecurityProfile(int secprofile) +UBX_CELL_error_t SparkFun_ublox_Cellular::resetSecurityProfile(int secprofile) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SEC_PROFILE) + 6; @@ -4068,7 +4068,7 @@ UBX_CELL_error_t UBX_CELL::resetSecurityProfile(int secprofile) return err; } -UBX_CELL_error_t UBX_CELL::configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value) +UBX_CELL_error_t SparkFun_ublox_Cellular::configSecurityProfile(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, int value) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_SEC_PROFILE) + 10; @@ -4079,7 +4079,7 @@ UBX_CELL_error_t UBX_CELL::configSecurityProfile(int secprofile, UBX_CELL_sec_pr return err; } -UBX_CELL_error_t UBX_CELL::configSecurityProfileString(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, +UBX_CELL_error_t SparkFun_ublox_Cellular::configSecurityProfileString(int secprofile, UBX_CELL_sec_profile_parameter_t parameter, String value) { UBX_CELL_error_t err; @@ -4095,7 +4095,7 @@ UBX_CELL_error_t UBX_CELL::configSecurityProfileString(int secprofile, UBX_CELL_ return err; } -UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, +UBX_CELL_error_t SparkFun_ublox_Cellular::setSecurityManager(UBX_CELL_sec_manager_opcode_t opcode, UBX_CELL_sec_manager_parameter_t parameter, String name, String data) { size_t cmdLen = strlen(UBX_CELL_SEC_MANAGER) + name.length() + 20; @@ -4138,7 +4138,7 @@ UBX_CELL_error_t UBX_CELL::setSecurityManager(UBX_CELL_sec_manager_opcode_t opco return err; } -UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) +UBX_CELL_error_t SparkFun_ublox_Cellular::activatePDPcontext(bool status, int cid) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONTEXT_ACTIVATE) + 32; @@ -4157,7 +4157,7 @@ UBX_CELL_error_t UBX_CELL::activatePDPcontext(bool status, int cid) return err; } -bool UBX_CELL::isGPSon(void) +bool SparkFun_ublox_Cellular::isGPSon(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_POWER) + 2; @@ -4185,7 +4185,7 @@ bool UBX_CELL::isGPSon(void) return on; } -UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_aiding_mode_t gnss_aiding) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_aiding_mode_t gnss_aiding) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_GNSS_POWER) + 32; // gnss_sys could be up to three digits @@ -4215,56 +4215,56 @@ UBX_CELL_error_t UBX_CELL::gpsPower(bool enable, gnss_system_t gnss_sys, gnss_ai } /* -UBX_CELL_error_t UBX_CELL::gpsEnableClock(bool enable) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsEnableClock(bool enable) { // AT+UGZDA=<0,1> UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBX_CELL_error_t UBX_CELL::gpsGetClock(struct ClockData *clock) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsGetClock(struct ClockData *clock) { // AT+UGZDA? UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBX_CELL_error_t UBX_CELL::gpsEnableFix(bool enable) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsEnableFix(bool enable) { // AT+UGGGA=<0,1> UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBX_CELL_error_t UBX_CELL::gpsGetFix(struct PositionData *pos) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsGetFix(struct PositionData *pos) { // AT+UGGGA? UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBX_CELL_error_t UBX_CELL::gpsEnablePos(bool enable) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsEnablePos(bool enable) { // AT+UGGLL=<0,1> UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBX_CELL_error_t UBX_CELL::gpsGetPos(struct PositionData *pos) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsGetPos(struct PositionData *pos) { // AT+UGGLL? UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBX_CELL_error_t UBX_CELL::gpsEnableSat(bool enable) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsEnableSat(bool enable) { // AT+UGGSV=<0,1> UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBX_CELL_error_t UBX_CELL::gpsGetSat(uint8_t *sats) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsGetSat(uint8_t *sats) { // AT+UGGSV? UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; @@ -4272,7 +4272,7 @@ UBX_CELL_error_t UBX_CELL::gpsGetSat(uint8_t *sats) } */ -UBX_CELL_error_t UBX_CELL::gpsEnableRmc(bool enable) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsEnableRmc(bool enable) { // AT+UGRMC=<0,1> UBX_CELL_error_t err; @@ -4297,7 +4297,7 @@ UBX_CELL_error_t UBX_CELL::gpsEnableRmc(bool enable) return err; } -UBX_CELL_error_t UBX_CELL::gpsGetRmc(struct PositionData *pos, struct SpeedData *spd, struct ClockData *clk, +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsGetRmc(struct PositionData *pos, struct SpeedData *spd, struct ClockData *clk, bool *valid) { UBX_CELL_error_t err; @@ -4327,14 +4327,14 @@ UBX_CELL_error_t UBX_CELL::gpsGetRmc(struct PositionData *pos, struct SpeedData } /* -UBX_CELL_error_t UBX_CELL::gpsEnableSpeed(bool enable) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsEnableSpeed(bool enable) { // AT+UGVTG=<0,1> UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; return err; } -UBX_CELL_error_t UBX_CELL::gpsGetSpeed(struct SpeedData *speed) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsGetSpeed(struct SpeedData *speed) { // AT+UGVTG? UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; @@ -4342,7 +4342,7 @@ UBX_CELL_error_t UBX_CELL::gpsGetSpeed(struct SpeedData *speed) } */ -UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, bool detailed, unsigned int sensor) +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsRequest(unsigned int timeout, uint32_t accuracy, bool detailed, unsigned int sensor) { // AT+ULOC=2,,,, UBX_CELL_error_t err; @@ -4373,7 +4373,7 @@ UBX_CELL_error_t UBX_CELL::gpsRequest(unsigned int timeout, uint32_t accuracy, b return err; } -UBX_CELL_error_t UBX_CELL::gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, +UBX_CELL_error_t SparkFun_ublox_Cellular::gpsAidingServerConf(const char *primaryServer, const char *secondaryServer, const char *authToken, unsigned int days, unsigned int period, unsigned int resolution, unsigned int gnssTypes, unsigned int mode, unsigned int dataType) @@ -4391,7 +4391,7 @@ UBX_CELL_error_t UBX_CELL::gpsAidingServerConf(const char *primaryServer, const } // OK for text files. But will fail with binary files (containing \0) on some platforms. -UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, const char *str, int len) +UBX_CELL_error_t SparkFun_ublox_Cellular::appendFileContents(String filename, const char *str, int len) { size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_DOWNLOAD_FILE) + filename.length() + 10; char *command; @@ -4438,13 +4438,13 @@ UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, const char *str, return err; } -UBX_CELL_error_t UBX_CELL::appendFileContents(String filename, String str) +UBX_CELL_error_t SparkFun_ublox_Cellular::appendFileContents(String filename, String str) { return appendFileContents(filename, str.c_str(), str.length()); } // OK for text files. But will fail with binary files (containing \0) on some platforms. -UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) +UBX_CELL_error_t SparkFun_ublox_Cellular::getFileContents(String filename, String *contents) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8; @@ -4567,7 +4567,7 @@ UBX_CELL_error_t UBX_CELL::getFileContents(String filename, String *contents) } // OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. -UBX_CELL_error_t UBX_CELL::getFileContents(String filename, char *contents) +UBX_CELL_error_t SparkFun_ublox_Cellular::getFileContents(String filename, char *contents) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_READ_FILE) + filename.length() + 8; @@ -4685,7 +4685,7 @@ UBX_CELL_error_t UBX_CELL::getFileContents(String filename, char *contents) return err; } -UBX_CELL_error_t UBX_CELL::getFileBlock(const String &filename, char *buffer, size_t offset, size_t requested_length, +UBX_CELL_error_t SparkFun_ublox_Cellular::getFileBlock(const String &filename, char *buffer, size_t offset, size_t requested_length, size_t &bytes_read) { bytes_read = 0; @@ -4757,7 +4757,7 @@ UBX_CELL_error_t UBX_CELL::getFileBlock(const String &filename, char *buffer, si return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) +UBX_CELL_error_t SparkFun_ublox_Cellular::getFileSize(String filename, int *size) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_LIST_FILES) + filename.length() + 8; @@ -4808,7 +4808,7 @@ UBX_CELL_error_t UBX_CELL::getFileSize(String filename, int *size) return err; } -UBX_CELL_error_t UBX_CELL::deleteFile(String filename) +UBX_CELL_error_t SparkFun_ublox_Cellular::deleteFile(String filename) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_FILE_SYSTEM_DELETE_FILE) + filename.length() + 8; @@ -4834,7 +4834,7 @@ UBX_CELL_error_t UBX_CELL::deleteFile(String filename) return err; } -UBX_CELL_error_t UBX_CELL::modulePowerOff(void) +UBX_CELL_error_t SparkFun_ublox_Cellular::modulePowerOff(void) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_POWER_OFF) + 6; @@ -4847,7 +4847,7 @@ UBX_CELL_error_t UBX_CELL::modulePowerOff(void) return err; } -void UBX_CELL::modulePowerOn(void) +void SparkFun_ublox_Cellular::modulePowerOn(void) { if (_powerPin >= 0) { @@ -4864,7 +4864,7 @@ void UBX_CELL::modulePowerOn(void) // Private // ///////////// -UBX_CELL_error_t UBX_CELL::init(unsigned long baud, UBX_CELL::UBX_CELL_init_type_t initType) +UBX_CELL_error_t SparkFun_ublox_Cellular::init(unsigned long baud, SparkFun_ublox_Cellular::UBX_CELL_init_type_t initType) { int retries = _maxInitTries; UBX_CELL_error_t err = UBX_CELL_ERROR_SUCCESS; @@ -4942,14 +4942,14 @@ UBX_CELL_error_t UBX_CELL::init(unsigned long baud, UBX_CELL::UBX_CELL_init_type return UBX_CELL_ERROR_SUCCESS; } -void UBX_CELL::invertPowerPin(bool invert) +void SparkFun_ublox_Cellular::invertPowerPin(bool invert) { _invertPowerPin = invert; } // Do a graceful power off. Hold the PWR_ON pin low for UBX_CELL_POWER_OFF_PULSE_PERIOD // Note: +CPWROFF () is preferred to this. -void UBX_CELL::powerOff(void) +void SparkFun_ublox_Cellular::powerOff(void) { if (_powerPin >= 0) { @@ -4969,7 +4969,7 @@ void UBX_CELL::powerOff(void) } } -void UBX_CELL::powerOn(void) +void SparkFun_ublox_Cellular::powerOn(void) { if (_powerPin >= 0) { @@ -4993,7 +4993,7 @@ void UBX_CELL::powerOn(void) // This does an abrupt emergency hardware shutdown of the SARA-R5 series modules. // It only works if you have access to both the RESET_N and PWR_ON pins. // You cannot use this function on the SparkFun Asset Tracker and RESET_N is tied to the MicroMod processor !RESET!... -void UBX_CELL::hwReset(void) +void SparkFun_ublox_Cellular::hwReset(void) { if ((_resetPin >= 0) && (_powerPin >= 0)) { @@ -5038,7 +5038,7 @@ void UBX_CELL::hwReset(void) } } -UBX_CELL_error_t UBX_CELL::functionality(UBX_CELL_functionality_t function) +UBX_CELL_error_t SparkFun_ublox_Cellular::functionality(UBX_CELL_functionality_t function) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_FUNC) + 16; @@ -5051,7 +5051,7 @@ UBX_CELL_error_t UBX_CELL::functionality(UBX_CELL_functionality_t function) return err; } -UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) +UBX_CELL_error_t SparkFun_ublox_Cellular::setMNOprofile(mobile_network_operator_t mno, bool autoReset, bool urcNotification) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_MNO) + 9; @@ -5068,7 +5068,7 @@ UBX_CELL_error_t UBX_CELL::setMNOprofile(mobile_network_operator_t mno, bool aut return err; } -UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) +UBX_CELL_error_t SparkFun_ublox_Cellular::getMNOprofile(mobile_network_operator_t *mno) { UBX_CELL_error_t err; size_t cmdLen = strlen(UBX_CELL_COMMAND_MNO) + 2; @@ -5114,7 +5114,7 @@ UBX_CELL_error_t UBX_CELL::getMNOprofile(mobile_network_operator_t *mno) return err; } -UBX_CELL_error_t UBX_CELL::waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout) +UBX_CELL_error_t SparkFun_ublox_Cellular::waitForResponse(const char *expectedResponse, const char *expectedError, uint16_t timeout) { unsigned long timeIn; bool found = false; @@ -5201,7 +5201,7 @@ UBX_CELL_error_t UBX_CELL::waitForResponse(const char *expectedResponse, const c return UBX_CELL_ERROR_NO_RESPONSE; } -UBX_CELL_error_t UBX_CELL::sendCommandWithResponse(const char *command, const char *expectedResponse, +UBX_CELL_error_t SparkFun_ublox_Cellular::sendCommandWithResponse(const char *command, const char *expectedResponse, char *responseDest, unsigned long commandTimeout, int destSize, bool at) { @@ -5341,14 +5341,14 @@ UBX_CELL_error_t UBX_CELL::sendCommandWithResponse(const char *command, const ch } // Send a custom command with an expected (potentially partial) response, store entire response -UBX_CELL_error_t UBX_CELL::sendCustomCommandWithResponse(const char *command, const char *expectedResponse, +UBX_CELL_error_t SparkFun_ublox_Cellular::sendCustomCommandWithResponse(const char *command, const char *expectedResponse, char *responseDest, unsigned long commandTimeout, bool at) { // Assume the user has allocated enough storage for any response. Set destSize to 32766. return sendCommandWithResponse(command, expectedResponse, responseDest, commandTimeout, 32766, at); } -void UBX_CELL::sendCommand(const char *command, bool at) +void SparkFun_ublox_Cellular::sendCommand(const char *command, bool at) { // Check for incoming serial data. Copy it into the backlog @@ -5399,7 +5399,7 @@ void UBX_CELL::sendCommand(const char *command, bool at) } } -UBX_CELL_error_t UBX_CELL::parseSocketReadIndication(int socket, int length) +UBX_CELL_error_t SparkFun_ublox_Cellular::parseSocketReadIndication(int socket, int length) { UBX_CELL_error_t err; char *readDest; @@ -5448,7 +5448,7 @@ UBX_CELL_error_t UBX_CELL::parseSocketReadIndication(int socket, int length) return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::parseSocketReadIndicationUDP(int socket, int length) +UBX_CELL_error_t SparkFun_ublox_Cellular::parseSocketReadIndicationUDP(int socket, int length) { UBX_CELL_error_t err; char *readDest; @@ -5496,7 +5496,7 @@ UBX_CELL_error_t UBX_CELL::parseSocketReadIndicationUDP(int socket, int length) return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::parseSocketListenIndication(int listeningSocket, IPAddress localIP, +UBX_CELL_error_t SparkFun_ublox_Cellular::parseSocketListenIndication(int listeningSocket, IPAddress localIP, unsigned int listeningPort, int socket, IPAddress remoteIP, unsigned int port) { @@ -5511,7 +5511,7 @@ UBX_CELL_error_t UBX_CELL::parseSocketListenIndication(int listeningSocket, IPAd return UBX_CELL_ERROR_SUCCESS; } -UBX_CELL_error_t UBX_CELL::parseSocketCloseIndication(String *closeIndication) +UBX_CELL_error_t SparkFun_ublox_Cellular::parseSocketCloseIndication(String *closeIndication) { int search; int socket; @@ -5532,7 +5532,7 @@ UBX_CELL_error_t UBX_CELL::parseSocketCloseIndication(String *closeIndication) return UBX_CELL_ERROR_SUCCESS; } -size_t UBX_CELL::hwPrint(const char *s) +size_t SparkFun_ublox_Cellular::hwPrint(const char *s) { if ((true == _printAtDebug) && (nullptr != s)) { @@ -5552,7 +5552,7 @@ size_t UBX_CELL::hwPrint(const char *s) return (size_t)0; } -size_t UBX_CELL::hwWriteData(const char *buff, int len) +size_t SparkFun_ublox_Cellular::hwWriteData(const char *buff, int len) { if ((true == _printAtDebug) && (nullptr != buff) && (0 < len)) { @@ -5571,7 +5571,7 @@ size_t UBX_CELL::hwWriteData(const char *buff, int len) return (size_t)0; } -size_t UBX_CELL::hwWrite(const char c) +size_t SparkFun_ublox_Cellular::hwWrite(const char c) { if (true == _printAtDebug) { @@ -5591,7 +5591,7 @@ size_t UBX_CELL::hwWrite(const char c) return (size_t)0; } -int UBX_CELL::readAvailable(char *inString) +int SparkFun_ublox_Cellular::readAvailable(char *inString) { int len = 0; @@ -5633,7 +5633,7 @@ int UBX_CELL::readAvailable(char *inString) return len; } -char UBX_CELL::readChar(void) +char SparkFun_ublox_Cellular::readChar(void) { char ret = 0; @@ -5651,7 +5651,7 @@ char UBX_CELL::readChar(void) return ret; } -int UBX_CELL::hwAvailable(void) +int SparkFun_ublox_Cellular::hwAvailable(void) { if (_hardSerial != nullptr) { @@ -5667,7 +5667,7 @@ int UBX_CELL::hwAvailable(void) return -1; } -void UBX_CELL::beginSerial(unsigned long baud) +void SparkFun_ublox_Cellular::beginSerial(unsigned long baud) { delay(100); if (_hardSerial != nullptr) @@ -5685,7 +5685,7 @@ void UBX_CELL::beginSerial(unsigned long baud) delay(100); } -void UBX_CELL::setTimeout(unsigned long timeout) +void SparkFun_ublox_Cellular::setTimeout(unsigned long timeout) { if (_hardSerial != nullptr) { @@ -5699,7 +5699,7 @@ void UBX_CELL::setTimeout(unsigned long timeout) #endif } -bool UBX_CELL::find(char *target) +bool SparkFun_ublox_Cellular::find(char *target) { bool found = false; if (_hardSerial != nullptr) @@ -5715,7 +5715,7 @@ bool UBX_CELL::find(char *target) return found; } -UBX_CELL_error_t UBX_CELL::autobaud(unsigned long desiredBaud) +UBX_CELL_error_t SparkFun_ublox_Cellular::autobaud(unsigned long desiredBaud) { UBX_CELL_error_t err = UBX_CELL_ERROR_INVALID; int b = 0; @@ -5734,14 +5734,14 @@ UBX_CELL_error_t UBX_CELL::autobaud(unsigned long desiredBaud) return err; } -char *UBX_CELL::ubx_cell_calloc_char(size_t num) +char *SparkFun_ublox_Cellular::ubx_cell_calloc_char(size_t num) { return (char *)calloc(num, sizeof(char)); } // This prunes the backlog of non-actionable events. If new actionable events are added, you must modify the if // statement. -void UBX_CELL::pruneBacklog() +void SparkFun_ublox_Cellular::pruneBacklog() { char *event; @@ -5806,7 +5806,7 @@ void UBX_CELL::pruneBacklog() // GPS Helper Functions: // Read a source string until a delimiter is hit, store the result in destination -char *UBX_CELL::readDataUntil(char *destination, unsigned int destSize, char *source, char delimiter) +char *SparkFun_ublox_Cellular::readDataUntil(char *destination, unsigned int destSize, char *source, char delimiter) { char *strEnd; @@ -5824,7 +5824,7 @@ char *UBX_CELL::readDataUntil(char *destination, unsigned int destSize, char *so return strEnd; } -bool UBX_CELL::parseGPRMCString(char *rmcString, PositionData *pos, ClockData *clk, SpeedData *spd) +bool SparkFun_ublox_Cellular::parseGPRMCString(char *rmcString, PositionData *pos, ClockData *clk, SpeedData *spd) { char *ptr, *search; unsigned long tTemp; diff --git a/src/sfe_ublox_cellular.h b/src/sfe_ublox_cellular.h index f0a21a5..9e391d6 100644 --- a/src/sfe_ublox_cellular.h +++ b/src/sfe_ublox_cellular.h @@ -629,15 +629,15 @@ typedef enum // DEEP_LOW_POWER_STATE = 127 // Not supported on SARA-R5 } UBX_CELL_functionality_t; -class UBX_CELL : public Print +class SparkFun_ublox_Cellular : public Print { public: // Constructor // The library will use the powerPin and resetPin (if provided) to power the module off/on and perform an emergency // reset maxInitTries sets the maximum number of initialization attempts. .init is called by .begin. - UBX_CELL(int powerPin = UBX_CELL_POWER_PIN, int resetPin = UBX_CELL_RESET_PIN, uint8_t maxInitTries = 9); + SparkFun_ublox_Cellular(int powerPin = UBX_CELL_POWER_PIN, int resetPin = UBX_CELL_RESET_PIN, uint8_t maxInitTries = 9); - ~UBX_CELL(); + ~SparkFun_ublox_Cellular(); // Begin -- initialize module and ensure it's connected #ifdef UBX_CELL_SOFTWARE_SERIAL_ENABLED bool begin(SoftwareSerial &softSerial, unsigned long baud = UBX_CELL_DEFAULT_BAUD_RATE); diff --git a/src/sfe_ublox_cellular_voice.h b/src/sfe_ublox_cellular_voice.h index a460de7..c824d02 100644 --- a/src/sfe_ublox_cellular_voice.h +++ b/src/sfe_ublox_cellular_voice.h @@ -20,10 +20,10 @@ typedef enum } UBX_CELL_audio_resource_t; // Base class for any modules supporting voice calls -template class UBX_CELL_VOICE +template class SparkFun_ublox_Cellular_Voice_Base { public: - UBX_CELL_VOICE(void) + SparkFun_ublox_Cellular_Voice_Base(void) { // Set ring URC callback to nullptr _ringCallback = nullptr; @@ -159,7 +159,7 @@ template class UBX_CELL_VOICE } }; -class UBX_CELL_VOICE_BASE : public UBX_CELL, public UBX_CELL_VOICE +class SparkFun_ublox_Cellular_Voice : public SparkFun_ublox_Cellular, public SparkFun_ublox_Cellular_Voice_Base { }; From 5de76b7efe959bfb717d2f190d7ced56cd68f4fe Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Tue, 2 Jan 2024 15:23:06 -0700 Subject: [PATCH 51/52] Remove empty else block --- src/sfe_ublox_cellular.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index 418c024..1e7e2db 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -894,9 +894,6 @@ bool SparkFun_ublox_Cellular::poll(void) _debugPort->println(_saraRXBuffer); } } - else - { - } } _pollReentrant = false; From 0c492f3244e87912afd9d26648054f42258d6ffc Mon Sep 17 00:00:00 2001 From: Dryw Wade Date: Tue, 2 Jan 2024 15:48:54 -0700 Subject: [PATCH 52/52] Add MQTT Example --- examples/Example8_MQTT/Example8_MQTT.ino | 268 +++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 examples/Example8_MQTT/Example8_MQTT.ino diff --git a/examples/Example8_MQTT/Example8_MQTT.ino b/examples/Example8_MQTT/Example8_MQTT.ino new file mode 100644 index 0000000..1904016 --- /dev/null +++ b/examples/Example8_MQTT/Example8_MQTT.ino @@ -0,0 +1,268 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used +// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class +// SparkFun_ublox_SARA_R500S myModule; +// SparkFun_ublox_SARA_R500S_01B myModule; +// SparkFun_ublox_SARA_R500S_61B myModule; +// SparkFun_ublox_SARA_R510M8S_61B myModule; +// SparkFun_ublox_SARA_R510S myModule; +// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class +// SparkFun_ublox_LARA_R6001 myModule; +// SparkFun_ublox_LARA_R6001D myModule; +// SparkFun_ublox_LARA_R6401 myModule; +// SparkFun_ublox_LARA_R6401D myModule; +// SparkFun_ublox_LARA_R6801_00B myModule; +// SparkFun_ublox_LARA_R6801D myModule; + +// You can change the Quality of Service (QoS) here if you want +int qos = 0; + +// Topics that will be used for publishing and subscribing +String publishTopic; +String subscribeTopic; + +// Whether we're connected to the MQTT broker +bool mqttConnected = false; + +// Callback function for handling MQTT responses from the module +void mqttCallback(int command, int result) +{ + if (command == UBX_CELL_MQTT_COMMAND_LOGIN && result == 1) + { + // Connected to broker + mqttConnected = true; + Serial.println(F("Connected to broker!")); + } + else if (command == UBX_CELL_MQTT_COMMAND_LOGOUT && result == 1) + { + // Disconnected from broker + mqttConnected = false; + Serial.println(F("Disconnected from broker!")); + } + else if (command == UBX_CELL_MQTT_COMMAND_SUBSCRIBE && result == 1) + { + // Topic subscription successful + Serial.println(F("Subscribed to topic!")); + Serial.println(F("Enter any text to post to the topic")); + Serial.println(); + } + else if (command == UBX_CELL_MQTT_COMMAND_READ) + { + // New message available + Serial.print(F("A new message is available! Total messages to read: ")); + Serial.println(result); + Serial.println(F("Enter a blank line to read the oldest message")); + Serial.println(); + } + else + { + // Other response + Serial.print(F("Unknown MQTT reponse! Command: ")); + Serial.print(command); + Serial.print(F(" Result: ")); + Serial.println(result); + } +} + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 8 - MQTT")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE)) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) + ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. " + "Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + Serial.println(); + + // Make sure any previous MQTT connection is closed + myModule.disconnectMQTT(); + + // Set callback for any MQTT responses from the module + myModule.setMQTTCommandCallback(mqttCallback); + + Serial.println(F("Enter the MQTT broker server name")); + + // Clear any previous input and wait for new input + while (Serial.available()) + Serial.read(); + while (!Serial.available()) + ; + + // Get the broker server name + String serverName = Serial.readStringUntil('\n'); + Serial.print(F("Server name: ")); + Serial.println(serverName); + Serial.println(); + + Serial.println(F("Enter the MQTT broker server port number")); + Serial.println(F("(or enter nothing for default port of 1883)")); + + // Clear any previous input and wait for new input + while (Serial.available()) + Serial.read(); + while (!Serial.available()) + ; + + // Get the broker server port + String serverPort = Serial.readStringUntil('\n'); + + // Attempt to parse the port number. If it fails, just set 1883 + int port = serverPort.toInt(); + if (port == 0) + port = 1883; + + Serial.print(F("Server port: ")); + Serial.println(port); + Serial.println(); + + // Now set the MQTT server + myModule.setMQTTserver(serverName, port); + + Serial.println(F("Enter the client ID")); + + // Clear any previous input and wait for new input + while (Serial.available()) + Serial.read(); + while (!Serial.available()) + ; + + // Get the client ID + String clientID = Serial.readStringUntil('\n'); + Serial.print(F("Client ID: ")); + Serial.println(clientID); + Serial.println(); + + // Set the client ID + myModule.setMQTTclientId(clientID); + + Serial.println(F("Connecting to MQTT broker...")); + myModule.connectMQTT(); + + // Wait for module to connect + while (!mqttConnected) + myModule.poll(); + + Serial.println(); + Serial.println(F("Enter a topic to publish to")); + + // Clear any previous input and wait for new input + while (Serial.available()) + Serial.read(); + while (!Serial.available()) + ; + + // Get the topic name + publishTopic = Serial.readStringUntil('\n'); + Serial.print(F("Publish topic: ")); + Serial.println(publishTopic); + Serial.println(); + + Serial.println(); + Serial.println(F("Enter a topic to subscribe to")); + + // Clear any previous input and wait for new input + while (Serial.available()) + Serial.read(); + while (!Serial.available()) + ; + + // Get the topic name + subscribeTopic = Serial.readStringUntil('\n'); + Serial.print(F("Subscribe topic: ")); + Serial.println(subscribeTopic); + Serial.println(); + + // Subscribe to the topic + myModule.subscribeMQTTtopic(qos, subscribeTopic); +} + +void loop() +{ + // Need to call poll() frequently to receive updates from the module. + myModule.poll(); + + // Check for user input + if (Serial.available()) + { + // Get user's input + String inputString = Serial.readStringUntil('\n'); + + // Clear any remaining input + while (Serial.available()) + Serial.read(); + + // Check whether the user entered anything + if (inputString.length() > 0) + { + // Publish the user's input to the topic + Serial.println(F("Publishing message:")); + Serial.println(inputString); + Serial.println(); + myModule.mqttPublishTextMsg(publishTopic, inputString.c_str()); + } + else + { + // Read next received message + uint8_t buffer[MAX_MQTT_DIRECT_MSG_LEN]; + int bytesRead = 0; + myModule.readMQTT(&qos, &subscribeTopic, buffer, MAX_MQTT_DIRECT_MSG_LEN, &bytesRead); + + // Print out message + Serial.println(F("Received message:")); + for (int i = 0; i < bytesRead; i++) + Serial.print((char)buffer[i]); + Serial.println(); + Serial.println(); + } + } +} \ No newline at end of file