From 8d3dfb860ee151820bcf64dd7cc8ef51782cfdf3 Mon Sep 17 00:00:00 2001 From: suwatchai Date: Fri, 5 Mar 2021 13:09:44 +0700 Subject: [PATCH] Fix memory leaks in url parsing utility function. --- README.md | 46 +- .../Access_Token_from_File.ino | 2 + .../Custom_Token_from_File.ino | 2 + .../AutomaticPlantWatering.ino | 10 +- .../Backup_and_Restore/Backup_and_Restore.ino | 11 +- .../Backup_and_Restore_Flash_Memory.ino | 6 +- .../Backup_and_Send_Email.ino | 3 +- .../RTDB/Basic_with_Cert/Basic_with_Cert.ino | 6 +- .../data/{cert.cer => cert.pem} | 0 .../MultiPath_Stream/MultiPath_Stream.ino | 8 + .../RTDB/Retry_and_Queue/Retry_and_Queue.ino | 2 + examples/RTDB/Stream/Stream.ino | 2 + .../RTDB/Stream_Callback/Stream_Callback.ino | 2 + .../Download_File/Download_File.ino | 2 +- .../Upload_Byte_Array_Memory.ino | 3 +- .../Upload_File/Upload_File.ino | 2 + .../Download_File/Download_File.ino | 2 +- .../Upload_File/Upload_File.ino | 2 +- library.json | 2 +- library.properties | 2 +- src/FirebaseFS.h | 27 +- src/Firebase_ESP_Client.cpp | 4 +- src/Firebase_ESP_Client.h | 4 +- src/README.md | 45 +- src/Utils.h | 29 +- src/common.h | 5 +- src/functions/FB_Functions.cpp | 4 +- src/gcs/GCS.cpp | 198 ++++--- src/gcs/GCS.h | 7 +- src/rtdb/FB_RTDB.cpp | 26 +- src/rtdb/FB_RTDB.h | 20 +- src/rtdb/QueueInfo.h | 4 +- src/session/FB_Session.cpp | 2 +- src/session/FB_Session.h | 2 +- src/signer/Signer.cpp | 19 +- src/storage/FCS.cpp | 6 +- src/storage/FCS.h | 4 +- src/wcs/HTTPCode.h | 2 + src/wcs/esp32/FB_HTTPClient32.cpp | 54 +- src/wcs/esp32/FB_HTTPClient32.h | 61 +- src/wcs/esp32/FB_WCS32.cpp | 370 ------------ src/wcs/esp32/FB_WCS32.h | 129 ----- src/wcs/esp32/fb_ssl_client32.cpp | 530 ------------------ src/wcs/esp32/fb_ssl_client32.h | 51 -- src/wcs/esp8266/FB_HTTPClient.cpp | 8 +- src/wcs/esp8266/FB_HTTPClient.h | 44 +- 46 files changed, 372 insertions(+), 1398 deletions(-) rename examples/RTDB/Basic_with_Cert/data/{cert.cer => cert.pem} (100%) delete mode 100644 src/wcs/esp32/FB_WCS32.cpp delete mode 100644 src/wcs/esp32/FB_WCS32.h delete mode 100644 src/wcs/esp32/fb_ssl_client32.cpp delete mode 100644 src/wcs/esp32/fb_ssl_client32.h diff --git a/README.md b/README.md index 362f3a1fe..3efae1a78 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Firebase Arduino Client Library for ESP8266 and ESP32 -Google's Firebase Arduino Client Library for ESP8266 and ESP32 v 2.0.3 +Google's Firebase Arduino Client Library for ESP8266 and ESP32 v 2.0.4 This library supports ESP8266 and ESP32 MCU from Espressif. The following are platforms in which the libraries are also available (RTDB only). @@ -18,7 +18,7 @@ This library supports ESP8266 and ESP32 MCU from Espressif. The following are pl * NodeMCU (ESP8266) * ESP-12F * LinkNode (ESP8266) -* Sparkfun ESP32 Thing + * Sparkfun ESP32 Thing * NodeMCU-32 * WEMOS LOLIN32 * TTGO T8 V1.8 @@ -337,12 +337,8 @@ The server's **Timestamp** can be stored in the database through `Firebase.RTDB. The returned **Timestamp** value can get from `fbdo.intData()`. +The file systems for flash and sd memory can be changed in [**FirebaseFS.h**](/src/FirebaseFS.h). -To use LittleFS file system for flash memory instead of SPIFFS (for ESP8266 at this time), add the following macro in **FirebaseFS.h** - -```C++ -#define USE_LITTLEFS -``` The following example showed how to store file data to flash memory at node "/test/file_data". @@ -352,7 +348,7 @@ The following example showed how to store file data to flash memory at node "/te if (Firebase.RTDB.getFile(&fbdo, mem_storage_type_flash, "/test/file_data", "/test.txt")) { - //To use LittleFS file system, add #define USE_LITTLEFS in FirebaseFS.h + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. File file = FLASH_FS.open("/test.txt", "r"); while (file.available()) @@ -732,13 +728,9 @@ if (fbdo.streamAvailable()) This library allows you to backup and restores the database at the defined path. -The backup file will store in SD card or flash memory (SPIFFS or LittleFS file systems). +The backup file will store in SD/SDMMC card or flash memory. -To use LittleFS file system for flash memory instead of SPIFFS (for ESP8266 only at this time), add the following macro in **FirebaseFS.h** - -```C++ -#define USE_LITTLEFS -``` +The file systems for flash and sd memory can be changed in [**FirebaseFS.h**](/src/FirebaseFS.h). Due to SD library used, only 8.3 DOS format file name supported. @@ -907,13 +899,9 @@ Serial.println(); ``` -Error Queues can be saved as a file in SD card or flash memory with function `saveErrorQueue`. - -To use LittleFS file system for flash memory instead of SPIFFS, add the following macro in **FirebaseFS.h** +Error Queues can be saved as a file in SD/SDMMC card or flash memory with function `saveErrorQueue`. -```C++ -#define USE_LITTLEFS -``` +The file systems for flash and sd memory can be changed in [**FirebaseFS.h**](/src/FirebaseFS.h). Error Queues store as a file can be restored to Error Queue collection with function `restoreErrorQueue`. @@ -1189,7 +1177,7 @@ String jsonStr; json.toString(jsonStr, true); Serial.println(jsonStr); -/* +/** This is the result of the above code { @@ -1215,7 +1203,7 @@ json.set("temp1/[7]", 25); //null will be created at array index 6 json.toString(jsonStr, true); Serial.println(jsonStr); -/* +/** The result of the above code { @@ -1248,7 +1236,7 @@ json.remove("temp2"); json.toString(jsonStr, true); Serial.println(jsonStr); -/* +/** The result of the above code { @@ -1288,7 +1276,7 @@ if (jsonData.success) } //The above code will show -/* +/** string Celcius */ @@ -1318,7 +1306,7 @@ for (size_t i = 0; i < myArr.size(); i++) Serial.println(jsonData.stringValue); } -/* +/** The result of above code Array index: 0, type: int, value: 47 Array index: 1, type: int, value: 34 @@ -1359,7 +1347,7 @@ String arrStr; arr.toString(arrStr, true); Serial.println(arrStr); -/* +/** This is the result of the above code [ @@ -1389,7 +1377,7 @@ arr.remove("[4]/[0]/[1]/amount"); arr.toString(arrStr, true); Serial.println(arrStr); -/* +/** The result of the above code [ @@ -1430,7 +1418,7 @@ if(jsonData.success) } //The above code will show -/* +/** string salad */ @@ -1471,7 +1459,7 @@ for (size_t i = 0; i < len; i++) myJson.iteratorEnd(); -/* +/** The result of the above code 0, Type: object, Key: food, Value: salad diff --git a/examples/Authentications/Access_Token_from_File/Access_Token_from_File.ino b/examples/Authentications/Access_Token_from_File/Access_Token_from_File.ino index a885c2077..3377553b6 100644 --- a/examples/Authentications/Access_Token_from_File/Access_Token_from_File.ino +++ b/examples/Authentications/Access_Token_from_File/Access_Token_from_File.ino @@ -77,6 +77,8 @@ void setup() /* Assign the project host (required) */ config.host = FIREBASE_HOST; + /* The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. */ + /* Assign the sevice account JSON file and the file storage type (required) */ config.service_account.json.path = "/service_account_file.json"; //change this for your json file config.service_account.json.storage_type = mem_storage_type_flash; diff --git a/examples/Authentications/Custom_Token_from_File/Custom_Token_from_File.ino b/examples/Authentications/Custom_Token_from_File/Custom_Token_from_File.ino index 9072503a1..d01b69d32 100644 --- a/examples/Authentications/Custom_Token_from_File/Custom_Token_from_File.ino +++ b/examples/Authentications/Custom_Token_from_File/Custom_Token_from_File.ino @@ -110,6 +110,8 @@ void setup() config.host = FIREBASE_HOST; config.api_key = API_KEY; + /* The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. */ + /* Assign the sevice account JSON file and the file storage type (required) */ config.service_account.json.path = "/service_account_file.json"; //change this for your json file config.service_account.json.storage_type = mem_storage_type_flash; //or mem_storage_type_sd diff --git a/examples/RTDB/AutomaticPlantWatering/AutomaticPlantWatering.ino b/examples/RTDB/AutomaticPlantWatering/AutomaticPlantWatering.ino index 4cd44eedd..1396a56e4 100644 --- a/examples/RTDB/AutomaticPlantWatering/AutomaticPlantWatering.ino +++ b/examples/RTDB/AutomaticPlantWatering/AutomaticPlantWatering.ino @@ -135,8 +135,10 @@ void setup() Firebase.reconnectWiFi(true); +#ifdef ESP8266 //Set the size of WiFi rx/tx buffers in the case where we want to work with large data. - fbdo2.setBSSLBufferSize(1024, 1024); + fbdo.setBSSLBufferSize(1024, 1024); +#endif //Set the size of HTTP response buffers in the case where we want to work with large data. fbdo2.setResponseSize(1024); @@ -359,7 +361,7 @@ void setClock(float time_zone, float daylight_offset_in_sec) if (timeReady) Firebase.RTDB.set(&fbdo2, Path.c_str(), "idle"); else - Firebase.RTDB.set(&fbdo2,Path.c_str(), "cannot get time"); + Firebase.RTDB.set(&fbdo2, Path.c_str(), "cannot get time"); } void addPump(String id, String name, String location, int gpio, int state, FirebaseJsonArray *pumpConfig) @@ -471,10 +473,10 @@ void runSchedule() scheduleInfo[i].state = 2; Path = path + "/control/" + pumpInfo[index].id; - Firebase.RTDB.set(&fbdo2,Path.c_str(), scheduleInfo[i].active); + Firebase.RTDB.set(&fbdo2, Path.c_str(), scheduleInfo[i].active); setPumpState(index, scheduleInfo[i].active); Path = path + "/status/terminal"; - Firebase.RTDB.set(&fbdo2,Path.c_str(), status); + Firebase.RTDB.set(&fbdo2, Path.c_str(), status); } } } diff --git a/examples/RTDB/Backup_and_Restore/Backup_and_Restore.ino b/examples/RTDB/Backup_and_Restore/Backup_and_Restore.ino index 842a150f9..afbff51de 100644 --- a/examples/RTDB/Backup_and_Restore/Backup_and_Restore.ino +++ b/examples/RTDB/Backup_and_Restore/Backup_and_Restore.ino @@ -64,8 +64,10 @@ void setup() Firebase.begin(&config, &auth); Firebase.reconnectWiFi(true); +#ifdef ESP8266 //Set the size of WiFi rx/tx buffers in the case where we want to work with large data. fbdo.setBSSLBufferSize(1024, 1024); +#endif //Set the size of HTTP response buffers in the case where we want to work with large data. fbdo.setResponseSize(1024); @@ -81,7 +83,7 @@ void setup() { Serial.println("FAILED"); Serial.println("REASON: " + fbdo.fileTransferError()); - Serial.println("------------------------------------"); + Serial.println("------------------------------------"); Serial.println(); } else @@ -89,7 +91,7 @@ void setup() Serial.println("PASSED"); Serial.println("BACKUP FILE: " + fbdo.getBackupFilename()); Serial.println("FILE SIZE: " + String(fbdo.getBackupFileSize())); - Serial.println("------------------------------------"); + Serial.println("------------------------------------"); Serial.println(); } @@ -100,18 +102,19 @@ void setup() //{TARGET_NODE_PATH} is the full path of database to restore //{FILE_NAME} is file name in 8.3 DOS format (max. 8 bytes file name and 3 bytes file extension) + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. if (!Firebase.RTDB.restore(&fbdo, mem_storage_type_sd, "/{TARGET_NODE_PATH}", "/{FILE_NAME}")) { Serial.println("FAILED"); Serial.println("REASON: " + fbdo.fileTransferError()); - Serial.println("------------------------------------"); + Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("PASSED"); Serial.println("BACKUP FILE: " + fbdo.getBackupFilename()); - Serial.println("------------------------------------"); + Serial.println("------------------------------------"); Serial.println(); } } diff --git a/examples/RTDB/Backup_and_Restore_Flash_Memory/Backup_and_Restore_Flash_Memory.ino b/examples/RTDB/Backup_and_Restore_Flash_Memory/Backup_and_Restore_Flash_Memory.ino index 4dce42b05..576b0e24a 100644 --- a/examples/RTDB/Backup_and_Restore_Flash_Memory/Backup_and_Restore_Flash_Memory.ino +++ b/examples/RTDB/Backup_and_Restore_Flash_Memory/Backup_and_Restore_Flash_Memory.ino @@ -63,8 +63,10 @@ void setup() Firebase.begin(&config, &auth); Firebase.reconnectWiFi(true); +#ifdef ESP8266 //Set the size of WiFi rx/tx buffers in the case where we want to work with large data. fbdo.setBSSLBufferSize(1024, 1024); +#endif //Set the size of HTTP response buffers in the case where we want to work with large data. fbdo.setResponseSize(1024); @@ -75,7 +77,7 @@ void setup() //Download and save data to Flash memory. //{TARGET_NODE_PATH} is the full path of database to backup and restore. //{FILE_NAME} is file name included path to save to Flash meory - + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. if (!Firebase.RTDB.backup(&fbdo, mem_storage_type_flash, "/{TARGET_NODE_PATH}", "/{FILE_NAME}")) { Serial.println("FAILED"); @@ -98,7 +100,7 @@ void setup() //Restore data to defined database path using backup file on Flash memory. //{TARGET_NODE_PATH} is the full path of database to restore //{FILE_NAME} is file name included path of backed up file. - + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. if (!Firebase.RTDB.restore(&fbdo, mem_storage_type_flash, "/{TARGET_NODE_PATH}", "/{FILE_NAME}")) { Serial.println("FAILED"); diff --git a/examples/RTDB/Backup_and_Send_Email/Backup_and_Send_Email.ino b/examples/RTDB/Backup_and_Send_Email/Backup_and_Send_Email.ino index 4714d6fb0..050cf440f 100644 --- a/examples/RTDB/Backup_and_Send_Email/Backup_and_Send_Email.ino +++ b/examples/RTDB/Backup_and_Send_Email/Backup_and_Send_Email.ino @@ -96,7 +96,8 @@ void setup() Serial.println("------------------------------------"); Serial.println("Backup test..."); - + + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. if (!Firebase.RTDB.backup(&fbdo, mem_storage_type_flash, "/PATH_TO_THE_NODE", "/PATH_TO_SAVE_FILE")) { Serial.println("FAILED"); diff --git a/examples/RTDB/Basic_with_Cert/Basic_with_Cert.ino b/examples/RTDB/Basic_with_Cert/Basic_with_Cert.ino index 39ca72753..dfbc1056c 100644 --- a/examples/RTDB/Basic_with_Cert/Basic_with_Cert.ino +++ b/examples/RTDB/Basic_with_Cert/Basic_with_Cert.ino @@ -89,12 +89,14 @@ void setup() /** * In case using flash mem to keep the certificate files - * Upload the certificate files cert.cer and cert.der to flash memory. + * Upload the certificate files cert.pem and cert.der to flash memory. * Use the following lines to set the certificate file. * * config.cert.file = "/cert.der"; or - * config.cert.file = "/cert.cer"; + * config.cert.file = "/cert.pem"; * config.cert.file_storage = mem_storage_type_flash; //or mem_storage_type_sd + * + * The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. */ /* In case the certificate data was used */ diff --git a/examples/RTDB/Basic_with_Cert/data/cert.cer b/examples/RTDB/Basic_with_Cert/data/cert.pem similarity index 100% rename from examples/RTDB/Basic_with_Cert/data/cert.cer rename to examples/RTDB/Basic_with_Cert/data/cert.pem diff --git a/examples/RTDB/MultiPath_Stream/MultiPath_Stream.ino b/examples/RTDB/MultiPath_Stream/MultiPath_Stream.ino index 9a87420ab..58a542e9b 100644 --- a/examples/RTDB/MultiPath_Stream/MultiPath_Stream.ino +++ b/examples/RTDB/MultiPath_Stream/MultiPath_Stream.ino @@ -117,6 +117,14 @@ void setup() //Set the size of HTTP response buffers in the case where we want to work with large data. fbdo2.setResponseSize(1024); + //The data under the node being stream (parent path) should keep small + //Large stream payload leads to the parsing error due to memory allocation. + + //The operations is the same as normal stream unless the JSON stream payload will be parsed + //with the predefined node path (child paths). + + //The changes occurred in any child node that is not in the child paths array will sent to the + //client as usual. if (!Firebase.RTDB.beginMultiPathStream(&fbdo1, parentPath.c_str(), childPath, childPathSize)) { Serial.println("------------------------------------"); diff --git a/examples/RTDB/Retry_and_Queue/Retry_and_Queue.ino b/examples/RTDB/Retry_and_Queue/Retry_and_Queue.ino index 459611c1f..de7c35792 100644 --- a/examples/RTDB/Retry_and_Queue/Retry_and_Queue.ino +++ b/examples/RTDB/Retry_and_Queue/Retry_and_Queue.ino @@ -111,6 +111,7 @@ void setup() fbdo.setResponseSize(1024); //Open and retore Firebase Error Queues from file. + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. if (Firebase.RTDB.errorQueueCount(&fbdo, "/test.txt", mem_storage_type_flash) > 0) { Firebase.RTDB.restoreErrorQueue(&fbdo, "/test.txt", mem_storage_type_flash); @@ -285,6 +286,7 @@ void setup() Serial.println(); //Save Error Queues to file + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. Firebase.RTDB.saveErrorQueue(&fbdo, "/test.txt", mem_storage_type_flash); } diff --git a/examples/RTDB/Stream/Stream.ino b/examples/RTDB/Stream/Stream.ino index d5ea934ad..86e53a60a 100644 --- a/examples/RTDB/Stream/Stream.ino +++ b/examples/RTDB/Stream/Stream.ino @@ -78,6 +78,8 @@ void setup() //Set the size of HTTP response buffers in the case where we want to work with large data. fbdo.setResponseSize(1024); + //The data under the node being stream (parent path) should keep small + //Large stream payload leads to the parsing error due to memory allocation. if (!Firebase.RTDB.beginStream(&fbdo, path.c_str())) { Serial.println("------------------------------------"); diff --git a/examples/RTDB/Stream_Callback/Stream_Callback.ino b/examples/RTDB/Stream_Callback/Stream_Callback.ino index 031d11ba5..384fc7376 100644 --- a/examples/RTDB/Stream_Callback/Stream_Callback.ino +++ b/examples/RTDB/Stream_Callback/Stream_Callback.ino @@ -111,6 +111,8 @@ void setup() //Set the size of HTTP response buffers in the case where we want to work with large data. fbdo2.setResponseSize(1024); + //The data under the node being stream (parent path) should keep small + //Large stream payload leads to the parsing error due to memory allocation. if (!Firebase.RTDB.beginStream(&fbdo1, path.c_str())) { Serial.println("------------------------------------"); diff --git a/examples/Storage/Firebase_Storage/Download_File/Download_File.ino b/examples/Storage/Firebase_Storage/Download_File/Download_File.ino index df45a415c..f54c5baca 100644 --- a/examples/Storage/Firebase_Storage/Download_File/Download_File.ino +++ b/examples/Storage/Firebase_Storage/Download_File/Download_File.ino @@ -80,7 +80,7 @@ void setup() Serial.println("------------------------------------"); Serial.println("Download file test..."); - + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. if (Firebase.Storage.download(&fbdo, STORAGE_BUCKET_ID /* Firebase Storage bucket id */, "path/to/file/filename" /* path of remote file stored in the bucket */, "/path/to/save/filename" /* path to local file */, mem_storage_type_flash /* memory storage type, mem_storage_type_flash and mem_storage_type_sd */)) { Serial.println("PASSED"); diff --git a/examples/Storage/Firebase_Storage/Upload_Byte_Array_Memory/Upload_Byte_Array_Memory.ino b/examples/Storage/Firebase_Storage/Upload_Byte_Array_Memory/Upload_Byte_Array_Memory.ino index 36cb6f3a2..c2c69d56b 100644 --- a/examples/Storage/Firebase_Storage/Upload_Byte_Array_Memory/Upload_Byte_Array_Memory.ino +++ b/examples/Storage/Firebase_Storage/Upload_Byte_Array_Memory/Upload_Byte_Array_Memory.ino @@ -85,7 +85,8 @@ void setup() Serial.println("------------------------------------"); Serial.println("Upload byte array test..."); - + + //MIME type should be valid to avoid the download problem. if (Firebase.Storage.upload(&fbdo, STORAGE_BUCKET_ID /* Firebase Storage bucket id */, test_data /* byte array from ram or flash */, 256 /* size of data in bytes */, "test.dat" /* path of remote file stored in the bucket */, "application/octet-stream" /* mime type */)) { diff --git a/examples/Storage/Firebase_Storage/Upload_File/Upload_File.ino b/examples/Storage/Firebase_Storage/Upload_File/Upload_File.ino index 71b6fd062..903c89741 100644 --- a/examples/Storage/Firebase_Storage/Upload_File/Upload_File.ino +++ b/examples/Storage/Firebase_Storage/Upload_File/Upload_File.ino @@ -89,6 +89,8 @@ void setup() //Upload large file over fews hundreds KiB is not allowable in Firebase Storage by using this method. //To upload the large file, please use the Firebase.GCStorage.upload instead. //The following upload will be error 503 service unavailable (upload rejected due to the large file size) + //MIME type should be valid to avoid the download problem. + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. if (Firebase.Storage.upload(&fbdo, STORAGE_BUCKET_ID /* Firebase Storage bucket id */, "/media.mp4" /* path to local file */, mem_storage_type_flash /* memory storage type, mem_storage_type_flash and mem_storage_type_sd */, "media.mp4" /* path of remote file stored in the bucket */, "video/mp4" /* mime type */)) { diff --git a/examples/Storage/Google_Cloud_Storage/Download_File/Download_File.ino b/examples/Storage/Google_Cloud_Storage/Download_File/Download_File.ino index e96b59eeb..9f0f588df 100644 --- a/examples/Storage/Google_Cloud_Storage/Download_File/Download_File.ino +++ b/examples/Storage/Google_Cloud_Storage/Download_File/Download_File.ino @@ -82,7 +82,7 @@ void setup() //StorageGetOptions option; //For query parameters description of StorageGetOptions, see https://cloud.google.com/storage/docs/json_api/v1/objects/get#optional-parameters - + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. if (Firebase.GCStorage.download(&fbdo, STORAGE_BUCKET_ID /* Firebase or Google Cloud Storage bucket id */, "path/to/file/filename" /* path of remote file stored in the bucket */, "/path/to/save/filename" /* path to local file */, mem_storage_type_flash /* memory storage type, mem_storage_type_flash and mem_storage_type_sd */, nullptr /* StorageGetOptions data */)) { Serial.println("PASSED"); diff --git a/examples/Storage/Google_Cloud_Storage/Upload_File/Upload_File.ino b/examples/Storage/Google_Cloud_Storage/Upload_File/Upload_File.ino index a0a05bb71..1657ec823 100644 --- a/examples/Storage/Google_Cloud_Storage/Upload_File/Upload_File.ino +++ b/examples/Storage/Google_Cloud_Storage/Upload_File/Upload_File.ino @@ -102,7 +102,7 @@ void setup() //For query parameters description of UploadOptions, see https://cloud.google.com/storage/docs/json_api/v1/objects/insert#optional-parameters //For request payload properties description of Requestproperties, see https://cloud.google.com/storage/docs/json_api/v1/objects/insert#optional-properties - + //The file systems for flash and SD/SDMMC can be changed in FirebaseFS.h. Firebase.GCStorage.upload(&fbdo, STORAGE_BUCKET_ID /* Firebase or Google Cloud Storage bucket id */, "/media.mp4" /* path to local file */, mem_storage_type_flash /* memory storage type, mem_storage_type_flash and mem_storage_type_sd */, gcs_upload_type_resumable /* upload type */, "media.mp4" /* path of remote file stored in the bucket */, "video/mp4" /* mime type */, nullptr /* UploadOptions data */, nullptr /* Requestproperties data */, nullptr /* UploadStatusInfo data to get the status */, gcsUploadCallback /* callback function */); } diff --git a/library.json b/library.json index 437647ff7..8662d30be 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Firebase Arduino Client Library for ESP8266 and ESP32", - "version": "2.0.3", + "version": "2.0.4", "keywords": "communication, REST, esp32, esp8266, arduino", "description": "This client library provides the functions to work with Firebase Realtime database, Firestore, Storage and Cloud messaging.", "repository": { diff --git a/library.properties b/library.properties index d4f184ae5..90f3b3ec1 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=Firebase Arduino Client Library for ESP8266 and ESP32 -version=2.0.3 +version=2.0.4 author=Mobizt diff --git a/src/FirebaseFS.h b/src/FirebaseFS.h index c4e7f0a1a..33121661a 100644 --- a/src/FirebaseFS.h +++ b/src/FirebaseFS.h @@ -1,5 +1,28 @@ + /** - * To use LittleFS file system instead of SPIFFS, uncomment the following line + * To use other flash file systems + * + * LittleFS File system + * + * #include + * #define DEFAULT_FLASH_FS LittleFS //For ESP8266 LitteFS + * + * + * FFat File system + * + * #include + * #define DEFAULT_FLASH_FS FFat //For ESP32 FFat + * */ +#define DEFAULT_FLASH_FS SPIFFS -//#define USE_LITTLEFS +/** + * To use SD card file systems with different hardware interface + * e.g. SDMMC hardware bus on the ESP32 + * https://github.com/espressif/arduino-esp32/tree/master/libraries/SD#faq + * + * #include + * #define DEFAULT_SD_FS SD_MMC //For ESP32 SDMMC + * +*/ +#define DEFAULT_SD_FS SD \ No newline at end of file diff --git a/src/Firebase_ESP_Client.cpp b/src/Firebase_ESP_Client.cpp index 6f037095e..c77cd48cb 100644 --- a/src/Firebase_ESP_Client.cpp +++ b/src/Firebase_ESP_Client.cpp @@ -1,9 +1,9 @@ /** - * Google's Firebase ESP Client Main class, Firebase_ESP_Client.h version 2.0.3 + * Google's Firebase ESP Client Main class, Firebase_ESP_Client.h version 2.0.4 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 21, 2021 + * Created March 5, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) diff --git a/src/Firebase_ESP_Client.h b/src/Firebase_ESP_Client.h index 9f3215850..3e5066a3b 100644 --- a/src/Firebase_ESP_Client.h +++ b/src/Firebase_ESP_Client.h @@ -1,9 +1,9 @@ /** - * Google's Firebase ESP Client Main class, Firebase_ESP_Client.h version 2.0.3 + * Google's Firebase ESP Client Main class, Firebase_ESP_Client.h version 2.0.4 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 21, 2021 + * Created March 5, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) diff --git a/src/README.md b/src/README.md index a7331c085..1eaa9ff95 100644 --- a/src/README.md +++ b/src/README.md @@ -1,7 +1,14 @@ # Firebase Arduino Client Library for ESP8266 and ESP32 -Google's Firebase Arduino Client Library for ESP8266 and ESP32 v 2.0.3 +Google's Firebase Arduino Client Library for ESP8266 and ESP32 v 2.0.4 + + +The default filessystem used in the library is SPIFFS for flash and SD. + + +To use other flash file systems other than SPIFFS e.g. LittleFS file system, change the config in **FirebaseFS.h** + ## Global functions @@ -25,15 +32,6 @@ void begin(FirebaseConfig *config, FirebaseAuth *auth); -To use LittleFS file system for flash memory instead of SPIFFS (only for ESP8266 at this time), add the following macro in **FirebaseFS.h** - -For Auth_Provider data usage, see the examples. - -```cpp -#define USE_LITTLEFS -``` - - #### Provide the details of token generation. @@ -697,6 +695,8 @@ param **`fbdo`** The pointer to Firebase Data Object. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + param **`path`** The path to the node in which binary data will be appended. param **`fileName`** The file path includes its name. @@ -1458,6 +1458,8 @@ param **`fbdo`** The pointer to Firebase Data Object. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + param **`path`** The path to the node in which binary data will be set. param **`fileName`** The file path includes its name. @@ -1500,6 +1502,8 @@ param **`fbdo`** The pointer to Firebase Data Object. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + param **`path`** The path to the node in which binary data from the file will be set. param **`fileName`** The file path includes its name. @@ -2191,6 +2195,8 @@ param **`fbdo`** The pointer to Firebase Data Object. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + param **`nodePath`** The path to the node that file data will be downloaded. param **`fileName`** The file path includes its name. @@ -2438,6 +2444,8 @@ param **`fbdo`** The pointer to Firebase Data Object. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + param **`nodePath`** The path to the node to be backuped. param **`fileName`** File name to save. @@ -2466,6 +2474,8 @@ param **`fbdo`** The pointer to Firebase Data Object. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + param **`nodePath`** The path to the node to be restored the data. param **`fileName`** File name to read. @@ -2529,6 +2539,8 @@ param **`fbdo`** The pointer to Firebase Data Object. param **`filename`** Filename to be saved. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + +The file systems can be changed in FirebaseFS.h. ```cpp bool saveErrorQueue(FirebaseData *fbdo, const char *filename, fb_esp_mem_storage_type storageType); @@ -2545,6 +2557,8 @@ bool saveErrorQueue(FirebaseData *fbdo, const char *filename, fb_esp_mem_storage param **`filename`** File name to delete. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + +The file systems can be changed in FirebaseFS.h. ```cpp bool deleteStorageFile(const char *filename, fb_esp_mem_storage_type storageType); @@ -2569,6 +2583,8 @@ param **`fbdo`** The pointer to Firebase Data Object. param **`filename`** Filename to be read and restore queues. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + +The file systems can be changed in FirebaseFS.h. ```cpp bool restoreErrorQueue(FirebaseData *fbdo, const char *filename, fb_esp_mem_storage_type storageType); @@ -2587,6 +2603,7 @@ param **`filename`** Filename to be read and count for queues. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. return **`Number`** (0-255) of queues store in defined queue file. @@ -3328,6 +3345,8 @@ param **`localFileName`** The file path includes its name to upload. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + param **`remotetFileName`** The file path includes its name of uploaded file in data bucket. param **`mime`** The file MIME type @@ -3383,6 +3402,8 @@ param **`localFileName`** The file path includes its name to save. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + return **`Boolean`** value, indicates the success of the operation. ```cpp @@ -3468,6 +3489,8 @@ param **`localFileName`** The file path includes its name to upload. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + param **`uploadType`** The enum of type of upload methods e.g. gcs_upload_type_simple, gcs_upload_type_multipart, gcs_upload_type_resumable param **`remotetFileName`** The file path includes its name of uploaded file in data bucket. @@ -3523,6 +3546,8 @@ param **`localFileName`** The file path includes its name to save. param **`storageType`** The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. +The file systems can be changed in FirebaseFS.h. + param **`option`** Optional. The pointer to StorageGetOptions data that contains the get query parameters. For the query parameters options, see https://cloud.google.com/storage/docs/json_api/v1/objects/get#optional-parameters diff --git a/src/Utils.h b/src/Utils.h index 9d140fb7d..25a494a92 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -1,9 +1,9 @@ /** - * Google's Firebase Util class, Utils.h version 1.0.3 + * Google's Firebase Util class, Utils.h version 1.0.4 * * This library supports Espressif ESP8266 and ESP32 * - * Created February 17, 2021 + * Created March 5, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2021, 2021 K. Suwatchai (Mobizt) @@ -302,9 +302,9 @@ class UtilsClass } void getUrlInfo(const std::string url, struct fb_esp_url_info_t &info) { - char *host = newS(url.length()); - char *uri = newS(url.length()); - char *auth = newS(url.length()); + char *host = newS(url.length() + 5); + char *uri = newS(url.length() + 5); + char *auth = newS(url.length()+ 5); int p1 = 0; char *tmp = strP(fb_esp_pgm_str_441); @@ -347,6 +347,9 @@ class UtilsClass info.uri = uri; info.host= host; info.auth = auth; + delS(uri); + delS(host); + delS(auth); } int url_decode(const char *s, char *dec) @@ -869,7 +872,7 @@ class UtilsClass if (dir.length() > 0) { if (storageType == mem_storage_type_sd) - SD.mkdir(dir.substr(0, dir.length() - 1).c_str()); + SD_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); } count = 0; @@ -878,7 +881,7 @@ class UtilsClass if (count > 0) { if (storageType == mem_storage_type_sd) - SD.mkdir(dir.c_str()); + SD_FS.mkdir(dir.c_str()); } std::string().swap(dir); } @@ -891,7 +894,7 @@ class UtilsClass { config->_int.fb_sd_used = false; config->_int.fb_sd_rdy = false; - SD.end(); + SD_FS.end(); } } @@ -1057,7 +1060,7 @@ class UtilsClass if (storageType == mem_storage_type_flash) file = FLASH_FS.open(filePath.c_str(), "r"); else if (storageType == mem_storage_type_sd) - file = SD.open(filePath.c_str(), FILE_READ); + file = SD_FS.open(filePath.c_str(), FILE_READ); if (!file) return; @@ -1383,9 +1386,9 @@ class UtilsClass { std::string filepath = "/sdtest01.txt"; - SD.begin(SD_CS_PIN); + SD_FS.begin(SD_CS_PIN); - file = SD.open(filepath.c_str(), FILE_WRITE); + file = SD_FS.open(filepath.c_str(), FILE_WRITE); if (!file) return false; @@ -1397,7 +1400,7 @@ class UtilsClass file.close(); - file = SD.open(filepath.c_str()); + file = SD_FS.open(filepath.c_str()); if (!file) return false; @@ -1411,7 +1414,7 @@ class UtilsClass } file.close(); - SD.remove(filepath.c_str()); + SD_FS.remove(filepath.c_str()); std::string().swap(filepath); diff --git a/src/common.h b/src/common.h index 98425821d..cf8ef8f5a 100644 --- a/src/common.h +++ b/src/common.h @@ -33,12 +33,10 @@ #include #include #include -#include #include #include #if defined(ESP32) #include -#include #include "wcs/esp32/FB_HTTPClient32.h" #elif defined(ESP8266) #include @@ -1647,6 +1645,9 @@ static const char fb_esp_pgm_str_536[] PROGMEM = "structuredQuery"; static const char fb_esp_pgm_str_537[] PROGMEM = "transaction"; static const char fb_esp_pgm_str_538[] PROGMEM = "newTransaction"; static const char fb_esp_pgm_str_539[] PROGMEM = "readTime"; +static const char fb_esp_pgm_str_540[] PROGMEM = "upload timed out"; +static const char fb_esp_pgm_str_541[] PROGMEM = "upload data sent error"; + static const unsigned char fb_esp_base64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char fb_esp_boundary_table[] PROGMEM = "=_abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; diff --git a/src/functions/FB_Functions.cpp b/src/functions/FB_Functions.cpp index 36640f271..d5ef9b8fa 100644 --- a/src/functions/FB_Functions.cpp +++ b/src/functions/FB_Functions.cpp @@ -143,14 +143,14 @@ bool FB_Functions::createFunctionInt(FirebaseData *fbdo, const char *functionId, return false; } - if (!SD.exists(config->_uploadArchiveFile.c_str())) + if (!SD_FS.exists(config->_uploadArchiveFile.c_str())) { fbdo->_ss.http_code = FIREBASE_ERROR_ARCHIVE_NOT_FOUND; sendCallback(fbdo, fb_esp_functions_operation_status_error, fbdo->errorReason().c_str(), cb, info); return false; } - Signer.getCfg()->_int.fb_file = SD.open(config->_uploadArchiveFile.c_str(), FILE_READ); + Signer.getCfg()->_int.fb_file = SD_FS.open(config->_uploadArchiveFile.c_str(), FILE_READ); } else if (config->_uploadArchiveStorageType == mem_storage_type_flash) { diff --git a/src/gcs/GCS.cpp b/src/gcs/GCS.cpp index a3846d780..96c16273d 100644 --- a/src/gcs/GCS.cpp +++ b/src/gcs/GCS.cpp @@ -3,7 +3,7 @@ * * This library supports Espressif ESP8266 and ESP32 * - * Created February 21, 2021 + * Created March 5, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -226,7 +226,7 @@ void GG_CloudStorage::reportUpploadProgress(FirebaseData *fbdo, struct fb_esp_gc if ((p % 2 == 0) && (p <= 100)) { - if (req->reportState != -1) + if (req->reportState == 0 || (p == 0 && req->reportState == -1)) { fbdo->_ss.gcs.cbInfo.status = fb_esp_gcs_upload_status_upload; UploadStatusInfo in; @@ -235,8 +235,12 @@ void GG_CloudStorage::reportUpploadProgress(FirebaseData *fbdo, struct fb_esp_gc in.status = fb_esp_gcs_upload_status_upload; in.progress = p; sendCallback(fbdo, in, req->callback, req->statusInfo); + + if (p == 0 && req->reportState == -1) + req->reportState = 1; + else if (req->reportState == 0) + req->reportState = -1; } - req->reportState = -1; } else req->reportState = 0; @@ -261,7 +265,7 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ fbdo->_ss.http_code = FIREBASE_ERROR_FILE_IO_ERROR; return false; } - Signer.getCfg()->_int.fb_file = SD.open(req->localFileName.c_str(), FILE_WRITE); + Signer.getCfg()->_int.fb_file = SD_FS.open(req->localFileName.c_str(), FILE_WRITE); } else if (req->storageType == mem_storage_type_flash) { @@ -288,13 +292,13 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ return false; } - if (!SD.exists(req->localFileName.c_str())) + if (!SD_FS.exists(req->localFileName.c_str())) { fbdo->_ss.http_code = FIREBASE_ERROR_FILE_IO_ERROR; return false; } - Signer.getCfg()->_int.fb_file = SD.open(req->localFileName.c_str(), FILE_READ); + Signer.getCfg()->_int.fb_file = SD_FS.open(req->localFileName.c_str(), FILE_READ); } else if (req->storageType == mem_storage_type_flash) { @@ -620,8 +624,7 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ fbdo->_ss.connected = true; if (req->requestType == fb_esp_gcs_request_type_upload_simple || req->requestType == fb_esp_gcs_request_type_upload_multipart) { - - reportUpploadProgress(fbdo, req, 0); + fbdo->_ss.long_running_task++; if (req->requestType == fb_esp_gcs_request_type_upload_multipart) { @@ -635,9 +638,9 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ int bufLen = 2048; uint8_t *buf = new uint8_t[bufLen + 1]; size_t read = 0; + while (available) { - delay(0); if (available > bufLen) available = bufLen; read = Signer.getCfg()->_int.fb_file.read(buf, available); @@ -645,13 +648,15 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ reportUpploadProgress(fbdo, req, byteRead); if (fbdo->httpClient.stream()->write(buf, read) != read) { - fbdo->_ss.connected = false; + fbdo->_ss.http_code = FIREBASE_ERROR_UPLOAD_DATA_ERRROR; + fbdo->closeSession(); break; } available = Signer.getCfg()->_int.fb_file.available(); } delete[] buf; + fbdo->_ss.long_running_task--; Signer.getCfg()->_int.fb_file.close(); @@ -668,10 +673,10 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ { size_t byteRead = 0; int available = 0; + int bufLen = 2048; uint8_t *buf = new uint8_t[bufLen + 1]; size_t read = 0; - size_t totalBytes = req->fileSize; if (req->chunkRange != -1 || req->location.length() > 0) { @@ -691,10 +696,10 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ read = Signer.getCfg()->_int.fb_file.read(buf, available); if (fbdo->httpClient.stream()->write(buf, read) != read) { - fbdo->_ss.connected = false; + fbdo->_ss.http_code = FIREBASE_ERROR_UPLOAD_DATA_ERRROR; + fbdo->closeSession(); break; } - byteRead += read; reportUpploadProgress(fbdo, req, byteRead); available = Signer.getCfg()->_int.fb_file.available(); @@ -736,6 +741,8 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ in.status = fb_esp_gcs_upload_status_complete; in.progress = 100; sendCallback(fbdo, in, req->callback, req->statusInfo); + fbdo->_ss.long_running_task -= _resumableUploadTasks.size(); + _resumableUploadTasks.clear(); } } return ret; @@ -751,6 +758,8 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ in.status = fb_esp_gcs_upload_status_error; in.errorMsg = fbdo->errorReason().c_str(); sendCallback(fbdo, in, req->callback, req->statusInfo); + fbdo->_ss.long_running_task -= _resumableUploadTasks.size(); + _resumableUploadTasks.clear(); } if (Signer.getCfg()->_int.fb_file && req->requestType == fb_esp_gcs_request_type_download) @@ -763,11 +772,11 @@ bool GG_CloudStorage::gcs_sendRequest(FirebaseData *fbdo, struct fb_esp_gcs_req_ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &header, bool hasParams) { + char *tmp = nullptr; if (req->getOptions) { if (strlen(req->getOptions->generation) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -780,9 +789,11 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_493); header += tmp; ut->delS(tmp); + int n = atoi(req->getOptions->generation); tmp = ut->intStr(n); header += tmp; @@ -790,7 +801,6 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h } if (strlen(req->getOptions->ifGenerationMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -803,9 +813,11 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_494); header += tmp; ut->delS(tmp); + int n = atoi(req->getOptions->ifGenerationMatch); tmp = ut->intStr(n); header += tmp; @@ -814,7 +826,6 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h if (strlen(req->getOptions->ifGenerationNotMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -827,9 +838,11 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_495); header += tmp; ut->delS(tmp); + int n = atoi(req->getOptions->ifGenerationNotMatch); tmp = ut->intStr(n); header += tmp; @@ -838,7 +851,6 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h if (strlen(req->getOptions->ifMetagenerationMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -851,9 +863,11 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_496); header += tmp; ut->delS(tmp); + int n = atoi(req->getOptions->ifMetagenerationMatch); tmp = ut->intStr(n); header += tmp; @@ -862,7 +876,6 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h if (strlen(req->getOptions->ifMetagenerationNotMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -875,9 +888,11 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_497); header += tmp; ut->delS(tmp); + int n = atoi(req->getOptions->ifMetagenerationNotMatch); tmp = ut->intStr(n); header += tmp; @@ -886,7 +901,6 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h if (strlen(req->getOptions->projection) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -899,8 +913,10 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_498); header += tmp; + ut->delS(tmp); header += req->getOptions->projection; } } @@ -908,11 +924,11 @@ void GG_CloudStorage::setGetOptions(struct fb_esp_gcs_req_t *req, std::string &h void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string &header, bool hasParams) { + char *tmp = nullptr; if (req->uploadOptions) { if (strlen(req->uploadOptions->contentEncoding) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -925,6 +941,7 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_499); header += tmp; ut->delS(tmp); @@ -933,7 +950,6 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string if (strlen(req->uploadOptions->ifGenerationMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -946,9 +962,11 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_494); header += tmp; ut->delS(tmp); + int n = atoi(req->uploadOptions->ifGenerationMatch); tmp = ut->intStr(n); header += tmp; @@ -957,7 +975,6 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string if (strlen(req->uploadOptions->ifGenerationNotMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -970,9 +987,11 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_495); header += tmp; ut->delS(tmp); + int n = atoi(req->uploadOptions->ifGenerationNotMatch); tmp = ut->intStr(n); header += tmp; @@ -981,7 +1000,6 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string if (strlen(req->uploadOptions->ifMetagenerationMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -994,9 +1012,11 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_496); header += tmp; ut->delS(tmp); + int n = atoi(req->uploadOptions->ifMetagenerationMatch); tmp = ut->intStr(n); header += tmp; @@ -1005,7 +1025,6 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string if (strlen(req->uploadOptions->ifMetagenerationNotMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1018,9 +1037,11 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_497); header += tmp; ut->delS(tmp); + int n = atoi(req->uploadOptions->ifMetagenerationNotMatch); tmp = ut->intStr(n); header += tmp; @@ -1029,7 +1050,6 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string if (strlen(req->uploadOptions->kmsKeyName) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1042,14 +1062,15 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_500); header += tmp; + ut->delS(tmp); header += req->uploadOptions->kmsKeyName; } if (strlen(req->uploadOptions->predefinedAcl) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1062,14 +1083,15 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_501); header += tmp; + ut->delS(tmp); header += req->uploadOptions->predefinedAcl; } if (strlen(req->uploadOptions->projection) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1082,8 +1104,10 @@ void GG_CloudStorage::setUploadOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_498); header += tmp; + ut->delS(tmp); header += req->uploadOptions->projection; } } @@ -1228,12 +1252,12 @@ void GG_CloudStorage::setRequestproperties(struct fb_esp_gcs_req_t *req, Firebas void GG_CloudStorage::setDeleteOptions(struct fb_esp_gcs_req_t *req, std::string &header, bool hasParams) { + char *tmp = nullptr; + if (req->deleteOptions) { - if (strlen(req->deleteOptions->ifGenerationMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1246,9 +1270,11 @@ void GG_CloudStorage::setDeleteOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_494); header += tmp; ut->delS(tmp); + int n = atoi(req->deleteOptions->ifGenerationMatch); tmp = ut->intStr(n); header += tmp; @@ -1257,7 +1283,6 @@ void GG_CloudStorage::setDeleteOptions(struct fb_esp_gcs_req_t *req, std::string if (strlen(req->deleteOptions->ifGenerationNotMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1270,9 +1295,11 @@ void GG_CloudStorage::setDeleteOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_495); header += tmp; ut->delS(tmp); + int n = atoi(req->deleteOptions->ifGenerationNotMatch); tmp = ut->intStr(n); header += tmp; @@ -1281,7 +1308,6 @@ void GG_CloudStorage::setDeleteOptions(struct fb_esp_gcs_req_t *req, std::string if (strlen(req->deleteOptions->ifMetagenerationMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1294,9 +1320,11 @@ void GG_CloudStorage::setDeleteOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_496); header += tmp; ut->delS(tmp); + int n = atoi(req->deleteOptions->ifMetagenerationMatch); tmp = ut->intStr(n); header += tmp; @@ -1305,7 +1333,6 @@ void GG_CloudStorage::setDeleteOptions(struct fb_esp_gcs_req_t *req, std::string if (strlen(req->deleteOptions->ifMetagenerationNotMatch) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1318,9 +1345,11 @@ void GG_CloudStorage::setDeleteOptions(struct fb_esp_gcs_req_t *req, std::string header += tmp; } ut->delS(tmp); + tmp = ut->strP(fb_esp_pgm_str_497); header += tmp; ut->delS(tmp); + int n = atoi(req->deleteOptions->ifMetagenerationNotMatch); tmp = ut->intStr(n); header += tmp; @@ -1332,11 +1361,13 @@ void GG_CloudStorage::setDeleteOptions(struct fb_esp_gcs_req_t *req, std::string void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string &header, bool hasParams) { + char *tmp = nullptr; + char *tmp2 = nullptr; + if (req->listOptions) { if (strlen(req->listOptions->delimiter) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1358,7 +1389,6 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & if (strlen(req->listOptions->endOffset) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1380,7 +1410,6 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & if (strlen(req->listOptions->includeTrailingDelimiter) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1399,7 +1428,7 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & ut->delS(tmp); tmp = ut->strP(fb_esp_pgm_str_107); - char *tmp2 = ut->strP(fb_esp_pgm_str_106); + tmp2 = ut->strP(fb_esp_pgm_str_106); if (strcmp(req->listOptions->includeTrailingDelimiter, tmp)) header += tmp; @@ -1411,7 +1440,6 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & if (strlen(req->listOptions->maxResults) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1437,7 +1465,6 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & if (strlen(req->listOptions->pageToken) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1452,7 +1479,7 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & ut->delS(tmp); tmp = ut->strP(fb_esp_pgm_str_358); - char *tmp2 = ut->strP(fb_esp_pgm_str_361); + tmp2 = ut->strP(fb_esp_pgm_str_361); header += tmp; header += tmp2; header += req->listOptions->pageToken; @@ -1462,7 +1489,6 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & if (strlen(req->listOptions->prefix) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1484,7 +1510,6 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & if (strlen(req->listOptions->projection) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1506,7 +1531,6 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & if (strlen(req->listOptions->startOffset) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1528,7 +1552,6 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & if (strlen(req->listOptions->versions) > 0) { - char *tmp = nullptr; if (hasParams) { tmp = ut->strP(fb_esp_pgm_str_172); @@ -1547,7 +1570,7 @@ void GG_CloudStorage::setListOptions(struct fb_esp_gcs_req_t *req, std::string & ut->delS(tmp); tmp = ut->strP(fb_esp_pgm_str_107); - char *tmp2 = ut->strP(fb_esp_pgm_str_106); + tmp2 = ut->strP(fb_esp_pgm_str_106); if (strcmp(req->listOptions->versions, tmp)) header += tmp; else @@ -1595,7 +1618,7 @@ void GG_CloudStorage::runResumableUploadTask() vTaskDelay(100 / portTICK_PERIOD_MS); if (_this->_resumableUploadTasks.size() == 0) - return; + break; if (_this->_resumableUplaodTaskIndex < _this->_resumableUploadTasks.size() - 1) _this->_resumableUplaodTaskIndex++; @@ -1617,13 +1640,6 @@ void GG_CloudStorage::runResumableUploadTask() if (n == _this->_resumableUploadTasks.size()) { - for (size_t i = 0; i < n; i++) - { - struct fb_gcs_upload_resumable_task_info_t *taskInfo = &_this->_resumableUploadTasks[i]; - taskInfo->fbdo->_ss.long_running_task--; - taskInfo->fbdo->clear(); - taskInfo->fbdo = nullptr; - } _this->_resumableUploadTasks.clear(); _this->_resumable_upload_task_enable = false; } @@ -1670,13 +1686,6 @@ void GG_CloudStorage::runResumableUploadTask() if (n == _resumableUploadTasks.size()) { - for (size_t i = 0; i < n; i++) - { - struct fb_gcs_upload_resumable_task_info_t *taskInfo = &_resumableUploadTasks[i]; - taskInfo->fbdo->_ss.long_running_task--; - taskInfo->fbdo->clear(); - taskInfo->fbdo = nullptr; - } _resumableUploadTasks.clear(); _resumable_upload_task_enable = false; } @@ -1718,11 +1727,22 @@ bool GG_CloudStorage::handleResponse(FirebaseData *fbdo, struct fb_esp_gcs_req_t std::string part1, part2, part3, part4, part5; size_t p1 = 0; size_t p2 = 0; - char *tmp1 = ut->strP(fb_esp_pgm_str_476); - char *tmp2 = ut->strP(fb_esp_pgm_str_477); - char *tmp3 = ut->strP(fb_esp_pgm_str_482); - char *tmp4 = ut->strP(fb_esp_pgm_str_483); - char *tmp5 = ut->strP(fb_esp_pgm_str_3); + + char *tmp1 = nullptr; + char *tmp2 = nullptr; + char *tmp3 = nullptr; + char *tmp4 = nullptr; + char *tmp5 = nullptr; + + if (req->requestType == fb_esp_gcs_request_type_list) + { + tmp1 = ut->strP(fb_esp_pgm_str_476); + tmp2 = ut->strP(fb_esp_pgm_str_477); + tmp3 = ut->strP(fb_esp_pgm_str_482); + tmp4 = ut->strP(fb_esp_pgm_str_483); + tmp5 = ut->strP(fb_esp_pgm_str_3); + } + std::string payload; fbdo->_ss.http_code = FIREBASE_ERROR_HTTP_CODE_OK; @@ -1835,24 +1855,25 @@ bool GG_CloudStorage::handleResponse(FirebaseData *fbdo, struct fb_esp_gcs_req_t ruTask.fbdo = fbdo; ruTask.req.requestType = fb_esp_gcs_request_type_upload_resumable_run; - char *tmp = ut->newS(strlen(header)); - strncpy(tmp, header + p1 + strlen_P(fb_esp_pgm_str_481), strlen(header) - p1 - strlen_P(fb_esp_pgm_str_481)); - ruTask.req.chunkRange = atoi(tmp); - ut->delS(tmp); + char *tmp6 = ut->newS(strlen(header)); + strncpy(tmp6, header + p1 + strlen_P(fb_esp_pgm_str_481), strlen(header) - p1 - strlen_P(fb_esp_pgm_str_481)); + ruTask.req.chunkRange = atoi(tmp6); + ut->delS(tmp6); - ruTask.req.callback = req->callback; - ruTask.req.statusInfo = req->statusInfo; + ruTask.req.callback = req->callback; + ruTask.req.statusInfo = req->statusInfo; - _resumableUploadTasks.push_back(ruTask); - fbdo->_ss.long_running_task++; - _resumable_upload_task_enable = true; + _resumableUploadTasks.push_back(ruTask); - if (_resumableUploadTasks.size() == 1) - { + fbdo->_ss.long_running_task++; + _resumable_upload_task_enable = true; + + if (_resumableUploadTasks.size() == 1) + { #if defined(ESP32) - tmp = ut->strP(fb_esp_pgm_str_480); - runResumableUploadTask(tmp); - ut->delS(tmp); + tmp6 = ut->strP(fb_esp_pgm_str_480); + runResumableUploadTask(tmp6); + ut->delS(tmp6); #elif defined(ESP8266) runResumableUploadTask(); #endif @@ -1875,16 +1896,16 @@ bool GG_CloudStorage::handleResponse(FirebaseData *fbdo, struct fb_esp_gcs_req_t ruTask.req.statusInfo = req->statusInfo; _resumableUploadTasks.push_back(ruTask); + fbdo->_ss.long_running_task++; _resumable_upload_task_enable = true; if (_resumableUploadTasks.size() == 1) { - #if defined(ESP32) - char *tmp = ut->strP(fb_esp_pgm_str_480); - runResumableUploadTask(tmp); - ut->delS(tmp); + char *tmp7 = ut->strP(fb_esp_pgm_str_480); + runResumableUploadTask(tmp7); + ut->delS(tmp7); #elif defined(ESP8266) runResumableUploadTask(); #endif @@ -2035,11 +2056,14 @@ bool GG_CloudStorage::handleResponse(FirebaseData *fbdo, struct fb_esp_gcs_req_t } } - ut->delS(tmp1); - ut->delS(tmp2); - ut->delS(tmp3); - ut->delS(tmp4); - ut->delS(tmp5); + if (req->requestType == fb_esp_gcs_request_type_list) + { + ut->delS(tmp1); + ut->delS(tmp2); + ut->delS(tmp3); + ut->delS(tmp4); + ut->delS(tmp5); + } if (hstate == 1) ut->delS(header); diff --git a/src/gcs/GCS.h b/src/gcs/GCS.h index 0d3d8f3e0..2e652ee86 100644 --- a/src/gcs/GCS.h +++ b/src/gcs/GCS.h @@ -3,7 +3,7 @@ * * This library supports Espressif ESP8266 and ESP32 * - * Created February 21, 2021 + * Created March 5, 2021 * * This work is a part of Firebase ESP Client library * Copyright (c) 2020, 2021 K. Suwatchai (Mobizt) @@ -37,6 +37,7 @@ #include "Utils.h" #include "session/FB_Session.h" + class GG_CloudStorage { friend class Firebase_ESP_Client; @@ -51,7 +52,7 @@ class GG_CloudStorage * @param fbdo The pointer to Firebase Data Object. * @param bucketID The Firebase or Google Cloud Storage bucket ID. * @param localFileName The file path includes its name to upload. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @param uploadType The enum of type of upload methods e.g. gcs_upload_type_simple, gcs_upload_type_multipart, gcs_upload_type_resumable * @param remotetFileName The file path includes its name of uploaded file in data bucket. * @param mime The file MIME type. @@ -83,7 +84,7 @@ class GG_CloudStorage * @param bucketID The Firebase or Google Cloud Storage bucket ID. * @param remotetFileName The file path includes its name of file in the data bucket to download. * @param localFileName The file path includes its name to save. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @param options Optional. The pointer to StorageGetOptions data that contains the get query parameters. * For the query parameters options, see https://cloud.google.com/storage/docs/json_api/v1/objects/get#optional-parameters * diff --git a/src/rtdb/FB_RTDB.cpp b/src/rtdb/FB_RTDB.cpp index d7d055fa8..5fe7bef34 100644 --- a/src/rtdb/FB_RTDB.cpp +++ b/src/rtdb/FB_RTDB.cpp @@ -2608,7 +2608,7 @@ uint32_t FB_RTDB::getErrorQueueID(FirebaseData *fbdo) void FB_RTDB::processErrorQueue(FirebaseData *fbdo, FirebaseData::QueueInfoCallback callback) { - delay(500); + delay(20); if (!fbdo->reconnect()) return; @@ -2971,7 +2971,7 @@ bool FB_RTDB::saveErrorQueue(FirebaseData *fbdo, const char *filename, fb_esp_me { if (!ut->sdTest(Signer.getCfg()->_int.fb_file)) return false; - Signer.getCfg()->_int.fb_file = SD.open(filename, FILE_WRITE); + Signer.getCfg()->_int.fb_file = SD_FS.open(filename, FILE_WRITE); } else if (storageType == mem_storage_type_flash) { @@ -3056,7 +3056,7 @@ bool FB_RTDB::deleteStorageFile(const char *filename, fb_esp_mem_storage_type st { if (!ut->sdTest(Signer.getCfg()->_int.fb_file)) return false; - return SD.remove(filename); + return SD_FS.remove(filename); } else { @@ -3075,7 +3075,7 @@ uint8_t FB_RTDB::openErrorQueue(FirebaseData *fbdo, const char *filename, fb_esp { if (!ut->sdTest(Signer.getCfg()->_int.fb_file)) return 0; - Signer.getCfg()->_int.fb_file = SD.open(filename, FILE_READ); + Signer.getCfg()->_int.fb_file = SD_FS.open(filename, FILE_READ); } else if (storageType == mem_storage_type_flash) { @@ -3537,8 +3537,8 @@ int FB_RTDB::sendRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_t * } else if (fbdo->_ss.rtdb.storage_type == mem_storage_type_sd) { - SD.remove(fbdo->_ss.rtdb.backup_filename.c_str()); - Signer.getCfg()->_int.fb_file = SD.open(fbdo->_ss.rtdb.backup_filename.c_str(), FILE_WRITE); + SD_FS.remove(fbdo->_ss.rtdb.backup_filename.c_str()); + Signer.getCfg()->_int.fb_file = SD_FS.open(fbdo->_ss.rtdb.backup_filename.c_str(), FILE_WRITE); } } else if (req->method == fb_esp_method::m_restore) @@ -3546,8 +3546,8 @@ int FB_RTDB::sendRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_t * if (fbdo->_ss.rtdb.storage_type == mem_storage_type_flash && FLASH_FS.exists(fbdo->_ss.rtdb.backup_filename.c_str())) Signer.getCfg()->_int.fb_file = FLASH_FS.open(fbdo->_ss.rtdb.backup_filename.c_str(), "r"); - else if (fbdo->_ss.rtdb.storage_type == mem_storage_type_sd && SD.exists(fbdo->_ss.rtdb.backup_filename.c_str())) - Signer.getCfg()->_int.fb_file = SD.open(fbdo->_ss.rtdb.backup_filename.c_str(), FILE_READ); + else if (fbdo->_ss.rtdb.storage_type == mem_storage_type_sd && SD_FS.exists(fbdo->_ss.rtdb.backup_filename.c_str())) + Signer.getCfg()->_int.fb_file = SD_FS.open(fbdo->_ss.rtdb.backup_filename.c_str(), FILE_READ); else { ut->appendP(fbdo->_ss.error, fb_esp_pgm_str_83, true); @@ -3576,8 +3576,8 @@ int FB_RTDB::sendRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_t * } else if (fbdo->_ss.rtdb.storage_type == mem_storage_type_sd) { - if (SD.exists(fbdo->_ss.rtdb.file_name.c_str())) - Signer.getCfg()->_int.fb_file = SD.open(fbdo->_ss.rtdb.file_name.c_str(), FILE_READ); + if (SD_FS.exists(fbdo->_ss.rtdb.file_name.c_str())) + Signer.getCfg()->_int.fb_file = SD_FS.open(fbdo->_ss.rtdb.file_name.c_str(), FILE_READ); else { ut->appendP(fbdo->_ss.error, fb_esp_pgm_str_83, true); @@ -3603,12 +3603,12 @@ int FB_RTDB::sendRequest(FirebaseData *fbdo, struct fb_esp_rtdb_request_info_t * else if (fbdo->_ss.rtdb.storage_type == mem_storage_type_sd) { - if (!SD.exists(folder.c_str())) + if (!SD_FS.exists(folder.c_str())) ut->createDirs(folder, fbdo->_ss.rtdb.storage_type); - SD.remove(fbdo->_ss.rtdb.file_name.c_str()); + SD_FS.remove(fbdo->_ss.rtdb.file_name.c_str()); - Signer.getCfg()->_int.fb_file = SD.open(fbdo->_ss.rtdb.file_name.c_str(), FILE_WRITE); + Signer.getCfg()->_int.fb_file = SD_FS.open(fbdo->_ss.rtdb.file_name.c_str(), FILE_WRITE); } std::string().swap(folder); } diff --git a/src/rtdb/FB_RTDB.h b/src/rtdb/FB_RTDB.h index 03e95af77..faa8c8e73 100644 --- a/src/rtdb/FB_RTDB.h +++ b/src/rtdb/FB_RTDB.h @@ -331,7 +331,7 @@ class FB_RTDB /** Append (post) new binary data from file stores on storage memory to the defined node. * * @param fbdo The pointer to Firebase Data Object. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @param path The path to the node in which binary data will be appended. * @param fileName The file path includes its name. * @return Boolean value, indicates the success of the operation. @@ -768,7 +768,7 @@ class FB_RTDB /** Set (put) the binary data from file to the defined node. * * @param fbdo The pointer to Firebase Data Object. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @param path The path to the node in which binary data will be set. * @param fileName The file path includes its name. * @return Boolean value, indicates the success of the operation. @@ -788,7 +788,7 @@ class FB_RTDB /** Set (put) the binary data from file to the defined node if defined node's ETag matched the ETag value. * * @param fbdo The pointer to Firebase Data Object. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @param path The path to the node in which binary data from the file will be set. * @param fileName The file path includes its name. * @param ETag Known unique identifier string (ETag) of defined node. @@ -1193,7 +1193,7 @@ class FB_RTDB * then please make sure that data at the defined node is the file type. * * @param fbdo The pointer to Firebase Data Object. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @param nodePath The path to the node that file data will be downloaded. * @param fileName The file path includes its name. * @return Boolean value, indicates the success of the operation. @@ -1328,7 +1328,7 @@ class FB_RTDB /** Backup (download) the database at the defined node to the storage memory. * * @param fbdo The pointer to Firebase Data Object. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @param nodePath The path to the node to be backuped. * @param fileName File name to save. * @return Boolean value, indicates the success of the operation. @@ -1340,7 +1340,7 @@ class FB_RTDB /** Restore the database at a defined path using backup file saved on SD card/Flash memory. * * @param fbdo The pointer to Firebase Data Object. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @param nodePath The path to the node to be restored the data. * @param fileName File name to read. * @return Boolean value, indicates the success of the operation. @@ -1371,14 +1371,14 @@ class FB_RTDB * * @param fbdo The pointer to Firebase Data Object. * @param filename Filename to be saved. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. */ bool saveErrorQueue(FirebaseData *fbdo, const char *filename, fb_esp_mem_storage_type storageType); /** Delete file in storage memory. * * @param filename File name to delete. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. */ bool deleteStorageFile(const char *filename, fb_esp_mem_storage_type storageType); @@ -1386,7 +1386,7 @@ class FB_RTDB * * @param fbdo The pointer to Firebase Data Object. * @param filename Filename to be read and restore queues. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. */ bool restoreErrorQueue(FirebaseData *fbdo, const char *filename, fb_esp_mem_storage_type storageType); @@ -1394,7 +1394,7 @@ class FB_RTDB * * @param fbdo The pointer to Firebase Data Object. * @param filename Filename to be read and count for queues. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @return Number (0-255) of queues store in defined queue file. */ uint8_t errorQueueCount(FirebaseData *fbdo, const char *filename, fb_esp_mem_storage_type storageType); diff --git a/src/rtdb/QueueInfo.h b/src/rtdb/QueueInfo.h index ba76c9ee6..932e5af33 100644 --- a/src/rtdb/QueueInfo.h +++ b/src/rtdb/QueueInfo.h @@ -36,7 +36,7 @@ #include "Utils.h" #include "QueryFilter.h" -struct QueueItem +typedef struct fb_esp_rtdb_queue_item_info_t { fb_esp_data_type dataType = fb_esp_data_type::d_any; fb_esp_method method = fb_esp_method::m_put; @@ -58,7 +58,7 @@ struct QueueItem FirebaseJson *jsonPtr = nullptr; FirebaseJsonArray *arrPtr = nullptr; std::vector *blobPtr = nullptr; -}; +} QueueItem; class QueueInfo { diff --git a/src/session/FB_Session.cpp b/src/session/FB_Session.cpp index 18af31385..70cb61063 100644 --- a/src/session/FB_Session.cpp +++ b/src/session/FB_Session.cpp @@ -147,7 +147,7 @@ void FirebaseData::stopWiFiClient() _ss.connected = false; } -FB_ESP_SSL_CLIENT *FirebaseData::getWiFiClient() +WiFiClientSecure *FirebaseData::getWiFiClient() { return httpClient._wcs.get(); } diff --git a/src/session/FB_Session.h b/src/session/FB_Session.h index 67371246f..ebf9699d9 100644 --- a/src/session/FB_Session.h +++ b/src/session/FB_Session.h @@ -90,7 +90,7 @@ class FirebaseData * * @return WiFi client instance. */ - FB_ESP_SSL_CLIENT *getWiFiClient(); + WiFiClientSecure *getWiFiClient(); /** Close the keep-alive connection of the internal WiFi client. * diff --git a/src/signer/Signer.cpp b/src/signer/Signer.cpp index 214e276fe..d66f41b3c 100644 --- a/src/signer/Signer.cpp +++ b/src/signer/Signer.cpp @@ -68,8 +68,8 @@ bool Firebase_Signer::parseSAFile() } else { - if (SD.exists(config->service_account.json.path.c_str())) - config->_int.fb_file = SD.open(config->service_account.json.path.c_str(), "r"); + if (SD_FS.exists(config->service_account.json.path.c_str())) + config->_int.fb_file = SD_FS.open(config->service_account.json.path.c_str(), "r"); } if (config->_int.fb_file) @@ -717,10 +717,11 @@ bool Firebase_Signer::handleTokenResponse() } chunkIdx++; } - } - if (millis() - datatime > 5000) - complete = true; + if (millis() - datatime > 5000) + complete = true; + } + } } @@ -1772,7 +1773,13 @@ void Firebase_Signer::errorToString(int httpCode, std::string &buff) case FIREBASE_ERROR_LONG_RUNNING_TASK: ut->appendP(buff, fb_esp_pgm_str_534); return; - default: + case FIREBASE_ERROR_UPLOAD_TIME_OUT: + ut->appendP(buff, fb_esp_pgm_str_540); + return; + case FIREBASE_ERROR_UPLOAD_DATA_ERRROR: + ut->appendP(buff, fb_esp_pgm_str_541); + return; + default: return; } } diff --git a/src/storage/FCS.cpp b/src/storage/FCS.cpp index 4d5eb88f0..24fc53c11 100644 --- a/src/storage/FCS.cpp +++ b/src/storage/FCS.cpp @@ -207,7 +207,7 @@ bool FB_CloudStorage::fcs_sendRequest(FirebaseData *fbdo, struct fb_esp_fcs_req_ fbdo->_ss.http_code = FIREBASE_ERROR_FILE_IO_ERROR; return false; } - Signer.getCfg()->_int.fb_file = SD.open(req->localFileName.c_str(), FILE_WRITE); + Signer.getCfg()->_int.fb_file = SD_FS.open(req->localFileName.c_str(), FILE_WRITE); } else if (req->storageType == mem_storage_type_flash) { @@ -234,13 +234,13 @@ bool FB_CloudStorage::fcs_sendRequest(FirebaseData *fbdo, struct fb_esp_fcs_req_ return false; } - if (!SD.exists(req->localFileName.c_str())) + if (!SD_FS.exists(req->localFileName.c_str())) { fbdo->_ss.http_code = FIREBASE_ERROR_FILE_IO_ERROR; return false; } - Signer.getCfg()->_int.fb_file = SD.open(req->localFileName.c_str(), FILE_READ); + Signer.getCfg()->_int.fb_file = SD_FS.open(req->localFileName.c_str(), FILE_READ); } else if (req->storageType == mem_storage_type_flash) { diff --git a/src/storage/FCS.h b/src/storage/FCS.h index fc9159bd9..ae64367e9 100644 --- a/src/storage/FCS.h +++ b/src/storage/FCS.h @@ -51,7 +51,7 @@ class FB_CloudStorage * @param fbdo The pointer to Firebase Data Object. * @param bucketID The Firebase storage bucket ID in the project. * @param localFileName The file path includes its name to upload. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * @param remotetFileName The file path includes its name of uploaded file in data bucket. * @param mime The file MIME type * . @@ -84,7 +84,7 @@ class FB_CloudStorage * @param bucketID The Firebase storage bucket ID in the project. * @param remotetFileName The file path includes its name of file in the data bucket to download. * @param localFileName The file path includes its name to save. - * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. + * @param storageType The enum of memory storage type e.g. mem_storage_type_flash and mem_storage_type_sd. The file systems can be changed in FirebaseFS.h. * * @return Boolean value, indicates the success of the operation. * diff --git a/src/wcs/HTTPCode.h b/src/wcs/HTTPCode.h index 563cf0410..05ce300f7 100644 --- a/src/wcs/HTTPCode.h +++ b/src/wcs/HTTPCode.h @@ -66,6 +66,8 @@ #define FIREBASE_ERROR_TOKEN_EXCHANGE -31 #define FIREBASE_ERROR_TOKEN_NOT_READY -32 #define FIREBASE_ERROR_LONG_RUNNING_TASK -33 +#define FIREBASE_ERROR_UPLOAD_TIME_OUT -34 +#define FIREBASE_ERROR_UPLOAD_DATA_ERRROR -35 /// HTTP codes see RFC7231 diff --git a/src/wcs/esp32/FB_HTTPClient32.cpp b/src/wcs/esp32/FB_HTTPClient32.cpp index 37c91ba83..d335a32ac 100644 --- a/src/wcs/esp32/FB_HTTPClient32.cpp +++ b/src/wcs/esp32/FB_HTTPClient32.cpp @@ -2,7 +2,7 @@ * Customized version of ESP32 HTTPClient Library. * Allow custom header and payload * - * v 1.0.5 + * v 1.0.6 * * The MIT License (MIT) * Copyright (c) 2021 K. Suwatchai (Mobizt) @@ -39,8 +39,6 @@ FB_HTTPClient32::FB_HTTPClient32() { - transportTraits = FB_ESP_TransportTraitsPtr(new TLSTraits(nullptr)); - _wcs = transportTraits->create(); } FB_HTTPClient32::~FB_HTTPClient32() @@ -55,7 +53,6 @@ FB_HTTPClient32::~FB_HTTPClient32() std::string().swap(_CAFile); _cacert.reset(new char); _cacert = nullptr; - transportTraits.reset(nullptr); } bool FB_HTTPClient32::begin(const char *host, uint16_t port) @@ -72,11 +69,18 @@ bool FB_HTTPClient32::connected() return false; } +void FB_HTTPClient32::stop() +{ + if (!connected()) + return; + return _wcs->stop(); +} + bool FB_HTTPClient32::send(const char *header) { if (!connected()) return false; - return (_wcs->write(header, strlen(header)) == strlen(header)); + return (_wcs->print(header) == strlen(header)); } int FB_HTTPClient32::send(const char *header, const char *payload) @@ -97,7 +101,7 @@ int FB_HTTPClient32::send(const char *header, const char *payload) if (size > 0) { - if (_wcs->write(&payload[0], size) != size) + if (_wcs->print(payload) != size) { return FIREBASE_ERROR_HTTPC_ERROR_SEND_PAYLOAD_FAILED; } @@ -122,10 +126,6 @@ bool FB_HTTPClient32::connect(void) return true; } - if (!transportTraits) - return false; - - transportTraits->verify(*_wcs, _host.c_str()); if (!_wcs->connect(_host.c_str(), _port)) return false; @@ -134,14 +134,29 @@ bool FB_HTTPClient32::connect(void) void FB_HTTPClient32::setCACert(const char *caCert) { + _wcs->setCACert(caCert); if (caCert) - { - transportTraits.reset(nullptr); - transportTraits = FB_ESP_TransportTraitsPtr(new TLSTraits(caCert)); _certType = 1; - } else + { + +#ifdef CONFIG_ARDUINO_IDF_BRANCH + size_t len = strlen_P(esp_idf_branch_str); + char *tmp = new char[len + 1]; + memset(tmp, 0, len + 1); + std::string s = CONFIG_ARDUINO_IDF_BRANCH; + size_t p1 = s.find(tmp, 0); + if (p1 != std::string::npos) + { + float v = atof(s.substr(p1 + len, s.length() - p1 - len).c_str()); + if (v >= 3.3f) + _wcs->setInsecure(); + } + delete[] tmp; +#endif _certType = 0; + } + //_wcs->setNoDelay(true); } void FB_HTTPClient32::setCACertFile(const char *caCertFile, uint8_t storageType, uint8_t sdPin) @@ -155,7 +170,7 @@ void FB_HTTPClient32::setCACertFile(const char *caCertFile, uint8_t storageType, if (storageType == 0) t = FLASH_FS.begin(true); else - t = SD.begin(); + t = SD_FS.begin(); if (!t) return; @@ -167,8 +182,8 @@ void FB_HTTPClient32::setCACertFile(const char *caCertFile, uint8_t storageType, } else if (storageType == 2) { - if (SD.exists(caCertFile)) - f = SD.open(caCertFile, FILE_READ); + if (SD_FS.exists(caCertFile)) + f = SD_FS.open(caCertFile, FILE_READ); } if (f) @@ -182,11 +197,10 @@ void FB_HTTPClient32::setCACertFile(const char *caCertFile, uint8_t storageType, f.readBytes(_cacert.get(), len); f.close(); - - transportTraits.reset(nullptr); - transportTraits = FB_ESP_TransportTraitsPtr(new TLSTraits(_cacert.get())); + _wcs->setCACert(_cacert.get()); } } + //_wcs->setNoDelay(true); } #endif /* ESP32 */ diff --git a/src/wcs/esp32/FB_HTTPClient32.h b/src/wcs/esp32/FB_HTTPClient32.h index 8b30f180f..b0e516197 100644 --- a/src/wcs/esp32/FB_HTTPClient32.h +++ b/src/wcs/esp32/FB_HTTPClient32.h @@ -2,7 +2,7 @@ * Customized version of ESP32 HTTPClient Library. * Allow custom header and payload * - * v 1.0.5 + * v 1.0.6 * * The MIT License (MIT) * Copyright (c) 2021 K. Suwatchai (Mobizt) @@ -35,63 +35,27 @@ #ifdef ESP32 + #include #include #include #include #include -#include "wcs/esp32/FB_WCS32.h" +#include "FirebaseFS.h" +#include #if __has_include() || __has_include() #error WiFi UART bridge was not supported. #endif -#include "wcs/HTTPCode.h" -#define FB_ESP_SSL_CLIENT WiFiClient +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#define FLASH_FS DEFAULT_FLASH_FS +#define SD_FS DEFAULT_SD_FS -class TransportTraits -{ -public: - virtual ~TransportTraits() {} - - virtual std::unique_ptr create() - { - return std::unique_ptr(new WiFiClient()); - } - - virtual bool - verify(WiFiClient &client, const char *host) - { - return true; - } -}; - -class TLSTraits : public TransportTraits -{ -public: - TLSTraits(const char *CAcert, const char *clicert = nullptr, const char *clikey = nullptr) : _cacert(CAcert), _clicert(clicert), _clikey(clikey) {} - - std::unique_ptr create() override - { - return std::unique_ptr(new FB_WCS32()); - } - - bool verify(WiFiClient &client, const char *host) override - { - FB_WCS32 &wcs = static_cast(client); - wcs.setCACert(_cacert); - wcs.setCertificate(_clicert); - wcs.setPrivateKey(_clikey); - return true; - } - -protected: - const char *_cacert; - const char *_clicert; - const char *_clikey; -}; +#include "wcs/HTTPCode.h" -typedef std::unique_ptr FB_ESP_TransportTraitsPtr; +static const char esp_idf_branch_str[] PROGMEM = "release/v"; class FB_HTTPClient32 { @@ -143,13 +107,14 @@ class FB_HTTPClient32 */ WiFiClient *stream(void); + void stop(); + bool connect(void); void setCACert(const char *caCert); void setCACertFile(const char *caCertFile, uint8_t storageType, uint8_t sdPin); protected: - FB_ESP_TransportTraitsPtr transportTraits; - std::unique_ptr _wcs; + std::unique_ptr _wcs = std::unique_ptr(new WiFiClientSecure()); std::unique_ptr _cacert; std::string _host = ""; uint16_t _port = 0; diff --git a/src/wcs/esp32/FB_WCS32.cpp b/src/wcs/esp32/FB_WCS32.cpp deleted file mode 100644 index 65fabdd8f..000000000 --- a/src/wcs/esp32/FB_WCS32.cpp +++ /dev/null @@ -1,370 +0,0 @@ -/** - *Copied version of WiFiClientSecure.cpp version 1.0.2 -*/ - -/** - WiFiClientSecureESP32.cpp - Client Secure class for ESP32 - Copyright (c) 2016 Hristo Gochkov All right reserved. - Additions Copyright (C) 2017 Evandro Luis Copercini. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef FB_WCS32_CPP -#define FB_WCS32_CPP - -#ifdef ESP32 - -#include "FB_WCS32.h" -#include -#include -#include - - -#undef connect -#undef write -#undef read - - -FB_WCS32::FB_WCS32() -{ - _connected = false; - - sslclient = new fb_esp_ssl_ctx32; - - ssl_init(sslclient); - sslclient->socket = -1; - sslclient->handshake_timeout = 120000; - _CA_cert = NULL; - _cert = NULL; - _private_key = NULL; - _pskIdent = NULL; - _psKey = NULL; - next = NULL; -} - - -FB_WCS32::FB_WCS32(int sock) -{ - _connected = false; - _timeout = 0; - - sslclient = new fb_esp_ssl_ctx32; - ssl_init(sslclient); - sslclient->socket = sock; - sslclient->handshake_timeout = 120000; - - if (sock >= 0) { - _connected = true; - } - - _CA_cert = NULL; - _cert = NULL; - _private_key = NULL; - _pskIdent = NULL; - _psKey = NULL; - next = NULL; -} - -FB_WCS32::FB_WCS32(bool starttls) -{ - _connected = false; - - sslclient = new fb_esp_ssl_ctx32; - ssl_init(sslclient); - sslclient->socket = -1; - sslclient->handshake_timeout = 120000; - _CA_cert = NULL; - _cert = NULL; - _private_key = NULL; - _pskIdent = NULL; - _psKey = NULL; - next = NULL; -} - -FB_WCS32::~FB_WCS32() -{ - stop(); - delete sslclient; -} - -FB_WCS32 &FB_WCS32::operator=(const FB_WCS32 &other) -{ - stop(); - sslclient->socket = other.sslclient->socket; - _connected = other._connected; - return *this; -} - -void FB_WCS32::stop() -{ - if (sslclient->socket >= 0) { - close(sslclient->socket); - sslclient->socket = -1; - _connected = false; - _peek = -1; - stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key); - } - -} - -int FB_WCS32::connect(IPAddress ip, uint16_t port) -{ - if (_pskIdent && _psKey) - return connect(ip, port, _pskIdent, _psKey); - return connect(ip, port, _CA_cert, _cert, _private_key); -} - -int FB_WCS32::connect(IPAddress ip, uint16_t port, int32_t timeout){ - _timeout = timeout; - return connect(ip, port); -} - -int FB_WCS32::connect(const char *host, uint16_t port) -{ - if (_pskIdent && _psKey) - return connect(host, port, _pskIdent, _psKey); - return connect(host, port, _CA_cert, _cert, _private_key); -} - -int FB_WCS32::connect(const char *host, uint16_t port, int32_t timeout){ - _timeout = timeout; - return connect(host, port); -} - -int FB_WCS32::connect(IPAddress ip, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key) -{ - return connect(ip.toString().c_str(), port, _CA_cert, _cert, _private_key); -} - -int FB_WCS32::connect(const char *host, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key) -{ - if(_timeout > 0){ - sslclient->handshake_timeout = _timeout; - } - int ret = start_ssl_client(sslclient, host, port, _timeout, _CA_cert, _cert, _private_key, NULL, NULL); - _lastError = ret; - if (ret < 0) { - log_e("start_ssl_client: %d", ret); - stop(); - return 0; - } - _connected = true; - return 1; -} - -int FB_WCS32::connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey) { - return connect(ip.toString().c_str(), port,_pskIdent, _psKey); -} - -int FB_WCS32::connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey) { - log_v("start_ssl_client with PSK"); - if(_timeout > 0){ - sslclient->handshake_timeout = _timeout; - } - int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, _pskIdent, _psKey); - _lastError = ret; - if (ret < 0) { - log_e("start_ssl_client: %d", ret); - stop(); - return 0; - } - _connected = true; - return 1; -} - -int FB_WCS32::peek(){ - if(_peek >= 0){ - return _peek; - } - _peek = timedRead(); - return _peek; -} - -size_t FB_WCS32::write(uint8_t data) -{ - return write(&data, 1); -} - -int FB_WCS32::read() -{ - uint8_t data = -1; - int res = read(&data, 1); - if (res < 0) { - return res; - } - return data; -} - -size_t FB_WCS32::write(const uint8_t *buf, size_t size) -{ - if (!_connected) { - return 0; - } - int res = send_ssl_data(sslclient, buf, size); - if (res < 0) { - stop(); - res = 0; - } - return res; -} - -int FB_WCS32::read(uint8_t *buf, size_t size) -{ - int peeked = 0; - int avail = available(); - if ((!buf && size) || avail <= 0) { - return -1; - } - if(!size){ - return 0; - } - if(_peek >= 0){ - buf[0] = _peek; - _peek = -1; - size--; - avail--; - if(!size || !avail){ - return 1; - } - buf++; - peeked = 1; - } - - int res = get_ssl_receive(sslclient, buf, size); - if (res < 0) { - stop(); - return peeked?peeked:res; - } - return res + peeked; -} - -int FB_WCS32::available() -{ - int peeked = (_peek >= 0); - if (!_connected) { - return peeked; - } - int res = data_to_read(sslclient); - if (res < 0) { - stop(); - return peeked?peeked:res; - } - return res+peeked; -} - -uint8_t FB_WCS32::connected() -{ - uint8_t dummy = 0; - read(&dummy, 0); - - return _connected; -} - -void FB_WCS32::setCACert (const char *rootCA) -{ - _CA_cert = rootCA; -} - -void FB_WCS32::setCertificate (const char *client_ca) -{ - _cert = client_ca; -} - -void FB_WCS32::setPrivateKey (const char *private_key) -{ - _private_key = private_key; -} - -void FB_WCS32::setPreSharedKey(const char *pskIdent, const char *psKey) { - _pskIdent = pskIdent; - _psKey = psKey; -} - -bool FB_WCS32::verify(const char* fp, const char* domain_name) -{ - if (!sslclient) - return false; - - return verify_ssl_fingerprint(sslclient, fp, domain_name); -} - -char *FB_WCS32::_streamLoad(Stream& stream, size_t size) { - static char *dest = nullptr; - if(dest) { - free(dest); - } - dest = (char*)malloc(size); - if (!dest) { - return nullptr; - } - if (size != stream.readBytes(dest, size)) { - free(dest); - dest = nullptr; - } - return dest; -} - -bool FB_WCS32::loadCACert(Stream& stream, size_t size) { - char *dest = _streamLoad(stream, size); - bool ret = false; - if (dest) { - setCACert(dest); - ret = true; - } - return ret; -} - -bool FB_WCS32::loadCertificate(Stream& stream, size_t size) { - char *dest = _streamLoad(stream, size); - bool ret = false; - if (dest) { - setCertificate(dest); - ret = true; - } - return ret; -} - -bool FB_WCS32::loadPrivateKey(Stream& stream, size_t size) { - char *dest = _streamLoad(stream, size); - bool ret = false; - if (dest) { - setPrivateKey(dest); - ret = true; - } - return ret; -} - -int FB_WCS32::lastError(char *buf, const size_t size) -{ - if (!_lastError) { - return 0; - } - char error_buf[100]; - mbedtls_strerror(_lastError, error_buf, 100); - snprintf(buf, size, "%s", error_buf); - return _lastError; -} - -void FB_WCS32::setHandshakeTimeout(unsigned long handshake_timeout) -{ - sslclient->handshake_timeout = handshake_timeout * 1000; -} - - - -#endif //ESP32 - -#endif //WiFiClientSecureESP32_CPP \ No newline at end of file diff --git a/src/wcs/esp32/FB_WCS32.h b/src/wcs/esp32/FB_WCS32.h deleted file mode 100644 index 9fbeb3d15..000000000 --- a/src/wcs/esp32/FB_WCS32.h +++ /dev/null @@ -1,129 +0,0 @@ - -/** - *Copied version of WiFiClientSecure.h version 1.0.2 -*/ - -/** - WiFiClientSecureESP32.h - Base class that provides Client SSL to ESP32 - Copyright (c) 2011 Adrian McEwen. All right reserved. - Additions Copyright (C) 2017 Evandro Luis Copercini. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef FB_WCS32_H -#define FB_WCS32_H - -#ifdef ESP32 - -#include -#include -#include -#include "fb_ssl_client32.h" - -#ifdef USE_LITTLEFS -#include -#define FLASH_FS LittleFS -#else -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#define FLASH_FS SPIFFS -#endif - -class FB_WCS32 : public WiFiClient -{ -protected: - fb_esp_ssl_ctx32 *sslclient; - - int _lastError = 0; - int _peek = -1; - int _timeout = 0; - const char *_CA_cert; - const char *_cert; - const char *_private_key; - const char *_pskIdent; // identity for PSK cipher suites - const char *_psKey; // key in hex for PSK cipher suites - - -public: - FB_WCS32 *next; - FB_WCS32(); - FB_WCS32(int socket); - FB_WCS32(bool starttls); - ~FB_WCS32(); - int connect(IPAddress ip, uint16_t port); - int connect(IPAddress ip, uint16_t port, int32_t timeout); - int connect(const char *host, uint16_t port); - int connect(const char *host, uint16_t port, int32_t timeout); - int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); - int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); - int connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey); - int connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey); - int peek(); - size_t write(uint8_t data); - size_t write(const uint8_t *buf, size_t size); - int available(); - int read(); - int read(uint8_t *buf, size_t size); - void flush() {} - void stop(); - uint8_t connected(); - int lastError(char *buf, const size_t size); - void setPreSharedKey(const char *pskIdent, const char *psKey); // psKey in Hex - void setCACert(const char *rootCA); - void setCertificate(const char *client_ca); - void setPrivateKey (const char *private_key); - bool loadCACert(Stream& stream, size_t size); - bool loadCertificate(Stream& stream, size_t size); - bool loadPrivateKey(Stream& stream, size_t size); - bool verify(const char* fingerprint, const char* domain_name); - void setHandshakeTimeout(unsigned long handshake_timeout); - - operator bool() - { - return connected(); - } - FB_WCS32 &operator=(const FB_WCS32 &other); - bool operator==(const bool value) - { - return bool() == value; - } - bool operator!=(const bool value) - { - return bool() != value; - } - bool operator==(const FB_WCS32 &); - bool operator!=(const FB_WCS32 &rhs) - { - return !this->operator==(rhs); - }; - - int socket() - { - return sslclient->socket = -1; - } - -private: - char *_streamLoad(Stream& stream, size_t size); - - //friend class WiFiServer; - using Print::write; -}; - -#endif //ESP32 - -#endif //WiFiClientSecureESP32_H - - diff --git a/src/wcs/esp32/fb_ssl_client32.cpp b/src/wcs/esp32/fb_ssl_client32.cpp deleted file mode 100644 index 4131e6453..000000000 --- a/src/wcs/esp32/fb_ssl_client32.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/** - *Modified version of ssl_client.cpp version 1.0.2 -*/ - -/** Provide SSL/TLS functions to ESP32 with Arduino IDE -* -* Adapted from the ssl_client1 example of mbedtls. -* -* Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License. -* Additions Copyright (C) 2017 Evandro Luis Copercini, Apache 2.0 License. -*/ -#ifndef FB_SSL_CLIENT32_CPP -#define FB_SSL_CLIENT32_CPP - -#ifdef ESP32 - -#include "Arduino.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "fb_ssl_client32.h" -#include "WiFi.h" - -const char *fb_ssl_pers32 = "esp32-tls"; - -static int _handle_error(int err, const char *file, int line) -{ - if (err == -30848) - { - return err; - } -#ifdef MBEDTLS_ERROR_C - char error_buf[100]; - mbedtls_strerror(err, error_buf, 100); - log_e("[%s():%d]: (%d) %s", file, line, err, error_buf); -#else - log_e("[%s():%d]: code %d", file, line, err); -#endif - return err; -} - -#define handle_error(e) _handle_error(e, __FUNCTION__, __LINE__) - -void ssl_init(fb_esp_ssl_ctx32 *ssl_client) -{ - mbedtls_ssl_init(&ssl_client->ssl_ctx); - mbedtls_ssl_config_init(&ssl_client->ssl_conf); - mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx); - ssl_client->ssl_freed = false; - ssl_client->is_entropy_ctx = false; -} - -int start_ssl_client(fb_esp_ssl_ctx32 *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey) -{ - char buf[512]; - int ret, flags; - int enable = 1; - log_v("Free internal heap before TLS %u", ESP.getFreeHeap()); - - log_v("Starting socket"); - ssl_client->socket = -1; - - ssl_client->socket = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (ssl_client->socket < 0) - { - log_e("ERROR opening socket"); - return ssl_client->socket; - } - - IPAddress srv((uint32_t)0); - if (!WiFiGenericClass::hostByName(host, srv)) - { - return -1; - } - - struct sockaddr_in serv_addr; - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = srv; - serv_addr.sin_port = htons(port); - - if (lwip_connect(ssl_client->socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) - { - if (timeout <= 0) - { - timeout = 30000; - } - lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); - lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); - lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); - lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); - } - else - { - log_e("Connect to Server failed!"); - return -1; - } - - fcntl(ssl_client->socket, F_SETFL, fcntl(ssl_client->socket, F_GETFL, 0) | O_NONBLOCK); - - ssl_client->ssl_freed = false; - ssl_client->is_entropy_ctx = true; - - log_v("Seeding the random number generator"); - mbedtls_entropy_init(&ssl_client->entropy_ctx); - - ret = mbedtls_ctr_drbg_seed(&ssl_client->drbg_ctx, mbedtls_entropy_func, - &ssl_client->entropy_ctx, (const unsigned char *)fb_ssl_pers32, strlen(fb_ssl_pers32)); - if (ret < 0) - { - return handle_error(ret); - } - - log_v("Setting up the SSL/TLS structure..."); - - if ((ret = mbedtls_ssl_config_defaults(&ssl_client->ssl_conf, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT)) != 0) - { - return handle_error(ret); - } - - // MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and - // MBEDTLS_SSL_VERIFY_NONE if not. - - if (rootCABuff != NULL) - { - log_v("Loading CA cert"); - mbedtls_x509_crt_init(&ssl_client->ca_cert); - mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED); - ret = mbedtls_x509_crt_parse(&ssl_client->ca_cert, (const unsigned char *)rootCABuff, strlen(rootCABuff) + 1); - mbedtls_ssl_conf_ca_chain(&ssl_client->ssl_conf, &ssl_client->ca_cert, NULL); - //mbedtls_ssl_conf_verify(&ssl_client->ssl_ctx, my_verify, NULL ); - if (ret < 0) - { - return handle_error(ret); - } - } - else if (pskIdent != NULL && psKey != NULL) - { - log_v("Setting up PSK"); - // convert PSK from hex to binary - if ((strlen(psKey) & 1) != 0 || strlen(psKey) > 2 * MBEDTLS_PSK_MAX_LEN) - { - log_e("pre-shared key not valid hex or too long"); - return -1; - } - unsigned char psk[MBEDTLS_PSK_MAX_LEN]; - size_t psk_len = strlen(psKey) / 2; - for (int j = 0; j < strlen(psKey); j += 2) - { - char c = psKey[j]; - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'F') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'f') - c -= 'a' - 10; - else - return -1; - psk[j / 2] = c << 4; - c = psKey[j + 1]; - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'F') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'f') - c -= 'a' - 10; - else - return -1; - psk[j / 2] |= c; - } - // set mbedtls config - ret = mbedtls_ssl_conf_psk(&ssl_client->ssl_conf, psk, psk_len, - (const unsigned char *)pskIdent, strlen(pskIdent)); - if (ret != 0) - { - log_e("mbedtls_ssl_conf_psk returned %d", ret); - return handle_error(ret); - } - } - else - { - mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_NONE); - log_i("WARNING: Use certificates for a more secure communication!"); - } - - if (cli_cert != NULL && cli_key != NULL) - { - mbedtls_x509_crt_init(&ssl_client->client_cert); - mbedtls_pk_init(&ssl_client->client_key); - - log_v("Loading CRT cert"); - - ret = mbedtls_x509_crt_parse(&ssl_client->client_cert, (const unsigned char *)cli_cert, strlen(cli_cert) + 1); - if (ret < 0) - { - return handle_error(ret); - } - - log_v("Loading private key"); - ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0); - - if (ret != 0) - { - return handle_error(ret); - } - - mbedtls_ssl_conf_own_cert(&ssl_client->ssl_conf, &ssl_client->client_cert, &ssl_client->client_key); - } - - log_v("Setting hostname for TLS session..."); - - // Hostname set here should match CN in server certificate - if ((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0) - { - return handle_error(ret); - } - - mbedtls_ssl_conf_rng(&ssl_client->ssl_conf, mbedtls_ctr_drbg_random, &ssl_client->drbg_ctx); - - if ((ret = mbedtls_ssl_setup(&ssl_client->ssl_ctx, &ssl_client->ssl_conf)) != 0) - { - return handle_error(ret); - } - - mbedtls_ssl_set_bio(&ssl_client->ssl_ctx, &ssl_client->socket, mbedtls_net_send, mbedtls_net_recv, NULL); - - log_v("Performing the SSL/TLS handshake..."); - unsigned long handshake_start_time = millis(); - while ((ret = mbedtls_ssl_handshake(&ssl_client->ssl_ctx)) != 0) - { - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) - { - return handle_error(ret); - } - if ((millis() - handshake_start_time) > ssl_client->handshake_timeout) - return -1; - vTaskDelay(10 / portTICK_PERIOD_MS); - } - - if (cli_cert != NULL && cli_key != NULL) - { - log_d("Protocol is %s Ciphersuite is %s", mbedtls_ssl_get_version(&ssl_client->ssl_ctx), mbedtls_ssl_get_ciphersuite(&ssl_client->ssl_ctx)); - if ((ret = mbedtls_ssl_get_record_expansion(&ssl_client->ssl_ctx)) >= 0) - { - log_d("Record expansion is %d", ret); - } - else - { - log_w("Record expansion is unknown (compression)"); - } - } - - log_v("Verifying peer X.509 certificate..."); - - if ((flags = mbedtls_ssl_get_verify_result(&ssl_client->ssl_ctx)) != 0) - { - bzero(buf, sizeof(buf)); - mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags); - log_e("Failed to verify peer certificate! verification info: %s", buf); - stop_ssl_socket(ssl_client, rootCABuff, cli_cert, cli_key); //It's not safe continue. - return handle_error(ret); - } - else - { - log_v("Certificate verified."); - } - - if (rootCABuff != NULL) - { - mbedtls_x509_crt_free(&ssl_client->ca_cert); - } - - if (cli_cert != NULL) - { - mbedtls_x509_crt_free(&ssl_client->client_cert); - } - - if (cli_key != NULL) - { - mbedtls_pk_free(&ssl_client->client_key); - } - - log_v("Free internal heap after TLS %u", ESP.getFreeHeap()); - - return ssl_client->socket; -} - -void stop_ssl_socket(fb_esp_ssl_ctx32 *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key) -{ - log_v("Cleaning SSL connection."); - - if (ssl_client->socket >= 0) - { - close(ssl_client->socket); - ssl_client->socket = -1; - } - - if (!ssl_client->ssl_freed) - { - //log_e("Free resource...."); - - mbedtls_ssl_free(&ssl_client->ssl_ctx); - mbedtls_ssl_config_free(&ssl_client->ssl_conf); - mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx); - if (ssl_client->is_entropy_ctx) - mbedtls_entropy_free(&ssl_client->entropy_ctx); - - ssl_client->is_entropy_ctx = false; - ssl_client->ssl_freed = true; - - //log_e("Free resource....ok"); - } -} - -int data_to_read(fb_esp_ssl_ctx32 *ssl_client) -{ - int ret, res; - ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, NULL, 0); - //log_e("RET: %i",ret); //for low level debug - - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0) - { - return handle_error(ret); - } - - res = mbedtls_ssl_get_bytes_avail(&ssl_client->ssl_ctx); - //log_e("RES: %i",res); //for low level debug - - return res; -} - -int send_ssl_data(fb_esp_ssl_ctx32 *ssl_client, const uint8_t *data, uint16_t len) -{ - log_v("Writing HTTP request..."); //for low level debug - int ret = -1; - - while ((ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data, len)) <= 0) - { - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) - { - return handle_error(ret); - } - } - - len = ret; - //log_v("%d bytes written", len); //for low level debug - return ret; -} - -int get_ssl_receive(fb_esp_ssl_ctx32 *ssl_client, uint8_t *data, int length) -{ - //log_d( "Reading HTTP response..."); //for low level debug - int ret = -1; - - ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, data, length); - - //log_v( "%d bytes read", ret); //for low level debug - return ret; -} - -static bool parseHexNibble(char pb, uint8_t *res) -{ - if (pb >= '0' && pb <= '9') - { - *res = (uint8_t)(pb - '0'); - return true; - } - else if (pb >= 'a' && pb <= 'f') - { - *res = (uint8_t)(pb - 'a' + 10); - return true; - } - else if (pb >= 'A' && pb <= 'F') - { - *res = (uint8_t)(pb - 'A' + 10); - return true; - } - return false; -} - -// Compare a name from certificate and domain name, return true if they match -static bool matchName(const std::string &name, const std::string &domainName) -{ - size_t wildcardPos = name.find('*'); - if (wildcardPos == std::string::npos) - { - // Not a wildcard, expect an exact match - return name == domainName; - } - - size_t firstDotPos = name.find('.'); - if (wildcardPos > firstDotPos) - { - // Wildcard is not part of leftmost component of domain name - // Do not attempt to match (rfc6125 6.4.3.1) - return false; - } - if (wildcardPos != 0 || firstDotPos != 1) - { - // Matching of wildcards such as baz*.example.com and b*z.example.com - // is optional. Maybe implement this in the future? - return false; - } - size_t domainNameFirstDotPos = domainName.find('.'); - if (domainNameFirstDotPos == std::string::npos) - { - return false; - } - return domainName.substr(domainNameFirstDotPos) == name.substr(firstDotPos); -} - -// Verifies certificate provided by the peer to match specified SHA256 fingerprint -bool verify_ssl_fingerprint(fb_esp_ssl_ctx32 *ssl_client, const char *fp, const char *domain_name) -{ - // Convert hex string to byte array - uint8_t fingerprint_local[32]; - int len = strlen(fp); - int pos = 0; - for (size_t i = 0; i < sizeof(fingerprint_local); ++i) - { - while (pos < len && ((fp[pos] == ' ') || (fp[pos] == ':'))) - { - ++pos; - } - if (pos > len - 2) - { - log_d("pos:%d len:%d fingerprint too short", pos, len); - return false; - } - uint8_t high, low; - if (!parseHexNibble(fp[pos], &high) || !parseHexNibble(fp[pos + 1], &low)) - { - log_d("pos:%d len:%d invalid hex sequence: %c%c", pos, len, fp[pos], fp[pos + 1]); - return false; - } - pos += 2; - fingerprint_local[i] = low | (high << 4); - } - - // Get certificate provided by the peer - const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&ssl_client->ssl_ctx); - - if (!crt) - { - log_d("could not fetch peer certificate"); - return false; - } - - // Calculate certificate's SHA256 fingerprint - uint8_t fingerprint_remote[32]; - mbedtls_sha256_context sha256_ctx; - mbedtls_sha256_init(&sha256_ctx); - mbedtls_sha256_starts(&sha256_ctx, false); - mbedtls_sha256_update(&sha256_ctx, crt->raw.p, crt->raw.len); - mbedtls_sha256_finish(&sha256_ctx, fingerprint_remote); - - // Check if fingerprints match - if (memcmp(fingerprint_local, fingerprint_remote, 32)) - { - log_d("fingerprint doesn't match"); - return false; - } - - // Additionally check if certificate has domain name if provided - if (domain_name) - return verify_ssl_dn(ssl_client, domain_name); - else - return true; -} - -// Checks if peer certificate has specified domain in CN or SANs -bool verify_ssl_dn(fb_esp_ssl_ctx32 *ssl_client, const char *domain_name) -{ - log_d("domain name: '%s'", (domain_name) ? domain_name : "(null)"); - std::string domain_name_str(domain_name); - std::transform(domain_name_str.begin(), domain_name_str.end(), domain_name_str.begin(), ::tolower); - - // Get certificate provided by the peer - const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&ssl_client->ssl_ctx); - - // Check for domain name in SANs - const mbedtls_x509_sequence *san = &crt->subject_alt_names; - while (san != nullptr) - { - std::string san_str((const char *)san->buf.p, san->buf.len); - std::transform(san_str.begin(), san_str.end(), san_str.begin(), ::tolower); - - if (matchName(san_str, domain_name_str)) - return true; - - log_d("SAN '%s': no match", san_str.c_str()); - - // Fetch next SAN - san = san->next; - } - - // Check for domain name in CN - const mbedtls_asn1_named_data *common_name = &crt->subject; - while (common_name != nullptr) - { - // While iterating through DN objects, check for CN object - if (!MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &common_name->oid)) - { - std::string common_name_str((const char *)common_name->val.p, common_name->val.len); - - if (matchName(common_name_str, domain_name_str)) - return true; - - log_d("CN '%s': not match", common_name_str.c_str()); - } - - // Fetch next DN object - common_name = common_name->next; - } - - return false; -} - -#endif /* ESP32 */ - -#endif /* FB_SSL_CLIENT32_CPP */ \ No newline at end of file diff --git a/src/wcs/esp32/fb_ssl_client32.h b/src/wcs/esp32/fb_ssl_client32.h deleted file mode 100644 index 3f7965a66..000000000 --- a/src/wcs/esp32/fb_ssl_client32.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - *Modified version of ssl_client.h version 1.0.2 -*/ - -/** Provide SSL/TLS functions to ESP32 with Arduino IDE - * by Evandro Copercini - 2017 - Apache 2.0 License - */ - -#ifndef FB_SSL_CLIENT32_H -#define FB_SSL_CLIENT32_H - -#ifdef ESP32 -#include -#include -#include -#include -#include -#include -#include - -typedef struct fb_esp_ssl_ctx32 -{ - int socket; - mbedtls_ssl_context ssl_ctx; - mbedtls_ssl_config ssl_conf; - - mbedtls_ctr_drbg_context drbg_ctx; - mbedtls_entropy_context entropy_ctx; - - mbedtls_x509_crt ca_cert; - mbedtls_x509_crt client_cert; - mbedtls_pk_context client_key; - - unsigned long handshake_timeout; - bool is_entropy_ctx; - bool ssl_freed; -} fb_esp_ssl_ctx32; - -void ssl_init(fb_esp_ssl_ctx32 *ssl_client); -int start_ssl_client(fb_esp_ssl_ctx32 *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey); -void stop_ssl_socket(fb_esp_ssl_ctx32 *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key); -int data_to_read(fb_esp_ssl_ctx32 *ssl_client); -int send_ssl_data(fb_esp_ssl_ctx32 *ssl_client, const uint8_t *data, uint16_t len); -int get_ssl_receive(fb_esp_ssl_ctx32 *ssl_client, uint8_t *data, int length); -bool verify_ssl_fingerprint(fb_esp_ssl_ctx32 *ssl_client, const char *fp, const char *domain_name); -bool verify_ssl_dn(fb_esp_ssl_ctx32 *ssl_client, const char *domain_name); - - -#endif /* ESP32 */ - -#endif /* FB_SSL_CLIENT32_H */ \ No newline at end of file diff --git a/src/wcs/esp8266/FB_HTTPClient.cpp b/src/wcs/esp8266/FB_HTTPClient.cpp index fa9514959..31bb32bb6 100644 --- a/src/wcs/esp8266/FB_HTTPClient.cpp +++ b/src/wcs/esp8266/FB_HTTPClient.cpp @@ -1,5 +1,5 @@ /** - * HTTP Client wrapper v1.1.5 + * HTTP Client wrapper v1.1.6 * * The MIT License (MIT) * Copyright (c) 2021 K. Suwatchai (Mobizt) @@ -201,13 +201,13 @@ void FB_HTTPClient::setCACertFile(const char* caCertFile, uint8_t storageType, u } else if (storageType == 2) { - bool t = SD.begin(_sdPin); + bool t = SD_FS.begin(_sdPin); if (t) { File f; - if (SD.exists(caCertFile)) + if (SD_FS.exists(caCertFile)) { - f = SD.open(caCertFile, FILE_READ); + f = SD_FS.open(caCertFile, FILE_READ); size_t len = f.size(); uint8_t *der = new uint8_t[len]; if (f.available()) diff --git a/src/wcs/esp8266/FB_HTTPClient.h b/src/wcs/esp8266/FB_HTTPClient.h index 4e02326d2..6dc2dfdf3 100644 --- a/src/wcs/esp8266/FB_HTTPClient.h +++ b/src/wcs/esp8266/FB_HTTPClient.h @@ -1,5 +1,5 @@ /** - * HTTP Client wrapper v1.1.5 + * HTTP Client wrapper v1.1.6 * * This library provides ESP8266 to perform REST API by GET PUT, POST, PATCH, DELETE data from/to with Google's Firebase database using get, set, update * and delete calls. @@ -33,22 +33,6 @@ #ifdef ESP8266 -//ARDUINO_ESP8266_GIT_VER -//2.6.2 0xbc204a9b -//2.6.1 0x482516e3 -//2.6.0 0x643ec203 -//2.5.2 0x8b899c12 -//2.5.1 0xac02aff5 -//2.5.0 0x951aeffa -//2.5.0-beta3 0x21db8fc9 -//2.5.0-beta2 0x0fd86a07 -//2.5.0-beta1 0x9c1e03a1 -//2.4.2 0xbb28d4a3 -//2.4.1 0x614f7c32 -//2.4.0 0x4ceabea9 -//2.4.0-rc2 0x0c897c37 -//2.4.0-rc1 0xf6d232f1 - #include #include #include @@ -62,40 +46,26 @@ #error Due to bugs in BearSSL in ESP8266 Arduino Core SDK version 2.6.1, please update ESP8266 Arduino Core SDK to newer version. The issue was found here https:\/\/github.com/esp8266/Arduino/issues/6811. #endif -#if ARDUINO_ESP8266_GIT_VER != 0xf6d232f1 && ARDUINO_ESP8266_GIT_VER != 0x0c897c37 && ARDUINO_ESP8266_GIT_VER != 0x4ceabea9 && ARDUINO_ESP8266_GIT_VER != 0x614f7c32 && ARDUINO_ESP8266_GIT_VER != 0xbb28d4a3 #include #include #define FB_ESP_SSL_CLIENT BearSSL::WiFiClientSecure -#elif ARDUINO_ESP8266_GIT_VER == 0xbb28d4a3 -#define USING_AXTLS -#include -using namespace axTLS; -#define FB_ESP_SSL_CLIENT axTLS::WiFiClientSecure -#else -#define USING_AXTLS -#include -#define FB_ESP_SSL_CLIENT WiFiClientSecure -#endif - #define FS_NO_GLOBALS #include #include +#include #include "FirebaseFS.h" -#ifdef USE_LITTLEFS -#include -#define FLASH_FS LittleFS -#else -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#define FLASH_FS SPIFFS -#endif #if __has_include() || __has_include() #error WiFi UART bridge was not supported. #endif +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#define FLASH_FS DEFAULT_FLASH_FS +#define SD_FS DEFAULT_SD_FS + #include "wcs/HTTPCode.h"