Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: example-ublox-at-cellular-interface-ext example-ublox-cellular-driver-gen HelloMQTT ublox_new_driver_test ... more
Revision 0:bb5fabac67ab, committed 2017-06-05
- Comitter:
- RobMeades
- Date:
- Mon Jun 05 13:00:31 2017 +0000
- Child:
- 1:458e1b3d460c
- Commit message:
- Initial revision.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TESTS/unit_tests/file-system/main.cpp Mon Jun 05 13:00:31 2017 +0000
@@ -0,0 +1,153 @@
+#include "mbed.h"
+#include "greentea-client/test_env.h"
+#include "unity.h"
+#include "utest.h"
+#include "UbloxCellularDriverGen.h"
+#include "UDPSocket.h"
+#include "FEATURE_COMMON_PAL/nanostack-libservice/mbed-client-libservice/common_functions.h"
+#include "mbed_trace.h"
+#define TRACE_GROUP "TEST"
+
+using namespace utest::v1;
+
+// IMPORTANT: these tests require
+
+// ----------------------------------------------------------------
+// COMPILE-TIME MACROS
+// ----------------------------------------------------------------
+
+// These macros can be overridden with an mbed_app.json file and
+// contents of the following form:
+//
+//{
+// "config": {
+// "default-pin": {
+// "value": "\"my_pin\""
+// }
+//}
+
+// The credentials of the SIM in the board.
+#ifndef MBED_CONF_APP_DEFAULT_PIN
+// Note: this is the PIN for the SIM with ICCID
+// 8944501104169548380.
+# define MBED_CONF_APP_DEFAULT_PIN "5134"
+#endif
+
+// The size of file to use.
+#ifndef MBED_CONF_APP_FILE_SIZE
+# define MBED_CONF_APP_FILE_SIZE 42000
+#endif
+
+// The name of the file to use.
+#ifndef MBED_CONF_APP_FILE_NAME
+# define MBED_CONF_APP_FILE_NAME "test_file"
+#endif
+
+// ----------------------------------------------------------------
+// PRIVATE VARIABLES
+// ----------------------------------------------------------------
+
+// Lock for debug prints
+static Mutex mtx;
+
+// An instance of the generic cellular class
+static UbloxCellularDriverGen *pDriver =
+ new UbloxCellularDriverGen(MDMTXD, MDMRXD,
+ MBED_CONF_UBLOX_CELL_BAUD_RATE,
+ true);
+
+// A general purpose buffer
+char buf[MBED_CONF_APP_FILE_SIZE];
+
+// ----------------------------------------------------------------
+// PRIVATE FUNCTIONS
+// ----------------------------------------------------------------
+
+// Locks for debug prints
+static void lock()
+{
+ mtx.lock();
+}
+
+static void unlock()
+{
+ mtx.unlock();
+}
+
+// ----------------------------------------------------------------
+// TESTS
+// ----------------------------------------------------------------
+
+// Initialise the module
+void test_start() {
+ TEST_ASSERT(pDriver->init(MBED_CONF_APP_DEFAULT_PIN));
+}
+
+// Write a file to the module's file system with known contents
+void test_write() {
+
+ for (int x = 0; x < sizeof (buf); x++) {
+ buf[x] = (char) x;
+ }
+
+ TEST_ASSERT(pDriver->writeFile(MBED_CONF_APP_FILE_NAME, buf, sizeof (buf)) == sizeof (buf));
+ TEST_ASSERT(pDriver->fileSize(MBED_CONF_APP_FILE_NAME) >= sizeof (buf));
+ tr_debug("%d bytes written to file \"%s\"", sizeof (buf), MBED_CONF_APP_FILE_NAME);
+}
+
+// Read a file back from the module's file system and check the contents
+void test_read() {
+ memset(buf, 0, sizeof (buf));
+
+ TEST_ASSERT(pDriver->readFile(MBED_CONF_APP_FILE_NAME, buf, sizeof (buf)) == sizeof (buf));
+
+ tr_debug("%d bytes read from file \"%s\"", sizeof (buf), MBED_CONF_APP_FILE_NAME);
+
+ for (int x = 0; x < sizeof (buf); x++) {
+ TEST_ASSERT(buf[x] == (char) x);
+ }
+}
+
+// Delete a file from the module's file system
+void test_delete() {
+ TEST_ASSERT(pDriver->delFile(MBED_CONF_APP_FILE_NAME));
+ tr_debug("File \"%s\" deleted", MBED_CONF_APP_FILE_NAME);
+}
+
+// ----------------------------------------------------------------
+// TEST ENVIRONMENT
+// ----------------------------------------------------------------
+
+// Setup the test environment
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+ // Setup Greentea with a timeout
+ GREENTEA_SETUP(180, "default_auto");
+ return verbose_test_setup_handler(number_of_cases);
+}
+
+// Test cases
+Case cases[] = {
+ Case("Start", test_start),
+ Case("Write file", test_write),
+ Case("Read file", test_read),
+ Case("Delete file", test_delete)
+};
+
+Specification specification(test_setup, cases);
+
+// ----------------------------------------------------------------
+// MAIN
+// ----------------------------------------------------------------
+
+int main() {
+ mbed_trace_init();
+
+ mbed_trace_mutex_wait_function_set(lock);
+ mbed_trace_mutex_release_function_set(unlock);
+
+ // Run tests
+ return !Harness::run(specification);
+}
+
+// End Of File
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TESTS/unit_tests/sms/main.cpp Mon Jun 05 13:00:31 2017 +0000
@@ -0,0 +1,176 @@
+#include "mbed.h"
+#include "greentea-client/test_env.h"
+#include "unity.h"
+#include "utest.h"
+#include "UbloxCellularDriverGen.h"
+#include "UDPSocket.h"
+#include "FEATURE_COMMON_PAL/nanostack-libservice/mbed-client-libservice/common_functions.h"
+#include "mbed_trace.h"
+#define TRACE_GROUP "TEST"
+
+using namespace utest::v1;
+
+// IMPORTANT: these tests require
+
+// ----------------------------------------------------------------
+// COMPILE-TIME MACROS
+// ----------------------------------------------------------------
+
+// These macros can be overridden with an mbed_app.json file and
+// contents of the following form:
+//
+//{
+// "config": {
+// "default-pin": {
+// "value": "\"my_pin\""
+// }
+//}
+
+// The credentials of the SIM in the board.
+#ifndef MBED_CONF_APP_DEFAULT_PIN
+// Note: this is the PIN for the SIM with ICCID
+// 8944501104169548380.
+# define MBED_CONF_APP_DEFAULT_PIN "5134"
+#endif
+
+// A number to send SMS messages to which will respond
+// to the instruction given in the messages.
+// IMPORTANT: spaces in the string are NOT allowed
+#ifndef MBED_CONF_APP_SMS_DESTINATION
+# error "Must define a destination number to use for SMS testing (and someone must be there to reply); the number must contain no spaces and should be in international format"
+#endif
+
+// The message to send.
+#ifndef MBED_CONF_APP_SMS_SEND_CONTENTS
+# define MBED_CONF_APP_SMS_SEND_CONTENTS "Please reply to this message within 60 seconds with the single word ACK (in upper case)."
+#endif
+
+// The number of milliseconds to wait for a reply to the sent SMS.
+#ifndef MBED_CONF_APP_SMS_RECEIVE_TIMEOUT
+# define MBED_CONF_APP_SMS_RECEIVE_TIMEOUT 60000
+#endif
+
+// The string that the reply must contain.
+#ifndef MBED_CONF_APP_SMS_RECEIVE_CONTENTS
+# define MBED_CONF_APP_SMS_RECEIVE_CONTENTS "ACK"
+#endif
+
+// ----------------------------------------------------------------
+// PRIVATE VARIABLES
+// ----------------------------------------------------------------
+
+// Lock for debug prints
+static Mutex mtx;
+
+// An instance of the generic cellular class
+static UbloxCellularDriverGen *pDriver =
+ new UbloxCellularDriverGen(MDMTXD, MDMRXD,
+ MBED_CONF_UBLOX_CELL_BAUD_RATE,
+ true);
+
+// ----------------------------------------------------------------
+// PRIVATE FUNCTIONS
+// ----------------------------------------------------------------
+
+// Locks for debug prints
+static void lock()
+{
+ mtx.lock();
+}
+
+static void unlock()
+{
+ mtx.unlock();
+}
+
+// ----------------------------------------------------------------
+// TESTS
+// ----------------------------------------------------------------
+
+// Register with the network
+void test_start() {
+ TEST_ASSERT(pDriver->init(MBED_CONF_APP_DEFAULT_PIN));
+ TEST_ASSERT(pDriver->nwk_registration());
+}
+
+// Send an SMS message
+void test_send() {
+ TEST_ASSERT(pDriver->smsSend(MBED_CONF_APP_SMS_DESTINATION,
+ MBED_CONF_APP_SMS_SEND_CONTENTS));
+}
+
+// Receive an SMS message, check it and delete it
+void test_receive() {
+ int numSms = 0;
+ int index;
+ char num[17];
+ char buf[SMS_BUFFER_SIZE];
+ Timer timer;
+
+ tr_error("!!! YOU HAVE %d SECONDS to reply to the text message !!!",
+ MBED_CONF_APP_SMS_RECEIVE_TIMEOUT / 1000);
+ timer.start();
+ while ((numSms == 0) &&
+ (timer.read_ms() < MBED_CONF_APP_SMS_RECEIVE_TIMEOUT)) {
+ numSms = pDriver->smsList("REC UNREAD", &index, 1);
+ if (numSms == 0) {
+ wait_ms(1000);
+ }
+ }
+ timer.stop();
+
+ TEST_ASSERT (numSms > 0);
+
+ TEST_ASSERT(pDriver->smsRead(index, num, buf, sizeof (buf)));
+ tr_debug("Received: \"%.*s\"", sizeof (buf), buf);
+ TEST_ASSERT (strstr(buf, MBED_CONF_APP_SMS_RECEIVE_CONTENTS) != NULL);
+
+ // Delete the message and check that it's gone
+ numSms = pDriver->smsList();
+ TEST_ASSERT(numSms > 0);
+ TEST_ASSERT(pDriver->smsDelete(index));
+ TEST_ASSERT(pDriver->smsList() == numSms - 1);
+}
+
+// De-register from the network
+void test_end() {
+ TEST_ASSERT(pDriver->nwk_deregistration());
+}
+
+// ----------------------------------------------------------------
+// TEST ENVIRONMENT
+// ----------------------------------------------------------------
+
+// Setup the test environment
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+ // Setup Greentea with a timeout
+ GREENTEA_SETUP(180, "default_auto");
+ return verbose_test_setup_handler(number_of_cases);
+}
+
+// Test cases
+Case cases[] = {
+ Case("Register", test_start),
+ Case("SMS send", test_send),
+ Case("SMS receive and delete", test_receive),
+ Case("Deregister", test_end)
+};
+
+Specification specification(test_setup, cases);
+
+// ----------------------------------------------------------------
+// MAIN
+// ----------------------------------------------------------------
+
+int main() {
+ mbed_trace_init();
+
+ mbed_trace_mutex_wait_function_set(lock);
+ mbed_trace_mutex_release_function_set(unlock);
+
+ // Run tests
+ return !Harness::run(specification);
+}
+
+// End Of File
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TESTS/unit_tests/sms/template_mbed_app.txt Mon Jun 05 13:00:31 2017 +0000
@@ -0,0 +1,18 @@
+{
+ "config": {
+ "sms-destination": {
+ "help": "The destination number to use for SMS testing (someone must be there to reply); the number must contain no spaces and should be in international format",
+ "value": "\"+6601234567890\""
+ }
+ },
+ "target_overrides": {
+ "*": {
+ "target.features_add": ["COMMON_PAL"],
+ "platform.stdio-convert-newlines": true,
+ "platform.stdio-baud-rate": 9600,
+ "platform.default-serial-baud-rate": 115200,
+ "mbed-trace.enable": 1
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TESTS/unit_tests/ussd/main.cpp Mon Jun 05 13:00:31 2017 +0000
@@ -0,0 +1,215 @@
+#include "mbed.h"
+#include "greentea-client/test_env.h"
+#include "unity.h"
+#include "utest.h"
+#include "UbloxCellularDriverGen.h"
+#include "UDPSocket.h"
+#include "FEATURE_COMMON_PAL/nanostack-libservice/mbed-client-libservice/common_functions.h"
+#include "mbed_trace.h"
+#define TRACE_GROUP "TEST"
+
+using namespace utest::v1;
+
+// ----------------------------------------------------------------
+// COMPILE-TIME MACROS
+// ----------------------------------------------------------------
+
+// These macros can be overridden with an mbed_app.json file and
+// contents of the following form:
+//
+//{
+// "config": {
+// "default-pin": {
+// "value": "\"my_pin\""
+// }
+//}
+
+// The credentials of the SIM in the board.
+#ifndef MBED_CONF_APP_DEFAULT_PIN
+// Note: this is the PIN for the SIM with ICCID
+// 8944501104169548380.
+# define MBED_CONF_APP_DEFAULT_PIN "5134"
+#endif
+
+// http://www.geckobeach.com/cellular/secrets/gsmcodes.php
+// https://en.wikipedia.org/wiki/Unstructured_Supplementary_Service_Data
+
+// A few USSD commands to try, set to "" to skip
+#ifndef MBED_CONF_APP_USSD_COMMAND_1
+# define MBED_CONF_APP_USSD_COMMAND_1 "*100#"
+#endif
+
+#ifndef MBED_CONF_APP_USSD_COMMAND_2
+# define MBED_CONF_APP_USSD_COMMAND_2 "*#21#"
+#endif
+
+#ifndef MBED_CONF_APP_USSD_COMMAND_3
+# define MBED_CONF_APP_USSD_COMMAND_3 "*#30#"
+#endif
+
+#ifndef MBED_CONF_APP_USSD_COMMAND_4
+# define MBED_CONF_APP_USSD_COMMAND_4 "*#31#"
+#endif
+
+#ifndef MBED_CONF_APP_USSD_COMMAND_5
+# define MBED_CONF_APP_USSD_COMMAND_5 "*#43#"
+#endif
+
+#ifndef MBED_CONF_APP_USSD_COMMAND_6
+# define MBED_CONF_APP_USSD_COMMAND_6 "*#61#"
+#endif
+
+#ifndef MBED_CONF_APP_USSD_COMMAND_7
+# define MBED_CONF_APP_USSD_COMMAND_7 ""
+#endif
+
+#ifndef MBED_CONF_APP_USSD_COMMAND_8
+# define MBED_CONF_APP_USSD_COMMAND_8 ""
+#endif
+
+#ifndef MBED_CONF_APP_USSD_COMMAND_9
+# define MBED_CONF_APP_USSD_COMMAND_9 ""
+#endif
+
+#ifndef MBED_CONF_APP_USSD_COMMAND_10
+# define MBED_CONF_APP_USSD_COMMAND_10 ""
+#endif
+
+// ----------------------------------------------------------------
+// PRIVATE VARIABLES
+// ----------------------------------------------------------------
+
+// Lock for debug prints
+static Mutex mtx;
+
+// An instance of the generic cellular class
+static UbloxCellularDriverGen *pDriver =
+ new UbloxCellularDriverGen(MDMTXD, MDMRXD,
+ MBED_CONF_UBLOX_CELL_BAUD_RATE,
+ true);
+// A general purpose buffer
+static char buf[USSD_STRING_LENGTH + 1];
+
+// ----------------------------------------------------------------
+// PRIVATE FUNCTIONS
+// ----------------------------------------------------------------
+
+// Locks for debug prints
+static void lock()
+{
+ mtx.lock();
+}
+
+static void unlock()
+{
+ mtx.unlock();
+}
+
+// ----------------------------------------------------------------
+// TESTS
+// ----------------------------------------------------------------
+
+// Test USSD
+void test_ussd() {
+ TEST_ASSERT(pDriver->init(MBED_CONF_APP_DEFAULT_PIN));
+ TEST_ASSERT(pDriver->nwk_registration());
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_1) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_1);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_1, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_2) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_2);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_2, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_3) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_3);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_3, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_4) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_4);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_4, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_5) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_5);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_5, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_6) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_6);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_6, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_7) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_7);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_7, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_8) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_8);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_8, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_9) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_9);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_9, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ if (strlen(MBED_CONF_APP_USSD_COMMAND_10) > 0) {
+ tr_debug("Sending : \"%s\".", MBED_CONF_APP_USSD_COMMAND_10);
+ TEST_ASSERT(pDriver->ussdCommand(MBED_CONF_APP_USSD_COMMAND_10, buf, sizeof (buf)));
+ tr_debug("USSD answer: \"%s\".", buf);
+ }
+
+ TEST_ASSERT(pDriver->nwk_deregistration());
+}
+
+// ----------------------------------------------------------------
+// TEST ENVIRONMENT
+// ----------------------------------------------------------------
+
+// Setup the test environment
+utest::v1::status_t test_setup(const size_t number_of_cases) {
+ // Setup Greentea with a timeout
+ GREENTEA_SETUP(180, "default_auto");
+ return verbose_test_setup_handler(number_of_cases);
+}
+
+// Test cases
+Case cases[] = {
+ Case("USSD test", test_ussd)
+
+};
+
+Specification specification(test_setup, cases);
+
+// ----------------------------------------------------------------
+// MAIN
+// ----------------------------------------------------------------
+
+int main() {
+
+ mbed_trace_init();
+
+ mbed_trace_mutex_wait_function_set(lock);
+ mbed_trace_mutex_release_function_set(unlock);
+
+ // Run tests
+ return !Harness::run(specification);
+}
+
+// End Of File
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/UbloxCellularDriverGen.cpp Mon Jun 05 13:00:31 2017 +0000
@@ -0,0 +1,730 @@
+/* Copyright (c) 2017 ublox Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "UbloxCellularDriverGen.h"
+#include "string.h"
+#if defined(FEATURE_COMMON_PAL)
+#include "mbed_trace.h"
+#define TRACE_GROUP "UCID"
+#else
+#define debug_if(_debug_trace_on, ...) (void(0)) // dummies if feature common pal is not added
+#define tr_info(...) (void(0)) // dummies if feature common pal is not added
+#define tr_error(...) (void(0)) // dummies if feature common pal is not added
+#endif
+
+/**********************************************************************
+ * PROTECTED METHODS: Short Message Service
+ **********************************************************************/
+
+// URC for Short Message listing.
+void UbloxCellularDriverGen::CMGL_URC()
+{
+ char buf[64];
+ int index;
+
+ // Note: not calling _at->recv() from here as we're
+ // already in an _at->recv()
+ // +CMGL: <ix>,...
+ *buf = 0;
+ if (read_at_to_char(buf, sizeof(buf), '\n') > 0) {
+ // Now also read out the text message, so that we don't
+ // accidentally trigger URCs or the like on any of
+ // its contents
+ *_smsBuf = 0;
+ read_at_to_char(_smsBuf, sizeof(_smsBuf), '\n');
+ // Note: don't put any debug in here, this URC is being
+ // called multiple times and debug may cause it to
+ // miss characters
+ if (sscanf(buf, ": %d,", &index) == 1) {
+ _smsCount++;
+ if ((_userSmsIndex != NULL) && (_userSmsNum > 0)) {
+ *_userSmsIndex = index;
+ _userSmsIndex++;
+ _userSmsNum--;
+ }
+ }
+ }
+}
+
+// URC for new SMS messages.
+void UbloxCellularDriverGen::CMTI_URC()
+{
+ char buf[32];
+
+ // Note: not calling _at->recv() from here as we're
+ // already in an _at->recv()
+ *buf = 0;
+ if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
+ // No need to parse, any content is good
+ tr_info("New SMS received");
+ }
+}
+
+/**********************************************************************
+ * PROTECTED METHODS: Unstructured Supplementary Service Data
+ **********************************************************************/
+
+// URC for call waiting.
+void UbloxCellularDriverGen::CCWA_URC()
+{
+ char buf[32];
+ int numChars;
+ int a;
+ int b = 0;
+
+ // Note: not calling _at->recv() from here as we're
+ // already in an _at->recv()
+ // +CCWA: <status>[, <class>]
+ numChars = read_at_to_char(buf, sizeof (buf), '\n');
+ if (numChars > 0) {
+ if (sscanf(buf, ": %d, %d", &a, &b) > 0) {
+ if (_ssUrcBuf == NULL) {
+ _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
+ if (_ssUrcBuf != NULL) {
+ memcpy (_ssUrcBuf, "+CCWA", 5);
+ memcpy (_ssUrcBuf + 5, buf, numChars);
+ *(_ssUrcBuf + numChars + 5) = 0;
+ if (a > 0) {
+ debug_if(_debug_trace_on, "Calling Waiting is active");
+ } else {
+ debug_if(_debug_trace_on, "Calling Waiting is not active");
+ }
+ if (b > 0) {
+ if (b & 0x01) {
+ debug_if(_debug_trace_on, " for voice\n");
+ }
+ if (b & 0x02) {
+ debug_if(_debug_trace_on, " for data\n");
+ }
+ if (b & 0x04) {
+ debug_if(_debug_trace_on, " for fax\n");
+ }
+ if (b & 0x08) {
+ debug_if(_debug_trace_on, " for SMS\n");
+ }
+ if (b & 0x10) {
+ debug_if(_debug_trace_on, " for data circuit sync\n");
+ }
+ if (b & 0x20) {
+ debug_if(_debug_trace_on, " for data circuit async\n");
+ }
+ if (b & 0x40) {
+ debug_if(_debug_trace_on, " for dedicated packet access\n");
+ }
+ if (b & 0x80) {
+ debug_if(_debug_trace_on, " for dedicated PAD access\n");
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// URC for call forwarding.
+void UbloxCellularDriverGen::CCFC_URC()
+{
+ char buf[32];
+ int numChars;
+ char num[32];
+ int a, b;
+ int numValues;
+
+ // Note: not calling _at->recv() from here as we're
+ // already in an _at->recv()
+ // +CCFC: <status>[, <class>]
+ numChars = read_at_to_char(buf, sizeof (buf), '\n');
+ if (numChars > 0) {
+ memset (num, 0, sizeof (num));
+ numValues = sscanf(buf, ": %d,%d,\"%32[^\"][\"]", &a, &b, num);
+ if (numValues > 0) {
+ if (_ssUrcBuf == NULL) {
+ _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
+ if (_ssUrcBuf != NULL) {
+ memcpy (_ssUrcBuf, "+CCFC", 5);
+ memcpy (_ssUrcBuf + 5, buf, numChars);
+ *(_ssUrcBuf + numChars + 5) = 0;
+ if (a > 0) {
+ debug_if(_debug_trace_on, "Calling Forwarding is active ");
+ } else {
+ debug_if(_debug_trace_on, "Calling Forwarding is not active ");
+ }
+ if (numValues > 1) {
+ if (b > 0) {
+ if (b & 0x01) {
+ debug_if(_debug_trace_on, " for voice");
+ }
+ if (b & 0x02) {
+ debug_if(_debug_trace_on, " for data");
+ }
+ if (b & 0x04) {
+ debug_if(_debug_trace_on, " for fax");
+ }
+ if (b & 0x08) {
+ debug_if(_debug_trace_on, " for SMS");
+ }
+ if (b & 0x10) {
+ debug_if(_debug_trace_on, " for data circuit sync");
+ }
+ if (b & 0x20) {
+ debug_if(_debug_trace_on, " for data circuit async");
+ }
+ if (b & 0x40) {
+ debug_if(_debug_trace_on, " for dedicated packet access");
+ }
+ if (b & 0x80) {
+ debug_if(_debug_trace_on, " for dedicated PAD access");
+ }
+ }
+ }
+ if (numValues > 2) {
+ debug_if(_debug_trace_on, " for %s\n", num);
+ } else {
+ debug_if(_debug_trace_on, "\n");
+ }
+ }
+ }
+ }
+ }
+}
+
+
+// URC for calling line ID restriction.
+void UbloxCellularDriverGen::CLIR_URC()
+{
+ char buf[32];
+ int numChars;
+ int a, b;
+ int numValues;
+
+ // Note: not calling _at->recv() from here as we're
+ // already in an _at->recv()
+ // +CLIR: <n>[, <m>]
+ numChars = read_at_to_char(buf, sizeof (buf), '\n');
+ if (numChars > 0) {
+ numValues = sscanf(buf, ": %d,%d", &a, &b);
+ if (numValues > 0) {
+ if (_ssUrcBuf == NULL) {
+ _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
+ if (_ssUrcBuf != NULL) {
+ memcpy (_ssUrcBuf, "+CLIR", 5);
+ memcpy (_ssUrcBuf + 5, buf, numChars);
+ *(_ssUrcBuf + numChars + 5) = 0;
+ switch (a) {
+ case 0:
+ debug_if(_debug_trace_on, "Calling Line ID restriction is as subscribed\n");
+ break;
+ case 1:
+ debug_if(_debug_trace_on, "Calling Line ID invocation ");
+ break;
+ case 2:
+ debug_if(_debug_trace_on, "Calling Line ID suppression ");
+ break;
+ }
+ if (numValues > 2) {
+ switch (b) {
+ case 0:
+ debug_if(_debug_trace_on, " is not provisioned\n");
+ break;
+ case 1:
+ debug_if(_debug_trace_on, " is provisioned permanently\n");
+ break;
+ case 2:
+ debug_if(_debug_trace_on, " is unknown\n");
+ break;
+ case 3:
+ debug_if(_debug_trace_on, " is in temporary mode, presentation restricted\n");
+ break;
+ case 4:
+ debug_if(_debug_trace_on, " is in temporary mode, presentation allowed\n");
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// URC for calling line ID presentation.
+void UbloxCellularDriverGen::CLIP_URC()
+{
+ char buf[32];
+ int numChars;
+ int a, b;
+ int numValues;
+
+ // Note: not calling _at->recv() from here as we're
+ // already in an _at->recv()
+ // +CLIP: <n>[, <m>]
+ numChars = read_at_to_char(buf, sizeof (buf), '\n');
+ if (numChars > 0) {
+ numValues = sscanf(buf, ": %d,%d", &a, &b);
+ if (numValues > 0) {
+ if (_ssUrcBuf == NULL) {
+ _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
+ if (_ssUrcBuf != NULL) {
+ memcpy (_ssUrcBuf, "+CLIP", 5);
+ memcpy (_ssUrcBuf + 5, buf, numChars);
+ *(_ssUrcBuf + numChars + 5) = 0;
+ switch (a) {
+ case 0:
+ debug_if(_debug_trace_on, "Calling Line ID disable ");
+ break;
+ case 1:
+ debug_if(_debug_trace_on, "Calling Line ID enable ");
+ break;
+ }
+ if (numValues > 1) {
+ switch (b) {
+ case 0:
+ debug_if(_debug_trace_on, " is not provisioned\n");
+ break;
+ case 1:
+ debug_if(_debug_trace_on, " is provisioned\n");
+ break;
+ case 2:
+ debug_if(_debug_trace_on, " is unknown\n");
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// URC for connected line ID presentation.
+void UbloxCellularDriverGen::COLP_URC()
+{
+ char buf[32];
+ int numChars;
+ int a, b;
+ int numValues;
+
+ // Note: not calling _at->recv() from here as we're
+ // already in an _at->recv()
+ // +COLP: <n>[, <m>]
+ numChars = read_at_to_char(buf, sizeof (buf), '\n');
+ if (numChars > 0) {
+ numValues = sscanf(buf, ": %d,%d", &a, &b);
+ if (numValues > 0) {
+ if (_ssUrcBuf == NULL) {
+ _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
+ if (_ssUrcBuf != NULL) {
+ memcpy (_ssUrcBuf, "+COLP", 5);
+ memcpy (_ssUrcBuf + 5, buf, numChars);
+ *(_ssUrcBuf + numChars + 5) = 0;
+ switch (a) {
+ case 0:
+ debug_if(_debug_trace_on, "Connected Line ID disable ");
+ break;
+ case 1:
+ debug_if(_debug_trace_on, "Connected Line ID enable ");
+ break;
+ }
+ if (numValues > 1) {
+ switch (b) {
+ case 0:
+ debug_if(_debug_trace_on, " is not provisioned\n");
+ break;
+ case 1:
+ debug_if(_debug_trace_on, " is provisioned\n");
+ break;
+ case 2:
+ debug_if(_debug_trace_on, " is unknown\n");
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// URC for connected line ID restriction.
+void UbloxCellularDriverGen::COLR_URC()
+{
+ char buf[32];
+ int numChars;
+ int a;
+
+ // Note: not calling _at->recv() from here as we're
+ // already in an _at->recv()
+ // +COLR: <status>
+ numChars = read_at_to_char(buf, sizeof (buf), '\n');
+ if (numChars > 0) {
+ if (sscanf(buf, ": %d", &a) > 0) {
+ if (_ssUrcBuf == NULL) {
+ _ssUrcBuf = (char *) malloc(numChars + 5 + 1);
+ if (_ssUrcBuf != NULL) {
+ memcpy (_ssUrcBuf, "+COLR", 5);
+ memcpy (_ssUrcBuf + 5, buf, numChars);
+ *(_ssUrcBuf + numChars + 5) = 0;
+ switch (a) {
+ case 0:
+ debug_if(_debug_trace_on, "Connected Line ID restriction is not provisioned\n");
+ break;
+ case 1:
+ debug_if(_debug_trace_on, "Connected Line ID restriction is provisioned\n");
+ break;
+ case 2:
+ debug_if(_debug_trace_on, "Connected Line ID restriction is unknown\n");
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+/**********************************************************************
+ * PUBLIC METHODS: Generic
+ **********************************************************************/
+
+// Constructor.
+UbloxCellularDriverGen::UbloxCellularDriverGen(PinName tx, PinName rx,
+ int baud, bool debug_on)
+{
+ _userSmsIndex = NULL;
+ _userSmsNum = 0;
+ _smsCount = 0;
+ _ssUrcBuf = NULL;
+
+ // Initialise the base class, which starts the AT parser
+ baseClassInit(tx, rx, baud, debug_on);
+
+ // URCs related to SMS
+ _at->oob("+CMGL", callback(this, &UbloxCellularDriverGen::CMGL_URC));
+ // Include the colon with this one as otherwise it could be found
+ // by +CMT, should it ever occur
+ _at->oob("+CMTI:", callback(this, &UbloxCellularDriverGen::CMTI_URC));
+
+ // URCs relater to supplementary services
+ _at->oob("+CCWA", callback(this, &UbloxCellularDriverGen::CCWA_URC));
+ _at->oob("+CCFC", callback(this, &UbloxCellularDriverGen::CCFC_URC));
+ _at->oob("+CLIR", callback(this, &UbloxCellularDriverGen::CLIR_URC));
+ _at->oob("+CLIP", callback(this, &UbloxCellularDriverGen::CLIP_URC));
+ _at->oob("+COLP", callback(this, &UbloxCellularDriverGen::COLP_URC));
+ _at->oob("+COLR", callback(this, &UbloxCellularDriverGen::COLR_URC));
+}
+
+// Destructor.
+UbloxCellularDriverGen::~UbloxCellularDriverGen()
+{
+}
+
+/**********************************************************************
+ * PUBLIC METHODS: Short Message Service
+ **********************************************************************/
+
+// Count the number of messages on the module.
+int UbloxCellularDriverGen::smsList(const char* stat, int* index, int num)
+{
+ int numMessages = -1;
+ LOCK();
+
+ _userSmsIndex = index;
+ _userSmsNum = num;
+ _smsCount = 0;
+ // There is a callback to capture the result
+ // +CMGL: <ix>,...
+ _at->debug_on(false); // No time for AT interface debug
+ // as the list comes out in one long
+ // stream and we can lose characters if we
+ // pause to do printfs
+ if (_at->send("AT+CMGL=\"%s\"", stat) && _at->recv("OK\n")) {
+ numMessages = _smsCount;
+ }
+ _at->debug_on(_debug_trace_on);
+
+ // Set this back to null so that the URC won't trample
+ _userSmsIndex = NULL;
+
+ UNLOCK();
+ return numMessages;
+}
+
+// Send an SMS message.
+bool UbloxCellularDriverGen::smsSend(const char* num, const char* buf)
+{
+ bool success = false;
+ char typeOfAddress = TYPE_OF_ADDRESS_NATIONAL;
+ LOCK();
+
+ if ((strlen (num) > 0) && (*(num) == '+')) {
+ typeOfAddress = TYPE_OF_ADDRESS_INTERNATIONAL;
+ }
+ if (_at->send("AT+CMGS=\"%s\",%d", num, typeOfAddress) && _at->recv(">")) {
+ if ((_at->write(buf, (int) strlen(buf)) >= (int) strlen(buf)) &&
+ (_at->putc(0x1A) == 0) && // CTRL-Z
+ _at->recv("OK")) {
+ success = true;
+ }
+ }
+
+ UNLOCK();
+ return success;
+}
+
+bool UbloxCellularDriverGen::smsDelete(int index)
+{
+ bool success;
+ LOCK();
+
+ success = _at->send("AT+CMGD=%d", index) && _at->recv("OK");
+
+ UNLOCK();
+ return success;
+}
+
+bool UbloxCellularDriverGen::smsRead(int index, char* num, char* buf, int len)
+{
+ bool success = false;
+ char * endOfString;
+ int smsReadLength = 0;
+ LOCK();
+
+ if (len > 0) {
+ //+CMGR: "REC READ", "+393488535999",,"07/04/05,18:02:28+08",145,4,0,0,"+393492000466",145,93
+ // The text of the message.
+ // OK
+ memset (_smsBuf, 0, sizeof (SMS_BUFFER_SIZE)); // Ensure terminator
+ if (_at->send("AT+CMGR=%d", index) &&
+ _at->recv("+CMGR: \"%*[^\"]\",\"%15[^\"]\"%*[^\n]\n", num) &&
+ _at->recv("%" stringify(SMS_BUFFER_SIZE) "[^\n]\n", _smsBuf) &&
+ _at->recv("OK")) {
+ endOfString = strchr(_smsBuf, 0);
+ if (endOfString != NULL) {
+ smsReadLength = endOfString - _smsBuf;
+ if (smsReadLength + 1 > len) { // +1 for terminator
+ smsReadLength = len - 1;
+ }
+ memcpy(buf, _smsBuf, smsReadLength);
+ *(buf + smsReadLength) = 0; // Add terminator
+ success = true;
+ }
+ }
+ }
+
+ UNLOCK();
+ return success;
+}
+
+/**********************************************************************
+ * PUBLIC METHODS: Unstructured Supplementary Service Data
+ **********************************************************************/
+
+// Perform a USSD command.
+bool UbloxCellularDriverGen::ussdCommand(const char* cmd, char* buf, int len)
+{
+ bool success = false;
+ char * tmpBuf;
+ int atTimeout;
+ int x;
+ Timer timer;
+ LOCK();
+ atTimeout = _at_timeout; // Has to be inside LOCK()s
+
+ if (len > 0) {
+ *buf = 0;
+ if (len > USSD_STRING_LENGTH + 1) {
+ len = USSD_STRING_LENGTH + 1;
+ }
+
+ tmpBuf = (char *) malloc(USSD_STRING_LENGTH + 1);
+
+ if (tmpBuf != NULL) {
+ memset (tmpBuf, 0, USSD_STRING_LENGTH + 1);
+ // +CUSD: \"%*d, \"%128[^\"]\",%*d"
+ if (_at->send("AT+CUSD=1,\"%s\"", cmd)) {
+ // Wait for either +CUSD to come back or
+ // one of the other SS related URCs to trigger
+ if (_ssUrcBuf != NULL) {
+ free (_ssUrcBuf);
+ _ssUrcBuf = NULL;
+ }
+ timer.start();
+ _at->set_timeout(1000);
+ while (!success && (timer.read_ms() < atTimeout)) {
+ if (_at->recv("+CUSD: %*d,\"")) {
+ // Note: don't wait for "OK" here as the +CUSD response may come
+ // before or after the OK
+ // Also, the return string may include newlines so can't just use
+ // recv() to capture it as recv() will stop capturing at a newline.
+ if (read_at_to_char(tmpBuf, USSD_STRING_LENGTH, '\"') > 0) {
+ success = true;
+ memcpy (buf, tmpBuf, len);
+ *(buf + len - 1) = 0;
+ }
+ } else {
+ // Some of the return values do not appear as +CUSD but
+ // instead as the relevant URC for call waiting, call forwarding,
+ // etc. Test those here.
+ if (_ssUrcBuf != NULL) {
+ success = true;
+ x = strlen (_ssUrcBuf);
+ if (x > len - 1 ) {
+ x = len - 1;
+ }
+ memcpy (buf, _ssUrcBuf, x);
+ *(buf + x) = 0;
+ free (_ssUrcBuf);
+ _ssUrcBuf = NULL;
+ }
+ }
+ }
+ at_set_timeout(atTimeout);
+ timer.stop();
+ }
+ }
+ }
+
+ UNLOCK();
+ return success;
+}
+
+/**********************************************************************
+ * PUBLIC: Module File System
+ **********************************************************************/
+
+// Delete a file from the module's file system.
+bool UbloxCellularDriverGen::delFile(const char* filename)
+{
+ bool success;
+ LOCK();
+
+ success = _at->send("AT+UDELFILE=\"%s\"", filename) && _at->recv("OK");
+
+ UNLOCK();
+ return success;
+}
+
+// Write a buffer of data to a file in the module's file system.
+int UbloxCellularDriverGen::writeFile(const char* filename, const char* buf, int len)
+{
+ int bytesWritten = -1;
+ LOCK();
+
+ if (_at->send("AT+UDWNFILE=\"%s\",%d", filename, len) && _at->recv(">")) {
+ if ((_at->write(buf, len) >= len) && _at->recv("OK")) {
+ bytesWritten = len;
+ }
+ }
+
+ UNLOCK();
+ return bytesWritten;
+}
+
+// Read a file from the module's file system
+// Note: this is implemented with block reads since UARTSerial
+// does not currently allow flow control and there is a danger
+// of character loss with large whole-file reads
+int UbloxCellularDriverGen::readFile(const char* filename, char* buf, int len)
+{
+ int countBytes = -1; // Counter for file reading (default value)
+ int bytesToRead = fileSize(filename); // Retrieve the size of the file
+ int offset = 0;
+ int blockSize = FILE_BUFFER_SIZE;
+ char respFilename[48 + 1];
+ int sz, sz_read;
+ bool success = true;
+ int ch = 0;
+ int timeLimit;
+ Timer timer;
+
+ debug_if(_debug_trace_on, "readFile: filename is %s; size is %d\n", filename, bytesToRead);
+
+ memset(respFilename, 0, sizeof (respFilename)); // Ensure terminator
+ if (bytesToRead > 0)
+ {
+ if (bytesToRead > len) {
+ bytesToRead = len;
+ }
+
+ while (success && (bytesToRead > 0)) {
+
+ if (bytesToRead < blockSize) {
+ blockSize = bytesToRead;
+ }
+ LOCK();
+
+ if (blockSize > 0) {
+ if (_at->send("AT+URDBLOCK=\"%s\",%d,%d\r\n", filename, offset, blockSize) &&
+ _at->recv("+URDBLOCK: \"%48[^\"]\",%d,\"", respFilename, &sz) &&
+ (strcmp(filename, respFilename) == 0)) {
+
+ // Would use _at->read() here, but if it runs ahead of the
+ // serial stream it returns -1 instead of the number of characters
+ // read so far, which is not very helpful so instead use _at->getc() and
+ // a time limit. The time limit is twice the amount of time it should take to
+ // read the block at the working baud rate
+ timer.reset();
+ timer.start();
+ timeLimit = blockSize * 2 / ((MBED_CONF_UBLOX_CELL_BAUD_RATE / 8) / 1000);
+ sz_read = 0;
+ while ((sz_read < blockSize) && (timer.read_ms() < timeLimit)) {
+ ch = _at->getc();
+ if (ch >= 0) {
+ *buf = ch;
+ buf++;
+ sz_read++;
+ }
+ }
+ timer.stop();
+
+ if (sz_read == blockSize) {
+ bytesToRead -= sz_read;
+ offset += sz_read;
+ _at->recv("OK");
+ } else {
+ debug_if(_debug_trace_on, "blockSize %d but only received %d bytes\n", blockSize, sz_read);
+ success = false;
+ }
+ } else {
+ success = false;
+ }
+ }
+
+ UNLOCK();
+ }
+
+ if (success) {
+ countBytes = offset;
+ }
+ }
+
+ return countBytes;
+}
+
+// Return the size of a file.
+int UbloxCellularDriverGen::fileSize(const char* filename)
+{
+ int returnValue = -1;
+ int fileSize;
+ LOCK();
+
+ if (_at->send("AT+ULSTFILE=2,\"%s\"", filename) &&
+ _at->recv("+ULSTFILE: %d\n", &fileSize) &&
+ _at->recv("OK")) {
+ returnValue = fileSize;
+ }
+
+ UNLOCK();
+ return returnValue;
+}
+
+// End of file
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/UbloxCellularDriverGen.h Mon Jun 05 13:00:31 2017 +0000
@@ -0,0 +1,269 @@
+/* Copyright (c) 2017 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UBLOX_CELLULAR_DRIVER_GEN_
+#define _UBLOX_CELLULAR_DRIVER_GEN_
+
+#include "ublox_modem_driver/UbloxCellularBase.h"
+
+/** UbloxCellularDriverGen class
+ * This interface provide SMS, USSD and
+ * module File System functionality.
+ */
+class UbloxCellularDriverGen: virtual public UbloxCellularBase {
+
+public:
+ /** Constructor.
+ *
+ * @param tx the UART TX data pin to which the modem is attached.
+ * @param rx the UART RX data pin to which the modem is attached.
+ * @param baud the UART baud rate.
+ * @param debugOn true to switch AT interface debug on, otherwise false.
+ */
+ UbloxCellularDriverGen(PinName tx = MDMTXD, PinName rx = MDMRXD,
+ int baud = MBED_CONF_UBLOX_CELL_BAUD_RATE,
+ bool debugOn = false);
+
+ /* Destructor.
+ */
+ ~UbloxCellularDriverGen();
+
+ /**********************************************************************
+ * PUBLIC: Short Message Service
+ **********************************************************************/
+
+ /** The size of an SMS storage buffer, including null terminator.
+ */
+ #define SMS_BUFFER_SIZE 145
+
+ /** Count the number of messages in the device and optionally return a
+ * list with indexes from the storage locations in the device.
+ *
+ * Note: init() should be called before this method can be used.
+ *
+ * @param stat what type of messages you can use:
+ * "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL".
+ * @param index list where to save the storage positions (pointer
+ * to an array of ints).
+ * @param num number of elements that can be stored in the list.
+ * @return the number of messages, this can be bigger than num,
+ * -1 on failure.
+ */
+ int smsList(const char* stat = "ALL", int* index = NULL, int num = 0);
+
+ /** Read a message from a storage position.
+ *
+ * Note: init() should be called before this method can be used.
+ *
+ * @param index the storage position to read.
+ * @param num the originator address (16 chars including terminator).
+ * @param buf a buffer where to save the short message.
+ * @param len the length of buf.
+ * @return true if successful, false otherwise.
+ */
+ bool smsRead(int index, char* num, char* buf, int len);
+
+ /** Delete a message.
+ *
+ * Note: init() should be called before this method can be used.
+ *
+ * @param index the storage position to delete.
+ * @return true if successful, false otherwise.
+ */
+ bool smsDelete(int index);
+
+ /** Send a message to a recipient.
+ *
+ * Note: init() and nwk_registration() should be called before
+ * this method can be used.
+ *
+ * @param num the phone number of the recipient as a null terminated
+ * string. Note: no spaces are allowed in this string.
+ * @param buf the content of the message to sent, null terminated.
+ * @return true if successful, false otherwise.
+ */
+ bool smsSend(const char* num, const char* buf);
+
+ /**********************************************************************
+ * PUBLIC: Unstructured Supplementary Service Data
+ **********************************************************************/
+
+ /** The maximum size of a USSD string (not including terminator).
+ */
+ #define USSD_STRING_LENGTH 128
+
+ /** Make a USSD query.
+ *
+ * Note: init() should be called before using this method can be
+ * used and, in many cases, nwk_registration() is also required as
+ * the USSD may need network access.
+ *
+ * Note: some USSD commands relate to call waiting, call forwarding,
+ * etc., which can result in multiple responses. This function returns
+ * only the first response. Instantiate this class with debugOn set to
+ * true to get a better view of what is really going on. If such
+ * responses are important to you, you should subclass this class and
+ * parse for them specifically and, probably, use specific AT commands
+ * rather than USSD.
+ *
+ * @param cmd the USSD string to send e.g "*#100#".
+ * @param buf a buffer where to save the reply, which
+ * will always be returned zero terminated.
+ * @param len the length of buf, set to USSD_STRING_LENGTH + 1 to
+ * obtain the maximum length response plus terminator.
+ * @return true if successful, false otherwise.
+ */
+ bool ussdCommand(const char* cmd, char* buf, int len);
+
+ /**********************************************************************
+ * PUBLIC: Module File System
+ **********************************************************************/
+
+ /** Delete a file from the module's local file system. An attempt
+ * to delete a non-existent file will fail.
+ *
+ * Note: init() should be called before this method can be used.
+ *
+ * @param filename the name of the file.
+ * @return true if successful, false otherwise.
+ */
+ bool delFile(const char* filename);
+
+ /** Write some data to a file in the module's local file system.
+ *
+ * Note: init() should be called before this method can be used.
+ *
+ * @param filename the name of the file.
+ * @param buf the data to write.
+ * @param len the size of the data to write.
+ * @return the number of bytes written.
+ */
+ int writeFile(const char* filename, const char* buf, int len);
+
+ /** Read a file from the module's local file system.
+ *
+ * Note: init() should be called before this method can be used.
+ *
+ * @param filename the name of the file
+ * @param buf a buffer to hold the data
+ * @param len the size to read
+ * @return the number of bytes read
+ */
+ int readFile(const char* filename, char* buf, int len);
+
+ /** Retrieve the file size from the module's local file system.
+ *
+ * Note: init() should be called before this method can be used.
+ *
+ * @param filename the name of the file.
+ * @return the file size in bytes.
+ */
+ int fileSize(const char* filename);
+
+protected:
+
+ /**********************************************************************
+ * PROTECTED: Short Message Service
+ **********************************************************************/
+
+ /** The number type for telephone numbers without a + on the front
+ */
+ #define TYPE_OF_ADDRESS_NATIONAL 129
+
+ /** The number type for telephone numbers with a + on the front
+ */
+ #define TYPE_OF_ADDRESS_INTERNATIONAL 145
+
+ /** Convert a #define to a string
+ */
+ #define stringify(a) str(a)
+ #define str(a) #a
+
+ /** Place to store the index of an SMS message.
+ */
+ int *_userSmsIndex;
+
+ /** The number of SMS message being returned to the user.
+ */
+ int _userSmsNum;
+
+ /** The number of SMS messages stored in the module.
+ */
+ int _smsCount;
+
+ /** Temporary storage for an SMS message.
+ */
+ char _smsBuf[SMS_BUFFER_SIZE];
+
+ /** URC for Short Message listing.
+ */
+ void CMGL_URC();
+
+ /** URC for new SMS messages.
+ */
+ void CMTI_URC();
+
+ /**********************************************************************
+ * PROTECTED: Unstructured Supplementary Service Data
+ **********************************************************************/
+
+ /** A buffer for the string assembled from the URC.
+ */
+ char * _ssUrcBuf;
+
+ /** URC for call waiting.
+ */
+ void CCWA_URC();
+
+ /** URC for call forwarding.
+ */
+ void CCFC_URC();
+
+ /** URC for calling lined ID restriction.
+ */
+ void CLIR_URC();
+
+ /** URC for calling lined ID presentation.
+ */
+ void CLIP_URC();
+
+ /** URC for connected lined ID restriction.
+ */
+ void COLR_URC();
+
+ /** URC for connected lined ID presentation.
+ */
+ void COLP_URC();
+
+ /**********************************************************************
+ * PROTECTED: File System
+ **********************************************************************/
+
+ /** The maximum size of a single read of file data.
+ * Note: this should be no larger than BUFFERED_SERIAL_RXBUF_SIZE
+ * (which defaults to 256) minus some margin for the AT command
+ * stuff that precedes it (which includes the filename). A good
+ * number is 192. If you want to use something bigger then add an
+ * entry to the target_overrides section of your mbed_app.json of the
+ * following form:
+ *
+ * "platform.buffered-serial-rxbuf-size": 1024
+ */
+
+ #define FILE_BUFFER_SIZE 192
+};
+
+#endif // _UBLOX_CELLULAR_DRIVER_GEN_
+