diff --git a/.github/workflows/arduino-lint.yml b/.github/workflows/arduino-lint.yml index 87c995e..3b3538b 100644 --- a/.github/workflows/arduino-lint.yml +++ b/.github/workflows/arduino-lint.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@v4 - name: Arduino Lint - uses: arduino/arduino-lint-action@v1 + uses: arduino/arduino-lint-action@v2 with: compliance: specification library-manager: update diff --git a/.github/workflows/render-documentation.yml b/.github/workflows/render-documentation.yml index 30ee933..82c498c 100644 --- a/.github/workflows/render-documentation.yml +++ b/.github/workflows/render-documentation.yml @@ -21,8 +21,8 @@ jobs: render-docs: permissions: contents: write - uses: sebromero/render-docs-github-action/.github/workflows/render-docs.yml@main + uses: arduino/render-docs-github-action/.github/workflows/render-docs.yml@main with: source-path: './src' target-path: './docs/api.md' - fail-on-warnings: true \ No newline at end of file + fail-on-warnings: true diff --git a/README.md b/README.md index f6162be..7a0fcdd 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,17 @@ [![Arduino Lint](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/arduino-lint.yml) [![Compile Examples](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/compile-examples.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/compile-examples.yml) [![Spell Check](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/spell-check.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/spell-check.yml) [![Sync Labels](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/sync-labels.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/sync-labels.yml) [![Render Documentation](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/render-documentation.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/render-documentation.yml) -This library provides a toolkit for interacting with the official Arduino 4G Modules ([EMEA](https://store.arduino.cc/products/4g-module-emea) and [Global Versions](https://store.arduino.cc/products/4g-module-global)). -It allows you to connect to the internet, send and receive SMS messages, and get location from the cellular network or GPS. +This library provides a toolkit for interacting with the official Arduino 4G Modules ([EMEA](https://store.arduino.cc/products/4g-module-emea) and [Global Versions](https://store.arduino.cc/products/4g-module-global)) on using the [Portenta Mid Carrier](https://store.arduino.cc/products/portenta-mid-carrier) and Portenta H7 or C33 boards. It allows you to connect to the internet, send and receive SMS messages, and get location from the cellular network or GPS. + + +> [!NOTE] +> GPS/GNSS functionality is only supported on the [Global Versions](https://store.arduino.cc/products/4g-module-global) version of the modem. + ## Examples * [DeleteSMS](examples/DeleteSMS) - Example that shows how to delete SMS. -* [GetLocation](examples/GetLocation) - Shows how to get the current GPS location. -* [GetTime](examples/GetTime) - Use GPS to acquire the time of the device. +* [GetLocation](examples/GetLocation) - Shows how to get the current GPS location. (Supported on the [Global Version](https://store.arduino.cc/products/4g-module-global)) +* [GetTime](examples/GetTime) - Use GPS to acquire the time of the device. (Supported on the [Global Version](https://store.arduino.cc/products/4g-module-global)) * [HTTPClient](examples/HTTPClient) - Example of using this library together with [ArduinoHttpClient]() to connect to a web server * [HTTPSClient](examples/HTTPSClient) - Example of using this library together with [ArduinoHttpClient]() that uses [BearSSL]() under the hood to create a secure connection to a web server * [ModemTerminal](examples/ModemTerminal) - A handy example for debugging and Testing AT commands @@ -19,27 +23,73 @@ It allows you to connect to the internet, send and receive SMS messages, and get ## ✨ Features * Fast 4G connection to the internet * Secure SSL connections with BearSSL -* Get location using GPS or GSM +* Get location using GPS or GSM * Synchronise time with the cell provider * Send and Receive SMS Messages ## 👀 Instructions -1. Insert your Arduino 4G module to the [Arduino Portenta Mid Carrier](https://store.arduino.cc/collections/portenta-family/products/portenta-mid-carrier) -2. Insert a valid SIM card either in the **PCIE_SIM** connector on the Portenta Mid Carrier -3. Connect the 5 **SERIAL1** header pins to their corresponding pins on the **PCIE_BREAKOUT** header using jumpers -![](./docs/header.jpg) -4. Connect the **3V3 PCIE** pin to the **3V3 Buck** -![](./docs/buck.jpg) -5. Connect external power to the Mid Carrier, via the **VIN** (5V) because modems use a lot of power when connecting or getting a GPS location. Make sure your supply can handle around 3A. -6. Get the APN settings from your network operator and add them to the "arduino_secrets.h" file for each sketch -```cpp -const char apn[] = "live.vodafone.com"; -const char gprsUser[] = "live"; -const char gprsPass[] = ""; -``` -7. Install the library and it's dependencies -8. Enjoy +1. Insert a nano SIM card in the **PCIE_SIM** connector on the [Arduino Portenta Mid Carrier](https://docs.arduino.cc/hardware/portenta-mid-carrier/). +2. Connect the Serial (J17) to the adjacent PCIE Breakout Pins (J16) with jumpers included in the Portenta Mid Carrier: + | Serial 1 (J17) | PCIE Breakout (J16) | + |------------------------|---------------------| + | RX (Pin 1) | CK_N (Pin 1) | + | TX (Pin 2) | CK_P (Pin 3) | + | RTS (Pin 3) | RX_N (Pin 5) | + | CTS (Pin 4) | RX_P (Pin 7) | + | mPCIE_GPIO_RST (Pin 5) | mPCIE_RST (Pin 9) | + + Portenta Mid Carrier with Portenta H7 and PCIE Breakout Pin Configuration + +3. On J9, using jumpers connect the following pins: + | Source (J9) | Buck Converter (J9) | + |------------------|---------------------| + | 3V3 PCIE (Pin 1) | 3V3 BUCK (Pin 3) | + | OUT VCC (Pin 2) | 3V3 BUCK EN (Pin 4) | + + Portenta Mid Carrier SIM and Power Pin Configuration + +4. Insert the [Arduino Pro 4G Module](https://docs.arduino.cc/hardware/pro-4g-module) in the Arduino Portenta Mid Carrier. + +5. Screw one black post with a white nut from under the Portenta Mid Carrier. Using another black post, screw the board to the post. Place two washers on top, and one underneath the Pro 4G Module. So that the board is fixed to the post snuggly and horizontally. + +6. (EMEA and GNSS variants) Connect the cellular antenna (flat antenna in [Arduino Pro 4G Module Antennas Kit](https://store.arduino.cc/products/4g-module-antenna)) to the left microUFL connector marked MAIN. + +7. (PRO 4G GNSS only) Connect the GNSS antenna (square antenna in [Arduino Pro 4G Module Antennas Kit](https://store.arduino.cc/products/4g-module-antenna)) to the middle microUFL connector marked GNSS. + + Portenta Mid Carrier with Pro 4G Module GNSS with both the MAIN and GNSS antennas connected + +8. Insert a [Portenta C33](https://docs.arduino.cc/hardware/portenta-c33) or [Portenta H7](https://docs.arduino.cc/hardware/portenta-h7) Board into the marked location. The USB-C port of the Portenta board should be next to the Ethernet port on the Mid Carrier. + +9. Insert a Terminal Block 2-pin > DC female adapter into the screw terminal (J4). Ensure that the negative (-) pin is connected to GND. + + Portenta Mid Carrier with Portenta C33 and Pro 4G Module GNSS with all antennas connected + +10. Use a 5V adapter that can output at least 3A and connect it to the DC female adapter. + +11. Connect the Portenta board to your computer using a USB-C cable. + +12. Install the `Arduino_Cellular` library and its dependencies + +13. Obtain the APN (Access Point Name) settings from your network operator and add them to the `arduino_secrets.h` file for each sketch. For example: + ```cpp + #define SECRET_PINNUMBER "" // replace with your SIM card PIN + #define SECRET_GPRS_APN "services.telenor.se" // replace with your GPRS APN + #define SECRET_GPRS_LOGIN "" // replace with your GPRS login + #define SECRET_GPRS_PASSWORD "" // replace with your GPRS password + ``` + +14. Upload sketch to the Portenta board. Enjoy! + + +## Compatibility +* This library is designed to be used with the the official Arduino 4G Modules [EMEA](https://store.arduino.cc/products/4g-module-emea) and [Global Versions](https://store.arduino.cc/products/4g-module-global) +* GPS/GNSS functionality is only supported on the [Global Version](https://store.arduino.cc/products/4g-module-global) +* This library compiles on the [Portenta C33](https://store.arduino.cc/products/portenta-c33?), [Portenta H7](https://store.arduino.cc/products/portenta-h7), [H7 Lite](https://store.arduino.cc/products/portenta-h7-lite), and [H7 Lite Connected](https://store.arduino.cc/products/portenta-h7-lite-connected) used in conjunction with the [Portenta Mid Carrier](https://store.arduino.cc/products/portenta-mid-carrier). Any other configuration is not supported by this library. +* Even though these Modules are PCIE devices and would physically fit on the [Portenta Max Carrier](https://store.arduino.cc/products/portenta-max-carrier), we do not support this configuration with the Arduino_Cellular library. But the Portenta Max Carrier has a SARA-R412M-02B cellular modem already. +* None of the library examples compile with the Portenta X8. The X8 handles the cellular connectivity in the Yocto Linux layer. ## 📖 Documentation For more information about this library please read the documentation [here](./docs). + + diff --git a/docs/Arduino_Portenta_Mid_Carrier_GNSS_with_GNSS_MAIN_Antennas.jpg b/docs/Arduino_Portenta_Mid_Carrier_GNSS_with_GNSS_MAIN_Antennas.jpg new file mode 100644 index 0000000..0ca4fa7 Binary files /dev/null and b/docs/Arduino_Portenta_Mid_Carrier_GNSS_with_GNSS_MAIN_Antennas.jpg differ diff --git a/docs/Arduino_Portenta_Mid_Carrier_PortentaC33_4GPRO_GNSS_All_Antennas.jpg b/docs/Arduino_Portenta_Mid_Carrier_PortentaC33_4GPRO_GNSS_All_Antennas.jpg new file mode 100644 index 0000000..35a1719 Binary files /dev/null and b/docs/Arduino_Portenta_Mid_Carrier_PortentaC33_4GPRO_GNSS_All_Antennas.jpg differ diff --git a/docs/Arduino_Portenta_Mid_Carrier_PortentaH7_and_PCIEBreakout_Pins.jpg b/docs/Arduino_Portenta_Mid_Carrier_PortentaH7_and_PCIEBreakout_Pins.jpg new file mode 100644 index 0000000..06e86d7 Binary files /dev/null and b/docs/Arduino_Portenta_Mid_Carrier_PortentaH7_and_PCIEBreakout_Pins.jpg differ diff --git a/docs/Arduino_Portenta_Mid_Carrier_SIM_and_Power_Pins.jpg b/docs/Arduino_Portenta_Mid_Carrier_SIM_and_Power_Pins.jpg new file mode 100644 index 0000000..37b3e2b Binary files /dev/null and b/docs/Arduino_Portenta_Mid_Carrier_SIM_and_Power_Pins.jpg differ diff --git a/docs/api.md b/docs/api.md index bd2cd17..7d5b0e4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -6,7 +6,7 @@ `class ` [`ModemInterface`](#class_modem_interface) | Represents the interface to the 4G modem module which extends the TinyGsmBG96 class. `class ` [`SMS`](#class_s_m_s) | Represents an [SMS](#class_s_m_s) message. `class ` [`Time`](#class_time) | Represents a point in time with year, month, day, hour, minute, second, and offset. -`struct ` [`Location`](#struct_location) | Represents a geographic location with latitude and longitude coordinates. +`struct ` [`Geolocation`](#struct_geolocation) | Represents a geographic location with latitude and longitude coordinates. # class `ArduinoCellular` @@ -23,12 +23,12 @@ This class provides methods to interact with the Arduino Pro Modem, such as conn | [`isConnectedToOperator`](#class_arduino_cellular_1af7453ef90702e9042e2b4b18fa89db03) | Checks if the modem is registered on the network. | | [`isConnectedToInternet`](#class_arduino_cellular_1a6f8251e06de1810897b8bd8f8fb1b1a2) | Checks if the GPRS network is connected. | | [`enableGPS`](#class_arduino_cellular_1abe77a53e0eba6e8d62ba5db3bb6f5e92) | Enables or disables the GPS functionality. | -| [`getGPSLocation`](#class_arduino_cellular_1aee57a2eec5be06172b2fb7cd574d9106) | Gets the GPS location. (Blocking call) | +| [`getGPSLocation`](#class_arduino_cellular_1a41225f52d059df173f028ecd0c039ec3) | Gets the GPS location. (Blocking call) | | [`getCellularTime`](#class_arduino_cellular_1a6b3ce5485badff582584d539e790aff4) | Gets the current time from the network. | | [`getGPSTime`](#class_arduino_cellular_1a4aeb898c958e6eb001d606f0c7da8799) | Gets the current time from the GPS module. | | [`sendSMS`](#class_arduino_cellular_1a371aef1318857f0863f443eaeabf4ac2) | Sends an [SMS](#class_s_m_s) message to the specified number. | -| [`getReadSMS`](#class_arduino_cellular_1a5da65683df86af75590c7a68766236ee) | Gets the list of read [SMS](#class_s_m_s) messages. | -| [`getUnreadSMS`](#class_arduino_cellular_1af1e3b2fad0a64f3b7675c88100ddbca5) | Gets the list of unread [SMS](#class_s_m_s) messages. | +| [`getReadSMS`](#class_arduino_cellular_1ae032c4e4cade6579a2c1edfe53d2ff2b) | Gets the list of read [SMS](#class_s_m_s) messages. | +| [`getUnreadSMS`](#class_arduino_cellular_1a212513654884058947a2a4d332f6ccfc) | Gets the list of unread [SMS](#class_s_m_s) messages. | | [`deleteSMS`](#class_arduino_cellular_1abe4337f0bc8c486a076011309120ace1) | Deletes an [SMS](#class_s_m_s) message at the specified index. | | [`sendATCommand`](#class_arduino_cellular_1a58a3e3713af0c01ad1075a2509c6874d) | Sends an AT command to the modem and waits for a response, then returns the response. | | [`sendUSSDCommand`](#class_arduino_cellular_1a6886aec5850836ea8e8f135d4e5632ab) | Sends a USSD command to the network operator and waits for a response. | @@ -135,10 +135,10 @@ Enables or disables the GPS functionality. True if GPS was enabled successfully, false otherwise.
-### `getGPSLocation` +### `getGPSLocation` ```cpp -Location getGPSLocation(unsigned long timeout) +Geolocation getGPSLocation(unsigned long timeout) ``` Gets the GPS location. (Blocking call) @@ -188,7 +188,7 @@ Sends an [SMS](#class_s_m_s) message to the specified number. * `message` The message to send.
-### `getReadSMS` +### `getReadSMS` ```cpp std::vector< SMS > getReadSMS() @@ -200,7 +200,7 @@ Gets the list of read [SMS](#class_s_m_s) messages. A vector of [SMS](#class_s_m_s) messages.
-### `getUnreadSMS` +### `getUnreadSMS` ```cpp std::vector< SMS > getUnreadSMS() @@ -824,7 +824,7 @@ Returns the timezone offset of the time. The timezone offset of the time.
-# struct `Location` +# struct `Geolocation` Represents a geographic location with latitude and longitude coordinates. @@ -832,12 +832,12 @@ Represents a geographic location with latitude and longitude coordinates. Members | Descriptions --------------------------------|--------------------------------------------- -| [`latitude`](#struct_location_1a194bf3edf130d2a4bf281720e7d01409) | The latitude coordinate of the location. | -| [`longitude`](#struct_location_1ae36169ef2dfcad63e26b492a6a82b990) | The longitude coordinate of the location. | +| [`latitude`](#struct_geolocation_1a86c7bea43545766d1da49a566b579846) | The latitude coordinate of the location. | +| [`longitude`](#struct_geolocation_1a6df627e2a4f3566e7a40cec69c94fd06) | The longitude coordinate of the location. | ## Members -### `latitude` +### `latitude` ```cpp float latitude @@ -846,7 +846,7 @@ float latitude The latitude coordinate of the location.
-### `longitude` +### `longitude` ```cpp float longitude diff --git a/docs/buck.jpg b/docs/buck.jpg deleted file mode 100644 index 3d6a235..0000000 Binary files a/docs/buck.jpg and /dev/null differ diff --git a/docs/header.jpg b/docs/header.jpg deleted file mode 100644 index f6c43c1..0000000 Binary files a/docs/header.jpg and /dev/null differ diff --git a/examples/GetLocation/GetLocation.ino b/examples/GetLocation/GetLocation.ino index 7ec02a7..a59aa6c 100644 --- a/examples/GetLocation/GetLocation.ino +++ b/examples/GetLocation/GetLocation.ino @@ -28,7 +28,7 @@ void setup(){ } void loop(){ - Location location = cellular.getGPSLocation(); + Geolocation location = cellular.getGPSLocation(); Serial.println("GPS Location:"); Serial.print("* Latitude: "); Serial.println(location.latitude, 6); Serial.print("* Longitude: "); Serial.println(location.longitude, 6); diff --git a/examples/GetTime/GetTime.ino b/examples/GetTime/GetTime.ino index af4e2b4..6071b44 100644 --- a/examples/GetTime/GetTime.ino +++ b/examples/GetTime/GetTime.ino @@ -28,7 +28,7 @@ void setup(){ } void loop(){ - Location location = cellular.getGPSLocation(10000); + Geolocation location = cellular.getGPSLocation(10000); if(location.latitude == 0.0 && location.longitude == 0.0){ Serial.println("Failed to get GPS location"); diff --git a/library.properties b/library.properties index 6d4a77e..8334a0f 100644 --- a/library.properties +++ b/library.properties @@ -1,11 +1,12 @@ name=Arduino_Cellular -version=1.1.0 +version=1.2.1 author=Arduino maintainer=Arduino -sentence=This library provides a toolkit for interacting with the official Arduino Pro 4G Modules. -paragraph=A library that allows you to connect to the Internet, send and receive SMS messages, and get location from the cellular network or GPS using the official Arduino Pro 4G Modules on the Portenta Mid Carrier board. +sentence=A library for interacting with the Arduino Pro 4G modules (Quectel EC200A-EU and EG25-G) on Portenta H7 and C33 boards. +paragraph=This library allows you to connect to the Internet, send and receive SMS messages, and get location data using the official Arduino Pro 4G Modules (SKU: TPX00201 – EMEA based on Quectel EC200A-EU and SKU: TPX00200 – GNSS based on Quectel EG25-G) on the Portenta H7 and Portenta C33 via the Mid Carrier board. GPS functionality is available only on the GNSS variant (TPX00200). category=Communication url=https://github.com/arduino-libraries/Arduino_Cellular depends=ArduinoBearSSL,StreamDebugger,TinyGSM,ArduinoHttpClient architectures=renesas_portenta, mbed_portenta -includes=Arduino_Cellular.h \ No newline at end of file +includes=Arduino_Cellular.h + diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index 4477d75..a4f0d2b 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -1,6 +1,9 @@ #include "ArduinoCellular.h" +#if defined(ARDUINO_ARCH_MBED) + #include "Watchdog.h" +#endif unsigned long ArduinoCellular::getTime() { int year, month, day, hour, minute, second; @@ -35,12 +38,18 @@ void ArduinoCellular::begin() { modem.sendAT("+CNMI=2,1,0,0,0"); modem.waitResponse(); - +#if defined(ARDUINO_CELLULAR_BEARSSL) ArduinoBearSSL.onGetTime(ArduinoCellular::getTime); +#endif + +} +bool ArduinoCellular::connect(String apn, bool waitForever) { + connect(apn,String(""),String(""), waitForever); } -bool ArduinoCellular::connect(String apn, String username, String password){ + +bool ArduinoCellular::connect(String apn, String username, String password, bool waitForever){ SimStatus simStatus = getSimStatus(); if(simStatus == SimStatus::SIM_LOCKED){ @@ -58,7 +67,7 @@ bool ArduinoCellular::connect(String apn, String username, String password){ return false; } - if(!awaitNetworkRegistration()){ + if(!awaitNetworkRegistration(waitForever)){ return false; } @@ -87,7 +96,7 @@ bool ArduinoCellular::connect(String apn, String username, String password){ } -Location ArduinoCellular::getGPSLocation(unsigned long timeout){ +Geolocation ArduinoCellular::getGPSLocation(unsigned long timeout){ if (model == ModemModel::EG25){ float latitude = 0.00000; float longitude = 0.00000; @@ -98,7 +107,7 @@ Location ArduinoCellular::getGPSLocation(unsigned long timeout){ delay(1000); } - Location loc; + Geolocation loc; loc.latitude = latitude; loc.longitude = longitude; @@ -107,7 +116,7 @@ Location ArduinoCellular::getGPSLocation(unsigned long timeout){ if(this->debugStream != nullptr){ this->debugStream->println("Unsupported modem model"); } - return Location(); + return Geolocation(); } } @@ -118,14 +127,23 @@ Time ArduinoCellular::getGPSTime(){ } Time ArduinoCellular::getCellularTime(){ - int year, month, day, hour, minute, second; + int year = 1970; + int month = 1; + int day = 1; + int hour = 0; + int minute = 0; + int second = 0; float tz; - modem.getNetworkTime(&year, &month, &day, &hour, &minute, &second, &tz); + if (modem.NTPServerSync() == 0) { + modem.getNetworkTime(&year, &month, &day, &hour, &minute, &second, &tz); + } return Time(year, month, day, hour, minute, second); } void ArduinoCellular::sendSMS(String number, String message){ + modem.sendAT("+CMGF=1"); + modem.waitResponse(1000); modem.sendAT(GF("+CMGS=\""), number, GF("\"")); if (modem.waitResponse(GF(">")) != 1) { } modem.stream->print(message); // Actually send the message @@ -155,6 +173,7 @@ HttpClient ArduinoCellular::getHTTPClient(const char * server, const int port){ return HttpClient(* new TinyGsmClient(modem), server, port); } +#if defined(ARDUINO_CELLULAR_BEARSSL) HttpClient ArduinoCellular::getHTTPSClient(const char * server, const int port){ return HttpClient(* new BearSSLClient(* new TinyGsmClient(modem)), server, port); } @@ -162,6 +181,7 @@ HttpClient ArduinoCellular::getHTTPSClient(const char * server, const int port){ BearSSLClient ArduinoCellular::getSecureNetworkClient(){ return BearSSLClient(* new TinyGsmClient(modem)); } +#endif bool ArduinoCellular::isConnectedToOperator(){ return modem.isNetworkConnected(); @@ -190,13 +210,13 @@ SimStatus ArduinoCellular::getSimStatus(){ this->debugStream->println("SIM Status: " + String(simStatus)); } - if (modem.getSimStatus() == 0) { + if (simStatus == 0) { return SimStatus::SIM_ERROR; - } else if (modem.getSimStatus() == 1) { + } else if (simStatus == 1) { return SimStatus::SIM_READY; - } else if (modem.getSimStatus() == 2) { + } else if (simStatus == 2) { return SimStatus::SIM_LOCKED; - } else if (modem.getSimStatus() == 3) { + } else if (simStatus == 3) { return SimStatus::SIM_ANTITHEFT_LOCKED; } else { return SimStatus::SIM_ERROR; @@ -204,22 +224,40 @@ SimStatus ArduinoCellular::getSimStatus(){ } bool ArduinoCellular::unlockSIM(String pin){ - if(this->debugStream != nullptr){ - this->debugStream->println("Unlocking SIM..."); + int simStatus = modem.getSimStatus(); + if(simStatus == SIM_LOCKED) { + if(this->debugStream != nullptr){ + this->debugStream->println("Unlocking SIM..."); + } + return modem.simUnlock(pin.c_str()); + } + else if(simStatus == SIM_ERROR || simStatus == SIM_ANTITHEFT_LOCKED) { + return false; } - return modem.simUnlock(pin.c_str()); + /* SIM is ready */ + return true; } -bool ArduinoCellular::awaitNetworkRegistration(){ +bool ArduinoCellular::awaitNetworkRegistration(bool waitForever){ if(this->debugStream != nullptr){ this->debugStream->println("Waiting for network registration..."); } - while (!modem.waitForNetwork()) { + while (!modem.waitForNetwork(waitForNetworkTimeout)) { + + if(!waitForever) { + return false; + } + if(this->debugStream != nullptr){ this->debugStream->print("."); } + #if defined(ARDUINO_ARCH_MBED) + if(mbed::Watchdog::get_instance().is_running()) { + mbed::Watchdog::get_instance().kick(); + } + #endif delay(2000); - } + } return true; } diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index c671b83..8f32de5 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -16,8 +16,18 @@ #include #include -#include "ArduinoBearSSLConfig.h" -#include + +#if defined __has_include + #if !__has_include () + #define ARDUINO_CELLULAR_BEARSSL + #endif +#endif + +#if defined(ARDUINO_CELLULAR_BEARSSL) + #include "ArduinoBearSSLConfig.h" + #include +#endif + #include #include @@ -60,6 +70,7 @@ class SMS { * @param timestamp The timestamp when the SMS was received. */ SMS(int16_t index, String sender, String message, Time timestamp) { + this->index = index; this->sender = sender; this->message = message; this->timestamp = timestamp; @@ -68,10 +79,10 @@ class SMS { /** - * @struct Location + * @struct Geolocation * @brief Represents a geographic location with latitude and longitude coordinates. */ -struct Location { +struct Geolocation { float latitude; /**< The latitude coordinate of the location. */ float longitude; /**< The longitude coordinate of the location. */ }; @@ -108,9 +119,19 @@ class ArduinoCellular { * @param apn The Access Point Name. * @param username The APN username. * @param password The APN password. + * @param waitForever The function does not return unless a connection has been established + * @return True if the connection is successful, false otherwise. + */ + bool connect(String apn = "", String username = "", String password = "", bool waitForever = true); + + /** + * @brief Registers with the cellular network and connects to the Internet + * if the APN, GPRS username, and GPRS password are provided. + * @param apn The Access Point Name. + * @param waitForever The function does not return unless a connection has been established * @return True if the connection is successful, false otherwise. */ - bool connect(String apn = "", String username = "", String password = ""); + bool connect(String apn, bool waitForever = true); /** * @brief Checks if the modem is registered on the network. @@ -136,7 +157,7 @@ class ArduinoCellular { * @param timeout The timeout (In milliseconds) to wait for the GPS location. * @return The GPS location. If the location is not retrieved, the latitude and longitude will be 0.0. */ - Location getGPSLocation(unsigned long timeout = 60000); + Geolocation getGPSLocation(unsigned long timeout = 60000); /** * @brief Gets the current time from the network. @@ -206,7 +227,9 @@ class ArduinoCellular { * @brief Gets the Transport Layer Security (TLS) client. (OSI Layer 4) * @return The GSM client. */ +#if defined(ARDUINO_CELLULAR_BEARSSL) BearSSLClient getSecureNetworkClient(); +#endif /** * @brief Gets the HTTP client for the specified server and port. @@ -246,20 +269,22 @@ class ArduinoCellular { */ void setDebugStream(Stream& stream); - private: - bool connectToGPRS(const char * apn, const char * gprsUser, const char * gprsPass); - - /** + /** * @brief Gets the SIM card status. * @return The SIM card status. */ SimStatus getSimStatus(); + private: + bool connectToGPRS(const char * apn, const char * gprsUser, const char * gprsPass); + + /** * @brief Waits for network registration. (Blocking call) + * @param waitForever if true the function does not return until a connection has been established * @return True if the network registration is successful, false otherwise. */ - bool awaitNetworkRegistration(); + bool awaitNetworkRegistration(bool waitForever); /** * @brief Gets the GPS location. (Blocking call) @@ -277,6 +302,8 @@ class ArduinoCellular { Stream* debugStream = nullptr; /**< The stream to be used for printing debugging messages. */ static unsigned long getTime(); /** Callback for getting the current time as an unix timestamp. */ + + static constexpr unsigned long waitForNetworkTimeout = 20000L; /**< Maximum wait time for network registration (In milliseconds). */ };