diff --git a/libraries/WiFiS3/examples/WiFiWebClient/WiFiWebClient.ino b/libraries/WiFiS3/examples/WiFiWebClient/WiFiWebClient.ino index 8f9dc053d..74d575902 100644 --- a/libraries/WiFiS3/examples/WiFiWebClient/WiFiWebClient.ino +++ b/libraries/WiFiS3/examples/WiFiWebClient/WiFiWebClient.ino @@ -26,12 +26,17 @@ #include "arduino_secrets.h" +#define MaximumConnections 1 + ///////please enter your sensitive data in the Secret tab/arduino_secrets.h char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) int keyIndex = 0; // your network key index number (needed only for WEP) +int connectionCount = 0; +bool clientConnected = false; int status = WL_IDLE_STATUS; + // if you don't want to use DNS (and reduce your sketch size) // use the numeric IP instead of the name for the server: //IPAddress server(74,125,232,128); // numeric IP for Google (no DNS) @@ -46,7 +51,7 @@ WiFiClient client; void setup() { /* -------------------------------------------------------------------------- */ //Initialize serial and wait for port to open: - Serial.begin(9600); + Serial.begin(115200); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } @@ -62,30 +67,19 @@ void setup() { if (fv < WIFI_FIRMWARE_LATEST_VERSION) { Serial.println("Please upgrade the firmware"); } - - // attempt to connect to WiFi network: - while (status != WL_CONNECTED) { - Serial.print("Attempting to connect to SSID: "); - Serial.println(ssid); - // Connect to WPA/WPA2 network. Change this line if using open or WEP network: - status = WiFi.begin(ssid, pass); - - // wait 10 seconds for connection: - delay(10000); - } - - printWifiStatus(); - - Serial.println("\nStarting connection to server..."); - // if you get a connection, report back via serial: - if (client.connect(server, 80)) { - Serial.println("connected to server"); - // Make a HTTP request: - client.println("GET /search?q=arduino HTTP/1.1"); - client.println("Host: www.google.com"); - client.println("Connection: close"); - client.println(); - } + + // 3 second wait for connection + client.setConnectionTimeout(3000); +} + +void connectToWifi() { + if (status != WL_IDLE_STATUS) + return; + + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid, pass); } /* just wrap the received data up to 80 columns in the serial print*/ @@ -109,16 +103,55 @@ void read_response() { /* -------------------------------------------------------------------------- */ void loop() { /* -------------------------------------------------------------------------- */ - read_response(); + // do some processing + Serial.println("loop processing"); + + // only allowed to connect n times + if (connectionCount >= MaximumConnections) { + delay(300); + return; + } - // if the server's disconnected, stop the client: - if (!client.connected()) { - Serial.println(); - Serial.println("disconnecting from server."); - client.stop(); + //connect and wait for connection to be made + connectToWifi(); + status = WiFi.isConnected(); - // do nothing forevermore: - while (true); + if (status == WL_CONNECTING) { + Serial.println("Connecting to wifi"); + delay(200); + } + + // If connected to Wifi then send a request to a server + if (status == WL_CONNECTED) { + Serial.println("Connected to WiFi"); + printWifiStatus(); + + Serial.println("\nStarting connection to server..."); + clientConnected = client.connect(server, 80); + + if (clientConnected) { + connectionCount++; + + // if you get a connection, report back via serial: + Serial.println("connected to server"); + // Make a HTTP request: + client.println("GET /search?q=arduino HTTP/1.1"); + client.println("Host: www.google.com"); + client.println("Connection: close"); + client.println(); + + Serial.println("Reading response"); + read_response(); + + if (clientConnected) { + // if the server's disconnected, stop the client: + if (!client.connected()) { + Serial.println(); + Serial.println("disconnecting from server."); + client.stop(); + } + } + } } } diff --git a/libraries/WiFiS3/examples/WiFiWebClientSSL/WiFiWebClientSSL.ino b/libraries/WiFiS3/examples/WiFiWebClientSSL/WiFiWebClientSSL.ino index ee7afc531..8efa99b7b 100644 --- a/libraries/WiFiS3/examples/WiFiWebClientSSL/WiFiWebClientSSL.ino +++ b/libraries/WiFiS3/examples/WiFiWebClientSSL/WiFiWebClientSSL.ino @@ -14,11 +14,17 @@ #include "arduino_secrets.h" +#define MaximumConnections 1 + ///////please enter your sensitive data in the Secret tab/arduino_secrets.h char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) + +int connectionCount = 0; +bool clientConnected = false; int status = WL_IDLE_STATUS; + // if you don't want to use DNS (and reduce your sketch size) // use the numeric IP instead of the name for the server: //IPAddress server(74,125,232,128); // numeric IP for Google (no DNS) @@ -50,30 +56,18 @@ void setup() { Serial.println("Please upgrade the firmware"); } - // attempt to connect to WiFi network: - while (status != WL_CONNECTED) { - Serial.print("Attempting to connect to SSID: "); - Serial.println(ssid); - // Connect to WPA/WPA2 network. - status = WiFi.begin(ssid, pass); - - // wait 10 seconds for connection: - delay(10000); - } - - printWifiStatus(); + // 3 second wait for connection + modem.readTimeout(3000); +} - Serial.println("\nStarting connection to server..."); - // if you get a connection, report back via serial: +void connectToWifi() { + if (status != WL_IDLE_STATUS) + return; - if (client.connect(server, 443)) { - Serial.println("connected to server"); - // Make a HTTP request: - client.println("GET / HTTP/1.1"); - client.println("Host: www.google.com"); - client.println("Connection: close"); - client.println(); - } + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid, pass); } /* just wrap the received data up to 80 columns in the serial print*/ @@ -97,16 +91,55 @@ void read_response() { /* -------------------------------------------------------------------------- */ void loop() { /* -------------------------------------------------------------------------- */ - read_response(); + // do some processing + Serial.println("loop processing"); + + // only allowed to connect n times + if (connectionCount >= MaximumConnections) { + delay(300); + return; + } - // if the server's disconnected, stop the client: - if (!client.connected()) { - Serial.println(); - Serial.println("disconnecting from server."); - client.stop(); + //connect and wait for connection to be made + connectToWifi(); + status = WiFi.isConnected(); - // do nothing forevermore: - while (true); + if (status == WL_CONNECTING) { + Serial.println("Connecting to wifi"); + delay(200); + } + + // If connected to Wifi then send a request to a server + if (status == WL_CONNECTED) { + Serial.println("Connected to WiFi"); + printWifiStatus(); + + Serial.println("\nStarting connection to server..."); + clientConnected = client.connect(server, 80); + + if (clientConnected) { + connectionCount++; + + // if you get a connection, report back via serial: + Serial.println("connected to server"); + // Make a HTTP request: + client.println("GET /search?q=arduino HTTP/1.1"); + client.println("Host: www.google.com"); + client.println("Connection: close"); + client.println(); + + Serial.println("Reading response"); + read_response(); + + if (clientConnected) { + // if the server's disconnected, stop the client: + if (!client.connected()) { + Serial.println(); + Serial.println("disconnecting from server."); + client.stop(); + } + } + } } } diff --git a/libraries/WiFiS3/src/Modem.cpp b/libraries/WiFiS3/src/Modem.cpp index 44303d9a3..caa7cd546 100644 --- a/libraries/WiFiS3/src/Modem.cpp +++ b/libraries/WiFiS3/src/Modem.cpp @@ -36,12 +36,14 @@ void ModemClass::begin(int badurate, int retry){ _serial->begin(badurate); string res = ""; _serial->flush(); + + unsigned long modemTimeout = _timeout; modem.timeout(500); while(!beginned && retry > 0) { beginned = modem.write(string(PROMPT(_SOFTRESETWIFI)),res, "%s" , CMD(_SOFTRESETWIFI)); retry -= 1; } - modem.timeout(MODEM_TIMEOUT); + modem.timeout(modemTimeout); } } @@ -186,7 +188,7 @@ ModemClass::ParseResult ModemClass::buf_read(const string &prompt, string &data_ unsigned long start_time = millis(); while(state != at_parse_state_t::Completed) { - if(millis() - start_time > _timeout) { + if(millis() - start_time > _readTimeout) { res = Timeout; break; } @@ -293,15 +295,15 @@ ModemClass::ParseResult ModemClass::buf_read(const string &prompt, string &data_ * in data_res contains the length of the next token */ - if(c == '|') { // sized read, the previous parameter is the length - sized_read_size = atoi(data_res.c_str()); - data_res.clear(); - if (sized_read_size != 0) { - state = at_parse_state_t::Sized; - } else { - state = at_parse_state_t::Res; - } - } else if(c == '\r') { + if(c == '|') { // sized read, the previous parameter is the length + sized_read_size = atoi(data_res.c_str()); + data_res.clear(); + if (sized_read_size != 0) { + state = at_parse_state_t::Sized; + } else { + state = at_parse_state_t::Res; + } + } else if(c == '\r') { state = at_parse_state_t::ResWaitLF; } else if(c == '\n') { state = at_parse_state_t::Res; diff --git a/libraries/WiFiS3/src/Modem.h b/libraries/WiFiS3/src/Modem.h index 566146de1..ad7d46f4a 100644 --- a/libraries/WiFiS3/src/Modem.h +++ b/libraries/WiFiS3/src/Modem.h @@ -17,89 +17,89 @@ /** * @brief A class that provides methods to interact with a modem. - * + * * This class is responsible for providing an interface to communicate with - * a modem through serial communication. It includes methods for initialization, + * a modem through serial communication. It includes methods for initialization, * sending and receiving data, and handling modem configurations. */ class ModemClass { public: - /** - * @brief Constructor for the ModemClass, which initializes the modem with the specified transmit (TX) and receive (RX) pins. - * - * @param Initializes an instance of the ModemClass class with - * specific transmit `tx` and receive `rx` pins for communication. - */ - ModemClass(int tx, int rx); - - /** - * @brief Constructor for the ModemClass, which initializes the modem with the specified UART interface. - * - * @param `_serial` is a pointer to the UART object that will be used for communication with the modem. - */ - ModemClass(UART * _serial); - - /** - * @brief Destructor for ModemClass. - */ - ~ModemClass(); - - - /** - * @brief Initializes the modem communication with a specified baud rate. - * - * @param[in] `badurate` sets the baud rate for the serial connection. - */ - void begin(int badurate = 115200, int retry = 3); - - /** - * @brief Ends the modem communication. - */ - void end(); - - - /** - * @brief Sends a formatted command string to a device and stores the response. - * - * This function formats a command string using the provided format and arguments, - * sends it to a device, and waits for a response, which is stored in the `str` string. - * - * @param `cmd` A string representing the command to be sent to the device. - * @param `str` A reference to a string that will hold the device's response. - * @param `fmt` A format string for constructing the command. - * - * @return `true` if the command was successfully sent and a response was received, - * `false` otherwise. - */ - bool write(const std::string &cmd, std::string &str, const char * fmt, ...); - - /** - * @brief Used to send a command to the modem without waiting for a response. - * - * @param It takes a command string `cmd`, a string `str` where the response will be stored, - * and a format string `fmt` along with additional arguments. - */ - void write_nowait(const std::string &cmd, std::string &str, const char * fmt, ...); - - /** - * @brief Sends binary data directly to the modem without any processing or interpretation. - * - * @param It takes a pointer to the binary `data` and the `size` of the data as arguments. - * Used for sending raw binary commands or data to the modem for operations that - * require direct communication without any additional formatting or parsing. - */ - bool passthrough(const uint8_t *data, size_t size); - - /** - * @brief Disables automatic trimming of results for one operation. - * - * This function disables the automatic trimming of results for one operation. - * After it is called, the results will not be trimmed automatically until - * the function is called again. - */ - void avoid_trim_results() { - /* one shot - it works only 1 time the it is necessary to call again this + /** + * @brief Constructor for the ModemClass, which initializes the modem with the specified transmit (TX) and receive (RX) pins. + * + * @param Initializes an instance of the ModemClass class with + * specific transmit `tx` and receive `rx` pins for communication. + */ + ModemClass(int tx, int rx); + + /** + * @brief Constructor for the ModemClass, which initializes the modem with the specified UART interface. + * + * @param `_serial` is a pointer to the UART object that will be used for communication with the modem. + */ + ModemClass(UART * _serial); + + /** + * @brief Destructor for ModemClass. + */ + ~ModemClass(); + + + /** + * @brief Initializes the modem communication with a specified baud rate. + * + * @param[in] `badurate` sets the baud rate for the serial connection. + */ + void begin(int badurate = 115200, int retry = 3); + + /** + * @brief Ends the modem communication. + */ + void end(); + + + /** + * @brief Sends a formatted command string to a device and stores the response. + * + * This function formats a command string using the provided format and arguments, + * sends it to a device, and waits for a response, which is stored in the `str` string. + * + * @param `cmd` A string representing the command to be sent to the device. + * @param `str` A reference to a string that will hold the device's response. + * @param `fmt` A format string for constructing the command. + * + * @return `true` if the command was successfully sent and a response was received, + * `false` otherwise. + */ + bool write(const std::string &cmd, std::string &str, const char * fmt, ...); + + /** + * @brief Used to send a command to the modem without waiting for a response. + * + * @param It takes a command string `cmd`, a string `str` where the response will be stored, + * and a format string `fmt` along with additional arguments. + */ + void write_nowait(const std::string &cmd, std::string &str, const char * fmt, ...); + + /** + * @brief Sends binary data directly to the modem without any processing or interpretation. + * + * @param It takes a pointer to the binary `data` and the `size` of the data as arguments. + * Used for sending raw binary commands or data to the modem for operations that + * require direct communication without any additional formatting or parsing. + */ + bool passthrough(const uint8_t *data, size_t size); + + /** + * @brief Disables automatic trimming of results for one operation. + * + * This function disables the automatic trimming of results for one operation. + * After it is called, the results will not be trimmed automatically until + * the function is called again. + */ + void avoid_trim_results() { + /* one shot - it works only 1 time the it is necessary to call again this funtion */ trim_results = false; } @@ -109,9 +109,9 @@ class ModemClass { * to be read is considered for processing. */ void read_using_size() { - // read_by_size = true; // deprecated + // read_by_size = true; // deprecated } - + bool beginned; /* Calling this function with no argument will enable debug message to be printed @@ -143,11 +143,32 @@ class ModemClass { /** * @brief Sets the timeout value for communication operations. - * + * * @param Can be called with a specified timeout value in milliseconds. */ void timeout(size_t timeout_ms) {_timeout = timeout_ms;} + /** + * @brief Gets the timeout value for communication operations. + * + * @return Can be called to get the specified timeout value in milliseconds. + */ + unsigned long getTimeout() { return _timeout; } + + /** + * @brief Sets the timeout value for reading communication operations. + * + * @param Can be called with a specified read timeout value in milliseconds. + */ + void readTimeout(size_t timeout_ms) {_readTimeout = timeout_ms;} + + /** + * @brief Gets the timeout value for reading communication operations. + * + * @return Can be called to get the specified read timeout value in milliseconds. + */ + unsigned long getReadTimeout() { return _readTimeout; } + private: enum ParseResult { Ok, @@ -160,6 +181,7 @@ class ModemClass { bool delete_serial; UART * _serial; unsigned long _timeout; + unsigned long _readTimeout = MODEM_TIMEOUT; uint8_t tx_buff[MAX_BUFF_SIZE]; bool trim_results; Stream * _serial_debug; diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index 35fa33d68..80bef472f 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -59,13 +59,22 @@ int CWifi::begin(const char* ssid, const char *passphrase) { } } - unsigned long start_time = millis(); - while(millis() - start_time < _timeout){ - if(status() == WL_CONNECTED) { - return WL_CONNECTED; - } - } - return WL_CONNECT_FAILED; + _start_connection_time = millis(); + return WL_CONNECTING; +} + + +int CWifi::isConnected() +{ + if (status() == WL_CONNECTED) + return WL_CONNECTED; + + if (millis() - _start_connection_time < _timeout) + { + return WL_CONNECTING; + } + + return WL_CONNECT_FAILED; } /* passphrase is needed so a default one will be set */ diff --git a/libraries/WiFiS3/src/WiFi.h b/libraries/WiFiS3/src/WiFi.h index eb7f5940f..89dc3c6bc 100644 --- a/libraries/WiFiS3/src/WiFi.h +++ b/libraries/WiFiS3/src/WiFi.h @@ -63,6 +63,7 @@ class CWifi { void _config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2); void _sortAPlist(uint8_t num); unsigned long _timeout; + unsigned long _start_connection_time; CAccessPoint access_points[WIFI_MAX_SSID_COUNT]; uint8_t _apsFound = 0; std::string ssid; @@ -453,7 +454,12 @@ class CWifi { */ void setTimeout(unsigned long timeout); - + /* + * @brief Retrieves the connected state + * + * @return Current connection state of WL_CONNECT_FAILED, WL_CONNECTED or WL_CONNECTING + */ + int isConnected(); }; /** diff --git a/libraries/WiFiS3/src/WiFiClient.h b/libraries/WiFiS3/src/WiFiClient.h index 32803a746..8bbfef1e2 100644 --- a/libraries/WiFiS3/src/WiFiClient.h +++ b/libraries/WiFiS3/src/WiFiClient.h @@ -229,7 +229,16 @@ class WiFiClient : public Client { void setConnectionTimeout(int timeout) { _connectionTimeout = timeout; } - + + /** + * @brief Retrieves the connection timeout period + * + * @return Returns the connection timeout in milliseconds + */ + int getConnectionTimeout() { + return _connectionTimeout; + } + /** * @brief Declares WiFiServer as a friend class. * diff --git a/libraries/WiFiS3/src/WiFiTypes.h b/libraries/WiFiS3/src/WiFiTypes.h index 8bd0b8d08..556fc09f3 100644 --- a/libraries/WiFiS3/src/WiFiTypes.h +++ b/libraries/WiFiS3/src/WiFiTypes.h @@ -24,7 +24,9 @@ typedef enum { WL_DISCONNECTED, WL_AP_LISTENING, WL_AP_CONNECTED, - WL_AP_FAILED + WL_AP_FAILED, + WL_CONNECTING, + WL_DISCONNECTING } wl_status_t; /* Encryption modes */